VB6程序实现XP或者WIN7风格

这是一个老掉牙的问题了,现在写,一是因为我才接触这一类界面美化(以前一直以功能为主,需要漂亮界面也都是自己画的),二是发现网上的内容很多不准确,所以在这里整理一下。

1,Manifest方法,即通过Microsoft Windows Common Controls 的DLL文件Comctl32.dll(版本6)来加载具备XP风格的组件。这个dll和ocx的版本6不同。下面其它方法也都是以此为基础的。

  •       用文本编辑器编写一个App.exe.Manifest文件,放到App.exe同文件夹下,注意与App同名。
  • <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <assemblyIdentity
        name="XP style manifest"
        processorArchitecture="x86"
        version="1.0.0.0"
        type="win32"/>
    <dependency>
        <dependentAssembly>
            <assemblyIdentity
                type="win32"
                name="Microsoft.Windows.Common-Controls"
                version="6.0.0.0"
                processorArchitecture="x86"
                publicKeyToken="6595b64144ccf1df"
                language="*"
            />
        </dependentAssembly>
    </dependency>
    </assembly>

    ※ 风格代码需要在加载窗体之前运行,所以不要在Form_load中初始化,否则窗口无法加载

  • 在启动窗体代码中加入窗口初始化代码。

  • Private Declare Sub InitCommonControls Lib "comctl32.dll" ()
    
    Private Sub Form_Initialize()
    	InitCommonControls
    End Sub
  • 或者在模块中加入类似代码,并把启动过程设置为Sub Main(),上面的简单,下面的复杂,两个实测都可用。

  • 函数InitCommonControls是个空函数,不做任何事情,只改变入口点,会影响(大部分)通用控件。InitCommonControlsEx则可以指定要初始化的控件。

  • Private Declare Function InitCommonControlsEx Lib "comctl32.dll" _
        (iccex As tagInitCommonControlsEx) As Boolean
    
    Private Type tagInitCommonControlsEx
        lngSize As Long
        lngICC As Long
    End Type
    
    Private Const ICC_USEREX_CLASSES = &H200
    
    'VB实现XP风格的初始化函数
    
    Public Function InitCommonControlsVB() As Boolean
    On Error Resume Next
    Dim iccex As tagInitCommonControlsEx
    
        With iccex
            .lngSize = LenB(iccex)
            .lngICC = ICC_USEREX_CLASSES
        End With
        
        InitCommonControlsEx iccex
        InitCommonControlsVB = (Err.Number = 0)
    
        On Error GoTo 0
    
    End Function
    
    
    Sub Main()                  '需要设置以此为启动函数
    
        InitCommonControlsVB    '调用初始化函数
        Form1.Show
    
    End Sub

    编译后运行可以看到基础控件、Microsoft Windows Common Controls 5.0控件(6.0不行,下图右侧是6.0控件)都变成XP/Win7风格(我是在Win7下测试的,XP没看到)

原界面
IDE界面
修改后界面
修改后运行界面

2,资源(.RES)方法,即把上面的.manifest文件作为资源参与编译。要点:

  • 资源类型必须是24,标识号为1,自定义无法添加(类型会有""号),所以需要使用资源编译工具。
  • .manifest文件长度必须可被4整除(可以在文本末加空格凑数)。

在.manifest目录中,新建一个文本文件,内容为

1 24 App.exe.manifest

保存后将文件改名为xp.rc,然后在命令提示符下进入VB安装目录的Wizard目录(如C:\Program Files\Microsoft Visual Studio\VB98\Wizards),在提示符处输入下行命令:

rc /r 文件所在路径\xp.rc

这样,资源文件xp.res就编译好了,这个资源可以在任意工程中使用,不需要另外的处理

3,使用工具eXeScope。打开eXeScope,选择文件->打开,打开你的程序。再选择编辑->XP样式,在对话框中确定即可。

这里是自动保存的,所以需要的话请事先备份。

4,未证实的问题:

  • Form_Initialize不太保险,最好还是用Sub Main()
  • 即便是使用eXeScope,也需要对程序进行处理如下(按照方法二推论,实际是不需要这个处理的)
    API声明:
    Private Declare Function InitCommonControls Lib "Comctl32.dll" () As Long
    在每个窗体的初始化添加红色代码:
    Private Sub Form_Initialize() 
       InitCommonControls 
    End Sub
    在主窗口结束处添加代码,没有这些代码,程序结束后可能提示错误。
    Private Sub Form_Unload(Cancel As Integer) 
    On Error Resume Next
       End

    End Sub
--------------------------------------------------------
22-12-30 更新
不使用资源编译器的资源(.RES)方法:
有时候,我们除了winXP/Win7风格,还要使用资源文件,比如有多语言支持,资源图片等,这时,可以编辑资源文件如下:
1,将上面的App.exe.Manifest保存下来,注意文件大小为4的倍数。
2,打开资源编辑器,添加自定义资源文件,将.Manifest文件添加进来,此时资源类型为"101"
3,属性 ->资源类型修改为"1",保存。改为1个数字是为了Unicode的"1"是两个字节,与24对应。
4,使用16进制编辑器打开资源文件(.res),在"<?xml xxx "前面不远可以找到 "31 00 00 00 FF FF 01 00",改为"FF FF 18 00 FF FF 01 00",即把刚才的类型"1"改为类型24(不带引号)
5,在VB6中删除资源文件,再重新添加,可以看到资源类型已经变成24。
6,编译运行,测试界面是否已改为XP风格。
Manifest文件的作用,实际上是把Common controls的版本从5.8改成6.0,这样还带来一个额外的好处:
TextBox可以支持Control+A全选了。
另外,据说使用W版API就可以支持Unicode了,测试中。
另,win7风格不要随便使用Administration权限,否则每次打开文件都会问权限。
---------------------------------------------------------
23-03-15 更新
  • 把.exe.manifest配置好后,可以看到win7风格,把manifest改名后,win7风格没了。然后再改名回来,win7风格没恢复!
再次编译后,又回来了。
去掉Form_Initialize再编译,居然还有!
再改名,再运行,又没有了。
再编译,还是没有。
可能是win7没有刷新。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
  <asmv3:application>
    <asmv3:windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
    </asmv3:windowsSettings>
  </asmv3:application>
</assembly>
其中dpiAware适用于WinVista以上,dpiAwareness适用于Win10以上。
上面的XML代码可以适用于Both。
在windows的sdk下有合并或者嵌入Manifest文件的工具mt.exe。
也可以适用API SetProcessDPIAware
--------------------------------------------------------
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值