WEB开发网
开发学院软件开发VC 未引用参数,添加任务栏命令及其它 阅读

未引用参数,添加任务栏命令及其它

 2006-07-20 11:40:57 来源:WEB开发网   
核心提示: CSysCmdRouter 是如何实现其魔法的呢?简单:它使用我那个以前专栏中无处不在的 CSubclassWnd,CSubclassWnd 使你不用从其派生便能子类化 MFC 窗口对象,未引用参数,添加任务栏命令及其它(7),CSysCmdRouter 派生自 CSubclassWnd

CSysCmdRouter 是如何实现其魔法的呢?简单:它使用我那个以前专栏中无处不在的 CSubclassWnd。CSubclassWnd 使你不用从其派生便能子类化 MFC 窗口对象。CSysCmdRouter 派生自 CSubclassWnd 并使用它子类化主框架。尤其是它截获发送到框架的 WM_SYSCOMMAND 消息。如果命令 ID 属于系统命令(大于 SC_SIZE = 0xF000),则 CSysCmdRouter 沿着 Windows 一路传递该消息;否则便吃掉 WM_SYSCOMMAND 并重新将它作为 WM_COMMAND 发送,于是 MFC 按照其常规路由过程,调用你的 ON_COMMAND 处理器。很聪明,是不是?

那么 ON_UPDATE_COMMAND_UI 处理器呢?CSysCmdRouter 是如何让它处理系统菜单命令的呢?很简单。就在 Windows 显示菜单前,他向你的主窗口发送一个 WM_INITMENUPOPUP 消息。这是你更新菜单项的最佳时机——启用或禁用它们,添加检讫标志等等。MFC 为每个菜单项创建一个 CCmdUI 对象并将它传递到你的消息映射中相应的 ON_UPDATE_COMMAND_UI 处理器。以它为参数的 MFC 函数是 CFrameWnd::OnInitMenuPopup,这个函数是这样的:

void CFrameWnd::OnInitMenuPopup(CMenu* pMenu, UINT nIndex, BOOL bSysMenu)
{
  if (bSysMenu)
  return; // don''t support system menu
  ...
}

MFC 初始化系统菜单时不做任何事情。为什么要去关心这种事呢?万一你要让 bSysMenu 为 FALSE,即使是系统菜单,那该怎么办?这恰恰是 CSysCmdRouter 做的事情。它截取 WM_INITMENUPOPUP 并清除 bSysMenu 标志,也就是 LPARAM 的 HIWORD:

if (msg==WM_INITMENUPOPUP) {
  lp = LOWORD(lp); // (set HIWORD = 0)
}

现在,当 MFC 获得 WM_INITMENUPOPUP,它认为该菜单是常规菜单。只要你的命令 IDs 与真正的系统菜单不冲突,一切都运行得很好。如果你改写 OnInitMenuPopup,唯一丢失的东西是不能从主窗口菜单中区分系统菜单。嘿,你不能什么都想要!通过改写 CWnd::WindowProc,你总是能处理 WM_INITMENUPOPUP 的,或你想要区分,就比较 HMENUs。但你确实不用关心命令来自何处。

上一页  2 3 4 5 6 7 8  下一页

Tags:引用 参数 添加

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接