comparison foosdk/wtl/Include/atlwinx.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
comparison
equal deleted inserted replaced
0:e9bb126753e7 1:20d02a178406
1 // Windows Template Library - WTL version 10.0
2 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
3 //
4 // This file is a part of the Windows Template Library.
5 // The use and distribution terms for this software are covered by the
6 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
7 // which can be found in the file MS-PL.txt at the root folder.
8
9 #ifndef __ATLWINX_H__
10 #define __ATLWINX_H__
11
12 #pragma once
13
14 #ifndef __ATLAPP_H__
15 #error atlwinx.h requires atlapp.h to be included first
16 #endif
17
18 #include <atlwin.h>
19
20
21 ///////////////////////////////////////////////////////////////////////////////
22 // Classes in this file:
23 //
24 // CWindowEx
25
26
27 /////////////////////////////////////////////////////////////////////////////
28 // Additional macros needed for template classes
29
30 #ifndef DECLARE_WND_CLASS_EX2
31 #define DECLARE_WND_CLASS_EX2(WndClassName, EnclosingClass, style, bkgnd) \
32 static ATL::CWndClassInfo& GetWndClassInfo() \
33 { \
34 static ATL::CWndClassInfo wc = \
35 { \
36 { sizeof(WNDCLASSEX), style, EnclosingClass::StartWindowProc, \
37 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName, NULL }, \
38 NULL, NULL, IDC_ARROW, TRUE, 0, _T("") \
39 }; \
40 return wc; \
41 }
42 #endif // DECLARE_WND_CLASS_EX2
43
44 #ifndef DECLARE_WND_SUPERCLASS2
45 #define DECLARE_WND_SUPERCLASS2(WndClassName, EnclosingClass, OrigWndClassName) \
46 static ATL::CWndClassInfo& GetWndClassInfo() \
47 { \
48 static ATL::CWndClassInfo wc = \
49 { \
50 { sizeof(WNDCLASSEX), 0, EnclosingClass::StartWindowProc, \
51 0, 0, NULL, NULL, NULL, NULL, NULL, WndClassName, NULL }, \
52 OrigWndClassName, NULL, NULL, TRUE, 0, _T("") \
53 }; \
54 return wc; \
55 }
56 #endif // DECLARE_WND_SUPERCLASS2
57
58
59 ///////////////////////////////////////////////////////////////////////////////
60 // Command Chaining Macros
61
62 #define CHAIN_COMMANDS(theChainClass) \
63 if(uMsg == WM_COMMAND) \
64 CHAIN_MSG_MAP(theChainClass)
65
66 #define CHAIN_COMMANDS_ALT(theChainClass, msgMapID) \
67 if(uMsg == WM_COMMAND) \
68 CHAIN_MSG_MAP_ALT(theChainClass, msgMapID)
69
70 #define CHAIN_COMMANDS_MEMBER(theChainMember) \
71 if(uMsg == WM_COMMAND) \
72 CHAIN_MSG_MAP_MEMBER(theChainMember)
73
74 #define CHAIN_COMMANDS_ALT_MEMBER(theChainMember, msgMapID) \
75 if(uMsg == WM_COMMAND) \
76 CHAIN_MSG_MAP_ALT_MEMBER(theChainMember, msgMapID)
77
78
79 ///////////////////////////////////////////////////////////////////////////////
80 // Macros for parent message map to selectively reflect control messages
81
82 // NOTE: ReflectNotifications is a member of ATL's CWindowImplRoot
83 // (and overridden in 2 cases - CContainedWindowT and CAxHostWindow)
84 // Since we can't modify ATL, we'll provide the needed additions
85 // in a separate function (that is not a member of CWindowImplRoot)
86
87 namespace WTL
88 {
89
90 inline LRESULT WtlReflectNotificationsFiltered(HWND hWndParent, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled,
91 UINT uMsgFilter = WM_NULL, UINT_PTR idFromFilter = 0, HWND hWndChildFilter = NULL)
92 {
93 if((uMsgFilter != WM_NULL) && (uMsgFilter != uMsg))
94 {
95 // The notification message doesn't match the filter.
96 bHandled = FALSE;
97 return 1;
98 }
99
100 HWND hWndChild = NULL;
101 UINT_PTR idFrom = 0;
102
103 switch(uMsg)
104 {
105 case WM_COMMAND:
106 if(lParam != NULL) // not from a menu
107 {
108 hWndChild = (HWND)lParam;
109 idFrom = (UINT_PTR)LOWORD(wParam);
110 }
111 break;
112 case WM_NOTIFY:
113 hWndChild = ((LPNMHDR)lParam)->hwndFrom;
114 idFrom = ((LPNMHDR)lParam)->idFrom;
115 break;
116 case WM_PARENTNOTIFY:
117 switch(LOWORD(wParam))
118 {
119 case WM_CREATE:
120 case WM_DESTROY:
121 hWndChild = (HWND)lParam;
122 idFrom = (UINT_PTR)HIWORD(wParam);
123 break;
124 default:
125 hWndChild = ::GetDlgItem(hWndParent, HIWORD(wParam));
126 idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild);
127 break;
128 }
129 break;
130 case WM_DRAWITEM:
131 if(wParam) // not from a menu
132 {
133 hWndChild = ((LPDRAWITEMSTRUCT)lParam)->hwndItem;
134 idFrom = (UINT_PTR)wParam;
135 }
136 break;
137 case WM_MEASUREITEM:
138 if(wParam) // not from a menu
139 {
140 hWndChild = ::GetDlgItem(hWndParent, ((LPMEASUREITEMSTRUCT)lParam)->CtlID);
141 idFrom = (UINT_PTR)wParam;
142 }
143 break;
144 case WM_COMPAREITEM:
145 if(wParam) // not from a menu
146 {
147 hWndChild = ((LPCOMPAREITEMSTRUCT)lParam)->hwndItem;
148 idFrom = (UINT_PTR)wParam;
149 }
150 break;
151 case WM_DELETEITEM:
152 if(wParam) // not from a menu
153 {
154 hWndChild = ((LPDELETEITEMSTRUCT)lParam)->hwndItem;
155 idFrom = (UINT_PTR)wParam;
156 }
157 break;
158 case WM_VKEYTOITEM:
159 case WM_CHARTOITEM:
160 case WM_HSCROLL:
161 case WM_VSCROLL:
162 hWndChild = (HWND)lParam;
163 idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild);
164 break;
165 case WM_CTLCOLORBTN:
166 case WM_CTLCOLORDLG:
167 case WM_CTLCOLOREDIT:
168 case WM_CTLCOLORLISTBOX:
169 case WM_CTLCOLORMSGBOX:
170 case WM_CTLCOLORSCROLLBAR:
171 case WM_CTLCOLORSTATIC:
172 hWndChild = (HWND)lParam;
173 idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild);
174 break;
175 default:
176 break;
177 }
178
179 if((hWndChild == NULL) ||
180 ((hWndChildFilter != NULL) && (hWndChildFilter != hWndChild)))
181 {
182 // Either hWndChild isn't valid, or
183 // hWndChild doesn't match the filter.
184 bHandled = FALSE;
185 return 1;
186 }
187
188 if((idFromFilter != 0) && (idFromFilter != idFrom))
189 {
190 // The dialog control id doesn't match the filter.
191 bHandled = FALSE;
192 return 1;
193 }
194
195 ATLASSERT(::IsWindow(hWndChild));
196 LRESULT lResult = ::SendMessage(hWndChild, OCM__BASE + uMsg, wParam, lParam);
197 if((lResult == 0) && (uMsg >= WM_CTLCOLORMSGBOX) && (uMsg <= WM_CTLCOLORSTATIC))
198 {
199 // Try to prevent problems with WM_CTLCOLOR* messages when
200 // the message wasn't really handled
201 bHandled = FALSE;
202 }
203
204 return lResult;
205 }
206
207 } // namespace WTL
208
209 // Try to prevent problems with WM_CTLCOLOR* messages when
210 // the message wasn't really handled
211 #define REFLECT_NOTIFICATIONS_EX() \
212 { \
213 bHandled = TRUE; \
214 lResult = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
215 if((lResult == 0) && (uMsg >= WM_CTLCOLORMSGBOX) && (uMsg <= WM_CTLCOLORSTATIC)) \
216 bHandled = FALSE; \
217 if(bHandled) \
218 return TRUE; \
219 }
220
221 #define REFLECT_NOTIFICATIONS_MSG_FILTERED(uMsgFilter) \
222 { \
223 bHandled = TRUE; \
224 lResult = WTL::WtlReflectNotificationsFiltered(this->m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, 0, NULL); \
225 if(bHandled) \
226 return TRUE; \
227 }
228
229 #define REFLECT_NOTIFICATIONS_ID_FILTERED(idFromFilter) \
230 { \
231 bHandled = TRUE; \
232 lResult = WTL::WtlReflectNotificationsFiltered(this->m_hWnd, uMsg, wParam, lParam, bHandled, WM_NULL, idFromFilter, NULL); \
233 if(bHandled) \
234 return TRUE; \
235 }
236
237 #define REFLECT_NOTIFICATIONS_HWND_FILTERED(hWndChildFilter) \
238 { \
239 bHandled = TRUE; \
240 lResult = WTL::WtlReflectNotificationsFiltered(this->m_hWnd, uMsg, wParam, lParam, bHandled, WM_NULL, 0, hWndChildFilter); \
241 if(bHandled) \
242 return TRUE; \
243 }
244
245 #define REFLECT_NOTIFICATIONS_MSG_ID_FILTERED(uMsgFilter, idFromFilter) \
246 { \
247 bHandled = TRUE; \
248 lResult = WTL::WtlReflectNotificationsFiltered(this->m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, idFromFilter, NULL); \
249 if(bHandled) \
250 return TRUE; \
251 }
252
253 #define REFLECT_NOTIFICATIONS_MSG_HWND_FILTERED(uMsgFilter, hWndChildFilter) \
254 { \
255 bHandled = TRUE; \
256 lResult = WTL::WtlReflectNotificationsFiltered(this->m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, 0, hWndChildFilter); \
257 if(bHandled) \
258 return TRUE; \
259 }
260
261 #define REFLECT_COMMAND(id, code) \
262 if((uMsg == WM_COMMAND) && (id == LOWORD(wParam)) && (code == HIWORD(wParam))) \
263 { \
264 bHandled = TRUE; \
265 lResult = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
266 if(bHandled) \
267 return TRUE; \
268 }
269
270 #define REFLECT_COMMAND_ID(id) \
271 if((uMsg == WM_COMMAND) && (id == LOWORD(wParam))) \
272 { \
273 bHandled = TRUE; \
274 lResult = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
275 if(bHandled) \
276 return TRUE; \
277 }
278
279 #define REFLECT_COMMAND_CODE(code) \
280 if((uMsg == WM_COMMAND) && (code == HIWORD(wParam))) \
281 { \
282 bHandled = TRUE; \
283 lResult = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
284 if(bHandled) \
285 return TRUE; \
286 }
287
288 #define REFLECT_COMMAND_RANGE(idFirst, idLast) \
289 if((uMsg == WM_COMMAND) && (LOWORD(wParam) >= idFirst) && (LOWORD(wParam) <= idLast)) \
290 { \
291 bHandled = TRUE; \
292 lResult = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
293 if(bHandled) \
294 return TRUE; \
295 }
296
297 #define REFLECT_COMMAND_RANGE_CODE(idFirst, idLast, code) \
298 if((uMsg == WM_COMMAND) && (code == HIWORD(wParam)) && (LOWORD(wParam) >= idFirst) && (LOWORD(wParam) <= idLast)) \
299 { \
300 bHandled = TRUE; \
301 lResult = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
302 if(bHandled) \
303 return TRUE; \
304 }
305
306 #define REFLECT_NOTIFY(id, cd) \
307 if((uMsg == WM_NOTIFY) && (id == ((LPNMHDR)lParam)->idFrom) && (cd == ((LPNMHDR)lParam)->code)) \
308 { \
309 bHandled = TRUE; \
310 lResult = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
311 if(bHandled) \
312 return TRUE; \
313 }
314
315 #define REFLECT_NOTIFY_ID(id) \
316 if((uMsg == WM_NOTIFY) && (id == ((LPNMHDR)lParam)->idFrom)) \
317 { \
318 bHandled = TRUE; \
319 lResult = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
320 if(bHandled) \
321 return TRUE; \
322 }
323
324 #define REFLECT_NOTIFY_CODE(cd) \
325 if((uMsg == WM_NOTIFY) && (cd == ((LPNMHDR)lParam)->code)) \
326 { \
327 bHandled = TRUE; \
328 lResult = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
329 if(bHandled) \
330 return TRUE; \
331 }
332
333 #define REFLECT_NOTIFY_RANGE(idFirst, idLast) \
334 if((uMsg == WM_NOTIFY) && (((LPNMHDR)lParam)->idFrom >= idFirst) && (((LPNMHDR)lParam)->idFrom <= idLast)) \
335 { \
336 bHandled = TRUE; \
337 lResult = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
338 if(bHandled) \
339 return TRUE; \
340 }
341
342 #define REFLECT_NOTIFY_RANGE_CODE(idFirst, idLast, cd) \
343 if((uMsg == WM_NOTIFY) && (cd == ((LPNMHDR)lParam)->code) && (((LPNMHDR)lParam)->idFrom >= idFirst) && (((LPNMHDR)lParam)->idFrom <= idLast)) \
344 { \
345 bHandled = TRUE; \
346 lResult = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
347 if(bHandled) \
348 return TRUE; \
349 }
350
351
352 ///////////////////////////////////////////////////////////////////////////////
353 // GetClassLong/SetClassLong redefinition to avoid problems with class members
354
355 #ifdef SetClassLongPtrA
356 #undef SetClassLongPtrA
357 inline LONG_PTR SetClassLongPtrA(HWND hWnd, int nIndex, LONG_PTR dwNewLong)
358 {
359 return ::SetClassLongA(hWnd, nIndex, LONG(dwNewLong));
360 }
361 #endif
362
363 #ifdef SetClassLongPtrW
364 #undef SetClassLongPtrW
365 inline LONG_PTR SetClassLongPtrW(HWND hWnd, int nIndex, LONG_PTR dwNewLong)
366 {
367 return ::SetClassLongW(hWnd, nIndex, LONG(dwNewLong));
368 }
369 #endif
370
371 #ifdef GetClassLongPtrA
372 #undef GetClassLongPtrA
373 inline LONG_PTR GetClassLongPtrA(HWND hWnd, int nIndex)
374 {
375 return ::GetClassLongA(hWnd, nIndex);
376 }
377 #endif
378
379 #ifdef GetClassLongPtrW
380 #undef GetClassLongPtrW
381 inline LONG_PTR GetClassLongPtrW(HWND hWnd, int nIndex)
382 {
383 return ::GetClassLongW(hWnd, nIndex);
384 }
385 #endif
386
387
388 ///////////////////////////////////////////////////////////////////////////////
389 // CWindowEx - extension of ATL::CWindow
390
391 namespace WTL
392 {
393
394 class CWindowEx : public ATL::CWindow
395 {
396 public:
397 CWindowEx(HWND hWnd = NULL) : ATL::CWindow(hWnd)
398 { }
399
400 CWindowEx& operator =(HWND hWnd)
401 {
402 m_hWnd = hWnd;
403 return *this;
404 }
405
406 operator HWND() const
407 {
408 return m_hWnd;
409 }
410
411 // Methods
412 BOOL PrintWindow(HDC hDC, UINT uFlags = 0)
413 {
414 ATLASSERT(::IsWindow(m_hWnd));
415 return ::PrintWindow(m_hWnd, hDC, uFlags);
416 }
417
418 BOOL DragDetect(POINT pt)
419 {
420 ATLASSERT(::IsWindow(m_hWnd));
421 return ::DragDetect(m_hWnd, pt);
422 }
423
424 BOOL DragDetect()
425 {
426 ATLASSERT(::IsWindow(m_hWnd));
427
428 POINT pt = {};
429 ::GetCursorPos(&pt);
430 return ::DragDetect(m_hWnd, pt);
431 }
432
433 CWindowEx GetAncestor(UINT uFlags) const
434 {
435 ATLASSERT(::IsWindow(m_hWnd));
436 return CWindowEx(::GetAncestor(m_hWnd, uFlags));
437 }
438
439 // Note: Does not work properly on Vista Aero and above
440 BOOL AnimateWindow(DWORD dwFlags, DWORD dwTime = 200)
441 {
442 ATLASSERT(::IsWindow(m_hWnd));
443 return ::AnimateWindow(m_hWnd, dwTime, dwFlags);
444 }
445
446 BOOL FlashWindowEx(DWORD dwFlags, UINT uCount, DWORD dwTimeout = 0)
447 {
448 ATLASSERT(::IsWindow(m_hWnd));
449
450 FLASHWINFO fi = { sizeof(FLASHWINFO) };
451 fi.hwnd = m_hWnd;
452 fi.dwFlags = dwFlags;
453 fi.uCount = uCount;
454 fi.dwTimeout = dwTimeout;
455 return ::FlashWindowEx(&fi);
456 }
457
458 BOOL StopFlashWindowEx()
459 {
460 ATLASSERT(::IsWindow(m_hWnd));
461
462 FLASHWINFO fi = { sizeof(FLASHWINFO) };
463 fi.hwnd = m_hWnd;
464 fi.dwFlags = FLASHW_STOP;
465 return ::FlashWindowEx(&fi);
466 }
467
468 // Class long properties
469 DWORD GetClassLong(int nIndex) const
470 {
471 ATLASSERT(::IsWindow(m_hWnd));
472 return ::GetClassLong(m_hWnd, nIndex);
473 }
474
475 DWORD SetClassLong(int nIndex, LONG dwNewLong)
476 {
477 ATLASSERT(::IsWindow(m_hWnd));
478 return ::SetClassLong(m_hWnd, nIndex, dwNewLong);
479 }
480
481 ULONG_PTR GetClassLongPtr(int nIndex) const
482 {
483 ATLASSERT(::IsWindow(m_hWnd));
484 return ::GetClassLongPtr(m_hWnd, nIndex);
485 }
486
487 ULONG_PTR SetClassLongPtr(int nIndex, LONG_PTR dwNewLong)
488 {
489 ATLASSERT(::IsWindow(m_hWnd));
490 return ::SetClassLongPtr(m_hWnd, nIndex, dwNewLong);
491 }
492
493 // Layered windows
494 BOOL SetLayeredWindowAttributes(COLORREF crlKey, BYTE byteAlpha, DWORD dwFlags)
495 {
496 ATLASSERT(::IsWindow(m_hWnd));
497 ATLASSERT((GetExStyle() & WS_EX_LAYERED) != 0);
498
499 return ::SetLayeredWindowAttributes(m_hWnd, crlKey, byteAlpha, dwFlags);
500 }
501
502 BOOL UpdateLayeredWindow(HDC hdcDst, LPPOINT pptDst, LPSIZE psize, HDC hdcSrc, LPPOINT pptSrc, COLORREF crlKey, BLENDFUNCTION* pblend, DWORD dwFlags)
503 {
504 ATLASSERT(::IsWindow(m_hWnd));
505 ATLASSERT((GetExStyle() & WS_EX_LAYERED) != 0);
506
507 return ::UpdateLayeredWindow(m_hWnd, hdcDst, pptDst, psize, hdcSrc, pptSrc, crlKey, pblend, dwFlags);
508 }
509
510 BOOL UpdateLayeredWindow(LPPOINT pptDst = NULL)
511 {
512 ATLASSERT(::IsWindow(m_hWnd));
513 ATLASSERT((GetExStyle() & WS_EX_LAYERED) != 0);
514
515 return ::UpdateLayeredWindow(m_hWnd, NULL, pptDst, NULL, NULL, NULL, CLR_NONE, NULL, 0);
516 }
517
518 BOOL GetLayeredWindowAttributes(COLORREF* pcrlKey, BYTE* pbyteAlpha, DWORD* pdwFlags) const
519 {
520 ATLASSERT(::IsWindow(m_hWnd));
521 ATLASSERT((GetExStyle() & WS_EX_LAYERED) != 0);
522
523 return ::GetLayeredWindowAttributes(m_hWnd, pcrlKey, pbyteAlpha, pdwFlags);
524 }
525
526 // Mouse tracking
527 BOOL StartTrackMouseLeave()
528 {
529 ATLASSERT(::IsWindow(m_hWnd));
530
531 TRACKMOUSEEVENT tme = {};
532 tme.cbSize = sizeof(TRACKMOUSEEVENT);
533 tme.dwFlags = TME_LEAVE;
534 tme.hwndTrack = m_hWnd;
535 return ::TrackMouseEvent(&tme);
536 }
537
538 BOOL StartTrackMouse(DWORD dwFlags, DWORD dwHoverTime = HOVER_DEFAULT)
539 {
540 ATLASSERT(::IsWindow(m_hWnd));
541
542 TRACKMOUSEEVENT tme = {};
543 tme.cbSize = sizeof(TRACKMOUSEEVENT);
544 tme.dwFlags = dwFlags;
545 tme.hwndTrack = m_hWnd;
546 tme.dwHoverTime = dwHoverTime;
547 return ::TrackMouseEvent(&tme);
548 }
549
550 BOOL CancelTrackMouse(DWORD dwType)
551 {
552 ATLASSERT(::IsWindow(m_hWnd));
553
554 TRACKMOUSEEVENT tme = {};
555 tme.cbSize = sizeof(TRACKMOUSEEVENT);
556 tme.dwFlags = TME_CANCEL | dwType;
557 tme.hwndTrack = m_hWnd;
558 return ::TrackMouseEvent(&tme);
559 }
560
561 // CString support
562 #ifdef __ATLSTR_H__
563 int GetWindowText(ATL::CString& strText) const
564 {
565 int nLength = GetWindowTextLength();
566 LPTSTR pszText = strText.GetBuffer(nLength + 1);
567 nLength = ::GetWindowText(m_hWnd, pszText, nLength + 1);
568 strText.ReleaseBuffer(nLength);
569
570 return nLength;
571 }
572
573 UINT GetDlgItemText(int nID, ATL::CString& strText) const
574 {
575 ATLASSERT(::IsWindow(m_hWnd));
576
577 HWND hItem = GetDlgItem(nID);
578 if(hItem != NULL)
579 {
580 int nLength = ::GetWindowTextLength(hItem);
581 LPTSTR pszText = strText.GetBuffer(nLength + 1);
582 nLength = ::GetWindowText(hItem, pszText, nLength + 1);
583 strText.ReleaseBuffer(nLength);
584
585 return nLength;
586 }
587 else
588 {
589 strText.Empty();
590
591 return 0;
592 }
593 }
594 #endif // __ATLSTR_H__
595 };
596
597 } // namespace WTL
598
599 #endif // __ATLWINX_H__