SAMPLE: GENSPLIT Putting a Generic CWnd in a Splitter PaneID: Q151032
|
A splitter window is a special window with the capability of being split
into multiple panes, each usually containing a view. Although the Online
documentation says that any CWnd object can replace a view in a pane, it
does not elaborate on how to do so.
GENSPLIT shows how to put different types of windows in splitter panes. The
sample creates an SDI application and creates a splitter window with four
panes. The panes contain a view, a generic CWnd derived window, a listbox,
and a dialog.
The following file is available for download from the Microsoft
Software Library:
~ Gensplit.exeFor more information about downloading files from the Microsoft Software Library, please see the following article in the Microsoft Knowledge Base:
Q119591 How to Obtain Microsoft Support Files from Online ServicesNOTE: Use the -d option when running GENSPLIT.EXE to decompress the file and recreate the proper directory structure.
GENSPLIT is an MFC SDI application in which CMainFrame::OnCreateClient
has been overridden to create a static splitter with two rows and two
columns. For more information on splitter windows and how to create
them, please see Online Help or the REFERENCES section in this article.
To create windows in the splitter panes, MFC uses CRuntime class
information. This information is passed to the CSplitterWnd::CreateView
call using the RUNTIME_CLASS macro. This API creates the panes in the
splitter. It first calls CreateObject to create the MFC object and then
calls the virtual function CWnd::Create to create the window. Any MFC class
willing to implement creation using runtime class information must be
tagged DECLARE_DYNCREATE. The corresponding macro, IMPLEMENT_DYNCREATE,
must be added to the implementation file for the class. Also,
CWnd::PostNcDestroy needs to be overridden for the class and it should make
a call to delete this pointer. This brings about cleanup of the dynamically
created MFC object.
In the GENSPLIT sample, the first pane is a simple view. This view is the
one associated with the document template registered in the application's
InitInstance.
The second pane is a window represented by an MFC class that is derived
directly from CWnd. The window shows a bouncing ball. To create this pane,
CreateView was passed the Runtime class information for the class.
The third pane is a listbox. Besides using the call to CreateView, there is
an extra step necessary here. As mentioned above, the pane window is
created by making the virtual call CWnd::Create. The CListBox class does
not have a Create function whose parameter list matches that of the virtual
function CWnd::Create. As a consequence, CreateView's call to Create gets
resolved to CWnd::Create rather than to CListBox::Create.
All CListBox::Create does is set the WINDOW class to "LISTBOX" and then
call CWnd::Create. Since setting the WINDOW class is the only step missing
in the pane creation, CWnd::PreCreateWindow has been overridden for the
Listbox class to set the lpszClass member of CREATESTRUCT to "LISTBOX". In
this function, listbox-specific window styles have also been set.
The process to place new Common controls in splitter panes is similar to
the one discussed above for Listbox controls. However, there is one
important difference: Before setting the WINDOW class, you may need to call
InitCommonControls(). This SDK API is necessary to load the Common control
DLL into memory. It is this DLL that is responsible for registering the
WINDOW classes for the Common controls. You need to call this API only if
you haven't already loaded this DLL. This can be done indirectly by
creating a Common control elsewhere in your application.
The fourth pane is a dialog. Creating a dialog in a pane is slightly
tricky. All the windows created in the panes of a splitter are child
windows of the splitter. Dialog windows are usually pop-up windows. They
can be created as child windows but there is no way to specify the child ID
for them. The splitter window architecture dictates which panes get which
IDs. Also, as in the case of CListBox, CDialog::Create does not have the
same argument list as CWnd::Create.
Since dialog creation does not go through CWnd::Create, PreCreateWindow
never gets called for CDialog-derived classes. As a consequence,
CWnd::Create was overridden in the CDialog-derived class. Here the base
class call CDialog::Create was made that creates the modeless dialog.
Immediately after this ::SetWindowLong was called to set the child ID of
the dialog to whatever the splitter window architecture demands.
NOTE: The easiest way to provide dialog-like functionality in a pane is to
work with the CFormView class.
MFC Technical Note no. 29 entitled "Splitter Windows"
CSplitterWnd::CreateView - in file ..\msdev\mfc\src\winsplit.cpp.
MFC technical Note no. 17 entitled "Destroying MFC objects" for a
discussion on CWnd::PostNcDestroy.
Keywords : kbcode kbfile kbprg kbsample kbui kbMFC KbUIDesign kbVC kbVC100 kbVC150 kbVC151 kbVC152 kbVC400 kbVC410 kbVC500 kbVC600
Version : 1.0 1.5 1.51 1.52 1.0 2.0 2.1
Platform : NT WINDOWS
Issue type :
Last Reviewed: July 21, 1999