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;
}
以下是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);
}
以上代码,有些代码与本文主题有出入,算是额外的福利,以上代码经过很多验证,是正确而且高效的。