CDialogBase.h
cpp
#pragma once
#include <Windows.h>
#include <tchar.h>
#include <string>
#pragma warning(disable:4100)
#ifdef UNICODE
using _tstring = std::wstring;
#else
using _tstring = std::string;
#endif
class CDialogBase;
typedef LRESULT(CDialogBase::* pMessageFn)(WPARAM wParam, LPARAM lParam);
typedef LRESULT(CDialogBase::* pCommandFn)(WORD wNotify, WORD wID, HWND hWnd);
typedef LRESULT(CDialogBase::* pNotifyFn)(WORD wID, LPNMHDR pNmhdr);
struct DLG_WND_MSGMAP_ENTRY
{
union
{
pMessageFn m_pFnMessage;
pCommandFn m_pFnCommand;
pNotifyFn m_pFnNotify;
}m_pFunc; //要调用的例程(或特殊值)
UINT m_nMessage; //Windows消息
UINT m_nCode; //控件码或 or WM_NOTIFY code
UINT m_nID; //控件ID (Windows消息则为0)
UINT m_nLastID; //用于指定控件 ID 范围的条目
DLG_WND_MSGMAP_ENTRY()
:
m_nMessage(0),
m_nCode(0),
m_nID(0),
m_nLastID(0)
{
m_pFunc.m_pFnMessage = nullptr;
}
DLG_WND_MSGMAP_ENTRY(UINT uMsg, pMessageFn pfn)
:
m_nMessage(uMsg),
m_nCode(0),
m_nID(0),
m_nLastID(0)
{
m_pFunc.m_pFnMessage = pfn;
}
DLG_WND_MSGMAP_ENTRY(UINT uMsg, UINT id, pCommandFn pfn)
:
m_nMessage(uMsg),
m_nCode(0),
m_nID(id),
m_nLastID(0)
{
m_pFunc.m_pFnCommand = pfn;
}
DLG_WND_MSGMAP_ENTRY(UINT uMsg, UINT id, UINT idLast, pCommandFn pfn)
:
m_nMessage(uMsg),
m_nCode(0),
m_nID(id),
m_nLastID(idLast)
{
m_pFunc.m_pFnCommand = pfn;
}
DLG_WND_MSGMAP_ENTRY(UINT uMsg, UINT wNotifyCode, UINT id, UINT idLast, pNotifyFn pfn)
:
m_nMessage(uMsg),
m_nCode(wNotifyCode),
m_nID(id),
m_nLastID(idLast)
{
m_pFunc.m_pFnNotify = pfn;
}
};
struct DLG_WND_MSGMAP
{
const DLG_WND_MSGMAP* (*pfnGetBaseMap)();
const DLG_WND_MSGMAP_ENTRY* lpEntries;
};
#ifndef dlg_msg
#define dlg_msg
#endif
#ifndef dlg_command
#define dlg_command
#endif
#ifndef dlg_notify
#define dlg_notify
#endif
#define DECLARE_DLG_MESSAGE_MAP() \
protected: \
static const DLG_WND_MSGMAP* GetThisMessageMap(); \
virtual const DLG_WND_MSGMAP* GetMessageMap() const; \
#define BEGIN_DLG_MESSAGE_MAP(theClass, baseClass) \
const DLG_WND_MSGMAP* theClass::GetMessageMap() const \
{ \
return GetThisMessageMap(); \
} \
const DLG_WND_MSGMAP* theClass::GetThisMessageMap() \
{ \
typedef baseClass TheBaseClass; \
static const DLG_WND_MSGMAP_ENTRY _messageEntries[] = \
{ \
#define ON_DLG_MESSAGE(message, memberFxn) \
DLG_WND_MSGMAP_ENTRY(message, static_cast< LRESULT (CDialogBase::*)(WPARAM, LPARAM) >(memberFxn)),
#define ON_DLG_COMMAND(_id, memberFxn) \
DLG_WND_MSGMAP_ENTRY(WM_COMMAND, _id, static_cast< LRESULT (CDialogBase::*)(WORD wNotify, WORD wID, HWND hWnd) >(memberFxn)),
#define ON_DLG_COMMAND_RANGE(_id, _idLast, memberFxn) \
DLG_WND_MSGMAP_ENTRY(WM_COMMAND, _id, _idLast, static_cast< LRESULT (CDialogBase::*)(WORD wNotify, WORD wID, HWND hWnd) >(memberFxn)),
#define ON_DLG_NOTIFY(_wNotifycode, _id, memberFxn) \
DLG_WND_MSGMAP_ENTRY(WM_NOTIFY, (UINT)_wNotifycode, _id, _id, static_cast< LRESULT (CDialogBase::*)(WORD wID, LPNMHDR pNmhdr) >(memberFxn)),
#define ON_DLG_NOTIFY_RANGE(_wNotifycode, _id, _idLast, memberFxn) \
DLG_WND_MSGMAP_ENTRY(WM_NOTIFY, (UINT)_wNotifycode, _id, _idLast, static_cast< LRESULT (CDialogBase::*)(WORD wID, LPNMHDR pNmhdr) >(memberFxn)),
#define END_DLG_MESSAGE_MAP() DLG_WND_MSGMAP_ENTRY(0, NULL) }; \
static const DLG_WND_MSGMAP messageMap = \
{&TheBaseClass::GetThisMessageMap , &_messageEntries[0] }; \
return &messageMap; \
} \
#define DECLARE_DLG_BASE_MESSAGE_MAP() \
protected: \
static const DLG_WND_MSGMAP* GetThisMessageMap(); \
virtual const DLG_WND_MSGMAP* GetMessageMap() const; \
static const DLG_WND_MSGMAP* GetBaseMessageMap(); \
#define BEGIN_DLG_BASE_MESSAGE_MAP(theClass) \
typedef theClass TheThisClass; \
const DLG_WND_MSGMAP* TheThisClass::GetMessageMap() const \
{ \
return GetThisMessageMap(); \
} \
const DLG_WND_MSGMAP* TheThisClass::GetBaseMessageMap() \
{ \
return NULL; \
} \
const DLG_WND_MSGMAP* TheThisClass::GetThisMessageMap() \
{ \
static const DLG_WND_MSGMAP_ENTRY _messageEntries[] = \
{ \
#define END_DLG_BASE_MESSAGE_MAP() DLG_WND_MSGMAP_ENTRY(0, nullptr) }; \
static const DLG_WND_MSGMAP messageMap = \
{&TheThisClass::GetBaseMessageMap, &_messageEntries[0] }; \
return &messageMap; \
} \
class CDialogBase
{
public:
CDialogBase();
CDialogBase(const CDialogBase& r) = delete;
CDialogBase& operator = (const CDialogBase& r) = delete;
~CDialogBase();
INT_PTR DoModal(HWND hWndParent, bool bCenter = true);
INT_PTR DoModal(UINT resourceID, HWND hWndParent, bool bCenter = true);
INT_PTR DoModalEx(UINT resourceID, HWND hWndParent, BOOL isShow = TRUE, bool bCenter = true);
HWND DoDialog(UINT resourceID, HWND hWndParent, BOOL isShow = TRUE, bool bCenter = true);
public:
dlg_msg LRESULT OnClose(WPARAM wParam, LPARAM lParam);
dlg_msg LRESULT OnMsgTest(WPARAM wParam, LPARAM lParam);
dlg_command LRESULT OnCommandTest(WORD wNotify, WORD wID, HWND hWnd);
dlg_notify LRESULT OnNotifyTest(WORD wID, LPNMHDR pNmhdr);
public:
//设置对话框资源
void SetResourceID(UINT resourceID);
//显示窗口
void ShowWindow(int cmdShow = SW_SHOW);
//检查窗口是否显示
bool IsVisiable() const;
//移动窗口到父窗口中心
void MoveToCenter(HWND hParent);
//修改菜单文本
void ModifyMenuText(HMENU hMnu, UINT uPosition, LPCTSTR lpNewItem, BOOL fByPos = TRUE);
//修改菜单文本为资源字符串
void ModifyMenuText(HMENU hMnu, UINT uPosition, UINT resourceID, BOOL fByPos = TRUE);
//修改菜单状态
void ModifyMenuState(HMENU hMnu, UINT uPosition, UINT fState = MFS_ENABLED, BOOL fByPos = TRUE);
//获取窗口句柄
HWND GetWndHandle() const;
//结束对话框
bool EndDialog(INT_PTR nResult);
//消息
bool PostMessage(UINT uMsg, WPARAM wParam, LPARAM lParam = 0);
LRESULT SendMessage(UINT uMsg, WPARAM wParam, LPARAM lParam = 0);
bool PostCommand(WORD wID, WORD wNotify = 0, LPARAM lParam = 0);
LRESULT SendCommand(WORD wID, WORD wNotify = 0, LPARAM lParam = 0);
//加载资源字符串
_tstring LoadString(UINT resourceID);
//获取子项文本
_tstring GetItemString(DWORD dwID);
//设置子项文本
void SetItemString(DWORD dwID, const _tstring& strText);
//检查子项按钮是否勾选
bool IsButtonChecked(int nIDButton) const;
//勾选子项按钮
bool CheckButton(int nIDButton, bool bCheck = true);
//获取子项窗口句柄
HWND GetItem(DWORD dwID) const;
//检查菜单项是否勾选
bool IsMenuItemChecked(HMENU hMenu, UINT uId, bool fByPosition = false);
//勾选菜单项
void CheckMenuItem(HMENU hMenu, UINT uId, bool bCheck, bool fByPosition = false);
//检查菜单项是否启用
bool IsMenuItemEnable(HMENU hMenu, UINT uId, bool fByPosition = false);
//启用菜单项
void EnableMenuItem(HMENU hMenu, UINT uId, bool bCheck, bool fByPosition = false);
//获取菜单项文本
_tstring GetMenuItemString(HMENU hMenu, UINT uId, bool bCheck, bool fByPosition = false);
//设置菜单项文本
bool SetMenuItemString(HMENU hMenu, UINT uId, const _tstring strText, bool fByPosition = false);
operator HWND() const
{
return m_hWnd;
}
protected:
//假模态对话框
dlg_msg LRESULT DoFakeModal(UINT resourceID, HWND hWndParent, BOOL isShow = TRUE);
static INT_PTR WINAPI DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
INT_PTR DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
public:
virtual BOOL PreTranslateMessage(LPMSG pMsg);
virtual BOOL DialogMessage(LPMSG pMsg);
protected:
HWND m_hWnd;
UINT m_resID;
BOOL m_bModel;
BOOL m_bFakeModel;
BOOL m_bCenter;
DECLARE_DLG_BASE_MESSAGE_MAP()
};
CDialogBase.cpp
cpp
#include "CDialogBase.h"
#include <Windows.h>
#include <strsafe.h>
#pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
BEGIN_DLG_BASE_MESSAGE_MAP(CDialogBase)
ON_DLG_MESSAGE(WM_CLOSE, &CDialogBase::OnClose)
ON_DLG_MESSAGE(0/*消息*/, &CDialogBase::OnMsgTest)
ON_DLG_COMMAND(0/*控件ID*/, &CDialogBase::OnCommandTest)
ON_DLG_NOTIFY(0/*通知码*/, 0/*控件ID*/, &CDialogBase::OnNotifyTest)
ON_DLG_COMMAND_RANGE(0/*控件ID起始*/, 0/*控件ID结束*/, &CDialogBase::OnCommandTest)
ON_DLG_NOTIFY_RANGE(0/*通知码*/, 0/*控件ID起始*/, 0/*控件ID结束*/, &CDialogBase::OnNotifyTest)
END_DLG_BASE_MESSAGE_MAP()
CDialogBase::CDialogBase()
:
m_hWnd(NULL),
m_resID(0),
m_bModel(FALSE),
m_bFakeModel(FALSE),
m_bCenter(FALSE)
{
}
CDialogBase::~CDialogBase()
{
if (NULL != m_hWnd)
{
::DestroyWindow(m_hWnd);
}
}
HWND CDialogBase::DoDialog(UINT resourceID, HWND hWndParent, BOOL isShow, bool bCenter/* = true*/)
{
m_bCenter = bCenter;
m_bModel = FALSE;
m_resID = resourceID;
HWND hWnd = ::CreateDialogParam(GetModuleHandle(NULL), MAKEINTRESOURCE(resourceID), hWndParent, DialogProc, (LPARAM)this);
m_hWnd = hWnd;
if (isShow)
{
::ShowWindow(m_hWnd, SW_SHOW);
}
return m_hWnd;
}
INT_PTR CDialogBase::DoModalEx(UINT resourceID, HWND hWndParent, BOOL isShow, bool bCenter/* = true*/)
{
m_bCenter = bCenter;
m_bModel = FALSE;
return DoFakeModal(resourceID, hWndParent, isShow);
}
INT_PTR CDialogBase::DoModal(HWND hWndParent, bool bCenter/* = true*/)
{
m_bCenter = bCenter;
m_bModel = TRUE;
return ::DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(m_resID), hWndParent, DialogProc, (LPARAM)this);
}
INT_PTR CDialogBase::DoModal(UINT resourceID, HWND hWndParent, bool bCenter/* = true*/)
{
m_bCenter = bCenter;
m_resID = resourceID;
m_bModel = TRUE;
return ::DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(m_resID), hWndParent, DialogProc, (LPARAM)this);
}
BOOL CDialogBase::DialogMessage(LPMSG pMsg)
{
return ::IsDialogMessage(m_hWnd, pMsg);
}
BOOL CDialogBase::PreTranslateMessage(LPMSG pMsg)
{
return FALSE;
}
bool CDialogBase::EndDialog(INT_PTR nResult)
{
if (NULL == m_hWnd)
{
return false;
}
if (m_bFakeModel)
{
//启用父窗口
HWND hParent = ::GetParent(m_hWnd);
if (hParent)
{
::EnableWindow(hParent, TRUE);
}
// 投递 WM_QUIT 消息退出消息环 (窗口句柄指定为NULL时,
// 该函数的行为类似于对 PostThreadMessage 的调用,
// 其中 dwThreadId 参数设置为当前线程的标识符。)
::PostMessage(NULL, WM_QUIT, nResult, 0);
}
if (m_bModel)
{
::EndDialog(m_hWnd, nResult);
m_hWnd = NULL;
}
else
{
::DestroyWindow(m_hWnd);
m_hWnd = NULL;
}
return TRUE;
}
LRESULT CDialogBase::OnClose(WPARAM wParam, LPARAM lParam)
{
return EndDialog(wParam);
}
LRESULT CDialogBase::DoFakeModal(UINT resourceID, HWND hWndParent, BOOL isShow)
{
m_bModel = FALSE;
m_resID = resourceID;
m_bFakeModel = TRUE;
m_hWnd = ::CreateDialogParam(GetModuleHandle(NULL), MAKEINTRESOURCE(resourceID), hWndParent, DialogProc, (LPARAM)this);
if (NULL == m_hWnd)
{
return -1;
}
if (isShow)
{
::ShowWindow(m_hWnd, SW_SHOW);
}
//禁用父窗口
HWND hParent = GetParent(m_hWnd);
if (hParent)
{
::EnableWindow(hParent, FALSE);
}
MSG msg = { 0 };
BOOL bRet = FALSE;
//如果 hWnd 为 NULL, 则 GetMessage 将检索属于当前线程的任何窗口的消息,以及当前线程的消息队列上 hwnd 值为 NULL 的任何消息,
//因此,如果 hWnd 为 NULL,则同时处理窗口消息和线程消息。
//如果 hWnd 为 - 1,则 GetMessage 仅检索当前线程的消息队列中 hwnd 值为 NULL 的消息,
//即当 hWnd 参数为 NULL 或 PostThreadMessage 时,PostMessage 发布的线程消息。
while (0 != (bRet = GetMessage(&msg, NULL, 0, 0)))
{
if (-1 == bRet)
{
break;
}
//类捕获消息处理与对话框 TAB 按键处理
if (PreTranslateMessage(&msg))
{
continue;
}
//类捕获消息处理与对话框 TAB 按键处理
if (DialogMessage(&msg))
{
continue;
}
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
return msg.wParam;
}
INT_PTR WINAPI CDialogBase::DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CDialogBase* pThis = reinterpret_cast<CDialogBase*>(GetProp(hWnd, _T("this")));
if (pThis)
{
return pThis->DialogProc(uMsg, wParam, lParam);
}
if (WM_INITDIALOG == uMsg)
{
pThis = reinterpret_cast<CDialogBase*>(lParam);
pThis->m_hWnd = hWnd;
SetProp(hWnd, _T("this"), pThis);
pThis->DialogProc(uMsg, wParam, lParam);
if (pThis->m_bCenter)
{
pThis->MoveToCenter(::GetParent(hWnd));
}
return (INT_PTR)TRUE;
}
return (INT_PTR)FALSE;
}
INT_PTR CDialogBase::DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
const DLG_WND_MSGMAP* pEntry = GetMessageMap();
LRESULT lpResult = NULL;
while (pEntry)
{
const DLG_WND_MSGMAP_ENTRY* lpEntries = pEntry->lpEntries;
while (lpEntries->m_pFunc.m_pFnMessage)
{
if (uMsg == lpEntries->m_nMessage)
{
//处理 WM_COMMAND 消息
if (WM_COMMAND == uMsg)
{
//消息源 HIWORD(wParam) LOWORD(wParam) lParam
//菜单 0 菜单ID 0
//快捷键 1 快捷键ID 0
//控件 控件定义的通知码 控件ID 控件窗口句柄
WORD wNotify = HIWORD(wParam);
WORD wID = LOWORD(wParam);
HWND hWnd = (HWND)lParam;
//ID范围检测
if (wID >= lpEntries->m_nID && wID <= lpEntries->m_nID)
{
lpResult = (this->*lpEntries->m_pFunc.m_pFnCommand)(wNotify, wID, hWnd);
break;
}
}
else if (WM_NOTIFY == uMsg)
{
WORD wID = (WORD)wParam; //发送消息的公共控件的标识符。 不保证此标识符是唯一的。
LPNMHDR pNmhdr = (LPNMHDR)lParam; //指向包含通知代码和其他信息的 NMHDR 结构的指针
if (pNmhdr->code == lpEntries->m_nCode && pNmhdr->idFrom >= lpEntries->m_nID && pNmhdr->idFrom <= lpEntries->m_nID)
{
lpResult = (this->*lpEntries->m_pFunc.m_pFnNotify)(wID, pNmhdr);
break;
}
}
else
{
lpResult = (this->*lpEntries->m_pFunc.m_pFnMessage)(wParam, lParam);
break;
}
}
lpEntries++;
}
//子类处理了则返回
if (lpResult)
{
::SetWindowLongPtr(m_hWnd, DWLP_MSGRESULT, lpResult);
return lpResult;
}
//获取基类的消息映射
pEntry = pEntry->pfnGetBaseMap();
}
return FALSE;
}
void CDialogBase::SetResourceID(UINT resourceID)
{
m_resID = resourceID;
}
void CDialogBase::ShowWindow(int cmdShow)
{
::ShowWindow(m_hWnd, cmdShow);
}
bool CDialogBase::IsVisiable() const
{
return ::IsWindowVisible(m_hWnd);
}
void CDialogBase::MoveToCenter(HWND hParent)
{
RECT rectParent = { 0 };
RECT rectChild = { 0 };
RECT rectWork = { 0 };
LONG dwParentW = 0;
LONG dwParentH = 0;
LONG dwChildW = 0;
LONG dwChildH = 0;
LONG dwChildX = 0;
LONG dwChildY = 0;
::GetWindowRect(m_hWnd, &rectChild);
SystemParametersInfo(SPI_GETWORKAREA, 0, &rectWork, 0);
if (NULL == hParent)
{
hParent = ::GetDesktopWindow();
}
::GetWindowRect(hParent, &rectParent);
dwParentW = rectParent.right - rectParent.left;
dwParentH = rectParent.bottom - rectParent.top;
dwChildW = rectChild.right - rectChild.left;
dwChildH = rectChild.bottom - rectChild.top;
dwChildX = rectParent.left + (dwParentW - dwChildW) / 2;
dwChildY = rectParent.top + (dwParentH - dwChildH) / 2;
if (dwChildX < 0)
{
dwChildX = 0;
}
if (dwChildY < 0)
{
dwChildY = 0;
}
if ((dwChildX + dwChildW) > rectWork.right)
{
dwChildX = rectWork.right - dwChildW;
}
if ((dwChildY + dwChildH) > rectWork.bottom)
{
dwChildY = rectWork.bottom - dwChildH;
}
::MoveWindow(
m_hWnd,
dwChildX,
dwChildY,
dwChildW,
dwChildH,
TRUE
);
}
_tstring CDialogBase::LoadString(UINT uID)
{
_tstring strResult;
LPTSTR lpData = nullptr;
do
{
//获取资源长度
LPCTSTR lpCStr = nullptr;
int nLength = ::LoadString(GetModuleHandle(NULL), uID, (LPWSTR)&lpCStr, 0);
if (0 == nLength)
{
break;
}
//分配字符串缓冲
nLength += 1;
lpData = (LPTSTR)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, nLength * sizeof(TCHAR));
if (NULL == lpData)
{
break;
}
//拷贝
::StringCchCopy(lpData, nLength, lpCStr);
strResult = lpData;
} while (false);
if (NULL != lpData)
{
::HeapFree(::GetProcessHeap(), 0, lpData);
}
return strResult;
}
_tstring CDialogBase::GetItemString(DWORD dwID)
{
_tstring strResult;
LPTSTR lpData = nullptr;
do
{
DWORD dwLength = GetWindowTextLength(GetDlgItem(m_hWnd, dwID));
if (0 == dwLength)
{
break;
}
dwLength += 1;
lpData = (LPTSTR)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength * sizeof(TCHAR));
if (NULL == lpData)
{
break;
}
::GetDlgItemText(m_hWnd, dwID, lpData, dwLength);
strResult = lpData;
} while (false);
if (NULL != lpData)
{
::HeapFree(::GetProcessHeap(), 0, lpData);
}
return strResult;
}
bool CDialogBase::IsButtonChecked(int nIDButton) const
{
return BST_CHECKED == ::IsDlgButtonChecked(m_hWnd, nIDButton);
}
bool CDialogBase::CheckButton(int nIDButton, bool bCheck/* = true*/)
{
return ::CheckDlgButton(m_hWnd, nIDButton, bCheck ? BST_CHECKED : BST_UNCHECKED);
}
HWND CDialogBase::GetItem(DWORD dwID) const
{
return ::GetDlgItem(m_hWnd, dwID);
}
bool CDialogBase::IsMenuItemChecked(HMENU hMenu, UINT uId, bool fByPosition/* = false*/)
{
MENUITEMINFO mii = { 0 };
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STATE;
::GetMenuItemInfo(hMenu, uId, fByPosition, &mii);
return mii.fState & MF_CHECKED;
}
void CDialogBase::CheckMenuItem(HMENU hMenu, UINT uId, bool bCheck, bool fByPosition/* = false*/)
{
MENUITEMINFO mii = { 0 };
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STATE;
::GetMenuItemInfo(hMenu, uId, fByPosition, &mii);
if (bCheck)
{
mii.fState |= MF_CHECKED;
}
else
{
mii.fState &= ~MF_CHECKED;
}
::SetMenuItemInfo(hMenu, uId, fByPosition, &mii);
}
bool CDialogBase::IsMenuItemEnable(HMENU hMenu, UINT uId, bool fByPosition/* = false*/)
{
MENUITEMINFO mii = { 0 };
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STATE;
::GetMenuItemInfo(hMenu, uId, fByPosition, &mii);
return (mii.fState & MFS_DISABLED) ? false : true;
}
void CDialogBase::EnableMenuItem(HMENU hMenu, UINT uId, bool bCheck, bool fByPosition/* = false*/)
{
MENUITEMINFO mii = { 0 };
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STATE;
::GetMenuItemInfo(hMenu, uId, fByPosition, &mii);
if (bCheck)
{
mii.fState &= ~MFS_DISABLED;
}
else
{
mii.fState |= MFS_DISABLED;
}
::SetMenuItemInfo(hMenu, uId, fByPosition, &mii);
}
_tstring CDialogBase::GetMenuItemString(HMENU hMenu, UINT uId, bool bCheck, bool fByPosition/* = false*/)
{
MENUITEMINFO mii = { 0 };
TCHAR szBuf[MAX_PATH] = { 0 };
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE | MIIM_DATA;
mii.dwTypeData = szBuf;
mii.cch = _countof(szBuf);
::GetMenuItemInfo(hMenu, uId, fByPosition, &mii);
if (nullptr == mii.dwTypeData)
{
return _tstring();
}
return mii.dwTypeData;
}
bool CDialogBase::SetMenuItemString(HMENU hMenu, UINT uId, const _tstring strText, bool fByPosition/* = false*/)
{
MENUITEMINFO mii = { 0 };
TCHAR szBuf[MAX_PATH] = { 0 };
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE | MIIM_DATA;
mii.dwTypeData = szBuf;
mii.cch = _countof(szBuf);
::GetMenuItemInfo(hMenu, uId, fByPosition, &mii);
::StringCchPrintf(szBuf, _countof(szBuf), strText.c_str());
return ::SetMenuItemInfo(hMenu, uId, fByPosition, &mii);
}
void CDialogBase::SetItemString(DWORD dwID, const _tstring& strText)
{
::SetDlgItemText(m_hWnd, dwID, strText.c_str());
}
VOID CDialogBase::ModifyMenuText(HMENU hMnu, UINT uPosition, LPCTSTR lpNewItem, BOOL fByPos)
{
MENUITEMINFO mii = { 0 };
TCHAR szBuf[MAX_PATH] = { 0 };
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE | MIIM_DATA;
mii.fType = MFT_STRING;
mii.dwTypeData = szBuf;
mii.cch = _countof(szBuf);
::GetMenuItemInfo(hMnu, uPosition, fByPos, &mii);
::StringCchCopy(szBuf, _countof(szBuf), lpNewItem);
::SetMenuItemInfo(hMnu, uPosition, fByPos, &mii);
}
VOID CDialogBase::ModifyMenuText(HMENU hMnu, UINT uPosition, UINT resourceID, BOOL fByPos)
{
ModifyMenuText(hMnu, uPosition, LoadString(resourceID).c_str(), fByPos);
}
VOID CDialogBase::ModifyMenuState(HMENU hMnu, UINT uPosition, UINT fState/* = MFS_ENABLED*/, BOOL fByPos/* = TRUE*/)
{
MENUITEMINFO mii = { 0 };
TCHAR szBuf[MAX_PATH] = { 0 };
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE | MIIM_STATE | MIIM_DATA;
mii.fType = MFT_STRING;
mii.dwTypeData = szBuf;
mii.cch = _countof(szBuf);
::GetMenuItemInfo(hMnu, uPosition, fByPos, &mii);
mii.fState = fState;
::SetMenuItemInfo(hMnu, uPosition, fByPos, &mii);
}
HWND CDialogBase::GetWndHandle() const
{
if (::IsWindow(m_hWnd))
{
return m_hWnd;
}
return NULL;
}
bool CDialogBase::PostMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
return ::PostMessage(m_hWnd, uMsg, wParam, lParam);
}
LRESULT CDialogBase::SendMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
return ::SendMessage(m_hWnd, uMsg, wParam, lParam);
}
bool CDialogBase::PostCommand(WORD wID, WORD wNotify, LPARAM lParam/* = 0*/)
{
return ::PostMessage(m_hWnd, WM_COMMAND, MAKEWPARAM(wID, wNotify), lParam);
}
LRESULT CDialogBase::SendCommand(WORD wID, WORD wNotify, LPARAM lParam/* = 0*/)
{
return ::SendMessage(m_hWnd, WM_COMMAND, MAKEWPARAM(wID, wNotify), lParam);
}
LRESULT CDialogBase::OnMsgTest(WPARAM wParam, LPARAM lParam)
{
return TRUE;
}
LRESULT CDialogBase::OnCommandTest(WORD wNotify, WORD wID, HWND hWnd)
{
return TRUE;
}
LRESULT CDialogBase::OnNotifyTest(WORD wID, LPNMHDR pNmhdr)
{
return TRUE;
}
测试
CDialogTest.h
cpp
#pragma once
#include "CWindow/CDialogBase.h"
class CDialogTest :
public CDialogBase
{
public:
protected:
dlg_msg LRESULT OnClose(WPARAM wParam, LPARAM lParam);
dlg_command LRESULT OnOK(WORD wNotify, WORD wID, HWND hWnd);
dlg_command LRESULT OnCancel(WORD wNotify, WORD wID, HWND hWnd);
dlg_command LRESULT OnFileExit(WORD wNotify, WORD wID, HWND hWnd);
dlg_command LRESULT OnSettingTopmost(WORD wNotify, WORD wID, HWND hWnd);
dlg_command LRESULT OnHelpAbout(WORD wNotify, WORD wID, HWND hWnd);
private:
DECLARE_DLG_MESSAGE_MAP()
};
CDialogTest.cpp
cpp
#include "CDialogTest.h"
#include <Windows.h>
#include <strsafe.h>
#include "resource.h"
BEGIN_DLG_MESSAGE_MAP(CDialogTest, CDialogBase)
ON_DLG_MESSAGE(WM_CLOSE, &CDialogTest::OnClose)
ON_DLG_COMMAND(IDOK, &CDialogTest::OnOK)
ON_DLG_COMMAND(IDCANCEL, &CDialogTest::OnCancel)
ON_DLG_COMMAND(ID_FILE_EXIT, &CDialogTest::OnFileExit)
ON_DLG_COMMAND(ID_SETTINGS_TOPMOST, &CDialogTest::OnSettingTopmost)
ON_DLG_COMMAND(ID_HELP_ABOUT, &CDialogTest::OnHelpAbout)
END_DLG_MESSAGE_MAP()
LRESULT CDialogTest::OnClose(WPARAM wParam, LPARAM lParam)
{
return (LRESULT)FALSE;
}
LRESULT CDialogTest::OnOK(WORD wNotify, WORD wID, HWND hWnd)
{
EndDialog(IDOK);
return (LRESULT)TRUE;
}
LRESULT CDialogTest::OnCancel(WORD wNotify, WORD wID, HWND hWnd)
{
EndDialog(IDCANCEL);
return (LRESULT)TRUE;
}
LRESULT CDialogTest::OnFileExit(WORD wNotify, WORD wID, HWND hWnd)
{
PostMessage(WM_CLOSE, 0, 0);
return (LRESULT)TRUE;
}
LRESULT CDialogTest::OnSettingTopmost(WORD wNotify, WORD wID, HWND hWnd)
{
bool bTopmost = IsMenuItemChecked(GetMenu(m_hWnd), wID);
CheckMenuItem(GetMenu(m_hWnd), wID, !bTopmost);
SetWindowPos(m_hWnd, !bTopmost ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
return (LRESULT)TRUE;
}
LRESULT CDialogTest::OnHelpAbout(WORD wNotify, WORD wID, HWND hWnd)
{
return (LRESULT)TRUE;
}
main.cpp
cpp
#include "CDialogTest.h"
#include <windows.h>
#include "resource.h"
int APIENTRY WinMain(
_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nShowCmd)
{
UNREFERENCED_PARAMETER(hInstance);
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
UNREFERENCED_PARAMETER(nShowCmd);
CDialogTest dlg;
dlg.DoModalEx(IDD_DIALOG_TEST, nullptr);
return 0;
}