annotate foosdk/sdk/pfc/win-objects.h @ 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 #pragma once
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 #include "ref_counter.h"
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 namespace pfc {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6 BOOL winFormatSystemErrorMessage(pfc::string_base & p_out,DWORD p_code);
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 // Prefix filesystem paths with \\?\ and \\?\UNC where appropriate.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 void winPrefixPath(pfc::string_base & out, const char * p_path);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 // Reverse winPrefixPath
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11 void winUnPrefixPath(pfc::string_base & out, const char * p_path);
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 string8 winPrefixPath( const char * in );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 string8 winUnPrefixPath( const char * in );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 class LastErrorRevertScope {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18 LastErrorRevertScope() : m_val(GetLastError()) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 ~LastErrorRevertScope() { SetLastError(m_val); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 const DWORD m_val;
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
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 string8 getWindowText(HWND wnd);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 void setWindowText(HWND wnd, const char * txt);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 string8 getWindowClassName( HWND wnd );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28 HWND findOwningPopup(HWND wnd);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 pfc::string8 format_win32_error(DWORD code);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 pfc::string8 format_hresult(HRESULT code);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 pfc::string8 format_hresult(HRESULT code, const char * msgOverride);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 class exception_win32 : public std::exception {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 exception_win32(DWORD p_code) : std::exception(format_win32_error(p_code)), m_code(p_code) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 DWORD get_code() const {return m_code;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 DWORD m_code;
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 #ifdef PFC_WINDOWS_DESKTOP_APP
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 void uAddWindowStyle(HWND p_wnd,LONG p_style);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 void uRemoveWindowStyle(HWND p_wnd,LONG p_style);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 void uAddWindowExStyle(HWND p_wnd,LONG p_style);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48 void uRemoveWindowExStyle(HWND p_wnd,LONG p_style);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 unsigned MapDialogWidth(HWND p_dialog,unsigned p_value);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 bool IsKeyPressed(unsigned vk);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 //! Returns current modifier keys pressed, using win32 MOD_* flags.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 unsigned GetHotkeyModifierFlags();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 class CClipboardOpenScope {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 CClipboardOpenScope() : m_open(false) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 ~CClipboardOpenScope() {Close();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 bool Open(HWND p_owner);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 void Close();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 bool m_open;
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 PFC_CLASS_NOT_COPYABLE_EX(CClipboardOpenScope)
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
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 class CGlobalLockScope {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 CGlobalLockScope(HGLOBAL p_handle);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 ~CGlobalLockScope();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71 void * GetPtr() const {return m_ptr;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 t_size GetSize() const {return GlobalSize(m_handle);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 void * m_ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 HGLOBAL m_handle;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 PFC_CLASS_NOT_COPYABLE_EX(CGlobalLockScope)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 template<typename TItem> class CGlobalLockScopeT {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 CGlobalLockScopeT(HGLOBAL handle) : m_scope(handle) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 TItem * GetPtr() const {return reinterpret_cast<TItem*>(m_scope.GetPtr());}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 t_size GetSize() const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 const t_size val = m_scope.GetSize();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 PFC_ASSERT( val % sizeof(TItem) == 0 );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 return val / sizeof(TItem);
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 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 CGlobalLockScope m_scope;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 };
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 //! Resigns active window status passing it to the parent window, if wnd or a child popup of is active. \n
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 //! Use this to mitigate Windows 10 1809 active window handling bugs - call prior to DestroyWindow()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 void ResignActiveWindow(HWND wnd);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 //! Is point inside a control?
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 bool IsPointInsideControl(const POINT& pt, HWND wnd);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 //! Is <child> a control inside <parent> window? Also returns true if child==parent.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 bool IsWindowChildOf(HWND child, HWND parent);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 //! Is <child> window a child (popup or control) of <parent> window? Also returns true if child==parent.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 bool IsPopupWindowChildOf(HWND child, HWND parent);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 class win32_menu {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 win32_menu(HMENU p_initval) : m_menu(p_initval) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 win32_menu() : m_menu(NULL) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 ~win32_menu() {release();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 void release();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 void set(HMENU p_menu) {release(); m_menu = p_menu;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 void create_popup();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 HMENU get() const {return m_menu;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 HMENU detach() {return pfc::replace_t(m_menu,(HMENU)NULL);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 bool is_valid() const {return m_menu != NULL;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 win32_menu(const win32_menu &) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117 void operator=(const win32_menu &) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 HMENU m_menu;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 class win32_event {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 win32_event() : m_handle(NULL) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127 ~win32_event() {release();}
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 void create(bool p_manualreset,bool p_initialstate);
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 void set(HANDLE p_handle) {release(); m_handle = p_handle;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132 HANDLE get() const {return m_handle;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 HANDLE get_handle() const {return m_handle;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 HANDLE detach() {return pfc::replace_t(m_handle,(HANDLE)NULL);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 bool is_valid() const {return m_handle != NULL;}
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 void release();
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 //! Returns true when signaled, false on timeout
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 bool wait_for(double p_timeout_seconds) {return g_wait_for(get(),p_timeout_seconds);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 void wait() { wait_for(-1); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 void wait_and_clear() { wait(); set_state(false); }
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 static DWORD g_calculate_wait_time(double p_seconds);
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 //! Returns true when signaled, false on timeout
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147 static bool g_wait_for(HANDLE p_event,double p_timeout_seconds);
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 void set_state(bool p_state);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150 bool is_set() { return wait_for(0); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152 // Two-wait event functions, return 0 on timeout, 1 on evt1 set, 2 on evt2 set
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153 static int g_twoEventWait( win32_event & ev1, win32_event & ev2, double timeout );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154 static int g_twoEventWait( HANDLE ev1, HANDLE ev2, double timeout );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156 // Multi-wait. Returns SIZE_MAX on timeout, 0 based event index if either event becomes set.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157 static size_t g_multiWait(const HANDLE* events, size_t count, double timeout);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158 static size_t g_multiWait( std::initializer_list<HANDLE> const & arg, double timeout );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160 win32_event(const win32_event&) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161 void operator=(const win32_event &) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163 HANDLE m_handle;
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 namespace pfc {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167 typedef HANDLE eventHandle_t;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169 static constexpr eventHandle_t eventInvalid = NULL;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
170
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
171 class event : public win32_event {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
172 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
173 event(bool initial = false) { create(true, initial); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
174
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
175 HANDLE get_handle() const { return win32_event::get(); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
176 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
177 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
178
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
179 void uSleepSeconds(double p_time,bool p_alertable);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
180
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
181 #ifdef PFC_WINDOWS_DESKTOP_APP
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
182
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
183 class win32_icon {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
184 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
185 win32_icon(HICON p_initval) : m_icon(p_initval) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
186 win32_icon() : m_icon(NULL) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
187 ~win32_icon() {release();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
188
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
189 void release();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
190
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
191 void set(HICON p_icon) {release(); m_icon = p_icon;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
192 HICON get() const {return m_icon;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
193 HICON detach() {return pfc::replace_t(m_icon,(HICON)NULL);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
194
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
195 bool is_valid() const {return m_icon != NULL;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
196
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
197 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
198 win32_icon(const win32_icon&) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
199 const win32_icon & operator=(const win32_icon &) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
200
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
201 HICON m_icon;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
202 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
203
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
204 class win32_accelerator {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
205 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
206 win32_accelerator() : m_accel(NULL) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
207 ~win32_accelerator() {release();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
208 HACCEL get() const {return m_accel;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
209
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
210 void load(HINSTANCE p_inst,const TCHAR * p_id);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
211 void release();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
212 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
213 HACCEL m_accel;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
214 PFC_CLASS_NOT_COPYABLE_EX(win32_accelerator);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
215 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
216
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
217 class SelectObjectScope {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
218 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
219 SelectObjectScope(HDC p_dc,HGDIOBJ p_obj) throw() : m_dc(p_dc), m_obj(SelectObject(p_dc,p_obj)) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
220 ~SelectObjectScope() throw() {SelectObject(m_dc,m_obj);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
221 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
222 PFC_CLASS_NOT_COPYABLE_EX(SelectObjectScope)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
223 HDC m_dc;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
224 HGDIOBJ m_obj;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
225 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
226
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
227 // WARNING: Windows is known to truncate the coordinates to float32 internally instead of retaining original int
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
228 // With large values, this OffsetWindowOrgEx behaves erratically
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
229 class OffsetWindowOrgScope {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
230 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
231 OffsetWindowOrgScope(HDC dc, const POINT & pt) throw() : m_dc(dc), m_pt(pt) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
232 OffsetWindowOrgEx(m_dc, m_pt.x, m_pt.y, NULL);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
233 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
234 ~OffsetWindowOrgScope() throw() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
235 OffsetWindowOrgEx(m_dc, -m_pt.x, -m_pt.y, NULL);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
236 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
237
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
238 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
239 const HDC m_dc;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
240 const POINT m_pt;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
241 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
242 class DCStateScope {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
243 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
244 DCStateScope(HDC p_dc) throw() : m_dc(p_dc) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
245 m_state = SaveDC(m_dc);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
246 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
247 ~DCStateScope() throw() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
248 RestoreDC(m_dc,m_state);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
249 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
250 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
251 const HDC m_dc;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
252 int m_state;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
253 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
254 #endif // #ifdef PFC_WINDOWS_DESKTOP_APP
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
255
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
256 class exception_com : public std::exception {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
257 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
258 exception_com(HRESULT p_code) : std::exception(format_hresult(p_code)), m_code(p_code) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
259 exception_com(HRESULT p_code, const char * msg) : std::exception(format_hresult(p_code, msg)), m_code(p_code) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
260 HRESULT get_code() const {return m_code;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
261 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
262 HRESULT m_code;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
263 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
264
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
265 #ifdef PFC_WINDOWS_DESKTOP_APP
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
266
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
267 // Same format as _WIN32_WINNT macro.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
268 WORD GetWindowsVersionCode() throw();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
269
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
270 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
271
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
272 //! Simple implementation of a COM reference counter. The initial reference count is zero, so it can be used with pfc::com_ptr_t<> with plain operator=/constructor rather than attach().
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
273 template<typename TBase> class ImplementCOMRefCounter : public TBase {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
274 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
275 template<typename ... arg_t> ImplementCOMRefCounter(arg_t && ... arg) : TBase(std::forward<arg_t>(arg) ...) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
276
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
277 ULONG STDMETHODCALLTYPE AddRef() override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
278 return ++m_refcounter;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
279 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
280 ULONG STDMETHODCALLTYPE Release() override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
281 long val = --m_refcounter;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
282 if (val == 0) delete this;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
283 return val;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
284 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
285 protected:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
286 virtual ~ImplementCOMRefCounter() {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
287 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
288 pfc::refcounter m_refcounter;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
289 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
290
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
291
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
292
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
293 template<typename TPtr>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
294 class CoTaskMemObject {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
295 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
296 CoTaskMemObject() : m_ptr() {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
297
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
298 ~CoTaskMemObject() {CoTaskMemFree(m_ptr);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
299 void Reset() {CoTaskMemFree(pfc::replace_null_t(m_ptr));}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
300 TPtr * Receive() {Reset(); return &m_ptr;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
301
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
302 TPtr m_ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
303 PFC_CLASS_NOT_COPYABLE(CoTaskMemObject, CoTaskMemObject<TPtr> );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
304 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
305
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
306
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
307 namespace pfc {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
308 bool isShiftKeyPressed();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
309 bool isCtrlKeyPressed();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
310 bool isAltKeyPressed();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
311
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
312 class winHandle {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
313 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
314 winHandle(HANDLE h_ = INVALID_HANDLE_VALUE) : h(h_) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
315 ~winHandle() { Close(); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
316 void Close() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
317 if (h != INVALID_HANDLE_VALUE && h != NULL ) { CloseHandle(h); h = INVALID_HANDLE_VALUE; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
318 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
319
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
320 void Attach(HANDLE h_) { Close(); h = h_; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
321 HANDLE Detach() { HANDLE t = h; h = INVALID_HANDLE_VALUE; return t; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
322
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
323 HANDLE Get() const { return h; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
324 operator HANDLE() const { return h; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
325
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
326 HANDLE h;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
327 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
328 winHandle(const winHandle&) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
329 void operator=(const winHandle&) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
330 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
331
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
332 void winSleep( double seconds );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
333 void sleepSeconds(double seconds);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
334 void yield();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
335
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
336 #ifdef PFC_WINDOWS_DESKTOP_APP
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
337 void winSetThreadDescription(HANDLE hThread, const wchar_t * desc);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
338
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
339 pfc::string8 format_window(HWND wnd);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
340 pfc::string8 format_windowStyle(DWORD);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
341 #endif // PFC_WINDOWS_DESKTOP_APP
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
342
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
343 int winNaturalSortCompare(const char* s1, const char* s2);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
344 int winNaturalSortCompare(const wchar_t* s1, const wchar_t* s2);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
345 int winNaturalSortCompareI(const char* s1, const char* s2);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
346 int winNaturalSortCompareI(const wchar_t* s1, const wchar_t* s2);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
347
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
348 }