Win32的。在dll中启用视觉样式

时间:2014-08-12 14:43:09

标签: c++ winapi dll visual-styles activation-context-api

我没有C ++和Win API方面的经验,很抱歉,如果这个问题没有问题。我有DLL创建一些组件,例如MessageBox。我添加了pragma注释以启用视觉样式,但它不起作用(我不应该从这个答案中得知:windows 7 style for combobox on internet explorer toolbar, how?

Dll代码(省略导出等):

#include "stdafx.h"
#include "my-dll.h"
#include <Windows.h>
#pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*'    publicKeyToken='6595b64144ccf1df' language='*'\"")

MYDLL_API int fnmydll(void)
{
   MessageBox(NULL, L"Message", NULL, 0);
   return 42;
}

然后我从我的app中调用这个dll函数:

#include <iostream>
#include <Windows.h>
#include "my-dll.h"

int WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    fnmydll();
    return 0;
}

而且我的消息框却没有视觉风格。据我所知,我应该在调用我的dll时激活上下文,但MSDN没有示例如何做到这一点。你能不能给我这样的例子或至少解释一下更多细节?因为我甚至无法理解为什么函数BOOL GetCurrentActCtx(_Out_ HANDLE *lphActCtx);会收到指向ACTCTX但指向某些HANDLE类型的签名。

1 个答案:

答案 0 :(得分:11)

如果您希望您的DLL使用视觉样式感知控件,即comctl32 v6,即使您的主机应用程序不使用它,您也必须使用Activation Context API。以下是如何使用它的示例:

 HANDLE hActCtx;
 ACTCTX actCtx;
 ZeroMemory(&actCtx, sizeof(actCtx));
 actCtx.cbSize = sizeof(actCtx);
 actCtx.hModule = hInst;
 actCtx.lpResourceName = MAKEINTRESOURCE(2);
 actCtx.dwFlags = ACTCTX_FLAG_HMODULE_VALID | ACTCTX_FLAG_RESOURCE_NAME_VALID;

 hActCtx = CreateActCtx(&actCtx);
 if (hActCtx != INVALID_HANDLE_VALUE) {
     ULONG_PTR cookie;
     ActivateActCtx(hActCtx, &cookie);

     // Do some UI stuff here; just show a message for example
     MessageBox(NULL, TEXT("Styled message box"), NULL, MB_OK);

     DeactivateActCtx(0, cookie);
     ReleaseActCtx(hActCtx);
 }

此处hInst是DLL的模块句柄,您可以将其保存在DllMain中的全局变量中,或使用GetModuleHandle函数来获取它。此示例意味着您的DLL将Common Controls版本6.0清单存储在其ID为2的资源中。

您可以在DLL初始化时仅调用CreateActCtx一次,而在不再需要时调用ReleaseActCtx。在创建任何窗口之前调用ActivateActCtx并在将控制权返回给应用程序之前调用DeactivateActCtx