问题描述
我用C语言调用Win32 API时发现,显示的窗口控件仍是 Win98 时代的按钮风格。
一开始我以为DLL调用都是这样的,我就用Python3调用了一下User32.dll下边的MessageBoxW函数结果却是系统样式的。看到这样的结果非常不解。
就决定去网上看看有什么办法可以解决,看到网上给出的最多的方法是添加一条#pragma
的预处理指令:
#ifdef _UNICODE
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
#endif
如果你是msvc编译器,复制粘贴上便的预处理指令到源码的开头应该就能解决问题了。
上面的方法对于GCC编译器并没有用,于是在群里问了大佬,大佬给了篇教程[1]根据这篇教程研究了一下终于解决了这个困扰很久的问题。
解决问题
0x01: 创建C源码文件–winstyle.c
#include <windows.h>
#include <commctrl.h>
INITCOMMONCONTROLSEX I;
int WINAPI WinMain(HINSTANCE hIns, HINSTANCE hPreIns, LPSTR lpCmdLine, int cmdshow)
{
I.dwICC = ICC_STANDARD_CLASSES | ICC_WIN95_CLASSES;
I.dwSize = sizeof (I);
InitCommonControlsEx(&I);
MessageBoxW(NULL, L"内容", L"标题", MB_ABORTRETRYIGNORE);
return 0;
}
0x02: 创建manifest文件–winstyle.exe.manifest
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="CompanyName.ProductName.YourApplication" type="win32" />
<description>Your application description here.</description>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" />
</dependentAssembly>
</dependency>
</assembly>
详细参数调节请参照 微软文档(启用视觉样式)。
0x03: 创建rc资源文件–winstyle.rc
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "winstyle.exe.manifest"
就这一条,最后的字符串指向你的manifest文件就行了。
0x04: 编译链接
rem # 编译`winstyle.c` 但不链接生成可链接的.o文件
gcc .\winstyle.c -c -o .\winstyle.o
rem # 编译资源文件`winstyle.rc` 生成可链接的.o文件
windres .\winstyle.rc -o .\winstyle.res
rem # 链接形成可执行文件
gcc .\winstyle.o .\winstyle.res -l ComCtl32 -o .\winstyle.exe
对于上边参数开关的一些解释:
- -c 只编译/汇编 不进行链接 可参考【GCC官方文档】中的
-c
段内容 - -o 用来指定输出文件位置和名称 可参考【GCC官方文档】中的
-o file
段内容 - -l 在链接时搜索传入的库名 可参考【GCC官方文档】中的
-l library
段内容这个参数同样支持无空格的方式输入库名如-lComCtl32
同样被允许
0x05: 运行编译出来的可执行程序–运行winstyle.exe
对于一些细节的解释:
为什么要使用
-l ComCtl32
参数在链接的时候搜索ComCtl32库呢?
– 因为运行时需要,微软在文档里写明:User32.dll 和 Comctl32.dll 提供对控件的支持。【文档链接】
ICC_STANDARD_CLASSES | ICC_WIN95_CLASSES
是什么?
– 这两个是定义在<commctrl.h>
里的宏,分别表示加载固有的User32控件类之一。用户控件包括按钮,编辑,静态,列表框,组合框和滚动条。和 加载动画控件,标题,热键,列表视图,进度栏,状态栏,选项卡,工具提示,工具栏,跟踪栏,树视图和上下控件类。【文档链接】
文章主要参考了:【文章链接】,感谢作者GMOD-AA775
今天的文章GCC编译器让调用Win32 API的C程序显示为系统风格的控件分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/67752.html