软件界面与Windows主题同步改变的实用方法

来源:互联网 发布:找不到网络扫描仪 编辑:程序博客网 时间:2024/04/29 15:25

随着软件行业的发展和客户要求的不断提高,一个软件的受欢迎程度不仅与功能和性能等内在因素有关系,而且界面包装等外观设计也日益重要。本问题以Borland C++ Builder 6(以下简称BCB6)编译的程序在Windows XP下的应用为例,专门就软件外观设计中的一个问题展开以下探讨。

对于使用旧版本Windows软件开发工具的程序员来说,有一个问题是比较容易引起困扰的:开发出来的软件界面如何才能与不同的Windows主题保持一致,并且能够随之自动同步更换界面样式。例如,BCB6开发出来的程序不管使用在什么主题的Windows下,除了窗口样式会符合主题外,其他控件诸如按钮、单选按钮等始终都是“经典Windows”的样式。

要让软件外观随Windows主题变化,最彻底也是最简便的方法当然是将工程文件用C++ Builder 2007或C++ Builder 2009升级并重新编译——注意在Project->Option->Application中要勾选Enable runtime theme。虽然现在新版本C++ Build开发出来的软件可以解决问题,但由于使用习惯以及控件等方面的缘故,目前仍然有很多程序员在使用BCB6。如何让BCB6开发的程序焕发生机呢?可以使用以下方法达到目的:

直接在软件发布时包含一个与可执行文件同名,后缀为.manifest的文件(以下称为界面配置文件)。例如需要发布的可执行文件为Test.exe,则只要在同一级目录下包含一个Test.exe.manifest文件即可。这个从Windows XP开始,由系统自带的界而配置文件虽然大小仅数百字节,但能耐却不小。当运行该同名的可执行文件时,Windows就可以自动将程序中的控件全部转换成主题样式。这个界面配置文件可以在WindwosXP的系统目录(如windows、system32)下找到很多,只需要复制任意一个,并更改文件名即可。

在界面配置文件的使用过程中,即可以发现系统对该文件的文件名称大小写不敏感,如上例中的文件名改为TEST.EXE.MANIFEST亦不会影响效果,但是如果该文件的名称与可执行文件不同名,则程序界面的样式就不会得到改变。此外,一个可执行文件必须要对应一个同名界面配置文件。可见软件是否能够随Windows主题起舞全依赖这个小小的文件。
既然软件变身全靠这个界面配置文件,用“记事本”打开Windows目录下的WindowsShell.Manifest,可以看到以下内容:

01.< ?xml version="1.0"encoding="UTF-8"standalone="yes"? >
02.< assembly xmlns="urn:schemas-microsoft-com:asm.v1"manifestVersion="l.0" >
03.< dependency >
04.< dependentAssembly >
05.< assemblyIdentity
06.Type="win32"
07.Name="Microsoft.Windows.Common-Controls"
08.version="6.0.0.0"
09.processorArchitecture="X86"
10.publicKeyToken="6595b64144ccfldf"
11.language="*"
12./ >
13.< /dependentAssembly >
14.< /dependency >
15.< /assembly >

显然,这是一个XML格式的配置文件。事实证明,这还是一个代码最简单的通用界面配置文件。有的界面配置文件因为内部增加了一些代码而使之成为某个文件的专用配置文件。因此请注意,并不是所有.manifest文件都可以让可执行文件的界面发生改变!通常仅包含以上代码的界面配置文件即可使程序界面随Windows主题改变。如果用户对界面配置文件的工作原理和代码定义没有深入了解,请不要擅自更改以上代码。

由于界面配置文件对名称有严格要求,因此如果被用户不小心更改了名称,就会完全失去作用。为了既能保证可执行文件与Windows主题保持一致,又能提高可靠性,可以让软件在运行之初就生成一个与可执行文件同名的界面配置文件,这样可靠性就能大大提高了。

按照这样的编程思路,可以在主窗口的OnCreate事件中,加入文件操作代码,很容易就能生成一个具有最简代码的界面配置文件。

但是首次运行改进后的软件时,会发现尽管界面配置文件可以生成,但是软件界面仍然是经典样式。只有当再次启动程序后,软件界面才发生更改。可见界面配置文件要能够起作用,就必须在窗体和控件创建之前就准备就绪。因此,为了让程序界面“第一次”展现在用户眼前时就已经符合Windows主题,还必须在创建完界面配置文件后让程序自动重启一遍!

程序要自动重启,方法有很多,以下例程中的方法仅是其中一种。需要在工程的.cpp文件,主窗口的.cpp,.h文件中添加代码。
以下给出实现软件界面符合Windows主题的例程代码。其中:工程名为Project1,对应的代码文件为Projecf1.cpp。程序由一个窗口(Form1)组成,对应的代码文件和头文件分别为Unit1.cpp、Unit.h。窗口上有一个按钮(Button1),主要用于观察界面是否符合Windows主题,不需要添加其他事件处理代码。

在Project1.cpp中作如下处理:

01.#include< vc1.h >
02.#include"Unit1.h"∥要包含Unit1.h文件
03.#pragma hdrstop ... WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
04.{ ... if(g_bIsRunAgain)//g_bIsRunAgain是用于判断是否重启的bool型变量,在Unit1.h中声明
05.{
06.AnsiString strPath;
07.STARTUPINFO StartInfo;
08.PROCESS_INFORMATION procStruct;
09.memset(&StartInfo, 0, sizeof(STARTUPINFO));
10.StartInfo.cb= sizeof(STARTUPINFO);
11.strPath = Application->ExeName;
12.if(!::CreateProcess((LPCTSTR)strPath.c_str(), NULL, NULL, NULL,
13.FALSE, NORMAF_PRIORITY_CLASS, NULL, NULL, &StartInfo, &procStruct))
14.return 0;
15.}
16.return 0;
17.}

在Unit1.h中作如下处理:

1.... Extern bool g_bIsRunAgain;    //声明用于重启判断的变量g_bIsfRunAgain
2.extern PACKAGE TForm1* Form1; ...

在Unit.cpp中作如下处理:

01.... #pragma package(smart_init)
02.#pragma resource "*.dfm"
03.TForm1* Form1;
04.Boo1 g_bIsRunAgain = false; ... void__fastcall TForm1::FormCreate(TObject* Sender)
05.{
06.String manifest=Application->ExeName+".manifest";
07.//文件名与可执行文件一致
08.if (!FileExists(manifest))
09.∥如果界面配置文件不存在,就创建它并重启程序
10.{
11.int handle=FileCreate(manifest);     ∥创建文件
12.∥======以下生成配置文件的内容======//
13.String a ="< ?xml verslon = \"1.0\" encoding=\"UTF一8\"
14.standalone=\"yes\"? >
15.< assembly xmlns = \"urn:schemas-microsoft-com:asm.v1\"
16.manjfestVersion = \"1.0\" >";
17.a = a + "< dependency >< dependentAssembjy >
18.< assemblyIdentity type = \"win32\"
19.Name = \"Microsoft.Windows.Common-Controls\"
20.Version = \"6.0.0.0\"";
21.a = a + "processorArchitecture = \"X86\"
22.publicKeyToken = \"6595b64144ccfldf\"language = \"*\"/ >";
23.a = a + "< /dependentAssembly >< /dependency >< /assembIv >";
24.FileWrite(handle, a.c_str(), a.Length());
25.∥将配置文件的代码写入文件
26.FileClose(handle);    //关闭文件
27.g_bIsRunAgain =true;  ∥重启标志置位,进行重启
28.Application->Terminate();
29.}
30.} ...

经过上述处理过后,当软件第一次在用用户电脑中运行或者程序所在目录不存在界面配置文件时,首先会生成一个Project1.exe.manifest文件(可执行文件为Project1.exe),然后窗口会出现瞬间闪现(实现了自我关闭并重启)并且以符合Windows主题的界面展现在用户的电腩屏幕上。当用户更改Windows主题时,软件界面也同步发生更改。
可见,要想使旧版本的开发工具创建的程序外观与windows主题保持一致并能随之改变,是通过后缀为.manifest的界面配置文件实现的。为了保证可靠性,可以让软件在检测到没有界面配置文件时创建一个该文件并自动重启,从而使用户无论何时运行软件都能看到一个与Windows主题协调一致并能随之同步改变的软件界面。

原创粉丝点击