{A}
简介
我描述主题的所有者和全定制Vista的风格推/菜单/图像按钮。本文介绍了一套Vista风格的任务按钮 - 或命令链接按钮 - 加上一个任务对话框基类。在Vista中,任务按钮提供了衰落的过渡和细微的发光效果。
任务按钮有一些区别正常的图像按钮。首先,未选中时,他们出现平坦,无明显边界。二,如下图所示,第一行是取材特大型真正站出来。最后,任务按钮所使用的边界,不同的热/默认/正常显著。
这些任务按钮类是与Windows 98中,2000,XP和Vista兼容。他们实施的C / MFC控件。来自标准按钮主题的视觉效果,因此可以利用在XP的主题方面。
{S0}背景
Vista中引入的任务对话框的概念,一个普通的老的MessageBox的改进版本。有是很大的灵活性,范围从基本TaskDialog功能到高级的实现,使用TaskDialogIndirect。这是描述。
就个人而言,一旦事情开始需要回调,我将分流到自己的类代码。一旦出现这种情况,就成了胜负难料:一个包装或自定义对话框的新类的新类。一个自定义对话框提供了更好的布局控制,如果你不喜欢TaskDialogIndirect结果,它避免了向后兼容性问题。有些元素是自定义任务对话框,但如双音背景,大字体和任务按钮本身,更难。但现在不是了!
其他人正在为旧操作系统的TaskDialogIndirect复制品。不过,我反对这种做法,因为矫枉过正。对于许多应用程序,你没有理由增加几百KB。我想小体积的方法。首先,我从我的CButtonVE_Image类派生一个任务按钮。第二,我用了一个任务对话框基类。第三,我带来了一些CStatic派生类包扎的东西,即文本和图标。
在我的第一篇文章中,我用VC6保持与Win98的向后兼容性。总得爱的虚拟机。它还编译VS7/2003或VS8/2005罚款。只要打开社会福利署署长项目文件。 VS8用户必须事先RT_MANIFEST的资源类别中删除条目。大卫赵是用来避免Win98/2k DLL的问题。你需要一个平台SDK与XP主题的头文件。 Visual Studio中VS8/2005 Express与在Windows Server 2003 R2平台SDK(一种常见的配置)的用户还可以在编译这篇文章中,经过一些调整。在演示中打开VS2005_Express_MFC_Stubs.zip细节。Vista的按钮转换
和我以前的按钮类一样,在Vista中这些自定义的任务按钮提供了各国之间的平稳过渡。主题API支持五国为按钮:残疾人,正常,热,拖欠和推。 Vista中执行不同的速度在这些国家之间的转换:一些快速和一些慢。在状态的变化,一个计时器tickcount初始化。这是用来计算合并随着时间的推移,旧的和新的国家图像alpha混合因子。对于一个更完整的说明与示例代码,请参阅。基本任务对话框
Vista提供两个任务对话框的主要口味。基本版本具有讽刺意味的不使用而更复杂的版本可以的任务按钮或命令链接。常见的方面是双音背景,图片和大标题字体。下面是一个基本的任务对话框:
CTaskDialogVE支持这些本身,没有任何额外的代码。类支持一个阴影透明图像(位图或图标),大标题文字,内容文字和一个或多个标准按钮。是动态创建的基本任务对话框;没有对话框资源是必需的。他们调整大小要容纳数额不等的文字。上面的例子是创建这个片段:CTaskDialogVE dlg(
NULL/*parent*/, AfxGetApp()->m_hInstance,
_T("ButtonVE CTaskDialogVE Demo"),
_T("Your viewing the default behavior for CTaskDialogVE"),
_T("Most features of the Vista 'TaskDialog' function are "\
"available. You can also derive from CTaskDialogVE to "\
"customize dialogs.\n\n"\
"Would you like to see a customized dialog with task "\
"buttons?"), TDCBF_YES_BUTTON|TDCBF_NO_BUTTON,
MAKEINTRESOURCE(IDB_BITMAP1));
DWORD result = dlg.DoModal();
从MessageBox API升级CTaskDialogVE基本对话框真的用不了多少在所有。我将介绍更简单的方法后,虽然。自定义任务对话框
进行更详细的CTaskDialogVE对话框资源模板是必需的。你现在在总量控制的布局。下面是用于创建演示:
{S2}
上述"取消"按钮的分隔行是重要的。您必须指定一个资源ID,然后通过调用SetHorzLine配置CTaskDialogVE。分离器控制双音效果越画,并提供了一个参考点。这样,一个WM_CTLCOLOR处理程序知道控制得到哪些背景颜色。双音提供的分隔位置的指导下一个WM_PAINT处理程序:
控件的背景颜色是由WM_CTLCOLOR处理程序管理,再通过分离器的指导:CStatic *horz = (CStatic*)GetDlgItem(m_horz_nID);
if (horz)
{
CRect rw,horz_rw;
pWnd->GetWindowRect(&rw);
horz->GetWindowRect(&horz_rw);
if (rw.top < horz_rw.top)
{
// Set text background mode so bgbrush color visible...
span>
pDC->SetBkMode(TRANSPARENT);
hbr = m_bgbrush;
}
}
变量m_bgcolor和m_bgbrush保持一个WM_SYSCOLORCHANGE处理。现在的双音对话框要简单得多。间接对话框模板
对于那些有兴趣,这里有一个短分流到间接的对话框模板。基本CTaskDialogVE任务对话框需要像所有对话框的布局模板。动态模板。他们开始用结构用于对话框控件的几大块组成。几个包装简化的东西:AllocTemplateSpace - 添加一大块空间连续的对话框模板。AddTemplateWord - 添加一个16位字。AddTemplateString - 添加一个Unicode字符串。AddTemplateItem - 添加一个对话框控制。
要创建一个基本任务对话框模板,首先要添加标题:DLGTEMPLATE *pDT = (DLGTEMPLATE*)AllocTemplateSpace(sizeof(DLGTEMPLATE));
pDT->style = WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME |
DS_SETFONT;
pDT->dwExtendedStyle = WS_EX_DLGMODALFRAME;
pDT->cdit = 0; // inc'd by AddTemplateItem
pDT->x = 0;
pDT->y = 0;
pDT->cx = TASKVE_DLGWIDTH;
pDT->cy = TASKVE_DLGHEIGHT;
AddTemplateWord(0); // menu (none)
AddTemplateWord(0); // class (default)
AddTemplateString(pszWindowTitle); // title
AddTemplateWord(8); // font point size
AddTemplateString("MS Sans Serif"); // font name
指定的窗口样式,位置,大小,菜单,注册窗口类,标题和字体。接下来是标准按钮:for (i=0; btnlist[i].mask>0; i++)
if (dwCommonButtons & btnlist[i].mask)
{
AddTemplateItem(
TASKVE_ATOM_BUTTON,
BS_PUSHBUTTON|WS_TABSTOP|WS_VISIBLE, 0,
xofs, yofs, TASKVE_BTNWIDTH, TASKVE_BTNHEIGHT,
btnlist[i].nID);
xofs += (TASKVE_BTNWIDTH+TASKVE_BTNSPACEX);
AddTemplateString(btnlist[i].label); // item title
AddTemplateWord(0);
}
btnlist数组包含配置口罩,按钮文字标签和资源ID。 xofs坐标更新为每个按钮添加。在其中控制添加的顺序对应的Tab键顺序。下一步,横向分隔线,图标,标题和内容文本。这里省略的步骤,因为它得到重复。最后,CDialog的的InitModalIndirect是我们的自定义模板:InitModalIndirect((LPCDLGTEMPLATE)m_dlgtemplate, pParentWnd);
开始DoModel和你有一个对话框!几乎无痛,是吗?使用代码
评估Vista的影响任务按钮,更换或子类与所有者绘制CButtonVE_Task的任何按钮的CButton的实例。只需添加到您的项目的源文件,添加一个图像和你业务。提供以下类:CButtonVE_Task - 所有者绘制任务按钮。在大多数情况下最佳。CButtonVE2_Task - 全定制的任务按钮。注入到其它窗口的好。CTaskDialogVE - 任务"对话框基地(基本或自定义)。CStaticTextVE - CStatic派生类用于绘制大字体。CStaticImageVE - CStatic派生类,透明度和阴影绘制位图/图标。
从CButtonVE_Image任务按钮派生类提供了以下功能:SetOwner - 指定窗口来接收单击按钮和菜单按钮命令。默认父。SetContentHorz - 指定水平对齐按钮图像/文本内容。也可以使用ModifyStyle。SetContentVert - 指定按钮图像/文本内容的垂直对齐。也可以使用ModifyStyle。SetContentMargin - 指定按钮的边框和内容之间的间距。SetBackgroundColor - 指定背景颜色。SetImagePosition - 指定的相对位置(左,右,上方或下方的文字)文本图像。SetImageSpacing - 指定图像和文字之间的间距。SetImageShadow - 控制阴影下的图像显示。SetTransparentColor - 指定位图的背景颜色。默认为左上角像素。SetHotImage - 指定位图或图标来显示按钮时,热。SetDisabledImage - 指定一个位图或图标时显示该按钮被禁用。默认情况下,一个源图像的阴影版本产生。SetBigFontScale - 控制大文本的大小。默认值是1.6倍的正常。
CStaticTextVE类规定:SetFontScale - 指定文字的大小。默认值是1个正常。SetFontColor - 指定的前景色。覆盖默认。SetBackgroundColor - 指定背景颜色。覆盖默认。
CStaticImageVE类规定:SetTransparentColor - 指定透明的颜色。默认是左上角像素。SetBackgroundColor - 指定背景颜色。覆盖默认。SetImageShadow - 控制,如果高斯模糊阴影下显示图像添加所有者绘制按钮
在对话框编辑器中添加一个标准的按钮,设置"所有者绘制"和"多行"的风格。如果你想多行文本,多行的风格是需要,即一个大,一个小。添加控制类型的成员变量,子类,并与CButtonVE_Task取代的CButton的头实例。
{S3}
添加完整的自定义按钮
有两种方法添加自定义按钮。第一种方法是标准按钮路径如上,但没有"所有者绘制"风格。
{S4}的
第二种方法是添加一个自定义控件在对话框编辑器,并在属性CButtonVE2_Task类名。在您的WM_INITDIALOG处理程序,你需要配置字体和窗口文本使用此方法为全定制控制。
{五}使用的基本任务对话框
的基本任务"对话框相似之处Vista的TaskDialog函数。 Unicode的参数字符串,但不要求。所有字符串作为参数的支持MAKEINTRESOURCE,使他们可以有选择地资源为基础。是用来找到资源,即如果储存在一个DLL的hInstance参数。 NULL意味着在EXE资源只能看。如果窗口的标题是空的,该程序的名称来代替。CTaskDialogVE(
CWnd *pParentWnd,
HINSTANCE hInstance,
LPCTSTR pszWindowTitle,
LPCTSTR pszMainInstruction,
LPCTSTR pszContent,
DWORD dwCommonButtons=TDCBF_OK_BUTTON,
LPCTSTR pszImage=NULL)
dwCommonButtons可以任意组合:
TDCBF_OK_BUTTONTDCBF_YES_BUTTONTDCBF_NO_BUTTONTDCBF_CANCEL_BUTTONTDCBF_RETRY_BUTTONTDCBF_CLOSE_BUTTON
可选图像的参数是MAKEINTRESOURCE一个位图或图标。也可使用下列标准的图示:TD_WARNING_ICONTD_ERROR_ICONTD_INFORMATION_ICONTD_QUESTION_ICON来自CTaskDialogVE自定义对话框
创建一个新的CDialog类,改变基类CTaskDialogVE。添加WM_INITDIALOG处理程序配置的东西。该演示使用这个:// Tell CTaskDialogVE about seperator...
SetHorzLine(IDC_STATIC1);
// Setup big font for headline...
m_info.SetFontScale(1.6);
m_info2.SetFontScale(1.2);
// Setup owner-drawn task button...
HBITMAP hTask = (HBITMAP)(LoadImage(
AfxGetApp()->m_hInstance,
MAKEINTRESOURCE(IDB_TASK),
IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR));
HBITMAP hTaskHot = (HBITMAP)(LoadImage(
AfxGetApp()->m_hInstance,
MAKEINTRESOURCE(IDB_TASK_HOT),
IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR));
m_buttonvet.ModifyStyle(0,BS_BITMAP);
m_buttonvet.SetImage(hTask);
m_buttonvet.SetHotImage(hTaskHot);
// Setup custom-drawn task button...
m_buttonvet2.ModifyStyle(0,BS_BITMAP);
m_buttonvet2.SetImage(hTask);
m_buttonvet2.SetHotImage(hTaskHot);
首先,分隔与SetHorzLine配置,使双色调的背景。接下来,我们指定对话框的标题文本的字体大小。所示的尺度近似Vista的,也看Win98/2k/XP良好。最后,正常和热图像添加两个按钮。所有控件子类,使设置更容易。剩下的就是给你。添加事件处理程序以响应按钮。演示有一个复选框,因此它也有增加了一个处理。其他物品
正如您所见,使用基本对话框CTaskDialogVE很简单。然而,如果你一个合适的MessageBox实例,升级它CTaskDialogVE是很容易的。只追加"VE:"MessageBoxVE(
_T("The game is over. Would you like to play again?"),
_T("ButtonVE_Task_demo"),
MB_YESNO|MB_ICONQUESTION);
全球功能MessageBoxVE自动执行简单的转换。转换nType领域,即MB_ *参数,到图标和按钮请求。它解析的文本字段中,进入到任务对话框内容的标题和平衡的第一句话。
{中六}
注意,你的文本的措词使得在任务对话框遇到的一个很大的区别。上述简单的例子,工程罚款。对方的提示,可能需要改写。享受!版权与许可
这篇文章是版权??2007年由Ian发送戴维斯。本文附带的演示代码和源代码,现予发布到公共领域。历史5月7日,2007年 - 首次发行。2007年5月24日 - 与MessageBoxVE固定分析问题时,给出了单句的文本。 CTaskDialogVE字符串查询按钮的文本替代的资源,即字符串资源ID为1取代"确定"更容易本地化的标签。 TD_ *图标固定的定义,以兼容Vista平台SDK。2007年7月17日 - 一些细微的变化。固定内存分配问题ButtonVE_Helper错误的情况下,在升级AlphaBlt代码动态链接AlphaBlend API。感谢bmallabon和blindd0t!代码现在可以运行在Win95和NT4.0的。也改变箭头位图到24位,因为16位的图像没有显示NT4.0正确。