*
* Copyright 1997 Dimitrie O. Paun
* Copyright 1998,2000 Eric Kohl
+ * Copyright 2014-2015 Michael Müller
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* -- ICC_WIN95_CLASSES
*/
-#include "comctl32.h"
-
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winnls.h"
+#include "commctrl.h"
+#include "winerror.h"
+#include "winreg.h"
#define NO_SHLWAPI_STREAM
-#include <shlwapi.h>
+#include "shlwapi.h"
+#include "comctl32.h"
+#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(commctrl);
-#define NAME L"microsoft.windows.common-controls"
-#define VERSION L"6.0.2600.2982"
-#define PUBLIC_KEY L"6595b64144ccf1df"
-
-#ifdef __i386__
-#define ARCH L"x86"
-#elif defined __x86_64__
-#define ARCH L"amd64"
-#else
-#define ARCH L"none"
-#endif
-
-static const WCHAR manifest_filename[] = ARCH L"_" NAME L"_" PUBLIC_KEY L"_" VERSION L"_none_deadbeef.manifest";
static LRESULT WINAPI COMCTL32_SubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
'C','C','3','2','S','u','b','c','l','a','s','s','I','n','f','o',0
};
-static BOOL create_manifest(BOOL install)
-{
- WCHAR *pwszBuf;
- HRSRC hResInfo;
- HGLOBAL hResData;
- PVOID pManifest;
- DWORD cchBuf, cbManifest, cbWritten;
- HANDLE hFile;
- BOOL bRet = FALSE;
-
- hResInfo = FindResourceW(COMCTL32_hModule, L"WINE_MANIFEST", (LPWSTR)RT_MANIFEST);
- if (!hResInfo)
- return FALSE;
+#ifdef __REACTOS__
- cbManifest = SizeofResource(COMCTL32_hModule, hResInfo);
- if (!cbManifest)
- return FALSE;
+#include <strsafe.h>
- hResData = LoadResource(COMCTL32_hModule, hResInfo);
- if (!hResData)
- return FALSE;
+#define NAME L"microsoft.windows.common-controls"
+#define VERSION_V5 L"5.82.2600.2982"
+#define VERSION L"6.0.2600.2982"
+#define PUBLIC_KEY L"6595b64144ccf1df"
- pManifest = LockResource(hResData);
- if (!pManifest)
- return FALSE;
+#ifdef __i386__
+#define ARCH L"x86"
+#elif defined __x86_64__
+#define ARCH L"amd64"
+#else
+#define ARCH L"none"
+#endif
+
+static const WCHAR manifest_filename[] = ARCH L"_" NAME L"_" PUBLIC_KEY L"_" VERSION L"_none_deadbeef.manifest";
+static const WCHAR manifest_filename_v5[] = ARCH L"_" NAME L"_" PUBLIC_KEY L"_" VERSION_V5 L"_none_deadbeef.manifest";
+
+static WCHAR* GetManifestPath(BOOL create, BOOL bV6)
+{
+ WCHAR *pwszBuf;
+ HRESULT hres;
- cchBuf = GetWindowsDirectoryW(NULL, 0) * sizeof(WCHAR) + sizeof(L"\\winsxs\\manifests\\") + sizeof(manifest_filename);
- pwszBuf = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, cchBuf * sizeof(WCHAR));
+ pwszBuf = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
if (!pwszBuf)
- return FALSE;
+ return NULL;
+
+ GetWindowsDirectoryW(pwszBuf, MAX_PATH);
+ hres = StringCchCatW(pwszBuf, MAX_PATH, L"\\winsxs");
+ if (FAILED(hres))
+ return NULL;
+ if (create)
+ CreateDirectoryW(pwszBuf, NULL);
+ hres = StringCchCatW(pwszBuf, MAX_PATH, L"\\manifests\\");
+ if (FAILED(hres))
+ return NULL;
+ if (create)
+ CreateDirectoryW(pwszBuf, NULL);
+
+ hres = StringCchCatW(pwszBuf, MAX_PATH, bV6 ? manifest_filename : manifest_filename_v5);
+ if (FAILED(hres))
+ return NULL;
+
+ return pwszBuf;
+}
- GetWindowsDirectoryW(pwszBuf, cchBuf);
- lstrcatW(pwszBuf, L"\\winsxs");
- CreateDirectoryW(pwszBuf, NULL);
- lstrcatW(pwszBuf, L"\\manifests\\");
- CreateDirectoryW(pwszBuf, NULL);
- lstrcatW(pwszBuf, manifest_filename);
- if (install)
+static HANDLE CreateComctl32ActCtx(BOOL bV6)
+{
+ HANDLE ret;
+ WCHAR* pwstrSource;
+ ACTCTXW ActCtx = {sizeof(ACTCTX)};
+
+ pwstrSource = GetManifestPath(FALSE, bV6);
+ if (!pwstrSource)
{
- hFile = CreateFileW(pwszBuf, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
- if (hFile != INVALID_HANDLE_VALUE)
- {
- if (WriteFile(hFile, pManifest, cbManifest, &cbWritten, NULL) && cbWritten == cbManifest)
- bRet = TRUE;
+ ERR("GetManifestPath failed! bV6=%d\n", bV6);
+ return INVALID_HANDLE_VALUE;
+ }
+ ActCtx.lpSource = pwstrSource;
+ ret = CreateActCtxW(&ActCtx);
+ HeapFree(GetProcessHeap(), 0, pwstrSource);
+ if (ret == INVALID_HANDLE_VALUE)
+ ERR("CreateActCtxW failed! bV6=%d\n", bV6);
+ return ret;
+}
- CloseHandle(hFile);
+static void RegisterControls(BOOL bV6)
+{
+ ANIMATE_Register ();
+ COMBOEX_Register ();
+ DATETIME_Register ();
+ FLATSB_Register ();
+ HEADER_Register ();
+ HOTKEY_Register ();
+ IPADDRESS_Register ();
+ LISTVIEW_Register ();
+ MONTHCAL_Register ();
+ NATIVEFONT_Register ();
+ PAGER_Register ();
+ PROGRESS_Register ();
+ REBAR_Register ();
+ STATUS_Register ();
+ SYSLINK_Register ();
+ TAB_Register ();
+ TOOLTIPS_Register ();
+ TRACKBAR_Register ();
+ TREEVIEW_Register ();
+ UPDOWN_Register ();
+
+ if (!bV6)
+ {
+ TOOLBAR_Register ();
+ }
+ else
+ {
+ BUTTON_Register ();
+ COMBO_Register ();
+ COMBOLBOX_Register ();
+ EDIT_Register ();
+ LISTBOX_Register ();
+ STATIC_Register ();
+
+ TOOLBARv6_Register();
+ }
+}
- if (!bRet)
- DeleteFileW(pwszBuf);
- else
- TRACE("created %s\n", debugstr_w(pwszBuf));
- }
+static void UnregisterControls(BOOL bV6)
+{
+ ANIMATE_Unregister ();
+ COMBOEX_Unregister ();
+ DATETIME_Unregister ();
+ FLATSB_Unregister ();
+ HEADER_Unregister ();
+ HOTKEY_Unregister ();
+ IPADDRESS_Unregister ();
+ LISTVIEW_Unregister ();
+ MONTHCAL_Unregister ();
+ NATIVEFONT_Unregister ();
+ PAGER_Unregister ();
+ PROGRESS_Unregister ();
+ REBAR_Unregister ();
+ STATUS_Unregister ();
+ SYSLINK_Unregister ();
+ TAB_Unregister ();
+ TOOLTIPS_Unregister ();
+ TRACKBAR_Unregister ();
+ TREEVIEW_Unregister ();
+ UPDOWN_Unregister ();
+
+ if (!bV6)
+ {
+ TOOLBAR_Unregister ();
}
else
- bRet = DeleteFileW(pwszBuf);
+ {
+ BUTTON_Unregister();
+ COMBO_Unregister ();
+ COMBOLBOX_Unregister ();
+ EDIT_Unregister ();
+ LISTBOX_Unregister ();
+ STATIC_Unregister ();
+
+ TOOLBARv6_Unregister ();
+ }
- HeapFree(GetProcessHeap(), 0, pwszBuf);
+}
- return bRet;
+static void InitializeClasses()
+{
+ HANDLE hActCtx5, hActCtx6;
+ BOOL activated;
+ ULONG_PTR ulCookie;
+
+ /* like comctl32 5.82+ register all the common control classes */
+ /* Register the classes once no matter what */
+ hActCtx5 = CreateComctl32ActCtx(FALSE);
+ activated = (hActCtx5 != INVALID_HANDLE_VALUE ? ActivateActCtx(hActCtx5, &ulCookie) : FALSE);
+ RegisterControls(FALSE); /* Register the classes pretending to be v5 */
+ if (activated) DeactivateActCtx(0, ulCookie);
+
+ hActCtx6 = CreateComctl32ActCtx(TRUE);
+ if (hActCtx6 != INVALID_HANDLE_VALUE)
+ {
+ activated = ActivateActCtx(hActCtx6, &ulCookie);
+ RegisterControls(TRUE); /* Register the classes pretending to be v6 */
+ if (activated) DeactivateActCtx(0, ulCookie);
+
+ /* Initialize the themed controls only when the v6 manifest is present */
+ THEMING_Initialize (hActCtx5, hActCtx6);
+ }
}
+static void UninitializeClasses()
+{
+ HANDLE hActCtx5, hActCtx6;
+ BOOL activated;
+ ULONG_PTR ulCookie;
+
+ hActCtx5 = CreateComctl32ActCtx(FALSE);
+ activated = (hActCtx5 != INVALID_HANDLE_VALUE ? ActivateActCtx(hActCtx5, &ulCookie) : FALSE);
+ UnregisterControls(FALSE);
+ if (activated) DeactivateActCtx(0, ulCookie);
+
+ hActCtx6 = CreateComctl32ActCtx(TRUE);
+ if (hActCtx6 != INVALID_HANDLE_VALUE)
+ {
+ activated = ActivateActCtx(hActCtx6, &ulCookie);
+ THEMING_Uninitialize();
+ UnregisterControls(TRUE);
+ if (activated) DeactivateActCtx(0, ulCookie);
+ }
+}
+
+/***********************************************************************
+ * RegisterClassNameW [COMCTL32.@]
+ *
+ * Register window class again while using as SxS module.
+ */
+BOOLEAN WINAPI RegisterClassNameW(LPCWSTR className)
+{
+ InitializeClasses();
+ return TRUE;
+}
+
+#endif /* __REACTOS__ */
+
+#ifndef __REACTOS__
+static void unregister_versioned_classes(void)
+{
+#define VERSION "6.0.2600.2982!"
+ static const char *classes[] =
+ {
+ VERSION WC_BUTTONA,
+ VERSION WC_COMBOBOXA,
+ VERSION "ComboLBox",
+ VERSION WC_EDITA,
+ VERSION WC_LISTBOXA,
+ VERSION WC_STATICA,
+ };
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(classes); i++)
+ UnregisterClassA(classes[i], NULL);
+
+#undef VERSION
+}
+#endif
/***********************************************************************
* DllMain [Internal]
/* Get all the colors at DLL load */
COMCTL32_RefreshSysColors();
+#ifndef __REACTOS__
/* like comctl32 5.82+ register all the common control classes */
ANIMATE_Register ();
COMBOEX_Register ();
TREEVIEW_Register ();
UPDOWN_Register ();
+ BUTTON_Register ();
+ COMBO_Register ();
+ COMBOLBOX_Register ();
+ EDIT_Register ();
+ LISTBOX_Register ();
+ STATIC_Register ();
+
/* subclass user32 controls */
THEMING_Initialize ();
+#else
+ InitializeClasses();
+#endif
+
break;
case DLL_PROCESS_DETACH:
if (lpvReserved) break;
+#ifndef __REACTOS__
/* clean up subclassing */
THEMING_Uninitialize();
TREEVIEW_Unregister ();
UPDOWN_Unregister ();
+ unregister_versioned_classes ();
+
+#else
+ UninitializeClasses();
+#endif
/* delete local pattern brush */
DeleteObject (COMCTL32_hPattern55AABrush);
DeleteObject (COMCTL32_hPattern55AABitmap);
if (uMenuID) {
WCHAR szText[256];
- if (!LoadStringW (hInst, uMenuID, szText, sizeof(szText)/sizeof(szText[0])))
+ if (!LoadStringW (hInst, uMenuID, szText, ARRAY_SIZE(szText)))
szText[0] = '\0';
SendMessageW (hwndStatus, SB_SETTEXTW,
HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline)
{
TRACE("(%u, %s): stub\n", bInstall, debugstr_w(cmdline));
- if (!create_manifest(bInstall))
- {
- ERR("create_manifest failed!\n");
- return HRESULT_FROM_WIN32(GetLastError());
- }
-
return S_OK;
}
TRACE ("(%p, %p, %lx, %lx)\n", hWnd, pfnSubclass, uIDSubclass, dwRef);
+ if (!hWnd || !pfnSubclass)
+ return FALSE;
+
/* Since the window procedure that we set here has two additional arguments,
* we can't simply set it as the new window procedure of the window. So we
* set our own window procedure and then calculate the other two arguments
* Gets the Reference data from a subclass.
*
* PARAMS
- * hWnd [in] Handle to window which were subclassing
+ * hWnd [in] Handle to the window which we are subclassing
* pfnSubclass [in] Pointer to the subclass procedure
* uID [in] Unique identifier of the subclassing procedure
* pdwRef [out] Pointer to the reference data
* Removes a window subclass.
*
* PARAMS
- * hWnd [in] Handle to the window were subclassing
+ * hWnd [in] Handle to the window which we are subclassing
* pfnSubclass [in] Pointer to the subclass procedure
* uID [in] Unique identifier of this subclass
*
{lCentre + 1, l2 - 3},
};
hOldPen = SelectObject(hDC, hPen);
- PolyPolyline(hDC, aptInsertMark, adwPolyPoints, sizeof(adwPolyPoints)/sizeof(adwPolyPoints[0]));
+ PolyPolyline(hDC, aptInsertMark, adwPolyPoints, ARRAY_SIZE(adwPolyPoints));
SelectObject(hDC, hOldPen);
DeleteObject(hPen);
}
bf.BlendFlags = 0;
bf.SourceConstantAlpha = 255;
bf.AlphaFormat = AC_SRC_ALPHA;
- if (!GdiAlphaBlend(hdc, prc->left + ixOffset, prc->top + iyOffset, bi.bmiHeader.biWidth, bi.bmiHeader.biHeight, hdcMem, 0, 0, bi.bmiHeader.biWidth, bi.bmiHeader.biHeight, bf))
- ERR("GdiAlphaBlend failed: %lu\n", GetLastError());
+ GdiAlphaBlend(hdc, prc->left + ixOffset, prc->top + iyOffset, bi.bmiHeader.biWidth, bi.bmiHeader.biHeight, hdcMem, 0, 0, bi.bmiHeader.biWidth, bi.bmiHeader.biHeight, bf);
/* Delete the helper bitmap */
SelectObject(hdcMem, hbmOld);
}
/***********************************************************************
- * TaskDialogIndirect [COMCTL32.@]
+ * LoadIconWithScaleDown [COMCTL32.@]
*/
-HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *pTaskConfig, int *pnButton,
- int *pnRadioButton, BOOL *pfVerificationFlagChecked)
+HRESULT WINAPI LoadIconWithScaleDown(HINSTANCE hinst, const WCHAR *name, int cx, int cy, HICON *icon)
{
- UINT uType = 0;
- INT ret;
- FIXME("%p, %p, %p, %p\n", pTaskConfig, pnButton, pnRadioButton, pfVerificationFlagChecked);
-
- if (pTaskConfig->dwCommonButtons & TDCBF_YES_BUTTON &&
- pTaskConfig->dwCommonButtons & TDCBF_NO_BUTTON &&
- pTaskConfig->dwCommonButtons & TDCBF_CANCEL_BUTTON)
- uType |= MB_YESNOCANCEL;
- else
- if (pTaskConfig->dwCommonButtons & TDCBF_YES_BUTTON &&
- pTaskConfig->dwCommonButtons & TDCBF_NO_BUTTON)
- uType |= MB_YESNO;
- else
- if (pTaskConfig->dwCommonButtons & TDCBF_RETRY_BUTTON &&
- pTaskConfig->dwCommonButtons & TDCBF_CANCEL_BUTTON)
- uType |= MB_RETRYCANCEL;
- else
- if (pTaskConfig->dwCommonButtons & TDCBF_OK_BUTTON &&
- pTaskConfig->dwCommonButtons & TDCBF_CANCEL_BUTTON)
- uType |= MB_OKCANCEL;
- else
- if (pTaskConfig->dwCommonButtons & TDCBF_OK_BUTTON)
- uType |= MB_OK;
- ret = MessageBoxW(pTaskConfig->hwndParent, pTaskConfig->pszMainInstruction,
- pTaskConfig->pszWindowTitle, uType);
- FIXME("dwCommonButtons=%x uType=%x ret=%x\n", pTaskConfig->dwCommonButtons, uType, ret);
-
- if (pnButton) *pnButton = ret;
- if (pnRadioButton) *pnRadioButton = pTaskConfig->nDefaultButton;
- if (pfVerificationFlagChecked) *pfVerificationFlagChecked = TRUE;
+ TRACE("(%p, %s, %d, %d, %p)\n", hinst, debugstr_w(name), cx, cy, icon);
+
+ *icon = NULL;
+
+ if (!name)
+ return E_INVALIDARG;
+
+ *icon = LoadImageW(hinst, name, IMAGE_ICON, cx, cy,
+ (hinst || IS_INTRESOURCE(name)) ? 0 : LR_LOADFROMFILE);
+ if (!*icon)
+ return HRESULT_FROM_WIN32(GetLastError());
+
return S_OK;
}
/***********************************************************************
- * RegisterClassNameW [COMCTL32.@]
- *
- * Register window class again while using as SxS module.
+ * LoadIconMetric [COMCTL32.@]
*/
-BOOLEAN WINAPI RegisterClassNameW(LPCWSTR className)
+HRESULT WINAPI LoadIconMetric(HINSTANCE hinst, const WCHAR *name, int size, HICON *icon)
{
- /* FIXME: actually register redirected user32 class,
- comctl32 classes are registered by this module anyway */
- return TRUE;
+ int cx, cy;
+
+ TRACE("(%p, %s, %d, %p)\n", hinst, debugstr_w(name), size, icon);
+
+ if (size == LIM_SMALL)
+ {
+ cx = GetSystemMetrics(SM_CXSMICON);
+ cy = GetSystemMetrics(SM_CYSMICON);
+ }
+ else if (size == LIM_LARGE)
+ {
+ cx = GetSystemMetrics(SM_CXICON);
+ cy = GetSystemMetrics(SM_CYICON);
+ }
+ else
+ {
+ *icon = NULL;
+ return E_INVALIDARG;
+ }
+
+ return LoadIconWithScaleDown(hinst, name, cx, cy, icon);
}