Correct errors with move to kernel time functions.
[wine/multimedia.git] / dlls / comctl32 / commctrl.c
blobad242dfdd910cb2655fb8a75b6f257473c42fd2f
1 /*
2 * Common controls functions
4 * Copyright 1997 Dimitrie O. Paun
5 * Copyright 1998,2000 Eric Kohl
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * NOTES
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.
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.
30 * TODO
31 * -- implement GetMUILanguage + InitMUILanguage
32 * -- LibMain => DLLMain ("DLLMain takes over the functionality of both the
33 * LibMain and the WEP function.", MSDN)
34 * -- finish NOTES for MenuHelp, GetEffectiveClientRect and GetStatusTextW
35 * -- FIXMEs + BUGS (search for them)
37 * Control Classes
38 * -- ICC_ANIMATE_CLASS
39 * -- ICC_BAR_CLASSES
40 * -- ICC_COOL_CLASSES
41 * -- ICC_DATE_CLASSES
42 * -- ICC_HOTKEY_CLASS
43 * -- ICC_INTERNET_CLASSES
44 * -- ICC_LINK_CLASS (not yet implemented)
45 * -- ICC_LISTVIEW_CLASSES
46 * -- ICC_NATIVEFNTCTL_CLASS
47 * -- ICC_PAGESCROLLER_CLASS
48 * -- ICC_PROGRESS_CLASS
49 * -- ICC_STANDARD_CLASSES (not yet implemented)
50 * -- ICC_TAB_CLASSES
51 * -- ICC_TREEVIEW_CLASSES
52 * -- ICC_UPDOWN_CLASS
53 * -- ICC_USEREX_CLASSES
54 * -- ICC_WIN95_CLASSES
57 #include <stdarg.h>
58 #include <string.h>
59 #include <stdlib.h>
61 #include "windef.h"
62 #include "winbase.h"
63 #include "wingdi.h"
64 #include "winuser.h"
65 #include "winnls.h"
66 #include "commctrl.h"
67 #include "winerror.h"
68 #include "winreg.h"
69 #define NO_SHLWAPI_STREAM
70 #include "shlwapi.h"
71 #include "comctl32.h"
72 #include "wine/debug.h"
74 WINE_DEFAULT_DEBUG_CHANNEL(commctrl);
76 extern void ANIMATE_Register(void);
77 extern void ANIMATE_Unregister(void);
78 extern void COMBOEX_Register(void);
79 extern void COMBOEX_Unregister(void);
80 extern void DATETIME_Register(void);
81 extern void DATETIME_Unregister(void);
82 extern void FLATSB_Register(void);
83 extern void FLATSB_Unregister(void);
84 extern void HEADER_Register(void);
85 extern void HEADER_Unregister(void);
86 extern void HOTKEY_Register(void);
87 extern void HOTKEY_Unregister(void);
88 extern void IPADDRESS_Register(void);
89 extern void IPADDRESS_Unregister(void);
90 extern void LISTVIEW_Register(void);
91 extern void LISTVIEW_Unregister(void);
92 extern void MONTHCAL_Register(void);
93 extern void MONTHCAL_Unregister(void);
94 extern void NATIVEFONT_Register(void);
95 extern void NATIVEFONT_Unregister(void);
96 extern void PAGER_Register(void);
97 extern void PAGER_Unregister(void);
98 extern void PROGRESS_Register(void);
99 extern void PROGRESS_Unregister(void);
100 extern void REBAR_Register(void);
101 extern void REBAR_Unregister(void);
102 extern void STATUS_Register(void);
103 extern void STATUS_Unregister(void);
104 extern void TAB_Register(void);
105 extern void TAB_Unregister(void);
106 extern void TOOLBAR_Register(void);
107 extern void TOOLBAR_Unregister(void);
108 extern void TOOLTIPS_Register(void);
109 extern void TOOLTIPS_Unregister(void);
110 extern void TRACKBAR_Register(void);
111 extern void TRACKBAR_Unregister(void);
112 extern void TREEVIEW_Register(void);
113 extern void TREEVIEW_Unregister(void);
114 extern void UPDOWN_Register(void);
115 extern void UPDOWN_Unregister(void);
117 static LRESULT WINAPI SubclassWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
119 LPSTR COMCTL32_aSubclass = NULL;
120 HMODULE COMCTL32_hModule = 0;
121 LANGID COMCTL32_uiLang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
122 HBRUSH COMCTL32_hPattern55AABrush = NULL;
123 COMCTL32_SysColor comctl32_color;
125 static HBITMAP COMCTL32_hPattern55AABitmap = NULL;
127 static const WORD wPattern55AA[] =
129 0x5555, 0xaaaa, 0x5555, 0xaaaa,
130 0x5555, 0xaaaa, 0x5555, 0xaaaa
134 /***********************************************************************
135 * DllMain [Internal]
137 * Initializes the internal 'COMCTL32.DLL'.
139 * PARAMS
140 * hinstDLL [I] handle to the 'dlls' instance
141 * fdwReason [I]
142 * lpvReserved [I] reserverd, must be NULL
144 * RETURNS
145 * Success: TRUE
146 * Failure: FALSE
149 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
151 TRACE("%p,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
153 switch (fdwReason) {
154 case DLL_PROCESS_ATTACH:
155 DisableThreadLibraryCalls(hinstDLL);
157 COMCTL32_hModule = (HMODULE)hinstDLL;
159 /* add global subclassing atom (used by 'tooltip' and 'updown') */
160 COMCTL32_aSubclass = (LPSTR)(DWORD)GlobalAddAtomA ("CC32SubclassInfo");
161 TRACE("Subclassing atom added: %p\n", COMCTL32_aSubclass);
163 /* create local pattern brush */
164 COMCTL32_hPattern55AABitmap = CreateBitmap (8, 8, 1, 1, wPattern55AA);
165 COMCTL32_hPattern55AABrush = CreatePatternBrush (COMCTL32_hPattern55AABitmap);
167 /* Get all the colors at DLL load */
168 COMCTL32_RefreshSysColors();
170 /* register all Win95 common control classes */
171 ANIMATE_Register ();
172 FLATSB_Register ();
173 HEADER_Register ();
174 HOTKEY_Register ();
175 LISTVIEW_Register ();
176 PROGRESS_Register ();
177 STATUS_Register ();
178 TAB_Register ();
179 TOOLBAR_Register ();
180 TOOLTIPS_Register ();
181 TRACKBAR_Register ();
182 TREEVIEW_Register ();
183 UPDOWN_Register ();
184 break;
186 case DLL_PROCESS_DETACH:
187 /* unregister all common control classes */
188 ANIMATE_Unregister ();
189 COMBOEX_Unregister ();
190 DATETIME_Unregister ();
191 FLATSB_Unregister ();
192 HEADER_Unregister ();
193 HOTKEY_Unregister ();
194 IPADDRESS_Unregister ();
195 LISTVIEW_Unregister ();
196 MONTHCAL_Unregister ();
197 NATIVEFONT_Unregister ();
198 PAGER_Unregister ();
199 PROGRESS_Unregister ();
200 REBAR_Unregister ();
201 STATUS_Unregister ();
202 TAB_Unregister ();
203 TOOLBAR_Unregister ();
204 TOOLTIPS_Unregister ();
205 TRACKBAR_Unregister ();
206 TREEVIEW_Unregister ();
207 UPDOWN_Unregister ();
209 /* delete local pattern brush */
210 DeleteObject (COMCTL32_hPattern55AABrush);
211 COMCTL32_hPattern55AABrush = NULL;
212 DeleteObject (COMCTL32_hPattern55AABitmap);
213 COMCTL32_hPattern55AABitmap = NULL;
215 /* delete global subclassing atom */
216 GlobalDeleteAtom (LOWORD(COMCTL32_aSubclass));
217 TRACE("Subclassing atom deleted: %p\n", COMCTL32_aSubclass);
218 COMCTL32_aSubclass = NULL;
219 break;
222 return TRUE;
226 /***********************************************************************
227 * MenuHelp [COMCTL32.2]
229 * Handles the setting of status bar help messages when the user
230 * selects menu items.
232 * PARAMS
233 * uMsg [I] message (WM_MENUSELECT) (see NOTES)
234 * wParam [I] wParam of the message uMsg
235 * lParam [I] lParam of the message uMsg
236 * hMainMenu [I] handle to the application's main menu
237 * hInst [I] handle to the module that contains string resources
238 * hwndStatus [I] handle to the status bar window
239 * lpwIDs [I] pointer to an array of integers (see NOTES)
241 * RETURNS
242 * No return value
244 * NOTES
245 * The official documentation is incomplete!
246 * This is the correct documentation:
248 * uMsg:
249 * MenuHelp() does NOT handle WM_COMMAND messages! It only handles
250 * WM_MENUSELECT messages.
252 * lpwIDs:
253 * (will be written ...)
256 VOID WINAPI
257 MenuHelp (UINT uMsg, WPARAM wParam, LPARAM lParam, HMENU hMainMenu,
258 HINSTANCE hInst, HWND hwndStatus, UINT* lpwIDs)
260 UINT uMenuID = 0;
262 if (!IsWindow (hwndStatus))
263 return;
265 switch (uMsg) {
266 case WM_MENUSELECT:
267 TRACE("WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
268 wParam, lParam);
270 if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
271 /* menu was closed */
272 TRACE("menu was closed!\n");
273 SendMessageA (hwndStatus, SB_SIMPLE, FALSE, 0);
275 else {
276 /* menu item was selected */
277 if (HIWORD(wParam) & MF_POPUP)
278 uMenuID = (UINT)*(lpwIDs+1);
279 else
280 uMenuID = (UINT)LOWORD(wParam);
281 TRACE("uMenuID = %u\n", uMenuID);
283 if (uMenuID) {
284 CHAR szText[256];
286 if (!LoadStringA (hInst, uMenuID, szText, 256))
287 szText[0] = '\0';
289 SendMessageA (hwndStatus, SB_SETTEXTA,
290 255 | SBT_NOBORDERS, (LPARAM)szText);
291 SendMessageA (hwndStatus, SB_SIMPLE, TRUE, 0);
294 break;
296 case WM_COMMAND :
297 TRACE("WM_COMMAND wParam=0x%X lParam=0x%lX\n",
298 wParam, lParam);
299 /* WM_COMMAND is not invalid since it is documented
300 * in the windows api reference. So don't output
301 * any FIXME for WM_COMMAND
303 WARN("We don't care about the WM_COMMAND\n");
304 break;
306 default:
307 FIXME("Invalid Message 0x%x!\n", uMsg);
308 break;
313 /***********************************************************************
314 * ShowHideMenuCtl [COMCTL32.3]
316 * Shows or hides controls and updates the corresponding menu item.
318 * PARAMS
319 * hwnd [I] handle to the client window.
320 * uFlags [I] menu command id.
321 * lpInfo [I] pointer to an array of integers. (See NOTES.)
323 * RETURNS
324 * Success: TRUE
325 * Failure: FALSE
327 * NOTES
328 * The official documentation is incomplete!
329 * This is the correct documentation:
331 * hwnd
332 * Handle to the window that contains the menu and controls.
334 * uFlags
335 * Identifier of the menu item to receive or loose a check mark.
337 * lpInfo
338 * The array of integers contains pairs of values. BOTH values of
339 * the first pair must be the handles to the application's main menu.
340 * Each subsequent pair consists of a menu id and control id.
343 BOOL WINAPI
344 ShowHideMenuCtl (HWND hwnd, UINT uFlags, LPINT lpInfo)
346 LPINT lpMenuId;
348 TRACE("%p, %x, %p\n", hwnd, uFlags, lpInfo);
350 if (lpInfo == NULL)
351 return FALSE;
353 if (!(lpInfo[0]) || !(lpInfo[1]))
354 return FALSE;
356 /* search for control */
357 lpMenuId = &lpInfo[2];
358 while (*lpMenuId != uFlags)
359 lpMenuId += 2;
361 if (GetMenuState ((HMENU)lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
362 /* uncheck menu item */
363 CheckMenuItem ((HMENU)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
365 /* hide control */
366 lpMenuId++;
367 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
368 SWP_HIDEWINDOW);
370 else {
371 /* check menu item */
372 CheckMenuItem ((HMENU)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
374 /* show control */
375 lpMenuId++;
376 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
377 SWP_SHOWWINDOW);
380 return TRUE;
384 /***********************************************************************
385 * GetEffectiveClientRect [COMCTL32.4]
387 * Calculates the coordinates of a rectangle in the client area.
389 * PARAMS
390 * hwnd [I] handle to the client window.
391 * lpRect [O] pointer to the rectangle of the client window
392 * lpInfo [I] pointer to an array of integers (see NOTES)
394 * RETURNS
395 * No return value.
397 * NOTES
398 * The official documentation is incomplete!
399 * This is the correct documentation:
401 * lpInfo
402 * (will be written ...)
405 VOID WINAPI
406 GetEffectiveClientRect (HWND hwnd, LPRECT lpRect, LPINT lpInfo)
408 RECT rcCtrl;
409 INT *lpRun;
410 HWND hwndCtrl;
412 TRACE("(0x%08lx 0x%08lx 0x%08lx)\n",
413 (DWORD)hwnd, (DWORD)lpRect, (DWORD)lpInfo);
415 GetClientRect (hwnd, lpRect);
416 lpRun = lpInfo;
418 do {
419 lpRun += 2;
420 if (*lpRun == 0)
421 return;
422 lpRun++;
423 hwndCtrl = GetDlgItem (hwnd, *lpRun);
424 if (GetWindowLongA (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
425 TRACE("control id 0x%x\n", *lpRun);
426 GetWindowRect (hwndCtrl, &rcCtrl);
427 MapWindowPoints (NULL, hwnd, (LPPOINT)&rcCtrl, 2);
428 SubtractRect (lpRect, lpRect, &rcCtrl);
430 lpRun++;
431 } while (*lpRun);
435 /***********************************************************************
436 * DrawStatusTextW [COMCTL32.@]
438 * Draws text with borders, like in a status bar.
440 * PARAMS
441 * hdc [I] handle to the window's display context
442 * lprc [I] pointer to a rectangle
443 * text [I] pointer to the text
444 * style [I] drawing style
446 * RETURNS
447 * No return value.
449 * NOTES
450 * The style variable can have one of the following values:
451 * (will be written ...)
454 void WINAPI DrawStatusTextW (HDC hdc, LPRECT lprc, LPCWSTR text, UINT style)
456 RECT r = *lprc;
457 UINT border = BDR_SUNKENOUTER;
459 if (style & SBT_POPOUT)
460 border = BDR_RAISEDOUTER;
461 else if (style & SBT_NOBORDERS)
462 border = 0;
464 DrawEdge (hdc, &r, border, BF_RECT|BF_ADJUST);
466 /* now draw text */
467 if (text) {
468 int oldbkmode = SetBkMode (hdc, TRANSPARENT);
469 UINT align = DT_LEFT;
470 if (*text == L'\t') {
471 text++;
472 align = DT_CENTER;
473 if (*text == L'\t') {
474 text++;
475 align = DT_RIGHT;
478 r.left += 3;
479 if (style & SBT_RTLREADING)
480 FIXME("Unsupported RTL style!\n");
481 DrawTextW (hdc, text, -1, &r, align|DT_VCENTER|DT_SINGLELINE);
482 SetBkMode(hdc, oldbkmode);
487 /***********************************************************************
488 * DrawStatusText [COMCTL32.@]
489 * DrawStatusTextA [COMCTL32.5]
491 * Draws text with borders, like in a status bar.
493 * PARAMS
494 * hdc [I] handle to the window's display context
495 * lprc [I] pointer to a rectangle
496 * text [I] pointer to the text
497 * style [I] drawing style
499 * RETURNS
500 * No return value.
503 void WINAPI DrawStatusTextA (HDC hdc, LPRECT lprc, LPCSTR text, UINT style)
505 INT len;
506 LPWSTR textW = NULL;
508 if ( text ) {
509 if ( (len = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 )) ) {
510 if ( (textW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )) )
511 MultiByteToWideChar( CP_ACP, 0, text, -1, textW, len );
514 DrawStatusTextW( hdc, lprc, textW, style );
515 HeapFree( GetProcessHeap(), 0, textW );
519 /***********************************************************************
520 * CreateStatusWindow [COMCTL32.@]
521 * CreateStatusWindowA [COMCTL32.6]
523 * Creates a status bar
525 * PARAMS
526 * style [I] window style
527 * text [I] pointer to the window text
528 * parent [I] handle to the parent window
529 * wid [I] control id of the status bar
531 * RETURNS
532 * Success: handle to the status window
533 * Failure: 0
536 HWND WINAPI
537 CreateStatusWindowA (LONG style, LPCSTR text, HWND parent, UINT wid)
539 return CreateWindowA(STATUSCLASSNAMEA, text, style,
540 CW_USEDEFAULT, CW_USEDEFAULT,
541 CW_USEDEFAULT, CW_USEDEFAULT,
542 parent, (HMENU)wid, 0, 0);
546 /***********************************************************************
547 * CreateStatusWindowW [COMCTL32.@]
549 * Creates a status bar control
551 * PARAMS
552 * style [I] window style
553 * text [I] pointer to the window text
554 * parent [I] handle to the parent window
555 * wid [I] control id of the status bar
557 * RETURNS
558 * Success: handle to the status window
559 * Failure: 0
562 HWND WINAPI
563 CreateStatusWindowW (LONG style, LPCWSTR text, HWND parent, UINT wid)
565 return CreateWindowW(STATUSCLASSNAMEW, text, style,
566 CW_USEDEFAULT, CW_USEDEFAULT,
567 CW_USEDEFAULT, CW_USEDEFAULT,
568 parent, (HMENU)wid, 0, 0);
572 /***********************************************************************
573 * CreateUpDownControl [COMCTL32.16]
575 * Creates an up-down control
577 * PARAMS
578 * style [I] window styles
579 * x [I] horizontal position of the control
580 * y [I] vertical position of the control
581 * cx [I] with of the control
582 * cy [I] height of the control
583 * parent [I] handle to the parent window
584 * id [I] the control's identifier
585 * inst [I] handle to the application's module instance
586 * buddy [I] handle to the buddy window, can be NULL
587 * maxVal [I] upper limit of the control
588 * minVal [I] lower limit of the control
589 * curVal [I] current value of the control
591 * RETURNS
592 * Success: handle to the updown control
593 * Failure: 0
596 HWND WINAPI
597 CreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
598 HWND parent, INT id, HINSTANCE inst,
599 HWND buddy, INT maxVal, INT minVal, INT curVal)
601 HWND hUD =
602 CreateWindowA (UPDOWN_CLASSA, 0, style, x, y, cx, cy,
603 parent, (HMENU)id, inst, 0);
604 if (hUD) {
605 SendMessageA (hUD, UDM_SETBUDDY, (WPARAM)buddy, 0);
606 SendMessageA (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
607 SendMessageA (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));
610 return hUD;
614 /***********************************************************************
615 * InitCommonControls [COMCTL32.17]
617 * Registers the common controls.
619 * PARAMS
620 * No parameters.
622 * RETURNS
623 * No return values.
625 * NOTES
626 * This function is just a dummy.
627 * The Win95 controls are registered at the DLL's initialization.
628 * To register other controls InitCommonControlsEx() must be used.
631 VOID WINAPI
632 InitCommonControls (void)
637 /***********************************************************************
638 * InitCommonControlsEx [COMCTL32.@]
640 * Registers the common controls.
642 * PARAMS
643 * lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
645 * RETURNS
646 * Success: TRUE
647 * Failure: FALSE
649 * NOTES
650 * Only the additional common controls are registered by this function.
651 * The Win95 controls are registered at the DLL's initialization.
653 * FIXME
654 * implement the following control classes:
655 * ICC_LINK_CLASS
656 * ICC_STANDARD_CLASSES
659 BOOL WINAPI
660 InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls)
662 INT cCount;
663 DWORD dwMask;
665 if (!lpInitCtrls)
666 return FALSE;
667 if (lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
668 return FALSE;
670 TRACE("(0x%08lx)\n", lpInitCtrls->dwICC);
672 for (cCount = 0; cCount < 32; cCount++) {
673 dwMask = 1 << cCount;
674 if (!(lpInitCtrls->dwICC & dwMask))
675 continue;
677 switch (lpInitCtrls->dwICC & dwMask) {
678 /* dummy initialization */
679 case ICC_ANIMATE_CLASS:
680 case ICC_BAR_CLASSES:
681 case ICC_LISTVIEW_CLASSES:
682 case ICC_TREEVIEW_CLASSES:
683 case ICC_TAB_CLASSES:
684 case ICC_UPDOWN_CLASS:
685 case ICC_PROGRESS_CLASS:
686 case ICC_HOTKEY_CLASS:
687 break;
689 /* advanced classes - not included in Win95 */
690 case ICC_DATE_CLASSES:
691 MONTHCAL_Register ();
692 DATETIME_Register ();
693 break;
695 case ICC_USEREX_CLASSES:
696 COMBOEX_Register ();
697 break;
699 case ICC_COOL_CLASSES:
700 REBAR_Register ();
701 break;
703 case ICC_INTERNET_CLASSES:
704 IPADDRESS_Register ();
705 break;
707 case ICC_PAGESCROLLER_CLASS:
708 PAGER_Register ();
709 break;
711 case ICC_NATIVEFNTCTL_CLASS:
712 NATIVEFONT_Register ();
713 break;
715 default:
716 FIXME("Unknown class! dwICC=0x%lX\n", dwMask);
717 break;
721 return TRUE;
725 /***********************************************************************
726 * CreateToolbarEx [COMCTL32.@]
728 * Creates a toolbar window.
730 * PARAMS
731 * hwnd
732 * style
733 * wID
734 * nBitmaps
735 * hBMInst
736 * wBMID
737 * lpButtons
738 * iNumButtons
739 * dxButton
740 * dyButton
741 * dxBitmap
742 * dyBitmap
743 * uStructSize
745 * RETURNS
746 * Success: handle to the tool bar control
747 * Failure: 0
750 HWND WINAPI
751 CreateToolbarEx (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
752 HINSTANCE hBMInst, UINT wBMID, LPCTBBUTTON lpButtons,
753 INT iNumButtons, INT dxButton, INT dyButton,
754 INT dxBitmap, INT dyBitmap, UINT uStructSize)
756 HWND hwndTB;
758 /* If not position is specified then put it at the top */
759 if ((style & CCS_BOTTOM) == 0) {
760 style|=CCS_TOP;
763 hwndTB =
764 CreateWindowExA (0, TOOLBARCLASSNAMEA, "", style|WS_CHILD, 0, 0, 0, 0,
765 hwnd, (HMENU)wID, 0, NULL);
766 if(hwndTB) {
767 TBADDBITMAP tbab;
769 SendMessageA (hwndTB, TB_BUTTONSTRUCTSIZE,
770 (WPARAM)uStructSize, 0);
772 /* set bitmap and button size */
773 /*If CreateToolbarEx receives 0, windows sets default values*/
774 if (dxBitmap <= 0)
775 dxBitmap = 16;
776 if (dyBitmap <= 0)
777 dyBitmap = 15;
778 SendMessageA (hwndTB, TB_SETBITMAPSIZE, 0,
779 MAKELPARAM((WORD)dxBitmap, (WORD)dyBitmap));
781 if (dxButton <= 0)
782 dxButton = 24;
783 if (dyButton <= 0)
784 dyButton = 22;
785 SendMessageA (hwndTB, TB_SETBUTTONSIZE, 0,
786 MAKELPARAM((WORD)dxButton, (WORD)dyButton));
789 /* add bitmaps */
790 if (nBitmaps > 0)
792 tbab.hInst = hBMInst;
793 tbab.nID = wBMID;
795 SendMessageA (hwndTB, TB_ADDBITMAP,
796 (WPARAM)nBitmaps, (LPARAM)&tbab);
798 /* add buttons */
799 if(iNumButtons > 0)
800 SendMessageA (hwndTB, TB_ADDBUTTONSA,
801 (WPARAM)iNumButtons, (LPARAM)lpButtons);
804 return hwndTB;
808 /***********************************************************************
809 * CreateMappedBitmap [COMCTL32.8]
811 * Loads a bitmap resource using a colour map.
813 * PARAMS
814 * hInstance [I] Handle to the module containing the bitmap.
815 * idBitmap [I] The bitmap resource ID.
816 * wFlags [I] CMB_MASKED for using bitmap as a mask or 0 for normal.
817 * lpColorMap [I] Colour information needed for the bitmap or NULL (uses system colours).
818 * iNumMaps [I] Number of COLORMAP's pointed to by lpColorMap.
820 * RETURNS
821 * Success: handle to the new bitmap
822 * Failure: 0
825 HBITMAP WINAPI
826 CreateMappedBitmap (HINSTANCE hInstance, INT idBitmap, UINT wFlags,
827 LPCOLORMAP lpColorMap, INT iNumMaps)
829 HGLOBAL hglb;
830 HRSRC hRsrc;
831 LPBITMAPINFOHEADER lpBitmap, lpBitmapInfo;
832 UINT nSize, nColorTableSize;
833 RGBQUAD *pColorTable;
834 INT iColor, i, iMaps, nWidth, nHeight;
835 HDC hdcScreen;
836 HBITMAP hbm;
837 LPCOLORMAP sysColorMap;
838 COLORREF cRef;
839 COLORMAP internalColorMap[4] =
840 {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
842 /* initialize pointer to colortable and default color table */
843 if (lpColorMap) {
844 iMaps = iNumMaps;
845 sysColorMap = lpColorMap;
847 else {
848 internalColorMap[0].to = GetSysColor (COLOR_BTNTEXT);
849 internalColorMap[1].to = GetSysColor (COLOR_BTNSHADOW);
850 internalColorMap[2].to = GetSysColor (COLOR_BTNFACE);
851 internalColorMap[3].to = GetSysColor (COLOR_BTNHIGHLIGHT);
852 iMaps = 4;
853 sysColorMap = (LPCOLORMAP)internalColorMap;
856 hRsrc = FindResourceA (hInstance, (LPSTR)idBitmap, (LPSTR)RT_BITMAP);
857 if (hRsrc == 0)
858 return 0;
859 hglb = LoadResource (hInstance, hRsrc);
860 if (hglb == 0)
861 return 0;
862 lpBitmap = (LPBITMAPINFOHEADER)LockResource (hglb);
863 if (lpBitmap == NULL)
864 return 0;
866 nColorTableSize = (1 << lpBitmap->biBitCount);
867 nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
868 lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc (GMEM_FIXED, nSize);
869 if (lpBitmapInfo == NULL)
870 return 0;
871 RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
873 pColorTable = (RGBQUAD*)(((LPBYTE)lpBitmapInfo)+(UINT)lpBitmapInfo->biSize);
875 for (iColor = 0; iColor < nColorTableSize; iColor++) {
876 for (i = 0; i < iMaps; i++) {
877 cRef = RGB(pColorTable[iColor].rgbRed,
878 pColorTable[iColor].rgbGreen,
879 pColorTable[iColor].rgbBlue);
880 if ( cRef == sysColorMap[i].from) {
881 #if 0
882 if (wFlags & CBS_MASKED) {
883 if (sysColorMap[i].to != COLOR_BTNTEXT)
884 pColorTable[iColor] = RGB(255, 255, 255);
886 else
887 #endif
888 pColorTable[iColor].rgbBlue = GetBValue(sysColorMap[i].to);
889 pColorTable[iColor].rgbGreen = GetGValue(sysColorMap[i].to);
890 pColorTable[iColor].rgbRed = GetRValue(sysColorMap[i].to);
891 break;
895 nWidth = (INT)lpBitmapInfo->biWidth;
896 nHeight = (INT)lpBitmapInfo->biHeight;
897 hdcScreen = GetDC (NULL);
898 hbm = CreateCompatibleBitmap (hdcScreen, nWidth, nHeight);
899 if (hbm) {
900 HDC hdcDst = CreateCompatibleDC (hdcScreen);
901 HBITMAP hbmOld = SelectObject (hdcDst, hbm);
902 LPBYTE lpBits = (LPBYTE)(lpBitmap + 1);
903 lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD);
904 StretchDIBits (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
905 lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
906 SRCCOPY);
907 SelectObject (hdcDst, hbmOld);
908 DeleteDC (hdcDst);
910 ReleaseDC (NULL, hdcScreen);
911 GlobalFree ((HGLOBAL)lpBitmapInfo);
912 FreeResource (hglb);
914 return hbm;
918 /***********************************************************************
919 * CreateToolbar [COMCTL32.7]
921 * Creates a toolbar control.
923 * PARAMS
924 * hwnd
925 * style
926 * wID
927 * nBitmaps
928 * hBMInst
929 * wBMID
930 * lpButtons
931 * iNumButtons
933 * RETURNS
934 * Success: handle to the tool bar control
935 * Failure: 0
937 * NOTES
938 * Do not use this functions anymore. Use CreateToolbarEx instead.
941 HWND WINAPI
942 CreateToolbar (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
943 HINSTANCE hBMInst, UINT wBMID,
944 LPCTBBUTTON lpButtons,INT iNumButtons)
946 return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
947 hBMInst, wBMID, lpButtons,
948 iNumButtons, 0, 0, 0, 0, CCSIZEOF_STRUCT(TBBUTTON, dwData));
952 /***********************************************************************
953 * DllGetVersion [COMCTL32.@]
955 * Retrieves version information of the 'COMCTL32.DLL'
957 * PARAMS
958 * pdvi [O] pointer to version information structure.
960 * RETURNS
961 * Success: S_OK
962 * Failure: E_INVALIDARG
964 * NOTES
965 * Returns version of a comctl32.dll from IE4.01 SP1.
968 HRESULT WINAPI
969 COMCTL32_DllGetVersion (DLLVERSIONINFO *pdvi)
971 if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
972 WARN("wrong DLLVERSIONINFO size from app\n");
973 return E_INVALIDARG;
976 pdvi->dwMajorVersion = COMCTL32_VERSION;
977 pdvi->dwMinorVersion = COMCTL32_VERSION_MINOR;
978 pdvi->dwBuildNumber = 2919;
979 pdvi->dwPlatformID = 6304;
981 TRACE("%lu.%lu.%lu.%lu\n",
982 pdvi->dwMajorVersion, pdvi->dwMinorVersion,
983 pdvi->dwBuildNumber, pdvi->dwPlatformID);
985 return S_OK;
988 /***********************************************************************
989 * DllInstall (COMCTL32.@)
991 * Installs the ComCtl32 DLL.
993 * RETURNS
994 * Success: S_OK
995 * Failure: A HRESULT error
997 HRESULT WINAPI COMCTL32_DllInstall(BOOL bInstall, LPCWSTR cmdline)
999 FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE",
1000 debugstr_w(cmdline));
1002 return S_OK;
1005 /***********************************************************************
1006 * _TrackMouseEvent [COMCTL32.@]
1008 * Requests notification of mouse events
1010 * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted
1011 * to the hwnd specified in the ptme structure. After the event message
1012 * is posted to the hwnd, the entry in the queue is removed.
1014 * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely
1015 * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted
1016 * immediately and the TME_LEAVE flag being ignored.
1018 * PARAMS
1019 * ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
1021 * RETURNS
1022 * Success: non-zero
1023 * Failure: zero
1025 * IMPLEMENTATION moved to USER32.TrackMouseEvent
1029 BOOL WINAPI
1030 _TrackMouseEvent (TRACKMOUSEEVENT *ptme)
1032 return TrackMouseEvent (ptme);
1035 /*************************************************************************
1036 * GetMUILanguage [COMCTL32.@]
1038 * Returns the user interface language in use by the current process.
1040 * RETURNS
1041 * Language ID in use by the current process.
1043 LANGID WINAPI GetMUILanguage (VOID)
1045 return COMCTL32_uiLang;
1049 /*************************************************************************
1050 * InitMUILanguage [COMCTL32.@]
1052 * Sets the user interface language to be used by the current process.
1054 * RETURNS
1055 * Nothing.
1057 VOID WINAPI InitMUILanguage (LANGID uiLang)
1059 COMCTL32_uiLang = uiLang;
1063 /***********************************************************************
1064 * SetWindowSubclass [COMCTL32.410]
1066 * Starts a window subclass
1068 * PARAMS
1069 * hWnd [in] handle to window subclass.
1070 * pfnSubclass [in] Pointer to new window procedure.
1071 * uIDSubclass [in] Unique identifier of sublass together with pfnSubclass.
1072 * dwRef [in] Reference data to pass to window procedure.
1074 * RETURNS
1075 * Success: non-zero
1076 * Failure: zero
1078 * BUGS
1079 * If an application manually subclasses a window after subclassing it with
1080 * this API and then with this API again, then none of the previous
1081 * subclasses get called or the origional window procedure.
1084 BOOL WINAPI SetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
1085 UINT_PTR uIDSubclass, DWORD_PTR dwRef)
1087 LPSUBCLASS_INFO stack;
1088 int newnum, n;
1090 TRACE ("(%p, %p, %x, %lx)\n", hWnd, pfnSubclass, uIDSubclass, dwRef);
1092 /* Since the window procedure that we set here has two additional arguments,
1093 * we can't simply set it as the new window procedure of the window. So we
1094 * set our own window procedure and then calculate the other two arguments
1095 * from there. */
1097 /* See if we have been called for this window */
1098 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1099 if (!stack) {
1100 /* allocate stack */
1101 stack = (LPSUBCLASS_INFO)HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY,
1102 sizeof(SUBCLASS_INFO));
1103 if (!stack) {
1104 ERR ("Failed to allocate our Subclassing stack\n");
1105 return FALSE;
1107 SetPropA (hWnd, COMCTL32_aSubclass, (HANDLE)stack);
1109 /* set window procedure to our own and save the current one */
1110 if (IsWindowUnicode (hWnd))
1111 stack->origproc = (WNDPROC)SetWindowLongW (hWnd, GWL_WNDPROC,
1112 (LONG)SubclassWndProc);
1113 else
1114 stack->origproc = (WNDPROC)SetWindowLongA (hWnd, GWL_WNDPROC,
1115 (LONG)SubclassWndProc);
1116 } else {
1117 WNDPROC current;
1118 if (IsWindowUnicode (hWnd))
1119 current = (WNDPROC)GetWindowLongW (hWnd, GWL_WNDPROC);
1120 else
1121 current = (WNDPROC)GetWindowLongA (hWnd, GWL_WNDPROC);
1123 if (current != SubclassWndProc) {
1124 ERR ("Application has subclassed with our procedure, then manually, then with us again. The current implementation can't handle this.\n");
1125 return FALSE;
1129 /* Check to see if we have called this function with the same uIDSubClass
1130 * and pfnSubclass */
1131 for (n = 0; n <= stack->stacknum + stack->stacknew - 1; n++)
1132 if ((stack->SubclassProcs[n].id == uIDSubclass) &&
1133 (stack->SubclassProcs[n].subproc == pfnSubclass)) {
1134 stack->SubclassProcs[n].ref = dwRef;
1135 return TRUE;
1138 if ((stack->stacknum + stack->stacknew) >= 32) {
1139 ERR ("We have a Subclass stack overflow, please increment size\n");
1140 return FALSE;
1143 /* we can't simply increment both stackpos and stacknum because there might
1144 * be a window procedure running lower in the stack, we can only get them
1145 * up to date once the last window procedure has run */
1146 if (stack->stacknum == stack->stackpos) {
1147 stack->stacknum++;
1148 stack->stackpos++;
1149 } else
1150 stack->stacknew++;
1152 newnum = stack->stacknew + stack->stacknum - 1;
1154 stack->SubclassProcs[newnum].subproc = pfnSubclass;
1155 stack->SubclassProcs[newnum].ref = dwRef;
1156 stack->SubclassProcs[newnum].id = uIDSubclass;
1158 return TRUE;
1162 /***********************************************************************
1163 * GetWindowSubclass [COMCTL32.411]
1165 * Gets the Reference data from a subclass.
1167 * PARAMS
1168 * hWnd [in] Handle to window which were subclassing
1169 * pfnSubclass [in] Pointer to the subclass procedure
1170 * uID [in] Unique indentifier of the subclassing procedure
1171 * pdwRef [out] Pointer to the reference data
1173 * RETURNS
1174 * Success: Non-zero
1175 * Failure: 0
1178 BOOL WINAPI GetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
1179 UINT_PTR uID, DWORD_PTR *pdwRef)
1181 LPSUBCLASS_INFO stack;
1182 int n;
1184 TRACE ("(%p, %p, %x, %p)\n", hWnd, pfnSubclass, uID, pdwRef);
1186 /* See if we have been called for this window */
1187 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1188 if (!stack)
1189 return FALSE;
1191 for (n = 0; n <= stack->stacknum + stack->stacknew - 1; n++)
1192 if ((stack->SubclassProcs[n].id == uID) &&
1193 (stack->SubclassProcs[n].subproc == pfnSubclass)) {
1194 *pdwRef = stack->SubclassProcs[n].ref;
1195 return TRUE;
1198 return FALSE;
1202 /***********************************************************************
1203 * RemoveWindowSubclass [COMCTL32.412]
1205 * Removes a window subclass.
1207 * PARAMS
1208 * hWnd [in] Handle to the window were subclassing
1209 * pfnSubclass [in] Pointer to the subclass procedure
1210 * uID [in] Unique identifier of this subclass
1212 * RETURNS
1213 * Success: non-zero
1214 * Failure: zero
1217 BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uID)
1219 LPSUBCLASS_INFO stack;
1220 int n;
1222 TRACE ("(%p, %p, %x)\n", hWnd, pfnSubclass, uID);
1224 /* Find the Subclass to remove */
1225 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1226 if (!stack)
1227 return FALSE;
1229 if ((stack->stacknum == 1) && (stack->stackpos == 1) && !stack->stacknew) {
1230 TRACE("Last Subclass removed, cleaning up\n");
1231 /* clean up our heap and reset the origional window procedure */
1232 if (IsWindowUnicode (hWnd))
1233 SetWindowLongW (hWnd, GWL_WNDPROC, (LONG)stack->origproc);
1234 else
1235 SetWindowLongA (hWnd, GWL_WNDPROC, (LONG)stack->origproc);
1236 HeapFree (GetProcessHeap (), 0, stack);
1237 RemovePropA( hWnd, COMCTL32_aSubclass );
1238 return TRUE;
1241 for (n = stack->stacknum + stack->stacknew - 1; n >= 0; n--)
1242 if ((stack->SubclassProcs[n].id == uID) &&
1243 (stack->SubclassProcs[n].subproc == pfnSubclass)) {
1244 if (n != (stack->stacknum + stack->stacknew))
1245 /* Fill the hole in the stack */
1246 memmove (&stack->SubclassProcs[n], &stack->SubclassProcs[n + 1],
1247 sizeof(stack->SubclassProcs[0]) * (stack->stacknew + stack->stacknum - n));
1248 stack->SubclassProcs[n].subproc = NULL;
1249 stack->SubclassProcs[n].ref = 0;
1250 stack->SubclassProcs[n].id = 0;
1252 /* If we are currently running a window procedure we have to manipulate
1253 * the stack position pointers so that we don't corrupt the stack */
1254 if ((n < stack->stackpos) || (stack->stackpos == stack->stacknum)) {
1255 stack->stacknum--;
1256 stack->stackpos--;
1257 } else if (n >= stack->stackpos)
1258 stack->stacknew--;
1259 return TRUE;
1262 return FALSE;
1266 /***********************************************************************
1267 * SubclassWndProc (internal)
1269 * Window procedure for all subclassed windows.
1270 * Saves the current subclassing stack position to support nested messages
1273 static LRESULT WINAPI SubclassWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1275 LPSUBCLASS_INFO stack;
1276 int stackpos;
1277 LRESULT ret;
1279 /* retrieve our little stack from the Properties */
1280 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1281 if (!stack) {
1282 ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd);
1283 return 0;
1285 stackpos = stack->stackpos;
1286 stack->stackpos = stack->stacknum;
1287 ret = DefSubclassProc(hWnd,uMsg,wParam,lParam);
1288 stack->stackpos = stackpos;
1289 return ret;
1293 /***********************************************************************
1294 * DefSubclassProc [COMCTL32.413]
1296 * Calls the next window procedure (ie. the one before this subclass)
1298 * PARAMS
1299 * hWnd [in] The window that we're subclassing
1300 * uMsg [in] Message
1301 * wParam [in] WPARAM
1302 * lParam [in] LPARAM
1304 * RETURNS
1305 * Success: non-zero
1306 * Failure: zero
1309 LRESULT WINAPI DefSubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1311 LPSUBCLASS_INFO stack;
1312 int stackpos;
1313 LRESULT ret;
1315 /* retrieve our little stack from the Properties */
1316 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1317 if (!stack) {
1318 ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd);
1319 return 0;
1322 /* If we are at pos 0 then we have to call the origional window procedure */
1323 if (stack->stackpos == 0) {
1324 if (IsWindowUnicode (hWnd))
1325 return CallWindowProcW (stack->origproc, hWnd, uMsg, wParam, lParam);
1326 else
1327 return CallWindowProcA (stack->origproc, hWnd, uMsg, wParam, lParam);
1330 stackpos = --stack->stackpos;
1331 /* call the Subclass procedure from the stack */
1332 ret = stack->SubclassProcs[stackpos].subproc (hWnd, uMsg, wParam, lParam,
1333 stack->SubclassProcs[stackpos].id, stack->SubclassProcs[stackpos].ref);
1334 stack->stackpos++;
1336 if ((stack->stackpos == stack->stacknum) && stack->stacknew) {
1337 stack->stacknum += stack->stacknew;
1338 stack->stackpos += stack->stacknew;
1339 stack->stacknew = 0;
1342 /* If we removed the last entry in our stack while a window procedure was
1343 * running then we have to clean up */
1344 if ((stack->stackpos == 0) && (stack->stacknum == 0)) {
1345 TRACE("Last Subclass removed, cleaning up\n");
1346 /* clean up our heap and reset the origional window procedure */
1347 if (IsWindowUnicode (hWnd))
1348 SetWindowLongW (hWnd, GWL_WNDPROC, (LONG)stack->origproc);
1349 else
1350 SetWindowLongA (hWnd, GWL_WNDPROC, (LONG)stack->origproc);
1351 HeapFree (GetProcessHeap (), 0, stack);
1352 RemovePropA( hWnd, COMCTL32_aSubclass );
1353 return TRUE;
1356 return ret;
1360 /***********************************************************************
1361 * COMCTL32_CreateToolTip [NOT AN API]
1363 * Creates a tooltip for the control specified in hwnd and does all
1364 * necessary setup and notifications.
1366 * PARAMS
1367 * hwndOwner [I] Handle to the window that will own the tool tip.
1369 * RETURNS
1370 * Success: Handle of tool tip window.
1371 * Failure: NULL
1374 HWND
1375 COMCTL32_CreateToolTip(HWND hwndOwner)
1377 HWND hwndToolTip;
1379 hwndToolTip = CreateWindowExA(0, TOOLTIPS_CLASSA, NULL, 0,
1380 CW_USEDEFAULT, CW_USEDEFAULT,
1381 CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner,
1382 0, 0, 0);
1384 /* Send NM_TOOLTIPSCREATED notification */
1385 if (hwndToolTip)
1387 NMTOOLTIPSCREATED nmttc;
1388 /* true owner can be different if hwndOwner is a child window */
1389 HWND hwndTrueOwner = GetWindow(hwndToolTip, GW_OWNER);
1390 nmttc.hdr.hwndFrom = hwndTrueOwner;
1391 nmttc.hdr.idFrom = GetWindowLongA(hwndTrueOwner, GWL_ID);
1392 nmttc.hdr.code = NM_TOOLTIPSCREATED;
1393 nmttc.hwndToolTips = hwndToolTip;
1395 SendMessageA(GetParent(hwndTrueOwner), WM_NOTIFY,
1396 (WPARAM)GetWindowLongA(hwndTrueOwner, GWL_ID),
1397 (LPARAM)&nmttc);
1400 return hwndToolTip;
1404 /***********************************************************************
1405 * COMCTL32_RefreshSysColors [NOT AN API]
1407 * Invoked on any control recognizing a WM_SYSCOLORCHANGE message to
1408 * refresh the color values in the color structure
1410 * PARAMS
1411 * none
1413 * RETURNS
1414 * none
1417 VOID
1418 COMCTL32_RefreshSysColors(void)
1420 comctl32_color.clrBtnHighlight = GetSysColor (COLOR_BTNHIGHLIGHT);
1421 comctl32_color.clrBtnShadow = GetSysColor (COLOR_BTNSHADOW);
1422 comctl32_color.clrBtnText = GetSysColor (COLOR_BTNTEXT);
1423 comctl32_color.clrBtnFace = GetSysColor (COLOR_BTNFACE);
1424 comctl32_color.clrHighlight = GetSysColor (COLOR_HIGHLIGHT);
1425 comctl32_color.clrHighlightText = GetSysColor (COLOR_HIGHLIGHTTEXT);
1426 comctl32_color.clr3dHilight = GetSysColor (COLOR_3DHILIGHT);
1427 comctl32_color.clr3dShadow = GetSysColor (COLOR_3DSHADOW);
1428 comctl32_color.clr3dDkShadow = GetSysColor (COLOR_3DDKSHADOW);
1429 comctl32_color.clr3dFace = GetSysColor (COLOR_3DFACE);
1430 comctl32_color.clrWindow = GetSysColor (COLOR_WINDOW);
1431 comctl32_color.clrWindowText = GetSysColor (COLOR_WINDOWTEXT);
1432 comctl32_color.clrGrayText = GetSysColor (COLOR_GRAYTEXT);
1433 comctl32_color.clrActiveCaption = GetSysColor (COLOR_ACTIVECAPTION);
1434 comctl32_color.clrInfoBk = GetSysColor (COLOR_INFOBK);
1435 comctl32_color.clrInfoText = GetSysColor (COLOR_INFOTEXT);