4

I want to catch the tab change event of a CMFCTabCtrl. Below is the code I'm trying to do that. But it does not catch the change event.

BOOL SurvChatDlg::OnNotify( WPARAM wParam, LPARAM lParam, LRESULT* 
                               pResult ) 
{ 
if(((LPNMHDR)lParam)->code==TCN_SELCHANGE) 
{ 
    int i = m_TabControl.GetActiveTab();
    AfxMessageBox("Changed");
} 
return CDialog::OnNotify( wParam, lParam, pResult ); 
}
Aruna Karunarathna
  • 981
  • 2
  • 23
  • 55

2 Answers2

1

According to this forum thread, you need to handle the AFX_WM_CHANGING_ACTIVE_TAB message sent to the parent window.

This forum thread has more code samples.

Edward Clements
  • 5,040
  • 2
  • 21
  • 27
  • Unfortunately it didn't catch the event. By the way the app is not a MDI tab application. – Aruna Karunarathna Jul 23 '13 at 14:30
  • The second forum thread link also shows how to catch the message in `CMainFrame` -- if you do not have a frame window, how are you hosting the tab control? – Edward Clements Jul 23 '13 at 16:21
  • I just override the CMFCTabCtrl class and added this line to the MESSAGE_MAP ON_REGISTERED_MESSAGE(AFX_WM_CHANGING_ACTIVE_TAB, &CMyTabCtrl::OnAfxWmChangingActiveTab) – Aruna Karunarathna Jul 24 '13 at 03:55
  • The `AFX_WM_CHANGING_ACTIVE_TAB` message is not sent to the tab control, it is sent to the parent -- are you embedding the tab control in a dialog or a SDIWindow or which kind of a window? – Edward Clements Jul 24 '13 at 06:33
  • It is in an object in a CDialog. – Aruna Karunarathna Jul 24 '13 at 09:57
  • your reply is not clear enough, is the parent of the tab control your dialog class or an object within the dialog? The `ON_REGISTERED_MESSAGE(AFX_WM_CHANGING_ACTIVE_TAB...)` should be declared in the class of the parent and should point to a member function in the class of the parent -- see if the function is invoked when you switch tabs – Edward Clements Jul 24 '13 at 10:42
  • Sorry for my bad English. ON_REGISTERED_MESSAGE(AFX_WM_CHANGING_ACTIVE_TAB...) is in the CMyTabCtrl class which inherited from the CMFCTabCtrl. And I am using a CMyTabCtrl object in the CDialog class. Is it clear now? – Aruna Karunarathna Jul 25 '13 at 04:30
  • Then try moving your `ON_REGISTERED_MESSAGE` and the function to `CDialog`, like `ON_REGISTERED_MESSAGE(AFX_WM_CHANGING_ACTIVE_TAB, &CMyDialog::OnAfxWmChangingActiveTab)` – Edward Clements Jul 25 '13 at 06:28
1

If you want to catch the post tab change, the tab that will be active, need AFX_WM_CHANGE_ACTIVE_TAB ie;

ON_REGISTERED_MESSAGE(AFX_WM_CHANGE_ACTIVE_TAB,OnTabSetActive)

LRESULT CYourClass::OnTabSetActive(WPARAM wParam, LPARAM lParam)
{
    const int iActiveTab = (int)wParam;
    int iCheckActiveTab = m_wndTabs.GetActiveTab(); //CMFCTabCtrl m_wndTabs;
    m_wndTabs.SetActiveTab(iActiveTab); //good idea to also add this depending on usage.
    return 0;
}

And if you require manually changing the tab call using;

    SendMessage(AFX_WM_CHANGE_ACTIVE_TAB, iTabNum2ChangeTo, 0);

Posted the above after trying to find a solution to my problem where using

CMFCTabCtrl::SetActiveTab() 

would crash but in debug mode only. And this OP was googles top answer.

AFX_WM_CHANGING_ACTIVE_TAB appears to catch the event prior to the actual tab change, hence why hasn't worked for the OP, and can be checked by;

int iCheckActiveTab = m_wndTabs.GetActiveTab();
ReturnVoid
  • 1,106
  • 1
  • 11
  • 18