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_DrawSizeGrip (HDC hdc
, LPRECT lpRect
)
44 pt
.x
= lpRect
->right
- 1;
45 pt
.y
= lpRect
->bottom
- 1;
47 hOldPen
= SelectObject (hdc
, GetSysColorPen (COLOR_3DFACE
));
48 MoveToEx (hdc
, pt
.x
- 12, pt
.y
, NULL
);
49 LineTo (hdc
, pt
.x
, pt
.y
);
50 LineTo (hdc
, pt
.x
, pt
.y
- 12);
55 SelectObject (hdc
, GetSysColorPen (COLOR_3DSHADOW
));
56 for (i
= 1; i
< 11; i
+= 4) {
57 MoveToEx (hdc
, pt
.x
- i
, pt
.y
, NULL
);
58 LineTo (hdc
, pt
.x
, pt
.y
- i
);
60 MoveToEx (hdc
, pt
.x
- i
-1, pt
.y
, NULL
);
61 LineTo (hdc
, pt
.x
, pt
.y
- i
-1);
64 SelectObject (hdc
, GetSysColorPen (COLOR_3DHIGHLIGHT
));
65 for (i
= 3; i
< 13; i
+= 4) {
66 MoveToEx (hdc
, pt
.x
- i
, pt
.y
, NULL
);
67 LineTo (hdc
, pt
.x
, pt
.y
- i
);
70 SelectObject (hdc
, hOldPen
);
75 STATUSBAR_DrawPart (HDC hdc
, STATUSWINDOWPART
*part
)
78 UINT border
= BDR_SUNKENOUTER
;
80 if (part
->style
& SBT_POPOUT
)
81 border
= BDR_RAISEDOUTER
;
82 else if (part
->style
& SBT_NOBORDERS
)
85 DrawEdge(hdc
, &r
, border
, BF_RECT
|BF_ADJUST
);
89 INT cy
= r
.bottom
- r
.top
;
92 DrawIconEx (hdc
, r
.left
, r
.top
, part
->hIcon
, cy
, cy
, 0, 0, DI_NORMAL
);
98 int oldbkmode
= SetBkMode(hdc
, TRANSPARENT
);
99 LPWSTR p
= (LPWSTR
)part
->text
;
100 UINT align
= DT_LEFT
;
111 DrawTextW (hdc
, p
, lstrlenW (p
), &r
, align
|DT_VCENTER
|DT_SINGLELINE
);
112 if (oldbkmode
!= TRANSPARENT
)
113 SetBkMode(hdc
, oldbkmode
);
119 STATUSBAR_RefreshPart (HWND hwnd
, STATUSWINDOWPART
*part
, HDC hdc
)
121 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
125 if (!IsWindowVisible (hwnd
))
128 if (self
->clrBk
!= CLR_DEFAULT
)
129 hbrBk
= CreateSolidBrush (self
->clrBk
);
131 hbrBk
= GetSysColorBrush (COLOR_3DFACE
);
132 FillRect(hdc
, &part
->bound
, hbrBk
);
134 hOldFont
= SelectObject (hdc
, self
->hFont
? self
->hFont
: self
->hDefaultFont
);
136 if (part
->style
& SBT_OWNERDRAW
) {
139 dis
.CtlID
= GetWindowLongA (hwnd
, GWL_ID
);
143 dis
.rcItem
= part
->bound
;
144 dis
.itemData
= (INT
)part
->text
;
145 SendMessageA (GetParent (hwnd
), WM_DRAWITEM
,
146 (WPARAM
)dis
.CtlID
, (LPARAM
)&dis
);
149 STATUSBAR_DrawPart (hdc
, part
);
151 SelectObject (hdc
, hOldFont
);
153 if (self
->clrBk
!= CLR_DEFAULT
)
154 DeleteObject (hbrBk
);
156 if (GetWindowLongA (hwnd
, GWL_STYLE
) & SBARS_SIZEGRIP
) {
159 GetClientRect (hwnd
, &rect
);
160 STATUSBAR_DrawSizeGrip (hdc
, &rect
);
166 STATUSBAR_Refresh (HWND hwnd
, HDC hdc
)
168 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
174 if (!IsWindowVisible(hwnd
))
177 GetClientRect (hwnd
, &rect
);
179 if (infoPtr
->clrBk
!= CLR_DEFAULT
)
180 hbrBk
= CreateSolidBrush (infoPtr
->clrBk
);
182 hbrBk
= GetSysColorBrush (COLOR_3DFACE
);
183 FillRect(hdc
, &rect
, hbrBk
);
185 hOldFont
= SelectObject (hdc
, infoPtr
->hFont
? infoPtr
->hFont
: infoPtr
->hDefaultFont
);
187 if (infoPtr
->simple
) {
188 STATUSBAR_DrawPart (hdc
, &infoPtr
->part0
);
191 for (i
= 0; i
< infoPtr
->numParts
; i
++) {
192 if (infoPtr
->parts
[i
].style
& SBT_OWNERDRAW
) {
195 dis
.CtlID
= GetWindowLongA (hwnd
, GWL_ID
);
199 dis
.rcItem
= infoPtr
->parts
[i
].bound
;
200 dis
.itemData
= (INT
)infoPtr
->parts
[i
].text
;
201 SendMessageA (GetParent (hwnd
), WM_DRAWITEM
,
202 (WPARAM
)dis
.CtlID
, (LPARAM
)&dis
);
205 STATUSBAR_DrawPart (hdc
, &infoPtr
->parts
[i
]);
209 SelectObject (hdc
, hOldFont
);
211 if (infoPtr
->clrBk
!= CLR_DEFAULT
)
212 DeleteObject (hbrBk
);
214 if (GetWindowLongA(hwnd
, GWL_STYLE
) & SBARS_SIZEGRIP
)
215 STATUSBAR_DrawSizeGrip (hdc
, &rect
);
222 STATUSBAR_SetPartBounds (HWND hwnd
)
224 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
225 STATUSWINDOWPART
*part
;
229 /* get our window size */
230 GetClientRect (hwnd
, &rect
);
232 rect
.top
+= VERT_BORDER
;
234 /* set bounds for simple rectangle */
235 self
->part0
.bound
= rect
;
237 /* set bounds for non-simple rectangles */
238 for (i
= 0; i
< self
->numParts
; i
++) {
239 part
= &self
->parts
[i
];
240 r
= &self
->parts
[i
].bound
;
242 r
->bottom
= rect
.bottom
;
246 r
->left
= self
->parts
[i
-1].bound
.right
+ HORZ_GAP
;
248 r
->right
= rect
.right
;
252 if (self
->hwndToolTip
) {
255 ti
.cbSize
= sizeof(TTTOOLINFOA
);
259 SendMessageA (self
->hwndToolTip
, TTM_NEWTOOLRECTA
,
267 STATUSBAR_RelayEvent (HWND hwndTip
, HWND hwndMsg
, UINT uMsg
,
268 WPARAM wParam
, LPARAM lParam
)
276 msg
.time
= GetMessageTime ();
277 msg
.pt
.x
= LOWORD(GetMessagePos ());
278 msg
.pt
.y
= HIWORD(GetMessagePos ());
280 SendMessageA (hwndTip
, TTM_RELAYEVENT
, 0, (LPARAM
)&msg
);
284 inline static LRESULT
285 STATUSBAR_GetBorders (LPARAM lParam
)
287 LPINT out
= (LPINT
) lParam
;
289 out
[0] = HORZ_BORDER
; /* horizontal border width */
290 out
[1] = VERT_BORDER
; /* vertical border width */
291 out
[2] = HORZ_GAP
; /* width of border between rectangles */
298 STATUSBAR_GetIcon (HWND hwnd
, WPARAM wParam
)
300 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
303 nPart
= (INT
)wParam
& 0x00ff;
304 if ((nPart
< -1) || (nPart
>= self
->numParts
))
308 return (self
->part0
.hIcon
);
310 return (self
->parts
[nPart
].hIcon
);
315 STATUSBAR_GetParts (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
317 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
322 num_parts
= (INT
) wParam
;
323 parts
= (LPINT
) lParam
;
325 return (infoPtr
->numParts
);
326 for (i
= 0; i
< num_parts
; i
++) {
327 parts
[i
] = infoPtr
->parts
[i
].x
;
330 return (infoPtr
->numParts
);
335 STATUSBAR_GetRect (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
337 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
341 part_num
= ((INT
) wParam
) & 0x00ff;
342 rect
= (LPRECT
) lParam
;
344 *rect
= infoPtr
->part0
.bound
;
346 *rect
= infoPtr
->parts
[part_num
].bound
;
352 STATUSBAR_GetTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
354 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
355 STATUSWINDOWPART
*part
;
359 nPart
= ((INT
) wParam
) & 0x00ff;
363 part
= &self
->parts
[nPart
];
365 if (part
->style
& SBT_OWNERDRAW
)
366 result
= (LRESULT
)part
->text
;
368 result
= part
->text
? lstrlenW (part
->text
) : 0;
369 result
|= (part
->style
<< 16);
370 if (lParam
&& LOWORD(result
))
371 lstrcpyWtoA ((LPSTR
)lParam
, part
->text
);
378 STATUSBAR_GetTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
380 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
381 STATUSWINDOWPART
*part
;
385 nPart
= ((INT
)wParam
) & 0x00ff;
387 part
= &infoPtr
->part0
;
389 part
= &infoPtr
->parts
[nPart
];
391 if (part
->style
& SBT_OWNERDRAW
)
392 result
= (LRESULT
)part
->text
;
394 result
= part
->text
? lstrlenW (part
->text
) : 0;
395 result
|= (part
->style
<< 16);
397 lstrcpyW ((LPWSTR
)lParam
, part
->text
);
404 STATUSBAR_GetTextLength (HWND hwnd
, WPARAM wParam
)
406 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
407 STATUSWINDOWPART
*part
;
411 part_num
= ((INT
) wParam
) & 0x00ff;
414 part
= &infoPtr
->part0
;
416 part
= &infoPtr
->parts
[part_num
];
419 result
= lstrlenW(part
->text
);
423 result
|= (part
->style
<< 16);
429 STATUSBAR_GetTipTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
431 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
433 if (infoPtr
->hwndToolTip
) {
435 ti
.cbSize
= sizeof(TTTOOLINFOA
);
437 ti
.uId
= LOWORD(wParam
);
438 SendMessageA (infoPtr
->hwndToolTip
, TTM_GETTEXTA
, 0, (LPARAM
)&ti
);
441 lstrcpynA ((LPSTR
)lParam
, ti
.lpszText
, HIWORD(wParam
));
449 STATUSBAR_GetTipTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
451 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
453 if (infoPtr
->hwndToolTip
) {
455 ti
.cbSize
= sizeof(TTTOOLINFOW
);
457 ti
.uId
= LOWORD(wParam
);
458 SendMessageW (infoPtr
->hwndToolTip
, TTM_GETTEXTW
, 0, (LPARAM
)&ti
);
461 lstrcpynW ((LPWSTR
)lParam
, ti
.lpszText
, HIWORD(wParam
));
468 inline static LRESULT
469 STATUSBAR_GetUnicodeFormat (HWND hwnd
)
471 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
472 return infoPtr
->bUnicode
;
476 inline static LRESULT
477 STATUSBAR_IsSimple (HWND hwnd
)
479 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
480 return infoPtr
->simple
;
485 STATUSBAR_SetBkColor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
487 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
491 oldBkColor
= self
->clrBk
;
492 self
->clrBk
= (COLORREF
)lParam
;
494 STATUSBAR_Refresh (hwnd
, hdc
);
495 ReleaseDC (hwnd
, hdc
);
502 STATUSBAR_SetIcon (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
504 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
505 INT nPart
= (INT
)wParam
& 0x00ff;
508 if ((nPart
< -1) || (nPart
>= self
->numParts
))
513 self
->part0
.hIcon
= (HICON
)lParam
;
515 STATUSBAR_RefreshPart (hwnd
, &self
->part0
, hdc
);
518 self
->parts
[nPart
].hIcon
= (HICON
)lParam
;
520 STATUSBAR_RefreshPart (hwnd
, &self
->parts
[nPart
], hdc
);
522 ReleaseDC (hwnd
, hdc
);
529 STATUSBAR_SetMinHeight (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
531 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
533 if (IsWindowVisible (hwnd
)) {
534 HWND parent
= GetParent (hwnd
);
538 GetClientRect (parent
, &parent_rect
);
539 self
->height
= (INT
)wParam
+ VERT_BORDER
;
540 width
= parent_rect
.right
- parent_rect
.left
;
541 x
= parent_rect
.left
;
542 y
= parent_rect
.bottom
- self
->height
;
543 MoveWindow (hwnd
, parent_rect
.left
,
544 parent_rect
.bottom
- self
->height
,
545 width
, self
->height
, TRUE
);
546 STATUSBAR_SetPartBounds (hwnd
);
554 STATUSBAR_SetParts (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
556 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
557 STATUSWINDOWPART
*tmp
;
564 self
->simple
= FALSE
;
566 oldNumParts
= self
->numParts
;
567 self
->numParts
= (INT
) wParam
;
568 parts
= (LPINT
) lParam
;
569 if (oldNumParts
> self
->numParts
) {
570 for (i
= self
->numParts
; i
< oldNumParts
; i
++) {
571 if (self
->parts
[i
].text
&& !(self
->parts
[i
].style
& SBT_OWNERDRAW
))
572 COMCTL32_Free (self
->parts
[i
].text
);
575 else if (oldNumParts
< self
->numParts
) {
576 tmp
= COMCTL32_Alloc (sizeof(STATUSWINDOWPART
) * self
->numParts
);
577 for (i
= 0; i
< oldNumParts
; i
++) {
578 tmp
[i
] = self
->parts
[i
];
581 COMCTL32_Free (self
->parts
);
585 for (i
= 0; i
< self
->numParts
; i
++) {
586 self
->parts
[i
].x
= parts
[i
];
589 if (self
->hwndToolTip
) {
591 SendMessageA (self
->hwndToolTip
, TTM_GETTOOLCOUNT
, 0, 0);
593 if (nTipCount
< self
->numParts
) {
598 ZeroMemory (&ti
, sizeof(TTTOOLINFOA
));
599 ti
.cbSize
= sizeof(TTTOOLINFOA
);
601 for (i
= nTipCount
; i
< self
->numParts
; i
++) {
602 TRACE("add tool %d\n", i
);
604 SendMessageA (self
->hwndToolTip
, TTM_ADDTOOLA
,
608 else if (nTipCount
> self
->numParts
) {
612 for (i
= nTipCount
- 1; i
>= self
->numParts
; i
--) {
614 FIXME("delete tool %d\n", i
);
620 STATUSBAR_SetPartBounds (hwnd
);
623 STATUSBAR_Refresh (hwnd
, hdc
);
624 ReleaseDC (hwnd
, hdc
);
631 STATUSBAR_SetTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
633 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
634 STATUSWINDOWPART
*part
;
641 text
= (LPSTR
) lParam
;
642 part_num
= ((INT
) wParam
) & 0x00ff;
643 style
= ((INT
) wParam
) & 0xff00;
645 if ((self
->simple
) || (self
->parts
==NULL
) || (part_num
==255))
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
);
668 STATUSBAR_RefreshPart (hwnd
, part
, hdc
);
669 ReleaseDC (hwnd
, hdc
);
676 STATUSBAR_SetTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
678 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
679 STATUSWINDOWPART
*part
;
680 INT part_num
, style
, len
;
684 text
= (LPWSTR
) lParam
;
685 part_num
= ((INT
) wParam
) & 0x00ff;
686 style
= ((INT
) wParam
) & 0xff00;
688 if ((self
->simple
) || (self
->parts
==NULL
) || (part_num
==255))
691 part
= &self
->parts
[part_num
];
692 if (!part
) return FALSE
;
694 if (!(part
->style
& SBT_OWNERDRAW
) && part
->text
)
695 COMCTL32_Free (part
->text
);
698 if (style
& SBT_OWNERDRAW
) {
702 /* duplicate string */
703 if (text
&& (len
= lstrlenW(text
))) {
704 part
->text
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
705 lstrcpyW(part
->text
, text
);
711 STATUSBAR_RefreshPart (hwnd
, part
, hdc
);
712 ReleaseDC (hwnd
, hdc
);
719 STATUSBAR_SetTipTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
721 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
723 TRACE("part %d: \"%s\"\n", (INT
)wParam
, (LPSTR
)lParam
);
724 if (infoPtr
->hwndToolTip
) {
726 ti
.cbSize
= sizeof(TTTOOLINFOA
);
728 ti
.uId
= (INT
)wParam
;
730 ti
.lpszText
= (LPSTR
)lParam
;
731 SendMessageA (infoPtr
->hwndToolTip
, TTM_UPDATETIPTEXTA
,
740 STATUSBAR_SetTipTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
742 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
744 TRACE("part %d: \"%s\"\n", (INT
)wParam
, (LPSTR
)lParam
);
745 if (infoPtr
->hwndToolTip
) {
747 ti
.cbSize
= sizeof(TTTOOLINFOW
);
749 ti
.uId
= (INT
)wParam
;
751 ti
.lpszText
= (LPWSTR
)lParam
;
752 SendMessageW (infoPtr
->hwndToolTip
, TTM_UPDATETIPTEXTW
,
760 inline static LRESULT
761 STATUSBAR_SetUnicodeFormat (HWND hwnd
, WPARAM wParam
)
763 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
764 BOOL bTemp
= infoPtr
->bUnicode
;
766 TRACE("(0x%x)\n", (BOOL
)wParam
);
767 infoPtr
->bUnicode
= (BOOL
)wParam
;
774 STATUSBAR_Simple (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
776 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
780 infoPtr
->simple
= (BOOL
)wParam
;
782 /* send notification */
783 nmhdr
.hwndFrom
= hwnd
;
784 nmhdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
785 nmhdr
.code
= SBN_SIMPLEMODECHANGE
;
786 SendMessageA (GetParent (hwnd
), WM_NOTIFY
, 0, (LPARAM
)&nmhdr
);
789 STATUSBAR_Refresh (hwnd
, hdc
);
790 ReleaseDC (hwnd
, hdc
);
797 STATUSBAR_WMCreate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
799 LPCREATESTRUCTA lpCreate
= (LPCREATESTRUCTA
)lParam
;
800 NONCLIENTMETRICSA nclm
;
804 STATUSWINDOWINFO
*self
;
806 self
= (STATUSWINDOWINFO
*)COMCTL32_Alloc (sizeof(STATUSWINDOWINFO
));
807 SetWindowLongA (hwnd
, 0, (DWORD
)self
);
811 self
->simple
= FALSE
;
812 self
->clrBk
= CLR_DEFAULT
;
814 GetClientRect (hwnd
, &rect
);
816 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
817 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
818 self
->hDefaultFont
= CreateFontIndirectA (&nclm
.lfStatusFont
);
820 /* initialize simple case */
821 self
->part0
.bound
= rect
;
822 self
->part0
.text
= 0;
824 self
->part0
.style
= 0;
825 self
->part0
.hIcon
= 0;
827 /* initialize first part */
828 self
->parts
= COMCTL32_Alloc (sizeof(STATUSWINDOWPART
));
829 self
->parts
[0].bound
= rect
;
830 self
->parts
[0].text
= 0;
831 self
->parts
[0].x
= -1;
832 self
->parts
[0].style
= 0;
833 self
->parts
[0].hIcon
= 0;
835 if (IsWindowUnicode (hwnd
)) {
836 self
->bUnicode
= TRUE
;
837 if (lpCreate
->lpszName
&&
838 (len
= lstrlenW ((LPCWSTR
)lpCreate
->lpszName
))) {
839 self
->parts
[0].text
= COMCTL32_Alloc ((len
+ 1)*sizeof(WCHAR
));
840 lstrcpyW (self
->parts
[0].text
, (LPCWSTR
)lpCreate
->lpszName
);
844 if (lpCreate
->lpszName
&&
845 (len
= lstrlenA ((LPCSTR
)lpCreate
->lpszName
))) {
846 self
->parts
[0].text
= COMCTL32_Alloc ((len
+ 1)*sizeof(WCHAR
));
847 lstrcpyAtoW (self
->parts
[0].text
, (LPCSTR
)lpCreate
->lpszName
);
851 if ((hdc
= GetDC (0))) {
855 hOldFont
= SelectObject (hdc
,self
->hDefaultFont
);
856 GetTextMetricsA(hdc
, &tm
);
857 self
->textHeight
= tm
.tmHeight
;
858 SelectObject (hdc
, hOldFont
);
862 if (GetWindowLongA (hwnd
, GWL_STYLE
) & SBT_TOOLTIPS
) {
864 CreateWindowExA (0, TOOLTIPS_CLASSA
, NULL
, 0,
865 CW_USEDEFAULT
, CW_USEDEFAULT
,
866 CW_USEDEFAULT
, CW_USEDEFAULT
,
868 GetWindowLongA (hwnd
, GWL_HINSTANCE
), NULL
);
870 if (self
->hwndToolTip
) {
871 NMTOOLTIPSCREATED nmttc
;
873 nmttc
.hdr
.hwndFrom
= hwnd
;
874 nmttc
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
875 nmttc
.hdr
.code
= NM_TOOLTIPSCREATED
;
876 nmttc
.hwndToolTips
= self
->hwndToolTip
;
878 SendMessageA (GetParent (hwnd
), WM_NOTIFY
,
879 (WPARAM
)nmttc
.hdr
.idFrom
, (LPARAM
)&nmttc
);
883 GetClientRect (GetParent (hwnd
), &rect
);
884 width
= rect
.right
- rect
.left
;
885 self
->height
= self
->textHeight
+ 4 + VERT_BORDER
;
886 MoveWindow (hwnd
, lpCreate
->x
, lpCreate
->y
-1,
887 width
, self
->height
, FALSE
);
888 STATUSBAR_SetPartBounds (hwnd
);
895 STATUSBAR_WMDestroy (HWND hwnd
)
897 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
900 for (i
= 0; i
< self
->numParts
; i
++) {
901 if (self
->parts
[i
].text
&& !(self
->parts
[i
].style
& SBT_OWNERDRAW
))
902 COMCTL32_Free (self
->parts
[i
].text
);
904 if (self
->part0
.text
&& !(self
->part0
.style
& SBT_OWNERDRAW
))
905 COMCTL32_Free (self
->part0
.text
);
906 COMCTL32_Free (self
->parts
);
908 /* delete default font */
909 if (self
->hDefaultFont
)
910 DeleteObject (self
->hDefaultFont
);
912 /* delete tool tip control */
913 if (self
->hwndToolTip
)
914 DestroyWindow (self
->hwndToolTip
);
916 COMCTL32_Free (self
);
922 static inline LRESULT
923 STATUSBAR_WMGetFont (HWND hwnd
)
925 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
926 return infoPtr
->hFont
;
931 STATUSBAR_WMGetText (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
933 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
936 if (!(infoPtr
->parts
[0].text
))
938 len
= lstrlenW (infoPtr
->parts
[0].text
);
940 if (infoPtr
->bUnicode
)
941 lstrcpyW ((LPWSTR
)lParam
, infoPtr
->parts
[0].text
);
943 lstrcpyWtoA ((LPSTR
)lParam
, infoPtr
->parts
[0].text
);
951 inline static LRESULT
952 STATUSBAR_WMMouseMove (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
954 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
956 if (infoPtr
->hwndToolTip
)
957 STATUSBAR_RelayEvent (infoPtr
->hwndToolTip
, hwnd
,
958 WM_MOUSEMOVE
, wParam
, lParam
);
964 STATUSBAR_WMNCHitTest (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
966 if (GetWindowLongA (hwnd
, GWL_STYLE
) & SBARS_SIZEGRIP
) {
970 GetClientRect (hwnd
, &rect
);
972 pt
.x
= (INT
)LOWORD(lParam
);
973 pt
.y
= (INT
)HIWORD(lParam
);
974 ScreenToClient (hwnd
, &pt
);
976 rect
.left
= rect
.right
- 13;
979 if (PtInRect (&rect
, pt
))
980 return HTBOTTOMRIGHT
;
983 return DefWindowProcA (hwnd
, WM_NCHITTEST
, wParam
, lParam
);
987 static inline LRESULT
988 STATUSBAR_WMNCLButtonDown (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
990 PostMessageA (GetParent (hwnd
), WM_NCLBUTTONDOWN
, wParam
, lParam
);
995 static inline LRESULT
996 STATUSBAR_WMNCLButtonUp (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
998 PostMessageA (GetParent (hwnd
), WM_NCLBUTTONUP
, wParam
, lParam
);
1004 STATUSBAR_WMPaint (HWND hwnd
, WPARAM wParam
)
1009 hdc
= wParam
==0 ? BeginPaint (hwnd
, &ps
) : (HDC
)wParam
;
1010 STATUSBAR_Refresh (hwnd
, hdc
);
1012 EndPaint (hwnd
, &ps
);
1019 STATUSBAR_WMSetFont (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1021 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
1023 infoPtr
->hFont
= (HFONT
)wParam
;
1024 if (LOWORD(lParam
) == TRUE
) {
1025 HDC hdc
= GetDC (hwnd
);
1026 STATUSBAR_Refresh (hwnd
, hdc
);
1027 ReleaseDC (hwnd
, hdc
);
1035 STATUSBAR_WMSetText (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1037 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
1038 STATUSWINDOWPART
*part
;
1042 if (infoPtr
->numParts
== 0)
1045 part
= &infoPtr
->parts
[0];
1046 /* duplicate string */
1048 COMCTL32_Free (part
->text
);
1050 if (infoPtr
->bUnicode
) {
1051 if (lParam
&& (len
= lstrlenW((LPCWSTR
)lParam
))) {
1052 part
->text
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1053 lstrcpyW (part
->text
, (LPCWSTR
)lParam
);
1057 if (lParam
&& (len
= lstrlenA((LPCSTR
)lParam
))) {
1058 part
->text
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1059 lstrcpyAtoW (part
->text
, (LPCSTR
)lParam
);
1064 STATUSBAR_RefreshPart (hwnd
, part
, hdc
);
1065 ReleaseDC (hwnd
, hdc
);
1072 STATUSBAR_WMSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1074 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
1075 INT width
, x
, y
, flags
;
1079 /* Need to resize width to match parent */
1080 flags
= (INT
) wParam
;
1082 /* FIXME for flags =
1083 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED, SIZE_RESTORED
1086 if (flags
== SIZE_RESTORED
) {
1087 /* width and height don't apply */
1088 parent
= GetParent (hwnd
);
1089 GetClientRect (parent
, &parent_rect
);
1090 width
= parent_rect
.right
- parent_rect
.left
;
1091 x
= parent_rect
.left
;
1092 y
= parent_rect
.bottom
- infoPtr
->height
;
1093 MoveWindow (hwnd
, parent_rect
.left
,
1094 parent_rect
.bottom
- infoPtr
->height
,
1095 width
, infoPtr
->height
, TRUE
);
1096 STATUSBAR_SetPartBounds (hwnd
);
1103 STATUSBAR_SendNotify (HWND hwnd
, UINT code
)
1107 nmhdr
.hwndFrom
= hwnd
;
1108 nmhdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
1110 SendMessageA (GetParent (hwnd
), WM_NOTIFY
, 0, (LPARAM
)&nmhdr
);
1116 static LRESULT WINAPI
1117 StatusWindowProc (HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1121 return STATUSBAR_GetBorders (lParam
);
1124 return STATUSBAR_GetIcon (hwnd
, wParam
);
1127 return STATUSBAR_GetParts (hwnd
, wParam
, lParam
);
1130 return STATUSBAR_GetRect (hwnd
, wParam
, lParam
);
1133 return STATUSBAR_GetTextA (hwnd
, wParam
, lParam
);
1136 return STATUSBAR_GetTextW (hwnd
, wParam
, lParam
);
1138 case SB_GETTEXTLENGTHA
:
1139 case SB_GETTEXTLENGTHW
:
1140 return STATUSBAR_GetTextLength (hwnd
, wParam
);
1142 case SB_GETTIPTEXTA
:
1143 return STATUSBAR_GetTipTextA (hwnd
, wParam
, lParam
);
1145 case SB_GETTIPTEXTW
:
1146 return STATUSBAR_GetTipTextW (hwnd
, wParam
, lParam
);
1148 case SB_GETUNICODEFORMAT
:
1149 return STATUSBAR_GetUnicodeFormat (hwnd
);
1152 return STATUSBAR_IsSimple (hwnd
);
1155 return STATUSBAR_SetBkColor (hwnd
, wParam
, lParam
);
1158 return STATUSBAR_SetIcon (hwnd
, wParam
, lParam
);
1160 case SB_SETMINHEIGHT
:
1161 return STATUSBAR_SetMinHeight (hwnd
, wParam
, lParam
);
1164 return STATUSBAR_SetParts (hwnd
, wParam
, lParam
);
1167 return STATUSBAR_SetTextA (hwnd
, wParam
, lParam
);
1170 return STATUSBAR_SetTextW (hwnd
, wParam
, lParam
);
1172 case SB_SETTIPTEXTA
:
1173 return STATUSBAR_SetTipTextA (hwnd
, wParam
, lParam
);
1175 case SB_SETTIPTEXTW
:
1176 return STATUSBAR_SetTipTextW (hwnd
, wParam
, lParam
);
1178 case SB_SETUNICODEFORMAT
:
1179 return STATUSBAR_SetUnicodeFormat (hwnd
, wParam
);
1182 return STATUSBAR_Simple (hwnd
, wParam
, lParam
);
1186 return STATUSBAR_WMCreate (hwnd
, wParam
, lParam
);
1189 return STATUSBAR_WMDestroy (hwnd
);
1192 return STATUSBAR_WMGetFont (hwnd
);
1195 return STATUSBAR_WMGetText (hwnd
, wParam
, lParam
);
1197 case WM_GETTEXTLENGTH
:
1198 return STATUSBAR_GetTextLength (hwnd
, 0);
1200 case WM_LBUTTONDBLCLK
:
1201 return STATUSBAR_SendNotify (hwnd
, NM_DBLCLK
);
1204 return STATUSBAR_SendNotify (hwnd
, NM_CLICK
);
1207 return STATUSBAR_WMMouseMove (hwnd
, wParam
, lParam
);
1210 return STATUSBAR_WMNCHitTest (hwnd
, wParam
, lParam
);
1212 case WM_NCLBUTTONDOWN
:
1213 return STATUSBAR_WMNCLButtonDown (hwnd
, wParam
, lParam
);
1215 case WM_NCLBUTTONUP
:
1216 return STATUSBAR_WMNCLButtonUp (hwnd
, wParam
, lParam
);
1219 return STATUSBAR_WMPaint (hwnd
, wParam
);
1221 case WM_RBUTTONDBLCLK
:
1222 return STATUSBAR_SendNotify (hwnd
, NM_RDBLCLK
);
1225 return STATUSBAR_SendNotify (hwnd
, NM_RCLICK
);
1228 return STATUSBAR_WMSetFont (hwnd
, wParam
, lParam
);
1231 return STATUSBAR_WMSetText (hwnd
, wParam
, lParam
);
1234 return STATUSBAR_WMSize (hwnd
, wParam
, lParam
);
1238 ERR("unknown msg %04x wp=%04x lp=%08lx\n",
1239 msg
, wParam
, lParam
);
1240 return DefWindowProcA (hwnd
, msg
, wParam
, lParam
);
1246 /***********************************************************************
1247 * STATUS_Register [Internal]
1249 * Registers the status window class.
1253 STATUS_Register (void)
1257 ZeroMemory (&wndClass
, sizeof(WNDCLASSA
));
1258 wndClass
.style
= CS_GLOBALCLASS
| CS_DBLCLKS
| CS_VREDRAW
;
1259 wndClass
.lpfnWndProc
= (WNDPROC
)StatusWindowProc
;
1260 wndClass
.cbClsExtra
= 0;
1261 wndClass
.cbWndExtra
= sizeof(STATUSWINDOWINFO
*);
1262 wndClass
.hCursor
= LoadCursorA (0, IDC_ARROWA
);
1263 wndClass
.hbrBackground
= (HBRUSH
)(COLOR_3DFACE
+ 1);
1264 wndClass
.lpszClassName
= STATUSCLASSNAMEA
;
1266 RegisterClassA (&wndClass
);
1270 /***********************************************************************
1271 * STATUS_Unregister [Internal]
1273 * Unregisters the status window class.
1277 STATUS_Unregister (void)
1279 UnregisterClassA (STATUSCLASSNAMEA
, (HINSTANCE
)NULL
);