Toolbar制作菜单条过程详解

文章来源:互联网 作者:ggg82/CSDN

  现在许多用户界面都使用工具栏制作菜单条,小弟最近对此感兴趣,便从网上求助,可是得到的帮助大多是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 = 0)
{
iNextPop = iButton;
SendMessage(hWndMain, WM_CANCELMODE, 0, 0);
}
else
{
iNextPop = -1;
}
}
}
  (经验与建议:不要试图在此处调用TrackPopup,我曾试图取消该函数内的while循环,直接在此调用该函数,结果是在TrackPopupMenuEx未返回之前,该函数已被调用)

  这里,仅仅处理了鼠标移动消息,真正的菜单还应处理键盘导航消息,详细的代码可以参考
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

(0)

相关推荐

  • Android5.0+ CollapsingToolbarLayout使用详解

    CollapsingToolbarLayout作用是提供了一个可以折叠的Toolbar,它继承至FrameLayout,给它设置layout_scrollFlags,它可以控制包含在CollapsingToolbarLayout中的控件(如:ImageView.Toolbar)在响应layout_behavior事件时作出相应的scrollFlags滚动事件(移除屏幕或固定在屏幕顶端). 使用CollapsingToolbarLayout: <android.support.design.wid

  • 分别用ToolBar和自定义导航栏实现沉浸式状态栏

    一.ToolBar 1.在build.gradle中添加依赖,例如: compile 'com.android.support:appcompat-v7:23.4.0' 2.去掉应用的ActionBar.可以是修改主题theme为"NoActionBar",例如: <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> 或者不修改主题为"NoAct

  • Java Swing中的工具栏(JToolBar)和分割面版(JSplitPane)组件使用案例

    一:工具栏(JToolBar) 代码示例: 复制代码 代码如下: import javax.swing.*; //工具栏的使用案例 public class JToolBarDemo2_jigloo extends javax.swing.JFrame { private JToolBar myJToolBar;  private JButton jB_file;  private JButton jB_edit;  private JButton jB_tools;  private JBut

  • iOS应用中使用Toolbar工具栏方式切换视图的方法详解

    关于UIToolbar ToolBar工具栏是视图View的属性,可以在工具栏上添加工具栏按钮Bar Button Item(可以是自定义的Custom.也可以是系统自带的BarButtonSystemItem ),视图控制器可以通过工具栏项对视图中内容进行操作. 注意事项: 在导航栏控制器中会有一个UIToolBar实例,但默认是隐藏的,如果需要显示,需要通过这个方法将其打开: 在这里需要注意的是,与UINavigationBar类似,导航控制器拥有且只拥有一个UIToolBar实例,但UIT

  • jquery toolbar与网页浮动工具条具体实现代码

    jquery 实现toolbar与网页浮动工具条jQuery实现方法 /* 基本StructureWe'll更新index.php教程的HTML代码和对新闻联播style.css教程中的CSS代码. 我们建立了一个固定的面板(ID为工具栏组)两个浮动方面,我们将在第二个步骤与他们的图标和提示气泡(左),一个快速菜单和"隐藏按钮列表"(添加到隐藏工具栏). 我们还可以期待一个"显示按钮",它是有用的,当面板隐藏,我们要重新激活它.基于这个原因,我们添加id为toolb

  • Android自定义Toolbar使用方法详解

    本篇文章介绍: 如何使用Toolbar; 自定义Toolbar; 先来看一看效果,了解一下toolbar: 布局文件: <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@co

  • 深入理解Android 5.0中的Toolbar

    环境说明: Android Studio 2.0 V7包版本:com.android.support:appcompat-v7:23.4.0 compileSdkVersion 23 buildToolsVersion "24.0.0" Toolbar 引入使用 XML布局中加入: <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="ma

  • iOS中的导航栏UINavigationBar与工具栏UIToolBar要点解析

    一.导航栏UINavigationBar 1.导航栏的使用 在iOS开发中,我们通常会使用导航控制器,导航控制器中封装了一个UINavigationBar,实际上,我们也可以在不使用导航控制器的前提下,单独使用导航栏,在UINavigationBar中,也有许多我们可以定制的属性,用起来十分方便. 2.UINavigationBar的创建和风格类型 导航栏继承于UIView,所以我们可以像创建普通视图那样创建导航栏,比如我们创建一个高度为80的导航栏,将其放在ViewController的头部,

  • 微软IE Developer Toolbar安装使用简要图文说明

    微软IE Developer Toolbar是微软专门为Web开发人员设计的一款免费产品,该产品让开发人员能够深入探索和理解Web页面,帮助开发者更好地创建Web应用.安装后可以在IE中快速分析网页的软件.该工具条可集成在IE窗口,或以浮动窗口形式存在.和IE Developer Toolbar功能相似的产品在FireFox下有:Web Developer Toolbar和Firebug,功能都比较强劲. 和其它应用程序一样,下载完IE Developer Toolbar之后,双击程序运行安装,

  • Android自定义ActionProvider ToolBar实现Menu小红点

    今天的几个目标: 1. 自定义ActionProvider 2. Toolbar ActionBar自定义Menu 3. Toolbar ActionBar 右侧Menu添加角标(Toolbar ActionBar Menu添加小红点) 源代码在文章末尾. -------------------------------------------------------------------------------- 效果预览 自定义Menu后不影响原生MD的任何效果.可以通过外部来控制显示的文字

随机推荐