diff --git a/examples/simpleWindow/build.bat b/examples/simpleWindow/build.bat index 971b6e5..2f24fa7 100644 --- a/examples/simpleWindow/build.bat +++ b/examples/simpleWindow/build.bat @@ -1,2 +1,2 @@ set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext -cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.dll.lib user32.lib opengl32.lib gdi32.lib /out:../../bin/example_window.exe +cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.dll.lib user32.lib /out:../../bin/example_simple_window.exe diff --git a/src/mp_app.c b/src/mp_app.c index cb053c3..7cc9f68 100644 --- a/src/mp_app.c +++ b/src/mp_app.c @@ -179,3 +179,39 @@ mp_event* mp_next_event(mem_arena* arena) } return(event); } + +//--------------------------------------------------------------- +// window rects helpers +//--------------------------------------------------------------- + +void mp_window_set_content_position(mp_window window, vec2 position) +{ + mp_rect rect = mp_window_get_content_rect(window); + rect.x = position.x; + rect.y = position.y; + mp_window_set_content_rect(window, rect); +} + +void mp_window_set_content_size(mp_window window, vec2 size) +{ + mp_rect rect = mp_window_get_content_rect(window); + rect.w = size.x; + rect.h = size.y; + mp_window_set_content_rect(window, rect); +} + +void mp_window_set_frame_position(mp_window window, vec2 position) +{ + mp_rect frame = mp_window_get_frame_rect(window); + frame.x = position.x; + frame.y = position.y; + mp_window_set_frame_rect(window, frame); +} + +void mp_window_set_frame_size(mp_window window, vec2 size) +{ + mp_rect frame = mp_window_get_frame_rect(window); + frame.w = size.x; + frame.h = size.y; + mp_window_set_frame_rect(window, frame); +} diff --git a/src/osx_app.m b/src/osx_app.m index 39405fd..093f0d6 100644 --- a/src/osx_app.m +++ b/src/osx_app.m @@ -1544,22 +1544,6 @@ void mp_window_set_frame_rect(mp_window window, mp_rect rect) } }} -void mp_window_set_frame_position(mp_window window, vec2 position) -{ - mp_rect frame = mp_window_get_frame_rect(window); - frame.x = position.x; - frame.y = position.y; - mp_window_set_frame_rect(window, frame); -} - -void mp_window_set_frame_size(mp_window window, vec2 size) -{ - mp_rect frame = mp_window_get_frame_rect(window); - frame.w = size.x; - frame.h = size.y; - mp_window_set_frame_rect(window, frame); -} - mp_rect mp_window_get_content_rect(mp_window window) {@autoreleasepool{ mp_window_data* windowData = mp_window_ptr_from_handle(window); @@ -1602,22 +1586,6 @@ void mp_window_set_content_rect(mp_window window, mp_rect rect) } }} -void mp_window_set_content_position(mp_window window, vec2 position) -{ - mp_rect rect = mp_window_get_content_rect(window); - rect.x = position.x; - rect.y = position.y; - mp_window_set_content_rect(window, rect); -} - -void mp_window_set_content_size(mp_window window, vec2 size) -{ - mp_rect rect = mp_window_get_content_rect(window); - rect.w = size.x; - rect.h = size.y; - mp_window_set_content_rect(window, rect); -} - //-------------------------------------------------------------------- // platform surface //-------------------------------------------------------------------- diff --git a/src/win32_app.c b/src/win32_app.c index 70fb48b..34b83dc 100644 --- a/src/win32_app.c +++ b/src/win32_app.c @@ -319,20 +319,12 @@ LRESULT WinProc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam) { RECT* rect = (RECT*)lParam; - u32 dpi = GetDpiForWindow(mpWindow->win32.hWnd); - f32 scaling = (f32)dpi/96.; - mp_event event = {0}; event.type = message == WM_SIZING ? MP_EVENT_WINDOW_RESIZE : MP_EVENT_WINDOW_MOVE; event.window = mp_window_handle_from_ptr(mpWindow); - event.move.frame = (mp_rect){ - rect->left / scaling, - rect->bottom / scaling, - (rect->bottom - rect->top)/scaling, - (rect->right - rect->left)/scaling }; - - event.move.contents = mp_window_get_content_rect(event.window); + event.move.frame = mp_window_get_frame_rect(event.window); + event.move.content = mp_window_get_content_rect(event.window); mp_queue_event(&event); @@ -588,12 +580,24 @@ mp_window mp_window_create(mp_rect rect, const char* title, mp_window_style styl HMONITOR monitor = MonitorFromPoint((POINT){rect.x, rect.y}, MONITOR_DEFAULTTOPRIMARY); GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY); - f32 dpiScalingX = (f32)dpiX/96.; - f32 dpiScalingY = (f32)dpiY/96.; + f32 scaleX = (f32)dpiX/96.; + f32 scaleY = (f32)dpiY/96.; + + RECT frame = { + rect.x * scaleX, + rect.y * scaleY, + (rect.x + rect.w)*scaleX, + (rect.y + rect.h)*scaleY + }; + + DWORD winStyle = WS_OVERLAPPEDWINDOW; + AdjustWindowRect(&frame, winStyle, FALSE); HWND windowHandle = CreateWindow("ApplicationWindowClass", "Test Window", - WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, - rect.w * dpiScalingX, rect.h * dpiScalingY, + winStyle, + frame.left, frame.top, + frame.right-frame.left, + frame.bottom-frame.top, 0, 0, windowClass.hInstance, 0); if(!windowHandle) @@ -797,23 +801,114 @@ void mp_window_bring_to_front(mp_window window) } } +mp_rect mp_window_get_frame_rect(mp_window window) +{ + mp_rect rect = {0}; + mp_window_data* windowData = mp_window_ptr_from_handle(window); + if(windowData) + { + //NOTE: GetWindowRect() includes the drop shadow, which we don't want, so we call + // DwmGetWindowAttribute() instead. + // Note that contrary to what the GetWindowRect() docs suggests when mentionning + // this, DwmGetWindowAttributes() _does_ seem to adjust for DPI. + u32 dpi = GetDpiForWindow(windowData->win32.hWnd); + f32 scale = (float)dpi/96.; + + RECT frame; + HRESULT res = DwmGetWindowAttribute(windowData->win32.hWnd, + DWMWA_EXTENDED_FRAME_BOUNDS, + &frame, + sizeof(RECT)); + if(res == S_OK) + { + rect = (mp_rect){ + frame.left / scale, + frame.top / scale, + (frame.right - frame.left)/scale, + (frame.bottom - frame.top)/scale}; + } + } + return(rect); +} + +void mp_window_set_frame_rect(mp_window window, mp_rect rect) +{ + mp_window_data* windowData = mp_window_ptr_from_handle(window); + if(windowData) + { + u32 dpi = GetDpiForWindow(windowData->win32.hWnd); + f32 scale = (float)dpi/96.; + + RECT frame = { + rect.x * scale, + rect.y * scale, + (rect.x + rect.w)*scale, + (rect.y + rect.h)*scale + }; + + SetWindowPos(windowData->win32.hWnd, + HWND_TOP, + frame.left, + frame.top, + frame.right - frame.left, + frame.bottom - frame.top, + SWP_NOZORDER|SWP_NOACTIVATE); + } +} + mp_rect mp_window_get_content_rect(mp_window window) { mp_rect rect = {0}; mp_window_data* windowData = mp_window_ptr_from_handle(window); if(windowData) { - RECT winRect; - if(GetClientRect(windowData->win32.hWnd, &winRect)) + RECT client; + if(GetClientRect(windowData->win32.hWnd, &client)) { u32 dpi = GetDpiForWindow(windowData->win32.hWnd); f32 scale = (float)dpi/96.; - rect = (mp_rect){0, 0, (winRect.right - winRect.left)/scale, (winRect.bottom - winRect.top)/scale}; + + POINT origin = {0, 0}; + ClientToScreen(windowData->win32.hWnd, &origin); + + rect = (mp_rect){ + origin.x/scale, + origin.y/scale, + (client.right - client.left)/scale, + (client.bottom - client.top)/scale}; } } return(rect); } +void mp_window_set_content_rect(mp_window window, mp_rect rect) +{ + mp_window_data* windowData = mp_window_ptr_from_handle(window); + if(windowData) + { + u32 dpi = GetDpiForWindow(windowData->win32.hWnd); + f32 scale = (float)dpi/96.; + + RECT frame = { + rect.x * scale, + rect.y * scale, + (rect.x + rect.w)*scale, + (rect.y + rect.h)*scale}; + + DWORD style = GetWindowLong(windowData->win32.hWnd, GWL_STYLE); + BOOL menu = (GetMenu(windowData->win32.hWnd) != NULL); + AdjustWindowRect(&frame, style, menu); + + SetWindowPos(windowData->win32.hWnd, + HWND_TOP, + frame.left, + frame.top, + frame.right - frame.left, + frame.bottom - frame.top, + SWP_NOZORDER|SWP_NOACTIVATE); + } +} + //TODO: set content rect, center void mp_window_center(mp_window window) {