ToolBar Button and Cursor in MFC
-
I am a newbie to MFC and want to do the following: I have a button added to a toolbar. I have also added the following in my code for the function to be executed once the Button is clicked: ON_COMMAND(ID_BUTTONRUN, OnRunTests)What I want is when the button is clicked I want the button state to be disabled and the cursor to look like a Hourglass untill the OnRunTests() is completed. I tried the :ON_UPDATE_COMMAND_UI(ID_BUTTONRUN, OnToolbarRunUpdate) but this got executed only after the OnRunTests() completed which is not what I want. Is there a way for me to change the cursor and the button state as soon as the OnRunTests() is entered and change it back when it is done. Any help and guidance will be appreciated.
-
I am a newbie to MFC and want to do the following: I have a button added to a toolbar. I have also added the following in my code for the function to be executed once the Button is clicked: ON_COMMAND(ID_BUTTONRUN, OnRunTests)What I want is when the button is clicked I want the button state to be disabled and the cursor to look like a Hourglass untill the OnRunTests() is completed. I tried the :ON_UPDATE_COMMAND_UI(ID_BUTTONRUN, OnToolbarRunUpdate) but this got executed only after the OnRunTests() completed which is not what I want. Is there a way for me to change the cursor and the button state as soon as the OnRunTests() is entered and change it back when it is done. Any help and guidance will be appreciated.
In resource.h:
#define WM_DOSOMETHING 12345//or whatever
In mainfrm.h, add a custom-message handler:afx_msg LRESULT OnDoSomething(WPARAM,LPARAM);
In the BEGIN_MESSAGE_MAP macro in mainfrm.cpp:ON_MESSAGE(WM_DOSOMETHING,OnDoSomething)
In the implementation for OnDoSomething:LRESULT CMainFrame::OnDoSomething(WPARAM,LPARAM) { m_wndToolBar.GetToolBarCtrl().EnableButton(ID_EDIT_COPY,FALSE); m_wndToolBar.RedrawWindow(); return 0; }
In your view class:void CWhateverView::OnUpdateEditCopy(CCmdUI* pCmdUI) { if (m_bDisable) pCmdUI->Enable(FALSE); else pCmdUI->Enable(TRUE); }
In your function for long operation:void CWhateverView::OnEditCopy() { m_bDisable = TRUE; BeginWaitCursor(); AfxGetApp()->GetMainWnd()->SendMessage(WM_DOSOMETHING); //long operation begin... int i, j,k; for (i = 0; i < 10000; i++) for (j = 0; j < 10000; j++) for (k = 0; k < 5; k++) { } //long operation end. m_bDisable = FALSE; }
And don't forget to declare m_bDisable in CWhateverView.h and initialize it as m_bDisable = FALSE; in the class constructor. this is this. -
In resource.h:
#define WM_DOSOMETHING 12345//or whatever
In mainfrm.h, add a custom-message handler:afx_msg LRESULT OnDoSomething(WPARAM,LPARAM);
In the BEGIN_MESSAGE_MAP macro in mainfrm.cpp:ON_MESSAGE(WM_DOSOMETHING,OnDoSomething)
In the implementation for OnDoSomething:LRESULT CMainFrame::OnDoSomething(WPARAM,LPARAM) { m_wndToolBar.GetToolBarCtrl().EnableButton(ID_EDIT_COPY,FALSE); m_wndToolBar.RedrawWindow(); return 0; }
In your view class:void CWhateverView::OnUpdateEditCopy(CCmdUI* pCmdUI) { if (m_bDisable) pCmdUI->Enable(FALSE); else pCmdUI->Enable(TRUE); }
In your function for long operation:void CWhateverView::OnEditCopy() { m_bDisable = TRUE; BeginWaitCursor(); AfxGetApp()->GetMainWnd()->SendMessage(WM_DOSOMETHING); //long operation begin... int i, j,k; for (i = 0; i < 10000; i++) for (j = 0; j < 10000; j++) for (k = 0; k < 5; k++) { } //long operation end. m_bDisable = FALSE; }
And don't forget to declare m_bDisable in CWhateverView.h and initialize it as m_bDisable = FALSE; in the class constructor. this is this.Thanks so much for your explaination and sample. It reall helped me. One question is : when I do BeginWaitCursor() it shows the hourglass for a fleeting second and again changes back to the arrow cursor. It does not stay as hourglass for the entire lengthy operation. Any help how to fix that?