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).
14 #include "wine/unicode.h"
16 #include "debugtools.h"
18 DEFAULT_DEBUG_CHANNEL(statusbar);
38 COLORREF clrBk; /* background color */
39 BOOL bUnicode; /* unicode flag */
40 STATUSWINDOWPART part0; /* simple window */
41 STATUSWINDOWPART *parts;
45 * Run tests using Waite Group Windows95 API Bible Vol. 1&2
46 * The second cdrom contains executables drawstat.exe,gettext.exe,
47 * simple.exe, getparts.exe, setparts.exe, statwnd.exe
51 #define _MAX(a,b) (((a)>(b))?(a):(b))
52 #define _MIN(a,b) (((a)>(b))?(b):(a))
58 #define STATUSBAR_GetInfoPtr(hwnd) ((STATUSWINDOWINFO *)GetWindowLongA (hwnd, 0))
62 STATUSBAR_SetPartBounds (HWND hwnd);
65 STATUSBAR_DrawSizeGrip (HDC hdc, LPRECT lpRect)
71 pt.x = lpRect->right - 1;
72 pt.y = lpRect->bottom - 1;
74 hOldPen = SelectObject (hdc, GetSysColorPen (COLOR_3DFACE));
75 MoveToEx (hdc, pt.x - 12, pt.y, NULL);
76 LineTo (hdc, pt.x, pt.y);
77 LineTo (hdc, pt.x, pt.y - 12);
82 SelectObject (hdc, GetSysColorPen (COLOR_3DSHADOW));
83 for (i = 1; i < 11; i += 4) {
84 MoveToEx (hdc, pt.x - i, pt.y, NULL);
85 LineTo (hdc, pt.x, pt.y - i);
87 MoveToEx (hdc, pt.x - i-1, pt.y, NULL);
88 LineTo (hdc, pt.x, pt.y - i-1);
91 SelectObject (hdc, GetSysColorPen (COLOR_3DHIGHLIGHT));
92 for (i = 3; i < 13; i += 4) {
93 MoveToEx (hdc, pt.x - i, pt.y, NULL);
94 LineTo (hdc, pt.x, pt.y - i);
97 SelectObject (hdc, hOldPen);
102 STATUSBAR_DrawPart (HDC hdc, STATUSWINDOWPART *part)
104 RECT r = part->bound;
105 UINT border = BDR_SUNKENOUTER;
107 if (part->style & SBT_POPOUT)
108 border = BDR_RAISEDOUTER;
109 else if (part->style & SBT_NOBORDERS)
112 DrawEdge(hdc, &r, border, BF_RECT|BF_ADJUST);
116 INT cy = r.bottom - r.top;
119 DrawIconEx (hdc, r.left, r.top, part->hIcon, cy, cy, 0, 0, DI_NORMAL);
125 int oldbkmode = SetBkMode(hdc, TRANSPARENT);
126 LPWSTR p = (LPWSTR)part->text;
127 UINT align = DT_LEFT;
138 DrawTextW (hdc, p, lstrlenW (p), &r, align|DT_VCENTER|DT_SINGLELINE);
139 if (oldbkmode != TRANSPARENT)
140 SetBkMode(hdc, oldbkmode);
146 STATUSBAR_RefreshPart (HWND hwnd, STATUSWINDOWPART *part, HDC hdc, int itemID)
148 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
152 if (!IsWindowVisible (hwnd))
155 if (part->bound.right < part->bound.left) return;
157 if (self->clrBk != CLR_DEFAULT)
158 hbrBk = CreateSolidBrush (self->clrBk);
160 hbrBk = GetSysColorBrush (COLOR_3DFACE);
161 FillRect(hdc, &part->bound, hbrBk);
163 hOldFont = SelectObject (hdc, self->hFont ? self->hFont : self->hDefaultFont);
165 if (part->style & SBT_OWNERDRAW) {
168 dis.CtlID = GetWindowLongA (hwnd, GWL_ID);
172 dis.rcItem = part->bound;
173 dis.itemData = (INT)part->text;
174 SendMessageA (GetParent (hwnd), WM_DRAWITEM,
175 (WPARAM)dis.CtlID, (LPARAM)&dis);
177 STATUSBAR_DrawPart (hdc, part);
179 SelectObject (hdc, hOldFont);
181 if (self->clrBk != CLR_DEFAULT)
182 DeleteObject (hbrBk);
184 if (GetWindowLongA (hwnd, GWL_STYLE) & SBARS_SIZEGRIP) {
187 GetClientRect (hwnd, &rect);
188 STATUSBAR_DrawSizeGrip (hdc, &rect);
194 STATUSBAR_Refresh (HWND hwnd, HDC hdc)
196 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
202 if (!IsWindowVisible(hwnd))
205 STATUSBAR_SetPartBounds(hwnd);
207 GetClientRect (hwnd, &rect);
209 if (infoPtr->clrBk != CLR_DEFAULT)
210 hbrBk = CreateSolidBrush (infoPtr->clrBk);
212 hbrBk = GetSysColorBrush (COLOR_3DFACE);
213 FillRect(hdc, &rect, hbrBk);
215 hOldFont = SelectObject (hdc, infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont);
217 if (infoPtr->simple) {
218 STATUSBAR_RefreshPart (hwnd, &infoPtr->part0, hdc, 0);
220 for (i = 0; i < infoPtr->numParts; i++) {
221 if (infoPtr->parts[i].style & SBT_OWNERDRAW) {
224 dis.CtlID = GetWindowLongA (hwnd, GWL_ID);
228 dis.rcItem = infoPtr->parts[i].bound;
229 dis.itemData = (INT)infoPtr->parts[i].text;
230 SendMessageA (GetParent (hwnd), WM_DRAWITEM,
231 (WPARAM)dis.CtlID, (LPARAM)&dis);
233 STATUSBAR_RefreshPart (hwnd, &infoPtr->parts[i], hdc, i);
237 SelectObject (hdc, hOldFont);
239 if (infoPtr->clrBk != CLR_DEFAULT)
240 DeleteObject (hbrBk);
242 if (GetWindowLongA(hwnd, GWL_STYLE) & SBARS_SIZEGRIP)
243 STATUSBAR_DrawSizeGrip (hdc, &rect);
250 STATUSBAR_SetPartBounds (HWND hwnd)
252 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
253 STATUSWINDOWPART *part;
257 /* get our window size */
258 GetClientRect (hwnd, &rect);
260 rect.top += VERT_BORDER;
262 /* set bounds for simple rectangle */
263 self->part0.bound = rect;
265 /* set bounds for non-simple rectangles */
266 for (i = 0; i < self->numParts; i++) {
267 part = &self->parts[i];
268 r = &self->parts[i].bound;
270 r->bottom = rect.bottom;
274 r->left = self->parts[i-1].bound.right + HORZ_GAP;
276 r->right = rect.right;
280 if (self->hwndToolTip) {
283 ti.cbSize = sizeof(TTTOOLINFOA);
287 SendMessageA (self->hwndToolTip, TTM_NEWTOOLRECTA,
295 STATUSBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
296 WPARAM wParam, LPARAM lParam)
304 msg.time = GetMessageTime ();
305 msg.pt.x = LOWORD(GetMessagePos ());
306 msg.pt.y = HIWORD(GetMessagePos ());
308 SendMessageA (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
312 inline static LRESULT
313 STATUSBAR_GetBorders (LPARAM lParam)
315 LPINT out = (LPINT) lParam;
317 out[0] = HORZ_BORDER; /* horizontal border width */
318 out[1] = VERT_BORDER; /* vertical border width */
319 out[2] = HORZ_GAP; /* width of border between rectangles */
326 STATUSBAR_GetIcon (HWND hwnd, WPARAM wParam)
328 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
331 nPart = (INT)wParam & 0x00ff;
332 if ((nPart < -1) || (nPart >= self->numParts))
336 return (self->part0.hIcon);
338 return (self->parts[nPart].hIcon);
343 STATUSBAR_GetParts (HWND hwnd, WPARAM wParam, LPARAM lParam)
345 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
350 num_parts = (INT) wParam;
351 parts = (LPINT) lParam;
353 for (i = 0; i < num_parts; i++) {
354 parts[i] = infoPtr->parts[i].x;
357 return (infoPtr->numParts);
362 STATUSBAR_GetRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
364 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
368 part_num = ((INT) wParam) & 0x00ff;
369 rect = (LPRECT) lParam;
371 *rect = infoPtr->part0.bound;
373 *rect = infoPtr->parts[part_num].bound;
379 STATUSBAR_GetTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
381 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
382 STATUSWINDOWPART *part;
386 nPart = ((INT) wParam) & 0x00ff;
390 part = &self->parts[nPart];
392 if (part->style & SBT_OWNERDRAW)
393 result = (LRESULT)part->text;
395 result = part->text ? lstrlenW (part->text) : 0;
396 result |= (part->style << 16);
397 if (lParam && LOWORD(result))
398 lstrcpyWtoA ((LPSTR)lParam, part->text);
405 STATUSBAR_GetTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
407 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
408 STATUSWINDOWPART *part;
412 nPart = ((INT)wParam) & 0x00ff;
414 part = &infoPtr->part0;
416 part = &infoPtr->parts[nPart];
418 if (part->style & SBT_OWNERDRAW)
419 result = (LRESULT)part->text;
421 result = part->text ? lstrlenW (part->text) : 0;
422 result |= (part->style << 16);
423 if (part->text && lParam)
424 strcpyW ((LPWSTR)lParam, part->text);
431 STATUSBAR_GetTextLength (HWND hwnd, WPARAM wParam)
433 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
434 STATUSWINDOWPART *part;
438 part_num = ((INT) wParam) & 0x00ff;
441 part = &infoPtr->part0;
443 part = &infoPtr->parts[part_num];
446 result = lstrlenW(part->text);
450 result |= (part->style << 16);
456 STATUSBAR_GetTipTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
458 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
460 if (infoPtr->hwndToolTip) {
462 ti.cbSize = sizeof(TTTOOLINFOA);
464 ti.uId = LOWORD(wParam);
465 SendMessageA (infoPtr->hwndToolTip, TTM_GETTEXTA, 0, (LPARAM)&ti);
468 lstrcpynA ((LPSTR)lParam, ti.lpszText, HIWORD(wParam));
476 STATUSBAR_GetTipTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
478 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
480 if (infoPtr->hwndToolTip) {
482 ti.cbSize = sizeof(TTTOOLINFOW);
484 ti.uId = LOWORD(wParam);
485 SendMessageW (infoPtr->hwndToolTip, TTM_GETTEXTW, 0, (LPARAM)&ti);
488 lstrcpynW ((LPWSTR)lParam, ti.lpszText, HIWORD(wParam));
495 inline static LRESULT
496 STATUSBAR_GetUnicodeFormat (HWND hwnd)
498 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
499 return infoPtr->bUnicode;
503 inline static LRESULT
504 STATUSBAR_IsSimple (HWND hwnd)
506 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
507 return infoPtr->simple;
512 STATUSBAR_SetBkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
514 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
517 oldBkColor = self->clrBk;
518 self->clrBk = (COLORREF)lParam;
519 InvalidateRect(hwnd, NULL, FALSE);
526 STATUSBAR_SetIcon (HWND hwnd, WPARAM wParam, LPARAM lParam)
528 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
529 INT nPart = (INT)wParam & 0x00ff;
531 if ((nPart < -1) || (nPart >= self->numParts))
534 TRACE("setting part %d, icon %lx\n",nPart,lParam);
537 if (self->part0.hIcon == (HICON)lParam) /* same as - no redraw */
539 self->part0.hIcon = (HICON)lParam;
541 InvalidateRect(hwnd, &self->part0.bound, FALSE);
543 if (self->parts[nPart].hIcon == (HICON)lParam) /* same as - no redraw */
546 self->parts[nPart].hIcon = (HICON)lParam;
548 InvalidateRect(hwnd, &self->parts[nPart].bound, FALSE);
555 STATUSBAR_SetMinHeight (HWND hwnd, WPARAM wParam, LPARAM lParam)
557 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
559 if (IsWindowVisible (hwnd)) {
560 HWND parent = GetParent (hwnd);
564 GetClientRect (parent, &parent_rect);
565 self->height = (INT)wParam + VERT_BORDER;
566 width = parent_rect.right - parent_rect.left;
567 x = parent_rect.left;
568 y = parent_rect.bottom - self->height;
569 MoveWindow (hwnd, parent_rect.left,
570 parent_rect.bottom - self->height,
571 width, self->height, TRUE);
572 STATUSBAR_SetPartBounds (hwnd);
580 STATUSBAR_SetParts (HWND hwnd, WPARAM wParam, LPARAM lParam)
582 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
583 STATUSWINDOWPART *tmp;
588 TRACE("(%d,%p)\n",wParam,(LPVOID)lParam);
591 self->simple = FALSE;
593 oldNumParts = self->numParts;
594 self->numParts = (INT) wParam;
595 parts = (LPINT) lParam;
596 if (oldNumParts > self->numParts) {
597 for (i = self->numParts ; i < oldNumParts; i++) {
598 if (self->parts[i].text && !(self->parts[i].style & SBT_OWNERDRAW))
599 COMCTL32_Free (self->parts[i].text);
602 if (oldNumParts < self->numParts) {
603 tmp = COMCTL32_Alloc (sizeof(STATUSWINDOWPART) * self->numParts);
604 for (i = 0; i < oldNumParts; i++) {
605 tmp[i] = self->parts[i];
608 COMCTL32_Free (self->parts);
611 if (oldNumParts == self->numParts) {
612 for (i=0;i<oldNumParts;i++)
613 if (self->parts[i].x != parts[i])
615 if (i==oldNumParts) /* Unchanged? no need to redraw! */
619 for (i = 0; i < self->numParts; i++)
620 self->parts[i].x = parts[i];
622 if (self->hwndToolTip) {
624 SendMessageA (self->hwndToolTip, TTM_GETTOOLCOUNT, 0, 0);
626 if (nTipCount < self->numParts) {
631 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
632 ti.cbSize = sizeof(TTTOOLINFOA);
634 for (i = nTipCount; i < self->numParts; i++) {
635 TRACE("add tool %d\n", i);
637 SendMessageA (self->hwndToolTip, TTM_ADDTOOLA,
641 else if (nTipCount > self->numParts) {
645 for (i = nTipCount - 1; i >= self->numParts; i--) {
646 FIXME("delete tool %d\n", i);
650 STATUSBAR_SetPartBounds (hwnd);
651 InvalidateRect(hwnd, NULL, FALSE);
657 STATUSBAR_SetTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
659 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
660 STATUSWINDOWPART *part=NULL;
664 BOOL changed = FALSE;
666 text = (LPSTR) lParam;
667 part_num = ((INT) wParam) & 0x00ff;
668 style = ((INT) wParam) & 0xff00;
670 TRACE("setting part %d, text %s\n",part_num,debugstr_a(text));
674 else if (!self->simple && self->parts!=NULL)
675 part = &self->parts[part_num];
676 if (!part) return FALSE;
678 if (part->style != style)
682 if (style & SBT_OWNERDRAW) {
683 if (part->text == (LPWSTR)text)
685 part->text = (LPWSTR)text;
689 /* check if text is unchanged -> no need to redraw */
691 LPWSTR tmptext = COMCTL32_Alloc((lstrlenA(text)+1)*sizeof(WCHAR));
692 lstrcpyAtoW (tmptext, text);
694 if (!changed && part->text && !lstrcmpW(tmptext,part->text)) {
695 COMCTL32_Free(tmptext);
700 if (!changed && !part->text)
706 COMCTL32_Free (part->text);
709 InvalidateRect(hwnd, &part->bound, FALSE);
716 STATUSBAR_SetTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
718 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
719 STATUSWINDOWPART *part;
720 INT part_num, style, len;
722 BOOL bRedraw = FALSE;
724 text = (LPWSTR) lParam;
725 part_num = ((INT) wParam) & 0x00ff;
726 style = ((INT) wParam) & 0xff00;
728 if ((self->simple) || (self->parts==NULL) || (part_num==255))
731 part = &self->parts[part_num];
732 if (!part) return FALSE;
734 if(part->style != style)
739 /* FIXME: not sure how/if we can check for change in string with ownerdraw(remove this if we can't)... */
740 if (style & SBT_OWNERDRAW)
748 COMCTL32_Free(part->text);
752 } else if(!part->text || strcmpW(part->text, text)) /* see if the new string differs from the existing string */
754 if(part->text) COMCTL32_Free(part->text);
756 len = lstrlenW(text);
757 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
758 strcpyW(part->text, text);
763 InvalidateRect(hwnd, &part->bound, FALSE);
770 STATUSBAR_SetTipTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
772 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
774 TRACE("part %d: \"%s\"\n", (INT)wParam, (LPSTR)lParam);
775 if (infoPtr->hwndToolTip) {
777 ti.cbSize = sizeof(TTTOOLINFOA);
779 ti.uId = (INT)wParam;
781 ti.lpszText = (LPSTR)lParam;
782 SendMessageA (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTA,
791 STATUSBAR_SetTipTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
793 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
795 TRACE("part %d: \"%s\"\n", (INT)wParam, (LPSTR)lParam);
796 if (infoPtr->hwndToolTip) {
798 ti.cbSize = sizeof(TTTOOLINFOW);
800 ti.uId = (INT)wParam;
802 ti.lpszText = (LPWSTR)lParam;
803 SendMessageW (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTW,
811 inline static LRESULT
812 STATUSBAR_SetUnicodeFormat (HWND hwnd, WPARAM wParam)
814 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
815 BOOL bTemp = infoPtr->bUnicode;
817 TRACE("(0x%x)\n", (BOOL)wParam);
818 infoPtr->bUnicode = (BOOL)wParam;
825 STATUSBAR_Simple (HWND hwnd, WPARAM wParam, LPARAM lParam)
827 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
830 if (infoPtr->simple == wParam) /* no need to change */
833 infoPtr->simple = (BOOL)wParam;
835 /* send notification */
836 nmhdr.hwndFrom = hwnd;
837 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
838 nmhdr.code = SBN_SIMPLEMODECHANGE;
839 SendMessageA (GetParent (hwnd), WM_NOTIFY, 0, (LPARAM)&nmhdr);
840 InvalidateRect(hwnd, NULL, FALSE);
846 STATUSBAR_WMCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
848 LPCREATESTRUCTA lpCreate = (LPCREATESTRUCTA)lParam;
849 NONCLIENTMETRICSA nclm;
853 STATUSWINDOWINFO *self;
855 self = (STATUSWINDOWINFO*)COMCTL32_Alloc (sizeof(STATUSWINDOWINFO));
856 SetWindowLongA (hwnd, 0, (DWORD)self);
860 self->simple = FALSE;
861 self->clrBk = CLR_DEFAULT;
863 GetClientRect (hwnd, &rect);
865 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
866 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
867 self->hDefaultFont = CreateFontIndirectA (&nclm.lfStatusFont);
869 /* initialize simple case */
870 self->part0.bound = rect;
871 self->part0.text = 0;
873 self->part0.style = 0;
874 self->part0.hIcon = 0;
876 /* initialize first part */
877 self->parts = COMCTL32_Alloc (sizeof(STATUSWINDOWPART));
878 self->parts[0].bound = rect;
879 self->parts[0].text = 0;
880 self->parts[0].x = -1;
881 self->parts[0].style = 0;
882 self->parts[0].hIcon = 0;
884 if (IsWindowUnicode (hwnd)) {
885 self->bUnicode = TRUE;
886 if (lpCreate->lpszName &&
887 (len = lstrlenW ((LPCWSTR)lpCreate->lpszName))) {
888 self->parts[0].text = COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
889 strcpyW (self->parts[0].text, (LPCWSTR)lpCreate->lpszName);
893 if (lpCreate->lpszName &&
894 (len = lstrlenA ((LPCSTR)lpCreate->lpszName))) {
895 self->parts[0].text = COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
896 lstrcpyAtoW (self->parts[0].text, (LPCSTR)lpCreate->lpszName);
900 if ((hdc = GetDC (0))) {
904 hOldFont = SelectObject (hdc,self->hDefaultFont);
905 GetTextMetricsA(hdc, &tm);
906 self->textHeight = tm.tmHeight;
907 SelectObject (hdc, hOldFont);
911 if (GetWindowLongA (hwnd, GWL_STYLE) & SBT_TOOLTIPS) {
913 CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
914 CW_USEDEFAULT, CW_USEDEFAULT,
915 CW_USEDEFAULT, CW_USEDEFAULT,
917 GetWindowLongA (hwnd, GWL_HINSTANCE), NULL);
919 if (self->hwndToolTip) {
920 NMTOOLTIPSCREATED nmttc;
922 nmttc.hdr.hwndFrom = hwnd;
923 nmttc.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
924 nmttc.hdr.code = NM_TOOLTIPSCREATED;
925 nmttc.hwndToolTips = self->hwndToolTip;
927 SendMessageA (GetParent (hwnd), WM_NOTIFY,
928 (WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc);
932 GetClientRect (GetParent (hwnd), &rect);
933 width = rect.right - rect.left;
934 self->height = self->textHeight + 4 + VERT_BORDER;
935 MoveWindow (hwnd, lpCreate->x, lpCreate->y - 1,
936 width, self->height, FALSE);
937 STATUSBAR_SetPartBounds (hwnd);
944 STATUSBAR_WMDestroy (HWND hwnd)
946 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
949 for (i = 0; i < self->numParts; i++) {
950 if (self->parts[i].text && !(self->parts[i].style & SBT_OWNERDRAW))
951 COMCTL32_Free (self->parts[i].text);
953 if (self->part0.text && !(self->part0.style & SBT_OWNERDRAW))
954 COMCTL32_Free (self->part0.text);
955 COMCTL32_Free (self->parts);
957 /* delete default font */
958 if (self->hDefaultFont)
959 DeleteObject (self->hDefaultFont);
961 /* delete tool tip control */
962 if (self->hwndToolTip)
963 DestroyWindow (self->hwndToolTip);
965 COMCTL32_Free (self);
966 SetWindowLongA(hwnd, 0, 0);
971 static inline LRESULT
972 STATUSBAR_WMGetFont (HWND hwnd)
974 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
975 return infoPtr->hFont? infoPtr->hFont : infoPtr->hDefaultFont;
980 STATUSBAR_WMGetText (HWND hwnd, WPARAM wParam, LPARAM lParam)
982 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
985 if (!(infoPtr->parts[0].text))
987 len = lstrlenW (infoPtr->parts[0].text);
989 if (infoPtr->bUnicode)
990 strcpyW ((LPWSTR)lParam, infoPtr->parts[0].text);
992 lstrcpyWtoA ((LPSTR)lParam, infoPtr->parts[0].text);
1000 inline static LRESULT
1001 STATUSBAR_WMMouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
1003 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1005 if (infoPtr->hwndToolTip)
1006 STATUSBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
1007 WM_MOUSEMOVE, wParam, lParam);
1013 STATUSBAR_WMNCHitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
1015 if (GetWindowLongA (hwnd, GWL_STYLE) & SBARS_SIZEGRIP) {
1019 GetClientRect (hwnd, &rect);
1021 pt.x = (INT)LOWORD(lParam);
1022 pt.y = (INT)HIWORD(lParam);
1023 ScreenToClient (hwnd, &pt);
1025 rect.left = rect.right - 13;
1028 if (PtInRect (&rect, pt))
1029 return HTBOTTOMRIGHT;
1032 return DefWindowProcA (hwnd, WM_NCHITTEST, wParam, lParam);
1036 static inline LRESULT
1037 STATUSBAR_WMNCLButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
1039 PostMessageA (GetParent (hwnd), WM_NCLBUTTONDOWN, wParam, lParam);
1044 static inline LRESULT
1045 STATUSBAR_WMNCLButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
1047 PostMessageA (GetParent (hwnd), WM_NCLBUTTONUP, wParam, lParam);
1053 STATUSBAR_WMPaint (HWND hwnd, WPARAM wParam)
1058 hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
1059 STATUSBAR_Refresh (hwnd, hdc);
1061 EndPaint (hwnd, &ps);
1068 STATUSBAR_WMSetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
1070 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1072 infoPtr->hFont = (HFONT)wParam;
1073 if (LOWORD(lParam) == TRUE)
1074 InvalidateRect(hwnd, NULL, FALSE);
1081 STATUSBAR_WMSetText (HWND hwnd, WPARAM wParam, LPARAM lParam)
1083 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1084 STATUSWINDOWPART *part;
1087 if (infoPtr->numParts == 0)
1090 part = &infoPtr->parts[0];
1091 /* duplicate string */
1093 COMCTL32_Free (part->text);
1095 if (infoPtr->bUnicode) {
1096 if (lParam && (len = lstrlenW((LPCWSTR)lParam))) {
1097 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1098 strcpyW (part->text, (LPCWSTR)lParam);
1102 if (lParam && (len = lstrlenA((LPCSTR)lParam))) {
1103 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1104 lstrcpyAtoW (part->text, (LPCSTR)lParam);
1108 InvalidateRect(hwnd, &part->bound, FALSE);
1115 STATUSBAR_WMSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1117 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1118 INT width, x, y, flags;
1122 /* Need to resize width to match parent */
1123 flags = (INT) wParam;
1125 /* FIXME for flags =
1126 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED, SIZE_RESTORED
1129 if (flags == SIZE_RESTORED) {
1130 /* width and height don't apply */
1131 parent = GetParent (hwnd);
1132 GetClientRect (parent, &parent_rect);
1133 width = parent_rect.right - parent_rect.left;
1134 x = parent_rect.left;
1135 y = parent_rect.bottom - infoPtr->height;
1136 MoveWindow (hwnd, parent_rect.left,
1137 parent_rect.bottom - infoPtr->height,
1138 width, infoPtr->height, TRUE);
1139 STATUSBAR_SetPartBounds (hwnd);
1146 STATUSBAR_SendNotify (HWND hwnd, UINT code)
1150 nmhdr.hwndFrom = hwnd;
1151 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1153 SendMessageA (GetParent (hwnd), WM_NOTIFY, 0, (LPARAM)&nmhdr);
1159 static LRESULT WINAPI
1160 StatusWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
1162 TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hwnd, msg, wParam, lParam);
1163 if (!(STATUSBAR_GetInfoPtr(hwnd)) && (msg != WM_CREATE))
1164 return DefWindowProcA (hwnd, msg, wParam, lParam);
1168 return STATUSBAR_GetBorders (lParam);
1171 return STATUSBAR_GetIcon (hwnd, wParam);
1174 return STATUSBAR_GetParts (hwnd, wParam, lParam);
1177 return STATUSBAR_GetRect (hwnd, wParam, lParam);
1180 return STATUSBAR_GetTextA (hwnd, wParam, lParam);
1183 return STATUSBAR_GetTextW (hwnd, wParam, lParam);
1185 case SB_GETTEXTLENGTHA:
1186 case SB_GETTEXTLENGTHW:
1187 return STATUSBAR_GetTextLength (hwnd, wParam);
1189 case SB_GETTIPTEXTA:
1190 return STATUSBAR_GetTipTextA (hwnd, wParam, lParam);
1192 case SB_GETTIPTEXTW:
1193 return STATUSBAR_GetTipTextW (hwnd, wParam, lParam);
1195 case SB_GETUNICODEFORMAT:
1196 return STATUSBAR_GetUnicodeFormat (hwnd);
1199 return STATUSBAR_IsSimple (hwnd);
1202 return STATUSBAR_SetBkColor (hwnd, wParam, lParam);
1205 return STATUSBAR_SetIcon (hwnd, wParam, lParam);
1207 case SB_SETMINHEIGHT:
1208 return STATUSBAR_SetMinHeight (hwnd, wParam, lParam);
1211 return STATUSBAR_SetParts (hwnd, wParam, lParam);
1214 return STATUSBAR_SetTextA (hwnd, wParam, lParam);
1217 return STATUSBAR_SetTextW (hwnd, wParam, lParam);
1219 case SB_SETTIPTEXTA:
1220 return STATUSBAR_SetTipTextA (hwnd, wParam, lParam);
1222 case SB_SETTIPTEXTW:
1223 return STATUSBAR_SetTipTextW (hwnd, wParam, lParam);
1225 case SB_SETUNICODEFORMAT:
1226 return STATUSBAR_SetUnicodeFormat (hwnd, wParam);
1229 return STATUSBAR_Simple (hwnd, wParam, lParam);
1233 return STATUSBAR_WMCreate (hwnd, wParam, lParam);
1236 return STATUSBAR_WMDestroy (hwnd);
1239 return STATUSBAR_WMGetFont (hwnd);
1242 return STATUSBAR_WMGetText (hwnd, wParam, lParam);
1244 case WM_GETTEXTLENGTH:
1245 return STATUSBAR_GetTextLength (hwnd, 0);
1247 case WM_LBUTTONDBLCLK:
1248 return STATUSBAR_SendNotify (hwnd, NM_DBLCLK);
1251 return STATUSBAR_SendNotify (hwnd, NM_CLICK);
1254 return STATUSBAR_WMMouseMove (hwnd, wParam, lParam);
1257 return STATUSBAR_WMNCHitTest (hwnd, wParam, lParam);
1259 case WM_NCLBUTTONDOWN:
1260 return STATUSBAR_WMNCLButtonDown (hwnd, wParam, lParam);
1262 case WM_NCLBUTTONUP:
1263 return STATUSBAR_WMNCLButtonUp (hwnd, wParam, lParam);
1266 return STATUSBAR_WMPaint (hwnd, wParam);
1268 case WM_RBUTTONDBLCLK:
1269 return STATUSBAR_SendNotify (hwnd, NM_RDBLCLK);
1272 return STATUSBAR_SendNotify (hwnd, NM_RCLICK);
1275 return STATUSBAR_WMSetFont (hwnd, wParam, lParam);
1278 return STATUSBAR_WMSetText (hwnd, wParam, lParam);
1281 return STATUSBAR_WMSize (hwnd, wParam, lParam);
1285 ERR("unknown msg %04x wp=%04x lp=%08lx\n",
1286 msg, wParam, lParam);
1287 return DefWindowProcA (hwnd, msg, wParam, lParam);
1293 /***********************************************************************
1294 * STATUS_Register [Internal]
1296 * Registers the status window class.
1300 STATUS_Register (void)
1304 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
1305 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW;
1306 wndClass.lpfnWndProc = (WNDPROC)StatusWindowProc;
1307 wndClass.cbClsExtra = 0;
1308 wndClass.cbWndExtra = sizeof(STATUSWINDOWINFO *);
1309 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
1310 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
1311 wndClass.lpszClassName = STATUSCLASSNAMEA;
1313 RegisterClassA (&wndClass);
1317 /***********************************************************************
1318 * STATUS_Unregister [Internal]
1320 * Unregisters the status window class.
1324 STATUS_Unregister (void)
1326 UnregisterClassA (STATUSCLASSNAMEA, (HINSTANCE)NULL);