如何模拟《WORD》的窗口形式

ezioooooo

ezioooooo

2016-01-29 11:52

如何模拟《WORD》的窗口形式,如何模拟《WORD》的窗口形式
如何模拟《WORD》的窗口形式
作者:lanzhengpeng2

提交者:eastvc 发布日期:2004-1-2 20:47:45
原文出处:http://www.csdn.net/


如何模拟《WORD》的窗口形式重点在CChildFrame上做文章。

1、利用向导生成一个多文档应用程序 TestMDI,则生成下列类:

CAboutDlg,CChildFrame,CMainFrame,CTestMDIApp,CTestMDIDoc,CTestMDIView
2、改造CTestMDIApp::InitInstance():pMainFrame-ShowWindow(SW_HIDE);
3、改造CChildFrame:首先用CFrameWnd替换它的基类,再将CMainFrame里跟创建工具栏状态栏相关代码移到CChildFrame里面。为了突出重点,

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/cyuyanjiaocheng/)

我只列出更改过的代码。如下:
//ChildFrm.h
class CChildFrame : public CFrameWnd
{
protected: // control bar embedded members
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//{{AFX_MSG(CChildFrame)
afx_msg void OnClose();
//}}AFX_MSG
};

//ChildFrm.cpp
IMPLEMENT_DYNCREATE(CChildFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CChildFrame, CFrameWnd)
//{{AFX_MSG_MAP(CChildFrame)
ON_WM_CREATE()
ON_WM_CLOSE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

static UINT indicators[] =
{
ID_SEPARATOR, // status line indicator
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};

BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;

return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CChildFrame message handlers
int CChildFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -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("Failed to create toolbarn");
return -1; // fail to create
}

if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status barn");
return -1; // fail to create
}

// TODO: Delete these three lines if you don't want the toolbar to
// be dockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);

return 0;
}

void CChildFrame::OnClose()
{
CFrameWnd::OnClose();
// AfxGetMainWnd()-PostMessage(WM_COMMAND,ID_CLOSE_CHILD,0);
}

好了,现在应该可以编译通过了。怎样,不错吧?
可是,你很快就发现,怎么我的程序没有关闭?是啊,主窗口被藏起来了,还没有被关闭。原来,在所有窗口都关闭的情况下,主窗口也应该

被关闭。于是,我选择了个时机CChildFrame::OnClose(),向主窗口发送一个消息,让主窗口自己检测是否还存在有CChildFrame窗口:

void CChildFrame::OnClose()
{
CFrameWnd::OnClose();
AfxGetMainWnd()-PostMessage(WM_COMMAND,ID_CLOSE_CHILD,0); //ID_CLOSE_CHILD是自定义消息
}
相应,CMainFrame有函数对应处理这个消息:
BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam)
{
if(wParam == ID_CLOSE_CHILD)
{
CheckChildWnd();
return TRUE;
}

return CMDIFrameWnd::OnCommand(wParam, lParam);
}

void CMainFrame::CheckChildWnd()
{
CWinApp * pApp = AfxGetApp();
POSITION ps = pApp-GetFirstDocTemplatePosition();
ASSERT(ps != NULL);
CDocTemplate * pDocTemplate = pApp-GetNextDocTemplate(ps);
ps = pDocTemplate-GetFirstDocPosition();
if(ps == NULL)
PostMessage(WM_CLOSE);
}

基本问题解决。

这样做有什么好处?
由于多个视图公用一个工具栏和状态栏,导致在视图切换的时候要去更新状态栏和工具栏,特别是不同的视图有不同的状态栏的时候,非常痛

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/cyuyanjiaocheng/)

苦。做成这样的单文档界面的方式,就省下了这一步。
当然,也应该有它的不足之处,希望各位来信告知,同时希望各位能把它涉及到的问题或BUG,一并来信告

展开更多 50%)
分享

猜你喜欢

如何模拟《WORD》的窗口形式

C语言教程 C语言函数
如何模拟《WORD》的窗口形式

Javascript模拟的DOS窗口

Web开发
Javascript模拟的DOS窗口

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

WindowManagerService服务是如何以堆栈的形式来组织窗口

编程语言 网络编程
WindowManagerService服务是如何以堆栈的形式来组织窗口

Word如何随意拆分文档窗口

word
Word如何随意拆分文档窗口

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

如何用闪灯来模拟窗口自然光

摄影 人像摄影 静物摄影
如何用闪灯来模拟窗口自然光

word窗口图标太大了

电脑入门
word窗口图标太大了

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

AutoCAD三维实体速成最简单入门法[第十五集]

AutoCAD三维实体速成最简单入门法[第十五集]

“mailto”的六则应用技巧

“mailto”的六则应用技巧
下拉加载更多内容 ↓