Mercurial > foo_out_sdl
comparison foosdk/sdk/foobar2000/helpers/window_placement_helper.cpp @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 #include "StdAfx.h" | |
| 2 | |
| 3 #ifdef FOOBAR2000_DESKTOP_WINDOWS | |
| 4 | |
| 5 #include "window_placement_helper.h" | |
| 6 #include <SDK/config_object.h> | |
| 7 | |
| 8 static bool g_is_enabled() | |
| 9 { | |
| 10 return standard_config_objects::query_remember_window_positions(); | |
| 11 } | |
| 12 | |
| 13 static BOOL CALLBACK __MonitorEnumProc( | |
| 14 HMONITOR hMonitor, // handle to display monitor | |
| 15 HDC hdcMonitor, // handle to monitor DC | |
| 16 LPRECT lprcMonitor, // monitor intersection rectangle | |
| 17 LPARAM dwData // data | |
| 18 ) { | |
| 19 RECT * clip = (RECT*)dwData; | |
| 20 RECT newclip; | |
| 21 if (UnionRect(&newclip,clip,lprcMonitor)) { | |
| 22 *clip = newclip; | |
| 23 } | |
| 24 return TRUE; | |
| 25 } | |
| 26 | |
| 27 static bool test_rect(const RECT * rc) { | |
| 28 RECT clip = {}; | |
| 29 if (EnumDisplayMonitors(NULL,NULL,__MonitorEnumProc,(LPARAM)&clip)) { | |
| 30 const LONG sanitycheck = 4; | |
| 31 const LONG cwidth = clip.right - clip.left; | |
| 32 const LONG cheight = clip.bottom - clip.top; | |
| 33 | |
| 34 const LONG width = rc->right - rc->left; | |
| 35 const LONG height = rc->bottom - rc->top; | |
| 36 | |
| 37 if (width > cwidth * sanitycheck || height > cheight * sanitycheck) return false; | |
| 38 } | |
| 39 | |
| 40 return MonitorFromRect(rc,MONITOR_DEFAULTTONULL) != NULL; | |
| 41 } | |
| 42 | |
| 43 | |
| 44 bool cfg_window_placement::read_from_window(HWND window) | |
| 45 { | |
| 46 WINDOWPLACEMENT wp = {}; | |
| 47 if (g_is_enabled()) { | |
| 48 wp.length = sizeof(wp); | |
| 49 if (!GetWindowPlacement(window,&wp)) { | |
| 50 PFC_ASSERT(!"GetWindowPlacement fail!"); | |
| 51 memset(&wp,0,sizeof(wp)); | |
| 52 } else { | |
| 53 // bad, breaks with taskbar on top | |
| 54 /*if (wp.showCmd == SW_SHOWNORMAL) { | |
| 55 GetWindowRect(window, &wp.rcNormalPosition); | |
| 56 }*/ | |
| 57 | |
| 58 if ( !IsWindowVisible( window ) ) wp.showCmd = SW_HIDE; | |
| 59 } | |
| 60 /*else | |
| 61 { | |
| 62 if (!IsWindowVisible(window)) wp.showCmd = SW_HIDE; | |
| 63 }*/ | |
| 64 } | |
| 65 | |
| 66 try { set(wp); } catch(...) {} // this tends to be called often / we really couldn't care less about this failing | |
| 67 | |
| 68 return wp.length == sizeof(wp); | |
| 69 } | |
| 70 | |
| 71 bool applyWindowPlacement(HWND window, WINDOWPLACEMENT const& data, bool allowHidden) { | |
| 72 bool ret = false; | |
| 73 if (data.length == sizeof(data) && test_rect(&data.rcNormalPosition)) | |
| 74 { | |
| 75 if (allowHidden || data.showCmd != SW_HIDE) { | |
| 76 if (data.showCmd == SW_HIDE && (data.flags & WPF_RESTORETOMAXIMIZED)) { | |
| 77 // Special case of hidden-from-maximized | |
| 78 auto fix = data; | |
| 79 fix.showCmd = SW_SHOWMINIMIZED; | |
| 80 if (SetWindowPlacement(window, &fix)) { | |
| 81 ShowWindow(window, SW_HIDE); | |
| 82 ret = true; | |
| 83 } | |
| 84 } else { | |
| 85 if (SetWindowPlacement(window, &data)) { | |
| 86 ret = true; | |
| 87 } | |
| 88 } | |
| 89 } | |
| 90 } | |
| 91 return ret; | |
| 92 } | |
| 93 | |
| 94 bool cfg_window_placement::apply_to_window(HWND window, bool allowHidden) { | |
| 95 bool ret = false; | |
| 96 if (g_is_enabled()) | |
| 97 { | |
| 98 auto data = get(); | |
| 99 ret = applyWindowPlacement(window, data, allowHidden); | |
| 100 } | |
| 101 | |
| 102 return ret; | |
| 103 } | |
| 104 | |
| 105 void cfg_window_placement::on_window_creation_silent(HWND window) { | |
| 106 } | |
| 107 bool cfg_window_placement::on_window_creation(HWND window, bool allowHidden) { | |
| 108 | |
| 109 return apply_to_window(window, allowHidden); | |
| 110 } | |
| 111 | |
| 112 | |
| 113 void cfg_window_placement::on_window_destruction(HWND window) | |
| 114 { | |
| 115 read_from_window(window); | |
| 116 } | |
| 117 | |
| 118 static BOOL SetWindowSize(HWND p_wnd,unsigned p_x,unsigned p_y) | |
| 119 { | |
| 120 if (p_x != ~0 && p_y != ~0) | |
| 121 return SetWindowPos(p_wnd,0,0,0,p_x,p_y,SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER); | |
| 122 else | |
| 123 return FALSE; | |
| 124 } | |
| 125 | |
| 126 bool cfg_window_size::apply_to_window(HWND p_wnd) { | |
| 127 bool ret = false; | |
| 128 | |
| 129 if (g_is_enabled()) | |
| 130 { | |
| 131 auto v = get(); | |
| 132 if (v.cx > 0 && v.cy > 0) { | |
| 133 if (SetWindowSize(p_wnd, v.cx, v.cy)) ret = true; | |
| 134 } | |
| 135 | |
| 136 } | |
| 137 return ret; | |
| 138 } | |
| 139 bool cfg_window_size::on_window_creation(HWND p_wnd) | |
| 140 { | |
| 141 return apply_to_window(p_wnd); | |
| 142 } | |
| 143 | |
| 144 void cfg_window_size::on_window_destruction(HWND p_wnd) | |
| 145 { | |
| 146 read_from_window(p_wnd); | |
| 147 } | |
| 148 | |
| 149 bool cfg_window_size::read_from_window(HWND p_wnd) | |
| 150 { | |
| 151 SIZE val = {}; | |
| 152 if (g_is_enabled()) | |
| 153 { | |
| 154 RECT r; | |
| 155 if (GetWindowRect(p_wnd,&r)) | |
| 156 { | |
| 157 val.cx = r.right - r.left; | |
| 158 val.cy = r.bottom - r.top; | |
| 159 } | |
| 160 } | |
| 161 | |
| 162 set(val); | |
| 163 return val.cx > 0 && val.cy > 0; | |
| 164 } | |
| 165 | |
| 166 #endif // FOOBAR2000_DESKTOP_WINDOWS |
