~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/comctl32/commctrl.c

Version: ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~ [ wine-1.0-rc5 ] ~ [ wine-1.0-rc4 ] ~ [ wine-1.0-rc3 ] ~ [ wine-1.0-rc2 ] ~ [ wine-1.0-rc1 ] ~ [ wine-0.9.61 ] ~ [ wine-0.9.60 ] ~ [ wine-0.9.59 ] ~ [ wine-0.9.58 ] ~ [ wine-0.9.57 ] ~ [ wine-0.9.56 ] ~ [ wine-0.9.55 ] ~ [ wine-0.9.54 ] ~ [ wine-0.9.53 ] ~ [ wine-0.9.52 ] ~ [ wine-0.9.51 ] ~ [ wine-0.9.50 ] ~ [ wine-0.9.49 ] ~ [ wine-0.9.48 ] ~ [ wine-0.9.47 ] ~ [ wine-0.9.46 ] ~ [ wine-0.9.45 ] ~ [ wine-0.9.44 ] ~ [ wine-0.9.43 ] ~ [ wine-0.9.42 ] ~ [ wine-0.9.41 ] ~ [ wine-0.9.40 ] ~ [ wine-0.9.39 ] ~ [ wine-0.9.38 ] ~ [ wine-0.9.37 ] ~ [ wine-0.9.36 ] ~ [ wine-0.9.35 ] ~ [ wine-0.9.34 ] ~ [ wine-0.9.33 ] ~ [ wine-0.9.32 ] ~ [ wine-0.9.31 ] ~ [ wine-0.9.30 ] ~ [ wine-0.9.29 ] ~ [ wine-0.9.28 ] ~ [ wine-0.9.27 ] ~ [ wine-0.9.26 ] ~ [ wine-0.9.25 ] ~ [ wine-0.9.24 ] ~ [ wine-0.9.23 ] ~ [ wine-0.9.22 ] ~ [ wine-0.9.21 ] ~ [ wine-0.9.20 ] ~ [ wine-0.9.19 ] ~ [ wine-0.9.18 ] ~ [ wine-0.9.17 ] ~ [ wine-0.9.16 ] ~ [ wine-0.9.15 ] ~ [ wine-0.9.14 ] ~ [ wine-0.9.13 ] ~ [ wine-0.9.12 ] ~ [ wine-0.9.11 ] ~ [ wine-0.9.10 ] ~ [ wine-0.9.9 ] ~ [ wine-0.9.8 ] ~ [ wine-0.9.7 ] ~ [ wine-0.9.6 ] ~ [ wine-0.9.5 ] ~ [ wine-0.9.4 ] ~ [ wine-0.9.3 ] ~ [ wine-0.9.2 ] ~ [ wine-0.9.1 ] ~ [ wine-0.9 ] ~ [ wine20050930 ] ~ [ wine20050830 ] ~ [ wine20050725 ] ~ [ wine20050628 ] ~ [ wine20050524 ] ~ [ wine20050419 ] ~ [ wine20050310 ] ~ [ wine20050211 ] ~ [ wine20050111 ] ~ [ wine20041201 ] ~ [ wine20041019 ] ~ [ wine20040914 ] ~ [ wine20040813 ] ~ [ wine20040716 ] ~ [ wine20040615 ] ~ [ wine20040505 ] ~ [ wine20040408 ] ~ [ wine20040309 ] ~ [ wine20040213 ] ~ [ wine20040121 ] ~ [ wine20031212 ] ~ [ wine20031118 ] ~ [ wine20031016 ] ~ [ wine20030911 ] ~ [ wine20030813 ] ~ [ wine20030709 ] ~ [ wine20030618 ] ~ [ wine20030508 ] ~ [ wine20030408 ] ~ [ wine20030318 ] ~ [ wine20030219 ] ~ [ wine20030115 ] ~ [ wine20021219 ] ~ [ wine20021125 ] ~ [ wine20021031 ] ~ [ wine20021007 ] ~ [ wine20020904 ] ~ [ wine20020804 ] ~ [ wine20020710 ] ~ [ wine20020605 ] ~ [ wine20020509 ] ~ [ wine20020411 ] ~ [ wine20020310 ] ~ [ wine20020228 ] ~ [ wine20011226 ] ~ [ wine20011108 ] ~ [ wine20011004 ] ~ [ wine20010824 ] ~ [ wine20010731 ] ~ [ wine20010629 ] ~ [ wine20010510 ] ~ [ wine20010418 ] ~ [ wine20010326 ] ~ [ wine20010305 ] ~ [ wine20010216 ] ~ [ wine20010112 ] ~ [ wine20001222 ] ~ [ wine20001202 ] ~ [ wine20001026 ] ~ [ wine20001002 ] ~ [ wine20000909 ] ~ [ wine20000821 ] ~ [ wine20000801 ] ~ [ wine20000716 ] ~ [ wine20000326 ] ~ [ wine20000227 ] ~ [ wine20000130 ] ~ [ wine20000109 ] ~

  1 /*
  2  * Common controls functions
  3  *
  4  * Copyright 1997 Dimitrie O. Paun
  5  * Copyright 1998,2000 Eric Kohl
  6  *
  7  * 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
 19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 20  *
 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  *
 26  * Unless otherwise noted, we believe this code to be complete, as per
 27  * the specification mentioned above.
 28  * If you discover missing features, or bugs, please note them below.
 29  *
 30  * TODO
 31  *   -- implement GetMUILanguage + InitMUILanguage
 32  *   -- 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
 42  *   -- ICC_LINK_CLASS
 43  *   -- 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
 53  */
 54 
 55 #include <stdarg.h>
 56 #include <string.h>
 57 #include <stdlib.h>
 58 
 59 #include "windef.h"
 60 #include "winbase.h"
 61 #include "wingdi.h"
 62 #include "winuser.h"
 63 #include "winnls.h"
 64 #include "commctrl.h"
 65 #include "winerror.h"
 66 #include "winreg.h"
 67 #define NO_SHLWAPI_STREAM
 68 #include "shlwapi.h"
 69 #include "comctl32.h"
 70 #include "wine/debug.h"
 71 
 72 WINE_DEFAULT_DEBUG_CHANNEL(commctrl);
 73 
 74 
 75 #define NAME       "microsoft.windows.common-controls"
 76 #define FILE       "comctl32.dll"
 77 #define VERSION    "6.0.2600.2982"
 78 #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 
 88 static 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 
124 static const char manifest_filename[] = ARCH "_" NAME "_" PUBLIC_KEY "_" VERSION "_none_deadbeef.manifest";
125 
126 LRESULT WINAPI COMCTL32_SubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
127 
128 LPWSTR  COMCTL32_wSubclass = NULL;
129 HMODULE COMCTL32_hModule = 0;
130 LANGID  COMCTL32_uiLang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
131 HBRUSH  COMCTL32_hPattern55AABrush = NULL;
132 COMCTL32_SysColor  comctl32_color;
133 
134 static HBITMAP COMCTL32_hPattern55AABitmap = NULL;
135 
136 static const WORD wPattern55AA[] =
137 {
138     0x5555, 0xaaaa, 0x5555, 0xaaaa,
139     0x5555, 0xaaaa, 0x5555, 0xaaaa
140 };
141 
142 static const WCHAR strCC32SubclassInfo[] = {
143     'C','C','3','2','S','u','b','c','l','a','s','s','I','n','f','o',0
144 };
145 
146 static BOOL create_manifest( BOOL install )
147 {
148     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};
150 
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 );
158     len += lstrlenW(winsxsW);
159     len += lstrlenW(manifestsW);
160     if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return FALSE;
161     GetWindowsDirectoryW( buffer, len );
162     lstrcatW( buffer, winsxsW );
163     CreateDirectoryW( buffer, NULL );
164     lstrcatW( buffer, manifestsW );
165     CreateDirectoryW( buffer, NULL );
166     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 
187 /***********************************************************************
188  * DllMain [Internal]
189  *
190  * Initializes the internal 'COMCTL32.DLL'.
191  *
192  * PARAMS
193  *     hinstDLL    [I] handle to the 'dlls' instance
194  *     fdwReason   [I]
195  *     lpvReserved [I] reserverd, must be NULL
196  *
197  * RETURNS
198  *     Success: TRUE
199  *     Failure: FALSE
200  */
201 
202 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
203 {
204     TRACE("%p,%x,%p\n", hinstDLL, fdwReason, lpvReserved);
205 
206     switch (fdwReason) {
207         case DLL_PROCESS_ATTACH:
208             DisableThreadLibraryCalls(hinstDLL);
209 
210             COMCTL32_hModule = hinstDLL;
211 
212             /* add global subclassing atom (used by 'tooltip' and 'updown') */
213             COMCTL32_wSubclass = (LPWSTR)(DWORD_PTR)GlobalAddAtomW (strCC32SubclassInfo);
214             TRACE("Subclassing atom added: %p\n", COMCTL32_wSubclass);
215 
216             /* create local pattern brush */
217             COMCTL32_hPattern55AABitmap = CreateBitmap (8, 8, 1, 1, wPattern55AA);
218             COMCTL32_hPattern55AABrush = CreatePatternBrush (COMCTL32_hPattern55AABitmap);
219 
220             /* Get all the colors at DLL load */
221             COMCTL32_RefreshSysColors();
222 
223             /* like comctl32 5.82+ register all the common control classes */
224             ANIMATE_Register ();
225             COMBOEX_Register ();
226             DATETIME_Register ();
227             FLATSB_Register ();
228             HEADER_Register ();
229             HOTKEY_Register ();
230             IPADDRESS_Register ();
231             LISTVIEW_Register ();
232             MONTHCAL_Register ();
233             NATIVEFONT_Register ();
234             PAGER_Register ();
235             PROGRESS_Register ();
236             REBAR_Register ();
237             STATUS_Register ();
238             SYSLINK_Register ();
239             TAB_Register ();
240             TOOLBAR_Register ();
241             TOOLTIPS_Register ();
242             TRACKBAR_Register ();
243             TREEVIEW_Register ();
244             UPDOWN_Register ();
245 
246             /* subclass user32 controls */
247             THEMING_Initialize ();
248             break;
249 
250         case DLL_PROCESS_DETACH:
251             /* clean up subclassing */ 
252             THEMING_Uninitialize();
253 
254             /* 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 ();
269             SYSLINK_Unregister ();
270             TAB_Unregister ();
271             TOOLBAR_Unregister ();
272             TOOLTIPS_Unregister ();
273             TRACKBAR_Unregister ();
274             TREEVIEW_Unregister ();
275             UPDOWN_Unregister ();
276 
277             /* delete local pattern brush */
278             DeleteObject (COMCTL32_hPattern55AABrush);
279             COMCTL32_hPattern55AABrush = NULL;
280             DeleteObject (COMCTL32_hPattern55AABitmap);
281             COMCTL32_hPattern55AABitmap = NULL;
282 
283             /* delete global subclassing atom */
284             GlobalDeleteAtom (LOWORD(COMCTL32_wSubclass));
285             TRACE("Subclassing atom deleted: %p\n", COMCTL32_wSubclass);
286             COMCTL32_wSubclass = NULL;
287             break;
288     }
289 
290     return TRUE;
291 }
292 
293 
294 /***********************************************************************
295  * MenuHelp [COMCTL32.2]
296  *
297  * Handles the setting of status bar help messages when the user
298  * selects menu items.
299  *
300  * PARAMS
301  *     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
306  *     hwndStatus [I] handle to the status bar window
307  *     lpwIDs     [I] pointer to an array of integers (see NOTES)
308  *
309  * RETURNS
310  *     No return value
311  *
312  * NOTES
313  *     The official documentation is incomplete!
314  *     This is the correct documentation:
315  *
316  *     uMsg:
317  *     MenuHelp() does NOT handle WM_COMMAND messages! It only handles
318  *     WM_MENUSELECT messages.
319  *
320  *     lpwIDs:
321  *     (will be written ...)
322  */
323 
324 VOID WINAPI
325 MenuHelp (UINT uMsg, WPARAM wParam, LPARAM lParam, HMENU hMainMenu,
326           HINSTANCE hInst, HWND hwndStatus, UINT* lpwIDs)
327 {
328     UINT uMenuID = 0;
329 
330     if (!IsWindow (hwndStatus))
331         return;
332 
333     switch (uMsg) {
334         case WM_MENUSELECT:
335             TRACE("WM_MENUSELECT wParam=0x%lX lParam=0x%lX\n",
336                    wParam, lParam);
337 
338             if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
339                 /* menu was closed */
340                 TRACE("menu was closed!\n");
341                 SendMessageW (hwndStatus, SB_SIMPLE, FALSE, 0);
342             }
343             else {
344                 /* menu item was selected */
345                 if (HIWORD(wParam) & MF_POPUP)
346                     uMenuID = *(lpwIDs+1);
347                 else
348                     uMenuID = (UINT)LOWORD(wParam);
349                 TRACE("uMenuID = %u\n", uMenuID);
350 
351                 if (uMenuID) {
352                     WCHAR szText[256];
353 
354                     if (!LoadStringW (hInst, uMenuID, szText, sizeof(szText)/sizeof(szText[0])))
355                         szText[0] = '\0';
356 
357                     SendMessageW (hwndStatus, SB_SETTEXTW,
358                                     255 | SBT_NOBORDERS, (LPARAM)szText);
359                     SendMessageW (hwndStatus, SB_SIMPLE, TRUE, 0);
360                 }
361             }
362             break;
363 
364         case WM_COMMAND :
365             TRACE("WM_COMMAND wParam=0x%lX lParam=0x%lX\n",
366                    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 
374         default:
375             FIXME("Invalid Message 0x%x!\n", uMsg);
376             break;
377     }
378 }
379 
380 
381 /***********************************************************************
382  * ShowHideMenuCtl [COMCTL32.3]
383  *
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
396  *     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
403  *     Identifier of the menu item to receive or lose a check mark.
404  *
405  *     lpInfo
406  *     The array of integers contains pairs of values. BOTH values of
407  *     the first pair must be the handles to the application's main menu.
408  *     Each subsequent pair consists of a menu id and control id.
409  */
410 
411 BOOL WINAPI
412 ShowHideMenuCtl (HWND hwnd, UINT_PTR uFlags, LPINT lpInfo)
413 {
414     LPINT lpMenuId;
415 
416     TRACE("%p, %lx, %p\n", hwnd, uFlags, lpInfo);
417 
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 
429     if (GetMenuState ((HMENU)(DWORD_PTR)lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
430         /* uncheck menu item */
431         CheckMenuItem ((HMENU)(DWORD_PTR)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
432 
433         /* hide control */
434         lpMenuId++;
435         SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
436                         SWP_HIDEWINDOW);
437     }
438     else {
439         /* check menu item */
440         CheckMenuItem ((HMENU)(DWORD_PTR)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
441 
442         /* show control */
443         lpMenuId++;
444         SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
445                         SWP_SHOWWINDOW);
446     }
447 
448     return TRUE;
449 }
450 
451 
452 /***********************************************************************
453  * GetEffectiveClientRect [COMCTL32.4]
454  *
455  * Calculates the coordinates of a rectangle in the client area.
456  *
457  * PARAMS
458  *     hwnd   [I] handle to the client window.
459  *     lpRect [O] pointer to the rectangle of the client window
460  *     lpInfo [I] pointer to an array of integers (see NOTES)
461  *
462  * RETURNS
463  *     No return value.
464  *
465  * NOTES
466  *     The official documentation is incomplete!
467  *     This is the correct documentation:
468  *
469  *     lpInfo
470  *     (will be written ...)
471  */
472 
473 VOID WINAPI
474 GetEffectiveClientRect (HWND hwnd, LPRECT lpRect, const INT *lpInfo)
475 {
476     RECT rcCtrl;
477     const INT *lpRun;
478     HWND hwndCtrl;
479 
480     TRACE("(%p %p %p)\n",
481            hwnd, lpRect, lpInfo);
482 
483     GetClientRect (hwnd, lpRect);
484     lpRun = lpInfo;
485 
486     do {
487         lpRun += 2;
488         if (*lpRun == 0)
489             return;
490         lpRun++;
491         hwndCtrl = GetDlgItem (hwnd, *lpRun);
492         if (GetWindowLongW (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
493             TRACE("control id 0x%x\n", *lpRun);
494             GetWindowRect (hwndCtrl, &rcCtrl);
495             MapWindowPoints (NULL, hwnd, (LPPOINT)&rcCtrl, 2);
496             SubtractRect (lpRect, lpRect, &rcCtrl);
497         }
498         lpRun++;
499     } while (*lpRun);
500 }
501 
502 
503 /***********************************************************************
504  * DrawStatusTextW [COMCTL32.@]
505  *
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
512  *     style [I] drawing style
513  *
514  * RETURNS
515  *     No return value.
516  *
517  * NOTES
518  *     The style variable can have one of the following values:
519  *     (will be written ...)
520  */
521 
522 void WINAPI DrawStatusTextW (HDC hdc, LPCRECT lprc, LPCWSTR text, UINT style)
523 {
524     RECT r = *lprc;
525     UINT border = BDR_SUNKENOUTER;
526 
527     if (style & SBT_POPOUT)
528         border = BDR_RAISEDOUTER;
529     else if (style & SBT_NOBORDERS)
530         border = 0;
531 
532     DrawEdge (hdc, &r, border, BF_RECT|BF_ADJUST);
533 
534     /* now draw text */
535     if (text) {
536         int oldbkmode = SetBkMode (hdc, TRANSPARENT);
537         UINT align = DT_LEFT;
538         int strCnt = 0;
539 
540         if (style & SBT_RTLREADING)
541             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);
559         SetBkMode(hdc, oldbkmode);
560     }
561 }
562 
563 
564 /***********************************************************************
565  * DrawStatusText  [COMCTL32.@]
566  * DrawStatusTextA [COMCTL32.5]
567  *
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
574  *     style [I] drawing style
575  *
576  * RETURNS
577  *     No return value.
578  */
579 
580 void WINAPI DrawStatusTextA (HDC hdc, LPCRECT lprc, LPCSTR text, UINT style)
581 {
582     INT len;
583     LPWSTR textW = NULL;
584 
585     if ( text ) {
586         if ( (len = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 )) ) {
587             if ( (textW = Alloc( len * sizeof(WCHAR) )) )
588                 MultiByteToWideChar( CP_ACP, 0, text, -1, textW, len );
589         }
590     }
591     DrawStatusTextW( hdc, lprc, textW, style );
592     Free( textW );
593 }
594 
595 
596 /***********************************************************************
597  * CreateStatusWindow  [COMCTL32.@]
598  * CreateStatusWindowA [COMCTL32.6]
599  *
600  * Creates a status bar
601  *
602  * PARAMS
603  *     style  [I] window style
604  *     text   [I] pointer to the window text
605  *     parent [I] handle to the parent window
606  *     wid    [I] control id of the status bar
607  *
608  * RETURNS
609  *     Success: handle to the status window
610  *     Failure: 0
611  */
612 
613 HWND WINAPI
614 CreateStatusWindowA (LONG style, LPCSTR text, HWND parent, UINT wid)
615 {
616     return CreateWindowA(STATUSCLASSNAMEA, text, style,
617                            CW_USEDEFAULT, CW_USEDEFAULT,
618                            CW_USEDEFAULT, CW_USEDEFAULT,
619                            parent, (HMENU)(DWORD_PTR)wid, 0, 0);
620 }
621 
622 
623 /***********************************************************************
624  * CreateStatusWindowW [COMCTL32.@]
625  *
626  * Creates a status bar control
627  *
628  * PARAMS
629  *     style  [I] window style
630  *     text   [I] pointer to the window text
631  *     parent [I] handle to the parent window
632  *     wid    [I] control id of the status bar
633  *
634  * RETURNS
635  *     Success: handle to the status window
636  *     Failure: 0
637  */
638 
639 HWND WINAPI
640 CreateStatusWindowW (LONG style, LPCWSTR text, HWND parent, UINT wid)
641 {
642     return CreateWindowW(STATUSCLASSNAMEW, text, style,
643                            CW_USEDEFAULT, CW_USEDEFAULT,
644                            CW_USEDEFAULT, CW_USEDEFAULT,
645                            parent, (HMENU)(DWORD_PTR)wid, 0, 0);
646 }
647 
648 
649 /***********************************************************************
650  * CreateUpDownControl [COMCTL32.16]
651  *
652  * Creates an up-down control
653  *
654  * PARAMS
655  *     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
660  *     parent [I] handle to the parent window
661  *     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
667  *
668  * RETURNS
669  *     Success: handle to the updown control
670  *     Failure: 0
671  */
672 
673 HWND WINAPI
674 CreateUpDownControl (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)
677 {
678     HWND hUD =
679         CreateWindowW (UPDOWN_CLASSW, 0, style, x, y, cx, cy,
680                          parent, (HMENU)(DWORD_PTR)id, inst, 0);
681     if (hUD) {
682         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));
685     }
686 
687     return hUD;
688 }
689 
690 
691 /***********************************************************************
692  * InitCommonControls [COMCTL32.17]
693  *
694  * Registers the common controls.
695  *
696  * PARAMS
697  *     No parameters.
698  *
699  * RETURNS
700  *     No return values.
701  *
702  * NOTES
703  *     This function is just a dummy - all the controls are registered at
704  *     the DLL's initialization. See InitCommonContolsEx for details.
705  */
706 
707 VOID WINAPI
708 InitCommonControls (void)
709 {
710 }
711 
712 
713 /***********************************************************************
714  * InitCommonControlsEx [COMCTL32.@]
715  *
716  * Registers the common controls.
717  *
718  * PARAMS
719  *     lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
720  *
721  * RETURNS
722  *     Success: TRUE
723  *     Failure: FALSE
724  *
725  * NOTES
726  *     Probably all versions of comctl32 initializes the Win95 controls in DllMain
727  *     during DLL initialization. Starting from comctl32 v5.82 all the controls
728  *     are initialized there. We follow this behaviour and this function is just
729  *     a dummy.
730  *
731  *     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.
735  */
736 
737 BOOL WINAPI
738 InitCommonControlsEx (const INITCOMMONCONTROLSEX *lpInitCtrls)
739 {
740     if (!lpInitCtrls || lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
741         return FALSE;
742 
743     TRACE("(0x%08x)\n", lpInitCtrls->dwICC);
744     return TRUE;
745 }
746 
747 
748 /***********************************************************************
749  * CreateToolbarEx [COMCTL32.@]
750  *
751  * Creates a toolbar window.
752  *
753  * 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
767  *
768  * RETURNS
769  *     Success: handle to the tool bar control
770  *     Failure: 0
771  */
772 
773 HWND WINAPI
774 CreateToolbarEx (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
775                  HINSTANCE hBMInst, UINT wBMID, LPCTBBUTTON lpButtons,
776                  INT iNumButtons, INT dxButton, INT dyButton,
777                  INT dxBitmap, INT dyBitmap, UINT uStructSize)
778 {
779     HWND hwndTB;
780 
781     hwndTB =
782         CreateWindowExW(0, TOOLBARCLASSNAMEW, NULL, style|WS_CHILD, 0,0,100,30,
783                         hwnd, (HMENU)(DWORD_PTR)wID, COMCTL32_hModule, NULL);
784     if(hwndTB) {
785         TBADDBITMAP tbab;
786 
787         SendMessageW (hwndTB, TB_BUTTONSTRUCTSIZE, (WPARAM)uStructSize, 0);
788 
789        /* set bitmap and button size */
790        /*If CreateToolbarEx receives 0, windows sets default values*/
791        if (dxBitmap < 0)
792            dxBitmap = 16;
793        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));
798 
799        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));
806 
807 
808         /* add bitmaps */
809         if (nBitmaps > 0 || hBMInst == HINST_COMMCTRL)
810         {
811             tbab.hInst = hBMInst;
812             tbab.nID   = wBMID;
813 
814             SendMessageW (hwndTB, TB_ADDBITMAP, (WPARAM)nBitmaps, (LPARAM)&tbab);
815         }
816         /* add buttons */
817         if(iNumButtons > 0)
818         SendMessageW (hwndTB, TB_ADDBUTTONSW,
819                         (WPARAM)iNumButtons, (LPARAM)lpButtons);
820     }
821 
822     return hwndTB;
823 }
824 
825 
826 /***********************************************************************
827  * CreateMappedBitmap [COMCTL32.8]
828  *
829  * Loads a bitmap resource using a colour map.
830  *
831  * PARAMS
832  *     hInstance  [I] Handle to the module containing the bitmap.
833  *     idBitmap   [I] The bitmap resource ID.
834  *     wFlags     [I] CMB_MASKED for using bitmap as a mask or 0 for normal.
835  *     lpColorMap [I] Colour information needed for the bitmap or NULL (uses system colours).
836  *     iNumMaps   [I] Number of COLORMAP's pointed to by lpColorMap.
837  *
838  * RETURNS
839  *     Success: handle to the new bitmap
840  *     Failure: 0
841  */
842 
843 HBITMAP WINAPI
844 CreateMappedBitmap (HINSTANCE hInstance, INT_PTR idBitmap, UINT wFlags,
845                     LPCOLORMAP lpColorMap, INT iNumMaps)
846 {
847     HGLOBAL hglb;
848     HRSRC hRsrc;
849     const BITMAPINFOHEADER *lpBitmap;
850     LPBITMAPINFOHEADER lpBitmapInfo;
851     UINT nSize, nColorTableSize, iColor;
852     RGBQUAD *pColorTable;
853     INT i, iMaps, nWidth, nHeight;
854     HDC hdcScreen;
855     HBITMAP hbm;
856     LPCOLORMAP sysColorMap;
857     COLORREF cRef;
858     COLORMAP internalColorMap[4] =
859         {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
860 
861     /* initialize pointer to colortable and default color table */
862     if (lpColorMap) {
863         iMaps = iNumMaps;
864         sysColorMap = lpColorMap;
865     }
866     else {
867         internalColorMap[0].to = GetSysColor (COLOR_BTNTEXT);
868         internalColorMap[1].to = GetSysColor (COLOR_BTNSHADOW);
869         internalColorMap[2].to = GetSysColor (COLOR_BTNFACE);
870         internalColorMap[3].to = GetSysColor (COLOR_BTNHIGHLIGHT);
871         iMaps = 4;
872         sysColorMap = (LPCOLORMAP)internalColorMap;
873     }
874 
875     hRsrc = FindResourceW (hInstance, (LPWSTR)idBitmap, (LPWSTR)RT_BITMAP);
876     if (hRsrc == 0)
877         return 0;
878     hglb = LoadResource (hInstance, hRsrc);
879     if (hglb == 0)
880         return 0;
881     lpBitmap = (LPBITMAPINFOHEADER)LockResource (hglb);
882     if (lpBitmap == NULL)
883         return 0;
884 
885     if (lpBitmap->biSize >= sizeof(BITMAPINFOHEADER) && lpBitmap->biClrUsed)
886         nColorTableSize = lpBitmap->biClrUsed;
887     else if (lpBitmap->biBitCount <= 8) 
888         nColorTableSize = (1 << lpBitmap->biBitCount);
889     else
890         nColorTableSize = 0;
891     nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
892     lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc (GMEM_FIXED, nSize);
893     if (lpBitmapInfo == NULL)
894         return 0;
895     RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
896 
897     pColorTable = (RGBQUAD*)(((LPBYTE)lpBitmapInfo) + lpBitmapInfo->biSize);
898 
899     for (iColor = 0; iColor < nColorTableSize; iColor++) {
900         for (i = 0; i < iMaps; i++) {
901             cRef = RGB(pColorTable[iColor].rgbRed,
902                        pColorTable[iColor].rgbGreen,
903                        pColorTable[iColor].rgbBlue);
904             if ( cRef  == sysColorMap[i].from) {
905 #if 0
906                 if (wFlags & CBS_MASKED) {
907                     if (sysColorMap[i].to != COLOR_BTNTEXT)
908                         pColorTable[iColor] = RGB(255, 255, 255);
909                 }
910                 else
911 #endif
912                     pColorTable[iColor].rgbBlue  = GetBValue(sysColorMap[i].to);
913                     pColorTable[iColor].rgbGreen = GetGValue(sysColorMap[i].to);
914                     pColorTable[iColor].rgbRed   = GetRValue(sysColorMap[i].to);
915                 break;
916             }
917         }
918     }
919     nWidth  = lpBitmapInfo->biWidth;
920     nHeight = lpBitmapInfo->biHeight;
921     hdcScreen = GetDC (NULL);
922     hbm = CreateCompatibleBitmap (hdcScreen, nWidth, nHeight);
923     if (hbm) {
924         HDC hdcDst = CreateCompatibleDC (hdcScreen);
925         HBITMAP hbmOld = SelectObject (hdcDst, hbm);
926         const BYTE *lpBits = (const BYTE *)(lpBitmap + 1);
927         lpBits += nColorTableSize * sizeof(RGBQUAD);
928         StretchDIBits (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
929                          lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
930                          SRCCOPY);
931         SelectObject (hdcDst, hbmOld);
932         DeleteDC (hdcDst);
933     }
934     ReleaseDC (NULL, hdcScreen);
935     GlobalFree ((HGLOBAL)lpBitmapInfo);
936     FreeResource (hglb);
937 
938     return hbm;
939 }
940 
941 
942 /***********************************************************************
943  * CreateToolbar [COMCTL32.7]
944  *
945  * Creates a toolbar control.
946  *
947  * PARAMS
948  *     hwnd
949  *     style
950  *     wID
951  *     nBitmaps
952  *     hBMInst
953  *