C++ 利用计时器更新MFC文档/视图应用程序

C++ 利用计时器更新MFC文档/视图应用程序,c++,timer,mfc,C++,Timer,Mfc,我正在试验一个基本(模板)MFC应用程序,我希望根据计时器事件更新CDocument(表示模型)实例,例如,根据循环的运行时间和速度,将循环从客户端区域的一点移动到另一点 我在应用程序类中添加了启动计时器的代码: m_timer = m_pMainWnd->SetTimer( 16, 1000, NULL); 它应该每秒发送60次计时器消息。 然而,我遇到了几个问题: 在派生的CDocument.cpp文件的消息映射中添加项时,引用c2446错误(将成员函数指针强制转换为无效指针)无效

我正在试验一个基本(模板)MFC应用程序,我希望根据计时器事件更新
CDocument
(表示模型)实例,例如,根据循环的运行时间和速度,将循环从客户端区域的一点移动到另一点

我在应用程序类中添加了启动计时器的代码:

m_timer = m_pMainWnd->SetTimer( 16, 1000, NULL);
它应该每秒发送60次计时器消息。 然而,我遇到了几个问题:

在派生的
CDocument
.cpp文件的消息映射中添加
项时,引用c2446错误(将成员函数指针强制转换为无效指针)无效

对具体的
CView
类进行同样的尝试不会导致错误,但不会调用
OnTimer
函数

调用
OnTimer
的唯一位置是在派生的
CFrameWndEx
类中,使用以下签名:

afx_msg void OnTimer( UINT_PTR nIDEvent );
据我所知,
CFrameWndEx
无法调用
CView
CDocument
派生类中的更改


我很确定这是因为我严重缺乏MFC体系结构的知识,所以我希望能得到一些提示。

在CView派生类中添加一个OnTimer函数和ON WM_TIMER message宏。从CView中,可以调用GetDocument()。这是最简单的方法。文档不是窗口,因此无法处理窗口消息。他们唯一能处理的是WM_命令消息,因为MFC让文档有机会通过其命令消息路由响应这些消息

另一种方法是创建TIMERPROC函数


我推荐第一种方法。

将OnTimer函数和ON\u WM\u TIMER message宏添加到CView派生类中。从CView中,可以调用GetDocument()。这是最简单的方法。文档不是窗口,因此无法处理窗口消息。他们唯一能处理的是WM_命令消息,因为MFC让文档有机会通过其命令消息路由响应这些消息

另一种方法是创建TIMERPROC函数


我推荐第一种方法。

就像Joe Willcoxson建议的那样,只需将
OnTimer
方法放在具体的
CView
中即可。但是,您不能像您发布的那样使用
SetTimer
方法:

m_timer = m_pMainWnd->SetTimer( 16, 1000, NULL);
您必须在
CView
类中的某个地方调用它,而不使用
m\u pMainWnd
,例如:

CMyView::OnInitialUpdate()
{
    m_timer = SetTimer( 16, 1000, NULL); // also nullptr instead of NULL would be nice
}

否则,主窗口将始终是处理消息的
CWnd

就像Joe Willcoxson建议的那样,只需将
OnTimer
方法放在具体的
CView
中即可。但是,您不能像您发布的那样使用
SetTimer
方法:

m_timer = m_pMainWnd->SetTimer( 16, 1000, NULL);
您必须在
CView
类中的某个地方调用它,而不使用
m\u pMainWnd
,例如:

CMyView::OnInitialUpdate()
{
    m_timer = SetTimer( 16, 1000, NULL); // also nullptr instead of NULL would be nice
}

否则,主窗口将始终是处理消息的
CWnd

如果不想让window类处理计时器消息,可以将自己的回调传递给。@IInspectable是的,我知道,但它没有解决核心问题,也就是说,我不知道如何使用它来根据计时器消息更新文档/视图。据我所知,
CFrameWndEx
对象对这两者都不了解。你能发布你的
CMyDocument::OnTimer()
函数的签名吗?看到你的问题的人并没有得到全部信息。您需要说明将
放置在\u WM\u TIMER()
上的位置,以及
OnTimer()函数的位置<决不会处理
CDocument
上的\u WM\u TIMER()
上的code>,因为它被定义为由
OnTimer
处理,后者位于
CWnd
中。在消息循环中,
CWnd
上有一个点正在调用
OnTimer
,这是一个在
CDocument
派生类上没有发生的事实。我建议您使用Spy++(64位版本上的Spy++64)查看消息工作流是否正在运行。MFC上没有MVC。您拥有的是文档/视图体系结构:如果不想让window类处理计时器消息,您可以将自己的回调传递给。@IInspectable是的,我知道,但它没有解决核心问题,即我不知道如何使用它根据计时器消息更新文档/视图。据我所知,
CFrameWndEx
对象对这两者都不了解。你能发布你的
CMyDocument::OnTimer()
函数的签名吗?看到你的问题的人并没有得到全部信息。您需要说明将
放置在\u WM\u TIMER()
上的位置,以及
OnTimer()函数的位置<决不会处理
CDocument
上的\u WM\u TIMER()
上的code>,因为它被定义为由
OnTimer
处理,后者位于
CWnd
中。在消息循环中,
CWnd
上有一个点正在调用
OnTimer
,这是一个在
CDocument
派生类上没有发生的事实。我建议您使用Spy++(64位版本上的Spy++64)查看消息工作流是否正在运行。MFC上没有MVC。您拥有的是文档/视图体系结构:正如我在问题中提到的,我使用了第一种方法,但从未调用过OnTimer函数。@IanYoung:您必须显示相关的源代码
CView
派生自
CWnd
,因此您可以安装一个计时器,并拥有
CView
(或
CView
-派生)类的实例来处理计时器消息。m_pMainWnd->GetActiveView()->SetTimer(…)正如我在问题中提到的,我采用了第一种方法,而OnTimer函数从未被调用。@IanYoung:那么您必须显示相关的源代码
CView
源于
CWnd
,因此您可以安装计时器并具有