Fixed bug 4018 - Implement SDL_GetWindowBordersSize() under Windows/Win32/WinAPI

Ismael Ferreras Morezuelas (Swyter)

As a new year gift I have implemented the Windows version of SDL_GetWindowBordersSize(). I needed it for auto-selecting a cozy window size for the game I'm currently working on and noticed that it only worked under X11, so I thought it could be a good excuse to contribute back more stuff. The Mercurial patch is attached as a .diff file. Let me know what you think.

Happy 2018 to all the SDL2 devs and users!

--

PS: Keep in mind that Windows 10 includes the 8px invisible grip borders as part of the frame. There's a way of detecting if Aero/DWM is being used and ask only for the visible rect, but I believe that GetWindowRect() is doing that for a reason and working as intended, so I haven't changed it. (See [2])


References:
[1]: http://www.firststeps.ru/mfc/winapi/r.php?72
[2]: https://stackoverflow.com/a/34143777/674685
[3]: https://stackoverflow.com/a/431548/674685
[4]: https://wiki.libsdl.org/SDL_GetWindowBordersSize
This commit is contained in:
Sam Lantinga 2018-01-03 10:58:58 -08:00
parent 8111a632be
commit 7c60bec493
3 changed files with 45 additions and 0 deletions

View File

@ -143,6 +143,7 @@ WIN_CreateDevice(int devindex)
device->SetWindowIcon = WIN_SetWindowIcon;
device->SetWindowPosition = WIN_SetWindowPosition;
device->SetWindowSize = WIN_SetWindowSize;
device->GetWindowBordersSize = WIN_GetWindowBordersSize;
device->SetWindowOpacity = WIN_SetWindowOpacity;
device->ShowWindow = WIN_ShowWindow;
device->HideWindow = WIN_HideWindow;

View File

@ -479,6 +479,49 @@ WIN_SetWindowSize(_THIS, SDL_Window * window)
WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOACTIVATE);
}
int
WIN_GetWindowBordersSize(_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right)
{
HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
RECT rcClient, rcWindow;
POINT ptDiff;
/* rcClient stores the size of the inner window, while rcWindow stores the outer size relative to the top-left
* screen position; so the top/left values of rcClient are always {0,0} and bottom/right are {height,width} */
GetClientRect(hwnd, &rcClient);
GetWindowRect(hwnd, &rcWindow);
/* convert the top/left values to make them relative to
* the window; they will end up being slightly negative */
ptDiff.y = rcWindow.top;
ptDiff.x = rcWindow.left;
ScreenToClient(hwnd, &ptDiff);
rcWindow.top = ptDiff.y;
rcWindow.left = ptDiff.x;
/* convert the bottom/right values to make them relative to the window,
* these will be slightly bigger than the inner width/height */
ptDiff.y = rcWindow.bottom;
ptDiff.x = rcWindow.right;
ScreenToClient(hwnd, &ptDiff);
rcWindow.bottom = ptDiff.y;
rcWindow.right = ptDiff.x;
/* Now that both the inner and outer rects use the same coordinate system we can substract them to get the border size.
* Keep in mind that the top/left coordinates of rcWindow are negative because the border lies slightly before {0,0},
* so switch them around because SDL2 wants them in positive. */
*top = rcClient.top - rcWindow.top;
*left = rcClient.left - rcWindow.left;
*bottom = rcWindow.bottom - rcClient.bottom;
*right = rcWindow.right - rcClient.right;
return 0;
}
void
WIN_ShowWindow(_THIS, SDL_Window * window)
{

View File

@ -58,6 +58,7 @@ extern void WIN_SetWindowTitle(_THIS, SDL_Window * window);
extern void WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
extern void WIN_SetWindowPosition(_THIS, SDL_Window * window);
extern void WIN_SetWindowSize(_THIS, SDL_Window * window);
extern int WIN_GetWindowBordersSize(_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right);
extern int WIN_SetWindowOpacity(_THIS, SDL_Window * window, float opacity);
extern void WIN_ShowWindow(_THIS, SDL_Window * window);
extern void WIN_HideWindow(_THIS, SDL_Window * window);