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