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).
15 #include "wine/unicode.h"
17 #include "debugtools.h"
19 DEFAULT_DEBUG_CHANNEL(statusbar);
39 COLORREF clrBk; /* background color */
40 BOOL bUnicode; /* unicode flag */
41 STATUSWINDOWPART part0; /* simple window */
42 STATUSWINDOWPART *parts;
46 * Run tests using Waite Group Windows95 API Bible Vol. 1&2
47 * The second cdrom contains executables drawstat.exe,gettext.exe,
48 * simple.exe, getparts.exe, setparts.exe, statwnd.exe
52 #define _MAX(a,b) (((a)>(b))?(a):(b))
53 #define _MIN(a,b) (((a)>(b))?(b):(a))
59 #define STATUSBAR_GetInfoPtr(hwnd) ((STATUSWINDOWINFO *)GetWindowLongA (hwnd, 0))
63 STATUSBAR_SetPartBounds (HWND hwnd);
66 STATUSBAR_DrawSizeGrip (HDC hdc, LPRECT lpRect)
72 pt.x = lpRect->right - 1;
73 pt.y = lpRect->bottom - 1;
75 hOldPen = SelectObject (hdc, GetSysColorPen (COLOR_3DFACE));
76 MoveToEx (hdc, pt.x - 12, pt.y, NULL);
77 LineTo (hdc, pt.x, pt.y);
78 LineTo (hdc, pt.x, pt.y - 12);
83 SelectObject (hdc, GetSysColorPen (COLOR_3DSHADOW));
84 for (i = 1; i < 11; i += 4) {
85 MoveToEx (hdc, pt.x - i, pt.y, NULL);
86 LineTo (hdc, pt.x, pt.y - i);
88 MoveToEx (hdc, pt.x - i-1, pt.y, NULL);
89 LineTo (hdc, pt.x, pt.y - i-1);
92 SelectObject (hdc, GetSysColorPen (COLOR_3DHIGHLIGHT));
93 for (i = 3; i < 13; i += 4) {
94 MoveToEx (hdc, pt.x - i, pt.y, NULL);
95 LineTo (hdc, pt.x, pt.y - i);
98 SelectObject (hdc, hOldPen);
103 STATUSBAR_DrawPart (HDC hdc, STATUSWINDOWPART *part)
105 RECT r = part->bound;
106 UINT border = BDR_SUNKENOUTER;
108 if (part->style & SBT_POPOUT)
109 border = BDR_RAISEDOUTER;
110 else if (part->style & SBT_NOBORDERS)
113 DrawEdge(hdc, &r, border, BF_RECT|BF_ADJUST);
117 INT cy = r.bottom - r.top;
120 DrawIconEx (hdc, r.left, r.top, part->hIcon, cy, cy, 0, 0, DI_NORMAL);
126 int oldbkmode = SetBkMode(hdc, TRANSPARENT);
127 LPWSTR p = (LPWSTR)part->text;
128 UINT align = DT_LEFT;
139 DrawTextW (hdc, p, -1, &r, align|DT_VCENTER|DT_SINGLELINE);
140 if (oldbkmode != TRANSPARENT)
141 SetBkMode(hdc, oldbkmode);
147 STATUSBAR_RefreshPart (HWND hwnd, STATUSWINDOWPART *part, HDC hdc, int itemID)
149 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
153 if (!IsWindowVisible (hwnd))
156 if (part->bound.right < part->bound.left) return;
158 if (self->clrBk != CLR_DEFAULT)
159 hbrBk = CreateSolidBrush (self->clrBk);
161 hbrBk = GetSysColorBrush (COLOR_3DFACE);
162 FillRect(hdc, &part->bound, hbrBk);
164 hOldFont = SelectObject (hdc, self->hFont ? self->hFont : self->hDefaultFont);
166 if (part->style & SBT_OWNERDRAW) {
169 dis.CtlID = GetWindowLongA (hwnd, GWL_ID);
173 dis.rcItem = part->bound;
174 dis.itemData = (INT)part->text;
175 SendMessageA (GetParent (hwnd), WM_DRAWITEM,
176 (WPARAM)dis.CtlID, (LPARAM)&dis);
178 STATUSBAR_DrawPart (hdc, part);
180 SelectObject (hdc, hOldFont);
182 if (self->clrBk != CLR_DEFAULT)
183 DeleteObject (hbrBk);
185 if (GetWindowLongA (hwnd, GWL_STYLE) & SBARS_SIZEGRIP) {
188 GetClientRect (hwnd, &rect);
189 STATUSBAR_DrawSizeGrip (hdc, &rect);
195 STATUSBAR_Refresh (HWND hwnd, HDC hdc)
197 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
203 if (!IsWindowVisible(hwnd))
206 STATUSBAR_SetPartBounds(hwnd);
208 GetClientRect (hwnd, &rect);
210 if (infoPtr->clrBk != CLR_DEFAULT)
211 hbrBk = CreateSolidBrush (infoPtr->clrBk);
213 hbrBk = GetSysColorBrush (COLOR_3DFACE);
214 FillRect(hdc, &rect, hbrBk);
216 hOldFont = SelectObject (hdc, infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont);
218 if (infoPtr->simple) {
219 STATUSBAR_RefreshPart (hwnd, &infoPtr->part0, hdc, 0);
221 for (i = 0; i < infoPtr->numParts; i++) {
222 if (infoPtr->parts[i].style & SBT_OWNERDRAW) {
225 dis.CtlID = GetWindowLongA (hwnd, GWL_ID);
229 dis.rcItem = infoPtr->parts[i].bound;
230 dis.itemData = (INT)infoPtr->parts[i].text;
231 SendMessageA (GetParent (hwnd), WM_DRAWITEM,
232 (WPARAM)dis.CtlID, (LPARAM)&dis);
234 STATUSBAR_RefreshPart (hwnd, &infoPtr->parts[i], hdc, i);
238 SelectObject (hdc, hOldFont);
240 if (infoPtr->clrBk != CLR_DEFAULT)
241 DeleteObject (hbrBk);
243 if (GetWindowLongA(hwnd, GWL_STYLE) & SBARS_SIZEGRIP)
244 STATUSBAR_DrawSizeGrip (hdc, &rect);
251 STATUSBAR_SetPartBounds (HWND hwnd)
253 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
254 STATUSWINDOWPART *part;
258 /* get our window size */
259 GetClientRect (hwnd, &rect);
261 rect.top += VERT_BORDER;
263 /* set bounds for simple rectangle */
264 self->part0.bound = rect;
266 /* set bounds for non-simple rectangles */
267 for (i = 0; i < self->numParts; i++) {
268 part = &self->parts[i];
269 r = &self->parts[i].bound;
271 r->bottom = rect.bottom;
275 r->left = self->parts[i-1].bound.right + HORZ_GAP;
277 r->right = rect.right;
281 if (self->hwndToolTip) {
284 ti.cbSize = sizeof(TTTOOLINFOA);
288 SendMessageA (self->hwndToolTip, TTM_NEWTOOLRECTA,
296 STATUSBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
297 WPARAM wParam, LPARAM lParam)
305 msg.time = GetMessageTime ();
306 msg.pt.x = LOWORD(GetMessagePos ());
307 msg.pt.y = HIWORD(GetMessagePos ());
309 SendMessageA (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
313 inline static LRESULT
314 STATUSBAR_GetBorders (LPARAM lParam)
316 LPINT out = (LPINT) lParam;
318 out[0] = HORZ_BORDER; /* horizontal border width */
319 out[1] = VERT_BORDER; /* vertical border width */
320 out[2] = HORZ_GAP; /* width of border between rectangles */
327 STATUSBAR_GetIcon (HWND hwnd, WPARAM wParam)
329 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
332 nPart = (INT)wParam & 0x00ff;
333 if ((nPart < -1) || (nPart >= self->numParts))
337 return (self->part0.hIcon);
339 return (self->parts[nPart].hIcon);
344 STATUSBAR_GetParts (HWND hwnd, WPARAM wParam, LPARAM lParam)
346 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
351 num_parts = (INT) wParam;
352 parts = (LPINT) lParam;
354 for (i = 0; i < num_parts; i++) {
355 parts[i] = infoPtr->parts[i].x;
358 return (infoPtr->numParts);
363 STATUSBAR_GetRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
365 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
369 part_num = ((INT) wParam) & 0x00ff;
370 rect = (LPRECT) lParam;
372 *rect = infoPtr->part0.bound;
374 *rect = infoPtr->parts[part_num].bound;
380 STATUSBAR_GetTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
382 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
383 STATUSWINDOWPART *part;
387 nPart = ((INT) wParam) & 0x00ff;
391 part = &self->parts[nPart];
393 if (part->style & SBT_OWNERDRAW)
394 result = (LRESULT)part->text;
396 DWORD len = part->text ? WideCharToMultiByte( CP_ACP, 0, part->text, -1,
397 NULL, 0, NULL, NULL ) - 1 : 0;
398 result = MAKELONG( len, part->style );
400 WideCharToMultiByte( CP_ACP, 0, part->text, -1, (LPSTR)lParam, len+1, NULL, NULL );
407 STATUSBAR_GetTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
409 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
410 STATUSWINDOWPART *part;
414 nPart = ((INT)wParam) & 0x00ff;
416 part = &infoPtr->part0;
418 part = &infoPtr->parts[nPart];
420 if (part->style & SBT_OWNERDRAW)
421 result = (LRESULT)part->text;
423 result = part->text ? strlenW (part->text) : 0;
424 result |= (part->style << 16);
425 if (part->text && lParam)
426 strcpyW ((LPWSTR)lParam, part->text);
433 STATUSBAR_GetTextLength (HWND hwnd, WPARAM wParam)
435 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
436 STATUSWINDOWPART *part;
440 part_num = ((INT) wParam) & 0x00ff;
443 part = &infoPtr->part0;
445 part = &infoPtr->parts[part_num];
448 result = strlenW(part->text);
452 result |= (part->style << 16);
458 STATUSBAR_GetTipTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
460 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
461 LPSTR tip = (LPSTR)lParam;
464 CHAR buf[INFOTIPSIZE];
467 if (infoPtr->hwndToolTip) {
469 ti.cbSize = sizeof(TTTOOLINFOA);
471 ti.uId = LOWORD(wParam);
473 SendMessageA(infoPtr->hwndToolTip, TTM_GETTEXTA, 0, (LPARAM)&ti);
475 lstrcpynA(tip, buf, HIWORD(wParam));
482 STATUSBAR_GetTipTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
484 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
485 LPWSTR tip = (LPWSTR)lParam;
488 WCHAR buf[INFOTIPSIZE];
491 if (infoPtr->hwndToolTip) {
493 ti.cbSize = sizeof(TTTOOLINFOW);
495 ti.uId = LOWORD(wParam);
497 SendMessageW(infoPtr->hwndToolTip, TTM_GETTEXTW, 0, (LPARAM)&ti);
499 lstrcpynW(tip, buf, HIWORD(wParam));
506 inline static LRESULT
507 STATUSBAR_GetUnicodeFormat (HWND hwnd)
509 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
510 return infoPtr->bUnicode;
514 inline static LRESULT
515 STATUSBAR_IsSimple (HWND hwnd)
517 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
518 return infoPtr->simple;
523 STATUSBAR_SetBkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
525 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
528 oldBkColor = self->clrBk;
529 self->clrBk = (COLORREF)lParam;
530 InvalidateRect(hwnd, NULL, FALSE);
537 STATUSBAR_SetIcon (HWND hwnd, WPARAM wParam, LPARAM lParam)
539 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
540 INT nPart = (INT)wParam & 0x00ff;
542 if ((nPart < -1) || (nPart >= self->numParts))
545 TRACE("setting part %d, icon %lx\n",nPart,lParam);
548 if (self->part0.hIcon == (HICON)lParam) /* same as - no redraw */
550 self->part0.hIcon = (HICON)lParam;
552 InvalidateRect(hwnd, &self->part0.bound, FALSE);
554 if (self->parts[nPart].hIcon == (HICON)lParam) /* same as - no redraw */
557 self->parts[nPart].hIcon = (HICON)lParam;
559 InvalidateRect(hwnd, &self->parts[nPart].bound, FALSE);
566 STATUSBAR_SetMinHeight (HWND hwnd, WPARAM wParam, LPARAM lParam)
568 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
570 if (IsWindowVisible (hwnd)) {
571 HWND parent = GetParent (hwnd);
575 GetClientRect (parent, &parent_rect);
576 self->height = (INT)wParam + VERT_BORDER;
577 width = parent_rect.right - parent_rect.left;
578 x = parent_rect.left;
579 y = parent_rect.bottom - self->height;
580 MoveWindow (hwnd, parent_rect.left,
581 parent_rect.bottom - self->height,
582 width, self->height, TRUE);
583 STATUSBAR_SetPartBounds (hwnd);
591 STATUSBAR_SetParts (HWND hwnd, WPARAM wParam, LPARAM lParam)
593 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
594 STATUSWINDOWPART *tmp;
599 TRACE("(%d,%p)\n",wParam,(LPVOID)lParam);
602 self->simple = FALSE;
604 oldNumParts = self->numParts;
605 self->numParts = (INT) wParam;
606 parts = (LPINT) lParam;
607 if (oldNumParts > self->numParts) {
608 for (i = self->numParts ; i < oldNumParts; i++) {
609 if (self->parts[i].text && !(self->parts[i].style & SBT_OWNERDRAW))
610 COMCTL32_Free (self->parts[i].text);
613 if (oldNumParts < self->numParts) {
614 tmp = COMCTL32_Alloc (sizeof(STATUSWINDOWPART) * self->numParts);
615 for (i = 0; i < oldNumParts; i++) {
616 tmp[i] = self->parts[i];
619 COMCTL32_Free (self->parts);
622 if (oldNumParts == self->numParts) {
623 for (i=0;i<oldNumParts;i++)
624 if (self->parts[i].x != parts[i])
626 if (i==oldNumParts) /* Unchanged? no need to redraw! */
630 for (i = 0; i < self->numParts; i++)
631 self->parts[i].x = parts[i];
633 if (self->hwndToolTip) {
635 SendMessageA (self->hwndToolTip, TTM_GETTOOLCOUNT, 0, 0);
637 if (nTipCount < self->numParts) {
642 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
643 ti.cbSize = sizeof(TTTOOLINFOA);
645 for (i = nTipCount; i < self->numParts; i++) {
646 TRACE("add tool %d\n", i);
648 SendMessageA (self->hwndToolTip, TTM_ADDTOOLA,
652 else if (nTipCount > self->numParts) {
656 for (i = nTipCount - 1; i >= self->numParts; i--) {
657 FIXME("delete tool %d\n", i);
661 STATUSBAR_SetPartBounds (hwnd);
662 InvalidateRect(hwnd, NULL, FALSE);
668 STATUSBAR_SetTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
670 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
671 STATUSWINDOWPART *part=NULL;
675 BOOL changed = FALSE;
677 text = (LPSTR) lParam;
678 part_num = ((INT) wParam) & 0x00ff;
679 style = ((INT) wParam) & 0xff00;
681 TRACE("setting part %d, text %s\n",part_num,debugstr_a(text));
685 else if (!self->simple && self->parts!=NULL)
686 part = &self->parts[part_num];
687 if (!part) return FALSE;
689 if (part->style != style)
693 if (style & SBT_OWNERDRAW) {
694 if (part->text == (LPWSTR)text)
696 part->text = (LPWSTR)text;
700 /* check if text is unchanged -> no need to redraw */
702 DWORD len = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 );
703 LPWSTR tmptext = COMCTL32_Alloc(len*sizeof(WCHAR));
704 MultiByteToWideChar( CP_ACP, 0, text, -1, tmptext, len );
706 if (!changed && part->text && !lstrcmpW(tmptext,part->text)) {
707 COMCTL32_Free(tmptext);
712 if (!changed && !part->text)
718 COMCTL32_Free (part->text);
721 InvalidateRect(hwnd, &part->bound, FALSE);
728 STATUSBAR_SetTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
730 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
731 STATUSWINDOWPART *part;
732 INT part_num, style, len;
734 BOOL bRedraw = FALSE;
736 text = (LPWSTR) lParam;
737 part_num = ((INT) wParam) & 0x00ff;
738 style = ((INT) wParam) & 0xff00;
740 if ((self->simple) || (self->parts==NULL) || (part_num==255))
743 part = &self->parts[part_num];
744 if (!part) return FALSE;
746 if(part->style != style)
751 /* FIXME: not sure how/if we can check for change in string with ownerdraw(remove this if we can't)... */
752 if (style & SBT_OWNERDRAW)
760 COMCTL32_Free(part->text);
764 } else if(!part->text || strcmpW(part->text, text)) /* see if the new string differs from the existing string */
766 if(part->text) COMCTL32_Free(part->text);
769 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
770 strcpyW(part->text, text);
775 InvalidateRect(hwnd, &part->bound, FALSE);
782 STATUSBAR_SetTipTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
784 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
786 TRACE("part %d: \"%s\"\n", (INT)wParam, (LPSTR)lParam);
787 if (infoPtr->hwndToolTip) {
789 ti.cbSize = sizeof(TTTOOLINFOA);
791 ti.uId = (INT)wParam;
793 ti.lpszText = (LPSTR)lParam;
794 SendMessageA (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTA,
803 STATUSBAR_SetTipTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
805 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
807 TRACE("part %d: \"%s\"\n", (INT)wParam, (LPSTR)lParam);
808 if (infoPtr->hwndToolTip) {
810 ti.cbSize = sizeof(TTTOOLINFOW);
812 ti.uId = (INT)wParam;
814 ti.lpszText = (LPWSTR)lParam;
815 SendMessageW (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTW,
823 inline static LRESULT
824 STATUSBAR_SetUnicodeFormat (HWND hwnd, WPARAM wParam)
826 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
827 BOOL bTemp = infoPtr->bUnicode;
829 TRACE("(0x%x)\n", (BOOL)wParam);
830 infoPtr->bUnicode = (BOOL)wParam;
837 STATUSBAR_Simple (HWND hwnd, WPARAM wParam, LPARAM lParam)
839 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
842 if (infoPtr->simple == wParam) /* no need to change */
845 infoPtr->simple = (BOOL)wParam;
847 /* send notification */
848 nmhdr.hwndFrom = hwnd;
849 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
850 nmhdr.code = SBN_SIMPLEMODECHANGE;
851 SendMessageA (GetParent (hwnd), WM_NOTIFY, 0, (LPARAM)&nmhdr);
852 InvalidateRect(hwnd, NULL, FALSE);
858 STATUSBAR_WMCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
860 LPCREATESTRUCTA lpCreate = (LPCREATESTRUCTA)lParam;
861 NONCLIENTMETRICSA nclm;
866 STATUSWINDOWINFO *self;
868 self = (STATUSWINDOWINFO*)COMCTL32_Alloc (sizeof(STATUSWINDOWINFO));
869 SetWindowLongA (hwnd, 0, (DWORD)self);
873 self->simple = FALSE;
874 self->clrBk = CLR_DEFAULT;
876 GetClientRect (hwnd, &rect);
878 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
879 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
880 self->hDefaultFont = CreateFontIndirectA (&nclm.lfStatusFont);
882 /* initialize simple case */
883 self->part0.bound = rect;
884 self->part0.text = 0;
886 self->part0.style = 0;
887 self->part0.hIcon = 0;
889 /* initialize first part */
890 self->parts = COMCTL32_Alloc (sizeof(STATUSWINDOWPART));
891 self->parts[0].bound = rect;
892 self->parts[0].text = 0;
893 self->parts[0].x = -1;
894 self->parts[0].style = 0;
895 self->parts[0].hIcon = 0;
897 if (IsWindowUnicode (hwnd)) {
898 self->bUnicode = TRUE;
899 if (lpCreate->lpszName &&
900 (len = strlenW ((LPCWSTR)lpCreate->lpszName))) {
901 self->parts[0].text = COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
902 strcpyW (self->parts[0].text, (LPCWSTR)lpCreate->lpszName);
906 if (lpCreate->lpszName &&
907 (len = strlen((LPCSTR)lpCreate->lpszName))) {
908 DWORD lenW = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)lpCreate->lpszName, -1, NULL, 0 );
909 self->parts[0].text = COMCTL32_Alloc (lenW*sizeof(WCHAR));
910 MultiByteToWideChar( CP_ACP, 0, (LPCSTR)lpCreate->lpszName, -1,
911 self->parts[0].text, lenW );
915 dwStyle = GetWindowLongA(hwnd, GWL_STYLE);
917 /* statusbars on managed windows should not have SIZEGRIP style */
918 if ((dwStyle & SBARS_SIZEGRIP) && lpCreate->hwndParent)
919 if (GetWindowLongA(lpCreate->hwndParent, GWL_EXSTYLE) & WS_EX_MANAGED)
920 SetWindowLongA (hwnd, GWL_STYLE, dwStyle & ~SBARS_SIZEGRIP);
922 if ((hdc = GetDC (0))) {
926 hOldFont = SelectObject (hdc,self->hDefaultFont);
927 GetTextMetricsA(hdc, &tm);
928 self->textHeight = tm.tmHeight;
929 SelectObject (hdc, hOldFont);
933 if (dwStyle & SBT_TOOLTIPS) {
935 CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
936 CW_USEDEFAULT, CW_USEDEFAULT,
937 CW_USEDEFAULT, CW_USEDEFAULT,
939 GetWindowLongA (hwnd, GWL_HINSTANCE), NULL);
941 if (self->hwndToolTip) {
942 NMTOOLTIPSCREATED nmttc;
944 nmttc.hdr.hwndFrom = hwnd;
945 nmttc.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
946 nmttc.hdr.code = NM_TOOLTIPSCREATED;
947 nmttc.hwndToolTips = self->hwndToolTip;
949 SendMessageA (GetParent (hwnd), WM_NOTIFY,
950 (WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc);
954 GetClientRect (GetParent (hwnd), &rect);
955 width = rect.right - rect.left;
956 self->height = self->textHeight + 4 + VERT_BORDER;
957 MoveWindow (hwnd, lpCreate->x, lpCreate->y - 1,
958 width, self->height, FALSE);
959 STATUSBAR_SetPartBounds (hwnd);
966 STATUSBAR_WMDestroy (HWND hwnd)
968 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
971 for (i = 0; i < self->numParts; i++) {
972 if (self->parts[i].text && !(self->parts[i].style & SBT_OWNERDRAW))
973 COMCTL32_Free (self->parts[i].text);
975 if (self->part0.text && !(self->part0.style & SBT_OWNERDRAW))
976 COMCTL32_Free (self->part0.text);
977 COMCTL32_Free (self->parts);
979 /* delete default font */
980 if (self->hDefaultFont)
981 DeleteObject (self->hDefaultFont);
983 /* delete tool tip control */
984 if (self->hwndToolTip)
985 DestroyWindow (self->hwndToolTip);
987 COMCTL32_Free (self);
988 SetWindowLongA(hwnd, 0, 0);
993 static inline LRESULT
994 STATUSBAR_WMGetFont (HWND hwnd)
996 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
997 return infoPtr->hFont? infoPtr->hFont : infoPtr->hDefaultFont;
1002 STATUSBAR_WMGetText (HWND hwnd, WPARAM wParam, LPARAM lParam)
1004 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1007 if (!(infoPtr->parts[0].text))
1009 if (infoPtr->bUnicode)
1010 len = strlenW (infoPtr->parts[0].text);
1012 len = WideCharToMultiByte( CP_ACP, 0, infoPtr->parts[0].text, -1, NULL, 0, NULL, NULL )-1;
1015 if (infoPtr->bUnicode)
1016 strcpyW ((LPWSTR)lParam, infoPtr->parts[0].text);
1018 WideCharToMultiByte( CP_ACP, 0, infoPtr->parts[0].text, -1,
1019 (LPSTR)lParam, len+1, NULL, NULL );
1027 inline static LRESULT
1028 STATUSBAR_WMMouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
1030 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1032 if (infoPtr->hwndToolTip)
1033 STATUSBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
1034 WM_MOUSEMOVE, wParam, lParam);
1040 STATUSBAR_WMNCHitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
1042 if (GetWindowLongA (hwnd, GWL_STYLE) & SBARS_SIZEGRIP) {
1046 GetClientRect (hwnd, &rect);
1048 pt.x = (INT)LOWORD(lParam);
1049 pt.y = (INT)HIWORD(lParam);
1050 ScreenToClient (hwnd, &pt);
1052 rect.left = rect.right - 13;
1055 if (PtInRect (&rect, pt))
1056 return HTBOTTOMRIGHT;
1059 return DefWindowProcA (hwnd, WM_NCHITTEST, wParam, lParam);
1063 static inline LRESULT
1064 STATUSBAR_WMNCLButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
1066 PostMessageA (GetParent (hwnd), WM_NCLBUTTONDOWN, wParam, lParam);
1071 static inline LRESULT
1072 STATUSBAR_WMNCLButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
1074 PostMessageA (GetParent (hwnd), WM_NCLBUTTONUP, wParam, lParam);
1080 STATUSBAR_WMPaint (HWND hwnd, WPARAM wParam)
1085 hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
1086 STATUSBAR_Refresh (hwnd, hdc);
1088 EndPaint (hwnd, &ps);
1095 STATUSBAR_WMSetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
1097 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1099 infoPtr->hFont = (HFONT)wParam;
1100 if (LOWORD(lParam) == TRUE)
1101 InvalidateRect(hwnd, NULL, FALSE);
1108 STATUSBAR_WMSetText (HWND hwnd, WPARAM wParam, LPARAM lParam)
1110 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1111 STATUSWINDOWPART *part;
1114 if (infoPtr->numParts == 0)
1117 part = &infoPtr->parts[0];
1118 /* duplicate string */
1120 COMCTL32_Free (part->text);
1122 if (infoPtr->bUnicode) {
1123 if (lParam && (len = strlenW((LPCWSTR)lParam))) {
1124 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1125 strcpyW (part->text, (LPCWSTR)lParam);
1129 if (lParam && (len = lstrlenA((LPCSTR)lParam))) {
1130 DWORD lenW = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)lParam, -1, NULL, 0 );
1131 part->text = COMCTL32_Alloc (lenW*sizeof(WCHAR));
1132 MultiByteToWideChar( CP_ACP, 0, (LPCSTR)lParam, -1, part->text, lenW );
1136 InvalidateRect(hwnd, &part->bound, FALSE);
1143 STATUSBAR_WMSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1145 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1146 INT width, x, y, flags;
1150 /* Need to resize width to match parent */
1151 flags = (INT) wParam;
1153 /* FIXME for flags =
1154 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED, SIZE_RESTORED
1157 if (flags == SIZE_RESTORED) {
1158 /* width and height don't apply */
1159 parent = GetParent (hwnd);
1160 GetClientRect (parent, &parent_rect);
1161 width = parent_rect.right - parent_rect.left;
1162 x = parent_rect.left;
1163 y = parent_rect.bottom - infoPtr->height;
1164 MoveWindow (hwnd, parent_rect.left,
1165 parent_rect.bottom - infoPtr->height,
1166 width, infoPtr->height, TRUE);
1167 STATUSBAR_SetPartBounds (hwnd);
1174 STATUSBAR_SendNotify (HWND hwnd, UINT code)
1178 nmhdr.hwndFrom = hwnd;
1179 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1181 SendMessageA (GetParent (hwnd), WM_NOTIFY, 0, (LPARAM)&nmhdr);
1187 static LRESULT WINAPI
1188 StatusWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
1190 TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hwnd, msg, wParam, lParam);
1191 if (!(STATUSBAR_GetInfoPtr(hwnd)) && (msg != WM_CREATE))
1192 return DefWindowProcA (hwnd, msg, wParam, lParam);
1196 return STATUSBAR_GetBorders (lParam);
1199 return STATUSBAR_GetIcon (hwnd, wParam);
1202 return STATUSBAR_GetParts (hwnd, wParam, lParam);
1205 return STATUSBAR_GetRect (hwnd, wParam, lParam);
1208 return STATUSBAR_GetTextA (hwnd, wParam, lParam);
1211 return STATUSBAR_GetTextW (hwnd, wParam, lParam);
1213 case SB_GETTEXTLENGTHA:
1214 case SB_GETTEXTLENGTHW:
1215 return STATUSBAR_GetTextLength (hwnd, wParam);
1217 case SB_GETTIPTEXTA:
1218 return STATUSBAR_GetTipTextA (hwnd, wParam, lParam);
1220 case SB_GETTIPTEXTW:
1221 return STATUSBAR_GetTipTextW (hwnd, wParam, lParam);
1223 case SB_GETUNICODEFORMAT:
1224 return STATUSBAR_GetUnicodeFormat (hwnd);
1227 return STATUSBAR_IsSimple (hwnd);
1230 return STATUSBAR_SetBkColor (hwnd, wParam, lParam);
1233 return STATUSBAR_SetIcon (hwnd, wParam, lParam);
1235 case SB_SETMINHEIGHT:
1236 return STATUSBAR_SetMinHeight (hwnd, wParam, lParam);
1239 return STATUSBAR_SetParts (hwnd, wParam, lParam);
1242 return STATUSBAR_SetTextA (hwnd, wParam, lParam);
1245 return STATUSBAR_SetTextW (hwnd, wParam, lParam);
1247 case SB_SETTIPTEXTA:
1248 return STATUSBAR_SetTipTextA (hwnd, wParam, lParam);
1250 case SB_SETTIPTEXTW:
1251 return STATUSBAR_SetTipTextW (hwnd, wParam, lParam);
1253 case SB_SETUNICODEFORMAT:
1254 return STATUSBAR_SetUnicodeFormat (hwnd, wParam);
1257 return STATUSBAR_Simple (hwnd, wParam, lParam);
1261 return STATUSBAR_WMCreate (hwnd, wParam, lParam);
1264 return STATUSBAR_WMDestroy (hwnd);
1267 return STATUSBAR_WMGetFont (hwnd);
1270 return STATUSBAR_WMGetText (hwnd, wParam, lParam);
1272 case WM_GETTEXTLENGTH:
1273 return STATUSBAR_GetTextLength (hwnd, 0);
1275 case WM_LBUTTONDBLCLK:
1276 return STATUSBAR_SendNotify (hwnd, NM_DBLCLK);
1279 return STATUSBAR_SendNotify (hwnd, NM_CLICK);
1282 return STATUSBAR_WMMouseMove (hwnd, wParam, lParam);
1285 return STATUSBAR_WMNCHitTest (hwnd, wParam, lParam);
1287 case WM_NCLBUTTONDOWN:
1288 return STATUSBAR_WMNCLButtonDown (hwnd, wParam, lParam);
1290 case WM_NCLBUTTONUP:
1291 return STATUSBAR_WMNCLButtonUp (hwnd, wParam, lParam);
1294 return STATUSBAR_WMPaint (hwnd, wParam);
1296 case WM_RBUTTONDBLCLK:
1297 return STATUSBAR_SendNotify (hwnd, NM_RDBLCLK);
1300 return STATUSBAR_SendNotify (hwnd, NM_RCLICK);
1303 return STATUSBAR_WMSetFont (hwnd, wParam, lParam);
1306 return STATUSBAR_WMSetText (hwnd, wParam, lParam);
1309 return STATUSBAR_WMSize (hwnd, wParam, lParam);
1313 ERR("unknown msg %04x wp=%04x lp=%08lx\n",
1314 msg, wParam, lParam);
1315 return DefWindowProcA (hwnd, msg, wParam, lParam);
1321 /***********************************************************************
1322 * STATUS_Register [Internal]
1324 * Registers the status window class.
1328 STATUS_Register (void)
1332 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
1333 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW;
1334 wndClass.lpfnWndProc = (WNDPROC)StatusWindowProc;
1335 wndClass.cbClsExtra = 0;
1336 wndClass.cbWndExtra = sizeof(STATUSWINDOWINFO *);
1337 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
1338 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
1339 wndClass.lpszClassName = STATUSCLASSNAMEA;
1341 RegisterClassA (&wndClass);
1345 /***********************************************************************
1346 * STATUS_Unregister [Internal]
1348 * Unregisters the status window class.
1352 STATUS_Unregister (void)
1354 UnregisterClassA (STATUSCLASSNAMEA, (HINSTANCE)NULL);