自定义标题(包括多行标题)





5.00/5 (9投票s)
简单的自定义窗口标题,包括多行标题
概述
本文介绍了一些类,可以非常快速轻松地自定义窗口标题。
使用这些类,您可以独立更改您选择的任何窗口的活动和非活动窗口标题的背景颜色以及文本字体和颜色。我还提供了一个示例类,允许使用位图作为标题背景,例如用于徽标或木纹或石纹效果。
更不寻常的是,您可以让子窗口标题自动换行到多行,以适应特别长的标题。此标题自动调整大小功能还允许在选定的窗口上使用特大字体和位图作为横幅标题。
背景
几年前,我正在编写一个 VC++/MFC MDI 数据库查询应用程序,该应用程序将查询结果显示为 MDI 子窗口中的数据表或列表。
出现了一个问题,即根据特定窗口的查询显示标题,例如“生产力排行榜:英国媒体公司,净营业额 > 25,000,000 英镑且员工人数 > 3500”。一些标题甚至比这更长,并且在显示为窗口标题时经常被截断。当用户平铺许多这些窗口时,情况会变得更糟,因为它们最终会显示五个或六个窗口,标题为“生产力排行榜:英国……”和“公司新闻头条:金融……”,等等。当他们的标题似乎都说一样的东西时,找到任何感兴趣的特定窗口显然是一件令人头痛的事!
对此类问题有几种解决方案,例如工具提示或仅依赖客户端区域的标题,但似乎都有令人烦恼的缺点。我忍不住觉得标题确实是显示此类长标题的正确位置,这样您一眼就能了解窗口的内容。我尝试使用 1997 年 Microsoft Systems Journal C++ 问答文章中由 Paul DiLascia 描述的拥有者绘制标题,该文章介绍了如何绘制渐变色标题背景。结果比我预期的要好,所以我认为我会将它们重塑成任何人都可以使用的东西。
结果就是这个小型的类套件。
类
CCaption
:抽象主
类,它会将自身安装到框架窗口中,并使用CCaptionBackground
和CCaptionTextAttributes
(见下文)管理标题的绘制。默认情况下,它绘制一个标准的窗口标题。CCaptionBackground
:由CCaption
使用。绘制标题的活动和非活动背景。默认情况下,它使用系统标题颜色。CCaptionTextAttributes
:由CCaption
使用。提供活动和非活动标题的文本字体和颜色。默认情况下,它使用系统标题字体和颜色。CSingleLineCaption
:派生自CCaption
,它为对话框和其他非 MDI 子窗口(例如带菜单的框架)提供标准高度的自定义标题。CMultiLineCaption
:派生自CCaption
,它根据标题的长度和字体大小将标题换行到其他行。仅适用于没有菜单的窗口(例如 MDI 子窗口),因为我还没有找到一种方法来修改菜单的默认位置……CMultiLineCaptionEx
:派生自CMultiLineCaption
并进行了扩展,以修复 Windows 95 和 WinNT 的一个奇怪的“功能”,即在系统菜单显示后,当鼠标活动发生在非客户区时,它会秘密地绘制一个标准标题。这会破坏多行标题的整洁外观,但不会影响 Windows 2000。CGradientCaptionBackground
:由CCaption
使用。派生自CCaptionBackground
,将活动背景绘制为渐变色(渐变到黑色)。CBmpCaptionBackground:
由CCaption
使用。将位图绘制为活动背景。CaptionDemo
项目中的一个示例类,展示了派生自己的自定义背景绘制器有多么容易。
[还使用了各种辅助类,特别是 Paul DiLascia 的 CSubclassWnd
,但它们不是 public
接口的一部分]。
如何使用
将标题对象(CSingleLineCaption
、CMultiLineCaption
或 CMultiLineCaptionEx
)声明为框架窗口类的成员。
#include "..\CustomCaption\MultiLineCaptionEx.h"
class CChildFrame : public CMDIChildWnd
{
...
private:
////////////
// Declare a caption object (this one is an extended multi-line caption)
//
CMultiLineCaptionEx m_Caption;
...
};
在框架窗口类的 OnCreate()
方法中安装标题(您可能需要使用 ClassWizard
插入此函数。
注意:选择“WM_CREATE
”消息,而不是“Create
”消息)
int CChildFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
///////
// Install caption into frame
//
m_Caption.Install(this);
return 0;
}
就是这样!如果您按上述方式安装了多行标题,那么对于太长而无法单行显示的标题,它们将自动换行到新行。您可以使用 SetMaxLines()
方法更改标题允许的最大行数。
现在您可以使用标题对象来设置标题的颜色和字体。为此,请使用 CCaption
方法访问 CCaptionBackground
和 CCaptionTextAttributes
对象,并修改其内容,例如:
/////////////////
// Set active text and background colours
//
COLORREF colorText = RGB(txt_red, txt_green, txt_blue);
COLORREF colorBk = RGB(bk_red, bk_green, bk_blue);
m_caption.GetTextAttributes()->SetActiveColor(colorTxt);
m_caption.GetBackground()->SetActiveColor(colorBk);
/////////////////////
// Get active font and change it to Arial italic
//
LOGFONT lf;
m_caption.GetTextAttributes()->GetActiveFont()->GetLogFont(&lf);
lf.lfFaceName = "Arial";
lf.lfItalic = TRUE;
m_caption.GetTextAttributes()->SetActiveFont(lf);
/////////////////
// Refresh caption so changes take immediate effect
//
m_Caption.Refresh();
要更改为不同的背景样式,或一次性替换所有文本属性,您可以创建一个新的 CCaptionBackground
或 CCaptionTextAttributes
对象,根据需要进行初始化,然后使用 CCaption
的 SetBackground()
或 SetTextAttributes()
方法将其设置到标题中。
//////////
// Construct a gradient background object
//
CCaptionBackground* pNewBackground = new CGradientCaptionBackground();
//////////
// Set the colours required
//
pNewBackground->SetCustomColors(ACTIVE_COLOR, INACTIVE_COLOR);
////////////
// Set the new background
//
m_Caption.SetBackground(pNewBackground);
请勿担心删除背景或文本属性对象,标题会为您处理。
有关演示如何操作各种自定义标题的完整工作代码,请参阅 Caption Demo
源代码,特别是mainfrm.cpp。我已经尽力记录了所有源代码,所以应该不难理解。
杂项
如果有人能阐明 WinNT/Win95 在显示系统菜单后发生的奇怪的秘密标题绘制“功能”,我将非常感兴趣(尝试安装 CMultiLineCaption
,设置一个较长的窗口标题,使其换行到多行,然后单击窗口图标显示系统菜单,您就会明白我的意思了。每当鼠标穿过非客户区或在标题中单击时,都会重新绘制正常的窗口标题,而不会发送任何 NC_PAINT
消息)。为什么?
关于在标题中显示位图的一个技巧——如果您想让短标题出现在较大位图的顶部,请在标题后面添加一长串空格,以使其换行到多行。
下载次数
这包含演示应用程序可执行文件CaptionDemo.exe 和自定义标题 DLLCustomCaption.dll。
演示项目实际上是一个 VC++6.0 工作区,包含两个项目:Caption Demo 应用程序和 Custom Caption DLL 项目。它们安装在单独的文件夹中,因此应使用路径信息进行解压缩。
这仅包含 Custom Caption 类的源代码。
雇主免责声明
我必须为我的雇主包含以下免责声明:
以上观点仅代表作者本人观点,不代表 Financial Times Information Limited 的观点。