2016-04-20 47 views
1

ボタンをクリックして、タイマーが終了するまでボタンを押したままにします。CButton:SetStateを使用すると、OnBnClicked()があまり呼び出されない

CButton::SetState(TRUE)の機能を使用すると、OnBnClickedButton1()が常に2回呼び出され、さらに悪いことに、ダイアログ内の別のボタンを押すか、ダイアログウィンドウを非表示にすると再び呼び出されます。

(更新:。。私は今WindowsXPのとVS6の下で自宅で同じコードをテストしている予想通り、それは正常に動作し、作業時(ウィンドウ10とVS2010)このコードは動作しません)

ヘッダファイル

class CTestDialog : public CDialog 
{ 
    CButton btnButton1; 

    enum {eTimerCoolingId = 123}; 
    BOOL m_bCooling; 
    DWORD m_dwStartTick; 
    ... 
} 

CPPファイルが

... 
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); 
} 
+0

同じボタンまたは異なるボタンに対してbtnStartTimerとOnBnClickedButton1はありますか? –

+0

ボタンを無効に表示します。 – acraig5075

+0

ボタンのIDは何ですか?同じIDを2回使用していますか? OnBnClickedButton1を他のメッセージのために呼び出していますか(メッセージマップ参照)ですか? OnBnClickedButton1にブレークポイントを設定し、ブレークポイントがヒットするたびにコールスタックをチェックして、誰が関数を呼び出しているのか、そしてそのメッセージが何であったのかを確認できます。 –

答えて

0

それは絶望的です。 SetState(TRUE)は非常に怪しげなもので、プッシュボタンのようなものではないでしょう。 MSDNさんの言葉:

"ボタンコントロールがハイライトされているかどうかを設定する"。

さまざまなボタン(Nornal-、Radio-、CheckBox-、MFCButton)で試してみました。これらのボタンのすべてについて:SetStateは、メッセージハンドラを再度呼び出すよう強制します。

私は今チェックボックスボタンを使用してプッシュのようなスタイルを設定する(!?なぜ知らないでください)。 SetState()の代わりにCButton :: SetCheck()を呼び出します。

関連する問題