C++ 基于windows版本更改控件的视觉样式
我希望vista/win7使用Aero风格的windows,而XP用户使用普通的窗口风格(顺便说一句,如何获得windows XP stlye而不是win95风格?) 这个想法是这样的:C++ 基于windows版本更改控件的视觉样式,c++,windows,winapi,controls,coding-style,C++,Windows,Winapi,Controls,Coding Style,我希望vista/win7使用Aero风格的windows,而XP用户使用普通的窗口风格(顺便说一句,如何获得windows XP stlye而不是win95风格?) 这个想法是这样的: OSVERSIONINFOEX osvi; osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); GetVersionEx((OSVERSIONINFO*)&osvi); if (osvi.dwMajorVersion > 5) {
OSVERSIONINFOEX osvi;
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionEx((OSVERSIONINFO*)&osvi);
if (osvi.dwMajorVersion > 5) {
#pragma comment(linker,"/manifestdependency:\"type='win32' "\
"name='Microsoft.Windows.Common-Controls' "\
"version='6.0.0.0' "\
"processorArchitecture='x86' "\
"publicKeyToken='6595b64144ccf1df' "\
"language='*' "\
"\"")
}
现在,无论if语句是真是假,#pragma都会被执行,我想这就是#pragma的工作方式。当然,还有其他方法可以让它发挥作用(我猜是类似于“ifndef”#define…#endif)
干杯您正在混合编译时对pragma的评估和代码的运行时执行。显然这行不通
可以将应用程序的清单保存在“PutYourProgramNameHere.exe.manifest”文件中。因此,如果XP和Vista/Win7需要不同的清单,那么在目标计算机上安装应用程序时,可以安装不同的清单文件。即,您的安装程序检查操作系统版本并安装匹配的清单 您将编译时对pragma的评估与代码的运行时执行混合在一起。显然这行不通 可以将应用程序的清单保存在“PutYourProgramNameHere.exe.manifest”文件中。因此,如果XP和Vista/Win7需要不同的清单,那么在目标计算机上安装应用程序时,可以安装不同的清单文件。即,您的安装程序检查操作系统版本并安装匹配的清单 您可以使用这些函数来执行此操作。这些要求是:
- 使用
&LoadLibrary
实际加载有问题的API函数,因为它们在NT 5.1之前不存在GetProcAddress
- 要么将包含comctl 6依赖项的清单作为资源id>16的资源嵌入,要么将其作为磁盘上的文件李>
ACTCTX actx = {0};
actx.cbSize = sizeof(ACTCTX);
actx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_HMODULE_VALID;
actx.lpResourceName = MAKEINTRESOURCE(17);
actx.hModule = GetModuleHandle(NULL); // assumes the manifest is exe embedded.
HANDLE hactx = INVALID_HANDLE_VALUE;
if(TestOsVersion())
hactx = CreateActCtx(&actx);
ULONG_PTR actxCookie = NULL;
if (hactx != INVALID_HANDLE_VALUE)
ActivateActCtx(hactx,&actxCookie);
// Now, with the activation context active, create the dialog box
// or window or whatever.
HWND hwndDialog = CreateDialogBoxParam(...);
// and pop the context. It doesn't matter if the dialog still exists, the
// ctl6 dll is now loaded and serving requests.
if (hactx != INVALID_HANDLE_VALUE)
DeactivateActCtx(0,actxCookie);
显然,为了使其正常工作,v6通用控件不能位于进程默认清单中。您可以使用函数来完成此操作。这些要求是:
- 使用
&LoadLibrary
实际加载有问题的API函数,因为它们在NT 5.1之前不存在GetProcAddress
- 要么将包含comctl 6依赖项的清单作为资源id>16的资源嵌入,要么将其作为磁盘上的文件李>
ACTCTX actx = {0};
actx.cbSize = sizeof(ACTCTX);
actx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_HMODULE_VALID;
actx.lpResourceName = MAKEINTRESOURCE(17);
actx.hModule = GetModuleHandle(NULL); // assumes the manifest is exe embedded.
HANDLE hactx = INVALID_HANDLE_VALUE;
if(TestOsVersion())
hactx = CreateActCtx(&actx);
ULONG_PTR actxCookie = NULL;
if (hactx != INVALID_HANDLE_VALUE)
ActivateActCtx(hactx,&actxCookie);
// Now, with the activation context active, create the dialog box
// or window or whatever.
HWND hwndDialog = CreateDialogBoxParam(...);
// and pop the context. It doesn't matter if the dialog still exists, the
// ctl6 dll is now loaded and serving requests.
if (hactx != INVALID_HANDLE_VALUE)
DeactivateActCtx(0,actxCookie);
显然,为了使其正常工作,v6通用控件不能位于进程默认清单中。您试图将编译时操作与运行时条件混合使用。另外,为什么要这样做?我希望它与xp以及win7/vista兼容,现在我明白了为什么我需要不同的可执行文件。欢迎您尝试将编译时操作与运行时条件混合。另外,为什么要这样做?我希望它与xp以及win7/vista兼容,现在我明白为什么需要不同的可执行文件了。干杯