GCC编译器让调用Win32 API的C程序显示为系统风格的控件

GCC编译器让调用Win32 API的C程序显示为系统风格的控件问题描述我用C语言调用Win32API时发现,显示的窗口控件仍是Win98时代的按钮风格

问题描述

我用C语言调用Win32 API时发现,显示的窗口控件仍是 Win98 时代的按钮风格。用C语言调用Win32API
一开始我以为DLL调用都是这样的,我就用Python3调用了一下User32.dll下边的MessageBoxW函数结果却是系统样式的。看到这样的结果非常不解。
用Python调用Win32API
就决定去网上看看有什么办法可以解决,看到网上给出的最多的方法是添加一条#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

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注