5

我没有 C++ 和 Win API 方面的经验,如果这个问题是 nooby,我很抱歉。例如,我有 DLL 在其中创建一些组件MessageBox。我添加了编译指示注释以启用视觉样式,但它不起作用(我不应该从这个答案中知道:windows 7 style for combobox on internet explorer工具栏,怎么样?

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

然后我从我的应用程序中调用这个 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类型的签名。

4

1 回答 1

12

如果您希望您的 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在将控制权返回给应用程序之前调用。ActivateActCtxDeactivateActCtx

于 2014-08-12T18:26:40.467 回答