学习了MFC之后变了几个小程序,但是总是觉得自己的程序界面不够漂亮,看到很多应用程序的界面都做的很漂亮,不免会有些羡慕。于是到网上去找了一些界面库,但是大多都是收费的。最近发现了一个免费的界面库Prof-UIS,而且它给的实例程序界面也十分专业十分漂亮,就下载来使用,但用起来有些复杂,于是我将学习的心得体会写下来,一是怕自己忘记,以便以后使用的时候查阅,二是和大家一起分享。由于水平有限所以写的肯定会有错误,请大家帮忙指正,谢谢!
Prof-UIS 2.6
第1章 框架生成的基本结构
1.1向导生成的代码
在使用Prof-UIS的向导时不选择任何Prof-UIS的属性,来生成一个SDI工程。生成的SDI工程经编译运行后的执行结果如图:
图1.1
Prof-UIS向导默认在程序中使用Prof-UIS扩展的工具栏和状态栏。下面是向导生成的代码:
在stdafx.h中包含了Prof-UIS扩展库的头文件
#include <Prof-UIS.h>
在YourApp.cpp中加为CYourApp类添加了一个新的成员函数
void SetupUiAdvancedOptions();
定义如下:
void CUIS0App::SetupUiAdvancedOptions()
{
VERIFY(
g_CmdManager->ProfileSetup(__PROF_UIS_PROJECT_CMD_PROFILE_NAME)
);
g_PaintManager.InstallPaintManager(
//RUNTIME_CLASS( CExtPaintManager )
RUNTIME_CLASS( CExtPaintManagerXP )
//RUNTIME_CLASS( CExtPaintManagerOffice2003 )
//RUNTIME_CLASS( CExtPaintManagerOffice2003NoThemes )
//RUNTIME_CLASS( CExtPaintManagerStudio2005 )
//RUNTIME_CLASS( CExtPaintManagerNativeXP )
//RUNTIME_CLASS( CExtPaintManagerOffice2007_R1 )
//RUNTIME_CLASS( CExtPaintManagerOffice2007_R2_LunaBlue )
//RUNTIME_CLASS( CExtPaintManagerOffice2007_R2_Obsidian )
);
CExtPopupMenuWnd::g_bMenuWithShadows = false;
CExtPopupMenuWnd::g_bMenuShowCoolTips = false;
CExtPopupMenuWnd::g_bMenuExpanding = false;
CExtPopupMenuWnd::g_bMenuHighlightRarely = false;
CExtPopupMenuWnd::g_bMenuExpandAnimation = false;
CExtPopupMenuWnd::g_bUseDesktopWorkArea = false;
CExtPopupMenuWnd::g_DefAnimationType=CExtPopupMenuWnd::__AT_FADE;
//$$__PROFUISAPPWIZ_KEY_MENU_ANIM_DISPMS$$
}
此函数在InitInstance函数中调用如下:
BOOL CUIS0App::InitInstance()
{
CWinApp::InitInstance();
SetupUiAdvancedOptions();
//...
}
它的作用是初始化Prof-UIS库并设置相应的控件风格
g_CmdManager->ProfileSetup(__PROF_UIS_PROJECT_CMD_PROFILE_NAME)中
g_CmdManager是Prof-UIS库中的一个全局变量定义在ExtCmdManager.h和ExtCmdManager.cpp中如下:
extern __PROF_UIS_API CExtCmdManager::CExtCmdManagerAutoPtr g_CmdManager;和
CExtCmdManager::CExtCmdManagerAutoPtr g_CmdManager;
CExtCmdManager类是一个辅助类,它包含着所用的Prof-UIS的用户接口的控件信息,包括,我们可以通过全局变量g_CmdManager来得到指向CExtCmdManager的指针。
CExtCmdManagerAutoPtr类有一个重载运算符
// command manager instance access
CExtCmdManager * operator -> ();
通过g_CmdManager->可以得到CExtCmdManager的指针。
1.2 Command Manager,Command Profile, Command description
Command Manager在Prof-UIS中是一个重要的概念,Command Manager是类CExtCmdManager的对象。Command Manager是一个指定的Command Profile的集合,每一个Command Profile是类CExtCmdProfile的对象,每一个Command Profile都有它自己唯一的名字并保存有一系列的HWND句柄,这就使得一个窗口(控件也是窗口)知道它属于哪一个Command Profile。Command Profile更重要的任务是保存Command description,Command description是类CExtCmdItem的对象,它保存这单一窗口的信息,包括:
标识符
菜单项,工具栏按钮,提示,状态栏的文本
图标
支持可扩展的弹出菜单的命令
大部分应用程序都是基于Command Manager中的单一的Command Profile,这个Command Profile保存这主框架窗口或主对话框的HWND句柄,这允许主窗口和它的所有的子窗口都可以自动的得到需要的Command description。
当开始使用Prof-UIS库时必须初始化一个Command Manager,将一个Command Profile添加到Command Manager中,然后把要使用的所有的Command description放到这个Command Profile中。你要在程序初始化或窗口创建时添加下列代码:
VERIFY(
g_CmdManager->ProfileSetup(
"name of the command profile",
GetSafeHwnd() //框架窗口的句柄
)
);
接下来就是注册你的控件的Command description
VERIFY(
g_CmdManager->UpdateFromMenu(
"name of the command profile",
IDR_MAINFRAME
)
);
VERIFY(
g_CmdManager->UpdateFromMenu(
"name of the command profile",
IDR_YourMdiProjectsDOCTYPE
)
);
VERIFY(
g_CmdManager->UpdateFromToolBar(
"name of the command profile",
IDR_TOOLBAR1
)
);
注意上面的"name of the command profile"这是Command Profile的标识符,必须使用你想要添加到并且是以及安装到Command Manager的Command Profile的名字。
注意,最后Command Manager必须被销毁,在CMainFrame::DestroyWindow()中(基于对话框的程序在OnOK()和OnCancel()中),以使得窗口句柄得到释放:
g_CmdManager->ProfileWndRemove(GetSafeHwnd());
1.3初始化过程
了解了Command Manager的概念和Prof-UIS库的初始化后再来看看用Prof-UIS向导生成的代码的初始化过程:
首先初始化
VERIFY(
g_CmdManager->ProfileSetup(__PROF_UIS_PROJECT_CMD_PROFILE_NAME)
);
首先为Command Manager安装一个不与任何窗口关联的Command Profile,在YourApp.h中有如下的定义
#define __PROF_UIS_PROJECT_CMD_PROFILE_NAME /
_T("CYourApp-command-manager-profile")
在int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)中向已安装的Command Profile中添加关联窗口,
VERIFY(
g_CmdManager->ProfileWndAdd(
__PROF_UIS_PROJECT_CMD_PROFILE_NAME,
GetSafeHwnd()
)
);
在BOOL CMainFrame::DestroyWindow()中销毁Command Manager
g_CmdManager->ProfileWndRemove(GetSafeHwnd());
1.4 显示风格
在void CUIS0App::SetupUiAdvancedOptions()中有下面一段代码:
g_PaintManager.InstallPaintManager(
//RUNTIME_CLASS( CExtPaintManager )
RUNTIME_CLASS( CExtPaintManagerXP )
//RUNTIME_CLASS( CExtPaintManagerOffice2003 )
//RUNTIME_CLASS( CExtPaintManagerOffice2003NoThemes )
//RUNTIME_CLASS( CExtPaintManagerStudio2005 )
//RUNTIME_CLASS( CExtPaintManagerNativeXP )
//RUNTIME_CLASS( CExtPaintManagerOffice2007_R1 )
//RUNTIME_CLASS( CExtPaintManagerOffice2007_R2_LunaBlue )
//RUNTIME_CLASS( CExtPaintManagerOffice2007_R2_Obsidian )
);
CExtPopupMenuWnd::g_bMenuWithShadows = false;
CExtPopupMenuWnd::g_bMenuShowCoolTips = false;
CExtPopupMenuWnd::g_bMenuExpanding = false;
CExtPopupMenuWnd::g_bMenuHighlightRarely = false;
CExtPopupMenuWnd::g_bMenuExpandAnimation = false;
CExtPopupMenuWnd::g_bUseDesktopWorkArea = false;
CExtPopupMenuWnd::g_DefAnimationType = CExtPopupMenuWnd::__AT_FADE;
这段代码是设置显示风格和设在菜单风格的代码。
g_PaintManager是全局变量在ExtPaintManager.h中ExtPaintManager.cpp分别有定义:
extern __PROF_UIS_API CExtPaintManager::CExtPaintManagerAutoPtr g_PaintManager;
和
CExtPaintManager::CExtPaintManagerAutoPtr g_PaintManager;
bool CExtPaintManager::CExtPaintManagerAutoPtr::
InstallPaintManager(CRuntimeClass * pRtcPaintManager)
和
bool CExtPaintManager::CExtPaintManagerAutoPtr::
InstallPaintManager(CExtPaintManager * pPaintManager)
是用来安装显示风格的,以上的
CExtPaintManager是传统的显示风格9x/2000的风格
CExtPaintManagerXP
CExtPaintManagerOffice2003等都是从CExtPaintManager派生的
CExtPopupMenuWnd::g_bMenuWithShadows = false;
CExtPopupMenuWnd::g_bMenuShowCoolTips = false;
CExtPopupMenuWnd::g_bMenuExpanding = false;
CExtPopupMenuWnd::g_bMenuHighlightRarely = false;
CExtPopupMenuWnd::g_bMenuExpandAnimation = false;
CExtPopupMenuWnd::g_bUseDesktopWorkArea = false;
CExtPopupMenuWnd::g_DefAnimationType = CExtPopupMenuWnd::__AT_FADE;
菜单的显示样式,具体在菜单的章节中介绍。
1.5 CExtNCW
Prof-UIS向导生成的代码中,对话框和主框架窗口都是从CExtNCW模板类继承的如:
class CAboutDlg : public CExtNCW < CExtResizableDialog >
class CMainFrame : public CExtNCW < CFrameWnd >
是对窗口的模板化,其中对窗口进行了一些处理以便适应不同显示样式对窗口的要求,主要是Office2007模式。
其中class CMainFrame : public CExtNCW < CFrameWnd >
使用了基本的模板类,但是
class CAboutDlg : public CExtNCW < CExtResizableDialog >
使用的是CExtNCW模板类的一个实例化。
1.6 系统默认工具栏和状态栏
Prof-UIS向导生成的代码中默认使用Prof-UIS扩展的工具栏和状态栏风格,因为Prof-UID扩展风格的菜单是使用Menu bar实现的,所以向导会要求用户选择是否使用menu bar。如果用户使用传统的菜单时,向导就不会对菜单进行扩展。
向导生成的代码中使用了如下的工具栏和状态栏
CExtStatusControlBar m_wndStatusBar;
CExtToolControlBar m_wndToolBar;
1.6.1 工具栏的创建过程:
使用CExtControlBar::Create函数创建工具栏如下:
if( !m_wndToolBar.Create(
NULL, // _T("Main Toolbar"),当Toolbar浮动是标题中显示的文本
this,
AFX_IDW_TOOLBAR,
WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_FLYBY | CBRS_SIZE_DYNAMIC | CBRS_TOOLTIPS) ||
!m_wndToolBar.LoadToolBar( IDR_MAINFRAME )
)
{
TRACE0("Failed to create toolbar/n");
return -1; // fail to create
}
使用
if( !CExtControlBar::FrameEnableDocking(this) )
{
ASSERT( FALSE );
return -1;
}
代替MFC的EnableDocking()
1.6.2 状态栏的创建过程
CExtStatusControlBar是直接从MFC的CStatusBar继承来的,所以它的创建方法与MFC的相同:
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar/n");
return -1; // fail to create
}
1.6.3 预留接口
在Prof-UIS向导生成的代码中预留了很多的扩展接口。
CWinApp * pApp = ::AfxGetApp();
ASSERT( pApp != NULL );
ASSERT( pApp->m_pszRegistryKey != NULL );