网站内容更新机制(【】)
优采云 发布时间: 2022-03-08 17:11网站内容更新机制(【】)
孙鑫解释道:
举个比较简单的例子,如果要在菜单项中设置禁用功能,那么首先系统会在菜单显示时发送一条WM_INITMENUPOPUP消息,然后程序窗口基类会接管这个消息,然后它会构造一个 CCmdUI 对象,与第一个菜单项相关联,并调用 Doupdate() 函数,该函数发送一个 CN_UPDATE_COMMAND_UI 消息,该消息封装了一个 CCmdUI 类型的指针。根据消息映射原理,系统会查看是否有这样一个ON_UPDATE_COMMAND_UI宏来接管消息,如果有消息映射,根据这个指针调用相应的函数,如(CCmdUI*)pCmdUI-> Enable(FALSE) 将这个菜单项禁用。更新完成后,相同的 CCmdUI 对象将与第二个菜单项相关联并依次处理。直到所有操作完成。
其他解释:
在 MFC 框架中,可以使用 ON_UPDATE_COMMAND_UI(id, memberFxn )
宏指定菜单或工具栏按钮等相应的状态设置功能
在memberFxn中,可以通过传入的CCmdUI对象指针来设置菜单项,
工具按钮的使用、禁用、标记等属性。
memberFxn中指定条件的所有变化都会实时反映在界面上。
其实现机制如下
工具栏按钮更新
由于工具栏始终可见,因此要实时更新,您必须不断调用 memberFxn 来检查更新情况
这是在 CWinApp::OnIdle() 和 WM_IDLEUPDATECMDUI 消息中完成的。
① 当程序空闲时,会调用 OnIdle
其基类 CWinThread 中的 OnIdle() 会调用主窗口的消息处理函数来处理 WM_IDLEUPDATECMDUI 消息,
同时向所有从属窗口发送 WM_IDLEUPDATECMDUI 消息。
②框架窗口对应WM_IDLEUPDATECMDUI消息
voidCMDIFrameWnd::OnIdleUpdateCmdUI()
voidCFrameWnd::OnIdleUpdateCmdUI()
需要时,会调用 OnUpdateFrameMenu 来更新菜单项
③每个控制栏,对话框接收WM_IDLEUPDATECMDUI消息
调用 CControlBar::OnIdleUpdateCmdUI() 进行相应的响应
在其中调用 CControlBar::OnUpdateCmdUI 进行更新
④OnUpdateCmdUI是控制条类的虚函数,不同的控制条会有不同的实现
以工具栏为例:
将为其上的每个按钮调用特定窗口的命令处理程序
一、查看是否有对反射消息的处理
还支持自处理
一般情况下会调用DoUpdate进行更新。
DoUpdate 会调用宿主窗口的 OnCmdMsg 进行处理
OnCmdMsg(m_nID, CN_UPDATE_COMMAND_UI,this, NULL);
它的nCode参数是CN_UPDATE_COMMAND_UI,表示是一次接口更新。它会调用ON_UPDATE_COMMAND_UI制作的成员,工具栏的信息会通过
CmdUI 被传递给处理函数。
最后,工具栏将调用 UpdateDialogControls 来更新其上的其他控件。
第二次菜单更新
①空闲时再次调用OnUpdateFrameMenu更新菜单。
该过程与工具栏更新大致相似。
②菜单打开时也会更新。
在 CFrameWnd::OnInitMenuPopup()
在此期间,会调用窗口的 OnCmdMsg(m_nID, CN_UPDATE_COMMAND_UI, this, NULL);
更新每个菜单项。
其他三个
当窗口接收到命令时,会试探性地调用命令的更新函数来测试命令是否被禁用。
如果该命令处于活动状态,它将由 OnCmdMsg 处理。