早听说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
);
}如果想研究如何绘制各种界面元素,尽管去看这些类的实现代码就行了。^_^下面简单的表示上面几个类的关系:
阅读(2963) | 评论(0) | 转发(0) |