#define _CRT_SECURE_NO_WARNINGS #include #include "dxwnd.h" #include "dxwcore.hpp" #include "syslibs.h" #include "dxhelper.h" #include "resource.h" // SAVELASTDC: optimized mode, if the last window handle and size didn't change, // it is not necessary to create a new VirtualHDC and attached bitmap, you can reuse // the last one, with the further advantage of avoiding multiple scaling to and from // the virtual image with quality loss (see "BattleZone 1998"). // Unfortunately something is wrong with Imperialism II, so better not activate .... #ifdef DXWND_SAVELASTDC static HWND gLasthWnd = NULL; static RECT gLastRect = {0,0,0,0}; #endif HDC dxwCore::AcquireEmulatedDC(HWND hwnd) { HDC wdc; RECT WinRect; HGDIOBJ PrevSelection; //OutTrace("ACQUIRE hwnd=%x vhdc=%x pic=%x\n", hwnd, VirtualHDC, VirtualPic); if(!(wdc=(*pGDIGetDC)(hwnd))){ // potential DC leakage OutTraceE("AcquireEmulatedDC: GetDC ERROR hwnd=%x err=%d at=%d\n", hwnd, GetLastError(), __LINE__); return NULL; } (*pGetClientRect)(hwnd, &WinRect); VirtualPicRect = WinRect; dxw.UnmapClient(&VirtualPicRect); #ifdef DXWND_SAVELASTDC if((hwnd == gLasthWnd) && (WinRect.right == gLastRect.right) && (WinRect.bottom == gLastRect.bottom)) { if(!(*pGDIStretchBlt)(VirtualHDC, VirtualPicRect.left, VirtualPicRect.top, VirtualPicRect.right, VirtualPicRect.bottom, wdc, 0, 0, WinRect.right, WinRect.bottom, SRCCOPY)) OutTraceE("AcquireEmulatedDC: StretchBlt ERROR err=%d at=%d\n", GetLastError(), __LINE__); if(!(pGDIReleaseDC)(hwnd, wdc)) OutTraceE("AcquireEmulatedDC: ReleaseDC ERROR hdc=%x err=%d at=%d\n", wdc, GetLastError(), __LINE__); return VirtualHDC; } gLasthWnd = hwnd; gLastRect = WinRect; #endif //OutTrace("WINDOW picrect=(%d,%d)-(%d,%d)\n", // VirtualPicRect.left, VirtualPicRect.top, VirtualPicRect.right, VirtualPicRect.bottom); OutTraceB("AcquireEmulatedDC: hwnd=%x Desktop=%x WinRect=(%d,%d)(%d,%d) VirtRect=(%d,%d)(%d,%d)\n", hwnd, dxw.IsDesktop(hwnd), WinRect.left, WinRect.top, WinRect.right, WinRect.bottom, VirtualPicRect.left, VirtualPicRect.top, VirtualPicRect.right, VirtualPicRect.bottom); // v2.03.91.fx3: loop required to eliminate resource leakage ("Yu No") if(VirtualHDC) { while(TRUE){ if(!DeleteObject(VirtualHDC)) OutTraceE("AcquireEmulatedDC: DeleteObject ERROR hdc=%x err=%d at=%d\n", VirtualHDC, GetLastError(), __LINE__); else break; (*pSleep)(1); } } if(VirtualPic) { while(TRUE){ if(!DeleteObject(VirtualPic)) OutTraceE("AcquireEmulatedDC: DeleteObject ERROR pic=%x err=%d at=%d\n", VirtualPic, GetLastError(), __LINE__); else break; (*pSleep)(1); } } if(!(VirtualHDC=CreateCompatibleDC(wdc))) OutTraceE("AcquireEmulatedDC: CreateCompatibleDC ERROR err=%d at=%d\n", GetLastError(), __LINE__); if(!(VirtualPic=CreateCompatibleBitmap(wdc, dxw.GetScreenWidth(), dxw.GetScreenHeight()))) OutTraceE("AcquireEmulatedDC: CreateCompatibleBitmap ERROR err=%d at=%d\n", GetLastError(), __LINE__); if(!(PrevSelection=(*pSelectObject)(VirtualHDC, VirtualPic))) OutTraceE("AcquireEmulatedDC: SelectObject ERROR err=%d at=%d\n", GetLastError(), __LINE__); else { if(!DeleteObject(PrevSelection)) OutTraceE("AcquireEmulatedDC: DeleteObject ERROR pic=%x err=%d at=%d\n", PrevSelection, GetLastError(), __LINE__);; } //OutTrace("RENEW_IMAGE hdc=%x pic=%x\n", VirtualHDC, VirtualPic); if(!(*pGDIStretchBlt)(VirtualHDC, VirtualPicRect.left, VirtualPicRect.top, VirtualPicRect.right, VirtualPicRect.bottom, wdc, 0, 0, WinRect.right, WinRect.bottom, SRCCOPY)) OutTraceE("AcquireEmulatedDC: StretchBlt ERROR err=%d at=%d\n", GetLastError(), __LINE__); if(!(pGDIReleaseDC)(hwnd, wdc)) OutTraceE("AcquireEmulatedDC: ReleaseDC ERROR hdc=%x err=%d at=%d\n", wdc, GetLastError(), __LINE__); return VirtualHDC; } BOOL dxwCore::ReleaseEmulatedDC(HWND hwnd) { HDC wdc; RECT WinRect; //OutTrace("RELEASE hwnd=%x\n", hwnd); (*pGetClientRect)(hwnd, &WinRect); OutTraceB("ReleaseEmulatedDC: hwnd=%x Desktop=%x WinRect=(%d,%d)(%d,%d) VirtRect=(%d,%d)(%d,%d)\n", hwnd, dxw.IsDesktop(hwnd), WinRect.left, WinRect.top, WinRect.right, WinRect.bottom, VirtualPicRect.left, VirtualPicRect.top, VirtualPicRect.right, VirtualPicRect.bottom); if(!(wdc=(*pGDIGetDC)(hwnd))) { // potential DC leakage OutTraceE("ReleaseEmulatedDC: GetDC ERROR err=%d at=%d\n", GetLastError(), __LINE__); return FALSE; } SetStretchBltMode(VirtualHDC, HALFTONE); if(!(*pGDIStretchBlt)(wdc, 0, 0, WinRect.right, WinRect.bottom, VirtualHDC, 0, 0, VirtualPicRect.right, VirtualPicRect.bottom, SRCCOPY)) OutTraceE("ReleaseEmulatedDC: StretchBlt ERROR err=%d at=%d\n", GetLastError(), __LINE__); if(!(*pGDIReleaseDC)(hwnd, wdc))// fixed DC leakage OutTraceE("ReleaseEmulatedDC: ReleaseDC ERROR hwnd=%x hdc=%x err=%d at=%d\n", hwnd, wdc, GetLastError(), __LINE__); return TRUE; } void dxwCore::ResetEmulatedDC() { //OutTrace("RESET\n"); VirtualHDC=NULL; VirtualPic=NULL; VirtualOffsetX=0; VirtualOffsetY=0; } BOOL dxwCore::IsVirtual(HDC hdc) { return (hdc==VirtualHDC) && (GDIEmulationMode == GDIMODE_EMULATED); }