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 (part->bound.right < part->bound.left) return;
133 if (self->clrBk != CLR_DEFAULT)
134 hbrBk = CreateSolidBrush (self->clrBk);
136 hbrBk = GetSysColorBrush (COLOR_3DFACE);
137 FillRect(hdc, &part->bound, hbrBk);
139 hOldFont = SelectObject (hdc, self->hFont ? self->hFont : self->hDefaultFont);
141 if (part->style & SBT_OWNERDRAW) {
144 dis.CtlID = GetWindowLongA (hwnd, GWL_ID);
148 dis.rcItem = part->bound;
149 dis.itemData = (INT)part->text;
150 SendMessageA (GetParent (hwnd), WM_DRAWITEM,
151 (WPARAM)dis.CtlID, (LPARAM)&dis);
154 STATUSBAR_DrawPart (hdc, part);
156 SelectObject (hdc, hOldFont);
158 if (self->clrBk != CLR_DEFAULT)
159 DeleteObject (hbrBk);
161 if (GetWindowLongA (hwnd, GWL_STYLE) & SBARS_SIZEGRIP) {
164 GetClientRect (hwnd, &rect);
165 STATUSBAR_DrawSizeGrip (hdc, &rect);
171 STATUSBAR_Refresh (HWND hwnd, HDC hdc)
173 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
179 if (!IsWindowVisible(hwnd))
182 STATUSBAR_SetPartBounds(hwnd);
184 GetClientRect (hwnd, &rect);
186 if (infoPtr->clrBk != CLR_DEFAULT)
187 hbrBk = CreateSolidBrush (infoPtr->clrBk);
189 hbrBk = GetSysColorBrush (COLOR_3DFACE);
190 FillRect(hdc, &rect, hbrBk);
192 hOldFont = SelectObject (hdc, infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont);
194 if (infoPtr->simple) {
195 STATUSBAR_RefreshPart (hwnd, &infoPtr->part0,hdc,0);
198 for (i = 0; i < infoPtr->numParts; i++) {
199 if (infoPtr->parts[i].style & SBT_OWNERDRAW) {
202 dis.CtlID = GetWindowLongA (hwnd, GWL_ID);
206 dis.rcItem = infoPtr->parts[i].bound;
207 dis.itemData = (INT)infoPtr->parts[i].text;
208 SendMessageA (GetParent (hwnd), WM_DRAWITEM,
209 (WPARAM)dis.CtlID, (LPARAM)&dis);
212 STATUSBAR_RefreshPart (hwnd, &infoPtr->parts[i], hdc,i);
216 SelectObject (hdc, hOldFont);
218 if (infoPtr->clrBk != CLR_DEFAULT)
219 DeleteObject (hbrBk);
221 if (GetWindowLongA(hwnd, GWL_STYLE) & SBARS_SIZEGRIP)
222 STATUSBAR_DrawSizeGrip (hdc, &rect);
229 STATUSBAR_SetPartBounds (HWND hwnd)
231 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
232 STATUSWINDOWPART *part;
236 /* get our window size */
237 GetClientRect (hwnd, &rect);
239 rect.top += VERT_BORDER;
241 /* set bounds for simple rectangle */
242 self->part0.bound = rect;
244 /* set bounds for non-simple rectangles */
245 for (i = 0; i < self->numParts; i++) {
246 part = &self->parts[i];
247 r = &self->parts[i].bound;
249 r->bottom = rect.bottom;
253 r->left = self->parts[i-1].bound.right + HORZ_GAP;
255 r->right = rect.right;
259 if (self->hwndToolTip) {
262 ti.cbSize = sizeof(TTTOOLINFOA);
266 SendMessageA (self->hwndToolTip, TTM_NEWTOOLRECTA,
274 STATUSBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
275 WPARAM wParam, LPARAM lParam)
283 msg.time = GetMessageTime ();
284 msg.pt.x = LOWORD(GetMessagePos ());
285 msg.pt.y = HIWORD(GetMessagePos ());
287 SendMessageA (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
291 inline static LRESULT
292 STATUSBAR_GetBorders (LPARAM lParam)
294 LPINT out = (LPINT) lParam;
296 out[0] = HORZ_BORDER; /* horizontal border width */
297 out[1] = VERT_BORDER; /* vertical border width */
298 out[2] = HORZ_GAP; /* width of border between rectangles */
305 STATUSBAR_GetIcon (HWND hwnd, WPARAM wParam)
307 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
310 nPart = (INT)wParam & 0x00ff;
311 if ((nPart < -1) || (nPart >= self->numParts))
315 return (self->part0.hIcon);
317 return (self->parts[nPart].hIcon);
322 STATUSBAR_GetParts (HWND hwnd, WPARAM wParam, LPARAM lParam)
324 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
329 num_parts = (INT) wParam;
330 parts = (LPINT) lParam;
332 for (i = 0; i < num_parts; i++) {
333 parts[i] = infoPtr->parts[i].x;
336 return (infoPtr->numParts);
341 STATUSBAR_GetRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
343 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
347 part_num = ((INT) wParam) & 0x00ff;
348 rect = (LPRECT) lParam;
350 *rect = infoPtr->part0.bound;
352 *rect = infoPtr->parts[part_num].bound;
358 STATUSBAR_GetTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
360 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
361 STATUSWINDOWPART *part;
365 nPart = ((INT) wParam) & 0x00ff;
369 part = &self->parts[nPart];
371 if (part->style & SBT_OWNERDRAW)
372 result = (LRESULT)part->text;
374 result = part->text ? lstrlenW (part->text) : 0;
375 result |= (part->style << 16);
376 if (lParam && LOWORD(result))
377 lstrcpyWtoA ((LPSTR)lParam, part->text);
384 STATUSBAR_GetTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
386 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
387 STATUSWINDOWPART *part;
391 nPart = ((INT)wParam) & 0x00ff;
393 part = &infoPtr->part0;
395 part = &infoPtr->parts[nPart];
397 if (part->style & SBT_OWNERDRAW)
398 result = (LRESULT)part->text;
400 result = part->text ? lstrlenW (part->text) : 0;
401 result |= (part->style << 16);
403 lstrcpyW ((LPWSTR)lParam, part->text);
410 STATUSBAR_GetTextLength (HWND hwnd, WPARAM wParam)
412 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
413 STATUSWINDOWPART *part;
417 part_num = ((INT) wParam) & 0x00ff;
420 part = &infoPtr->part0;
422 part = &infoPtr->parts[part_num];
425 result = lstrlenW(part->text);
429 result |= (part->style << 16);
435 STATUSBAR_GetTipTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
437 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
439 if (infoPtr->hwndToolTip) {
441 ti.cbSize = sizeof(TTTOOLINFOA);
443 ti.uId = LOWORD(wParam);
444 SendMessageA (infoPtr->hwndToolTip, TTM_GETTEXTA, 0, (LPARAM)&ti);
447 lstrcpynA ((LPSTR)lParam, ti.lpszText, HIWORD(wParam));
455 STATUSBAR_GetTipTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
457 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
459 if (infoPtr->hwndToolTip) {
461 ti.cbSize = sizeof(TTTOOLINFOW);
463 ti.uId = LOWORD(wParam);
464 SendMessageW (infoPtr->hwndToolTip, TTM_GETTEXTW, 0, (LPARAM)&ti);
467 lstrcpynW ((LPWSTR)lParam, ti.lpszText, HIWORD(wParam));
474 inline static LRESULT
475 STATUSBAR_GetUnicodeFormat (HWND hwnd)
477 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
478 return infoPtr->bUnicode;
482 inline static LRESULT
483 STATUSBAR_IsSimple (HWND hwnd)
485 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
486 return infoPtr->simple;
491 STATUSBAR_SetBkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
493 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
496 oldBkColor = self->clrBk;
497 self->clrBk = (COLORREF)lParam;
498 RedrawWindow(hwnd,(RECT*)NULL,(HRGN)NULL,RDW_INVALIDATE|RDW_UPDATENOW);
505 STATUSBAR_SetIcon (HWND hwnd, WPARAM wParam, LPARAM lParam)
507 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
508 INT nPart = (INT)wParam & 0x00ff;
511 if ((nPart < -1) || (nPart >= self->numParts))
516 self->part0.hIcon = (HICON)lParam;
518 RedrawWindow(hwnd, &self->part0.bound,(HRGN)NULL,
519 RDW_INVALIDATE|RDW_UPDATENOW);
522 self->parts[nPart].hIcon = (HICON)lParam;
524 RedrawWindow(hwnd,&self->parts[nPart].bound,(HRGN)NULL,
525 RDW_INVALIDATE|RDW_UPDATENOW);
527 ReleaseDC (hwnd, hdc);
534 STATUSBAR_SetMinHeight (HWND hwnd, WPARAM wParam, LPARAM lParam)
536 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
538 if (IsWindowVisible (hwnd)) {
539 HWND parent = GetParent (hwnd);
543 GetClientRect (parent, &parent_rect);
544 self->height = (INT)wParam + VERT_BORDER;
545 width = parent_rect.right - parent_rect.left;
546 x = parent_rect.left;
547 y = parent_rect.bottom - self->height;
548 MoveWindow (hwnd, parent_rect.left,
549 parent_rect.bottom - self->height,
550 width, self->height, TRUE);
551 STATUSBAR_SetPartBounds (hwnd);
559 STATUSBAR_SetParts (HWND hwnd, WPARAM wParam, LPARAM lParam)
561 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
562 STATUSWINDOWPART *tmp;
568 self->simple = FALSE;
570 oldNumParts = self->numParts;
571 self->numParts = (INT) wParam;
572 parts = (LPINT) lParam;
573 if (oldNumParts > self->numParts) {
574 for (i = self->numParts ; i < oldNumParts; i++) {
575 if (self->parts[i].text && !(self->parts[i].style & SBT_OWNERDRAW))
576 COMCTL32_Free (self->parts[i].text);
579 else if (oldNumParts < self->numParts) {
580 tmp = COMCTL32_Alloc (sizeof(STATUSWINDOWPART) * self->numParts);
581 for (i = 0; i < oldNumParts; i++) {
582 tmp[i] = self->parts[i];
585 COMCTL32_Free (self->parts);
589 for (i = 0; i < self->numParts; i++) {
590 self->parts[i].x = parts[i];
593 if (self->hwndToolTip) {
595 SendMessageA (self->hwndToolTip, TTM_GETTOOLCOUNT, 0, 0);
597 if (nTipCount < self->numParts) {
602 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
603 ti.cbSize = sizeof(TTTOOLINFOA);
605 for (i = nTipCount; i < self->numParts; i++) {
606 TRACE("add tool %d\n", i);
608 SendMessageA (self->hwndToolTip, TTM_ADDTOOLA,
612 else if (nTipCount > self->numParts) {
616 for (i = nTipCount - 1; i >= self->numParts; i--) {
618 FIXME("delete tool %d\n", i);
624 STATUSBAR_SetPartBounds (hwnd);
626 RedrawWindow(hwnd,(RECT*)NULL,(HRGN)NULL,RDW_INVALIDATE|RDW_UPDATENOW);
633 STATUSBAR_SetTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
635 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
636 STATUSWINDOWPART *part=NULL;
642 text = (LPSTR) lParam;
643 part_num = ((INT) wParam) & 0x00ff;
644 style = ((INT) wParam) & 0xff00;
648 else if (!self->simple && self->parts!=NULL)
649 part = &self->parts[part_num];
650 if (!part) return FALSE;
652 if (!(part->style & SBT_OWNERDRAW) && part->text)
653 COMCTL32_Free (part->text);
656 if (style & SBT_OWNERDRAW) {
657 part->text = (LPWSTR)text;
660 /* duplicate string */
661 if (text && (len = lstrlenA(text))) {
662 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
663 lstrcpyAtoW (part->text, text);
668 RedrawWindow(hwnd,&part->bound,(HRGN)NULL,RDW_INVALIDATE|RDW_UPDATENOW);
675 STATUSBAR_SetTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
677 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
678 STATUSWINDOWPART *part;
679 INT part_num, style, len;
682 text = (LPWSTR) lParam;
683 part_num = ((INT) wParam) & 0x00ff;
684 style = ((INT) wParam) & 0xff00;
686 if ((self->simple) || (self->parts==NULL) || (part_num==255))
689 part = &self->parts[part_num];
690 if (!part) return FALSE;
692 if (!(part->style & SBT_OWNERDRAW) && part->text)
693 COMCTL32_Free (part->text);
696 if (style & SBT_OWNERDRAW) {
700 /* duplicate string */
701 if (text && (len = lstrlenW(text))) {
702 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
703 lstrcpyW(part->text, text);
708 RedrawWindow(hwnd,&part->bound,(HRGN)NULL,RDW_INVALIDATE|RDW_UPDATENOW);
715 STATUSBAR_SetTipTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
717 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
719 TRACE("part %d: \"%s\"\n", (INT)wParam, (LPSTR)lParam);
720 if (infoPtr->hwndToolTip) {
722 ti.cbSize = sizeof(TTTOOLINFOA);
724 ti.uId = (INT)wParam;
726 ti.lpszText = (LPSTR)lParam;
727 SendMessageA (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTA,
736 STATUSBAR_SetTipTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
738 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
740 TRACE("part %d: \"%s\"\n", (INT)wParam, (LPSTR)lParam);
741 if (infoPtr->hwndToolTip) {
743 ti.cbSize = sizeof(TTTOOLINFOW);
745 ti.uId = (INT)wParam;
747 ti.lpszText = (LPWSTR)lParam;
748 SendMessageW (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTW,
756 inline static LRESULT
757 STATUSBAR_SetUnicodeFormat (HWND hwnd, WPARAM wParam)
759 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
760 BOOL bTemp = infoPtr->bUnicode;
762 TRACE("(0x%x)\n", (BOOL)wParam);
763 infoPtr->bUnicode = (BOOL)wParam;
770 STATUSBAR_Simple (HWND hwnd, WPARAM wParam, LPARAM lParam)
772 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
775 infoPtr->simple = (BOOL)wParam;
777 /* send notification */
778 nmhdr.hwndFrom = hwnd;
779 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
780 nmhdr.code = SBN_SIMPLEMODECHANGE;
781 SendMessageA (GetParent (hwnd), WM_NOTIFY, 0, (LPARAM)&nmhdr);
783 RedrawWindow(hwnd,(RECT*)NULL,(HRGN)NULL,RDW_INVALIDATE|RDW_UPDATENOW);
790 STATUSBAR_WMCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
792 LPCREATESTRUCTA lpCreate = (LPCREATESTRUCTA)lParam;
793 NONCLIENTMETRICSA nclm;
797 STATUSWINDOWINFO *self;
799 self = (STATUSWINDOWINFO*)COMCTL32_Alloc (sizeof(STATUSWINDOWINFO));
800 SetWindowLongA (hwnd, 0, (DWORD)self);
804 self->simple = FALSE;
805 self->clrBk = CLR_DEFAULT;
807 GetClientRect (hwnd, &rect);
809 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
810 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
811 self->hDefaultFont = CreateFontIndirectA (&nclm.lfStatusFont);
813 /* initialize simple case */
814 self->part0.bound = rect;
815 self->part0.text = 0;
817 self->part0.style = 0;
818 self->part0.hIcon = 0;
820 /* initialize first part */
821 self->parts = COMCTL32_Alloc (sizeof(STATUSWINDOWPART));
822 self->parts[0].bound = rect;
823 self->parts[0].text = 0;
824 self->parts[0].x = -1;
825 self->parts[0].style = 0;
826 self->parts[0].hIcon = 0;
828 if (IsWindowUnicode (hwnd)) {
829 self->bUnicode = TRUE;
830 if (lpCreate->lpszName &&
831 (len = lstrlenW ((LPCWSTR)lpCreate->lpszName))) {
832 self->parts[0].text = COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
833 lstrcpyW (self->parts[0].text, (LPCWSTR)lpCreate->lpszName);
837 if (lpCreate->lpszName &&
838 (len = lstrlenA ((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 = GetDC (0))) {
848 hOldFont = SelectObject (hdc,self->hDefaultFont);
849 GetTextMetricsA(hdc, &tm);
850 self->textHeight = tm.tmHeight;
851 SelectObject (hdc, hOldFont);
855 if (GetWindowLongA (hwnd, GWL_STYLE) & SBT_TOOLTIPS) {
857 CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
858 CW_USEDEFAULT, CW_USEDEFAULT,
859 CW_USEDEFAULT, CW_USEDEFAULT,
861 GetWindowLongA (hwnd, GWL_HINSTANCE), NULL);
863 if (self->hwndToolTip) {
864 NMTOOLTIPSCREATED nmttc;
866 nmttc.hdr.hwndFrom = hwnd;
867 nmttc.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
868 nmttc.hdr.code = NM_TOOLTIPSCREATED;
869 nmttc.hwndToolTips = self->hwndToolTip;
871 SendMessageA (GetParent (hwnd), WM_NOTIFY,
872 (WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc);
876 GetClientRect (GetParent (hwnd), &rect);
877 width = rect.right - rect.left;
878 self->height = self->textHeight + 4 + VERT_BORDER;
879 MoveWindow (hwnd, lpCreate->x, lpCreate->y-1,
880 width, self->height, FALSE);
881 STATUSBAR_SetPartBounds (hwnd);
888 STATUSBAR_WMDestroy (HWND hwnd)
890 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
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 DeleteObject (self->hDefaultFont);
905 /* delete tool tip control */
906 if (self->hwndToolTip)
907 DestroyWindow (self->hwndToolTip);
909 COMCTL32_Free (self);
910 SetWindowLongA(hwnd, 0, 0);
915 static inline LRESULT
916 STATUSBAR_WMGetFont (HWND hwnd)
918 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
919 return infoPtr->hFont;
924 STATUSBAR_WMGetText (HWND hwnd, WPARAM wParam, LPARAM lParam)
926 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
929 if (!(infoPtr->parts[0].text))
931 len = lstrlenW (infoPtr->parts[0].text);
933 if (infoPtr->bUnicode)
934 lstrcpyW ((LPWSTR)lParam, infoPtr->parts[0].text);
936 lstrcpyWtoA ((LPSTR)lParam, infoPtr->parts[0].text);
944 inline static LRESULT
945 STATUSBAR_WMMouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
947 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
949 if (infoPtr->hwndToolTip)
950 STATUSBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
951 WM_MOUSEMOVE, wParam, lParam);
957 STATUSBAR_WMNCHitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
959 if (GetWindowLongA (hwnd, GWL_STYLE) & SBARS_SIZEGRIP) {
963 GetClientRect (hwnd, &rect);
965 pt.x = (INT)LOWORD(lParam);
966 pt.y = (INT)HIWORD(lParam);
967 ScreenToClient (hwnd, &pt);
969 rect.left = rect.right - 13;
972 if (PtInRect (&rect, pt))
973 return HTBOTTOMRIGHT;
976 return DefWindowProcA (hwnd, WM_NCHITTEST, wParam, lParam);
980 static inline LRESULT
981 STATUSBAR_WMNCLButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
983 PostMessageA (GetParent (hwnd), WM_NCLBUTTONDOWN, wParam, lParam);
988 static inline LRESULT
989 STATUSBAR_WMNCLButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
991 PostMessageA (GetParent (hwnd), WM_NCLBUTTONUP, wParam, lParam);
997 STATUSBAR_WMPaint (HWND hwnd, WPARAM wParam)
1002 hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
1003 STATUSBAR_Refresh (hwnd, hdc);
1005 EndPaint (hwnd, &ps);
1012 STATUSBAR_WMSetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
1014 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1016 infoPtr->hFont = (HFONT)wParam;
1017 if (LOWORD(lParam) == TRUE)
1018 RedrawWindow(hwnd,(RECT*)NULL,(HRGN)NULL,
1019 RDW_INVALIDATE|RDW_UPDATENOW);
1026 STATUSBAR_WMSetText (HWND hwnd, WPARAM wParam, LPARAM lParam)
1028 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1029 STATUSWINDOWPART *part;
1032 if (infoPtr->numParts == 0)
1035 part = &infoPtr->parts[0];
1036 /* duplicate string */
1038 COMCTL32_Free (part->text);
1040 if (infoPtr->bUnicode) {
1041 if (lParam && (len = lstrlenW((LPCWSTR)lParam))) {
1042 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1043 lstrcpyW (part->text, (LPCWSTR)lParam);
1047 if (lParam && (len = lstrlenA((LPCSTR)lParam))) {
1048 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1049 lstrcpyAtoW (part->text, (LPCSTR)lParam);
1053 RedrawWindow(hwnd,&part->bound,(HRGN)NULL,RDW_INVALIDATE|RDW_UPDATENOW);
1060 STATUSBAR_WMSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1062 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1063 INT width, x, y, flags;
1067 /* Need to resize width to match parent */
1068 flags = (INT) wParam;
1070 /* FIXME for flags =
1071 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED, SIZE_RESTORED
1074 if (flags == SIZE_RESTORED) {
1075 /* width and height don't apply */
1076 parent = GetParent (hwnd);
1077 GetClientRect (parent, &parent_rect);
1078 width = parent_rect.right - parent_rect.left;
1079 x = parent_rect.left;
1080 y = parent_rect.bottom - infoPtr->height;
1081 MoveWindow (hwnd, parent_rect.left,
1082 parent_rect.bottom - infoPtr->height,
1083 width, infoPtr->height, TRUE);
1084 STATUSBAR_SetPartBounds (hwnd);
1091 STATUSBAR_SendNotify (HWND hwnd, UINT code)
1095 nmhdr.hwndFrom = hwnd;
1096 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1098 SendMessageA (GetParent (hwnd), WM_NOTIFY, 0, (LPARAM)&nmhdr);
1104 static LRESULT WINAPI
1105 StatusWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
1107 TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hwnd, msg, wParam, lParam);
1108 if (!(STATUSBAR_GetInfoPtr(hwnd)) && (msg != WM_CREATE))
1109 return DefWindowProcA (hwnd, msg, wParam, lParam);
1113 return STATUSBAR_GetBorders (lParam);
1116 return STATUSBAR_GetIcon (hwnd, wParam);
1119 return STATUSBAR_GetParts (hwnd, wParam, lParam);
1122 return STATUSBAR_GetRect (hwnd, wParam, lParam);
1125 return STATUSBAR_GetTextA (hwnd, wParam, lParam);
1128 return STATUSBAR_GetTextW (hwnd, wParam, lParam);
1130 case SB_GETTEXTLENGTHA:
1131 case SB_GETTEXTLENGTHW:
1132 return STATUSBAR_GetTextLength (hwnd, wParam);
1134 case SB_GETTIPTEXTA:
1135 return STATUSBAR_GetTipTextA (hwnd, wParam, lParam);
1137 case SB_GETTIPTEXTW:
1138 return STATUSBAR_GetTipTextW (hwnd, wParam, lParam);
1140 case SB_GETUNICODEFORMAT:
1141 return STATUSBAR_GetUnicodeFormat (hwnd);
1144 return STATUSBAR_IsSimple (hwnd);
1147 return STATUSBAR_SetBkColor (hwnd, wParam, lParam);
1150 return STATUSBAR_SetIcon (hwnd, wParam, lParam);
1152 case SB_SETMINHEIGHT:
1153 return STATUSBAR_SetMinHeight (hwnd, wParam, lParam);
1156 return STATUSBAR_SetParts (hwnd, wParam, lParam);
1159 return STATUSBAR_SetTextA (hwnd, wParam, lParam);
1162 return STATUSBAR_SetTextW (hwnd, wParam, lParam);
1164 case SB_SETTIPTEXTA:
1165 return STATUSBAR_SetTipTextA (hwnd, wParam, lParam);
1167 case SB_SETTIPTEXTW:
1168 return STATUSBAR_SetTipTextW (hwnd, wParam, lParam);
1170 case SB_SETUNICODEFORMAT:
1171 return STATUSBAR_SetUnicodeFormat (hwnd, wParam);
1174 return STATUSBAR_Simple (hwnd, wParam, lParam);
1178 return STATUSBAR_WMCreate (hwnd, wParam, lParam);
1181 return STATUSBAR_WMDestroy (hwnd);
1184 return STATUSBAR_WMGetFont (hwnd);
1187 return STATUSBAR_WMGetText (hwnd, wParam, lParam);
1189 case WM_GETTEXTLENGTH:
1190 return STATUSBAR_GetTextLength (hwnd, 0);
1192 case WM_LBUTTONDBLCLK:
1193 return STATUSBAR_SendNotify (hwnd, NM_DBLCLK);
1196 return STATUSBAR_SendNotify (hwnd, NM_CLICK);
1199 return STATUSBAR_WMMouseMove (hwnd, wParam, lParam);
1202 return STATUSBAR_WMNCHitTest (hwnd, wParam, lParam);
1204 case WM_NCLBUTTONDOWN:
1205 return STATUSBAR_WMNCLButtonDown (hwnd, wParam, lParam);
1207 case WM_NCLBUTTONUP:
1208 return STATUSBAR_WMNCLButtonUp (hwnd, wParam, lParam);
1211 return STATUSBAR_WMPaint (hwnd, wParam);
1213 case WM_RBUTTONDBLCLK:
1214 return STATUSBAR_SendNotify (hwnd, NM_RDBLCLK);
1217 return STATUSBAR_SendNotify (hwnd, NM_RCLICK);
1220 return STATUSBAR_WMSetFont (hwnd, wParam, lParam);
1223 return STATUSBAR_WMSetText (hwnd, wParam, lParam);
1226 return STATUSBAR_WMSize (hwnd, wParam, lParam);
1230 ERR("unknown msg %04x wp=%04x lp=%08lx\n",
1231 msg, wParam, lParam);
1232 return DefWindowProcA (hwnd, msg, wParam, lParam);
1238 /***********************************************************************
1239 * STATUS_Register [Internal]
1241 * Registers the status window class.
1245 STATUS_Register (void)
1249 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
1250 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW;
1251 wndClass.lpfnWndProc = (WNDPROC)StatusWindowProc;
1252 wndClass.cbClsExtra = 0;
1253 wndClass.cbWndExtra = sizeof(STATUSWINDOWINFO *);
1254 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
1255 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
1256 wndClass.lpszClassName = STATUSCLASSNAMEA;
1258 RegisterClassA (&wndClass);
1262 /***********************************************************************
1263 * STATUS_Unregister [Internal]
1265 * Unregisters the status window class.
1269 STATUS_Unregister (void)
1271 UnregisterClassA (STATUSCLASSNAMEA, (HINSTANCE)NULL);