
如何发送命令到文档对象
展开全部
在这个程序中,我创建了一个文档对象和几个视图。文档对象负责有规律地采集数据,然后通知相关的视图以不同的格式显示这些数据。文档对象为了有规律地采集数据,它需要一个定时(time)事件。但是,文档不是一个基于窗口的对象,所以它没有这样的定时事件。我权衡了三种解决方案:在其中的一个视图中创建定时器。当事件发生时通知文档对象获取数据。为每一个文档(或在每个文档内)创建一个单独的线程,以便这个线程能有规律地创建时间事件。在CMainFrame中创建一个定时器并从中调用文档函数这三种方法我都不满意。能否给出一种更好的解决方案?解答: 在你列出的解决方案中,将定时器放入视图是最糟的想法,因为那样的话你就得为每个视图建一个定时器,你应该将定时器视为一种相对有限的资源(这一点在过去尤其如此,现在这个问题考虑得较少)。创建单独的线程对于定时器这样简单的东西又有牛刀弑鸡之嫌。线程无疑使事情复杂化。那么还有第三个方案:在主框架中创建定时器并从中调用文档函数。我会告诉你如何用这个方案直截了当地实现所要的功能,然后我还会展示另外一种你没有想到的方法。
假设你不愿意用第三种方案的原因是它需要从主框架中调用文档,这样做有点丑陋。(为什么框架要掺乎到文档中去呢?)但有一种直截了当的方法来做,不用直接调用CMyDoc::DoTimerThing,你可以将WM_TIMER消息转换成一个ID为ID_APPTIMER的WM_COMMAND,并用通常的方式广播这个命令以便文档能用ON_COMMAND处理它,文档无法处理所有的窗口消息,但它们可以处理WM_COMMAND。事实上,这是MFC命令处理例程体系结构的主要创新之一,它使非窗口对象可以处理命令。所以这样看来,你要做的事情就是://CMainFrame::OnTimer(...){ SendMessage(WM_COMMAND, ID_APPTIMER);}// 也就是说,当主框架得到定时器信号的同时,也向自己发送了一个ID_APPTIMER命令。MFC会将这个命令发送到系统,任何具有ON_COMMAND处理器并能处理ID_APPTIMER命令的对象都可以处理这个事件。你可以用ON_COMMAND_EX来对付多个对象处理相同事件的情况。
这样做虽然能行得通,但有一个问题。MFC只把命令发送到活动视图/文档。如果其它文档处于打开状态,但没有被激活,则它们不会得到WM_COMMAND消息。虽然你可以修改程序把命令广播到非激活文档,但那样的话,像“文件|保存”这样普通的命令会被发送到所有的文档——很狼狈!因为我们只需要定时器命令到达所有文档。怎么办呢?如何发送WM_COMMAND到所有的文档?
MFC将命令发送到文档这样的非窗口对象,其方法是通过虚函数CCmdTarget::OnCmdMsg来实现的。当窗口获得WM_COMMAND消息时,它要运行许多CWnd代码和虚函数。最终,控制到达CWnd::OnCommand,由它调用OnCmdMsg。// in CWnd::OnCommandOnCmdMsg(nID, CN_COMMAND, NULL, NULL);// 这里,nID是命令ID,编码CN_COMMAND告诉OnCmdMsg这是个命令事件——与更新UI事件相对(此时编码应该是CN_UPDATE_COMMAND_UI)。其它参数对于CN_COMMAND没用。
假设你不愿意用第三种方案的原因是它需要从主框架中调用文档,这样做有点丑陋。(为什么框架要掺乎到文档中去呢?)但有一种直截了当的方法来做,不用直接调用CMyDoc::DoTimerThing,你可以将WM_TIMER消息转换成一个ID为ID_APPTIMER的WM_COMMAND,并用通常的方式广播这个命令以便文档能用ON_COMMAND处理它,文档无法处理所有的窗口消息,但它们可以处理WM_COMMAND。事实上,这是MFC命令处理例程体系结构的主要创新之一,它使非窗口对象可以处理命令。所以这样看来,你要做的事情就是://CMainFrame::OnTimer(...){ SendMessage(WM_COMMAND, ID_APPTIMER);}// 也就是说,当主框架得到定时器信号的同时,也向自己发送了一个ID_APPTIMER命令。MFC会将这个命令发送到系统,任何具有ON_COMMAND处理器并能处理ID_APPTIMER命令的对象都可以处理这个事件。你可以用ON_COMMAND_EX来对付多个对象处理相同事件的情况。
这样做虽然能行得通,但有一个问题。MFC只把命令发送到活动视图/文档。如果其它文档处于打开状态,但没有被激活,则它们不会得到WM_COMMAND消息。虽然你可以修改程序把命令广播到非激活文档,但那样的话,像“文件|保存”这样普通的命令会被发送到所有的文档——很狼狈!因为我们只需要定时器命令到达所有文档。怎么办呢?如何发送WM_COMMAND到所有的文档?
MFC将命令发送到文档这样的非窗口对象,其方法是通过虚函数CCmdTarget::OnCmdMsg来实现的。当窗口获得WM_COMMAND消息时,它要运行许多CWnd代码和虚函数。最终,控制到达CWnd::OnCommand,由它调用OnCmdMsg。// in CWnd::OnCommandOnCmdMsg(nID, CN_COMMAND, NULL, NULL);// 这里,nID是命令ID,编码CN_COMMAND告诉OnCmdMsg这是个命令事件——与更新UI事件相对(此时编码应该是CN_UPDATE_COMMAND_UI)。其它参数对于CN_COMMAND没用。
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询