2 * Interface code to StatusWindow widget/control
4 * Copyright 1996 Bruce Milner
5 * Copyright 1998 Eric Kohl
15 * Run tests using Waite Group Windows95 API Bible Vol. 1&2
16 * The second cdrom contains executables drawstat.exe,gettext.exe,
17 * simple.exe, getparts.exe, setparts.exe, statwnd.exe
22 * 1) Don't hard code bar to bottom of window, allow CCS_TOP also.
23 * 2) Tooltip support (almost done).
26 #define _MAX(a,b) (((a)>(b))?(a):(b))
27 #define _MIN(a,b) (((a)>(b))?(b):(a))
33 #define STATUSBAR_GetInfoPtr(wndPtr) ((STATUSWINDOWINFO *)wndPtr->wExtra[0])
37 STATUSBAR_DrawSizeGrip (HDC32 hdc
, LPRECT32 lpRect
)
43 pt
.x
= lpRect
->right
- 1;
44 pt
.y
= lpRect
->bottom
- 1;
46 hOldPen
= SelectObject32 (hdc
, GetSysColorPen32 (COLOR_3DFACE
));
47 MoveToEx32 (hdc
, pt
.x
- 12, pt
.y
, NULL
);
48 LineTo32 (hdc
, pt
.x
, pt
.y
);
49 LineTo32 (hdc
, pt
.x
, pt
.y
- 12);
54 SelectObject32 (hdc
, GetSysColorPen32 (COLOR_3DSHADOW
));
55 for (i
= 1; i
< 11; i
+= 4) {
56 MoveToEx32 (hdc
, pt
.x
- i
, pt
.y
, NULL
);
57 LineTo32 (hdc
, pt
.x
, pt
.y
- i
);
59 MoveToEx32 (hdc
, pt
.x
- i
-1, pt
.y
, NULL
);
60 LineTo32 (hdc
, pt
.x
, pt
.y
- i
-1);
63 SelectObject32 (hdc
, GetSysColorPen32 (COLOR_3DHIGHLIGHT
));
64 for (i
= 3; i
< 13; i
+= 4) {
65 MoveToEx32 (hdc
, pt
.x
- i
, pt
.y
, NULL
);
66 LineTo32 (hdc
, pt
.x
, pt
.y
- i
);
69 SelectObject32 (hdc
, hOldPen
);
74 STATUSBAR_DrawPart (HDC32 hdc
, STATUSWINDOWPART
*part
)
76 RECT32 r
= part
->bound
;
77 UINT32 border
= BDR_SUNKENOUTER
;
79 if (part
->style
==SBT_POPOUT
)
80 border
= BDR_RAISEDOUTER
;
81 else if (part
->style
==SBT_NOBORDERS
)
84 DrawEdge32(hdc
, &r
, border
, BF_RECT
|BF_ADJUST
);
88 INT32 cy
= r
.bottom
- r
.top
;
91 DrawIconEx32 (hdc
, r
.left
, r
.top
, part
->hIcon
, cy
, cy
, 0, 0, DI_NORMAL
);
97 int oldbkmode
= SetBkMode32(hdc
, TRANSPARENT
);
98 LPWSTR p
= (LPWSTR
)part
->text
;
99 UINT32 align
= DT_LEFT
;
110 DrawText32W (hdc
, p
, lstrlen32W (p
), &r
, align
|DT_VCENTER
|DT_SINGLELINE
);
111 if (oldbkmode
!= TRANSPARENT
)
112 SetBkMode32(hdc
, oldbkmode
);
118 STATUSBAR_RefreshPart (WND
*wndPtr
, STATUSWINDOWPART
*part
, HDC32 hdc
)
120 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (wndPtr
);
124 if (!IsWindowVisible32(wndPtr
->hwndSelf
))
127 if (self
->clrBk
!= CLR_DEFAULT
)
128 hbrBk
= CreateSolidBrush32 (self
->clrBk
);
130 hbrBk
= GetSysColorBrush32 (COLOR_3DFACE
);
131 FillRect32(hdc
, &part
->bound
, hbrBk
);
133 hOldFont
= SelectObject32 (hdc
, self
->hFont
? self
->hFont
: self
->hDefaultFont
);
135 if (part
->style
== SBT_OWNERDRAW
) {
136 DRAWITEMSTRUCT32 dis
;
138 dis
.CtlID
= wndPtr
->wIDmenu
;
140 dis
.hwndItem
= wndPtr
->hwndSelf
;
142 dis
.rcItem
= part
->bound
;
143 dis
.itemData
= (INT32
)part
->text
;
144 SendMessage32A (GetParent32 (wndPtr
->hwndSelf
), WM_DRAWITEM
,
145 (WPARAM32
)wndPtr
->wIDmenu
, (LPARAM
)&dis
);
148 STATUSBAR_DrawPart (hdc
, part
);
150 SelectObject32 (hdc
, hOldFont
);
152 if (self
->clrBk
!= CLR_DEFAULT
)
153 DeleteObject32 (hbrBk
);
155 if (wndPtr
->dwStyle
& SBARS_SIZEGRIP
) {
158 GetClientRect32 (wndPtr
->hwndSelf
, &rect
);
159 STATUSBAR_DrawSizeGrip (hdc
, &rect
);
165 STATUSBAR_Refresh (WND
*wndPtr
, HDC32 hdc
)
167 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (wndPtr
);
173 if (!IsWindowVisible32(wndPtr
->hwndSelf
))
176 GetClientRect32 (wndPtr
->hwndSelf
, &rect
);
178 if (self
->clrBk
!= CLR_DEFAULT
)
179 hbrBk
= CreateSolidBrush32 (self
->clrBk
);
181 hbrBk
= GetSysColorBrush32 (COLOR_3DFACE
);
182 FillRect32(hdc
, &rect
, hbrBk
);
184 hOldFont
= SelectObject32 (hdc
, self
->hFont
? self
->hFont
: self
->hDefaultFont
);
187 STATUSBAR_DrawPart (hdc
, &self
->part0
);
190 for (i
= 0; i
< self
->numParts
; i
++) {
191 if (self
->parts
[i
].style
== SBT_OWNERDRAW
) {
192 DRAWITEMSTRUCT32 dis
;
194 dis
.CtlID
= wndPtr
->wIDmenu
;
196 dis
.hwndItem
= wndPtr
->hwndSelf
;
198 dis
.rcItem
= self
->parts
[i
].bound
;
199 dis
.itemData
= (INT32
)self
->parts
[i
].text
;
200 SendMessage32A (GetParent32 (wndPtr
->hwndSelf
), WM_DRAWITEM
,
201 (WPARAM32
)wndPtr
->wIDmenu
, (LPARAM
)&dis
);
204 STATUSBAR_DrawPart (hdc
, &self
->parts
[i
]);
208 SelectObject32 (hdc
, hOldFont
);
210 if (self
->clrBk
!= CLR_DEFAULT
)
211 DeleteObject32 (hbrBk
);
213 if (wndPtr
->dwStyle
& SBARS_SIZEGRIP
)
214 STATUSBAR_DrawSizeGrip (hdc
, &rect
);
221 STATUSBAR_SetPartBounds (WND
*wndPtr
)
223 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (wndPtr
);
224 STATUSWINDOWPART
*part
;
228 /* get our window size */
229 GetClientRect32 (wndPtr
->hwndSelf
, &rect
);
231 rect
.top
+= VERT_BORDER
;
233 /* set bounds for simple rectangle */
234 self
->part0
.bound
= rect
;
236 /* set bounds for non-simple rectangles */
237 for (i
= 0; i
< self
->numParts
; i
++) {
238 part
= &self
->parts
[i
];
239 r
= &self
->parts
[i
].bound
;
241 r
->bottom
= rect
.bottom
;
245 r
->left
= self
->parts
[i
-1].bound
.right
+ HORZ_GAP
;
247 r
->right
= rect
.right
;
251 if (self
->hwndToolTip
) {
254 ti
.cbSize
= sizeof(TTTOOLINFO32A
);
255 ti
.hwnd
= wndPtr
->hwndSelf
;
258 SendMessage32A (self
->hwndToolTip
, TTM_NEWTOOLRECT32A
,
266 STATUSBAR_RelayEvent (HWND32 hwndTip
, HWND32 hwndMsg
, UINT32 uMsg
,
267 WPARAM32 wParam
, LPARAM lParam
)
275 msg
.time
= GetMessageTime ();
276 msg
.pt
.x
= LOWORD(GetMessagePos ());
277 msg
.pt
.y
= HIWORD(GetMessagePos ());
279 SendMessage32A (hwndTip
, TTM_RELAYEVENT
, 0, (LPARAM
)&msg
);
283 __inline__
static LRESULT
284 STATUSBAR_GetBorders (LPARAM lParam
)
286 LPINT32 out
= (LPINT32
) lParam
;
288 out
[0] = HORZ_BORDER
; /* horizontal border width */
289 out
[1] = VERT_BORDER
; /* vertical border width */
290 out
[2] = HORZ_GAP
; /* width of border between rectangles */
297 STATUSBAR_GetIcon (WND
*wndPtr
, WPARAM32 wParam
)
299 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (wndPtr
);
302 nPart
= (INT32
)wParam
& 0x00ff;
303 if ((nPart
< -1) || (nPart
>= self
->numParts
)) return 0;
306 return (self
->part0
.hIcon
);
308 return (self
->parts
[nPart
].hIcon
);
313 STATUSBAR_GetParts (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
315 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (wndPtr
);
320 num_parts
= (INT32
) wParam
;
321 parts
= (LPINT32
) lParam
;
323 return (self
->numParts
);
324 for (i
= 0; i
< num_parts
; i
++) {
325 parts
[i
] = self
->parts
[i
].x
;
328 return (self
->numParts
);
333 STATUSBAR_GetRect (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
335 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (wndPtr
);
339 part_num
= ((INT32
) wParam
) & 0x00ff;
340 rect
= (LPRECT32
) lParam
;
342 *rect
= infoPtr
->part0
.bound
;
344 *rect
= infoPtr
->parts
[part_num
].bound
;
350 STATUSBAR_GetText32A (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
352 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (wndPtr
);
353 STATUSWINDOWPART
*part
;
357 nPart
= ((INT32
) wParam
) & 0x00ff;
361 part
= &self
->parts
[nPart
];
363 if (part
->style
== SBT_OWNERDRAW
)
364 result
= (LRESULT
)part
->text
;
366 result
= part
->text
? lstrlen32W (part
->text
) : 0;
367 result
|= (part
->style
<< 16);
368 if (lParam
&& LOWORD(result
))
369 lstrcpyWtoA ((LPSTR
)lParam
, part
->text
);
376 STATUSBAR_GetText32W (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
378 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (wndPtr
);
379 STATUSWINDOWPART
*part
;
383 nPart
= ((INT32
)wParam
) & 0x00ff;
387 part
= &self
->parts
[nPart
];
389 if (part
->style
== SBT_OWNERDRAW
)
390 result
= (LRESULT
)part
->text
;
392 result
= part
->text
? lstrlen32W (part
->text
) : 0;
393 result
|= (part
->style
<< 16);
395 lstrcpy32W ((LPWSTR
)lParam
, part
->text
);
402 STATUSBAR_GetTextLength (WND
*wndPtr
, WPARAM32 wParam
)
404 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (wndPtr
);
405 STATUSWINDOWPART
*part
;
409 part_num
= ((INT32
) wParam
) & 0x00ff;
412 part
= &infoPtr
->part0
;
414 part
= &infoPtr
->parts
[part_num
];
417 result
= lstrlen32W(part
->text
);
421 result
|= (part
->style
<< 16);
427 STATUSBAR_GetTipText32A (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
429 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (wndPtr
);
431 if (infoPtr
->hwndToolTip
) {
433 ti
.cbSize
= sizeof(TTTOOLINFO32A
);
434 ti
.hwnd
= wndPtr
->hwndSelf
;
435 ti
.uId
= LOWORD(wParam
);
436 SendMessage32A (infoPtr
->hwndToolTip
, TTM_GETTEXT32A
, 0, (LPARAM
)&ti
);
439 lstrcpyn32A ((LPSTR
)lParam
, ti
.lpszText
, HIWORD(wParam
));
447 STATUSBAR_GetTipText32W (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
449 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (wndPtr
);
451 if (infoPtr
->hwndToolTip
) {
453 ti
.cbSize
= sizeof(TTTOOLINFO32W
);
454 ti
.hwnd
= wndPtr
->hwndSelf
;
455 ti
.uId
= LOWORD(wParam
);
456 SendMessage32W (infoPtr
->hwndToolTip
, TTM_GETTEXT32W
, 0, (LPARAM
)&ti
);
459 lstrcpyn32W ((LPWSTR
)lParam
, ti
.lpszText
, HIWORD(wParam
));
466 __inline__
static LRESULT
467 STATUSBAR_GetUnicodeFormat (WND
*wndPtr
)
469 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (wndPtr
);
470 return infoPtr
->bUnicode
;
474 __inline__
static LRESULT
475 STATUSBAR_IsSimple (WND
*wndPtr
)
477 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (wndPtr
);
478 return infoPtr
->simple
;
483 STATUSBAR_SetBkColor (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
485 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (wndPtr
);
489 oldBkColor
= self
->clrBk
;
490 self
->clrBk
= (COLORREF
)lParam
;
491 hdc
= GetDC32 (wndPtr
->hwndSelf
);
492 STATUSBAR_Refresh (wndPtr
, hdc
);
493 ReleaseDC32 (wndPtr
->hwndSelf
, hdc
);
500 STATUSBAR_SetIcon (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
502 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (wndPtr
);
503 INT32 nPart
= (INT32
)wParam
& 0x00ff;
506 if ((nPart
< -1) || (nPart
>= self
->numParts
))
509 hdc
= GetDC32 (wndPtr
->hwndSelf
);
511 self
->part0
.hIcon
= (HICON32
)lParam
;
513 STATUSBAR_RefreshPart (wndPtr
, &self
->part0
, hdc
);
516 self
->parts
[nPart
].hIcon
= (HICON32
)lParam
;
518 STATUSBAR_RefreshPart (wndPtr
, &self
->parts
[nPart
], hdc
);
520 ReleaseDC32 (wndPtr
->hwndSelf
, hdc
);
527 STATUSBAR_SetMinHeight (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
529 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (wndPtr
);
531 if (IsWindowVisible32 (wndPtr
->hwndSelf
)) {
532 HWND32 parent
= GetParent32 (wndPtr
->hwndSelf
);
536 GetClientRect32 (parent
, &parent_rect
);
537 self
->height
= (INT32
)wParam
+ VERT_BORDER
;
538 width
= parent_rect
.right
- parent_rect
.left
;
539 x
= parent_rect
.left
;
540 y
= parent_rect
.bottom
- self
->height
;
541 MoveWindow32 (wndPtr
->hwndSelf
, parent_rect
.left
,
542 parent_rect
.bottom
- self
->height
,
543 width
, self
->height
, TRUE
);
544 STATUSBAR_SetPartBounds (wndPtr
);
552 STATUSBAR_SetParts (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
554 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (wndPtr
);
555 STATUSWINDOWPART
*tmp
;
562 self
->simple
= FALSE
;
564 oldNumParts
= self
->numParts
;
565 self
->numParts
= (INT32
) wParam
;
566 parts
= (LPINT32
) 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 SendMessage32A (self
->hwndToolTip
, TTM_GETTOOLCOUNT
, 0, 0);
591 if (nTipCount
< self
->numParts
) {
596 ZeroMemory (&ti
, sizeof(TTTOOLINFO32A
));
597 ti
.cbSize
= sizeof(TTTOOLINFO32A
);
598 ti
.hwnd
= wndPtr
->hwndSelf
;
599 for (i
= nTipCount
; i
< self
->numParts
; i
++) {
600 TRACE (statusbar
, "add tool %d\n", i
);
602 SendMessage32A (self
->hwndToolTip
, TTM_ADDTOOL32A
,
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 (wndPtr
);
620 hdc
= GetDC32 (wndPtr
->hwndSelf
);
621 STATUSBAR_Refresh (wndPtr
, hdc
);
622 ReleaseDC32 (wndPtr
->hwndSelf
, hdc
);
629 STATUSBAR_SetText32A (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
631 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (wndPtr
);
632 STATUSWINDOWPART
*part
;
639 text
= (LPSTR
) lParam
;
640 part_num
= ((INT32
) wParam
) & 0x00ff;
641 style
= ((INT32
) 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
= lstrlen32A(text
))) {
658 part
->text
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
659 lstrcpyAtoW (part
->text
, text
);
663 hdc
= GetDC32 (wndPtr
->hwndSelf
);
664 STATUSBAR_RefreshPart (wndPtr
, part
, hdc
);
665 ReleaseDC32 (wndPtr
->hwndSelf
, hdc
);
672 STATUSBAR_SetText32W (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
674 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (wndPtr
);
675 STATUSWINDOWPART
*part
;
676 INT32 part_num
, style
, len
;
680 text
= (LPWSTR
) lParam
;
681 part_num
= ((INT32
) wParam
) & 0x00ff;
682 style
= ((INT32
) 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
= lstrlen32W(text
))) {
699 part
->text
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
700 lstrcpy32W(part
->text
, text
);
704 hdc
= GetDC32 (wndPtr
->hwndSelf
);
705 STATUSBAR_RefreshPart (wndPtr
, part
, hdc
);
706 ReleaseDC32 (wndPtr
->hwndSelf
, hdc
);
713 STATUSBAR_SetTipText32A (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
715 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (wndPtr
);
717 TRACE (statusbar
, "part %d: \"%s\"\n", (INT32
)wParam
, (LPSTR
)lParam
);
718 if (infoPtr
->hwndToolTip
) {
720 ti
.cbSize
= sizeof(TTTOOLINFO32A
);
721 ti
.hwnd
= wndPtr
->hwndSelf
;
722 ti
.uId
= (INT32
)wParam
;
724 ti
.lpszText
= (LPSTR
)lParam
;
725 SendMessage32A (infoPtr
->hwndToolTip
, TTM_UPDATETIPTEXT32A
,
734 STATUSBAR_SetTipText32W (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
736 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (wndPtr
);
738 TRACE (statusbar
, "part %d: \"%s\"\n", (INT32
)wParam
, (LPSTR
)lParam
);
739 if (infoPtr
->hwndToolTip
) {
741 ti
.cbSize
= sizeof(TTTOOLINFO32W
);
742 ti
.hwnd
= wndPtr
->hwndSelf
;
743 ti
.uId
= (INT32
)wParam
;
745 ti
.lpszText
= (LPWSTR
)lParam
;
746 SendMessage32W (infoPtr
->hwndToolTip
, TTM_UPDATETIPTEXT32W
,
754 __inline__
static LRESULT
755 STATUSBAR_SetUnicodeFormat (WND
*wndPtr
, WPARAM32 wParam
)
757 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (wndPtr
);
758 BOOL32 bTemp
= infoPtr
->bUnicode
;
760 TRACE (statusbar
, "(0x%x)\n", (BOOL32
)wParam
);
761 infoPtr
->bUnicode
= (BOOL32
)wParam
;
768 STATUSBAR_Simple (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
770 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (wndPtr
);
774 infoPtr
->simple
= (BOOL32
)wParam
;
776 /* send notification */
777 nmhdr
.hwndFrom
= wndPtr
->hwndSelf
;
778 nmhdr
.idFrom
= wndPtr
->wIDmenu
;
779 nmhdr
.code
= SBN_SIMPLEMODECHANGE
;
780 SendMessage32A (GetParent32 (wndPtr
->hwndSelf
), WM_NOTIFY
,
783 hdc
= GetDC32 (wndPtr
->hwndSelf
);
784 STATUSBAR_Refresh (wndPtr
, hdc
);
785 ReleaseDC32 (wndPtr
->hwndSelf
, hdc
);
792 STATUSBAR_WMCreate (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
794 LPCREATESTRUCT32A lpCreate
= (LPCREATESTRUCT32A
)lParam
;
795 NONCLIENTMETRICS32A nclm
;
799 STATUSWINDOWINFO
*self
;
801 self
= (STATUSWINDOWINFO
*)COMCTL32_Alloc (sizeof(STATUSWINDOWINFO
));
802 wndPtr
->wExtra
[0] = (DWORD
)self
;
806 self
->simple
= FALSE
;
807 self
->clrBk
= CLR_DEFAULT
;
809 GetClientRect32 (wndPtr
->hwndSelf
, &rect
);
811 nclm
.cbSize
= sizeof(NONCLIENTMETRICS32A
);
812 SystemParametersInfo32A (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
813 self
->hDefaultFont
= CreateFontIndirect32A (&nclm
.lfStatusFont
);
815 /* initialize simple case */
816 self
->part0
.bound
= rect
;
817 self
->part0
.text
= 0;
819 self
->part0
.style
= 0;
820 self
->part0
.hIcon
= 0;
822 /* initialize first part */
823 self
->parts
= COMCTL32_Alloc (sizeof(STATUSWINDOWPART
));
824 self
->parts
[0].bound
= rect
;
825 self
->parts
[0].text
= 0;
826 self
->parts
[0].x
= -1;
827 self
->parts
[0].style
= 0;
828 self
->parts
[0].hIcon
= 0;
830 if (IsWindowUnicode (wndPtr
->hwndSelf
)) {
831 self
->bUnicode
= TRUE
;
832 if ((len
= lstrlen32W ((LPCWSTR
)lpCreate
->lpszName
))) {
833 self
->parts
[0].text
= COMCTL32_Alloc ((len
+ 1)*sizeof(WCHAR
));
834 lstrcpy32W (self
->parts
[0].text
, (LPCWSTR
)lpCreate
->lpszName
);
838 if ((len
= lstrlen32A ((LPCSTR
)lpCreate
->lpszName
))) {
839 self
->parts
[0].text
= COMCTL32_Alloc ((len
+ 1)*sizeof(WCHAR
));
840 lstrcpyAtoW (self
->parts
[0].text
, (LPCSTR
)lpCreate
->lpszName
);
844 if ((hdc
= GetDC32 (0))) {
848 hOldFont
= SelectObject32 (hdc
,self
->hDefaultFont
);
849 GetTextMetrics32A(hdc
, &tm
);
850 self
->textHeight
= tm
.tmHeight
;
851 SelectObject32 (hdc
, hOldFont
);
855 if (wndPtr
->dwStyle
& SBT_TOOLTIPS
) {
857 CreateWindowEx32A (0, TOOLTIPS_CLASS32A
, NULL
, 0,
858 CW_USEDEFAULT32
, CW_USEDEFAULT32
,
859 CW_USEDEFAULT32
, CW_USEDEFAULT32
,
861 wndPtr
->hInstance
, NULL
);
863 if (self
->hwndToolTip
) {
864 NMTOOLTIPSCREATED nmttc
;
866 nmttc
.hdr
.hwndFrom
= wndPtr
->hwndSelf
;
867 nmttc
.hdr
.idFrom
= wndPtr
->wIDmenu
;
868 nmttc
.hdr
.code
= NM_TOOLTIPSCREATED
;
869 nmttc
.hwndToolTips
= self
->hwndToolTip
;
871 SendMessage32A (GetParent32 (wndPtr
->hwndSelf
), WM_NOTIFY
,
872 (WPARAM32
)wndPtr
->wIDmenu
, (LPARAM
)&nmttc
);
876 GetClientRect32 (GetParent32 (wndPtr
->hwndSelf
), &rect
);
877 width
= rect
.right
- rect
.left
;
878 self
->height
= self
->textHeight
+ 4 + VERT_BORDER
;
879 MoveWindow32 (wndPtr
->hwndSelf
, lpCreate
->x
, lpCreate
->y
-1,
880 width
, self
->height
, FALSE
);
881 STATUSBAR_SetPartBounds (wndPtr
);
888 STATUSBAR_WMDestroy (WND
*wndPtr
)
890 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (wndPtr
);
893 for (i
= 0; i
< self
->numParts
; i
++) {
894 if (self
->parts
[i
].text
&& (self
->parts
[i
].style
!= SBT_OWNERDRAW
))
895 COMCTL32_Free (self
->parts
[i
].text
);
897 if (self
->part0
.text
&& (self
->part0
.style
!= SBT_OWNERDRAW
))
898 COMCTL32_Free (self
->part0
.text
);
899 COMCTL32_Free (self
->parts
);
901 /* delete default font */
902 if (self
->hDefaultFont
)
903 DeleteObject32 (self
->hDefaultFont
);
905 /* delete tool tip control */
906 if (self
->hwndToolTip
)
907 DestroyWindow32 (self
->hwndToolTip
);
909 COMCTL32_Free (self
);
915 static __inline__ LRESULT
916 STATUSBAR_WMGetFont (WND
*wndPtr
)
918 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (wndPtr
);
919 return infoPtr
->hFont
;
924 STATUSBAR_WMGetText (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
926 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (wndPtr
);
929 if (!(infoPtr
->parts
[0].text
))
931 len
= lstrlen32W (infoPtr
->parts
[0].text
);
933 if (infoPtr
->bUnicode
)
934 lstrcpy32W ((LPWSTR
)lParam
, infoPtr
->parts
[0].text
);
936 lstrcpyWtoA ((LPSTR
)lParam
, infoPtr
->parts
[0].text
);
944 __inline__
static LRESULT
945 STATUSBAR_WMMouseMove (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
947 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (wndPtr
);
949 if (infoPtr
->hwndToolTip
)
950 STATUSBAR_RelayEvent (infoPtr
->hwndToolTip
, wndPtr
->hwndSelf
,
951 WM_MOUSEMOVE
, wParam
, lParam
);
957 STATUSBAR_WMNCHitTest (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
959 if (wndPtr
->dwStyle
& SBARS_SIZEGRIP
) {
963 GetClientRect32 (wndPtr
->hwndSelf
, &rect
);
965 pt
.x
= (INT32
)LOWORD(lParam
);
966 pt
.y
= (INT32
)HIWORD(lParam
);
967 ScreenToClient32 (wndPtr
->hwndSelf
, &pt
);
969 rect
.left
= rect
.right
- 13;
972 if (PtInRect32 (&rect
, pt
))
973 return HTBOTTOMRIGHT
;
976 return DefWindowProc32A (wndPtr
->hwndSelf
, WM_NCHITTEST
, wParam
, lParam
);
980 static __inline__ LRESULT
981 STATUSBAR_WMNCLButtonDown (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
983 PostMessage32A (wndPtr
->parent
->hwndSelf
, WM_NCLBUTTONDOWN
,
989 static __inline__ LRESULT
990 STATUSBAR_WMNCLButtonUp (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
992 PostMessage32A (wndPtr
->parent
->hwndSelf
, WM_NCLBUTTONUP
,
999 STATUSBAR_WMPaint (WND
*wndPtr
, WPARAM32 wParam
)
1004 hdc
= wParam
==0 ? BeginPaint32 (wndPtr
->hwndSelf
, &ps
) : (HDC32
)wParam
;
1005 STATUSBAR_Refresh (wndPtr
, hdc
);
1007 EndPaint32 (wndPtr
->hwndSelf
, &ps
);
1014 STATUSBAR_WMSetFont (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
1016 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (wndPtr
);
1018 infoPtr
->hFont
= (HFONT32
)wParam
;
1019 if (LOWORD(lParam
) == TRUE
) {
1020 HDC32 hdc
= GetDC32 (wndPtr
->hwndSelf
);
1021 STATUSBAR_Refresh (wndPtr
, hdc
);
1022 ReleaseDC32 (wndPtr
->hwndSelf
, hdc
);
1030 STATUSBAR_WMSetText (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
1032 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (wndPtr
);
1033 STATUSWINDOWPART
*part
;
1037 if (infoPtr
->numParts
== 0)
1040 part
= &infoPtr
->parts
[0];
1041 /* duplicate string */
1043 COMCTL32_Free (part
->text
);
1045 if (infoPtr
->bUnicode
) {
1046 if (lParam
&& (len
= lstrlen32W((LPCWSTR
)lParam
))) {
1047 part
->text
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1048 lstrcpy32W (part
->text
, (LPCWSTR
)lParam
);
1052 if (lParam
&& (len
= lstrlen32A((LPCSTR
)lParam
))) {
1053 part
->text
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1054 lstrcpyAtoW (part
->text
, (LPCSTR
)lParam
);
1058 hdc
= GetDC32 (wndPtr
->hwndSelf
);
1059 STATUSBAR_RefreshPart (wndPtr
, part
, hdc
);
1060 ReleaseDC32 (wndPtr
->hwndSelf
, hdc
);
1067 STATUSBAR_WMSize (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
1069 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (wndPtr
);
1070 INT32 width
, x
, y
, flags
;
1074 /* Need to resize width to match parent */
1075 flags
= (INT32
) wParam
;
1077 /* FIXME for flags =
1078 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED, SIZE_RESTORED
1081 if (flags
== SIZE_RESTORED
) {
1082 /* width and height don't apply */
1083 parent
= GetParent32 (wndPtr
->hwndSelf
);
1084 GetClientRect32 (parent
, &parent_rect
);
1085 width
= parent_rect
.right
- parent_rect
.left
;
1086 x
= parent_rect
.left
;
1087 y
= parent_rect
.bottom
- infoPtr
->height
;
1088 MoveWindow32 (wndPtr
->hwndSelf
, parent_rect
.left
,
1089 parent_rect
.bottom
- infoPtr
->height
,
1090 width
, infoPtr
->height
, TRUE
);
1091 STATUSBAR_SetPartBounds (wndPtr
);
1098 STATUSBAR_SendNotify (WND
*wndPtr
, UINT32 code
)
1102 nmhdr
.hwndFrom
= wndPtr
->hwndSelf
;
1103 nmhdr
.idFrom
= wndPtr
->wIDmenu
;
1105 SendMessage32A (GetParent32 (wndPtr
->hwndSelf
), WM_NOTIFY
,
1113 StatusWindowProc (HWND32 hwnd
, UINT32 msg
, WPARAM32 wParam
, LPARAM lParam
)
1115 WND
*wndPtr
= WIN_FindWndPtr (hwnd
);
1119 return STATUSBAR_GetBorders (lParam
);
1122 return STATUSBAR_GetIcon (wndPtr
, wParam
);
1125 return STATUSBAR_GetParts (wndPtr
, wParam
, lParam
);
1128 return STATUSBAR_GetRect (wndPtr
, wParam
, lParam
);
1131 return STATUSBAR_GetText32A (wndPtr
, wParam
, lParam
);
1134 return STATUSBAR_GetText32W (wndPtr
, wParam
, lParam
);
1136 case SB_GETTEXTLENGTH32A
:
1137 case SB_GETTEXTLENGTH32W
:
1138 return STATUSBAR_GetTextLength (wndPtr
, wParam
);
1140 case SB_GETTIPTEXT32A
:
1141 return STATUSBAR_GetTipText32A (wndPtr
, wParam
, lParam
);
1143 case SB_GETTIPTEXT32W
:
1144 return STATUSBAR_GetTipText32W (wndPtr
, wParam
, lParam
);
1146 case SB_GETUNICODEFORMAT
:
1147 return STATUSBAR_GetUnicodeFormat (wndPtr
);
1150 return STATUSBAR_IsSimple (wndPtr
);
1153 return STATUSBAR_SetBkColor (wndPtr
, wParam
, lParam
);
1156 return STATUSBAR_SetIcon (wndPtr
, wParam
, lParam
);
1158 case SB_SETMINHEIGHT
:
1159 return STATUSBAR_SetMinHeight (wndPtr
, wParam
, lParam
);
1162 return STATUSBAR_SetParts (wndPtr
, wParam
, lParam
);
1165 return STATUSBAR_SetText32A (wndPtr
, wParam
, lParam
);
1168 return STATUSBAR_SetText32W (wndPtr
, wParam
, lParam
);
1170 case SB_SETTIPTEXT32A
:
1171 return STATUSBAR_SetTipText32A (wndPtr
, wParam
, lParam
);
1173 case SB_SETTIPTEXT32W
:
1174 return STATUSBAR_SetTipText32W (wndPtr
, wParam
, lParam
);
1176 case SB_SETUNICODEFORMAT
:
1177 return STATUSBAR_SetUnicodeFormat (wndPtr
, wParam
);
1180 return STATUSBAR_Simple (wndPtr
, wParam
, lParam
);
1184 return STATUSBAR_WMCreate (wndPtr
, wParam
, lParam
);
1187 return STATUSBAR_WMDestroy (wndPtr
);
1190 return STATUSBAR_WMGetFont (wndPtr
);
1193 return STATUSBAR_WMGetText (wndPtr
, wParam
, lParam
);
1195 case WM_GETTEXTLENGTH
:
1196 return STATUSBAR_GetTextLength (wndPtr
, 0);
1198 case WM_LBUTTONDBLCLK
:
1199 return STATUSBAR_SendNotify (wndPtr
, NM_DBLCLK
);
1202 return STATUSBAR_SendNotify (wndPtr
, NM_CLICK
);
1205 return STATUSBAR_WMMouseMove (wndPtr
, wParam
, lParam
);
1208 return STATUSBAR_WMNCHitTest (wndPtr
, wParam
, lParam
);
1210 case WM_NCLBUTTONDOWN
:
1211 return STATUSBAR_WMNCLButtonDown (wndPtr
, wParam
, lParam
);
1213 case WM_NCLBUTTONUP
:
1214 return STATUSBAR_WMNCLButtonUp (wndPtr
, wParam
, lParam
);
1217 return STATUSBAR_WMPaint (wndPtr
, wParam
);
1219 case WM_RBUTTONDBLCLK
:
1220 return STATUSBAR_SendNotify (wndPtr
, NM_RDBLCLK
);
1223 return STATUSBAR_SendNotify (wndPtr
, NM_RCLICK
);
1226 return STATUSBAR_WMSetFont (wndPtr
, wParam
, lParam
);
1229 return STATUSBAR_WMSetText (wndPtr
, wParam
, lParam
);
1232 return STATUSBAR_WMSize (wndPtr
, wParam
, lParam
);
1236 ERR (statusbar
, "unknown msg %04x wp=%04x lp=%08lx\n",
1237 msg
, wParam
, lParam
);
1238 return DefWindowProc32A (hwnd
, msg
, wParam
, lParam
);
1244 /***********************************************************************
1245 * STATUS_Register [Internal]
1247 * Registers the status window class.
1251 STATUS_Register (VOID
)
1253 WNDCLASS32A wndClass
;
1255 if (GlobalFindAtom32A (STATUSCLASSNAME32A
)) return;
1257 ZeroMemory (&wndClass
, sizeof(WNDCLASS32A
));
1258 wndClass
.style
= CS_GLOBALCLASS
| CS_DBLCLKS
| CS_VREDRAW
;
1259 wndClass
.lpfnWndProc
= (WNDPROC32
)StatusWindowProc
;
1260 wndClass
.cbClsExtra
= 0;
1261 wndClass
.cbWndExtra
= sizeof(STATUSWINDOWINFO
*);
1262 wndClass
.hCursor
= LoadCursor32A (0, IDC_ARROW32A
);
1263 wndClass
.hbrBackground
= (HBRUSH32
)(COLOR_3DFACE
+ 1);
1264 wndClass
.lpszClassName
= STATUSCLASSNAME32A
;
1266 RegisterClass32A (&wndClass
);
1270 /***********************************************************************
1271 * STATUS_Unregister [Internal]
1273 * Unregisters the status window class.
1277 STATUS_Unregister (VOID
)
1279 if (GlobalFindAtom32A (STATUSCLASSNAME32A
))
1280 UnregisterClass32A (STATUSCLASSNAME32A
, (HINSTANCE32
)NULL
);