From b411ad17ffaca049b4520ca18927f3cc82fa26fa Mon Sep 17 00:00:00 2001 From: gho tik Date: Sun, 24 Apr 2016 12:45:47 -0400 Subject: [PATCH] v2_03_65_src Former-commit-id: 88c8490ef419733cac9523f4d1169c87a79dd60c --- build/dxwnd.dll | 4 +- build/dxwnd.exe | 4 +- build/dxwnd.ini | 97 +++++++++++++++++++ build/readme-relnotes.txt | 6 +- dll/ddraw.cpp | 17 +++- dll/dxhook.cpp | 36 +++++-- dll/dxwcore.hpp | 1 + dll/dxwnd.cpp | 2 +- dll/dxwnd.vs2008.suo | Bin 508416 -> 540672 bytes dll/dxwnd.vs2008.vcproj | 6 +- dll/toggle_fs.cpp | 169 ++++++++++++++++++++++++++++++++ dll/winproc.cpp | 125 +----------------------- host/SpecialEdit.cpp | 182 +++++++++++++++++++++++++++++++++++ host/SpecialEdit.h | 52 ++++++++++ host/TabProgram.cpp | 19 +++- host/TabProgram.h | 5 + host/TargetDlg.h | 1 + host/dxwndhost.aps | Bin 166748 -> 167432 bytes host/dxwndhost.rc | Bin 113498 -> 113446 bytes host/dxwndhost.vs2008.suo | Bin 152576 -> 183296 bytes host/dxwndhost.vs2008.vcproj | 8 ++ host/resource | Bin 40028 -> 40028 bytes 22 files changed, 594 insertions(+), 140 deletions(-) create mode 100644 build/dxwnd.ini create mode 100644 dll/toggle_fs.cpp create mode 100644 host/SpecialEdit.cpp create mode 100644 host/SpecialEdit.h 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 a2070cb42507da894dc9d98e65e476c7e935b2da..12942a421d41d66e5edd2f857e1865efe6795986 100644 GIT binary patch delta 23922 zcmc)S37k#!|3C0^?zzhtV~jDzWF2OVow09Y8oM+YqGYMDRbL@n2)QGYkeI9a6wzoI z$r|Oh2`y5o(E3$hP1=zpB!%Dmb?)o({(pbVzyJUL{XYJuKJ$6q=Y603+;h)e+=6*E z3kqs2ZB(g@Wm&c~cSx`-kA$>kof>*AuVsbpBzvj7)ic%;zva-P%-q!nY)9_TX&jp2 zeJ7@;jCV48Gp2`K#`eopqN9eU#P$un?rj!29oyG$`{bTLXjx&y(3G-$LtQF$+!}YzaUHZ8ki9lO)EMI(I)cB^g6CVySqZ)Eo@vCNFZK*qM>qIoxa zPsz^MR_|=D#PY4Io2|*#Bx|HK)EZ@t57{Hyn8RsKdiaYNdtZ#*DZH+NeS;@BN2YL( zw7JseNxN6td};SdTOjRzX$z$-lD1gdMcGG7q<>Iap)~9=3?a$e)NR7S6C7Pu*oD@?W=frp#+9rFAogY3@&8cCV?q7IQOiFvZXGxar3Fo)B zi|wLpJHI5y_J{McaqBy$ipkyYO)^co+s#XQ+8*;-2fImlNq2jaZ8r4{_>I4pJ$QSr z-N^67+)ZYGdqD!ymUvk!X*bLAg!lHhm-h62fjD%f-Lj|Yoabbk*UtKDn_V@XxbTUu z?ZhFTjqzd6)t-xa;rw3q65H+*nv-42Ze=FE@2PGQvb_nu#&Q@94h>JPUi70~BV41< zbEK@D8Maq@)@ItbnF=p^YMIB&J4t5$V;*m%JFT(S6zgx+IO`5;y!2C~pJaBg@KrNk ze(R)};x_(z;gj!s9`}?S^rV`?1D^4wpqJg=>>n0L3HLwc$+1nr$DY)1>S<4DWmEX8 z++TdH-N@{J&gTth#yKPGl6c2s3d=d;O=h<3HM?&2RWUg?JIUde3C>Nn+4`L$V<$SL zWlUiOr~hAG#MPdvc3tyT1*fJdKH#Zhs#J5v*kiFZuB=|G|8n)@QG(UHRsI`mjh4sG zE%NATB9ER4@}Ffja3>lnt>`a{2i6EFnPLq$wPJmZLkoXTG`*I3ZZWmLb!uOk&wsNS zn=SQR<*8$vytn-6ChuB1E_`^Yr?zbdulB@;<7+sDzLE^byS6yZ@oaD8fbt*`MfKJ9m=l_qAQgWDE^dF)1hfIfY|oYt3>>TbSZHPQKY6OsdtRA!wzoj`_%OtL zZ)r1A*xt@Ihp+b5#w2>0h3kBY;lVd~yW3{O898ugeeO#tTIKVa;%qxHoV(onTn95L z+fFvAHJxO$?`CgHQ+&`{&7|(|#K?MhlfrEay?brbeyJxRoUq@!)HVlya8kl4A9;VM zzqa^**Hcv4m->9FuQXs1Q$4Lid(S1C;~#pHP4O6CFZ1g6PE2^fMehb#>-yddv$T64 zIh+;a8)cisI!zDXu2%eVd3K~@*5y&Pl%<**tpr{&3#Z?$fdLvEb`Hq@hk9kr|ULD74sy*j>p=bvt_l2+Yn#le;{+ut#Hn|^q zl1=g<->ci}`S;hcyP6Mr`?JG~->&+ z?T{R1D+>I#I7J)$^G*L3J)2CyC!X2iM$h`!m#crbEJ(BFEm~SuCF}AN_Hq4$oh7Ge z%UW8p(;qON22P@xaKIDiK6QjQZ15klx9|1mq?O6ETFB|6wdG#<;QAuY{Lm$kQZzr% zIH|XsYA4H%?=C&gL6fcQp6;pn%CaVTpWb`4IFwg?lIfo&C!5l11M%T4$NhN$b7a3K zGrWD1JgJ!COI|t0@9`h8&CqY;ftzsJKXv;#|CF-9Qn@_%TAEj`NA`>6ECq#c*`leBZvewKDp+Aq?6m4@+7OMgb%S!usX`%&8O(s17&(*G&# zf@77lE=ss0&6Wk&?hSNF@!RF(_^pP^qwth!fsd-#o=9#J$c+nSdi`eaP$w(w=^D7` z!!ur!@N=jAxsEBwb8<{hufQO6e!R-e&+{jFn#kjPkH39*f3JW%5y=@R)sYPzzSK9c zyX;>-M_)e87S>8N`9lMx|LIA{=RT2`THiX?nl1Icv1UShIh&Ub3*;x2|1X|At5)oM zuxK?764@x1(900&_v2ExErlC#tV zIZVe}*|K9}O{Y9(a@pwVt%=MxD9=$9?y#o0=entK&^NI%txl%Xlq{&1k6ynAGf{m6+i zB`5qX!>_FkWP42WK7o32`f;EBQ!{+ACcC~j!M%t#OVgah@J+da`F5d6HK`i{^+J2& z8<{B^0(mhVpea*V`Jc&$hCfs>%NWR)5E`S47?R@ zK0DzbAM7m~E`XOxGK`X5CgHZ*CAW|~meyYKXx2?rbqgd9ko)eZ)sQ@$b<1g4Vh_!!bBR_J6>`SFPyuHS>3c~_q_w8a5Nkv0NE5QMX;;%~i{%7~*ATH0 z`$}#keLotOuD@jTLul9my(D88L#rwIcG}%EOlLOjVH(DHgce*u#EeTMcaeS*4Kv&< zSze-AZ_+AAUMU&F$FvN|=Ov@wk@G3GOciOLu&x0Ob$unHZcxO67B+*tqIZWoS%@1` zCF2mCL2Dv;ChO+Wnu*;@TSmifDx|HTrHd6yo-6$tT0_Yzy+Qda!xkd)vyw4vrD1K} zkqmy1R#x(NlCjl(py6mllDkXahX%h_@^I-F28mdjZJ2`$D`}~c zAC-)ugoX$ATH3p+?o-Lv%6*^FkoU3fJguGBAGCnH%Yg-{*FpZo$PEnTiCCBfS|#am zPBKl(2O5~f8V+9qxKDBOP4@zS4O9BKT$L?&!cH|snpY?cN_&+}BVg3IVXT862(vvG}YbSQS^wE=^yZv7yrpX9uQD z!C?_Ef67UpAU$s5V361Hi~Gr24fzRyw&uunaypDTDsL!c?Fh_Un=&d8YnE4tyf-87 z=E<85-lY>49m9z!JS#TvXaH|&U$V_5C*TWLn-%z`jLACZk1>PJ`4hsYy@6ai*t}9? zUNS4Ig=7q^Xt-)?ExD8QZIrd8wNuuf)`51tjFTmKmh>H!WlP486S1I$?bL}lkcHSU z*V9JOmWYj{O`ze$>qOe!w8dhxX^UuBn8mb}${wxcJ_6-ESmNKLa03fpRko9MfOeDA z9i$yocAWMH4SVsDblx4zvZ5vuIsu zqr|#N?kRnDWj$y;X+acTBR4QyOPnY8s0qIM3qP%#}Y_BV2&@pm+xxvd8q+NyY*^ zL#riuJ#B-sjUL(mDBMKE)y!rVZlMWTVaYO2>qS~U$!|%%PWrtxe7YpBSKO=7x0T`P z71KRP!xh8dC8PcyK~?x63%^uWO8ZXP_p}op<&9!%4EcN!177`LdIM;f-eB6zj_iLF zVx(p)7_JIOvyextyD;Nu(^!XvnJyU%a~BN@g98}Tokf#q&5?|SnNM?HFDxc5i=q@P zrx{uuv60Nts|_LRQ8D@7eW?{)<8`$4tVi8*wCyx`yTN)vaxh22i>h!33*VyQ`SV@L z81M!fW`gTlype{pp!=Se^jKqT9y}r{OOHCdSlr8TuToZ1vK(GkmRI(Fbb=iP^92X8 z5EHy!@<8dw(=fqmk}*tBhSzqO;KMX5;3JZUO8-0!)7vf??U*UZi1ymn38Ds>_tH(3oHi`O`=Gnlvonr&8BX`Yf76tFvTmh_1Bel6y+V{H*~* z%w(WsY}TPP)C`k9nDHnYX3`CJ$Z!h{d5mPtWGoFcnZUZ)G|U695wU;^qz^{d3WV|wch$hi`STd%!f`;j>l8j*=4byv1@(^tQGek`A ztYmDO8uB3J5?Zw+V}fZkOfUlvVi|_eFu|dcvFq-qVR{QC_mzG#4O?{uw?Y_({g2@# zxq+GBBYeyl6Fe^&3)3(rVwhkf$vvbWMw4g_myB^o(lG8M$vFC_(J=0G$(Y{VG%QST zl-$4&BqGn1j0xULYa{u7)`e)8$#Tgm zo`|+e#zeL&dx5rthG)AC%x|$5vfh@Ag?^WY=^d1e>3yQ?Q`+aQ$@a&Z9F`m7r2kSC ze!;>c%D$r=Rd#}QiiYcneavUr3t7KO#sdDX>;g7B@S;Ln79HkDA3X^Dv>0V&Y2}n9 z&=Qs5doP$?Wo1=q!RiWAiM5s0q19E^fYwM^Q(7}+EorTlwWD>2SmgYlEjQ$>Y2~QG zE-dV(tS7CPvRqmpWqGvz$_CPIP&T-X?0;;Up$czi;c!~2+&_YOjH(;Uy79^;(k3gL zN}H~1Chcxqe?|9k0r4JX_tNfDwve`1*@LuY%9hhsC|gB)jOLzyo*+IUM=yp_F> z^*rms%3h+qqHHH^x3V{Adz8IhMjrpz{O>A!pN0FCeMtLQ*&*67WhW$GkXI`nIhf+5 z`K9@!;nTW+^fA)PNQ;$LR$83bG+AN$J?9<`Xf0x8lSF6In%GViX3?%z)`iwxSua|yvc9zb$_CPI zyliqv3?<%l8Rc1qHd@(jw6V(WpiNdbl{Q`3OxoSb3Sc-S=PI1f!uypirWGoCh-Q?n zq^(xAhW3QA654v{-Af`_25S>>n=0H+dr8?2+HPfgXnU3Iqa9H85$*FU7PJl%k6c0P zTgiB%?mJ~iS$9&|ue7tu&eJX^v&u#eV88Uy<1OAb+5QO%uVP_MWsPV}l{KfeQr4E% zL0L8}M_CtIH<)`$k~Qr~?4=6((E2GGKpU)V7;S{I(X=tj#?dA!D>H@ozkJ!O;63?X zT+$0pN)T_|;5B@@G`!=Ft(PV(Q5r5zDoTUlT@l>IeK@1S8cVAs4If3qVYooSwB*v$ zswWMG0aw;|4boN`td%tR04wNz6oz-rq9bQX#soUjDoc;gW-!5Q8WygTv}>ewrAg;r zOX55RkIopEZ?OI}T*6%^4Z~=e|K-Bl1n}x-ytL@Z3nXLYg*319%cRM*tQDeRjh0KR zC9Q~t1$<0eXK7E;AK)G9!0)mAkt~?mi(4IjJV^ZsvY=>&It}k9UFDnWkpYsT0#pM!>sY_ypbm zfJ||Ld@I+TVvEQWdq_c|`z6`Ua!l;9&BT~MFZ0IkK$ad3t8bBo#uj=R z3oi}BtI}Y*O|xgcRfBaT9*~AZ?Vz-1+2@i`_9YGP(UmfP$6h+?s5I35Bn{)D?gaB` z_R?9uOGDis(ol!P?;;Md-V!b;#JzdAEjIaJ{#>|dPzWC zE-gjoZ}sMlJoYFYz{2ZkSi2#Tv357p@V)FCnDf~SStBH4CZlK=cZ_6=JD!FwEsU0o z@3dNX5G7iZC1d0}X_=Cz(q@{8TfG&7b9fi_%stFcvlp^9uza(s+rs>kKohHY^chYavHg~+gT z%8+5dD?^5zSB4DxLm4vcPi4rk3%F>I|J|){fp}3FG72v#Lx$ljFVP(r8D=X(hIy1B z!yH-=`w2IIUR8(;^C?4y`IRBV@J*lS!XU$9lp({)D3cs?F;*cm3d<@(hQ%pEhLux> z42xHW3@fh;8J2+e@uN$fK&+q&kx`ha3>j8Y88R$M88WPrGGthC)Nsnc4PfOcGQ(1o zA;Ydxh77Bs3>j8c88WPzGUOnzxcVd>ca*!(Dz z8!pySg~%w(py4ESTt>h+b!j+&8?mmjGGvU~L>V%y>1C7cj~l?u%NWV9X3CIZ&6Od; zS|~$?wWQ%hgA8k>3^{=P-&!Fu3fm|{hP73O3~Q$h8P;AIGOPm)TMHSMB|XkR?g<1p zfE`sKGAvseGVE$)$gmt`$gobzkYSy#SkS!z>~aO&4C|^48P-i1GOW8YWLOVn$grNu zkOR0Xy+$E23VSI-hFz-+8J4RI8P;1FGOUj>WLRGq_CNLsZUFOCAu_C=GGthPWyrAW zlp(_gC_{z~R2IYy;PncTVK*p4h7D4N47*VoGHkFiWY`d8$YMcjs6u2E4pW8}DFyAIPwLWyrAM%8+3rT$AmOk#Pe!QWYY@M$>TeX~297d+fT~SvOW0GR7UJ3>h|F z+4vyw4u!}loS+ODHc=TeY?3l$*kl?`KFF{s%8+5fI~5`Wrz%5+O;d&po30EQc9$|_ z*bExB7BXyR#3I*!xB;A{3Xx%VD?^6OR)!42mW-avqFc2<88YhTD4T=lf8ad|kzsR{ zA;ab=Lx$a}3>h|G88YlXWyr7vdZ`x>?^lJ$C|sxv8Ma6nGHkIjWY`1BkYP(`?)4vT z03TF^$gri#kYUS|A;SulA;Ut-kYUS}Nse6qJ){sBg+|tfdut$_3!&WFm zhON}se=CWPszPKGu2O~!TTR3H0~z+1GGth>GGy4AsNwvN8^Fh-$P9Z@Y`S`rX%^pO znyqXOZLYHUv<1o*(H>A1TuLk?;vrN-TdfM$(4JEEG;O`IjkIT#Jx2>GdnsZ;Ylp&J zEPPGbo3yu-y+hll>;u{XWgpQ#QTBJ*=dLBl>dJ7KSX$PM8RshsmWhkJa4su7wg`rJ zT7t5Qv`WfSXjPO|r`1$eo0hJuZp4CCeT9u!*i>0_T1#bZXzi3`(Xy3wqIIER1$)r? zx`v}thW^BXEQAfB4OWJKnvJ&^hASIIyH(j3+BjtsXp@xP86-|qIDHJBT|~;cK)# z%HF2Euj~NrQ)P!}KPWp!`$^f!IGI28=V^t%vGAfYyIiEskv{q;3D6RhRivdTt4gb- zES*+AsIU>Sxw2NYw#quta+GzUU85|Q)=$|0+F+Wy{f86BsKRlyiOQzXrYgIOHdEPb zT7j~;w0o5;C@0T~*!+tWE@9y^Wy@(s*$Ub!WyQ27l$FrdDceBXTyE5r{kfI+yefQw z_KLEdwAYpGp}nnaAMJy3X7F5JM(}fW-(lYOm9lSW-zz&x`$^eJ+ONva(#|RSgLWZe zJk!a0@Yv!W>7xg-j}}l?mR3$#0xeNlGA%_}Ra%;|y77FZ)mPYvg-w(-qqR`hn$}iX zHm$p|YiNCx^`l)ERCqmcn6iA@C}p?OZdW#*HbL2B+EitC(Pq-z?LV7XpbF>G?p1a_ z?FnTiv~|ih(snC*gSJQ6+wpv)y{qtj7VcN}A?;&jpV1B}`v>hyWk+bol%1gcg8d&o z;7${NQ-$Yg7nI?{LmaG*^wDtxv;<`pY01j2qE(9;wtr1x?I?=Xq198?kk(jPCat-$ zR$w*mEA}istmsw;#lVJeZJbk+j;+Zb^k=# z6lK$BcPYD@cCWGpw1vtZpgpLpFk(S#xkAIj70Oo89#i%>?MY?$H@Mhv&nUyczlCj8 z_B<`@n)_IjuM84jQH48cyOq5`+oSAl+Pli|k6$t4{mMS1eWL78kcgj{i5|H4i5ZOi zow6Tk$CUj{yQIt`7w;I?D}8i&0a_VlakOB(!V1KS$|}=pDodj^R+dR?rK}wdpEE}n zrW>tC#3I|j7qPc0%%k;JHjs9MvLUo#%JOL=l#Qm{rtJ0vnLjqyc!d*LI7Qhs8vdzy zbWQM2%`q;15GiW-F(lYBWy@*!8K!6*K2S&9DoiAb@=Hf9KA{Xha)d(sz)`dgKX3%Y zj~hh|KW+qjUfBz@mzBLr+f8$~{~N@&RN*_c_mu6YeW>gc+TWFZK|8GME7~{8zE7}j zaF_Z=g~wU=v$9jPGs@1<{!n(2=BZ%bU*c;XtXLtkRVqs#-BML(HI&t&r7NpTYpAR# zt+}#RwCj}(j#$tduW%v@XDKU?+(&lXJY|b%OO-8`jNNOLt)Q(^R!m#(8c%MUi7%?c z9kiXwUZ=gOY%lE{W$)1rDEpZ9rLrSI;mxP~j}1wtHyzs=5WV zg~}eFJ*X^1TcK1XWD^E+TDC-{`xe_r&6;`FCDa)YM zQ`V5ySXm~mxw6)@?5JV;cOrI)qF8rYPi5EAu2XhBZIH4dw2{hgq1~oztYr7w$5Rwe zW8q!OX3^#;yN`Civc7jalx5R$ly#wXQ`VE#OIdGP-zyfh z`V$9UL2D3gh_ah#!(J45?T*?HQZ$}Z7t`DSbM;pvr(hit$# zZvR+foGL6&tDr22R#{mUT6JZqv9eqzzGa6D?mEek%bBc#E>#*?Y7Pl;Ia6uyP+O`;7KE&E5Wo ziKVLWYub0pexyZzfQ2*sQ+A$qQJJ00>pw@nF&^Cte#uzsGRop;<&`DU zl9Z*;swk^YOI4Oe%Se{>kIuLOv5_ilN^7PJzng&tjQ&OjwnBRveitJ;y{l=RmEkus zFmCksFl7BBzk>nntqS|G@H%DJ)9@P^(U}aP4O5m+8=-78?N()DB)ivtV-?=P!imbJ z(55Q8i#Ai)Y+8Y`xwQGp7SWa@%g?c3P2{rPdPq>dwO|#oFjjI?Y1-1{_9JpX{+-K; PWV7ohPhKdmO!9vKIO3tP delta 2576 zcmai0dr(x@8NcVfEbFqY3sPLk@>*7;bVYnraJ{0SRYZnKt)&KckYH= zeCOQX_dDPD9yb)q4()!Ty(rD1X&O=^@i;UMDrVm71FBp5bIl@P5tsr+qs< zhK<&g?WokqcFZtzhf9r$a;%|o>L!-?Tzj+B`InJ{ zo@eL$i;jQ#A<8oj%yW!wF^1-C_I(?l#8yok9c@yy$9V;hOlFTME;($$x2M(!wlWD|sLV2|_+i4JnncI!FV8oC1~yj=RJSx|=v*aEg+gQ;0%vlA$En($3uQ&`s8X{t9Z4JLjS- zB!eCjWwAm9G;kC8@g8Qoj0VEu@!>@6bt3TVnDA<(Z1J2c*8 z#blkf*%;lBEj?{yXhv7?BZ6aRNr?>JAyERJGGu{Tm8a6?qr(U)jH;6{0cOL|A>O$4>)aS8Yr6KeE7OowWVB3C+uv0p{>>i3_D|}lydlD86P+jUa7XO+I zma`&crkD@zSE(qk%@UbVv7YUV`IyTHUv$Ck^{f}-bNFhgYiBoO0agS%Q%SmUHQfa( zJJ=h*ubJ_7kl9geqdKS4Mv6=?aMPY#e~9%ViNkC}s2HCJm;Ow0VIYV2!7)=fVgC`f zF%fW({R1-f{Fru0XmlpD{R`L{N)L88;YDa;cl^^Z*>*z;JDYv2l8QX zIWNXj277DxJH;G5QhDebGd0}CZ3J$6)s3&*#WPikp%|M9%^R3oI!^HQB>Xdlwwqtf z8>?kcSBfdIfXku zAoM%DT^60;Z%*)OTAFGlYzQ;`Nbl7%`XUO8EqMGzRl4 zKsGt_lnA;euhp8>t7&V3SBFebD-Vp0&yf89Pln4~%nE~lz>j3xRfLb?h@6Q-)ci-Ez)l(T|MUBzNQ# z%Yv-9$TxqS*mVU^KaLs~xg6=rV#S!n-+yJ%b4lcxtk_L+zxqL2Z1`2c^w})s{{}SE BMHc`7 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 8c42425ea16552a16b71e00c89579b119e721c61..3ca5037b9215c8f3f7fd6205f2593511b757de48 100644 GIT binary patch delta 4081 zcmbVN3s6*57(V}5SQb!xu&B!t?-eSPmm;C24k%DoXf{%zV4^%$SXdU=EE5a`17-Cj zheQz{88tn$Z3ZVTZE{9taz;~gtTC0wQD>S-hoLfiZ2!5-wWXb$Gr?T${lD+~pXa}q z%N+qNy8;}Mkg+W)W@hQ@loV$aWZ9Qi78lf|6egt>rcEz=X_ak7L8+z2HnpO5jjgQ0 zQdwrRSPP2n^_9g6Y+XsnVatkgYD{J4$`{1Rxr8~B&3{r!vDukj`4C8oH?wt?bCTMF z?Az^=+19F)lKRh>x%#H0_B=CN^W){Fag{JvTL>Gpnk0kYWJxvslG=ODakhtKM;-0V zuFI7jb-MH2`tM~UmpJ#VeUDC;8_0IZ&B`o%cFDXYxtYY}VsKpVY+9Eho9n3a%=#SJ zE-pBe8b727a)l8ZE9$w{9g_b4-W4rn4K?Y`nx+?Jn@M!u+;mm8nMKa4Ejwk!7PkG3 znUY&n&u&O-*Rzb)`I2#)S!ZjOq_&;?+|pg<<0Q2mtWR3Y*{@qCOUCVFY3;J#t+$x1-8AXH zCc*~V4eVIE@xKKT4g#=uxJS?G*2*5> zLFXgedIO+`ebbehIGq%dm&ht&BP&P&DJ2$CgU?e*1*s)#@Tm-+ETj_eHoRM%kM5f7 z3+Gwc-Wb^7+_Jac6e_-&i*qw`=4a(DNl7NjDKnA?1p>sM#hjYQ;9;Xr3L(U~^3=fm zzRc0^SP-=Ebw-%Y)2vY57a0Zxlb@Q;oTSjnSJlEhrdSN% za{1!bDPoaM%$0N>+o@pvJh={nXWtz`btzQ5##6pq!SY97-3r#i8%2mCBdEO!b!!B+ zPr)W(JO5O%U%_(t*CK>{1T_r=*E<4BQ?N@Tuo()b<5Bex9Fp$q8T~PZD&@KL@MH5_ zJM_)9(;gjU@PP&z2M4%+BaMMWd`csY&>B+-@iDWD<>A^Mbj#{y-*ts+PhkhT9=@}Y zhHKB82^reYKX0VbnpRR%hnF}553v6}-{HmUaPwlL zRDbTpU&lTd#;d%0Up$J@5nTWwc?rN@c^C{O%pRP>VLrt#eu<1D}?_MWQ z-iinKevZn!SId+C0prho3b^?R9NJtgHft$x%MvtBW8?#9oDoJSHsvS+esmd*^MIC+ z(gYDO%-qK#lU#iCa-*$JT4{oi5r)edwgu`09-`TvOBm zyo*7oFQ)6=!w(AV&OYFe_JDz36Uu~x{Dwe>J_eq6Xc*OylfY+w0fvrE)F-h2tVpd9 zC&zDZq#>FM1Gt-4-K^&9An?FD!_w0lIxN*G(!hSb3i!KyPnsxqMN=iR=0qChzo)v5 zz+>5}bd(~cNAmfCW*Y8y_id3sh(9wLKX?tzSkbXB6$H`E+|rB{Ik2Lyu3+^i1ifoe zrQ7&NNC$Q*Wd)&rs{&}=)Kh+D9Chn84y@@btjX=&mL}>D;%#p47Nsx&YCH4na}7~rDK(VL z!ozGci{x6oAV{38=K?K9`__HF+KXR+n^B7Y9Nhlny!Zg*&sI<#Xr_j2f*bKir79lp zB^Ix9m{sK`c=0bFf5A%mm?~=UyMhavS3`NLFg75QSBFLo8ZDS}2#rJ=HLPzyW|v)! mIp`HL17Go3FRT1JUVJz5o$FM-*NYFrWceFZ{@s7`K>h~n;v=*G delta 2994 zcmaJ?e@v8R9Dlyg!J%Yy$k{wNPL7|4vda{cQp*aGoS`*Lwn%c4@kZt#ig7y4=*QU1_fM!<3d&W{z0dmd&E)dG#ij_xP}PpZEEEzCWMm zd%P`OkyrLddJ-VRYfhRoyo-|J7YeiM*4T;*Yv&csonQ1^W|5<6ePKz3qq?xTZi}s0 zyjiQ(AK$sIO#9PZLXrvo+el4pO0S-6wd)KLdlILtEdPf}`>Luys$OMzjzv=S1{-pmm#TM_p6Ymc$7bc1+Seggc3umC^=zG? zl-8Z2QkxCHpvt7w*0;*jcooZze7Sr|>D!enKlg8x=?#PO0w#csI@6`~g;QQ%mQvaD zj=TV?@<;PEc>$}GyL%4GWg9!yD!-pvW^~Eb9c+gyM|yj^*)3PLRCTk}`^KexAEs=j zV+Lz*r$_@FV}AE*Qgsho)HYkH?q#mFG^yIket3*;2b<$bi+nhA%;+(&Mo+vn+ zlPXn_>AmtM53u*VDU*}E={2y=ym6DML!6@RancN(EW2Hvp^JIigED;BZeTYa6Rw+C zSh_UX5v7g|L~00eGIRHcH^Xc?F@arXST1nX3~vcsoCs?pCirR~1$fZ_G1HzU-;$~PPmp*z5fUHBYg8HU zB|_xP`wqEe($W#KD*;VOFbfiVFDAiu;NgA4$*@+upfMHN1rDWx6ZE(s4ZiSYSfFJ^ zL<ub>9bQs~F{I{4@f{te)zg!AWsnysH7#zXF)%3TiP7Jwkb_%T1U z>s0MBF?uV+EGZ6>x>czoi0e_gvq9WpmAixMM2O_D$ms-zE}95zekvV*wiRjwLg8~p0i)x($2d~`ebj&7$TTFAhCjWi89@Y6<`1ikou zBb}vwMemfUUs0`-d;itRQoBvK)Jel=?;&=p$D}=3PKfI;mN{u6Eq)T+PHLi_XdD!1 zi9x@>EIp11Jgvv5CXNNMXl3e>%iesy1tV*>4)FshlOaWh&4 zp5Kgl95pT*;4_uH2r*bQtI#dT(^Y^)H4q!l4|AXf{mt|h&8B+5i4Pz)bt)kz81MjG@+0mHIUK5E&$!dSx}^)iS~7ck|)r}5uGUqI)^d~X}JdY`Omxzu}K~ect(WuOaRf3D050k-8h}% zF+IH>d1eyDk5lOV$okBH=My14bvXf@H^A5b8=Uqw#hwBlSYKrB&!88&1@`iwC$0MHNU*wdH6gx|~XC&V^`KG>%#^GQq zeOhxiuv=S3r)y_${oY3WyOqwPnI&j-@u?mu!90PBOVK89xD?$2lgn{X;HpjN7ih1* uF@Y94M(yL+Z%3<&4$KpnTa7k><2C3O=&8j)fw#AzpQGmJPKqxzP{V)Jcf%q8 diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc index 781b00d4f1a9ff3c0439ff82d89f925efe88c269..08655db1dcf251359e8fc84f999e61ec0be50c8c 100644 GIT binary patch delta 50 zcmcchjcwUCwhb~&)0v7G7i~VkbR%H$gAkv|e}Wx=bWroMknPJt7>}ibrKbz*X7mC8 DU0W8F delta 65 zcmZ4XjqTPqwhb~&ldrHW*}RYGM!;mbw``Mn&Y4Zt3)Y+bBG?Mf|L3RCoENe^FNE<- Q>hxKg8JA4Ivy0IS0O3R(!2kdN diff --git a/host/dxwndhost.vs2008.suo b/host/dxwndhost.vs2008.suo index 31481db51237c0291d3f0b5ab72569ed08169d0e..bad4f18cc7acc2c7414e5ad48286d18b366e004e 100644 GIT binary patch delta 23336 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 + + @@ -536,6 +540,10 @@ RelativePath=".\Resource.h" > + + diff --git a/host/resource b/host/resource index 73902db56b57943c917790e64c18be394c6da4a3..b224b14daa831abf7816e8d11b17d3682a8df878 100644 GIT binary patch delta 21 dcmcb!gXzu=rVY1dPo7jNG5Ovsk;!ax!T^7~3a$VE delta 21 dcmcb!gXzu=rVY1dPyUoEG5Ovsk;!ax!T^Je3kCoH