Click here to Skip to main content
15,867,453 members
Articles / Desktop Programming / ATL
Article

Sharp Layout

Rate me:
Please Sign up or sign in to vote.
4.80/5 (11 votes)
31 Jan 20052 min read 42.4K   1.3K   33   2
Sharp Layout manager for ATL/WTL.

Sharp Layout

Introduction

I will describe here what the article/code snippet does, why it's useful, the problem it solves etc. Splitter is good, but often I need more than just repositioning two panes - implementation of multiple panes, hide/show panes, frozen panes, resize manager, save/load layout. The idea is taken from the new VS.NET C# form editor. You can dock any window at any side or you can set anchor on any side of the window.

Using the code

So we have two kinds of windows - docking and anchored.

The following styles are applicable for docking windows.

  • SSP_DOCKTOP - docked at top.
  • SSP_DOCKBOTTOM - docked at bottom.
  • SSP_DOCKLEFT - docked at left.
  • SSP_DOCKRIGHT - docked at right.
  • SSP_PROPORTIONAL - pane size (width/height) will be relative to the layout size.
  • SSP_DOCKFILL - fill all empty space.

Any docking window can have a splitter - four pixels on opposite side, and splitter can be interactive.

  • SSP_SPLITTER - enable splitter (for docking windows only).
  • SSP_INTERACTIVE - enable interactive splitter.

And for anchored windows, we have.

  • SSP_ALIGNLEFT - left anchor.
  • SSP_ALIGNRIGHT - right anchor.
  • SSP_ALIGNTOP - top anchor.
  • AAP_ALIGNBOTTOM - bottom anchor.

Additionally, one more flag for both types of panes:

  • SSP_INGNORE - controls whether layout will be tried to reposition corresponding pane.

For using layout, you need to:

  • Derive your own class from CWindowImpl/CDialogImpl and CSharpLayout.
  • Chain message map to CSharpLayout.
  • Initialize panes.
class CSharpLayoutSampleView : public CDialogImpl<CSharpLayoutSampleView>,
    public CSharpLayoutImpl<CSharpLayoutSampleView>
{
public:
    enum { IDD = IDD_SHARPLAYOUTSAMPLE_FORM };

    BOOL PreTranslateMessage(MSG* pMsg)
    {
        return CWindow::IsDialogMessage(pMsg);
    }

    BEGIN_MSG_MAP(CSharpLayoutSampleView)
        MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
        MESSAGE_HANDLER(WM_CONTEXTMENU, OnContextMenu)
        MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup)
        MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
        COMMAND_ID_HANDLER(ID_1_SHOWTOPDOCKBAR, OnShowTop)
        COMMAND_ID_HANDLER(ID_1_SHOWLEFTDOCKBAR, OnShowLeft)
        CHAIN_MSG_MAP(CSharpLayoutImpl<CSharpLayoutSampleView>)
    END_MSG_MAP()

    LRESULT OnShowTop(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
    {
        //hide show top pane
        CWindow wnd = GetDlgItem(IDC_EDIT1);
        wnd.ShowWindow(wnd.IsWindowVisible() ? SW_HIDE : SW_SHOW);
        RecalcLayout();
        return 0;
    }
    LRESULT OnShowLeft(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
    {
        //hide show left pane
        CWindow wnd = GetDlgItem(IDC_LIST1);
        wnd.ShowWindow(wnd.IsWindowVisible() ? SW_HIDE : SW_SHOW);
        RecalcLayout();
        return 0;
    }

    LRESULT OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
    {
        CMenu menu;
        menu.LoadMenu(IDR_CONTEXTMENU);
        menu.GetSubMenu(0).TrackPopupMenu(
            0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), m_hWnd);
        return 0;
    }
    LRESULT OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
    {
        //track pane state
        CMenuHandle menu((HMENU)wParam);
        menu.CheckMenuItem(ID_1_SHOWTOPDOCKBAR, 
            GetDlgItem(IDC_EDIT1).IsWindowVisible() ? MF_CHECKED : MF_UNCHECKED);
        menu.CheckMenuItem(ID_1_SHOWLEFTDOCKBAR, 
            GetDlgItem(IDC_LIST1).IsWindowVisible() ? MF_CHECKED : MF_UNCHECKED);
        return 0;
    }
    LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
    {
        //save layout to registry
        SaveLayout(HKEY_CURRENT_USER, _T("Software\\wtlsplit\\Layout"));
        return 0;
    }
    LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
    {
        //initialize panes
        SetPaneStyle(GetDlgItem(IDC_EDIT1), 
            SSP_DOCKTOP|SSP_SPLITTER, false);
        SetPaneStyle(GetDlgItem(IDC_LIST1), 
            SSP_DOCKLEFT|SSP_SPLITTER|SSP_INTERACTIVE|SSP_PROPORTIONAL, false);
        SetPaneStyle(GetDlgItem(IDC_BUTTON1), 
            SSP_ALIGNRIGHT|SSP_ALIGNTOP, false);
        SetPaneStyle(GetDlgItem(IDC_BUTTON2), 
            SSP_ALIGNRIGHT|SSP_ALIGNTOP, false);
        SetPaneStyle(GetDlgItem(IDC_BUTTON3), 
            SSP_ALIGNRIGHT|SSP_ALIGNBOTTOM, false);
        SetPaneStyle(GetDlgItem(IDC_EDIT2), 
            SSP_ALIGNRIGHT|SSP_ALIGNLEFT|SSP_ALIGNBOTTOM|SSP_ALIGNTOP, false);
        //load layout from registry
        LoadLayout(HKEY_CURRENT_USER, _T("Software\\wtlsplit\\Layout"), true);
        return 0;
    }
};

Function reference

There is nothing to comment, all functions are self documented.

  • bool SetPaneStyle(CWindow wnd, int style, bool update)
  • bool SetPaneWidth(CWindow wnd, int width, bool update)
  • bool SetPaneHeight(CWindow wnd, int height, bool update)
  • bool SetPaneDockSize(CWindow wnd, int size, bool update)
  • void RecalcLayout()
  • bool SaveLayout(HKEY hkey, LPCTSTR szkey)
  • bool LoadLayout(HKEY hkey, LPCTSTR szkey, bool update)

Hope it will be useful!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Russian Federation Russian Federation
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralError Pin
johnsmith252913-May-10 17:10
johnsmith252913-May-10 17:10 
GeneralRe: Error Pin
Southmountain7-Mar-20 9:29
Southmountain7-Mar-20 9:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.