我没有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
类型的签名。
答案 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
。