foobar2000 SDK  2015-01-14
window_placement_helper.cpp
Go to the documentation of this file.
1 #include "stdafx.h"
2 
3 #ifdef _WIN32
4 
5 static bool g_is_enabled()
6 {
8 }
9 
10 static BOOL CALLBACK __MonitorEnumProc(
11  HMONITOR hMonitor, // handle to display monitor
12  HDC hdcMonitor, // handle to monitor DC
13  LPRECT lprcMonitor, // monitor intersection rectangle
14  LPARAM dwData // data
15  ) {
16  RECT * clip = (RECT*)dwData;
17  RECT newclip;
18  if (UnionRect(&newclip,clip,lprcMonitor)) {
19  *clip = newclip;
20  }
21  return TRUE;
22 }
23 
24 static bool test_rect(const RECT * rc) {
25  RECT clip = {};
26  if (EnumDisplayMonitors(NULL,NULL,__MonitorEnumProc,(LPARAM)&clip)) {
27  const LONG sanitycheck = 4;
28  const LONG cwidth = clip.right - clip.left;
29  const LONG cheight = clip.bottom - clip.top;
30 
31  const LONG width = rc->right - rc->left;
32  const LONG height = rc->bottom - rc->top;
33 
34  if (width > cwidth * sanitycheck || height > cheight * sanitycheck) return false;
35  }
36 
37  return MonitorFromRect(rc,MONITOR_DEFAULTTONULL) != NULL;
38 }
39 
40 
42 {
43  WINDOWPLACEMENT wp = {};
44  if (g_is_enabled()) {
45  wp.length = sizeof(wp);
46  if (!GetWindowPlacement(window,&wp)) {
47  PFC_ASSERT(!"GetWindowPlacement fail!");
48  memset(&wp,0,sizeof(wp));
49  } else {
50  // bad, breaks with taskbar on top
51  /*if (wp.showCmd == SW_SHOWNORMAL) {
52  GetWindowRect(window, &wp.rcNormalPosition);
53  }*/
54  }
55  /*else
56  {
57  if (!IsWindowVisible(window)) wp.showCmd = SW_HIDE;
58  }*/
59  }
60  m_data = wp;
61  return m_data.length == sizeof(m_data);
62 }
63 
65  PFC_ASSERT(!m_windows.have_item(window));
66  m_windows.add_item(window);
67 }
69 {
70  bool ret = false;
71  PFC_ASSERT(!m_windows.have_item(window));
72  m_windows.add_item(window);
73 
74  if (g_is_enabled())
75  {
76  if (m_data.length==sizeof(m_data) && test_rect(&m_data.rcNormalPosition))
77  {
78  if (SetWindowPlacement(window,&m_data))
79  {
80  ret = true;
81  }
82  }
83  }
84 
85  return ret;
86 }
87 
88 
90 {
91  if (m_windows.have_item(window))
92  {
93  read_from_window(window);
94  m_windows.remove_item(window);
95  }
96 }
97 
99  if (g_is_enabled()) {
100  {
101  t_size n, m = m_windows.get_count();
102  for(n=0;n<m;n++) {
103  HWND window = m_windows[n];
104  PFC_ASSERT(IsWindow(window));
105  if (IsWindow(window) && read_from_window(window)) break;
106  }
107  }
108 
109  if (m_data.length == sizeof(m_data)) {
110  p_stream->write_object(&m_data,sizeof(m_data),p_abort);
111  }
112  }
113 }
114 
116  if (p_sizehint == 0) return;
117  WINDOWPLACEMENT temp;
118  try {
119  p_stream->read_object(&temp,sizeof(temp),p_abort);
120  } catch(exception_io_data) {return;}
121  if (temp.length == sizeof(temp)) m_data = temp;
122 }
123 
124 
126 {
127  memset(&m_data,0,sizeof(m_data));
128 }
129 
130 
131 cfg_window_size::cfg_window_size(const GUID & p_guid) : cfg_var(p_guid), m_width(~0), m_height(~0) {}
132 
133 static BOOL SetWindowSize(HWND p_wnd,unsigned p_x,unsigned p_y)
134 {
135  if (p_x != ~0 && p_y != ~0)
136  return SetWindowPos(p_wnd,0,0,0,p_x,p_y,SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER);
137  else
138  return FALSE;
139 }
140 
142 {
143  bool ret = false;
144  PFC_ASSERT(!m_windows.have_item(p_wnd));
145  m_windows.add_item(p_wnd);
146 
147  if (g_is_enabled())
148  {
149  if (SetWindowSize(p_wnd,m_width,m_height)) ret = true;
150  }
151 
152  return ret;
153 }
154 
156 {
157  if (m_windows.have_item(p_wnd))
158  {
159  read_from_window(p_wnd);
160  m_windows.remove_item(p_wnd);
161  }
162 }
163 
165 {
166  if (g_is_enabled())
167  {
168  RECT r;
169  if (GetWindowRect(p_wnd,&r))
170  {
171  m_width = r.right - r.left;
172  m_height = r.bottom - r.top;
173  return true;
174  }
175  else
176  {
177  m_width = m_height = ~0;
178  return false;
179  }
180  }
181  else
182  {
183  m_width = m_height = ~0;
184  return false;
185  }
186 }
187 
189  if (g_is_enabled()) {
190  {
191  t_size n, m = m_windows.get_count();
192  for(n=0;n<m;n++) {
193  HWND window = m_windows[n];
194  PFC_ASSERT(IsWindow(window));
195  if (IsWindow(window) && read_from_window(window)) break;
196  }
197  }
198 
199  if (m_width != ~0 && m_height != ~0) {
200  p_stream->write_lendian_t(m_width,p_abort);
201  p_stream->write_lendian_t(m_height,p_abort);
202  }
203  }
204 }
205 
206 void cfg_window_size::set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort) {
207  if (p_sizehint == 0) return;
208  t_uint32 width,height;
209  try {
210  p_stream->read_lendian_t(width,p_abort);
211  p_stream->read_lendian_t(height,p_abort);
212  } catch(exception_io_data) {return;}
213 
214  m_width = width; m_height = height;
215 }
216 #endif // _WIN32
void on_window_destruction(HWND window)
Definition: pfc.h:53
static BOOL CALLBACK __MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
void set_data_raw(stream_reader *p_stream, t_size p_sizehint, abort_callback &p_abort)
Sets state of the variable. Called only from main thread, when reading configuration file...
typedef BOOL(WINAPI *pPowerSetRequest_t)(__in HANDLE PowerRequest
t_size get_count() const
Definition: list.h:365
static bool test_rect(const RECT *rc)
bool read_from_window(HWND window)
void get_data_raw(stream_writer *p_stream, abort_callback &p_abort)
Retrieves state of the variable. Called only from main thread, when writing configuration file...
cfg_window_placement(const GUID &p_guid)
size_t t_size
Definition: int_types.h:48
t_size add_item(const T &item)
Definition: list.h:522
void on_window_creation_silent(HWND window)
static bool g_is_enabled()
bool on_window_creation(HWND window)
pfc::list_hybrid_t< HWND, 2 > m_windows
pfc::list_hybrid_t< HWND, 2 > m_windows
cfg_window_size(const GUID &p_guid)
void get_data_raw(stream_writer *p_stream, abort_callback &p_abort)
Retrieves state of the variable. Called only from main thread, when writing configuration file...
static bool query_remember_window_positions()
Definition: config_object.h:71
void remove_item(const T &item)
Definition: list.h:532
static BOOL SetWindowSize(HWND p_wnd, unsigned p_x, unsigned p_y)
void on_window_destruction(HWND window)
void set_data_raw(stream_reader *p_stream, t_size p_sizehint, abort_callback &p_abort)
Sets state of the variable. Called only from main thread, when reading configuration file...
bool read_from_window(HWND window)
Base class for configuration variable classes; provides self-registration mechaisms and methods to se...
Definition: cfg_var.h:54
bool on_window_creation(HWND window)
bool have_item(const t_search &p_item) const
Definition: list.h:569
uint32_t t_uint32
Definition: int_types.h:5