原作者:Alexander Bischofberger 翻译:Aweay
我并没有完全按照原文翻译,加了一些我的理解,如果大家不满意我这样的做法,请直接参考原文
简介
在WindowsXP里,你是否注意了类似于控制面板、我收藏的图片这样的特殊文件夹,他们有一个类似于上图的窗口用于显示用户最常用的操作,由于Windows帮助你思考了你可能想做什么,这就使得新手非常容易上手使用。我想这样的用户帮助也同样适用于我的程序,于是我就写了一个类来模拟这样的控件。
背景知识
其实具有这样行为的控件并不难写,我发现Windows使用很多不同的颜色(具体来说就是不同的蓝色),但是我并不知道在不依靠主题的情况下,如何得到这些颜色的定义。所以不管方法是否正确,目前我只是简单的得到了类似的颜色,希望在不久的将来能够支持主题。
这样的界面还有一个特点,就是如果你使用Spy++去查看窗口的信息,你会发现你只能得到是DirectUI类,而所有子窗体全部都不能得到,即便是那些一定是子窗体的东西,比如能相应键盘消息的编辑器等,他们看上去想直接画上去的。也许这就是它为什么叫DirectUI的原因吧。
关于代码
这个类目前已经支持主题风格,如果你想激活使用他们,仅需要在StdAfx.h中定义USE_THEMES宏,否则将使用我模拟的XP风格(译著,文章可能更新过,所以作者上面还说暂时不支持Xp主题,这里又说已经支持了,而且还有它模拟的风格)。
添加两个文件到你的工程中,并且确保在你的工程中有一个CMemDC类,或者直接使用例子中已经提供的代码。
在任何你喜欢的位置插入CWndDirectUI做为一个普通的控件。在开始编译之前,确保你有一个手型光标的资源文件叫做IDC_MYHAND。
缺省情况下,控件使用主题风格绘制(如上面的截图)。你可以任何时候手动改变绘制风格--使用CWndDirectUI::styleOffice, CWndDirectUI::styleXPclassic, CWndDirectUI::styleXP或者CWndDirectUI::styleThemed调用SetStyle()函数。使用GetStyle()函数得到当前的绘制风格。在使用Office风格的时候要注意,因为这类风格没有折叠、展开按钮,所以已经折叠的组不能在使用这样的风格时再展开。
对于手动的折叠、展开可是使用ExpandGroup(groupNr,expand)函数。
填充控件的最好方法是使用InitFromMenu(UINT id)函数,传递一个包含了2D菜单(不含有子菜单)的菜单id,这个函数将自动创建菜单条目到组里面(Group,就是一个DirectUI界面集合的意思)。如果你愿意,你可以插入一个工具条,这是使用SetToolbarImages(UINT uiToolBar)函数。请把所有的条目放在一个Toolbar里,因为同一个时刻,这个函数只能使用一个Toolbar。另外,滚动条会在空间不够时自动显示。
{
...
m_wndDirectUI.InitFromMenu(IDR_DIRECT1);
m_wndDirectUI.SetToolbarImages(IDR_MAINFRAME);
...
}
为了使用超过16色的图像,你需要调用SetToolbarImages(uiToolbar, uiAlternateImages, nFlagColor, clBackground, nWidth)函数,参数说明如下:
uiAlternateImages: 高彩的图像资源id
nFlagColor: See for more info. Default is ILC_COLOR8 for 256 color images
clBackground: Background color used for maps (default is purple)
nWidth: Button width (default is 16)
对于手动增加组(Group)和条目(Item),请参考类的定义和函数AddGroup,AddItemCommand等。所以这就像在使用List,当用户选择了List里的条目,你的程序就像处理普通的菜单命令一样来处理这些命令。如果你希望使用可停靠的窗体,已经有很多类实现了这些,你可以查找,我没有理由再发明一遍轮子。
使用静态文本和编辑控件
到目前为止,CWndUI又包含了两个新的条目:静态文本和编辑器控件。如果你想使用他们,你只能手动调用AddItemCommand函数。因此使用静态文本和编辑器控件的代码类似于:
{
...
int nGroup;
nGroup = m_wndDirectUI.AddGroup("Test group");
m_wndDirectUI.AddItem(nGroup, new CDirectUIItemStatic(
_T("This is\na multiline\ntest text")));
m_wndDirectUI.AddItem(nGroup, new CDirectUIItemEdit(
_T("Edit this!"), &m_wndDirectUI));
m_wndDirectUI.AddItemCommand(nGroup, "item 1", ID_NUMBER1);
...
}
这两个新的控件导致代码稍微有点改动,CDirectUIItemEdit使用了流行的CInPlaceEdit类,这个类是由Zafir Anjum编写的(我适当的修改了一些以便适应我的类),感谢他的代码。在上面的截图中,我并没有放入CDirectUIItemStatic和CDirectUIItemEdit,因为我不知道官方的绘制方法会是什么样子,我仅以我的想法去绘制了他们。如果你有任何详细信息,请告诉我。
需要改进的地方
如下的功能没有在第一版中实现:
键盘支持,只能使用鼠标来访问这些控件
焦点框,当按钮被按下的时候,没有焦点框,也不能响应任何焦点到达消息
这是我第一在代码中使用主题,如果可能请告诉我范的错误。
兼容性测试
代码使用WindowXp和VC6测试通过,他应该可以在Windows98以上的操作系统和VC5上通过,我没有做详细的测试,如果有什么问题请告诉我。非常抱歉的是,例子程序中的资源混合了英语和德语。
版权和荣誉
只要你将如下信息加入到你的程序文档中,则可以把代码使用在任何类型的应用中(免费、共享甚至商业软件):
Thanks a lot to Keith Rule for his CMemDC class!
Thanks to David Yuheng Zhao for his CVisualStylesXP class.
Thanks to all of you who found a bug (see discussions below), you are mentioned inside the code!
Thanks to Zafir Anjum for his CInPlaceEdit class I used!
Thanks to Mathieu Dubaele for his help with the edit item.
维护历史
July 27, 2004: Two new items added, lot of code changed
May 8, 2004: Now supports Themes as a new style
May 2, 2004: Support for hi-color icons, thanks to Dany Cantin for his code for hi-color toolbars
December 1, 2003: Bugfix (GDI resources), thanks to Michel Wassink and the others who helped me finding the bug.
March 1, 2003:
BugFix: When a group is collapsed you can still select an item (OnHittest)
BugFix: When scrolled the OnHittest returns wrong results
BugFix: Warning for IDC_HAND is fixed
Example: How to use in a dialog (select the menu item DIRECTUI_WINDOW, Show dialog for an example)
January 5, 2003: Scrolling, expand+collapse, new styles, minor changes. Class and files renamed for CJobWnd to CDirectUI
November 19, 2002: First version
关于作者Alexander Bischofberger
开始接触编程是在C64上,当时使用在“错误中不断尝试”的方法,很多年后,父母给我买了第一台PC(Atari PC4,AT 8 MHz),那是使用Turbo Pascal,后来又陆续开始使用Windows上的Turbo Pascal,VC1.52,到最后的VC6。
我又很多大型的软件开发经验,比如:
可以独立运行的磁盘拷贝系统,支持自动重启,磁盘加密...
政府部门的战略决策系统
MLM行销工具
维护着演示计划系统和其他电视软件
我所有的代码,心得和获得的帮助都来自于本站点(www.codeproject.com),再次感谢那些曾经帮助过我的人,没有他们我将什么也学不到,我会尽力共享我的代码(那些有价值的代码)以便帮助更多的人。
点击这里查看作者的个人信息。
关于翻译作者Aweay
经常原创、翻译一些技术文章自娱,虽然从事游戏的研发工作,但是对通用软件技术还是情有独衷,欢迎访问我的站点获得更多技术文章。
也可以通过电子邮件和我联系
siney@yeah.net