Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2290041
  • 博文数量: 266
  • 博客积分: 5485
  • 博客等级: 大校
  • 技术积分: 3695
  • 用 户 组: 普通用户
  • 注册时间: 2007-06-20 11:05
个人简介

多读书,多做事,广交朋友,趣味丛生

文章分类

全部博文(266)

分类: C/C++

2012-12-31 00:23:17

早听说Visual C++ 2008 FR1提供了很多新的功能,其中就包括MFC的新界面。现在拿到Visual Studio 2008 SP1简体中文版,急不可待的用了一下。果然,在向导中,就可以在工程里加入modern风格的界面了,可以模仿Office和Visual Stidio的界面风格。


阅读向导生成的代码发现,MFC用了一套新的框架类:
SDI:CFrameWndEx
MDI:CMDIFrameWndEx,CMDIChildWndEx


让我们先从框架类看起吧。

CFrameWndEx和CMDIFrameWndEx都是通过类CFrameImpl实现具体的框架绘制操作。CFrameWndEx和CMDIFrameWndEx都对我们熟悉的消息做了处理:
WM_NCHITTEST
WM_NCCALCSIZE
WM_NCPAINT
WM_NCMOUSEMOVE
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_ACTIVATEAPP
WM_MOUSEMOVE
WM_SIZE
WM_SIZING
这些消息的处理又是调用CFrameImpl完成的。


MFC能显示多种风格的界面,这是如何实现的呢?看到向导创建了如下的代码:

void CMainFrame::OnApplicationLook(UINT id)
{

CWaitCursor wait;

theApp.m_nAppLook = id;

switch
(theApp.m_nAppLook)
{

case
ID_VIEW_APPLOOK_WIN_2000:
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManager));
break
;

case
ID_VIEW_APPLOOK_OFF_XP:
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOfficeXP));
break
;

case
ID_VIEW_APPLOOK_WIN_XP:
CMFCVisualManagerWindows::m_b3DTabsXPTheme = TRUE;
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
break
;

case
ID_VIEW_APPLOOK_OFF_2003:
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOffice2003));
CDockingManager::SetDockingMode(DT_SMART);
break
;

case
ID_VIEW_APPLOOK_VS_2005:
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerVS2005));
CDockingManager::SetDockingMode(DT_SMART);
break
;

default
:
switch
(theApp.m_nAppLook)
{

case
ID_VIEW_APPLOOK_OFF_2007_BLUE:
CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_LunaBlue);
break
;

case
ID_VIEW_APPLOOK_OFF_2007_BLACK:
CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_ObsidianBlack);
break
;

case
ID_VIEW_APPLOOK_OFF_2007_SILVER:
CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_Silver);
break
;

case
ID_VIEW_APPLOOK_OFF_2007_AQUA:
CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_Aqua);
break
;
}


CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOffice2007));
CDockingManager::SetDockingMode(DT_SMART);
}


RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW | RDW_FRAME | RDW_ERASE);

theApp.WriteInt(_T("ApplicationLook"), theApp.m_nAppLook);
}

这段代码是切换界面风格的命令处理函数。CMFCVisualManager是UI界面的基类(事实上,他还有一个基类:CMFCBaseVisualManager),他提供类似于Windows2000风格的UI界面。
其他几种UI界面类都是从它直接或间接派生的。SetDefaultManager用来设置不同的UI界面风格类。
从上面的代码可以看出CMFCVisualManager是一个单件,一个程序只需要一个这样的类就可以了。
AFX_IMPORT_DATA static CMFCVisualManager* m_pVisManager;
当设置新界面风格时,SetDefaultManager销毁原来的界面风格类,创建新的界面风格类。界面风格类通过(RUNTIME_CLASS创建,这是一种工厂方法。MFC很早就使用这种方法创建对象了,比C++的RTTI出来得还早。


CMFCVisualManager提供了很多类似于OnNcPaint的虚函数,这些函数不用说就是用来绘制界面的。CFrameImpl正是调用CMFCVisualManager来实现界面绘制工作的,例如:

BOOL CFrameImpl::OnNcPaint()
{

ASSERT_VALID(m_pFrame);

if
(!IsOwnerDrawCaption() || g_bInSettingChange)
{

return
FALSE;
}


return
CMFCVisualManager::GetInstance()->OnNcPaint(m_pFrame, m_lstCaptionSysButtons, m_rectRedraw);
}

如果想研究如何绘制各种界面元素,尽管去看这些类的实现代码就行了。^_^


下面简单的表示上面几个类的关系:

阅读(2881) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~