如何激活并打开多文档多视图中Frame窗口,VC++,愿愿原创。

    void CMainFrame::CreateOrActivateFrame(CDocTemplate* pTemplate,
        const CString &wndTextParam)
    {
        CString wndText;
        CMDIChildWnd* pChild = GetFirstMDIChildWnd();
        while (pChild)//查找是否已经创建,若是,则激活。
        {
            pChild->GetWindowTextW(wndText);
            if(wndText==wndTextParam)
            {
                m_pCurrentMDIWnd=pChild;
                pChild->ActivateFrame();
                
                //m_wndToolBar.RedrawWindow();
                return;
            }
            pChild = GetNextMDIChildWnd();
        }
        CDocument* pDoc= pTemplate->CreateNewDocument();
        ASSERT(pDoc != NULL);
        CMDIChildWnd* tmpMDIChildWnd=(CMDIChildWnd* )pTemplate->CreateNewFrame(pDoc, NULL);
        if (tmpMDIChildWnd == NULL)
            return;     // not created
        ASSERT_KINDOF(CMDIChildWnd, tmpMDIChildWnd);
        m_pCurrentMDIWnd=tmpMDIChildWnd;
        pTemplate->InitialUpdateFrame(tmpMDIChildWnd, pDoc);
        //m_wndToolBar.RedrawWindow();
    }

    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
        //::EnableMenuItem(::GetSystemMenu(this->m_hWnd,FALSE),SC_CLOSE,MF_BYCOMMAND|MF_DISABLED);
        if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
            return -1;
        // 设置寻找标记
        ::SetProp(m_hWnd, AfxGetApp()->m_pszExeName, (HANDLE)1);
        if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
            | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
            !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
        {
            TRACE0("未能创建工具栏\n");
            return -1;      // 未能创建
        }

        if (!m_wndStatusBar.Create(this) ||
            !m_wndStatusBar.SetIndicators(indicators,
            sizeof(indicators)/sizeof(UINT)))
        {
            TRACE0("未能创建状态栏\n");
            return -1;      // 未能创建
        }
        //把m_wndClient子类化为主框架窗口的客户窗口
        if(!m_wndMDIClient.SubclassWindow(m_hWndMDIClient))
        {
            TRACE("Fail to subclass MDI client window\n");
            return -1;
        }
        // TODO: 如果不需要可停靠工具栏,则删除这三行
        m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
        EnableDocking(CBRS_ALIGN_ANY);
        DockControlBar(&m_wndToolBar);

        return 0;
    }

//----------------------------------------------------------------
// This function finds the CMDIChildWnd in the list of windows
// maintained by the application's MDIClient window following the
// one pointed to by the member variable m_pWndCurrentChild. If no
// further CMDIChildWnds are in the list, NULL is returned.
//----------------------------------------------------------------

CMDIChildWnd* CMainFrame::GetNextMDIChildWnd()
{
   if (!m_pWndCurrentChild)
     {
      // Get the first child window.
      m_pWndCurrentChild = m_wndMDIClient.GetWindow(GW_CHILD);
     }
   else
     {
      // Get the next child window in the list.
        m_pWndCurrentChild=
           (CMDIChildWnd*)m_pWndCurrentChild->GetWindow(GW_HWNDNEXT);
     }

   if (!m_pWndCurrentChild)
     {
      // No child windows exist in the MDIClient,
      // or you are at the end of the list. This check
      // will terminate any recursion.
      return NULL;
     }

  // Check the kind of window
    if (!m_pWndCurrentChild->GetWindow(GW_OWNER))
      {
        if (m_pWndCurrentChild->
                           IsKindOf(RUNTIME_CLASS(CMDIChildWnd)))
          {
                 // CMDIChildWnd or a derived class.
                 return (CMDIChildWnd*)m_pWndCurrentChild;
          }
        else
          {
                 // Window is foreign to the MFC framework.
                 // Check the next window in the list recursively.
                 return GetNextMDIChildWnd();
          }
      }
    else
      {
          // Title window associated with an iconized child window.
          // Recurse over the window manager's list of windows.
          return GetNextMDIChildWnd();
      }
}

CMDIChildWnd* CMainFrame::GetFirstMDIChildWnd()
{
      m_pWndCurrentChild = m_wndMDIClient.GetWindow(GW_CHILD);
      return (CMDIChildWnd*)m_pWndCurrentChild;
}

扫描二维码关注公众号,回复: 2429764 查看本文章

以下是app头文件,为了读者能更准确的把握各个名字的类型

class CtaiZhangFormatTransApp : public CWinApp
{
private:
    static CString m_pszExeName;
    CMultiDocTemplate* m_pMultiDocTemplate_FormatTans;
    CMultiDocTemplate* m_pMultiDocTemplate_Verify;
    CMultiDocTemplate* m_pMultiDocTemplate_Setting;
    CMultiDocTemplate* m_pMultiDocTemplate_ImOrExport;
    CMultiDocTemplate* m_pMultiDocTemplate_JinSanSetting;
    CMultiDocTemplate* m_pMultiDocTemplate_JinSanFormatTans;
    CMultiDocTemplate* m_pMultiDocTemplate_JinSanVerify;
public:
    static CString m_MDIChildFrameNameArray[7];
    static CString m_CFormViewFrameNameArray[7];
    //CWnd *m_pMainWndMy;
    //_CrtMemState s1;
    CtaiZhangFormatTransApp();

    CList<CString,CString&> m_BetweenFramesFileName;//在多文档窗口间传递需要验证的文件的文件名
    //CList<CString,CString&> m_BetweenFramesFileName_NHZ;//在多文档窗口间传递需要验证的文件的文件名
    CString strTempPathFullName;
    // 重写
public:
    virtual BOOL InitInstance();
    BOOL IsAlreadyRun(void);
    CMultiDocTemplate *GetCMultiDocTemplateFormatTrans(void);
    CMDIChildWnd *GetCMDIChildWndFormatTans(void);
    CFormView *GetCFormViewFormatTrans(void);
    CDocument* GetCDocumentFormatTans(void);
    
    CMultiDocTemplate *GetCMultiDocTemplateVerify(void);
    CMDIChildWnd *GetCMDIChildWndVerify(void);
    CFormView *GetCFormViewVerify(void);
    CDocument* GetCDocumentVerify(void);
    
    CMultiDocTemplate *GetCMultiDocTemplateSetting(void);
    CMDIChildWnd *GetCMDIChildWndSetting(void);
    CFormView *GetCFormViewSetting(void);
    CDocument* GetCDocumentSetting(void);

    CMultiDocTemplate *GetCMultiDocTemplate_JinSanSetting(void);
    CMDIChildWnd *GetCMDIChildWnd_JinSanSetting(void);
    CFormView *GetCFormView_JinSanSetting(void);
    CDocument* GetCDocument_JinSanSetting(void);

    CMultiDocTemplate *GetCMultiDocTemplate_JinSanFormatTans(void);
    CMDIChildWnd *GetCMDIChildWnd_JinSanFormatTans(void);
    CFormView *GetCFormView_JinSanFormatTans(void);
    CDocument* GetCDocument_JinSanFormatTans(void);

    CMultiDocTemplate *GetCMultiDocTemplate_JinSanVerify(void);
    CMDIChildWnd *GetCMDIChildWnd_JinSanVerify(void);
    CFormView *GetCFormView_JinSanVerify(void);
    CDocument* GetCDocument_JinSanVerify(void);
    // 实现
    afx_msg void OnAppAbout();
    DECLARE_MESSAGE_MAP()
    virtual int ExitInstance();
private:
    CDocument *GetDoc(CRuntimeClass* pDocClass);
    CMultiDocTemplate *GetCMultiDocTemplate(CDocument* pDocClass);
    CView* GetCView(CDocument* pDoc,const CString &wndTextParam);
    CMDIChildWnd* GetCMDIChildWnd(const CString &WndTextParam);
};

extern CtaiZhangFormatTransApp theApp;

以下是app实现文件:部分内容

    ::CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
    if(IsAlreadyRun()==FALSE)//保证程序只有一个实例运行
    {
        ::AfxMessageBox(_T("已经运行!"));
        return FALSE;
    }

。。。。。。

    m_pMultiDocTemplate_FormatTans = new CMultiDocTemplate(
        IDR_taiZhangFormatTTYPE,           //文档关联文件类型字符串资源。可以用来注册关联文件类型
        RUNTIME_CLASS(CDocumentFormatTans),
        RUNTIME_CLASS(CMDIChildWndFormatTans), // custom MDI child frame
        RUNTIME_CLASS(CFormViewFormatTrans));        // view class
    //CFormViewVerify
    if (!m_pMultiDocTemplate_FormatTans)
        return FALSE;
    AddDocTemplate(m_pMultiDocTemplate_FormatTans);//加入CWinApp维护的文档列表

    m_pMultiDocTemplate_Verify = new CMultiDocTemplate(
        IDR_taiZhangFormatTTYPE,           //文档关联文件类型字符串资源。可以用来注册关联文件类型
        RUNTIME_CLASS(CDocumentVerify),
        RUNTIME_CLASS(CMDIChildWndVerify), // custom MDI child frame
        RUNTIME_CLASS(CFormViewVerify));        // view class

    if (!m_pMultiDocTemplate_Verify)
        return FALSE;
    AddDocTemplate(m_pMultiDocTemplate_Verify);//加入CWinApp维护的文档列表

    m_pMultiDocTemplate_Setting = new CMultiDocTemplate(
        IDR_taiZhangFormatTTYPE,           //文档关联文件类型字符串资源。可以用来注册关联文件类型
        RUNTIME_CLASS(CDocumentSetting),
        RUNTIME_CLASS(CMDIChildWndSetting), // custom MDI child frame
        RUNTIME_CLASS(CFormViewSetting));        // view class

    if (!m_pMultiDocTemplate_Setting)
        return FALSE;
    AddDocTemplate(m_pMultiDocTemplate_Setting);//加入CWinApp维护的文档列表

    m_pMultiDocTemplate_JinSanSetting = new CMultiDocTemplate(
        IDR_taiZhangFormatTTYPE,           //文档关联文件类型字符串资源。可以用来注册关联文件类型
        RUNTIME_CLASS(CDocument_JinSanSetting),
        RUNTIME_CLASS(CMDIChildWnd_JinSanSetting), // custom MDI child frame
        RUNTIME_CLASS(CFormView_JinSanSetting));        // view class

    if (!m_pMultiDocTemplate_JinSanSetting)
        return FALSE;
    AddDocTemplate(m_pMultiDocTemplate_JinSanSetting);//加入CWinApp维护的文档列表

    m_pMultiDocTemplate_JinSanFormatTans = new CMultiDocTemplate(
        IDR_taiZhangFormatTTYPE,           //文档关联文件类型字符串资源。可以用来注册关联文件类型
        RUNTIME_CLASS(CDocumentFormatTrans_JinSan),
        RUNTIME_CLASS(CMDIChildWndFormatTrans_JinSan), // custom MDI child frame
        RUNTIME_CLASS(CFormViewFormatTrans_JinSan));        // view class

    if (!m_pMultiDocTemplate_JinSanFormatTans)
        return FALSE;
    AddDocTemplate(m_pMultiDocTemplate_JinSanFormatTans);//加入CWinApp维护的文档列表

    m_pMultiDocTemplate_JinSanVerify = new CMultiDocTemplate(
        IDR_taiZhangFormatTTYPE,           //文档关联文件类型字符串资源。可以用来注册关联文件类型
        RUNTIME_CLASS(CDocumentVerify_JinSan),
        RUNTIME_CLASS(CMDIChildWndVerify_JinSan), // custom MDI child frame
        RUNTIME_CLASS(CFormViewVerify_JinSan));        // view class

    if (!m_pMultiDocTemplate_JinSanVerify)
        return FALSE;
    AddDocTemplate(m_pMultiDocTemplate_JinSanVerify);//加入CWinApp维护的文档列表
    //m_pMultiDocTemplate_ImOrExport = new CMultiDocTemplate(
    //    IDR_taiZhangFormatTTYPE,           //文档关联文件类型字符串资源。可以用来注册关联文件类型
    //    RUNTIME_CLASS(CDocumentImOrExport),
    //    RUNTIME_CLASS(CMDIChildWndImOrExport), // custom MDI child frame
    //    RUNTIME_CLASS(CFormViewImOrExport));        // view class

    //if (!m_pMultiDocTemplate_ImOrExport)
    //    return FALSE;
    //AddDocTemplate(m_pMultiDocTemplate_ImOrExport);//加入CWinApp维护的文档列表
    // 创建主 MDI 框架窗口
    CMainFrame* pMainFrame = new CMainFrame;
    if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME))
    {
        delete pMainFrame;
        return FALSE;
    }
    m_pMainWnd = pMainFrame;
    // 仅当具有后缀时才调用 DragAcceptFiles
    //  在 MDI 应用程序中,这应在设置 m_pMainWnd 之后立即发生


    // 分析标准外壳命令、DDE、打开文件操作的命令行
    CCommandLineInfo cmdInfo;
    ParseCommandLine(cmdInfo);
    cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing; //注意这里这样设置可以避免boundschecker提示conflict

    // 调度在命令行中指定的命令。如果
    // 用 /RegServer、/Register、/Unregserver 或 /Unregister 启动应用程序,则返回 FALSE。
    if (!ProcessShellCommand(cmdInfo))
        return FALSE;
    // 主窗口已初始化,因此显示它并对其进行更新
    pMainFrame->OnButtonJinSanSetting();
    //pMainFrame->OnUpdateButtonJinSanSetting();
    pMainFrame->ShowWindow(SW_SHOWMAXIMIZED);
    pMainFrame->UpdateWindow();

    return TRUE;

以下是检测程序是否已经有一个实例:

BOOL CtaiZhangFormatTransApp::IsAlreadyRun(void)
{
    try{
        // 用应用程序名创建信号量
        HANDLE hSem = CreateSemaphore(NULL, 1, 1,
            CtaiZhangFormatTransApp::m_pszExeName);

        // 信号量已存在?
        // 信号量存在,则程序已有一个实例运行
        if (GetLastError() == ERROR_ALREADY_EXISTS)
        {
            // 关闭信号量句柄
            CloseHandle(hSem);
            // 寻找先前实例的主窗口
            HWND hWndPrevious = ::GetWindow(::GetDesktopWindow(), GW_CHILD);
            while (::IsWindow(hWndPrevious))
            {
                // 检查窗口是否有预设的标记?
                // 有,则是我们寻找的主窗
                if (::GetProp(hWndPrevious, m_pszExeName))
                {
                    // 主窗口已最小化,则恢复其大小
                    if (::IsIconic(hWndPrevious))
                        ::ShowWindow(hWndPrevious, SW_RESTORE);
                    // 将主窗激活
                    ::SetForegroundWindow(hWndPrevious);
                    // 将主窗的对话框激活
                    ::SetForegroundWindow(::GetLastActivePopup(hWndPrevious));
                    // 退出本实例
                    return FALSE;
                }
                // 继续寻找下一个窗口
                hWndPrevious = ::GetWindow(hWndPrevious, GW_HWNDNEXT);
            }
            // 前一实例已存在,但找不到其主窗
            // 可能出错了
            // 退出本实例
            return FALSE;
        }
    }
    catch(...)   
    {   
        ::AfxMessageBox(_T("IsAlreadyRun Error!"));
        return FALSE;
    }  
    return TRUE;
}

以下是补充代码,为了让大家更好的理解整个代码:

int CtaiZhangFormatTransApp::ExitInstance()
{
    // TODO: 在此添加专用代码和/或调用基类
    ::CoUninitialize();
    return CWinApp::ExitInstance();
}
CDocument *CtaiZhangFormatTransApp::GetDoc(
    CRuntimeClass* pDocClass)
{
    POSITION pos = GetFirstDocTemplatePosition();
    while (pos != NULL)
    {
        CMultiDocTemplate * docTmpl=(CMultiDocTemplate *)GetNextDocTemplate(pos);
        POSITION pos2 = docTmpl->GetFirstDocPosition();
        while (pos2 != NULL)
        {
            CDocument* pDoc=docTmpl->GetNextDoc(pos2);
            if(pDoc->IsKindOf(pDocClass))
            {
                return pDoc;
            }
        }
    }
    return NULL;
}

CView*  CtaiZhangFormatTransApp::GetCView(CDocument* pDoc,const CString &wndTextParam)
{
    CString wndText;
    if(pDoc==NULL){
        return NULL;
    }
        POSITION pos2 = pDoc->GetFirstViewPosition();
        while (pos2 != NULL)
        {
            
            CView* pView = pDoc->GetNextView(pos2);
            pView->GetWindowText(wndText);
            if (wndText==wndTextParam)
            {
                return pView;
            }
        }
    return NULL;
}
CMDIChildWnd* CtaiZhangFormatTransApp::GetCMDIChildWnd(
    const CString &WndTextParam)
{
        CString wndText;
        CMDIChildWnd* pChild = ((CMainFrame*)m_pMainWnd)->GetFirstMDIChildWnd();
        while (pChild)
        {
            pChild->GetWindowText(wndText);
            if(wndText==WndTextParam)
            {
                return pChild;
            }
            pChild = ((CMainFrame*)m_pMainWnd)->GetNextMDIChildWnd();
        }
        return NULL;
}
CMultiDocTemplate *CtaiZhangFormatTransApp::GetCMultiDocTemplateFormatTrans(void)
{
    return m_pMultiDocTemplate_FormatTans;
}
CMultiDocTemplate *CtaiZhangFormatTransApp::GetCMultiDocTemplateVerify(void)
{
    return m_pMultiDocTemplate_Verify;
}
CMultiDocTemplate *CtaiZhangFormatTransApp::GetCMultiDocTemplateSetting(void)
{
    return m_pMultiDocTemplate_Setting;
}
CMultiDocTemplate *CtaiZhangFormatTransApp::GetCMultiDocTemplate_JinSanSetting(void)
{
    return m_pMultiDocTemplate_JinSanSetting;
}
CMultiDocTemplate *CtaiZhangFormatTransApp::GetCMultiDocTemplate_JinSanFormatTans(void)
{
    return m_pMultiDocTemplate_JinSanFormatTans;
}
CMultiDocTemplate *CtaiZhangFormatTransApp::GetCMultiDocTemplate_JinSanVerify(void)
{
    return m_pMultiDocTemplate_JinSanVerify;
}
CFormView *CtaiZhangFormatTransApp::GetCFormViewFormatTrans(void)
{
    return (CFormViewFormatTrans *)GetCView(GetCDocumentFormatTans(),
        m_CFormViewFrameNameArray[1]);
}
CDocument* CtaiZhangFormatTransApp::GetCDocumentFormatTans(void)
{
    return (CDocumentFormatTans* )GetDoc(RUNTIME_CLASS(CDocumentFormatTans));
}
CDocument* CtaiZhangFormatTransApp::GetCDocumentVerify(void)
{
    return (CDocumentVerify* )GetDoc(RUNTIME_CLASS(CDocumentVerify));
}
CDocument* CtaiZhangFormatTransApp::GetCDocumentSetting(void)
{
    return (CDocumentSetting* )GetDoc(RUNTIME_CLASS(CDocumentSetting));
}
CDocument* CtaiZhangFormatTransApp::GetCDocument_JinSanSetting(void)
{
    return (CDocument_JinSanSetting* )GetDoc(RUNTIME_CLASS(CDocument_JinSanSetting));
}
CDocument* CtaiZhangFormatTransApp::GetCDocument_JinSanFormatTans(void)
{
    return (CDocumentFormatTrans_JinSan* )GetDoc(RUNTIME_CLASS(CDocumentFormatTrans_JinSan));
}
CDocument* CtaiZhangFormatTransApp::GetCDocument_JinSanVerify(void)
{
    return (CDocumentVerify_JinSan* )GetDoc(RUNTIME_CLASS(CDocumentVerify_JinSan));
}
CFormView *CtaiZhangFormatTransApp::GetCFormViewVerify(void)
{
    return (CFormViewVerify *)GetCView(GetCDocumentVerify(),
        m_CFormViewFrameNameArray[2]);
}
CFormView *CtaiZhangFormatTransApp::GetCFormViewSetting(void)
{
    return (CFormViewSetting *)GetCView(GetCDocumentSetting(),
        m_CFormViewFrameNameArray[0]);
}
CFormView *CtaiZhangFormatTransApp::GetCFormView_JinSanSetting(void)
{
    return (CFormView_JinSanSetting *)GetCView(GetCDocument_JinSanSetting(),
        m_CFormViewFrameNameArray[4]);
}
CFormView *CtaiZhangFormatTransApp::GetCFormView_JinSanFormatTans(void)
{
    return (CFormViewFormatTrans_JinSan *)GetCView(GetCDocument_JinSanFormatTans(),
        m_CFormViewFrameNameArray[5]);
}
CFormView *CtaiZhangFormatTransApp::GetCFormView_JinSanVerify(void)
{
    return (CFormViewVerify_JinSan *)GetCView(GetCDocument_JinSanVerify(),
        m_CFormViewFrameNameArray[6]);
}
CMDIChildWnd *CtaiZhangFormatTransApp::GetCMDIChildWndFormatTans(void)
{
    return (CMDIChildWndFormatTans *)GetCMDIChildWnd(m_MDIChildFrameNameArray[1]);
}
CMDIChildWnd *CtaiZhangFormatTransApp::GetCMDIChildWndVerify(void)
{
    return (CMDIChildWndVerify *)GetCMDIChildWnd(m_MDIChildFrameNameArray[2]);
}
CMDIChildWnd *CtaiZhangFormatTransApp::GetCMDIChildWndSetting(void)
{
    return (CMDIChildWndSetting *)GetCMDIChildWnd(m_MDIChildFrameNameArray[0]);
}
CMDIChildWnd *CtaiZhangFormatTransApp::GetCMDIChildWnd_JinSanSetting(void)
{
    return (CMDIChildWnd_JinSanSetting *)GetCMDIChildWnd(m_MDIChildFrameNameArray[4]);
}

CMDIChildWnd *CtaiZhangFormatTransApp::GetCMDIChildWnd_JinSanFormatTans(void)
{
    return (CMDIChildWndFormatTrans_JinSan *)GetCMDIChildWnd(m_MDIChildFrameNameArray[5]);
}
CMDIChildWnd *CtaiZhangFormatTransApp::GetCMDIChildWnd_JinSanVerify(void)
{
    return (CMDIChildWndVerify_JinSan *)GetCMDIChildWnd(m_MDIChildFrameNameArray[4]);
}

以下是调用的例子:

    // CMainFrame 消息处理程序

    void CMainFrame::OnBUTTONFormatTrans()
    {
        // TODO: Add your command handler code here
        CreateOrActivateFrame(theApp.GetCMultiDocTemplateFormatTrans(),
            theApp.m_MDIChildFrameNameArray[1]);
                UpdateDialogControls(&(this->m_wndToolBar), TRUE);
    }
    void CMainFrame::OnBUTTONVerify()
    {
        // TODO: Add your command handler code here
        CreateOrActivateFrame(theApp.GetCMultiDocTemplateVerify(),
            theApp.m_MDIChildFrameNameArray[2]);
                UpdateDialogControls(&(this->m_wndToolBar), TRUE);
    }

以上代码,有些代码与本文主题有出入,算是额外的福利,以上代码经过很多验证,是正确而且高效的。

猜你喜欢

转载自blog.csdn.net/tom_xuzg/article/details/81206060