Property Sheet as the View Window of a CFrameWnd (161886)
The information in this article applies to:
- The Microsoft Foundation Classes (MFC), when used with:
- Microsoft Visual C++, 32-bit Editions 4.0
- Microsoft Visual C++, 32-bit Editions 4.1
- Microsoft Visual C++, 32-bit Enterprise Edition 4.2
- Microsoft Visual C++, 32-bit Professional Edition 4.2
This article was previously published under Q161886 SUMMARY The Psview.exe sample illustrates a technique of having a
PropertySheet- like view inside a CFrameWnd-derived class.
The following
files are available for download from the Microsoft Download
Center: Psview.exe For additional information about how
to download Microsoft Support files, click the following article number to view
the article in the Microsoft Knowledge Base: 119591 How to Obtain Microsoft Support Files from Online Services
Microsoft scanned this file for viruses. Microsoft used the most
current virus-detection software that was available on the date that the file
was posted. The file is stored on security-enhanced servers that help to
prevent any unauthorized changes to the file.
NOTE: Use the -d option when running Psview.exe to
decompress the file and recreate the proper directory structure. MORE INFORMATION The PropertySheet-like view is a window that has the look
of PropertySheet. It contains a row of tabs; clicking each tab will load the
appropriate page (or dialog template). NOTE: This article does not
make use of either the Property Sheet or the Property Pages like the SNAPVW
sample. Because of this, the frame window that contains the PropertySheet-like
view can be resized as it normally would. However, controls inside a page (or
dialog template) need to be moved manually to fit the page as they appear in a
regular dialog box. The picture below shows the general layout of
the frame window when it is first running: CFrameWnd-derived class
+---------------------------------------------------+
| +-----------------------------------------------+ |
| | CToolBar class | |
| +-----------------------------------------------+ |
| +-----------------------------------------------+<----+
| | CTabCtrl class | | |
| |-----------------------------------------------| | |
| | | | |
| | | | |
| | CDialog-derived class | | |-- CView-derived
| | (a child of CTabCtrl class) | | | class
| | | | |
| | | | |
| | | | |
| +-----------------------------------------------+<----+
| +-----------------------------------------------+ |
| | CStatusBar class | |
| +-----------------------------------------------+ |
+---------------------------------------------------+
As the picture shows, a frame window (CFrameWnd-derived class)
contains the following child windows:
- toolbar (CToolBar)
- view (CView-derived class)
- status bar (CStatuBar)
The view window has tab control (CTabCtrl) as its child window,
and tab control has one or more modeless dialog boxes (CDialog-derived class)
as its child windows. In other words, the tab control will occupy the whole
client area of the view window and the modeless dialog boxes (or pages) will
occupy the display rectangle inside the tab control. However, there can be only
one page visible at any given time. For simplicity, all pages in the
sample code are created after the tab control is successfully created in the
view window. (The code for page creation can be found in the CreatePages()
function in tabview.cpp file.) These pages will not be destroyed until the
application shuts down. When the view window receives the input focus (when the
application is first running), the page for the first tab will be the visible
page in the display area of the tab control. Whenever a tab is
selected from the tab control, both TCN_SELCHANGING and TCN_SELCHANGE
notification codes will be sent to the parent window (the CView-derived class).
The first notification code is to notify the parent window that the currently
selected tab is about to change. It is a good place to put code to hide the
currently visible page. On the other hand, displaying the newly-selected page
may be handled in the second notification code. The following list
shows the general steps to have a PropertySheet-like view in an
AppWizard-generated application: - Create all pages (or dialog boxes) for the tab control in
dialog resource editor. Each page has a caption (for the tab text), a child
style, and a thin border.
- Create the header and implementation files for all pages
(or dialog boxes) using ClassWizard.
- Make the following changes to the header file (.h) of your
CView-derived class:
- Include "afxtempl.h" at the beginning of your .h file.
It contains all the declarations for a template class variable, m_DlgArray in
the CView-derived class.
- Add the following two member variables to your
CView-derived class:
// Tab control is a child of tab view window.
CTabCtrl* m_TabCtrl;
// Array of all the property-page dialogs
CTypedPtrArray<CObArray, CDialog*> m_DlgArray;
- Add a CreatePages() function prototype to your
CView-derived class:
// Call this function to create all pages for the tab view window.
void CreatePages();
- Add a HandleKeyDownMsg() function prototype to your
CView-derived class. This function will be called in the PreTranslateMessage()
function of your CWinApp-derived class:
// Call this function to handle all WM_KEYDOWN messages. It
// returns TRUE if message is being handled; FALSE otherwise.
BOOL HandleKeyDownMsg(MSG* pMsg);
- Use ClassWizard to add handlers for the following
messages that are sent to your CView-derived class:
WM_CREATE - to
create tab control and all pages for the tab control. WM_SIZE - size the
tab control to cover up your entire view. WM_SETFOCUS - show page for the
first tab in the tab control. - Add the following function prototypes to your
CView-derived class for handling all notification codes sent by the tab
control:
afx_msg void OnTabSelChanging(NMHDR* pnmhdr, LRESULT* pResult);
afx_msg void OnTabSelChange(NMHDR* pnmhdr, LRESULT* pResult);
- Make the following changes to the implementation file
(.cpp) of your CView-derived class:
- Define the identifier (id) for the tab control, such
as:
#define ID_TABCTRL 1111 // id for the CTabCtrl
- Add the following ON_NOTIFY macro to the message map
table:
BEGIN_MESSAGE_MAP(CTabView, CView)
//{{AFX_MSG_MAP(CTabView)
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_SETFOCUS()
... // other message macros
//}}AFX_MSG_MAP
ON_NOTIFY(TCN_SELCHANGE, ID_TABCTRL, OnTabSelChange)
ON_NOTIFY(TCN_SELCHANGING, ID_TABCTRL, OnTabSelChanging)
... // other message macros
END_MESSAGE_MAP()
- Initialize member variable m_TabCtrl to NULL in the
constructor function.
- Perform clean-up in the destructor function of your
CView-derived class. Refer to the destructor function sample in tabview.cpp
file.
- Create tab control and then call the CreatePages()
function in the OnCreate() function. The tab control is a child window of your
view window. Refer to the sample OnCreate() function in tabview.cpp
file.
- Call MoveWindow() to size the tab control in OnSize()
function so the tab control will cover up the entire client area of your view
window. Refer to the sample OnSize() function in tabview.cpp file.
- Call OnTabSelChange() in OnSetFocus() function to show
page for the first tab in tab control. Refer to the sample OnSetFocus()
function in tabview.cpp file.
- Implement OnTabSelChange(), and OnTabSelChanging()
functions: (Sample code can be found in the tabview.cpp file.)
OnTabSelChange - hide the current visible page. OnTabSelChanging - show
the newly selected page. - Implement HandleKeyDownMsg() function to process
CTL+TAB and SHIFT+CTRL+TAB, ENTER and ESCAPE keydown messages. These keystroke
combinations are used to activate a tab that is either before or after the
currently selected tab. Refer to the sample HandleKeyDownMsg() function in
tabview.cpp file.
- Include header files for all pages (CDialog-derived
class) for the tab control.
- Implement the CreatePages() function to create all
pages for the tab control(CTabCtrl). Refer to the sample CreatePages() function
in tabview.cpp file.
- Use ClassWizard to add the PreTranslateMessage() function
to your CWinApp-derived class. In the body of this function, call the view's
HandleKeyDownMsg() function so it gets a chance to handle any keystroke
messages that are relevant to its tab control. For messages that are not
handled by the view, pass them to the default handler. Please refer to the
sample PreTranslateMessage() in psview.cpp file.
The Readme.txt file included with the sample explains in more
detail how the sample is created in AppWizard and what files are included.
REFERENCES Please refer to Visual C++ Books for information about the
classes mentioned in the article and ClassWizard usage for creating .h and .cpp
files for all pages.
Modification Type: | Minor | Last Reviewed: | 8/5/2004 |
---|
Keywords: | kbdownload kbcode kbDocView kbfile kbsample KB161886 |
---|
|