2 * Interface code to StatusWindow widget/control
4 * Copyright 1996 Bruce Milner
5 * Copyright 1998, 1999 Eric Kohl
9 * 1) Don't hard code bar to bottom of window, allow CCS_TOP also.
10 * 2) Tooltip support (almost done).
11 * 3) I think RedrawWindow() is rather wrong, we should use InvalidateRect
16 #include "wine/unicode.h"
18 #include "debugtools.h"
20 DEFAULT_DEBUG_CHANNEL(statusbar
);
40 COLORREF clrBk
; /* background color */
41 BOOL bUnicode
; /* unicode flag */
42 STATUSWINDOWPART part0
; /* simple window */
43 STATUSWINDOWPART
*parts
;
47 * Run tests using Waite Group Windows95 API Bible Vol. 1&2
48 * The second cdrom contains executables drawstat.exe,gettext.exe,
49 * simple.exe, getparts.exe, setparts.exe, statwnd.exe
53 #define _MAX(a,b) (((a)>(b))?(a):(b))
54 #define _MIN(a,b) (((a)>(b))?(b):(a))
60 #define STATUSBAR_GetInfoPtr(hwnd) ((STATUSWINDOWINFO *)GetWindowLongA (hwnd, 0))
64 STATUSBAR_SetPartBounds (HWND hwnd
);
67 STATUSBAR_DrawSizeGrip (HDC hdc
, LPRECT lpRect
)
73 pt
.x
= lpRect
->right
- 1;
74 pt
.y
= lpRect
->bottom
- 1;
76 hOldPen
= SelectObject (hdc
, GetSysColorPen (COLOR_3DFACE
));
77 MoveToEx (hdc
, pt
.x
- 12, pt
.y
, NULL
);
78 LineTo (hdc
, pt
.x
, pt
.y
);
79 LineTo (hdc
, pt
.x
, pt
.y
- 12);
84 SelectObject (hdc
, GetSysColorPen (COLOR_3DSHADOW
));
85 for (i
= 1; i
< 11; i
+= 4) {
86 MoveToEx (hdc
, pt
.x
- i
, pt
.y
, NULL
);
87 LineTo (hdc
, pt
.x
, pt
.y
- i
);
89 MoveToEx (hdc
, pt
.x
- i
-1, pt
.y
, NULL
);
90 LineTo (hdc
, pt
.x
, pt
.y
- i
-1);
93 SelectObject (hdc
, GetSysColorPen (COLOR_3DHIGHLIGHT
));
94 for (i
= 3; i
< 13; i
+= 4) {
95 MoveToEx (hdc
, pt
.x
- i
, pt
.y
, NULL
);
96 LineTo (hdc
, pt
.x
, pt
.y
- i
);
99 SelectObject (hdc
, hOldPen
);
104 STATUSBAR_DrawPart (HDC hdc
, STATUSWINDOWPART
*part
)
106 RECT r
= part
->bound
;
107 UINT border
= BDR_SUNKENOUTER
;
109 if (part
->style
& SBT_POPOUT
)
110 border
= BDR_RAISEDOUTER
;
111 else if (part
->style
& SBT_NOBORDERS
)
114 DrawEdge(hdc
, &r
, border
, BF_RECT
|BF_ADJUST
);
118 INT cy
= r
.bottom
- r
.top
;
121 DrawIconEx (hdc
, r
.left
, r
.top
, part
->hIcon
, cy
, cy
, 0, 0, DI_NORMAL
);
127 int oldbkmode
= SetBkMode(hdc
, TRANSPARENT
);
128 LPWSTR p
= (LPWSTR
)part
->text
;
129 UINT align
= DT_LEFT
;
140 DrawTextW (hdc
, p
, lstrlenW (p
), &r
, align
|DT_VCENTER
|DT_SINGLELINE
);
141 if (oldbkmode
!= TRANSPARENT
)
142 SetBkMode(hdc
, oldbkmode
);
148 STATUSBAR_RefreshPart (HWND hwnd
, STATUSWINDOWPART
*part
, HDC hdc
, int itemID
)
150 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
154 if (!IsWindowVisible (hwnd
))
157 if (part
->bound
.right
< part
->bound
.left
) return;
159 if (self
->clrBk
!= CLR_DEFAULT
)
160 hbrBk
= CreateSolidBrush (self
->clrBk
);
162 hbrBk
= GetSysColorBrush (COLOR_3DFACE
);
163 FillRect(hdc
, &part
->bound
, hbrBk
);
165 hOldFont
= SelectObject (hdc
, self
->hFont
? self
->hFont
: self
->hDefaultFont
);
167 if (part
->style
& SBT_OWNERDRAW
) {
170 dis
.CtlID
= GetWindowLongA (hwnd
, GWL_ID
);
174 dis
.rcItem
= part
->bound
;
175 dis
.itemData
= (INT
)part
->text
;
176 SendMessageA (GetParent (hwnd
), WM_DRAWITEM
,
177 (WPARAM
)dis
.CtlID
, (LPARAM
)&dis
);
179 STATUSBAR_DrawPart (hdc
, part
);
181 SelectObject (hdc
, hOldFont
);
183 if (self
->clrBk
!= CLR_DEFAULT
)
184 DeleteObject (hbrBk
);
186 if (GetWindowLongA (hwnd
, GWL_STYLE
) & SBARS_SIZEGRIP
) {
189 GetClientRect (hwnd
, &rect
);
190 STATUSBAR_DrawSizeGrip (hdc
, &rect
);
196 STATUSBAR_Refresh (HWND hwnd
, HDC hdc
)
198 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
204 if (!IsWindowVisible(hwnd
))
207 STATUSBAR_SetPartBounds(hwnd
);
209 GetClientRect (hwnd
, &rect
);
211 if (infoPtr
->clrBk
!= CLR_DEFAULT
)
212 hbrBk
= CreateSolidBrush (infoPtr
->clrBk
);
214 hbrBk
= GetSysColorBrush (COLOR_3DFACE
);
215 FillRect(hdc
, &rect
, hbrBk
);
217 hOldFont
= SelectObject (hdc
, infoPtr
->hFont
? infoPtr
->hFont
: infoPtr
->hDefaultFont
);
219 if (infoPtr
->simple
) {
220 STATUSBAR_RefreshPart (hwnd
, &infoPtr
->part0
,hdc
,0);
222 for (i
= 0; i
< infoPtr
->numParts
; i
++) {
223 if (infoPtr
->parts
[i
].style
& SBT_OWNERDRAW
) {
226 dis
.CtlID
= GetWindowLongA (hwnd
, GWL_ID
);
230 dis
.rcItem
= infoPtr
->parts
[i
].bound
;
231 dis
.itemData
= (INT
)infoPtr
->parts
[i
].text
;
232 SendMessageA (GetParent (hwnd
), WM_DRAWITEM
,
233 (WPARAM
)dis
.CtlID
, (LPARAM
)&dis
);
235 STATUSBAR_RefreshPart (hwnd
, &infoPtr
->parts
[i
], hdc
,i
);
239 SelectObject (hdc
, hOldFont
);
241 if (infoPtr
->clrBk
!= CLR_DEFAULT
)
242 DeleteObject (hbrBk
);
244 if (GetWindowLongA(hwnd
, GWL_STYLE
) & SBARS_SIZEGRIP
)
245 STATUSBAR_DrawSizeGrip (hdc
, &rect
);
252 STATUSBAR_SetPartBounds (HWND hwnd
)
254 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
255 STATUSWINDOWPART
*part
;
259 /* get our window size */
260 GetClientRect (hwnd
, &rect
);
262 rect
.top
+= VERT_BORDER
;
264 /* set bounds for simple rectangle */
265 self
->part0
.bound
= rect
;
267 /* set bounds for non-simple rectangles */
268 for (i
= 0; i
< self
->numParts
; i
++) {
269 part
= &self
->parts
[i
];
270 r
= &self
->parts
[i
].bound
;
272 r
->bottom
= rect
.bottom
;
276 r
->left
= self
->parts
[i
-1].bound
.right
+ HORZ_GAP
;
278 r
->right
= rect
.right
;
282 if (self
->hwndToolTip
) {
285 ti
.cbSize
= sizeof(TTTOOLINFOA
);
289 SendMessageA (self
->hwndToolTip
, TTM_NEWTOOLRECTA
,
297 STATUSBAR_RelayEvent (HWND hwndTip
, HWND hwndMsg
, UINT uMsg
,
298 WPARAM wParam
, LPARAM lParam
)
306 msg
.time
= GetMessageTime ();
307 msg
.pt
.x
= LOWORD(GetMessagePos ());
308 msg
.pt
.y
= HIWORD(GetMessagePos ());
310 SendMessageA (hwndTip
, TTM_RELAYEVENT
, 0, (LPARAM
)&msg
);
314 inline static LRESULT
315 STATUSBAR_GetBorders (LPARAM lParam
)
317 LPINT out
= (LPINT
) lParam
;
319 out
[0] = HORZ_BORDER
; /* horizontal border width */
320 out
[1] = VERT_BORDER
; /* vertical border width */
321 out
[2] = HORZ_GAP
; /* width of border between rectangles */
328 STATUSBAR_GetIcon (HWND hwnd
, WPARAM wParam
)
330 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
333 nPart
= (INT
)wParam
& 0x00ff;
334 if ((nPart
< -1) || (nPart
>= self
->numParts
))
338 return (self
->part0
.hIcon
);
340 return (self
->parts
[nPart
].hIcon
);
345 STATUSBAR_GetParts (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
347 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
352 num_parts
= (INT
) wParam
;
353 parts
= (LPINT
) lParam
;
355 for (i
= 0; i
< num_parts
; i
++) {
356 parts
[i
] = infoPtr
->parts
[i
].x
;
359 return (infoPtr
->numParts
);
364 STATUSBAR_GetRect (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
366 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
370 part_num
= ((INT
) wParam
) & 0x00ff;
371 rect
= (LPRECT
) lParam
;
373 *rect
= infoPtr
->part0
.bound
;
375 *rect
= infoPtr
->parts
[part_num
].bound
;
381 STATUSBAR_GetTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
383 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
384 STATUSWINDOWPART
*part
;
388 nPart
= ((INT
) wParam
) & 0x00ff;
392 part
= &self
->parts
[nPart
];
394 if (part
->style
& SBT_OWNERDRAW
)
395 result
= (LRESULT
)part
->text
;
397 result
= part
->text
? lstrlenW (part
->text
) : 0;
398 result
|= (part
->style
<< 16);
399 if (lParam
&& LOWORD(result
))
400 lstrcpyWtoA ((LPSTR
)lParam
, part
->text
);
407 STATUSBAR_GetTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
409 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
410 STATUSWINDOWPART
*part
;
414 nPart
= ((INT
)wParam
) & 0x00ff;
416 part
= &infoPtr
->part0
;
418 part
= &infoPtr
->parts
[nPart
];
420 if (part
->style
& SBT_OWNERDRAW
)
421 result
= (LRESULT
)part
->text
;
423 result
= part
->text
? lstrlenW (part
->text
) : 0;
424 result
|= (part
->style
<< 16);
426 strcpyW ((LPWSTR
)lParam
, part
->text
);
433 STATUSBAR_GetTextLength (HWND hwnd
, WPARAM wParam
)
435 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
436 STATUSWINDOWPART
*part
;
440 part_num
= ((INT
) wParam
) & 0x00ff;
443 part
= &infoPtr
->part0
;
445 part
= &infoPtr
->parts
[part_num
];
448 result
= lstrlenW(part
->text
);
452 result
|= (part
->style
<< 16);
458 STATUSBAR_GetTipTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
460 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
462 if (infoPtr
->hwndToolTip
) {
464 ti
.cbSize
= sizeof(TTTOOLINFOA
);
466 ti
.uId
= LOWORD(wParam
);
467 SendMessageA (infoPtr
->hwndToolTip
, TTM_GETTEXTA
, 0, (LPARAM
)&ti
);
470 lstrcpynA ((LPSTR
)lParam
, ti
.lpszText
, HIWORD(wParam
));
478 STATUSBAR_GetTipTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
480 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
482 if (infoPtr
->hwndToolTip
) {
484 ti
.cbSize
= sizeof(TTTOOLINFOW
);
486 ti
.uId
= LOWORD(wParam
);
487 SendMessageW (infoPtr
->hwndToolTip
, TTM_GETTEXTW
, 0, (LPARAM
)&ti
);
490 lstrcpynW ((LPWSTR
)lParam
, ti
.lpszText
, HIWORD(wParam
));
497 inline static LRESULT
498 STATUSBAR_GetUnicodeFormat (HWND hwnd
)
500 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
501 return infoPtr
->bUnicode
;
505 inline static LRESULT
506 STATUSBAR_IsSimple (HWND hwnd
)
508 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
509 return infoPtr
->simple
;
514 STATUSBAR_SetBkColor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
516 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
519 oldBkColor
= self
->clrBk
;
520 self
->clrBk
= (COLORREF
)lParam
;
521 RedrawWindow(hwnd
,(RECT
*)NULL
,(HRGN
)NULL
,RDW_INVALIDATE
|RDW_UPDATENOW
);
528 STATUSBAR_SetIcon (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
530 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
531 INT nPart
= (INT
)wParam
& 0x00ff;
533 if ((nPart
< -1) || (nPart
>= self
->numParts
))
536 TRACE("setting part %d, icon %lx\n",nPart
,lParam
);
539 if (self
->part0
.hIcon
== (HICON
)lParam
) /* same as - no redraw */
541 self
->part0
.hIcon
= (HICON
)lParam
;
543 RedrawWindow(hwnd
, &self
->part0
.bound
,(HRGN
)NULL
,
544 RDW_INVALIDATE
|RDW_UPDATENOW
);
546 if (self
->parts
[nPart
].hIcon
== (HICON
)lParam
) /* same as - no redraw */
549 self
->parts
[nPart
].hIcon
= (HICON
)lParam
;
551 RedrawWindow(hwnd
,&self
->parts
[nPart
].bound
,(HRGN
)NULL
,
552 RDW_INVALIDATE
|RDW_UPDATENOW
);
559 STATUSBAR_SetMinHeight (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
561 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
563 if (IsWindowVisible (hwnd
)) {
564 HWND parent
= GetParent (hwnd
);
568 GetClientRect (parent
, &parent_rect
);
569 self
->height
= (INT
)wParam
+ VERT_BORDER
;
570 width
= parent_rect
.right
- parent_rect
.left
;
571 x
= parent_rect
.left
;
572 y
= parent_rect
.bottom
- self
->height
;
573 MoveWindow (hwnd
, parent_rect
.left
,
574 parent_rect
.bottom
- self
->height
,
575 width
, self
->height
, TRUE
);
576 STATUSBAR_SetPartBounds (hwnd
);
584 STATUSBAR_SetParts (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
586 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
587 STATUSWINDOWPART
*tmp
;
592 TRACE("(%d,%p)\n",wParam
,(LPVOID
)lParam
);
595 self
->simple
= FALSE
;
597 oldNumParts
= self
->numParts
;
598 self
->numParts
= (INT
) wParam
;
599 parts
= (LPINT
) lParam
;
600 if (oldNumParts
> self
->numParts
) {
601 for (i
= self
->numParts
; i
< oldNumParts
; i
++) {
602 if (self
->parts
[i
].text
&& !(self
->parts
[i
].style
& SBT_OWNERDRAW
))
603 COMCTL32_Free (self
->parts
[i
].text
);
606 if (oldNumParts
< self
->numParts
) {
607 tmp
= COMCTL32_Alloc (sizeof(STATUSWINDOWPART
) * self
->numParts
);
608 for (i
= 0; i
< oldNumParts
; i
++) {
609 tmp
[i
] = self
->parts
[i
];
612 COMCTL32_Free (self
->parts
);
615 if (oldNumParts
== self
->numParts
) {
616 for (i
=0;i
<oldNumParts
;i
++)
617 if (self
->parts
[i
].x
!= parts
[i
])
619 if (i
==oldNumParts
) /* Unchanged? no need to redraw! */
623 for (i
= 0; i
< self
->numParts
; i
++)
624 self
->parts
[i
].x
= parts
[i
];
626 if (self
->hwndToolTip
) {
628 SendMessageA (self
->hwndToolTip
, TTM_GETTOOLCOUNT
, 0, 0);
630 if (nTipCount
< self
->numParts
) {
635 ZeroMemory (&ti
, sizeof(TTTOOLINFOA
));
636 ti
.cbSize
= sizeof(TTTOOLINFOA
);
638 for (i
= nTipCount
; i
< self
->numParts
; i
++) {
639 TRACE("add tool %d\n", i
);
641 SendMessageA (self
->hwndToolTip
, TTM_ADDTOOLA
,
645 else if (nTipCount
> self
->numParts
) {
649 for (i
= nTipCount
- 1; i
>= self
->numParts
; i
--) {
650 FIXME("delete tool %d\n", i
);
654 STATUSBAR_SetPartBounds (hwnd
);
655 RedrawWindow(hwnd
,(RECT
*)NULL
,(HRGN
)NULL
,RDW_INVALIDATE
|RDW_UPDATENOW
);
661 STATUSBAR_SetTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
663 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
664 STATUSWINDOWPART
*part
=NULL
;
668 BOOL changed
= FALSE
;
670 text
= (LPSTR
) lParam
;
671 part_num
= ((INT
) wParam
) & 0x00ff;
672 style
= ((INT
) wParam
) & 0xff00;
674 TRACE("setting part %d, text %s\n",part_num
,debugstr_a(text
));
678 else if (!self
->simple
&& self
->parts
!=NULL
)
679 part
= &self
->parts
[part_num
];
680 if (!part
) return FALSE
;
682 if (part
->style
!= style
)
686 if (style
& SBT_OWNERDRAW
) {
687 if (part
->text
== (LPWSTR
)text
)
689 part
->text
= (LPWSTR
)text
;
693 /* check if text is unchanged -> no need to redraw */
695 LPWSTR tmptext
= COMCTL32_Alloc((lstrlenA(text
)+1)*sizeof(WCHAR
));
696 lstrcpyAtoW (tmptext
, text
);
698 if (!changed
&& part
->text
&& !lstrcmpW(tmptext
,part
->text
)) {
699 COMCTL32_Free(tmptext
);
704 if (!changed
&& !part
->text
)
710 COMCTL32_Free (part
->text
);
713 RedrawWindow(hwnd
,&part
->bound
,(HRGN
)NULL
,RDW_INVALIDATE
|RDW_UPDATENOW
);
720 STATUSBAR_SetTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
722 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
723 STATUSWINDOWPART
*part
;
724 INT part_num
, style
, len
;
727 text
= (LPWSTR
) lParam
;
728 part_num
= ((INT
) wParam
) & 0x00ff;
729 style
= ((INT
) wParam
) & 0xff00;
731 if ((self
->simple
) || (self
->parts
==NULL
) || (part_num
==255))
734 part
= &self
->parts
[part_num
];
735 if (!part
) return FALSE
;
737 if (!(part
->style
& SBT_OWNERDRAW
) && part
->text
)
738 COMCTL32_Free (part
->text
);
741 /* FIXME: add "no need to redraw logic" */
742 if (style
& SBT_OWNERDRAW
) {
745 /* duplicate string */
746 if (text
&& (len
= lstrlenW(text
))) {
747 part
->text
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
748 strcpyW(part
->text
, text
);
753 RedrawWindow(hwnd
,&part
->bound
,(HRGN
)NULL
,RDW_INVALIDATE
|RDW_UPDATENOW
);
760 STATUSBAR_SetTipTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
762 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
764 TRACE("part %d: \"%s\"\n", (INT
)wParam
, (LPSTR
)lParam
);
765 if (infoPtr
->hwndToolTip
) {
767 ti
.cbSize
= sizeof(TTTOOLINFOA
);
769 ti
.uId
= (INT
)wParam
;
771 ti
.lpszText
= (LPSTR
)lParam
;
772 SendMessageA (infoPtr
->hwndToolTip
, TTM_UPDATETIPTEXTA
,
781 STATUSBAR_SetTipTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
783 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
785 TRACE("part %d: \"%s\"\n", (INT
)wParam
, (LPSTR
)lParam
);
786 if (infoPtr
->hwndToolTip
) {
788 ti
.cbSize
= sizeof(TTTOOLINFOW
);
790 ti
.uId
= (INT
)wParam
;
792 ti
.lpszText
= (LPWSTR
)lParam
;
793 SendMessageW (infoPtr
->hwndToolTip
, TTM_UPDATETIPTEXTW
,
801 inline static LRESULT
802 STATUSBAR_SetUnicodeFormat (HWND hwnd
, WPARAM wParam
)
804 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
805 BOOL bTemp
= infoPtr
->bUnicode
;
807 TRACE("(0x%x)\n", (BOOL
)wParam
);
808 infoPtr
->bUnicode
= (BOOL
)wParam
;
815 STATUSBAR_Simple (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
817 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
820 if (infoPtr
->simple
== wParam
) /* no need to change */
823 infoPtr
->simple
= (BOOL
)wParam
;
825 /* send notification */
826 nmhdr
.hwndFrom
= hwnd
;
827 nmhdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
828 nmhdr
.code
= SBN_SIMPLEMODECHANGE
;
829 SendMessageA (GetParent (hwnd
), WM_NOTIFY
, 0, (LPARAM
)&nmhdr
);
830 RedrawWindow(hwnd
,(RECT
*)NULL
,(HRGN
)NULL
,RDW_INVALIDATE
|RDW_UPDATENOW
);
836 STATUSBAR_WMCreate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
838 LPCREATESTRUCTA lpCreate
= (LPCREATESTRUCTA
)lParam
;
839 NONCLIENTMETRICSA nclm
;
843 STATUSWINDOWINFO
*self
;
845 self
= (STATUSWINDOWINFO
*)COMCTL32_Alloc (sizeof(STATUSWINDOWINFO
));
846 SetWindowLongA (hwnd
, 0, (DWORD
)self
);
850 self
->simple
= FALSE
;
851 self
->clrBk
= CLR_DEFAULT
;
853 GetClientRect (hwnd
, &rect
);
855 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
856 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
857 self
->hDefaultFont
= CreateFontIndirectA (&nclm
.lfStatusFont
);
859 /* initialize simple case */
860 self
->part0
.bound
= rect
;
861 self
->part0
.text
= 0;
863 self
->part0
.style
= 0;
864 self
->part0
.hIcon
= 0;
866 /* initialize first part */
867 self
->parts
= COMCTL32_Alloc (sizeof(STATUSWINDOWPART
));
868 self
->parts
[0].bound
= rect
;
869 self
->parts
[0].text
= 0;
870 self
->parts
[0].x
= -1;
871 self
->parts
[0].style
= 0;
872 self
->parts
[0].hIcon
= 0;
874 if (IsWindowUnicode (hwnd
)) {
875 self
->bUnicode
= TRUE
;
876 if (lpCreate
->lpszName
&&
877 (len
= lstrlenW ((LPCWSTR
)lpCreate
->lpszName
))) {
878 self
->parts
[0].text
= COMCTL32_Alloc ((len
+ 1)*sizeof(WCHAR
));
879 strcpyW (self
->parts
[0].text
, (LPCWSTR
)lpCreate
->lpszName
);
883 if (lpCreate
->lpszName
&&
884 (len
= lstrlenA ((LPCSTR
)lpCreate
->lpszName
))) {
885 self
->parts
[0].text
= COMCTL32_Alloc ((len
+ 1)*sizeof(WCHAR
));
886 lstrcpyAtoW (self
->parts
[0].text
, (LPCSTR
)lpCreate
->lpszName
);
890 if ((hdc
= GetDC (0))) {
894 hOldFont
= SelectObject (hdc
,self
->hDefaultFont
);
895 GetTextMetricsA(hdc
, &tm
);
896 self
->textHeight
= tm
.tmHeight
;
897 SelectObject (hdc
, hOldFont
);
901 if (GetWindowLongA (hwnd
, GWL_STYLE
) & SBT_TOOLTIPS
) {
903 CreateWindowExA (0, TOOLTIPS_CLASSA
, NULL
, 0,
904 CW_USEDEFAULT
, CW_USEDEFAULT
,
905 CW_USEDEFAULT
, CW_USEDEFAULT
,
907 GetWindowLongA (hwnd
, GWL_HINSTANCE
), NULL
);
909 if (self
->hwndToolTip
) {
910 NMTOOLTIPSCREATED nmttc
;
912 nmttc
.hdr
.hwndFrom
= hwnd
;
913 nmttc
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
914 nmttc
.hdr
.code
= NM_TOOLTIPSCREATED
;
915 nmttc
.hwndToolTips
= self
->hwndToolTip
;
917 SendMessageA (GetParent (hwnd
), WM_NOTIFY
,
918 (WPARAM
)nmttc
.hdr
.idFrom
, (LPARAM
)&nmttc
);
922 GetClientRect (GetParent (hwnd
), &rect
);
923 width
= rect
.right
- rect
.left
;
924 self
->height
= self
->textHeight
+ 4 + VERT_BORDER
;
925 MoveWindow (hwnd
, lpCreate
->x
, lpCreate
->y
-1,
926 width
, self
->height
, FALSE
);
927 STATUSBAR_SetPartBounds (hwnd
);
934 STATUSBAR_WMDestroy (HWND hwnd
)
936 STATUSWINDOWINFO
*self
= STATUSBAR_GetInfoPtr (hwnd
);
939 for (i
= 0; i
< self
->numParts
; i
++) {
940 if (self
->parts
[i
].text
&& !(self
->parts
[i
].style
& SBT_OWNERDRAW
))
941 COMCTL32_Free (self
->parts
[i
].text
);
943 if (self
->part0
.text
&& !(self
->part0
.style
& SBT_OWNERDRAW
))
944 COMCTL32_Free (self
->part0
.text
);
945 COMCTL32_Free (self
->parts
);
947 /* delete default font */
948 if (self
->hDefaultFont
)
949 DeleteObject (self
->hDefaultFont
);
951 /* delete tool tip control */
952 if (self
->hwndToolTip
)
953 DestroyWindow (self
->hwndToolTip
);
955 COMCTL32_Free (self
);
956 SetWindowLongA(hwnd
, 0, 0);
961 static inline LRESULT
962 STATUSBAR_WMGetFont (HWND hwnd
)
964 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
965 return infoPtr
->hFont
;
970 STATUSBAR_WMGetText (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
972 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
975 if (!(infoPtr
->parts
[0].text
))
977 len
= lstrlenW (infoPtr
->parts
[0].text
);
979 if (infoPtr
->bUnicode
)
980 strcpyW ((LPWSTR
)lParam
, infoPtr
->parts
[0].text
);
982 lstrcpyWtoA ((LPSTR
)lParam
, infoPtr
->parts
[0].text
);
990 inline static LRESULT
991 STATUSBAR_WMMouseMove (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
993 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
995 if (infoPtr
->hwndToolTip
)
996 STATUSBAR_RelayEvent (infoPtr
->hwndToolTip
, hwnd
,
997 WM_MOUSEMOVE
, wParam
, lParam
);
1003 STATUSBAR_WMNCHitTest (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1005 if (GetWindowLongA (hwnd
, GWL_STYLE
) & SBARS_SIZEGRIP
) {
1009 GetClientRect (hwnd
, &rect
);
1011 pt
.x
= (INT
)LOWORD(lParam
);
1012 pt
.y
= (INT
)HIWORD(lParam
);
1013 ScreenToClient (hwnd
, &pt
);
1015 rect
.left
= rect
.right
- 13;
1018 if (PtInRect (&rect
, pt
))
1019 return HTBOTTOMRIGHT
;
1022 return DefWindowProcA (hwnd
, WM_NCHITTEST
, wParam
, lParam
);
1026 static inline LRESULT
1027 STATUSBAR_WMNCLButtonDown (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1029 PostMessageA (GetParent (hwnd
), WM_NCLBUTTONDOWN
, wParam
, lParam
);
1034 static inline LRESULT
1035 STATUSBAR_WMNCLButtonUp (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1037 PostMessageA (GetParent (hwnd
), WM_NCLBUTTONUP
, wParam
, lParam
);
1043 STATUSBAR_WMPaint (HWND hwnd
, WPARAM wParam
)
1048 hdc
= wParam
==0 ? BeginPaint (hwnd
, &ps
) : (HDC
)wParam
;
1049 STATUSBAR_Refresh (hwnd
, hdc
);
1051 EndPaint (hwnd
, &ps
);
1058 STATUSBAR_WMSetFont (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1060 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
1062 infoPtr
->hFont
= (HFONT
)wParam
;
1063 if (LOWORD(lParam
) == TRUE
)
1064 RedrawWindow(hwnd
,(RECT
*)NULL
,(HRGN
)NULL
,
1065 RDW_INVALIDATE
|RDW_UPDATENOW
);
1072 STATUSBAR_WMSetText (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1074 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
1075 STATUSWINDOWPART
*part
;
1078 if (infoPtr
->numParts
== 0)
1081 part
= &infoPtr
->parts
[0];
1082 /* duplicate string */
1084 COMCTL32_Free (part
->text
);
1086 if (infoPtr
->bUnicode
) {
1087 if (lParam
&& (len
= lstrlenW((LPCWSTR
)lParam
))) {
1088 part
->text
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1089 strcpyW (part
->text
, (LPCWSTR
)lParam
);
1093 if (lParam
&& (len
= lstrlenA((LPCSTR
)lParam
))) {
1094 part
->text
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1095 lstrcpyAtoW (part
->text
, (LPCSTR
)lParam
);
1099 RedrawWindow(hwnd
,&part
->bound
,(HRGN
)NULL
,RDW_INVALIDATE
|RDW_UPDATENOW
);
1106 STATUSBAR_WMSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1108 STATUSWINDOWINFO
*infoPtr
= STATUSBAR_GetInfoPtr (hwnd
);
1109 INT width
, x
, y
, flags
;
1113 /* Need to resize width to match parent */
1114 flags
= (INT
) wParam
;
1116 /* FIXME for flags =
1117 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED, SIZE_RESTORED
1120 if (flags
== SIZE_RESTORED
) {
1121 /* width and height don't apply */
1122 parent
= GetParent (hwnd
);
1123 GetClientRect (parent
, &parent_rect
);
1124 width
= parent_rect
.right
- parent_rect
.left
;
1125 x
= parent_rect
.left
;
1126 y
= parent_rect
.bottom
- infoPtr
->height
;
1127 MoveWindow (hwnd
, parent_rect
.left
,
1128 parent_rect
.bottom
- infoPtr
->height
,
1129 width
, infoPtr
->height
, TRUE
);
1130 STATUSBAR_SetPartBounds (hwnd
);
1137 STATUSBAR_SendNotify (HWND hwnd
, UINT code
)
1141 nmhdr
.hwndFrom
= hwnd
;
1142 nmhdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
1144 SendMessageA (GetParent (hwnd
), WM_NOTIFY
, 0, (LPARAM
)&nmhdr
);
1150 static LRESULT WINAPI
1151 StatusWindowProc (HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1153 TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hwnd
, msg
, wParam
, lParam
);
1154 if (!(STATUSBAR_GetInfoPtr(hwnd
)) && (msg
!= WM_CREATE
))
1155 return DefWindowProcA (hwnd
, msg
, wParam
, lParam
);
1159 return STATUSBAR_GetBorders (lParam
);
1162 return STATUSBAR_GetIcon (hwnd
, wParam
);
1165 return STATUSBAR_GetParts (hwnd
, wParam
, lParam
);
1168 return STATUSBAR_GetRect (hwnd
, wParam
, lParam
);
1171 return STATUSBAR_GetTextA (hwnd
, wParam
, lParam
);
1174 return STATUSBAR_GetTextW (hwnd
, wParam
, lParam
);
1176 case SB_GETTEXTLENGTHA
:
1177 case SB_GETTEXTLENGTHW
:
1178 return STATUSBAR_GetTextLength (hwnd
, wParam
);
1180 case SB_GETTIPTEXTA
:
1181 return STATUSBAR_GetTipTextA (hwnd
, wParam
, lParam
);
1183 case SB_GETTIPTEXTW
:
1184 return STATUSBAR_GetTipTextW (hwnd
, wParam
, lParam
);
1186 case SB_GETUNICODEFORMAT
:
1187 return STATUSBAR_GetUnicodeFormat (hwnd
);
1190 return STATUSBAR_IsSimple (hwnd
);
1193 return STATUSBAR_SetBkColor (hwnd
, wParam
, lParam
);
1196 return STATUSBAR_SetIcon (hwnd
, wParam
, lParam
);
1198 case SB_SETMINHEIGHT
:
1199 return STATUSBAR_SetMinHeight (hwnd
, wParam
, lParam
);
1202 return STATUSBAR_SetParts (hwnd
, wParam
, lParam
);
1205 return STATUSBAR_SetTextA (hwnd
, wParam
, lParam
);
1208 return STATUSBAR_SetTextW (hwnd
, wParam
, lParam
);
1210 case SB_SETTIPTEXTA
:
1211 return STATUSBAR_SetTipTextA (hwnd
, wParam
, lParam
);
1213 case SB_SETTIPTEXTW
:
1214 return STATUSBAR_SetTipTextW (hwnd
, wParam
, lParam
);
1216 case SB_SETUNICODEFORMAT
:
1217 return STATUSBAR_SetUnicodeFormat (hwnd
, wParam
);
1220 return STATUSBAR_Simple (hwnd
, wParam
, lParam
);
1224 return STATUSBAR_WMCreate (hwnd
, wParam
, lParam
);
1227 return STATUSBAR_WMDestroy (hwnd
);
1230 return STATUSBAR_WMGetFont (hwnd
);
1233 return STATUSBAR_WMGetText (hwnd
, wParam
, lParam
);
1235 case WM_GETTEXTLENGTH
:
1236 return STATUSBAR_GetTextLength (hwnd
, 0);
1238 case WM_LBUTTONDBLCLK
:
1239 return STATUSBAR_SendNotify (hwnd
, NM_DBLCLK
);
1242 return STATUSBAR_SendNotify (hwnd
, NM_CLICK
);
1245 return STATUSBAR_WMMouseMove (hwnd
, wParam
, lParam
);
1248 return STATUSBAR_WMNCHitTest (hwnd
, wParam
, lParam
);
1250 case WM_NCLBUTTONDOWN
:
1251 return STATUSBAR_WMNCLButtonDown (hwnd
, wParam
, lParam
);
1253 case WM_NCLBUTTONUP
:
1254 return STATUSBAR_WMNCLButtonUp (hwnd
, wParam
, lParam
);
1257 return STATUSBAR_WMPaint (hwnd
, wParam
);
1259 case WM_RBUTTONDBLCLK
:
1260 return STATUSBAR_SendNotify (hwnd
, NM_RDBLCLK
);
1263 return STATUSBAR_SendNotify (hwnd
, NM_RCLICK
);
1266 return STATUSBAR_WMSetFont (hwnd
, wParam
, lParam
);
1269 return STATUSBAR_WMSetText (hwnd
, wParam
, lParam
);
1272 return STATUSBAR_WMSize (hwnd
, wParam
, lParam
);
1276 ERR("unknown msg %04x wp=%04x lp=%08lx\n",
1277 msg
, wParam
, lParam
);
1278 return DefWindowProcA (hwnd
, msg
, wParam
, lParam
);
1284 /***********************************************************************
1285 * STATUS_Register [Internal]
1287 * Registers the status window class.
1291 STATUS_Register (void)
1295 ZeroMemory (&wndClass
, sizeof(WNDCLASSA
));
1296 wndClass
.style
= CS_GLOBALCLASS
| CS_DBLCLKS
| CS_VREDRAW
;
1297 wndClass
.lpfnWndProc
= (WNDPROC
)StatusWindowProc
;
1298 wndClass
.cbClsExtra
= 0;
1299 wndClass
.cbWndExtra
= sizeof(STATUSWINDOWINFO
*);
1300 wndClass
.hCursor
= LoadCursorA (0, IDC_ARROWA
);
1301 wndClass
.hbrBackground
= (HBRUSH
)(COLOR_3DFACE
+ 1);
1302 wndClass
.lpszClassName
= STATUSCLASSNAMEA
;
1304 RegisterClassA (&wndClass
);
1308 /***********************************************************************
1309 * STATUS_Unregister [Internal]
1311 * Unregisters the status window class.
1315 STATUS_Unregister (void)
1317 UnregisterClassA (STATUSCLASSNAMEA
, (HINSTANCE
)NULL
);