2014-07-17 19:05:47 -05:00
|
|
|
/* 17 july 2014 */
|
|
|
|
|
|
|
|
#include "winapi_windows.h"
|
|
|
|
|
|
|
|
static ULONG_PTR comctlManifestCookie;
|
|
|
|
static HMODULE comctl32;
|
|
|
|
|
2014-07-21 08:43:37 -05:00
|
|
|
/* these are listed as WINAPI in both Microsoft's and MinGW's headers, but not on MSDN for some reason */
|
2014-07-17 23:22:21 -05:00
|
|
|
BOOL (*WINAPI fv_SetWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR);
|
|
|
|
BOOL (*WINAPI fv_RemoveWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR);
|
|
|
|
LRESULT (*WINAPI fv_DefSubclassProc)(HWND, UINT, WPARAM, LPARAM);
|
|
|
|
|
2014-07-17 19:05:47 -05:00
|
|
|
DWORD initCommonControls(LPCWSTR manifest, char **errmsg)
|
|
|
|
{
|
|
|
|
ACTCTX actctx;
|
|
|
|
HANDLE ac;
|
|
|
|
INITCOMMONCONTROLSEX icc;
|
|
|
|
FARPROC f;
|
2014-07-21 08:43:37 -05:00
|
|
|
/* this is listed as WINAPI in both Microsoft's and MinGW's headers, but not on MSDN for some reason */
|
2014-07-17 19:05:47 -05:00
|
|
|
BOOL (*WINAPI ficc)(const LPINITCOMMONCONTROLSEX);
|
|
|
|
|
|
|
|
ZeroMemory(&actctx, sizeof (ACTCTX));
|
|
|
|
actctx.cbSize = sizeof (ACTCTX);
|
|
|
|
actctx.dwFlags = ACTCTX_FLAG_SET_PROCESS_DEFAULT;
|
|
|
|
actctx.lpSource = manifest;
|
|
|
|
ac = CreateActCtx(&actctx);
|
|
|
|
if (ac == INVALID_HANDLE_VALUE) {
|
|
|
|
*errmsg = "error creating activation context for synthesized manifest file";
|
|
|
|
return GetLastError();
|
|
|
|
}
|
|
|
|
if (ActivateActCtx(ac, &comctlManifestCookie) == FALSE) {
|
|
|
|
*errmsg = "error activating activation context for synthesized manifest file";
|
|
|
|
return GetLastError();
|
|
|
|
}
|
|
|
|
|
|
|
|
ZeroMemory(&icc, sizeof (INITCOMMONCONTROLSEX));
|
|
|
|
icc.dwSize = sizeof (INITCOMMONCONTROLSEX);
|
2014-07-25 14:58:24 -05:00
|
|
|
icc.dwICC = ICC_PROGRESS_CLASS | ICC_TAB_CLASSES;
|
2014-07-17 19:05:47 -05:00
|
|
|
|
|
|
|
comctl32 = LoadLibraryW(L"comctl32.dll");
|
|
|
|
if (comctl32 == NULL) {
|
|
|
|
*errmsg = "error loading comctl32.dll";
|
|
|
|
return GetLastError();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* GetProcAddress() only takes a multibyte string */
|
2014-07-17 22:56:16 -05:00
|
|
|
#define LOAD(fn) f = GetProcAddress(comctl32, fn); \
|
2014-07-17 19:05:47 -05:00
|
|
|
if (f == NULL) { \
|
|
|
|
*errmsg = "error loading " fn "()"; \
|
|
|
|
return GetLastError(); \
|
|
|
|
}
|
|
|
|
|
|
|
|
LOAD("InitCommonControlsEx");
|
|
|
|
ficc = (BOOL (*WINAPI)(const LPINITCOMMONCONTROLSEX)) f;
|
|
|
|
LOAD("SetWindowSubclass");
|
|
|
|
fv_SetWindowSubclass = (BOOL (*WINAPI)(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR)) f;
|
|
|
|
LOAD("RemoveWindowSubclass");
|
|
|
|
fv_RemoveWindowSubclass = (BOOL (*WINAPI)(HWND, SUBCLASSPROC, UINT_PTR)) f;
|
|
|
|
LOAD("DefSubclassProc");
|
|
|
|
fv_DefSubclassProc = (LRESULT (*WINAPI)(HWND, UINT, WPARAM, LPARAM)) f;
|
|
|
|
|
|
|
|
if ((*ficc)(&icc) == FALSE) {
|
|
|
|
*errmsg = "error initializing Common Controls (comctl32.dll)";
|
|
|
|
return GetLastError();
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|