Skip to content

Commit 75d08e0

Browse files
Merge pull request #418 from erepb/window
various window related fixes
2 parents e0f8a82 + d4cf3d9 commit 75d08e0

File tree

14 files changed

+249
-90
lines changed

14 files changed

+249
-90
lines changed

src/Layers/xrRender/HW.cpp

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ void CHW::DestroyDevice()
200200
}
201201

202202
extern void GetMonitorResolution(u32& horizontal, u32& vertical);
203-
203+
extern void GetMonitorPosition(int& x, int& y);
204204
void CHW::selectResolution(u32& dwWidth, u32& dwHeight, BOOL bWindowed)
205205
{
206206
fill_vid_mode_list(this);
@@ -216,12 +216,19 @@ void CHW::selectResolution(u32& dwWidth, u32& dwHeight, BOOL bWindowed)
216216
if (psCurrentVidMode[0] == 0 || psCurrentVidMode[1] == 0)
217217
GetMonitorResolution(psCurrentVidMode[0], psCurrentVidMode[1]);
218218

219-
if (bWindowed)
219+
if (g_screenmode == 0)
220+
{
221+
RECT clientRect;
222+
GetClientRect(Device.m_hWnd, &clientRect);
223+
dwWidth = clientRect.right;
224+
dwHeight = clientRect.bottom;
225+
}
226+
else if (g_screenmode == 1)
220227
{
221228
dwWidth = psCurrentVidMode[0];
222229
dwHeight = psCurrentVidMode[1];
223230
}
224-
else //check
231+
else
225232
{
226233
#ifndef _EDITOR
227234
string64 buff;
@@ -264,6 +271,17 @@ void CHW::CreateDevice(HWND m_hWnd, bool move_window)
264271
#endif
265272

266273
DevAdapter = D3DADAPTER_DEFAULT;
274+
{
275+
HMONITOR hWindowMonitor = MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTOPRIMARY);
276+
for (UINT Adapter = 0; Adapter < pD3D->GetAdapterCount(); Adapter++)
277+
{
278+
if (pD3D->GetAdapterMonitor(Adapter) == hWindowMonitor)
279+
{
280+
DevAdapter = Adapter;
281+
break;
282+
}
283+
}
284+
}
267285
DevT = Caps.bForceGPU_REF ? D3DDEVTYPE_REF : D3DDEVTYPE_HAL;
268286

269287
#ifndef MASTER_GOLD
@@ -591,15 +609,23 @@ void CHW::updateWindowProps(HWND m_hWnd)
591609
bWindowed = (g_screenmode != 2);
592610
#endif
593611

594-
u32 dwWindowStyle = 0;
595612
// Set window properties depending on what mode were in.
596613
if (bWindowed)
597614
{
598615
if (m_move_window)
599616
{
600-
dwWindowStyle = WS_BORDER | WS_VISIBLE;
601-
if (!strstr(Core.Params, "-no_dialog_header"))
602-
dwWindowStyle |= WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX;
617+
u32 dwWindowStyle = 0;
618+
if (g_screenmode == 1)
619+
{
620+
dwWindowStyle |= WS_POPUP;
621+
}
622+
else
623+
{
624+
dwWindowStyle |= WS_BORDER | WS_OVERLAPPEDWINDOW;
625+
if (!strstr(Core.Params, "-no_dialog_header"))
626+
dwWindowStyle |= WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX;
627+
}
628+
603629
SetWindowLong(m_hWnd, GWL_STYLE, dwWindowStyle);
604630
// When moving from fullscreen to windowed mode, it is important to
605631
// adjust the window size after recreating the device rather than
@@ -610,31 +636,37 @@ void CHW::updateWindowProps(HWND m_hWnd)
610636
// changed to 1024x768, because windows cannot be larger than the
611637
// desktop.
612638

639+
u32 monW, monH;
640+
GetMonitorResolution(monW, monH);
641+
int monX, monY;
642+
GetMonitorPosition(monX, monY);
643+
644+
LONG res_width = g_screenmode == 0 ? psCurrentVidMode[0] : monW;
645+
LONG res_height = g_screenmode == 0 ? psCurrentVidMode[1] : monH;
646+
613647
RECT m_rcWindowBounds;
614648
RECT DesktopRect;
615649

616650
GetClientRect(GetDesktopWindow(), &DesktopRect);
617651

618652
SetRect(&m_rcWindowBounds,
619-
(DesktopRect.right - DevPP.BackBufferWidth) / 2,
620-
(DesktopRect.bottom - DevPP.BackBufferHeight) / 2,
621-
(DesktopRect.right + DevPP.BackBufferWidth) / 2,
622-
(DesktopRect.bottom + DevPP.BackBufferHeight) / 2);
623-
624-
AdjustWindowRect(&m_rcWindowBounds, dwWindowStyle, FALSE);
653+
(LONG(monW) - res_width) / 2,
654+
(LONG(monH) - res_height) / 2,
655+
(monW + res_width) / 2,
656+
(monH + res_height) / 2);
625657

626658
SetWindowPos(m_hWnd,
627659
HWND_NOTOPMOST,
628-
m_rcWindowBounds.left,
629-
m_rcWindowBounds.top,
660+
monX + m_rcWindowBounds.left,
661+
monY + m_rcWindowBounds.top,
630662
(m_rcWindowBounds.right - m_rcWindowBounds.left),
631663
(m_rcWindowBounds.bottom - m_rcWindowBounds.top),
632664
SWP_SHOWWINDOW | SWP_NOCOPYBITS | SWP_DRAWFRAME);
633665
}
634666
}
635667
else
636668
{
637-
SetWindowLong(m_hWnd, GWL_STYLE, dwWindowStyle = (WS_POPUP | WS_VISIBLE));
669+
SetWindowLong(m_hWnd, GWL_STYLE, WS_POPUP | WS_VISIBLE);
638670
SetWindowLong(m_hWnd, GWL_EXSTYLE, WS_EX_TOPMOST);
639671
}
640672

src/Layers/xrRenderDX10/dx10HW.cpp

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,12 @@ void CHW::Reset(HWND hwnd)
694694
cd.Windowed = bWindowed;
695695
#endif
696696

697+
if (!bWindowed)
698+
{
699+
ShowWindow(hwnd, SW_SHOWNORMAL);
700+
SetForegroundWindow(hwnd);
701+
}
702+
697703
m_pSwapChain->SetFullscreenState(!bWindowed, NULL);
698704

699705
#if defined(USE_DX11)
@@ -841,6 +847,7 @@ D3DFORMAT CHW::selectDepthStencil(D3DFORMAT fTarget)
841847
}
842848

843849
extern void GetMonitorResolution(u32& horizontal, u32& vertical);
850+
extern void GetMonitorPosition(int& x, int& y);
844851

845852
void CHW::selectResolution(u32& dwWidth, u32& dwHeight, BOOL bWindowed)
846853
{
@@ -849,12 +856,19 @@ void CHW::selectResolution(u32& dwWidth, u32& dwHeight, BOOL bWindowed)
849856
if (psCurrentVidMode[0] == 0 || psCurrentVidMode[1] == 0)
850857
GetMonitorResolution(psCurrentVidMode[0], psCurrentVidMode[1]);
851858

852-
if (bWindowed)
859+
if (g_screenmode == 0)
860+
{
861+
RECT clientRect;
862+
GetClientRect(Device.m_hWnd, &clientRect);
863+
dwWidth = clientRect.right;
864+
dwHeight = clientRect.bottom;
865+
}
866+
else if (g_screenmode == 1)
853867
{
854868
dwWidth = psCurrentVidMode[0];
855-
dwHeight = psCurrentVidMode[1];
869+
dwHeight = psCurrentVidMode[1];
856870
}
857-
else //check
871+
else
858872
{
859873
string64 buff;
860874
xr_sprintf(buff, sizeof(buff), "%dx%d", psCurrentVidMode[0], psCurrentVidMode[1]);
@@ -1082,15 +1096,23 @@ void CHW::updateWindowProps(HWND m_hWnd)
10821096
// BOOL bWindowed = strstr(Core.Params,"-dedicated") ? TRUE : !psDeviceFlags.is (rsFullscreen);
10831097
BOOL bWindowed = (g_screenmode != 2);
10841098

1085-
u32 dwWindowStyle = 0;
10861099
// Set window properties depending on what mode were in.
10871100
if (bWindowed)
10881101
{
10891102
if (m_move_window)
10901103
{
1091-
dwWindowStyle = WS_BORDER | WS_VISIBLE;
1092-
if (!strstr(Core.Params, "-no_dialog_header"))
1093-
dwWindowStyle |= WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX;
1104+
u32 dwWindowStyle = 0;
1105+
if (g_screenmode == 1)
1106+
{
1107+
dwWindowStyle |= WS_POPUP;
1108+
}
1109+
else
1110+
{
1111+
dwWindowStyle |= WS_BORDER | WS_OVERLAPPEDWINDOW;
1112+
if (!strstr(Core.Params, "-no_dialog_header"))
1113+
dwWindowStyle |= WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX;
1114+
}
1115+
10941116
SetWindowLong(m_hWnd, GWL_STYLE, dwWindowStyle);
10951117
// When moving from fullscreen to windowed mode, it is important to
10961118
// adjust the window size after recreating the device rather than
@@ -1101,39 +1123,39 @@ void CHW::updateWindowProps(HWND m_hWnd)
11011123
// changed to 1024x768, because windows cannot be larger than the
11021124
// desktop.
11031125

1104-
RECT m_rcWindowBounds;
1105-
RECT DesktopRect;
1126+
u32 monW, monH;
1127+
GetMonitorResolution(monW, monH);
1128+
int monX, monY;
1129+
GetMonitorPosition(monX, monY);
11061130

1107-
GetClientRect(GetDesktopWindow(), &DesktopRect);
1131+
if (psCurrentVidMode[0] == 0 || psCurrentVidMode[1] == 0)
1132+
GetMonitorResolution(psCurrentVidMode[0], psCurrentVidMode[1]);
1133+
LONG res_width = g_screenmode == 0 ? psCurrentVidMode[0] : monW;
1134+
LONG res_height = g_screenmode == 0 ? psCurrentVidMode[1] : monH;
11081135

1109-
#if defined(USE_DX11)
1110-
UINT res_width = m_ChainDesc.Width;
1111-
UINT res_height = m_ChainDesc.Height;
1112-
#elif defined(USE_DX10)
1113-
UINT res_width = m_ChainDesc.BufferDesc.Width;
1114-
UINT res_height = m_ChainDesc.BufferDesc.Height;
1115-
#endif
1136+
RECT m_rcWindowBounds;
1137+
RECT DesktopRect;
11161138

1117-
SetRect(&m_rcWindowBounds,
1118-
(DesktopRect.right - res_width) / 2,
1119-
(DesktopRect.bottom - res_height) / 2,
1120-
(DesktopRect.right + res_width) / 2,
1121-
(DesktopRect.bottom + res_height) / 2);
1139+
GetClientRect(GetDesktopWindow(), &DesktopRect);
11221140

1123-
AdjustWindowRect(&m_rcWindowBounds, dwWindowStyle, FALSE);
1141+
SetRect(&m_rcWindowBounds,
1142+
(LONG(monW) - res_width) / 2,
1143+
(LONG(monH) - res_height) / 2,
1144+
(monW + res_width) / 2,
1145+
(monH + res_height) / 2);
11241146

11251147
SetWindowPos(m_hWnd,
11261148
HWND_NOTOPMOST,
1127-
m_rcWindowBounds.left,
1128-
m_rcWindowBounds.top,
1149+
monX + m_rcWindowBounds.left,
1150+
monY + m_rcWindowBounds.top,
11291151
(m_rcWindowBounds.right - m_rcWindowBounds.left),
11301152
(m_rcWindowBounds.bottom - m_rcWindowBounds.top),
11311153
SWP_SHOWWINDOW | SWP_NOCOPYBITS | SWP_DRAWFRAME);
11321154
}
11331155
}
11341156
else
11351157
{
1136-
SetWindowLong(m_hWnd, GWL_STYLE, dwWindowStyle = (WS_POPUP | WS_VISIBLE));
1158+
SetWindowLong(m_hWnd, GWL_STYLE, WS_POPUP | WS_VISIBLE);
11371159
}
11381160

11391161
ShowCursor(FALSE);

src/Layers/xrRenderPC_R2/xrRender_R2.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,30 @@ bool /*_declspec(dllexport)*/ SupportsAdvancedRendering();
3535

3636
bool /*_declspec(dllexport)*/ SupportsAdvancedRendering()
3737
{
38+
// Save DPI awareness context — Direct3DCreate9() can change the thread's
39+
// DPI context, which later causes SetWindowPos to use the wrong scale on
40+
// secondary monitors with different DPI.
41+
typedef HANDLE(WINAPI* pfnSetThreadDpiAwarenessContext)(HANDLE);
42+
pfnSetThreadDpiAwarenessContext fnSetCtx = NULL;
43+
HANDLE prevDpiContext = NULL;
44+
HMODULE user32 = GetModuleHandleA("user32.dll");
45+
if (user32)
46+
{
47+
fnSetCtx = (pfnSetThreadDpiAwarenessContext)GetProcAddress(user32, "SetThreadDpiAwarenessContext");
48+
if (fnSetCtx)
49+
prevDpiContext = fnSetCtx(/*DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2*/ (HANDLE)-4);
50+
}
51+
3852
D3DCAPS9 caps;
3953
CHW _HW;
4054
_HW.CreateD3D();
4155
_HW.pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
4256
_HW.DestroyD3D();
57+
58+
// Restore DPI awareness context
59+
if (fnSetCtx && prevDpiContext)
60+
fnSetCtx(prevDpiContext);
61+
4362
u16 ps_ver_major = u16(u32(u32(caps.PixelShaderVersion) & u32(0xf << 8ul)) >> 8);
4463

4564
if (ps_ver_major < 3)

src/xrEngine/Device_create.cpp

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -163,14 +163,40 @@ void CRenderDevice::ConnectToRender()
163163

164164
extern u32 g_screenmode;
165165
extern void GetMonitorResolution(u32& horizontal, u32& vertical);
166+
extern void GetMonitorPosition(int& x, int& y);
166167

167168
PROTECT_API void CRenderDevice::Create()
168169
{
169170
//SECUROM_MARKER_SECURITY_ON(4)
170171

171172
if (b_is_Ready) return; // prevent double call
172-
Statistic = xr_new<CStats>();
173173

174+
u32 w, h;
175+
GetMonitorResolution(w, h);
176+
int monX, monY;
177+
GetMonitorPosition(monX, monY);
178+
if (psCurrentVidMode[0] == 0 || psCurrentVidMode[1] == 0)
179+
{
180+
psCurrentVidMode[0] = w;
181+
psCurrentVidMode[1] = h;
182+
}
183+
184+
DWORD style;
185+
if (g_screenmode == 0)
186+
{
187+
style = WS_OVERLAPPEDWINDOW;
188+
w = psCurrentVidMode[0];
189+
h = psCurrentVidMode[1];
190+
}
191+
else
192+
{
193+
style = WS_POPUP;
194+
}
195+
196+
SetWindowLongPtr(m_hWnd, GWL_STYLE, style);
197+
SetWindowPos(m_hWnd, HWND_TOP, monX, monY, w, h, SWP_FRAMECHANGED);
198+
199+
Statistic = xr_new<CStats>();
174200
#ifdef DEBUG
175201
cdb_clRAY = &Statistic->clRAY; // total: ray-testing
176202
cdb_clBOX = &Statistic->clBOX; // total: box query
@@ -202,18 +228,12 @@ PROTECT_API void CRenderDevice::Create()
202228
true
203229
);
204230

205-
if (g_screenmode == 1)
206-
{
207-
u32 w, h;
208-
GetMonitorResolution(w, h);
209-
SetWindowLongPtr(Device.m_hWnd, GWL_STYLE, WS_VISIBLE | WS_POPUP);
210-
SetWindowPos(Device.m_hWnd, HWND_TOP, 0, 0, w, h, SWP_FRAMECHANGED);
211-
}
212-
213231
DisableProcessWindowsGhosting();
214232

215233
RECT winRect;
216234
GetClientRect(m_hWnd, &winRect);
235+
clientWidth = winRect.right;
236+
clientHeight = winRect.bottom;
217237
MapWindowPoints(m_hWnd, nullptr, reinterpret_cast<LPPOINT>(&winRect), 2);
218238
ClipCursor(&winRect);
219239
SetActiveWindow(m_hWnd);

src/xrEngine/Device_destroy.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ extern bool init_reshade();
6161
extern void unregister_reshade();
6262
extern u32 g_screenmode;
6363
extern void GetMonitorResolution(u32& horizontal, u32& vertical);
64+
extern void GetMonitorPosition(int& x, int& y);
6465

6566
void CRenderDevice::Reset(bool precache)
6667
{
@@ -101,15 +102,19 @@ void CRenderDevice::Reset(bool precache)
101102
if (g_screenmode == 1)
102103
{
103104
u32 w, h;
105+
int monX, monY;
104106
GetMonitorResolution(w, h);
107+
GetMonitorPosition(monX, monY);
105108
SetWindowLongPtr(Device.m_hWnd, GWL_STYLE, WS_VISIBLE | WS_POPUP);
106-
SetWindowPos(Device.m_hWnd, HWND_TOP, 0, 0, w, h, SWP_FRAMECHANGED);
109+
SetWindowPos(Device.m_hWnd, HWND_TOP, monX, monY, w, h, SWP_FRAMECHANGED);
107110
}
108111

109112
#ifndef DEDICATED_SERVER
110113
ShowCursor(FALSE);
111114
RECT winRect;
112115
GetClientRect(m_hWnd, &winRect);
116+
clientWidth = winRect.right;
117+
clientHeight = winRect.bottom;
113118
MapWindowPoints(m_hWnd, nullptr, reinterpret_cast<LPPOINT>(&winRect), 2);
114119
ClipCursor(&winRect);
115120
#endif

src/xrEngine/IInputReceiver.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ void IInputReceiver::IR_GetMousePosIndependent(Fvector2& f)
7373
Ivector2 p;
7474
IR_GetMousePosReal(p);
7575
f.set(
76-
2.f * float(p.x) / float(RDEVICE.dwWidth) - 1.f,
77-
2.f * float(p.y) / float(RDEVICE.dwHeight) - 1.f
76+
2.f * float(p.x) / float(RDEVICE.clientWidth) - 1.f,
77+
2.f * float(p.y) / float(RDEVICE.clientHeight) - 1.f
7878
);
7979
}
8080

0 commit comments

Comments
 (0)