blob: eb0f6b5293e4c7d2e6cb17034e04841b2c37e94f [file] [log] [blame]
Vincent Béron9a624912002-05-31 23:06:46 +00001/*
Alexandre Julliard17216f51997-10-12 16:30:17 +00002 * Common controls functions
3 *
4 * Copyright 1997 Dimitrie O. Paun
Eric Kohlb3f681e2000-06-03 21:06:44 +00005 * Copyright 1998,2000 Eric Kohl
Alexandre Julliard17216f51997-10-12 16:30:17 +00006 *
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00007 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
Jonathan Ernst360a3f92006-05-18 14:49:52 +020019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
Christian Neumair513eb2a2002-10-23 18:43:32 +000020 *
21 * NOTES
22 *
23 * This code was audited for completeness against the documented features
24 * of Comctl32.dll version 6.0 on Oct. 21, 2002, by Christian Neumair.
25 *
Robert Shearman3c6956d2004-03-11 00:39:53 +000026 * Unless otherwise noted, we believe this code to be complete, as per
Christian Neumair513eb2a2002-10-23 18:43:32 +000027 * the specification mentioned above.
28 * If you discover missing features, or bugs, please note them below.
29 *
30 * TODO
31 * -- implement GetMUILanguage + InitMUILanguage
Christian Neumair513eb2a2002-10-23 18:43:32 +000032 * -- finish NOTES for MenuHelp, GetEffectiveClientRect and GetStatusTextW
33 * -- FIXMEs + BUGS (search for them)
34 *
35 * Control Classes
36 * -- ICC_ANIMATE_CLASS
37 * -- ICC_BAR_CLASSES
38 * -- ICC_COOL_CLASSES
39 * -- ICC_DATE_CLASSES
40 * -- ICC_HOTKEY_CLASS
41 * -- ICC_INTERNET_CLASSES
Dimitrie O. Paun268f62f2004-09-22 19:10:47 +000042 * -- ICC_LINK_CLASS
Christian Neumair513eb2a2002-10-23 18:43:32 +000043 * -- ICC_LISTVIEW_CLASSES
44 * -- ICC_NATIVEFNTCTL_CLASS
45 * -- ICC_PAGESCROLLER_CLASS
46 * -- ICC_PROGRESS_CLASS
47 * -- ICC_STANDARD_CLASSES (not yet implemented)
48 * -- ICC_TAB_CLASSES
49 * -- ICC_TREEVIEW_CLASSES
50 * -- ICC_UPDOWN_CLASS
51 * -- ICC_USEREX_CLASSES
52 * -- ICC_WIN95_CLASSES
Alexandre Julliard17216f51997-10-12 16:30:17 +000053 */
54
Alexandre Julliarde37c6e12003-09-05 23:08:26 +000055#include <stdarg.h>
Patrik Stridvall6cc47d42000-03-08 18:26:56 +000056#include <string.h>
Jon Griffiths603f20f2001-12-11 00:30:17 +000057#include <stdlib.h>
Patrik Stridvall6cc47d42000-03-08 18:26:56 +000058
Alexandre Julliarde37c6e12003-09-05 23:08:26 +000059#include "windef.h"
Marcus Meissner3480e4a1999-03-16 10:53:11 +000060#include "winbase.h"
Alexandre Julliarde37c6e12003-09-05 23:08:26 +000061#include "wingdi.h"
62#include "winuser.h"
63#include "winnls.h"
Alexandre Julliard17216f51997-10-12 16:30:17 +000064#include "commctrl.h"
Alexandre Julliarda0d77311998-09-13 16:32:00 +000065#include "winerror.h"
Guy Albertelliaafec982001-11-06 22:31:19 +000066#include "winreg.h"
Jon Griffiths603f20f2001-12-11 00:30:17 +000067#define NO_SHLWAPI_STREAM
Francois Gouget8aa79fb2000-09-29 01:03:30 +000068#include "shlwapi.h"
Gerard Patel8b21b6b2001-03-16 16:50:24 +000069#include "comctl32.h"
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000070#include "wine/debug.h"
Alexandre Julliard17216f51997-10-12 16:30:17 +000071
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000072WINE_DEFAULT_DEBUG_CHANNEL(commctrl);
Alexandre Julliard70c9e092000-08-09 00:41:17 +000073
Alexandre Julliard6790cdb2007-08-14 12:31:27 +020074
75#define NAME "microsoft.windows.common-controls"
76#define FILE "comctl32.dll"
Rob Shearmanf2efcf5f2007-11-22 19:09:27 +000077#define VERSION "6.0.2600.2982"
Alexandre Julliard6790cdb2007-08-14 12:31:27 +020078#define PUBLIC_KEY "6595b64144ccf1df"
79
80#ifdef __i386__
81#define ARCH "x86"
82#elif defined __x86_64__
83#define ARCH "amd64"
84#else
85#define ARCH "none"
86#endif
87
88static const char manifest[] =
89 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
90 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">\n"
91 " <assemblyIdentity type=\"win32\" name=\"" NAME "\" version=\"" VERSION "\" processorArchitecture=\"" ARCH "\" publicKeyToken=\"" PUBLIC_KEY "\"/>\n"
92 " <file name=\"" FILE "\">\n"
93 " <windowClass>Button</windowClass>\n"
94 " <windowClass>ButtonListBox</windowClass>\n"
95 " <windowClass>ComboBoxEx32</windowClass>\n"
96 " <windowClass>ComboLBox</windowClass>\n"
97 " <windowClass>Combobox</windowClass>\n"
98 " <windowClass>Edit</windowClass>\n"
99 " <windowClass>Listbox</windowClass>\n"
100 " <windowClass>NativeFontCtl</windowClass>\n"
101 " <windowClass>ReBarWindow32</windowClass>\n"
102 " <windowClass>ScrollBar</windowClass>\n"
103 " <windowClass>Static</windowClass>\n"
104 " <windowClass>SysAnimate32</windowClass>\n"
105 " <windowClass>SysDateTimePick32</windowClass>\n"
106 " <windowClass>SysHeader32</windowClass>\n"
107 " <windowClass>SysIPAddress32</windowClass>\n"
108 " <windowClass>SysLink</windowClass>\n"
109 " <windowClass>SysListView32</windowClass>\n"
110 " <windowClass>SysMonthCal32</windowClass>\n"
111 " <windowClass>SysPager</windowClass>\n"
112 " <windowClass>SysTabControl32</windowClass>\n"
113 " <windowClass>SysTreeView32</windowClass>\n"
114 " <windowClass>ToolbarWindow32</windowClass>\n"
115 " <windowClass>msctls_hotkey32</windowClass>\n"
116 " <windowClass>msctls_progress32</windowClass>\n"
117 " <windowClass>msctls_statusbar32</windowClass>\n"
118 " <windowClass>msctls_trackbar32</windowClass>\n"
119 " <windowClass>msctls_updown32</windowClass>\n"
120 " <windowClass>tooltips_class32</windowClass>\n"
121 " </file>\n"
122 "</assembly>\n";
123
124static const char manifest_filename[] = ARCH "_" NAME "_" PUBLIC_KEY "_" VERSION "_none_deadbeef.manifest";
125
Alexandre Julliardc6aebe12008-12-04 12:46:45 +0100126static LRESULT WINAPI COMCTL32_SubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000127
Andrew Talbotc8cf4212009-01-02 12:54:46 +0000128static LPWSTR COMCTL32_wSubclass = NULL;
Bertho Stultiensd1895a71999-04-25 18:31:35 +0000129HMODULE COMCTL32_hModule = 0;
Andrew Talbotc8cf4212009-01-02 12:54:46 +0000130static LANGID COMCTL32_uiLang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
Francois Gouget9b0b1e02003-01-14 23:43:41 +0000131HBRUSH COMCTL32_hPattern55AABrush = NULL;
Guy L. Albertelli35d8e1e2002-04-05 21:14:05 +0000132COMCTL32_SysColor comctl32_color;
Eric Kohl7379b892000-11-25 01:27:42 +0000133
Francois Gouget9b0b1e02003-01-14 23:43:41 +0000134static HBITMAP COMCTL32_hPattern55AABitmap = NULL;
Eric Kohl7379b892000-11-25 01:27:42 +0000135
136static const WORD wPattern55AA[] =
137{
138 0x5555, 0xaaaa, 0x5555, 0xaaaa,
139 0x5555, 0xaaaa, 0x5555, 0xaaaa
140};
Eric Kohl37d68ef1998-10-11 13:17:47 +0000141
Dimitrie O. Paun2e0431e2005-03-23 10:22:37 +0000142static const WCHAR strCC32SubclassInfo[] = {
143 'C','C','3','2','S','u','b','c','l','a','s','s','I','n','f','o',0
144};
Eric Kohl37d68ef1998-10-11 13:17:47 +0000145
Alexandre Julliard6790cdb2007-08-14 12:31:27 +0200146static BOOL create_manifest( BOOL install )
147{
Alexandre Julliard4bac1e92007-08-20 12:46:37 +0200148 static const WCHAR winsxsW[] = {'\\','w','i','n','s','x','s',0};
149 static const WCHAR manifestsW[] = {'\\','m','a','n','i','f','e','s','t','s','\\',0};
Alexandre Julliard6790cdb2007-08-14 12:31:27 +0200150
151 DWORD len, written;
152 WCHAR *buffer;
153 HANDLE file;
154 BOOL ret = FALSE;
155
156 len = MultiByteToWideChar( CP_UTF8, 0, manifest_filename, sizeof(manifest_filename), NULL, 0 );
157 len += GetWindowsDirectoryW( NULL, 0 );
Alexandre Julliard4bac1e92007-08-20 12:46:37 +0200158 len += lstrlenW(winsxsW);
159 len += lstrlenW(manifestsW);
160 if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return FALSE;
Alexandre Julliard6790cdb2007-08-14 12:31:27 +0200161 GetWindowsDirectoryW( buffer, len );
Alexandre Julliard4bac1e92007-08-20 12:46:37 +0200162 lstrcatW( buffer, winsxsW );
163 CreateDirectoryW( buffer, NULL );
164 lstrcatW( buffer, manifestsW );
165 CreateDirectoryW( buffer, NULL );
Alexandre Julliard6790cdb2007-08-14 12:31:27 +0200166 MultiByteToWideChar( CP_UTF8, 0, manifest_filename, sizeof(manifest_filename),
167 buffer + lstrlenW(buffer), len );
168 if (install)
169 {
170 file = CreateFileW( buffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL );
171 if (file != INVALID_HANDLE_VALUE)
172 {
173 ret = (WriteFile( file, manifest, sizeof(manifest)-1, &written, NULL ) &&
174 written == sizeof(manifest)-1);
175 CloseHandle( file );
176 if (!ret) DeleteFileW( buffer );
177 else TRACE("created %s\n", debugstr_w(buffer));
178 }
179 }
180 else ret = DeleteFileW( buffer );
181
182 HeapFree( GetProcessHeap(), 0, buffer );
183 return ret;
184}
185
186
Alexandre Julliard767e6f61998-08-09 12:47:43 +0000187/***********************************************************************
Robert Shearman57cc6f52004-02-27 04:40:08 +0000188 * DllMain [Internal]
189 *
190 * Initializes the internal 'COMCTL32.DLL'.
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000191 *
192 * PARAMS
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000193 * hinstDLL [I] handle to the 'dlls' instance
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000194 * fdwReason [I]
Eric Kohl37d68ef1998-10-11 13:17:47 +0000195 * lpvReserved [I] reserverd, must be NULL
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000196 *
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000197 * RETURNS
198 * Success: TRUE
199 * Failure: FALSE
Alexandre Julliard767e6f61998-08-09 12:47:43 +0000200 */
Alexandre Julliard17216f51997-10-12 16:30:17 +0000201
Alexandre Julliard1e1313d2002-11-04 23:53:41 +0000202BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000203{
Michael Ploujnikov1c16d832006-10-13 09:34:21 -0400204 TRACE("%p,%x,%p\n", hinstDLL, fdwReason, lpvReserved);
Alexandre Julliard767e6f61998-08-09 12:47:43 +0000205
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000206 switch (fdwReason) {
207 case DLL_PROCESS_ATTACH:
Dmitry Timoshkov4e1ef0c2003-06-30 20:53:48 +0000208 DisableThreadLibraryCalls(hinstDLL);
209
Andrew Talbot867f2542007-12-29 15:37:34 +0000210 COMCTL32_hModule = hinstDLL;
Bertho Stultiensd1895a71999-04-25 18:31:35 +0000211
Alexandre Julliard06187462001-01-17 22:03:18 +0000212 /* add global subclassing atom (used by 'tooltip' and 'updown') */
Frank Richter9e570912005-08-30 10:07:17 +0000213 COMCTL32_wSubclass = (LPWSTR)(DWORD_PTR)GlobalAddAtomW (strCC32SubclassInfo);
Dimitrie O. Paun2e0431e2005-03-23 10:22:37 +0000214 TRACE("Subclassing atom added: %p\n", COMCTL32_wSubclass);
Eric Kohl37d68ef1998-10-11 13:17:47 +0000215
Alexandre Julliard06187462001-01-17 22:03:18 +0000216 /* create local pattern brush */
217 COMCTL32_hPattern55AABitmap = CreateBitmap (8, 8, 1, 1, wPattern55AA);
218 COMCTL32_hPattern55AABrush = CreatePatternBrush (COMCTL32_hPattern55AABitmap);
Eric Kohl8d1a2ff1998-11-22 18:02:24 +0000219
Guy L. Albertelli35d8e1e2002-04-05 21:14:05 +0000220 /* Get all the colors at DLL load */
221 COMCTL32_RefreshSysColors();
222
Mikołaj Zalewskia66784c2007-03-14 12:04:47 +0100223 /* like comctl32 5.82+ register all the common control classes */
Alexandre Julliard06187462001-01-17 22:03:18 +0000224 ANIMATE_Register ();
Mikołaj Zalewskia66784c2007-03-14 12:04:47 +0100225 COMBOEX_Register ();
226 DATETIME_Register ();
Alexandre Julliard06187462001-01-17 22:03:18 +0000227 FLATSB_Register ();
228 HEADER_Register ();
229 HOTKEY_Register ();
Mikołaj Zalewskia66784c2007-03-14 12:04:47 +0100230 IPADDRESS_Register ();
Alexandre Julliard06187462001-01-17 22:03:18 +0000231 LISTVIEW_Register ();
Mikołaj Zalewskia66784c2007-03-14 12:04:47 +0100232 MONTHCAL_Register ();
233 NATIVEFONT_Register ();
234 PAGER_Register ();
Alexandre Julliard06187462001-01-17 22:03:18 +0000235 PROGRESS_Register ();
Mikołaj Zalewskia66784c2007-03-14 12:04:47 +0100236 REBAR_Register ();
Alexandre Julliard06187462001-01-17 22:03:18 +0000237 STATUS_Register ();
Thomas Weidenmüller9d6f88c2004-08-06 19:17:49 +0000238 SYSLINK_Register ();
Alexandre Julliard06187462001-01-17 22:03:18 +0000239 TAB_Register ();
240 TOOLBAR_Register ();
241 TOOLTIPS_Register ();
242 TRACKBAR_Register ();
243 TREEVIEW_Register ();
244 UPDOWN_Register ();
Frank Richter7d00bb32005-07-27 10:54:49 +0000245
246 /* subclass user32 controls */
247 THEMING_Initialize ();
Alexandre Julliard06187462001-01-17 22:03:18 +0000248 break;
Eric Kohl37d68ef1998-10-11 13:17:47 +0000249
250 case DLL_PROCESS_DETACH:
Frank Richterfc4b08d2005-09-12 11:10:58 +0000251 /* clean up subclassing */
252 THEMING_Uninitialize();
253
Alexandre Julliard06187462001-01-17 22:03:18 +0000254 /* unregister all common control classes */
255 ANIMATE_Unregister ();
256 COMBOEX_Unregister ();
257 DATETIME_Unregister ();
258 FLATSB_Unregister ();
259 HEADER_Unregister ();
260 HOTKEY_Unregister ();
261 IPADDRESS_Unregister ();
262 LISTVIEW_Unregister ();
263 MONTHCAL_Unregister ();
264 NATIVEFONT_Unregister ();
265 PAGER_Unregister ();
266 PROGRESS_Unregister ();
267 REBAR_Unregister ();
268 STATUS_Unregister ();
Thomas Weidenmüller9d6f88c2004-08-06 19:17:49 +0000269 SYSLINK_Unregister ();
Alexandre Julliard06187462001-01-17 22:03:18 +0000270 TAB_Unregister ();
271 TOOLBAR_Unregister ();
272 TOOLTIPS_Unregister ();
273 TRACKBAR_Unregister ();
274 TREEVIEW_Unregister ();
275 UPDOWN_Unregister ();
Eric Kohl37d68ef1998-10-11 13:17:47 +0000276
Alexandre Julliard06187462001-01-17 22:03:18 +0000277 /* delete local pattern brush */
278 DeleteObject (COMCTL32_hPattern55AABrush);
Francois Gouget9b0b1e02003-01-14 23:43:41 +0000279 COMCTL32_hPattern55AABrush = NULL;
Alexandre Julliard06187462001-01-17 22:03:18 +0000280 DeleteObject (COMCTL32_hPattern55AABitmap);
Francois Gouget9b0b1e02003-01-14 23:43:41 +0000281 COMCTL32_hPattern55AABitmap = NULL;
Eric Kohl7379b892000-11-25 01:27:42 +0000282
Alexandre Julliard06187462001-01-17 22:03:18 +0000283 /* delete global subclassing atom */
Dimitrie O. Paun2e0431e2005-03-23 10:22:37 +0000284 GlobalDeleteAtom (LOWORD(COMCTL32_wSubclass));
285 TRACE("Subclassing atom deleted: %p\n", COMCTL32_wSubclass);
286 COMCTL32_wSubclass = NULL;
Alexandre Julliard06187462001-01-17 22:03:18 +0000287 break;
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000288 }
289
290 return TRUE;
Alexandre Julliard767e6f61998-08-09 12:47:43 +0000291}
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000292
293
Alexandre Julliard17216f51997-10-12 16:30:17 +0000294/***********************************************************************
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000295 * MenuHelp [COMCTL32.2]
296 *
Robert Shearman57cc6f52004-02-27 04:40:08 +0000297 * Handles the setting of status bar help messages when the user
298 * selects menu items.
299 *
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000300 * PARAMS
Eric Kohld68d5011999-01-24 19:14:58 +0000301 * uMsg [I] message (WM_MENUSELECT) (see NOTES)
302 * wParam [I] wParam of the message uMsg
303 * lParam [I] lParam of the message uMsg
304 * hMainMenu [I] handle to the application's main menu
305 * hInst [I] handle to the module that contains string resources
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000306 * hwndStatus [I] handle to the status bar window
Andreas Mohra6d83eb2000-12-27 04:02:46 +0000307 * lpwIDs [I] pointer to an array of integers (see NOTES)
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000308 *
309 * RETURNS
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000310 * No return value
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000311 *
312 * NOTES
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000313 * The official documentation is incomplete!
Eric Kohld68d5011999-01-24 19:14:58 +0000314 * This is the correct documentation:
315 *
316 * uMsg:
Andreas Mohr20cd9352000-09-12 23:40:40 +0000317 * MenuHelp() does NOT handle WM_COMMAND messages! It only handles
Eric Kohld68d5011999-01-24 19:14:58 +0000318 * WM_MENUSELECT messages.
319 *
320 * lpwIDs:
321 * (will be written ...)
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000322 */
323
324VOID WINAPI
Alexandre Julliarda3960291999-02-26 11:11:13 +0000325MenuHelp (UINT uMsg, WPARAM wParam, LPARAM lParam, HMENU hMainMenu,
Francois Gougetbba4bb12002-09-17 01:35:09 +0000326 HINSTANCE hInst, HWND hwndStatus, UINT* lpwIDs)
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000327{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000328 UINT uMenuID = 0;
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000329
Alexandre Julliarda3960291999-02-26 11:11:13 +0000330 if (!IsWindow (hwndStatus))
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000331 return;
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000332
333 switch (uMsg) {
334 case WM_MENUSELECT:
Dmitry Timoshkov3c9e7a72007-05-24 23:41:17 +0900335 TRACE("WM_MENUSELECT wParam=0x%lX lParam=0x%lX\n",
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000336 wParam, lParam);
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000337
338 if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
339 /* menu was closed */
Alexandre Julliarda099a551999-06-12 15:45:58 +0000340 TRACE("menu was closed!\n");
Dimitrie O. Paun2e0431e2005-03-23 10:22:37 +0000341 SendMessageW (hwndStatus, SB_SIMPLE, FALSE, 0);
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000342 }
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000343 else {
344 /* menu item was selected */
345 if (HIWORD(wParam) & MF_POPUP)
Andrew Talbot1bf787d2007-12-01 16:14:50 +0000346 uMenuID = *(lpwIDs+1);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000347 else
Alexandre Julliarda3960291999-02-26 11:11:13 +0000348 uMenuID = (UINT)LOWORD(wParam);
Alexandre Julliarda099a551999-06-12 15:45:58 +0000349 TRACE("uMenuID = %u\n", uMenuID);
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000350
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000351 if (uMenuID) {
Dimitrie O. Paun2e0431e2005-03-23 10:22:37 +0000352 WCHAR szText[256];
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000353
Dimitrie O. Paun2e0431e2005-03-23 10:22:37 +0000354 if (!LoadStringW (hInst, uMenuID, szText, sizeof(szText)/sizeof(szText[0])))
Eric Kohl37d68ef1998-10-11 13:17:47 +0000355 szText[0] = '\0';
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000356
Dimitrie O. Paun2e0431e2005-03-23 10:22:37 +0000357 SendMessageW (hwndStatus, SB_SETTEXTW,
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000358 255 | SBT_NOBORDERS, (LPARAM)szText);
Dimitrie O. Paun2e0431e2005-03-23 10:22:37 +0000359 SendMessageW (hwndStatus, SB_SIMPLE, TRUE, 0);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000360 }
361 }
362 break;
363
Dennis Björklund87bca231999-09-20 18:37:25 +0000364 case WM_COMMAND :
Dmitry Timoshkov3c9e7a72007-05-24 23:41:17 +0900365 TRACE("WM_COMMAND wParam=0x%lX lParam=0x%lX\n",
Dennis Björklund87bca231999-09-20 18:37:25 +0000366 wParam, lParam);
367 /* WM_COMMAND is not invalid since it is documented
368 * in the windows api reference. So don't output
369 * any FIXME for WM_COMMAND
370 */
371 WARN("We don't care about the WM_COMMAND\n");
372 break;
373
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000374 default:
Alexandre Julliarda099a551999-06-12 15:45:58 +0000375 FIXME("Invalid Message 0x%x!\n", uMsg);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000376 break;
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000377 }
378}
379
380
381/***********************************************************************
Vincent Béron9a624912002-05-31 23:06:46 +0000382 * ShowHideMenuCtl [COMCTL32.3]
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000383 *
384 * Shows or hides controls and updates the corresponding menu item.
385 *
386 * PARAMS
387 * hwnd [I] handle to the client window.
388 * uFlags [I] menu command id.
389 * lpInfo [I] pointer to an array of integers. (See NOTES.)
390 *
391 * RETURNS
392 * Success: TRUE
393 * Failure: FALSE
394 *
395 * NOTES
Eric Kohld68d5011999-01-24 19:14:58 +0000396 * The official documentation is incomplete!
397 * This is the correct documentation:
398 *
399 * hwnd
400 * Handle to the window that contains the menu and controls.
401 *
402 * uFlags
Francois Gouget9d589ac2005-01-04 20:39:54 +0000403 * Identifier of the menu item to receive or lose a check mark.
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000404 *
405 * lpInfo
406 * The array of integers contains pairs of values. BOTH values of
Eric Kohld68d5011999-01-24 19:14:58 +0000407 * the first pair must be the handles to the application's main menu.
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000408 * Each subsequent pair consists of a menu id and control id.
409 */
410
Alexandre Julliarda3960291999-02-26 11:11:13 +0000411BOOL WINAPI
Frank Richter9e570912005-08-30 10:07:17 +0000412ShowHideMenuCtl (HWND hwnd, UINT_PTR uFlags, LPINT lpInfo)
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000413{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000414 LPINT lpMenuId;
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000415
Dmitry Timoshkov3c9e7a72007-05-24 23:41:17 +0900416 TRACE("%p, %lx, %p\n", hwnd, uFlags, lpInfo);
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000417
418 if (lpInfo == NULL)
419 return FALSE;
420
421 if (!(lpInfo[0]) || !(lpInfo[1]))
422 return FALSE;
423
424 /* search for control */
425 lpMenuId = &lpInfo[2];
426 while (*lpMenuId != uFlags)
427 lpMenuId += 2;
428
Frank Richter9e570912005-08-30 10:07:17 +0000429 if (GetMenuState ((HMENU)(DWORD_PTR)lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000430 /* uncheck menu item */
Frank Richter9e570912005-08-30 10:07:17 +0000431 CheckMenuItem ((HMENU)(DWORD_PTR)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000432
433 /* hide control */
434 lpMenuId++;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000435 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000436 SWP_HIDEWINDOW);
437 }
438 else {
439 /* check menu item */
Frank Richter9e570912005-08-30 10:07:17 +0000440 CheckMenuItem ((HMENU)(DWORD_PTR)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000441
442 /* show control */
443 lpMenuId++;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000444 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000445 SWP_SHOWWINDOW);
446 }
447
448 return TRUE;
449}
450
451
452/***********************************************************************
453 * GetEffectiveClientRect [COMCTL32.4]
454 *
Robert Shearman57cc6f52004-02-27 04:40:08 +0000455 * Calculates the coordinates of a rectangle in the client area.
456 *
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000457 * PARAMS
458 * hwnd [I] handle to the client window.
459 * lpRect [O] pointer to the rectangle of the client window
Eric Kohld68d5011999-01-24 19:14:58 +0000460 * lpInfo [I] pointer to an array of integers (see NOTES)
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000461 *
462 * RETURNS
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000463 * No return value.
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000464 *
465 * NOTES
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000466 * The official documentation is incomplete!
Eric Kohld68d5011999-01-24 19:14:58 +0000467 * This is the correct documentation:
468 *
469 * lpInfo
Christian Neumair513eb2a2002-10-23 18:43:32 +0000470 * (will be written ...)
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000471 */
472
473VOID WINAPI
Andrew Talbot94ebade2007-03-22 23:02:31 +0000474GetEffectiveClientRect (HWND hwnd, LPRECT lpRect, const INT *lpInfo)
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000475{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000476 RECT rcCtrl;
Andrew Talbot94ebade2007-03-22 23:02:31 +0000477 const INT *lpRun;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000478 HWND hwndCtrl;
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000479
Frank Richter9e570912005-08-30 10:07:17 +0000480 TRACE("(%p %p %p)\n",
481 hwnd, lpRect, lpInfo);
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000482
Alexandre Julliarda3960291999-02-26 11:11:13 +0000483 GetClientRect (hwnd, lpRect);
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000484 lpRun = lpInfo;
485
486 do {
487 lpRun += 2;
488 if (*lpRun == 0)
489 return;
490 lpRun++;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000491 hwndCtrl = GetDlgItem (hwnd, *lpRun);
Dimitrie O. Paun2e0431e2005-03-23 10:22:37 +0000492 if (GetWindowLongW (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
Alexandre Julliarda099a551999-06-12 15:45:58 +0000493 TRACE("control id 0x%x\n", *lpRun);
Alexandre Julliarda3960291999-02-26 11:11:13 +0000494 GetWindowRect (hwndCtrl, &rcCtrl);
Francois Gougetd2667a42002-12-02 18:10:57 +0000495 MapWindowPoints (NULL, hwnd, (LPPOINT)&rcCtrl, 2);
Alexandre Julliarda3960291999-02-26 11:11:13 +0000496 SubtractRect (lpRect, lpRect, &rcCtrl);
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000497 }
498 lpRun++;
499 } while (*lpRun);
500}
501
502
503/***********************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +0000504 * DrawStatusTextW [COMCTL32.@]
Alexandre Julliard642d3131998-07-12 19:29:36 +0000505 *
506 * Draws text with borders, like in a status bar.
507 *
508 * PARAMS
509 * hdc [I] handle to the window's display context
510 * lprc [I] pointer to a rectangle
511 * text [I] pointer to the text
Eric Kohld68d5011999-01-24 19:14:58 +0000512 * style [I] drawing style
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000513 *
514 * RETURNS
515 * No return value.
Eric Kohld68d5011999-01-24 19:14:58 +0000516 *
517 * NOTES
518 * The style variable can have one of the following values:
519 * (will be written ...)
Alexandre Julliard17216f51997-10-12 16:30:17 +0000520 */
Alexandre Julliard642d3131998-07-12 19:29:36 +0000521
Andrew Talbot94ebade2007-03-22 23:02:31 +0000522void WINAPI DrawStatusTextW (HDC hdc, LPCRECT lprc, LPCWSTR text, UINT style)
Alexandre Julliard17216f51997-10-12 16:30:17 +0000523{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000524 RECT r = *lprc;
525 UINT border = BDR_SUNKENOUTER;
Alexandre Julliard17216f51997-10-12 16:30:17 +0000526
Alexandre Julliard0df48781999-05-29 14:14:27 +0000527 if (style & SBT_POPOUT)
Dimitrie O. Paun52e0e9c2002-04-17 16:47:48 +0000528 border = BDR_RAISEDOUTER;
Alexandre Julliard0df48781999-05-29 14:14:27 +0000529 else if (style & SBT_NOBORDERS)
Dimitrie O. Paun52e0e9c2002-04-17 16:47:48 +0000530 border = 0;
Alexandre Julliard17216f51997-10-12 16:30:17 +0000531
Dimitrie O. Paun52e0e9c2002-04-17 16:47:48 +0000532 DrawEdge (hdc, &r, border, BF_RECT|BF_ADJUST);
Alexandre Julliard17216f51997-10-12 16:30:17 +0000533
534 /* now draw text */
535 if (text) {
Dimitrie O. Paun52e0e9c2002-04-17 16:47:48 +0000536 int oldbkmode = SetBkMode (hdc, TRANSPARENT);
537 UINT align = DT_LEFT;
Igor Tarasovfb618562008-05-14 05:50:20 +0500538 int strCnt = 0;
539
Dimitrie O. Paun52e0e9c2002-04-17 16:47:48 +0000540 if (style & SBT_RTLREADING)
Igor Tarasovfb618562008-05-14 05:50:20 +0500541 FIXME("Unsupported RTL style!\n");
542 r.left += 3;
543 do {
544 if (*text == '\t') {
545 if (strCnt) {
546 DrawTextW (hdc, text - strCnt, strCnt, &r, align|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX);
547 strCnt = 0;
548 }
549 if (align==DT_RIGHT) {
550 break;
551 }
552 align = (align==DT_LEFT ? DT_CENTER : DT_RIGHT);
553 } else {
554 strCnt++;
555 }
556 } while(*text++);
557
558 if (strCnt) DrawTextW (hdc, text - strCnt, -1, &r, align|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX);
Alexandre Julliarda3960291999-02-26 11:11:13 +0000559 SetBkMode(hdc, oldbkmode);
Alexandre Julliard17216f51997-10-12 16:30:17 +0000560 }
Alexandre Julliard17216f51997-10-12 16:30:17 +0000561}
562
Alexandre Julliard642d3131998-07-12 19:29:36 +0000563
Alexandre Julliard17216f51997-10-12 16:30:17 +0000564/***********************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +0000565 * DrawStatusText [COMCTL32.@]
Dimitrie O. Paun0c165642002-01-02 21:43:48 +0000566 * DrawStatusTextA [COMCTL32.5]
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000567 *
568 * Draws text with borders, like in a status bar.
569 *
570 * PARAMS
571 * hdc [I] handle to the window's display context
572 * lprc [I] pointer to a rectangle
573 * text [I] pointer to the text
Eric Kohld68d5011999-01-24 19:14:58 +0000574 * style [I] drawing style
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000575 *
576 * RETURNS
577 * No return value.
Alexandre Julliard17216f51997-10-12 16:30:17 +0000578 */
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000579
Andrew Talbot94ebade2007-03-22 23:02:31 +0000580void WINAPI DrawStatusTextA (HDC hdc, LPCRECT lprc, LPCSTR text, UINT style)
Alexandre Julliard17216f51997-10-12 16:30:17 +0000581{
Dimitrie O. Paun0c165642002-01-02 21:43:48 +0000582 INT len;
583 LPWSTR textW = NULL;
584
585 if ( text ) {
586 if ( (len = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 )) ) {
Dimitrie O. Paun8df71a62005-03-25 20:49:00 +0000587 if ( (textW = Alloc( len * sizeof(WCHAR) )) )
Dimitrie O. Paun0c165642002-01-02 21:43:48 +0000588 MultiByteToWideChar( CP_ACP, 0, text, -1, textW, len );
589 }
590 }
591 DrawStatusTextW( hdc, lprc, textW, style );
Dimitrie O. Paun8df71a62005-03-25 20:49:00 +0000592 Free( textW );
Alexandre Julliard17216f51997-10-12 16:30:17 +0000593}
594
Alexandre Julliard642d3131998-07-12 19:29:36 +0000595
Alexandre Julliard17216f51997-10-12 16:30:17 +0000596/***********************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +0000597 * CreateStatusWindow [COMCTL32.@]
Patrik Stridvall60767292001-06-19 03:34:07 +0000598 * CreateStatusWindowA [COMCTL32.6]
Eric Kohld040e9d1998-11-08 11:33:05 +0000599 *
600 * Creates a status bar
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000601 *
602 * PARAMS
Eric Kohld68d5011999-01-24 19:14:58 +0000603 * style [I] window style
604 * text [I] pointer to the window text
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000605 * parent [I] handle to the parent window
Eric Kohl9d8e8641998-10-24 10:49:27 +0000606 * wid [I] control id of the status bar
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000607 *
608 * RETURNS
Eric Kohld68d5011999-01-24 19:14:58 +0000609 * Success: handle to the status window
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000610 * Failure: 0
Alexandre Julliard17216f51997-10-12 16:30:17 +0000611 */
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000612
Alexandre Julliarda3960291999-02-26 11:11:13 +0000613HWND WINAPI
Filip Navara1ccaaa12003-08-22 23:51:15 +0000614CreateStatusWindowA (LONG style, LPCSTR text, HWND parent, UINT wid)
Alexandre Julliard17216f51997-10-12 16:30:17 +0000615{
Vincent Béron9a624912002-05-31 23:06:46 +0000616 return CreateWindowA(STATUSCLASSNAMEA, text, style,
Alexandre Julliarda3960291999-02-26 11:11:13 +0000617 CW_USEDEFAULT, CW_USEDEFAULT,
Vincent Béron9a624912002-05-31 23:06:46 +0000618 CW_USEDEFAULT, CW_USEDEFAULT,
Frank Richter9e570912005-08-30 10:07:17 +0000619 parent, (HMENU)(DWORD_PTR)wid, 0, 0);
Alexandre Julliard17216f51997-10-12 16:30:17 +0000620}
621
Alexandre Julliard642d3131998-07-12 19:29:36 +0000622
Alexandre Julliard17216f51997-10-12 16:30:17 +0000623/***********************************************************************
Robert Shearman57cc6f52004-02-27 04:40:08 +0000624 * CreateStatusWindowW [COMCTL32.@]
625 *
626 * Creates a status bar control
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000627 *
628 * PARAMS
Eric Kohld68d5011999-01-24 19:14:58 +0000629 * style [I] window style
630 * text [I] pointer to the window text
Eric Kohl37d68ef1998-10-11 13:17:47 +0000631 * parent [I] handle to the parent window
632 * wid [I] control id of the status bar
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000633 *
634 * RETURNS
Eric Kohld68d5011999-01-24 19:14:58 +0000635 * Success: handle to the status window
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000636 * Failure: 0
Alexandre Julliard17216f51997-10-12 16:30:17 +0000637 */
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000638
Alexandre Julliarda3960291999-02-26 11:11:13 +0000639HWND WINAPI
Filip Navara1ccaaa12003-08-22 23:51:15 +0000640CreateStatusWindowW (LONG style, LPCWSTR text, HWND parent, UINT wid)
Alexandre Julliard17216f51997-10-12 16:30:17 +0000641{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000642 return CreateWindowW(STATUSCLASSNAMEW, text, style,
643 CW_USEDEFAULT, CW_USEDEFAULT,
644 CW_USEDEFAULT, CW_USEDEFAULT,
Frank Richter9e570912005-08-30 10:07:17 +0000645 parent, (HMENU)(DWORD_PTR)wid, 0, 0);
Alexandre Julliard17216f51997-10-12 16:30:17 +0000646}
647
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000648
Alexandre Julliard17216f51997-10-12 16:30:17 +0000649/***********************************************************************
Robert Shearman57cc6f52004-02-27 04:40:08 +0000650 * CreateUpDownControl [COMCTL32.16]
651 *
652 * Creates an up-down control
Eric Kohld040e9d1998-11-08 11:33:05 +0000653 *
654 * PARAMS
Eric Kohld68d5011999-01-24 19:14:58 +0000655 * style [I] window styles
656 * x [I] horizontal position of the control
657 * y [I] vertical position of the control
658 * cx [I] with of the control
659 * cy [I] height of the control
Eric Kohld040e9d1998-11-08 11:33:05 +0000660 * parent [I] handle to the parent window
Eric Kohld68d5011999-01-24 19:14:58 +0000661 * id [I] the control's identifier
662 * inst [I] handle to the application's module instance
663 * buddy [I] handle to the buddy window, can be NULL
664 * maxVal [I] upper limit of the control
665 * minVal [I] lower limit of the control
666 * curVal [I] current value of the control
Eric Kohld040e9d1998-11-08 11:33:05 +0000667 *
668 * RETURNS
Eric Kohld68d5011999-01-24 19:14:58 +0000669 * Success: handle to the updown control
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000670 * Failure: 0
Alexandre Julliard17216f51997-10-12 16:30:17 +0000671 */
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000672
Alexandre Julliarda3960291999-02-26 11:11:13 +0000673HWND WINAPI
674CreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
675 HWND parent, INT id, HINSTANCE inst,
676 HWND buddy, INT maxVal, INT minVal, INT curVal)
Alexandre Julliard17216f51997-10-12 16:30:17 +0000677{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000678 HWND hUD =
Dimitrie O. Paun2e0431e2005-03-23 10:22:37 +0000679 CreateWindowW (UPDOWN_CLASSW, 0, style, x, y, cx, cy,
Frank Richter9e570912005-08-30 10:07:17 +0000680 parent, (HMENU)(DWORD_PTR)id, inst, 0);
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000681 if (hUD) {
Dimitrie O. Paun2e0431e2005-03-23 10:22:37 +0000682 SendMessageW (hUD, UDM_SETBUDDY, (WPARAM)buddy, 0);
683 SendMessageW (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
684 SendMessageW (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000685 }
Alexandre Julliard17216f51997-10-12 16:30:17 +0000686
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000687 return hUD;
Alexandre Julliard17216f51997-10-12 16:30:17 +0000688}
689
690
691/***********************************************************************
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000692 * InitCommonControls [COMCTL32.17]
693 *
Alexandre Julliard642d3131998-07-12 19:29:36 +0000694 * Registers the common controls.
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000695 *
Alexandre Julliard642d3131998-07-12 19:29:36 +0000696 * PARAMS
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000697 * No parameters.
698 *
699 * RETURNS
700 * No return values.
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000701 *
Alexandre Julliard642d3131998-07-12 19:29:36 +0000702 * NOTES
Mikołaj Zalewskia66784c2007-03-14 12:04:47 +0100703 * This function is just a dummy - all the controls are registered at
704 * the DLL's initialization. See InitCommonContolsEx for details.
Alexandre Julliard17216f51997-10-12 16:30:17 +0000705 */
Alexandre Julliard17216f51997-10-12 16:30:17 +0000706
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000707VOID WINAPI
Patrik Stridvall9e61c1c1999-06-12 08:27:49 +0000708InitCommonControls (void)
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000709{
Alexandre Julliard17216f51997-10-12 16:30:17 +0000710}
711
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000712
713/***********************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +0000714 * InitCommonControlsEx [COMCTL32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000715 *
Alexandre Julliard642d3131998-07-12 19:29:36 +0000716 * Registers the common controls.
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000717 *
Alexandre Julliard642d3131998-07-12 19:29:36 +0000718 * PARAMS
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000719 * lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
720 *
721 * RETURNS
722 * Success: TRUE
723 * Failure: FALSE
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000724 *
725 * NOTES
Austin Englishc2a79142008-01-23 16:05:21 -0600726 * Probably all versions of comctl32 initializes the Win95 controls in DllMain
Francois Gougetf1c27ed2007-12-18 09:48:16 +0100727 * during DLL initialization. Starting from comctl32 v5.82 all the controls
Mikołaj Zalewskia66784c2007-03-14 12:04:47 +0100728 * are initialized there. We follow this behaviour and this function is just
729 * a dummy.
Christian Neumair513eb2a2002-10-23 18:43:32 +0000730 *
Mikołaj Zalewskia66784c2007-03-14 12:04:47 +0100731 * Note: when writing programs under Windows, if you don't call any function
732 * from comctl32 the linker may not link this DLL. If InitCommonControlsEx
733 * was the only comctl32 function you were calling and you remove it you may
734 * have a false impression that InitCommonControlsEx actually did something.
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000735 */
736
Alexandre Julliarda3960291999-02-26 11:11:13 +0000737BOOL WINAPI
Thomas Weidenmuellerfda77752007-01-19 13:40:04 +0100738InitCommonControlsEx (const INITCOMMONCONTROLSEX *lpInitCtrls)
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000739{
Mikołaj Zalewskia66784c2007-03-14 12:04:47 +0100740 if (!lpInitCtrls || lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
741 return FALSE;
Eric Kohl37d68ef1998-10-11 13:17:47 +0000742
Michael Ploujnikov1c16d832006-10-13 09:34:21 -0400743 TRACE("(0x%08x)\n", lpInitCtrls->dwICC);
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000744 return TRUE;
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000745}
Alexandre Julliarda845b881998-06-01 10:44:35 +0000746
747
748/***********************************************************************
Robert Shearman57cc6f52004-02-27 04:40:08 +0000749 * CreateToolbarEx [COMCTL32.@]
750 *
751 * Creates a toolbar window.
Alexandre Julliarda845b881998-06-01 10:44:35 +0000752 *
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000753 * PARAMS
754 * hwnd
755 * style
756 * wID
757 * nBitmaps
758 * hBMInst
759 * wBMID
760 * lpButtons
761 * iNumButtons
762 * dxButton
763 * dyButton
764 * dxBitmap
765 * dyBitmap
766 * uStructSize
Alexandre Julliarda845b881998-06-01 10:44:35 +0000767 *
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000768 * RETURNS
769 * Success: handle to the tool bar control
770 * Failure: 0
Alexandre Julliarda845b881998-06-01 10:44:35 +0000771 */
772
Alexandre Julliarda3960291999-02-26 11:11:13 +0000773HWND WINAPI
774CreateToolbarEx (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
Timo Kreuzerb4cc1172009-04-29 12:39:56 -0400775 HINSTANCE hBMInst, UINT_PTR wBMID, LPCTBBUTTON lpButtons,
Alexandre Julliarda3960291999-02-26 11:11:13 +0000776 INT iNumButtons, INT dxButton, INT dyButton,
777 INT dxBitmap, INT dyBitmap, UINT uStructSize)
Alexandre Julliarda845b881998-06-01 10:44:35 +0000778{
Francois Gouget0ce209c2000-09-24 03:03:52 +0000779 HWND hwndTB;
780
Francois Gouget0ce209c2000-09-24 03:03:52 +0000781 hwndTB =
Dimitrie O. Paun2e0431e2005-03-23 10:22:37 +0000782 CreateWindowExW(0, TOOLBARCLASSNAMEW, NULL, style|WS_CHILD, 0,0,100,30,
Frank Richter9e570912005-08-30 10:07:17 +0000783 hwnd, (HMENU)(DWORD_PTR)wID, COMCTL32_hModule, NULL);
Alexandre Julliarda845b881998-06-01 10:44:35 +0000784 if(hwndTB) {
785 TBADDBITMAP tbab;
786
Michael Stefaniuc9dd502a2009-12-27 23:51:33 +0100787 SendMessageW (hwndTB, TB_BUTTONSTRUCTSIZE, uStructSize, 0);
Alexandre Julliarda845b881998-06-01 10:44:35 +0000788
Francois Gouget0ce209c2000-09-24 03:03:52 +0000789 /* set bitmap and button size */
790 /*If CreateToolbarEx receives 0, windows sets default values*/
Mikołaj Zalewskica7b0c82007-04-05 12:32:47 +0200791 if (dxBitmap < 0)
Francois Gouget0ce209c2000-09-24 03:03:52 +0000792 dxBitmap = 16;
Mikołaj Zalewskica7b0c82007-04-05 12:32:47 +0200793 if (dyBitmap < 0)
794 dyBitmap = 16;
795 if (dxBitmap == 0 || dyBitmap == 0)
796 dxBitmap = dyBitmap = 16;
797 SendMessageW(hwndTB, TB_SETBITMAPSIZE, 0, MAKELPARAM(dxBitmap, dyBitmap));
Pascal Lessard60935ec1999-03-25 16:42:27 +0000798
Mikołaj Zalewskic9ca25a2007-03-19 10:40:53 +0100799 if (dxButton < 0)
800 dxButton = dxBitmap;
801 if (dyButton < 0)
802 dyButton = dyBitmap;
803 /* TB_SETBUTTONSIZE -> TB_SETBITMAPSIZE bug introduced for Windows compatibility */
804 if (dxButton != 0 && dyButton != 0)
805 SendMessageW(hwndTB, TB_SETBITMAPSIZE, 0, MAKELPARAM(dxButton, dyButton));
Pascal Lessard60935ec1999-03-25 16:42:27 +0000806
Alexandre Julliarda845b881998-06-01 10:44:35 +0000807
Alexandre Julliard829fe321998-07-26 14:27:39 +0000808 /* add bitmaps */
Jason Edmeades718e23f2007-07-25 20:51:18 +0100809 if (nBitmaps > 0 || hBMInst == HINST_COMMCTRL)
Pascal Lessard60935ec1999-03-25 16:42:27 +0000810 {
Dimitrie O. Paun2e0431e2005-03-23 10:22:37 +0000811 tbab.hInst = hBMInst;
812 tbab.nID = wBMID;
Pascal Lessard60935ec1999-03-25 16:42:27 +0000813
Michael Stefaniuc9dd502a2009-12-27 23:51:33 +0100814 SendMessageW (hwndTB, TB_ADDBITMAP, nBitmaps, (LPARAM)&tbab);
Pascal Lessard60935ec1999-03-25 16:42:27 +0000815 }
Alexandre Julliarda845b881998-06-01 10:44:35 +0000816 /* add buttons */
Pascal Lessard60935ec1999-03-25 16:42:27 +0000817 if(iNumButtons > 0)
Michael Stefaniuc9dd502a2009-12-27 23:51:33 +0100818 SendMessageW (hwndTB, TB_ADDBUTTONSW, iNumButtons, (LPARAM)lpButtons);
Alexandre Julliarda845b881998-06-01 10:44:35 +0000819 }
820
Alexandre Julliardf90efa91998-06-14 15:24:15 +0000821 return hwndTB;
Alexandre Julliarda845b881998-06-01 10:44:35 +0000822}
823
824
825/***********************************************************************
826 * CreateMappedBitmap [COMCTL32.8]
827 *
Robert Shearman57cc6f52004-02-27 04:40:08 +0000828 * Loads a bitmap resource using a colour map.
829 *
Alexandre Julliard642d3131998-07-12 19:29:36 +0000830 * PARAMS
Robert Shearman57cc6f52004-02-27 04:40:08 +0000831 * hInstance [I] Handle to the module containing the bitmap.
832 * idBitmap [I] The bitmap resource ID.
833 * wFlags [I] CMB_MASKED for using bitmap as a mask or 0 for normal.
834 * lpColorMap [I] Colour information needed for the bitmap or NULL (uses system colours).
835 * iNumMaps [I] Number of COLORMAP's pointed to by lpColorMap.
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000836 *
837 * RETURNS
Eric Kohld68d5011999-01-24 19:14:58 +0000838 * Success: handle to the new bitmap
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000839 * Failure: 0
Alexandre Julliarda845b881998-06-01 10:44:35 +0000840 */
841
Alexandre Julliarda3960291999-02-26 11:11:13 +0000842HBITMAP WINAPI
Frank Richter9e570912005-08-30 10:07:17 +0000843CreateMappedBitmap (HINSTANCE hInstance, INT_PTR idBitmap, UINT wFlags,
Alexandre Julliarda3960291999-02-26 11:11:13 +0000844 LPCOLORMAP lpColorMap, INT iNumMaps)
Alexandre Julliarda845b881998-06-01 10:44:35 +0000845{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000846 HGLOBAL hglb;
847 HRSRC hRsrc;
Andrew Talbot94ebade2007-03-22 23:02:31 +0000848 const BITMAPINFOHEADER *lpBitmap;
849 LPBITMAPINFOHEADER lpBitmapInfo;
Hans Leidekker411fc5f2004-09-02 23:00:53 +0000850 UINT nSize, nColorTableSize, iColor;
Stephane Lussier62c90d61999-09-11 16:23:35 +0000851 RGBQUAD *pColorTable;
Hans Leidekker411fc5f2004-09-02 23:00:53 +0000852 INT i, iMaps, nWidth, nHeight;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000853 HDC hdcScreen;
854 HBITMAP hbm;
Alexandre Julliard642d3131998-07-12 19:29:36 +0000855 LPCOLORMAP sysColorMap;
Stephane Lussier62c90d61999-09-11 16:23:35 +0000856 COLORREF cRef;
Alexandre Julliard642d3131998-07-12 19:29:36 +0000857 COLORMAP internalColorMap[4] =
858 {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
Alexandre Julliarda845b881998-06-01 10:44:35 +0000859
Alexandre Julliard642d3131998-07-12 19:29:36 +0000860 /* initialize pointer to colortable and default color table */
861 if (lpColorMap) {
862 iMaps = iNumMaps;
863 sysColorMap = lpColorMap;
864 }
865 else {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000866 internalColorMap[0].to = GetSysColor (COLOR_BTNTEXT);
867 internalColorMap[1].to = GetSysColor (COLOR_BTNSHADOW);
868 internalColorMap[2].to = GetSysColor (COLOR_BTNFACE);
869 internalColorMap[3].to = GetSysColor (COLOR_BTNHIGHLIGHT);
Alexandre Julliard642d3131998-07-12 19:29:36 +0000870 iMaps = 4;
Michael Stefaniucda6d7922009-02-13 10:21:25 +0100871 sysColorMap = internalColorMap;
Alexandre Julliard642d3131998-07-12 19:29:36 +0000872 }
Alexandre Julliarda845b881998-06-01 10:44:35 +0000873
Dimitrie O. Paun2e0431e2005-03-23 10:22:37 +0000874 hRsrc = FindResourceW (hInstance, (LPWSTR)idBitmap, (LPWSTR)RT_BITMAP);
Alexandre Julliard829fe321998-07-26 14:27:39 +0000875 if (hRsrc == 0)
876 return 0;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000877 hglb = LoadResource (hInstance, hRsrc);
Alexandre Julliard829fe321998-07-26 14:27:39 +0000878 if (hglb == 0)
879 return 0;
Michael Stefaniuc6060ca92008-10-23 23:52:45 +0200880 lpBitmap = LockResource (hglb);
Alexandre Julliard642d3131998-07-12 19:29:36 +0000881 if (lpBitmap == NULL)
Alexandre Julliard829fe321998-07-26 14:27:39 +0000882 return 0;
Alexandre Julliard642d3131998-07-12 19:29:36 +0000883
Filip Navarafb6aa772004-07-21 21:19:08 +0000884 if (lpBitmap->biSize >= sizeof(BITMAPINFOHEADER) && lpBitmap->biClrUsed)
885 nColorTableSize = lpBitmap->biClrUsed;
886 else if (lpBitmap->biBitCount <= 8)
887 nColorTableSize = (1 << lpBitmap->biBitCount);
888 else
889 nColorTableSize = 0;
Alexandre Julliard642d3131998-07-12 19:29:36 +0000890 nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
Michael Stefaniucb12fbe12008-10-28 23:35:49 +0100891 lpBitmapInfo = GlobalAlloc (GMEM_FIXED, nSize);
Alexandre Julliard642d3131998-07-12 19:29:36 +0000892 if (lpBitmapInfo == NULL)
Alexandre Julliard829fe321998-07-26 14:27:39 +0000893 return 0;
Alexandre Julliard642d3131998-07-12 19:29:36 +0000894 RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
895
Andrew Talbot867f2542007-12-29 15:37:34 +0000896 pColorTable = (RGBQUAD*)(((LPBYTE)lpBitmapInfo) + lpBitmapInfo->biSize);
Alexandre Julliard642d3131998-07-12 19:29:36 +0000897
898 for (iColor = 0; iColor < nColorTableSize; iColor++) {
899 for (i = 0; i < iMaps; i++) {
Stephane Lussier62c90d61999-09-11 16:23:35 +0000900 cRef = RGB(pColorTable[iColor].rgbRed,
901 pColorTable[iColor].rgbGreen,
902 pColorTable[iColor].rgbBlue);
903 if ( cRef == sysColorMap[i].from) {
Alexandre Julliard642d3131998-07-12 19:29:36 +0000904#if 0
905 if (wFlags & CBS_MASKED) {
906 if (sysColorMap[i].to != COLOR_BTNTEXT)
907 pColorTable[iColor] = RGB(255, 255, 255);
908 }
909 else
910#endif
Stephane Lussier62c90d61999-09-11 16:23:35 +0000911 pColorTable[iColor].rgbBlue = GetBValue(sysColorMap[i].to);
912 pColorTable[iColor].rgbGreen = GetGValue(sysColorMap[i].to);
913 pColorTable[iColor].rgbRed = GetRValue(sysColorMap[i].to);
Alexandre Julliard642d3131998-07-12 19:29:36 +0000914 break;
915 }
916 }
917 }
Andrew Talbot867f2542007-12-29 15:37:34 +0000918 nWidth = lpBitmapInfo->biWidth;
919 nHeight = lpBitmapInfo->biHeight;
Francois Gougetd2667a42002-12-02 18:10:57 +0000920 hdcScreen = GetDC (NULL);
Alexandre Julliarda3960291999-02-26 11:11:13 +0000921 hbm = CreateCompatibleBitmap (hdcScreen, nWidth, nHeight);
Alexandre Julliard642d3131998-07-12 19:29:36 +0000922 if (hbm) {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000923 HDC hdcDst = CreateCompatibleDC (hdcScreen);
924 HBITMAP hbmOld = SelectObject (hdcDst, hbm);
Alexandre Julliard5d6e0522010-04-21 14:56:37 +0200925 const BYTE *lpBits = (const BYTE *)lpBitmap + nSize;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000926 StretchDIBits (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
Alexandre Julliard642d3131998-07-12 19:29:36 +0000927 lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
928 SRCCOPY);
Alexandre Julliarda3960291999-02-26 11:11:13 +0000929 SelectObject (hdcDst, hbmOld);
930 DeleteDC (hdcDst);
Alexandre Julliard642d3131998-07-12 19:29:36 +0000931 }
Francois Gougetd2667a42002-12-02 18:10:57 +0000932 ReleaseDC (NULL, hdcScreen);
Michael Stefaniucc46a88a2008-11-07 00:56:07 +0100933 GlobalFree (lpBitmapInfo);
Alexandre Julliarda3960291999-02-26 11:11:13 +0000934 FreeResource (hglb);
Alexandre Julliarda845b881998-06-01 10:44:35 +0000935
936 return hbm;
Alexandre Julliard642d3131998-07-12 19:29:36 +0000937}
Alexandre Julliarda845b881998-06-01 10:44:35 +0000938
939
940/***********************************************************************
Robert Shearman57cc6f52004-02-27 04:40:08 +0000941 * CreateToolbar [COMCTL32.7]
942 *
943 * Creates a toolbar control.
Alexandre Julliarda845b881998-06-01 10:44:35 +0000944 *
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000945 * PARAMS
946 * hwnd
947 * style
948 * wID
949 * nBitmaps
950 * hBMInst
951 * wBMID
952 * lpButtons
953 * iNumButtons
Alexandre Julliarda845b881998-06-01 10:44:35 +0000954 *
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000955 * RETURNS
956 * Success: handle to the tool bar control
957 * Failure: 0
Alexandre Julliarda845b881998-06-01 10:44:35 +0000958 *
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000959 * NOTES
960 * Do not use this functions anymore. Use CreateToolbarEx instead.
Alexandre Julliarda845b881998-06-01 10:44:35 +0000961 */
962
Alexandre Julliarda3960291999-02-26 11:11:13 +0000963HWND WINAPI
964CreateToolbar (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
965 HINSTANCE hBMInst, UINT wBMID,
Filip Navara1ccaaa12003-08-22 23:51:15 +0000966 LPCTBBUTTON lpButtons,INT iNumButtons)
Alexandre Julliarda845b881998-06-01 10:44:35 +0000967{
968 return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
Filip Navara1ccaaa12003-08-22 23:51:15 +0000969 hBMInst, wBMID, lpButtons,
970 iNumButtons, 0, 0, 0, 0, CCSIZEOF_STRUCT(TBBUTTON, dwData));
Alexandre Julliarda845b881998-06-01 10:44:35 +0000971}
972
Alexandre Julliardf90efa91998-06-14 15:24:15 +0000973
974/***********************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +0000975 * DllGetVersion [COMCTL32.@]
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000976 *
977 * Retrieves version information of the 'COMCTL32.DLL'
Alexandre Julliardf90efa91998-06-14 15:24:15 +0000978 *
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000979 * PARAMS
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000980 * pdvi [O] pointer to version information structure.
Alexandre Julliardf90efa91998-06-14 15:24:15 +0000981 *
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000982 * RETURNS
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000983 * Success: S_OK
984 * Failure: E_INVALIDARG
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000985 *
986 * NOTES
987 * Returns version of a comctl32.dll from IE4.01 SP1.
Alexandre Julliardf90efa91998-06-14 15:24:15 +0000988 */
989
Alexandre Julliardd37f0ab2005-08-08 17:35:28 +0000990HRESULT WINAPI DllGetVersion (DLLVERSIONINFO *pdvi)
Alexandre Julliardf90efa91998-06-14 15:24:15 +0000991{
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000992 if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
Francois Gougete76218d2001-05-09 17:31:31 +0000993 WARN("wrong DLLVERSIONINFO size from app\n");
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000994 return E_INVALIDARG;
Alexandre Julliard642d3131998-07-12 19:29:36 +0000995 }
996
Gerard Patel8b21b6b2001-03-16 16:50:24 +0000997 pdvi->dwMajorVersion = COMCTL32_VERSION;
998 pdvi->dwMinorVersion = COMCTL32_VERSION_MINOR;
Eric Kohlb3f681e2000-06-03 21:06:44 +0000999 pdvi->dwBuildNumber = 2919;
1000 pdvi->dwPlatformID = 6304;
Alexandre Julliarda0d77311998-09-13 16:32:00 +00001001
Michael Ploujnikov1c16d832006-10-13 09:34:21 -04001002 TRACE("%u.%u.%u.%u\n",
Alexandre Julliarda0d77311998-09-13 16:32:00 +00001003 pdvi->dwMajorVersion, pdvi->dwMinorVersion,
1004 pdvi->dwBuildNumber, pdvi->dwPlatformID);
1005
1006 return S_OK;
Alexandre Julliardf90efa91998-06-14 15:24:15 +00001007}
Shaun Morris271f5221999-12-20 03:48:25 +00001008
Patrik Stridvall55ef9a52000-04-24 18:03:54 +00001009/***********************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00001010 * DllInstall (COMCTL32.@)
Robert Shearman57cc6f52004-02-27 04:40:08 +00001011 *
1012 * Installs the ComCtl32 DLL.
1013 *
1014 * RETURNS
1015 * Success: S_OK
1016 * Failure: A HRESULT error
Patrik Stridvall55ef9a52000-04-24 18:03:54 +00001017 */
Alexandre Julliardd37f0ab2005-08-08 17:35:28 +00001018HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline)
Patrik Stridvall55ef9a52000-04-24 18:03:54 +00001019{
Alexandre Julliard6790cdb2007-08-14 12:31:27 +02001020 TRACE("(%u, %s): stub\n", bInstall, debugstr_w(cmdline));
1021 if (!create_manifest( bInstall )) return HRESULT_FROM_WIN32(GetLastError());
1022 return S_OK;
Patrik Stridvall55ef9a52000-04-24 18:03:54 +00001023}
Shaun Morris271f5221999-12-20 03:48:25 +00001024
Shaun Morris271f5221999-12-20 03:48:25 +00001025/***********************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00001026 * _TrackMouseEvent [COMCTL32.@]
Shaun Morris271f5221999-12-20 03:48:25 +00001027 *
1028 * Requests notification of mouse events
1029 *
Alexandre Julliard2fb5dee2000-04-28 20:49:20 +00001030 * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted
1031 * to the hwnd specified in the ptme structure. After the event message
1032 * is posted to the hwnd, the entry in the queue is removed.
1033 *
1034 * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely
1035 * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted
1036 * immediately and the TME_LEAVE flag being ignored.
1037 *
Shaun Morris271f5221999-12-20 03:48:25 +00001038 * PARAMS
1039 * ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
1040 *
1041 * RETURNS
1042 * Success: non-zero
1043 * Failure: zero
1044 *
Rein Klazes49762a32002-01-15 20:41:41 +00001045 * IMPLEMENTATION moved to USER32.TrackMouseEvent
1046 *
Shaun Morris271f5221999-12-20 03:48:25 +00001047 */
1048
1049BOOL WINAPI
1050_TrackMouseEvent (TRACKMOUSEEVENT *ptme)
1051{
Rein Klazes49762a32002-01-15 20:41:41 +00001052 return TrackMouseEvent (ptme);
Shaun Morris271f5221999-12-20 03:48:25 +00001053}
Eric Kohlb3f681e2000-06-03 21:06:44 +00001054
Eric Kohlb3f681e2000-06-03 21:06:44 +00001055/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00001056 * GetMUILanguage [COMCTL32.@]
Eric Kohlb3f681e2000-06-03 21:06:44 +00001057 *
Robert Shearman57cc6f52004-02-27 04:40:08 +00001058 * Returns the user interface language in use by the current process.
Eric Kohlb3f681e2000-06-03 21:06:44 +00001059 *
Robert Shearman57cc6f52004-02-27 04:40:08 +00001060 * RETURNS
1061 * Language ID in use by the current process.
Eric Kohlb3f681e2000-06-03 21:06:44 +00001062 */
1063LANGID WINAPI GetMUILanguage (VOID)
1064{
1065 return COMCTL32_uiLang;
1066}
1067
1068
1069/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00001070 * InitMUILanguage [COMCTL32.@]
Eric Kohlb3f681e2000-06-03 21:06:44 +00001071 *
Robert Shearman57cc6f52004-02-27 04:40:08 +00001072 * Sets the user interface language to be used by the current process.
Eric Kohlb3f681e2000-06-03 21:06:44 +00001073 *
Robert Shearman57cc6f52004-02-27 04:40:08 +00001074 * RETURNS
1075 * Nothing.
Eric Kohlb3f681e2000-06-03 21:06:44 +00001076 */
Eric Kohlb3f681e2000-06-03 21:06:44 +00001077VOID WINAPI InitMUILanguage (LANGID uiLang)
1078{
1079 COMCTL32_uiLang = uiLang;
1080}
Chris Morgan5f9fd772000-09-13 20:27:30 +00001081
1082
1083/***********************************************************************
Alexandre Julliarddd74d9d2003-05-11 03:40:59 +00001084 * SetWindowSubclass [COMCTL32.410]
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001085 *
1086 * Starts a window subclass
1087 *
1088 * PARAMS
1089 * hWnd [in] handle to window subclass.
1090 * pfnSubclass [in] Pointer to new window procedure.
1091 * uIDSubclass [in] Unique identifier of sublass together with pfnSubclass.
1092 * dwRef [in] Reference data to pass to window procedure.
1093 *
1094 * RETURNS
1095 * Success: non-zero
1096 * Failure: zero
1097 *
1098 * BUGS
1099 * If an application manually subclasses a window after subclassing it with
Christian Neumair513eb2a2002-10-23 18:43:32 +00001100 * this API and then with this API again, then none of the previous
Austin Englishc2a79142008-01-23 16:05:21 -06001101 * subclasses get called or the original window procedure.
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001102 */
Christian Neumair513eb2a2002-10-23 18:43:32 +00001103
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001104BOOL WINAPI SetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
1105 UINT_PTR uIDSubclass, DWORD_PTR dwRef)
1106{
1107 LPSUBCLASS_INFO stack;
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001108 LPSUBCLASSPROCS proc;
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001109
Dmitry Timoshkov3c9e7a72007-05-24 23:41:17 +09001110 TRACE ("(%p, %p, %lx, %lx)\n", hWnd, pfnSubclass, uIDSubclass, dwRef);
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001111
1112 /* Since the window procedure that we set here has two additional arguments,
1113 * we can't simply set it as the new window procedure of the window. So we
1114 * set our own window procedure and then calculate the other two arguments
1115 * from there. */
1116
1117 /* See if we have been called for this window */
Michael Stefaniucb12fbe12008-10-28 23:35:49 +01001118 stack = GetPropW (hWnd, COMCTL32_wSubclass);
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001119 if (!stack) {
1120 /* allocate stack */
Dimitrie O. Paun8df71a62005-03-25 20:49:00 +00001121 stack = Alloc (sizeof(SUBCLASS_INFO));
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001122 if (!stack) {
Francois Gouget6b6ed722004-01-27 00:01:43 +00001123 ERR ("Failed to allocate our Subclassing stack\n");
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001124 return FALSE;
1125 }
Michael Stefaniucda6d7922009-02-13 10:21:25 +01001126 SetPropW (hWnd, COMCTL32_wSubclass, stack);
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001127
1128 /* set window procedure to our own and save the current one */
1129 if (IsWindowUnicode (hWnd))
Robert Shearmancdb263e2004-08-25 17:33:01 +00001130 stack->origproc = (WNDPROC)SetWindowLongPtrW (hWnd, GWLP_WNDPROC,
1131 (DWORD_PTR)COMCTL32_SubclassProc);
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001132 else
Robert Shearmancdb263e2004-08-25 17:33:01 +00001133 stack->origproc = (WNDPROC)SetWindowLongPtrA (hWnd, GWLP_WNDPROC,
1134 (DWORD_PTR)COMCTL32_SubclassProc);
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001135 }
1136 else {
1137 /* Check to see if we have called this function with the same uIDSubClass
1138 * and pfnSubclass */
1139 proc = stack->SubclassProcs;
1140 while (proc) {
1141 if ((proc->id == uIDSubclass) &&
1142 (proc->subproc == pfnSubclass)) {
1143 proc->ref = dwRef;
1144 return TRUE;
1145 }
1146 proc = proc->next;
György 'Nog' Jeney748425e2002-10-03 23:01:01 +00001147 }
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001148 }
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001149
Dimitrie O. Paun8df71a62005-03-25 20:49:00 +00001150 proc = Alloc(sizeof(SUBCLASSPROCS));
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001151 if (!proc) {
1152 ERR ("Failed to allocate subclass entry in stack\n");
1153 if (IsWindowUnicode (hWnd))
Robert Shearmancdb263e2004-08-25 17:33:01 +00001154 SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001155 else
Robert Shearmancdb263e2004-08-25 17:33:01 +00001156 SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
Dimitrie O. Paun8df71a62005-03-25 20:49:00 +00001157 Free (stack);
Dimitrie O. Paun2e0431e2005-03-23 10:22:37 +00001158 RemovePropW( hWnd, COMCTL32_wSubclass );
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001159 return FALSE;
1160 }
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001161
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001162 proc->subproc = pfnSubclass;
1163 proc->ref = dwRef;
1164 proc->id = uIDSubclass;
1165 proc->next = stack->SubclassProcs;
1166 stack->SubclassProcs = proc;
1167
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001168 return TRUE;
1169}
1170
1171
1172/***********************************************************************
Alexandre Julliarddd74d9d2003-05-11 03:40:59 +00001173 * GetWindowSubclass [COMCTL32.411]
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001174 *
1175 * Gets the Reference data from a subclass.
1176 *
1177 * PARAMS
1178 * hWnd [in] Handle to window which were subclassing
1179 * pfnSubclass [in] Pointer to the subclass procedure
Jon Griffithscd4234a2003-03-18 18:35:48 +00001180 * uID [in] Unique indentifier of the subclassing procedure
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001181 * pdwRef [out] Pointer to the reference data
1182 *
1183 * RETURNS
Jon Griffithscd4234a2003-03-18 18:35:48 +00001184 * Success: Non-zero
1185 * Failure: 0
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001186 */
Christian Neumair513eb2a2002-10-23 18:43:32 +00001187
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001188BOOL WINAPI GetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
1189 UINT_PTR uID, DWORD_PTR *pdwRef)
1190{
Andrew Talbot94ebade2007-03-22 23:02:31 +00001191 const SUBCLASS_INFO *stack;
1192 const SUBCLASSPROCS *proc;
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001193
Dmitry Timoshkov3c9e7a72007-05-24 23:41:17 +09001194 TRACE ("(%p, %p, %lx, %p)\n", hWnd, pfnSubclass, uID, pdwRef);
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001195
1196 /* See if we have been called for this window */
Michael Stefaniucb12fbe12008-10-28 23:35:49 +01001197 stack = GetPropW (hWnd, COMCTL32_wSubclass);
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001198 if (!stack)
1199 return FALSE;
1200
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001201 proc = stack->SubclassProcs;
1202 while (proc) {
1203 if ((proc->id == uID) &&
1204 (proc->subproc == pfnSubclass)) {
1205 *pdwRef = proc->ref;
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001206 return TRUE;
1207 }
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001208 proc = proc->next;
1209 }
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001210
1211 return FALSE;
1212}
1213
1214
1215/***********************************************************************
Alexandre Julliarddd74d9d2003-05-11 03:40:59 +00001216 * RemoveWindowSubclass [COMCTL32.412]
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001217 *
1218 * Removes a window subclass.
1219 *
1220 * PARAMS
1221 * hWnd [in] Handle to the window were subclassing
1222 * pfnSubclass [in] Pointer to the subclass procedure
1223 * uID [in] Unique identifier of this subclass
1224 *
1225 * RETURNS
1226 * Success: non-zero
1227 * Failure: zero
1228 */
Christian Neumair513eb2a2002-10-23 18:43:32 +00001229
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001230BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uID)
1231{
1232 LPSUBCLASS_INFO stack;
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001233 LPSUBCLASSPROCS prevproc = NULL;
1234 LPSUBCLASSPROCS proc;
1235 BOOL ret = FALSE;
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001236
Dmitry Timoshkov3c9e7a72007-05-24 23:41:17 +09001237 TRACE ("(%p, %p, %lx)\n", hWnd, pfnSubclass, uID);
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001238
1239 /* Find the Subclass to remove */
Michael Stefaniucb12fbe12008-10-28 23:35:49 +01001240 stack = GetPropW (hWnd, COMCTL32_wSubclass);
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001241 if (!stack)
1242 return FALSE;
1243
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001244 proc = stack->SubclassProcs;
1245 while (proc) {
1246 if ((proc->id == uID) &&
1247 (proc->subproc == pfnSubclass)) {
1248
1249 if (!prevproc)
1250 stack->SubclassProcs = proc->next;
1251 else
1252 prevproc->next = proc->next;
1253
1254 if (stack->stackpos == proc)
1255 stack->stackpos = stack->stackpos->next;
1256
Dimitrie O. Paun8df71a62005-03-25 20:49:00 +00001257 Free (proc);
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001258 ret = TRUE;
1259 break;
1260 }
1261 prevproc = proc;
1262 proc = proc->next;
1263 }
1264
1265 if (!stack->SubclassProcs && !stack->running) {
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001266 TRACE("Last Subclass removed, cleaning up\n");
Austin Englishc2a79142008-01-23 16:05:21 -06001267 /* clean up our heap and reset the original window procedure */
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001268 if (IsWindowUnicode (hWnd))
Robert Shearmancdb263e2004-08-25 17:33:01 +00001269 SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001270 else
Robert Shearmancdb263e2004-08-25 17:33:01 +00001271 SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
Dimitrie O. Paun8df71a62005-03-25 20:49:00 +00001272 Free (stack);
Dimitrie O. Paun2e0431e2005-03-23 10:22:37 +00001273 RemovePropW( hWnd, COMCTL32_wSubclass );
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001274 }
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001275
1276 return ret;
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001277}
1278
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001279/***********************************************************************
1280 * COMCTL32_SubclassProc (internal)
1281 *
1282 * Window procedure for all subclassed windows.
1283 * Saves the current subclassing stack position to support nested messages
1284 */
Alexandre Julliardc6aebe12008-12-04 12:46:45 +01001285static LRESULT WINAPI COMCTL32_SubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001286{
1287 LPSUBCLASS_INFO stack;
1288 LPSUBCLASSPROCS proc;
1289 LRESULT ret;
1290
Dmitry Timoshkov3c9e7a72007-05-24 23:41:17 +09001291 TRACE ("(%p, 0x%08x, 0x%08lx, 0x%08lx)\n", hWnd, uMsg, wParam, lParam);
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001292
Michael Stefaniucb12fbe12008-10-28 23:35:49 +01001293 stack = GetPropW (hWnd, COMCTL32_wSubclass);
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001294 if (!stack) {
1295 ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd);
1296 return 0;
1297 }
1298
1299 /* Save our old stackpos to properly handle nested messages */
1300 proc = stack->stackpos;
1301 stack->stackpos = stack->SubclassProcs;
Kevin Koltzauc95959d2004-09-06 20:26:04 +00001302 stack->running++;
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001303 ret = DefSubclassProc(hWnd, uMsg, wParam, lParam);
Kevin Koltzauc95959d2004-09-06 20:26:04 +00001304 stack->running--;
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001305 stack->stackpos = proc;
1306
Ge van Geldorp4e44eb22004-10-18 23:14:38 +00001307 if (!stack->SubclassProcs && !stack->running) {
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001308 TRACE("Last Subclass removed, cleaning up\n");
Austin Englishc2a79142008-01-23 16:05:21 -06001309 /* clean up our heap and reset the original window procedure */
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001310 if (IsWindowUnicode (hWnd))
Robert Shearmancdb263e2004-08-25 17:33:01 +00001311 SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001312 else
Robert Shearmancdb263e2004-08-25 17:33:01 +00001313 SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
Dimitrie O. Paun8df71a62005-03-25 20:49:00 +00001314 Free (stack);
Dimitrie O. Paun2e0431e2005-03-23 10:22:37 +00001315 RemovePropW( hWnd, COMCTL32_wSubclass );
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001316 }
1317 return ret;
1318}
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001319
1320/***********************************************************************
Alexandre Julliarddd74d9d2003-05-11 03:40:59 +00001321 * DefSubclassProc [COMCTL32.413]
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001322 *
1323 * Calls the next window procedure (ie. the one before this subclass)
1324 *
1325 * PARAMS
1326 * hWnd [in] The window that we're subclassing
1327 * uMsg [in] Message
1328 * wParam [in] WPARAM
1329 * lParam [in] LPARAM
1330 *
1331 * RETURNS
1332 * Success: non-zero
1333 * Failure: zero
1334 */
Christian Neumair513eb2a2002-10-23 18:43:32 +00001335
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001336LRESULT WINAPI DefSubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1337{
1338 LPSUBCLASS_INFO stack;
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001339 LRESULT ret;
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001340
Dmitry Timoshkov3c9e7a72007-05-24 23:41:17 +09001341 TRACE ("(%p, 0x%08x, 0x%08lx, 0x%08lx)\n", hWnd, uMsg, wParam, lParam);
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001342
1343 /* retrieve our little stack from the Properties */
Michael Stefaniucb12fbe12008-10-28 23:35:49 +01001344 stack = GetPropW (hWnd, COMCTL32_wSubclass);
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001345 if (!stack) {
Michael Stefaniuc353529b2002-10-23 22:19:10 +00001346 ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd);
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001347 return 0;
1348 }
1349
Filip Navarac8aba952004-05-17 19:48:24 +00001350 /* If we are at the end of stack then we have to call the original
1351 * window procedure */
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001352 if (!stack->stackpos) {
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001353 if (IsWindowUnicode (hWnd))
Filip Navarac8aba952004-05-17 19:48:24 +00001354 ret = CallWindowProcW (stack->origproc, hWnd, uMsg, wParam, lParam);
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001355 else
Filip Navarac8aba952004-05-17 19:48:24 +00001356 ret = CallWindowProcA (stack->origproc, hWnd, uMsg, wParam, lParam);
1357 } else {
Andrew Talbot94ebade2007-03-22 23:02:31 +00001358 const SUBCLASSPROCS *proc = stack->stackpos;
Kevin Koltzau59302ae2004-08-22 22:29:37 +00001359 stack->stackpos = stack->stackpos->next;
Filip Navarac8aba952004-05-17 19:48:24 +00001360 /* call the Subclass procedure from the stack */
Kevin Koltzauc95959d2004-09-06 20:26:04 +00001361 ret = proc->subproc (hWnd, uMsg, wParam, lParam,
1362 proc->id, proc->ref);
György 'Nog' Jeneyf9c01112002-10-02 20:01:01 +00001363 }
1364
1365 return ret;
1366}
1367
1368
1369/***********************************************************************
Chris Morgan5f9fd772000-09-13 20:27:30 +00001370 * COMCTL32_CreateToolTip [NOT AN API]
1371 *
1372 * Creates a tooltip for the control specified in hwnd and does all
1373 * necessary setup and notifications.
1374 *
1375 * PARAMS
1376 * hwndOwner [I] Handle to the window that will own the tool tip.
1377 *
1378 * RETURNS
1379 * Success: Handle of tool tip window.
1380 * Failure: NULL
1381 */
Christian Neumair513eb2a2002-10-23 18:43:32 +00001382
Chris Morgan5f9fd772000-09-13 20:27:30 +00001383HWND
1384COMCTL32_CreateToolTip(HWND hwndOwner)
1385{
1386 HWND hwndToolTip;
1387
Oleg Krylov32caf302006-10-25 13:31:44 +03001388 hwndToolTip = CreateWindowExW(0, TOOLTIPS_CLASSW, NULL, WS_POPUP,
Chris Morgan5f9fd772000-09-13 20:27:30 +00001389 CW_USEDEFAULT, CW_USEDEFAULT,
1390 CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner,
1391 0, 0, 0);
1392
1393 /* Send NM_TOOLTIPSCREATED notification */
1394 if (hwndToolTip)
1395 {
1396 NMTOOLTIPSCREATED nmttc;
Gerard Pateld834e4c2001-01-09 20:50:13 +00001397 /* true owner can be different if hwndOwner is a child window */
1398 HWND hwndTrueOwner = GetWindow(hwndToolTip, GW_OWNER);
1399 nmttc.hdr.hwndFrom = hwndTrueOwner;
Robert Shearmancdb263e2004-08-25 17:33:01 +00001400 nmttc.hdr.idFrom = GetWindowLongPtrW(hwndTrueOwner, GWLP_ID);
Chris Morgan5f9fd772000-09-13 20:27:30 +00001401 nmttc.hdr.code = NM_TOOLTIPSCREATED;
1402 nmttc.hwndToolTips = hwndToolTip;
1403
Michael Stefaniuc9dd502a2009-12-27 23:51:33 +01001404 SendMessageW(GetParent(hwndTrueOwner), WM_NOTIFY,
1405 GetWindowLongPtrW(hwndTrueOwner, GWLP_ID), (LPARAM)&nmttc);
Chris Morgan5f9fd772000-09-13 20:27:30 +00001406 }
1407
1408 return hwndToolTip;
1409}
Guy L. Albertelli35d8e1e2002-04-05 21:14:05 +00001410
1411
1412/***********************************************************************
1413 * COMCTL32_RefreshSysColors [NOT AN API]
1414 *
1415 * Invoked on any control recognizing a WM_SYSCOLORCHANGE message to
1416 * refresh the color values in the color structure
1417 *
1418 * PARAMS
1419 * none
1420 *
1421 * RETURNS
1422 * none
1423 */
Christian Neumair513eb2a2002-10-23 18:43:32 +00001424
Guy L. Albertelli35d8e1e2002-04-05 21:14:05 +00001425VOID
1426COMCTL32_RefreshSysColors(void)
1427{
1428 comctl32_color.clrBtnHighlight = GetSysColor (COLOR_BTNHIGHLIGHT);
1429 comctl32_color.clrBtnShadow = GetSysColor (COLOR_BTNSHADOW);
1430 comctl32_color.clrBtnText = GetSysColor (COLOR_BTNTEXT);
1431 comctl32_color.clrBtnFace = GetSysColor (COLOR_BTNFACE);
1432 comctl32_color.clrHighlight = GetSysColor (COLOR_HIGHLIGHT);
1433 comctl32_color.clrHighlightText = GetSysColor (COLOR_HIGHLIGHTTEXT);
Anatoly Lyutind8ab4af2008-03-25 19:15:59 +03001434 comctl32_color.clrHotTrackingColor = GetSysColor (COLOR_HOTLIGHT);
Guy L. Albertelli35d8e1e2002-04-05 21:14:05 +00001435 comctl32_color.clr3dHilight = GetSysColor (COLOR_3DHILIGHT);
1436 comctl32_color.clr3dShadow = GetSysColor (COLOR_3DSHADOW);
1437 comctl32_color.clr3dDkShadow = GetSysColor (COLOR_3DDKSHADOW);
1438 comctl32_color.clr3dFace = GetSysColor (COLOR_3DFACE);
1439 comctl32_color.clrWindow = GetSysColor (COLOR_WINDOW);
1440 comctl32_color.clrWindowText = GetSysColor (COLOR_WINDOWTEXT);
1441 comctl32_color.clrGrayText = GetSysColor (COLOR_GRAYTEXT);
1442 comctl32_color.clrActiveCaption = GetSysColor (COLOR_ACTIVECAPTION);
1443 comctl32_color.clrInfoBk = GetSysColor (COLOR_INFOBK);
1444 comctl32_color.clrInfoText = GetSysColor (COLOR_INFOTEXT);
1445}
Robert Shearman4c1438a2004-08-19 19:58:49 +00001446
1447/***********************************************************************
1448 * COMCTL32_DrawInsertMark [NOT AN API]
1449 *
1450 * Draws an insertion mark (which looks similar to an 'I').
1451 *
1452 * PARAMS
1453 * hDC [I] Device context to draw onto.
1454 * lpRect [I] Co-ordinates of insertion mark.
1455 * clrInsertMark [I] Colour of the insertion mark.
1456 * bHorizontal [I] True if insert mark should be drawn horizontally,
1457 * vertical otherwise.
1458 *
1459 * RETURNS
1460 * none
1461 *
1462 * NOTES
1463 * Draws up to but not including the bottom co-ordinate when drawing
1464 * vertically or the right co-ordinate when horizontal.
1465 */
1466void COMCTL32_DrawInsertMark(HDC hDC, const RECT *lpRect, COLORREF clrInsertMark, BOOL bHorizontal)
1467{
1468 HPEN hPen = CreatePen(PS_SOLID, 1, clrInsertMark);
1469 HPEN hOldPen;
1470 static const DWORD adwPolyPoints[] = {4,4,4};
1471 LONG lCentre = (bHorizontal ?
1472 lpRect->top + (lpRect->bottom - lpRect->top)/2 :
1473 lpRect->left + (lpRect->right - lpRect->left)/2);
1474 LONG l1 = (bHorizontal ? lpRect->left : lpRect->top);
1475 LONG l2 = (bHorizontal ? lpRect->right : lpRect->bottom);
1476 const POINT aptInsertMark[] =
1477 {
1478 /* top (V) or left (H) arrow */
1479 {lCentre , l1 + 2},
1480 {lCentre - 2, l1 },
1481 {lCentre + 3, l1 },
1482 {lCentre + 1, l1 + 2},
1483 /* middle line */
1484 {lCentre , l2 - 2},
1485 {lCentre , l1 - 1},
1486 {lCentre + 1, l1 - 1},
1487 {lCentre + 1, l2 - 2},
1488 /* bottom (V) or right (H) arrow */
1489 {lCentre , l2 - 3},
1490 {lCentre - 2, l2 - 1},
1491 {lCentre + 3, l2 - 1},
1492 {lCentre + 1, l2 - 3},
1493 };
1494 hOldPen = SelectObject(hDC, hPen);
1495 PolyPolyline(hDC, aptInsertMark, adwPolyPoints, sizeof(adwPolyPoints)/sizeof(adwPolyPoints[0]));
1496 SelectObject(hDC, hOldPen);
1497 DeleteObject(hPen);
1498}
Robert Shearman9cfb9432004-10-19 22:59:59 +00001499
1500/***********************************************************************
Mikołaj Zalewski8cbca5d2006-09-21 22:18:04 +02001501 * COMCTL32_EnsureBitmapSize [internal]
1502 *
Francois Gouget96c337f2007-06-07 11:48:55 +02001503 * If needed, enlarge the bitmap so that the width is at least cxMinWidth and
1504 * the height is at least cyMinHeight. If the bitmap already has these
Mikołaj Zalewski8cbca5d2006-09-21 22:18:04 +02001505 * dimensions nothing changes.
1506 *
1507 * PARAMS
1508 * hBitmap [I/O] Bitmap to modify. The handle may change
Francois Gouget96c337f2007-06-07 11:48:55 +02001509 * cxMinWidth [I] If the width of the bitmap is smaller, then it will
Mikołaj Zalewski8cbca5d2006-09-21 22:18:04 +02001510 * be enlarged to this value
Francois Gouget96c337f2007-06-07 11:48:55 +02001511 * cyMinHeight [I] If the height of the bitmap is smaller, then it will
Mikołaj Zalewski8cbca5d2006-09-21 22:18:04 +02001512 * be enlarged to this value
1513 * cyBackground [I] The color with which the new area will be filled
1514 *
1515 * RETURNS
1516 * none
1517 */
1518void COMCTL32_EnsureBitmapSize(HBITMAP *pBitmap, int cxMinWidth, int cyMinHeight, COLORREF crBackground)
1519{
1520 int cxNew, cyNew;
1521 BITMAP bmp;
1522 HBITMAP hNewBitmap;
1523 HBITMAP hNewDCBitmap, hOldDCBitmap;
1524 HBRUSH hNewDCBrush;
1525 HDC hdcNew, hdcOld;
1526
1527 if (!GetObjectW(*pBitmap, sizeof(BITMAP), &bmp))
1528 return;
1529 cxNew = (cxMinWidth > bmp.bmWidth ? cxMinWidth : bmp.bmWidth);
1530 cyNew = (cyMinHeight > bmp.bmHeight ? cyMinHeight : bmp.bmHeight);
1531 if (cxNew == bmp.bmWidth && cyNew == bmp.bmHeight)
1532 return;
1533
1534 hdcNew = CreateCompatibleDC(NULL);
1535 hNewBitmap = CreateBitmap(cxNew, cyNew, bmp.bmPlanes, bmp.bmBitsPixel, NULL);
1536 hNewDCBitmap = SelectObject(hdcNew, hNewBitmap);
1537 hNewDCBrush = SelectObject(hdcNew, CreateSolidBrush(crBackground));
1538
1539 hdcOld = CreateCompatibleDC(NULL);
1540 hOldDCBitmap = SelectObject(hdcOld, *pBitmap);
1541
1542 BitBlt(hdcNew, 0, 0, bmp.bmWidth, bmp.bmHeight, hdcOld, 0, 0, SRCCOPY);
1543 if (bmp.bmWidth < cxMinWidth)
1544 PatBlt(hdcNew, bmp.bmWidth, 0, cxNew, bmp.bmHeight, PATCOPY);
1545 if (bmp.bmHeight < cyMinHeight)
1546 PatBlt(hdcNew, 0, bmp.bmHeight, bmp.bmWidth, cyNew, PATCOPY);
1547 if (bmp.bmWidth < cxMinWidth && bmp.bmHeight < cyMinHeight)
1548 PatBlt(hdcNew, bmp.bmWidth, bmp.bmHeight, cxNew, cyNew, PATCOPY);
1549
1550 SelectObject(hdcNew, hNewDCBitmap);
1551 DeleteObject(SelectObject(hdcNew, hNewDCBrush));
1552 DeleteDC(hdcNew);
1553 SelectObject(hdcOld, hOldDCBitmap);
1554 DeleteDC(hdcOld);
1555
1556 DeleteObject(*pBitmap);
1557 *pBitmap = hNewBitmap;
1558 return;
1559}
1560
Mikołaj Zalewski9aee00e2008-07-16 20:21:09 +02001561void COMCTL32_GetFontMetrics(HFONT hFont, TEXTMETRICW *ptm)
1562{
1563 HDC hdc = GetDC(NULL);
1564 HFONT hOldFont;
1565
1566 hOldFont = SelectObject(hdc, hFont);
1567 GetTextMetricsW(hdc, ptm);
1568 SelectObject(hdc, hOldFont);
1569 ReleaseDC(NULL, hdc);
1570}
1571
Mikołaj Zalewski60a1e202008-07-22 00:18:09 +02001572#ifndef OCM__BASE /* avoid including olectl.h */
1573#define OCM__BASE (WM_USER+0x1c00)
1574#endif
1575
1576/***********************************************************************
1577 * COMCTL32_IsReflectedMessage [internal]
1578 *
1579 * Some parents reflect notify messages - for some messages sent by the child,
1580 * they send it back with the message code increased by OCM__BASE (0x2000).
1581 * This allows better subclassing of controls. We don't need to handle such
1582 * messages but we don't want to print ERRs for them, so this helper function
1583 * identifies them.
1584 *
1585 * Some of the codes are in the CCM_FIRST..CCM_LAST range, but there is no
1586 * colision with defined CCM_ codes.
1587 */
1588BOOL COMCTL32_IsReflectedMessage(UINT uMsg)
1589{
1590 switch (uMsg)
1591 {
1592 case OCM__BASE + WM_COMMAND:
1593 case OCM__BASE + WM_CTLCOLORBTN:
1594 case OCM__BASE + WM_CTLCOLOREDIT:
1595 case OCM__BASE + WM_CTLCOLORDLG:
1596 case OCM__BASE + WM_CTLCOLORLISTBOX:
1597 case OCM__BASE + WM_CTLCOLORMSGBOX:
1598 case OCM__BASE + WM_CTLCOLORSCROLLBAR:
1599 case OCM__BASE + WM_CTLCOLORSTATIC:
1600 case OCM__BASE + WM_DRAWITEM:
1601 case OCM__BASE + WM_MEASUREITEM:
1602 case OCM__BASE + WM_DELETEITEM:
1603 case OCM__BASE + WM_VKEYTOITEM:
1604 case OCM__BASE + WM_CHARTOITEM:
1605 case OCM__BASE + WM_COMPAREITEM:
1606 case OCM__BASE + WM_HSCROLL:
1607 case OCM__BASE + WM_VSCROLL:
1608 case OCM__BASE + WM_PARENTNOTIFY:
1609 case OCM__BASE + WM_NOTIFY:
1610 return TRUE;
1611 default:
1612 return FALSE;
1613 }
1614}
1615
Mikołaj Zalewski8cbca5d2006-09-21 22:18:04 +02001616/***********************************************************************
Robert Shearman9cfb9432004-10-19 22:59:59 +00001617 * MirrorIcon [COMCTL32.414]
1618 *
1619 * Mirrors an icon so that it will appear correctly on a mirrored DC.
1620 *
1621 * PARAMS
1622 * phicon1 [I/O] Icon.
1623 * phicon2 [I/O] Icon.
1624 *
1625 * RETURNS
1626 * Success: TRUE.
1627 * Failure: FALSE.
1628 */
1629BOOL WINAPI MirrorIcon(HICON *phicon1, HICON *phicon2)
1630{
1631 FIXME("(%p, %p): stub\n", phicon1, phicon2);
1632 return FALSE;
1633}
1634
1635static inline int IsDelimiter(WCHAR c)
1636{
1637 switch(c)
1638 {
1639 case '/':
1640 case '\\':
1641 case '.':
1642 case ' ':
1643 return TRUE;
1644 }
1645 return FALSE;
1646}
1647
Andrew Talbot9a767632007-03-31 17:42:01 +01001648static int CALLBACK PathWordBreakProc(LPCWSTR lpch, int ichCurrent, int cch, int code)
Robert Shearman9cfb9432004-10-19 22:59:59 +00001649{
1650 if (code == WB_ISDELIMITER)
1651 return IsDelimiter(lpch[ichCurrent]);
1652 else
1653 {
1654 int dir = (code == WB_LEFT) ? -1 : 1;
1655 for(; 0 <= ichCurrent && ichCurrent < cch; ichCurrent += dir)
1656 if (IsDelimiter(lpch[ichCurrent])) return ichCurrent;
1657 }
1658 return ichCurrent;
1659}
1660
1661/***********************************************************************
1662 * SetPathWordBreakProc [COMCTL32.384]
1663 *
1664 * Sets the word break procedure for an edit control to one that understands
1665 * paths so that the user can jump over directories.
1666 *
1667 * PARAMS
1668 * hwnd [I] Handle to edit control.
1669 * bSet [I] If this is TRUE then the word break proc is set, otherwise it is removed.
1670 *
1671 * RETURNS
1672 * Result from EM_SETWORDBREAKPROC message.
1673 */
1674LRESULT WINAPI SetPathWordBreakProc(HWND hwnd, BOOL bSet)
1675{
1676 return SendMessageW(hwnd, EM_SETWORDBREAKPROC, 0,
1677 (LPARAM)(bSet ? PathWordBreakProc : NULL));
1678}
Louis Lendersb7a59852007-05-30 21:19:52 +01001679
1680/***********************************************************************
1681 * DrawShadowText [COMCTL32.@]
1682 *
1683 * Draw text with shadow.
1684 */
Francois Gouget22d09f72007-07-31 19:01:00 +02001685int WINAPI DrawShadowText(HDC hdc, LPCWSTR pszText, UINT cch, RECT *rect, DWORD dwFlags,
Louis Lendersb7a59852007-05-30 21:19:52 +01001686 COLORREF crText, COLORREF crShadow, int ixOffset, int iyOffset)
1687{
Francois Gouget22d09f72007-07-31 19:01:00 +02001688 FIXME("(%p, %s, %d, %p, %d, 0x%08x, 0x%08x, %d, %d): stub\n", hdc, debugstr_w(pszText), cch, rect, dwFlags,
Louis Lendersb7a59852007-05-30 21:19:52 +01001689 crText, crShadow, ixOffset, iyOffset);
Francois Gouget22d09f72007-07-31 19:01:00 +02001690 return DrawTextW(hdc, pszText, cch, rect, DT_LEFT);
Louis Lendersb7a59852007-05-30 21:19:52 +01001691}