I want to click a button and shown it "pressed" until a timer has terminated.
The problem I have is, wenn I use CButton::SetState(TRUE)
the function OnBnClickedButton1()
is called always twice and even worse it is called again when I press a another button in the dialog or hide the dialog window.
(Update: I have now tested the same code at home under VS6 with WindowsXP, it works fine as expected. At work (VS2010 with Window 10) this code does not work.)
Header file
class CTestDialog : public CDialog
{
CButton btnButton1;
enum {eTimerCoolingId = 123};
BOOL m_bCooling;
DWORD m_dwStartTick;
...
}
CPP file
...
DDX_Control(pDX, IDC_BUTTON1, m_btnButton1);
void CTestDialog::OnBnClickedButton1()
{
m_bCooling = !m_bCooling;
m_btnButton1.SetState(m_bCooling);
m_dwStartTick = GetTickCount();
if (m_bCooling)
SetTimer(eTimerCoolingId,100,NULL);
else
KillTimer(eTimerCoolingId);
}
void CTestDlg::OnTimer(UINT nIDEvent)
{
int nCoolTime = 5; // [sec]
CString str;
switch(nIDEvent)
{
case eTimerCoolingId:
int nElapsedTime = (GetTickCount() - m_dwStartTick) / 1000;
if (nElapsedTime > nCoolTime)
{
KillTimer(eTimerCoolingId);
m_bCooling = false;
m_btnButton1.SetState(FALSE);
str.Format("Cooler On");
}
else
{
str.Format("Cooling.. %d [sec]", (nCoolTime - nElapsedTime));
}
}
m_btnButton1.SetWindowText(str);
CDialog::OnTimer(nIDEvent);
}
It's hopeless. SetState(TRUE) is very fishy and probably not indended for push like buttons. MSDN says:
I have tried it with different buttons (Nornal-, Radio-, CheckBox-, MFCButton). For all of this buttons: SetState is forcing the message handler to be called again. (Don't know why!?)
I use now a Check-Box Button and set the push-like style. And call CButton::SetCheck() instead of SetState().