Visual C++ in the Tab View of a variety of methods

  • 2020-04-02 02:50:40
  • OfStack

This article illustrates the Visual C++ in the Tab View of a variety of implementation methods, to share for your reference. The details are as follows:

One, the introduction

Tab Control is one of the commonly used controls in VC++ programming. It allows multiple pages to be set in a single dialog box or window, and each page represents a group of controls. When a TAB on a page is selected, the controls inside the page are displayed. The label control allows more information to be displayed in a limited window space and is clearly categorized. At the same time, VC++ provides a simple way to develop applications in a Document/View structure, to save data in documents and display data in views. In both SDI and MDI program, each document can be corresponding to one or more views, but often in displaying data, need to use the same set of data, according to the different views such as list view, such as tree view, or use a view shows part of the data, with another view shows another part of the data, and hope to be able to in the same display area, when you need to switch. Tab View is formed by applying Tab control to the toggling of multiple views.
Through the above analysis, it is not difficult to find that the implementation of a Tab View mainly requires the following two aspects of work:

Implement a TAB window. It should have the function of drawing window, responding to user selection, judging and processing user selection, etc. In this paper, the Tab View implementation method is classified according to the Tab window.

Switch between multiple views. To judge the result of user selection based on the TAB window, select one view from multiple views and display it in the display area.

This paper analyzes and summarizes three Tab View implementation methods:

1) use CTabCtrl control to implement Tab View.
2) use CSheetCtrl Tab selection window to achieve Tab View.
3) use static segmentation window to achieve Tab View.

Two, CTabCtrl control to achieve Tab View

CTabCtrl is the standard control class defined in the MFC class library. Through the processing of message tcn-selchange and the use of function GetCurSel(), SetCurSel(), etc., can well complete the response, judgment and set the label control work, so the use of CTabCtrl control Tab View is a relatively easy method.

1. The main class of the implementation

//To switch the viewport class shown 
class CMyView1 : public CListView
class CMyView2 : public CView
     //Derived label control class
class CViewTabCtrl : public CTabCtrl
     //Defines the main window of the Tab view
class CTabCtrlView : public CWnd
{
    protected:
       CViewTabCtrl m_TabCtl;
    ...
}
class CMainFrame : public CFrameWnd
{
      CTabCtrlView m_TabView;
  ...
}

2. The parent-child relationship between Windows and the location relationship
The following code determines the location relationship between the Windows.
void CTabCtrlView::RecalcLayout()
{    ...
  CRect rect;
  //The client area size of the CTabCtrlView window is
  GetClientRect(&rect);
  m_TabCtl.RecalcLayout(rect, pWnd);
  ...
}
void CViewTabCtrl::RecalcLayout(CRect & rect, CWnd * wnd)
{
  //The label control occupies the client area of the CTabCtrlView window
  SetWindowPos(NULL, rect.left, rect.top, rect.right - rect.left,
        rect.bottom - rect.top, SWP_NOZORDER);
  //Adjust the position of the viewport to be displayed so that it occupies the display area of the label control
  AdjustRect(FALSE, &rect);
  wnd->SetWindowPos(NULL, rect.left, rect.top, rect.right - rect.left,
      rect.bottom - rect.top, SWP_NOZORDER);
}

3. Multi - vision switch between the implementation
Visual switching mainly completes the following work:
//Step 1: set the ID
of the currently active child window CView* pOldActiveView = GetActiveView();
::SetWindowLong(pOldActiveView->m_hWnd, GWL_ID, m_nCurrentExample);
//Step 2: generate a new runtime class
corresponding to the selected viewport CRuntimeClass* pNewViewClass;
switch (nViewID)//
for each view of nViewID {
 case ID_MYVIEW1:
     pNewViewClass = RUNTIME_CLASS(CMyView1);
     break;
 case ID_MYVIEW2:
     pNewViewClass = RUNTIME_CLASS(CMyView2);
     break;
  default:
    ASSERT(0);
    return;
}
//Step 3: prepare the relevant context for the new view class and create a new view
CCreateContext Context;
Context.m_pNewViewClass = pNewViewClass;
Context.m_pCurrentDoc = GetActiveDocument();
CView* pNewView = m_TabView.CreateView(pNewViewClass, CSize(100,100), &Context);
if (pNewView != NULL)
{
         //Step 4: display the new view
         pNewView->ShowWindow(SW_SHOW);
         SetActiveView(pNewView);
         ...
         //Step 5: close the old view
         pOldActiveView->DestroyWindow();
}

During view switching, you need to regenerate the new view and close the old view. But in some cases, you want multiple view Windows to exist at the same time, showing only one at a time and hiding the others. You can save the window information for each new view you add by defining the following data structure and variables.
typedef struct
{
         CWnd *pWnd;   //Window pointer
         char szLabel[32]; //TAB window to view the string
}TCB_ITEM;
//Save each incoming view information to a list
CList <TCB_ITEM *,TCB_ITEM *> m_Views;

When switching, set the parameters SWP_SHOWWINDOW or SWP_HIDEWINDOW in the function SetWindowPos() to display the selected new view or hide the old view. In this way, the View is more flexible, and it is easy to add and remove different views in Tab View.

CSheetCtrl Tab selection window to achieve Tab View

CSheetCtrl is not a class in the MFC class library, and it implements Tab View in much the same way as the previous method. In the "other controls" category of the VC programming source code set of the programmer base site, "A Tab-like Sheet Ctrl" program contains this type of source code, but when used to switch the window to the view switch.

1. TAB window creation

The Attach() function, implemented by CSheetCtrl, is its interface to the outside. Define CSheetsWnd m_Sheet in CTabSheetCtrl. During initialization, CSheetCtrl is created as a child of the CTabSheetCtrl window by calling m_sheet.attach (this).

BOOL CSheetsWnd::Attach(CWnd * pWndParent, COLORREF rgbBackground)
{
     //Determines the size and position of the TAB window
     CRect rect = GetRect(pWndParent);
     ...
     BOOL bResult = Create( ... , rect , ... );
     ...
     return bResult;
}
CRect CSheetsWnd::GetRect(CWnd* pWndParent)
{
     CRect rect;
     pWndParent->GetClientRect(rect);
     rect.top = rect.bottom - GetSystemMetrics(SM_CYVTHUMB);
     return rect;
}

2. Finds the selected view window

CSheetCtrl implements ctabctrl-like functions such as drawing TAB Windows, determining user choices, and so on. It does not save any information about the view itself, and when the view switches, it looks through its parent window to find the view window the user has selected.

//Gets the first view child window pointer function of the parent window 
CWnd* CSheetsWnd::GetFirstView()
{
     m_pViewFind = GetParent()->GetWindow(GW_CHILD);
     //M_hWnd stores the CSheetCtrl TAB window
     //Exclude CSheetCtrl TAB window
         while (m_pViewFind && m_pViewFind->m_hWnd == m_hWnd)
              m_pViewFind = m_pViewFind->GetWindow(GW_HWNDNEXT);
         return m_pViewFind;
}  
//Gets the next view window pointer function
CWnd* CSheetsWnd::GetNextView()
{
         if (m_pViewFind)
         {
             m_pViewFind = m_pViewFind->GetWindow(GW_HWNDNEXT);
             while (m_pViewFind && m_pViewFind->m_hWnd == m_hWnd)
                  m_pViewFind = m_pViewFind->GetWindow(GW_HWNDNEXT);
             return m_pViewFind;
         }
         return NULL;
}

After getting the pointer to the child window (CMyView1, CMyView2) of all parent Windows (CTabSheetCtrl) in a certain order, determine the selected view window according to the space occupied by the title of each child window.
//Gets the first view window pointer 
CWnd* pChild = GetFirstView();
while (pChild)
{
  CRect rect(cx,0,0,0);
  //Rect returns the rectangle size
needed to draw the title of the window   pDC->DrawText(GetViewTitle(pChild), rect, DEFAULTFORMATDRAWTEXT | DT_CALCRECT);
  rect.top = 0;
  rect.bottom = m_DrawRect.Height();
  if ((aPointX > cx - LRB) && (aPointX   <= cx + rect.Width() + LRB))//APointX mouse position of the abscissa
  break;//Find the selected view
  //Gets a pointer to the next view window
  pChild = GetNextView();
  int next = rect.Width() + 6 + LRB;
  cx += next;
}

Four, static partition window to achieve Tab View

Using static split window CSplitterWnd to implement Tab View, its main design idea is to split the window, using Pane(0,0) of splitter window as the display area to switch the View, Pane(0,1) to display the advanced Tab window CWndTab similar to figure 3. The CSplitterWnd window does the work of the CTabCtrlView and CTabSheetView in the above two methods, as a container for the viewing window and TAB window. This method of source code, in the programmer base site also have.

5. Conclusion

The author through the analysis of a number of related program source code, and in the actual programming process, according to the need to achieve their own Tab View. Here is a brief summary of three ways to implement Tab View, I hope to be helpful to the reader's programming.


Related articles: