You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1403 lines
44 KiB
1403 lines
44 KiB
// This is a part of the Active Template Library.
|
|
// Copyright (C) 1996-1997 Microsoft Corporation
|
|
// All rights reserved.
|
|
//
|
|
// This source code is only intended as a supplement to the
|
|
// Active Template Library Reference and related
|
|
// electronic documentation provided with the library.
|
|
// See these sources for detailed information regarding the
|
|
// Active Template Library product.
|
|
|
|
#ifndef __ATLWIN_H__
|
|
#define __ATLWIN_H__
|
|
|
|
#ifndef __cplusplus
|
|
#error ATL requires C++ compilation (use a .cpp suffix)
|
|
#endif
|
|
|
|
#ifndef __ATLBASE_H__
|
|
#error atlwin.h requires atlbase.h to be included first
|
|
#endif
|
|
|
|
#ifndef WS_EX_NOINHERITLAYOUT
|
|
#define WS_EX_NOINHERITLAYOUT 0x00100000L // Disable inheritence of mirroring by children
|
|
#endif
|
|
#ifndef WS_EX_LAYOUTRTL
|
|
#define WS_EX_LAYOUTRTL 0x00400000L // Right to left mirroring
|
|
#endif
|
|
#ifndef NOMIRRORBITMAP
|
|
#define NOMIRRORBITMAP (DWORD)0x80000000 // Do not Mirror the bitmap in this call
|
|
#endif
|
|
#ifndef LAYOUT_RTL
|
|
#define LAYOUT_RTL 0x00000001 // Right to left
|
|
#endif
|
|
#ifndef LAYOUT_BTT
|
|
#define LAYOUT_BTT 0x00000002 // Bottom to top
|
|
#endif
|
|
#ifndef LAYOUT_VBH
|
|
#define LAYOUT_VBH 0x00000004 // Vertical before horizontal
|
|
#endif
|
|
#ifndef LAYOUT_ORIENTATIONMASK
|
|
#define LAYOUT_ORIENTATIONMASK LAYOUT_RTL | LAYOUT_BTT | LAYOUT_VBH
|
|
#endif
|
|
#ifndef LAYOUT_BITMAPORIENTATIONPRESERVED
|
|
#define LAYOUT_BITMAPORIENTATIONPRESERVED 0x00000008
|
|
#endif
|
|
|
|
#ifdef SubclassWindow
|
|
#pragma push_macro( "SubclassWindow" )
|
|
#define _ATL_REDEF_SUBCLASSWINDOW
|
|
#undef SubclassWindow
|
|
#endif
|
|
|
|
#ifndef ATL_NO_NAMESPACE
|
|
namespace ATL
|
|
{
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Forward declarations
|
|
|
|
class CWindow;
|
|
class CMessageMap;
|
|
class CDynamicChain;
|
|
class CWndClassInfo;
|
|
template <class T> class CWindowImpl;
|
|
template <class T> class CDialogImpl;
|
|
class CContainedWindow;
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CWindow - client side for a Windows window
|
|
|
|
class CWindow
|
|
{
|
|
public:
|
|
HWND m_hWnd;
|
|
|
|
CWindow(HWND hWnd = NULL)
|
|
{
|
|
m_hWnd = hWnd;
|
|
}
|
|
|
|
CWindow& operator=(HWND hWnd)
|
|
{
|
|
m_hWnd = hWnd;
|
|
return *this;
|
|
}
|
|
|
|
void Attach(HWND hWndNew)
|
|
{
|
|
_ASSERTE(::IsWindow(hWndNew));
|
|
m_hWnd = hWndNew;
|
|
}
|
|
|
|
HWND Detach()
|
|
{
|
|
HWND hWnd = m_hWnd;
|
|
m_hWnd = NULL;
|
|
return hWnd;
|
|
}
|
|
|
|
BOOL DestroyWindow()
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
|
|
if(!::DestroyWindow(m_hWnd))
|
|
return FALSE;
|
|
|
|
m_hWnd = NULL;
|
|
return TRUE;
|
|
}
|
|
|
|
// Attributes
|
|
|
|
operator HWND() const { return m_hWnd; }
|
|
|
|
DWORD GetStyle() const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return (DWORD)::GetWindowLong(m_hWnd, GWL_STYLE);
|
|
}
|
|
|
|
DWORD GetExStyle() const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return (DWORD)::GetWindowLong(m_hWnd, GWL_EXSTYLE);
|
|
}
|
|
|
|
BOOL ModifyStyle(DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0);
|
|
BOOL ModifyStyleEx(DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0);
|
|
|
|
LONG GetWindowLong(int nIndex) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetWindowLong(m_hWnd, nIndex);
|
|
}
|
|
|
|
LONG SetWindowLong(int nIndex, LONG dwNewLong)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::SetWindowLong(m_hWnd, nIndex, dwNewLong);
|
|
}
|
|
|
|
WORD GetWindowWord(int nIndex) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetWindowWord(m_hWnd, nIndex);
|
|
}
|
|
|
|
WORD SetWindowWord(int nIndex, WORD wNewWord)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::SetWindowWord(m_hWnd, nIndex, wNewWord);
|
|
}
|
|
|
|
// Message Functions
|
|
|
|
LRESULT SendMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::SendMessage(m_hWnd,message,wParam,lParam);
|
|
}
|
|
|
|
BOOL PostMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::PostMessage(m_hWnd,message,wParam,lParam);
|
|
}
|
|
|
|
BOOL SendNotifyMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::SendNotifyMessage(m_hWnd, message, wParam, lParam);
|
|
}
|
|
|
|
// Window Text Functions
|
|
|
|
BOOL SetWindowText(LPCTSTR lpszString)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::SetWindowText(m_hWnd, lpszString);
|
|
}
|
|
|
|
int GetWindowText(LPTSTR lpszStringBuf, int nMaxCount) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetWindowText(m_hWnd, lpszStringBuf, nMaxCount);
|
|
}
|
|
|
|
int GetWindowTextLength() const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetWindowTextLength(m_hWnd);
|
|
}
|
|
|
|
BOOL GetWindowText(BSTR& bstrText);
|
|
|
|
// Font Functions
|
|
|
|
void SetFont(HFONT hFont, BOOL bRedraw = TRUE)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
::SendMessage(m_hWnd, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(bRedraw, 0));
|
|
}
|
|
|
|
HFONT GetFont() const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return (HFONT)::SendMessage(m_hWnd, WM_GETFONT, 0, 0);
|
|
}
|
|
|
|
// Menu Functions (non-child windows only)
|
|
#if defined(_WINUSER_) && !defined(NOMENUS)
|
|
HMENU GetMenu() const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetMenu(m_hWnd);
|
|
}
|
|
|
|
BOOL SetMenu(HMENU hMenu)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::SetMenu(m_hWnd, hMenu);
|
|
}
|
|
|
|
BOOL DrawMenuBar()
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::DrawMenuBar(m_hWnd);
|
|
}
|
|
|
|
HMENU GetSystemMenu(BOOL bRevert) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetSystemMenu(m_hWnd, bRevert);
|
|
}
|
|
|
|
BOOL HiliteMenuItem(HMENU hMenu, UINT uItemHilite, UINT uHilite)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::HiliteMenuItem(m_hWnd, hMenu, uItemHilite, uHilite);
|
|
}
|
|
#endif
|
|
// Window Size and Position Functions
|
|
|
|
BOOL IsIconic() const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::IsIconic(m_hWnd);
|
|
}
|
|
|
|
BOOL IsZoomed() const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::IsZoomed(m_hWnd);
|
|
}
|
|
|
|
BOOL MoveWindow(int x, int y, int nWidth, int nHeight, BOOL bRepaint = TRUE)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::MoveWindow(m_hWnd, x, y, nWidth, nHeight, bRepaint);
|
|
}
|
|
|
|
BOOL MoveWindow(LPCRECT lpRect, BOOL bRepaint = TRUE)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::MoveWindow(m_hWnd, lpRect->left, lpRect->top, lpRect->right - lpRect->left, lpRect->bottom - lpRect->top, bRepaint);
|
|
}
|
|
|
|
BOOL SetWindowPos(HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT nFlags)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::SetWindowPos(m_hWnd, hWndInsertAfter, x, y, cx, cy, nFlags);
|
|
}
|
|
|
|
BOOL SetWindowPos(HWND hWndInsertAfter, LPCRECT lpRect, UINT nFlags)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::SetWindowPos(m_hWnd, hWndInsertAfter, lpRect->left, lpRect->top, lpRect->right - lpRect->left, lpRect->bottom - lpRect->top, nFlags);
|
|
}
|
|
|
|
#if defined(_WINUSER_) && !defined(NOMDI)
|
|
UINT ArrangeIconicWindows()
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::ArrangeIconicWindows(m_hWnd);
|
|
}
|
|
#endif
|
|
BOOL BringWindowToTop()
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::BringWindowToTop(m_hWnd);
|
|
}
|
|
|
|
BOOL GetWindowRect(LPRECT lpRect) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetWindowRect(m_hWnd, lpRect);
|
|
}
|
|
|
|
BOOL GetClientRect(LPRECT lpRect) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetClientRect(m_hWnd, lpRect);
|
|
}
|
|
|
|
BOOL GetWindowPlacement(WINDOWPLACEMENT FAR* lpwndpl) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetWindowPlacement(m_hWnd, lpwndpl);
|
|
}
|
|
|
|
BOOL SetWindowPlacement(const WINDOWPLACEMENT FAR* lpwndpl)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::SetWindowPlacement(m_hWnd, lpwndpl);
|
|
}
|
|
|
|
// Coordinate Mapping Functions
|
|
|
|
BOOL ClientToScreen(LPPOINT lpPoint) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::ClientToScreen(m_hWnd, lpPoint);
|
|
}
|
|
|
|
BOOL ClientToScreen(LPRECT lpRect) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
if(!::ClientToScreen(m_hWnd, (LPPOINT)lpRect))
|
|
return FALSE;
|
|
if(!::ClientToScreen(m_hWnd, ((LPPOINT)lpRect)+1))
|
|
return FALSE;
|
|
if (GetExStyle() & WS_EX_LAYOUTRTL) {
|
|
// Swap left and right
|
|
LONG temp = lpRect->left;
|
|
lpRect->left = lpRect->right;
|
|
lpRect->right = temp;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL ScreenToClient(LPPOINT lpPoint) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::ScreenToClient(m_hWnd, lpPoint);
|
|
}
|
|
|
|
BOOL ScreenToClient(LPRECT lpRect) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
if(!::ScreenToClient(m_hWnd, (LPPOINT)lpRect))
|
|
return FALSE;
|
|
if(!::ScreenToClient(m_hWnd, ((LPPOINT)lpRect)+1))
|
|
return FALSE;
|
|
if (GetExStyle() & WS_EX_LAYOUTRTL) {
|
|
// Swap left and right
|
|
LONG temp = lpRect->left;
|
|
lpRect->left = lpRect->right;
|
|
lpRect->right = temp;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
int MapWindowPoints(HWND hWndTo, LPPOINT lpPoint, UINT nCount) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::MapWindowPoints(m_hWnd, hWndTo, lpPoint, nCount);
|
|
}
|
|
|
|
int MapWindowPoints(HWND hWndTo, LPRECT lpRect) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::MapWindowPoints(m_hWnd, hWndTo, (LPPOINT)lpRect, 2);
|
|
}
|
|
|
|
// Update and Painting Functions
|
|
|
|
HDC BeginPaint(LPPAINTSTRUCT lpPaint)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::BeginPaint(m_hWnd, lpPaint);
|
|
}
|
|
|
|
void EndPaint(LPPAINTSTRUCT lpPaint)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
::EndPaint(m_hWnd, lpPaint);
|
|
}
|
|
|
|
HDC GetDC()
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetDC(m_hWnd);
|
|
}
|
|
|
|
HDC GetWindowDC()
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetWindowDC(m_hWnd);
|
|
}
|
|
|
|
int ReleaseDC(HDC hDC)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::ReleaseDC(m_hWnd, hDC);
|
|
}
|
|
|
|
void Print(HDC hDC, DWORD dwFlags) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
::SendMessage(m_hWnd, WM_PRINT, (WPARAM)hDC, dwFlags);
|
|
}
|
|
|
|
void PrintClient(HDC hDC, DWORD dwFlags) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
::SendMessage(m_hWnd, WM_PRINTCLIENT, (WPARAM)hDC, dwFlags);
|
|
}
|
|
|
|
BOOL UpdateWindow()
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::UpdateWindow(m_hWnd);
|
|
}
|
|
|
|
void SetRedraw(BOOL bRedraw = TRUE)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
::SendMessage(m_hWnd, WM_SETREDRAW, (WPARAM)bRedraw, 0);
|
|
}
|
|
|
|
BOOL GetUpdateRect(LPRECT lpRect, BOOL bErase = FALSE)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetUpdateRect(m_hWnd, lpRect, bErase);
|
|
}
|
|
|
|
int GetUpdateRgn(HRGN hRgn, BOOL bErase = FALSE)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetUpdateRgn(m_hWnd, hRgn, bErase);
|
|
}
|
|
|
|
BOOL Invalidate(BOOL bErase = TRUE)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::InvalidateRect(m_hWnd, NULL, bErase);
|
|
}
|
|
|
|
BOOL InvalidateRect(LPCRECT lpRect, BOOL bErase = TRUE)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::InvalidateRect(m_hWnd, lpRect, bErase);
|
|
}
|
|
|
|
void InvalidateRgn(HRGN hRgn, BOOL bErase = TRUE)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
::InvalidateRgn(m_hWnd, hRgn, bErase);
|
|
}
|
|
|
|
BOOL ValidateRect(LPCRECT lpRect)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::ValidateRect(m_hWnd, lpRect);
|
|
}
|
|
|
|
BOOL ValidateRgn(HRGN hRgn)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::ValidateRgn(m_hWnd, hRgn);
|
|
}
|
|
|
|
BOOL ShowWindow(int nCmdShow)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::ShowWindow(m_hWnd, nCmdShow);
|
|
}
|
|
|
|
BOOL IsWindowVisible() const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::IsWindowVisible(m_hWnd);
|
|
}
|
|
|
|
BOOL ShowOwnedPopups(BOOL bShow = TRUE)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::ShowOwnedPopups(m_hWnd, bShow);
|
|
}
|
|
|
|
HDC GetDCEx(HRGN hRgnClip, DWORD flags)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetDCEx(m_hWnd, hRgnClip, flags);
|
|
}
|
|
|
|
BOOL LockWindowUpdate(BOOL bLock = TRUE)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::LockWindowUpdate(bLock ? m_hWnd : NULL);
|
|
}
|
|
|
|
BOOL RedrawWindow(LPCRECT lpRectUpdate = NULL, HRGN hRgnUpdate = NULL, UINT flags = RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::RedrawWindow(m_hWnd, lpRectUpdate, hRgnUpdate, flags);
|
|
}
|
|
|
|
// Timer Functions
|
|
|
|
UINT_PTR SetTimer(UINT_PTR nIDEvent, UINT nElapse, void (CALLBACK* lpfnTimer)(HWND, UINT, UINT_PTR, DWORD))
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::SetTimer(m_hWnd, nIDEvent, nElapse, (TIMERPROC)lpfnTimer);
|
|
}
|
|
|
|
BOOL KillTimer(UINT_PTR nIDEvent)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::KillTimer(m_hWnd, nIDEvent);
|
|
}
|
|
|
|
// Window State Functions
|
|
|
|
BOOL IsWindowEnabled() const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::IsWindowEnabled(m_hWnd);
|
|
}
|
|
|
|
BOOL EnableWindow(BOOL bEnable = TRUE)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::EnableWindow(m_hWnd, bEnable);
|
|
}
|
|
|
|
HWND SetActiveWindow()
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::SetActiveWindow(m_hWnd);
|
|
}
|
|
|
|
HWND SetCapture()
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::SetCapture(m_hWnd);
|
|
}
|
|
|
|
HWND SetFocus()
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::SetFocus(m_hWnd);
|
|
}
|
|
|
|
// Dialog-Box Item Functions
|
|
|
|
BOOL CheckDlgButton(int nIDButton, UINT nCheck)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::CheckDlgButton(m_hWnd, nIDButton, nCheck);
|
|
}
|
|
|
|
BOOL CheckRadioButton(int nIDFirstButton, int nIDLastButton, int nIDCheckButton)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::CheckRadioButton(m_hWnd, nIDFirstButton, nIDLastButton, nIDCheckButton);
|
|
}
|
|
|
|
int DlgDirList(LPTSTR lpPathSpec, int nIDListBox, int nIDStaticPath, UINT nFileType)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::DlgDirList(m_hWnd, lpPathSpec, nIDListBox, nIDStaticPath, nFileType);
|
|
}
|
|
|
|
int DlgDirListComboBox(LPTSTR lpPathSpec, int nIDComboBox, int nIDStaticPath, UINT nFileType)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::DlgDirListComboBox(m_hWnd, lpPathSpec, nIDComboBox, nIDStaticPath, nFileType);
|
|
}
|
|
|
|
BOOL DlgDirSelect(LPTSTR lpString, int nCount, int nIDListBox)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::DlgDirSelectEx(m_hWnd, lpString, nCount, nIDListBox);
|
|
}
|
|
|
|
BOOL DlgDirSelectComboBox(LPTSTR lpString, int nCount, int nIDComboBox)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::DlgDirSelectComboBoxEx(m_hWnd, lpString, nCount, nIDComboBox);
|
|
}
|
|
|
|
UINT GetDlgItemInt(int nID, BOOL* lpTrans = NULL, BOOL bSigned = TRUE) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetDlgItemInt(m_hWnd, nID, lpTrans, bSigned);
|
|
}
|
|
|
|
UINT GetDlgItemText(int nID, LPTSTR lpStr, int nMaxCount) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetDlgItemText(m_hWnd, nID, lpStr, nMaxCount);
|
|
}
|
|
|
|
BOOL GetDlgItemText(int nID, BSTR& bstrText) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
|
|
HWND hWndCtl = GetDlgItem(nID);
|
|
if(hWndCtl == NULL)
|
|
return FALSE;
|
|
|
|
return CWindow(hWndCtl).GetWindowText(bstrText);
|
|
}
|
|
|
|
HWND GetNextDlgGroupItem(HWND hWndCtl, BOOL bPrevious = FALSE) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetNextDlgGroupItem(m_hWnd, hWndCtl, bPrevious);
|
|
}
|
|
|
|
HWND GetNextDlgTabItem(HWND hWndCtl, BOOL bPrevious = FALSE) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetNextDlgTabItem(m_hWnd, hWndCtl, bPrevious);
|
|
}
|
|
|
|
UINT IsDlgButtonChecked(int nIDButton) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::IsDlgButtonChecked(m_hWnd, nIDButton);
|
|
}
|
|
|
|
LRESULT SendDlgItemMessage(int nID, UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::SendDlgItemMessage(m_hWnd, nID, message, wParam, lParam);
|
|
}
|
|
|
|
BOOL SetDlgItemInt(int nID, UINT nValue, BOOL bSigned = TRUE)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::SetDlgItemInt(m_hWnd, nID, nValue, bSigned);
|
|
}
|
|
|
|
BOOL SetDlgItemText(int nID, LPCTSTR lpszString)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::SetDlgItemText(m_hWnd, nID, lpszString);
|
|
}
|
|
|
|
// Scrolling Functions
|
|
|
|
int GetScrollPos(int nBar) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetScrollPos(m_hWnd, nBar);
|
|
}
|
|
|
|
BOOL GetScrollRange(int nBar, LPINT lpMinPos, LPINT lpMaxPos) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetScrollRange(m_hWnd, nBar, lpMinPos, lpMaxPos);
|
|
}
|
|
|
|
BOOL ScrollWindow(int xAmount, int yAmount, LPCRECT lpRect = NULL, LPCRECT lpClipRect = NULL)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::ScrollWindow(m_hWnd, xAmount, yAmount, lpRect, lpClipRect);
|
|
}
|
|
|
|
int ScrollWindowEx(int dx, int dy, LPCRECT lpRectScroll, LPCRECT lpRectClip, HRGN hRgnUpdate, LPRECT lpRectUpdate, UINT flags)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::ScrollWindowEx(m_hWnd, dx, dy, lpRectScroll, lpRectClip, hRgnUpdate, lpRectUpdate, flags);
|
|
}
|
|
|
|
int SetScrollPos(int nBar, int nPos, BOOL bRedraw = TRUE)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::SetScrollPos(m_hWnd, nBar, nPos, bRedraw);
|
|
}
|
|
|
|
BOOL SetScrollRange(int nBar, int nMinPos, int nMaxPos, BOOL bRedraw = TRUE)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::SetScrollRange(m_hWnd, nBar, nMinPos, nMaxPos, bRedraw);
|
|
}
|
|
|
|
BOOL ShowScrollBar(UINT nBar, BOOL bShow = TRUE)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::ShowScrollBar(m_hWnd, nBar, bShow);
|
|
}
|
|
|
|
BOOL EnableScrollBar(UINT uSBFlags, UINT uArrowFlags = ESB_ENABLE_BOTH)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::EnableScrollBar(m_hWnd, uSBFlags, uArrowFlags);
|
|
}
|
|
|
|
// Window Access Functions
|
|
|
|
HWND ChildWindowFromPoint(POINT point) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::ChildWindowFromPoint(m_hWnd, point);
|
|
}
|
|
|
|
HWND ChildWindowFromPointEx(POINT point, UINT uFlags) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::ChildWindowFromPointEx(m_hWnd, point, uFlags);
|
|
}
|
|
|
|
HWND GetTopWindow() const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetTopWindow(m_hWnd);
|
|
}
|
|
|
|
HWND GetWindow(UINT nCmd) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetWindow(m_hWnd, nCmd);
|
|
}
|
|
|
|
HWND GetLastActivePopup() const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetLastActivePopup(m_hWnd);
|
|
}
|
|
|
|
BOOL IsChild(HWND hWnd) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::IsChild(m_hWnd, hWnd);
|
|
}
|
|
|
|
HWND GetParent() const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetParent(m_hWnd);
|
|
}
|
|
|
|
HWND SetParent(HWND hWndNewParent)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::SetParent(m_hWnd, hWndNewParent);
|
|
}
|
|
|
|
// Window Tree Access
|
|
|
|
int GetDlgCtrlID() const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetDlgCtrlID(m_hWnd);
|
|
}
|
|
|
|
int SetDlgCtrlID(int nID)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return (int)::SetWindowLong(m_hWnd, GWL_ID, nID);
|
|
}
|
|
|
|
HWND GetDlgItem(int nID) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetDlgItem(m_hWnd, nID);
|
|
}
|
|
|
|
HWND GetDescendantWindow(int nID) const;
|
|
|
|
void SendMessageToDescendants(UINT message, WPARAM wParam = 0, LPARAM lParam = 0, BOOL bDeep = TRUE);
|
|
|
|
// Alert Functions
|
|
|
|
BOOL FlashWindow(BOOL bInvert)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::FlashWindow(m_hWnd, bInvert);
|
|
}
|
|
|
|
int MessageBox(LPCTSTR lpszText, LPCTSTR lpszCaption = NULL, UINT nType = MB_OK)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::MessageBox(m_hWnd, lpszText, lpszCaption, nType);
|
|
}
|
|
|
|
// Clipboard Functions
|
|
|
|
BOOL ChangeClipboardChain(HWND hWndNewNext)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::ChangeClipboardChain(m_hWnd, hWndNewNext);
|
|
}
|
|
|
|
HWND SetClipboardViewer()
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::SetClipboardViewer(m_hWnd);
|
|
}
|
|
|
|
BOOL OpenClipboard()
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::OpenClipboard(m_hWnd);
|
|
}
|
|
|
|
// Caret Functions
|
|
|
|
BOOL CreateCaret(HBITMAP hBitmap)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::CreateCaret(m_hWnd, hBitmap, 0, 0);
|
|
}
|
|
|
|
BOOL CreateSolidCaret(int nWidth, int nHeight)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::CreateCaret(m_hWnd, (HBITMAP)0, nWidth, nHeight);
|
|
}
|
|
|
|
BOOL CreateGrayCaret(int nWidth, int nHeight)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::CreateCaret(m_hWnd, (HBITMAP)1, nWidth, nHeight);
|
|
}
|
|
|
|
BOOL HideCaret()
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::HideCaret(m_hWnd);
|
|
}
|
|
|
|
BOOL ShowCaret()
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::ShowCaret(m_hWnd);
|
|
}
|
|
|
|
// Drag-Drop Functions
|
|
#ifdef _INC_SHELLAPI
|
|
void DragAcceptFiles(BOOL bAccept = TRUE)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd)); ::DragAcceptFiles(m_hWnd, bAccept);
|
|
}
|
|
#endif
|
|
// Icon Functions
|
|
|
|
HICON SetIcon(HICON hIcon, BOOL bBigIcon = TRUE)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return (HICON)::SendMessage(m_hWnd, WM_SETICON, bBigIcon, (LPARAM)hIcon);
|
|
}
|
|
|
|
HICON GetIcon(BOOL bBigIcon = TRUE) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return (HICON)::SendMessage(m_hWnd, WM_GETICON, bBigIcon, 0);
|
|
}
|
|
|
|
// Help Functions
|
|
#if defined(_WINUSER_) && !defined(NOHELP)
|
|
|
|
BOOL WinHelp(LPCTSTR lpszHelp, UINT nCmd = HELP_CONTEXT, DWORD_PTR dwData = 0)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::WinHelp(m_hWnd, lpszHelp, nCmd, dwData);
|
|
}
|
|
|
|
BOOL SetWindowContextHelpId(DWORD dwContextHelpId)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::SetWindowContextHelpId(m_hWnd, dwContextHelpId);
|
|
}
|
|
|
|
DWORD GetWindowContextHelpId() const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return ::GetWindowContextHelpId(m_hWnd);
|
|
}
|
|
#endif
|
|
// Hot Key Functions
|
|
|
|
int SetHotKey(WORD wVirtualKeyCode, WORD wModifiers)
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return (int)::SendMessage(m_hWnd, WM_SETHOTKEY, MAKEWORD(wVirtualKeyCode, wModifiers), 0);
|
|
}
|
|
|
|
DWORD GetHotKey(WORD& /* wVirtualKeyCode */, WORD& /* wModifiers */) const
|
|
{
|
|
_ASSERTE(::IsWindow(m_hWnd));
|
|
return (DWORD)::SendMessage(m_hWnd, WM_GETHOTKEY, 0, 0);
|
|
}
|
|
|
|
// Misc. Operations
|
|
|
|
BOOL CenterWindow(HWND hWndCenter = NULL);
|
|
|
|
HWND GetTopLevelParent() const;
|
|
HWND GetTopLevelWindow() const;
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Thunks for __stdcall member functions
|
|
|
|
#if defined(_M_IX86)
|
|
#pragma pack(push,1)
|
|
struct _stdcallthunk
|
|
{
|
|
DWORD m_mov; // mov dword ptr [esp+0x4], pThis (esp+0x4 is hWnd)
|
|
DWORD m_this; //
|
|
BYTE m_jmp; // jmp WndProc
|
|
DWORD m_relproc; // relative jmp
|
|
void Init(DWORD_PTR proc, void* pThis)
|
|
{
|
|
m_mov = 0x042444C7; //C7 44 24 0C
|
|
m_this = PtrToUlong(pThis);
|
|
m_jmp = 0xe9;
|
|
m_relproc = DWORD((INT_PTR)proc - ((INT_PTR)this+sizeof(_stdcallthunk)));
|
|
// write block from data cache and
|
|
// flush from instruction cache
|
|
FlushInstructionCache(GetCurrentProcess(), this, sizeof(_stdcallthunk));
|
|
}
|
|
};
|
|
#pragma pack(pop)
|
|
#elif defined (_M_AMD64)
|
|
#pragma pack(push,2)
|
|
struct _stdcallthunk
|
|
{
|
|
USHORT RcxMov; // mov rcx, pThis
|
|
ULONG64 RcxImm; //
|
|
USHORT RaxMov; // mov rax, target
|
|
ULONG64 RaxImm; //
|
|
USHORT RaxJmp; // jmp target
|
|
void Init(DWORD_PTR proc, void *pThis)
|
|
{
|
|
RcxMov = 0xb948; // mov rcx, pThis
|
|
RcxImm = (ULONG64)pThis; //
|
|
RaxMov = 0xb848; // mov rax, target
|
|
RaxImm = (ULONG64)proc; //
|
|
RaxJmp = 0xe0ff; // jmp rax
|
|
FlushInstructionCache(GetCurrentProcess(), this, sizeof(_stdcallthunk));
|
|
}
|
|
};
|
|
#pragma pack(pop)
|
|
#elif defined(_M_IA64)
|
|
#pragma pack(push,8)
|
|
extern "C" LRESULT CALLBACK _WndProcThunkProc( HWND, UINT, WPARAM, LPARAM );
|
|
struct _FuncDesc
|
|
{
|
|
void* pfn;
|
|
void* gp;
|
|
};
|
|
struct _stdcallthunk
|
|
{
|
|
_FuncDesc m_funcdesc;
|
|
void* m_pFunc;
|
|
void* m_pThis;
|
|
void Init(DWORD_PTR proc, void* pThis)
|
|
{
|
|
const _FuncDesc* pThunkProc;
|
|
|
|
pThunkProc = reinterpret_cast< const _FuncDesc* >( _WndProcThunkProc );
|
|
m_funcdesc.pfn = pThunkProc->pfn;
|
|
m_funcdesc.gp = &m_pFunc;
|
|
m_pFunc = reinterpret_cast< void* >( proc );
|
|
m_pThis = pThis;
|
|
::FlushInstructionCache( GetCurrentProcess(), this, sizeof( _stdcallthunk ) );
|
|
}
|
|
};
|
|
#pragma pack(pop)
|
|
#else
|
|
#error Only AMD64, IA64, and X86 supported
|
|
#endif
|
|
|
|
class CDynamicStdCallThunk
|
|
{
|
|
public:
|
|
_stdcallthunk *pThunk;
|
|
|
|
CDynamicStdCallThunk()
|
|
{
|
|
pThunk = NULL;
|
|
}
|
|
|
|
~CDynamicStdCallThunk()
|
|
{
|
|
if (pThunk)
|
|
HeapFree(GetProcessHeap(), 0, pThunk);
|
|
}
|
|
|
|
void Init(DWORD_PTR proc, void *pThis)
|
|
{
|
|
if (!pThunk) {
|
|
pThunk = static_cast<_stdcallthunk *>(HeapAlloc(GetProcessHeap(),
|
|
HEAP_GENERATE_EXCEPTIONS, sizeof(_stdcallthunk)));
|
|
}
|
|
ATLASSERT(pThunk);
|
|
pThunk->Init(proc, pThis);
|
|
}
|
|
};
|
|
typedef CDynamicStdCallThunk CStdCallThunk;
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// WindowProc thunks
|
|
|
|
class CWndProcThunk
|
|
{
|
|
public:
|
|
_AtlCreateWndData cd;
|
|
CStdCallThunk thunk;
|
|
|
|
void Init(WNDPROC proc, void* pThis)
|
|
{
|
|
thunk.Init((DWORD_PTR)proc, pThis);
|
|
}
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMessageMap - abstract class that provides an interface for message maps
|
|
|
|
class ATL_NO_VTABLE CMessageMap
|
|
{
|
|
public:
|
|
virtual BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
|
|
LRESULT& lResult, DWORD dwMsgMapID) = 0;
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Message map
|
|
|
|
#define BEGIN_MSG_MAP(theClass) \
|
|
public: \
|
|
BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID = 0) \
|
|
{ \
|
|
BOOL bHandled = TRUE; \
|
|
hWnd; \
|
|
switch(dwMsgMapID) \
|
|
{ \
|
|
case 0:
|
|
|
|
#define ALT_MSG_MAP(msgMapID) \
|
|
break; \
|
|
case msgMapID:
|
|
|
|
#define MESSAGE_HANDLER(msg, func) \
|
|
if(uMsg == msg) \
|
|
{ \
|
|
bHandled = TRUE; \
|
|
lResult = func(uMsg, wParam, lParam, bHandled); \
|
|
if(bHandled) \
|
|
return TRUE; \
|
|
}
|
|
|
|
#define MESSAGE_RANGE_HANDLER(msgFirst, msgLast, func) \
|
|
if(uMsg >= msgFirst && uMsg <= msgLast) \
|
|
{ \
|
|
bHandled = TRUE; \
|
|
lResult = func(uMsg, wParam, lParam, bHandled); \
|
|
if(bHandled) \
|
|
return TRUE; \
|
|
}
|
|
|
|
#define COMMAND_HANDLER(id, code, func) \
|
|
if(uMsg == WM_COMMAND && id == LOWORD(wParam) && code == HIWORD(wParam)) \
|
|
{ \
|
|
bHandled = TRUE; \
|
|
lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
|
|
if(bHandled) \
|
|
return TRUE; \
|
|
}
|
|
|
|
#define COMMAND_ID_HANDLER(id, func) \
|
|
if(uMsg == WM_COMMAND && id == LOWORD(wParam)) \
|
|
{ \
|
|
bHandled = TRUE; \
|
|
lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
|
|
if(bHandled) \
|
|
return TRUE; \
|
|
}
|
|
|
|
#define COMMAND_CODE_HANDLER(code, func) \
|
|
if(uMsg == WM_COMMAND && code == HIWORD(wParam)) \
|
|
{ \
|
|
bHandled = TRUE; \
|
|
lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
|
|
if(bHandled) \
|
|
return TRUE; \
|
|
}
|
|
|
|
#define COMMAND_RANGE_HANDLER(idFirst, idLast, func) \
|
|
if(uMsg == WM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \
|
|
{ \
|
|
bHandled = TRUE; \
|
|
lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
|
|
if(bHandled) \
|
|
return TRUE; \
|
|
}
|
|
|
|
#define NOTIFY_HANDLER(id, cd, func) \
|
|
if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom && cd == ((LPNMHDR)lParam)->code) \
|
|
{ \
|
|
bHandled = TRUE; \
|
|
lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
|
|
if(bHandled) \
|
|
return TRUE; \
|
|
}
|
|
|
|
#define NOTIFY_ID_HANDLER(id, func) \
|
|
if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \
|
|
{ \
|
|
bHandled = TRUE; \
|
|
lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
|
|
if(bHandled) \
|
|
return TRUE; \
|
|
}
|
|
|
|
#define NOTIFY_CODE_HANDLER(cd, func) \
|
|
if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \
|
|
{ \
|
|
bHandled = TRUE; \
|
|
lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
|
|
if(bHandled) \
|
|
return TRUE; \
|
|
}
|
|
|
|
#define NOTIFY_RANGE_HANDLER(idFirst, idLast, func) \
|
|
if(uMsg == WM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \
|
|
{ \
|
|
bHandled = TRUE; \
|
|
lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
|
|
if(bHandled) \
|
|
return TRUE; \
|
|
}
|
|
|
|
#define CHAIN_MSG_MAP(theChainClass) \
|
|
{ \
|
|
if(theChainClass::ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult)) \
|
|
return TRUE; \
|
|
}
|
|
|
|
#define CHAIN_MSG_MAP_MEMBER(theChainMember) \
|
|
{ \
|
|
if(theChainMember.ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult)) \
|
|
return TRUE; \
|
|
}
|
|
|
|
#define CHAIN_MSG_MAP_ALT(theChainClass, msgMapID) \
|
|
{ \
|
|
if(theChainClass::ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, msgMapID)) \
|
|
return TRUE; \
|
|
}
|
|
|
|
#define CHAIN_MSG_MAP_ALT_MEMBER(theChainMember, msgMapID) \
|
|
{ \
|
|
if(theChainMember.ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, msgMapID)) \
|
|
return TRUE; \
|
|
}
|
|
|
|
#define CHAIN_MSG_MAP_DYNAMIC(dynaChainID) \
|
|
{ \
|
|
if(CDynamicChain::CallChain(dynaChainID, hWnd, uMsg, wParam, lParam, lResult)) \
|
|
return TRUE; \
|
|
}
|
|
|
|
#define CHAIN_MSG_MAP_ALT_DYNAMIC(dynaChainID, msgMapID) \
|
|
{ \
|
|
if(CDynamicChain::CallChain(dynaChainID, hWnd, uMsg, wParam, lParam, lResult, msgMapID)) \
|
|
return TRUE; \
|
|
}
|
|
|
|
#define END_MSG_MAP() \
|
|
break; \
|
|
default: \
|
|
ATLTRACE(_T("Invalid message map ID (%i)\n"), dwMsgMapID); \
|
|
_ASSERTE(FALSE); \
|
|
break; \
|
|
} \
|
|
return FALSE; \
|
|
}
|
|
|
|
|
|
// Handler prototypes:
|
|
// LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
|
// LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
|
|
// LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CDynamicChain - provides support for dynamic chaining
|
|
|
|
class CDynamicChain
|
|
{
|
|
public:
|
|
struct ATL_CHAIN_ENTRY
|
|
{
|
|
DWORD m_dwChainID;
|
|
CMessageMap* m_pObject;
|
|
DWORD m_dwMsgMapID;
|
|
};
|
|
|
|
int m_nEntries;
|
|
ATL_CHAIN_ENTRY** m_pChainEntry;
|
|
|
|
CDynamicChain() : m_nEntries(0), m_pChainEntry(NULL)
|
|
{ }
|
|
|
|
~CDynamicChain();
|
|
BOOL SetChainEntry(DWORD dwChainID, CMessageMap* pObject, DWORD dwMsgMapID = 0);
|
|
BOOL RemoveChainEntry(DWORD dwChainID);
|
|
BOOL CallChain(DWORD dwChainID, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult);
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CWndClassInfo - Manages Windows class information
|
|
|
|
class CWndClassInfo
|
|
{
|
|
public:
|
|
WNDCLASSEX m_wc;
|
|
LPCTSTR m_lpszOrigName;
|
|
WNDPROC pWndProc;
|
|
LPCTSTR m_lpszCursorID;
|
|
BOOL m_bSystemCursor;
|
|
ATOM m_atom;
|
|
TCHAR m_szAutoName[sizeof("ATL:") + (sizeof(PVOID)*2)+1];
|
|
ATOM Register(WNDPROC*);
|
|
};
|
|
|
|
#define DECLARE_WND_CLASS(WndClassName) \
|
|
static CWndClassInfo& GetWndClassInfo() \
|
|
{ \
|
|
static CWndClassInfo wc = \
|
|
{ \
|
|
{ sizeof(WNDCLASSEX), CS_HREDRAW|CS_VREDRAW, StartWindowProc, \
|
|
0, 0, 0, 0, 0, (HBRUSH)(COLOR_WINDOW+1), 0, WndClassName, 0 }, \
|
|
NULL, NULL, IDC_ARROW, TRUE, 0, _T("") \
|
|
}; \
|
|
return wc; \
|
|
}
|
|
|
|
#define DECLARE_WND_SUPERCLASS(WndClassName, OrigWndClassName) \
|
|
static CWndClassInfo& GetWndClassInfo() \
|
|
{ \
|
|
static CWndClassInfo wc = \
|
|
{ \
|
|
{ sizeof(WNDCLASSEX), NULL, StartWindowProc, \
|
|
0, 0, 0, 0, 0, NULL, 0, WndClassName, 0 }, \
|
|
OrigWndClassName, NULL, NULL, TRUE, 0, _T("") \
|
|
}; \
|
|
return wc; \
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CWindowImpl - Implements a window
|
|
|
|
class ATL_NO_VTABLE CWindowImplBase : public CWindow, public CMessageMap
|
|
{
|
|
public:
|
|
CWndProcThunk m_thunk;
|
|
WNDPROC m_pfnSuperWindowProc;
|
|
|
|
CWindowImplBase() : m_pfnSuperWindowProc(::DefWindowProc)
|
|
{}
|
|
|
|
static LRESULT CALLBACK StartWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName,
|
|
DWORD dwStyle, DWORD dwExStyle, UINT_PTR nID, ATOM atom);
|
|
BOOL SubclassWindow(HWND hWnd);
|
|
HWND UnsubclassWindow();
|
|
|
|
LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
#ifdef STRICT
|
|
return ::CallWindowProc(m_pfnSuperWindowProc, m_hWnd, uMsg, wParam, lParam);
|
|
#else
|
|
return ::CallWindowProc((FARPROC)m_pfnSuperWindowProc, m_hWnd, uMsg, wParam, lParam);
|
|
#endif
|
|
}
|
|
};
|
|
|
|
template <class T>
|
|
class ATL_NO_VTABLE CWindowImpl : public CWindowImplBase
|
|
{
|
|
public:
|
|
DECLARE_WND_CLASS(NULL)
|
|
|
|
HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName = NULL,
|
|
DWORD dwStyle = WS_CHILD | WS_VISIBLE, DWORD dwExStyle = 0,
|
|
UINT_PTR nID = 0)
|
|
{
|
|
ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc);
|
|
return CWindowImplBase::Create(hWndParent, rcPos, szWindowName, dwStyle, dwExStyle,
|
|
nID, atom);
|
|
}
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CDialog - Implements a dialog box
|
|
|
|
class ATL_NO_VTABLE CDialogImplBase : public CWindow, public CMessageMap
|
|
{
|
|
public:
|
|
CWndProcThunk m_thunk;
|
|
|
|
static INT_PTR CALLBACK StartDialogProc(HWND hWnd, UINT uMsg,
|
|
WPARAM wParam, LPARAM lParam);
|
|
static INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
BOOL EndDialog(int nRetCode);
|
|
};
|
|
|
|
template <class T>
|
|
class ATL_NO_VTABLE CDialogImpl : public CDialogImplBase
|
|
{
|
|
public:
|
|
INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow())
|
|
{
|
|
_ASSERTE(m_hWnd == NULL);
|
|
_Module.AddCreateWndData(&m_thunk.cd, (CDialogImplBase*)this);
|
|
INT_PTR nRet = ::DialogBoxParam(_Module.GetResourceInstance(),
|
|
MAKEINTRESOURCE(T::IDD),
|
|
hWndParent,
|
|
T::StartDialogProc,
|
|
NULL);
|
|
m_hWnd = NULL;
|
|
return nRet;
|
|
}
|
|
|
|
HWND Create(HWND hWndParent)
|
|
{
|
|
_ASSERTE(m_hWnd == NULL);
|
|
_Module.AddCreateWndData(&m_thunk.cd, (CDialogImplBase*)this);
|
|
HWND hWnd = ::CreateDialogParam(_Module.GetResourceInstance(),
|
|
MAKEINTRESOURCE(T::IDD),
|
|
hWndParent,
|
|
T::StartDialogProc,
|
|
NULL);
|
|
_ASSERTE(m_hWnd == hWnd);
|
|
return hWnd;
|
|
}
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CContainedWindow - Implements a contained window
|
|
|
|
class CContainedWindow : public CWindow
|
|
{
|
|
public:
|
|
CWndProcThunk m_thunk;
|
|
LPTSTR m_lpszClassName;
|
|
WNDPROC m_pfnSuperWindowProc;
|
|
CMessageMap* m_pObject;
|
|
DWORD m_dwMsgMapID;
|
|
|
|
CContainedWindow(LPTSTR lpszClassName, CMessageMap* pObject, DWORD dwMsgMapID = 0)
|
|
: m_lpszClassName(lpszClassName),
|
|
m_pfnSuperWindowProc(::DefWindowProc),
|
|
m_pObject(pObject), m_dwMsgMapID(dwMsgMapID)
|
|
{ }
|
|
|
|
void SwitchMessageMap(DWORD dwMsgMapID)
|
|
{
|
|
m_dwMsgMapID = dwMsgMapID;
|
|
}
|
|
|
|
static LRESULT CALLBACK StartWindowProc(HWND hWnd, UINT uMsg,
|
|
WPARAM wParam, LPARAM lParam);
|
|
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
ATOM RegisterWndSuperclass();
|
|
HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName = NULL,
|
|
DWORD dwStyle = WS_CHILD | WS_VISIBLE, DWORD dwExStyle = 0,
|
|
UINT nID = 0);
|
|
BOOL SubclassWindow(HWND hWnd);
|
|
HWND UnsubclassWindow();
|
|
|
|
LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
#ifdef STRICT
|
|
return ::CallWindowProc(m_pfnSuperWindowProc, m_hWnd, uMsg, wParam, lParam);
|
|
#else
|
|
return ::CallWindowProc((FARPROC)m_pfnSuperWindowProc, m_hWnd, uMsg, wParam, lParam);
|
|
#endif
|
|
}
|
|
};
|
|
|
|
|
|
#ifndef ATL_NO_NAMESPACE
|
|
}; //namespace ATL
|
|
#endif
|
|
|
|
#ifdef _ATL_REDEF_SUBCLASSWINDOW
|
|
#pragma pop_macro( "SubclassWindow" )
|
|
#undef _ATL_REDEF_SUBCLASSWINDOW
|
|
#endif
|
|
|
|
#endif // __ATLWIN_H__
|