我没有c++和Win API的经验,所以很抱歉,如果这个问题是noby。我有DLL,我创建一些组件,例如MessageBox
。我添加了pragma注释来启用视觉样式,但它不起作用(而且我从这个答案中知道它不应该:windows 7样式的ie工具栏上的组合框,怎么回事?
Dll代码(省略export等):
#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
类型的签名。
如果你想让你的DLL使用视觉样式感知控件,即comtl32 v6,即使你的主机应用程序不使用它,你必须使用激活上下文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在其ID为2的资源中存储Common Controls version 6.0清单。
你只能在DLL初始化时调用一次CreateActCtx
,当不再需要ReleaseActCtx
时调用它。在创建任何窗口之前调用ActivateActCtx
,在将控制权返回给应用程序之前调用DeactivateActCtx
。