经常在网上闲转,发现很多vc热衷着发贴询问在MFC中菜单栏如何重绘,这几天有点闲工夫,写了一个关于MFC菜单重绘的demo,写的很粗糙,很多小细节的地方都没有去仔细处理,希望能对大家有所帮助吧,呵呵也以此抛砖引玉吧。呵呵废话不说了吧,进入正题。
对于菜单如何重绘网上到处都是,在这里就不再罗嗦了,呵呵
对于一个菜单栏如何重绘,我们需要做的第一步工作就是如何不让系统默认的画菜单栏操做去执行。其实解决这个问题很简单,我们只需要处理一下windows的一个消息即可,也就是WM_NCHITTEST消息,WM_NCHITTEST消息返回值(HTMENU)有很多种,其中一个就是告诉系统鼠标是不是在菜单上,我们把这个返回值给屏蔽掉,不让它返回这个值,我拦截这个消息让它返回一个1即可。这样我们就做到了不让系统去做他默认处理菜单的事情了,呵呵。
e.g
if(message == WM_NCHITTEST)
{
LRESULT lRet = T::WindowProc(message, wParam, lParam);
if (lRet == HTMENU)
{
return 1;
}
return lRet;
}
紧接着下来的工作就是我们自己要绘制我们想要的菜单栏了。在这里一个非常关键Win32 API GetMenuBarInfo,通过这个函数我们去获取菜单栏响应位置信息
如何使用这个函数,详细使用方法见MSDN,我就不详细介绍了,读者自己去看,通过这个API我们就获取了我们想需要得到的信息了,下来就绘制了。
e.g
MENUBARINFO __getMenuBarInfo(long idItem)
{
MENUBARINFO _menuBarInfo;
_menuBarInfo.cbSize = sizeof(MENUBARINFO);
GetMenuBarInfo(OBJID_MENU, idItem, &_menuBarInfo);
return _menuBarInfo;
}
如何去绘制我们的菜单栏呢,我们需要处理一下几个消息:
WM_KICKIDLE
WM_MOUSELEAVE
WM_NCHITTEST
WM_GETDLGCODE
WM_ACTIVATE
WM_NOTIFY
WM_NCPAINT
WM_LBUTTONDOWN
WM_ENTERIDLE
详细的处理过成见代码吧,我就不详细介绍了,如果有更好的方法来处理菜单栏重绘的方法希望告诉我一声,呵呵。下面附上完整代码:
e.g
template<class T >
class CODrawMenuBar : public T
{
public:
CODrawMenuBar(void)
{
m_btrackPopupMenu = m_bMouseOver = FALSE;
m_MenuItemPos = -2;
m_trackPopuMenu = -1;
};
CODrawMenuBar(UINT nID, CWnd* pParent) : T(nID, pParent)
{
m_btrackPopupMenu = m_bMouseOver = FALSE;
m_MenuItemPos = -2;
m_trackPopuMenu = -1;
}
CODrawMenuBar(UINT nID) : T(nID)
{
m_btrackPopupMenu = m_bMouseOver = FALSE;
m_MenuItemPos= -2;
m_trackPopuMenu = -1;
}
public:
~CODrawMenuBar(void){};
private:
BOOL m_bMouseOver;
int m_MenuItemPos;
BOOL m_btrackPopupMenu;
int m_trackPopuMenu;
protected:
/*
对于菜单栏重绘关键在于:第一禁止系统默认的画操作,要控制这个我们必须同伙WM_NCHITTEST消息
来控制不让系统重绘菜单栏。
第二如何响应原有系统菜单消息。
*/
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
MFC中菜单栏的重绘方法
最新推荐文章于 2024-07-19 12:32:40 发布
本文介绍如何在MFC中自定义菜单栏的重绘,通过处理WM_NCHITTEST消息防止系统默认绘制,并利用Win32 API GetMenuBarInfo获取菜单信息,结合其他消息如WM_KICKIDLE、WM_MOUSELEAVE等实现自定义绘制效果。提供了一个名为CODrawMenuBar的模板类作为示例代码。
摘要由CSDN通过智能技术生成