Frame Related Classes and Message Map Macros for Windows Mobile and Desktop WTL Applications (Part 1)






4.80/5 (6 votes)
Message map macros, split frames, full screen implementation, and automatic mapping of UI elements.
- Download the FrameX1 samples project - 30.5 KB
- Download the atlframx.h classes and macros - 6.44 KB
- Download the MDISplitFrame sample - 57.8 KB
- Download the SDIFrameX sample - 64.7 KB
Introduction
This is the first of two articles presenting various frame related classes and message map macros for Windows Mobile and Desktop WTL applications.
The second part will focus on multiple views implementation in frame and pane control classes.
This first part presents various message map macros, MDI and SDI split frame classes, a full screen mode implementation class, and the removing of the WTL UPDATE_UI_MAP
through automatic mapping of UI elements.
The attached SDIFrameX and MDISplitFrame samples in FrameX1.zip show how simple it is include this code in existing or new applications.
The reusable code for both article is in atlframx.zip.
Message Map Macros
These macros add message answering and forwarding, conditional message map chaining, and message map definition in an implementation file.
MESSAGE_ANSWER(msg, res)
returnsres
and handles the message. It saves a function call in the cases where the returnedLRESULT
value is context independent, typically:
MESSAGE_ANSWER(WM_ERASEBKGND, TRUE)
FORWARD_MESSAGE_WINDOW(msg, hWnd)
sends the msg
message to the provided hWnd
and handles the message. Useful when a command should be executed by an unsubclassed child control.FORWARD_MESSAGE(msg)
is a single message complement to the ATL FORWARD_NOTIFICATIONS()
macro. It sends the msg
message to the parent window and handles the message.CHAIN_MSG_MAP_CONDITION(bCondition, theChainClass)
and CHAIN_MSG_MAP_ALT_CONDITION(bCondition, theChainClass, msgMapID)
perform a CHAIN_MSG_MAP()
if bCondition
evaluates to true
. Useful in situations where chained class handling depends on the context.CHAIN_MSG_MAP_CONDITION_MEMBER(bCondition, theChainMember)
and CHAIN_MSG_MAP_ALT_CONDITION_MEMBER(bCondition, theChainMember, msgMapID)
perform similarly with CHAIN_MSG_MAP_MEMBER()
if bCondition
evaluates to true
.DECLARE_MSG_MAP(theClass)
alone in MyClass.h, and replace BEGIN_MSG_MAP()
by IMPLEMENT_MSG_MAP(theClass)
at the beginning of your message map declaration in MyClass.cpp.Split frame classes
Using these classes removes the usual intermediate CSplitterWindow
and associated message traffic from split frame layouts.
CSplitFrameImplBase
CSplitFrameImplBase
is a direct derivation of some TFrameImpl
(itself derived from WTL::CFrameWindowImplBase
) and WTL::CSplitterImpl
. With adequate TFrameImpl
template parameters, it specializes in:
CSplitFrameWindowImpl
, a ready to use split frame base class.CMDISplitFrameWindowImpl
, a ready to use MDI split frame base class.
Definition
template <class T, class TFrameImpl, bool t_bVertical = true> class ATL_NO_VTABLE CSplitFrameImplBase : public TFrameImpl, public CSplitterImpl<T, t_bVertical> { typedef CSplitFrameImplBase<T, TFrameImpl, t_bVertical> thisClass; public: typedef thisClass SplitFrame; typedef TFrameImpl Frame; typedef CSplitterImpl<T, t_bVertical> Splitter;
Overrides
CSplitFrameImplBase
performs a simple splitter initialization in its constructor and does not use the WM_CREATE
message.
// Splitter initialization in constructor CSplitFrameImplBase() { #ifndef _WIN32_WCE m_cxySplitBar = ::GetSystemMetrics(t_bVertical ? SM_CXSIZEFRAME : SM_CYSIZEFRAME); m_cxyMin = 2 * ::GetSystemMetrics(t_bVertical ? SM_CXEDGE : SM_CYEDGE); ::SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, &m_bFullDrag, 0); #else // CE specific m_cxyMin = m_cxySplitBar = 2 * ::GetSystemMetrics(t_bVertical ? SM_CXEDGE : SM_CYEDGE); #endif // _WIN32_WCE }
CSplitFrameImplBase
overrides TFrameImpl::UpdateLayout()
:
void UpdateLayout(BOOL bResizeBars = TRUE) { RECT rect; GetClientRect(&rect); // position bars and offset their dimensions UpdateBarsPosition(rect, bResizeBars); // resize splitter and children SetSplitterRect(&rect); }
CSplitFrameWindowImpl
CSplitFrameWindowImpl
is a CSplitFrameImplBase
using CFrameWindowImpl<T, ATL::CWindow>
as the TFrameImpl
template parameter.
Definition
template <class T, bool t_bVertical = true, class TBase = ATL::CWindow, class TWinTraits = ATL::CFrameWinTraits> class ATL_NO_VTABLE CSplitFrameWindowImpl : public CSplitFrameImplBase<T, CFrameWindowImpl<T, TBase, TWinTraits>, t_bVertical> { typedef CSplitFrameWindowImpl<T, t_bVertical, TBase, TWinTraits> thisClass; };
Usage
See the SDIFrameX sample in Step 1.
CMDISplitFrameWindowImpl
CMDISplitFrameWindowImpl
is a ready to use MDI split frame; it is a CSplitFrameImplBase
using CMDIFrameWindowImpl<T, WTL::CMDIWindow>
as the TFrameImpl
template parameter. A bool t_bRightView
template parameter sets the MDI pane to right (or bottom) if true
(default).
Definition
template <class T, bool t_bRightView = true, bool t_bVertical = true, class TBase = WTL::CMDIWindow, class TWinTraits = ATL::CFrameWinTraits> class ATL_NO_VTABLE CMDISplitFrameWindowImpl : public CSplitFrameImplBase<T, CMDIFrameWindowImpl<T, TBase, TWinTraits>, t_bVertical> { typedef CMDISplitFrameWindowImpl<T, t_bRightView, t_bVertical, TBase, TWinTraits> thisClass; public: HWND CreateMDIClient(HMENU hWindowMenu = NULL, UINT nID = ATL_IDW_CLIENT, UINT nFirstChildID = ATL_IDM_FIRST_MDICHILD) { HWND hWndMDIClient = Frame::CreateMDIClient(hWindowMenu, nID, nFirstChildID); SetSplitterPane(t_bRightView, hWndMDIClient); return hWndMDIClient; } BEGIN_MSG_MAP(thisClass) MESSAGE_HANDLER(WM_MDISETMENU, OnMDISetMenu) CHAIN_MSG_MAP(SplitFrame) END_MSG_MAP() };
Overrides
CMDISplitFrameWindowImpl
overrides CMDIFrameWindowImpl::CreateMDIClient()
and sets the splitter MDI pane according to t_bRightView
.
Usage
See the MDISplitFrame sample.
CFullScreenImpl
CFullScreenImpl
manages a full screen display mode for any popup (non-child) window. First intended for frame windows, it may as well be applied to dialogs or splash windows.
CFullScreenImpl
does not apply to Windows CE which already has a CFullScreenFrame
class in atlwince.h.
Definition
template <class T, UINT t_uIdExitAccel = 0, bool t_bIsFrame = true> class CFullScreenImpl { typedef CFullScreenImpl<T, t_uIdExitAccel, t_bIsFrame> thisClass; public: typedef thisClass FullScreen;
One of the design problem of a desktop full screen mode is to give the user a way to get back to normal windowing, as full screen mode has no more menu or toolbars. CFullScreenImpl
uses an optional t_uIdExitAccel
accelerator resource template parameter and a PreTranslateMessage
member to help that. The third template parameter, t_bIsFrame
, is set to true
when T
derives from CFrameWindowImplBase
and then manages visibility of the toolbar and statusbar.
Construction
The default constructor initializes the WINDOWPLACEMENT m_wp
member and the CAccelerator m_ExitAccel
member from a t_uIdExitAccel
resource if t_uIdExitAccel
is provided.
CFullScreenImpl() : m_bFullScreen(false), m_bTopVisible(false), m_bBottomVisible(false) { m_wp.length = sizeof WINDOWPLACEMENT; if (t_uIdExitAccel) m_ExitAccel.LoadAccelerators(t_uIdExitAccel); }
API
bool IsFullScreen()
returns the full screen state.void SetExitAccelerator(BYTE fVirt, WORD key, WORD cmd)
sets theCAccelerator m_ExitAccel
member to a single keystroke according to the parameters.void SetExitAccelerator(UINT uIdExitAccel)
loads theCAccelerator m_ExitAccel
member from auIdExitAccel
accelerator resource.bool SetFullScreen(bool bFullScreen)
sets the full screen state according tobFullScreen
if it is not already set and if the derived classOnFullScreen(bFullScreen)
returnstrue
.SetFullScreen()
returnstrue
if the full screen state has changed,false
otherwise.
bool SetFullScreen(bool bFullScreen) { if (bFullScreen == m_bFullScreen) return false; T* pT = static_cast<T*>(this); ATLASSERT(pT->IsWindow()); if (!pT->OnFullScreen(bFullScreen)) return false; if (bFullScreen) { // save current position pT->GetWindowPlacement(&m_wp); // remove framish styles pT->ModifyStyle(WS_CAPTION | WS_BORDER | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, 0, SWP_FRAMECHANGED); // hide bars if necessary if (t_bIsFrame) { m_bTopVisible = ::IsWindow(pT->m_hWndToolBar) && ::IsWindowVisible(pT->m_hWndToolBar); if (m_bTopVisible) ::ShowWindow(pT->m_hWndToolBar, SW_HIDE); m_bBottomVisible = ::IsWindow(pT->m_hWndStatusBar) && ::IsWindowVisible(pT->m_hWndStatusBar); if (m_bBottomVisible) ::ShowWindow(pT->m_hWndStatusBar, SW_HIDE); } // move to full screen CWindowDC dc(NULL); pT->SetWindowPos(NULL, 0, 0, dc.GetDeviceCaps(HORZRES), dc.GetDeviceCaps(VERTRES), SWP_FRAMECHANGED); } else { // restore original styles pT->ModifyStyle(0, T::GetWndStyle(0), SWP_FRAMECHANGED); // restore bars if (t_bIsFrame) { if (m_bTopVisible) ::ShowWindow(pT->m_hWndToolBar, SW_SHOW); if (m_bBottomVisible) ::ShowWindow(pT->m_hWndStatusBar, SW_SHOW); } // move to saved position pT->SetWindowPlacement(&m_wp); } m_bFullScreen = bFullScreen; return true; }
BOOL PreTranslateMessage(MSG* pMsg)
returns FALSE
if not in full screen mode or if m_ExitAccel
is not initialized; the result of m_ExitAccel.TranslateAccelerator()
otherwise.BOOL PreTranslateMessage(MSG* pMsg) { return !IsFullScreen() || m_ExitAccel.IsNull() ? FALSE : m_ExitAccel.TranslateAccelerator(static_cast<T*>(this)->m_hWnd, pMsg); }
Overrideable
bool OnFullScreen(bool bFullScreen)
is called bySetFullScreen()
. The defaultCFullScreenImpl::OnFullScreen()
returnstrue
to allow full screen mode change. Override in your derived class if you want to prevent changes or do some layout or UI changes.
Usage
See the SDIFrameX sample in Step 2.
CAutoUpdateUI
CAutoUpdateUI
is a replacement class for WTL::CUpdateUI
not requiring a derived class UPDATE_UI_MAP
. It is handy in development stages where UI layout and IDs are not stabilized, and later eases UI maintenance: adding, removing, or renaming a command, or changing its host toolbar, menu, or dialog.
If the derived class has no UPDATE_UI_MAP
, CAutoUpdateUI
embeds an empty UPDATE_UI_MAP
. The derived or embedded UPDATE_UI_MAP
is populated by calls to the UIAddxxx
members.
Definition
template <class T> class CAutoUpdateUI : public WTL::CDynamicUpdateUI<T> {
API
bool UIAddMenu(HMENU hm, bool bSetText = false)
adds the menu with thehm
handle and its submenus to theUPDATE_UI_MAP
.bool UIAddMenu(UINT uID, bool bSetText = false)
adds the menu resource with theuID
ID and its submenus to theUPDATE_UI_MAP
.
If bSetText
is true
, both call UISetText()
with the menu item text.
Overrides
bool UIAddToolBar(HWND hWndToolBar)
adds the toolbar control withhWndToolBar
HWND
to theUPDATE_UI_MAP
. If the toolbar has embedded controls, they are added to theUPDATE_UI_MAP
by a call toUIAddChildWindowContainer()
.bool UIAddChildWindowContainer(HWND hWnd)
adds the direct children of thehWnd
window to theUPDATE_UI_MAP
. Grandchildren are not added.
In Windows CE projects, UIAddToolBar()
enters an infinite loop if called on a MenuBar, so it is disabled. Enable it with #define _AUTOUI_CE_TOOLBAR
to call it on a genuine ToolBarCtrl.
Usage
See the SDIFrameX sample in Step 3.
The SDIFrameX sample
This sample details all the steps to implement a CSplitFrameWindowImpl
derived, CFullScreenImpl
derived, and CAutoUpdateUI
derived frame from the code issued by the WTL AppWizard for an Explorer (split layout) application.
Step 0:
#include "atlframx.h"
in SDIFrameX.cpp.
// SDIFrameX.cpp : main source file for SDIFrameX.exe // ... #include "..\atlframx.h" // 0
Step 1: Derive CMainFrame from CSplitFrameWindowImpl and remove the intermediate CSplitterWindow
- Derive
CMainFrame
fromCSplitFrameWindowImpl
. - Use
DECLARE_FRAME_WND_CLASS_EX
withCS_DBLCLKS
to enable the double click on splitter bar equalizes panes feature. - Remove the
m_splitter
member declaration.
// MainFrm.h : interface of the CMainFrame class // ... class CMainFrame : public CSplitFrameWindowImpl<CMainFrame>, // 1 // ... { public: DECLARE_FRAME_WND_CLASS_EX(NULL, IDR_MAINFRAME, CS_DBLCLKS, COLOR_WINDOW) // 1 //CSplitterWindow m_splitter; // 1 // ...
OnCreate()
:- Remove the
m_splitter.Create()
call. - Change the parent of
m_pane
andm_view
tom_hWnd
. - Remove the m_splitter. prefix from the calls to
CSplitterImpl
members.
LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { // ... //m_hWndClient = m_splitter.Create(m_hWnd, rcDefault, NULL, //WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); // 1 // ... m_pane.Create(/*m_splitter*/m_hWnd, _T("Tree"), WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); // 1 // ... m_view.Create(/*m_splitter*/m_hWnd, rcDefault, _T("http://www.microsoft.com"), WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_HSCROLL | WS_VSCROLL, WS_EX_CLIENTEDGE); // 1 /*m_splitter.*/SetSplitterPanes(m_pane, m_view); // 1 UpdateLayout(); /*m_splitter.*/SetSplitterPosPct(25); // 1
OnViewTreePane()
and OnTreePaneClose()
, remove the m_splitter. prefix from the calls to CSplitterImpl
members.LRESULT OnViewTreePane(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { bool bShow = (/*m_splitter.*/GetSinglePaneMode() != SPLIT_PANE_NONE); // 1 /*m_splitter.*/SetSinglePaneMode(bShow ? SPLIT_PANE_NONE : SPLIT_PANE_RIGHT); // 1 UISetCheck(ID_VIEW_TREEPANE, bShow); return 0; } LRESULT OnTreePaneClose(WORD /*wNotifyCode*/, WORD /*wID*/, HWND hWndCtl, BOOL& /*bHandled*/) { if(hWndCtl == m_pane.m_hWnd) { /*m_splitter.*/SetSinglePaneMode(SPLIT_PANE_RIGHT); // 1 UISetCheck(ID_VIEW_TREEPANE, 0); } return 0; }
Step 2: Implement a Full Screen mode exited by the Escape key
- Declare a
ID_VIEW_FULLSCREEN
identifier in resource.h.
// resource.h // ... #define ID_VIEW_FULLSCREEN 0xE802 // 2
ID_VIEW_FULLSCREEN
accelerator resource.// Microsoft Visual C++ generated resource script. // SDIFrameX.rc // ... IDR_MAINFRAME MENU BEGIN // ... POPUP "&View" BEGIN MENUITEM "&Toolbar", ID_VIEW_TOOLBAR MENUITEM "&Status Bar", ID_VIEW_STATUS_BAR MENUITEM "Tree &Pane", ID_VIEW_TREEPANE MENUITEM "&Full Screen", ID_VIEW_FULLSCREEN // 2 END // ... // Accelerator // ... ID_VIEW_FULLSCREEN ACCELERATORS // 2 BEGIN // 2 VK_ESCAPE, ID_VIEW_FULLSCREEN, VIRTKEY, NOINVERT // 2 END // 2
CMainFrame
from CFullScreenImpl
.CMainFrame::OnFullScreen
member to hide the splitter left pane in full screen mode.FullScreen::PreTranslateMessage
from CMainFrame::PreTranslateMessage
to activate the ID_VIEW_FULLSCREEN
accelerator in full screen mode.// MainFrm.h : interface of the CMainFrame class // ... class CMainFrame : // ... public CFullScreenImpl<CMainFrame, ID_VIEW_FULLSCREEN>, // 2 // … { // ... bool OnFullScreen(bool bFullScreen) // 2 { if (bFullScreen) // 2 SetSinglePaneMode(SPLIT_PANE_RIGHT); // 2 else if (UIGetState(ID_VIEW_TREEPANE) & UPDUI_CHECKED) // 2 SetSinglePaneMode(SPLIT_PANE_NONE); // 2 return true; // allow change // 2 } virtual BOOL PreTranslateMessage(MSG* pMsg) { if (FullScreen::PreTranslateMessage(pMsg)) // 2 return TRUE; // 2 // ...
ID_VIEW_FULLSCREEN
.// ... BEGIN_MSG_MAP(CMainFrame) // ... COMMAND_ID_HANDLER(ID_VIEW_FULLSCREEN, OnViewFullScreen) // 2 // ... LRESULT OnViewFullScreen(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) // 2 { SetFullScreen(!IsFullScreen()); // 2 return 0; // 2 } // 2
Step 3: Derive CMainFrame from CAutoUpdateUI and remove the UPDATE_UI_MAP macros
- Derive
CMainFrame
fromCAutoUpdateUI
. - Remove the
UPDATE_UI_MAP
macros and chain toCAutoUpdateUI
in the message map. - Call
UIAddMenu()
inCMainFrame::OnCreate()
.
// MainFrm.h : interface of the CMainFrame class // ... class CMainFrame : // ... public CAutoUpdateUI<CMainFrame>, // 3 // ... { // ... /* BEGIN_UPDATE_UI_MAP(CMainFrame) // 3 UPDATE_ELEMENT(ID_VIEW_TOOLBAR, UPDUI_MENUPOPUP) UPDATE_ELEMENT(ID_VIEW_STATUS_BAR, UPDUI_MENUPOPUP) UPDATE_ELEMENT(ID_VIEW_TREEPANE, UPDUI_MENUPOPUP) END_UPDATE_UI_MAP()*/ // 3 // … BEGIN_MSG_MAP(CMainFrame) // ... CHAIN_MSG_MAP(CAutoUpdateUI<CMainFrame>) // 3 // ... LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { UIAddMenu(IDR_MAINFRAME); // 3 // ...
The MDISplitFrame sample
This sample implements a basic MDI split frame, merging code issued by the WTL AppWizard for the MDI and Explorer (split layout) applications.
CMainFrame
derives from CMDISplitFrameWindowImpl<CMainFrame>
; the left pane members, command handlers are added, ID_VIEW_TREEPANE
is added to the menu resource.
class CMainFrame : public CMDISplitFrameWindowImpl, public CUpdateUI , public CMessageFilter, public CIdleHandler { public: DECLARE_FRAME_WND_CLASS_EX(_T("WTL_MDISplitFrame"), IDR_MAINFRAME, CS_DBLCLKS, COLOR_WINDOW) CPaneContainer m_pane; CTreeViewCtrl m_treeview; CMDICommandBarCtrl m_CmdBar; virtual BOOL PreTranslateMessage(MSG* pMsg) { if(Frame::PreTranslateMessage(pMsg)) return TRUE; HWND hWnd = MDIGetActive(); if(hWnd != NULL) return (BOOL)::SendMessage(hWnd, WM_FORWARDMSG, 0, (LPARAM)pMsg); return FALSE; } // ... BEGIN_UPDATE_UI_MAP(CMainFrame) UPDATE_ELEMENT(ID_VIEW_TOOLBAR, UPDUI_MENUPOPUP) UPDATE_ELEMENT(ID_VIEW_STATUS_BAR, UPDUI_MENUPOPUP) UPDATE_ELEMENT(ID_VIEW_TREEPANE, UPDUI_MENUPOPUP) END_UPDATE_UI_MAP() BEGIN_MSG_MAP(CMainFrame) MESSAGE_HANDLER(WM_CREATE, OnCreate) MESSAGE_HANDLER(WM_DESTROY, OnDestroy) COMMAND_ID_HANDLER(ID_APP_EXIT, OnFileExit) COMMAND_ID_HANDLER(ID_FILE_NEW, OnFileNew) COMMAND_ID_HANDLER(ID_VIEW_TOOLBAR, OnViewToolBar) COMMAND_ID_HANDLER(ID_VIEW_STATUS_BAR, OnViewStatusBar) COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout) COMMAND_ID_HANDLER(ID_VIEW_TREEPANE, OnViewTreePane) COMMAND_ID_HANDLER(ID_PANE_CLOSE, OnViewTreePane) COMMAND_ID_HANDLER(ID_WINDOW_CASCADE, OnWindowCascade) COMMAND_ID_HANDLER(ID_WINDOW_TILE_HORZ, OnWindowTile) COMMAND_ID_HANDLER(ID_WINDOW_ARRANGE, OnWindowArrangeIcons) CHAIN_MDI_CHILD_COMMANDS() CHAIN_MSG_MAP(CUpdateUI ) CHAIN_MSG_MAP(CMDISplitFrameWindowImpl ) END_MSG_MAP()
The OnCreate()
member creates the left pane, and calls the overridden CMDISplitFrameWindowImpl::CreateMDIClient()
which sets the right pane to CMDIWindow::m_hWndMDIClient
.
LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { // create command bar window HWND hWndCmdBar = m_CmdBar.Create(m_hWnd, rcDefault, NULL, ATL_SIMPLE_CMDBAR_PANE_STYLE); // attach menu m_CmdBar.AttachMenu(GetMenu()); // load command bar images m_CmdBar.LoadImages(IDR_MAINFRAME); // remove old menu SetMenu(NULL); HWND hWndToolBar = CreateSimpleToolBarCtrl(m_hWnd, IDR_MAINFRAME, FALSE, ATL_SIMPLE_TOOLBAR_PANE_STYLE); CreateSimpleReBar(ATL_SIMPLE_REBAR_NOBORDER_STYLE); AddSimpleReBarBand(hWndCmdBar); AddSimpleReBarBand(hWndToolBar, NULL, TRUE); CreateSimpleStatusBar(); // Create left pane content m_pane.SetPaneContainerExtendedStyle(PANECNT_NOBORDER); m_pane.Create(m_hWnd, _T("Tree"), WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); m_treeview.Create(m_pane, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | TVS_SHOWSELALWAYS, WS_EX_CLIENTEDGE); m_treeview.SetFont(AtlGetDefaultGuiFont()); m_pane.SetClient(m_treeview); // Set left pane SetSplitterPane(SPLIT_PANE_LEFT, m_pane); UpdateLayout(); SetSplitterPosPct(25); CreateMDIClient(); m_CmdBar.SetMDIClient(m_hWndMDIClient); UIAddToolBar(hWndToolBar); UISetCheck(ID_VIEW_TOOLBAR, 1); UISetCheck(ID_VIEW_STATUS_BAR, 1); UISetCheck(ID_VIEW_TREEPANE, 1); // register object for message filtering and idle updates CMessageLoop* pLoop = _Module.GetMessageLoop(); ATLASSERT(pLoop != NULL); pLoop->AddMessageFilter(this); pLoop->AddIdleHandler(this); return 0; }
First part conclusion
This first part has presented some simple enhancements to the current WTL 8.0 frame management and message routing.
The second part will introduce a multiple views implementation and an application to frame and pane container classes.
Hope to see you there soon, cheers!
History
- July 29 2009: First release.