最终效果
一: 点击菜单栏标题后弹出菜单,在OnNcHitTest中增加代码 ,使得当鼠标在 菜单标题的区域点击后,触发对应的函数
LRESULT CMFCDrawnTitleDlg::OnNcHitTest(CPoint point)
{// TODO: 在此添加消息处理程序代码和/或调用默认值UINT nHitTest = CDialogEx::OnNcHitTest(point);CRect rect;GetClientRect(&rect);rect.bottom = 70;//函数参数point是相对于屏幕坐标的,需要将其转换为//客户区坐标才能使用PtInRect(),否则会因为坐标的不同使判断失误//rect.left = rect.left + 200;ScreenToClient(&point);if (rect.PtInRect(point)){if (HTCLIENT == nHitTest)nHitTest = HTCAPTION;//如果鼠标点中的是关闭按钮的位置,需要将上一步的设置还原,if (m_rtBtnfile.PtInRect(point) || m_rtBtnSelect.PtInRect(point) || m_rtBtnHelp.PtInRect(point)){nHitTest = HTCLIENT;}}return nHitTest;
}
二:添加消息afx_msg void OnLButtonDown(UINT nFlags, CPoint point);增加代码
void CMFCDrawnTitleDlg::OnLButtonDown(UINT nFlags, CPoint point)
{// TODO: Add your message handler code here and/or call defaultif (m_rtBtnfile.PtInRect(point)){CMenuEx m_MenuEx;m_MenuEx.CreatePopupMenu();m_MenuEx.SetItemHeight(30);m_MenuEx.SetFontInfo(14);m_MenuEx.SetBorderColor(RGB(45, 51, 60));m_MenuEx.SetMenuWidth(60);m_MenuEx.InstallHook(theApp.m_hInstance);m_MenuEx.AppendItem(MF_STRING, MSG_MENU_START,_T("开始"), _T(""), 0);m_MenuEx.AppendItem(MF_STRING, MSG_MENU_STOP, _T("停止"), _T(""), 0);CRect rectDlg;GetWindowRect(rectDlg);//获得窗体的大小m_MenuEx.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, rectDlg.left + 10, rectDlg.top + static_cast<int>((rectDlg.bottom - rectDlg.top) * 0.104), this);m_MenuEx.DestroyMenu();m_MenuEx.UnInstallHook();}if (m_rtBtnSelect.PtInRect(point)){CRect rectDlg;GetWindowRect(rectDlg);//获得窗体的大小CMenuEx m_MenuEx;m_MenuEx.CreatePopupMenu();m_MenuEx.SetItemHeight(30);m_MenuEx.SetFontInfo(14);m_MenuEx.SetBorderColor(RGB(45, 51, 60));m_MenuEx.SetMenuWidth(130);m_MenuEx.InstallHook(theApp.m_hInstance);m_MenuEx.AppendItem(MF_STRING, MSG_MENU_BEGIN, _T("开始"), _T(""), 0);m_MenuEx.AppendItem(MF_STRING, MSG_MENU_END, _T("停止"), _T(""), 0);m_MenuEx.AppendItem(MF_STRING, MSG_MENU_STOP, _T("重启"), _T(""), 0);m_MenuEx.AppendItem(MF_STRING, MSG_MENU_RELOAD, _T("打开"), _T(""), 0);m_MenuEx.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, rectDlg.left + 70, rectDlg.top + static_cast<int>((rectDlg.bottom - rectDlg.top) * 0.104), this);m_MenuEx.DestroyMenu();m_MenuEx.UnInstallHook();}if (m_rtBtnHelp.PtInRect(point)){CRect rectDlg;GetWindowRect(rectDlg);//获得窗体的大小CMenuEx m_MenuEx;m_MenuEx.CreatePopupMenu();m_MenuEx.SetItemHeight(30);m_MenuEx.SetFontInfo(14);m_MenuEx.SetBorderColor(RGB(45, 51, 60));m_MenuEx.SetMenuWidth(130);m_MenuEx.InstallHook(theApp.m_hInstance);m_MenuEx.AppendItem(MF_STRING, MSG_MENU_HELP, _T("关于 MFC"), _T(""), 0);m_MenuEx.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, rectDlg.left + 130, rectDlg.top + static_cast<int>((rectDlg.bottom - rectDlg.top) * 0.104), this);m_MenuEx.DestroyMenu();m_MenuEx.UnInstallHook();}//CDialogEx::OnLButtonDown(nFlags, point);}
三:对菜单栏进行重绘
#pragma once#include <string>
#include <vector>using namespace std;// 项类型
typedef enum _EnumItemType
{ITEMTYPE_STRING, // 字符串项ITEMTYPE_SEPARATOR, // 分隔符项ITEMTYPE_SUBMENU, // 子菜单项
}EnumItemType;// 顺序类型
typedef enum _EnumaOrderType
{ORDERTYPE_FIRST, // 第一个ORDERTYPE_CENTER, // 中间ORDERTYPE_LAST, // 最后一个
}EnumaOrderType;// 项信息
typedef struct StruItemInfo
{ int nFlags;int nID; HICON hIcon;CString strText; // 字符串CString strShortcut; // 快捷键说明EnumItemType eItemType; // 项类型EnumaOrderType eOrderType; // 顺序类型
}StruItemInfo;typedef vector<StruItemInfo*> ItemInfoVec;
typedef ItemInfoVec::iterator ItemInfoIter;// CMenuEx 对话框class CMenuEx : public CMenu
{public:CMenuEx(); // 标准构造函数virtual ~CMenuEx();private:virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);// 获取系统默认字体大小int GetSysFontSize();// 获取系统默认字体风格//string GetSysFontFaceName();LPCTSTR GetSysFontFaceName();// 生成顺序类型EnumaOrderType GenerateOrderType();HHOOK m_hook; // 钩子句柄int m_nFontSize; // 字体大小int m_nItemHeight; // 项高度//string m_strFontFaceName; // 字体风格LPCTSTR m_strFontFaceName;int m_nLeftWidth; // 图标区域宽度int m_nIconWidth; // 图标宽度int m_nIconHeight; // 图标高度int m_nMenuWidth; // 菜单宽度int m_nSeparatorHeight; // 分隔符高度bool m_bHasIcon; // 是否有图标COLORREF m_clrBk; // 背景色COLORREF m_clrBkHover; // 经过背景色COLORREF m_clrText; // 字体颜色COLORREF m_clrTextDisable; // 无效字体颜色COLORREF m_clrSeparator; // 分割线颜色COLORREF m_clrBorder; // 边框颜色ItemInfoVec m_ItemList;
public:// 钩子void InstallHook(HINSTANCE hInst);void UnInstallHook();// 添加一项void AppendItem(UINT nFlags, UINT nID, CString strText, CString strShortcut, UINT nIconID);// 添加一个子菜单void AppendSubMenu(UINT nFlags, UINT nID, CMenuEx* subMenu, CString strText, UINT nIconID);// 添加分隔符void AppendSeparator(UINT nFlags, UINT nID);void DestroyMenu();// 设置字体大小void SetFontInfo(int nSize, const char* szFontFaceName=NULL);// 设置项高度void SetItemHeight(int nItemHeight) { m_nItemHeight = nItemHeight; }// 设置菜单的宽度void SetMenuWidth(int nWidth) { m_nMenuWidth = nWidth; }// 设置边框颜色void SetBorderColor(COLORREF clr) { m_clrBorder = clr; }};
// MenuEx.cpp : 实现文件
//#include "pch.h"
#include "MenuEx.h"#pragma warning ( disable : 4311 )
#pragma warning ( disable : 4302 )
#pragma warning ( disable : 4172 )
#define GWL_WNDPROC (-4)
CMenuEx::CMenuEx()
{m_hook = NULL;m_nItemHeight = ::GetSystemMetrics(SM_CYMENU);m_nFontSize = GetSysFontSize();//m_strFontFaceName = GetSysFontFaceName();m_strFontFaceName = _T("黑体");m_nLeftWidth = 30;m_nIconWidth = 16;m_nIconHeight = 16;m_clrBk = RGB(57, 63, 73);m_clrBkHover = RGB(19,68,93);m_clrText = RGB(255,255,255);m_clrText = RGB(255, 255, 255);m_clrSeparator = RGB(230,230,230);m_clrTextDisable = RGB(180,180,180);m_nMenuWidth = 150;m_bHasIcon = false;m_nSeparatorHeight = 7;}CMenuEx::~CMenuEx()
{
}void CMenuEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{// TODO: 添加您的代码以绘制指定项CString strText; CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC); //获取菜单项的设备句柄 StruItemInfo *pStruItemInfo =(StruItemInfo*)lpDrawItemStruct->itemData; if(pStruItemInfo == NULL){return;}CRect rect(lpDrawItemStruct->rcItem); if(pStruItemInfo->eItemType == ITEMTYPE_SEPARATOR) //分隔条 { // 画背景pDC->FillSolidRect(rect, m_clrBk); // 画线CRect rcSeparator(rect); rcSeparator.top = rcSeparator.top + rcSeparator.Height() / 2; rcSeparator.bottom = rcSeparator.top + 1; rcSeparator.left += 5;rcSeparator.right -= 5; pDC->Draw3dRect(rcSeparator, m_clrSeparator, m_clrSeparator);}else{// 画背景if(lpDrawItemStruct->itemState & ODS_GRAYED) // 无效变灰{ pDC->FillSolidRect(rect, m_clrBk); pDC->SetTextColor(m_clrTextDisable); } else if(lpDrawItemStruct->itemState & ODS_SELECTED ) // 经过{ //在菜单项上自绘矩形框的背景颜色 pDC->FillSolidRect(rect, m_clrBkHover); //设置菜单文字颜色 pDC->SetTextColor(m_clrText); } else { pDC->FillSolidRect(rect, m_clrBk); pDC->SetTextColor(m_clrText); }pDC->SetBkMode(TRANSPARENT); CRect rcIcon(rect);rcIcon.left += (m_nLeftWidth - m_nIconWidth) / 2;rcIcon.right = rcIcon.left + m_nIconWidth;rcIcon.top += (rcIcon.Height() - m_nIconHeight) / 2;if(pStruItemInfo->hIcon != NULL) { DrawIconEx(pDC->m_hDC, rcIcon.left, rcIcon.top, pStruItemInfo->hIcon, m_nIconWidth, m_nIconHeight, 0, NULL, DI_NORMAL); } // 文字字体和字号设置 LOGFONT fontInfo; pDC->GetCurrentFont()->GetLogFont(&fontInfo); fontInfo.lfHeight = m_nFontSize;lstrcpy(fontInfo.lfFaceName, m_strFontFaceName); CFont fontCh; fontCh.CreateFontIndirect(&fontInfo); pDC->SelectObject(&fontCh); CRect rcText(rect);if (m_bHasIcon){rcText.left += m_nLeftWidth;}else{rcText.left += 10;}rcText.top += (rcText.Height() - m_nFontSize) / 2;rcText.bottom = rcText.top + m_nFontSize;//子菜单项if(pStruItemInfo->eItemType == ITEMTYPE_SUBMENU) { pDC->TextOut(rcText.left, rcText.top, pStruItemInfo->strText, pStruItemInfo->strText.GetLength()); // 换上自定义小箭头//::ExcludeClipRect(pDC->m_hDC,rect.right-15,rect.top,rect.right,rect.bottom); //DrawIconEx(pDC->m_hDC,rect.right-40,rect.top+7,AfxGetApp()->LoadIconA(IDI_ICON1),32,32,1,NULL,DI_NORMAL); } else if (pStruItemInfo->eItemType == ITEMTYPE_STRING) { // 字符串项pDC->TextOut(rcText.left, rcText.top, pStruItemInfo->strText, pStruItemInfo->strText.GetLength()); //fontInfo.lfHeight = 16; //CFont fontEn; //lstrcpy(fontInfo.lfFaceName, _T("Arial")); //fontEn.CreateFontIndirect(&fontInfo); //pDC->SelectObject(&fontEn); pDC->TextOut(rcText.left, rcText.top, pStruItemInfo->strShortcut, pStruItemInfo->strShortcut.GetLength()); } }// 画边框CPen penBorder(PS_SOLID, 1, m_clrBorder);CPen *pOldPen = pDC->SelectObject(&penBorder);pDC->MoveTo(rect.left, rect.top);pDC->LineTo(rect.left, rect.bottom);pDC->MoveTo(rect.right-1, rect.top);pDC->LineTo(rect.right-1, rect.bottom);if (m_ItemList.size() == 1){// 如果只有一项的话就上下边都画pDC->MoveTo(rect.left, rect.top);pDC->LineTo(rect.right-1, rect.top);pDC->MoveTo(rect.left, rect.bottom-1);pDC->LineTo(rect.right-1, rect.bottom-1);}else{// 有多项的话,第一项画上边,最后一项画下边if (pStruItemInfo->eOrderType == ORDERTYPE_FIRST){pDC->MoveTo(rect.left, rect.top);pDC->LineTo(rect.right-1, rect.top);} else if (pStruItemInfo->eOrderType == ORDERTYPE_LAST){pDC->MoveTo(rect.left, rect.bottom-1);pDC->LineTo(rect.right-1, rect.bottom-1);}}pDC->SelectObject(pOldPen);}void CMenuEx::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{// TODO: 添加您的代码以确定指定项的大小StruItemInfo *pStruItemInfo =(StruItemInfo*)lpMeasureItemStruct->itemData; if (pStruItemInfo->eItemType == ITEMTYPE_SEPARATOR){// 设置分隔符项高度lpMeasureItemStruct->itemHeight = m_nSeparatorHeight;}else{lpMeasureItemStruct->itemHeight = m_nItemHeight;}// 设置项宽度lpMeasureItemStruct->itemWidth = m_nMenuWidth;}void CMenuEx::AppendSeparator(UINT nFlags, UINT nID)
{ StruItemInfo *pStruItemInfo = new StruItemInfo;pStruItemInfo->nID = nID;pStruItemInfo->hIcon = NULL;pStruItemInfo->strText = "";pStruItemInfo->strShortcut = "";pStruItemInfo->eItemType = ITEMTYPE_SEPARATOR;nFlags |= MF_SEPARATOR|MF_OWNERDRAW;pStruItemInfo->nFlags = nFlags;pStruItemInfo->eOrderType = GenerateOrderType();m_ItemList.push_back(pStruItemInfo);CMenu::AppendMenu(nFlags, 0, (LPCTSTR)pStruItemInfo);
} void CMenuEx::AppendSubMenu(UINT nFlags, UINT nID, CMenuEx* subMenu, CString strText,UINT nIconID)
{ StruItemInfo *pStruItemInfo = new StruItemInfo; pStruItemInfo->nID = nID; if(nIconID == 0) { pStruItemInfo->hIcon = NULL; } else { pStruItemInfo->hIcon = (HICON)::LoadImage(AfxGetInstanceHandle(),MAKEINTRESOURCE(nIconID),IMAGE_ICON, m_nIconWidth, m_nIconHeight, 0);if (pStruItemInfo->hIcon != NULL){m_bHasIcon = true;}} pStruItemInfo->strText = strText; pStruItemInfo->strShortcut = ""; pStruItemInfo->eItemType = ITEMTYPE_SUBMENU; nFlags |= MF_POPUP|MF_OWNERDRAW; pStruItemInfo->nFlags = nFlags; pStruItemInfo->eOrderType = GenerateOrderType();m_ItemList.push_back(pStruItemInfo);CMenu::AppendMenu(nFlags, (UINT)subMenu->GetSafeHmenu(), (LPCTSTR)pStruItemInfo);
} void CMenuEx::AppendItem(UINT nFlags, UINT nID, CString strText, CString strShortcut, UINT nIconID)
{ StruItemInfo *pStruItemInfo = new StruItemInfo; pStruItemInfo->nID = nID; if(nIconID == 0) { pStruItemInfo->hIcon = NULL; } else { pStruItemInfo->hIcon = (HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(nIconID), IMAGE_ICON, m_nIconWidth, m_nIconHeight, 0); //pStruItemInfo->hIcon = AfxGetApp()->LoadIcon(nIconID) ; if (pStruItemInfo->hIcon != NULL){m_bHasIcon = true;}} pStruItemInfo->strText = strText; pStruItemInfo->strShortcut = strShortcut; pStruItemInfo->eItemType = ITEMTYPE_STRING; nFlags |= MF_OWNERDRAW; pStruItemInfo->nFlags = nFlags; pStruItemInfo->eOrderType = GenerateOrderType();m_ItemList.push_back(pStruItemInfo);CMenu::AppendMenu(nFlags, pStruItemInfo->nID, (LPCTSTR)pStruItemInfo);
} static LRESULT WINAPI CallWndProc(int, WPARAM, LPARAM); // 安装的钩子的窗口过程
static LRESULT WINAPI MenuWndProc(HWND, UINT, WPARAM, LPARAM); // 用来处理菜单的窗口过程
WNDPROC oldWndProc = NULL; // 用来保存被替换的窗口过程 LRESULT WINAPI CallWndProc(int code, WPARAM wParam, LPARAM lParam)
{ CWPSTRUCT* pStruct =(CWPSTRUCT*)lParam; while(code == HC_ACTION)//HC_ACTION 为必须处理 { HWND hWnd = pStruct->hwnd; // 捕捉创建消息WM_CREATE,后面筛选为是否是菜单的创建 if( pStruct->message != WM_CREATE) break; TCHAR sClassName[10]; int Count = ::GetClassName(hWnd, sClassName, sizeof(sClassName)/sizeof(sClassName[0])); // 检查是否菜单窗口,#32768为菜单类名 if( Count != 6 || _tcscmp(sClassName, _T("#32768")) != 0 ) break; WNDPROC lastWndProc =(WNDPROC)GetWindowLongPtr(hWnd, GWL_WNDPROC); //获得指定窗口的信息 GWL_WNDPROC得到窗口回调函数的地址或句柄 //获取传入进程中窗口的窗口过程,这个窗口过程用于接收和处理系统向窗口发送的消息 if(lastWndProc != MenuWndProc) { // 替换菜单窗口过程 SetWindowLongPtr(hWnd, GWL_WNDPROC, (LONG_PTR)MenuWndProc);// 保留原有的窗口过程 oldWndProc = lastWndProc; } break; } //每一个钩子函数在进行处理时都要考虑是否需要把事件传递给下一个钩子处理函数。如果需要传递,就要调用函数CallNestHookEx()。 //在实际使用时还是强烈建议无论是否需要进行事件传递都要在过程的最后调用一次CallNextHookEx( ),否则将会引起一些无法预知的系统行为或是系统锁定。 return CallNextHookEx((HHOOK)WH_CALLWNDPROC, code, wParam, lParam);
} // 处理菜单的窗口过程
LRESULT WINAPI MenuWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{ LRESULT lResult; switch(message) { case WM_CREATE://是否是菜单的创建 { // 首先要去掉菜单窗口的一些扩展风格 // 包括:WS_BORDER、WS_EX_DLGMODALFRAME、WS_EX_WINDOWEDGE lResult = CallWindowProc(oldWndProc, hWnd, message, wParam, lParam); DWORD dwStyle = ::GetWindowLong(hWnd, GWL_STYLE); DWORD dwNewStyle =(dwStyle & ~WS_BORDER); ::SetWindowLong(hWnd, GWL_STYLE, dwNewStyle); DWORD dwExStyle = ::GetWindowLong(hWnd, GWL_EXSTYLE); DWORD dwNewExStyle =(dwExStyle & ~(WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE)); ::SetWindowLong(hWnd, GWL_EXSTYLE, dwNewExStyle); return lResult; } case WM_PRINT: // 此处阻止非客户区地绘制 return CallWindowProc( oldWndProc, hWnd, WM_PRINTCLIENT, wParam, lParam); case WM_WINDOWPOSCHANGING: { // 最后,由于我们在MeasureItem里指定了菜单大小,而系统会自动替菜单加边框, // 因此必须去掉此部分额外地尺寸,将菜单大小改小 LPWINDOWPOS lpPos =(LPWINDOWPOS)lParam; lpPos->cx -= 2*GetSystemMetrics(SM_CXBORDER)+4; lpPos->cy -= 2*GetSystemMetrics(SM_CYBORDER)+4; lResult = CallWindowProc(oldWndProc, hWnd, message, wParam, lParam); return 0; } case WM_GETICON: return 0; default: return CallWindowProc( oldWndProc, hWnd, message, wParam, lParam); }
} void CMenuEx::InstallHook(HINSTANCE hInst)
{ // 需要移除边框时,要安装钩子 if(m_hook == NULL) { DWORD id = ::GetCurrentThreadId(); // 获取当前线程的ID m_hook = SetWindowsHookEx(WH_CALLWNDPROC,CallWndProc,hInst,id);//负责将回调函数放置于钩子链表的开始位置。 //HHOOK SetWindowsHookEx(int idHook;HOOKPROC lpfn;HINSTANCE hMod;DWORD dwThreadId); //idHook 指定了钩子的类型,WH_CALLWNDPROC 系统将消息发送到指定窗口之前的“钩子” //参数lpfn为指向钩子函数的指针,也即回调函数的首地址; //参数hMod标识了钩子处理函数所处模块的句柄; //参数dwThreadId 指定被监视的线程,如果明确指定了某个线程的ID就只监视该线程,此时的钩子即为线程钩子; //如果该参数被设置为0,则表示此钩子为监视系统所有线程的全局钩子。 //此函数在执行完后将返回一个钩子句柄。 }
} void CMenuEx::UnInstallHook()
{ if(m_hook != NULL) { UnhookWindowsHookEx(m_hook); m_hook = NULL; }
} int CMenuEx::GetSysFontSize()
{HFONT hFont = (HFONT)::GetStockObject(DEFAULT_GUI_FONT);if (hFont == NULL){return 12;}LOGFONT lf;GetObject(hFont, sizeof(LOGFONT), &lf);return abs(lf.lfHeight);
}LPCTSTR CMenuEx::GetSysFontFaceName()
{HFONT hFont = (HFONT)::GetStockObject(DEFAULT_GUI_FONT);if (hFont == NULL){return _T("");}LOGFONT lf;GetObject(hFont, sizeof(LOGFONT), &lf);return lf.lfFaceName;
}void CMenuEx::SetFontInfo(int nSize, const char* szFontFaceName/*=NULL*/)
{m_nFontSize = nSize;if (szFontFaceName != NULL){m_strFontFaceName = (LPCTSTR)szFontFaceName;}
}void CMenuEx::DestroyMenu()
{ItemInfoIter it = m_ItemList.begin();for ( ; it != m_ItemList.end(); it++){StruItemInfo* pStruItemInfo = (StruItemInfo*)*it;if (pStruItemInfo != NULL){delete pStruItemInfo;pStruItemInfo = NULL;}}CMenu::DestroyMenu();
}EnumaOrderType CMenuEx::GenerateOrderType()
{size_t nSize = m_ItemList.size();if (nSize == 0){return ORDERTYPE_FIRST;} else{ItemInfoIter it = m_ItemList.begin();for ( ; it != m_ItemList.end(); it++){if ((*it)->eOrderType == ORDERTYPE_LAST){(*it)->eOrderType = ORDERTYPE_CENTER;break;}}return ORDERTYPE_LAST;}
}
四:这里去除菜单栏的边框使用了钩子技术,实际上处理菜单消息会跑到我们定义的这个函数里面去LRESULT WINAPI MenuWndProc
注意注册了Hook记得注销。
五:关于踩的坑。我编译的版本是x64,之前在网上查资料,一般设置自己的处理菜单函数都是用的这两个函数GetWindowLong ,SetWindowLong
但是在64位系统下面要使用这两个GetWindowLongPtr,SetWindowLongPtr
SetWindowLongPtr(hWnd, GWL_WNDPROC, (LONG_PTR)MenuWndProc);
这个函数注册我们自己的窗口处理函数,传递一个函数指针过去,x64形式的要传递64位的函数指针,即这种形式(LONG_PTR)MenuWndProc,LONG_PTR类型就表示一个64位的 指针。
之前我传的是(long)MenuWndProc,传了32位的指针,这样如果你是x64的编译形式,就会产生截断,程序报错。
六:设置MFC界面的背景颜色
HBRUSH CMFCDrawnTitleDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);// TODO: 在此更改 DC 的任何特性// TODO: 如果默认的不是所需画笔,则返回另一个画笔switch (nCtlColor){case CTLCOLOR_DLG:HBRUSH aBrush;aBrush = CreateSolidBrush(RGB(30, 34, 39));hbr = aBrush;break;}if (nCtlColor == CTLCOLOR_STATIC){}return hbr;
}