Disabling dialog button from within the ON_BN_CLICKED handler
-
Hi all, I have a problem. I need to start a long computing work when the user clicks a dialog button. During this time the button needs to be disabled. The following simple code doesn't work. Despite the fact that the button changes state from enable to disabled (grayed), it actually gets the mouse inputs. Some of you knows the reason? I wasn't able to disable this button and then I had to write a workaround. Thanks, Daniele Godi /////////////////////////////////////////////////////////////// Sample code void CMyDlg::OnBnClickedButton1() { // disable the button m_ctrlButton1.EnableWindow(FALSE); BeginWaitCursor(); DoSomeLongWork(); EndWaitCursor(); // workaround, I have to remove manually the mouse input from // the message queue if (::GetInputState()) { MSG msg; while ( ::PeekMessage( &msg, NULL, NULL, NULL, PM_NOREMOVE ) ) { // found a mouse message, remove it if ((msg.message >= WM_MOUSEFIRST) && (msg.message <= WM_MOUSELAST)) { ::PeekMessage( &msg, NULL, NULL, NULL, PM_REMOVE); } else { if ( !::AfxGetThread()->PumpMessage() ) { // if FALSE exit both dialog and application EndDialog(FALSE); ::PostQuitMessage( -1 ); return; } } } } m_ctrlButton1.EnableWindow(TRUE); return; } Daniele Godi
-
Hi all, I have a problem. I need to start a long computing work when the user clicks a dialog button. During this time the button needs to be disabled. The following simple code doesn't work. Despite the fact that the button changes state from enable to disabled (grayed), it actually gets the mouse inputs. Some of you knows the reason? I wasn't able to disable this button and then I had to write a workaround. Thanks, Daniele Godi /////////////////////////////////////////////////////////////// Sample code void CMyDlg::OnBnClickedButton1() { // disable the button m_ctrlButton1.EnableWindow(FALSE); BeginWaitCursor(); DoSomeLongWork(); EndWaitCursor(); // workaround, I have to remove manually the mouse input from // the message queue if (::GetInputState()) { MSG msg; while ( ::PeekMessage( &msg, NULL, NULL, NULL, PM_NOREMOVE ) ) { // found a mouse message, remove it if ((msg.message >= WM_MOUSEFIRST) && (msg.message <= WM_MOUSELAST)) { ::PeekMessage( &msg, NULL, NULL, NULL, PM_REMOVE); } else { if ( !::AfxGetThread()->PumpMessage() ) { // if FALSE exit both dialog and application EndDialog(FALSE); ::PostQuitMessage( -1 ); return; } } } } m_ctrlButton1.EnableWindow(TRUE); return; } Daniele Godi
if you apply the
EnableWindow()
directly to a member object, you have to callUpdateData(FALSE)
to update your controls with the changes done on the associated member object (andUpdateData(TRUE)
for the opposite)... otherwise, this single line also works :((CButton*)GetDlgItem(IDC_MY_BUTTON))->EnableWindow(FALSE); // To disable
I assume (of course) that IDC_MY_BUTTON is the ident of the button you want to change the state...
TOXCCT >>> GEII power
[toxcct][VisualCalc] -
Hi all, I have a problem. I need to start a long computing work when the user clicks a dialog button. During this time the button needs to be disabled. The following simple code doesn't work. Despite the fact that the button changes state from enable to disabled (grayed), it actually gets the mouse inputs. Some of you knows the reason? I wasn't able to disable this button and then I had to write a workaround. Thanks, Daniele Godi /////////////////////////////////////////////////////////////// Sample code void CMyDlg::OnBnClickedButton1() { // disable the button m_ctrlButton1.EnableWindow(FALSE); BeginWaitCursor(); DoSomeLongWork(); EndWaitCursor(); // workaround, I have to remove manually the mouse input from // the message queue if (::GetInputState()) { MSG msg; while ( ::PeekMessage( &msg, NULL, NULL, NULL, PM_NOREMOVE ) ) { // found a mouse message, remove it if ((msg.message >= WM_MOUSEFIRST) && (msg.message <= WM_MOUSELAST)) { ::PeekMessage( &msg, NULL, NULL, NULL, PM_REMOVE); } else { if ( !::AfxGetThread()->PumpMessage() ) { // if FALSE exit both dialog and application EndDialog(FALSE); ::PostQuitMessage( -1 ); return; } } } } m_ctrlButton1.EnableWindow(TRUE); return; } Daniele Godi
Hi, why don't u check LockWindowUpdate() and unLockWindowUpdate(). :cool: Lokesh
-
Hi, why don't u check LockWindowUpdate() and unLockWindowUpdate(). :cool: Lokesh
-
if you apply the
EnableWindow()
directly to a member object, you have to callUpdateData(FALSE)
to update your controls with the changes done on the associated member object (andUpdateData(TRUE)
for the opposite)... otherwise, this single line also works :((CButton*)GetDlgItem(IDC_MY_BUTTON))->EnableWindow(FALSE); // To disable
I assume (of course) that IDC_MY_BUTTON is the ident of the button you want to change the state...
TOXCCT >>> GEII power
[toxcct][VisualCalc] -
The code is exactly the same I have provided on my first query. (Except for the workaround) I work with MS Visual Studio .NET 2003 The application is MFC based. The Dlg-box is modal Build a empty application and add an handler to the OK button on the about box, then 1 - at the beginnig of the handling function disable the button that the user pressed using the wrapper class m_ctrlButtonOK.EnableWindow(FALSE) (same as GetDlgItem(ID)->EnableWindow(FALSE)) 2 - perform a long work ::MessageBeep(MB_OK); ::Sleep(10000); works fine... 3 - at the end of the function call m_ctrlButtonOK.EnableWindow(TRUE) If you click on the OK button while it is disabled, you will see that after the work the handler function get called once again. Thank you and ciao... Daniele
-
The code is exactly the same I have provided on my first query. (Except for the workaround) I work with MS Visual Studio .NET 2003 The application is MFC based. The Dlg-box is modal Build a empty application and add an handler to the OK button on the about box, then 1 - at the beginnig of the handling function disable the button that the user pressed using the wrapper class m_ctrlButtonOK.EnableWindow(FALSE) (same as GetDlgItem(ID)->EnableWindow(FALSE)) 2 - perform a long work ::MessageBeep(MB_OK); ::Sleep(10000); works fine... 3 - at the end of the function call m_ctrlButtonOK.EnableWindow(TRUE) If you click on the OK button while it is disabled, you will see that after the work the handler function get called once again. Thank you and ciao... Daniele
Dear all, I found the solution and I like to share it with you. I took the idea from an article I have found on your site, http://www.codeproject.com/cpp/cppforumfaq.asp#ui\_workerthread I implemented this code within the button handler and... wonder!, it works. OnButtonClicked() { m_crtlButton->Enable(FALSE); while (Do_A_Bit_Of_Work()) { MSG msk; while(PeekMessage(&msg, NULL, NULL, PM_NOREMOVE) { AfxGetApp()->PumpMessage(); } } m_crtlButton->Enable(TRUE); return; } Ciao and thanks for your kind help. Daniele