Toolbar制作菜单条过程详解

原创 2003年10月22日 12:08:00

Toolbar制作菜单条过程详解


现在许多用户界面都使用工具栏制作菜单条,小弟最近对此感兴趣,便从网上求助,可是得到的帮助大多是BCGControlBar的源代码或者是SizableRebar的源代码,对于只希望是自己的界面具有该功能的朋友来说,这也许是不错的选择,只要看一下demo,然后直接调用别人的类库就可以了,但对于我等对此话题感兴趣,希望弄懂其来龙去脉的读者来说,直接看这些没有详细解释的源代码,要从中弄出个所以然来,实不是件容易的是,至少对于像我这样的菜鸟来说是这样的,本文出于此种原因,希望对还在寻求此帮助的读者能提供一些帮助。
下面我们边看边侃:

在接收到toolbarbutton按下消息时,我们一般使用TrackPopupMenuEx弹出菜单,问题的关键是,在菜单未关闭时,TrackPopupMenuEx并不返回,并拦截鼠标和键盘消息,使用spy可以看到,此时的工具栏收不到任何消息,当然无从改变热点,这就需要我们自己探测鼠标位置并在鼠标移动到下一个热点时关闭上一个菜单并显示下一个菜单。这里我们使用钩子函数SetWindowsHookEx在调用TrackPupupMenuEx前安装WH_MSGFILTER钩子,代码如下:
m_hMsgHook = SetWindowsHookEx( WH_MSGFILTER, MessageProc, 0, GetCurrentThreadId() );
MssageProc是钩子函数,代码如下:
LRESULT CALLBACK  MessageProc(int code, WPARAM wParam, LPARAM lParam)
{
    if (code == MSGF_MENU)
    {
        HookMessageProc(lParam);
    }
    return CallNextHookEx(m_hMsgHook, code, wParam, lParam);
}
函数检查消息,如果是来自菜单,则将消息传递给函数HookMessageProc处理,我们所要做的就是在该函数中检测消息WM_MOUSEMOVE,并测试鼠标位置,如果鼠标已经移动到另一个按钮上,则关闭菜单并显示下一个菜单,关闭菜单使用消息WM_CANCELMODE,当菜单关闭后,我们要释放钩子,在下一个菜单弹出时重新安装钩子,弹出菜单示例代码如下:
void TrackPopup(HWND hWndToolBar, int iButton)
{
    while (iButton >= 0)
    {
        SendMessage(hWndToolBar,TB_SETHOTITEM,iButton,0);
        iPopup = iButton;
        //安装钩子
        g_hMsgHook = SetWindowsHookEx(WH_MSGFILTER, MessageProc, 0, GetCurrentThreadId());
        //弹出菜单
        TrackPopupMenuEx(…);
        //卸载钩子
        UnhookWindowsHookEx(g_hMsgHook);
        iButton = iNextPop; //下一个弹出项,若为负,则退出
    }
    SendMessage(hWndToolBar,TB_SETHOTITEM,-1,0);

}
(经验与建议:如果button使用样式TBSTYLE_DROPDOWN,请不要在消息TBN_DROPDOWN中直接调用该函数,应使用中间消息,然后使用PostMessa个发送该消息,以使TBN_DROPDOWN可以直接返回,否则消除第一个高亮热点是很麻烦的事。)
iPopup为当前弹出项,iNextPop为下一个弹出项,这些变量需要在函数HookMessageProc中处理,示例代码如下:
void HookMessageProc(MSG * pMsg)
{
    if (pMsg->message == WM_MOUSEMOVE)
    {
        int iButton, iCount;
        POINT pt = { LOWORD(pMsg->lParam), HIWORD(pMsg->lParam) };
        ScreenToClient(hWndToolbar, &pt);
        iButton = SendMessage(hWndToolbar, TB_HITTEST, 0, &pt);
        iCount = SendMessage(hWndToolbar, TB_BUTTONCOUNT, 0, 0);
        if (iPopup != iButton && iButton < iCount && iButton >= 0)
        {
            iNextPop = iButton;
            SendMessage(hWndMain, WM_CANCELMODE, 0, 0);
(经验与建议:不要试图在此处调用TrackPopup,我曾试图取消该函数内的while循环,直接在此调用该函数,结果是在TrackPopupMenuEx未返回之前,该函数已被调用)
        }
        else
        {
            iNextPop = -1;
        }
    }
}
这里,仅仅处理了鼠标移动消息,真正的菜单还应处理键盘导航消息,详细的代码可以参考
BCGControlBar(http://www.vckbase.com/code/downcode.asp?id=1382)
或SizableRebar(http://www.codeproject.com/docking/sizablerebar/SizableRebar_demo.zip
),
有了这底层框架,这些处理过程应该不再困难,文章所涉及到的一些API函数可以参考msdn。
Msdn上相关资料:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/faq/iemenubar.asp
http://www.microsoft.com/msj/0199/c/c0199.aspx

Android ToolBar 使用完全解析

ToolBar简介ToolBar是Android 5.0推出的一个新的导航控件用于取代之前的ActionBar,由于其高度的可定制性、灵活性、具有Material Design风格等优点,越来越多的应...
  • a553181867
  • a553181867
  • 2016年05月07日 11:12
  • 17437

VS2013/MFC编程入门之三十四(工具栏:工具栏资源及CToolBar类)

上一节中讲了菜单及CMenu类的使用,这一节讲与菜单有密切联系的工具栏。        工具栏简介        工具栏一般位于主框架窗口的上部,菜单栏的下方,由一些带图片的按钮组成。当用...
  • zhaoyinhui0802
  • zhaoyinhui0802
  • 2016年12月05日 23:21
  • 2512

Android自定义工具栏(二)——试试Toolbar

接上篇,上篇提到要实现下面这个样子的工具栏: 主要是两个改动:一是把三个小圆点换成三个小方点,还有就是把弹出菜单的位置改到下面。 既然需要用到Toolbar这个组件,首先先在layout里加上下面这段...
  • TurkeyCock
  • TurkeyCock
  • 2016年07月06日 11:41
  • 2760

自定义控件:菜单按钮关联动画控件(仿toolbar)详解

支持原创哦。yhGO。   项目中需要一个这样的控件,本来是从网上下了一个写好的仿ToolBar控件,但是一看惨不忍睹,只实现了开始和结束两个状态。中间过程的线条变换杂乱无章。又正好学习完Path...
  • yh940612
  • yh940612
  • 2016年10月26日 15:06
  • 201

Extjs-工具条和菜单 Ext.menu和Ext.Toolbar

1.创建一个简单工具条 效果图 Ext.onReady(function(){ // 创建带三个按钮的工具条 var tb = new Ext.Toolbar({...
  • itlwc
  • itlwc
  • 2012年08月17日 16:15
  • 13324

j2se菜单menu和工具条toolbar的简单使用例子

public class my_menu extends JFrame{ //定义组件 //定义菜单的bar JMenuBar jmb = new JMenuBar(); //定义一级菜单...
  • mingli_a
  • mingli_a
  • 2015年03月03日 17:37
  • 306

Android中DrawerLayout和Toolbar实现侧滑菜单

  • 2017年12月26日 16:16
  • 83KB
  • 下载

Toolbar menu 菜单的学习与实现

  • 2017年11月30日 12:48
  • 1.94MB
  • 下载

Android ToolBar使用图标、菜单事件示例

  • 2017年11月10日 13:22
  • 22.75MB
  • 下载

toolbar,syslist,结合右击菜单的控件

  • 2008年08月22日 15:39
  • 3.81MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Toolbar制作菜单条过程详解
举报原因:
原因补充:

(最多只允许输入30个字)