Visual Studio MFC框架结构设计_框架结构设计百度文库
Visual Studio MFC框架结构设计由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“框架结构设计百度文库”。
Visual Studio 2010 MFC框架结构设计(图解)
建立一个类似于fisualStudio2010的界面,总体步骤如下: 第一步是建立一个标准的MFC工程(这对我们学习有利)第二步是添加必要的资源,当然也可以边做边加入。
第三步是从CDockablePane派生一个视图类用于停靠在框架窗口的左边。为这个类要创建一个CViewTree类,它主要是在派生出来的类中加入树控件。第四步就是设计这个派生的类,为其添加工具栏,弹出菜单等 第五步就是将这个派生类加到框架中去。下面我们开始制作:
一、新建标准的MFC工程
点新建项目
选择Visual C++的MFC选择MFC应用程序输入MyTest工程名(位置就自己定吧。这里解决方案名称会与名称同步,你可以修改“解决方案名称(M)”,它其实就是工程的总目录名)点击确定。
下一步
这里我们使用的是“多信文档”选项卡式档,项目类型选择MFC校准点击完成。
二、设计左侧停靠窗口CDockablePane
在类视图中点击右键,在弹出菜单中选择“类向导”
点击“添加类”
类名中添加“CPersonView”基类选择“CDockablePane”点击完成,回到类向导中,我们看到类名已经是我们刚刚建立的类。
点击确定。这样我们就建立了一个由CDockablePane派生的子类“CPersonView”。接下类我们再从CTreeCtrl类派生一个CViewTree子类,它是有要CPersonView中生成树形结构。作为系统功能菜单使用。步骤与建立CPersonView上面相同。接下来是为CPersonView停靠窗口上方添一个独特的工具栏,为此我们要生成一类,这个类不必用向导生成,只需要在CPersonView类头文件中添加如下代码就可以了,因这个类不作为其公用类(比较小)。(CPersonView.h文件)
#pragma once #include “viewtree.h”
cla CPersonViewToolBar : public CMFCToolBar { virtual void OnUpdateCmdUI(CFrameWnd* /*pTarget*/, BOOL bDisableIfNoHndler)//此成员函数由框架类调用,以便更新状态工具栏或状态栏,pTarget指向应用程序的主窗口,这个指针用于路由更新消息,bDisablefNoHndler是个标志,指示控件没有更新处理程序应该自动显示为禁用。
};CMFCToolBar是选件类类似于 CToolBar Cla,但是,提供用户界面功能附加支持。其中包括简单的工具栏、工具栏有快捷图像的,大图标、寻呼机按钮、锁定的工具栏、rebar控件、文本在图像下,背景图像和选项卡式工具栏。CMFCToolBar 选件类还包含内置为工具栏的用户可自定义的支持,并菜单、拖放到工具栏和菜单之间,组合框按钮,编辑框按钮、颜色选取器和汇总按钮。{ } virtual BOOL AllowShowOnList()const { return FALSE;} CMFCToolBar::OnUpdateCmdUI((CFrameWnd*)GetOwner(), bDisableIfNoHndler);
下面是将CViewTree附加到CPersonView中。方法是:
在类视图中右键选择CPersonView类
访问选择“protected”变量类型选择输入“CViewTree”变量名输入“m_wndViewTree”点击完成。这样就在CPersonView类的头文件中定议一个名为m_wndViewTree的变量。
代码如下:
protected: DECLARE_MESSAGE_MAP()CViewTree m_wndViewTree;同样方法为CPersonView添加如下两个变量:
CImageList m_PersonViewImages;CPersonViewToolBar m_wndToolBar;接下来我们要为CPersonView添加一个弹出式菜单方法是:选择资源视图(或者在解决方案视图中找到资源文件(MyTest.rc)双击进入资源视图)
右击“Menu”
选择添加资源
点击新建
方法不再赘述,其ID改为IDR_POPUP_EXPLORER,保存。添加位图资源(与菜单相同)其ID改为IDB_PERSON_VIEW
添加工具栏其ID改为IDR_EXPLORER
同法添加IDB_EXPLORER_24及IDB_FILE_VIEW
CPerosnView添加自定义方法OnChangeVisualStyle()和AdjustLayout,方法是,进入类向导选择“方法”
点击添加方法
返回类型为void,参数类型不添加,访问选择public 点确定。再添加一个用于对树添加节点的私有方法:FillFileView方法。
下面是三个方法的代码
void CPersonView::OnChangeVisualStyle(void){
CBitmap bmp;if(!bmp.LoadBitmap(uiBmpId)){
} TRACE(_T(“无T法¤¡§加¨®载?位?图ª?: %xn”), uiBmpId);ASSERT(FALSE);return;UINT uiBmpId = theApp.m_bHiColorIcons ? IDB_PERSON_VIEW_24 : IDB_PERSON_VIEW;m_PersonViewImages.DeleteImageList();m_wndToolBar.CleanUpLockedImages();m_wndToolBar.LoadBitmap(theApp.m_bHiColorIcons ? IDB_EXPLORER_24 : IDR_EXPLORER, 0, 0, TRUE /* 锁?定¡§*/);
}
void CPersonView::AdjustLayout(void){
}
void CPersonView::FillFileView(void){
m_wndViewTree.InsertItem(_T(“FakeApp.cpp”), 1, 1, hSrc);m_wndViewTree.InsertItem(_T(“FakeApp.rc”), 1, 1, hSrc);m_wndViewTree.InsertItem(_T(“FakeAppDoc.cpp”), 1, 1, hSrc);m_wndViewTree.InsertItem(_T(“FakeAppView.cpp”), 1, 1, hSrc);HTREEITEM hSrc = m_wndViewTree.InsertItem(_T(“FakeApp 源¡ä文?件t”), 0, 0, hRoot);
HTREEITEM hRoot = m_wndViewTree.InsertItem(_T(“FakeApp 文?件t”), 0, 0);m_wndViewTree.SetItemState(hRoot, TVIS_BOLD, TVIS_BOLD);m_wndToolBar.SetWindowPos(NULL, rectClient.left, rectClient.top, rectClient.Width(), cyTlb, SWP_NOACTIVATE | m_wndViewTree.SetWindowPos(NULL, rectClient.left + 1, rectClient.top + cyTlb + 1, rectClient.Width()cyTlb-2, SWP_NOACTIVATE | SWP_NOZORDER);int cyTlb = m_wndToolBar.CalcFixedLayout(FALSE, TRUE).cy;CRect rectClient;GetClientRect(rectClient);if(GetSafeHwnd()== NULL){ } return;m_wndViewTree.SetImageList(&m_PersonViewImages, TVSIL_NORMAL);m_PersonViewImages.Create(16, bmpObj.bmHeight, nFlags, 0, 0);m_PersonViewImages.Add(&bmp, RGB(255, 0, 255));nFlags |=(theApp.m_bHiColorIcons)? ILC_COLOR24 : ILC_COLOR4;UINT nFlags = ILC_MASK;BITMAP bmpObj;bmp.GetBitmap(&bmpObj);
} m_wndViewTree.InsertItem(_T(“MainFrm.cpp”), 1, 1, hSrc);m_wndViewTree.InsertItem(_T(“StdAfx.cpp”), 1, 1, hSrc);HTREEITEM hInc = m_wndViewTree.InsertItem(_T(“FakeApp 头ª¡¤文?件t”), 0, 0, hRoot);m_wndViewTree.InsertItem(_T(“FakeApp.h”), 2, 2, hInc);m_wndViewTree.InsertItem(_T(“FakeAppDoc.h”), 2, 2, hInc);m_wndViewTree.InsertItem(_T(“FakeAppView.h”), 2, 2, hInc);m_wndViewTree.InsertItem(_T(“Resource.h”), 2, 2, hInc);m_wndViewTree.InsertItem(_T(“MainFrm.h”), 2, 2, hInc);m_wndViewTree.InsertItem(_T(“StdAfx.h”), 2, 2, hInc);HTREEITEM hRes = m_wndViewTree.InsertItem(_T(“FakeApp 资Á¨º源¡ä文?件t”), 0, 0, hRoot);m_wndViewTree.InsertItem(_T(“FakeApp.ico”), 2, 2, hRes);m_wndViewTree.InsertItem(_T(“FakeApp.rc2”), 2, 2, hRes);m_wndViewTree.InsertItem(_T(“FakeAppDoc.ico”), 2, 2, hRes);m_wndViewTree.InsertItem(_T(“FakeToolbar.bmp”), 2, 2, hRes);m_wndViewTree.Expand(hRoot, TVE_EXPAND);m_wndViewTree.Expand(hSrc, TVE_EXPAND);m_wndViewTree.Expand(hInc, TVE_EXPAND);下面为CPersonView类添加消息响应函数 右击CPersonView选择“类向导”选择“消息”
分别添加(双击)WM_CONTEXTMENU WM_CREATE WM_PAINT
鼠标右键消息
窗口创建消息 窗口刷新消息
WM_SETFOCUS 窗口得到焦点消息 WM_SIZE 窗口尺寸变化消息
五个消息,代码如下
void CPersonView::OnContextMenu(CWnd* pWnd, CPoint point){
} // TODO: 在¨²此ä?处ä|添¬¨ª加¨®消?息¡é处ä|理¤¨ª程¨¬序¨°代䨲码? CTreeCtrl* pWndTree =(CTreeCtrl*)&m_wndViewTree;ASSERT_VALID(pWndTree);if(pWnd!= pWndTree){
} if(point!= CPoint(-1,-1)){
} pWndTree->SetFocus();theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EXPLORER, point.x, point.y, this, TRUE);// 选?择?已°?单Ì£¤击¡Â的Ì?项?: CPoint ptTree = point;pWndTree->ScreenToClient(&ptTree);UINT flags = 0;HTREEITEM hTreeItem = pWndTree->HitTest(ptTree, &flags);if(hTreeItem!= NULL){ } pWndTree->SelectItem(hTreeItem);CDockablePane::OnContextMenu(pWnd, point);return;int CPersonView::OnCreate(LPCREATESTRUCT lpCreateStruct){
if(!m_wndViewTree.Create(dwViewStyle, rectDummy, this, 4)){ TRACE0(“未¡ä能¨¹创ä¡ä建¡§文?件t视º¨®图ª?n”);return-1;
// 未¡ä能¨¹创ä¡ä建¡§ // 创ä¡ä建¡§视º¨®图ª?:
const DWORD dwViewStyle = WS_CHILD | WS_VISIBLE | TVS_HASLINES | TVS_LINESATROOT | // TODO: 在¨²此ä?添¬¨ª加¨®您¨²专Á¡§用®?的Ì?创ä¡ä建¡§代䨲码? rectDummy.SetRectEmpty();CRect rectDummy;if(CDockablePane::OnCreate(lpCreateStruct)==-1)return-1;TVS_HASBUTTONS;
} } // 加¨®载?视º¨®图ª?图ª?像?:
m_PersonViewImages.Create(IDB_PERSON_VIEW, 16, 0, RGB(255, 0, 255));m_wndViewTree.SetImageList(&m_PersonViewImages, TVSIL_NORMAL);m_wndToolBar.Create(this, AFX_DEFAULT_TOOLBAR_STYLE, IDR_EXPLORER);m_wndToolBar.LoadToolBar(IDR_EXPLORER, 0, 0, TRUE /* 已°?锁?定¡§*/);OnChangeVisualStyle();m_wndToolBar.SetPaneStyle(m_wndToolBar.GetPaneStyle()| CBRS_TOOLTIPS | CBRS_FLYBY);m_wndToolBar.SetPaneStyle(m_wndToolBar.GetPaneStyle()& ~(CBRS_GRIPPER | CBRS_SIZE_DYNAMIC | CBRS_BORDER_TOP | CBRS_BORDER_BOTTOM | CBRS_BORDER_LEFT | CBRS_BORDER_RIGHT));m_wndToolBar.SetOwner(this);// 所¨´有®D命¨¹令¢?将?通ª¡§过y此ä?控?件t路¡¤由®¨¦,ê?而?不?是º?通ª¡§过y主¡Â框¨°架¨¹路¡¤由®¨¦: m_wndToolBar.SetRouteCommandsViaFrame(FALSE);// 填入一些静态树视图数据此处只需填入虚拟代码,而不是复杂的数据)FillFileView();AdjustLayout();return 0;void CPersonView::OnPaint(){
}
void CPersonView::OnSetFocus(CWnd* pOldWnd){ rectTree.InflateRect(1, 1);dc.Draw3dRect(rectTree, ::GetSysColor(COLOR_3DSHADOW), ::GetSysColor(COLOR_3DSHADOW));CRect rectTree;m_wndViewTree.GetWindowRect(rectTree);ScreenToClient(rectTree);CPaintDC dc(this);// device context for painting
// TODO: 在¨²此ä?处ä|添¬¨ª加¨®消?息¡é处ä|理¤¨ª程¨¬序¨°代䨲码? // 不?为a绘?图ª?消?息¡é调Ì¡Â用®? CDockablePane::OnPaint()CDockablePane::OnSetFocus(pOldWnd);
// TODO: 在¨²此ä?处ä|添¬¨ª加¨®消?息¡é处ä|理¤¨ª程¨¬序¨°代䨲码?
m_wndViewTree.SetFocus();}
void CPersonView::OnSize(UINT nType, int cx, int cy){ CDockablePane::OnSize(nType, cx, cy);
// TODO: 在¨²此ä?处ä|添¬¨ª加¨®消?息¡é处ä|理¤¨ª程¨¬序¨°代䨲码?
AdjustLayout();}
我们现在就以完成了CPersonView类的设计,可以编译运行一下,如查没有发生错误就可以接着将CPersonView加到框架中去了。
三、将新视图添加到框架窗口中 添加一个字符串资源
ID为IDS_PERSON_VIEW 标题为“人力资源”。保存 再添加一个空ID为ID_VIEW_PERSONVIEW
点击新建
再添加两个图标资源IDI_PERSON_VIEW_HC 和 IDI_PERSON_VIEW
接下来我们在类视图中找到CMainFrame类,点击右键,为其添加CPersonView变量m_wndPersonView。
下面为CMainFrame添加两个自定义方法,代码如下:
BOOL CMainFrame::CreateDockingWindow(void){ BOOL bNameValid;
// 创建类视图
CString strClaView;bNameValid = strClaView.LoadString(IDS_PERSON_VIEW);ASSERT(bNameValid);if(!m_wndPersonView.Create(strClaView, this, CRect(0, 0, 200, 200), TRUE, ID_VIEW_PERSONVIEW, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_LEFT | CBRS_FLOAT_MULTI)){
} SetDockingWindowIcons(theApp.m_bHiColorIcons);return TRUE;}
void CMainFrame::SetDockingWindowIcons(bool bHiColorIcons){ HICON hFileViewIcon =(HICON)::LoadImage(::AfxGetResourceHandle(), MAKEINTRESOURCE(bHiColorIcons
?
IDI_PERSON_VIEW_HC
: TRACE0(“未能创建“人力资源视图”窗口n”);return FALSE;// 未能创建 IDI_PERSON_VIEW), IMAGE_ICON, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), 0);m_wndPersonView.SetIcon(hFileViewIcon, FALSE);} 双击框架类的成员函数OnCreate
添加代码
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct){ if(CMDIFrameWndEx::OnCreate(lpCreateStruct)==-1)
return-1;BOOL bNameValid;// 基于持久值设置视觉管理器和样式
OnApplicationLook(theApp.m_nAppLook);
CMDITabInfo mdiTabParams;mdiTabParams.m_style = CMFCTabCtrl::STYLE_3D_ONENOTE;// 其他可用样式...mdiTabParams.m_bActiveTabCloseButton = TRUE;
// 设置为 FALSE 会将关闭按钮放置在选项卡区域的右侧
mdiTabParams.m_bTabIcons = FALSE;
// 设置为 TRUE 将在 MDI 选项卡上启用文档图标
mdiTabParams.m_bAutoColor = TRUE;
// 设置为 FALSE 将禁用 MDI 选项卡的自动着色
mdiTabParams.m_bDocumentMenu = TRUE;// 在选项卡区域的右边缘启用文档菜单
EnableMDITabbedGroups(TRUE, mdiTabParams);
if(!m_wndMenuBar.Create(this)){
} TRACE0(“未能创建菜单栏n”);return-1;
// 未能创建 m_wndMenuBar.SetPaneStyle(m_wndMenuBar.GetPaneStyle()CBRS_SIZE_DYNAMIC | CBRS_TOOLTIPS | CBRS_FLYBY);
// 防止菜单栏在激活时获得焦点
CMFCPopupMenu::SetForceMenuFocus(FALSE);
| 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(theApp.m_bHiColorIcons
? IDR_MAINFRAME_256 : IDR_MAINFRAME)){
}
CString strToolBarName;bNameValid = strToolBarName.LoadString(IDS_TOOLBAR_STANDARD);ASSERT(bNameValid);m_wndToolBar.SetWindowText(strToolBarName);
CString strCustomize;bNameValid = strCustomize.LoadString(IDS_TOOLBAR_CUSTOMIZE);TRACE0(“未能创建工具栏n”);return-1;
// 未能创建 ASSERT(bNameValid);m_wndToolBar.EnableCustomizeButton(TRUE, strCustomize);
// 允许用户定义的工具栏操作: InitUserToolbars(NULL, uiFirstUserToolBarId, uiLastUserToolBarId);
if(!m_wndStatusBar.Create(this)){
} m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));
// TODO: 如果您不希望工具栏和菜单栏可停靠,请删除这五行
m_wndMenuBar.EnableDocking(CBRS_ALIGN_ANY);m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);EnableDocking(CBRS_ALIGN_ANY);DockPane(&m_wndMenuBar);DockPane(&m_wndToolBar);
// 启用 Visual Studio 2005 样式停靠窗口行为 TRACE0(“未能创建状态栏n”);return-1;
// 未能创建
ID_VIEW_CUSTOMIZE, CDockingManager::SetDockingMode(DT_SMART);// 启用 Visual Studio 2005 样式停靠窗口自动隐藏行为
EnableAutoHidePanes(CBRS_ALIGN_ANY);
// 启用增强的窗口管理对话框
EnableWindowsDialog(ID_WINDOW_MANAGER,// 启用工具栏和停靠窗口菜单替换
EnablePaneMenu(TRUE, ID_VIEW_CUSTOMIZE,// 启用快速(按住 Alt 拖动)工具栏自定义
CMFCToolBar::EnableQuickCustomization();
if(CMFCToolBar::GetUserImages()== NULL){
// 加载用户定义的工具栏图像
if(m_UserImages.Load(_T(“.UserImages.bmp”)))
{
CMFCToolBar::SetUserImages(&m_UserImages);
} }
strCustomize, ID_WINDOW_MANAGER, TRUE);ID_VIEW_TOOLBAR);
if(!CreateDockingWindow()){
} m_wndPersonView.EnableDocking(CBRS_ALIGN_ANY);DockPane(&m_wndPersonView);
// 启用菜单个性化(最近使用的命令)// TODO: 定义您自己的基本命令,确保每个下拉菜单至少有一个基本命令。
CList lstBasicCommands;
lstBasicCommands.AddTail(ID_FILE_NEW);lstBasicCommands.AddTail(ID_FILE_OPEN);lstBasicCommands.AddTail(ID_FILE_SAVE);lstBasicCommands.AddTail(ID_FILE_PRINT);lstBasicCommands.AddTail(ID_APP_EXIT);lstBasicCommands.AddTail(ID_EDIT_CUT);lstBasicCommands.AddTail(ID_EDIT_PASTE);lstBasicCommands.AddTail(ID_EDIT_UNDO);TRACE0(“未能创建停靠窗口n”);return-1;lstBasicCommands.AddTail(ID_APP_ABOUT);lstBasicCommands.AddTail(ID_VIEW_STATUS_BAR);lstBasicCommands.AddTail(ID_VIEW_TOOLBAR);lstBasicCommands.AddTail(ID_VIEW_APPLOOK_OFF_2003);lstBasicCommands.AddTail(ID_VIEW_APPLOOK_VS_2005);lstBasicCommands.AddTail(ID_VIEW_APPLOOK_OFF_2007_BLUE);lstBasicCommands.AddTail(ID_VIEW_APPLOOK_OFF_2007_SILVER);lstBasicCommands.AddTail(ID_VIEW_APPLOOK_OFF_2007_BLACK);lstBasicCommands.AddTail(ID_VIEW_APPLOOK_OFF_2007_AQUA);lstBasicCommands.AddTail(ID_VIEW_APPLOOK_WINDOWS_7);
CMFCToolBar::SetBasicCommands(lstBasicCommands);
// 将文档名和应用程序名称在窗口标题栏上的顺序进行交换。这
// 将改进任务栏的可用性,因为显示的文档名带有缩略图。
ModifyStyle(0, FWS_PREFIXTITLE);
return 0;}
好了,现在可以运行一下了。看看如何。