按照MSDN上的说法,只要把SetTimer的第四个参数设为NULL,当定时器的时间用完时,一个WM_TIMER消息就会被放入消息队列中,之后调用OnTimer函数。MSDN上关于OnTimer的说法是这样的:
The framework calls this member function after each interval specified in the SetTimer member function used to install a timer. 这样看来,只要定时器的时间一到,系统就会调用这个OnTimer函数。所以,我们可以通过override窗口的OnTimer函数来做点事情。在VC技术内幕(第5版)上的例子ex12a,就是一个对话框,上面放了三样东西:一个start按钮和一个cancel按钮,以及一个进度条。 它们之间的关系是这样的:按start,进度条开始走,走完之后对话框自动关闭。按cancel按钮会导致进度条一下子变满,之后关闭对话框。三个相关的函数如下所示:void CComputeDlg::OnStart()
{
MSG message; m_nTimer = SetTimer(1, 100, NULL); // 1/10 second
ASSERT(m_nTimer != 0);
GetDlgItem(IDC_START)->EnableWindow(FALSE);
volatile int nTemp;
for (m_nCount = 0; m_nCount < nMaxCount; m_nCount++)
{
if (m_nCount==800)
{
int a = 1;
}
for (nTemp = 0; nTemp < 50000; nTemp++)
{
// uses up CPU cycles
} if (::PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&message);
::DispatchMessage(&message);
}
}
CDialog::OnOK();
}void CComputeDlg::OnTimer(UINT nIDEvent)
{
CProgressCtrl* pBar = (CProgressCtrl*) GetDlgItem(IDC_PROGRESS1);
pBar->SetPos(m_nCount * 100 / nMaxCount);
}void CComputeDlg::OnCancel()
{
TRACE("entering CComputeDlg::OnCancel\n");
if (m_nCount == 0) { // prior to Start button
CDialog::OnCancel();
}
else { // computation in progress
m_nCount = nMaxCount; // Force exit from OnStart
}
}
-----------------------------------------------------------------------------------------
我的问题是这样的:
如果去掉OnStart函数中的
if (::PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&message);
::DispatchMessage(&message);
}
进度条就不会动了,可这是为什么呢?按照我的理解,只要时间到了,框架就自动调用OnTimer函数,而我自己又做了一个测试,只要执行CProgressCtrl::SetPos进度条就会往前走,既然这样,那么进度条的前进就应该和这个if结构体没有关系,可事实上不是这样的。难道这个WM_TIMER消息不是自动发送的,而是由这个if结构体发送的?还望高人指点,多谢多谢!
The framework calls this member function after each interval specified in the SetTimer member function used to install a timer. 这样看来,只要定时器的时间一到,系统就会调用这个OnTimer函数。所以,我们可以通过override窗口的OnTimer函数来做点事情。在VC技术内幕(第5版)上的例子ex12a,就是一个对话框,上面放了三样东西:一个start按钮和一个cancel按钮,以及一个进度条。 它们之间的关系是这样的:按start,进度条开始走,走完之后对话框自动关闭。按cancel按钮会导致进度条一下子变满,之后关闭对话框。三个相关的函数如下所示:void CComputeDlg::OnStart()
{
MSG message; m_nTimer = SetTimer(1, 100, NULL); // 1/10 second
ASSERT(m_nTimer != 0);
GetDlgItem(IDC_START)->EnableWindow(FALSE);
volatile int nTemp;
for (m_nCount = 0; m_nCount < nMaxCount; m_nCount++)
{
if (m_nCount==800)
{
int a = 1;
}
for (nTemp = 0; nTemp < 50000; nTemp++)
{
// uses up CPU cycles
} if (::PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&message);
::DispatchMessage(&message);
}
}
CDialog::OnOK();
}void CComputeDlg::OnTimer(UINT nIDEvent)
{
CProgressCtrl* pBar = (CProgressCtrl*) GetDlgItem(IDC_PROGRESS1);
pBar->SetPos(m_nCount * 100 / nMaxCount);
}void CComputeDlg::OnCancel()
{
TRACE("entering CComputeDlg::OnCancel\n");
if (m_nCount == 0) { // prior to Start button
CDialog::OnCancel();
}
else { // computation in progress
m_nCount = nMaxCount; // Force exit from OnStart
}
}
-----------------------------------------------------------------------------------------
我的问题是这样的:
如果去掉OnStart函数中的
if (::PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&message);
::DispatchMessage(&message);
}
进度条就不会动了,可这是为什么呢?按照我的理解,只要时间到了,框架就自动调用OnTimer函数,而我自己又做了一个测试,只要执行CProgressCtrl::SetPos进度条就会往前走,既然这样,那么进度条的前进就应该和这个if结构体没有关系,可事实上不是这样的。难道这个WM_TIMER消息不是自动发送的,而是由这个if结构体发送的?还望高人指点,多谢多谢!
解决方案 »
- MATLAB与VC混编中出现“unknown character 'oxoa'”
- 频繁的修改static文字和EditBox中的文字会出现闪烁现象。
- CComboBoxEx 中不响应OnDropDown函数,怎么处理
- MFC下 socketTCP网络传输文件为什么传下来的会比实际文件大,怎么解决???
- [■]如何裁剪图像的某个区域???
- 可以把SDI做成对话框的样子吗??(View自CFormView派生
- 无解之题-----能给出满意答案者连加500分*3次
- 我想去掉SDI边框上的“最大化”按钮或让其不可用要怎么做?
- ----请教关于TCP协议的问题!----
- 急!!!请高手帮忙解决!
- 有关定时器
- 如何动态修改根菜单和弹出菜单的文字?
int m_nTimer;
int m_nCount; //在InitalDialog中设为0
enum {nMaxCount = 10000};
{
::TranslateMessage(&message);
::DispatchMessage(&message);
}
的作用是保持消息的流动,去掉了以后,消息就没办法到达你的窗口过程了,既界面线程执行了那个非常消耗cpu时间的for循环,没办法响应消息。
WM_TIMER是要通过消息循环才能到达你的窗口过程,如果界面线程执行了那个非常消耗cpu时间的for循环,没办法响应消息,OnTimer函数是不会执行的。
建议lz看一下《windows程序设计》这本书,了解一下windows的GUI子系统的工作原理
那么这个循环可以处理WM_TIMER,那么应该即使程序中没有
这个消息循环处理也应该处理WM_TIMER事件呀?
哪为什么去掉循环会不行呢?
学习中???
肯定不能,ok
看一下lz的例子,线程在执行那个非常消耗cpu时间的for循环的时候还会同时执行消息循环么?
我原来错误以为SetTimer后随时可能触发WM_TIMER消息,
不应该等到函数结束后才触发WM_TIMER,
I get it,thank you!