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