2 * Interface code to StatusWindow widget/control
4 * Copyright 1996 Bruce Milner
5 * Copyright 1998, 1999 Eric Kohl
11 #include "debugtools.h"
13 DEFAULT_DEBUG_CHANNEL(statusbar
)
16 * Run tests using Waite Group Windows95 API Bible Vol. 1&2
17 * The second cdrom contains executables drawstat.exe,gettext.exe,
18 * simple.exe, getparts.exe, setparts.exe, statwnd.exe
23 * 1) Don't hard code bar to bottom of window, allow CCS_TOP also.
24 * 2) Tooltip support (almost done).
27 #define _MAX(a,b) (((a)>(b))?(a):(b))
28 #define _MIN(a,b) (((a)>(b))?(b):(a))
34 #define STATUSBAR_GetInfoPtr(hwnd) ((STATUSWINDOWINFO *)GetWindowLongA (hwnd, 0))
38 STATUSBAR_SetPartBounds (HWND hwnd
);
41 STATUSBAR_DrawSizeGrip (HDC hdc
, LPRECT lpRect
)
47 pt
.x
= lpRect
->right
- 1;
48 pt
.y
= lpRect
->bottom
- 1;
50 hOldPen
= SelectObject (hdc
, GetSysColorPen (COLOR_3DFACE
));
51 MoveToEx (hdc
, pt
.x
- 12, pt
.y
, NULL
);
52 LineTo (hdc
, pt
.x
, pt
.y
);
53 LineTo (hdc
, pt
.x
, pt
.y
- 12);
58 SelectObject (hdc
, GetSysColorPen (COLOR_3DSHADOW
));
59 for (i
= 1; i
< 11; i
+= 4) {
60 MoveToEx (hdc
, pt
.x
- i
, pt
.y
, NULL
);
61 LineTo (hdc
, pt
.x
, pt
.y
- i
);
63 MoveToEx (hdc
, pt
.x
- i
-1, pt
.y
, NULL
);
64 LineTo (hdc
, pt
.x
, pt
.y
- i
-1);
67 SelectObject (hdc
, GetSysColorPen (COLOR_3DHIGHLIGHT
));
68 for (i
= 3; i
< 13; i
+= 4) {
69 MoveToEx (hdc
, pt
.x
- i
, pt
.y
, NULL
);
70 LineTo (hdc
, pt
.x
, pt
.y
- i
);
73 SelectObject (hdc
, hOldPen
);
78 STATUSBAR_DrawPart (HDC hdc
, STATUSWINDOWPART
*part
)
81 UINT border
= BDR_SUNKENOUTER
;
83 if (part
->style
& SBT_POPOUT
)
84 border
= BDR_RAISEDOUTER
;
85 else if (part
->style
& SBT_NOBORDERS
)
88 DrawEdge(hdc
, &r
, border
, BF_RECT
|BF_ADJUST
);
92 INT cy
= r
.bottom
- r
.top
;
95 DrawIconEx (hdc
, r
.left
, r
.top
, part
->hIcon
, cy
, cy
, 0, 0, DI_NORMAL
);
101 int oldbkmode
= SetBkMode(hdc
, TRANSPARENT
);
102 LPWSTR p
= (LPWSTR
)part
->text
;
103 UINT align
= DT_LEFT
;
114 DrawTextW (hdc
, p
, lstrlenW (p
), &r
, align
|DT_VCENTER
|DT_SINGLELINE
);
115 if (oldbkmode
!= TRANSPARENT
)
116 SetBkMode(hdc
, oldbkmode
);
122 STATUSBAR_RefreshPart (HWND hwnd
, STATUSWINDOWPART
*part
, HDC hdc
, int itemID
)
124 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
128 if (!IsWindowVisible (hwnd
))
131 if (self
->clrBk
!= CLR_DEFAULT
)
132 hbrBk
= CreateSolidBrush (self
->clrBk
);
134 hbrBk
= GetSysColorBrush (COLOR_3DFACE
);
135 FillRect(hdc
, &part
->bound
, hbrBk
);
137 hOldFont
= SelectObject (hdc
, self
->hFont
? self
->hFont
: self
->hDefaultFont
);
139 if (part
->style
& SBT_OWNERDRAW
) {
142 dis
.CtlID
= GetWindowLongA (hwnd
, GWL_ID
);
146 dis
.rcItem
= part
->bound
;
147 dis
.itemData
= (INT
)part
->text
;
148 SendMessageA (GetParent (hwnd
), WM_DRAWITEM
,
149 (WPARAM
)dis
.CtlID
, (LPARAM
)&dis
);
152 STATUSBAR_DrawPart (hdc
, part
);
154 SelectObject (hdc
, hOldFont
);
156 if (self
->clrBk
!= CLR_DEFAULT
)
157 DeleteObject (hbrBk
);
159 if (GetWindowLongA (hwnd
, GWL_STYLE
) & SBARS_SIZEGRIP
) {
162 GetClientRect (hwnd
, &rect
);
163 STATUSBAR_DrawSizeGrip (hdc
, &rect
);
169 STATUSBAR_Refresh (HWND hwnd
, HDC hdc
)
171 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
177 if (!IsWindowVisible(hwnd
))
180 STATUSBAR_SetPartBounds(hwnd
);
182 GetClientRect (hwnd
, &rect
);
184 if (infoPtr
->clrBk
!= CLR_DEFAULT
)
185 hbrBk
= CreateSolidBrush (infoPtr
->clrBk
);
187 hbrBk
= GetSysColorBrush (COLOR_3DFACE
);
188 FillRect(hdc
, &rect
, hbrBk
);
190 hOldFont
= SelectObject (hdc
, infoPtr
->hFont
? infoPtr
->hFont
: infoPtr
->hDefaultFont
);
192 if (infoPtr
->simple
) {
193 STATUSBAR_RefreshPart (hwnd
, &infoPtr
->part0
,hdc
,0);
196 for (i
= 0; i
< infoPtr
->numParts
; i
++) {
197 if (infoPtr
->parts
[i
].style
& SBT_OWNERDRAW
) {
200 dis
.CtlID
= GetWindowLongA (hwnd
, GWL_ID
);
204 dis
.rcItem
= infoPtr
->parts
[i
].bound
;
205 dis
.itemData
= (INT
)infoPtr
->parts
[i
].text
;
206 SendMessageA (GetParent (hwnd
), WM_DRAWITEM
,
207 (WPARAM
)dis
.CtlID
, (LPARAM
)&dis
);
210 STATUSBAR_RefreshPart (hwnd
, &infoPtr
->parts
[i
], hdc
,i
);
214 SelectObject (hdc
, hOldFont
);
216 if (infoPtr
->clrBk
!= CLR_DEFAULT
)
217 DeleteObject (hbrBk
);
219 if (GetWindowLongA(hwnd
, GWL_STYLE
) & SBARS_SIZEGRIP
)
220 STATUSBAR_DrawSizeGrip (hdc
, &rect
);
227 STATUSBAR_SetPartBounds (HWND hwnd
)
229 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
230 STATUSWINDOWPART
*part
;
234 /* get our window size */
235 GetClientRect (hwnd
, &rect
);
237 rect
.top
+= VERT_BORDER
;
239 /* set bounds for simple rectangle */
240 self
->part0
.bound
= rect
;
242 /* set bounds for non-simple rectangles */
243 for (i
= 0; i
< self
->numParts
; i
++) {
244 part
= &self
->parts
[i
];
245 r
= &self
->parts
[i
].bound
;
247 r
->bottom
= rect
.bottom
;
251 r
->left
= self
->parts
[i
-1].bound
.right
+ HORZ_GAP
;
253 r
->right
= rect
.right
;
257 if (self
->hwndToolTip
) {
260 ti
.cbSize
= sizeof(TTTOOLINFOA
);
264 SendMessageA (self
->hwndToolTip
, TTM_NEWTOOLRECTA
,
272 STATUSBAR_RelayEvent (HWND hwndTip
, HWND hwndMsg
, UINT uMsg
,
273 WPARAM wParam
, LPARAM lParam
)
281 msg
.time
= GetMessageTime ();
282 msg
.pt
.x
= LOWORD(GetMessagePos ());
283 msg
.pt
.y
= HIWORD(GetMessagePos ());
285 SendMessageA (hwndTip
, TTM_RELAYEVENT
, 0, (LPARAM
)&msg
);
289 inline static LRESULT
290 STATUSBAR_GetBorders (LPARAM lParam
)
292 LPINT out
= (LPINT
) lParam
;
294 out
[0] = HORZ_BORDER
; /* horizontal border width */
295 out
[1] = VERT_BORDER
; /* vertical border width */
296 out
[2] = HORZ_GAP
; /* width of border between rectangles */
303 STATUSBAR_GetIcon (HWND hwnd
, WPARAM wParam
)
305 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
308 nPart
= (INT
)wParam
& 0x00ff;
309 if ((nPart
< -1) || (nPart
>= self
->numParts
))
313 return (self
->part0
.hIcon
);
315 return (self
->parts
[nPart
].hIcon
);
320 STATUSBAR_GetParts (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
322 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
327 num_parts
= (INT
) wParam
;
328 parts
= (LPINT
) lParam
;
330 return (infoPtr
->numParts
);
331 for (i
= 0; i
< num_parts
; i
++) {
332 parts
[i
] = infoPtr
->parts
[i
].x
;
335 return (infoPtr
->numParts
);
340 STATUSBAR_GetRect (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
342 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
346 part_num
= ((INT
) wParam
) & 0x00ff;
347 rect
= (LPRECT
) lParam
;
349 *rect
= infoPtr
->part0
.bound
;
351 *rect
= infoPtr
->parts
[part_num
].bound
;
357 STATUSBAR_GetTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
359 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
360 STATUSWINDOWPART
*part
;
364 nPart
= ((INT
) wParam
) & 0x00ff;
368 part
= &self
->parts
[nPart
];
370 if (part
->style
& SBT_OWNERDRAW
)
371 result
= (LRESULT
)part
->text
;
373 result
= part
->text
? lstrlenW (part
->text
) : 0;
374 result
|= (part
->style
<< 16);
375 if (lParam
&& LOWORD(result
))
376 lstrcpyWtoA ((LPSTR
)lParam
, part
->text
);
383 STATUSBAR_GetTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
385 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
386 STATUSWINDOWPART
*part
;
390 nPart
= ((INT
)wParam
) & 0x00ff;
392 part
= &infoPtr
->part0
;
394 part
= &infoPtr
->parts
[nPart
];
396 if (part
->style
& SBT_OWNERDRAW
)
397 result
= (LRESULT
)part
->text
;
399 result
= part
->text
? lstrlenW (part
->text
) : 0;
400 result
|= (part
->style
<< 16);
402 lstrcpyW ((LPWSTR
)lParam
, part
->text
);
409 STATUSBAR_GetTextLength (HWND hwnd
, WPARAM wParam
)
411 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
412 STATUSWINDOWPART
*part
;
416 part_num
= ((INT
) wParam
) & 0x00ff;
419 part
= &infoPtr
->part0
;
421 part
= &infoPtr
->parts
[part_num
];
424 result
= lstrlenW(part
->text
);
428 result
|= (part
->style
<< 16);
434 STATUSBAR_GetTipTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
436 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
438 if (infoPtr
->hwndToolTip
) {
440 ti
.cbSize
= sizeof(TTTOOLINFOA
);
442 ti
.uId
= LOWORD(wParam
);
443 SendMessageA (infoPtr
->hwndToolTip
, TTM_GETTEXTA
, 0, (LPARAM
)&ti
);
446 lstrcpynA ((LPSTR
)lParam
, ti
.lpszText
, HIWORD(wParam
));
454 STATUSBAR_GetTipTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
456 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
458 if (infoPtr
->hwndToolTip
) {
460 ti
.cbSize
= sizeof(TTTOOLINFOW
);
462 ti
.uId
= LOWORD(wParam
);
463 SendMessageW (infoPtr
->hwndToolTip
, TTM_GETTEXTW
, 0, (LPARAM
)&ti
);
466 lstrcpynW ((LPWSTR
)lParam
, ti
.lpszText
, HIWORD(wParam
));
473 inline static LRESULT
474 STATUSBAR_GetUnicodeFormat (HWND hwnd
)
476 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
477 return infoPtr
->bUnicode
;
481 inline static LRESULT
482 STATUSBAR_IsSimple (HWND hwnd
)
484 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
485 return infoPtr
->simple
;
490 STATUSBAR_SetBkColor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
492 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
495 oldBkColor
= self
->clrBk
;
496 self
->clrBk
= (COLORREF
)lParam
;
497 RedrawWindow(hwnd
,(RECT
*)NULL
,(HRGN
)NULL
,RDW_INVALIDATE
|RDW_UPDATENOW
);
504 STATUSBAR_SetIcon (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
506 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
507 INT nPart
= (INT
)wParam
& 0x00ff;
510 if ((nPart
< -1) || (nPart
>= self
->numParts
))
515 self
->part0
.hIcon
= (HICON
)lParam
;
517 RedrawWindow(hwnd
, &self
->part0
.bound
,(HRGN
)NULL
,
518 RDW_INVALIDATE
|RDW_UPDATENOW
);
521 self
->parts
[nPart
].hIcon
= (HICON
)lParam
;
523 RedrawWindow(hwnd
,&self
->parts
[nPart
].bound
,(HRGN
)NULL
,
524 RDW_INVALIDATE
|RDW_UPDATENOW
);
526 ReleaseDC (hwnd
, hdc
);
533 STATUSBAR_SetMinHeight (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
535 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
537 if (IsWindowVisible (hwnd
)) {
538 HWND parent
= GetParent (hwnd
);
542 GetClientRect (parent
, &parent_rect
);
543 self
->height
= (INT
)wParam
+ VERT_BORDER
;
544 width
= parent_rect
.right
- parent_rect
.left
;
545 x
= parent_rect
.left
;
546 y
= parent_rect
.bottom
- self
->height
;
547 MoveWindow (hwnd
, parent_rect
.left
,
548 parent_rect
.bottom
- self
->height
,
549 width
, self
->height
, TRUE
);
550 STATUSBAR_SetPartBounds (hwnd
);
558 STATUSBAR_SetParts (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
560 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
561 STATUSWINDOWPART
*tmp
;
567 self
->simple
= FALSE
;
569 oldNumParts
= self
->numParts
;
570 self
->numParts
= (INT
) wParam
;
571 parts
= (LPINT
) lParam
;
572 if (oldNumParts
> self
->numParts
) {
573 for (i
= self
->numParts
; i
< oldNumParts
; i
++) {
574 if (self
->parts
[i
].text
&& !(self
->parts
[i
].style
& SBT_OWNERDRAW
))
575 COMCTL32_Free (self
->parts
[i
].text
);
578 else if (oldNumParts
< self
->numParts
) {
579 tmp
= COMCTL32_Alloc (sizeof(STATUSWINDOWPART
) * self
->numParts
);
580 for (i
= 0; i
< oldNumParts
; i
++) {
581 tmp
[i
] = self
->parts
[i
];
584 COMCTL32_Free (self
->parts
);
588 for (i
= 0; i
< self
->numParts
; i
++) {
589 self
->parts
[i
].x
= parts
[i
];
592 if (self
->hwndToolTip
) {
594 SendMessageA (self
->hwndToolTip
, TTM_GETTOOLCOUNT
, 0, 0);
596 if (nTipCount
< self
->numParts
) {
601 ZeroMemory (&ti
, sizeof(TTTOOLINFOA
));
602 ti
.cbSize
= sizeof(TTTOOLINFOA
);
604 for (i
= nTipCount
; i
< self
->numParts
; i
++) {
605 TRACE("add tool %d\n", i
);
607 SendMessageA (self
->hwndToolTip
, TTM_ADDTOOLA
,
611 else if (nTipCount
> self
->numParts
) {
615 for (i
= nTipCount
- 1; i
>= self
->numParts
; i
--) {
617 FIXME("delete tool %d\n", i
);
623 STATUSBAR_SetPartBounds (hwnd
);
625 RedrawWindow(hwnd
,(RECT
*)NULL
,(HRGN
)NULL
,RDW_INVALIDATE
|RDW_UPDATENOW
);
632 STATUSBAR_SetTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
634 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
635 STATUSWINDOWPART
*part
=NULL
;
641 text
= (LPSTR
) lParam
;
642 part_num
= ((INT
) wParam
) & 0x00ff;
643 style
= ((INT
) wParam
) & 0xff00;
647 else if (!self
->simple
&& self
->parts
!=NULL
)
648 part
= &self
->parts
[part_num
];
649 if (!part
) return FALSE
;
651 if (!(part
->style
& SBT_OWNERDRAW
) && part
->text
)
652 COMCTL32_Free (part
->text
);
655 if (style
& SBT_OWNERDRAW
) {
656 part
->text
= (LPWSTR
)text
;
659 /* duplicate string */
660 if (text
&& (len
= lstrlenA(text
))) {
661 part
->text
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
662 lstrcpyAtoW (part
->text
, text
);
667 RedrawWindow(hwnd
,&part
->bound
,(HRGN
)NULL
,RDW_INVALIDATE
|RDW_UPDATENOW
);
674 STATUSBAR_SetTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
676 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
677 STATUSWINDOWPART
*part
;
678 INT part_num
, style
, len
;
681 text
= (LPWSTR
) lParam
;
682 part_num
= ((INT
) wParam
) & 0x00ff;
683 style
= ((INT
) wParam
) & 0xff00;
685 if ((self
->simple
) || (self
->parts
==NULL
) || (part_num
==255))
688 part
= &self
->parts
[part_num
];
689 if (!part
) return FALSE
;
691 if (!(part
->style
& SBT_OWNERDRAW
) && part
->text
)
692 COMCTL32_Free (part
->text
);
695 if (style
& SBT_OWNERDRAW
) {
699 /* duplicate string */
700 if (text
&& (len
= lstrlenW(text
))) {
701 part
->text
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
702 lstrcpyW(part
->text
, text
);
707 RedrawWindow(hwnd
,&part
->bound
,(HRGN
)NULL
,RDW_INVALIDATE
|RDW_UPDATENOW
);
714 STATUSBAR_SetTipTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
716 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
718 TRACE("part %d: \"%s\"\n", (INT
)wParam
, (LPSTR
)lParam
);
719 if (infoPtr
->hwndToolTip
) {
721 ti
.cbSize
= sizeof(TTTOOLINFOA
);
723 ti
.uId
= (INT
)wParam
;
725 ti
.lpszText
= (LPSTR
)lParam
;
726 SendMessageA (infoPtr
->hwndToolTip
, TTM_UPDATETIPTEXTA
,
735 STATUSBAR_SetTipTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
737 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
739 TRACE("part %d: \"%s\"\n", (INT
)wParam
, (LPSTR
)lParam
);
740 if (infoPtr
->hwndToolTip
) {
742 ti
.cbSize
= sizeof(TTTOOLINFOW
);
744 ti
.uId
= (INT
)wParam
;
746 ti
.lpszText
= (LPWSTR
)lParam
;
747 SendMessageW (infoPtr
->hwndToolTip
, TTM_UPDATETIPTEXTW
,
755 inline static LRESULT
756 STATUSBAR_SetUnicodeFormat (HWND hwnd
, WPARAM wParam
)
758 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
759 BOOL bTemp
= infoPtr
->bUnicode
;
761 TRACE("(0x%x)\n", (BOOL
)wParam
);
762 infoPtr
->bUnicode
= (BOOL
)wParam
;
769 STATUSBAR_Simple (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
771 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
);
782 RedrawWindow(hwnd
,(RECT
*)NULL
,(HRGN
)NULL
,RDW_INVALIDATE
|RDW_UPDATENOW
);
789 STATUSBAR_WMCreate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
791 LPCREATESTRUCTA lpCreate
= (LPCREATESTRUCTA
)lParam
;
792 NONCLIENTMETRICSA nclm
;
796 STATUSWINDOWINFO
*self
;
798 self
= (STATUSWINDOWINFO
*)COMCTL32_Alloc (sizeof(STATUSWINDOWINFO
));
799 SetWindowLongA (hwnd
, 0, (DWORD
)self
);
803 self
->simple
= FALSE
;
804 self
->clrBk
= CLR_DEFAULT
;
806 GetClientRect (hwnd
, &rect
);
808 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
809 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
810 self
->hDefaultFont
= CreateFontIndirectA (&nclm
.lfStatusFont
);
812 /* initialize simple case */
813 self
->part0
.bound
= rect
;
814 self
->part0
.text
= 0;
816 self
->part0
.style
= 0;
817 self
->part0
.hIcon
= 0;
819 /* initialize first part */
820 self
->parts
= COMCTL32_Alloc (sizeof(STATUSWINDOWPART
));
821 self
->parts
[0].bound
= rect
;
822 self
->parts
[0].text
= 0;
823 self
->parts
[0].x
= -1;
824 self
->parts
[0].style
= 0;
825 self
->parts
[0].hIcon
= 0;
827 if (IsWindowUnicode (hwnd
)) {
828 self
->bUnicode
= TRUE
;
829 if (lpCreate
->lpszName
&&
830 (len
= lstrlenW ((LPCWSTR
)lpCreate
->lpszName
))) {
831 self
->parts
[0].text
= COMCTL32_Alloc ((len
+ 1)*sizeof(WCHAR
));
832 lstrcpyW (self
->parts
[0].text
, (LPCWSTR
)lpCreate
->lpszName
);
836 if (lpCreate
->lpszName
&&
837 (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
);
909 SetWindowLongA(hwnd
, 0, 0);
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 RedrawWindow(hwnd
,(RECT
*)NULL
,(HRGN
)NULL
,
1018 RDW_INVALIDATE
|RDW_UPDATENOW
);
1025 STATUSBAR_WMSetText (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1027 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
1028 STATUSWINDOWPART
*part
;
1031 if (infoPtr
->numParts
== 0)
1034 part
= &infoPtr
->parts
[0];
1035 /* duplicate string */
1037 COMCTL32_Free (part
->text
);
1039 if (infoPtr
->bUnicode
) {
1040 if (lParam
&& (len
= lstrlenW((LPCWSTR
)lParam
))) {
1041 part
->text
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1042 lstrcpyW (part
->text
, (LPCWSTR
)lParam
);
1046 if (lParam
&& (len
= lstrlenA((LPCSTR
)lParam
))) {
1047 part
->text
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1048 lstrcpyAtoW (part
->text
, (LPCSTR
)lParam
);
1052 RedrawWindow(hwnd
,&part
->bound
,(HRGN
)NULL
,RDW_INVALIDATE
|RDW_UPDATENOW
);
1059 STATUSBAR_WMSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1061 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
1062 INT width
, x
, y
, flags
;
1066 /* Need to resize width to match parent */
1067 flags
= (INT
) wParam
;
1069 /* FIXME for flags =
1070 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED, SIZE_RESTORED
1073 if (flags
== SIZE_RESTORED
) {
1074 /* width and height don't apply */
1075 parent
= GetParent (hwnd
);
1076 GetClientRect (parent
, &parent_rect
);
1077 width
= parent_rect
.right
- parent_rect
.left
;
1078 x
= parent_rect
.left
;
1079 y
= parent_rect
.bottom
- infoPtr
->height
;
1080 MoveWindow (hwnd
, parent_rect
.left
,
1081 parent_rect
.bottom
- infoPtr
->height
,
1082 width
, infoPtr
->height
, TRUE
);
1083 STATUSBAR_SetPartBounds (hwnd
);
1090 STATUSBAR_SendNotify (HWND hwnd
, UINT code
)
1094 nmhdr
.hwndFrom
= hwnd
;
1095 nmhdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
1097 SendMessageA (GetParent (hwnd
), WM_NOTIFY
, 0, (LPARAM
)&nmhdr
);
1103 static LRESULT WINAPI
1104 StatusWindowProc (HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1106 TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hwnd
, msg
, wParam
, lParam
);
1107 if (!(STATUSBAR_GetInfoPtr(hwnd
)) && (msg
!= WM_CREATE
))
1108 return DefWindowProcA (hwnd
, msg
, wParam
, lParam
);
1112 return STATUSBAR_GetBorders (lParam
);
1115 return STATUSBAR_GetIcon (hwnd
, wParam
);
1118 return STATUSBAR_GetParts (hwnd
, wParam
, lParam
);
1121 return STATUSBAR_GetRect (hwnd
, wParam
, lParam
);
1124 return STATUSBAR_GetTextA (hwnd
, wParam
, lParam
);
1127 return STATUSBAR_GetTextW (hwnd
, wParam
, lParam
);
1129 case SB_GETTEXTLENGTHA
:
1130 case SB_GETTEXTLENGTHW
:
1131 return STATUSBAR_GetTextLength (hwnd
, wParam
);
1133 case SB_GETTIPTEXTA
:
1134 return STATUSBAR_GetTipTextA (hwnd
, wParam
, lParam
);
1136 case SB_GETTIPTEXTW
:
1137 return STATUSBAR_GetTipTextW (hwnd
, wParam
, lParam
);
1139 case SB_GETUNICODEFORMAT
:
1140 return STATUSBAR_GetUnicodeFormat (hwnd
);
1143 return STATUSBAR_IsSimple (hwnd
);
1146 return STATUSBAR_SetBkColor (hwnd
, wParam
, lParam
);
1149 return STATUSBAR_SetIcon (hwnd
, wParam
, lParam
);
1151 case SB_SETMINHEIGHT
:
1152 return STATUSBAR_SetMinHeight (hwnd
, wParam
, lParam
);
1155 return STATUSBAR_SetParts (hwnd
, wParam
, lParam
);
1158 return STATUSBAR_SetTextA (hwnd
, wParam
, lParam
);
1161 return STATUSBAR_SetTextW (hwnd
, wParam
, lParam
);
1163 case SB_SETTIPTEXTA
:
1164 return STATUSBAR_SetTipTextA (hwnd
, wParam
, lParam
);
1166 case SB_SETTIPTEXTW
:
1167 return STATUSBAR_SetTipTextW (hwnd
, wParam
, lParam
);
1169 case SB_SETUNICODEFORMAT
:
1170 return STATUSBAR_SetUnicodeFormat (hwnd
, wParam
);
1173 return STATUSBAR_Simple (hwnd
, wParam
, lParam
);
1177 return STATUSBAR_WMCreate (hwnd
, wParam
, lParam
);
1180 return STATUSBAR_WMDestroy (hwnd
);
1183 return STATUSBAR_WMGetFont (hwnd
);
1186 return STATUSBAR_WMGetText (hwnd
, wParam
, lParam
);
1188 case WM_GETTEXTLENGTH
:
1189 return STATUSBAR_GetTextLength (hwnd
, 0);
1191 case WM_LBUTTONDBLCLK
:
1192 return STATUSBAR_SendNotify (hwnd
, NM_DBLCLK
);
1195 return STATUSBAR_SendNotify (hwnd
, NM_CLICK
);
1198 return STATUSBAR_WMMouseMove (hwnd
, wParam
, lParam
);
1201 return STATUSBAR_WMNCHitTest (hwnd
, wParam
, lParam
);
1203 case WM_NCLBUTTONDOWN
:
1204 return STATUSBAR_WMNCLButtonDown (hwnd
, wParam
, lParam
);
1206 case WM_NCLBUTTONUP
:
1207 return STATUSBAR_WMNCLButtonUp (hwnd
, wParam
, lParam
);
1210 return STATUSBAR_WMPaint (hwnd
, wParam
);
1212 case WM_RBUTTONDBLCLK
:
1213 return STATUSBAR_SendNotify (hwnd
, NM_RDBLCLK
);
1216 return STATUSBAR_SendNotify (hwnd
, NM_RCLICK
);
1219 return STATUSBAR_WMSetFont (hwnd
, wParam
, lParam
);
1222 return STATUSBAR_WMSetText (hwnd
, wParam
, lParam
);
1225 return STATUSBAR_WMSize (hwnd
, wParam
, lParam
);
1229 ERR("unknown msg %04x wp=%04x lp=%08lx\n",
1230 msg
, wParam
, lParam
);
1231 return DefWindowProcA (hwnd
, msg
, wParam
, lParam
);
1237 /***********************************************************************
1238 * STATUS_Register [Internal]
1240 * Registers the status window class.
1244 STATUS_Register (void)
1248 ZeroMemory (&wndClass
, sizeof(WNDCLASSA
));
1249 wndClass
.style
= CS_GLOBALCLASS
| CS_DBLCLKS
| CS_VREDRAW
;
1250 wndClass
.lpfnWndProc
= (WNDPROC
)StatusWindowProc
;
1251 wndClass
.cbClsExtra
= 0;
1252 wndClass
.cbWndExtra
= sizeof(STATUSWINDOWINFO
*);
1253 wndClass
.hCursor
= LoadCursorA (0, IDC_ARROWA
);
1254 wndClass
.hbrBackground
= (HBRUSH
)(COLOR_3DFACE
+ 1);
1255 wndClass
.lpszClassName
= STATUSCLASSNAMEA
;
1257 RegisterClassA (&wndClass
);
1261 /***********************************************************************
1262 * STATUS_Unregister [Internal]
1264 * Unregisters the status window class.
1268 STATUS_Unregister (void)
1270 UnregisterClassA (STATUSCLASSNAMEA
, (HINSTANCE
)NULL
);