Removed extra output.
[wine/multimedia.git] / dlls / comctl32 / status.c
blob2efee9dbfd1d3733d6a84d439b3a2be1e34c82ee
1 /*
2 * Interface code to StatusWindow widget/control
4 * Copyright 1996 Bruce Milner
5 * Copyright 1998 Eric Kohl
6 */
8 #include "windows.h"
9 #include "commctrl.h"
10 #include "status.h"
11 #include "win.h"
12 #include "debug.h"
15 * Run tests using Waite Group Windows95 API Bible Vol. 1&2
16 * The second cdrom contains executables drawstat.exe,gettext.exe,
17 * simple.exe, getparts.exe, setparts.exe, statwnd.exe
21 * Fixme/Todo
22 * 1) Don't hard code bar to bottom of window, allow CCS_TOP also.
23 * 2) Tooltip support (almost done).
26 #define _MAX(a,b) (((a)>(b))?(a):(b))
27 #define _MIN(a,b) (((a)>(b))?(b):(a))
29 #define HORZ_BORDER 0
30 #define VERT_BORDER 2
31 #define HORZ_GAP 2
33 #define STATUSBAR_GetInfoPtr(wndPtr) ((STATUSWINDOWINFO *)wndPtr->wExtra[0])
36 static void
37 STATUSBAR_DrawSizeGrip (HDC32 hdc, LPRECT32 lpRect)
39 HPEN32 hOldPen;
40 POINT32 pt;
41 INT32 i;
43 pt.x = lpRect->right - 1;
44 pt.y = lpRect->bottom - 1;
46 hOldPen = SelectObject32 (hdc, GetSysColorPen32 (COLOR_3DFACE));
47 MoveToEx32 (hdc, pt.x - 12, pt.y, NULL);
48 LineTo32 (hdc, pt.x, pt.y);
49 LineTo32 (hdc, pt.x, pt.y - 12);
51 pt.x--;
52 pt.y--;
54 SelectObject32 (hdc, GetSysColorPen32 (COLOR_3DSHADOW));
55 for (i = 1; i < 11; i += 4) {
56 MoveToEx32 (hdc, pt.x - i, pt.y, NULL);
57 LineTo32 (hdc, pt.x, pt.y - i);
59 MoveToEx32 (hdc, pt.x - i-1, pt.y, NULL);
60 LineTo32 (hdc, pt.x, pt.y - i-1);
63 SelectObject32 (hdc, GetSysColorPen32 (COLOR_3DHIGHLIGHT));
64 for (i = 3; i < 13; i += 4) {
65 MoveToEx32 (hdc, pt.x - i, pt.y, NULL);
66 LineTo32 (hdc, pt.x, pt.y - i);
69 SelectObject32 (hdc, hOldPen);
73 static void
74 STATUSBAR_DrawPart (HDC32 hdc, STATUSWINDOWPART *part)
76 RECT32 r = part->bound;
77 UINT32 border = BDR_SUNKENOUTER;
79 if (part->style==SBT_POPOUT)
80 border = BDR_RAISEDOUTER;
81 else if (part->style==SBT_NOBORDERS)
82 border = 0;
84 DrawEdge32(hdc, &r, border, BF_RECT|BF_ADJUST);
86 /* draw the icon */
87 if (part->hIcon) {
88 INT32 cy = r.bottom - r.top;
90 r.left += 2;
91 DrawIconEx32 (hdc, r.left, r.top, part->hIcon, cy, cy, 0, 0, DI_NORMAL);
92 r.left += cy;
95 /* now draw text */
96 if (part->text) {
97 int oldbkmode = SetBkMode32(hdc, TRANSPARENT);
98 LPWSTR p = (LPWSTR)part->text;
99 UINT32 align = DT_LEFT;
100 if (*p == L'\t') {
101 p++;
102 align = DT_CENTER;
104 if (*p == L'\t') {
105 p++;
106 align = DT_RIGHT;
109 r.left += 3;
110 DrawText32W (hdc, p, lstrlen32W (p), &r, align|DT_VCENTER|DT_SINGLELINE);
111 if (oldbkmode != TRANSPARENT)
112 SetBkMode32(hdc, oldbkmode);
117 static VOID
118 STATUSBAR_RefreshPart (WND *wndPtr, STATUSWINDOWPART *part, HDC32 hdc)
120 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (wndPtr);
121 HBRUSH32 hbrBk;
122 HFONT32 hOldFont;
124 if (!IsWindowVisible32(wndPtr->hwndSelf))
125 return;
127 if (self->clrBk != CLR_DEFAULT)
128 hbrBk = CreateSolidBrush32 (self->clrBk);
129 else
130 hbrBk = GetSysColorBrush32 (COLOR_3DFACE);
131 FillRect32(hdc, &part->bound, hbrBk);
133 hOldFont = SelectObject32 (hdc, self->hFont ? self->hFont : self->hDefaultFont);
135 if (part->style == SBT_OWNERDRAW) {
136 DRAWITEMSTRUCT32 dis;
138 dis.CtlID = wndPtr->wIDmenu;
139 dis.itemID = -1;
140 dis.hwndItem = wndPtr->hwndSelf;
141 dis.hDC = hdc;
142 dis.rcItem = part->bound;
143 dis.itemData = (INT32)part->text;
144 SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_DRAWITEM,
145 (WPARAM32)wndPtr->wIDmenu, (LPARAM)&dis);
147 else
148 STATUSBAR_DrawPart (hdc, part);
150 SelectObject32 (hdc, hOldFont);
152 if (self->clrBk != CLR_DEFAULT)
153 DeleteObject32 (hbrBk);
155 if (wndPtr->dwStyle & SBARS_SIZEGRIP) {
156 RECT32 rect;
158 GetClientRect32 (wndPtr->hwndSelf, &rect);
159 STATUSBAR_DrawSizeGrip (hdc, &rect);
164 static BOOL32
165 STATUSBAR_Refresh (WND *wndPtr, HDC32 hdc)
167 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (wndPtr);
168 int i;
169 RECT32 rect;
170 HBRUSH32 hbrBk;
171 HFONT32 hOldFont;
173 if (!IsWindowVisible32(wndPtr->hwndSelf))
174 return (TRUE);
176 GetClientRect32 (wndPtr->hwndSelf, &rect);
178 if (self->clrBk != CLR_DEFAULT)
179 hbrBk = CreateSolidBrush32 (self->clrBk);
180 else
181 hbrBk = GetSysColorBrush32 (COLOR_3DFACE);
182 FillRect32(hdc, &rect, hbrBk);
184 hOldFont = SelectObject32 (hdc, self->hFont ? self->hFont : self->hDefaultFont);
186 if (self->simple) {
187 STATUSBAR_DrawPart (hdc, &self->part0);
189 else {
190 for (i = 0; i < self->numParts; i++) {
191 if (self->parts[i].style == SBT_OWNERDRAW) {
192 DRAWITEMSTRUCT32 dis;
194 dis.CtlID = wndPtr->wIDmenu;
195 dis.itemID = -1;
196 dis.hwndItem = wndPtr->hwndSelf;
197 dis.hDC = hdc;
198 dis.rcItem = self->parts[i].bound;
199 dis.itemData = (INT32)self->parts[i].text;
200 SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_DRAWITEM,
201 (WPARAM32)wndPtr->wIDmenu, (LPARAM)&dis);
203 else
204 STATUSBAR_DrawPart (hdc, &self->parts[i]);
208 SelectObject32 (hdc, hOldFont);
210 if (self->clrBk != CLR_DEFAULT)
211 DeleteObject32 (hbrBk);
213 if (wndPtr->dwStyle & SBARS_SIZEGRIP)
214 STATUSBAR_DrawSizeGrip (hdc, &rect);
216 return TRUE;
220 static void
221 STATUSBAR_SetPartBounds (WND *wndPtr)
223 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (wndPtr);
224 STATUSWINDOWPART *part;
225 RECT32 rect, *r;
226 int i;
228 /* get our window size */
229 GetClientRect32 (wndPtr->hwndSelf, &rect);
231 rect.top += VERT_BORDER;
233 /* set bounds for simple rectangle */
234 self->part0.bound = rect;
236 /* set bounds for non-simple rectangles */
237 for (i = 0; i < self->numParts; i++) {
238 part = &self->parts[i];
239 r = &self->parts[i].bound;
240 r->top = rect.top;
241 r->bottom = rect.bottom;
242 if (i == 0)
243 r->left = 0;
244 else
245 r->left = self->parts[i-1].bound.right + HORZ_GAP;
246 if (part->x == -1)
247 r->right = rect.right;
248 else
249 r->right = part->x;
251 if (self->hwndToolTip) {
252 TTTOOLINFO32A ti;
254 ti.cbSize = sizeof(TTTOOLINFO32A);
255 ti.hwnd = wndPtr->hwndSelf;
256 ti.uId = i;
257 ti.rect = *r;
258 SendMessage32A (self->hwndToolTip, TTM_NEWTOOLRECT32A,
259 0, (LPARAM)&ti);
265 static VOID
266 STATUSBAR_RelayEvent (HWND32 hwndTip, HWND32 hwndMsg, UINT32 uMsg,
267 WPARAM32 wParam, LPARAM lParam)
269 MSG32 msg;
271 msg.hwnd = hwndMsg;
272 msg.message = uMsg;
273 msg.wParam = wParam;
274 msg.lParam = lParam;
275 msg.time = GetMessageTime ();
276 msg.pt.x = LOWORD(GetMessagePos ());
277 msg.pt.y = HIWORD(GetMessagePos ());
279 SendMessage32A (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
283 __inline__ static LRESULT
284 STATUSBAR_GetBorders (LPARAM lParam)
286 LPINT32 out = (LPINT32) lParam;
288 out[0] = HORZ_BORDER; /* horizontal border width */
289 out[1] = VERT_BORDER; /* vertical border width */
290 out[2] = HORZ_GAP; /* width of border between rectangles */
292 return TRUE;
296 static LRESULT
297 STATUSBAR_GetIcon (WND *wndPtr, WPARAM32 wParam)
299 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (wndPtr);
300 INT32 nPart;
302 nPart = (INT32)wParam & 0x00ff;
303 if ((nPart < -1) || (nPart >= self->numParts)) return 0;
305 if (nPart == -1)
306 return (self->part0.hIcon);
307 else
308 return (self->parts[nPart].hIcon);
312 static LRESULT
313 STATUSBAR_GetParts (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
315 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (wndPtr);
316 LPINT32 parts;
317 INT32 num_parts;
318 int i;
320 num_parts = (INT32) wParam;
321 parts = (LPINT32) lParam;
322 if (parts) {
323 return (self->numParts);
324 for (i = 0; i < num_parts; i++) {
325 parts[i] = self->parts[i].x;
328 return (self->numParts);
332 static LRESULT
333 STATUSBAR_GetRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
335 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (wndPtr);
336 int part_num;
337 LPRECT32 rect;
339 part_num = ((INT32) wParam) & 0x00ff;
340 rect = (LPRECT32) lParam;
341 if (infoPtr->simple)
342 *rect = infoPtr->part0.bound;
343 else
344 *rect = infoPtr->parts[part_num].bound;
345 return TRUE;
349 static LRESULT
350 STATUSBAR_GetText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
352 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (wndPtr);
353 STATUSWINDOWPART *part;
354 INT32 nPart;
355 LRESULT result;
357 nPart = ((INT32) wParam) & 0x00ff;
358 if (self->simple)
359 part = &self->part0;
360 else
361 part = &self->parts[nPart];
363 if (part->style == SBT_OWNERDRAW)
364 result = (LRESULT)part->text;
365 else {
366 result = part->text ? lstrlen32W (part->text) : 0;
367 result |= (part->style << 16);
368 if (lParam)
369 lstrcpyWtoA ((LPSTR)lParam, part->text);
371 return result;
375 static LRESULT
376 STATUSBAR_GetText32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
378 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (wndPtr);
379 STATUSWINDOWPART *part;
380 INT32 nPart;
381 LRESULT result;
383 nPart = ((INT32)wParam) & 0x00ff;
384 if (self->simple)
385 part = &self->part0;
386 else
387 part = &self->parts[nPart];
389 if (part->style == SBT_OWNERDRAW)
390 result = (LRESULT)part->text;
391 else {
392 result = part->text ? lstrlen32W (part->text) : 0;
393 result |= (part->style << 16);
394 if (lParam)
395 lstrcpy32W ((LPWSTR)lParam, part->text);
397 return result;
401 static LRESULT
402 STATUSBAR_GetTextLength (WND *wndPtr, WPARAM32 wParam)
404 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (wndPtr);
405 STATUSWINDOWPART *part;
406 INT32 part_num;
407 DWORD result;
409 part_num = ((INT32) wParam) & 0x00ff;
411 if (infoPtr->simple)
412 part = &infoPtr->part0;
413 else
414 part = &infoPtr->parts[part_num];
416 if (part->text)
417 result = lstrlen32W(part->text);
418 else
419 result = 0;
421 result |= (part->style << 16);
422 return result;
426 static LRESULT
427 STATUSBAR_GetTipText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
429 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (wndPtr);
431 if (infoPtr->hwndToolTip) {
432 TTTOOLINFO32A ti;
433 ti.cbSize = sizeof(TTTOOLINFO32A);
434 ti.hwnd = wndPtr->hwndSelf;
435 ti.uId = LOWORD(wParam);
436 SendMessage32A (infoPtr->hwndToolTip, TTM_GETTEXT32A, 0, (LPARAM)&ti);
438 if (ti.lpszText)
439 lstrcpyn32A ((LPSTR)lParam, ti.lpszText, HIWORD(wParam));
442 return 0;
446 static LRESULT
447 STATUSBAR_GetTipText32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
449 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (wndPtr);
451 if (infoPtr->hwndToolTip) {
452 TTTOOLINFO32W ti;
453 ti.cbSize = sizeof(TTTOOLINFO32W);
454 ti.hwnd = wndPtr->hwndSelf;
455 ti.uId = LOWORD(wParam);
456 SendMessage32W (infoPtr->hwndToolTip, TTM_GETTEXT32W, 0, (LPARAM)&ti);
458 if (ti.lpszText)
459 lstrcpyn32W ((LPWSTR)lParam, ti.lpszText, HIWORD(wParam));
462 return 0;
466 __inline__ static LRESULT
467 STATUSBAR_GetUnicodeFormat (WND *wndPtr)
469 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (wndPtr);
470 return infoPtr->bUnicode;
474 __inline__ static LRESULT
475 STATUSBAR_IsSimple (WND *wndPtr)
477 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (wndPtr);
478 return infoPtr->simple;
482 static LRESULT
483 STATUSBAR_SetBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
485 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (wndPtr);
486 COLORREF oldBkColor;
487 HDC32 hdc;
489 oldBkColor = self->clrBk;
490 self->clrBk = (COLORREF)lParam;
491 hdc = GetDC32 (wndPtr->hwndSelf);
492 STATUSBAR_Refresh (wndPtr, hdc);
493 ReleaseDC32 (wndPtr->hwndSelf, hdc);
495 return oldBkColor;
499 static LRESULT
500 STATUSBAR_SetIcon (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
502 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (wndPtr);
503 INT32 nPart = (INT32)wParam & 0x00ff;
504 HDC32 hdc;
506 if ((nPart < -1) || (nPart >= self->numParts))
507 return FALSE;
509 hdc = GetDC32 (wndPtr->hwndSelf);
510 if (nPart == -1) {
511 self->part0.hIcon = (HICON32)lParam;
512 if (self->simple)
513 STATUSBAR_RefreshPart (wndPtr, &self->part0, hdc);
515 else {
516 self->parts[nPart].hIcon = (HICON32)lParam;
517 if (!(self->simple))
518 STATUSBAR_RefreshPart (wndPtr, &self->parts[nPart], hdc);
520 ReleaseDC32 (wndPtr->hwndSelf, hdc);
522 return TRUE;
526 static LRESULT
527 STATUSBAR_SetMinHeight (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
529 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (wndPtr);
531 if (IsWindowVisible32 (wndPtr->hwndSelf)) {
532 HWND32 parent = GetParent32 (wndPtr->hwndSelf);
533 INT32 width, x, y;
534 RECT32 parent_rect;
536 GetClientRect32 (parent, &parent_rect);
537 self->height = (INT32)wParam + VERT_BORDER;
538 width = parent_rect.right - parent_rect.left;
539 x = parent_rect.left;
540 y = parent_rect.bottom - self->height;
541 MoveWindow32 (wndPtr->hwndSelf, parent_rect.left,
542 parent_rect.bottom - self->height,
543 width, self->height, TRUE);
544 STATUSBAR_SetPartBounds (wndPtr);
547 return TRUE;
551 static LRESULT
552 STATUSBAR_SetParts (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
554 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (wndPtr);
555 STATUSWINDOWPART *tmp;
556 HDC32 hdc;
557 LPINT32 parts;
558 int i;
559 int oldNumParts;
561 if (self->simple)
562 self->simple = FALSE;
564 oldNumParts = self->numParts;
565 self->numParts = (INT32) wParam;
566 parts = (LPINT32) 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];
578 if (self->parts)
579 COMCTL32_Free (self->parts);
580 self->parts = tmp;
583 for (i = 0; i < self->numParts; i++) {
584 self->parts[i].x = parts[i];
587 if (self->hwndToolTip) {
588 INT32 nTipCount =
589 SendMessage32A (self->hwndToolTip, TTM_GETTOOLCOUNT, 0, 0);
591 if (nTipCount < self->numParts) {
592 /* add tools */
593 TTTOOLINFO32A ti;
594 INT32 i;
596 ZeroMemory (&ti, sizeof(TTTOOLINFO32A));
597 ti.cbSize = sizeof(TTTOOLINFO32A);
598 ti.hwnd = wndPtr->hwndSelf;
599 for (i = nTipCount; i < self->numParts; i++) {
600 TRACE (statusbar, "add tool %d\n", i);
601 ti.uId = i;
602 SendMessage32A (self->hwndToolTip, TTM_ADDTOOL32A,
603 0, (LPARAM)&ti);
606 else if (nTipCount > self->numParts) {
607 /* delete tools */
608 INT32 i;
610 for (i = nTipCount - 1; i >= self->numParts; i--) {
612 FIXME (statusbar, "delete tool %d\n", i);
618 STATUSBAR_SetPartBounds (wndPtr);
620 hdc = GetDC32 (wndPtr->hwndSelf);
621 STATUSBAR_Refresh (wndPtr, hdc);
622 ReleaseDC32 (wndPtr->hwndSelf, hdc);
624 return TRUE;
628 static LRESULT
629 STATUSBAR_SetText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
631 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (wndPtr);
632 STATUSWINDOWPART *part;
633 int part_num;
634 int style;
635 LPSTR text;
636 int len;
637 HDC32 hdc;
639 text = (LPSTR) lParam;
640 part_num = ((INT32) wParam) & 0x00ff;
641 style = ((INT32) wParam) & 0xff00;
643 if ((self->simple) || (self->parts==NULL) || (part_num==255))
644 part = &self->part0;
645 else
646 part = &self->parts[part_num];
647 if (!part) return FALSE;
648 part->style = style;
649 if (style == SBT_OWNERDRAW) {
650 part->text = (LPWSTR)text;
652 else {
653 /* duplicate string */
654 if (part->text)
655 COMCTL32_Free (part->text);
656 part->text = 0;
657 if (text && (len = lstrlen32A(text))) {
658 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
659 lstrcpyAtoW (part->text, text);
663 hdc = GetDC32 (wndPtr->hwndSelf);
664 STATUSBAR_RefreshPart (wndPtr, part, hdc);
665 ReleaseDC32 (wndPtr->hwndSelf, hdc);
667 return TRUE;
671 static LRESULT
672 STATUSBAR_SetText32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
674 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (wndPtr);
675 STATUSWINDOWPART *part;
676 INT32 part_num, style, len;
677 LPWSTR text;
678 HDC32 hdc;
680 text = (LPWSTR) lParam;
681 part_num = ((INT32) wParam) & 0x00ff;
682 style = ((INT32) wParam) & 0xff00;
684 if ((self->simple) || (self->parts==NULL) || (part_num==255))
685 part = &self->part0;
686 else
687 part = &self->parts[part_num];
688 if (!part) return FALSE;
689 part->style = style;
690 if (style == SBT_OWNERDRAW) {
691 part->text = text;
693 else {
694 /* duplicate string */
695 if (part->text)
696 COMCTL32_Free (part->text);
697 part->text = 0;
698 if (text && (len = lstrlen32W(text))) {
699 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
700 lstrcpy32W(part->text, text);
704 hdc = GetDC32 (wndPtr->hwndSelf);
705 STATUSBAR_RefreshPart (wndPtr, part, hdc);
706 ReleaseDC32 (wndPtr->hwndSelf, hdc);
708 return TRUE;
712 static LRESULT
713 STATUSBAR_SetTipText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
715 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (wndPtr);
717 TRACE (statusbar, "part %d: \"%s\"\n", (INT32)wParam, (LPSTR)lParam);
718 if (infoPtr->hwndToolTip) {
719 TTTOOLINFO32A ti;
720 ti.cbSize = sizeof(TTTOOLINFO32A);
721 ti.hwnd = wndPtr->hwndSelf;
722 ti.uId = (INT32)wParam;
723 ti.hinst = 0;
724 ti.lpszText = (LPSTR)lParam;
725 SendMessage32A (infoPtr->hwndToolTip, TTM_UPDATETIPTEXT32A,
726 0, (LPARAM)&ti);
729 return 0;
733 static LRESULT
734 STATUSBAR_SetTipText32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
736 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (wndPtr);
738 TRACE (statusbar, "part %d: \"%s\"\n", (INT32)wParam, (LPSTR)lParam);
739 if (infoPtr->hwndToolTip) {
740 TTTOOLINFO32W ti;
741 ti.cbSize = sizeof(TTTOOLINFO32W);
742 ti.hwnd = wndPtr->hwndSelf;
743 ti.uId = (INT32)wParam;
744 ti.hinst = 0;
745 ti.lpszText = (LPWSTR)lParam;
746 SendMessage32W (infoPtr->hwndToolTip, TTM_UPDATETIPTEXT32W,
747 0, (LPARAM)&ti);
750 return 0;
754 __inline__ static LRESULT
755 STATUSBAR_SetUnicodeFormat (WND *wndPtr, WPARAM32 wParam)
757 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (wndPtr);
758 BOOL32 bTemp = infoPtr->bUnicode;
760 TRACE (statusbar, "(0x%x)\n", (BOOL32)wParam);
761 infoPtr->bUnicode = (BOOL32)wParam;
763 return bTemp;
767 static LRESULT
768 STATUSBAR_Simple (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
770 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (wndPtr);
771 HDC32 hdc;
772 NMHDR nmhdr;
774 infoPtr->simple = (BOOL32)wParam;
776 /* send notification */
777 nmhdr.hwndFrom = wndPtr->hwndSelf;
778 nmhdr.idFrom = wndPtr->wIDmenu;
779 nmhdr.code = SBN_SIMPLEMODECHANGE;
780 SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
781 0, (LPARAM)&nmhdr);
783 hdc = GetDC32 (wndPtr->hwndSelf);
784 STATUSBAR_Refresh (wndPtr, hdc);
785 ReleaseDC32 (wndPtr->hwndSelf, hdc);
787 return TRUE;
791 static LRESULT
792 STATUSBAR_WMCreate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
794 LPCREATESTRUCT32A lpCreate = (LPCREATESTRUCT32A)lParam;
795 NONCLIENTMETRICS32A nclm;
796 RECT32 rect;
797 int width, len;
798 HDC32 hdc;
799 STATUSWINDOWINFO *self;
801 self = (STATUSWINDOWINFO*)COMCTL32_Alloc (sizeof(STATUSWINDOWINFO));
802 wndPtr->wExtra[0] = (DWORD)self;
804 self->numParts = 1;
805 self->parts = 0;
806 self->simple = FALSE;
807 self->clrBk = CLR_DEFAULT;
808 self->hFont = 0;
809 GetClientRect32 (wndPtr->hwndSelf, &rect);
811 nclm.cbSize = sizeof(NONCLIENTMETRICS32A);
812 SystemParametersInfo32A (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
813 self->hDefaultFont = CreateFontIndirect32A (&nclm.lfStatusFont);
815 /* initialize simple case */
816 self->part0.bound = rect;
817 self->part0.text = 0;
818 self->part0.x = 0;
819 self->part0.style = 0;
820 self->part0.hIcon = 0;
822 /* initialize first part */
823 self->parts = COMCTL32_Alloc (sizeof(STATUSWINDOWPART));
824 self->parts[0].bound = rect;
825 self->parts[0].text = 0;
826 self->parts[0].x = -1;
827 self->parts[0].style = 0;
828 self->parts[0].hIcon = 0;
830 if (IsWindowUnicode (wndPtr->hwndSelf)) {
831 self->bUnicode = TRUE;
832 if ((len = lstrlen32W ((LPCWSTR)lpCreate->lpszName))) {
833 self->parts[0].text = COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
834 lstrcpy32W (self->parts[0].text, (LPCWSTR)lpCreate->lpszName);
837 else {
838 if ((len = lstrlen32A ((LPCSTR)lpCreate->lpszName))) {
839 self->parts[0].text = COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
840 lstrcpyAtoW (self->parts[0].text, (LPCSTR)lpCreate->lpszName);
844 if ((hdc = GetDC32 (0))) {
845 TEXTMETRIC32A tm;
846 HFONT32 hOldFont;
848 hOldFont = SelectObject32 (hdc,self->hDefaultFont);
849 GetTextMetrics32A(hdc, &tm);
850 self->textHeight = tm.tmHeight;
851 SelectObject32 (hdc, hOldFont);
852 ReleaseDC32(0, hdc);
855 if (wndPtr->dwStyle & SBT_TOOLTIPS) {
856 self->hwndToolTip =
857 CreateWindowEx32A (0, TOOLTIPS_CLASS32A, NULL, 0,
858 CW_USEDEFAULT32, CW_USEDEFAULT32,
859 CW_USEDEFAULT32, CW_USEDEFAULT32,
860 wndPtr->hwndSelf, 0,
861 wndPtr->hInstance, NULL);
863 if (self->hwndToolTip) {
864 NMTOOLTIPSCREATED nmttc;
866 nmttc.hdr.hwndFrom = wndPtr->hwndSelf;
867 nmttc.hdr.idFrom = wndPtr->wIDmenu;
868 nmttc.hdr.code = NM_TOOLTIPSCREATED;
869 nmttc.hwndToolTips = self->hwndToolTip;
871 SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
872 (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmttc);
876 GetClientRect32 (GetParent32 (wndPtr->hwndSelf), &rect);
877 width = rect.right - rect.left;
878 self->height = self->textHeight + 4 + VERT_BORDER;
879 MoveWindow32 (wndPtr->hwndSelf, lpCreate->x, lpCreate->y-1,
880 width, self->height, FALSE);
881 STATUSBAR_SetPartBounds (wndPtr);
883 return 0;
887 static LRESULT
888 STATUSBAR_WMDestroy (WND *wndPtr)
890 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (wndPtr);
891 int i;
893 for (i = 0; i < self->numParts; i++) {
894 if (self->parts[i].text && (self->parts[i].style != SBT_OWNERDRAW))
895 COMCTL32_Free (self->parts[i].text);
897 if (self->part0.text && (self->part0.style != SBT_OWNERDRAW))
898 COMCTL32_Free (self->part0.text);
899 COMCTL32_Free (self->parts);
901 /* delete default font */
902 if (self->hDefaultFont)
903 DeleteObject32 (self->hDefaultFont);
905 /* delete tool tip control */
906 if (self->hwndToolTip)
907 DestroyWindow32 (self->hwndToolTip);
909 COMCTL32_Free (self);
911 return 0;
915 static __inline__ LRESULT
916 STATUSBAR_WMGetFont (WND *wndPtr)
918 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (wndPtr);
919 return infoPtr->hFont;
923 static LRESULT
924 STATUSBAR_WMGetText (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
926 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (wndPtr);
927 INT32 len;
929 if (!(infoPtr->parts[0].text))
930 return 0;
931 len = lstrlen32W (infoPtr->parts[0].text);
932 if (wParam > len) {
933 if (infoPtr->bUnicode)
934 lstrcpy32W ((LPWSTR)lParam, infoPtr->parts[0].text);
935 else
936 lstrcpyWtoA ((LPSTR)lParam, infoPtr->parts[0].text);
937 return len;
940 return -1;
944 __inline__ static LRESULT
945 STATUSBAR_WMMouseMove (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
947 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (wndPtr);
949 if (infoPtr->hwndToolTip)
950 STATUSBAR_RelayEvent (infoPtr->hwndToolTip, wndPtr->hwndSelf,
951 WM_MOUSEMOVE, wParam, lParam);
952 return 0;
956 static LRESULT
957 STATUSBAR_WMNCHitTest (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
959 if (wndPtr->dwStyle & SBARS_SIZEGRIP) {
960 RECT32 rect;
961 POINT32 pt;
963 GetClientRect32 (wndPtr->hwndSelf, &rect);
965 pt.x = (INT32)LOWORD(lParam);
966 pt.y = (INT32)HIWORD(lParam);
967 ScreenToClient32 (wndPtr->hwndSelf, &pt);
969 rect.left = rect.right - 13;
970 rect.top += 2;
972 if (PtInRect32 (&rect, pt))
973 return HTBOTTOMRIGHT;
976 return DefWindowProc32A (wndPtr->hwndSelf, WM_NCHITTEST, wParam, lParam);
980 static __inline__ LRESULT
981 STATUSBAR_WMNCLButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
983 PostMessage32A (wndPtr->parent->hwndSelf, WM_NCLBUTTONDOWN,
984 wParam, lParam);
985 return 0;
989 static __inline__ LRESULT
990 STATUSBAR_WMNCLButtonUp (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
992 PostMessage32A (wndPtr->parent->hwndSelf, WM_NCLBUTTONUP,
993 wParam, lParam);
994 return 0;
998 static LRESULT
999 STATUSBAR_WMPaint (WND *wndPtr, WPARAM32 wParam)
1001 HDC32 hdc;
1002 PAINTSTRUCT32 ps;
1004 hdc = wParam==0 ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam;
1005 STATUSBAR_Refresh (wndPtr, hdc);
1006 if (!wParam)
1007 EndPaint32 (wndPtr->hwndSelf, &ps);
1009 return 0;
1013 static LRESULT
1014 STATUSBAR_WMSetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1016 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (wndPtr);
1018 infoPtr->hFont = (HFONT32)wParam;
1019 if (LOWORD(lParam) == TRUE) {
1020 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
1021 STATUSBAR_Refresh (wndPtr, hdc);
1022 ReleaseDC32 (wndPtr->hwndSelf, hdc);
1025 return 0;
1029 static LRESULT
1030 STATUSBAR_WMSetText (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1032 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (wndPtr);
1033 STATUSWINDOWPART *part;
1034 int len;
1035 HDC32 hdc;
1037 if (infoPtr->numParts == 0)
1038 return FALSE;
1040 part = &infoPtr->parts[0];
1041 /* duplicate string */
1042 if (part->text)
1043 COMCTL32_Free (part->text);
1044 part->text = 0;
1045 if (infoPtr->bUnicode) {
1046 if (lParam && (len = lstrlen32W((LPCWSTR)lParam))) {
1047 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1048 lstrcpy32W (part->text, (LPCWSTR)lParam);
1051 else {
1052 if (lParam && (len = lstrlen32A((LPCSTR)lParam))) {
1053 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1054 lstrcpyAtoW (part->text, (LPCSTR)lParam);
1058 hdc = GetDC32 (wndPtr->hwndSelf);
1059 STATUSBAR_RefreshPart (wndPtr, part, hdc);
1060 ReleaseDC32 (wndPtr->hwndSelf, hdc);
1062 return TRUE;
1066 static LRESULT
1067 STATUSBAR_WMSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1069 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (wndPtr);
1070 INT32 width, x, y, flags;
1071 RECT32 parent_rect;
1072 HWND32 parent;
1074 /* Need to resize width to match parent */
1075 flags = (INT32) wParam;
1077 /* FIXME for flags =
1078 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED, SIZE_RESTORED
1081 if (flags == SIZE_RESTORED) {
1082 /* width and height don't apply */
1083 parent = GetParent32 (wndPtr->hwndSelf);
1084 GetClientRect32 (parent, &parent_rect);
1085 width = parent_rect.right - parent_rect.left;
1086 x = parent_rect.left;
1087 y = parent_rect.bottom - infoPtr->height;
1088 MoveWindow32 (wndPtr->hwndSelf, parent_rect.left,
1089 parent_rect.bottom - infoPtr->height,
1090 width, infoPtr->height, TRUE);
1091 STATUSBAR_SetPartBounds (wndPtr);
1093 return 0;
1097 static LRESULT
1098 STATUSBAR_SendNotify (WND *wndPtr, UINT32 code)
1100 NMHDR nmhdr;
1102 nmhdr.hwndFrom = wndPtr->hwndSelf;
1103 nmhdr.idFrom = wndPtr->wIDmenu;
1104 nmhdr.code = code;
1105 SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
1106 0, (LPARAM)&nmhdr);
1107 return 0;
1112 LRESULT WINAPI
1113 StatusWindowProc (HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
1115 WND *wndPtr = WIN_FindWndPtr (hwnd);
1117 switch (msg) {
1118 case SB_GETBORDERS:
1119 return STATUSBAR_GetBorders (lParam);
1121 case SB_GETICON:
1122 return STATUSBAR_GetIcon (wndPtr, wParam);
1124 case SB_GETPARTS:
1125 return STATUSBAR_GetParts (wndPtr, wParam, lParam);
1127 case SB_GETRECT:
1128 return STATUSBAR_GetRect (wndPtr, wParam, lParam);
1130 case SB_GETTEXT32A:
1131 return STATUSBAR_GetText32A (wndPtr, wParam, lParam);
1133 case SB_GETTEXT32W:
1134 return STATUSBAR_GetText32W (wndPtr, wParam, lParam);
1136 case SB_GETTEXTLENGTH32A:
1137 case SB_GETTEXTLENGTH32W:
1138 return STATUSBAR_GetTextLength (wndPtr, wParam);
1140 case SB_GETTIPTEXT32A:
1141 return STATUSBAR_GetTipText32A (wndPtr, wParam, lParam);
1143 case SB_GETTIPTEXT32W:
1144 return STATUSBAR_GetTipText32W (wndPtr, wParam, lParam);
1146 case SB_GETUNICODEFORMAT:
1147 return STATUSBAR_GetUnicodeFormat (wndPtr);
1149 case SB_ISSIMPLE:
1150 return STATUSBAR_IsSimple (wndPtr);
1152 case SB_SETBKCOLOR:
1153 return STATUSBAR_SetBkColor (wndPtr, wParam, lParam);
1155 case SB_SETICON:
1156 return STATUSBAR_SetIcon (wndPtr, wParam, lParam);
1158 case SB_SETMINHEIGHT:
1159 return STATUSBAR_SetMinHeight (wndPtr, wParam, lParam);
1161 case SB_SETPARTS:
1162 return STATUSBAR_SetParts (wndPtr, wParam, lParam);
1164 case SB_SETTEXT32A:
1165 return STATUSBAR_SetText32A (wndPtr, wParam, lParam);
1167 case SB_SETTEXT32W:
1168 return STATUSBAR_SetText32W (wndPtr, wParam, lParam);
1170 case SB_SETTIPTEXT32A:
1171 return STATUSBAR_SetTipText32A (wndPtr, wParam, lParam);
1173 case SB_SETTIPTEXT32W:
1174 return STATUSBAR_SetTipText32W (wndPtr, wParam, lParam);
1176 case SB_SETUNICODEFORMAT:
1177 return STATUSBAR_SetUnicodeFormat (wndPtr, wParam);
1179 case SB_SIMPLE:
1180 return STATUSBAR_Simple (wndPtr, wParam, lParam);
1183 case WM_CREATE:
1184 return STATUSBAR_WMCreate (wndPtr, wParam, lParam);
1186 case WM_DESTROY:
1187 return STATUSBAR_WMDestroy (wndPtr);
1189 case WM_GETFONT:
1190 return STATUSBAR_WMGetFont (wndPtr);
1192 case WM_GETTEXT:
1193 return STATUSBAR_WMGetText (wndPtr, wParam, lParam);
1195 case WM_GETTEXTLENGTH:
1196 return STATUSBAR_GetTextLength (wndPtr, 0);
1198 case WM_LBUTTONDBLCLK:
1199 return STATUSBAR_SendNotify (wndPtr, NM_DBLCLK);
1201 case WM_LBUTTONUP:
1202 return STATUSBAR_SendNotify (wndPtr, NM_CLICK);
1204 case WM_MOUSEMOVE:
1205 return STATUSBAR_WMMouseMove (wndPtr, wParam, lParam);
1207 case WM_NCHITTEST:
1208 return STATUSBAR_WMNCHitTest (wndPtr, wParam, lParam);
1210 case WM_NCLBUTTONDOWN:
1211 return STATUSBAR_WMNCLButtonDown (wndPtr, wParam, lParam);
1213 case WM_NCLBUTTONUP:
1214 return STATUSBAR_WMNCLButtonUp (wndPtr, wParam, lParam);
1216 case WM_PAINT:
1217 return STATUSBAR_WMPaint (wndPtr, wParam);
1219 case WM_RBUTTONDBLCLK:
1220 return STATUSBAR_SendNotify (wndPtr, NM_RDBLCLK);
1222 case WM_RBUTTONUP:
1223 return STATUSBAR_SendNotify (wndPtr, NM_RCLICK);
1225 case WM_SETFONT:
1226 return STATUSBAR_WMSetFont (wndPtr, wParam, lParam);
1228 case WM_SETTEXT:
1229 return STATUSBAR_WMSetText (wndPtr, wParam, lParam);
1231 case WM_SIZE:
1232 return STATUSBAR_WMSize (wndPtr, wParam, lParam);
1234 default:
1235 if (msg >= WM_USER)
1236 ERR (statusbar, "unknown msg %04x wp=%04x lp=%08lx\n",
1237 msg, wParam, lParam);
1238 return DefWindowProc32A (hwnd, msg, wParam, lParam);
1240 return 0;
1244 /***********************************************************************
1245 * STATUS_Register [Internal]
1247 * Registers the status window class.
1250 VOID
1251 STATUS_Register (VOID)
1253 WNDCLASS32A wndClass;
1255 if (GlobalFindAtom32A (STATUSCLASSNAME32A)) return;
1257 ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
1258 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW;
1259 wndClass.lpfnWndProc = (WNDPROC32)StatusWindowProc;
1260 wndClass.cbClsExtra = 0;
1261 wndClass.cbWndExtra = sizeof(STATUSWINDOWINFO *);
1262 wndClass.hCursor = LoadCursor32A (0, IDC_ARROW32A);
1263 wndClass.hbrBackground = (HBRUSH32)(COLOR_3DFACE + 1);
1264 wndClass.lpszClassName = STATUSCLASSNAME32A;
1266 RegisterClass32A (&wndClass);
1270 /***********************************************************************
1271 * STATUS_Unregister [Internal]
1273 * Unregisters the status window class.
1276 VOID
1277 STATUS_Unregister (VOID)
1279 if (GlobalFindAtom32A (STATUSCLASSNAME32A))
1280 UnregisterClass32A (STATUSCLASSNAME32A, (HINSTANCE32)NULL);