Click here to Skip to main content
Click here to Skip to main content

Sharp Layout

, 31 Jan 2005
Rate this:
Please Sign up or sign in to vote.
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

Share

About the Author

Alex Mol
Web Developer
Russian Federation Russian Federation
No Biography provided

Comments and Discussions

 
GeneralError Pinmemberjohnsmith252913-May-10 17:10 

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

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

| Advertise | Privacy | Mobile
Web01 | 2.8.140814.1 | Last Updated 31 Jan 2005
Article Copyright 2005 by Alex Mol
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid