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, -1, &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 DWORD len = part->text ? WideCharToMultiByte( CP_ACP, 0, part->text, -1,
396 NULL, 0, NULL, NULL ) - 1 : 0;
397 result = MAKELONG( len, part->style );
399 WideCharToMultiByte( CP_ACP, 0, part->text, -1, (LPSTR)lParam, len+1, NULL, NULL );
406 STATUSBAR_GetTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
408 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
409 STATUSWINDOWPART *part;
413 nPart = ((INT)wParam) & 0x00ff;
415 part = &infoPtr->part0;
417 part = &infoPtr->parts[nPart];
419 if (part->style & SBT_OWNERDRAW)
420 result = (LRESULT)part->text;
422 result = part->text ? strlenW (part->text) : 0;
423 result |= (part->style << 16);
424 if (part->text && lParam)
425 strcpyW ((LPWSTR)lParam, part->text);
432 STATUSBAR_GetTextLength (HWND hwnd, WPARAM wParam)
434 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
435 STATUSWINDOWPART *part;
439 part_num = ((INT) wParam) & 0x00ff;
442 part = &infoPtr->part0;
444 part = &infoPtr->parts[part_num];
447 result = strlenW(part->text);
451 result |= (part->style << 16);
457 STATUSBAR_GetTipTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
459 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
461 if (infoPtr->hwndToolTip) {
463 ti.cbSize = sizeof(TTTOOLINFOA);
465 ti.uId = LOWORD(wParam);
466 SendMessageA (infoPtr->hwndToolTip, TTM_GETTEXTA, 0, (LPARAM)&ti);
469 lstrcpynA ((LPSTR)lParam, ti.lpszText, HIWORD(wParam));
477 STATUSBAR_GetTipTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
479 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
481 if (infoPtr->hwndToolTip) {
483 ti.cbSize = sizeof(TTTOOLINFOW);
485 ti.uId = LOWORD(wParam);
486 SendMessageW (infoPtr->hwndToolTip, TTM_GETTEXTW, 0, (LPARAM)&ti);
489 lstrcpynW ((LPWSTR)lParam, ti.lpszText, HIWORD(wParam));
496 inline static LRESULT
497 STATUSBAR_GetUnicodeFormat (HWND hwnd)
499 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
500 return infoPtr->bUnicode;
504 inline static LRESULT
505 STATUSBAR_IsSimple (HWND hwnd)
507 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
508 return infoPtr->simple;
513 STATUSBAR_SetBkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
515 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
518 oldBkColor = self->clrBk;
519 self->clrBk = (COLORREF)lParam;
520 InvalidateRect(hwnd, NULL, FALSE);
527 STATUSBAR_SetIcon (HWND hwnd, WPARAM wParam, LPARAM lParam)
529 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
530 INT nPart = (INT)wParam & 0x00ff;
532 if ((nPart < -1) || (nPart >= self->numParts))
535 TRACE("setting part %d, icon %lx\n",nPart,lParam);
538 if (self->part0.hIcon == (HICON)lParam) /* same as - no redraw */
540 self->part0.hIcon = (HICON)lParam;
542 InvalidateRect(hwnd, &self->part0.bound, FALSE);
544 if (self->parts[nPart].hIcon == (HICON)lParam) /* same as - no redraw */
547 self->parts[nPart].hIcon = (HICON)lParam;
549 InvalidateRect(hwnd, &self->parts[nPart].bound, FALSE);
556 STATUSBAR_SetMinHeight (HWND hwnd, WPARAM wParam, LPARAM lParam)
558 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
560 if (IsWindowVisible (hwnd)) {
561 HWND parent = GetParent (hwnd);
565 GetClientRect (parent, &parent_rect);
566 self->height = (INT)wParam + VERT_BORDER;
567 width = parent_rect.right - parent_rect.left;
568 x = parent_rect.left;
569 y = parent_rect.bottom - self->height;
570 MoveWindow (hwnd, parent_rect.left,
571 parent_rect.bottom - self->height,
572 width, self->height, TRUE);
573 STATUSBAR_SetPartBounds (hwnd);
581 STATUSBAR_SetParts (HWND hwnd, WPARAM wParam, LPARAM lParam)
583 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
584 STATUSWINDOWPART *tmp;
589 TRACE("(%d,%p)\n",wParam,(LPVOID)lParam);
592 self->simple = FALSE;
594 oldNumParts = self->numParts;
595 self->numParts = (INT) wParam;
596 parts = (LPINT) lParam;
597 if (oldNumParts > self->numParts) {
598 for (i = self->numParts ; i < oldNumParts; i++) {
599 if (self->parts[i].text && !(self->parts[i].style & SBT_OWNERDRAW))
600 COMCTL32_Free (self->parts[i].text);
603 if (oldNumParts < self->numParts) {
604 tmp = COMCTL32_Alloc (sizeof(STATUSWINDOWPART) * self->numParts);
605 for (i = 0; i < oldNumParts; i++) {
606 tmp[i] = self->parts[i];
609 COMCTL32_Free (self->parts);
612 if (oldNumParts == self->numParts) {
613 for (i=0;i<oldNumParts;i++)
614 if (self->parts[i].x != parts[i])
616 if (i==oldNumParts) /* Unchanged? no need to redraw! */
620 for (i = 0; i < self->numParts; i++)
621 self->parts[i].x = parts[i];
623 if (self->hwndToolTip) {
625 SendMessageA (self->hwndToolTip, TTM_GETTOOLCOUNT, 0, 0);
627 if (nTipCount < self->numParts) {
632 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
633 ti.cbSize = sizeof(TTTOOLINFOA);
635 for (i = nTipCount; i < self->numParts; i++) {
636 TRACE("add tool %d\n", i);
638 SendMessageA (self->hwndToolTip, TTM_ADDTOOLA,
642 else if (nTipCount > self->numParts) {
646 for (i = nTipCount - 1; i >= self->numParts; i--) {
647 FIXME("delete tool %d\n", i);
651 STATUSBAR_SetPartBounds (hwnd);
652 InvalidateRect(hwnd, NULL, FALSE);
658 STATUSBAR_SetTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
660 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
661 STATUSWINDOWPART *part=NULL;
665 BOOL changed = FALSE;
667 text = (LPSTR) lParam;
668 part_num = ((INT) wParam) & 0x00ff;
669 style = ((INT) wParam) & 0xff00;
671 TRACE("setting part %d, text %s\n",part_num,debugstr_a(text));
675 else if (!self->simple && self->parts!=NULL)
676 part = &self->parts[part_num];
677 if (!part) return FALSE;
679 if (part->style != style)
683 if (style & SBT_OWNERDRAW) {
684 if (part->text == (LPWSTR)text)
686 part->text = (LPWSTR)text;
690 /* check if text is unchanged -> no need to redraw */
692 DWORD len = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 );
693 LPWSTR tmptext = COMCTL32_Alloc(len*sizeof(WCHAR));
694 MultiByteToWideChar( CP_ACP, 0, text, -1, tmptext, len );
696 if (!changed && part->text && !lstrcmpW(tmptext,part->text)) {
697 COMCTL32_Free(tmptext);
702 if (!changed && !part->text)
708 COMCTL32_Free (part->text);
711 InvalidateRect(hwnd, &part->bound, FALSE);
718 STATUSBAR_SetTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
720 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
721 STATUSWINDOWPART *part;
722 INT part_num, style, len;
724 BOOL bRedraw = FALSE;
726 text = (LPWSTR) lParam;
727 part_num = ((INT) wParam) & 0x00ff;
728 style = ((INT) wParam) & 0xff00;
730 if ((self->simple) || (self->parts==NULL) || (part_num==255))
733 part = &self->parts[part_num];
734 if (!part) return FALSE;
736 if(part->style != style)
741 /* FIXME: not sure how/if we can check for change in string with ownerdraw(remove this if we can't)... */
742 if (style & SBT_OWNERDRAW)
750 COMCTL32_Free(part->text);
754 } else if(!part->text || strcmpW(part->text, text)) /* see if the new string differs from the existing string */
756 if(part->text) COMCTL32_Free(part->text);
759 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
760 strcpyW(part->text, text);
765 InvalidateRect(hwnd, &part->bound, FALSE);
772 STATUSBAR_SetTipTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
774 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
776 TRACE("part %d: \"%s\"\n", (INT)wParam, (LPSTR)lParam);
777 if (infoPtr->hwndToolTip) {
779 ti.cbSize = sizeof(TTTOOLINFOA);
781 ti.uId = (INT)wParam;
783 ti.lpszText = (LPSTR)lParam;
784 SendMessageA (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTA,
793 STATUSBAR_SetTipTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
795 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
797 TRACE("part %d: \"%s\"\n", (INT)wParam, (LPSTR)lParam);
798 if (infoPtr->hwndToolTip) {
800 ti.cbSize = sizeof(TTTOOLINFOW);
802 ti.uId = (INT)wParam;
804 ti.lpszText = (LPWSTR)lParam;
805 SendMessageW (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTW,
813 inline static LRESULT
814 STATUSBAR_SetUnicodeFormat (HWND hwnd, WPARAM wParam)
816 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
817 BOOL bTemp = infoPtr->bUnicode;
819 TRACE("(0x%x)\n", (BOOL)wParam);
820 infoPtr->bUnicode = (BOOL)wParam;
827 STATUSBAR_Simple (HWND hwnd, WPARAM wParam, LPARAM lParam)
829 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
832 if (infoPtr->simple == wParam) /* no need to change */
835 infoPtr->simple = (BOOL)wParam;
837 /* send notification */
838 nmhdr.hwndFrom = hwnd;
839 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
840 nmhdr.code = SBN_SIMPLEMODECHANGE;
841 SendMessageA (GetParent (hwnd), WM_NOTIFY, 0, (LPARAM)&nmhdr);
842 InvalidateRect(hwnd, NULL, FALSE);
848 STATUSBAR_WMCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
850 LPCREATESTRUCTA lpCreate = (LPCREATESTRUCTA)lParam;
851 NONCLIENTMETRICSA nclm;
856 STATUSWINDOWINFO *self;
858 self = (STATUSWINDOWINFO*)COMCTL32_Alloc (sizeof(STATUSWINDOWINFO));
859 SetWindowLongA (hwnd, 0, (DWORD)self);
863 self->simple = FALSE;
864 self->clrBk = CLR_DEFAULT;
866 GetClientRect (hwnd, &rect);
868 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
869 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
870 self->hDefaultFont = CreateFontIndirectA (&nclm.lfStatusFont);
872 /* initialize simple case */
873 self->part0.bound = rect;
874 self->part0.text = 0;
876 self->part0.style = 0;
877 self->part0.hIcon = 0;
879 /* initialize first part */
880 self->parts = COMCTL32_Alloc (sizeof(STATUSWINDOWPART));
881 self->parts[0].bound = rect;
882 self->parts[0].text = 0;
883 self->parts[0].x = -1;
884 self->parts[0].style = 0;
885 self->parts[0].hIcon = 0;
887 if (IsWindowUnicode (hwnd)) {
888 self->bUnicode = TRUE;
889 if (lpCreate->lpszName &&
890 (len = strlenW ((LPCWSTR)lpCreate->lpszName))) {
891 self->parts[0].text = COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
892 strcpyW (self->parts[0].text, (LPCWSTR)lpCreate->lpszName);
896 if (lpCreate->lpszName &&
897 (len = strlen((LPCSTR)lpCreate->lpszName))) {
898 DWORD lenW = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)lpCreate->lpszName, -1, NULL, 0 );
899 self->parts[0].text = COMCTL32_Alloc (lenW*sizeof(WCHAR));
900 MultiByteToWideChar( CP_ACP, 0, (LPCSTR)lpCreate->lpszName, -1,
901 self->parts[0].text, lenW );
905 dwStyle = GetWindowLongA(hwnd, GWL_STYLE);
907 /* statusbars on managed windows should not have SIZEGRIP style */
908 if ((dwStyle & SBARS_SIZEGRIP) && lpCreate->hwndParent)
909 if (GetWindowLongA(lpCreate->hwndParent, GWL_EXSTYLE) & WS_EX_MANAGED)
910 SetWindowLongA (hwnd, GWL_STYLE, dwStyle & ~SBARS_SIZEGRIP);
912 if ((hdc = GetDC (0))) {
916 hOldFont = SelectObject (hdc,self->hDefaultFont);
917 GetTextMetricsA(hdc, &tm);
918 self->textHeight = tm.tmHeight;
919 SelectObject (hdc, hOldFont);
923 if (dwStyle & SBT_TOOLTIPS) {
925 CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
926 CW_USEDEFAULT, CW_USEDEFAULT,
927 CW_USEDEFAULT, CW_USEDEFAULT,
929 GetWindowLongA (hwnd, GWL_HINSTANCE), NULL);
931 if (self->hwndToolTip) {
932 NMTOOLTIPSCREATED nmttc;
934 nmttc.hdr.hwndFrom = hwnd;
935 nmttc.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
936 nmttc.hdr.code = NM_TOOLTIPSCREATED;
937 nmttc.hwndToolTips = self->hwndToolTip;
939 SendMessageA (GetParent (hwnd), WM_NOTIFY,
940 (WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc);
944 GetClientRect (GetParent (hwnd), &rect);
945 width = rect.right - rect.left;
946 self->height = self->textHeight + 4 + VERT_BORDER;
947 MoveWindow (hwnd, lpCreate->x, lpCreate->y - 1,
948 width, self->height, FALSE);
949 STATUSBAR_SetPartBounds (hwnd);
956 STATUSBAR_WMDestroy (HWND hwnd)
958 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
961 for (i = 0; i < self->numParts; i++) {
962 if (self->parts[i].text && !(self->parts[i].style & SBT_OWNERDRAW))
963 COMCTL32_Free (self->parts[i].text);
965 if (self->part0.text && !(self->part0.style & SBT_OWNERDRAW))
966 COMCTL32_Free (self->part0.text);
967 COMCTL32_Free (self->parts);
969 /* delete default font */
970 if (self->hDefaultFont)
971 DeleteObject (self->hDefaultFont);
973 /* delete tool tip control */
974 if (self->hwndToolTip)
975 DestroyWindow (self->hwndToolTip);
977 COMCTL32_Free (self);
978 SetWindowLongA(hwnd, 0, 0);
983 static inline LRESULT
984 STATUSBAR_WMGetFont (HWND hwnd)
986 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
987 return infoPtr->hFont? infoPtr->hFont : infoPtr->hDefaultFont;
992 STATUSBAR_WMGetText (HWND hwnd, WPARAM wParam, LPARAM lParam)
994 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
997 if (!(infoPtr->parts[0].text))
999 if (infoPtr->bUnicode)
1000 len = strlenW (infoPtr->parts[0].text);
1002 len = WideCharToMultiByte( CP_ACP, 0, infoPtr->parts[0].text, -1, NULL, 0, NULL, NULL )-1;
1005 if (infoPtr->bUnicode)
1006 strcpyW ((LPWSTR)lParam, infoPtr->parts[0].text);
1008 WideCharToMultiByte( CP_ACP, 0, infoPtr->parts[0].text, -1,
1009 (LPSTR)lParam, len+1, NULL, NULL );
1017 inline static LRESULT
1018 STATUSBAR_WMMouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
1020 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1022 if (infoPtr->hwndToolTip)
1023 STATUSBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
1024 WM_MOUSEMOVE, wParam, lParam);
1030 STATUSBAR_WMNCHitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
1032 if (GetWindowLongA (hwnd, GWL_STYLE) & SBARS_SIZEGRIP) {
1036 GetClientRect (hwnd, &rect);
1038 pt.x = (INT)LOWORD(lParam);
1039 pt.y = (INT)HIWORD(lParam);
1040 ScreenToClient (hwnd, &pt);
1042 rect.left = rect.right - 13;
1045 if (PtInRect (&rect, pt))
1046 return HTBOTTOMRIGHT;
1049 return DefWindowProcA (hwnd, WM_NCHITTEST, wParam, lParam);
1053 static inline LRESULT
1054 STATUSBAR_WMNCLButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
1056 PostMessageA (GetParent (hwnd), WM_NCLBUTTONDOWN, wParam, lParam);
1061 static inline LRESULT
1062 STATUSBAR_WMNCLButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
1064 PostMessageA (GetParent (hwnd), WM_NCLBUTTONUP, wParam, lParam);
1070 STATUSBAR_WMPaint (HWND hwnd, WPARAM wParam)
1075 hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
1076 STATUSBAR_Refresh (hwnd, hdc);
1078 EndPaint (hwnd, &ps);
1085 STATUSBAR_WMSetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
1087 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1089 infoPtr->hFont = (HFONT)wParam;
1090 if (LOWORD(lParam) == TRUE)
1091 InvalidateRect(hwnd, NULL, FALSE);
1098 STATUSBAR_WMSetText (HWND hwnd, WPARAM wParam, LPARAM lParam)
1100 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1101 STATUSWINDOWPART *part;
1104 if (infoPtr->numParts == 0)
1107 part = &infoPtr->parts[0];
1108 /* duplicate string */
1110 COMCTL32_Free (part->text);
1112 if (infoPtr->bUnicode) {
1113 if (lParam && (len = strlenW((LPCWSTR)lParam))) {
1114 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1115 strcpyW (part->text, (LPCWSTR)lParam);
1119 if (lParam && (len = lstrlenA((LPCSTR)lParam))) {
1120 DWORD lenW = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)lParam, -1, NULL, 0 );
1121 part->text = COMCTL32_Alloc (lenW*sizeof(WCHAR));
1122 MultiByteToWideChar( CP_ACP, 0, (LPCSTR)lParam, -1, part->text, lenW );
1126 InvalidateRect(hwnd, &part->bound, FALSE);
1133 STATUSBAR_WMSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1135 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1136 INT width, x, y, flags;
1140 /* Need to resize width to match parent */
1141 flags = (INT) wParam;
1143 /* FIXME for flags =
1144 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED, SIZE_RESTORED
1147 if (flags == SIZE_RESTORED) {
1148 /* width and height don't apply */
1149 parent = GetParent (hwnd);
1150 GetClientRect (parent, &parent_rect);
1151 width = parent_rect.right - parent_rect.left;
1152 x = parent_rect.left;
1153 y = parent_rect.bottom - infoPtr->height;
1154 MoveWindow (hwnd, parent_rect.left,
1155 parent_rect.bottom - infoPtr->height,
1156 width, infoPtr->height, TRUE);
1157 STATUSBAR_SetPartBounds (hwnd);
1164 STATUSBAR_SendNotify (HWND hwnd, UINT code)
1168 nmhdr.hwndFrom = hwnd;
1169 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1171 SendMessageA (GetParent (hwnd), WM_NOTIFY, 0, (LPARAM)&nmhdr);
1177 static LRESULT WINAPI
1178 StatusWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
1180 TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hwnd, msg, wParam, lParam);
1181 if (!(STATUSBAR_GetInfoPtr(hwnd)) && (msg != WM_CREATE))
1182 return DefWindowProcA (hwnd, msg, wParam, lParam);
1186 return STATUSBAR_GetBorders (lParam);
1189 return STATUSBAR_GetIcon (hwnd, wParam);
1192 return STATUSBAR_GetParts (hwnd, wParam, lParam);
1195 return STATUSBAR_GetRect (hwnd, wParam, lParam);
1198 return STATUSBAR_GetTextA (hwnd, wParam, lParam);
1201 return STATUSBAR_GetTextW (hwnd, wParam, lParam);
1203 case SB_GETTEXTLENGTHA:
1204 case SB_GETTEXTLENGTHW:
1205 return STATUSBAR_GetTextLength (hwnd, wParam);
1207 case SB_GETTIPTEXTA:
1208 return STATUSBAR_GetTipTextA (hwnd, wParam, lParam);
1210 case SB_GETTIPTEXTW:
1211 return STATUSBAR_GetTipTextW (hwnd, wParam, lParam);
1213 case SB_GETUNICODEFORMAT:
1214 return STATUSBAR_GetUnicodeFormat (hwnd);
1217 return STATUSBAR_IsSimple (hwnd);
1220 return STATUSBAR_SetBkColor (hwnd, wParam, lParam);
1223 return STATUSBAR_SetIcon (hwnd, wParam, lParam);
1225 case SB_SETMINHEIGHT:
1226 return STATUSBAR_SetMinHeight (hwnd, wParam, lParam);
1229 return STATUSBAR_SetParts (hwnd, wParam, lParam);
1232 return STATUSBAR_SetTextA (hwnd, wParam, lParam);
1235 return STATUSBAR_SetTextW (hwnd, wParam, lParam);
1237 case SB_SETTIPTEXTA:
1238 return STATUSBAR_SetTipTextA (hwnd, wParam, lParam);
1240 case SB_SETTIPTEXTW:
1241 return STATUSBAR_SetTipTextW (hwnd, wParam, lParam);
1243 case SB_SETUNICODEFORMAT:
1244 return STATUSBAR_SetUnicodeFormat (hwnd, wParam);
1247 return STATUSBAR_Simple (hwnd, wParam, lParam);
1251 return STATUSBAR_WMCreate (hwnd, wParam, lParam);
1254 return STATUSBAR_WMDestroy (hwnd);
1257 return STATUSBAR_WMGetFont (hwnd);
1260 return STATUSBAR_WMGetText (hwnd, wParam, lParam);
1262 case WM_GETTEXTLENGTH:
1263 return STATUSBAR_GetTextLength (hwnd, 0);
1265 case WM_LBUTTONDBLCLK:
1266 return STATUSBAR_SendNotify (hwnd, NM_DBLCLK);
1269 return STATUSBAR_SendNotify (hwnd, NM_CLICK);
1272 return STATUSBAR_WMMouseMove (hwnd, wParam, lParam);
1275 return STATUSBAR_WMNCHitTest (hwnd, wParam, lParam);
1277 case WM_NCLBUTTONDOWN:
1278 return STATUSBAR_WMNCLButtonDown (hwnd, wParam, lParam);
1280 case WM_NCLBUTTONUP:
1281 return STATUSBAR_WMNCLButtonUp (hwnd, wParam, lParam);
1284 return STATUSBAR_WMPaint (hwnd, wParam);
1286 case WM_RBUTTONDBLCLK:
1287 return STATUSBAR_SendNotify (hwnd, NM_RDBLCLK);
1290 return STATUSBAR_SendNotify (hwnd, NM_RCLICK);
1293 return STATUSBAR_WMSetFont (hwnd, wParam, lParam);
1296 return STATUSBAR_WMSetText (hwnd, wParam, lParam);
1299 return STATUSBAR_WMSize (hwnd, wParam, lParam);
1303 ERR("unknown msg %04x wp=%04x lp=%08lx\n",
1304 msg, wParam, lParam);
1305 return DefWindowProcA (hwnd, msg, wParam, lParam);
1311 /***********************************************************************
1312 * STATUS_Register [Internal]
1314 * Registers the status window class.
1318 STATUS_Register (void)
1322 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
1323 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW;
1324 wndClass.lpfnWndProc = (WNDPROC)StatusWindowProc;
1325 wndClass.cbClsExtra = 0;
1326 wndClass.cbWndExtra = sizeof(STATUSWINDOWINFO *);
1327 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
1328 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
1329 wndClass.lpszClassName = STATUSCLASSNAMEA;
1331 RegisterClassA (&wndClass);
1335 /***********************************************************************
1336 * STATUS_Unregister [Internal]
1338 * Unregisters the status window class.
1342 STATUS_Unregister (void)
1344 UnregisterClassA (STATUSCLASSNAMEA, (HINSTANCE)NULL);