MDI 界面开发

一般的多文档应用都会有居于左侧或右侧的导航窗口,在VC中是如何实现的呢?
试建了一个MDI项目,发现MFC的MDI功能在2008上有很大的增强,支持很多很炫的布局效果(见截图)。

image

这是典型的Office 2007风格,特别是Outlook 2007及VS 2008的风格,看起来相当的漂亮。

在进一步了解这个示例的代码前,我想自己尝试一下,如何在经典的MDI主窗口添加公用面板。达到如下效果:

image 
经过一番努力,实现了这个功能,步骤如下:
第一步:从CDockablePane继承,创建一个自定义类CNavView
CNavView.h的代码:

#pragma once

// CNavView

class CNavView : public CDockablePane
{
    DECLARE_DYNAMIC(CNavView)

public:
    CNavView();
    virtual ~CNavView();
protected:
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg void OnSize(UINT nType, int cx, int cy);
public:
    CTreeCtrl m_wndClassView;
    void AdjustLayout();
protected:
    DECLARE_MESSAGE_MAP()
};

CNavView.cpp的代码:
// NavView.cpp : implementation file
//

#include "stdafx.h"
#include "MDISample.h"
#include "NavView.h"

// CNavView

IMPLEMENT_DYNAMIC(CNavView, CDockablePane)

CNavView::CNavView()
{

}

CNavView::~CNavView()
{
}

BEGIN_MESSAGE_MAP(CNavView, CDockablePane)
    ON_WM_CREATE()
    ON_WM_SIZE()
END_MESSAGE_MAP()

void CNavView::OnSize(UINT nType, int cx, int cy)
{
    CDockablePane::OnSize(nType, cx, cy);
    AdjustLayout();
}

void CNavView::AdjustLayout()
{
    if (GetSafeHwnd() == NULL)
    {
        return;
    }

    CRect rectClient;
    GetClientRect(rectClient);

    int cyTlb = 3;

    m_wndClassView.SetWindowPos(NULL, rectClient.left + 1, rectClient.top + cyTlb + 1, rectClient.Width() - 2, rectClient.Height() - cyTlb - 2, SWP_NOACTIVATE | SWP_NOZORDER);
}
// CNavView message handlers

int CNavView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
        CRect rectDummy;
    rectDummy.SetRectEmpty();

    // Create views:
    const DWORD dwViewStyle = WS_CHILD | WS_VISIBLE | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;

    if (!m_wndClassView.Create(dwViewStyle, rectDummy, this, 2))
    {
        TRACE0("Failed to create Class View/n");
        return -1;      // fail to create
    }

    HTREEITEM hRoot = m_wndClassView.InsertItem(_T("FakeApp classes"), 0, 0);
    m_wndClassView.SetItemState(hRoot, TVIS_BOLD, TVIS_BOLD);

    HTREEITEM hClass = m_wndClassView.InsertItem(_T("CFakeAboutDlg"), 1, 1, hRoot);
    m_wndClassView.InsertItem(_T("CFakeAboutDlg()"), 3, 3, hClass);

    m_wndClassView.Expand(hRoot, TVE_EXPAND);

    hClass = m_wndClassView.InsertItem(_T("CFakeApp"), 1, 1, hRoot);
    m_wndClassView.InsertItem(_T("CFakeApp()"), 3, 3, hClass);
    m_wndClassView.InsertItem(_T("InitInstance()"), 3, 3, hClass);
    m_wndClassView.InsertItem(_T("OnAppAbout()"), 3, 3, hClass);

    hClass = m_wndClassView.InsertItem(_T("CFakeAppDoc"), 1, 1, hRoot);
    m_wndClassView.InsertItem(_T("CFakeAppDoc()"), 4, 4, hClass);
    m_wndClassView.InsertItem(_T("~CFakeAppDoc()"), 3, 3, hClass);
    m_wndClassView.InsertItem(_T("OnNewDocument()"), 3, 3, hClass);

    hClass = m_wndClassView.InsertItem(_T("CFakeAppView"), 1, 1, hRoot);
    m_wndClassView.InsertItem(_T("CFakeAppView()"), 4, 4, hClass);
    m_wndClassView.InsertItem(_T("~CFakeAppView()"), 3, 3, hClass);
    m_wndClassView.InsertItem(_T("GetDocument()"), 3, 3, hClass);
    m_wndClassView.Expand(hClass, TVE_EXPAND);

    hClass = m_wndClassView.InsertItem(_T("CFakeAppFrame"), 1, 1, hRoot);
    m_wndClassView.InsertItem(_T("CFakeAppFrame()"), 3, 3, hClass);
    m_wndClassView.InsertItem(_T("~CFakeAppFrame()"), 3, 3, hClass);
    m_wndClassView.InsertItem(_T("m_wndMenuBar"), 6, 6, hClass);
    m_wndClassView.InsertItem(_T("m_wndToolBar"), 6, 6, hClass);
    m_wndClassView.InsertItem(_T("m_wndStatusBar"), 6, 6, hClass);

    hClass = m_wndClassView.InsertItem(_T("Globals"), 2, 2, hRoot);
    m_wndClassView.InsertItem(_T("theFakeApp"), 5, 5, hClass);
    m_wndClassView.Expand(hClass, TVE_EXPAND);

    return 0;

}

第二步:在MainFrame的头文件中加入一个新成员变量:

#include "NavView.h"
......
public:
    CNavView m_Nav;

第三步:在MainFrm.cpp中OnCreate方法最后加入如下代码
CString str;
str.LoadString(ID_VIEW_NAV);
if (!m_Nav.Create(str, this, CRect(0, 0, 200, 200), TRUE, ID_VIEW_NAV, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_LEFT | CBRS_FLOAT_MULTI))
{
    TRACE0("Failed to create navigate window/n");
    return FALSE; // failed to create
}

m_Nav.EnableDocking(CBRS_ALIGN_ANY);
DockPane(&m_Nav); 
注意:ID_VIEW_NAV是自定义的字符串资源。

这样,自定义面板就出现在主窗口的最左侧了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值