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, int itemID)
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_RefreshPart (hwnd, &infoPtr->part0,hdc,0);
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_RefreshPart (hwnd, &infoPtr->parts[i], hdc,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);
490 oldBkColor = self->clrBk;
491 self->clrBk = (COLORREF)lParam;
492 RedrawWindow(hwnd,(RECT*)NULL,(HRGN)NULL,RDW_INVALIDATE|RDW_UPDATENOW);
499 STATUSBAR_SetIcon (HWND hwnd, WPARAM wParam, LPARAM lParam)
501 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
502 INT nPart = (INT)wParam & 0x00ff;
505 if ((nPart < -1) || (nPart >= self->numParts))
510 self->part0.hIcon = (HICON)lParam;
512 RedrawWindow(hwnd, &self->part0.bound,(HRGN)NULL,
513 RDW_INVALIDATE|RDW_UPDATENOW);
516 self->parts[nPart].hIcon = (HICON)lParam;
518 RedrawWindow(hwnd,&self->parts[nPart].bound,(HRGN)NULL,
519 RDW_INVALIDATE|RDW_UPDATENOW);
521 ReleaseDC (hwnd, hdc);
528 STATUSBAR_SetMinHeight (HWND hwnd, WPARAM wParam, LPARAM lParam)
530 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
532 if (IsWindowVisible (hwnd)) {
533 HWND parent = GetParent (hwnd);
537 GetClientRect (parent, &parent_rect);
538 self->height = (INT)wParam + VERT_BORDER;
539 width = parent_rect.right - parent_rect.left;
540 x = parent_rect.left;
541 y = parent_rect.bottom - self->height;
542 MoveWindow (hwnd, parent_rect.left,
543 parent_rect.bottom - self->height,
544 width, self->height, TRUE);
545 STATUSBAR_SetPartBounds (hwnd);
553 STATUSBAR_SetParts (HWND hwnd, WPARAM wParam, LPARAM lParam)
555 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
556 STATUSWINDOWPART *tmp;
562 self->simple = FALSE;
564 oldNumParts = self->numParts;
565 self->numParts = (INT) wParam;
566 parts = (LPINT) 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 SendMessageA (self->hwndToolTip, TTM_GETTOOLCOUNT, 0, 0);
591 if (nTipCount < self->numParts) {
596 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
597 ti.cbSize = sizeof(TTTOOLINFOA);
599 for (i = nTipCount; i < self->numParts; i++) {
600 TRACE("add tool %d\n", i);
602 SendMessageA (self->hwndToolTip, TTM_ADDTOOLA,
606 else if (nTipCount > self->numParts) {
610 for (i = nTipCount - 1; i >= self->numParts; i--) {
612 FIXME("delete tool %d\n", i);
618 STATUSBAR_SetPartBounds (hwnd);
620 RedrawWindow(hwnd,(RECT*)NULL,(HRGN)NULL,RDW_INVALIDATE|RDW_UPDATENOW);
627 STATUSBAR_SetTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
629 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
630 STATUSWINDOWPART *part=NULL;
636 text = (LPSTR) lParam;
637 part_num = ((INT) wParam) & 0x00ff;
638 style = ((INT) wParam) & 0xff00;
642 else if (!self->simple && self->parts!=NULL)
643 part = &self->parts[part_num];
644 if (!part) return FALSE;
646 if (!(part->style & SBT_OWNERDRAW) && part->text)
647 COMCTL32_Free (part->text);
650 if (style & SBT_OWNERDRAW) {
651 part->text = (LPWSTR)text;
654 /* duplicate string */
655 if (text && (len = lstrlenA(text))) {
656 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
657 lstrcpyAtoW (part->text, text);
662 RedrawWindow(hwnd,&part->bound,(HRGN)NULL,RDW_INVALIDATE|RDW_UPDATENOW);
669 STATUSBAR_SetTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
671 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
672 STATUSWINDOWPART *part;
673 INT part_num, style, len;
676 text = (LPWSTR) lParam;
677 part_num = ((INT) wParam) & 0x00ff;
678 style = ((INT) wParam) & 0xff00;
680 if ((self->simple) || (self->parts==NULL) || (part_num==255))
683 part = &self->parts[part_num];
684 if (!part) return FALSE;
686 if (!(part->style & SBT_OWNERDRAW) && part->text)
687 COMCTL32_Free (part->text);
690 if (style & SBT_OWNERDRAW) {
694 /* duplicate string */
695 if (text && (len = lstrlenW(text))) {
696 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
697 lstrcpyW(part->text, text);
702 RedrawWindow(hwnd,&part->bound,(HRGN)NULL,RDW_INVALIDATE|RDW_UPDATENOW);
709 STATUSBAR_SetTipTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
711 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
713 TRACE("part %d: \"%s\"\n", (INT)wParam, (LPSTR)lParam);
714 if (infoPtr->hwndToolTip) {
716 ti.cbSize = sizeof(TTTOOLINFOA);
718 ti.uId = (INT)wParam;
720 ti.lpszText = (LPSTR)lParam;
721 SendMessageA (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTA,
730 STATUSBAR_SetTipTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
732 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
734 TRACE("part %d: \"%s\"\n", (INT)wParam, (LPSTR)lParam);
735 if (infoPtr->hwndToolTip) {
737 ti.cbSize = sizeof(TTTOOLINFOW);
739 ti.uId = (INT)wParam;
741 ti.lpszText = (LPWSTR)lParam;
742 SendMessageW (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTW,
750 inline static LRESULT
751 STATUSBAR_SetUnicodeFormat (HWND hwnd, WPARAM wParam)
753 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
754 BOOL bTemp = infoPtr->bUnicode;
756 TRACE("(0x%x)\n", (BOOL)wParam);
757 infoPtr->bUnicode = (BOOL)wParam;
764 STATUSBAR_Simple (HWND hwnd, WPARAM wParam, LPARAM lParam)
766 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
769 infoPtr->simple = (BOOL)wParam;
771 /* send notification */
772 nmhdr.hwndFrom = hwnd;
773 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
774 nmhdr.code = SBN_SIMPLEMODECHANGE;
775 SendMessageA (GetParent (hwnd), WM_NOTIFY, 0, (LPARAM)&nmhdr);
777 RedrawWindow(hwnd,(RECT*)NULL,(HRGN)NULL,RDW_INVALIDATE|RDW_UPDATENOW);
784 STATUSBAR_WMCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
786 LPCREATESTRUCTA lpCreate = (LPCREATESTRUCTA)lParam;
787 NONCLIENTMETRICSA nclm;
791 STATUSWINDOWINFO *self;
793 self = (STATUSWINDOWINFO*)COMCTL32_Alloc (sizeof(STATUSWINDOWINFO));
794 SetWindowLongA (hwnd, 0, (DWORD)self);
798 self->simple = FALSE;
799 self->clrBk = CLR_DEFAULT;
801 GetClientRect (hwnd, &rect);
803 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
804 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
805 self->hDefaultFont = CreateFontIndirectA (&nclm.lfStatusFont);
807 /* initialize simple case */
808 self->part0.bound = rect;
809 self->part0.text = 0;
811 self->part0.style = 0;
812 self->part0.hIcon = 0;
814 /* initialize first part */
815 self->parts = COMCTL32_Alloc (sizeof(STATUSWINDOWPART));
816 self->parts[0].bound = rect;
817 self->parts[0].text = 0;
818 self->parts[0].x = -1;
819 self->parts[0].style = 0;
820 self->parts[0].hIcon = 0;
822 if (IsWindowUnicode (hwnd)) {
823 self->bUnicode = TRUE;
824 if (lpCreate->lpszName &&
825 (len = lstrlenW ((LPCWSTR)lpCreate->lpszName))) {
826 self->parts[0].text = COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
827 lstrcpyW (self->parts[0].text, (LPCWSTR)lpCreate->lpszName);
831 if (lpCreate->lpszName &&
832 (len = lstrlenA ((LPCSTR)lpCreate->lpszName))) {
833 self->parts[0].text = COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
834 lstrcpyAtoW (self->parts[0].text, (LPCSTR)lpCreate->lpszName);
838 if ((hdc = GetDC (0))) {
842 hOldFont = SelectObject (hdc,self->hDefaultFont);
843 GetTextMetricsA(hdc, &tm);
844 self->textHeight = tm.tmHeight;
845 SelectObject (hdc, hOldFont);
849 if (GetWindowLongA (hwnd, GWL_STYLE) & SBT_TOOLTIPS) {
851 CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
852 CW_USEDEFAULT, CW_USEDEFAULT,
853 CW_USEDEFAULT, CW_USEDEFAULT,
855 GetWindowLongA (hwnd, GWL_HINSTANCE), NULL);
857 if (self->hwndToolTip) {
858 NMTOOLTIPSCREATED nmttc;
860 nmttc.hdr.hwndFrom = hwnd;
861 nmttc.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
862 nmttc.hdr.code = NM_TOOLTIPSCREATED;
863 nmttc.hwndToolTips = self->hwndToolTip;
865 SendMessageA (GetParent (hwnd), WM_NOTIFY,
866 (WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc);
870 GetClientRect (GetParent (hwnd), &rect);
871 width = rect.right - rect.left;
872 self->height = self->textHeight + 4 + VERT_BORDER;
873 MoveWindow (hwnd, lpCreate->x, lpCreate->y-1,
874 width, self->height, FALSE);
875 STATUSBAR_SetPartBounds (hwnd);
882 STATUSBAR_WMDestroy (HWND hwnd)
884 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
887 for (i = 0; i < self->numParts; i++) {
888 if (self->parts[i].text && !(self->parts[i].style & SBT_OWNERDRAW))
889 COMCTL32_Free (self->parts[i].text);
891 if (self->part0.text && !(self->part0.style & SBT_OWNERDRAW))
892 COMCTL32_Free (self->part0.text);
893 COMCTL32_Free (self->parts);
895 /* delete default font */
896 if (self->hDefaultFont)
897 DeleteObject (self->hDefaultFont);
899 /* delete tool tip control */
900 if (self->hwndToolTip)
901 DestroyWindow (self->hwndToolTip);
903 COMCTL32_Free (self);
904 SetWindowLongA(hwnd, 0, 0);
909 static inline LRESULT
910 STATUSBAR_WMGetFont (HWND hwnd)
912 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
913 return infoPtr->hFont;
918 STATUSBAR_WMGetText (HWND hwnd, WPARAM wParam, LPARAM lParam)
920 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
923 if (!(infoPtr->parts[0].text))
925 len = lstrlenW (infoPtr->parts[0].text);
927 if (infoPtr->bUnicode)
928 lstrcpyW ((LPWSTR)lParam, infoPtr->parts[0].text);
930 lstrcpyWtoA ((LPSTR)lParam, infoPtr->parts[0].text);
938 inline static LRESULT
939 STATUSBAR_WMMouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
941 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
943 if (infoPtr->hwndToolTip)
944 STATUSBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
945 WM_MOUSEMOVE, wParam, lParam);
951 STATUSBAR_WMNCHitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
953 if (GetWindowLongA (hwnd, GWL_STYLE) & SBARS_SIZEGRIP) {
957 GetClientRect (hwnd, &rect);
959 pt.x = (INT)LOWORD(lParam);
960 pt.y = (INT)HIWORD(lParam);
961 ScreenToClient (hwnd, &pt);
963 rect.left = rect.right - 13;
966 if (PtInRect (&rect, pt))
967 return HTBOTTOMRIGHT;
970 return DefWindowProcA (hwnd, WM_NCHITTEST, wParam, lParam);
974 static inline LRESULT
975 STATUSBAR_WMNCLButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
977 PostMessageA (GetParent (hwnd), WM_NCLBUTTONDOWN, wParam, lParam);
982 static inline LRESULT
983 STATUSBAR_WMNCLButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
985 PostMessageA (GetParent (hwnd), WM_NCLBUTTONUP, wParam, lParam);
991 STATUSBAR_WMPaint (HWND hwnd, WPARAM wParam)
996 hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
997 STATUSBAR_Refresh (hwnd, hdc);
999 EndPaint (hwnd, &ps);
1006 STATUSBAR_WMSetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
1008 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1010 infoPtr->hFont = (HFONT)wParam;
1011 if (LOWORD(lParam) == TRUE)
1012 RedrawWindow(hwnd,(RECT*)NULL,(HRGN)NULL,
1013 RDW_INVALIDATE|RDW_UPDATENOW);
1020 STATUSBAR_WMSetText (HWND hwnd, WPARAM wParam, LPARAM lParam)
1022 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1023 STATUSWINDOWPART *part;
1026 if (infoPtr->numParts == 0)
1029 part = &infoPtr->parts[0];
1030 /* duplicate string */
1032 COMCTL32_Free (part->text);
1034 if (infoPtr->bUnicode) {
1035 if (lParam && (len = lstrlenW((LPCWSTR)lParam))) {
1036 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1037 lstrcpyW (part->text, (LPCWSTR)lParam);
1041 if (lParam && (len = lstrlenA((LPCSTR)lParam))) {
1042 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1043 lstrcpyAtoW (part->text, (LPCSTR)lParam);
1047 RedrawWindow(hwnd,&part->bound,(HRGN)NULL,RDW_INVALIDATE|RDW_UPDATENOW);
1054 STATUSBAR_WMSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1056 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1057 INT width, x, y, flags;
1061 /* Need to resize width to match parent */
1062 flags = (INT) wParam;
1064 /* FIXME for flags =
1065 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED, SIZE_RESTORED
1068 if (flags == SIZE_RESTORED) {
1069 /* width and height don't apply */
1070 parent = GetParent (hwnd);
1071 GetClientRect (parent, &parent_rect);
1072 width = parent_rect.right - parent_rect.left;
1073 x = parent_rect.left;
1074 y = parent_rect.bottom - infoPtr->height;
1075 MoveWindow (hwnd, parent_rect.left,
1076 parent_rect.bottom - infoPtr->height,
1077 width, infoPtr->height, TRUE);
1078 STATUSBAR_SetPartBounds (hwnd);
1085 STATUSBAR_SendNotify (HWND hwnd, UINT code)
1089 nmhdr.hwndFrom = hwnd;
1090 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1092 SendMessageA (GetParent (hwnd), WM_NOTIFY, 0, (LPARAM)&nmhdr);
1098 static LRESULT WINAPI
1099 StatusWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
1101 TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hwnd, msg, wParam, lParam);
1102 if (!(STATUSBAR_GetInfoPtr(hwnd)) && (msg != WM_CREATE))
1103 return DefWindowProcA (hwnd, msg, wParam, lParam);
1107 return STATUSBAR_GetBorders (lParam);
1110 return STATUSBAR_GetIcon (hwnd, wParam);
1113 return STATUSBAR_GetParts (hwnd, wParam, lParam);
1116 return STATUSBAR_GetRect (hwnd, wParam, lParam);
1119 return STATUSBAR_GetTextA (hwnd, wParam, lParam);
1122 return STATUSBAR_GetTextW (hwnd, wParam, lParam);
1124 case SB_GETTEXTLENGTHA:
1125 case SB_GETTEXTLENGTHW:
1126 return STATUSBAR_GetTextLength (hwnd, wParam);
1128 case SB_GETTIPTEXTA:
1129 return STATUSBAR_GetTipTextA (hwnd, wParam, lParam);
1131 case SB_GETTIPTEXTW:
1132 return STATUSBAR_GetTipTextW (hwnd, wParam, lParam);
1134 case SB_GETUNICODEFORMAT:
1135 return STATUSBAR_GetUnicodeFormat (hwnd);
1138 return STATUSBAR_IsSimple (hwnd);
1141 return STATUSBAR_SetBkColor (hwnd, wParam, lParam);
1144 return STATUSBAR_SetIcon (hwnd, wParam, lParam);
1146 case SB_SETMINHEIGHT:
1147 return STATUSBAR_SetMinHeight (hwnd, wParam, lParam);
1150 return STATUSBAR_SetParts (hwnd, wParam, lParam);
1153 return STATUSBAR_SetTextA (hwnd, wParam, lParam);
1156 return STATUSBAR_SetTextW (hwnd, wParam, lParam);
1158 case SB_SETTIPTEXTA:
1159 return STATUSBAR_SetTipTextA (hwnd, wParam, lParam);
1161 case SB_SETTIPTEXTW:
1162 return STATUSBAR_SetTipTextW (hwnd, wParam, lParam);
1164 case SB_SETUNICODEFORMAT:
1165 return STATUSBAR_SetUnicodeFormat (hwnd, wParam);
1168 return STATUSBAR_Simple (hwnd, wParam, lParam);
1172 return STATUSBAR_WMCreate (hwnd, wParam, lParam);
1175 return STATUSBAR_WMDestroy (hwnd);
1178 return STATUSBAR_WMGetFont (hwnd);
1181 return STATUSBAR_WMGetText (hwnd, wParam, lParam);
1183 case WM_GETTEXTLENGTH:
1184 return STATUSBAR_GetTextLength (hwnd, 0);
1186 case WM_LBUTTONDBLCLK:
1187 return STATUSBAR_SendNotify (hwnd, NM_DBLCLK);
1190 return STATUSBAR_SendNotify (hwnd, NM_CLICK);
1193 return STATUSBAR_WMMouseMove (hwnd, wParam, lParam);
1196 return STATUSBAR_WMNCHitTest (hwnd, wParam, lParam);
1198 case WM_NCLBUTTONDOWN:
1199 return STATUSBAR_WMNCLButtonDown (hwnd, wParam, lParam);
1201 case WM_NCLBUTTONUP:
1202 return STATUSBAR_WMNCLButtonUp (hwnd, wParam, lParam);
1205 return STATUSBAR_WMPaint (hwnd, wParam);
1207 case WM_RBUTTONDBLCLK:
1208 return STATUSBAR_SendNotify (hwnd, NM_RDBLCLK);
1211 return STATUSBAR_SendNotify (hwnd, NM_RCLICK);
1214 return STATUSBAR_WMSetFont (hwnd, wParam, lParam);
1217 return STATUSBAR_WMSetText (hwnd, wParam, lParam);
1220 return STATUSBAR_WMSize (hwnd, wParam, lParam);
1224 ERR("unknown msg %04x wp=%04x lp=%08lx\n",
1225 msg, wParam, lParam);
1226 return DefWindowProcA (hwnd, msg, wParam, lParam);
1232 /***********************************************************************
1233 * STATUS_Register [Internal]
1235 * Registers the status window class.
1239 STATUS_Register (void)
1243 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
1244 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW;
1245 wndClass.lpfnWndProc = (WNDPROC)StatusWindowProc;
1246 wndClass.cbClsExtra = 0;
1247 wndClass.cbWndExtra = sizeof(STATUSWINDOWINFO *);
1248 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
1249 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
1250 wndClass.lpszClassName = STATUSCLASSNAMEA;
1252 RegisterClassA (&wndClass);
1256 /***********************************************************************
1257 * STATUS_Unregister [Internal]
1259 * Unregisters the status window class.
1263 STATUS_Unregister (void)
1265 UnregisterClassA (STATUSCLASSNAMEA, (HINSTANCE)NULL);