2 * Interface code to StatusWindow widget/control
4 * Copyright 1996 Bruce Milner
5 * Copyright 1998, 1999 Eric Kohl
14 * Run tests using Waite Group Windows95 API Bible Vol. 1&2
15 * The second cdrom contains executables drawstat.exe,gettext.exe,
16 * simple.exe, getparts.exe, setparts.exe, statwnd.exe
21 * 1) Don't hard code bar to bottom of window, allow CCS_TOP also.
22 * 2) Tooltip support (almost done).
25 #define _MAX(a,b) (((a)>(b))?(a):(b))
26 #define _MIN(a,b) (((a)>(b))?(b):(a))
32 #define STATUSBAR_GetInfoPtr(hwnd) ((STATUSWINDOWINFO *)GetWindowLongA (hwnd, 0))
36 STATUSBAR_DrawSizeGrip (HDC hdc
, LPRECT lpRect
)
42 pt
.x
= lpRect
->right
- 1;
43 pt
.y
= lpRect
->bottom
- 1;
45 hOldPen
= SelectObject (hdc
, GetSysColorPen (COLOR_3DFACE
));
46 MoveToEx (hdc
, pt
.x
- 12, pt
.y
, NULL
);
47 LineTo (hdc
, pt
.x
, pt
.y
);
48 LineTo (hdc
, pt
.x
, pt
.y
- 12);
53 SelectObject (hdc
, GetSysColorPen (COLOR_3DSHADOW
));
54 for (i
= 1; i
< 11; i
+= 4) {
55 MoveToEx (hdc
, pt
.x
- i
, pt
.y
, NULL
);
56 LineTo (hdc
, pt
.x
, pt
.y
- i
);
58 MoveToEx (hdc
, pt
.x
- i
-1, pt
.y
, NULL
);
59 LineTo (hdc
, pt
.x
, pt
.y
- i
-1);
62 SelectObject (hdc
, GetSysColorPen (COLOR_3DHIGHLIGHT
));
63 for (i
= 3; i
< 13; i
+= 4) {
64 MoveToEx (hdc
, pt
.x
- i
, pt
.y
, NULL
);
65 LineTo (hdc
, pt
.x
, pt
.y
- i
);
68 SelectObject (hdc
, hOldPen
);
73 STATUSBAR_DrawPart (HDC hdc
, STATUSWINDOWPART
*part
)
76 UINT border
= BDR_SUNKENOUTER
;
78 if (part
->style
==SBT_POPOUT
)
79 border
= BDR_RAISEDOUTER
;
80 else if (part
->style
==SBT_NOBORDERS
)
83 DrawEdge(hdc
, &r
, border
, BF_RECT
|BF_ADJUST
);
87 INT cy
= r
.bottom
- r
.top
;
90 DrawIconEx (hdc
, r
.left
, r
.top
, part
->hIcon
, cy
, cy
, 0, 0, DI_NORMAL
);
96 int oldbkmode
= SetBkMode(hdc
, TRANSPARENT
);
97 LPWSTR p
= (LPWSTR
)part
->text
;
109 DrawTextW (hdc
, p
, lstrlenW (p
), &r
, align
|DT_VCENTER
|DT_SINGLELINE
);
110 if (oldbkmode
!= TRANSPARENT
)
111 SetBkMode(hdc
, oldbkmode
);
117 STATUSBAR_RefreshPart (HWND hwnd
, STATUSWINDOWPART
*part
, HDC hdc
)
119 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
123 if (!IsWindowVisible (hwnd
))
126 if (self
->clrBk
!= CLR_DEFAULT
)
127 hbrBk
= CreateSolidBrush (self
->clrBk
);
129 hbrBk
= GetSysColorBrush (COLOR_3DFACE
);
130 FillRect(hdc
, &part
->bound
, hbrBk
);
132 hOldFont
= SelectObject (hdc
, self
->hFont
? self
->hFont
: self
->hDefaultFont
);
134 if (part
->style
== SBT_OWNERDRAW
) {
137 dis
.CtlID
= GetWindowLongA (hwnd
, GWL_ID
);
141 dis
.rcItem
= part
->bound
;
142 dis
.itemData
= (INT
)part
->text
;
143 SendMessageA (GetParent (hwnd
), WM_DRAWITEM
,
144 (WPARAM
)dis
.CtlID
, (LPARAM
)&dis
);
147 STATUSBAR_DrawPart (hdc
, part
);
149 SelectObject (hdc
, hOldFont
);
151 if (self
->clrBk
!= CLR_DEFAULT
)
152 DeleteObject (hbrBk
);
154 if (GetWindowLongA (hwnd
, GWL_STYLE
) & SBARS_SIZEGRIP
) {
157 GetClientRect (hwnd
, &rect
);
158 STATUSBAR_DrawSizeGrip (hdc
, &rect
);
164 STATUSBAR_Refresh (HWND hwnd
, HDC hdc
)
166 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
172 if (!IsWindowVisible(hwnd
))
175 GetClientRect (hwnd
, &rect
);
177 if (infoPtr
->clrBk
!= CLR_DEFAULT
)
178 hbrBk
= CreateSolidBrush (infoPtr
->clrBk
);
180 hbrBk
= GetSysColorBrush (COLOR_3DFACE
);
181 FillRect(hdc
, &rect
, hbrBk
);
183 hOldFont
= SelectObject (hdc
, infoPtr
->hFont
? infoPtr
->hFont
: infoPtr
->hDefaultFont
);
185 if (infoPtr
->simple
) {
186 STATUSBAR_DrawPart (hdc
, &infoPtr
->part0
);
189 for (i
= 0; i
< infoPtr
->numParts
; i
++) {
190 if (infoPtr
->parts
[i
].style
== SBT_OWNERDRAW
) {
193 dis
.CtlID
= GetWindowLongA (hwnd
, GWL_ID
);
197 dis
.rcItem
= infoPtr
->parts
[i
].bound
;
198 dis
.itemData
= (INT
)infoPtr
->parts
[i
].text
;
199 SendMessageA (GetParent (hwnd
), WM_DRAWITEM
,
200 (WPARAM
)dis
.CtlID
, (LPARAM
)&dis
);
203 STATUSBAR_DrawPart (hdc
, &infoPtr
->parts
[i
]);
207 SelectObject (hdc
, hOldFont
);
209 if (infoPtr
->clrBk
!= CLR_DEFAULT
)
210 DeleteObject (hbrBk
);
212 if (GetWindowLongA(hwnd
, GWL_STYLE
) & SBARS_SIZEGRIP
)
213 STATUSBAR_DrawSizeGrip (hdc
, &rect
);
220 STATUSBAR_SetPartBounds (HWND hwnd
)
222 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
223 STATUSWINDOWPART
*part
;
227 /* get our window size */
228 GetClientRect (hwnd
, &rect
);
230 rect
.top
+= VERT_BORDER
;
232 /* set bounds for simple rectangle */
233 self
->part0
.bound
= rect
;
235 /* set bounds for non-simple rectangles */
236 for (i
= 0; i
< self
->numParts
; i
++) {
237 part
= &self
->parts
[i
];
238 r
= &self
->parts
[i
].bound
;
240 r
->bottom
= rect
.bottom
;
244 r
->left
= self
->parts
[i
-1].bound
.right
+ HORZ_GAP
;
246 r
->right
= rect
.right
;
250 if (self
->hwndToolTip
) {
253 ti
.cbSize
= sizeof(TTTOOLINFOA
);
257 SendMessageA (self
->hwndToolTip
, TTM_NEWTOOLRECTA
,
265 STATUSBAR_RelayEvent (HWND hwndTip
, HWND hwndMsg
, UINT uMsg
,
266 WPARAM wParam
, LPARAM lParam
)
274 msg
.time
= GetMessageTime ();
275 msg
.pt
.x
= LOWORD(GetMessagePos ());
276 msg
.pt
.y
= HIWORD(GetMessagePos ());
278 SendMessageA (hwndTip
, TTM_RELAYEVENT
, 0, (LPARAM
)&msg
);
282 __inline__
static LRESULT
283 STATUSBAR_GetBorders (LPARAM lParam
)
285 LPINT out
= (LPINT
) lParam
;
287 out
[0] = HORZ_BORDER
; /* horizontal border width */
288 out
[1] = VERT_BORDER
; /* vertical border width */
289 out
[2] = HORZ_GAP
; /* width of border between rectangles */
296 STATUSBAR_GetIcon (HWND hwnd
, WPARAM wParam
)
298 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
301 nPart
= (INT
)wParam
& 0x00ff;
302 if ((nPart
< -1) || (nPart
>= self
->numParts
))
306 return (self
->part0
.hIcon
);
308 return (self
->parts
[nPart
].hIcon
);
313 STATUSBAR_GetParts (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
315 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
320 num_parts
= (INT
) wParam
;
321 parts
= (LPINT
) lParam
;
323 return (infoPtr
->numParts
);
324 for (i
= 0; i
< num_parts
; i
++) {
325 parts
[i
] = infoPtr
->parts
[i
].x
;
328 return (infoPtr
->numParts
);
333 STATUSBAR_GetRect (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
335 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
339 part_num
= ((INT
) wParam
) & 0x00ff;
340 rect
= (LPRECT
) lParam
;
342 *rect
= infoPtr
->part0
.bound
;
344 *rect
= infoPtr
->parts
[part_num
].bound
;
350 STATUSBAR_GetTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
352 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
353 STATUSWINDOWPART
*part
;
357 nPart
= ((INT
) wParam
) & 0x00ff;
361 part
= &self
->parts
[nPart
];
363 if (part
->style
== SBT_OWNERDRAW
)
364 result
= (LRESULT
)part
->text
;
366 result
= part
->text
? lstrlenW (part
->text
) : 0;
367 result
|= (part
->style
<< 16);
368 if (lParam
&& LOWORD(result
))
369 lstrcpyWtoA ((LPSTR
)lParam
, part
->text
);
376 STATUSBAR_GetTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
378 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
379 STATUSWINDOWPART
*part
;
383 nPart
= ((INT
)wParam
) & 0x00ff;
385 part
= &infoPtr
->part0
;
387 part
= &infoPtr
->parts
[nPart
];
389 if (part
->style
== SBT_OWNERDRAW
)
390 result
= (LRESULT
)part
->text
;
392 result
= part
->text
? lstrlenW (part
->text
) : 0;
393 result
|= (part
->style
<< 16);
395 lstrcpyW ((LPWSTR
)lParam
, part
->text
);
402 STATUSBAR_GetTextLength (HWND hwnd
, WPARAM wParam
)
404 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
405 STATUSWINDOWPART
*part
;
409 part_num
= ((INT
) wParam
) & 0x00ff;
412 part
= &infoPtr
->part0
;
414 part
= &infoPtr
->parts
[part_num
];
417 result
= lstrlenW(part
->text
);
421 result
|= (part
->style
<< 16);
427 STATUSBAR_GetTipTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
429 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
431 if (infoPtr
->hwndToolTip
) {
433 ti
.cbSize
= sizeof(TTTOOLINFOA
);
435 ti
.uId
= LOWORD(wParam
);
436 SendMessageA (infoPtr
->hwndToolTip
, TTM_GETTEXTA
, 0, (LPARAM
)&ti
);
439 lstrcpynA ((LPSTR
)lParam
, ti
.lpszText
, HIWORD(wParam
));
447 STATUSBAR_GetTipTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
449 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
451 if (infoPtr
->hwndToolTip
) {
453 ti
.cbSize
= sizeof(TTTOOLINFOW
);
455 ti
.uId
= LOWORD(wParam
);
456 SendMessageW (infoPtr
->hwndToolTip
, TTM_GETTEXTW
, 0, (LPARAM
)&ti
);
459 lstrcpynW ((LPWSTR
)lParam
, ti
.lpszText
, HIWORD(wParam
));
466 __inline__
static LRESULT
467 STATUSBAR_GetUnicodeFormat (HWND hwnd
)
469 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
470 return infoPtr
->bUnicode
;
474 __inline__
static LRESULT
475 STATUSBAR_IsSimple (HWND hwnd
)
477 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
478 return infoPtr
->simple
;
483 STATUSBAR_SetBkColor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
485 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
489 oldBkColor
= self
->clrBk
;
490 self
->clrBk
= (COLORREF
)lParam
;
492 STATUSBAR_Refresh (hwnd
, hdc
);
493 ReleaseDC (hwnd
, hdc
);
500 STATUSBAR_SetIcon (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
502 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
503 INT nPart
= (INT
)wParam
& 0x00ff;
506 if ((nPart
< -1) || (nPart
>= self
->numParts
))
511 self
->part0
.hIcon
= (HICON
)lParam
;
513 STATUSBAR_RefreshPart (hwnd
, &self
->part0
, hdc
);
516 self
->parts
[nPart
].hIcon
= (HICON
)lParam
;
518 STATUSBAR_RefreshPart (hwnd
, &self
->parts
[nPart
], hdc
);
520 ReleaseDC (hwnd
, hdc
);
527 STATUSBAR_SetMinHeight (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
529 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
531 if (IsWindowVisible (hwnd
)) {
532 HWND parent
= GetParent (hwnd
);
536 GetClientRect (parent
, &parent_rect
);
537 self
->height
= (INT
)wParam
+ VERT_BORDER
;
538 width
= parent_rect
.right
- parent_rect
.left
;
539 x
= parent_rect
.left
;
540 y
= parent_rect
.bottom
- self
->height
;
541 MoveWindow (hwnd
, parent_rect
.left
,
542 parent_rect
.bottom
- self
->height
,
543 width
, self
->height
, TRUE
);
544 STATUSBAR_SetPartBounds (hwnd
);
552 STATUSBAR_SetParts (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
554 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
555 STATUSWINDOWPART
*tmp
;
562 self
->simple
= FALSE
;
564 oldNumParts
= self
->numParts
;
565 self
->numParts
= (INT
) wParam
;
566 parts
= (LPINT
) lParam
;
567 if (oldNumParts
> self
->numParts
) {
568 for (i
= self
->numParts
; i
< oldNumParts
; i
++) {
569 if (self
->parts
[i
].text
&& (self
->parts
[i
].style
!= SBT_OWNERDRAW
))
570 COMCTL32_Free (self
->parts
[i
].text
);
573 else if (oldNumParts
< self
->numParts
) {
574 tmp
= COMCTL32_Alloc (sizeof(STATUSWINDOWPART
) * self
->numParts
);
575 for (i
= 0; i
< oldNumParts
; i
++) {
576 tmp
[i
] = self
->parts
[i
];
579 COMCTL32_Free (self
->parts
);
583 for (i
= 0; i
< self
->numParts
; i
++) {
584 self
->parts
[i
].x
= parts
[i
];
587 if (self
->hwndToolTip
) {
589 SendMessageA (self
->hwndToolTip
, TTM_GETTOOLCOUNT
, 0, 0);
591 if (nTipCount
< self
->numParts
) {
596 ZeroMemory (&ti
, sizeof(TTTOOLINFOA
));
597 ti
.cbSize
= sizeof(TTTOOLINFOA
);
599 for (i
= nTipCount
; i
< self
->numParts
; i
++) {
600 TRACE (statusbar
, "add tool %d\n", i
);
602 SendMessageA (self
->hwndToolTip
, TTM_ADDTOOLA
,
606 else if (nTipCount
> self
->numParts
) {
610 for (i
= nTipCount
- 1; i
>= self
->numParts
; i
--) {
612 FIXME (statusbar
, "delete tool %d\n", i
);
618 STATUSBAR_SetPartBounds (hwnd
);
621 STATUSBAR_Refresh (hwnd
, hdc
);
622 ReleaseDC (hwnd
, hdc
);
629 STATUSBAR_SetTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
631 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
632 STATUSWINDOWPART
*part
;
639 text
= (LPSTR
) lParam
;
640 part_num
= ((INT
) wParam
) & 0x00ff;
641 style
= ((INT
) wParam
) & 0xff00;
643 if ((self
->simple
) || (self
->parts
==NULL
) || (part_num
==255))
646 part
= &self
->parts
[part_num
];
647 if (!part
) return FALSE
;
649 if (style
== SBT_OWNERDRAW
) {
650 part
->text
= (LPWSTR
)text
;
653 /* duplicate string */
655 COMCTL32_Free (part
->text
);
657 if (text
&& (len
= lstrlenA(text
))) {
658 part
->text
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
659 lstrcpyAtoW (part
->text
, text
);
664 STATUSBAR_RefreshPart (hwnd
, part
, hdc
);
665 ReleaseDC (hwnd
, hdc
);
672 STATUSBAR_SetTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
674 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
675 STATUSWINDOWPART
*part
;
676 INT part_num
, style
, len
;
680 text
= (LPWSTR
) lParam
;
681 part_num
= ((INT
) wParam
) & 0x00ff;
682 style
= ((INT
) wParam
) & 0xff00;
684 if ((self
->simple
) || (self
->parts
==NULL
) || (part_num
==255))
687 part
= &self
->parts
[part_num
];
688 if (!part
) return FALSE
;
690 if (style
== SBT_OWNERDRAW
) {
694 /* duplicate string */
696 COMCTL32_Free (part
->text
);
698 if (text
&& (len
= lstrlenW(text
))) {
699 part
->text
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
700 lstrcpyW(part
->text
, text
);
705 STATUSBAR_RefreshPart (hwnd
, part
, hdc
);
706 ReleaseDC (hwnd
, hdc
);
713 STATUSBAR_SetTipTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
715 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
717 TRACE (statusbar
, "part %d: \"%s\"\n", (INT
)wParam
, (LPSTR
)lParam
);
718 if (infoPtr
->hwndToolTip
) {
720 ti
.cbSize
= sizeof(TTTOOLINFOA
);
722 ti
.uId
= (INT
)wParam
;
724 ti
.lpszText
= (LPSTR
)lParam
;
725 SendMessageA (infoPtr
->hwndToolTip
, TTM_UPDATETIPTEXTA
,
734 STATUSBAR_SetTipTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
736 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
738 TRACE (statusbar
, "part %d: \"%s\"\n", (INT
)wParam
, (LPSTR
)lParam
);
739 if (infoPtr
->hwndToolTip
) {
741 ti
.cbSize
= sizeof(TTTOOLINFOW
);
743 ti
.uId
= (INT
)wParam
;
745 ti
.lpszText
= (LPWSTR
)lParam
;
746 SendMessageW (infoPtr
->hwndToolTip
, TTM_UPDATETIPTEXTW
,
754 __inline__
static LRESULT
755 STATUSBAR_SetUnicodeFormat (HWND hwnd
, WPARAM wParam
)
757 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
758 BOOL bTemp
= infoPtr
->bUnicode
;
760 TRACE (statusbar
, "(0x%x)\n", (BOOL
)wParam
);
761 infoPtr
->bUnicode
= (BOOL
)wParam
;
768 STATUSBAR_Simple (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
770 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
774 infoPtr
->simple
= (BOOL
)wParam
;
776 /* send notification */
777 nmhdr
.hwndFrom
= hwnd
;
778 nmhdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
779 nmhdr
.code
= SBN_SIMPLEMODECHANGE
;
780 SendMessageA (GetParent (hwnd
), WM_NOTIFY
, 0, (LPARAM
)&nmhdr
);
783 STATUSBAR_Refresh (hwnd
, hdc
);
784 ReleaseDC (hwnd
, hdc
);
791 STATUSBAR_WMCreate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
793 LPCREATESTRUCTA lpCreate
= (LPCREATESTRUCTA
)lParam
;
794 NONCLIENTMETRICSA nclm
;
798 STATUSWINDOWINFO
*self
;
800 self
= (STATUSWINDOWINFO
*)COMCTL32_Alloc (sizeof(STATUSWINDOWINFO
));
801 SetWindowLongA (hwnd
, 0, (DWORD
)self
);
805 self
->simple
= FALSE
;
806 self
->clrBk
= CLR_DEFAULT
;
808 GetClientRect (hwnd
, &rect
);
810 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
811 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
812 self
->hDefaultFont
= CreateFontIndirectA (&nclm
.lfStatusFont
);
814 /* initialize simple case */
815 self
->part0
.bound
= rect
;
816 self
->part0
.text
= 0;
818 self
->part0
.style
= 0;
819 self
->part0
.hIcon
= 0;
821 /* initialize first part */
822 self
->parts
= COMCTL32_Alloc (sizeof(STATUSWINDOWPART
));
823 self
->parts
[0].bound
= rect
;
824 self
->parts
[0].text
= 0;
825 self
->parts
[0].x
= -1;
826 self
->parts
[0].style
= 0;
827 self
->parts
[0].hIcon
= 0;
829 if (IsWindowUnicode (hwnd
)) {
830 self
->bUnicode
= TRUE
;
831 if ((len
= lstrlenW ((LPCWSTR
)lpCreate
->lpszName
))) {
832 self
->parts
[0].text
= COMCTL32_Alloc ((len
+ 1)*sizeof(WCHAR
));
833 lstrcpyW (self
->parts
[0].text
, (LPCWSTR
)lpCreate
->lpszName
);
837 if ((len
= lstrlenA ((LPCSTR
)lpCreate
->lpszName
))) {
838 self
->parts
[0].text
= COMCTL32_Alloc ((len
+ 1)*sizeof(WCHAR
));
839 lstrcpyAtoW (self
->parts
[0].text
, (LPCSTR
)lpCreate
->lpszName
);
843 if ((hdc
= GetDC (0))) {
847 hOldFont
= SelectObject (hdc
,self
->hDefaultFont
);
848 GetTextMetricsA(hdc
, &tm
);
849 self
->textHeight
= tm
.tmHeight
;
850 SelectObject (hdc
, hOldFont
);
854 if (GetWindowLongA (hwnd
, GWL_STYLE
) & SBT_TOOLTIPS
) {
856 CreateWindowExA (0, TOOLTIPS_CLASSA
, NULL
, 0,
857 CW_USEDEFAULT
, CW_USEDEFAULT
,
858 CW_USEDEFAULT
, CW_USEDEFAULT
,
860 GetWindowLongA (hwnd
, GWL_HINSTANCE
), NULL
);
862 if (self
->hwndToolTip
) {
863 NMTOOLTIPSCREATED nmttc
;
865 nmttc
.hdr
.hwndFrom
= hwnd
;
866 nmttc
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
867 nmttc
.hdr
.code
= NM_TOOLTIPSCREATED
;
868 nmttc
.hwndToolTips
= self
->hwndToolTip
;
870 SendMessageA (GetParent (hwnd
), WM_NOTIFY
,
871 (WPARAM
)nmttc
.hdr
.idFrom
, (LPARAM
)&nmttc
);
875 GetClientRect (GetParent (hwnd
), &rect
);
876 width
= rect
.right
- rect
.left
;
877 self
->height
= self
->textHeight
+ 4 + VERT_BORDER
;
878 MoveWindow (hwnd
, lpCreate
->x
, lpCreate
->y
-1,
879 width
, self
->height
, FALSE
);
880 STATUSBAR_SetPartBounds (hwnd
);
887 STATUSBAR_WMDestroy (HWND hwnd
)
889 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
892 for (i
= 0; i
< self
->numParts
; i
++) {
893 if (self
->parts
[i
].text
&& (self
->parts
[i
].style
!= SBT_OWNERDRAW
))
894 COMCTL32_Free (self
->parts
[i
].text
);
896 if (self
->part0
.text
&& (self
->part0
.style
!= SBT_OWNERDRAW
))
897 COMCTL32_Free (self
->part0
.text
);
898 COMCTL32_Free (self
->parts
);
900 /* delete default font */
901 if (self
->hDefaultFont
)
902 DeleteObject (self
->hDefaultFont
);
904 /* delete tool tip control */
905 if (self
->hwndToolTip
)
906 DestroyWindow (self
->hwndToolTip
);
908 COMCTL32_Free (self
);
914 static __inline__ LRESULT
915 STATUSBAR_WMGetFont (HWND hwnd
)
917 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
918 return infoPtr
->hFont
;
923 STATUSBAR_WMGetText (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
925 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
928 if (!(infoPtr
->parts
[0].text
))
930 len
= lstrlenW (infoPtr
->parts
[0].text
);
932 if (infoPtr
->bUnicode
)
933 lstrcpyW ((LPWSTR
)lParam
, infoPtr
->parts
[0].text
);
935 lstrcpyWtoA ((LPSTR
)lParam
, infoPtr
->parts
[0].text
);
943 __inline__
static LRESULT
944 STATUSBAR_WMMouseMove (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
946 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
948 if (infoPtr
->hwndToolTip
)
949 STATUSBAR_RelayEvent (infoPtr
->hwndToolTip
, hwnd
,
950 WM_MOUSEMOVE
, wParam
, lParam
);
956 STATUSBAR_WMNCHitTest (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
958 if (GetWindowLongA (hwnd
, GWL_STYLE
) & SBARS_SIZEGRIP
) {
962 GetClientRect (hwnd
, &rect
);
964 pt
.x
= (INT
)LOWORD(lParam
);
965 pt
.y
= (INT
)HIWORD(lParam
);
966 ScreenToClient (hwnd
, &pt
);
968 rect
.left
= rect
.right
- 13;
971 if (PtInRect (&rect
, pt
))
972 return HTBOTTOMRIGHT
;
975 return DefWindowProcA (hwnd
, WM_NCHITTEST
, wParam
, lParam
);
979 static __inline__ LRESULT
980 STATUSBAR_WMNCLButtonDown (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
982 PostMessageA (GetParent (hwnd
), WM_NCLBUTTONDOWN
, wParam
, lParam
);
987 static __inline__ LRESULT
988 STATUSBAR_WMNCLButtonUp (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
990 PostMessageA (GetParent (hwnd
), WM_NCLBUTTONUP
, wParam
, lParam
);
996 STATUSBAR_WMPaint (HWND hwnd
, WPARAM wParam
)
1001 hdc
= wParam
==0 ? BeginPaint (hwnd
, &ps
) : (HDC
)wParam
;
1002 STATUSBAR_Refresh (hwnd
, hdc
);
1004 EndPaint (hwnd
, &ps
);
1011 STATUSBAR_WMSetFont (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1013 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
1015 infoPtr
->hFont
= (HFONT
)wParam
;
1016 if (LOWORD(lParam
) == TRUE
) {
1017 HDC hdc
= GetDC (hwnd
);
1018 STATUSBAR_Refresh (hwnd
, hdc
);
1019 ReleaseDC (hwnd
, hdc
);
1027 STATUSBAR_WMSetText (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1029 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
1030 STATUSWINDOWPART
*part
;
1034 if (infoPtr
->numParts
== 0)
1037 part
= &infoPtr
->parts
[0];
1038 /* duplicate string */
1040 COMCTL32_Free (part
->text
);
1042 if (infoPtr
->bUnicode
) {
1043 if (lParam
&& (len
= lstrlenW((LPCWSTR
)lParam
))) {
1044 part
->text
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1045 lstrcpyW (part
->text
, (LPCWSTR
)lParam
);
1049 if (lParam
&& (len
= lstrlenA((LPCSTR
)lParam
))) {
1050 part
->text
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1051 lstrcpyAtoW (part
->text
, (LPCSTR
)lParam
);
1056 STATUSBAR_RefreshPart (hwnd
, part
, hdc
);
1057 ReleaseDC (hwnd
, hdc
);
1064 STATUSBAR_WMSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1066 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
1067 INT width
, x
, y
, flags
;
1071 /* Need to resize width to match parent */
1072 flags
= (INT
) wParam
;
1074 /* FIXME for flags =
1075 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED, SIZE_RESTORED
1078 if (flags
== SIZE_RESTORED
) {
1079 /* width and height don't apply */
1080 parent
= GetParent (hwnd
);
1081 GetClientRect (parent
, &parent_rect
);
1082 width
= parent_rect
.right
- parent_rect
.left
;
1083 x
= parent_rect
.left
;
1084 y
= parent_rect
.bottom
- infoPtr
->height
;
1085 MoveWindow (hwnd
, parent_rect
.left
,
1086 parent_rect
.bottom
- infoPtr
->height
,
1087 width
, infoPtr
->height
, TRUE
);
1088 STATUSBAR_SetPartBounds (hwnd
);
1095 STATUSBAR_SendNotify (HWND hwnd
, UINT code
)
1099 nmhdr
.hwndFrom
= hwnd
;
1100 nmhdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
1102 SendMessageA (GetParent (hwnd
), WM_NOTIFY
, 0, (LPARAM
)&nmhdr
);
1109 StatusWindowProc (HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1113 return STATUSBAR_GetBorders (lParam
);
1116 return STATUSBAR_GetIcon (hwnd
, wParam
);
1119 return STATUSBAR_GetParts (hwnd
, wParam
, lParam
);
1122 return STATUSBAR_GetRect (hwnd
, wParam
, lParam
);
1125 return STATUSBAR_GetTextA (hwnd
, wParam
, lParam
);
1128 return STATUSBAR_GetTextW (hwnd
, wParam
, lParam
);
1130 case SB_GETTEXTLENGTHA
:
1131 case SB_GETTEXTLENGTHW
:
1132 return STATUSBAR_GetTextLength (hwnd
, wParam
);
1134 case SB_GETTIPTEXTA
:
1135 return STATUSBAR_GetTipTextA (hwnd
, wParam
, lParam
);
1137 case SB_GETTIPTEXTW
:
1138 return STATUSBAR_GetTipTextW (hwnd
, wParam
, lParam
);
1140 case SB_GETUNICODEFORMAT
:
1141 return STATUSBAR_GetUnicodeFormat (hwnd
);
1144 return STATUSBAR_IsSimple (hwnd
);
1147 return STATUSBAR_SetBkColor (hwnd
, wParam
, lParam
);
1150 return STATUSBAR_SetIcon (hwnd
, wParam
, lParam
);
1152 case SB_SETMINHEIGHT
:
1153 return STATUSBAR_SetMinHeight (hwnd
, wParam
, lParam
);
1156 return STATUSBAR_SetParts (hwnd
, wParam
, lParam
);
1159 return STATUSBAR_SetTextA (hwnd
, wParam
, lParam
);
1162 return STATUSBAR_SetTextW (hwnd
, wParam
, lParam
);
1164 case SB_SETTIPTEXTA
:
1165 return STATUSBAR_SetTipTextA (hwnd
, wParam
, lParam
);
1167 case SB_SETTIPTEXTW
:
1168 return STATUSBAR_SetTipTextW (hwnd
, wParam
, lParam
);
1170 case SB_SETUNICODEFORMAT
:
1171 return STATUSBAR_SetUnicodeFormat (hwnd
, wParam
);
1174 return STATUSBAR_Simple (hwnd
, wParam
, lParam
);
1178 return STATUSBAR_WMCreate (hwnd
, wParam
, lParam
);
1181 return STATUSBAR_WMDestroy (hwnd
);
1184 return STATUSBAR_WMGetFont (hwnd
);
1187 return STATUSBAR_WMGetText (hwnd
, wParam
, lParam
);
1189 case WM_GETTEXTLENGTH
:
1190 return STATUSBAR_GetTextLength (hwnd
, 0);
1192 case WM_LBUTTONDBLCLK
:
1193 return STATUSBAR_SendNotify (hwnd
, NM_DBLCLK
);
1196 return STATUSBAR_SendNotify (hwnd
, NM_CLICK
);
1199 return STATUSBAR_WMMouseMove (hwnd
, wParam
, lParam
);
1202 return STATUSBAR_WMNCHitTest (hwnd
, wParam
, lParam
);
1204 case WM_NCLBUTTONDOWN
:
1205 return STATUSBAR_WMNCLButtonDown (hwnd
, wParam
, lParam
);
1207 case WM_NCLBUTTONUP
:
1208 return STATUSBAR_WMNCLButtonUp (hwnd
, wParam
, lParam
);
1211 return STATUSBAR_WMPaint (hwnd
, wParam
);
1213 case WM_RBUTTONDBLCLK
:
1214 return STATUSBAR_SendNotify (hwnd
, NM_RDBLCLK
);
1217 return STATUSBAR_SendNotify (hwnd
, NM_RCLICK
);
1220 return STATUSBAR_WMSetFont (hwnd
, wParam
, lParam
);
1223 return STATUSBAR_WMSetText (hwnd
, wParam
, lParam
);
1226 return STATUSBAR_WMSize (hwnd
, wParam
, lParam
);
1230 ERR (statusbar
, "unknown msg %04x wp=%04x lp=%08lx\n",
1231 msg
, wParam
, lParam
);
1232 return DefWindowProcA (hwnd
, msg
, wParam
, lParam
);
1238 /***********************************************************************
1239 * STATUS_Register [Internal]
1241 * Registers the status window class.
1245 STATUS_Register (VOID
)
1249 if (GlobalFindAtomA (STATUSCLASSNAMEA
)) return;
1251 ZeroMemory (&wndClass
, sizeof(WNDCLASSA
));
1252 wndClass
.style
= CS_GLOBALCLASS
| CS_DBLCLKS
| CS_VREDRAW
;
1253 wndClass
.lpfnWndProc
= (WNDPROC
)StatusWindowProc
;
1254 wndClass
.cbClsExtra
= 0;
1255 wndClass
.cbWndExtra
= sizeof(STATUSWINDOWINFO
*);
1256 wndClass
.hCursor
= LoadCursorA (0, IDC_ARROWA
);
1257 wndClass
.hbrBackground
= (HBRUSH
)(COLOR_3DFACE
+ 1);
1258 wndClass
.lpszClassName
= STATUSCLASSNAMEA
;
1260 RegisterClassA (&wndClass
);
1264 /***********************************************************************
1265 * STATUS_Unregister [Internal]
1267 * Unregisters the status window class.
1271 STATUS_Unregister (VOID
)
1273 if (GlobalFindAtomA (STATUSCLASSNAMEA
))
1274 UnregisterClassA (STATUSCLASSNAMEA
, (HINSTANCE
)NULL
);