• 在CDockablePane中嵌入CFormView


    CDockablePane中嵌入CFormView与嵌入CDialogEx稍有不同,差异主要体现在CFormView类本身与CDialogEx类的不同上,CDockablePane层面的操作完全相同。

    a)      创建单文档应用程序;

    b)     加入对话框资源,注意,对话框必须有Child属性,Border设置为None

    由CFormView派生的类,可以关联一个对话框资源。但该对话框资源必须在属性设定中Style选定[Child]属性,否则的话,
    代码可以编译,但Debug运行会报告一个断言错误,跟踪代码,断言在:

    #ifdef _DEBUG

        // dialog template must exist and be invisible with WS_CHILD set
        if (!_AfxCheckDialogTemplate(m_lpszTemplateName, TRUE))
        {
            ASSERT(FALSE);   // invalid dialog template name
            PostNcDestroy();  // cleanup if Create fails too soon
            return FALSE;
        }

    #endif //_DEBUG

      CFormView比较特殊,是一个父窗体嵌套了一个子窗体,所以CFormView类的派生类的实例不响应WM_CLOSE消息,仅仅响应WM_DESTROY消息。另外,若要用代码关闭当前View,也不能直接:PostMessage(WM_CLOSE,0,0);而必须先获取父窗体的指针,然后对父窗体发送WM_CLOSE消息才行,像这样:GetParent()->PostMessage(WM_CLOSE,0,0);才能够达到目的。《深入浅出MFC》第八章461页图8-1清楚地说明了这种情况,View窗口是CChildFrame窗口的子窗口。

     

    c)      为对话框创建类CFormViewEmbeded,基类为CFormView

    d)     重载CFormViewEmbeded类的Create函数,将访问权限改为Public(基类为protect),不用添加额外代码,为了在程序中使用该函数

    e)     重写CFormViewEmbeded类的OnMouseActive消息响应函数,为了防止CDockablePane处于悬浮状态时程序崩溃(不重载必然崩溃!)

    int CFormViewEmbeded::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)

    {

        // TODO: 在此添消息处理程序代码

        int nResult = 0;

        CFrameWnd* pParentFrame = GetParentFrame();

        if( pParentFrame == pDesktopWnd )

        {

            // When this is docked

            nResult= CFormView::OnMouseActivate(pDesktopWnd, nHitTest, message);

        }

        else

        {

            // When this is not docked

            BOOL isMiniFrameWnd =pDesktopWnd->IsKindOf( RUNTIME_CLASS( CMiniFrameWnd ) );

            BOOL isPaneFrameWnd =pDesktopWnd->IsKindOf( RUNTIME_CLASS( CPaneFrameWnd ) );

    BOOL isMultiPaneFrameWnd =

    pDesktopWnd->IsKindOf( RUNTIME_CLASS( CMultiPaneFrameWnd ) );

            // pDesktopWnd is the frame window for CDockablePane

            nResult = CWnd::OnMouseActivate( pDesktopWnd, nHitTest, message );

        }

        return nResult;

    }

    f)      创建派生自CDockablePane的类CDockableFormView

    g)     由于CFormView类的构造函数访问权限为protect,不能直接声明变量,所以为CDockableFormView添加CDialogEmbeded*类型的成员变量m_pFormViewEmbeded,(另一种解决方法是将CMainFrame声明为友元类);

    h)     在CDockableFormView类的构造函数中添加

        m_pFormViewEmbeded =

                      (CFormViewEmbeded*)(RUNTIME_CLASS(CFormViewEmbeded))->CreateObject();

    i)       重载CDockableFormView的OnCreate函数

    int CDockableFormView::OnCreate(LPCREATESTRUCT lpCreateStruct)

    {

        if (CDockablePane::OnCreate(lpCreateStruct) == -1)

            return -1;

        // TODO:  在此添加您专用的代码

        CRect rect;

        GetClientRect(&rect);

        m_pFormViewEmbeded->Create(NULL,NULL,WS_CHILD|WS_VISIBLE,rect,this,0,NULL);

        return 0;

    }

    a)      重载CDockableFormView的OnSize函数

    void CDockableFormView::OnSize(UINT nType, int cx, int cy)

    {

       CDockablePane::OnSize(nType, cx, cy);

       // TODO: 在此处添加消息处理程序代码

       if(m_pFormViewEmbeded->GetSafeHwnd())

       {

           CRect rect;

           GetClientRect(&rect);

           m_pFormViewEmbeded->SetWindowPos(NULL,

               rect.left,rect.top,rect.Width(),rect.Height(),

               SWP_NOACTIVATE|SWP_NOZORDER);

       }

    }

    b)     重载CDockableFormView的OnDestory函数

    void CDockableFormView::OnDestroy()

    {

       CDockablePane::OnDestroy();

       // TODO: 在此处添加消息处理程序代码

       m_pFormViewEmbeded->DestroyWindow();

    }

    c)      在框架类中添加CDockableDlg对象m_dockDlg

    d)     在CMainFrame类的OnCreate函数中添加以下代码,Create函数里面的1002是这个停靠栏的ID,这里是随便指定的一个数值,只要不和其他已用资源重复即可,真正应用的时候,以在字符串表中添加一个ID

    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

    {

       …

       EnableDocking(CBRS_ALIGN_ANY);

       m_dockDlg.Create("Dock FormView",this,CRect(0,0,200,200),TRUE,1002,

       WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|CBRS_RIGHT|CBRS_FLOAT_MULTI);

       m_dockDlg.EnableDocking(CBRS_ALIGN_ANY);

       DockPane(&m_dockFormView);

       return 0;

    }

    e)     疑问:m_dockFormView什么时候销毁?

  • 相关阅读:
    实验 MPLS LDP配置
    IEEP-OSPF域内路由故障-现象与排障思路
    IEEP部署企业级网络工程-OSPF邻居关系故障排除
    IEEP部署企业级网络工程-网络故障-环路故障
    IEEP-网络实施-项目交付流程
    Python正则表达式
    如何解决TortoiseSVN不显示状态小图标问题
    如何在win下一键升级 python 所有包
    vmware workstation 与 device/credential guard 不兼容
    windows系统中在jupyter安装虚拟环境内核
  • 原文地址:https://www.cnblogs.com/canger/p/4156542.html
Copyright © 2020-2023  润新知