根据windows版本改变控件的视觉风格

发布于 2024-10-11 13:39:29 字数 733 浏览 1 评论 0原文

我希望 vista/win7 使用 Aero 风格的窗口,而 XP 用户使用普通的窗口风格(如何获得 Windows XP stlye 而不是 win95 风格顺便说一句?)

这个想法是这样的:

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='*' "\
               "\"")
}

现在,#pragma 被执行无论 if 语句是真还是假,我想这就是 #pragma 的工作方式。当然还有其他方法可以让它发挥作用(比如#ifndef #define ... #endif 我猜)

干杯

I'm looking to have vista/win7 use Aero-style windows while XP users use normal window style (how does one get windows XP stlye and not win95 styles btw?)

The idea is something like this:

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='*' "\
               "\"")
}

Now, the #pragma gets executed no matter if the if-statement is true or false, which I guess is just the way #pragma works. Surely there is some other way to get this to working (something like #ifndef #define ... #endif I guess)

Cheers

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

岁月静好 2024-10-18 13:39:29

您将编译时编译时求值与代码运行时执行混合在一起。显然这行不通。

可以在“PutYourProgramNameHere.exe.manifest”文件中保留应用程序的清单。因此,如果您需要 XP 和 Vista/Win7 的不同清单,那么您可以在目标计算机上安装应用程序时安装不同的清单文件。即您的安装程序检查操作系统版本并安装匹配的清单。

You are mixing compile-time evaluation of pragma with run-time execution of code. Obviously this won't work.

It's possible to keep a manifest for the application in "PutYourProgramNameHere.exe.manifest" file. So if you need different manifests for XP and Vista/Win7, then you can install different manifest files when you install the application on the target computer. I.e. your installer checks OS version and installs matching manifest.

你另情深 2024-10-18 13:39:29

您可以使用激活上下文 API 函数来执行此操作。要求是:

  • 使用LoadLibrary & GetProcAddress 实际加载有问题的 API 函数,因为它们在 NT 5.1 之前不存在
  • 要么嵌入包含 comctl 6 依赖项的清单作为资源,且资源 ID > > 16,或者将其作为磁盘上的文件。

此示例代码假设清单作为 RT_MANIFEST 资源嵌入,ID 为 17。TestOSVersion() 是您决定是否需要皮肤窗口的函数。

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 公共控件不能位于进程默认清单中。

You can use the Activation Context API functions to do this. The requirements are:

  • Use LoadLibrary & GetProcAddress to actually load the API functions in question as they don't exist prior to NT 5.1
  • Either embed a manifest containing the comctl 6 dependency as a resource with a resource id > 16, or have it as a file on disk.

This sample code assumes that the manifest is embedded as a RT_MANIFEST resource, with an id of 17. TestOSVersion() is your function to decide wether or not you want a skinned window.

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);

Obviously, in order for this to work, the v6 common control cannot be in the processes default manifest.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文