Get rid of the WIN_SetRectangles export from user32.
[wine.git] / dlls / comctl32 / commctrl.c
blobad91b8a3d8429ad7d1074ea80f7b7bdf7df6b299
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 SYSLINK_Register(void);
105 extern void SYSLINK_Unregister(void);
106 extern void TAB_Register(void);
107 extern void TAB_Unregister(void);
108 extern void TOOLBAR_Register(void);
109 extern void TOOLBAR_Unregister(void);
110 extern void TOOLTIPS_Register(void);
111 extern void TOOLTIPS_Unregister(void);
112 extern void TRACKBAR_Register(void);
113 extern void TRACKBAR_Unregister(void);
114 extern void TREEVIEW_Register(void);
115 extern void TREEVIEW_Unregister(void);
116 extern void UPDOWN_Register(void);
117 extern void UPDOWN_Unregister(void);
119 LRESULT WINAPI COMCTL32_SubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
121 LPSTR COMCTL32_aSubclass = NULL;
122 HMODULE COMCTL32_hModule = 0;
123 LANGID COMCTL32_uiLang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
124 HBRUSH COMCTL32_hPattern55AABrush = NULL;
125 COMCTL32_SysColor comctl32_color;
127 static HBITMAP COMCTL32_hPattern55AABitmap = NULL;
129 static const WORD wPattern55AA[] =
131 0x5555, 0xaaaa, 0x5555, 0xaaaa,
132 0x5555, 0xaaaa, 0x5555, 0xaaaa
136 /***********************************************************************
137 * DllMain [Internal]
139 * Initializes the internal 'COMCTL32.DLL'.
141 * PARAMS
142 * hinstDLL [I] handle to the 'dlls' instance
143 * fdwReason [I]
144 * lpvReserved [I] reserverd, must be NULL
146 * RETURNS
147 * Success: TRUE
148 * Failure: FALSE
151 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
153 TRACE("%p,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
155 switch (fdwReason) {
156 case DLL_PROCESS_ATTACH:
157 DisableThreadLibraryCalls(hinstDLL);
159 COMCTL32_hModule = (HMODULE)hinstDLL;
161 /* add global subclassing atom (used by 'tooltip' and 'updown') */
162 COMCTL32_aSubclass = (LPSTR)(DWORD)GlobalAddAtomA ("CC32SubclassInfo");
163 TRACE("Subclassing atom added: %p\n", COMCTL32_aSubclass);
165 /* create local pattern brush */
166 COMCTL32_hPattern55AABitmap = CreateBitmap (8, 8, 1, 1, wPattern55AA);
167 COMCTL32_hPattern55AABrush = CreatePatternBrush (COMCTL32_hPattern55AABitmap);
169 /* Get all the colors at DLL load */
170 COMCTL32_RefreshSysColors();
172 /* register all Win95 common control classes */
173 ANIMATE_Register ();
174 FLATSB_Register ();
175 HEADER_Register ();
176 HOTKEY_Register ();
177 LISTVIEW_Register ();
178 PROGRESS_Register ();
179 STATUS_Register ();
180 SYSLINK_Register ();
181 TAB_Register ();
182 TOOLBAR_Register ();
183 TOOLTIPS_Register ();
184 TRACKBAR_Register ();
185 TREEVIEW_Register ();
186 UPDOWN_Register ();
187 break;
189 case DLL_PROCESS_DETACH:
190 /* unregister all common control classes */
191 ANIMATE_Unregister ();
192 COMBOEX_Unregister ();
193 DATETIME_Unregister ();
194 FLATSB_Unregister ();
195 HEADER_Unregister ();
196 HOTKEY_Unregister ();
197 IPADDRESS_Unregister ();
198 LISTVIEW_Unregister ();
199 MONTHCAL_Unregister ();
200 NATIVEFONT_Unregister ();
201 PAGER_Unregister ();
202 PROGRESS_Unregister ();
203 REBAR_Unregister ();
204 STATUS_Unregister ();
205 SYSLINK_Unregister ();
206 TAB_Unregister ();
207 TOOLBAR_Unregister ();
208 TOOLTIPS_Unregister ();
209 TRACKBAR_Unregister ();
210 TREEVIEW_Unregister ();
211 UPDOWN_Unregister ();
213 /* delete local pattern brush */
214 DeleteObject (COMCTL32_hPattern55AABrush);
215 COMCTL32_hPattern55AABrush = NULL;
216 DeleteObject (COMCTL32_hPattern55AABitmap);
217 COMCTL32_hPattern55AABitmap = NULL;
219 /* delete global subclassing atom */
220 GlobalDeleteAtom (LOWORD(COMCTL32_aSubclass));
221 TRACE("Subclassing atom deleted: %p\n", COMCTL32_aSubclass);
222 COMCTL32_aSubclass = NULL;
223 break;
226 return TRUE;
230 /***********************************************************************
231 * MenuHelp [COMCTL32.2]
233 * Handles the setting of status bar help messages when the user
234 * selects menu items.
236 * PARAMS
237 * uMsg [I] message (WM_MENUSELECT) (see NOTES)
238 * wParam [I] wParam of the message uMsg
239 * lParam [I] lParam of the message uMsg
240 * hMainMenu [I] handle to the application's main menu
241 * hInst [I] handle to the module that contains string resources
242 * hwndStatus [I] handle to the status bar window
243 * lpwIDs [I] pointer to an array of integers (see NOTES)
245 * RETURNS
246 * No return value
248 * NOTES
249 * The official documentation is incomplete!
250 * This is the correct documentation:
252 * uMsg:
253 * MenuHelp() does NOT handle WM_COMMAND messages! It only handles
254 * WM_MENUSELECT messages.
256 * lpwIDs:
257 * (will be written ...)
260 VOID WINAPI
261 MenuHelp (UINT uMsg, WPARAM wParam, LPARAM lParam, HMENU hMainMenu,
262 HINSTANCE hInst, HWND hwndStatus, UINT* lpwIDs)
264 UINT uMenuID = 0;
266 if (!IsWindow (hwndStatus))
267 return;
269 switch (uMsg) {
270 case WM_MENUSELECT:
271 TRACE("WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
272 wParam, lParam);
274 if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
275 /* menu was closed */
276 TRACE("menu was closed!\n");
277 SendMessageA (hwndStatus, SB_SIMPLE, FALSE, 0);
279 else {
280 /* menu item was selected */
281 if (HIWORD(wParam) & MF_POPUP)
282 uMenuID = (UINT)*(lpwIDs+1);
283 else
284 uMenuID = (UINT)LOWORD(wParam);
285 TRACE("uMenuID = %u\n", uMenuID);
287 if (uMenuID) {
288 CHAR szText[256];
290 if (!LoadStringA (hInst, uMenuID, szText, 256))
291 szText[0] = '\0';
293 SendMessageA (hwndStatus, SB_SETTEXTA,
294 255 | SBT_NOBORDERS, (LPARAM)szText);
295 SendMessageA (hwndStatus, SB_SIMPLE, TRUE, 0);
298 break;
300 case WM_COMMAND :
301 TRACE("WM_COMMAND wParam=0x%X lParam=0x%lX\n",
302 wParam, lParam);
303 /* WM_COMMAND is not invalid since it is documented
304 * in the windows api reference. So don't output
305 * any FIXME for WM_COMMAND
307 WARN("We don't care about the WM_COMMAND\n");
308 break;
310 default:
311 FIXME("Invalid Message 0x%x!\n", uMsg);
312 break;
317 /***********************************************************************
318 * ShowHideMenuCtl [COMCTL32.3]
320 * Shows or hides controls and updates the corresponding menu item.
322 * PARAMS
323 * hwnd [I] handle to the client window.
324 * uFlags [I] menu command id.
325 * lpInfo [I] pointer to an array of integers. (See NOTES.)
327 * RETURNS
328 * Success: TRUE
329 * Failure: FALSE
331 * NOTES
332 * The official documentation is incomplete!
333 * This is the correct documentation:
335 * hwnd
336 * Handle to the window that contains the menu and controls.
338 * uFlags
339 * Identifier of the menu item to receive or loose a check mark.
341 * lpInfo
342 * The array of integers contains pairs of values. BOTH values of
343 * the first pair must be the handles to the application's main menu.
344 * Each subsequent pair consists of a menu id and control id.
347 BOOL WINAPI
348 ShowHideMenuCtl (HWND hwnd, UINT uFlags, LPINT lpInfo)
350 LPINT lpMenuId;
352 TRACE("%p, %x, %p\n", hwnd, uFlags, lpInfo);
354 if (lpInfo == NULL)
355 return FALSE;
357 if (!(lpInfo[0]) || !(lpInfo[1]))
358 return FALSE;
360 /* search for control */
361 lpMenuId = &lpInfo[2];
362 while (*lpMenuId != uFlags)
363 lpMenuId += 2;
365 if (GetMenuState ((HMENU)lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
366 /* uncheck menu item */
367 CheckMenuItem ((HMENU)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
369 /* hide control */
370 lpMenuId++;
371 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
372 SWP_HIDEWINDOW);
374 else {
375 /* check menu item */
376 CheckMenuItem ((HMENU)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
378 /* show control */
379 lpMenuId++;
380 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
381 SWP_SHOWWINDOW);
384 return TRUE;
388 /***********************************************************************
389 * GetEffectiveClientRect [COMCTL32.4]
391 * Calculates the coordinates of a rectangle in the client area.
393 * PARAMS
394 * hwnd [I] handle to the client window.
395 * lpRect [O] pointer to the rectangle of the client window
396 * lpInfo [I] pointer to an array of integers (see NOTES)
398 * RETURNS
399 * No return value.
401 * NOTES
402 * The official documentation is incomplete!
403 * This is the correct documentation:
405 * lpInfo
406 * (will be written ...)
409 VOID WINAPI
410 GetEffectiveClientRect (HWND hwnd, LPRECT lpRect, LPINT lpInfo)
412 RECT rcCtrl;
413 INT *lpRun;
414 HWND hwndCtrl;
416 TRACE("(0x%08lx 0x%08lx 0x%08lx)\n",
417 (DWORD)hwnd, (DWORD)lpRect, (DWORD)lpInfo);
419 GetClientRect (hwnd, lpRect);
420 lpRun = lpInfo;
422 do {
423 lpRun += 2;
424 if (*lpRun == 0)
425 return;
426 lpRun++;
427 hwndCtrl = GetDlgItem (hwnd, *lpRun);
428 if (GetWindowLongA (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
429 TRACE("control id 0x%x\n", *lpRun);
430 GetWindowRect (hwndCtrl, &rcCtrl);
431 MapWindowPoints (NULL, hwnd, (LPPOINT)&rcCtrl, 2);
432 SubtractRect (lpRect, lpRect, &rcCtrl);
434 lpRun++;
435 } while (*lpRun);
439 /***********************************************************************
440 * DrawStatusTextW [COMCTL32.@]
442 * Draws text with borders, like in a status bar.
444 * PARAMS
445 * hdc [I] handle to the window's display context
446 * lprc [I] pointer to a rectangle
447 * text [I] pointer to the text
448 * style [I] drawing style
450 * RETURNS
451 * No return value.
453 * NOTES
454 * The style variable can have one of the following values:
455 * (will be written ...)
458 void WINAPI DrawStatusTextW (HDC hdc, LPRECT lprc, LPCWSTR text, UINT style)
460 RECT r = *lprc;
461 UINT border = BDR_SUNKENOUTER;
463 if (style & SBT_POPOUT)
464 border = BDR_RAISEDOUTER;
465 else if (style & SBT_NOBORDERS)
466 border = 0;
468 DrawEdge (hdc, &r, border, BF_RECT|BF_ADJUST);
470 /* now draw text */
471 if (text) {
472 int oldbkmode = SetBkMode (hdc, TRANSPARENT);
473 UINT align = DT_LEFT;
474 if (*text == L'\t') {
475 text++;
476 align = DT_CENTER;
477 if (*text == L'\t') {
478 text++;
479 align = DT_RIGHT;
482 r.left += 3;
483 if (style & SBT_RTLREADING)
484 FIXME("Unsupported RTL style!\n");
485 DrawTextW (hdc, text, -1, &r, align|DT_VCENTER|DT_SINGLELINE);
486 SetBkMode(hdc, oldbkmode);
491 /***********************************************************************
492 * DrawStatusText [COMCTL32.@]
493 * DrawStatusTextA [COMCTL32.5]
495 * Draws text with borders, like in a status bar.
497 * PARAMS
498 * hdc [I] handle to the window's display context
499 * lprc [I] pointer to a rectangle
500 * text [I] pointer to the text
501 * style [I] drawing style
503 * RETURNS
504 * No return value.
507 void WINAPI DrawStatusTextA (HDC hdc, LPRECT lprc, LPCSTR text, UINT style)
509 INT len;
510 LPWSTR textW = NULL;
512 if ( text ) {
513 if ( (len = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 )) ) {
514 if ( (textW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )) )
515 MultiByteToWideChar( CP_ACP, 0, text, -1, textW, len );
518 DrawStatusTextW( hdc, lprc, textW, style );
519 HeapFree( GetProcessHeap(), 0, textW );
523 /***********************************************************************
524 * CreateStatusWindow [COMCTL32.@]
525 * CreateStatusWindowA [COMCTL32.6]
527 * Creates a status bar
529 * PARAMS
530 * style [I] window style
531 * text [I] pointer to the window text
532 * parent [I] handle to the parent window
533 * wid [I] control id of the status bar
535 * RETURNS
536 * Success: handle to the status window
537 * Failure: 0
540 HWND WINAPI
541 CreateStatusWindowA (LONG style, LPCSTR text, HWND parent, UINT wid)
543 return CreateWindowA(STATUSCLASSNAMEA, text, style,
544 CW_USEDEFAULT, CW_USEDEFAULT,
545 CW_USEDEFAULT, CW_USEDEFAULT,
546 parent, (HMENU)wid, 0, 0);
550 /***********************************************************************
551 * CreateStatusWindowW [COMCTL32.@]
553 * Creates a status bar control
555 * PARAMS
556 * style [I] window style
557 * text [I] pointer to the window text
558 * parent [I] handle to the parent window
559 * wid [I] control id of the status bar
561 * RETURNS
562 * Success: handle to the status window
563 * Failure: 0
566 HWND WINAPI
567 CreateStatusWindowW (LONG style, LPCWSTR text, HWND parent, UINT wid)
569 return CreateWindowW(STATUSCLASSNAMEW, text, style,
570 CW_USEDEFAULT, CW_USEDEFAULT,
571 CW_USEDEFAULT, CW_USEDEFAULT,
572 parent, (HMENU)wid, 0, 0);
576 /***********************************************************************
577 * CreateUpDownControl [COMCTL32.16]
579 * Creates an up-down control
581 * PARAMS
582 * style [I] window styles
583 * x [I] horizontal position of the control
584 * y [I] vertical position of the control
585 * cx [I] with of the control
586 * cy [I] height of the control
587 * parent [I] handle to the parent window
588 * id [I] the control's identifier
589 * inst [I] handle to the application's module instance
590 * buddy [I] handle to the buddy window, can be NULL
591 * maxVal [I] upper limit of the control
592 * minVal [I] lower limit of the control
593 * curVal [I] current value of the control
595 * RETURNS
596 * Success: handle to the updown control
597 * Failure: 0
600 HWND WINAPI
601 CreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
602 HWND parent, INT id, HINSTANCE inst,
603 HWND buddy, INT maxVal, INT minVal, INT curVal)
605 HWND hUD =
606 CreateWindowA (UPDOWN_CLASSA, 0, style, x, y, cx, cy,
607 parent, (HMENU)id, inst, 0);
608 if (hUD) {
609 SendMessageA (hUD, UDM_SETBUDDY, (WPARAM)buddy, 0);
610 SendMessageA (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
611 SendMessageA (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));
614 return hUD;
618 /***********************************************************************
619 * InitCommonControls [COMCTL32.17]
621 * Registers the common controls.
623 * PARAMS
624 * No parameters.
626 * RETURNS
627 * No return values.
629 * NOTES
630 * This function is just a dummy.
631 * The Win95 controls are registered at the DLL's initialization.
632 * To register other controls InitCommonControlsEx() must be used.
635 VOID WINAPI
636 InitCommonControls (void)
641 /***********************************************************************
642 * InitCommonControlsEx [COMCTL32.@]
644 * Registers the common controls.
646 * PARAMS
647 * lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
649 * RETURNS
650 * Success: TRUE
651 * Failure: FALSE
653 * NOTES
654 * Only the additional common controls are registered by this function.
655 * The Win95 controls are registered at the DLL's initialization.
657 * FIXME
658 * implement the following control classes:
659 * ICC_LINK_CLASS
660 * ICC_STANDARD_CLASSES
663 BOOL WINAPI
664 InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls)
666 INT cCount;
667 DWORD dwMask;
669 if (!lpInitCtrls)
670 return FALSE;
671 if (lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
672 return FALSE;
674 TRACE("(0x%08lx)\n", lpInitCtrls->dwICC);
676 for (cCount = 0; cCount < 32; cCount++) {
677 dwMask = 1 << cCount;
678 if (!(lpInitCtrls->dwICC & dwMask))
679 continue;
681 switch (lpInitCtrls->dwICC & dwMask) {
682 /* dummy initialization */
683 case ICC_ANIMATE_CLASS:
684 case ICC_BAR_CLASSES:
685 case ICC_LISTVIEW_CLASSES:
686 case ICC_TREEVIEW_CLASSES:
687 case ICC_TAB_CLASSES:
688 case ICC_UPDOWN_CLASS:
689 case ICC_PROGRESS_CLASS:
690 case ICC_HOTKEY_CLASS:
691 break;
693 /* advanced classes - not included in Win95 */
694 case ICC_DATE_CLASSES:
695 MONTHCAL_Register ();
696 DATETIME_Register ();
697 break;
699 case ICC_USEREX_CLASSES:
700 COMBOEX_Register ();
701 break;
703 case ICC_COOL_CLASSES:
704 REBAR_Register ();
705 break;
707 case ICC_INTERNET_CLASSES:
708 IPADDRESS_Register ();
709 break;
711 case ICC_PAGESCROLLER_CLASS:
712 PAGER_Register ();
713 break;
715 case ICC_NATIVEFNTCTL_CLASS:
716 NATIVEFONT_Register ();
717 break;
719 case ICC_LINK_CLASS:
720 SYSLINK_Register ();
721 break;
723 default:
724 FIXME("Unknown class! dwICC=0x%lX\n", dwMask);
725 break;
729 return TRUE;
733 /***********************************************************************
734 * CreateToolbarEx [COMCTL32.@]
736 * Creates a toolbar window.
738 * PARAMS
739 * hwnd
740 * style
741 * wID
742 * nBitmaps
743 * hBMInst
744 * wBMID
745 * lpButtons
746 * iNumButtons
747 * dxButton
748 * dyButton
749 * dxBitmap
750 * dyBitmap
751 * uStructSize
753 * RETURNS
754 * Success: handle to the tool bar control
755 * Failure: 0
758 HWND WINAPI
759 CreateToolbarEx (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
760 HINSTANCE hBMInst, UINT wBMID, LPCTBBUTTON lpButtons,
761 INT iNumButtons, INT dxButton, INT dyButton,
762 INT dxBitmap, INT dyBitmap, UINT uStructSize)
764 HWND hwndTB;
766 hwndTB =
767 CreateWindowExA(0, TOOLBARCLASSNAMEA, NULL, style|WS_CHILD, 0,0,100,30,
768 hwnd, (HMENU)wID, COMCTL32_hModule, NULL);
769 if(hwndTB) {
770 TBADDBITMAP tbab;
772 SendMessageA (hwndTB, TB_BUTTONSTRUCTSIZE,
773 (WPARAM)uStructSize, 0);
775 /* set bitmap and button size */
776 /*If CreateToolbarEx receives 0, windows sets default values*/
777 if (dxBitmap <= 0)
778 dxBitmap = 16;
779 if (dyBitmap <= 0)
780 dyBitmap = 15;
781 SendMessageA (hwndTB, TB_SETBITMAPSIZE, 0,
782 MAKELPARAM((WORD)dxBitmap, (WORD)dyBitmap));
784 if (dxButton <= 0)
785 dxButton = 24;
786 if (dyButton <= 0)
787 dyButton = 22;
788 SendMessageA (hwndTB, TB_SETBUTTONSIZE, 0,
789 MAKELPARAM((WORD)dxButton, (WORD)dyButton));
792 /* add bitmaps */
793 if (nBitmaps > 0)
795 tbab.hInst = hBMInst;
796 tbab.nID = wBMID;
798 SendMessageA (hwndTB, TB_ADDBITMAP,
799 (WPARAM)nBitmaps, (LPARAM)&tbab);
801 /* add buttons */
802 if(iNumButtons > 0)
803 SendMessageA (hwndTB, TB_ADDBUTTONSA,
804 (WPARAM)iNumButtons, (LPARAM)lpButtons);
807 return hwndTB;
811 /***********************************************************************
812 * CreateMappedBitmap [COMCTL32.8]
814 * Loads a bitmap resource using a colour map.
816 * PARAMS
817 * hInstance [I] Handle to the module containing the bitmap.
818 * idBitmap [I] The bitmap resource ID.
819 * wFlags [I] CMB_MASKED for using bitmap as a mask or 0 for normal.
820 * lpColorMap [I] Colour information needed for the bitmap or NULL (uses system colours).
821 * iNumMaps [I] Number of COLORMAP's pointed to by lpColorMap.
823 * RETURNS
824 * Success: handle to the new bitmap
825 * Failure: 0
828 HBITMAP WINAPI
829 CreateMappedBitmap (HINSTANCE hInstance, INT idBitmap, UINT wFlags,
830 LPCOLORMAP lpColorMap, INT iNumMaps)
832 HGLOBAL hglb;
833 HRSRC hRsrc;
834 LPBITMAPINFOHEADER lpBitmap, lpBitmapInfo;
835 UINT nSize, nColorTableSize, iColor;
836 RGBQUAD *pColorTable;
837 INT i, iMaps, nWidth, nHeight;
838 HDC hdcScreen;
839 HBITMAP hbm;
840 LPCOLORMAP sysColorMap;
841 COLORREF cRef;
842 COLORMAP internalColorMap[4] =
843 {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
845 /* initialize pointer to colortable and default color table */
846 if (lpColorMap) {
847 iMaps = iNumMaps;
848 sysColorMap = lpColorMap;
850 else {
851 internalColorMap[0].to = GetSysColor (COLOR_BTNTEXT);
852 internalColorMap[1].to = GetSysColor (COLOR_BTNSHADOW);
853 internalColorMap[2].to = GetSysColor (COLOR_BTNFACE);
854 internalColorMap[3].to = GetSysColor (COLOR_BTNHIGHLIGHT);
855 iMaps = 4;
856 sysColorMap = (LPCOLORMAP)internalColorMap;
859 hRsrc = FindResourceA (hInstance, (LPSTR)idBitmap, (LPSTR)RT_BITMAP);
860 if (hRsrc == 0)
861 return 0;
862 hglb = LoadResource (hInstance, hRsrc);
863 if (hglb == 0)
864 return 0;
865 lpBitmap = (LPBITMAPINFOHEADER)LockResource (hglb);
866 if (lpBitmap == NULL)
867 return 0;
869 if (lpBitmap->biSize >= sizeof(BITMAPINFOHEADER) && lpBitmap->biClrUsed)
870 nColorTableSize = lpBitmap->biClrUsed;
871 else if (lpBitmap->biBitCount <= 8)
872 nColorTableSize = (1 << lpBitmap->biBitCount);
873 else
874 nColorTableSize = 0;
875 nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
876 lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc (GMEM_FIXED, nSize);
877 if (lpBitmapInfo == NULL)
878 return 0;
879 RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
881 pColorTable = (RGBQUAD*)(((LPBYTE)lpBitmapInfo)+(UINT)lpBitmapInfo->biSize);
883 for (iColor = 0; iColor < nColorTableSize; iColor++) {
884 for (i = 0; i < iMaps; i++) {
885 cRef = RGB(pColorTable[iColor].rgbRed,
886 pColorTable[iColor].rgbGreen,
887 pColorTable[iColor].rgbBlue);
888 if ( cRef == sysColorMap[i].from) {
889 #if 0
890 if (wFlags & CBS_MASKED) {
891 if (sysColorMap[i].to != COLOR_BTNTEXT)
892 pColorTable[iColor] = RGB(255, 255, 255);
894 else
895 #endif
896 pColorTable[iColor].rgbBlue = GetBValue(sysColorMap[i].to);
897 pColorTable[iColor].rgbGreen = GetGValue(sysColorMap[i].to);
898 pColorTable[iColor].rgbRed = GetRValue(sysColorMap[i].to);
899 break;
903 nWidth = (INT)lpBitmapInfo->biWidth;
904 nHeight = (INT)lpBitmapInfo->biHeight;
905 hdcScreen = GetDC (NULL);
906 hbm = CreateCompatibleBitmap (hdcScreen, nWidth, nHeight);
907 if (hbm) {
908 HDC hdcDst = CreateCompatibleDC (hdcScreen);
909 HBITMAP hbmOld = SelectObject (hdcDst, hbm);
910 LPBYTE lpBits = (LPBYTE)(lpBitmap + 1);
911 lpBits += nColorTableSize * sizeof(RGBQUAD);
912 StretchDIBits (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
913 lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
914 SRCCOPY);
915 SelectObject (hdcDst, hbmOld);
916 DeleteDC (hdcDst);
918 ReleaseDC (NULL, hdcScreen);
919 GlobalFree ((HGLOBAL)lpBitmapInfo);
920 FreeResource (hglb);
922 return hbm;
926 /***********************************************************************
927 * CreateToolbar [COMCTL32.7]
929 * Creates a toolbar control.
931 * PARAMS
932 * hwnd
933 * style
934 * wID
935 * nBitmaps
936 * hBMInst
937 * wBMID
938 * lpButtons
939 * iNumButtons
941 * RETURNS
942 * Success: handle to the tool bar control
943 * Failure: 0
945 * NOTES
946 * Do not use this functions anymore. Use CreateToolbarEx instead.
949 HWND WINAPI
950 CreateToolbar (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
951 HINSTANCE hBMInst, UINT wBMID,
952 LPCTBBUTTON lpButtons,INT iNumButtons)
954 return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
955 hBMInst, wBMID, lpButtons,
956 iNumButtons, 0, 0, 0, 0, CCSIZEOF_STRUCT(TBBUTTON, dwData));
960 /***********************************************************************
961 * DllGetVersion [COMCTL32.@]
963 * Retrieves version information of the 'COMCTL32.DLL'
965 * PARAMS
966 * pdvi [O] pointer to version information structure.
968 * RETURNS
969 * Success: S_OK
970 * Failure: E_INVALIDARG
972 * NOTES
973 * Returns version of a comctl32.dll from IE4.01 SP1.
976 HRESULT WINAPI
977 COMCTL32_DllGetVersion (DLLVERSIONINFO *pdvi)
979 if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
980 WARN("wrong DLLVERSIONINFO size from app\n");
981 return E_INVALIDARG;
984 pdvi->dwMajorVersion = COMCTL32_VERSION;
985 pdvi->dwMinorVersion = COMCTL32_VERSION_MINOR;
986 pdvi->dwBuildNumber = 2919;
987 pdvi->dwPlatformID = 6304;
989 TRACE("%lu.%lu.%lu.%lu\n",
990 pdvi->dwMajorVersion, pdvi->dwMinorVersion,
991 pdvi->dwBuildNumber, pdvi->dwPlatformID);
993 return S_OK;
996 /***********************************************************************
997 * DllInstall (COMCTL32.@)
999 * Installs the ComCtl32 DLL.
1001 * RETURNS
1002 * Success: S_OK
1003 * Failure: A HRESULT error
1005 HRESULT WINAPI COMCTL32_DllInstall(BOOL bInstall, LPCWSTR cmdline)
1007 FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE",
1008 debugstr_w(cmdline));
1010 return S_OK;
1013 /***********************************************************************
1014 * _TrackMouseEvent [COMCTL32.@]
1016 * Requests notification of mouse events
1018 * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted
1019 * to the hwnd specified in the ptme structure. After the event message
1020 * is posted to the hwnd, the entry in the queue is removed.
1022 * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely
1023 * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted
1024 * immediately and the TME_LEAVE flag being ignored.
1026 * PARAMS
1027 * ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
1029 * RETURNS
1030 * Success: non-zero
1031 * Failure: zero
1033 * IMPLEMENTATION moved to USER32.TrackMouseEvent
1037 BOOL WINAPI
1038 _TrackMouseEvent (TRACKMOUSEEVENT *ptme)
1040 return TrackMouseEvent (ptme);
1043 /*************************************************************************
1044 * GetMUILanguage [COMCTL32.@]
1046 * Returns the user interface language in use by the current process.
1048 * RETURNS
1049 * Language ID in use by the current process.
1051 LANGID WINAPI GetMUILanguage (VOID)
1053 return COMCTL32_uiLang;
1057 /*************************************************************************
1058 * InitMUILanguage [COMCTL32.@]
1060 * Sets the user interface language to be used by the current process.
1062 * RETURNS
1063 * Nothing.
1065 VOID WINAPI InitMUILanguage (LANGID uiLang)
1067 COMCTL32_uiLang = uiLang;
1071 /***********************************************************************
1072 * SetWindowSubclass [COMCTL32.410]
1074 * Starts a window subclass
1076 * PARAMS
1077 * hWnd [in] handle to window subclass.
1078 * pfnSubclass [in] Pointer to new window procedure.
1079 * uIDSubclass [in] Unique identifier of sublass together with pfnSubclass.
1080 * dwRef [in] Reference data to pass to window procedure.
1082 * RETURNS
1083 * Success: non-zero
1084 * Failure: zero
1086 * BUGS
1087 * If an application manually subclasses a window after subclassing it with
1088 * this API and then with this API again, then none of the previous
1089 * subclasses get called or the origional window procedure.
1092 BOOL WINAPI SetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
1093 UINT_PTR uIDSubclass, DWORD_PTR dwRef)
1095 LPSUBCLASS_INFO stack;
1096 LPSUBCLASSPROCS proc;
1098 TRACE ("(%p, %p, %x, %lx)\n", hWnd, pfnSubclass, uIDSubclass, dwRef);
1100 /* Since the window procedure that we set here has two additional arguments,
1101 * we can't simply set it as the new window procedure of the window. So we
1102 * set our own window procedure and then calculate the other two arguments
1103 * from there. */
1105 /* See if we have been called for this window */
1106 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1107 if (!stack) {
1108 /* allocate stack */
1109 stack = (LPSUBCLASS_INFO)HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY,
1110 sizeof(SUBCLASS_INFO));
1111 if (!stack) {
1112 ERR ("Failed to allocate our Subclassing stack\n");
1113 return FALSE;
1115 SetPropA (hWnd, COMCTL32_aSubclass, (HANDLE)stack);
1117 /* set window procedure to our own and save the current one */
1118 if (IsWindowUnicode (hWnd))
1119 stack->origproc = (WNDPROC)SetWindowLongPtrW (hWnd, GWLP_WNDPROC,
1120 (DWORD_PTR)COMCTL32_SubclassProc);
1121 else
1122 stack->origproc = (WNDPROC)SetWindowLongPtrA (hWnd, GWLP_WNDPROC,
1123 (DWORD_PTR)COMCTL32_SubclassProc);
1125 else {
1126 /* Check to see if we have called this function with the same uIDSubClass
1127 * and pfnSubclass */
1128 proc = stack->SubclassProcs;
1129 while (proc) {
1130 if ((proc->id == uIDSubclass) &&
1131 (proc->subproc == pfnSubclass)) {
1132 proc->ref = dwRef;
1133 return TRUE;
1135 proc = proc->next;
1139 proc = HeapAlloc(GetProcessHeap(), 0, sizeof(SUBCLASSPROCS));
1140 if (!proc) {
1141 ERR ("Failed to allocate subclass entry in stack\n");
1142 if (IsWindowUnicode (hWnd))
1143 SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
1144 else
1145 SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
1146 HeapFree (GetProcessHeap (), 0, stack);
1147 RemovePropA( hWnd, COMCTL32_aSubclass );
1148 return FALSE;
1151 proc->subproc = pfnSubclass;
1152 proc->ref = dwRef;
1153 proc->id = uIDSubclass;
1154 proc->next = stack->SubclassProcs;
1155 stack->SubclassProcs = proc;
1157 return TRUE;
1161 /***********************************************************************
1162 * GetWindowSubclass [COMCTL32.411]
1164 * Gets the Reference data from a subclass.
1166 * PARAMS
1167 * hWnd [in] Handle to window which were subclassing
1168 * pfnSubclass [in] Pointer to the subclass procedure
1169 * uID [in] Unique indentifier of the subclassing procedure
1170 * pdwRef [out] Pointer to the reference data
1172 * RETURNS
1173 * Success: Non-zero
1174 * Failure: 0
1177 BOOL WINAPI GetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
1178 UINT_PTR uID, DWORD_PTR *pdwRef)
1180 LPSUBCLASS_INFO stack;
1181 LPSUBCLASSPROCS proc;
1183 TRACE ("(%p, %p, %x, %p)\n", hWnd, pfnSubclass, uID, pdwRef);
1185 /* See if we have been called for this window */
1186 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1187 if (!stack)
1188 return FALSE;
1190 proc = stack->SubclassProcs;
1191 while (proc) {
1192 if ((proc->id == uID) &&
1193 (proc->subproc == pfnSubclass)) {
1194 *pdwRef = proc->ref;
1195 return TRUE;
1197 proc = proc->next;
1200 return FALSE;
1204 /***********************************************************************
1205 * RemoveWindowSubclass [COMCTL32.412]
1207 * Removes a window subclass.
1209 * PARAMS
1210 * hWnd [in] Handle to the window were subclassing
1211 * pfnSubclass [in] Pointer to the subclass procedure
1212 * uID [in] Unique identifier of this subclass
1214 * RETURNS
1215 * Success: non-zero
1216 * Failure: zero
1219 BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uID)
1221 LPSUBCLASS_INFO stack;
1222 LPSUBCLASSPROCS prevproc = NULL;
1223 LPSUBCLASSPROCS proc;
1224 BOOL ret = FALSE;
1226 TRACE ("(%p, %p, %x)\n", hWnd, pfnSubclass, uID);
1228 /* Find the Subclass to remove */
1229 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1230 if (!stack)
1231 return FALSE;
1233 proc = stack->SubclassProcs;
1234 while (proc) {
1235 if ((proc->id == uID) &&
1236 (proc->subproc == pfnSubclass)) {
1238 if (!prevproc)
1239 stack->SubclassProcs = proc->next;
1240 else
1241 prevproc->next = proc->next;
1243 if (stack->stackpos == proc)
1244 stack->stackpos = stack->stackpos->next;
1246 HeapFree (GetProcessHeap (), 0, proc);
1247 ret = TRUE;
1248 break;
1250 prevproc = proc;
1251 proc = proc->next;
1254 if (!stack->SubclassProcs && !stack->running) {
1255 TRACE("Last Subclass removed, cleaning up\n");
1256 /* clean up our heap and reset the origional window procedure */
1257 if (IsWindowUnicode (hWnd))
1258 SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
1259 else
1260 SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
1261 HeapFree (GetProcessHeap (), 0, stack);
1262 RemovePropA( hWnd, COMCTL32_aSubclass );
1265 return ret;
1268 /***********************************************************************
1269 * COMCTL32_SubclassProc (internal)
1271 * Window procedure for all subclassed windows.
1272 * Saves the current subclassing stack position to support nested messages
1274 LRESULT WINAPI COMCTL32_SubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1276 LPSUBCLASS_INFO stack;
1277 LPSUBCLASSPROCS proc;
1278 LRESULT ret;
1280 TRACE ("(%p, 0x%08x, 0x%08x, 0x%08lx)\n", hWnd, uMsg, wParam, lParam);
1282 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1283 if (!stack) {
1284 ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd);
1285 return 0;
1288 /* Save our old stackpos to properly handle nested messages */
1289 proc = stack->stackpos;
1290 stack->stackpos = stack->SubclassProcs;
1291 stack->running++;
1292 ret = DefSubclassProc(hWnd, uMsg, wParam, lParam);
1293 stack->running--;
1294 stack->stackpos = proc;
1296 if (!stack->SubclassProcs) {
1297 TRACE("Last Subclass removed, cleaning up\n");
1298 /* clean up our heap and reset the origional window procedure */
1299 if (IsWindowUnicode (hWnd))
1300 SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
1301 else
1302 SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
1303 HeapFree (GetProcessHeap (), 0, stack);
1304 RemovePropA( hWnd, COMCTL32_aSubclass );
1306 return ret;
1309 /***********************************************************************
1310 * DefSubclassProc [COMCTL32.413]
1312 * Calls the next window procedure (ie. the one before this subclass)
1314 * PARAMS
1315 * hWnd [in] The window that we're subclassing
1316 * uMsg [in] Message
1317 * wParam [in] WPARAM
1318 * lParam [in] LPARAM
1320 * RETURNS
1321 * Success: non-zero
1322 * Failure: zero
1325 LRESULT WINAPI DefSubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1327 LPSUBCLASS_INFO stack;
1328 LRESULT ret;
1330 TRACE ("(%p, 0x%08x, 0x%08x, 0x%08lx)\n", hWnd, uMsg, wParam, lParam);
1332 /* retrieve our little stack from the Properties */
1333 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1334 if (!stack) {
1335 ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd);
1336 return 0;
1339 /* If we are at the end of stack then we have to call the original
1340 * window procedure */
1341 if (!stack->stackpos) {
1342 if (IsWindowUnicode (hWnd))
1343 ret = CallWindowProcW (stack->origproc, hWnd, uMsg, wParam, lParam);
1344 else
1345 ret = CallWindowProcA (stack->origproc, hWnd, uMsg, wParam, lParam);
1346 } else {
1347 LPSUBCLASSPROCS proc = stack->stackpos;
1348 stack->stackpos = stack->stackpos->next;
1349 /* call the Subclass procedure from the stack */
1350 ret = proc->subproc (hWnd, uMsg, wParam, lParam,
1351 proc->id, proc->ref);
1354 return ret;
1358 /***********************************************************************
1359 * COMCTL32_CreateToolTip [NOT AN API]
1361 * Creates a tooltip for the control specified in hwnd and does all
1362 * necessary setup and notifications.
1364 * PARAMS
1365 * hwndOwner [I] Handle to the window that will own the tool tip.
1367 * RETURNS
1368 * Success: Handle of tool tip window.
1369 * Failure: NULL
1372 HWND
1373 COMCTL32_CreateToolTip(HWND hwndOwner)
1375 HWND hwndToolTip;
1377 hwndToolTip = CreateWindowExA(0, TOOLTIPS_CLASSA, NULL, 0,
1378 CW_USEDEFAULT, CW_USEDEFAULT,
1379 CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner,
1380 0, 0, 0);
1382 /* Send NM_TOOLTIPSCREATED notification */
1383 if (hwndToolTip)
1385 NMTOOLTIPSCREATED nmttc;
1386 /* true owner can be different if hwndOwner is a child window */
1387 HWND hwndTrueOwner = GetWindow(hwndToolTip, GW_OWNER);
1388 nmttc.hdr.hwndFrom = hwndTrueOwner;
1389 nmttc.hdr.idFrom = GetWindowLongPtrW(hwndTrueOwner, GWLP_ID);
1390 nmttc.hdr.code = NM_TOOLTIPSCREATED;
1391 nmttc.hwndToolTips = hwndToolTip;
1393 SendMessageA(GetParent(hwndTrueOwner), WM_NOTIFY,
1394 (WPARAM)GetWindowLongPtrW(hwndTrueOwner, GWLP_ID),
1395 (LPARAM)&nmttc);
1398 return hwndToolTip;
1402 /***********************************************************************
1403 * COMCTL32_RefreshSysColors [NOT AN API]
1405 * Invoked on any control recognizing a WM_SYSCOLORCHANGE message to
1406 * refresh the color values in the color structure
1408 * PARAMS
1409 * none
1411 * RETURNS
1412 * none
1415 VOID
1416 COMCTL32_RefreshSysColors(void)
1418 comctl32_color.clrBtnHighlight = GetSysColor (COLOR_BTNHIGHLIGHT);
1419 comctl32_color.clrBtnShadow = GetSysColor (COLOR_BTNSHADOW);
1420 comctl32_color.clrBtnText = GetSysColor (COLOR_BTNTEXT);
1421 comctl32_color.clrBtnFace = GetSysColor (COLOR_BTNFACE);
1422 comctl32_color.clrHighlight = GetSysColor (COLOR_HIGHLIGHT);
1423 comctl32_color.clrHighlightText = GetSysColor (COLOR_HIGHLIGHTTEXT);
1424 comctl32_color.clr3dHilight = GetSysColor (COLOR_3DHILIGHT);
1425 comctl32_color.clr3dShadow = GetSysColor (COLOR_3DSHADOW);
1426 comctl32_color.clr3dDkShadow = GetSysColor (COLOR_3DDKSHADOW);
1427 comctl32_color.clr3dFace = GetSysColor (COLOR_3DFACE);
1428 comctl32_color.clrWindow = GetSysColor (COLOR_WINDOW);
1429 comctl32_color.clrWindowText = GetSysColor (COLOR_WINDOWTEXT);
1430 comctl32_color.clrGrayText = GetSysColor (COLOR_GRAYTEXT);
1431 comctl32_color.clrActiveCaption = GetSysColor (COLOR_ACTIVECAPTION);
1432 comctl32_color.clrInfoBk = GetSysColor (COLOR_INFOBK);
1433 comctl32_color.clrInfoText = GetSysColor (COLOR_INFOTEXT);
1436 /***********************************************************************
1437 * COMCTL32_DrawInsertMark [NOT AN API]
1439 * Draws an insertion mark (which looks similar to an 'I').
1441 * PARAMS
1442 * hDC [I] Device context to draw onto.
1443 * lpRect [I] Co-ordinates of insertion mark.
1444 * clrInsertMark [I] Colour of the insertion mark.
1445 * bHorizontal [I] True if insert mark should be drawn horizontally,
1446 * vertical otherwise.
1448 * RETURNS
1449 * none
1451 * NOTES
1452 * Draws up to but not including the bottom co-ordinate when drawing
1453 * vertically or the right co-ordinate when horizontal.
1455 void COMCTL32_DrawInsertMark(HDC hDC, const RECT *lpRect, COLORREF clrInsertMark, BOOL bHorizontal)
1457 HPEN hPen = CreatePen(PS_SOLID, 1, clrInsertMark);
1458 HPEN hOldPen;
1459 static const DWORD adwPolyPoints[] = {4,4,4};
1460 LONG lCentre = (bHorizontal ?
1461 lpRect->top + (lpRect->bottom - lpRect->top)/2 :
1462 lpRect->left + (lpRect->right - lpRect->left)/2);
1463 LONG l1 = (bHorizontal ? lpRect->left : lpRect->top);
1464 LONG l2 = (bHorizontal ? lpRect->right : lpRect->bottom);
1465 const POINT aptInsertMark[] =
1467 /* top (V) or left (H) arrow */
1468 {lCentre , l1 + 2},
1469 {lCentre - 2, l1 },
1470 {lCentre + 3, l1 },
1471 {lCentre + 1, l1 + 2},
1472 /* middle line */
1473 {lCentre , l2 - 2},
1474 {lCentre , l1 - 1},
1475 {lCentre + 1, l1 - 1},
1476 {lCentre + 1, l2 - 2},
1477 /* bottom (V) or right (H) arrow */
1478 {lCentre , l2 - 3},
1479 {lCentre - 2, l2 - 1},
1480 {lCentre + 3, l2 - 1},
1481 {lCentre + 1, l2 - 3},
1483 hOldPen = SelectObject(hDC, hPen);
1484 PolyPolyline(hDC, aptInsertMark, adwPolyPoints, sizeof(adwPolyPoints)/sizeof(adwPolyPoints[0]));
1485 SelectObject(hDC, hOldPen);
1486 DeleteObject(hPen);