From da35a2c243085b67ea4222c55b97c1169a254892 Mon Sep 17 00:00:00 2001 From: gho tik Date: Fri, 10 Apr 2015 12:42:09 -0400 Subject: [PATCH] v2_03_39_src Former-commit-id: 2a15921bbbcf86a3440dde9b17d2a75812d6edfe --- Include/dxwnd.h | 2 + build/dxwnd.dll | 4 +- build/dxwnd.exe | 4 +- build/exports/Battlezone (1998).dxw | 32 + build/readme-relnotes.txt | 5 + dll/dxhook.cpp | 2 +- dll/dxwcore.cpp | 177 +- dll/dxwcore.hpp | 4 +- dll/dxwnd.cpp | 2 +- dll/dxwnd.sln | 20 + dll/dxwnd.vs2008.sln | 20 + dll/dxwnd.vs2008.suo | Bin 540672 -> 0 bytes dll/dxwnd.vs2008.vcproj | 4 +- dll/glhook.h | 5 +- dll/opengl.cpp | 61 +- dll/user32.cpp | 66 +- dll/user32.old.cpp | 3099 --------------------------- host/TabSysLibs.cpp | 2 + host/TargetDlg.cpp | 5 +- host/TargetDlg.h | 2 + host/dxwndhost.aps | Bin 132756 -> 160664 bytes host/dxwndhost.rc | Bin 104888 -> 105340 bytes host/dxwndhost.vs2008.sln | 20 + host/dxwndhost.vs2008.suo | Bin 7168 -> 0 bytes host/dxwndhostView.cpp | 4 + host/resource | Bin 36960 -> 37172 bytes 26 files changed, 307 insertions(+), 3233 deletions(-) create mode 100644 build/exports/Battlezone (1998).dxw create mode 100644 dll/dxwnd.sln create mode 100644 dll/dxwnd.vs2008.sln delete mode 100644 dll/dxwnd.vs2008.suo delete mode 100644 dll/user32.old.cpp create mode 100644 host/dxwndhost.vs2008.sln delete mode 100644 host/dxwndhost.vs2008.suo diff --git a/Include/dxwnd.h b/Include/dxwnd.h index f1018cc..97fa17b 100644 --- a/Include/dxwnd.h +++ b/Include/dxwnd.h @@ -203,6 +203,8 @@ #define WOW32REGISTRY 0x00080000 // Sets KEY_WOW32_64KEY registry flag #define STRETCHMOVIES 0x00100000 // Stretches ActiveMovie Windows to the whole window size #define BYPASSMCI 0x00200000 // bypass all MCI calls returning OK. +#define FIXPIXELZOOM 0x00400000 +#define REUSEEMULATEDDC 0x00800000 // logging Tflags DWORD: #define OUTTRACE 0x00000001 // enables tracing to dxwnd.log in general diff --git a/build/dxwnd.dll b/build/dxwnd.dll index e70f813..dc7b14b 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:870503d6ed66355803bffaf4e2a6faeaae7aef2ddab2b21a5ebe07aeb276eceb -size 587776 +oid sha256:4bc660ee000849fc12e93d97f058cd62e641538ffd39a9e145889a8f71d72091 +size 588800 diff --git a/build/dxwnd.exe b/build/dxwnd.exe index 6cf634c..1482c7d 100644 --- a/build/dxwnd.exe +++ b/build/dxwnd.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b3af6279bc2e830fe03fb38ba567676000fc17486c763e711fee3539605cf3c0 -size 544768 +oid sha256:1224f1ef28770a40f73036db53a6f6f0b810c026d2d3cf57a5b5006197f4e0b0 +size 545280 diff --git a/build/exports/Battlezone (1998).dxw b/build/exports/Battlezone (1998).dxw new file mode 100644 index 0000000..562c98d --- /dev/null +++ b/build/exports/Battlezone (1998).dxw @@ -0,0 +1,32 @@ +[target] +title0=Battlezone (1998) +path0=D:\Games\Battlezone\bzone.exe +launchpath0= +module0= +opengllib0= +notes0= +registry0= +ver0=0 +coord0=0 +flag0=-1608515533 +flagg0=1241513984 +flagh0=98320 +flagi0=138412036 +flagj0=4224 +flagk0=0 +tflag0=0 +initx0=0 +inity0=0 +minx0=0 +miny0=0 +maxx0=0 +maxy0=0 +posx0=150 +posy0=150 +sizx0=880 +sizy0=660 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index c85d789..a2175d2 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -915,3 +915,8 @@ v2.03.38 fix: handling of WM_ACTIVATE and WM_NCACTIVATE messages, should bring the window to HWND_NOTOPMOST z-order position only when activation is on, not off! fix: in "Share GDI and draw DC" mode, check if the primary surface really has a DC and switch to another one if the DC is missing. fix: eliminated some redundant code in GDI ReleaseDC in DC emulated mode + +v2.03.39 +add: "Fix glPixelZoom args" flag to scale images rendered by OpenGL through GDI. It is needed for "Strength and Honor". +add: "Reuse emulated DC" flag to optimize GDI emulation. experimental. + diff --git a/dll/dxhook.cpp b/dll/dxhook.cpp index 63c40c9..b2877cc 100644 --- a/dll/dxhook.cpp +++ b/dll/dxhook.cpp @@ -110,7 +110,7 @@ static char *Flag6Names[32]={ "FIXPITCH", "POWER2WIDTH", "HIDETASKBAR", "ACTIVATEAPP", "NOSYSMEMPRIMARY", "NOSYSMEMBACKBUF", "CONFIRMONCLOSE", "TERMINATEONCLOSE", "FLIPEMULATION", "SETZBUFFERBITDEPTHS", "SHAREDDC", "WOW32REGISTRY", - "STRETCHMOVIES", "BYPASSMCI", "", "", + "STRETCHMOVIES", "BYPASSMCI", "FIXPIXELZOOM", "REUSEEMULATEDDC", "", "", "", "", "", "", "", "", }; diff --git a/dll/dxwcore.cpp b/dll/dxwcore.cpp index 5a60ffe..b33a912 100644 --- a/dll/dxwcore.cpp +++ b/dll/dxwcore.cpp @@ -7,7 +7,10 @@ #include "syslibs.h" #include "dxhelper.h" #include "resource.h" +#include "hddraw.h" #include "d3d9.h" +extern GetDC_Type pGetDC; +extern ReleaseDC_Type pReleaseDC; /* ------------------------------------------------------------------ */ // Internal function pointers @@ -796,6 +799,8 @@ POINT dxwCore::ClientOffset(HWND hwnd) desk0 = upleft; if (desktop.right) ret.x = (((win0.x - desk0.x) * (LONG)dwScreenWidth) + (desktop.right >> 1)) / desktop.right; if (desktop.bottom) ret.y = (((win0.y - desk0.y) * (LONG)dwScreenHeight) + (desktop.bottom >> 1)) / desktop.bottom; + if(ret.x < 0) ret.x = 0; + if(ret.y < 0) ret.y = 0; OutTraceB("ClientOffset: hwnd=%x offset=(%d,%d)\n", hwnd, ret.x, ret.y); return ret; } @@ -1524,94 +1529,79 @@ void dxwCore::FixStyle(char *ApiName, HWND hwnd, WPARAM wParam, LPARAM lParam) HDC dxwCore::AcquireEmulatedDC(HWND hwnd) { HDC wdc; + RECT WinRect; + if(!(wdc=(*pGDIGetDC)(hwnd))){ OutTraceE("GetDC: ERROR err=%d at=%d\n", GetLastError(), __LINE__); return NULL; } - return AcquireEmulatedDC(wdc); -} - -HDC dxwCore::AcquireEmulatedDC(LPDIRECTDRAWSURFACE lpdds) -{ - HDC ddc; - typedef HRESULT (WINAPI *GetDC_Type) (LPDIRECTDRAWSURFACE, HDC FAR *); - extern GetDC_Type pGetDC; - if((*pGetDC)(lpdds, &ddc)) - OutTraceE("GetDC: ERROR err=%d at=%d\n", GetLastError(), __LINE__); - return AcquireEmulatedDC(ddc); -} - -HDC dxwCore::AcquireEmulatedDC(HDC wdc) -{ RealHDC=wdc; - HWND hwnd; - RECT WinRect; + + RECT LastVRect; + LastVRect = VirtualPicRect; + if(!(hwnd=WindowFromDC(wdc))) OutTraceE("WindowFromDC: ERROR err=%d at=%d\n", GetLastError(), __LINE__); (*pGetClientRect)(hwnd, &WinRect); if(dxw.IsDesktop(hwnd)){ - dxw.VirtualPicRect = dxw.GetScreenRect(); + // when screen resolution changes, better renew service resources + VirtualPicRect = dxw.GetScreenRect(); + if((LastVRect.right != VirtualPicRect.right) || (LastVRect.bottom != VirtualPicRect.bottom)) { + DeleteObject(VirtualHDC); + VirtualHDC = NULL; + DeleteObject(VirtualPic); + VirtualPic = NULL; + } } else { VirtualPicRect = WinRect; dxw.UnmapClient(&VirtualPicRect); } - if(!(VirtualHDC=CreateCompatibleDC(wdc))) - OutTraceE("CreateCompatibleDC: ERROR err=%d at=%d\n", GetLastError(), __LINE__); - if(!(VirtualPic=CreateCompatibleBitmap(wdc, VirtualPicRect.right, VirtualPicRect.bottom))) - OutTraceE("CreateCompatibleBitmap: ERROR err=%d at=%d\n", GetLastError(), __LINE__); - if(!SelectObject(VirtualHDC, VirtualPic)){ - if(!DeleteObject(VirtualPic)) - OutTraceE("DeleteObject: ERROR err=%d at=%d\n", GetLastError(), __LINE__); + + 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); + + if (!VirtualHDC){ + OutTraceB("AcquireEmulatedDC: INITIALIZE\n"); + if(!(VirtualHDC=CreateCompatibleDC(wdc))) + OutTraceE("CreateCompatibleDC: ERROR err=%d at=%d\n", GetLastError(), __LINE__); + if(!(VirtualPic=CreateCompatibleBitmap(wdc, dxw.GetScreenWidth(), dxw.GetScreenHeight()))) OutTraceE("CreateCompatibleBitmap: ERROR err=%d at=%d\n", GetLastError(), __LINE__); + if(!SelectObject(VirtualHDC, VirtualPic)) OutTraceE("SelectObject: ERROR err=%d at=%d\n", GetLastError(), __LINE__); + + if(!(*pGDIStretchBlt)(VirtualHDC, 0, 0, VirtualPicRect.right, VirtualPicRect.bottom, wdc, 0, 0, WinRect.right, WinRect.bottom, SRCCOPY)) + OutTraceE("StretchBlt: ERROR err=%d at=%d\n", GetLastError(), __LINE__); } - if(!(*pGDIStretchBlt)(VirtualHDC, 0, 0, VirtualPicRect.right, VirtualPicRect.bottom, wdc, 0, 0, WinRect.right, WinRect.bottom, SRCCOPY)) - OutTraceE("StretchBlt: ERROR err=%d at=%d\n", GetLastError(), __LINE__); + return VirtualHDC; } BOOL dxwCore::ReleaseEmulatedDC(HWND hwnd) { - BOOL ret; HDC wdc; - RECT client; - (*pGetClientRect)(hwnd, &client); + RECT WinRect; + + (*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))) OutTraceE("GetDC: ERROR err=%d at=%d\n", GetLastError(), __LINE__); - //OutTrace("StretchBlt: destdc=%x destrect=(0,0)-(%d,%d) srcdc=%x srcrect=(0,0)-(%d,%d)\n", wdc, client.right, client.bottom, VirtualHDC, VirtualPicRect.right, VirtualPicRect.bottom); - // v2.02.94: set HALFTONE stretching. But causes problems with Imperialism II - // SetStretchBltMode(wdc,HALFTONE); -#if 1 - if(!(*pGDIStretchBlt)(wdc, 0, 0, client.right, client.bottom, VirtualHDC, 0, 0, VirtualPicRect.right, VirtualPicRect.bottom, SRCCOPY)) + SetStretchBltMode(wdc, HALFTONE); + if(!(*pGDIStretchBlt)(wdc, 0, 0, WinRect.right, WinRect.bottom, VirtualHDC, 0, 0, VirtualPicRect.right, VirtualPicRect.bottom, SRCCOPY)) OutTraceE("StretchBlt: ERROR err=%d at=%d\n", GetLastError(), __LINE__); -#else - int w, h, bx, by; // width, height and x,y borders - RECT RetRect; - bx = by = 0; - RetRect=client; - if (dwFlags2 & KEEPASPECTRATIO){ - w = RetRect.right - RetRect.left; - h = RetRect.bottom - RetRect.top; - if ((w * iRatioY) > (h * iRatioX)){ - bx = (w - (h * iRatioX / iRatioY))/2; - } - else { - by = (h - (w * iRatioY / iRatioX))/2; - } - } - if(!(*pGDIStretchBlt)(wdc, bx, by, client.right-bx, client.bottom-by, VirtualHDC, 0, 0, VirtualPicRect.right, VirtualPicRect.bottom, SRCCOPY)) - OutTraceE("StretchBlt: ERROR err=%d at=%d\n", GetLastError(), __LINE__); -#endif //(*pInvalidateRect)(hwnd, NULL, 0); - if(!DeleteObject(VirtualPic)) - OutTraceE("DeleteObject: ERROR err=%d at=%d\n", GetLastError(), __LINE__); - if(!DeleteObject(VirtualHDC)) - OutTraceE("DeleteObject: ERROR err=%d at=%d\n", GetLastError(), __LINE__); - ret=TRUE; - return ret; + + (*pGDIReleaseDC)(hwnd, VirtualHDC); + return TRUE; } void dxwCore::ResetEmulatedDC() @@ -1627,6 +1617,75 @@ BOOL dxwCore::IsVirtual(HDC hdc) return (hdc==VirtualHDC) && (dwFlags3 & GDIEMULATEDC); } +HDC dxwCore::AcquireSharedDC(HWND hwnd) +{ + extern HDC hFlippedDC; + LPDIRECTDRAWSURFACE lpDDSPrim; + lpDDSPrim = dxwss.GetPrimarySurface(); + if (lpDDSPrim) (*pGetDC)(lpDDSPrim, &hFlippedDC); + while((hFlippedDC == NULL) && lpDDSPrim) { + OutTraceDW("AcquireSharedDC: found primary surface with no DC, unref lpdds=%x\n", lpDDSPrim); + dxwss.UnrefSurface(lpDDSPrim); + lpDDSPrim = dxwss.GetPrimarySurface(); + if (lpDDSPrim) (*pGetDC)(lpDDSPrim, &hFlippedDC); + } + if (!(hwnd == dxw.GethWnd())) { + POINT father, child, offset; + father.x = father.y = 0; + child.x = child.y = 0; + (*pClientToScreen)(dxw.GethWnd(),&father); + (*pClientToScreen)(hwnd,&child); + offset.x = child.x - father.x; + offset.y = child.y - father.y; + dxw.UnmapClient(&offset); + OutTraceDW("AcquireSharedDC: child window hwnd=%x offset=(%d,%d)\n", hwnd, offset.x, offset.y); + (*pSetViewportOrgEx)(hFlippedDC, offset.x, offset.y, NULL); + } + else + (*pSetViewportOrgEx)(VirtualHDC, 0, 0, NULL); + + OutTraceDW("AcquireSharedDC: remapping flipped GDI lpDDSPrim=%x hdc=%x\n", lpDDSPrim, hFlippedDC); + return hFlippedDC; +} + +BOOL dxwCore::ReleaseSharedDC(HWND hwnd, HDC hDC) +{ + HRESULT ret; + LPDIRECTDRAWSURFACE lpDDSPrim; + lpDDSPrim = dxwss.GetPrimarySurface(); + if(!lpDDSPrim) return(TRUE); + OutTraceDW("GDI.ReleaseDC: releasing flipped GDI hdc=%x\n", hDC); + ret=(*pReleaseDC)(dxwss.GetPrimarySurface(), hDC); + if (!(hwnd == dxw.GethWnd())) { + POINT father, child, offset; + RECT rect; + HDC hdc; + father.x = father.y = 0; + child.x = child.y = 0; + (*pClientToScreen)(dxw.GethWnd(),&father); + (*pClientToScreen)(hwnd,&child); + offset.x = child.x - father.x; + offset.y = child.y - father.y; + if(offset.x || offset.y){ + // if the graphis was blitted to primary but below a modal child window, + // bring that up to the window surface to make it visible. + BOOL ret2; + (*pGetClientRect)(hwnd, &rect); + hdc=(*pGDIGetDC)(hwnd); + if(!hdc) OutTrace("GDI.ReleaseDC: GetDC ERROR=%d at %d\n", GetLastError(), __LINE__); + ret2=(*pGDIBitBlt)(hdc, rect.left, rect.top, rect.right, rect.bottom, hDC, offset.x, offset.y, SRCCOPY); + if(!ret2) OutTrace("GDI.ReleaseDC: BitBlt ERROR=%d at %d\n", GetLastError(), __LINE__); + ret2=(*pGDIReleaseDC)(hwnd, hdc); + if(!ret2)OutTrace("GDI.ReleaseDC: ReleaseDC ERROR=%d at %d\n", GetLastError(), __LINE__); + // this may flicker .... + (*pInvalidateRect)(hwnd, NULL, FALSE); + } + } + if (ret) OutTraceE("GDI.ReleaseDC ERROR: err=%x(%s) at %d\n", ret, ExplainDDError(ret), __LINE__); + else dxw.ScreenRefresh(); + return (ret == DD_OK); +} + void dxwCore::PushTimer(UINT uTimerId, UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, DWORD_PTR dwUser, UINT fuEvent) { // save current timer diff --git a/dll/dxwcore.hpp b/dll/dxwcore.hpp index 9a01f44..c297a71 100644 --- a/dll/dxwcore.hpp +++ b/dll/dxwcore.hpp @@ -110,9 +110,9 @@ public: // methods void FixStyle(char *, HWND, WPARAM, LPARAM); void FixWindowFrame(HWND); HDC AcquireEmulatedDC(HWND); - HDC AcquireEmulatedDC(HDC); - HDC AcquireEmulatedDC(LPDIRECTDRAWSURFACE); BOOL ReleaseEmulatedDC(HWND); + HDC AcquireSharedDC(HWND); + BOOL ReleaseSharedDC(HWND, HDC); BOOL IsVirtual(HDC); void ResetEmulatedDC(); int VirtualOffsetX, VirtualOffsetY; diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp index ffd06be..61acf34 100644 --- a/dll/dxwnd.cpp +++ b/dll/dxwnd.cpp @@ -27,7 +27,7 @@ along with this program. If not, see . #include "TlHelp32.h" -#define VERSION "2.03.38" +#define VERSION "2.03.39" #define DDTHREADLOCK 1 //#define LOCKTHREADS diff --git a/dll/dxwnd.sln b/dll/dxwnd.sln new file mode 100644 index 0000000..7be8845 --- /dev/null +++ b/dll/dxwnd.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dxwnd", "dxwnd.vcproj", "{579E7FE7-2745-4100-A802-23511711FCDE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {579E7FE7-2745-4100-A802-23511711FCDE}.Debug|Win32.ActiveCfg = Debug|Win32 + {579E7FE7-2745-4100-A802-23511711FCDE}.Debug|Win32.Build.0 = Debug|Win32 + {579E7FE7-2745-4100-A802-23511711FCDE}.Release|Win32.ActiveCfg = Release|Win32 + {579E7FE7-2745-4100-A802-23511711FCDE}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/dll/dxwnd.vs2008.sln b/dll/dxwnd.vs2008.sln new file mode 100644 index 0000000..0d2e531 --- /dev/null +++ b/dll/dxwnd.vs2008.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dxwnd", "dxwnd.vs2008.vcproj", "{579E7FE7-2745-4100-A802-23511711FCDE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {579E7FE7-2745-4100-A802-23511711FCDE}.Debug|Win32.ActiveCfg = Debug|Win32 + {579E7FE7-2745-4100-A802-23511711FCDE}.Debug|Win32.Build.0 = Debug|Win32 + {579E7FE7-2745-4100-A802-23511711FCDE}.Release|Win32.ActiveCfg = Release|Win32 + {579E7FE7-2745-4100-A802-23511711FCDE}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo deleted file mode 100644 index cc7bc5b506ffa8f96f7e7e1a9467d896c2d1e59c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 540672 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 -#include -#include "dxwnd.h" -#include "dxwcore.hpp" -#include "syslibs.h" -#include "dxhook.h" -#include "hddraw.h" -#include "dxhelper.h" - -#define FIXCHILDSIZE FALSE - -BOOL IsChangeDisplaySettingsHotPatched = FALSE; -#define GDIMODE_STRETCHED 0 -#define GDIMODE_EMULATED 1 -int GDIEmulationMode = 0; -extern BOOL bFlippedDC; -extern HDC hFlippedDC; - -//typedef BOOL (WINAPI *ValidateRect_Type)(HWND, const RECT *); -//BOOL WINAPI extValidateRect(HWND, const RECT *); -//ValidateRect_Type pValidateRect = NULL; - -//typedef BOOL (WINAPI *EnumDisplayMonitors_Type)(HDC, LPCRECT, MONITORENUMPROC, LPARAM); -//EnumDisplayMonitors_Type pEnumDisplayMonitors = NULL; -//BOOL WINAPI extEnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC, LPARAM); - -typedef BOOL (WINAPI *BringWindowToTop_Type)(HWND); -BringWindowToTop_Type pBringWindowToTop = NULL; -BOOL WINAPI extBringWindowToTop(HWND); -typedef BOOL (WINAPI *SetForegroundWindow_Type)(HWND); -SetForegroundWindow_Type pSetForegroundWindow = NULL; -BOOL WINAPI extSetForegroundWindow(HWND); -typedef HHOOK (WINAPI *SetWindowsHookEx_Type)(int, HOOKPROC, HINSTANCE, DWORD); -SetWindowsHookEx_Type pSetWindowsHookEx = NULL; -HHOOK WINAPI extSetWindowsHookEx(int, HOOKPROC, HINSTANCE, DWORD); -typedef BOOL (WINAPI *PostMessageA_Type)(HWND, UINT, WPARAM, LPARAM); -PostMessageA_Type pPostMessageA = NULL; -BOOL WINAPI extPostMessageA(HWND, UINT, WPARAM, LPARAM); -typedef HRESULT (WINAPI *MessageBoxTimeoutA_Type)(HWND, LPCSTR, LPCSTR, UINT, WORD, DWORD); -MessageBoxTimeoutA_Type pMessageBoxTimeoutA = NULL; -HRESULT WINAPI extMessageBoxTimeoutA(HWND, LPCSTR, LPCSTR, UINT, WORD, DWORD); -typedef HRESULT (WINAPI *MessageBoxTimeoutW_Type)(HWND, LPCWSTR, LPCWSTR, UINT, WORD, DWORD); -MessageBoxTimeoutW_Type pMessageBoxTimeoutW = NULL; -HRESULT WINAPI extMessageBoxTimeoutW(HWND, LPCWSTR, LPCWSTR, UINT, WORD, DWORD); -typedef BOOL (WINAPI *IsIconic_Type)(HWND); -IsIconic_Type pIsIconic = NULL; -BOOL WINAPI extIsIconic(HWND); -typedef BOOL (WINAPI *IsZoomed_Type)(HWND); -IsZoomed_Type pIsZoomed = NULL; -BOOL WINAPI extIsZoomed(HWND); -typedef HDESK (WINAPI *CreateDesktop_Type)(LPCTSTR, LPCTSTR, DEVMODE *, DWORD, ACCESS_MASK, LPSECURITY_ATTRIBUTES); -CreateDesktop_Type pCreateDesktop = NULL; -HDESK WINAPI extCreateDesktop(LPCTSTR, LPCTSTR, DEVMODE *, DWORD, ACCESS_MASK, LPSECURITY_ATTRIBUTES); -typedef BOOL (WINAPI *SwitchDesktop_Type)(HDESK); -SwitchDesktop_Type pSwitchDesktop = NULL; -BOOL WINAPI extSwitchDesktop(HDESK); -typedef HDESK (WINAPI *OpenDesktop_Type)(LPTSTR, DWORD, BOOL, ACCESS_MASK); -OpenDesktop_Type pOpenDesktop = NULL; -HDESK WINAPI extOpenDesktop(LPTSTR, DWORD, BOOL, ACCESS_MASK); -typedef BOOL (WINAPI *CloseDesktop_Type)(HDESK); -CloseDesktop_Type pCloseDesktop = NULL; -BOOL WINAPI extCloseDesktop(HDESK); - -typedef INT_PTR (WINAPI *DialogBoxParamA_Type)(HINSTANCE, LPCTSTR, HWND, DLGPROC, LPARAM); -DialogBoxParamA_Type pDialogBoxParamA = NULL; -INT_PTR WINAPI extDialogBoxParamA(HINSTANCE, LPCTSTR, HWND, DLGPROC, LPARAM); - -#ifdef TRACEPALETTE -typedef UINT (WINAPI *GetDIBColorTable_Type)(HDC, UINT, UINT, RGBQUAD *); -GetDIBColorTable_Type pGetDIBColorTable = NULL; -UINT WINAPI extGetDIBColorTable(HDC, UINT, UINT, RGBQUAD *); -typedef UINT (WINAPI *SetDIBColorTable_Type)(HDC, UINT, UINT, const RGBQUAD *); -SetDIBColorTable_Type pSetDIBColorTable = NULL; -UINT WINAPI extSetDIBColorTable(HDC, UINT, UINT, const RGBQUAD *); -#endif - -static HookEntry_Type Hooks[]={ - {HOOK_IAT_CANDIDATE, "UpdateWindow", (FARPROC)NULL, (FARPROC *)&pUpdateWindow, (FARPROC)extUpdateWindow}, - {HOOK_IAT_CANDIDATE, "GetWindowPlacement", (FARPROC)NULL, (FARPROC *)&pGetWindowPlacement, (FARPROC)extGetWindowPlacement}, - {HOOK_IAT_CANDIDATE, "SetWindowPlacement", (FARPROC)NULL, (FARPROC *)&pSetWindowPlacement, (FARPROC)extSetWindowPlacement}, - {HOOK_HOT_CANDIDATE, "ChangeDisplaySettingsA", (FARPROC)ChangeDisplaySettingsA, (FARPROC *)&pChangeDisplaySettingsA, (FARPROC)extChangeDisplaySettingsA}, - {HOOK_HOT_CANDIDATE, "ChangeDisplaySettingsExA", (FARPROC)ChangeDisplaySettingsExA, (FARPROC *)&pChangeDisplaySettingsExA, (FARPROC)extChangeDisplaySettingsExA}, - {HOOK_HOT_CANDIDATE, "ChangeDisplaySettingsW", (FARPROC)NULL, (FARPROC *)&pChangeDisplaySettingsW, (FARPROC)extChangeDisplaySettingsW}, // ref. by Knights of Honor - {HOOK_HOT_CANDIDATE, "ChangeDisplaySettingsExW", (FARPROC)NULL, (FARPROC *)&pChangeDisplaySettingsExW, (FARPROC)extChangeDisplaySettingsExW}, - {HOOK_HOT_CANDIDATE, "GetMonitorInfoA", (FARPROC)GetMonitorInfoA, (FARPROC *)&pGetMonitorInfoA, (FARPROC)extGetMonitorInfoA}, - {HOOK_HOT_CANDIDATE, "GetMonitorInfoW", (FARPROC)GetMonitorInfoW, (FARPROC *)&pGetMonitorInfoW, (FARPROC)extGetMonitorInfoW}, - {HOOK_IAT_CANDIDATE, "ShowCursor", (FARPROC)ShowCursor, (FARPROC *)&pShowCursor, (FARPROC)extShowCursor}, - {HOOK_IAT_CANDIDATE, "CreateDialogIndirectParamA", (FARPROC)CreateDialogIndirectParamA, (FARPROC *)&pCreateDialogIndirectParam, (FARPROC)extCreateDialogIndirectParam}, - {HOOK_IAT_CANDIDATE, "CreateDialogParamA", (FARPROC)CreateDialogParamA, (FARPROC *)&pCreateDialogParam, (FARPROC)extCreateDialogParam}, - {HOOK_IAT_CANDIDATE, "MoveWindow", (FARPROC)MoveWindow, (FARPROC *)&pMoveWindow, (FARPROC)extMoveWindow}, - {HOOK_IAT_CANDIDATE, "EnumDisplaySettingsA", (FARPROC)EnumDisplaySettingsA, (FARPROC *)&pEnumDisplaySettings, (FARPROC)extEnumDisplaySettings}, - {HOOK_IAT_CANDIDATE, "GetClipCursor", (FARPROC)GetClipCursor, (FARPROC*)&pGetClipCursor, (FARPROC)extGetClipCursor}, - {HOOK_IAT_CANDIDATE, "ClipCursor", (FARPROC)ClipCursor, (FARPROC *)&pClipCursor, (FARPROC)extClipCursor}, - {HOOK_IAT_CANDIDATE, "DefWindowProcA", (FARPROC)DefWindowProcA, (FARPROC *)&pDefWindowProcA, (FARPROC)extDefWindowProcA}, - {HOOK_IAT_CANDIDATE, "DefWindowProcW", (FARPROC)DefWindowProcW, (FARPROC *)&pDefWindowProcW, (FARPROC)extDefWindowProcW}, - {HOOK_HOT_CANDIDATE, "CreateWindowExA", (FARPROC)CreateWindowExA, (FARPROC *)&pCreateWindowExA, (FARPROC)extCreateWindowExA}, - {HOOK_HOT_CANDIDATE, "CreateWindowExW", (FARPROC)CreateWindowExW, (FARPROC *)&pCreateWindowExW, (FARPROC)extCreateWindowExW}, - {HOOK_IAT_CANDIDATE, "RegisterClassExA", (FARPROC)RegisterClassExA, (FARPROC *)&pRegisterClassExA, (FARPROC)extRegisterClassExA}, - {HOOK_IAT_CANDIDATE, "RegisterClassA", (FARPROC)RegisterClassA, (FARPROC *)&pRegisterClassA, (FARPROC)extRegisterClassA}, - {HOOK_HOT_CANDIDATE, "GetSystemMetrics", (FARPROC)GetSystemMetrics, (FARPROC *)&pGetSystemMetrics, (FARPROC)extGetSystemMetrics}, - {HOOK_HOT_CANDIDATE, "GetDesktopWindow", (FARPROC)GetDesktopWindow, (FARPROC *)&pGetDesktopWindow, (FARPROC)extGetDesktopWindow}, - {HOOK_IAT_CANDIDATE, "CloseWindow", (FARPROC)NULL, (FARPROC *)&pCloseWindow, (FARPROC)extCloseWindow}, - {HOOK_IAT_CANDIDATE, "DestroyWindow", (FARPROC)NULL, (FARPROC *)&pDestroyWindow, (FARPROC)extDestroyWindow}, - {HOOK_IAT_CANDIDATE, "SetSysColors", (FARPROC)NULL, (FARPROC *)&pSetSysColors, (FARPROC)extSetSysColors}, - {HOOK_IAT_CANDIDATE, "SetCapture", (FARPROC)NULL, (FARPROC *)&pSetCapture, (FARPROC)extSetCapture}, - {HOOK_HOT_CANDIDATE, "SetWindowLongA", (FARPROC)SetWindowLongA, (FARPROC *)&pSetWindowLongA, (FARPROC)extSetWindowLongA}, - {HOOK_HOT_CANDIDATE, "GetWindowLongA", (FARPROC)GetWindowLongA, (FARPROC *)&pGetWindowLongA, (FARPROC)extGetWindowLongA}, - {HOOK_HOT_CANDIDATE, "SetWindowLongW", (FARPROC)SetWindowLongW, (FARPROC *)&pSetWindowLongW, (FARPROC)extSetWindowLongW}, - {HOOK_HOT_CANDIDATE, "GetWindowLongW", (FARPROC)GetWindowLongW, (FARPROC *)&pGetWindowLongW, (FARPROC)extGetWindowLongW}, - {HOOK_IAT_CANDIDATE, "IsWindowVisible", (FARPROC)NULL, (FARPROC *)&pIsWindowVisible, (FARPROC)extIsWindowVisible}, - // hot by MinHook since v2.03.07 - {HOOK_HOT_CANDIDATE, "SystemParametersInfoA", (FARPROC)SystemParametersInfoA, (FARPROC *)&pSystemParametersInfoA, (FARPROC)extSystemParametersInfoA}, - {HOOK_HOT_CANDIDATE, "SystemParametersInfoW", (FARPROC)SystemParametersInfoW, (FARPROC *)&pSystemParametersInfoW, (FARPROC)extSystemParametersInfoW}, - //{HOOK_HOT_CANDIDATE, "GetActiveWindow", (FARPROC)NULL, (FARPROC *)&pGetActiveWindow, (FARPROC)extGetActiveWindow}, - //{HOOK_HOT_CANDIDATE, "GetForegroundWindow", (FARPROC)GetForegroundWindow, (FARPROC *)&pGetForegroundWindow, (FARPROC)extGetForegroundWindow}, - //{HOOK_IAT_CANDIDATE, "GetWindowTextA", (FARPROC)GetWindowTextA, (FARPROC *)&pGetWindowTextA, (FARPROC)extGetWindowTextA}, - //{HOOK_HOT_CANDIDATE, "EnumDisplayMonitors", (FARPROC)EnumDisplayMonitors, (FARPROC *)&pEnumDisplayMonitors, (FARPROC)extEnumDisplayMonitors}, -#ifdef TRACEPALETTE - {HOOK_HOT_CANDIDATE, "GetDIBColorTable", (FARPROC)GetDIBColorTable, (FARPROC *)&pGetDIBColorTable, (FARPROC)extGetDIBColorTable}, - {HOOK_HOT_CANDIDATE, "SetDIBColorTable", (FARPROC)SetDIBColorTable, (FARPROC *)&pSetDIBColorTable, (FARPROC)extSetDIBColorTable}, -#endif - - {HOOK_HOT_CANDIDATE, "BringWindowToTop", (FARPROC)BringWindowToTop, (FARPROC *)&pBringWindowToTop, (FARPROC)extBringWindowToTop}, - {HOOK_HOT_CANDIDATE, "SetForegroundWindow", (FARPROC)SetForegroundWindow, (FARPROC *)&pSetForegroundWindow, (FARPROC)extSetForegroundWindow}, - {HOOK_HOT_CANDIDATE, "ChildWindowFromPoint", (FARPROC)ChildWindowFromPoint, (FARPROC *)&pChildWindowFromPoint, (FARPROC)extChildWindowFromPoint}, - {HOOK_HOT_CANDIDATE, "ChildWindowFromPointEx", (FARPROC)ChildWindowFromPointEx, (FARPROC *)&pChildWindowFromPointEx, (FARPROC)extChildWindowFromPointEx}, - {HOOK_HOT_CANDIDATE, "WindowFromPoint", (FARPROC)WindowFromPoint, (FARPROC *)&pWindowFromPoint, (FARPROC)extWindowFromPoint}, - {HOOK_HOT_CANDIDATE, "SetWindowsHookExA", (FARPROC)SetWindowsHookExA, (FARPROC *)&pSetWindowsHookEx, (FARPROC)extSetWindowsHookEx}, - - //{HOOK_HOT_CANDIDATE, "MessageBoxTimeoutA", (FARPROC)NULL, (FARPROC *)&pMessageBoxTimeoutA, (FARPROC)extMessageBoxTimeoutA}, - //{HOOK_HOT_CANDIDATE, "MessageBoxTimeoutW", (FARPROC)NULL, (FARPROC *)&pMessageBoxTimeoutW, (FARPROC)extMessageBoxTimeoutW}, - - {HOOK_IAT_CANDIDATE, "CreateDesktopA", (FARPROC)CreateDesktopA, (FARPROC *)&pCreateDesktop, (FARPROC)extCreateDesktop}, - {HOOK_IAT_CANDIDATE, "SwitchDesktop", (FARPROC)SwitchDesktop, (FARPROC *)&pSwitchDesktop, (FARPROC)extSwitchDesktop}, - {HOOK_IAT_CANDIDATE, "OpenDesktopA", (FARPROC)OpenDesktopA, (FARPROC *)&pOpenDesktop, (FARPROC)extOpenDesktop}, - {HOOK_IAT_CANDIDATE, "CloseDesktop", (FARPROC)CloseDesktop, (FARPROC *)&pCloseDesktop, (FARPROC)extCloseDesktop}, - - {HOOK_IAT_CANDIDATE, "GetDC", (FARPROC)GetDC, (FARPROC *)&pGDIGetDC, (FARPROC)extGDIGetDC}, - {HOOK_IAT_CANDIDATE, "GetDCEx", (FARPROC)GetDCEx, (FARPROC *)&pGDIGetDCEx, (FARPROC)extGDIGetDCEx}, - {HOOK_IAT_CANDIDATE, "GetWindowDC", (FARPROC)GetWindowDC, (FARPROC *)&pGDIGetWindowDC, (FARPROC)extGDIGetWindowDC}, - {HOOK_IAT_CANDIDATE, "ReleaseDC", (FARPROC)ReleaseDC, (FARPROC *)&pGDIReleaseDC, (FARPROC)extGDIReleaseDC}, - - {HOOK_HOT_CANDIDATE, "BeginPaint", (FARPROC)BeginPaint, (FARPROC *)&pBeginPaint, (FARPROC)extBeginPaint}, - {HOOK_HOT_CANDIDATE, "EndPaint", (FARPROC)EndPaint, (FARPROC *)&pEndPaint, (FARPROC)extEndPaint}, - - {HOOK_IAT_CANDIDATE, "DialogBoxParamA", (FARPROC)NULL, (FARPROC *)&pDialogBoxParamA, (FARPROC)extDialogBoxParamA}, - - //{HOOK_IAT_CANDIDATE, "IsZoomed", (FARPROC)NULL, (FARPROC *)&pIsZoomed, (FARPROC)extIsZoomed}, - //{HOOK_HOT_CANDIDATE, "IsIconic", (FARPROC)IsIconic, (FARPROC *)&pIsIconic, (FARPROC)extIsIconic}, - - {HOOK_HOT_CANDIDATE, "FillRect", (FARPROC)NULL, (FARPROC *)&pFillRect, (FARPROC)extFillRect}, - - {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator -}; - -static HookEntry_Type NoGDIHooks[]={ - {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator -}; - -static HookEntry_Type EmulateHooks[]={ - //{HOOK_IAT_CANDIDATE, "GetDC", (FARPROC)GetDC, (FARPROC *)&pGDIGetDC, (FARPROC)extGDIGetDC}, - //{HOOK_IAT_CANDIDATE, "GetDCEx", (FARPROC)GetDCEx, (FARPROC *)&pGDIGetDCEx, (FARPROC)extGDIGetDCEx}, - //{HOOK_IAT_CANDIDATE, "GetWindowDC", (FARPROC)GetWindowDC, (FARPROC *)&pGDIGetWindowDC, (FARPROC)extGDIGetWindowDC}, - //{HOOK_IAT_CANDIDATE, "ReleaseDC", (FARPROC)ReleaseDC, (FARPROC *)&pGDIReleaseDC, (FARPROC)extGDIReleaseDC}, - //{HOOK_IAT_CANDIDATE, "InvalidateRect", (FARPROC)InvalidateRect, (FARPROC *)&pInvalidateRect, (FARPROC)extInvalidateRect}, - {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator -}; - -static HookEntry_Type ScaledHooks[]={ - {HOOK_IAT_CANDIDATE, "FrameRect", (FARPROC)NULL, (FARPROC *)&pFrameRect, (FARPROC)extFrameRect}, - {HOOK_IAT_CANDIDATE, "TabbedTextOutA", (FARPROC)TabbedTextOutA, (FARPROC *)&pTabbedTextOutA, (FARPROC)extTabbedTextOutA}, - {HOOK_IAT_CANDIDATE, "DrawTextA", (FARPROC)DrawTextA, (FARPROC *)&pDrawText, (FARPROC)extDrawTextA}, - {HOOK_IAT_CANDIDATE, "DrawTextExA", (FARPROC)DrawTextExA, (FARPROC *)&pDrawTextEx, (FARPROC)extDrawTextExA}, - //{HOOK_HOT_CANDIDATE, "FillRect", (FARPROC)NULL, (FARPROC *)&pFillRect, (FARPROC)extFillRect}, - //{HOOK_IAT_CANDIDATE, "GetDC", (FARPROC)GetDC, (FARPROC *)&pGDIGetDC, (FARPROC)extGDIGetDC}, - //{HOOK_IAT_CANDIDATE, "GetDCEx", (FARPROC)NULL, (FARPROC *)&pGDIGetDCEx, (FARPROC)extGDIGetDCEx}, - //{HOOK_IAT_CANDIDATE, "GetWindowDC", (FARPROC)GetWindowDC, (FARPROC *)&pGDIGetWindowDC, (FARPROC)extGDIGetWindowDC}, - //{HOOK_IAT_CANDIDATE, "ReleaseDC", (FARPROC)ReleaseDC, (FARPROC *)&pGDIReleaseDC, (FARPROC)extGDIReleaseDC}, - {HOOK_IAT_CANDIDATE, "InvalidateRect", (FARPROC)InvalidateRect, (FARPROC *)&pInvalidateRect, (FARPROC)extInvalidateRect}, - //{HOOK_IAT_CANDIDATE, "ValidateRect", (FARPROC)ValidateRect, (FARPROC *)&pValidateRect, (FARPROC)extValidateRect}, - {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator -}; - -static HookEntry_Type RemapHooks[]={ - {HOOK_IAT_CANDIDATE, "ScreenToClient", (FARPROC)ScreenToClient, (FARPROC *)&pScreenToClient, (FARPROC)extScreenToClient}, - {HOOK_IAT_CANDIDATE, "ClientToScreen", (FARPROC)ClientToScreen, (FARPROC *)&pClientToScreen, (FARPROC)extClientToScreen}, - {HOOK_IAT_CANDIDATE, "GetClientRect", (FARPROC)GetClientRect, (FARPROC *)&pGetClientRect, (FARPROC)extGetClientRect}, - {HOOK_IAT_CANDIDATE, "GetWindowRect", (FARPROC)GetWindowRect, (FARPROC *)&pGetWindowRect, (FARPROC)extGetWindowRect}, - {HOOK_IAT_CANDIDATE, "MapWindowPoints", (FARPROC)MapWindowPoints, (FARPROC *)&pMapWindowPoints, (FARPROC)extMapWindowPoints}, - {HOOK_IAT_CANDIDATE, "GetUpdateRgn", (FARPROC)GetUpdateRgn, (FARPROC *)&pGetUpdateRgn, (FARPROC)extGetUpdateRgn}, - //{HOOK_IAT_CANDIDATE, "GetUpdateRect", (FARPROC)GetUpdateRect, (FARPROC *)&pGetUpdateRect, (FARPROC)extGetUpdateRect}, - //{HOOK_IAT_CANDIDATE, "RedrawWindow", (FARPROC)RedrawWindow, (FARPROC *)&pRedrawWindow, (FARPROC)extRedrawWindow}, - {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator -}; - -static HookEntry_Type PeekAllHooks[]={ - {HOOK_IAT_CANDIDATE, "PeekMessageA", (FARPROC)NULL, (FARPROC *)&pPeekMessage, (FARPROC)extPeekMessage}, - {HOOK_IAT_CANDIDATE, "PeekMessageW", (FARPROC)NULL, (FARPROC *)&pPeekMessage, (FARPROC)extPeekMessage}, - {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator -}; - -static HookEntry_Type MouseHooks[]={ - {HOOK_HOT_CANDIDATE, "GetCursorPos", (FARPROC)GetCursorPos, (FARPROC *)&pGetCursorPos, (FARPROC)extGetCursorPos}, - {HOOK_IAT_CANDIDATE, "GetCursorInfo", (FARPROC)GetCursorInfo, (FARPROC *)&pGetCursorInfo, (FARPROC)extGetCursorInfo}, - {HOOK_IAT_CANDIDATE, "SetCursor", (FARPROC)SetCursor, (FARPROC *)&pSetCursor, (FARPROC)extSetCursor}, - {HOOK_IAT_CANDIDATE, "SendMessageA", (FARPROC)SendMessageA, (FARPROC *)&pSendMessageA, (FARPROC)extSendMessageA}, - {HOOK_IAT_CANDIDATE, "SendMessageW", (FARPROC)SendMessageW, (FARPROC *)&pSendMessageW, (FARPROC)extSendMessageW}, - //{HOOK_IAT_CANDIDATE, "SetPhysicalCursorPos", NULL, (FARPROC *)&pSetCursor, (FARPROC)extSetCursor}, // ??? - {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator -}; - -static HookEntry_Type WinHooks[]={ - {HOOK_HOT_CANDIDATE, "ShowWindow", (FARPROC)ShowWindow, (FARPROC *)&pShowWindow, (FARPROC)extShowWindow}, - {HOOK_HOT_CANDIDATE, "SetWindowPos", (FARPROC)SetWindowPos, (FARPROC *)&pSetWindowPos, (FARPROC)extSetWindowPos}, - {HOOK_HOT_CANDIDATE, "DeferWindowPos", (FARPROC)DeferWindowPos, (FARPROC *)&pGDIDeferWindowPos, (FARPROC)extDeferWindowPos}, - {HOOK_HOT_CANDIDATE, "CallWindowProcA", (FARPROC)CallWindowProcA, (FARPROC *)&pCallWindowProcA, (FARPROC)extCallWindowProcA}, - {HOOK_HOT_CANDIDATE, "CallWindowProcW", (FARPROC)CallWindowProcW, (FARPROC *)&pCallWindowProcW, (FARPROC)extCallWindowProcW}, - {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator -}; - -static HookEntry_Type MouseHooks2[]={ - {HOOK_HOT_CANDIDATE, "SetCursorPos", (FARPROC)SetCursorPos, (FARPROC *)&pSetCursorPos, (FARPROC)extSetCursorPos}, - {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator -}; - -static HookEntry_Type TimeHooks[]={ - {HOOK_IAT_CANDIDATE, "SetTimer", (FARPROC)SetTimer, (FARPROC *)&pSetTimer, (FARPROC)extSetTimer}, - {HOOK_IAT_CANDIDATE, "KillTimer", (FARPROC)KillTimer, (FARPROC *)&pKillTimer, (FARPROC)extKillTimer}, - {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator -}; - -FARPROC Remap_user32_ProcAddress(LPCSTR proc, HMODULE hModule) -{ - FARPROC addr; - if (addr=RemapLibrary(proc, hModule, Hooks)) return addr; - if (dxw.dwFlags1 & CLIENTREMAPPING) if (addr=RemapLibrary(proc, hModule, RemapHooks)) return addr; - - if (dxw.dwFlags2 & GDISTRETCHED) if (addr=RemapLibrary(proc, hModule, ScaledHooks)) return addr; - if (dxw.dwFlags3 & GDIEMULATEDC) if (addr=RemapLibrary(proc, hModule, EmulateHooks)) return addr; - if (!(dxw.dwFlags2 & GDISTRETCHED) && !(dxw.dwFlags3 & GDIEMULATEDC)) - if (addr=RemapLibrary(proc, hModule, NoGDIHooks)) return addr; - - if (dxw.dwFlags1 & MODIFYMOUSE) if (addr=RemapLibrary(proc, hModule, MouseHooks)) return addr; - if (dxw.dwFlags1 & (PREVENTMAXIMIZE|FIXWINFRAME|LOCKWINPOS|LOCKWINSTYLE)) - if (addr=RemapLibrary(proc, hModule, WinHooks)) return addr; - if ((dxw.dwFlags1 & (MODIFYMOUSE|SLOWDOWN|KEEPCURSORWITHIN)) || (dxw.dwFlags2 & KEEPCURSORFIXED)) - if (addr=RemapLibrary(proc, hModule, MouseHooks2)) return addr; - if (dxw.dwFlags3 & PEEKALLMESSAGES) - if (addr=RemapLibrary(proc, hModule, PeekAllHooks)) return addr; - if((dxw.dwFlags2 & TIMESTRETCH) && (dxw.dwFlags4 & STRETCHTIMERS)) - if (addr=RemapLibrary(proc, hModule, TimeHooks)) return addr; - - return NULL; -} - -static char *libname = "user32.dll"; - -void HookUser32(HMODULE hModule) -{ - GDIEmulationMode = GDIMODE_STRETCHED; // default - if (dxw.dwFlags2 & GDISTRETCHED) GDIEmulationMode = GDIMODE_STRETCHED; - if (dxw.dwFlags3 & GDIEMULATEDC) GDIEmulationMode = GDIMODE_EMULATED; - - HookLibrary(hModule, Hooks, libname); - if (!(dxw.dwFlags2 & GDISTRETCHED) && !(dxw.dwFlags3 & GDIEMULATEDC)) - HookLibrary(hModule, NoGDIHooks, libname); - if (dxw.dwFlags3 & GDIEMULATEDC) HookLibrary(hModule, EmulateHooks, libname); - if (dxw.dwFlags2 & GDISTRETCHED) HookLibrary(hModule, ScaledHooks, libname); - - if (dxw.dwFlags1 & CLIENTREMAPPING) HookLibrary(hModule, RemapHooks, libname); - if (dxw.dwFlags1 & MODIFYMOUSE) HookLibrary(hModule, MouseHooks, libname); - if (dxw.dwFlags1 & (PREVENTMAXIMIZE|FIXWINFRAME|LOCKWINPOS|LOCKWINSTYLE)) HookLibrary(hModule, WinHooks, libname); - if ((dxw.dwFlags1 & (MODIFYMOUSE|SLOWDOWN|KEEPCURSORWITHIN)) || (dxw.dwFlags2 & KEEPCURSORFIXED)) HookLibrary(hModule, MouseHooks2, libname); - if (dxw.dwFlags3 & PEEKALLMESSAGES) HookLibrary(hModule, PeekAllHooks, libname); - if (dxw.dwFlags2 & TIMESTRETCH) HookLibrary(hModule, TimeHooks, libname); - - IsChangeDisplaySettingsHotPatched = IsHotPatched(Hooks, "ChangeDisplaySettingsExA") || IsHotPatched(Hooks, "ChangeDisplaySettingsExW"); - return; -} - -void HookUser32Init() -{ - HookLibInit(Hooks); - HookLibInit(ScaledHooks); - HookLibInit(EmulateHooks); - HookLibInit(RemapHooks); - HookLibInit(MouseHooks); - HookLibInit(WinHooks); - HookLibInit(MouseHooks2); -} - -/* ------------------------------------------------------------------------------ */ -// auxiliary (static) functions -/* ------------------------------------------------------------------------------ */ - -static void Stopper(char *s, int line) -{ - char sMsg[81]; - sprintf(sMsg,"break: \"%s\"", s); - MessageBox(0, sMsg, "break", MB_OK | MB_ICONEXCLAMATION); -} - -//#define STOPPER_TEST // comment out to eliminate -#ifdef STOPPER_TEST -#define STOPPER(s) Stopper(s, __LINE__) -#else -#define STOPPER(s) -#endif - -static LPCSTR sTemplateName(LPCSTR tn) -{ - static char sBuf[20+1]; - if((DWORD)tn >> 16) - return tn; - else { - sprintf(sBuf, "ID:(%x)", ((DWORD)tn & 0x0000FFFF)); - return sBuf; - } -} - -// -------------------------------------------------------------------------- -// -// globals, externs, static functions... -// -// -------------------------------------------------------------------------- - -// PrimHDC: DC handle of the selected DirectDraw primary surface. NULL when invalid. -HDC PrimHDC=NULL; - -LPRECT lpClipRegion=NULL; -RECT ClipRegion; -int LastCurPosX, LastCurPosY; - -extern GetDC_Type pGetDC; -extern ReleaseDC_Type pReleaseDC; -//extern void FixWindowFrame(HWND); -extern HRESULT WINAPI sBlt(char *, LPDIRECTDRAWSURFACE, LPRECT, LPDIRECTDRAWSURFACE, LPRECT, DWORD, LPDDBLTFX, BOOL); - -LONG WINAPI MyChangeDisplaySettings(char *fname, BOOL WideChar, void *lpDevMode, DWORD dwflags) -{ - HRESULT res; - DWORD dmFields, dmBitsPerPel, dmPelsWidth, dmPelsHeight; - - // v2.02.32: reset the emulated DC used in GDIEMULATEDC mode - dxw.ResetEmulatedDC(); - - if(lpDevMode){ - if(WideChar){ - dmFields=((DEVMODEW *)lpDevMode)->dmFields; - dmPelsWidth=((DEVMODEW *)lpDevMode)->dmPelsWidth; - dmPelsHeight=((DEVMODEW *)lpDevMode)->dmPelsHeight; - dmBitsPerPel=((DEVMODEW *)lpDevMode)->dmBitsPerPel; - } - else{ - dmFields=((DEVMODEA *)lpDevMode)->dmFields; - dmPelsWidth=((DEVMODEA *)lpDevMode)->dmPelsWidth; - dmPelsHeight=((DEVMODEA *)lpDevMode)->dmPelsHeight; - dmBitsPerPel=((DEVMODEA *)lpDevMode)->dmBitsPerPel; - } - } - - // save desired settings first v.2.1.89 - // v2.1.95 protect when lpDevMode is null (closing game... Jedi Outcast) - // v2.2.23 consider new width/height only when dmFields flags are set. - if(lpDevMode && (dmFields & (DM_PELSWIDTH | DM_PELSHEIGHT))){ - RECT client; - dxw.SetScreenSize(dmPelsWidth, dmPelsHeight); - - // v2.02.31: when main win is bigger that expected resolution, you're in windowed fullscreen mode - //(*pGetClientRect)((dxw.dwFlags1 & FIXPARENTWIN) ? dxw.hParentWnd : dxw.GethWnd(), &client); - (*pGetClientRect)(dxw.GethWnd(), &client); - OutTraceDW("%s: current hWnd=%x size=(%d,%d)\n", fname, dxw.GethWnd(), client.right, client.bottom); - if((client.right>=(LONG)dmPelsWidth) && (client.bottom>=(LONG)dmPelsHeight)) { - OutTraceDW("%s: entering FULLSCREEN mode\n", fname); - dxw.SetFullScreen(TRUE); - } - } - - if ((dwflags==0 || dwflags==CDS_FULLSCREEN) && lpDevMode){ - if (dxw.dwFlags1 & EMULATESURFACE || !(dmFields & DM_BITSPERPEL)){ - OutTraceDW("%s: BYPASS res=DISP_CHANGE_SUCCESSFUL\n", fname); - return DISP_CHANGE_SUCCESSFUL; - } - else{ - DEVMODEA NewMode; - if(dwflags==CDS_FULLSCREEN) dwflags=0; // no FULLSCREEN - (*pEnumDisplaySettings)(NULL, ENUM_CURRENT_SETTINGS, &NewMode); - OutTraceDW("ChangeDisplaySettings: CURRENT wxh=(%dx%d) BitsPerPel=%d -> %d\n", - NewMode.dmPelsWidth, NewMode.dmPelsHeight, NewMode.dmBitsPerPel, dmBitsPerPel); - NewMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - NewMode.dmBitsPerPel = dmBitsPerPel; - res=(*pChangeDisplaySettingsExA)(NULL, &NewMode, NULL, 0, NULL); - if(res) OutTraceE("ChangeDisplaySettings: ERROR err=%d at %d\n", GetLastError(), __LINE__); - return res; - } - } - else{ - if(WideChar) - return (*pChangeDisplaySettingsExW)(NULL, (LPDEVMODEW)lpDevMode, NULL, dwflags, NULL); - else - return (*pChangeDisplaySettingsExA)(NULL, (LPDEVMODEA)lpDevMode, NULL, dwflags, NULL); - } -} - -void dxwFixWindowPos(char *ApiName, HWND hwnd, LPARAM lParam) -{ - LPWINDOWPOS wp; - int MaxX, MaxY; - wp = (LPWINDOWPOS)lParam; - MaxX = dxw.iSizX; - MaxY = dxw.iSizY; - if (!MaxX) MaxX = dxw.GetScreenWidth(); - if (!MaxY) MaxY = dxw.GetScreenHeight(); - static int iLastCX, iLastCY; - static int BorderX=-1; - static int BorderY=-1; - int cx, cy; - extern void CalculateWindowPos(HWND, DWORD, DWORD, LPWINDOWPOS); - - OutTraceDW("%s: GOT hwnd=%x pos=(%d,%d) dim=(%d,%d) Flags=%x(%s)\n", - ApiName, hwnd, wp->x, wp->y, wp->cx, wp->cy, wp->flags, ExplainWPFlags(wp->flags)); - - if (dxw.dwFlags1 & PREVENTMAXIMIZE){ - int UpdFlag = 0; - WINDOWPOS MaxPos; - CalculateWindowPos(hwnd, MaxX, MaxY, &MaxPos); - - if(wp->cx>MaxPos.cx) { wp->cx=MaxPos.cx; UpdFlag=1; } - if(wp->cy>MaxPos.cy) { wp->cy=MaxPos.cy; UpdFlag=1; } - if (UpdFlag) - OutTraceDW("%s: SET max dim=(%d,%d)\n", ApiName, wp->cx, wp->cy); - } - - if ((wp->flags & (SWP_NOMOVE|SWP_NOSIZE))==(SWP_NOMOVE|SWP_NOSIZE)) return; //v2.02.13 - - if ((dxw.dwFlags1 & LOCKWINPOS) && dxw.IsFullScreen() && (hwnd==dxw.GethWnd())){ - CalculateWindowPos(hwnd, MaxX, MaxY, wp); - OutTraceDW("%s: LOCK pos=(%d,%d) dim=(%d,%d)\n", ApiName, wp->x, wp->y, wp->cx, wp->cy); - } - - if ((dxw.dwFlags2 & KEEPASPECTRATIO) && dxw.IsFullScreen() && (hwnd==dxw.GethWnd())){ - // note: while keeping aspect ration, resizing from one corner doesn't tell - // which coordinate is prevalent to the other. We made an arbitrary choice. - // note: v2.1.93: compensation must refer to the client area, not the wp - // window dimensions that include the window borders. - if(BorderX==-1){ - // v2.02.92: Fixed for AERO mode, where GetWindowRect substantially LIES! - RECT client, full; - LONG dwStyle, dwExStyle; - HMENU hMenu; - extern GetWindowLong_Type pGetWindowLongA; - (*pGetClientRect)(hwnd, &client); - full=client; - dwStyle=(*pGetWindowLongA)(hwnd, GWL_STYLE); - dwExStyle=(*pGetWindowLongA)(hwnd, GWL_EXSTYLE); - hMenu = (dwStyle & WS_CHILD) ? NULL : GetMenu(hwnd); - AdjustWindowRectEx(&full, dwStyle, (hMenu!=NULL), dwExStyle); - if (hMenu && (hMenu != (HMENU)-1)) __try {CloseHandle(hMenu);} __except(EXCEPTION_EXECUTE_HANDLER){}; - BorderX= full.right - full.left - client.right; - BorderY= full.bottom - full.top - client.bottom; - OutTraceDW("%s: KEEPASPECTRATIO window borders=(%d,%d)\n", ApiName, BorderX, BorderY); - } - extern LRESULT LastCursorPos; - switch (LastCursorPos){ - case HTBOTTOM: - case HTTOP: - case HTBOTTOMLEFT: - case HTBOTTOMRIGHT: - case HTTOPLEFT: - case HTTOPRIGHT: - cx = BorderX + ((wp->cy - BorderY) * dxw.iRatioX) / dxw.iRatioY; - if(cx!=wp->cx){ - OutTraceDW("%s: KEEPASPECTRATIO adjusted cx=%d->%d\n", ApiName, wp->cx, cx); - wp->cx = cx; - } - break; - case HTLEFT: - case HTRIGHT: - cy = BorderY + ((wp->cx - BorderX) * dxw.iRatioY) / dxw.iRatioX; - if(cy!=wp->cy){ - OutTraceDW("%s: KEEPASPECTRATIO adjusted cy=%d->%d\n", ApiName, wp->cy, cy); - wp->cy = cy; - } - break; - } - } - - if ((dxw.dwFlags5 & CENTERTOWIN) && dxw.IsFullScreen() && (hwnd==dxw.GethWnd())){ - RECT wrect; - LONG dwStyle, dwExStyle; - HMENU hMenu; - int minx, miny; - wrect = dxw.GetScreenRect(); - dwStyle=(*pGetWindowLongA)(hwnd, GWL_STYLE); - dwExStyle=(*pGetWindowLongA)(hwnd, GWL_EXSTYLE); - hMenu = (dwStyle & WS_CHILD) ? NULL : GetMenu(hwnd); - AdjustWindowRectEx(&wrect, dwStyle, (hMenu!=NULL), dwExStyle); - minx = wrect.right - wrect.left; - miny = wrect.bottom - wrect.top; - if(wp->cx < minx) wp->cx = minx; - if(wp->cy < miny) wp->cy = miny; - } - - iLastCX= wp->cx; - iLastCY= wp->cy; -} - -void dxwFixMinMaxInfo(char *ApiName, HWND hwnd, LPARAM lParam) -{ - if (dxw.dwFlags1 & PREVENTMAXIMIZE){ - LPMINMAXINFO lpmmi; - lpmmi=(LPMINMAXINFO)lParam; - OutTraceDW("%s: GOT MaxPosition=(%d,%d) MaxSize=(%d,%d)\n", ApiName, - lpmmi->ptMaxPosition.x, lpmmi->ptMaxPosition.y, lpmmi->ptMaxSize.x, lpmmi->ptMaxSize.y); - lpmmi->ptMaxPosition.x=0; - lpmmi->ptMaxPosition.y=0; - lpmmi->ptMaxSize.x = dxw.GetScreenWidth(); - lpmmi->ptMaxSize.y = dxw.GetScreenHeight(); - - OutTraceDW("%s: SET PREVENTMAXIMIZE MaxPosition=(%d,%d) MaxSize=(%d,%d)\n", ApiName, - lpmmi->ptMaxPosition.x, lpmmi->ptMaxPosition.y, lpmmi->ptMaxSize.x, lpmmi->ptMaxSize.y); - } - - // v2.1.75: added logic to fix win coordinates to selected ones. - // fixes the problem with "Achtung Spitfire", that can't be managed through PREVENTMAXIMIZE flag. - if (dxw.dwFlags1 & LOCKWINPOS){ - LPMINMAXINFO lpmmi; - lpmmi=(LPMINMAXINFO)lParam; - OutTraceDW("%s: GOT MaxPosition=(%d,%d) MaxSize=(%d,%d)\n", ApiName, - lpmmi->ptMaxPosition.x, lpmmi->ptMaxPosition.y, lpmmi->ptMaxSize.x, lpmmi->ptMaxSize.y); - lpmmi->ptMaxPosition.x=dxw.iPosX; - lpmmi->ptMaxPosition.y=dxw.iPosY; - lpmmi->ptMaxSize.x = dxw.iSizX ? dxw.iSizX : dxw.GetScreenWidth(); - lpmmi->ptMaxSize.y = dxw.iSizY ? dxw.iSizY : dxw.GetScreenHeight(); - OutTraceDW("%s: SET LOCKWINPOS MaxPosition=(%d,%d) MaxSize=(%d,%d)\n", ApiName, - lpmmi->ptMaxPosition.x, lpmmi->ptMaxPosition.y, lpmmi->ptMaxSize.x, lpmmi->ptMaxSize.y); - } -} - -static LRESULT WINAPI FixWindowProc(char *ApiName, HWND hwnd, UINT Msg, WPARAM wParam, LPARAM *lpParam) -{ - LPARAM lParam; - - lParam=*lpParam; - OutTraceW("%s: hwnd=%x msg=[0x%x]%s(%x,%x)\n", - ApiName, hwnd, Msg, ExplainWinMessage(Msg), wParam, lParam); - - switch(Msg){ - case WM_NCHITTEST: - // v2.02.71 fix: when processing WM_NCHITTEST messages whith fixed coordinates avoid calling - // the *pDefWindowProc call - // fixes "Microsoft Motocross Madness" mouse handling - if((dxw.dwFlags2 & FIXNCHITTEST) && (dxw.dwFlags1 & MODIFYMOUSE)){ // mouse processing - OutTraceDW("%s: suppress WM_NCHITTEST\n", ApiName); - return TRUE; - } - break; - case WM_ERASEBKGND: - OutTraceDW("%s: prevent erase background\n", ApiName); - return TRUE; // 1=erased - break; // useless - case WM_GETMINMAXINFO: - dxwFixMinMaxInfo(ApiName, hwnd, lParam); - break; - case WM_WINDOWPOSCHANGING: - case WM_WINDOWPOSCHANGED: - dxwFixWindowPos(ApiName, hwnd, lParam); - break; - case WM_STYLECHANGING: - case WM_STYLECHANGED: - dxw.FixStyle(ApiName, hwnd, wParam, lParam); - break; - case WM_SIZE: - if ((dxw.dwFlags1 & LOCKWINPOS) && dxw.IsFullScreen()) return 0; - if (dxw.dwFlags1 & PREVENTMAXIMIZE){ - if ((wParam == SIZE_MAXIMIZED)||(wParam == SIZE_MAXSHOW)){ - OutTraceDW("%s: prevent screen SIZE to fullscreen wparam=%d(%s) size=(%d,%d)\n", ApiName, - wParam, ExplainResizing(wParam), HIWORD(lParam), LOWORD(lParam)); - return 0; // checked - //lParam = MAKELPARAM(dxw.GetScreenWidth(), dxw.GetScreenHeight()); - //OutTraceDW("%s: updated SIZE wparam=%d(%s) size=(%d,%d)\n", ApiName, - // wParam, ExplainResizing(wParam), HIWORD(lParam), LOWORD(lParam)); - } - } - break; - default: - break; - } - - // marker to run hooked function - return(-1); -} - -// -------------------------------------------------------------------------- -// -// user32 API hookers -// -// -------------------------------------------------------------------------- - - -BOOL WINAPI extInvalidateRect(HWND hwnd, RECT *lpRect, BOOL bErase) -{ - if(lpRect) - OutTraceDW("InvalidateRect: hwnd=%x rect=(%d,%d)-(%d,%d) erase=%x\n", - hwnd, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, bErase); - else - OutTraceDW("InvalidateRect: hwnd=%x rect=NULL erase=%x\n", - hwnd, bErase); - - if(dxw.IsFullScreen() && dxw.IsRealDesktop(hwnd)) { - hwnd=dxw.GethWnd(); - dxw.MapClient(lpRect); - return (*pInvalidateRect)(hwnd, lpRect, bErase); - } - else{ - // just exagerate ... - return (*pInvalidateRect)(hwnd, NULL, bErase); - } -} - -BOOL WINAPI extShowWindow(HWND hwnd, int nCmdShow) -{ - BOOL res; - - OutTraceDW("ShowWindow: hwnd=%x, CmdShow=%x(%s)\n", hwnd, nCmdShow, ExplainShowCmd(nCmdShow)); - if (dxw.dwFlags1 & PREVENTMAXIMIZE){ - if(nCmdShow==SW_MAXIMIZE){ - OutTraceDW("ShowWindow: suppress SW_MAXIMIZE maximize\n"); - nCmdShow=SW_SHOWNORMAL; - } - if(nCmdShow==SW_SHOWDEFAULT){ - STARTUPINFO StartupInfo; - GetStartupInfo(&StartupInfo); - OutTraceDW("DEBUG: StartupInfo dwFlags=%x ShowWindow=%x\n", StartupInfo.dwFlags, StartupInfo.wShowWindow); - if((StartupInfo.dwFlags & STARTF_USESHOWWINDOW) && (StartupInfo.wShowWindow == SW_MAXIMIZE)){ - OutTraceDW("ShowWindow: suppress SW_SHOWDEFAULT maximize\n"); - nCmdShow=SW_SHOWNORMAL; - } - } - } - - res=(*pShowWindow)(hwnd, nCmdShow); - OutTraceDW("ShowWindow: res=%x\n", res); - - return res; -} - -LONG WINAPI extGetWindowLong(GetWindowLong_Type pGetWindowLong, char *ApiName, HWND hwnd, int nIndex) -{ - LONG res; - - res=(*pGetWindowLong)(hwnd, nIndex); - - OutTraceDW("%s: hwnd=%x, Index=%x(%s) res=%x\n", ApiName, hwnd, nIndex, ExplainSetWindowIndex(nIndex), res); - - if((nIndex==GWL_WNDPROC)||(nIndex==DWL_DLGPROC)){ - WNDPROC wp; - wp=dxwws.GetProc(hwnd); - OutTraceDW("%s: remapping WindowProc res=%x -> %x\n", ApiName, res, (LONG)wp); - if(wp) res=(LONG)wp; // if not found, don't alter the value. - } - - return res; -} - -LONG WINAPI extGetWindowLongA(HWND hwnd, int nIndex) -{ - return extGetWindowLong(pGetWindowLongA, "GetWindowLongA", hwnd, nIndex); -} - -LONG WINAPI extGetWindowLongW(HWND hwnd, int nIndex) -{ - return extGetWindowLong(pGetWindowLongW, "GetWindowLongW", hwnd, nIndex); -} - -LONG WINAPI extSetWindowLong(HWND hwnd, int nIndex, LONG dwNewLong, SetWindowLong_Type pSetWindowLong) -{ - LONG res; - - OutTraceDW("SetWindowLong: hwnd=%x, Index=%x(%s) Val=%x\n", - hwnd, nIndex, ExplainSetWindowIndex(nIndex), dwNewLong); - - if (dxw.Windowize){ - if(dxw.dwFlags1 & LOCKWINSTYLE){ - if(nIndex==GWL_STYLE){ - OutTraceDW("SetWindowLong: Lock GWL_STYLE=%x\n", dwNewLong); - return (*pGetWindowLongA)(hwnd, nIndex); - } - if(nIndex==GWL_EXSTYLE){ - OutTraceDW("SetWindowLong: Lock GWL_EXSTYLE=%x\n", dwNewLong); - return (*pGetWindowLongA)(hwnd, nIndex); - } - } - - if (dxw.dwFlags1 & PREVENTMAXIMIZE){ - if(nIndex==GWL_STYLE){ - dwNewLong &= ~WS_MAXIMIZE; - if(dxw.IsDesktop(hwnd)){ - OutTraceDW("SetWindowLong: GWL_STYLE %x suppress MAXIMIZE\n", dwNewLong); - dwNewLong |= WS_OVERLAPPEDWINDOW; - dwNewLong &= ~(WS_DLGFRAME|WS_MAXIMIZE|WS_VSCROLL|WS_HSCROLL|WS_CLIPSIBLINGS); - } - } - // v2.02.32: disable topmost for main window only - if(dxw.IsDesktop(hwnd) && (nIndex==GWL_EXSTYLE)){ - OutTraceDW("SetWindowLong: GWL_EXSTYLE %x suppress TOPMOST\n", dwNewLong); - dwNewLong = dwNewLong & ~(WS_EX_TOPMOST); - } - } - - if (dxw.dwFlags1 & FIXWINFRAME){ - //if((nIndex==GWL_STYLE) && !(dwNewLong & WS_CHILD)){ - if((nIndex==GWL_STYLE) && !(dwNewLong & WS_CHILD) && dxw.IsDesktop(hwnd)){ - OutTraceDW("SetWindowLong: GWL_STYLE %x force OVERLAPPEDWINDOW\n", dwNewLong); - dwNewLong |= WS_OVERLAPPEDWINDOW; - dwNewLong &= ~WS_CLIPSIBLINGS; - } - } - } - - if (((nIndex==GWL_WNDPROC)||(nIndex==DWL_DLGPROC)) && dxw.IsFullScreen()){ // v2.02.51 - see A10 Cuba.... - WNDPROC lres; - WNDPROC OldProc; - // GPL fix - if(dxw.IsRealDesktop(hwnd) && dxw.Windowize) { - hwnd=dxw.GethWnd(); - OutTraceDW("SetWindowLong: DESKTOP hwnd, FIXING hwnd=%x\n",hwnd); - } - // end of GPL fix - - OldProc = (WNDPROC)(*pGetWindowLongA)(hwnd, nIndex); - // v2.02.70 fix - if((OldProc==extWindowProc) || - (OldProc==extChildWindowProc)|| - (OldProc==extDialogWindowProc)) - OldProc=dxwws.GetProc(hwnd); - dxwws.PutProc(hwnd, (WNDPROC)dwNewLong); - res=(LONG)OldProc; - SetLastError(0); - lres=(WNDPROC)(*pSetWindowLongA)(hwnd, nIndex, (LONG)extWindowProc); - if(!lres && GetLastError())OutTraceE("SetWindowLong: ERROR err=%d at %d\n", GetLastError(), __LINE__); - } - else { - res=(*pSetWindowLongA)(hwnd, nIndex, dwNewLong); - } - - OutTraceDW("SetWindowLong: hwnd=%x, nIndex=%x, Val=%x, res=%x\n", hwnd, nIndex, dwNewLong, res); - return res; -} - -LONG WINAPI extSetWindowLongA(HWND hwnd, int nIndex, LONG dwNewLong) -{ - return extSetWindowLong(hwnd, nIndex, dwNewLong, pSetWindowLongA); -} - -LONG WINAPI extSetWindowLongW(HWND hwnd, int nIndex, LONG dwNewLong) -{ - return extSetWindowLong(hwnd, nIndex, dwNewLong, pSetWindowLongW); -} - -BOOL WINAPI extSetWindowPos(HWND hwnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags) -{ - BOOL res; - - OutTraceDW("SetWindowPos: hwnd=%x%s pos=(%d,%d) dim=(%d,%d) Flags=%x\n", - hwnd, dxw.IsFullScreen()?"(FULLSCREEN)":"", X, Y, cx, cy, uFlags); - - // when not in fullscreen mode, just proxy the call - if (!dxw.IsFullScreen()){ - res=(*pSetWindowPos)(hwnd, hWndInsertAfter, X, Y, cx, cy, uFlags); - if(!res)OutTraceE("SetWindowPos: ERROR err=%d at %d\n", GetLastError(), __LINE__); - return res; - } - - // in fullscreen, but a child window inside ..... - if (!dxw.IsDesktop(hwnd)){ - RECT r; - r.left = X; - r.right = X + cx; - r.top = Y; - r.bottom = Y + cy; - if ((*pGetWindowLongA)(hwnd, GWL_STYLE) & WS_CHILD){ - r = dxw.MapClientRect(&r); - } - else { - //r = dxw.MapWindowRect(&r); - } - X = r.left; - Y = r.top; - cx = r.right - r.left; - cy = r.bottom - r.top; - - res=(*pSetWindowPos)(hwnd, hWndInsertAfter, X, Y, cx, cy, uFlags); - if(!res)OutTraceE("SetWindowPos: ERROR err=%d at %d\n", GetLastError(), __LINE__); - - //HFONT hFont; - //hFont=CreateFont ( - // 30, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, - // FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, - // DEFAULT_PITCH | FF_SWISS, NULL); // "Arial"); - //SendMessage (hwnd, WM_SETFONT, WPARAM (hFont), TRUE); - - return res; - } - - if (dxw.dwFlags1 & LOCKWINPOS){ - // Note: any attempt to change the window position, no matter where and how, through the - // SetWindowPos API is causing resizing to the default 1:1 pixed size in Commandos. - // in such cases, there is incompatibility between LOCKWINPOS and LOCKWINSTYLE. - OutTraceDW("SetWindowPos: locked position\n"); - return 1; - } - - if (dxw.dwFlags1 & PREVENTMAXIMIZE){ - int UpdFlag =0; - int MaxX, MaxY; - MaxX = dxw.iSizX; - MaxY = dxw.iSizY; - if (!MaxX) MaxX = dxw.GetScreenWidth(); - if (!MaxY) MaxY = dxw.GetScreenHeight(); - if(cx>MaxX) { cx=MaxX; UpdFlag=1; } - if(cy>MaxY) { cy=MaxY; UpdFlag=1; } - if (UpdFlag) - OutTraceDW("SetWindowPos: using max dim=(%d,%d)\n", cx, cy); - } - - // useful??? to be demonstrated.... - // when altering main window in fullscreen mode, fix the coordinates for borders - DWORD dwCurStyle, dwExStyle; - HMENU hMenu; - RECT rect; - rect.top=rect.left=0; - rect.right=cx; rect.bottom=cy; - dwCurStyle=(*pGetWindowLongA)(hwnd, GWL_STYLE); - dwExStyle=(*pGetWindowLongA)(hwnd, GWL_EXSTYLE); - // BEWARE: from MSDN - If the window is a child window, the return value is undefined. - hMenu = (dwCurStyle & WS_CHILD) ? NULL : GetMenu(hwnd); - AdjustWindowRectEx(&rect, dwCurStyle, (hMenu!=NULL), dwExStyle); - if (hMenu && (hMenu != (HMENU)-1)) __try {CloseHandle(hMenu);} __except(EXCEPTION_EXECUTE_HANDLER){}; - cx=rect.right; cy=rect.bottom; - OutTraceDW("SetWindowPos: main form hwnd=%x fixed size=(%d,%d)\n", hwnd, cx, cy); - - res=(*pSetWindowPos)(hwnd, hWndInsertAfter, X, Y, cx, cy, uFlags); - if(!res)OutTraceE("SetWindowPos: ERROR err=%d at %d\n", GetLastError(), __LINE__); - return res; -} - -HDWP WINAPI extDeferWindowPos(HDWP hWinPosInfo, HWND hwnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags) -{ - // v2.02.31: heavily used by "Imperialism II" !!! - HDWP res; - - OutTraceDW("DeferWindowPos: hwnd=%x%s pos=(%d,%d) dim=(%d,%d) Flags=%x\n", - hwnd, dxw.IsFullScreen()?"(FULLSCREEN)":"", X, Y, cx, cy, uFlags); - - if(dxw.IsFullScreen()){ - dxw.MapClient(&X, &Y, &cx, &cy); - OutTraceDW("DeferWindowPos: remapped pos=(%d,%d) dim=(%d,%d)\n", X, Y, cx, cy); - } - - res=(*pGDIDeferWindowPos)(hWinPosInfo, hwnd, hWndInsertAfter, X, Y, cx, cy, uFlags); - if(!res)OutTraceE("DeferWindowPos: ERROR err=%d at %d\n", GetLastError(), __LINE__); - return res; -} - -LRESULT WINAPI extSendMessage(char *apiname, SendMessage_Type pSendMessage, HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - LRESULT ret; - OutTraceW("%s: hwnd=%x WinMsg=[0x%x]%s(%x,%x)\n", - apiname, hwnd, Msg, ExplainWinMessage(Msg), wParam, lParam); - - if(dxw.dwFlags1 & MODIFYMOUSE){ - switch (Msg){ - case WM_MOUSEMOVE: - case WM_MOUSEWHEEL: - case WM_LBUTTONDOWN: - case WM_LBUTTONUP: - case WM_LBUTTONDBLCLK: - case WM_RBUTTONDOWN: - case WM_RBUTTONUP: - case WM_RBUTTONDBLCLK: - case WM_MBUTTONDOWN: - case WM_MBUTTONUP: - case WM_MBUTTONDBLCLK: - // revert here the WindowProc mouse correction - POINT prev, curr; - RECT rect; - prev.x = LOWORD(lParam); - prev.y = HIWORD(lParam); - (*pGetClientRect)(dxw.GethWnd(), &rect); - curr.x = (prev.x * rect.right) / dxw.GetScreenWidth(); - curr.y = (prev.y * rect.bottom) / dxw.GetScreenHeight(); - if (Msg == WM_MOUSEWHEEL){ // v2.02.33 mousewheel fix - POINT upleft={0,0}; - (*pClientToScreen)(dxw.GethWnd(), &upleft); - curr = dxw.AddCoordinates(curr, upleft); - } - lParam = MAKELPARAM(curr.x, curr.y); - OutTraceC("%s: hwnd=%x pos XY=(%d,%d)->(%d,%d)\n", apiname, hwnd, prev.x, prev.y, curr.x, curr.y); - break; - default: - break; - } - } - ret=(*pSendMessage)(hwnd, Msg, wParam, lParam); - OutTraceW("%s: lresult=%x\n", apiname, ret); - return ret; -} - -LRESULT WINAPI extSendMessageA(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - return extSendMessage("SendMessageA", pSendMessageA, hwnd, Msg, wParam, lParam); -} - -LRESULT WINAPI extSendMessageW(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - return extSendMessage("SendMessageW", pSendMessageW, hwnd, Msg, wParam, lParam); -} - -HCURSOR WINAPI extSetCursor(HCURSOR hCursor) -{ - HCURSOR ret; - - ret=(*pSetCursor)(hCursor); - OutTraceDW("GDI.SetCursor: Cursor=%x, ret=%x\n", hCursor, ret); - //MessageBox(0, "SelectPalette", "GDI32.dll", MB_OK | MB_ICONEXCLAMATION); - return ret; -} - -BOOL WINAPI extGetCursorPos(LPPOINT lppoint) -{ - HRESULT res; - static int PrevX, PrevY; - POINT prev; - - if(dxw.dwFlags1 & SLOWDOWN) dxw.DoSlow(2); - - if (pGetCursorPos) { - res=(*pGetCursorPos)(lppoint); - } - else { - lppoint->x =0; lppoint->y=0; - res=1; - } - - prev=*lppoint; - *lppoint=dxw.ScreenToClient(*lppoint); - *lppoint=dxw.FixCursorPos(*lppoint); - - GetHookInfo()->CursorX=(short)lppoint->x; - GetHookInfo()->CursorY=(short)lppoint->y; - OutTraceC("GetCursorPos: FIXED pos=(%d,%d)->(%d,%d)\n", prev.x, prev.y, lppoint->x, lppoint->y); - - return res; -} - -BOOL WINAPI extSetCursorPos(int x, int y) -{ - BOOL res; - int PrevX, PrevY; - - PrevX=x; - PrevY=y; - - if(dxw.dwFlags2 & KEEPCURSORFIXED) { - OutTraceC("SetCursorPos: FIXED pos=(%d,%d)\n", x, y); - LastCurPosX=x; - LastCurPosY=y; - return 1; - } - - if(dxw.dwFlags1 & SLOWDOWN) dxw.DoSlow(2); - - if(dxw.dwFlags1 & KEEPCURSORWITHIN){ - // Intercept SetCursorPos outside screen boundaries (used as Cursor OFF in some games) - if ((y<0)||(y>=(int)dxw.GetScreenHeight())||(x<0)||(x>=(int)dxw.GetScreenWidth())) return 1; - } - - if(dxw.dwFlags1 & MODIFYMOUSE){ - POINT cur; - RECT rect; - - // find window metrics - if (!(*pGetClientRect)(dxw.GethWnd(), &rect)) { - // report error and ignore ... - OutTraceE("GetClientRect(%x) ERROR %d at %d\n", dxw.GethWnd(), GetLastError(), __LINE__); - return 0; - } - - x= x * rect.right / dxw.GetScreenWidth(); - y= y * rect.bottom / dxw.GetScreenHeight(); - - // check for boundaries (???) - if (x >= rect.right) x=rect.right-1; - if (x<0) x=0; - if (y >= rect.bottom) y=rect.bottom-1; - if (y<0) y=0; - - // make it screen absolute - cur.x = x; - cur.y = y; - if (!(*pClientToScreen)(dxw.GethWnd(), &cur)) { - OutTraceE("ClientToScreen(%x) ERROR %d at %d\n", dxw.GethWnd(), GetLastError(), __LINE__); - return 0; - } - x = cur.x; - y = cur.y; - } - - res=0; - if (pSetCursorPos) res=(*pSetCursorPos)(x,y); - - OutTraceC("SetCursorPos: res=%x XY=(%d,%d)->(%d,%d)\n", res, PrevX, PrevY, x, y); - return res; -} - -BOOL WINAPI extPeekMessage(LPMSG lpMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg) -{ - BOOL res; - - if((wMsgFilterMin==0) && (wMsgFilterMax == 0)){ - // no filtering, everything is good - res=(*pPeekMessage)(lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax, (wRemoveMsg & 0x000F)); - } - else { - MSG Dummy; - // better eliminate all messages before and after the selected range !!!! - //if(wMsgFilterMin)(*pPeekMessage)(&Dummy, hwnd, 0, wMsgFilterMin-1, TRUE); - if(wMsgFilterMin>0x0F)(*pPeekMessage)(&Dummy, hwnd, 0x0F, wMsgFilterMin-1, TRUE); - res=(*pPeekMessage)(lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax, (wRemoveMsg & 0x000F)); - if(wMsgFilterMaxhwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg, ExplainPeekRemoveMsg(wRemoveMsg), - lpMsg->message, ExplainWinMessage(lpMsg->message & 0xFFFF), - lpMsg->wParam, lpMsg->lParam, lpMsg->pt.x, lpMsg->pt.y, res); - else - OutTraceW("PeekMessage: ANY lpmsg=%x hwnd=%x filter=(%x-%x) remove=%x(%s) res=%x\n", - lpMsg, lpMsg->hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg, ExplainPeekRemoveMsg(wRemoveMsg), res); - - - return res; -} - -BOOL WINAPI extClientToScreen(HWND hwnd, LPPOINT lppoint) -{ - // v2.02.10: fully revised to handle scaled windows - BOOL res; - - OutTraceB("ClientToScreen: hwnd=%x hWnd=%x FullScreen=%x point=(%d,%d)\n", - hwnd, dxw.GethWnd(), dxw.IsFullScreen(), lppoint->x, lppoint->y); - if (lppoint && dxw.IsFullScreen()){ - // optimization: in fullscreen mode, coordinate conversion for the desktop window - // should always keep the same values inaltered - if(hwnd != dxw.GethWnd()){ - *lppoint = dxw.AddCoordinates(*lppoint, dxw.ClientOffset(hwnd)); - } - OutTraceB("ClientToScreen: FIXED point=(%d,%d)\n", lppoint->x, lppoint->y); - res=TRUE; - } - else { - res=(*pClientToScreen)(hwnd, lppoint); - } - return res; -} - -BOOL WINAPI extScreenToClient(HWND hwnd, LPPOINT lppoint) -{ - // v2.02.10: fully revised to handle scaled windows - BOOL res; - OutTraceB("ScreenToClient: hwnd=%x hWnd=%x FullScreen=%x point=(%d,%d)\n", - hwnd, dxw.GethWnd(), dxw.IsFullScreen(), lppoint->x, lppoint->y); - - if (lppoint && (lppoint->x == -32000) && (lppoint->y == -32000)) return 1; - - if (lppoint && dxw.IsFullScreen()){ - // optimization: in fullscreen mode, coordinate conversion for the desktop window - // should always keep the same values inaltered - if(hwnd != dxw.GethWnd()){ - *lppoint = dxw.SubCoordinates(*lppoint, dxw.ClientOffset(hwnd)); - OutTraceB("ScreenToClient: FIXED point=(%d,%d)\n", lppoint->x, lppoint->y); - } - res=TRUE; - } - else { - res=(*pScreenToClient)(hwnd, lppoint); - } - return res; -} - -BOOL WINAPI extGetClientRect(HWND hwnd, LPRECT lpRect) -{ - BOOL ret; - OutTraceB("GetClientRect: whnd=%x FullScreen=%x\n", hwnd, dxw.IsFullScreen()); - - if(!lpRect) return 0; - - // proxed call - ret=(*pGetClientRect)(hwnd, lpRect); - if(!ret) { - OutTraceE("GetClientRect: ERROR hwnd=%x err=%d at %d\n", hwnd, GetLastError(), __LINE__); - return ret; - } - OutTraceB("GetClientRect: actual rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); - - if (dxw.IsDesktop(hwnd)){ - *lpRect = dxw.GetScreenRect(); - OutTraceB("GetClientRect: desktop rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); - } - else - if (dxw.IsFullScreen()){ - int w, h; - if(FIXCHILDSIZE){ - if(dxwws.GetSize(hwnd, &w, &h)){ - lpRect->top=lpRect->left=0; - lpRect->right=w; - lpRect->bottom=h; - OutTraceB("GetClientRect: fixed rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); - return TRUE; - } - } - *lpRect=dxw.GetClientRect(*lpRect); - OutTraceB("GetClientRect: fixed rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); - } - return ret; -} - -BOOL WINAPI extGetWindowRect(HWND hwnd, LPRECT lpRect) -{ - BOOL ret; - OutTraceB("GetWindowRect: hwnd=%x hWnd=%x FullScreen=%x\n", hwnd, dxw.GethWnd(), dxw.IsFullScreen()); - ret=(*pGetWindowRect)(hwnd, lpRect); - if(!ret) { - OutTraceE("GetWindowRect: GetWindowRect hwnd=%x error %d at %d\n", hwnd, GetLastError(), __LINE__); - return ret; - } - OutTraceB("GetWindowRect: rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); - - // minimized windows behaviour - if((lpRect->left == -32000)||(lpRect->top == -32000)) return ret; - - if (dxw.IsDesktop(hwnd)){ - // to avoid keeping track of window frame - *lpRect = dxw.GetScreenRect(); - OutTraceB("GetWindowRect: desktop rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); - } - else - if (dxw.IsFullScreen()){ - *lpRect=dxw.GetWindowRect(*lpRect); - - // Diablo fix: it retrieves coordinates for the explorer window, that are as big as the real desktop!!! - if(lpRect->left < 0) lpRect->left=0; -// if(lpRect->left > (LONG)dxw.GetScreenWidth()) lpRect->left=dxw.GetScreenWidth(); -// if(lpRect->right < 0) lpRect->right=0; - if(lpRect->right > (LONG)dxw.GetScreenWidth()) lpRect->right=dxw.GetScreenWidth(); - if(lpRect->top < 0) lpRect->top=0; -// if(lpRect->top > (LONG)dxw.GetScreenHeight()) lpRect->top=dxw.GetScreenHeight(); -// if(lpRect->bottom < 0) lpRect->bottom=0; - if(lpRect->bottom > (LONG)dxw.GetScreenHeight()) lpRect->bottom=dxw.GetScreenHeight(); - - OutTraceB("GetWindowRect: fixed rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); - } - - return ret; -} - -int WINAPI extMapWindowPoints(HWND hWndFrom, HWND hWndTo, LPPOINT lpPoints, UINT cPoints) -{ - UINT pi; - int ret; - // a rarely used API, but responsible for a painful headache: needs hooking for "Commandos 2", "Alien Nations". - // used also in "Full Pipe" activemovie - // used also in "NBA Live 99" menu screen - - OutTraceDW("MapWindowPoints: hWndFrom=%x%s hWndTo=%x%s cPoints=%d FullScreen=%x\n", - hWndFrom, dxw.IsDesktop(hWndFrom)?"(DESKTOP)":"", - hWndTo, dxw.IsDesktop(hWndTo)?"(DESKTOP)":"", - cPoints, dxw.IsFullScreen()); - if(IsDebug){ - OutTrace("Points: "); - for(pi=0; pi>16, ret&0x0000FFFF); - return ret; -} - -HWND WINAPI extGetDesktopWindow(void) -{ - HWND res; - - if((!dxw.Windowize) || (dxw.dwFlags5 & DIABLOTWEAK)) return (*pGetDesktopWindow)(); - - OutTraceDW("GetDesktopWindow: FullScreen=%x\n", dxw.IsFullScreen()); - if (dxw.IsFullScreen()){ -#ifdef CREATEDESKTOP - if(CREATEDESKTOP){ - extern HWND hDesktopWindow; - OutTraceDW("GetDesktopWindow: returning desktop emulated hwnd=%x\n", hDesktopWindow); - return hDesktopWindow; - } -#endif - OutTraceDW("GetDesktopWindow: returning main window hwnd=%x\n", dxw.GethWnd()); - return dxw.GethWnd(); - } - else{ - res=(*pGetDesktopWindow)(); - OutTraceDW("GetDesktopWindow: returning desktop window hwnd=%x\n", res); - return res; - } -} - -int WINAPI extGetSystemMetrics(int nindex) -{ - HRESULT res; - - res=(*pGetSystemMetrics)(nindex); - OutTraceDW("GetSystemMetrics: index=%x(%s), res=%d\n", nindex, ExplainsSystemMetrics(nindex), res); - - if(!dxw.Windowize){ - // v2.02.95: if not in window mode, just implement the HIDEMULTIMONITOR flag - if( (nindex ==SM_CMONITORS) && - (dxw.dwFlags2 & HIDEMULTIMONITOR) && - res>1) { - res=1; - OutTraceDW("GetSystemMetrics: fix SM_CMONITORS=%d\n", res); - } - return res; - } - - switch(nindex){ - case SM_CXFULLSCREEN: - case SM_CXSCREEN: - case SM_CXVIRTUALSCREEN: // v2.02.31 - res= dxw.GetScreenWidth(); - OutTraceDW("GetSystemMetrics: fix SM_CXSCREEN=%d\n", res); - break; - case SM_CYFULLSCREEN: - case SM_CYSCREEN: - case SM_CYVIRTUALSCREEN: // v2.02.31 - res= dxw.GetScreenHeight(); - OutTraceDW("GetSystemMetrics: fix SM_CYSCREEN=%d\n", res); - break; - case SM_CMONITORS: - if((dxw.dwFlags2 & HIDEMULTIMONITOR) && res>1) { - res=1; - OutTraceDW("GetSystemMetrics: fix SM_CMONITORS=%d\n", res); - } - break; - } - - return res; -} - -ATOM WINAPI extRegisterClassExA(WNDCLASSEX *lpwcx) -{ - OutTraceDW("RegisterClassEx: PROXED ClassName=%s style=%x(%s) WndProc=%x cbClsExtra=%d cbWndExtra=%d hInstance=%x\n", - lpwcx->lpszClassName, lpwcx->style, ExplainStyle(lpwcx->style), lpwcx->lpfnWndProc, lpwcx->cbClsExtra, lpwcx->cbWndExtra, lpwcx->hInstance); - return (*pRegisterClassExA)(lpwcx); -} - -ATOM WINAPI extRegisterClassA(WNDCLASS *lpwcx) -{ - // referenced by Syberia, together with RegisterClassExA - OutTraceDW("RegisterClass: PROXED ClassName=%s style=%x(%s) WndProc=%x cbClsExtra=%d cbWndExtra=%d hInstance=%x\n", - lpwcx->lpszClassName, lpwcx->style, ExplainStyle(lpwcx->style), lpwcx->lpfnWndProc, lpwcx->cbClsExtra, lpwcx->cbWndExtra, lpwcx->hInstance); - return (*pRegisterClassA)(lpwcx); -} - -static void HookChildWndProc(HWND hwnd, DWORD dwStyle, LPCTSTR ApiName) -{ - // child window inherit the father's windproc, so if it's redirected to - // a hooker (either extWindowProc or extChildWindowProc) you have to retrieve - // the correct value (dxwws.GetProc) before saving it (dxwws.PutProc). - long res; - WNDPROC pWindowProc; - - pWindowProc = (WNDPROC)(*pGetWindowLongA)(hwnd, GWL_WNDPROC); - if((pWindowProc == extWindowProc) || - (pWindowProc == extChildWindowProc) || - (pWindowProc == extDialogWindowProc)){ // avoid recursions - HWND Father; - WNDPROC pFatherProc; - Father=GetParent(hwnd); - pFatherProc=dxwws.GetProc(Father); - OutTraceDW("%s: WndProc=%s father=%x WndProc=%x\n", ApiName, - (pWindowProc == extWindowProc) ? "extWindowProc" : ((pWindowProc == extChildWindowProc) ? "extChildWindowProc" : "extDialogWindowProc"), - Father, pFatherProc); - pWindowProc = pFatherProc; - } - dxwws.PutProc(hwnd, pWindowProc); - if(dwStyle & WS_CHILD){ - OutTraceDW("%s: Hooking CHILD hwnd=%x father WindowProc %x->%x\n", ApiName, hwnd, pWindowProc, extChildWindowProc); - res=(*pSetWindowLongA)(hwnd, GWL_WNDPROC, (LONG)extChildWindowProc); - } - else { // must be dwStyle & WS_DLGFRAME - OutTraceDW("%s: Hooking DLGFRAME hwnd=%x father WindowProc %x->%x\n", ApiName, hwnd, pWindowProc, extDialogWindowProc); - res=(*pSetWindowLongA)(hwnd, GWL_WNDPROC, (LONG)extDialogWindowProc); - } - if(!res) OutTraceE("%s: SetWindowLong ERROR %x\n", ApiName, GetLastError()); -} - -HWND hControlParentWnd = NULL; - -static HWND WINAPI extCreateWindowCommon( - LPCTSTR ApiName, - BOOL WideChar, - DWORD dwExStyle, - void *lpClassName, - void *lpWindowName, - DWORD dwStyle, - int x, - int y, - int nWidth, - int nHeight, - HWND hWndParent, - HMENU hMenu, - HINSTANCE hInstance, - LPVOID lpParam) -{ - HWND hwnd; - BOOL isValidHandle=TRUE; - int iOrigW, iOrigH; - - iOrigW=nWidth; - iOrigH=nHeight; - if(!dxw.Windowize || (hWndParent == HWND_MESSAGE)){ // v2.02.87: don't process message windows (hWndParent == HWND_MESSAGE) - if(WideChar) - hwnd= (*pCreateWindowExW)(dwExStyle, (LPCWSTR)lpClassName, (LPCWSTR)lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); - else - hwnd= (*pCreateWindowExA)(dwExStyle, (LPCSTR)lpClassName, (LPCSTR)lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); - - if ((dxw.dwFlags1 & HOOKCHILDWIN) && (dwStyle & (WS_CHILD|WS_DLGFRAME))) - HookChildWndProc(hwnd, dwStyle, ApiName); - - OutTraceDW("%s: ret=%x\n", ApiName, hwnd); - return hwnd; - } - - // no maximized windows in any case - if (dxw.dwFlags1 & PREVENTMAXIMIZE){ - OutTraceDW("%s: handling PREVENTMAXIMIZE mode\n", ApiName); - dwStyle &= ~WS_MAXIMIZE; - } - -#ifdef CREATEDESKTOP - if(CREATEDESKTOP){ - extern HWND hDesktopWindow; - if (dxw.IsRealDesktop(hWndParent)){ - OutTraceE("%s: new parent win %x->%x\n", ApiName, hWndParent, hDesktopWindow); - hWndParent=hDesktopWindow; - } - } -#endif - - // v2.1.92: fixes size & position for auxiliary big window, often used - // for intro movies etc. : needed for ...... - // evidently, this was supposed to be a fullscreen window.... - // v2.1.100: fixes for "The Grinch": this game creates a new main window for OpenGL - // rendering using CW_USEDEFAULT placement and 800x600 size while the previous - // main win was 640x480 only! - // v2.02.13: if it's a WS_CHILD window, don't reposition the x,y, placement for BIG win. - // v2.02.30: fix (Fable - lost chapters) Fable creates a bigger win with negative x,y coordinates. - if ( - ( - ((x<=0)&&(y<=0)) - || - ((x==CW_USEDEFAULT)&&(y==CW_USEDEFAULT)) - ) - && - ( - ((nWidth>=(int)dxw.GetScreenWidth())&&(nHeight>=(int)dxw.GetScreenHeight())) - || - ((nWidth==CW_USEDEFAULT)&&(nHeight==CW_USEDEFAULT)) // good for Imperialism, but is it general? - ) - && - !(dwExStyle & WS_EX_CONTROLPARENT) // Diablo fix - && - !(dwStyle & WS_CHILD) // Diablo fix - ) - { - RECT screen; - POINT upleft = {0,0}; - - // v2.02.30: fix (Fable - lost chapters) - if(nWidth==CW_USEDEFAULT) nWidth=dxw.GetScreenWidth(); - if(nHeight==CW_USEDEFAULT) nHeight=dxw.GetScreenHeight(); - - // update virtual screen size if it has grown - dxw.SetScreenSize(nWidth, nHeight); - // inserted some checks here, since the main window could be destroyed - // or minimized (see "Jedi Outcast") so that you may get a dangerous - // zero size. In this case, better renew the hWnd assignement and its coordinates. - do { // fake loop - isValidHandle = FALSE; - if (!(*pGetClientRect)(dxw.GethWnd(),&screen)) break; - if (!(*pClientToScreen)(dxw.GethWnd(),&upleft)) break; - if (screen.right==0 || screen.bottom==0) break; - isValidHandle = TRUE; - } while(FALSE); - if (isValidHandle){ // use parent's coordinates - if (!(dwStyle & WS_CHILD)){ - x=upleft.x; - y=upleft.y; - } - nWidth=screen.right; - nHeight=screen.bottom; - OutTraceDW("%s: fixed BIG win pos=(%d,%d) size=(%d,%d)\n", ApiName, x, y, nWidth, nHeight); - } - else { - // invalid parent coordinates: use initial placement, but leave the size. - // should also fix the window style and compensate for borders here? - // if (!(dwStyle & WS_CHILD)){ // commented out: can't be! see if condition - x=dxw.iPosX; - y=dxw.iPosY; - //} - nWidth=dxw.iSizX; - nHeight=dxw.iSizY; - OutTraceDW("%s: renewed BIG win pos=(%d,%d) size=(%d,%d)\n", ApiName, x, y, nWidth, nHeight); - } - dxw.SetFullScreen(TRUE); - if(dxw.Coordinates==DXW_DESKTOP_WORKAREA){ - RECT workarea; - (*pSystemParametersInfoA)(SPI_GETWORKAREA, NULL, &workarea, 0); - x=0; - y=0; - nWidth=workarea.right; - nHeight=workarea.bottom; - dwStyle=0; - OutTraceDW("%s: WORKAREA win pos=(%d,%d) size=(%d,%d)\n", ApiName, x, y, nWidth, nHeight); - } - else if(dxw.Coordinates==DXW_DESKTOP_FULL){ - RECT workarea; - (*pGetClientRect)((*pGetDesktopWindow)(), &workarea); - x=0; - y=0; - nWidth=workarea.right; - nHeight=workarea.bottom; - dwStyle=0; - OutTraceDW("%s: FULLDESKTOP win pos=(%d,%d) size=(%d,%d)\n", ApiName, x, y, nWidth, nHeight); - } - } - - if(!dxw.IsFullScreen()){ // v2.1.63: needed for "Monster Truck Madness" - if(WideChar) - hwnd= (*pCreateWindowExW)(dwExStyle, (LPCWSTR)lpClassName, (LPCWSTR)lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); - else - hwnd= (*pCreateWindowExA)(dwExStyle, (LPCSTR)lpClassName, (LPCSTR)lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); - OutTraceDW("%s: windowed mode ret=%x\n", ApiName, hwnd); - return hwnd; - } - - // tested on Gangsters: coordinates must be window-relative!!! - // Age of Empires.... - if (dwStyle & WS_CHILD){ - dxw.MapClient(&x, &y, &nWidth, &nHeight); - OutTraceDW("%s: fixed WS_CHILD pos=(%d,%d) size=(%d,%d)\n", - ApiName, x, y, nWidth, nHeight); - } - // needed for Diablo, that creates a new control parent window that must be - // overlapped to the directdraw surface. - else if (dwExStyle & WS_EX_CONTROLPARENT){ - dxw.MapWindow(&x, &y, &nWidth, &nHeight); - OutTraceDW("%s: fixed WS_EX_CONTROLPARENT pos=(%d,%d) size=(%d,%d)\n", - ApiName, x, y, nWidth, nHeight); - } - - OutTraceB("%s: fixed pos=(%d,%d) size=(%d,%d) Style=%x(%s) ExStyle=%x(%s)\n", - ApiName, x, y, nWidth, nHeight, dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle)); - - if(WideChar) - hwnd= (*pCreateWindowExW)(dwExStyle, (LPCWSTR)lpClassName, (LPCWSTR)lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); - else - hwnd= (*pCreateWindowExA)(dwExStyle, (LPCSTR)lpClassName, (LPCSTR)lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); - if (hwnd==(HWND)NULL){ - OutTraceE("%s: ERROR err=%d Style=%x(%s) ExStyle=%x\n", - ApiName, GetLastError(), dwStyle, ExplainStyle(dwStyle), dwExStyle); - return hwnd; - } - - if (dwExStyle & WS_EX_CONTROLPARENT) hControlParentWnd=hwnd; - - if ((!isValidHandle) && dxw.IsFullScreen()){ - dxw.SethWnd(hwnd); - extern void AdjustWindowPos(HWND, DWORD, DWORD); - (*pSetWindowLongA)(hwnd, GWL_STYLE, (dxw.dwFlags2 & MODALSTYLE) ? 0 : WS_OVERLAPPEDWINDOW); - (*pSetWindowLongA)(hwnd, GWL_EXSTYLE, 0); - OutTraceDW("%s: hwnd=%x, set style=WS_OVERLAPPEDWINDOW extstyle=0\n", ApiName, hwnd); - AdjustWindowPos(hwnd, nWidth, nHeight); - (*pShowWindow)(hwnd, SW_SHOWNORMAL); - } - - //if ((dxw.dwFlags1 & FIXWINFRAME) && !(dwStyle & WS_CHILD)) - if ((dxw.dwFlags1 & FIXWINFRAME) && !(dwStyle & WS_CHILD) && dxw.IsDesktop(hwnd)) - dxw.FixWindowFrame(hwnd); - - if ((dxw.dwFlags1 & HOOKCHILDWIN) && (dwStyle & (WS_CHILD|WS_DLGFRAME))) - HookChildWndProc(hwnd, dwStyle, ApiName); - - if ((FIXCHILDSIZE) && (dwStyle & (WS_CHILD|WS_DLGFRAME))) - dxwws.PutSize(hwnd, iOrigW, iOrigH); - - // "Hoyle Casino Empire" needs to be in a maximized state to continue after the intro movie. - // Sending a SW_MAXIMIZE message intercepted by the PREVENTMAXIMIZE handling fixes the problem. - //if (dxw.IsFullScreen() && (dxw.dwFlags1 & PREVENTMAXIMIZE)){ - if ((hwnd == dxw.GethWnd()) && dxw.IsFullScreen() && (dxw.dwFlags1 & PREVENTMAXIMIZE)){ - OutTraceDW("%s: entering maximized state\n", ApiName); - (*pShowWindow)(hwnd, SW_MAXIMIZE); - } - - OutTraceDW("%s: ret=%x\n", ApiName, hwnd); - return hwnd; -} - -static LPCSTR ClassToStr(LPCSTR Class) -{ - static char AtomBuf[20+1]; - if(((DWORD)Class & 0xFFFF0000) == 0){ - sprintf(AtomBuf, "ATOM(%X)", (DWORD)Class); - return AtomBuf; - } - return Class; -} - -static LPCWSTR ClassToWStr(LPCWSTR Class) -{ - static WCHAR AtomBuf[20+1]; - if(((DWORD)Class & 0xFFFF0000) == 0){ - swprintf(AtomBuf, L"ATOM(%X)", (DWORD)Class); - return AtomBuf; - } - return Class; -} -// to do: implement and use ClassToWStr() for widechar call - -HWND WINAPI extCreateWindowExW( - DWORD dwExStyle, - LPCWSTR lpClassName, - LPCWSTR lpWindowName, - DWORD dwStyle, - int x, - int y, - int nWidth, - int nHeight, - HWND hWndParent, - HMENU hMenu, - HINSTANCE hInstance, - LPVOID lpParam) -{ - if(IsTraceDW){ - char xString[20], yString[20], wString[20], hString[20]; - if (x==CW_USEDEFAULT) strcpy(xString,"CW_USEDEFAULT"); - else sprintf(xString,"%d", x); - if (y==CW_USEDEFAULT) strcpy(yString,"CW_USEDEFAULT"); - else sprintf(yString,"%d", y); - if (nWidth==CW_USEDEFAULT) strcpy(wString,"CW_USEDEFAULT"); - else sprintf(wString,"%d", nWidth); - if (nHeight==CW_USEDEFAULT) strcpy(hString,"CW_USEDEFAULT"); - else sprintf(hString,"%d", nHeight); - OutTrace("CreateWindowExW: class=\"%ls\" wname=\"%ls\" pos=(%s,%s) size=(%s,%s) Style=%x(%s) ExStyle=%x(%s) hWndParent=%x%s hMenu=%x\n", - ClassToWStr(lpClassName), lpWindowName, xString, yString, wString, hString, - dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle), - hWndParent, hWndParent==HWND_MESSAGE?"(HWND_MESSAGE)":"", hMenu); - } - if(IsDebug) OutTrace("CreateWindowExW: DEBUG screen=(%d,%d)\n", dxw.GetScreenWidth(), dxw.GetScreenHeight()); - - if(!wcscmp(lpWindowName, L"ActiveMovie Window")){ - //x = y = 0; - RECT MainWin; - (*pGetClientRect)(dxw.GethWnd(), &MainWin); - //nWidth = dxw.GetScreenWidth(); - //nHeight = dxw.GetScreenHeight(); - nWidth = MainWin.right; - nHeight = MainWin.bottom; - } - - return extCreateWindowCommon("CreateWindowExW", TRUE, dwExStyle, (void *)lpClassName, (void *)lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); -} - -// GHO: pro Diablo -HWND WINAPI extCreateWindowExA( - DWORD dwExStyle, - LPCTSTR lpClassName, - LPCTSTR lpWindowName, - DWORD dwStyle, - int x, - int y, - int nWidth, - int nHeight, - HWND hWndParent, - HMENU hMenu, - HINSTANCE hInstance, - LPVOID lpParam) -{ - if(IsTraceDW){ - char xString[20], yString[20], wString[20], hString[20]; - if (x==CW_USEDEFAULT) strcpy(xString,"CW_USEDEFAULT"); - else sprintf(xString,"%d", x); - if (y==CW_USEDEFAULT) strcpy(yString,"CW_USEDEFAULT"); - else sprintf(yString,"%d", y); - if (nWidth==CW_USEDEFAULT) strcpy(wString,"CW_USEDEFAULT"); - else sprintf(wString,"%d", nWidth); - if (nHeight==CW_USEDEFAULT) strcpy(hString,"CW_USEDEFAULT"); - else sprintf(hString,"%d", nHeight); - OutTrace("CreateWindowExA: class=\"%s\" wname=\"%s\" pos=(%s,%s) size=(%s,%s) Style=%x(%s) ExStyle=%x(%s) hWndParent=%x%s hMenu=%x\n", - ClassToStr(lpClassName), lpWindowName, xString, yString, wString, hString, - dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle), - hWndParent, hWndParent==HWND_MESSAGE?"(HWND_MESSAGE)":"", hMenu); - } - if(IsDebug) OutTrace("CreateWindowExA: DEBUG screen=(%d,%d)\n", dxw.GetScreenWidth(), dxw.GetScreenHeight()); - - if(!strcmp(lpWindowName, "ActiveMovie Window")){ - //x = y = 0; - RECT MainWin; - (*pGetClientRect)(dxw.GethWnd(), &MainWin); - //nWidth = dxw.GetScreenWidth(); - //nHeight = dxw.GetScreenHeight(); - nWidth = MainWin.right; - nHeight = MainWin.bottom; - } - - return extCreateWindowCommon("CreateWindowExA", FALSE, dwExStyle, (void *)lpClassName, (void *)lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); -} - -LRESULT WINAPI extCallWindowProcA(WNDPROC lpPrevWndFunc, HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - // v2.02.30: fix (Imperialism II): apply to main window only !!! - HRESULT res; - - res = -1; - if(hwnd == dxw.GethWnd()) res=FixWindowProc("CallWindowProcA", hwnd, Msg, wParam, &lParam); - - if (res==(HRESULT)-1) - return (*pCallWindowProcA)(lpPrevWndFunc, hwnd, Msg, wParam, lParam); - else - return res; -} - -LRESULT WINAPI extCallWindowProcW(WNDPROC lpPrevWndFunc, HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - // v2.02.30: fix (Imperialism II): apply to main window only !!! - HRESULT res; - - res = -1; - if(hwnd == dxw.GethWnd()) res=FixWindowProc("CallWindowProcW", hwnd, Msg, wParam, &lParam); - - if (res==(HRESULT)-1) - return (*pCallWindowProcW)(lpPrevWndFunc, hwnd, Msg, wParam, lParam); - else - return res; -} - -LRESULT WINAPI extDefWindowProcA(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - // v2.02.30: fix (Imperialism II): apply to main window only !!! - HRESULT res; - - res = (HRESULT)-1; - if(hwnd == dxw.GethWnd()) res=FixWindowProc("DefWindowProcA", hwnd, Msg, wParam, &lParam); - - if (res==(HRESULT)-1) - return (*pDefWindowProcA)(hwnd, Msg, wParam, lParam); - else - return res; -} - -LRESULT WINAPI extDefWindowProcW(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - // v2.02.30: fix (Imperialism II): apply to main window only !!! - HRESULT res; - - res = (HRESULT)-1; - if(hwnd == dxw.GethWnd()) res=FixWindowProc("DefWindowProcW", hwnd, Msg, wParam, &lParam); - - if (res==(HRESULT)-1) - return (*pDefWindowProcW)(hwnd, Msg, wParam, lParam); - else - return res; -} - -int WINAPI extFillRect(HDC hdc, const RECT *lprc, HBRUSH hbr) -{ - int res; - RECT rc; - OutTraceDW("FillRect: hdc=%x hbrush=%x rect=(%d,%d)-(%d,%d)\n", hdc, hbr, lprc->left, lprc->top, lprc->right, lprc->bottom); - - if(dxw.dwFlags4 & NOFILLRECT) { - OutTraceDW("FillRect: SUPPRESS\n", hdc, hbr, lprc->left, lprc->top, lprc->right, lprc->bottom); - return TRUE; - } - - memcpy(&rc, lprc, sizeof(rc)); - - if(dxw.IsRealDesktop(WindowFromDC(hdc))) { - HWND VirtualDesktop; - VirtualDesktop=dxw.GethWnd(); - if(VirtualDesktop==NULL){ - OutTraceDW("FillRect: no virtual desktop\n"); - return TRUE; - } - OutTraceDW("FillRect: remapped hdc to virtual desktop hwnd=%x\n", dxw.GethWnd()); - hdc=(*pGDIGetDC)(dxw.GethWnd()); - } - - if(!dxw.IsFullScreen()) { - // when not in fullscreen mode, just proxy the call - // but check coordinates: some games may use excessive coordinates: see "Premier Manager 98" - RECT client; - HWND hwnd; - hwnd=WindowFromDC(hdc); - (*pGetClientRect)(hwnd, &client); - if(rc.left < 0) rc.left=0; - if(rc.top < 0) rc.top=0; - if(rc.right > client.right) rc.right=client.right; - if(rc.bottom > client.bottom) rc.bottom=client.bottom; - OutTraceDW("FillRect: remapped hdc from hwnd=%x to rect=(%d,%d)-(%d,%d)\n", hwnd, rc.left, rc.top, rc.right, rc.bottom); - return (*pFillRect)(hdc, &rc, hbr); - } - - if(OBJ_DC == GetObjectType(hdc)){ - if(rc.left < 0) rc.left = 0; - if(rc.top < 0) rc.top = 0; - if((DWORD)rc.right > dxw.GetScreenWidth()) rc.right = dxw.GetScreenWidth(); - if((DWORD)rc.bottom > dxw.GetScreenHeight()) rc.bottom = dxw.GetScreenHeight(); - dxw.MapClient(&rc); - //dxw.MapWindow(&rc); - OutTraceDW("FillRect: fixed rect=(%d,%d)-(%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom); - } - - res=(*pFillRect)(hdc, &rc, hbr); - return res; -} - -int WINAPI extFrameRect(HDC hdc, const RECT *lprc, HBRUSH hbr) -{ - int res; - RECT rc; - OutTraceDW("FrameRect: hdc=%x hbrush=%x rect=(%d,%d)-(%d,%d)\n", hdc, hbr, lprc->left, lprc->top, lprc->right, lprc->bottom); - - // when not in fullscreen mode, just proxy the call - if(!dxw.IsFullScreen()) return (*pFrameRect)(hdc, lprc, hbr); - - memcpy(&rc, lprc, sizeof(rc)); - if(OBJ_DC == GetObjectType(hdc)){ - if(rc.left < 0) rc.left = 0; - if(rc.top < 0) rc.top = 0; - if((DWORD)rc.right > dxw.GetScreenWidth()) rc.right = dxw.GetScreenWidth(); - if((DWORD)rc.bottom > dxw.GetScreenHeight()) rc.bottom = dxw.GetScreenHeight(); - dxw.MapClient(&rc); - OutTraceDW("FrameRect: fixed rect=(%d,%d)-(%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom); - } - - res=(*pFrameRect)(hdc, &rc, hbr); - return res; -} - -BOOL WINAPI extClipCursor(RECT *lpRectArg) -{ - // reference: hooking and setting ClipCursor is mandatori in "Emergency: Fighters for Life" - // where the application expects the cursor to be moved just in a inner rect within the - // main window surface. - - BOOL res; - RECT *lpRect; - RECT Rect; - - if(IsTraceC){ - if (lpRectArg) - OutTrace("ClipCursor: rect=(%d,%d)-(%d,%d)\n", - lpRectArg->left,lpRectArg->top,lpRectArg->right,lpRectArg->bottom); - else - OutTrace("ClipCursor: rect=(NULL)\n"); - } - - if (!(dxw.dwFlags1 & ENABLECLIPPING)) return 1; - - if(lpRectArg){ - Rect=*lpRectArg; - lpRect=&Rect; - } - else - lpRect=NULL; - - if(dxw.dwFlags1 & MODIFYMOUSE){ - // save desired clip region - // v2.02.39: fix - do not attempt to write to NULL lpRect - if (lpRect) { - ClipRegion=*lpRectArg; - lpClipRegion=&ClipRegion; - *lpRect=dxw.MapWindowRect(lpRect); - } - else - lpClipRegion=NULL; - } - - if (pClipCursor) res=(*pClipCursor)(lpRect); - if (lpRect) OutTraceDW("ClipCursor: REMAPPED rect=(%d,%d)-(%d,%d) res=%x\n", lpRect->left,lpRect->top,lpRect->right,lpRect->bottom, res); - - return TRUE; -} - -BOOL WINAPI extGetClipCursor(LPRECT lpRect) -{ - // v2.1.93: if ENABLECLIPPING, return the saved clip rect coordinates - - BOOL ret; - - // proxy.... - if (!(dxw.dwFlags1 & ENABLECLIPPING)) { - ret=(*pGetClipCursor)(lpRect); - // v2.03.11: fix for "SubCulture" mouse movement - if(lpRect && dxw.Windowize) *lpRect = dxw.GetScreenRect(); - if(IsTraceDDRAW){ - if (lpRect) - OutTrace("GetClipCursor: rect=(%d,%d)-(%d,%d) ret=%d\n", - lpRect->left,lpRect->top,lpRect->right,lpRect->bottom, ret); - else - OutTrace("GetClipCursor: rect=(NULL) ret=%d\n", ret); - } - return ret; - } - - if(lpRect){ - if(lpClipRegion) - *lpRect=ClipRegion; - else - *lpRect=dxw.GetScreenRect(); - OutTraceDW("GetClipCursor: rect=(%d,%d)-(%d,%d) ret=%d\n", - lpRect->left,lpRect->top,lpRect->right,lpRect->bottom, TRUE); - } - - return TRUE; -} - -LONG WINAPI extEnumDisplaySettings(LPCTSTR lpszDeviceName, DWORD iModeNum, DEVMODE *lpDevMode) -{ - LONG res; - OutTraceDW("EnumDisplaySettings: Devicename=%s ModeNum=%x\n", lpszDeviceName, iModeNum); - res=(*pEnumDisplaySettings)(lpszDeviceName, iModeNum, lpDevMode); - if(dxw.dwFlags4 & LIMITSCREENRES){ - #define HUGE 100000 - DWORD maxw, maxh; - maxw = maxh = HUGE; - switch(dxw.MaxScreenRes){ - case DXW_NO_LIMIT: maxw=HUGE; maxh=HUGE; break; - case DXW_LIMIT_320x200: maxw=320; maxh=200; break; - case DXW_LIMIT_640x480: maxw=640; maxh=480; break; - case DXW_LIMIT_800x600: maxw=800; maxh=600; break; - case DXW_LIMIT_1024x768: maxw=1024; maxh=768; break; - case DXW_LIMIT_1280x960: maxw=1280; maxh=960; break; - } - if((lpDevMode->dmPelsWidth > maxw) || (lpDevMode->dmPelsHeight > maxh)){ - OutTraceDW("EnumDisplaySettings: limit device size=(%d,%d)\n", maxw, maxh); - lpDevMode->dmPelsWidth = maxw; - lpDevMode->dmPelsHeight = maxh; - } - } - return res; -} - -LONG WINAPI extChangeDisplaySettingsA(DEVMODEA *lpDevMode, DWORD dwflags) -{ - if(IsTraceDDRAW){ - char sInfo[1024]; - strcpy(sInfo, ""); - if (lpDevMode) sprintf(sInfo, " DeviceName=%s fields=%x(%s) size=(%d x %d) bpp=%d", - lpDevMode->dmDeviceName, lpDevMode->dmFields, ExplainDevModeFields(lpDevMode->dmFields), - lpDevMode->dmPelsWidth, lpDevMode->dmPelsHeight, lpDevMode->dmBitsPerPel); - OutTrace("ChangeDisplaySettingsA: lpDevMode=%x flags=%x(%s)%s\n", - lpDevMode, dwflags, ExplainChangeDisplaySettingsFlags(dwflags), sInfo); - } - - if(dxw.Windowize) - return MyChangeDisplaySettings("ChangeDisplaySettingsA", FALSE, lpDevMode, dwflags); - else - return (*pChangeDisplaySettingsExA)(NULL, lpDevMode, NULL, dwflags, NULL); -} - -LONG WINAPI extChangeDisplaySettingsW(DEVMODEW *lpDevMode, DWORD dwflags) -{ - if(IsTraceDDRAW){ - char sInfo[1024]; - strcpy(sInfo, ""); - if (lpDevMode) sprintf(sInfo, " DeviceName=%ls fields=%x(%s) size=(%d x %d) bpp=%d", - lpDevMode->dmDeviceName, lpDevMode->dmFields, ExplainDevModeFields(lpDevMode->dmFields), - lpDevMode->dmPelsWidth, lpDevMode->dmPelsHeight, lpDevMode->dmBitsPerPel); - OutTrace("ChangeDisplaySettingsW: lpDevMode=%x flags=%x(%s)%s\n", - lpDevMode, dwflags, ExplainChangeDisplaySettingsFlags(dwflags), sInfo); - } - - if(dxw.Windowize) - return MyChangeDisplaySettings("ChangeDisplaySettingsW", TRUE, lpDevMode, dwflags); - else - return (*pChangeDisplaySettingsW)(lpDevMode, dwflags); -} - -LONG WINAPI extChangeDisplaySettingsExA(LPCTSTR lpszDeviceName, DEVMODEA *lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam) -{ - if(IsTraceDDRAW){ - char sInfo[1024]; - strcpy(sInfo, ""); - if (lpDevMode) sprintf(sInfo, " DeviceName=%s fields=%x(%s) size=(%d x %d) bpp=%d", - lpDevMode->dmDeviceName, lpDevMode->dmFields, ExplainDevModeFields(lpDevMode->dmFields), - lpDevMode->dmPelsWidth, lpDevMode->dmPelsHeight, lpDevMode->dmBitsPerPel); - OutTrace("ChangeDisplaySettingsExA: DeviceName=%s lpDevMode=%x flags=%x(%s)%s\n", - lpszDeviceName, lpDevMode, dwflags, ExplainChangeDisplaySettingsFlags(dwflags), sInfo); - } - - if(dxw.Windowize) - return MyChangeDisplaySettings("ChangeDisplaySettingsExA", FALSE, lpDevMode, dwflags); - else - return (*pChangeDisplaySettingsExA)(lpszDeviceName, lpDevMode, hwnd, dwflags, lParam); -} - -LONG WINAPI extChangeDisplaySettingsExW(LPCTSTR lpszDeviceName, DEVMODEW *lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam) -{ - if(IsTraceDDRAW){ - char sInfo[1024]; - strcpy(sInfo, ""); - if (lpDevMode) sprintf(sInfo, " DeviceName=%ls fields=%x(%s) size=(%d x %d) bpp=%d", - lpDevMode->dmDeviceName, lpDevMode->dmFields, ExplainDevModeFields(lpDevMode->dmFields), - lpDevMode->dmPelsWidth, lpDevMode->dmPelsHeight, lpDevMode->dmBitsPerPel); - OutTrace("ChangeDisplaySettingsExW: DeviceName=%ls lpDevMode=%x flags=%x(%s)%s\n", - lpszDeviceName, lpDevMode, dwflags, ExplainChangeDisplaySettingsFlags(dwflags), sInfo); - } - - if(dxw.Windowize) - return MyChangeDisplaySettings("ChangeDisplaySettingsExW", TRUE, lpDevMode, dwflags); - else - return (*pChangeDisplaySettingsExW)(lpszDeviceName, lpDevMode, hwnd, dwflags, lParam); -} - -static HDC WINAPI sGetDC(HWND hwnd, char *ApiName) -{ - // to do: add parameter and reference to pGDIGetDCEx to merge properly GetDC and GetDCEx - HDC ret; - HWND lochwnd; - - if(!dxw.IsFullScreen()) return(*pGDIGetDC)(hwnd); - - lochwnd=hwnd; - - if (dxw.IsRealDesktop(hwnd)) { - OutTraceDW("%s: desktop remapping hwnd=%x->%x\n", ApiName, hwnd, dxw.GethWnd()); - lochwnd=dxw.GethWnd(); - } - - if(bFlippedDC) { - extern HDC hFlippedDC; - LPDIRECTDRAWSURFACE lpDDSPrim; - lpDDSPrim = dxwss.GetPrimarySurface(); - if (lpDDSPrim) (*pGetDC)(lpDDSPrim, &hFlippedDC); - if (!(hwnd == dxw.GethWnd())) { - POINT father, child, offset; - father.x = father.y = 0; - child.x = child.y = 0; - (*pClientToScreen)(dxw.GethWnd(),&father); - (*pClientToScreen)(hwnd,&child); - offset.x = child.x - father.x; - offset.y = child.y - father.y; - offset.x >>= 2; - offset.y >>= 2; - dxw.UnmapClient(&offset); - OutTraceDW("%s: child window hwnd=%x offset=(%d,%d)\n", ApiName, hwnd, offset.x, offset.y); - (*pSetViewportOrgEx)(hFlippedDC, offset.x, offset.y, NULL); - } - OutTraceDW("%s: remapping flipped GDI lpDDSPrim=%x hdc=%x\n", ApiName, lpDDSPrim, hFlippedDC); - if(hFlippedDC) return hFlippedDC; - } - - switch(GDIEmulationMode){ - case GDIMODE_STRETCHED: - ret=(*pGDIGetDC)(lochwnd); - break; - case GDIMODE_EMULATED: - ret=dxw.AcquireEmulatedDC(lochwnd); - dxw.VirtualHDC=ret; - break; - } - - if(ret){ - OutTraceDW("%s: hwnd=%x ret=%x\n", ApiName, lochwnd, ret); - } - else{ - int err; - err=GetLastError(); - OutTraceE("%s ERROR: hwnd=%x err=%d at %d\n", ApiName, lochwnd, err, __LINE__); - if((err==ERROR_INVALID_WINDOW_HANDLE) && (lochwnd!=hwnd)){ - ret=(*pGDIGetDC)(hwnd); - if(ret) - OutTraceDW("%s: hwnd=%x ret=%x\n", ApiName, hwnd, ret); - else - OutTraceE("%s ERROR: hwnd=%x err=%d at %d\n", ApiName, hwnd, GetLastError(), __LINE__); - } - } - - return ret; -} - -HDC WINAPI extGDIGetDC(HWND hwnd) -{ - OutTraceDW("GDI.GetDC: hwnd=%x\n", hwnd); - return sGetDC(hwnd, "GDI.GetDC"); -} - -HDC WINAPI extGDIGetDCEx(HWND hwnd, HRGN hrgnClip, DWORD flags) -{ - // used by Star Wars Shadow of the Empire - OutTraceDW("GDI.GetDCEx: hwnd=%x hrgnClip=%x flags=%x(%s)\n", hwnd, hrgnClip, flags, ExplainGetDCExFlags(flags)); - return sGetDC(hwnd, "GDI.GetDCEx"); -} - -HDC WINAPI extGDIGetWindowDC(HWND hwnd) -{ - OutTraceDW("GDI.GetWindowDC: hwnd=%x\n", hwnd); - - // if not fullscreen or not desktop win, just proxy the call - if(!dxw.IsFullScreen() || !dxw.IsDesktop(hwnd)){ - HDC ret; - ret=(*pGDIGetWindowDC)(hwnd); - OutTraceDW("GDI.GetWindowDC: hwnd=%x hdc=%x\n", hwnd, ret); - return ret; - } - - return sGetDC(hwnd, "GDI.GetWindowDC"); -} - -int WINAPI extGDIReleaseDC(HWND hwnd, HDC hDC) -{ - int res; - - OutTraceDW("GDI.ReleaseDC: hwnd=%x hdc=%x\n", hwnd, hDC); - - if (dxw.IsRealDesktop(hwnd)) hwnd=dxw.GethWnd(); - if(hwnd == 0) return(TRUE); - - if(bFlippedDC && (hDC == hFlippedDC)) { - HRESULT ret; - LPDIRECTDRAWSURFACE lpDDSPrim; - lpDDSPrim = dxwss.GetPrimarySurface(); - if(!lpDDSPrim) return(TRUE); - OutTraceDW("GDI.ReleaseDC: releasing flipped GDI hdc=%x\n", hDC); - ret=(*pReleaseDC)(dxwss.GetPrimarySurface(), hDC); - if (ret) OutTraceE("GDI.ReleaseDC ERROR: err=%x(%s) at %d\n", ret, ExplainDDError(ret), __LINE__); - else dxw.ScreenRefresh(); - return (ret == DD_OK); - } - - switch(GDIEmulationMode){ - case GDIMODE_STRETCHED: - res=(*pGDIReleaseDC)(hwnd, hDC); - break; - case GDIMODE_EMULATED: - HDC windc; - windc=(*pGDIGetDC)(hwnd); - res=dxw.ReleaseEmulatedDC(hwnd); - res=(*pGDIReleaseDC)(hwnd, windc); - break; - } - - if (!res) OutTraceE("GDI.ReleaseDC ERROR: err=%d at %d\n", GetLastError(), __LINE__); - return(res); -} - -HDC WINAPI extBeginPaint(HWND hwnd, LPPAINTSTRUCT lpPaint) -{ - HDC hdc; - - OutTraceDW("GDI.BeginPaint: hwnd=%x lpPaint=%x FullScreen=%x\n", hwnd, lpPaint, dxw.IsFullScreen()); - - // avoid access to real desktop - if(dxw.IsRealDesktop(hwnd)) hwnd=dxw.GethWnd(); - - //if(bFlippedDC) { - // LPDIRECTDRAWSURFACE lpDDSPrim; - // lpDDSPrim = dxwss.GetPrimarySurface(); - // if (lpDDSPrim) (*pGetDC)(lpDDSPrim, &hFlippedDC); - // if (!(hwnd == dxw.GethWnd())) { - // POINT father, child, offset; - // father.x = father.y = 0; - // child.x = child.y = 0; - // (*pClientToScreen)(dxw.GethWnd(),&father); - // (*pClientToScreen)(hwnd,&child); - // offset.x = child.x - father.x; - // offset.y = child.y - father.y; - // dxw.UnmapClient(&offset); - // OutTraceDW("GDI.BeginPaint: child window hwnd=%x offset=(%d,%d)\n", hwnd, offset.x, offset.y); - // (*pSetViewportOrgEx)(hFlippedDC, offset.x, offset.y, NULL); - // } - // OutTraceDW("GDI.BeginPaint: remapping flipped GDI lpDDSPrim=%x hdc=%x\n", lpDDSPrim, hFlippedDC); - // if(hFlippedDC) { - // lpPaint->hdc=hFlippedDC; - // return hFlippedDC; - // } - //} - - hdc=(*pBeginPaint)(hwnd, lpPaint); - - // if not in fullscreen mode, that's all! - if(!dxw.IsFullScreen()) return hdc; - - // on CLIENTREMAPPING, resize the paint area to virtual screen size - if(dxw.dwFlags1 & CLIENTREMAPPING) lpPaint->rcPaint=dxw.GetScreenRect(); - - switch(GDIEmulationMode){ - case GDIMODE_STRETCHED: - break; - case GDIMODE_EMULATED: - HDC EmuHDC; - EmuHDC = dxw.AcquireEmulatedDC(hwnd); - lpPaint->hdc=EmuHDC; - hdc = EmuHDC; - break; - } - - OutTraceDW("GDI.BeginPaint: hdc=%x rcPaint=(%d,%d)-(%d,%d)\n", - hdc, lpPaint->rcPaint.left, lpPaint->rcPaint.top, lpPaint->rcPaint.right, lpPaint->rcPaint.bottom); - return hdc; -} - -BOOL WINAPI extEndPaint(HWND hwnd, const PAINTSTRUCT *lpPaint) -{ - BOOL ret; - - OutTraceDW("GDI.EndPaint: hwnd=%x lpPaint=%x lpPaint.hdc=%x lpPaint.rcpaint=(%d,%d)-(%d-%d)\n", - hwnd, lpPaint, lpPaint->hdc, lpPaint->rcPaint.left, lpPaint->rcPaint.top, lpPaint->rcPaint.right, lpPaint->rcPaint.bottom); - - //if(bFlippedDC && hFlippedDC) { - // LPDIRECTDRAWSURFACE lpDDSPrim; - // lpDDSPrim = dxwss.GetPrimarySurface(); - // ret = DDERR_GENERIC; - // if (lpDDSPrim) ret=(*pReleaseDC)(lpDDSPrim, hFlippedDC); - // OutTraceDW("GDI.EndPaint: remapping flipped GDI lpDDSPrim=%x hdc=%x\n", lpDDSPrim, hFlippedDC); - - // //dxw.ScreenRefresh(); - // return (ret == DD_OK); - //} - - // if not fullscreen or not desktop win, just proxy the call - if(!dxw.IsFullScreen() || !dxw.Windowize){ - ret=(*pEndPaint)(hwnd, lpPaint); - return ret; - } - - // avoid access to real desktop - if(dxw.IsRealDesktop(hwnd)) hwnd=dxw.GethWnd(); - - switch(GDIEmulationMode){ - case GDIMODE_STRETCHED: - ret=(*pEndPaint)(hwnd, lpPaint); - break; - case GDIMODE_EMULATED: - ret=dxw.ReleaseEmulatedDC(hwnd); - break; - } - - if(ret) - OutTraceDW("GDI.EndPaint: hwnd=%x ret=%x\n", hwnd, ret); - else - OutTraceE("GDI.EndPaint ERROR: err=%d at %d\n", GetLastError(), __LINE__); - - return ret; -} - -HWND WINAPI extCreateDialogIndirectParam(HINSTANCE hInstance, LPCDLGTEMPLATE lpTemplate, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM lParamInit) -{ - HWND RetHWND; - BOOL FullScreen; - FullScreen = dxw.IsFullScreen(); - OutTraceDW("CreateDialogIndirectParam: hInstance=%x lpTemplate=(style=%x extstyle=%x items=%d pos=(%d,%d) size=(%dx%d)) hWndParent=%x lpDialogFunc=%x lParamInit=%x\n", - hInstance, - lpTemplate->style, lpTemplate->dwExtendedStyle, lpTemplate->cdit, lpTemplate->x, lpTemplate->y, lpTemplate->cx, lpTemplate->cy, - hWndParent, lpDialogFunc, lParamInit); - if(dxw.IsFullScreen() && hWndParent==NULL) hWndParent=dxw.GethWnd(); - RetHWND=(*pCreateDialogIndirectParam)(hInstance, lpTemplate, hWndParent, lpDialogFunc, lParamInit); - dxw.SetFullScreen(FullScreen); - - // v2.02.73: redirect lpDialogFunc only when it is nor NULL - if(lpDialogFunc) { - dxwws.PutProc(RetHWND, (WNDPROC)lpDialogFunc); - if(!(*pSetWindowLongA)(RetHWND, DWL_DLGPROC, (LONG)extDialogWindowProc)) - OutTraceE("SetWindowLong: ERROR err=%d at %d\n", GetLastError(), __LINE__); - } - - OutTraceDW("CreateDialogIndirectParam: hwnd=%x\n", RetHWND); - return RetHWND; -} - -HWND WINAPI extCreateDialogParam(HINSTANCE hInstance, LPCTSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM lParamInit) -{ - HWND RetHWND; - BOOL FullScreen; - FullScreen = dxw.IsFullScreen(); - OutTraceDW("CreateDialogParam: hInstance=%x lpTemplateName=%s hWndParent=%x lpDialogFunc=%x lParamInit=%x\n", - hInstance, sTemplateName(lpTemplateName), hWndParent, lpDialogFunc, lParamInit); - if(hWndParent==NULL) hWndParent=dxw.GethWnd(); - RetHWND=(*pCreateDialogParam)(hInstance, lpTemplateName, hWndParent, lpDialogFunc, lParamInit); - dxw.SetFullScreen(FullScreen); - - // v2.02.73: redirect lpDialogFunc only when it is nor NULL: fix for "LEGO Stunt Rally" - if(lpDialogFunc) { - dxwws.PutProc(RetHWND, (WNDPROC)lpDialogFunc); - if(!(*pSetWindowLongA)(RetHWND, DWL_DLGPROC, (LONG)extDialogWindowProc)) - OutTraceE("SetWindowLong: ERROR err=%d at %d\n", GetLastError(), __LINE__); - } - - OutTraceDW("CreateDialogParam: hwnd=%x\n", RetHWND); - return RetHWND; -} - -BOOL WINAPI extMoveWindow(HWND hwnd, int X, int Y, int nWidth, int nHeight, BOOL bRepaint) -{ - BOOL ret; - OutTraceDW("MoveWindow: hwnd=%x xy=(%d,%d) size=(%d,%d) repaint=%x fullscreen=%x\n", - hwnd, X, Y, nWidth, nHeight, bRepaint, dxw.IsFullScreen()); - - if(dxw.Windowize){ - if(dxw.IsDesktop(hwnd)){ - // v2.1.93: happens in "Emergency Fighters for Life" ... - // what is the meaning of this? is it related to video stretching? - OutTraceDW("MoveWindow: prevent moving desktop win\n"); - return TRUE; - } - - if((hwnd==dxw.GethWnd()) || (hwnd==dxw.hParentWnd)){ - OutTraceDW("MoveWindow: prevent moving main win\n"); - return TRUE; - } - - if (dxw.IsFullScreen()){ - POINT upleft={0,0}; - RECT client; - BOOL isChild; - (*pClientToScreen)(dxw.GethWnd(),&upleft); - (*pGetClientRect)(dxw.GethWnd(),&client); - if ((*pGetWindowLongA)(hwnd, GWL_STYLE) & WS_CHILD){ - isChild=TRUE; - // child coordinate adjustement - X = (X * client.right) / dxw.GetScreenWidth(); - Y = (Y * client.bottom) / dxw.GetScreenHeight(); - nWidth = (nWidth * client.right) / dxw.GetScreenWidth(); - nHeight = (nHeight * client.bottom) / dxw.GetScreenHeight(); - } - else { - isChild=FALSE; - // regular win coordinate adjustement - X = upleft.x + (X * client.right) / dxw.GetScreenWidth(); - Y = upleft.y + (Y * client.bottom) / dxw.GetScreenHeight(); - nWidth = (nWidth * client.right) / dxw.GetScreenWidth(); - nHeight = (nHeight * client.bottom) / dxw.GetScreenHeight(); - } - OutTraceDW("MoveWindow: DEBUG client=(%d,%d) screen=(%d,%d)\n", - client.right, client.bottom, dxw.GetScreenWidth(), dxw.GetScreenHeight()); - OutTraceDW("MoveWindow: hwnd=%x child=%x relocated to xy=(%d,%d) size=(%d,%d)\n", - hwnd, isChild, X, Y, nWidth, nHeight); - } - else{ - if((X==0)&&(Y==0)&&(nWidth==dxw.GetScreenWidth())&&(nHeight==dxw.GetScreenHeight())){ - // evidently, this was supposed to be a fullscreen window.... - RECT screen; - POINT upleft = {0,0}; - (*pGetClientRect)(dxw.GethWnd(),&screen); - (*pClientToScreen)(dxw.GethWnd(),&upleft); - X=upleft.x; - Y=upleft.y; - nWidth=screen.right; - nHeight=screen.bottom; - OutTraceDW("MoveWindow: fixed BIG win pos=(%d,%d) size=(%d,%d)\n", X, Y, nWidth, nHeight); - } - } - } - - ret=(*pMoveWindow)(hwnd, X, Y, nWidth, nHeight, bRepaint); - if(!ret) OutTraceE("MoveWindow: ERROR err=%d at %d\n", GetLastError(), __LINE__); - return ret; -} - -int WINAPI extShowCursor(BOOL bShow) -{ - static int iFakeCounter; - int ret; - - OutTraceC("ShowCursor: bShow=%x\n", bShow); - if (bShow){ - if (dxw.dwFlags1 & HIDEHWCURSOR){ - iFakeCounter++; - OutTraceC("ShowCursor: HIDEHWCURSOR ret=%x\n", iFakeCounter); - return iFakeCounter; - } - } - else { - if (dxw.dwFlags2 & SHOWHWCURSOR){ - iFakeCounter--; - OutTraceC("ShowCursor: SHOWHWCURSOR ret=%x\n", iFakeCounter); - return iFakeCounter; - } - } - ret=(*pShowCursor)(bShow); - OutTraceC("ShowCursor: ret=%x\n", ret); - return ret; -} - -BOOL WINAPI extDrawFocusRect(HDC hDC, const RECT *lprc) -{ - return TRUE; -} - -BOOL WINAPI extScrollDC(HDC hDC, int dx, int dy, const RECT *lprcScroll, const RECT *lprcClip, HRGN hrgnUpdate, LPRECT lprcUpdate) -{ - return TRUE; -} - -HWND WINAPI extGetTopWindow(HWND hwnd) -{ - HWND ret; - OutTraceDW("GetTopWindow: hwnd=%x fullscreen=%x\n", hwnd, dxw.IsFullScreen()); - // a fullscreen program is supposed to be always top Z-order on the desktop! - ret = (dxw.IsFullScreen() && dxw.IsDesktop(hwnd)) ? dxw.GethWnd() : (*pGetTopWindow)(hwnd); - OutTraceDW("GetTopWindow: ret=%x\n", ret); - return ret; -} - -LONG WINAPI extTabbedTextOutA(HDC hdc, int X, int Y, LPCTSTR lpString, int nCount, int nTabPositions, const LPINT lpnTabStopPositions, int nTabOrigin) -{ - BOOL res; - OutTraceDW("TabbedTextOut: hdc=%x xy=(%d,%d) nCount=%d nTP=%d nTOS=%d str=(%d)\"%s\"\n", - hdc, X, Y, nCount, nTabPositions, nTabOrigin, lpString); - - if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc))){ - dxw.MapClient(&X, &Y); - OutTraceDW("TextOut: fixed dest=(%d,%d)\n", X, Y); - } - - res=(*pTabbedTextOutA)(hdc, X, Y, lpString, nCount, nTabPositions, lpnTabStopPositions, nTabOrigin); - return res; -} - -BOOL WINAPI extDestroyWindow(HWND hWnd) -{ - // v2.02.43: "Empire Earth" builds test surfaces that must be destroyed! - // v2.03.20: "Prince of Persia 3D" destroys the main window that must be preserved! - BOOL res; - OutTraceB("DestroyWindow: hwnd=%x\n", hWnd); - if (hWnd == dxw.GethWnd()) { - if(dxw.dwFlags6 & NODESTROYWINDOW) { - OutTraceDW("DestroyWindow: do NOT destroy main hwnd=%x\n", hWnd); - return TRUE; - } - OutTraceDW("DestroyWindow: destroy main hwnd=%x\n", hWnd); - dxw.SethWnd(NULL); - } - if (hControlParentWnd && (hWnd == hControlParentWnd)) { - OutTraceDW("DestroyWindow: destroy control parent hwnd=%x\n", hWnd); - hControlParentWnd = NULL; - } - res=(*pDestroyWindow)(hWnd); - if(!res)OutTraceE("DestroyWindow: ERROR err=%d\n", GetLastError()); - return res; -} - -static char *ExplainTAAlign(UINT c) -{ - static char eb[256]; - unsigned int l; - strcpy(eb,"TA_"); - strcat(eb, (c & TA_UPDATECP) ? "UPDATECP+" : "NOUPDATECP+"); - strcat(eb, (c & TA_RIGHT) ? (((c & TA_CENTER) == TA_CENTER) ? "CENTER+" : "RIGHT+") : "LEFT+"); - strcat(eb, (c & TA_BOTTOM) ? "BOTTOM+" : "TOP+"); - if ((c & TA_BASELINE)==TA_BASELINE) strcat(eb, "BASELINE+"); - if (c & TA_RTLREADING) strcat(eb, "RTLREADING+"); - l=strlen(eb); - eb[l-1]=0; - return(eb); -} - -static char *ExplainDTFormat(UINT c) -{ - static char eb[256]; - unsigned int l; - strcpy(eb,"DT_"); - if(!(c & (DT_CENTER|DT_RIGHT))) strcat(eb, "LEFT+"); - if(c & DT_CENTER) strcat(eb, "CENTER+"); - if(c & DT_RIGHT) strcat(eb, "RIGHT+"); - if(!(c & (DT_VCENTER|DT_BOTTOM))) strcat(eb, "TOP+"); - if(c & DT_VCENTER) strcat(eb, "VCENTER+"); - if(c & DT_BOTTOM) strcat(eb, "BOTTOM+"); - if(c & DT_WORDBREAK) strcat(eb, "WORDBREAK+"); - if(c & DT_SINGLELINE) strcat(eb, "SINGLELINE+"); - if(c & DT_EXPANDTABS) strcat(eb, "EXPANDTABS+"); - if(c & DT_TABSTOP) strcat(eb, "TABSTOP+"); - if(c & DT_NOCLIP) strcat(eb, "NOCLIP+"); - if(c & DT_EXTERNALLEADING) strcat(eb, "EXTERNALLEADING+"); - if(c & DT_CALCRECT) strcat(eb, "CALCRECT+"); - if(c & DT_NOPREFIX) strcat(eb, "NOPREFIX+"); - if(c & DT_INTERNAL) strcat(eb, "INTERNAL+"); - l=strlen(eb); - eb[l-1]=0; - return(eb); -} - -BOOL gFixed; - -int WINAPI extDrawTextA(HDC hdc, LPCTSTR lpchText, int nCount, LPRECT lpRect, UINT uFormat) -{ - int ret; - BOOL MustScale; - OutTraceDW("DrawText: hdc=%x rect=(%d,%d)-(%d,%d) Format=%x(%s) Text=(%d)\"%s\"\n", - hdc, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, uFormat, ExplainDTFormat(uFormat), nCount, lpchText); - - MustScale = dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc)); - if (MustScale){ - dxw.MapClient((RECT *)lpRect); - OutTraceDW("DrawText: fixed rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); - } - - gFixed = TRUE; - ret=(*pDrawText)(hdc, lpchText, nCount, lpRect, uFormat); - gFixed=FALSE; - - // if nCount is zero, DrawRect returns 0 as text heigth, but this is not an error! (ref. "Imperialism II") - if(nCount && !ret) OutTraceE("DrawText: ERROR ret=%x err=%d\n", ret, GetLastError()); - - if (MustScale){ - dxw.UnmapClient((RECT *)lpRect); - OutTraceDW("DrawText: fixed output rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); - } - - return ret; -} - -int WINAPI extDrawTextExA(HDC hdc, LPTSTR lpchText, int nCount, LPRECT lpRect, UINT dwDTFormat, LPDRAWTEXTPARAMS lpDTParams) -{ - int ret; - BOOL MustScale; - - OutTraceDW("DrawTextEx: hdc=%x rect=(%d,%d)-(%d,%d) DTFormat=%x Text=(%d)\"%s\"\n", - hdc, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, dwDTFormat, nCount, lpchText); - if (IsDebug){ - if(lpDTParams) - OutTrace("DTParams: size=%d (L,R)margins=(%d,%d) TabLength=%d lDrawn=%d\n", - lpDTParams->cbSize, lpDTParams->iLeftMargin, lpDTParams->iRightMargin, - lpDTParams->iTabLength, lpDTParams->uiLengthDrawn); - else - OutTrace("DTParams: NULL\n"); - } - - MustScale = dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdc)); - - if (MustScale){ - dxw.MapClient((RECT *)lpRect); - OutTraceDW("DrawTextEx: fixed rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); - } - - gFixed = TRUE; - ret=(*pDrawTextEx)(hdc, lpchText, nCount, lpRect, dwDTFormat, lpDTParams); - gFixed=FALSE; - if(nCount && !ret) OutTraceE("DrawTextEx: ERROR ret=%x err=%d\n", ret, GetLastError()); - - if (MustScale){ - dxw.UnmapClient((RECT *)lpRect); - OutTraceDW("DrawTextEx: fixed output rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); - } - - return ret; -} - -BOOL WINAPI extCloseWindow(HWND hWnd) -{ - // from MSDN: Minimizes (but does not destroy) the specified window. - BOOL res; - OutTraceB("CloseWindow: hwnd=%x\n", hWnd); - if (hWnd == dxw.GethWnd()) { - OutTraceDW("CloseWindow: close main hwnd=%x\n", hWnd); - // do not delete the reference to main hWnd. - } - res=(*pCloseWindow)(hWnd); - if(!res)OutTraceE("CloseWindow: ERROR err=%d\n", GetLastError()); - return res; -} - -BOOL WINAPI extSetSysColors(int cElements, const INT *lpaElements, const COLORREF *lpaRgbValues) -{ - // v2.02.32: added to avoid SysColors changes by "Western Front" - BOOL ret; - OutTraceDW("SetSysColors: Elements=%d\n", cElements); - - if(dxw.dwFlags3 & LOCKSYSCOLORS) return TRUE; - - ret=(*pSetSysColors)(cElements, lpaElements, lpaRgbValues); - if(!ret) OutTraceE("SetSysColors: ERROR er=%d\n", GetLastError()); - return ret; -} - -BOOL WINAPI extUpdateWindow(HWND hwnd) -{ - BOOL ret; - OutTraceDW("UpdateWindow: hwnd=%x\n", hwnd); - - if(dxw.Windowize && dxw.IsRealDesktop(hwnd)){ - OutTraceDW("UpdateWindow: remapping hwnd=%x->%x\n", hwnd, dxw.GethWnd()); - hwnd=dxw.GethWnd(); - } - - ret=(*pUpdateWindow)(hwnd); - if(!ret) OutTraceE("UpdateWindow: ERROR er=%d\n", GetLastError()); - return ret; -} - -BOOL WINAPI extRedrawWindow(HWND hWnd, const RECT *lprcUpdate, HRGN hrgnUpdate, UINT flags) -{ - OutTraceDW("RedrawWindow: hwnd=%x flags=%x\n", hWnd, flags); - return (*pRedrawWindow)(hWnd, lprcUpdate, hrgnUpdate, flags); -} - - -BOOL WINAPI extGetWindowPlacement(HWND hwnd, WINDOWPLACEMENT *lpwndpl) -{ - BOOL ret; - OutTraceDW("GetWindowPlacement: hwnd=%x\n", hwnd); - - if(dxw.IsRealDesktop(hwnd)){ - OutTraceDW("GetWindowPlacement: remapping hwnd=%x->%x\n", hwnd, dxw.GethWnd()); - hwnd=dxw.GethWnd(); - } - - ret=(*pGetWindowPlacement)(hwnd, lpwndpl); - OutTraceDW("GetWindowPlacement: flags=%x showCmd=%x MinPosition=(%d,%d) MaxPosition=(%d,%d) NormalPosition=(%d,%d)-(%d,%d)\n", - lpwndpl->flags, lpwndpl->showCmd, - lpwndpl->ptMinPosition.x, lpwndpl->ptMinPosition.y, - lpwndpl->ptMaxPosition.x, lpwndpl->ptMaxPosition.y, - lpwndpl->rcNormalPosition.left, lpwndpl->rcNormalPosition.top, lpwndpl->rcNormalPosition.right, lpwndpl->rcNormalPosition.bottom); - - switch (lpwndpl->showCmd){ - case SW_SHOW: - if (dxw.IsFullScreen()){ - lpwndpl->showCmd = SW_MAXIMIZE; - OutTraceDW("GetWindowPlacement: forcing SW_MAXIMIZE state\n"); - } - break; - } - if(!ret) OutTraceE("GetWindowPlacement: ERROR er=%d\n", GetLastError()); - return ret; -} - -BOOL WINAPI extSetWindowPlacement(HWND hwnd, WINDOWPLACEMENT *lpwndpl) -{ - BOOL ret; - OutTraceDW("SetWindowPlacement: hwnd=%x\n", hwnd); - - if(dxw.IsRealDesktop(hwnd)){ - OutTraceDW("SetWindowPlacement: remapping hwnd=%x->%x\n", hwnd, dxw.GethWnd()); - hwnd=dxw.GethWnd(); - } - - OutTraceDW("SetWindowPlacement: flags=%x showCmd=%x MinPosition=(%d,%d) MaxPosition=(%d,%d) NormalPosition=(%d,%d)-(%d,%d)\n", - lpwndpl->flags, lpwndpl->showCmd, - lpwndpl->ptMinPosition.x, lpwndpl->ptMinPosition.y, - lpwndpl->ptMaxPosition.x, lpwndpl->ptMaxPosition.y, - lpwndpl->rcNormalPosition.left, lpwndpl->rcNormalPosition.top, lpwndpl->rcNormalPosition.right, lpwndpl->rcNormalPosition.bottom); - - switch (lpwndpl->showCmd){ - case SW_MAXIMIZE: - if (dxw.IsFullScreen()){ - lpwndpl->showCmd = SW_SHOW; - OutTraceDW("SetWindowPlacement: forcing SW_SHOW state\n"); - } - break; - } - ret=(*pSetWindowPlacement)(hwnd, lpwndpl); - if(!ret) OutTraceE("SetWindowPlacement: ERROR er=%d\n", GetLastError()); - return ret; -} - -HWND WINAPI extSetCapture(HWND hwnd) -{ - HWND ret; - OutTraceDW("SetCapture: hwnd=%x\n", hwnd); - ret=(*pSetCapture)(hwnd); - OutTraceDW("SetCapture: ret=%x\n", ret); - return ret; -} - -HWND WINAPI extGetActiveWindow(void) -{ - HWND ret; - ret=(*pGetActiveWindow)(); - if(dxw.Windowize && dxw.IsFullScreen()) { - OutTraceDW("GetActiveWindow: ret=%x->%x\n", ret, dxw.GethWnd()); - return dxw.GethWnd(); - } - return ret; -} - -HWND WINAPI extGetForegroundWindow(void) -{ - HWND ret; - ret=(*pGetForegroundWindow)(); - if(dxw.Windowize && dxw.IsFullScreen()) { - OutTraceDW("GetForegroundWindow: ret=%x->%x\n", ret, dxw.GethWnd()); - return dxw.GethWnd(); - } - return ret; -} - -BOOL WINAPI extIsWindowVisible(HWND hwnd) -{ - BOOL ret; - ret=(*pIsWindowVisible)(hwnd); - OutTraceB("IsWindowVisible: hwnd=%x ret=%x\n", hwnd, ret); - if(dxw.IsDesktop(hwnd) && !ret){ - OutTraceDW("IsWindowVisible: FORCING ret=TRUE\n"); - ret=TRUE; - } - return ret; -} - -BOOL WINAPI extSystemParametersInfoA(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni) -{ - BOOL ret; - OutTraceDW("SystemParametersInfoA: Action=%x Param=%x WinIni=%x\n", uiAction, uiParam, fWinIni); - switch(uiAction){ - case SPI_SETKEYBOARDDELAY: - case SPI_SETKEYBOARDSPEED: - OutTraceDW("SystemParametersInfoA: bypass action=%x\n", uiAction); - return TRUE; - break; - } - ret=(*pSystemParametersInfoA)(uiAction, uiParam, pvParam, fWinIni); - if(uiAction==SPI_GETWORKAREA){ - LPRECT cli = (LPRECT)pvParam; - *cli = dxw.GetScreenRect(); - OutTraceDW("SystemParametersInfoA: resized client workarea rect=(%d,%d)-(%d,%d)\n", cli->left, cli->top, cli->right, cli->bottom); - } - return ret; -} - -BOOL WINAPI extSystemParametersInfoW(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni) -{ - BOOL ret; - OutTraceDW("SystemParametersInfoW: Action=%x Param=%x WinIni=%x\n", uiAction, uiParam, fWinIni); - switch(uiAction){ - case SPI_SETKEYBOARDDELAY: - case SPI_SETKEYBOARDSPEED: - OutTraceDW("SystemParametersInfoW: bypass action=%x\n", uiAction); - return TRUE; - break; - } - ret=(*pSystemParametersInfoW)(uiAction, uiParam, pvParam, fWinIni); - if(uiAction==SPI_GETWORKAREA){ - LPRECT cli = (LPRECT)pvParam; - *cli = dxw.GetScreenRect(); - OutTraceDW("SystemParametersInfoW: resized client workarea rect=(%d,%d)-(%d,%d)\n", cli->left, cli->top, cli->right, cli->bottom); - } - return ret; -} - -#undef OutTraceDW -#define OutTraceDW OutTrace - -UINT_PTR WINAPI extSetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc) -{ - UINT uShiftedElapse; - UINT_PTR ret; - // beware: the quicker the time flows, the more the time clicks are incremented, - // and the lesser the pauses must be lasting! Shift operations are reverted in - // GetSystemTime vs. Sleep or SetTimer - uShiftedElapse = dxw.StretchTime(uElapse); - OutTraceDW("SetTimer: hwnd=%x TimerFunc=%x elapse=%d->%d timeshift=%d\n", hWnd, lpTimerFunc, uElapse, uShiftedElapse, dxw.TimeShift); - ret = (*pSetTimer)(hWnd, nIDEvent, uShiftedElapse, lpTimerFunc); - if(ret) dxw.PushTimer(hWnd, ret, uElapse, lpTimerFunc); - OutTraceDW("SetTimer: IDEvent=%x ret=%x\n", nIDEvent, ret); - return ret; -} - -BOOL WINAPI extKillTimer(HWND hWnd, UINT_PTR uIDEvent) -{ - BOOL ret; - OutTraceDW("KillTimer: hwnd=%x IDEvent=%x\n", hWnd, uIDEvent); - ret = (*pKillTimer)(hWnd, uIDEvent); - OutTraceDW("KillTimer: ret=%x\n", ret); - if(ret) dxw.PopTimer(hWnd, uIDEvent); - return ret; -} - -BOOL WINAPI extGetUpdateRect(HWND hWnd, LPRECT lpRect, BOOL bErase) -{ - BOOL ret; - OutTraceDW("GetUpdateRect: hwnd=%x Erase=%x\n", hWnd, bErase); - ret = (*pGetUpdateRect)(hWnd, lpRect, bErase); - if(ret){ - OutTraceDW("GetUpdateRect: rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); - if(dxw.IsFullScreen()){ - dxw.UnmapClient(lpRect); - OutTraceDW("GetUpdateRect: FIXED rect=(%d,%d)-(%d,%d)\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); - } - } - else - OutTraceE("GetUpdateRect ERROR: err=%d\n", GetLastError()); - return ret; -} - -BOOL WINAPI extGetCursorInfo(PCURSORINFO pci) -{ - BOOL ret; - OutTraceDW("GetCursorInfo\n"); - ret = (*pGetCursorInfo)(pci); - if(ret){ - OutTraceDW("GetCursorInfo: flags=%x hcursor=%x pos=(%d,%d)\n", pci->flags, pci->hCursor, pci->ptScreenPos.x, pci->ptScreenPos.y); - if(dxw.IsFullScreen()){ - dxw.UnmapClient(&(pci->ptScreenPos)); - OutTraceDW("GetCursorInfo: FIXED pos=(%d,%d)\n", pci->ptScreenPos.x, pci->ptScreenPos.y); - } - } - else - OutTraceE("GetCursorInfo ERROR: err=%d\n", GetLastError()); - return ret; -} - -// --- to be hooked .... - -HWND WINAPI extWindowFromPoint(POINT Point) -{ - HWND ret; - OutTraceDW("WindowFromPoint: point=(%d,%d)\n", Point.x, Point.y); - if(dxw.IsFullScreen()){ - dxw.UnmapWindow(&Point); - OutTraceDW("WindowFromPoint: FIXED point=(%d,%d)\n", Point.x, Point.y); - } - ret = (*pWindowFromPoint)(Point); - OutTraceDW("WindowFromPoint: hwnd=%x\n", ret); - return ret; -} - -HWND WINAPI extChildWindowFromPoint(HWND hWndParent, POINT Point) -{ - HWND ret; - OutTraceDW("ChildWindowFromPoint: hWndParent=%x point=(%d,%d)\n", hWndParent, Point.x, Point.y); - if(dxw.IsDesktop(hWndParent) && dxw.IsFullScreen() && dxw.Windowize){ - dxw.UnmapClient(&Point); - OutTraceDW("ChildWindowFromPoint: FIXED point=(%d,%d)\n", Point.x, Point.y); - } - ret = (*pChildWindowFromPoint)(hWndParent, Point); - OutTraceDW("ChildWindowFromPoint: hwnd=%x\n", ret); - return ret; -} - -HWND WINAPI extChildWindowFromPointEx(HWND hWndParent, POINT Point, UINT uFlags) -{ - HWND ret; - OutTraceDW("ChildWindowFromPoint: hWndParent=%x point=(%d,%d) flags=%x\n", hWndParent, Point.x, Point.y, uFlags); - if(dxw.IsDesktop(hWndParent) && dxw.IsFullScreen() && dxw.Windowize){ - dxw.UnmapClient(&Point); - OutTraceDW("ChildWindowFromPointEx: FIXED point=(%d,%d)\n", Point.x, Point.y); - } - ret = (*pChildWindowFromPointEx)(hWndParent, Point, uFlags); - OutTraceDW("ChildWindowFromPointEx: hwnd=%x\n", ret); - return ret; -} - -BOOL extGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpmi, GetMonitorInfo_Type pGetMonitorInfo) -{ - BOOL res; - OutTraceDW("GetMonitorInfo: hMonitor=%x mi=MONITORINFO%s\n", hMonitor, lpmi->cbSize==sizeof(MONITORINFO)?"":"EX"); - res=(*pGetMonitorInfo)(hMonitor, lpmi); - //v2.03.15 - must fix the coordinates also in case of error: that may depend on the windowed mode. - if(dxw.Windowize){ - OutTraceDW("GetMonitorInfo: FIX Work=(%d,%d)-(%d,%d) Monitor=(%d,%d)-(%d,%d) -> (%d,%d)-(%d,%d)\n", - lpmi->rcWork.left, lpmi->rcWork.top, lpmi->rcWork.right, lpmi->rcWork.bottom, - lpmi->rcMonitor.left, lpmi->rcMonitor.top, lpmi->rcMonitor.right, lpmi->rcMonitor.bottom, - 0, 0, dxw.GetScreenWidth(), dxw.GetScreenHeight()); - lpmi->rcWork = dxw.GetScreenRect(); - lpmi->rcMonitor = dxw.GetScreenRect(); - res=TRUE; - } - else - OutTraceE("GetMonitorInfo: ERROR err=%d\n", GetLastError()); - - return res; -} - -BOOL WINAPI extGetMonitorInfoA(HMONITOR hMonitor, LPMONITORINFO lpmi) -{ - return extGetMonitorInfo(hMonitor, lpmi, pGetMonitorInfoA); -} - -BOOL WINAPI extGetMonitorInfoW(HMONITOR hMonitor, LPMONITORINFO lpmi) -{ - return extGetMonitorInfo(hMonitor, lpmi, pGetMonitorInfoW); -} - -int WINAPI extGetUpdateRgn(HWND hWnd, HRGN hRgn, BOOL bErase) -{ - int regionType; - regionType=(*pGetUpdateRgn)(hWnd, hRgn, bErase); - OutTraceDW("GetUpdateRgn: hwnd=%x hrgn=%x erase=%x regionType=%x(%s)\n", - hWnd, hRgn, bErase, regionType, ExplainRegionType(regionType)); - - if(dxw.Windowize && dxw.IsFullScreen()){ - if(regionType == SIMPLEREGION){ - RECT rc; - if(!pGetRgnBox) pGetRgnBox=GetRgnBox; - regionType = (*pGetRgnBox)(hRgn, &rc); - OutTraceDW("GetUpdateRgn: regionType=%x(%s) box=(%d,%d)-(%d,%d)\n", - regionType, ExplainRegionType(regionType), rc.left, rc.top, rc.right, rc.bottom); - if(regionType == SIMPLEREGION){ - dxw.UnmapClient(&rc); - if(SetRectRgn(hRgn, rc.left, rc.top, rc.right, rc.bottom )){ - // success - OutTraceDW("GetUpdateRgn: FIXED box=(%d,%d)-(%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom); - } - } - } -#if 0 - if(regionType == COMPLEXREGION){ - RECT rc; - if(!pGetRgnBox) pGetRgnBox=GetRgnBox; - regionType = (*pGetRgnBox)(hRgn, &rc); - OutTraceDW("GetUpdateRgn: regionType=%x(%s) box=(%d,%d)-(%d,%d)\n", - regionType, ExplainRegionType(regionType), rc.left, rc.top, rc.right, rc.bottom); - if(regionType == COMPLEXREGION){ - //dxw.UnmapClient(&rc); - //if(SetRectRgn(hRgn, rc.left, rc.top, rc.right, rc.bottom )){ - if(SetRectRgn(hRgn, 0, 0, dxw.GetScreenWidth(), dxw.GetScreenHeight())){ - // success - OutTraceDW("GetUpdateRgn: FIXED box=(%d,%d)-(%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom); - } - } - } -#endif - } - - return regionType; -} - -#ifdef TRACEPALETTE -UINT WINAPI extGetDIBColorTable(HDC hdc, UINT uStartIndex, UINT cEntries, RGBQUAD *pColors) -{ - UINT ret; - OutTraceDW("GetDIBColorTable: hdc=%x start=%d entries=%d\n", hdc, uStartIndex, cEntries); - - //if((OBJ_DC == GetObjectType(hdc)) && (dxw.dwFlags1 & EMULATESURFACE)){ - // //extern PALETTEENTRY PalEntries[256]; - // extern DWORD *PaletteEntries; - // if((uStartIndex+cEntries) > 256) cEntries = 256 - uStartIndex; - // for(UINT i=0; i 256) cEntries = 256 - uStartIndex; - // for(UINT i=0; ileft, lpRect->top, lpRect->right, lpRect->bottom); - else - OutTrace("ValidateRect: hwnd=%x rect=NULL\n", hWnd); - } - ret = (*pValidateRect)(hWnd, lpRect); - return ret; -} - -int WINAPI extGetWindowTextA(HWND hWnd, LPTSTR lpString, int nMaxCount) -{ - // purpose of this wrapped call is to clear the FPS indicator (format " ~ (%d FPS)") - // from the window title, if present. It crashes games such as "Panzer General 3 Scorched Earth" - // when FPS on window title is activated. - int ret; - OutTraceDW("GetWindowTextA: hwnd=%x MaxCount=%d\n", hWnd, nMaxCount); - ret=(*pGetWindowTextA)(hWnd, lpString, nMaxCount); - if(ret) OutTraceDW("GetWindowTextA: ret=%d String=\"%s\"\n", ret, lpString); - if (ret && (dxw.dwFlags2 & SHOWFPS) && dxw.ishWndFPS(hWnd)){ - char *p; - p=strstr(lpString, " ~ ("); - if(p){ - *p = NULL; - ret = strlen(lpString); - OutTraceDW("GetWindowTextA: FIXED ret=%d String=\"%s\"\n", ret, lpString); - } - } - return ret; -} -#endif - -BOOL WINAPI extBringWindowToTop(HWND hwnd) -{ - BOOL res; - OutTraceDW("BringWindowToTop: hwnd=%x\n", hwnd); - if(dxw.dwFlags5 & UNLOCKZORDER) return TRUE; - res=(*pBringWindowToTop)(hwnd); - return res; -} - -BOOL WINAPI extSetForegroundWindow(HWND hwnd) -{ - BOOL res; - OutTraceDW("SetForegroundWindow: hwnd=%x\n", hwnd); - if(dxw.dwFlags5 & UNLOCKZORDER) return TRUE; - res=(*pSetForegroundWindow)(hwnd); - return res; -} - -HOOKPROC glpMouseHookProcessFunction; -HOOKPROC glpMessageHookProcessFunction; -/* -LRESULT CALLBACK extMouseHookProc(int code, WPARAM wParam, LPARAM lParam) -{ - LRESULT ret; - OutTrace("HookProc intercepted: code=%x wParam=%x lParam=%x\n", code, wParam, lParam); - MOUSEHOOKSTRUCT * pMouseStruct = (MOUSEHOOKSTRUCT *)lParam; - if (pMouseStruct != NULL){ - dxw.UnmapWindow(&(pMouseStruct->pt)); - } - ret= (*glpMouseHookProcessFunction)(code, wParam, lParam); - return ret; -} -*/ - -LRESULT CALLBACK extMessageHookProc(int code, WPARAM wParam, LPARAM lParam) -{ - LRESULT ret; - OutTrace("MessageHookProc: code=%x wParam=%x lParam=%x\n", code, wParam, lParam); - MSG * pMessage = (MSG *)lParam; - ret = NULL; - if(pMessage){ - UINT message = pMessage->message; - if ((message >= 0x600) || // custom messages - ((message >= WM_KEYFIRST) && (message <= WM_KEYLAST))) // keyboard messages - ret = (*glpMessageHookProcessFunction)(code, wParam, lParam); - } - return ret; -} - -HHOOK WINAPI extSetWindowsHookEx(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId) -{ - HHOOK ret; - if(dxw.dwFlags5 & EASPORTSHACK){ - if(idHook == WH_MOUSE) return NULL; - if(idHook == WH_GETMESSAGE) { - glpMessageHookProcessFunction = lpfn; - lpfn=extMessageHookProc; - } - } - ret=(*pSetWindowsHookEx)(idHook, lpfn, hMod, dwThreadId); - return ret; -} - - -HRESULT WINAPI extMessageBoxTimeoutA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType, WORD wLanguageId, DWORD dwMilliseconds) -{ - HRESULT res; - if(1) dwMilliseconds=1000; - res=(*pMessageBoxTimeoutA)(hWnd, lpText, lpCaption, uType, wLanguageId, dwMilliseconds); - return res; -} - -HRESULT WINAPI extMessageBoxTimeoutW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType, WORD wLanguageId, DWORD dwMilliseconds) -{ - HRESULT res; - if(1) dwMilliseconds=1000; - res=(*pMessageBoxTimeoutW)(hWnd, lpText, lpCaption, uType, wLanguageId, dwMilliseconds); - return res; -} - -HDESK WINAPI extCreateDesktop( LPCTSTR lpszDesktop, LPCTSTR lpszDevice, DEVMODE *pDevmode, DWORD dwFlags, ACCESS_MASK dwDesiredAccess, LPSECURITY_ATTRIBUTES lpsa) -{ - //OutTrace("CreateDesktop: SUPPRESS Desktop=%s Device=%s flags=%x access=%x\n", lpszDesktop, lpszDevice, dwFlags, dwDesiredAccess); - OutTraceDW("CreateDesktop: SUPPRESS flags=%x access=%x\n", dwFlags, dwDesiredAccess); - return (HDESK)0xDEADBEEF; // fake handle - //return (HDESK)NULL; // fake handle -} - -BOOL WINAPI extSwitchDesktop(HDESK hDesktop) -{ - OutTraceDW("SwitchDesktop: SUPPRESS hDesktop=%x\n", hDesktop); - return TRUE; -} - -HDESK WINAPI extOpenDesktop(LPTSTR lpszDesktop, DWORD dwFlags, BOOL fInherit, ACCESS_MASK dwDesiredAccess) -{ - OutTraceDW("CreateDesktop: SUPPRESS flags=%x access=%x\n", dwFlags, dwDesiredAccess); - return (HDESK)0xDEADBEEF; // fake handle - //return (HDESK)NULL; // fake handle -} - -BOOL WINAPI extCloseDesktop(HDESK hDesktop) -{ - OutTraceDW("CloseDesktop: SUPPRESS hDesktop=%x\n", hDesktop); - return TRUE; -} - -INT_PTR WINAPI extDialogBoxParamA(HINSTANCE hInstance, LPCTSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam) -{ - BOOL ret, FullScreen; - FullScreen = dxw.IsFullScreen(); - OutTraceDW("DialogBoxParamA: FullScreen=%x TemplateName=\"%s\" WndParent=%x\n", - FullScreen, sTemplateName(lpTemplateName), hWndParent); - dxw.SetFullScreen(FALSE); - ret = (*pDialogBoxParamA)(hInstance, lpTemplateName, hWndParent, lpDialogFunc, dwInitParam); - dxw.SetFullScreen(FullScreen); - OutTraceDW("DialogBoxParamA: ret=%x\n", ret); - return ret; -} - -BOOL WINAPI extIsZoomed(HWND hWnd) -{ - BOOL ret; - ret = (*pIsZoomed)(hWnd); - OutTrace("IsZoomed: hwnd=%x ret=%x\n", hWnd, ret); - //if(dxw.IsFullScreen()) ret = FALSE; - return ret; -} - -BOOL WINAPI extIsIconic(HWND hWnd) -{ - BOOL ret; - ret = (*pIsIconic)(hWnd); - OutTrace("IsIconic: hwnd=%x ret=%x\n", hWnd, ret); - //return FALSE; - return ret; -} diff --git a/host/TabSysLibs.cpp b/host/TabSysLibs.cpp index a0e8c11..235fe07 100644 --- a/host/TabSysLibs.cpp +++ b/host/TabSysLibs.cpp @@ -33,10 +33,12 @@ void CTabSysLibs::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_FIXTEXTOUT, cTarget->m_FixTextOut); DDX_Check(pDX, IDC_SHAREDDC, cTarget->m_SharedDC); DDX_Check(pDX, IDC_NOFILLRECT, cTarget->m_NoFillRect); + DDX_Check(pDX, IDC_REUSEEMULATEDDC, cTarget->m_ReuseEmulatedDC); // OpenGL DDX_Check(pDX, IDC_HOOKOPENGL, cTarget->m_HookOpenGL); // duplicated DDX_Check(pDX, IDC_FORCEHOOKOPENGL, cTarget->m_ForceHookOpenGL); + DDX_Check(pDX, IDC_FIXPIXELZOOM, cTarget->m_FixPixelZoom); DDX_Text(pDX, IDC_OPENGLLIB, cTarget->m_OpenGLLib); // Glide diff --git a/host/TargetDlg.cpp b/host/TargetDlg.cpp index 3407cf3..d554b24 100644 --- a/host/TargetDlg.cpp +++ b/host/TargetDlg.cpp @@ -26,6 +26,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_DxFilterMode = 0; // default: ddraw filtering m_DCEmulationMode = 0; // default: no emulation m_MouseVisibility = 0; + m_TextureHandling = 0; m_HookDI = FALSE; m_ModifyMouse = TRUE; // default true !! m_LogEnabled = FALSE; @@ -134,7 +135,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_KeepCursorFixed = FALSE; m_UseRGB565 = TRUE; // seems the default for 16bit video mode m_SuppressDXErrors = FALSE; - m_FlipEmulation = FALSE; + m_FlipEmulation = TRUE; // better set true default, since this mode is more compatible m_MarkBlit = FALSE; m_MarkLock = FALSE; m_NoSysMemPrimary = FALSE; @@ -181,6 +182,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_InterceptRDTSC = FALSE; m_HookOpenGL = FALSE; m_ForceHookOpenGL = FALSE; + m_FixPixelZoom = FALSE; m_FakeVersion = FALSE; m_FullRectBlt = FALSE; m_CenterToWin = FALSE; @@ -190,6 +192,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_NoDDRAWFlip = FALSE; m_NoGDIBlt = FALSE; m_NoFillRect = FALSE; + m_ReuseEmulatedDC = FALSE; // ?? m_AnalyticMode = FALSE; m_NoPaletteUpdate = FALSE; m_WireFrame = FALSE; diff --git a/host/TargetDlg.h b/host/TargetDlg.h index 3bceea0..fda4200 100644 --- a/host/TargetDlg.h +++ b/host/TargetDlg.h @@ -148,6 +148,7 @@ public: BOOL m_InterceptRDTSC; BOOL m_HookOpenGL; BOOL m_ForceHookOpenGL; + BOOL m_FixPixelZoom; BOOL m_FakeVersion; BOOL m_FullRectBlt; BOOL m_CenterToWin; @@ -157,6 +158,7 @@ public: BOOL m_NoDDRAWFlip; BOOL m_NoGDIBlt; BOOL m_NoFillRect; + BOOL m_ReuseEmulatedDC; BOOL m_AnalyticMode; BOOL m_NoPaletteUpdate; BOOL m_LimitResources; diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps index 50c8c15c84a35564c9df4dbcb89834e0473b077e..90d15a5c2332cf0fb60d3869d5743f28927bf567 100644 GIT binary patch delta 21918 zcmZ{M37k~LwfC(-WnYEa*cIG??jD#$je4h-nUeQ)I=k~2Pjkx2_BR3`*d(W=%&NzBmVolGgGnQQvD@U5jO>O0GUU*s5ZvPK+;3&`Y zzJG@2&G9_D;DDOxI}bb4{99vxyqrq+=F`2&%+g%0%ZtVqHG4-GFP$iN^B*J*D7t}e|uQmoT%YqZrn(LR5TscTrw zNbXv?E1xTHd$EX@v3ssD4Tp9yI*(CvsF;@(n2uCytjWvS$hD^4>g-$BnlYv%<=xks(Wcveajj`=SW=awC!I~?Xuw*V7J5B) z{&i-m>9r?bXBr#(m`VuB@l3ABx@cGxd!pGoD7N-7l0o(+R=1dCTlJ;2Tb1 zd@)%nBs%ypas{M#sDci3=HFdf161_Aqg><%~oGcV_1+O_0!JwaJBWq3l zu&*1>M*g3fY|CrS0mqykBKH$r>1^E3bB$*2j1aQNPnUQO5xW*|h269k&7NtWS!-rY z`$mYAM;~Mu{j<>Ab~HDf9;4pbcH;GBnmNbLzuwF==i2P`X1Y1go_D>OWmejot~WEx zD*HHnthR3v<@xqwqP)P4xB-+G+Cy$IGmg0^)EcdZEa?MH#A4nzL&$h0=@)#gOhPt! z7u)_D!1WS)H+@`ce~ORe*Mw>$d*jJ`DUEeNRa(5uLfCZn#ALjJZS}r|{w@DP`WI{S zzHJw*1LN=5%sMl@=5k}Ve_`sTgHcn=yFwV1{PuE}pJw(=OMAzTlwe$ocTE*oN@L(U7~bk#TZO|Y6dBs)T^E3++Znnr;;psE zuQzq|*H@8=WP3MrS{Ux|M;3njeX)x)3`sj z4bR)T`sb#pX87p&vVUBP{lmWgwwZH4V1wDY|2yWQnjpm9@=Nn-2yp&;=2s!WvR|1` zLxAP~W?l#Zj(*>Ch5&cHZ;lNC_PlT22m*G#_wQy+NRXYU|HgD0rP+zyux41O!q0za zmWL}OKQs@8A^ZQQX>}}kL*2RLk7jF##?JV&IWolf>wh-;he@vd#B3WE+Hya(H-BVm zclv)ZwITkdW#EFz(5T~U(=l-|3Yt&qCt>G!}b$UHsJ66Kpz3^f16PYk!Kl-E}`yX$bS)<#$ zviD8zLhmv!YWIK3%(juY%-!^7yE-OYON{0yPP!8@lkgDtHJRj7EbEAIp4e`0Dg zglekP66;7X5iRe-PlcmOVhQg=vbdNWIY6-exz@yB+7Ca6exuDWj7y5;CCNe&+e{fc z&UvVo?#ObnqZ^9Kq_eQFUJNo*>+R+CbO$+SMFur9sMv*#tpaSO)}T?9D2fptGK>W5 zhs%*pq|0y4py!^+JzL;m4TgHG6IJr)g2^BK~Y{ zYmrZQ!31xPC_KW%P5sT0W<@O2PcQ{xOH@8vV^X0tCUh;BuZ&+L3|cTE-rjEvUSBwY z@cNptUkw%TbMY`7Zi>k~91ytAUc>`MI?<0KK-4qC@U%aE55Vt;A=3c_28jB7?Wy3L zPQ?9eJek2{V7dbU!NM%S2SzPC6yPTIc?;zM6N|j}Me@|&M_ad)vpKItO5%{V%0p)| zlZRHBQ((oD2>_7f_EWuO2vN?!6D4CnD3CjFywlHiVC*mifU;kZ#h8|heO*a=$_6v0 zADwW-?S))V5tbo}0TSWaKN7=3bJ*JtaQa7|)A4&G^|0KP>ZOU&mq$Zzy;v=@w%Hhw zZQ?qlnnKx!&$a|~O&CfZgpl1MQ^>?M!k8>#u@649--jv~ZEAcNaMe|VMa0k<3YC?E zg~ZUA3YFEPlFVWtt=E{>ABE@6lJJ_KHKiiVW-3&qb)`)ox^Y)0TUQSJb^J& zD^=9+(_X-saTSa`@hmfXCIiP;fXS|W2?M@JyFS5wzTV8BnHsXIu(MomTBV-u7qo>i zW?}_{Nt7XHJKC%&m{dW@PC|PN*Ex_872}QVg~5|OyZ%YjI1KB;KJ+A{2`sWaj(8>P z+=Wt>w&)nnctf#%2PShDkZKF!WxuRW$Y|17h2SlKO9%SHh*lu9 z1EC6SfCmOJUd|%KBO7=Vnd2cXV5@8*vpf_*GU@Q4i6o||+hJ+P zRKT+P(tgZ{TKmM=2!C+7j{DD%3D__tp!o~)0-G3zDaxi(h<}iY3)#37PC0O2@)ZOr zGM7(czr;~jS{hj~azstTgtYE*K&Dbj$Dmq?;sT44@O_A7WlG4RXXgW88Xr>5@QU!=S$J;bkx(t&M&izY zA()O_bzdm@UHME>cLv>T;^povMuI|psG?&^s;23Y?CQ?=I8=5QQhq$?9S#Z|U71*l zZ|_c}c&l)OJlfuUj;Wu^V;Q1!oUjMEDQ$mwj+rd$ISzk{I^-8H^d;sL;4tR_nd3$;#`(il3Bk!lZ1N!p*O(Mk4#^UPE~&?p9?(9yoA8QWOIZOLT1F&y3bJR+3EL@$TC zsQU=Man;fGh4V}!EjRRoiA(7cueTxtC^ets+B#cA6u@X$-9{~v07%2?c4`$b zy_6|c%>>M#-|3}H8tMr}lH;A}OahI9kK3$;56n*y8v?9WoN$$?V}I~RQ@b1xT>>Is zA(?_&J9An5g`J@qs#d|b`|-tCk3OP;Y@*!GEW_#-F<@k7+_rq6J!zFWa8_U}NUIWU z1(o(~y#3B9(|B+|_o~5SsgDQFZNKB~_En~Cc7Ppx4Vjs=Fx`eb%6_!U&2sWT;$;aI z;|M71v`eGx#MKA}FuRF%{%V94xIEf+0WQr*$6y)!Ohp=1{&;)UYSSoHM%sH;n+91} z>dq&yF;E@t zt`37=SlphW18k&K`%6BQ97%*%D{MWjd=Y?-DkKC|&{31tF%|ND7Kf>5q)od>hlY4r zV)Zih+jOzWLdxda{cM)EjW+GEu2dX9O6uB0+77C0+QN=j6uD|>Nc%s=zIlN&CZfw! zt`JY6<;tRKb9R_zVzgT{bkd~`25N>ztWC#R%#`{~aRkdn@`~ZG`3udI;mm5JXHWPU zX0Q4m72DdBfQ|N|*u|vDF`iupI%Dir7rKc%y5cazbGVwrwGmb#HUKcLPPBYdpsJb? zgX(k?lH@_bgu7bQqeOXUxnw$|r}#S)d4=yIlfDRUKOV2RPy$ll7a; z$-?MD6>7IKKSPQW*O;)z{_Y}Y3no^Eo6gtCF4i#(Eu14|Pxc9H&zG%jgqa>oL*ONSG2jTUsu4IG9mFfu0z`4M#LbMiAAZx+w{uzS zk$9xKS97!4Q}HO4iVsW|TQt3#Gd0G}zt}X2@fJdaFXBmB48+4lI7ZpiE;hAGxH%Ea z&-yT$sNlM3U$~eYY%)o7_=@8u2zCJdCZfe>%bo45SfSGXdl2LZorL+~u+(B$2iJdH8 zDkMrptiMWhM0VqB4%0kCApt@;uR-iLtdKk712@Pg#W}#OYFgHWuc3J$tGZaKCr74} ze3}A{kqe}Z^Xx|-n8}9#qO;gd4mx~vW49$@oycSC>NTc8w5fY5rLKT45vh*G*n8KQ zMwuV#;^08(LQc_UU9^IteH4M3;*t*9Nm|s+5Z;RG#N|8TbY2TC>r>oPq;r0wV91>T zd<<1_DzZmi=FY;CS(Pw~;YO6diO$LkzWxlkCRJ z%(SnCs7kmRVLh~H2gUJ`4YxB_TAbvy;he>>_IH<=1~E%+sbc;@a@-h2qt0I(W5<8X zg=B;wxvlX;A=jl*xoFsBOr+7VT&XANlLaETktTr{P@Oyy&xks=k)lMfNR$uYV#HDB zIqEvJ8^7i3mnbER(->`25F*EW1bL1!zf(RU-)z2|(ji>r{#!&|}eF});5QHGdv2H_y&pT(uJvAe!) zrXHj7#km9dbet9#(N|qTS#+|MQ{s0$7=y>5k3}exV==VJem5%!4VI zYL!HH7gQE=exD32v4W#TaJR;JI^bdimuPVD^UeZ;q~CdTqEl=+ypJJpk4-)1;!-k# zoqg@_nq-5FIseU#ASFq_?a5n(DRj6(oh+miL=!vY$yK@QW9d3PBb2w#1d`NheC!5M%D< zO1eaLTa(xb=e8!E`+N(B!#pws38xcQcRDh)xE=g+zZsVdXn{>I?5{?fs9tCVV^yZo z1;jSw1`}vi#7H~;N;6d=!?LB&$cbU3>@HBcdFnW{BZ+v9!vd4N9D41z{DR{9{B9 z*!JO)HJ|B2B)!Lrtig2+-!b4CqbI$TR3|_^R1=WyV+E+!00c}SBvyJ$XozPt^vZfRuBzAnTb_gf| zb~B%hr+wtp0?Q{u>pz9$Mbx*;o-z#$0Y>fJh?s&72O&a#_bD@z>9#$kEx-MgUZ8!7 z!n8_Fy4pd;1tlIw+7J<=%CmPW>2W(veN|fAbrkbBBq1@Ah>;T<;DV)yTcCKMC^+f= zM$~T!5Rrqu7#ST%4Mly{xb!z(78H_bfnc56KkPKMbl472EX1LMX;>W&MQ88|M*8r# zpK9b_;?rgZ#c_nTfLxm-C++%i${av*2p<7$=lw(#wfHBdaapATT~5K-MnXvz!%x{P z;rp*D7M%hzq?9VMa|vTbEia%29-QC1HotU`hM%ewEl&O(SGd#_EDA_>t|&%Y$rU=v z(hBy}Ay_`6LO$%Q)Y+4s)@D}YmW@Su;#t+#+s~S54Eg+7okHWE!+8d^2Ir`Q6a53Y zl8N2oymJOubJeS)f&B3nwR}uVIRcdWu4ap2fxLAw$ds5+&SP(OiSlZ?1YVWGx!nS< z=CHFE0u0FEyl+O(+@R}vN@0gA+-n%}x=?1jSEC&oWw1qRuJ0k^&#bLa<;eyb6J8gy8NU#_7_|VHGU~YEe!+*Q&9b zk^4SP%G5AR%Zbg%rzTI-v+rDOrVQ@SJ~HI1QeX`a&XQ*&<&3c0F0X=`z|e(yJ|ttF z(TML!&Iw;PvipO|>^0ict}%^E1~UmI(2L4>xx1q@)yBLFH9a`B9({k|8dE#F+B4Qp zD8HU@oMTU6HuNu?W6x-rX@NX@f!Zk2=tosWuqR$?W+Pk5-g2#}ofu5KmqsZ0UZ+?k z0YCUmN%;CqiTH9Q!ELkH>Kmcs9MZB2kcO}1l#zcBH^MVTC_`EKA^~OQQ$8iSsZLEW zGhb*ZwV67x{W?>(qRMk^i%M{eUSX7Zr{fLjRSMR5ff zOll6q=Yx12XRHxGIJgRQ8D92_(grp*t+M$Rwe-*3Qt?n&9(ERlT0_3F0vWD}D1zqg z%rzru-NFQ~32IVZZ;4oNA3|1EHpypuzh@?}n$G>6X~4@h6)dzPwm&-oWMVO_YZP~g50>k|WaT(#oKXnpSM10zG_t^v z@GC>qHcpycc>&hi?Pd!3>)=8esaQXhha`OXBxCo0LLD@mCn%E3ltRMJwAK{}pECf_ zfJ%VYnIg_orQ2Yxfa4(4D;6(GVvzkIhgi`NwZ?-(N;8P@65QZRBW8eP1(81ok0_m` zj0ieP5sqSOz}fBAG_Y!aVO6!CS~c!t@6bck{5zE9#5>f=pY2fV?-27UPJYG5Cqbzd zO3y3p#KVsZ^%-GZEa4^;)d^4OI!pka+S&g{)_4o`iRSG*&u+chG_24E zXbwY%D<-5Llqnq%HCrecD6}DTF<#)6+d`7>1D{*MGoS_0K-bjtji%n;7wuwPU`bnQ zEa%Z6vR72f9$& z>SnR^PSbFvOaN|_V)opk97Y^73YesE!Ob;!yc~v7)VlM62({nd$2p%|gNMjo{(V!Y ziv_nT2zr&Bv22s0ncen%Q>%NQQn*>tCbJ~);$V+oz{?2y9+-2STkJpK;LL%l43fqJ zw857Q1#6>gU2v`?@U~&+(7J=(I2=ka=&eKLzj>{T7`E7F*P7}3l8W9y#Y=Q9`U*kl zJ;Zqg(xX7A7f4ns@%Rvdh9+C=0=$YSp~4oM!~2M?yb>=Zy7G7N4x^M??Uq3K=hwT0 zqE`D!g-@#;iFXbi{h@fPQPk2JR4JWk0%hd6DU88^5UUP z2EXYzlw$DPj!MCAJdS~)Ty9^hjjXFS-Gx^mT?gs?$3sBr!ligk7_X<&3pjyyAen8O z-L%e3nJwiCRq$mA_DF-!J#TrU|N&=aEM z)Zjr>PznfIt`psJF z*v-o4@0-mm7GTSKPvsJM6A{Kg}>e%m`NNHy+VO*1N(MS9tdkwFI9%qKkX4{l;82LaH=a@?r83LOkU7&v(7KXJ8|*Gr@~aUJv4-jLk4LQxBRT&_R#1t zx{&k}xok#ebbDz07@x#(KSd@%81P2ZA8Nd(fCSPii@>1{hi{S&^MDS|y}}`|aa8ef zoEO+4N87`5KB&{L1=lKK7PYRJBPT-7&qiCGK3DqAPM5 z?j>7vfG^u(j$n=tZc&bJZ!w26#K0Uco|J+1ZS)BelkKCrUd$yS)8Fk$@oqmsQ)4BDggY4dB4r7|e?Iyy7uI<{?=Iy4@-n89JWH6pY z3%}TI>KO88K!TAHIf8 z#ggLe04k2w;m>Ikndekf=RK#WTY#!s%%UWemT}cVJ2ees61h5ozHn9pf2Dz(+kp>k zA+A1sB#-Az=XfwWyUe# z?p>;|3D57VH|?b?zw<`Dk-$J$7~qSYun-hB0tGLfArzJF;ErdAKER=pNM*M^ujcjX z=T&U;f~jM#CMj9i7J!3;o+>gL@OBLxwBnigDY%#S=ZDrUp8}3s7Q#f)+$pr zQHow(p!wj3_7flxnM!HCBI9MTHNT>L=zB#azTy>a;J#PX=DzugD)!S?v@<8Yie)_O zRdsU~ysFXyEMs=*tIFf9S9P#|;vgTqsyx1YRk==oO>4zpQxVR3O;PJ!QxUd1$a}Au zLwNCg;fQCwuGLq+j_*+^zi!4d9#3L#?|EI#HVO?go!b%rhPMCux|-XDH&ooOy`i)y zC~aIu=DTmGY&+i2O22D2Sh#pVGyS9^1J`m#8;aE7Vm4Kh-T?pJoxFN0n4EMbJo!-y98*z2W z&7YsYgk=0U{{w`}y@4AFN6_Pw1tg449(b#`a$ww%2Mql4@DU5nM_Z%34cd0WTj5;{ z-Yd|~3bb}HT0RY5e6zwk1CWFl-w`csDHyZk4-fuoIzD#1{M7_}Y=8d?`q=U({&?hn z=ws&(M;QLx+#sL#93h`~9wVQ(Wz6b^Y18o4g>%r6>R0eUQ2ntVd})pvPTy;I2c{H# zui=pqV0%{t$=_h&h*$l_9{M7y$G_oO`Xa0TwZ`*4xGh*==vVyE7x&y?gEa1od#Yb7 zLSH^|>|H^cpoTK2(@91AM5k@i6eA!iN#?p~87b zgAWy+ISzcN@O&ruP+?Zu3>=?o7=9wA%L#d~+6&<0JzzzJyH5oxDzuitiVA;3VJj6j zE(a?rluiRHDja);xov!nKWxp}W?=N0jfafzyyq{cp4Z^_ZXFUGMtmFw&5T%U2JX7L z;n0sUg!y$uI}E=V9{fz0z#shQ;W3_f1e?OKZ9wPKkD$9#Dnpu zf7nhl@UtDlYvJpT_JDoTMtYwXq|a2ZXE>yNLoj~xReIT^IQ_>#B1d&k|X*MZ12@0lFr3Q&`-vIY@TZ0jD*yc-uHMZ|KDgeV(Io6R z{BGPQ{f!U8IE_JI!R~ytQh((M=t%}A! zkff4hd}Km{$vBDAnNE_SQ`6q9yaWYLNHkzU5-eu)2Y5wsciAIWN5oMW*|}r4om`F65za45 zK&P48Rtx@eapLbM0ayUEz9uD8vluWHjoK;a7`5r%B$B83+v}<41qH(I?e;o>- z876}uwVnW$;!5pS0JCwf_Ar3?sfhsoSKxQh1&gAZ_8{&OUJru!8Zyv&YH)tC7=8$X zupOGUmP(wi-KoKE(V*R`#ck)i>hR3~C+PSE{zW93IDp@!ay#)RJ`^qfE82edZM6Mg zvLgAfP0{wt{Am06ifDV!r)oz7_kdz8@4=d^=ElC>VSuF6*~=5!W9f#gE2U}dDz zQ&lC|B3ObnaM^-O>GR8GETm~4%*=2~VTI3E83~45fsjxZErBBX*fi6;MR)&0j87P1X84$IK70hXKf(Hq&q~Q-~LsoierIdKQZZ&M>B>X;E zEvMZERWjn&adxPVa--FE+8y9UI(Q`=eRMr52mQ1mJDpOpQ*f0;Rz?Ad7FQ+l@%11AP(_w=e>dQ`7YLQ;OYQQ>rkI!NHB0IydT84ktWK z7E6Y*2FZIZ-B2%8K{XUm%RRwRK-}@p0voJFTK|bbS%=jANjgTT&yrcV9>EPb0tF-_#O)$eD83@(8m(S3^vpP`glCZz$Xc+ilr5rOuY;WRu-cjlxSjzuM-7t!P9hlLkb;DF(R0lUFYiKk~x(S_%o?v3wul2`j)e|V!+nE>!0pE@@is9iJB#m%Xc#y)5L z_cpgGx;{O(_3~Kv?iid-E1Uiu>)N*6h(Z1&QdV&6K)zjHeat$$#gtVPn6Nx z<8cZfy&k8aGslzZKgZ4bL91wX$6P%Tpl3RA^+b@~h$lkyk2r$vbR^UKPNQxRWp^gi zmUwC%Q|IETpELDo9EGdQkF);}N9wqQ* zYO7*Sm@^Ty3j!2O0`0Z{?=u(?AT=4Z>_!HU7?cQbHU+eZ05A=-0|JE8*++nSBl`$2 zkjp*-WGrGI0nQe(PZNW$irGhi2P*pr5H4dM-qXnqUR$-?;4vFwFA=U-!(IaXlfj4p zC+pd38-wL**-HRe$6f+_ww}GVDK2HsCT-moH0CA&H0=?Ox5B^P(Rz$N^W4niiu~%3 z_Qer2%>9hZ_2`JuCh(8z!$)eWY~*PMpC@!^E4o;FE(O5Z5z|KNtk<3s<4$YKUO_`y z4#R;rg?1|ccn}{}ov-jpc`N3{?+`x5d)?^Qrk>|{g;(#Tm{+IN#(A;tolBZwfaewY zp8IP|+x0~4u#AiK@^+XH{k&rQ*}K}`?}_!Y@8I27j$G6yXwQ734e`!+lF;7xMw|K& z4SB+&m+!Uc+E2=HB;z9CWEmfy@TvKz{W)LB%oAA* z@Xk1THMzumj2E9QM(x@PzVn3m5_d+pBXjQJtx`1SQ*xv}=PAtGs6y?bPs!K(Ey{$1 z8P%v2`<48}nH;L(&WRSqmT;KCg%-XktzOh_3(&=2M1T|@YS}v&?DV5nBEXqds6_<0 z7((rU0Btp>^$GA5g9{Rb*++n$)$Aj{$~ElM%HR%z5&@R4XCDC`HLy=BuTA`$n70YL c_nH&Mhw!7Tyvx~WPJEEh_4$y$mz&N12mPVUod5s; diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc index bec4db029fa7451cb9bb3e4d0269cd5e9b285a28..abdb2023323e817a5b86ad317dd5ea74b327a078 100644 GIT binary patch delta 241 zcmdn7neERuwuUW?&$uRCR&y_9C}v1yPypgwhEj$chD3%EAUg#p;=Z$aVqAPyXm1&TPnFH2pLe<5zAo1{0u0Lm)Jm9P4R0 zorQ-{hTELM3@m8GU^aQ7i{W%WRYtw(T|A6kj7F37uiH;HSj;A$4s<~PLncE7&uHu@k RcinF42S%3dG7^k)8Ua$IIQRen delta 79 zcmeyfjcvzfwuUW?&$y;vkYiMuz95^CWBMm<#tqD-3`WzJ@-W77n=zO$=r9;E7%`Yl iUg%;t-Hw-W$K<4IGGGnc#rPRJxERg0&zEGp+Xw(Rz8QD` diff --git a/host/dxwndhost.vs2008.sln b/host/dxwndhost.vs2008.sln new file mode 100644 index 0000000..5bf4fb1 --- /dev/null +++ b/host/dxwndhost.vs2008.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dxwndhost", "dxwndhost.vs2008.vcproj", "{FD0B0234-8EC5-43C0-A384-1B881DD3D925}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FD0B0234-8EC5-43C0-A384-1B881DD3D925}.Debug|Win32.ActiveCfg = Debug|Win32 + {FD0B0234-8EC5-43C0-A384-1B881DD3D925}.Debug|Win32.Build.0 = Debug|Win32 + {FD0B0234-8EC5-43C0-A384-1B881DD3D925}.Release|Win32.ActiveCfg = Release|Win32 + {FD0B0234-8EC5-43C0-A384-1B881DD3D925}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/host/dxwndhost.vs2008.suo b/host/dxwndhost.vs2008.suo deleted file mode 100644 index 30dbff60917186c3906db55bbbea8182e3ee63c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7168 zcmeI0O-x)>6vq#()naQuY^_==j)hi?mOw$JC29%-tqBBLDAk0-P-ccwhL12nX|$T? z!i^>_OmySIq;9& z|2=nZE$sdEtD6UJTMoTuTWxWv(jE-eSMV1ss5rk(k|MJ4fB)S3+OX#Lw1R;VzM

K=J_Yd=P#L zJ_J7vtKTz}vEco1P=@Ex`zGCg3w-g`PT5N4EyrE`cp`05Jvia5 z!$-wo@Lr^a!4F8)RsIxB3I#bv=tB3pkzv$y@`QO_|o;ifQ6wgWQ zwH}n~e_hNxhSw<%yb#2~gk8xSg)id&!Y<_oQT<=JS6`sK;(Z#KQ>;yhl|?$2875it zGXAWd55s*STJ*V%{{bbut6atsz<&r*?$%k95g;k zDZCIBlJ9cSIF^})SED-QD;HCa7Ippm=o>z_0w`KBeK~b2CMxnFEG&o09k2Ygi~Ub~ zyR6f45MR`pIcd%V&0gi-5K)UY@q7m_jdPB+!pF%in(P=Sayvfy5^qh^w9#_RPI-BU zS{vxw%&&oQacbk7#K-AY zOX2my)GGgQElj=&5&z4v7uElC_ZSZxteZ3LGCQDLCpX6Xu~;!WjQ?wIgeg(wSJC%_ zVB$7buNz>-%bSwyMXnY>$2v0atDx=ok zCv7dd2x(7wXVM5(OyVyoyw{IF-H!9m+(K(E^;*r2yQg0Gg_9m*I(g8Pb}Za>ab}BkErL@j9<)R=}F>2{}F}$eO^|$ zV)?DKmm0iH|A38>0SNg=k*+(Goy3);&Of(yl`C6U z|2jgoyMOny$9-M|roG$l9QN1F&tm&xcW=$E^IxdzbWmL}Ql1pfe~a}m*6w6SU4OCp K*4kc<{C@x%@XbB| diff --git a/host/dxwndhostView.cpp b/host/dxwndhostView.cpp index 20c7c29..f1bea04 100644 --- a/host/dxwndhostView.cpp +++ b/host/dxwndhostView.cpp @@ -380,6 +380,7 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) if(dlg->m_InterceptRDTSC) t->flags4 |= INTERCEPTRDTSC; if(dlg->m_HookOpenGL) t->flags2 |= HOOKOPENGL; if(dlg->m_ForceHookOpenGL) t->flags3 |= FORCEHOOKOPENGL; + if(dlg->m_FixPixelZoom) t->flags6 |= FIXPIXELZOOM; if(dlg->m_WireFrame) t->flags2 |= WIREFRAME; if(dlg->m_NoTextures) t->flags4 |= NOTEXTURES; if(dlg->m_BlackWhite) t->flags3 |= BLACKWHITE; @@ -393,6 +394,7 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) if(dlg->m_NoDDRAWFlip) t->flags3 |= NODDRAWFLIP; if(dlg->m_NoGDIBlt) t->flags3 |= NOGDIBLT; if(dlg->m_NoFillRect) t->flags4 |= NOFILLRECT; + if(dlg->m_ReuseEmulatedDC) t->flags6 |= REUSEEMULATEDDC; if(dlg->m_AnalyticMode) t->flags3 |= ANALYTICMODE; if(dlg->m_ReplacePrivOps) t->flags5 |= REPLACEPRIVOPS; t->initx = dlg->m_InitX; @@ -614,6 +616,7 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) dlg->m_InterceptRDTSC = t->flags4 & INTERCEPTRDTSC ? 1 : 0; dlg->m_HookOpenGL = t->flags2 & HOOKOPENGL ? 1 : 0; dlg->m_ForceHookOpenGL = t->flags3 & FORCEHOOKOPENGL ? 1 : 0; + dlg->m_FixPixelZoom = t->flags6 & FIXPIXELZOOM ? 1 : 0; dlg->m_WireFrame = t->flags2 & WIREFRAME ? 1 : 0; dlg->m_NoTextures = t->flags4 & NOTEXTURES ? 1 : 0; dlg->m_BlackWhite = t->flags3 & BLACKWHITE ? 1 : 0; @@ -627,6 +630,7 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) dlg->m_NoDDRAWFlip = t->flags3 & NODDRAWFLIP ? 1 : 0; dlg->m_NoGDIBlt = t->flags3 & NOGDIBLT ? 1 : 0; dlg->m_NoFillRect = t->flags4 & NOFILLRECT ? 1 : 0; + dlg->m_ReuseEmulatedDC = t->flags6 & REUSEEMULATEDDC ? 1 : 0; dlg->m_AnalyticMode = t->flags3 & ANALYTICMODE ? 1 : 0; dlg->m_ReplacePrivOps = t->flags5 & REPLACEPRIVOPS ? 1 : 0; dlg->m_InitX = t->initx; diff --git a/host/resource b/host/resource index 561b289cf93f8698f666f583bb15f2d26b5fedf5..b2a4983ddd65033c211a3d2bffd313a04781c7ff 100644 GIT binary patch delta 90 zcmaE`fN9GjrVU-0laGX|O?Jp&o4iR(ZnA+Y2frsn1cNJs4?`4#KM?v(7UWcBG@3kL oS#ffJ5{qCcLoiU*mBE)G6sX3LA!IUthB8>c3zyX9EtzZ70KoGY(*OVf delta 28 ecmdn8i0Q!srVU-0oSY0$IC*`h;^vO5HEIBcjtKVv