foobar2000 SDK  2015-08-03
win-objects.cpp
Go to the documentation of this file.
1 #include "pfc.h"
2 
3 #include "pp-winapi.h"
4 
5 #ifdef _WIN32
6 
8  switch(p_code) {
9  case ERROR_CHILD_NOT_COMPLETE:
10  p_out = "Application cannot be run in Win32 mode.";
11  return TRUE;
12  case ERROR_INVALID_ORDINAL:
13  p_out = "Invalid ordinal.";
14  return TRUE;
15  case ERROR_INVALID_STARTING_CODESEG:
16  p_out = "Invalid code segment.";
17  return TRUE;
18  case ERROR_INVALID_STACKSEG:
19  p_out = "Invalid stack segment.";
20  return TRUE;
21  case ERROR_INVALID_MODULETYPE:
22  p_out = "Invalid module type.";
23  return TRUE;
24  case ERROR_INVALID_EXE_SIGNATURE:
25  p_out = "Invalid executable signature.";
26  return TRUE;
27  case ERROR_BAD_EXE_FORMAT:
28  p_out = "Not a valid Win32 application.";
29  return TRUE;
30  case ERROR_EXE_MACHINE_TYPE_MISMATCH:
31  p_out = "Machine type mismatch.";
32  return TRUE;
33  case ERROR_EXE_CANNOT_MODIFY_SIGNED_BINARY:
34  case ERROR_EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY:
35  p_out = "Unable to modify a signed binary.";
36  return TRUE;
37  default:
38  {
39  TCHAR temp[512];
40  if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,0,p_code,0,temp,_countof(temp),0) == 0) return FALSE;
41  for(t_size n=0;n<_countof(temp);n++) {
42  switch(temp[n]) {
43  case '\n':
44  case '\r':
45  temp[n] = ' ';
46  break;
47  }
48  }
49  p_out = stringcvt::string_utf8_from_os(temp,_countof(temp));
50  return TRUE;
51  }
52  break;
53  }
54 }
55 void pfc::winPrefixPath(pfc::string_base & out, const char * p_path) {
56  const char * prepend_header = "\\\\?\\";
57  const char * prepend_header_net = "\\\\?\\UNC\\";
58  if (pfc::strcmp_partial( p_path, prepend_header ) == 0) { out = p_path; return; }
59  out.reset();
60  if (pfc::strcmp_partial(p_path,"\\\\") != 0) {
61  out << prepend_header << p_path;
62  } else {
63  out << prepend_header_net << (p_path+2);
64  }
65 };
66 
67 void pfc::winUnPrefixPath(pfc::string_base & out, const char * p_path) {
68  const char * prepend_header = "\\\\?\\";
69  const char * prepend_header_net = "\\\\?\\UNC\\";
70  if (pfc::strcmp_partial(p_path, prepend_header_net) == 0) {
71  out = pfc::string_formatter() << "\\\\" << (p_path + strlen(prepend_header_net) );
72  return;
73  }
74  if (pfc::strcmp_partial(p_path, prepend_header) == 0) {
75  out = (p_path + strlen(prepend_header));
76  return;
77  }
78  out = p_path;
79 }
80 
82  LastErrorRevertScope revert;
83  if (p_code == 0) m_buffer = "Undefined error";
84  else if (!pfc::winFormatSystemErrorMessage(m_buffer,p_code)) m_buffer << "Unknown error code (" << (unsigned)p_code << ")";
85 }
86 
88  if (!pfc::winFormatSystemErrorMessage(m_buffer,(DWORD)p_code)) m_buffer = "Unknown error code";
89  stamp_hex(p_code);
90 }
91 format_hresult::format_hresult(HRESULT p_code, const char * msgOverride) {
92  m_buffer = msgOverride;
93  stamp_hex(p_code);
94 }
95 
96 void format_hresult::stamp_hex(HRESULT p_code) {
97  m_buffer << " (0x" << pfc::format_hex((t_uint32)p_code, 8) << ")";
98 }
99 
100 #ifdef PFC_WINDOWS_DESKTOP_APP
101 
102 void uAddWindowStyle(HWND p_wnd,LONG p_style) {
103  SetWindowLong(p_wnd,GWL_STYLE, GetWindowLong(p_wnd,GWL_STYLE) | p_style);
104 }
105 
106 void uRemoveWindowStyle(HWND p_wnd,LONG p_style) {
107  SetWindowLong(p_wnd,GWL_STYLE, GetWindowLong(p_wnd,GWL_STYLE) & ~p_style);
108 }
109 
110 void uAddWindowExStyle(HWND p_wnd,LONG p_style) {
111  SetWindowLong(p_wnd,GWL_EXSTYLE, GetWindowLong(p_wnd,GWL_EXSTYLE) | p_style);
112 }
113 
114 void uRemoveWindowExStyle(HWND p_wnd,LONG p_style) {
115  SetWindowLong(p_wnd,GWL_EXSTYLE, GetWindowLong(p_wnd,GWL_EXSTYLE) & ~p_style);
116 }
117 
118 unsigned MapDialogWidth(HWND p_dialog,unsigned p_value) {
119  RECT temp;
120  temp.left = 0; temp.right = p_value; temp.top = temp.bottom = 0;
121  if (!MapDialogRect(p_dialog,&temp)) return 0;
122  return temp.right;
123 }
124 
125 bool IsKeyPressed(unsigned vk) {
126  return (GetKeyState(vk) & 0x8000) ? true : false;
127 }
128 
131  unsigned ret = 0;
132  if (IsKeyPressed(VK_CONTROL)) ret |= MOD_CONTROL;
133  if (IsKeyPressed(VK_SHIFT)) ret |= MOD_SHIFT;
134  if (IsKeyPressed(VK_MENU)) ret |= MOD_ALT;
135  if (IsKeyPressed(VK_LWIN) || IsKeyPressed(VK_RWIN)) ret |= MOD_WIN;
136  return ret;
137 }
138 
139 
140 
141 bool CClipboardOpenScope::Open(HWND p_owner) {
142  Close();
143  if (OpenClipboard(p_owner)) {
144  m_open = true;
145  return true;
146  } else {
147  return false;
148  }
149 }
151  if (m_open) {
152  m_open = false;
153  CloseClipboard();
154  }
155 }
156 
157 
158 CGlobalLockScope::CGlobalLockScope(HGLOBAL p_handle) : m_handle(p_handle), m_ptr(GlobalLock(p_handle)) {
159  if (m_ptr == NULL) throw std::bad_alloc();
160 }
162  if (m_ptr != NULL) GlobalUnlock(m_handle);
163 }
164 
165 bool IsPointInsideControl(const POINT& pt, HWND wnd) {
166  HWND walk = WindowFromPoint(pt);
167  for(;;) {
168  if (walk == NULL) return false;
169  if (walk == wnd) return true;
170  if (GetWindowLong(walk,GWL_STYLE) & WS_POPUP) return false;
171  walk = GetParent(walk);
172  }
173 }
174 
175 bool IsWindowChildOf(HWND child, HWND parent) {
176  HWND walk = child;
177  while(walk != parent && walk != NULL && (GetWindowLong(walk,GWL_STYLE) & WS_CHILD) != 0) {
178  walk = GetParent(walk);
179  }
180  return walk == parent;
181 }
182 
184  if (m_menu != NULL) {
185  DestroyMenu(m_menu);
186  m_menu = NULL;
187  }
188 }
189 
191  release();
192  SetLastError(NO_ERROR);
193  m_menu = CreatePopupMenu();
194  if (m_menu == NULL) throw exception_win32(GetLastError());
195 }
196 
197 #endif // #ifdef PFC_WINDOWS_DESKTOP_APP
198 
199 void win32_event::create(bool p_manualreset,bool p_initialstate) {
200  release();
201  SetLastError(NO_ERROR);
202  m_handle = CreateEvent(NULL,p_manualreset ? TRUE : FALSE, p_initialstate ? TRUE : FALSE,NULL);
203  if (m_handle == NULL) throw exception_win32(GetLastError());
204 }
205 
207  HANDLE temp = detach();
208  if (temp != NULL) CloseHandle(temp);
209 }
210 
211 
212 DWORD win32_event::g_calculate_wait_time(double p_seconds) {
213  DWORD time = 0;
214  if (p_seconds> 0) {
215  time = pfc::rint32(p_seconds * 1000.0);
216  if (time == 0) time = 1;
217  } else if (p_seconds < 0) {
218  time = INFINITE;
219  }
220  return time;
221 }
222 
224 bool win32_event::g_wait_for(HANDLE p_event,double p_timeout_seconds) {
225  SetLastError(NO_ERROR);
226  DWORD status = WaitForSingleObject(p_event,g_calculate_wait_time(p_timeout_seconds));
227  switch(status) {
228  case WAIT_FAILED:
229  throw exception_win32(GetLastError());
230  default:
231  throw pfc::exception_bug_check();
232  case WAIT_OBJECT_0:
233  return true;
234  case WAIT_TIMEOUT:
235  return false;
236  }
237 }
238 
239 void win32_event::set_state(bool p_state) {
240  PFC_ASSERT(m_handle != NULL);
241  if (p_state) SetEvent(m_handle);
242  else ResetEvent(m_handle);
243 }
244 
245 int win32_event::g_twoEventWait( HANDLE ev1, HANDLE ev2, double timeout ) {
246  HANDLE h[2] = {ev1, ev2};
247  switch(WaitForMultipleObjects(2, h, FALSE, g_calculate_wait_time( timeout ) )) {
248  default:
249  pfc::crash();
250  case WAIT_TIMEOUT:
251  return 0;
252  case WAIT_OBJECT_0:
253  return 1;
254  case WAIT_OBJECT_0 + 1:
255  return 2;
256  }
257 }
258 
259 int win32_event::g_twoEventWait( win32_event & ev1, win32_event & ev2, double timeout ) {
260  return g_twoEventWait( ev1.get_handle(), ev2.get_handle(), timeout );
261 }
262 
263 #ifdef PFC_WINDOWS_DESKTOP_APP
264 
266  HICON temp = detach();
267  if (temp != NULL) DestroyIcon(temp);
268 }
269 
270 
271 void win32_accelerator::load(HINSTANCE p_inst,const TCHAR * p_id) {
272  release();
273  SetLastError(NO_ERROR);
274  m_accel = LoadAccelerators(p_inst,p_id);
275  if (m_accel == NULL) {
276  throw exception_win32(GetLastError());
277  }
278 }
279 
281  if (m_accel != NULL) {
282  DestroyAcceleratorTable(m_accel);
283  m_accel = NULL;
284  }
285 }
286 
287 #endif // #ifdef PFC_WINDOWS_DESKTOP_APP
288 
289 void uSleepSeconds(double p_time,bool p_alertable) {
290  SleepEx(win32_event::g_calculate_wait_time(p_time),p_alertable ? TRUE : FALSE);
291 }
292 
293 
294 #ifdef PFC_WINDOWS_DESKTOP_APP
295 
296 WORD GetWindowsVersionCode() throw() {
297  const DWORD ver = GetVersion();
298  return (WORD)HIBYTE(LOWORD(ver)) | ((WORD)LOBYTE(LOWORD(ver)) << 8);
299 }
300 
301 
302 namespace pfc {
303  bool isShiftKeyPressed() {
304  return IsKeyPressed(VK_SHIFT);
305  }
306  bool isCtrlKeyPressed() {
307  return IsKeyPressed(VK_CONTROL);
308  }
309  bool isAltKeyPressed() {
310  return IsKeyPressed(VK_MENU);
311  }
312 }
313 
314 #else
315 // If unknown / not available on this architecture, return false always
316 namespace pfc {
317  bool isShiftKeyPressed() {
318  return false;
319  }
320  bool isCtrlKeyPressed() {
321  return false;
322  }
323  bool isAltKeyPressed() {
324  return false;
325  }
326 }
327 
328 #endif // #ifdef PFC_WINDOWS_DESKTOP_APP
329 
330 #endif
void release()
void stamp_hex(HRESULT p_code)
Definition: win-objects.cpp:96
DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE *lpHandles, BOOL bWaitAll, DWORD dwMilliseconds)
Definition: pp-winapi.h:20
void uSleepSeconds(double p_time, bool p_alertable)
void uAddWindowStyle(HWND p_wnd, LONG p_style)
CGlobalLockScope(HGLOBAL p_handle)
BOOL winFormatSystemErrorMessage(pfc::string_base &p_out, DWORD p_code)
Definition: win-objects.cpp:7
void load(HINSTANCE p_inst, const TCHAR *p_id)
void create_popup()
void uRemoveWindowStyle(HWND p_wnd, LONG p_style)
unsigned MapDialogWidth(HWND p_dialog, unsigned p_value)
bool isShiftKeyPressed()
typedef BOOL(WINAPI *pPowerSetRequest_t)(__in HANDLE PowerRequest
HANDLE get_handle() const
Definition: win-objects.h:132
bool isCtrlKeyPressed()
void release()
bool IsKeyPressed(unsigned vk)
bool isAltKeyPressed()
void winPrefixPath(pfc::string_base &out, const char *p_path)
Definition: win-objects.cpp:55
typedef HANDLE(WINAPI *pPowerCreateRequest_t)(__in void *Context)
HGLOBAL m_handle
Definition: win-objects.h:81
static int g_twoEventWait(win32_event &ev1, win32_event &ev2, double timeout)
string_utf8_from_wide string_utf8_from_os
Definition: string_conv.h:517
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
Definition: pp-winapi.h:16
format_hresult(HRESULT p_code)
Definition: win-objects.cpp:87
static bool g_wait_for(HANDLE p_event, double p_timeout_seconds)
Returns true when signaled, false on timeout.
void uAddWindowExStyle(HWND p_wnd, LONG p_style)
void winUnPrefixPath(pfc::string_base &out, const char *p_path)
Definition: win-objects.cpp:67
format_win32_error(DWORD p_code)
Definition: win-objects.cpp:81
size_t t_size
Definition: int_types.h:48
string8_fastalloc string_formatter
Definition: string_base.h:615
void crash()
Definition: other.cpp:112
t_int32 rint32(double p_val)
Definition: other.cpp:209
unsigned GetHotkeyModifierFlags()
Returns current modifier keys pressed, using win32 MOD_* flags.
HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCTSTR lpName)
Definition: pp-winapi.h:8
void release()
WORD GetWindowsVersionCode()
static DWORD g_calculate_wait_time(double p_seconds)
bool IsPointInsideControl(const POINT &pt, HWND wnd)
bool IsWindowChildOf(HWND child, HWND parent)
void uRemoveWindowExStyle(HWND p_wnd, LONG p_style)
int strcmp_partial(const char *str, const char *substr)
Definition: string_base.h:1089
bool Open(HWND p_owner)
void create(bool p_manualreset, bool p_initialstate)
uint32_t t_uint32
Definition: int_types.h:5
pfc::string8 m_buffer
Definition: win-objects.h:27
void set_state(bool p_state)