2016-04-20 1 views
1

Je veux cliquer sur un bouton et l'afficher "pressé" jusqu'à ce qu'une minuterie se termine. Le problème que j'ai est, quand j'utilise CButton::SetState(TRUE) la fonction OnBnClickedButton1() est appelée toujours deux fois et même pire elle est appelée encore quand j'appuie sur un autre bouton dans la boîte de dialogue ou cache la fenêtre de dialogue.CButton: OnBnClicked() est appelé inexprectedly lorsque SetState est utilisé

(Mise à jour:.. J'ai maintenant testé le même code à la maison sous VS6 avec WindowsXP, il fonctionne très bien comme prévu au travail (VS2010 avec fenêtre 10) ce code ne fonctionne pas)

fichier d'en-tête

class CTestDialog : public CDialog 
{ 
    CButton btnButton1; 

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

fichier RPC

... 
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 et OnBnClickedButton1 sont-ils disponibles pour le même bouton ou pour différents boutons? –

+0

Afficher le bouton comme désactivé plutôt. – acraig5075

+0

Quel est l'identifiant du bouton? Utilisez-vous le même identifiant deux fois? Appellez-vous également OnBnClickedButton1 pour d'autres messages (voir la carte des messages)? Vous pouvez définir un point d'arrêt dans OnBnClickedButton1 et vérifier la pile d'appels chaque fois que le point d'arrêt est atteint pour voir qui appelle la fonction et quel était le message. –

Répondre

0

Il est sans espoir. SetState (TRUE) est très fishy et probablement pas indended pour pousser comme des boutons. MSDN dit:

"Définir si un contrôle de bouton est en surbrillance ou non".

Je l'ai essayé avec différents boutons (Nornal-, Radio-, CheckBox-, MFCButton). Pour tous ces boutons: SetState force le gestionnaire de messages à être appelé à nouveau. (Je ne sais pas pourquoi !?)

J'utilise maintenant un bouton Check-Box et réglez le de style push-comme. Et appelez CButton :: SetCheck() au lieu de SetState().