Win32. Включить визуальные стили в dll

У меня нет опыта работы с C++ и Win API, так что извините, если этот вопрос будет нубским. У меня есть DLL, в которой я создаю некоторые компоненты, например MessageBox. Я добавил прагматический комментарий, чтобы включить визуальные стили, и он не работает (и не должен, как я знаю из этого ответа: стиль Windows 7 для поля со списком на панели инструментов 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.


person Moses    schedule 12.08.2014    source источник
comment
Что ж, вам нужно будет создать и активировать контекст активации. Проще всего это сделать с помощью ISOLATION_AWARE_ENABLED.   -  person David Heffernan    schedule 12.08.2014
comment
Что касается GetCurrentActCtx, это должно быть ошибка документации. Функция возвращает HANDLE в контекст активации. Вы можете использовать этот дескриптор с QueryActCtxW и QueryActCtxSettingsW для запроса контекстной информации.   -  person Alexey Ivanov    schedule 12.08.2014


Ответы (1)


Если вы хотите, чтобы ваша 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 в своих ресурсах с идентификатором 2.

Вы можете вызвать CreateActCtx только один раз, когда ваша DLL инициализируется и ReleaseActCtx при это больше не нужно. Перед созданием любых окон и вызовите DeactivateActCtx, прежде чем вернуть управление приложению .

person Alexey Ivanov    schedule 12.08.2014