mfcclistviewctabctrl

MFC: Adding CListView tab to a CTabView (CBCGPTabView) on request doesn't call CMyListView::OnInitialUpdate()


I have a CMyTabView derived from CBCGPTabView (CTabView) that I want to add tabs to on the fly. The tab being added will be a CMyListView derived from CListView. If I add the tab during CMyTabView::OnCreate() it works fine. If I try to do it via a custom message, it adds the tab, but it's blank (CMyListView::OnInitialUpdate() is never called).

What do I need to do for it to work?

Here's what works (the test tab):

int CMyTabView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
  if (__super::OnCreate(lpCreateStruct) == -1)
    return -1;

  CBCGPTabWnd &tabctrl=GetTabControl();

  int index=AddView(RUNTIME_CLASS(CMyForm), _T("My Form"));
  if (index!=-1) {
    m_IDTabMyForm=tabctrl.GetTabID(index);
  }

  AddView(RUNTIME_CLASS(CMyListView), _T("Test"));

  tabctrl.HideNoTabs();

  return 0;
}

This doesn't (other than adding the tab with a blank window).

afx_msg LRESULT CMyTabView::OnUwmAddMyListViewTab(WPARAM wparam, LPARAM lparam)
{
  CString mytabname;
  mytabname=_T("My ListView");
  
  // check if tab already exists - if so select it
  CBCGPTabWnd &tabcontrol=GetTabControl();
  for (int i=0; i<tabcontrol.GetTabsNum(); i++) {
    CString tablabel;
    if (tabcontrol.GetTabLabel(i, tablabel)) {
      if (tablabel==mytabname) {
        tabcontrol.SetActiveTab(i);
        return 0;
      }
    }
  }
  // new tab so add it
  int index=AddView(RUNTIME_CLASS(CMyListView), mytabname);
  if (index!=-1) {
    tabcontrol.SetActiveTab(index);
  }
  
  return 0;
}

Solution

  • It turns out you have to call it yourself, version below works:

    afx_msg LRESULT CMyTabView::OnUwmAddMyListViewTab(WPARAM wparam, LPARAM lparam)
    {
      CString mytabname;
      mytabname=_T("My ListView");
      
      // check if tab already exists - if so select it
      CBCGPTabWnd &tabcontrol=GetTabControl();
      for (int i=0; i<tabcontrol.GetTabsNum(); i++) {
        CString tablabel;
        if (tabcontrol.GetTabLabel(i, tablabel)) {
          if (tablabel==mytabname) {
            tabcontrol.SetActiveTab(i);
            return 0;
          }
        }
      }
      // new tab so add it
      int index=AddView(RUNTIME_CLASS(CMyListView), mytabname);
      if (index!=-1) {
        CView* thetabview=GetView(index);
        if (thetabview) {
          // we need to call OnInitUpdate ourself
          thetabview->SendMessage(WM_INITIALUPDATE);
          //make sure any child windows of the view get the message too
          thetabview->SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);
        }
    
        tabcontrol.SetActiveTab(index);
      }
      
      return 0;
    }