65.9K
CodeProject 正在变化。 阅读更多。
Home

Sharp Layout

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (10投票s)

2005 年 1 月 31 日

2分钟阅读

viewsIcon

43899

downloadIcon

1290

用于 ATL/WTL 的 Sharp Layout 管理器。

Sharp Layout

引言

在这里,我将描述这篇文章/代码片段的作用、为什么它有用、它解决了什么问题等等。分割器很好,但通常我需要的不仅仅是重新定位两个窗格 - 实现多个窗格、隐藏/显示窗格、冻结窗格、调整大小管理器、保存/加载布局。这个想法来自新的 VS.NET C# 表单编辑器。您可以在任何一侧停靠任何窗口,或者可以在窗口的任何一侧设置锚点。

使用代码

所以我们有两种窗口 - 停靠和锚定。

以下样式适用于停靠窗口。

  • SSP_DOCKTOP - 停靠在顶部。
  • SSP_DOCKBOTTOM - 停靠在底部。
  • SSP_DOCKLEFT - 停靠在左侧。
  • SSP_DOCKRIGHT - 停靠在右侧。
  • SSP_PROPORTIONAL - 窗格大小(宽度/高度)将相对于布局大小。
  • SSP_DOCKFILL - 填充所有空白空间。

任何停靠窗口都可以有一个分割器 - 在相对侧的四个像素,并且分割器可以是交互式的。

  • SSP_SPLITTER - 启用分割器(仅适用于停靠窗口)。
  • SSP_INTERACTIVE - 启用交互式分割器。

对于锚定窗口,我们有。

  • SSP_ALIGNLEFT - 左侧锚点。
  • SSP_ALIGNRIGHT - 右侧锚点。
  • SSP_ALIGNTOP - 顶部锚点。
  • AAP_ALIGNBOTTOM - 底部锚点。

此外,还有另一个用于两种类型窗格的标志

  • SSP_INGNORE - 控制是否尝试重新定位相应的窗格。

要使用布局,您需要

  • CWindowImpl/CDialogImplCSharpLayout 派生您自己的类。
  • 将消息映射链接到 CSharpLayout
  • 初始化窗格。
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;
    }
};

函数参考

没有什么可评论的,所有函数都有自文档。

  • 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)

希望它对您有所帮助!

© . All rights reserved.