Skip to content

[ZH] Center Window on Startup #541

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,13 @@ void GameEngine::init( int argc, char *argv[] )
#endif/////////////////////////////////////////////////////////////////////////////////////////////


// TheSuperHackers @bugfix helmutbuhler 04/14/2025
// Pump messages during startup to avoid "(Not responding)" in the window title
// on slower computers and in debug build.
// This also ensures that the window is correctly positioned, because Windows
// apparently ignores the SetWindowPos call when the window is not responding.
serviceWindowsOS();


#if defined(_DEBUG) || defined(_INTERNAL)
// If we're in Debug or Internal, load the Debug info as well.
Expand Down
140 changes: 78 additions & 62 deletions GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@
//#define CREATE_DX8_MULTI_THREADED
//#define CREATE_DX8_FPU_PRESERVE
#define WW3D_DEVTYPE D3DDEVTYPE_HAL

#undef WINVER
#define WINVER 0x0500
#include "dx8wrapper.h"
#include "dx8webbrowser.h"
#include "dx8fvf.h"
Expand Down Expand Up @@ -242,6 +243,26 @@ void Non_Fatal_Log_DX8_ErrorCode(unsigned res,const char * file,int line)
}
}

// TheSuperHackers @info helmutbuhler 04/14/2025
// Helper function that moves x and y such that the inner rect fits into the outer rect.
// If inner already is in outer, this does nothing.
void MoveRectIntoOtherRect(const RECT& inner, const RECT& outer, int* x, int* y)
{
int dx = 0;
if (inner.right > outer.right)
dx = outer.right-inner.right;
if (inner.left < outer.left)
dx = outer.left-inner.left;

int dy = 0;
if (inner.bottom > outer.bottom)
dy = outer.bottom-inner.bottom;
if (inner.top < outer.top)
dy = outer.top-inner.top;

*x += dx;
*y += dy;
}


bool DX8Wrapper::Init(void * hwnd, bool lite)
Expand Down Expand Up @@ -885,6 +906,60 @@ void DX8Wrapper::Get_Format_Name(unsigned int format, StringClass *tex_format)
}
}

void DX8Wrapper::Resize_And_Position_Window()
{
// Get the current dimensions of the 'render area' of the window
RECT rect = { 0 };
::GetClientRect (_Hwnd, &rect);

// Is the window the correct size for this resolution?
if ((rect.right-rect.left) != ResolutionWidth ||
(rect.bottom-rect.top) != ResolutionHeight) {

// Calculate what the main window's bounding rectangle should be to
// accomodate this resolution
rect.left = 0;
rect.top = 0;
rect.right = ResolutionWidth;
rect.bottom = ResolutionHeight;
DWORD dwstyle = ::GetWindowLong (_Hwnd, GWL_STYLE);
AdjustWindowRect (&rect, dwstyle, FALSE);
int width = rect.right-rect.left;
int height = rect.bottom-rect.top;

// Resize the window to fit this resolution
if (!IsWindowed)
::SetWindowPos(_Hwnd, HWND_TOPMOST, 0, 0, width, height, SWP_NOSIZE | SWP_NOMOVE);
else
{
// TheSuperHackers @feature helmutbuhler 04/14/2025
// Center the window in the workarea of the monitor it is on.
MONITORINFO mi = {sizeof(MONITORINFO)};
GetMonitorInfo(MonitorFromWindow(_Hwnd, MONITOR_DEFAULTTOPRIMARY), &mi);
int left = (mi.rcWork.left + mi.rcWork.right - width) / 2;
int top = (mi.rcWork.top + mi.rcWork.bottom - height) / 2;

// TheSuperHackers @feature helmutbuhler 04/14/2025
// In case part of the resulting client area is off monitor, move it.
// This can happen when the window is larger than the work area.
RECT rectClient;
rectClient.left = left - rect.left;
rectClient.top = top - rect.top;
rectClient.right = rectClient.left + ResolutionWidth;
rectClient.bottom = rectClient.top + ResolutionHeight;
MoveRectIntoOtherRect(rectClient, mi.rcMonitor, &left, &top);

::SetWindowPos (_Hwnd,
NULL,
left,
top,
width,
height,
SWP_NOZORDER);
}
}
}

bool DX8Wrapper::Set_Render_Device(int dev, int width, int height, int bits, int windowed,
bool resize_window,bool reset_device, bool restore_assets)
{
Expand Down Expand Up @@ -926,36 +1001,7 @@ bool DX8Wrapper::Set_Render_Device(int dev, int width, int height, int bits, int
// push the client area to be the size you really want.
// if ( resize_window && windowed ) {
if (resize_window) {

// Get the current dimensions of the 'render area' of the window
RECT rect = { 0 };
::GetClientRect (_Hwnd, &rect);

// Is the window the correct size for this resolution?
if ((rect.right-rect.left) != ResolutionWidth ||
(rect.bottom-rect.top) != ResolutionHeight) {

// Calculate what the main window's bounding rectangle should be to
// accomodate this resolution
rect.left = 0;
rect.top = 0;
rect.right = ResolutionWidth;
rect.bottom = ResolutionHeight;
DWORD dwstyle = ::GetWindowLong (_Hwnd, GWL_STYLE);
AdjustWindowRect (&rect, dwstyle, FALSE);

// Resize the window to fit this resolution
if (!windowed)
::SetWindowPos(_Hwnd, HWND_TOPMOST, 0, 0, rect.right-rect.left, rect.bottom-rect.top,SWP_NOSIZE |SWP_NOMOVE);
else
::SetWindowPos (_Hwnd,
NULL,
0,
0,
rect.right-rect.left,
rect.bottom-rect.top,
SWP_NOZORDER | SWP_NOMOVE);
}
Resize_And_Position_Window();
}
#endif
//must be either resetting existing device or creating a new one.
Expand Down Expand Up @@ -1204,37 +1250,7 @@ bool DX8Wrapper::Set_Device_Resolution(int width,int height,int bits,int windowe
}
if (resize_window)
{

// Get the current dimensions of the 'render area' of the window
RECT rect = { 0 };
::GetClientRect (_Hwnd, &rect);

// Is the window the correct size for this resolution?
if ((rect.right-rect.left) != ResolutionWidth ||
(rect.bottom-rect.top) != ResolutionHeight)
{

// Calculate what the main window's bounding rectangle should be to
// accomodate this resolution
rect.left = 0;
rect.top = 0;
rect.right = ResolutionWidth;
rect.bottom = ResolutionHeight;
DWORD dwstyle = ::GetWindowLong (_Hwnd, GWL_STYLE);
AdjustWindowRect (&rect, dwstyle, FALSE);

// Resize the window to fit this resolution
if (!windowed)
::SetWindowPos(_Hwnd, HWND_TOPMOST, 0, 0, rect.right-rect.left, rect.bottom-rect.top,SWP_NOSIZE |SWP_NOMOVE);
else
::SetWindowPos (_Hwnd,
NULL,
0,
0,
rect.right-rect.left,
rect.bottom-rect.top,
SWP_NOZORDER | SWP_NOMOVE);
}
Resize_And_Position_Window();
}
#pragma message("TODO: support changing windowed status and changing the bit depth")
return Reset_Device();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,7 @@ class DX8Wrapper
/*
** Internal functions
*/
static void Resize_And_Position_Window();
static bool Find_Color_And_Z_Mode(int resx,int resy,int bitdepth,D3DFORMAT * set_colorbuffer,D3DFORMAT * set_backbuffer, D3DFORMAT * set_zmode);
static bool Find_Color_Mode(D3DFORMAT colorbuffer, int resx, int resy, UINT *mode);
static bool Find_Z_Mode(D3DFORMAT colorbuffer,D3DFORMAT backbuffer, D3DFORMAT *zmode);
Expand Down