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