diff --git a/build/dxwnd.dll b/build/dxwnd.dll index 990b74e..9e197c5 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:73656cf90cf6d5ad5a6c62da1bd48b14b7d0ff353dca4e04d87fb50445dfe178 -size 646656 +oid sha256:0911330dda18c4e1fb5f3caa8c1b951a333f79a64f3fe23b3eaf9d65225391b7 +size 647680 diff --git a/build/dxwnd.exe b/build/dxwnd.exe index 1d2df4c..0b632d7 100644 --- a/build/dxwnd.exe +++ b/build/dxwnd.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:41b726e8f958c18372ccc7f6fbc5b53b3a2293c2298e5933dbb0b4b0f6fe4fba -size 557056 +oid sha256:6a8148495ebac5bf9b0f2298eaaab28a3572c88cc967ecebbef876b60cf8eb95 +size 567296 diff --git a/build/dxwnd.ini b/build/dxwnd.ini new file mode 100644 index 0000000..ba6f1a0 --- /dev/null +++ b/build/dxwnd.ini @@ -0,0 +1,97 @@ +[window] +posx=950 +posy=64 +sizx=320 +sizy=200 +exportpath=D:\DxWnd\exports.ok\ +exepath=D:\Games\Restricted Area\ +[keymapping] +corner=0x78 +fullscreen=0x0D +workarea=0x7A +desktop=0x7B +[target] +title0=Betrayal in Antara +path0=D:\Games\Betrayal in Antara\ANTARAR.EXE +launchpath0= +module0= +opengllib0= +notes0= +registry0= +ver0=0 +coord0=0 +flag0=681574434 +flagg0=1207959552 +flagh0=20 +flagi0=-2011168764 +flagj0=4224 +flagk0=65536 +flagl0=0 +flagm0=0 +dflag0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 +maxddinterface0=7 +title1=Silver +path1=D:\Games\Silver\silver.exe +launchpath1= +module1= +opengllib1= +notes1= +registry1= +ver1=0 +coord1=0 +flag1=136314998 +flagg1=1208483856 +flagh1=20 +flagi1=138412036 +flagj1=4224 +flagk1=268500992 +flagl1=0 +flagm1=0 +dflag1=0 +posx1=-1250 +posy1=50 +sizx1=800 +sizy1=600 +maxfps1=0 +initts1=0 +winver1=0 +maxres1=-1 +swapeffect1=0 +maxddinterface1=7 +title2=Restricted Area +path2=D:\Games\Restricted Area\Ra.exe +launchpath2= +module2= +opengllib2= +notes2= +registry2= +ver2=0 +coord2=0 +flag2=681574434 +flagg2=1744830464 +flagh2=20 +flagi2=138412038 +flagj2=4224 +flagk2=327680 +flagl2=0 +flagm2=0 +dflag2=0 +posx2=50 +posy2=50 +sizx2=800 +sizy2=600 +maxfps2=0 +initts2=0 +winver2=0 +maxres2=-1 +swapeffect2=0 +maxddinterface2=7 diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index b8cb6ef..706e874 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -1093,4 +1093,8 @@ v2.03.64 fix: completed the hook pointers separation per COM interface version: this is of growing importance on Win10 because of the system updates (shims?) fix: fixed incoherences in task refences of the GUI fix: recovered task kill on WinXP -fix: updated RedrawWindow, now allows better handling of "Galapagos" pause screen \ No newline at end of file +fix: updated RedrawWindow, now allows better handling of "Galapagos" pause screen + +v2.03.65 +fix: handling of fullscreen switching on closest monitor (in multimonitor systems) +fix: X,Y starting win position can now be negative integer (in multimonitor systems) \ No newline at end of file diff --git a/dll/ddraw.cpp b/dll/ddraw.cpp index ecdfa00..efab376 100644 --- a/dll/ddraw.cpp +++ b/dll/ddraw.cpp @@ -5358,11 +5358,26 @@ static HRESULT WINAPI extGetSurfaceDesc(int dxversion, GetSurfaceDesc_Type pGetS return DDERR_INVALIDPARAMS; } +#define FIXSURFACEDESCSIZE TRUE + if(FIXSURFACEDESCSIZE){ + switch(dxversion){ + case 1: + case 2: + case 3: + lpddsd->dwSize = sizeof(DDSURFACEDESC); + break; + case 4: + case 7: + lpddsd->dwSize = sizeof(DDSURFACEDESC2); + break; + } + } + res=(*pGetSurfaceDesc)(lpdds, lpddsd); OutTraceDDRAW("GetSurfaceDesc: %slpdds=%x%s res=%x(%s)\n", res?"ERROR ":"", lpdds, IsPrim?"(PRIM)":(IsBack?"(BACK)":""), res, ExplainDDError(res)); if(res) { - OutTraceE("GetSurfaceDesc: ERROR err=%d(%s) at %d\n", res, ExplainDDError(res), __LINE__); + OutTraceE("GetSurfaceDesc: ERROR err=%x(%s) dxversion=%d s->len=%d at %d\n", res, ExplainDDError(res), dxversion, lpddsd->dwSize, __LINE__); return res; } diff --git a/dll/dxhook.cpp b/dll/dxhook.cpp index 3faa977..baf65a9 100644 --- a/dll/dxhook.cpp +++ b/dll/dxhook.cpp @@ -585,16 +585,26 @@ void CalculateWindowPos(HWND hwnd, DWORD width, DWORD height, LPWINDOWPOS wp) } // shift down-right so that the border is visible - // and also update the iPosX,iPosY upper-left coordinates of the client area - if(rect.left < 0){ - rect.right -= rect.left; - rect.left = 0; + if(rect.left < dxw.VirtualDesktop.left){ + rect.right = dxw.VirtualDesktop.left - rect.left + rect.right; + rect.left = dxw.VirtualDesktop.left; } - if(rect.top < 0){ - rect.bottom -= rect.top; - rect.top = 0; + if(rect.top < dxw.VirtualDesktop.top){ + rect.bottom = dxw.VirtualDesktop.top - rect.top + rect.bottom; + rect.top = dxw.VirtualDesktop.top; } + // shift up-left so that the windows doesn't exceed on the other side + if(rect.right > dxw.VirtualDesktop.right){ + rect.left = dxw.VirtualDesktop.right - rect.right + rect.left; + rect.right = dxw.VirtualDesktop.right; + } + if(rect.bottom > dxw.VirtualDesktop.bottom){ + rect.top = dxw.VirtualDesktop.bottom - rect.bottom + rect.top; + rect.bottom = dxw.VirtualDesktop.bottom; + } + + // update the arguments for the window creation wp->x=rect.left; wp->y=rect.top; wp->cx=rect.right-rect.left; @@ -1193,6 +1203,7 @@ extern HHOOK hMouseHook; void HookInit(TARGETMAP *target, HWND hwnd) { + static BOOL DoOnce = TRUE; HMODULE base; char *sModule; char sModuleBuf[60+1]; @@ -1230,6 +1241,17 @@ void HookInit(TARGETMAP *target, HWND hwnd) if(dxw.dwFlags5 & GDIMODE) dxw.dwFlags1 |= EMULATESURFACE; if(dxw.dwFlags5 & STRESSRESOURCES) dxw.dwFlags5 |= LIMITRESOURCES; + if(DoOnce){ + DoOnce = FALSE; + dxw.VirtualDesktop.left = GetSystemMetrics(SM_XVIRTUALSCREEN); + dxw.VirtualDesktop.top = GetSystemMetrics(SM_YVIRTUALSCREEN); + dxw.VirtualDesktop.right = dxw.VirtualDesktop.left + GetSystemMetrics(SM_CXVIRTUALSCREEN); + dxw.VirtualDesktop.bottom = dxw.VirtualDesktop.top + GetSystemMetrics(SM_CYVIRTUALSCREEN); + OutTraceDW("Virtual Desktop: monitors=%d area=(%d,%d)-(%d,%d)\n", + GetSystemMetrics(SM_CMONITORS), + dxw.VirtualDesktop.left, dxw.VirtualDesktop.top, dxw.VirtualDesktop.right, dxw.VirtualDesktop.bottom); + } + if(hwnd){ // v2.02.32: skip this when in code injection mode. // v2.1.75: is it correct to set hWnd here? //dxw.SethWnd(hwnd); diff --git a/dll/dxwcore.hpp b/dll/dxwcore.hpp index 6c37661..8a67627 100644 --- a/dll/dxwcore.hpp +++ b/dll/dxwcore.hpp @@ -177,6 +177,7 @@ public: // simple data variables HDC VirtualHDC; int GDIEmulationMode; BOOL TimeFreeze; + RECT VirtualDesktop; // Implementation protected: diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp index 450f68e..7288362 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.64" +#define VERSION "2.03.65" #define DDTHREADLOCK 1 //#define LOCKTHREADS diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo index a2070cb..12942a4 100644 Binary files a/dll/dxwnd.vs2008.suo and b/dll/dxwnd.vs2008.suo differ diff --git a/dll/dxwnd.vs2008.vcproj b/dll/dxwnd.vs2008.vcproj index 6fa5a7e..ecd20c2 100644 --- a/dll/dxwnd.vs2008.vcproj +++ b/dll/dxwnd.vs2008.vcproj @@ -1,7 +1,7 @@ + + diff --git a/dll/toggle_fs.cpp b/dll/toggle_fs.cpp new file mode 100644 index 0000000..8f89eb8 --- /dev/null +++ b/dll/toggle_fs.cpp @@ -0,0 +1,169 @@ +#define _WIN32_WINNT 0x0600 +#define WIN32_LEAN_AND_MEAN +#define _CRT_SECURE_NO_DEPRECATE 1 + +#include +#include +#include +#include "dxwnd.h" +#include "dxwcore.hpp" +#include "dxhelper.h" + +extern void RecoverScreenMode(); +extern void RestoreDDrawSurfaces(); +extern void RestoreD3DSurfaces(BOOL); + +void dx_FullScreenToggle(HWND hwnd) +{ + static BOOL bFullScreen = FALSE; + static RECT WinRect = {0, 0, 0, 0}; + static DWORD OldStyle, OldExtStyle; + static DEVMODE oldDisplayMode; + static DWORD OrigFlags; + static char szDevice[32]; + + // toggle .... + if (bFullScreen){ + OutTraceDW("DxWnd: exiting fullscreen mode: style=%x extstyle=%x pos=(%d,%d)-(%d,%d)\n", + OldStyle, OldExtStyle, WinRect.left, WinRect.top, WinRect.right, WinRect.bottom); + int ChangeDisplayResult = (*pChangeDisplaySettingsExA)(szDevice, &oldDisplayMode, NULL, CDS_FULLSCREEN, NULL); + if(ChangeDisplayResult != DISP_CHANGE_SUCCESSFUL){ + OutTraceE("ChangeDisplaySettingsEx ERROR: res=%d at %d\n", ChangeDisplayResult, __LINE__); + MessageBox(NULL,"Error: Failed to recover display mode.", "Error", 0); + } + // MoveWindow doesn't recover the exact position!!! + (*pSetWindowLong)(hwnd, GWL_STYLE, OldStyle); + (*pSetWindowLong)(hwnd, GWL_EXSTYLE, OldExtStyle); + (*pSetWindowPos)(hwnd, HWND_TOP, + WinRect.left, WinRect.top, (WinRect.right-WinRect.left), (WinRect.bottom-WinRect.top), + SWP_DRAWFRAME|SWP_FRAMECHANGED|SWP_SHOWWINDOW); + memset(&WinRect, 0, sizeof(WinRect)); + } + else { + OutTraceDW("DxWnd: entering fullscreen mode\n"); + int BestIndex, iCost, iBestCost; + (*pGetWindowRect)(hwnd, &WinRect); + OldStyle = (*pGetWindowLongA)(hwnd, GWL_STYLE); + OldExtStyle = (*pGetWindowLongA)(hwnd, GWL_EXSTYLE); + (*pSetWindowLong)(hwnd, GWL_STYLE, WS_VISIBLE|WS_CLIPSIBLINGS|WS_OVERLAPPED); + (*pSetWindowLong)(hwnd, GWL_EXSTYLE, 0); + + DEVMODE DisplayMode; + HMONITOR hBestMonitor; + hBestMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); + MONITORINFOEX mi; + memset(&mi, 0, sizeof(mi)); + mi.cbSize=sizeof(mi); + GetMonitorInfo(hBestMonitor, &mi); + OutTraceDW("Using monitor=\"%s\", rect=(%d,%d)-(%d,%d) type=%s\n", + mi.szDevice, + mi.rcMonitor.left, mi.rcMonitor.top, mi.rcMonitor.right, mi.rcMonitor.bottom, + (mi.dwFlags & MONITORINFOF_PRIMARY) ? "PRIMARY" : "SECONDARY"); + memset(&oldDisplayMode, 0, sizeof(DEVMODE)); + if(!(*pEnumDisplaySettings)(mi.szDevice, ENUM_CURRENT_SETTINGS, &oldDisplayMode)){ + MessageBox(NULL, "EnumDisplaySettings Failed ???", "Error!", 0); + } + iBestCost=1000000; // huge + for (int i=0; ;i++){ + iCost=0; + memset(&DisplayMode, 0, sizeof(DEVMODE)); + DisplayMode.dmSize = sizeof(DEVMODE); + if(!(*pEnumDisplaySettings)(mi.szDevice, i, &DisplayMode))break; // no more modes + if(DisplayMode.dmPelsWidth < dxw.GetScreenWidth()) continue; // bad: too narrow + if(DisplayMode.dmPelsHeight < dxw.GetScreenHeight()) continue; // bad: too low + if (DisplayMode.dmBitsPerPel != oldDisplayMode.dmBitsPerPel) continue; // bad: different color depth + iCost = + (DisplayMode.dmPelsWidth - dxw.GetScreenWidth()) + + (DisplayMode.dmPelsHeight - dxw.GetScreenHeight()) + + (DisplayMode.dmDisplayFrequency == oldDisplayMode.dmDisplayFrequency) ? 1 : 0; + if(iCost < iBestCost){ + iBestCost = iCost; + BestIndex = i; + } + if(iBestCost == 0) break; // got the perfect one! + } + memset(&DisplayMode, 0, sizeof(DEVMODE)); + strncpy(szDevice, mi.szDevice, 32); + (*pEnumDisplaySettings)(mi.szDevice, BestIndex, &DisplayMode); + OutTraceDW("DxWnd: selected mode bpp=%d size=(%dx%d) freq=%d\n", + DisplayMode.dmBitsPerPel, DisplayMode.dmPelsWidth, DisplayMode.dmPelsHeight, DisplayMode.dmDisplayFrequency); + DisplayMode.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT|DM_DISPLAYFLAGS|DM_DISPLAYFREQUENCY|DM_POSITION; + int ChangeDisplayResult = (*pChangeDisplaySettingsExA)(mi.szDevice, &DisplayMode, NULL, CDS_FULLSCREEN, NULL); + if(ChangeDisplayResult != DISP_CHANGE_SUCCESSFUL){ + OutTraceE("ChangeDisplaySettingsEx ERROR: res=%d at %d\n", ChangeDisplayResult, __LINE__); + MessageBox(NULL,"Error: Failed to change display mode.", "Error", 0); + } + // query again the NEW screen coordinates .... + memset(&mi, 0, sizeof(mi)); + mi.cbSize=sizeof(mi); + GetMonitorInfo(hBestMonitor, &mi); + OutTraceDW("Updated monitor=\"%s\", rect=(%d,%d)-(%d,%d) type=%s\n", + mi.szDevice, + mi.rcMonitor.left, mi.rcMonitor.top, mi.rcMonitor.right, mi.rcMonitor.bottom, + (mi.dwFlags & MONITORINFOF_PRIMARY) ? "PRIMARY" : "SECONDARY"); + (*pMoveWindow)(hwnd, + mi.rcMonitor.left, mi.rcMonitor.top, // x, y + DisplayMode.dmPelsWidth, // width + DisplayMode.dmPelsHeight, // height + TRUE); + } + (*pUpdateWindow)(hwnd); + RestoreDDrawSurfaces(); + RestoreD3DSurfaces(bFullScreen); + bFullScreen = !bFullScreen; // switch toggle +} + +void dx_DesktopToggle(HWND hwnd, BOOL bWorkArea) +{ + static BOOL bDesktopToggle = FALSE; + static RECT WinRect = {0, 0, 0, 0}; + static DWORD OldStyle, OldExtStyle; + + if (bDesktopToggle){ // toggle .... + OutTraceDW("DxWnd: exiting desktop mode: style=%x extstyle=%x pos=(%d,%d)-(%d,%d)\n", + OldStyle, OldExtStyle, WinRect.left, WinRect.top, WinRect.right, WinRect.bottom); + (*pSetWindowLong)(hwnd, GWL_STYLE, OldStyle); + (*pSetWindowLong)(hwnd, GWL_EXSTYLE, OldExtStyle); + // MoveWindow doesn't recover the exact position!!! + (*pSetWindowPos)(hwnd, HWND_TOP, + WinRect.left, WinRect.top, (WinRect.right-WinRect.left), (WinRect.bottom-WinRect.top), + SWP_DRAWFRAME|SWP_FRAMECHANGED|SWP_SHOWWINDOW); + memset(&WinRect, 0, sizeof(WinRect)); + } + else { + RECT DesktopRect; + HWND DesktopWnd; + HDC hClientDC; + OutTraceDW("DxWnd: entering desktop mode\n"); + if((WinRect.left==0) && (WinRect.right==0) && (WinRect.top==0) && (WinRect.bottom==0)) (*pGetWindowRect)(hwnd, &WinRect); + OldStyle = (*pGetWindowLongA)(hwnd, GWL_STYLE); + OldExtStyle = (*pGetWindowLongA)(hwnd, GWL_EXSTYLE); + (*pSetWindowLong)(hwnd, GWL_STYLE, WS_VISIBLE|WS_CLIPSIBLINGS|WS_OVERLAPPED); + (*pSetWindowLong)(hwnd, GWL_EXSTYLE, 0); + (*pUpdateWindow)(hwnd); + DesktopWnd = (*pGetDesktopWindow)(); + hClientDC=(*pGDIGetDC)(hwnd); + + HMONITOR hBestMonitor; + hBestMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); + MONITORINFOEX mi; + memset(&mi, 0, sizeof(mi)); + mi.cbSize=sizeof(mi); + GetMonitorInfo(hBestMonitor, &mi); + OutTraceDW("Using monitor=\"%s\", rect=(%d,%d)-(%d,%d) type=%s\n", + mi.szDevice, + mi.rcMonitor.left, mi.rcMonitor.top, mi.rcMonitor.right, mi.rcMonitor.bottom, + (mi.dwFlags & MONITORINFOF_PRIMARY) ? "PRIMARY" : "SECONDARY"); + + DesktopRect = bWorkArea ? mi.rcWork : mi.rcMonitor; + OutTraceDW("DxWnd: desktop=(%d,%d)-(%d,%d)\n"); + (*pSetWindowPos)(hwnd, HWND_TOP, + DesktopRect.left, DesktopRect.top, (DesktopRect.right-DesktopRect.left), (DesktopRect.bottom-DesktopRect.top), + SWP_DRAWFRAME|SWP_FRAMECHANGED|SWP_SHOWWINDOW); + (*pGDIBitBlt)(hClientDC, DesktopRect.left, DesktopRect.top, DesktopRect.right, DesktopRect.bottom, NULL, 0, 0, BLACKNESS); + } + bDesktopToggle = !bDesktopToggle; // switch toggle + (*pUpdateWindow)(hwnd); + dxw.ScreenRefresh(); + (*pInvalidateRect)(hwnd, NULL, FALSE); // force window update +} diff --git a/dll/winproc.cpp b/dll/winproc.cpp index d1f2b9e..2b8e155 100644 --- a/dll/winproc.cpp +++ b/dll/winproc.cpp @@ -11,8 +11,8 @@ extern void SuppressIMEWindow(); extern void RecoverScreenMode(); -extern void RestoreDDrawSurfaces(); -extern void RestoreD3DSurfaces(BOOL); +extern void dx_FullScreenToggle(HWND); +extern void dx_DesktopToggle(HWND, BOOL); static void dx_ToggleLogging() { @@ -194,127 +194,6 @@ static void dx_Cornerize(HWND hwnd) dxw.ScreenRefresh(); } -void dx_FullScreenToggle(HWND hwnd) -{ - static BOOL bFullScreen = FALSE; - static RECT WinRect = {0, 0, 0, 0}; - static DWORD OldStyle, OldExtStyle; - static DEVMODE oldDisplayMode; - static DWORD OrigFlags; - - // toggle .... - if (bFullScreen){ - OutTraceDW("DxWnd: exiting fullscreen mode: style=%x extstyle=%x pos=(%d,%d)-(%d,%d)\n", - OldStyle, OldExtStyle, WinRect.left, WinRect.top, WinRect.right, WinRect.bottom); - int ChangeDisplayResult = (*pChangeDisplaySettingsA)(&oldDisplayMode, CDS_FULLSCREEN); - if(ChangeDisplayResult != DISP_CHANGE_SUCCESSFUL){ - MessageBox(NULL,"Error: Failed to recover display mode.", "Error", 0); - } - // MoveWindow doesn't recover the exact position!!! - (*pSetWindowLong)(hwnd, GWL_STYLE, OldStyle); - (*pSetWindowLong)(hwnd, GWL_EXSTYLE, OldExtStyle); - (*pSetWindowPos)(hwnd, HWND_TOP, - WinRect.left, WinRect.top, (WinRect.right-WinRect.left), (WinRect.bottom-WinRect.top), - SWP_DRAWFRAME|SWP_FRAMECHANGED|SWP_SHOWWINDOW); - memset(&WinRect, 0, sizeof(WinRect)); - } - else { - OutTraceDW("DxWnd: entering fullscreen mode\n"); - int BestIndex, iCost, iBestCost; - if((WinRect.left==0) && (WinRect.right==0) && (WinRect.top==0) && (WinRect.bottom==0)) (*pGetWindowRect)(hwnd, &WinRect); - OldStyle = (*pGetWindowLongA)(hwnd, GWL_STYLE); - OldExtStyle = (*pGetWindowLongA)(hwnd, GWL_EXSTYLE); - (*pSetWindowLong)(hwnd, GWL_STYLE, WS_VISIBLE|WS_CLIPSIBLINGS|WS_OVERLAPPED); - (*pSetWindowLong)(hwnd, GWL_EXSTYLE, 0); - (*pMoveWindow)(hwnd, 0, 0, dxw.GetScreenWidth(), dxw.GetScreenHeight(), TRUE); - (*pUpdateWindow)(hwnd); - - DEVMODE DisplayMode; - memset(&oldDisplayMode, 0, sizeof(DEVMODE)); - if(!(*pEnumDisplaySettings)(NULL, ENUM_CURRENT_SETTINGS, &oldDisplayMode)){ - MessageBox(NULL, "EnumDisplaySettings Failed ???", "Error!", 0); - } - iBestCost=1000000; // huge - for (int i=0; ;i++){ - iCost=0; - memset(&DisplayMode, 0, sizeof(DEVMODE)); - DisplayMode.dmSize = sizeof(DEVMODE); - if(!(*pEnumDisplaySettings)(NULL, i, &DisplayMode))break; // no more modes - if(DisplayMode.dmPelsWidth < dxw.GetScreenWidth()) continue; // bad: too narrow - if(DisplayMode.dmPelsHeight < dxw.GetScreenHeight()) continue; // bad: too low - if (DisplayMode.dmBitsPerPel != oldDisplayMode.dmBitsPerPel) continue; // bad: different color depth - iCost = - (DisplayMode.dmPelsWidth - dxw.GetScreenWidth()) + - (DisplayMode.dmPelsHeight - dxw.GetScreenHeight()) + - (DisplayMode.dmDisplayFrequency == oldDisplayMode.dmDisplayFrequency) ? 1 : 0; - if(iCost < iBestCost){ - iBestCost = iCost; - BestIndex = i; - } - if(iBestCost == 0) break; // got the perfect one! - } - memset(&DisplayMode, 0, sizeof(DEVMODE)); - (*pEnumDisplaySettings)(NULL, BestIndex, &DisplayMode); - OutTraceDW("DxWnd: selected mode bpp=%d size=(%dx%d) freq=%d\n", - DisplayMode.dmBitsPerPel, DisplayMode.dmPelsWidth, DisplayMode.dmPelsHeight, DisplayMode.dmDisplayFrequency); - DisplayMode.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT|DM_DISPLAYFLAGS|DM_DISPLAYFREQUENCY|DM_POSITION; - int ChangeDisplayResult = (*pChangeDisplaySettingsA)(&DisplayMode, CDS_FULLSCREEN); - if(ChangeDisplayResult != DISP_CHANGE_SUCCESSFUL){ - MessageBox(NULL,"Error: Failed to change display mode.", "Error", 0); - } - } - (*pUpdateWindow)(hwnd); - RestoreDDrawSurfaces(); - RestoreD3DSurfaces(bFullScreen); - bFullScreen = !bFullScreen; // switch toggle -} - -static void dx_DesktopToggle(HWND hwnd, BOOL bWorkArea) -{ - static BOOL bDesktopToggle = FALSE; - static RECT WinRect = {0, 0, 0, 0}; - static DWORD OldStyle, OldExtStyle; - - if (bDesktopToggle){ // toggle .... - OutTraceDW("DxWnd: exiting desktop mode: style=%x extstyle=%x pos=(%d,%d)-(%d,%d)\n", - OldStyle, OldExtStyle, WinRect.left, WinRect.top, WinRect.right, WinRect.bottom); - (*pSetWindowLong)(hwnd, GWL_STYLE, OldStyle); - (*pSetWindowLong)(hwnd, GWL_EXSTYLE, OldExtStyle); - // MoveWindow doesn't recover the exact position!!! - (*pSetWindowPos)(hwnd, HWND_TOP, - WinRect.left, WinRect.top, (WinRect.right-WinRect.left), (WinRect.bottom-WinRect.top), - SWP_DRAWFRAME|SWP_FRAMECHANGED|SWP_SHOWWINDOW); - memset(&WinRect, 0, sizeof(WinRect)); - } - else { - RECT DesktopRect; - HWND DesktopWnd; - HDC hClientDC; - OutTraceDW("DxWnd: entering desktop mode\n"); - if((WinRect.left==0) && (WinRect.right==0) && (WinRect.top==0) && (WinRect.bottom==0)) (*pGetWindowRect)(hwnd, &WinRect); - OldStyle = (*pGetWindowLongA)(hwnd, GWL_STYLE); - OldExtStyle = (*pGetWindowLongA)(hwnd, GWL_EXSTYLE); - (*pSetWindowLong)(hwnd, GWL_STYLE, WS_VISIBLE|WS_CLIPSIBLINGS|WS_OVERLAPPED); - (*pSetWindowLong)(hwnd, GWL_EXSTYLE, 0); - (*pUpdateWindow)(hwnd); - DesktopWnd = (*pGetDesktopWindow)(); - hClientDC=(*pGDIGetDC)(hwnd); - if(bWorkArea) - (*pSystemParametersInfoA)(SPI_GETWORKAREA, NULL, &DesktopRect, 0); - else - (*pGetClientRect)(DesktopWnd, &DesktopRect); - OutTraceDW("DxWnd: desktop=(%d,%d)-(%d,%d)\n"); - (*pSetWindowPos)(hwnd, HWND_TOP, - DesktopRect.left, DesktopRect.top, (DesktopRect.right-DesktopRect.left), (DesktopRect.bottom-DesktopRect.top), - SWP_DRAWFRAME|SWP_FRAMECHANGED|SWP_SHOWWINDOW); - (*pGDIBitBlt)(hClientDC, DesktopRect.left, DesktopRect.top, DesktopRect.right, DesktopRect.bottom, NULL, 0, 0, BLACKNESS); - } - bDesktopToggle = !bDesktopToggle; // switch toggle - (*pUpdateWindow)(hwnd); - dxw.ScreenRefresh(); - (*pInvalidateRect)(hwnd, NULL, FALSE); // force window update -} - LRESULT LastCursorPos; LRESULT CALLBACK extWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) diff --git a/host/SpecialEdit.cpp b/host/SpecialEdit.cpp new file mode 100644 index 0000000..6db9b30 --- /dev/null +++ b/host/SpecialEdit.cpp @@ -0,0 +1,182 @@ +#include "stdafx.h" +#include "SpecialEdit.h" + +#include +#include +#include + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +BaseFormat::BaseFormat() +{ +} + +BaseFormat::~BaseFormat() +{ +} + +void BaseFormat::SetAllowedChars(std::vector chars) +{ + m_listChars = chars; +} + +void BaseFormat::SetAllowedChars(LPCTSTR chars, int size) +{ + m_listChars.erase(m_listChars.begin(), m_listChars.end()); + m_listChars.reserve(size); + m_listChars.assign(chars, chars+size); +} + +RelIntegerFormat::RelIntegerFormat() +{ + LPCTSTR format = _T("-+0123456789"); + SetAllowedChars(format, _tcslen(format)); +} + +RelIntegerFormat::~RelIntegerFormat() +{ +} + +bool BaseFormat::IsCharAllowed(TCHAR nChar) +{ + std::vector::iterator pos = std::find(m_listChars.begin(), m_listChars.end(), nChar); + return (pos != m_listChars.end()); +} + +CSpecialEdit::CSpecialEdit() +{ + m_formatter = NULL; +} + +CSpecialEdit::~CSpecialEdit() +{ +} + +BEGIN_MESSAGE_MAP(CSpecialEdit, CEdit) + //{{AFX_MSG_MAP(CSpecialEdit) + ON_WM_CHAR() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSpecialEdit message handlers + +void CSpecialEdit::SetFormatter(IFormat *formatter) +{ + ASSERT(formatter != NULL); + m_formatter = formatter; +} + +bool CSpecialEdit::IsCharAllowed(TCHAR nChar) +{ + switch(nChar){ + case _T('\b'): + case 10: + case 13: + return true; + } + + ASSERT(m_formatter != NULL); + return m_formatter->IsCharAllowed(nChar); +} + +bool CSpecialEdit::IsClipboardOK() +{ + bool isOK = true; + COleDataObject obj; + + if (obj.AttachClipboard()) { + HGLOBAL hmem = NULL; + TCHAR *pUniText = NULL; + DWORD dwLen = 0; + bool bText = false; + + if (obj.IsDataAvailable(CF_TEXT)){ + hmem = obj.GetGlobalData(CF_TEXT); + + char *pCharText = (char*)::GlobalLock(hmem); +#ifdef UNICODE + int lenA = strlen(pCharText); + int lenW = MultiByteToWideChar(CP_ACP, 0, pCharText, lenA, 0, 0); + if (lenW > 0){ + pUniText = ::SysAllocStringLen(0, lenW); + MultiByteToWideChar(CP_ACP, 0, pCharText, lenA, pUniText, lenW); + bText = true; + } + else{ + ::GlobalUnlock(hmem); + return false; + } +#else + pUniText = pCharText; +#endif + } +#ifdef UNICODE + else if(obj.IsDataAvailable(CF_UNICODETEXT)){ + hmem = obj.GetGlobalData(CF_UNICODETEXT); + pUniText = (TCHAR*)::GlobalLock(hmem); + } +#endif + if(hmem){ + DWORD dwLen = _tcslen(pUniText); + for(DWORD i=0; i + +class IFormat +{ +public: + virtual ~IFormat(); + virtual bool IsCharAllowed(TCHAR nChar) = 0; +}; + +class BaseFormat : public IFormat +{ +protected: + std::vector m_listChars; + BaseFormat(); + virtual ~BaseFormat(); +public: + void SetAllowedChars(std::vector chars); + void SetAllowedChars(LPCTSTR chars, int size); + virtual bool IsCharAllowed(TCHAR nChar); +}; + +class RelIntegerFormat : public BaseFormat +{ +public: + RelIntegerFormat(); + virtual ~RelIntegerFormat(); +}; + +class CSpecialEdit : public CEdit +{ + IFormat *m_formatter; + bool IsClipboardOK(); + bool IsCharAllowed(TCHAR nChar); + +public: + CSpecialEdit(); + virtual ~CSpecialEdit(); + void SetFormatter(IFormat *formatter); + +protected: + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CSpecialEdit) + virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam); + //}}AFX_VIRTUAL + + //{{AFX_MSG(CSpecialEdit) + afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() +}; diff --git a/host/TabProgram.cpp b/host/TabProgram.cpp index 155f2ce..6f3775c 100644 --- a/host/TabProgram.cpp +++ b/host/TabProgram.cpp @@ -5,6 +5,7 @@ #include "TargetDlg.h" #include "TabProgram.h" #include "dxwndhost.h" +#include "specialedit.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -33,8 +34,11 @@ CTabProgram::CTabProgram(CWnd* pParent /*=NULL*/) void CTabProgram::DoDataExchange(CDataExchange* pDX) { + CString sPosX, sPosY; CDialog::DoDataExchange(pDX); CTargetDlg *cTarget = ((CTargetDlg *)(this->GetParent()->GetParent())); + sPosX.Format("%d", cTarget->m_PosX); + sPosY.Format("%d", cTarget->m_PosY); DDX_Radio(pDX, IDC_COORDINATES, cTarget->m_Coordinates); DDX_Control(pDX, IDC_FILE, cTarget->m_File); DDX_Control(pDX, IDC_LAUNCH, cTarget->m_Launch); @@ -50,10 +54,14 @@ void CTabProgram::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_SAVELOAD, cTarget->m_SaveLoad); DDX_Check(pDX, IDC_KEEPASPECTRATIO, cTarget->m_KeepAspectRatio); DDX_Check(pDX, IDC_NOBANNER, cTarget->m_NoBanner); - DDX_Text(pDX, IDC_POSX, cTarget->m_PosX); - DDX_Text(pDX, IDC_POSY, cTarget->m_PosY); + //DDX_Text(pDX, IDC_POSX, cTarget->m_PosX); + //DDX_Text(pDX, IDC_POSY, cTarget->m_PosY); + DDX_Text(pDX, IDC_POSX, sPosX); + DDX_Text(pDX, IDC_POSY, sPosY); DDX_Text(pDX, IDC_SIZX, cTarget->m_SizX); DDX_Text(pDX, IDC_SIZY, cTarget->m_SizY); + cTarget->m_PosX = atoi(sPosX); + cTarget->m_PosY = atoi(sPosY); } BEGIN_MESSAGE_MAP(CTabProgram, CDialog) @@ -147,6 +155,7 @@ BOOL CTabProgram::OnInitDialog() HINSTANCE Hinst; HICON Icon, PrevIcon; CStatic *IconBox; + IFormat *m_pRelIntegerFormat = new(RelIntegerFormat); CDialog::OnInitDialog(); CTargetDlg *cTarget = ((CTargetDlg *)(this->GetParent()->GetParent())); @@ -159,5 +168,11 @@ BOOL CTabProgram::OnInitDialog() IconBox->SetIcon(::LoadIcon(NULL, IDI_ERROR)); ::FreeLibrary(Hinst); if(PrevIcon) ::DestroyIcon(PrevIcon); + + m_EditPosX.SubclassDlgItem(IDC_POSX, this); + m_EditPosY.SubclassDlgItem(IDC_POSY, this); + m_EditPosX.SetFormatter(m_pRelIntegerFormat); + m_EditPosY.SetFormatter(m_pRelIntegerFormat); return TRUE; } + diff --git a/host/TabProgram.h b/host/TabProgram.h index 098eb4c..efcedb3 100644 --- a/host/TabProgram.h +++ b/host/TabProgram.h @@ -7,6 +7,8 @@ // TabProgram.h : header file // #include "resource.h" +#include "afxwin.h" +#include "specialedit.h" ///////////////////////////////////////////////////////////////////////////// // CTabProgram dialog @@ -40,6 +42,9 @@ protected: DECLARE_MESSAGE_MAP() public: BOOL OnInitDialog(); +protected: + CSpecialEdit m_EditPosX; + CSpecialEdit m_EditPosY; }; //{{AFX_INSERT_LOCATION}} diff --git a/host/TargetDlg.h b/host/TargetDlg.h index cfa8e60..3fcd66e 100644 --- a/host/TargetDlg.h +++ b/host/TargetDlg.h @@ -7,6 +7,7 @@ // TargetDlg.h : Header file // #include "dxTabCtrl.h" +#include "SpecialEdit.h" ///////////////////////////////////////////////////////////////////////////// // CTargetDlg Dialog diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps index 8c42425..3ca5037 100644 Binary files a/host/dxwndhost.aps and b/host/dxwndhost.aps differ diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc index 781b00d..08655db 100644 Binary files a/host/dxwndhost.rc and b/host/dxwndhost.rc differ diff --git a/host/dxwndhost.vs2008.suo b/host/dxwndhost.vs2008.suo index 31481db..bad4f18 100644 Binary files a/host/dxwndhost.vs2008.suo and b/host/dxwndhost.vs2008.suo differ diff --git a/host/dxwndhost.vs2008.vcproj b/host/dxwndhost.vs2008.vcproj index 3e9fe2f..3489566 100644 --- a/host/dxwndhost.vs2008.vcproj +++ b/host/dxwndhost.vs2008.vcproj @@ -381,6 +381,10 @@ RelativePath=".\ShimsDialog.cpp" > + + @@ -536,6 +540,10 @@ RelativePath=".\Resource.h" > + + diff --git a/host/resource b/host/resource index 73902db..b224b14 100644 Binary files a/host/resource and b/host/resource differ