source: trunk/src/comctl32/status.cpp@ 3154

Last change on this file since 3154 was 3154, checked in by cbratschi, 25 years ago

Corel 20000317 merge, ccbase finished, bug fixes

File size: 31.1 KB
Line 
1/* $Id: status.cpp,v 1.2 2000-03-18 16:17:29 cbratschi Exp $ */
2/*
3 * Interface code to StatusWindow widget/control
4 *
5 * Copyright 1996 Bruce Milner
6 * Copyright 1998, 1999 Eric Kohl
7 * Copyright 1999 Achim Hasenmueller
8 * Copyright 1999 Christoph Bratschi
9 */
10
11/* WINE 990923 level */
12
13#include "winbase.h"
14#include "commctrl.h"
15#include "comctl32.h"
16#include "ccbase.h"
17#include "status.h"
18#include <string.h>
19
20/*
21 * Run tests using Waite Group Windows95 API Bible Vol. 1&2
22 * The second cdrom contains executables drawstat.exe,gettext.exe,
23 * simple.exe, getparts.exe, setparts.exe, statwnd.exe
24 */
25
26/*
27 * Fixme/Todo
28 * 1) Don't hard code bar to bottom of window, allow CCS_TOP also.
29 * 2) Tooltip support (almost done).
30 */
31
32/* CB: Odin problems
33 - DrawText: DT_VCENTER doesn't work (DT_SINGLELINE bug?)
34*/
35
36#define _MAX(a,b) (((a)>(b))?(a):(b))
37#define _MIN(a,b) (((a)>(b))?(b):(a))
38
39#define HORZ_BORDER 0
40#define VERT_BORDER 2
41#define VERT_SPACE 2 //space between border and text
42#define HORZ_GAP 2
43#define TOP_MARGIN 2
44#define ICON_SPACE 2
45#define TEXT_SPACE 3
46
47#define STATUSBAR_GetInfoPtr(hwnd) ((STATUSWINDOWINFO*)getInfoPtr(hwnd))
48
49
50static RECT STATUSBAR_GetSizeBox(HWND hwnd)
51{
52 RECT rect;
53
54 GetClientRect(hwnd,&rect);
55 rect.left = rect.right-GetSystemMetrics(SM_CXVSCROLL);
56 rect.top = rect.bottom-GetSystemMetrics(SM_CYHSCROLL);
57
58 return rect;
59}
60
61static void
62STATUSBAR_DrawSizeGrip (HDC hdc, LPRECT lpRect)
63{
64 HPEN hOldPen;
65 POINT pt;
66 INT i;
67
68 pt.x = lpRect->right - 1;
69 pt.y = lpRect->bottom - 1;
70
71 hOldPen = SelectObject (hdc, GetSysColorPen (COLOR_3DFACE));
72 MoveToEx (hdc, pt.x - 12, pt.y, NULL);
73 LineTo (hdc, pt.x, pt.y);
74 LineTo (hdc, pt.x, pt.y - 12);
75
76 pt.x--;
77 pt.y--;
78
79 SelectObject (hdc, GetSysColorPen (COLOR_3DSHADOW));
80 for (i = 1; i < 11; i += 4) {
81 MoveToEx (hdc, pt.x - i, pt.y, NULL);
82 LineTo (hdc, pt.x, pt.y - i);
83
84 MoveToEx (hdc, pt.x - i-1, pt.y, NULL);
85 LineTo (hdc, pt.x, pt.y - i-1);
86 }
87
88 SelectObject (hdc, GetSysColorPen (COLOR_3DHIGHLIGHT));
89 for (i = 3; i < 13; i += 4) {
90 MoveToEx (hdc, pt.x - i, pt.y, NULL);
91 LineTo (hdc, pt.x, pt.y - i);
92 }
93
94 SelectObject (hdc, hOldPen);
95}
96
97
98static void
99STATUSBAR_DrawPart (HDC hdc, STATUSWINDOWPART *part)
100{
101 RECT r = part->bound;
102 UINT border = BDR_SUNKENOUTER;
103
104 if (part->style & SBT_POPOUT)
105 border = BDR_RAISEDOUTER;
106 else if (part->style & SBT_NOBORDERS)
107 border = 0;
108
109 DrawEdge(hdc, &r, border, BF_RECT|BF_ADJUST);
110
111 r.bottom -= VERT_SPACE;
112 r.top += VERT_SPACE;
113
114 /* draw the icon */
115 if (part->hIcon) {
116 INT cy = r.bottom - r.top;
117
118 r.left += ICON_SPACE;
119 DrawIconEx (hdc, r.left, r.top, part->hIcon, cy, cy, 0, 0, DI_NORMAL);
120 r.left += cy;
121 }
122
123 /* now draw text */
124 if (part->text) {
125 int oldbkmode = SetBkMode(hdc, TRANSPARENT);
126 LPWSTR p = (LPWSTR)part->text;
127 UINT align = DT_LEFT;
128 if (*p == L'\t') {
129 p++;
130 align = DT_CENTER;
131
132 if (*p == L'\t') {
133 p++;
134 align = DT_RIGHT;
135 }
136 }
137 r.left += TEXT_SPACE;
138 DrawTextW (hdc, p, lstrlenW (p), &r, align|DT_VCENTER|DT_SINGLELINE);
139 if (oldbkmode != TRANSPARENT)
140 SetBkMode(hdc, oldbkmode);
141 }
142}
143
144
145static VOID
146STATUSBAR_RefreshPart (HWND hwnd, STATUSWINDOWPART *part, HDC hdc)
147{
148 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
149 HBRUSH hbrBk;
150 HFONT hOldFont;
151
152 if (!IsWindowVisible (hwnd))
153 return;
154
155 if (self->clrBk != CLR_DEFAULT)
156 hbrBk = CreateSolidBrush (self->clrBk);
157 else
158 hbrBk = GetSysColorBrush (COLOR_3DFACE);
159 FillRect(hdc, &part->bound, hbrBk);
160
161 hOldFont = SelectObject (hdc, self->hFont ? self->hFont : self->hDefaultFont);
162
163 if (part->style & SBT_OWNERDRAW) {
164 DRAWITEMSTRUCT dis;
165
166 dis.CtlID = GetWindowLongA (hwnd, GWL_ID);
167 dis.itemID = -1;
168 dis.hwndItem = hwnd;
169 dis.hDC = hdc;
170 dis.rcItem = part->bound;
171 dis.itemData = (INT)part->text;
172 SendMessageA (GetParent (hwnd), WM_DRAWITEM,
173 (WPARAM)dis.CtlID, (LPARAM)&dis);
174 }
175 else
176 STATUSBAR_DrawPart (hdc, part);
177
178 SelectObject (hdc, hOldFont);
179
180 if (self->clrBk != CLR_DEFAULT)
181 DeleteObject (hbrBk);
182
183 if (GetWindowLongA (hwnd, GWL_STYLE) & SBARS_SIZEGRIP) {
184 RECT rect;
185
186 GetClientRect (hwnd, &rect);
187 STATUSBAR_DrawSizeGrip (hdc, &rect);
188 }
189}
190
191
192static BOOL
193STATUSBAR_Refresh (HWND hwnd, HDC hdc)
194{
195 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
196 int i;
197 RECT rect;
198 HBRUSH hbrBk;
199 HFONT hOldFont;
200
201 if (!IsWindowVisible(hwnd))
202 return (TRUE);
203
204 GetClientRect (hwnd, &rect);
205
206 if (infoPtr->clrBk != CLR_DEFAULT)
207 hbrBk = CreateSolidBrush (infoPtr->clrBk);
208 else
209 hbrBk = GetSysColorBrush (COLOR_3DFACE);
210 FillRect(hdc, &rect, hbrBk);
211
212 hOldFont = SelectObject (hdc, infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont);
213
214 if (infoPtr->simple) {
215 STATUSBAR_DrawPart (hdc, &infoPtr->part0);
216 }
217 else {
218 for (i = 0; i < infoPtr->numParts; i++) {
219 if (infoPtr->parts[i].style & SBT_OWNERDRAW) {
220 DRAWITEMSTRUCT dis;
221
222 dis.CtlID = GetWindowLongA (hwnd, GWL_ID);
223 dis.itemID = -1;
224 dis.hwndItem = hwnd;
225 dis.hDC = hdc;
226 dis.rcItem = infoPtr->parts[i].bound;
227 dis.itemData = (INT)infoPtr->parts[i].text;
228 SendMessageA (GetParent (hwnd), WM_DRAWITEM,
229 (WPARAM)dis.CtlID, (LPARAM)&dis);
230 }
231 else
232 STATUSBAR_DrawPart (hdc, &infoPtr->parts[i]);
233 }
234 }
235
236 SelectObject (hdc, hOldFont);
237
238 if (infoPtr->clrBk != CLR_DEFAULT)
239 DeleteObject (hbrBk);
240
241 if (GetWindowLongA(hwnd, GWL_STYLE) & SBARS_SIZEGRIP)
242 STATUSBAR_DrawSizeGrip (hdc, &rect);
243
244 return TRUE;
245}
246
247
248static void
249STATUSBAR_SetPartBounds (HWND hwnd)
250{
251 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
252 STATUSWINDOWPART *part;
253 RECT rect, *r;
254 int i;
255
256 /* get our window size */
257 GetClientRect (hwnd, &rect);
258
259 rect.top += TOP_MARGIN;
260
261 /* set bounds for simple rectangle */
262 self->part0.bound = rect;
263
264 /* set bounds for non-simple rectangles */
265 for (i = 0; i < self->numParts; i++) {
266 part = &self->parts[i];
267 r = &self->parts[i].bound;
268 r->top = rect.top;
269 r->bottom = rect.bottom;
270 if (i == 0)
271 r->left = 0;
272 else
273 r->left = self->parts[i-1].bound.right + HORZ_GAP;
274 if (part->x == -1)
275 r->right = rect.right;
276 else
277 r->right = part->x;
278
279 if (self->hwndToolTip) {
280 TTTOOLINFOA ti;
281
282 ti.cbSize = sizeof(TTTOOLINFOA);
283 ti.hwnd = hwnd;
284 ti.uId = i;
285 ti.rect = *r;
286 SendMessageA (self->hwndToolTip, TTM_NEWTOOLRECTA,
287 0, (LPARAM)&ti);
288 }
289 }
290}
291
292
293static VOID
294STATUSBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
295 WPARAM wParam, LPARAM lParam)
296{
297 MSG msg;
298
299 msg.hwnd = hwndMsg;
300 msg.message = uMsg;
301 msg.wParam = wParam;
302 msg.lParam = lParam;
303 msg.time = GetMessageTime ();
304 msg.pt.x = LOWORD(GetMessagePos ());
305 msg.pt.y = HIWORD(GetMessagePos ());
306
307 SendMessageA (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
308}
309
310
311static LRESULT
312STATUSBAR_GetBorders (LPARAM lParam)
313{
314 LPINT out = (LPINT) lParam;
315
316 out[0] = HORZ_BORDER; /* horizontal border width */
317 out[1] = VERT_BORDER; /* vertical border width */
318 out[2] = HORZ_GAP; /* width of border between rectangles */
319
320 return TRUE;
321}
322
323
324static LRESULT
325STATUSBAR_GetIcon (HWND hwnd, WPARAM wParam)
326{
327 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
328 INT nPart;
329
330 nPart = (INT)wParam & 0x00ff;
331 if ((nPart < -1) || (nPart >= self->numParts))
332 return 0;
333
334 if (nPart == -1)
335 return (self->part0.hIcon);
336 else
337 return (self->parts[nPart].hIcon);
338}
339
340
341static LRESULT
342STATUSBAR_GetParts (HWND hwnd, WPARAM wParam, LPARAM lParam)
343{
344 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
345 LPINT parts;
346 INT num_parts;
347 INT i;
348
349 num_parts = (INT) wParam;
350 parts = (LPINT) lParam;
351 if (parts) {
352 return (infoPtr->numParts);
353 for (i = 0; i < num_parts; i++) {
354 parts[i] = infoPtr->parts[i].x;
355 }
356 }
357 return (infoPtr->numParts);
358}
359
360
361static LRESULT
362STATUSBAR_GetRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
363{
364 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
365 int part_num;
366 LPRECT rect;
367
368 part_num = ((INT) wParam) & 0x00ff;
369 rect = (LPRECT) lParam;
370 if (infoPtr->simple)
371 *rect = infoPtr->part0.bound;
372 else
373 *rect = infoPtr->parts[part_num].bound;
374 return TRUE;
375}
376
377
378static LRESULT
379STATUSBAR_GetTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
380{
381 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
382 STATUSWINDOWPART *part;
383 INT nPart;
384 LRESULT result;
385
386 nPart = ((INT) wParam) & 0x00ff;
387 if (self->simple)
388 part = &self->part0;
389 else
390 part = &self->parts[nPart];
391
392 if (part->style & SBT_OWNERDRAW)
393 result = (LRESULT)part->text;
394 else {
395 result = part->text ? lstrlenW (part->text) : 0;
396 result |= (part->style << 16);
397 if (lParam && LOWORD(result))
398 lstrcpyWtoA((LPSTR)lParam, part->text);
399 }
400 return result;
401}
402
403
404static LRESULT
405STATUSBAR_GetTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
406{
407 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
408 STATUSWINDOWPART *part;
409 INT nPart;
410 LRESULT result;
411
412 nPart = ((INT)wParam) & 0x00ff;
413 if (infoPtr->simple)
414 part = &infoPtr->part0;
415 else
416 part = &infoPtr->parts[nPart];
417
418 if (part->style & SBT_OWNERDRAW)
419 result = (LRESULT)part->text;
420 else {
421 result = part->text ? lstrlenW (part->text) : 0;
422 result |= (part->style << 16);
423 if (lParam)
424 lstrcpyW ((LPWSTR)lParam, part->text);
425 }
426 return result;
427}
428
429
430static LRESULT
431STATUSBAR_GetTextLength (HWND hwnd, WPARAM wParam)
432{
433 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
434 STATUSWINDOWPART *part;
435 INT part_num;
436 DWORD result;
437
438 part_num = ((INT) wParam) & 0x00ff;
439
440 if (infoPtr->simple)
441 part = &infoPtr->part0;
442 else
443 part = &infoPtr->parts[part_num];
444
445 if (part->text)
446 result = lstrlenW(part->text);
447 else
448 result = 0;
449
450 result |= (part->style << 16);
451 return result;
452}
453
454
455static LRESULT
456STATUSBAR_GetTipTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
457{
458 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
459
460 if (infoPtr->hwndToolTip) {
461 TTTOOLINFOA ti;
462 ti.cbSize = sizeof(TTTOOLINFOA);
463 ti.hwnd = hwnd;
464 ti.uId = LOWORD(wParam);
465 SendMessageA (infoPtr->hwndToolTip, TTM_GETTEXTA, 0, (LPARAM)&ti);
466
467 if (ti.lpszText)
468 lstrcpynA ((LPSTR)lParam, ti.lpszText, HIWORD(wParam));
469 }
470
471 return 0;
472}
473
474
475static LRESULT
476STATUSBAR_GetTipTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
477{
478 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
479
480 if (infoPtr->hwndToolTip) {
481 TTTOOLINFOW ti;
482 ti.cbSize = sizeof(TTTOOLINFOW);
483 ti.hwnd = hwnd;
484 ti.uId = LOWORD(wParam);
485 SendMessageW (infoPtr->hwndToolTip, TTM_GETTEXTW, 0, (LPARAM)&ti);
486
487 if (ti.lpszText)
488 lstrcpynW ((LPWSTR)lParam, ti.lpszText, HIWORD(wParam));
489 }
490
491 return 0;
492}
493
494static LRESULT
495STATUSBAR_IsSimple (HWND hwnd)
496{
497 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
498 return infoPtr->simple;
499}
500
501
502static LRESULT
503STATUSBAR_SetBkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
504{
505 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
506 COLORREF oldBkColor;
507 HDC hdc;
508
509 oldBkColor = self->clrBk;
510 self->clrBk = (COLORREF)lParam;
511 hdc = GetDC (hwnd);
512 STATUSBAR_Refresh (hwnd, hdc);
513 ReleaseDC (hwnd, hdc);
514
515 return oldBkColor;
516}
517
518
519static LRESULT
520STATUSBAR_SetIcon (HWND hwnd, WPARAM wParam, LPARAM lParam)
521{
522 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
523 INT nPart = (INT)wParam & 0x00ff;
524 HDC hdc;
525
526 if ((nPart < -1) || (nPart >= self->numParts))
527 return FALSE;
528
529 hdc = GetDC (hwnd);
530 if (nPart == -1) {
531 self->part0.hIcon = (HICON)lParam;
532 if (self->simple)
533 STATUSBAR_RefreshPart (hwnd, &self->part0, hdc);
534 }
535 else {
536 self->parts[nPart].hIcon = (HICON)lParam;
537 if (!(self->simple))
538 STATUSBAR_RefreshPart (hwnd, &self->parts[nPart], hdc);
539 }
540 ReleaseDC (hwnd, hdc);
541
542 return TRUE;
543}
544
545
546static LRESULT
547STATUSBAR_SetMinHeight (HWND hwnd, WPARAM wParam, LPARAM lParam)
548{
549 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
550
551 if (IsWindowVisible (hwnd)) {
552 HWND parent = GetParent (hwnd);
553 INT width, x, y;
554 RECT parent_rect;
555
556 GetClientRect (parent, &parent_rect);
557 self->height = (INT)wParam + VERT_BORDER;
558 width = parent_rect.right - parent_rect.left;
559 x = parent_rect.left;
560 y = parent_rect.bottom - self->height;
561 MoveWindow (hwnd, parent_rect.left,
562 parent_rect.bottom - self->height,
563 width, self->height, TRUE);
564 STATUSBAR_SetPartBounds (hwnd);
565 }
566
567 return TRUE;
568}
569
570
571static LRESULT
572STATUSBAR_SetParts (HWND hwnd, WPARAM wParam, LPARAM lParam)
573{
574 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
575 STATUSWINDOWPART *tmp;
576 HDC hdc;
577 LPINT parts;
578 int i;
579 int oldNumParts;
580
581 if (self->simple)
582 self->simple = FALSE;
583
584 oldNumParts = self->numParts;
585 self->numParts = (INT) wParam;
586 parts = (LPINT) lParam;
587 if (oldNumParts > self->numParts) {
588 for (i = self->numParts ; i < oldNumParts; i++) {
589 if (self->parts[i].text && !(self->parts[i].style & SBT_OWNERDRAW))
590 COMCTL32_Free (self->parts[i].text);
591 }
592 }
593 else if (oldNumParts < self->numParts) {
594 tmp = (STATUSWINDOWPART*)COMCTL32_Alloc (sizeof(STATUSWINDOWPART) * self->numParts);
595 for (i = 0; i < oldNumParts; i++) {
596 tmp[i] = self->parts[i];
597 }
598 if (self->parts)
599 COMCTL32_Free (self->parts);
600 self->parts = tmp;
601 }
602
603 for (i = 0; i < self->numParts; i++) {
604 self->parts[i].x = parts[i];
605 }
606
607 if (self->hwndToolTip) {
608 INT nTipCount =
609 SendMessageA (self->hwndToolTip, TTM_GETTOOLCOUNT, 0, 0);
610
611 if (nTipCount < self->numParts) {
612 /* add tools */
613 TTTOOLINFOA ti;
614 INT i;
615
616 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
617 ti.cbSize = sizeof(TTTOOLINFOA);
618 ti.hwnd = hwnd;
619 for (i = nTipCount; i < self->numParts; i++) {
620// TRACE (statusbar, "add tool %d\n", i);
621 ti.uId = i;
622 SendMessageA (self->hwndToolTip, TTM_ADDTOOLA,
623 0, (LPARAM)&ti);
624 }
625 }
626 else if (nTipCount > self->numParts) {
627 /* delete tools */
628 INT i;
629
630 for (i = nTipCount - 1; i >= self->numParts; i--) {
631
632// FIXME (statusbar, "delete tool %d\n", i);
633
634 }
635 }
636 }
637
638 STATUSBAR_SetPartBounds (hwnd);
639
640 hdc = GetDC (hwnd);
641 STATUSBAR_Refresh (hwnd, hdc);
642 ReleaseDC (hwnd, hdc);
643
644 return TRUE;
645}
646
647
648static LRESULT
649STATUSBAR_SetTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
650{
651 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
652 STATUSWINDOWPART *part;
653 int part_num;
654 int style;
655 LPSTR text;
656 LPWSTR newText;
657 int len;
658 HDC hdc;
659
660 text = (LPSTR) lParam;
661 part_num = ((INT) wParam) & 0x00ff;
662 style = ((INT) wParam) & 0xff00;
663
664 if ((self->simple) || (self->parts==NULL) || (part_num==255))
665 part = &self->part0;
666 else
667 part = &self->parts[part_num];
668 if (!part) return FALSE;
669
670 if (style & SBT_OWNERDRAW)
671 {
672 if (!(part->style & SBT_OWNERDRAW) && part->text) COMCTL32_Free(part->text);
673 part->text = (LPWSTR)text;
674 } else
675 {
676 //compare
677 if (text && (len = lstrlenA(text)))
678 {
679 newText = (WCHAR*)COMCTL32_Alloc((len+1)*sizeof(WCHAR));
680 lstrcpyAtoW (newText,text);
681 } else newText = NULL;
682 if (lstrcmpW(part->text,newText) == 0)
683 {
684 COMCTL32_Free(newText);
685 if (part->style != style)
686 {
687 hdc = GetDC(hwnd);
688 STATUSBAR_RefreshPart(hwnd,part,hdc);
689 ReleaseDC(hwnd, hdc);
690 }
691 return TRUE;
692 }
693
694 COMCTL32_Free(part->text);
695 part->text = newText;
696 }
697 part->style = style;
698
699 hdc = GetDC (hwnd);
700 STATUSBAR_RefreshPart (hwnd, part, hdc);
701 ReleaseDC (hwnd, hdc);
702
703 return TRUE;
704}
705
706
707static LRESULT
708STATUSBAR_SetTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
709{
710 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
711 STATUSWINDOWPART *part;
712 INT part_num, style, len;
713 LPWSTR text;
714 HDC hdc;
715
716 text = (LPWSTR) lParam;
717 part_num = ((INT) wParam) & 0x00ff;
718 style = ((INT) wParam) & 0xff00;
719
720 if ((self->simple) || (self->parts==NULL) || (part_num==255))
721 part = &self->part0;
722 else
723 part = &self->parts[part_num];
724 if (!part) return FALSE;
725
726 if (style & SBT_OWNERDRAW)
727 {
728 if (!(part->style & SBT_OWNERDRAW) && part->text) COMCTL32_Free(part->text);
729 part->text = text;
730 } else
731 {
732 //compare
733 if (lstrcmpW(part->text,text) == 0)
734 {
735 if (part->style != style)
736 {
737 hdc = GetDC(hwnd);
738 STATUSBAR_RefreshPart(hwnd,part,hdc);
739 ReleaseDC(hwnd, hdc);
740 }
741 return TRUE;
742 }
743
744 /* duplicate string */
745 COMCTL32_Free(part->text);
746 if (text && (len = lstrlenW(text)))
747 {
748 part->text = (WCHAR*)COMCTL32_Alloc((len+1)*sizeof(WCHAR));
749 lstrcpyW(part->text,text);
750 }
751 }
752 part->style = style;
753
754 hdc = GetDC (hwnd);
755 STATUSBAR_RefreshPart (hwnd, part, hdc);
756 ReleaseDC (hwnd, hdc);
757
758 return TRUE;
759}
760
761
762static LRESULT
763STATUSBAR_SetTipTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
764{
765 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
766
767// TRACE (statusbar, "part %d: \"%s\"\n", (INT)wParam, (LPSTR)lParam);
768 if (infoPtr->hwndToolTip) {
769 TTTOOLINFOA ti;
770 ti.cbSize = sizeof(TTTOOLINFOA);
771 ti.hwnd = hwnd;
772 ti.uId = (INT)wParam;
773 ti.hinst = 0;
774 ti.lpszText = (LPSTR)lParam;
775 SendMessageA (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTA,
776 0, (LPARAM)&ti);
777 }
778
779 return 0;
780}
781
782
783static LRESULT
784STATUSBAR_SetTipTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
785{
786 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
787
788 if (infoPtr->hwndToolTip) {
789 TTTOOLINFOW ti;
790 ti.cbSize = sizeof(TTTOOLINFOW);
791 ti.hwnd = hwnd;
792 ti.uId = (INT)wParam;
793 ti.hinst = 0;
794 ti.lpszText = (LPWSTR)lParam;
795 SendMessageW (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTW,
796 0, (LPARAM)&ti);
797 }
798
799 return 0;
800}
801
802static LRESULT
803STATUSBAR_Simple (HWND hwnd, WPARAM wParam, LPARAM lParam)
804{
805 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
806 HDC hdc;
807
808 infoPtr->simple = (BOOL)wParam;
809
810 /* send notification */
811 sendNotify(hwnd,SBN_SIMPLEMODECHANGE);
812
813 hdc = GetDC (hwnd);
814 STATUSBAR_Refresh (hwnd, hdc);
815 ReleaseDC (hwnd, hdc);
816
817 return TRUE;
818}
819
820
821static LRESULT
822STATUSBAR_WMCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
823{
824 LPCREATESTRUCTA lpCreate = (LPCREATESTRUCTA)lParam;
825 NONCLIENTMETRICSA nclm;
826 RECT rect;
827 int width, len;
828 HDC hdc;
829 STATUSWINDOWINFO *infoPtr;
830
831 infoPtr = (STATUSWINDOWINFO*)initControl(hwnd,sizeof(STATUSWINDOWINFO));
832
833 infoPtr->numParts = 1;
834 infoPtr->parts = 0;
835 infoPtr->simple = FALSE;
836 infoPtr->clrBk = CLR_DEFAULT;
837 infoPtr->hFont = 0;
838 GetClientRect (hwnd, &rect);
839
840 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
841 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
842 infoPtr->hDefaultFont = CreateFontIndirectA (&nclm.lfStatusFont);
843
844 /* initialize simple case */
845 infoPtr->part0.bound = rect;
846 infoPtr->part0.text = 0;
847 infoPtr->part0.x = 0;
848 infoPtr->part0.style = 0;
849 infoPtr->part0.hIcon = 0;
850
851 /* initialize first part */
852 infoPtr->parts = (STATUSWINDOWPART*)COMCTL32_Alloc (sizeof(STATUSWINDOWPART));
853 infoPtr->parts[0].bound = rect;
854 infoPtr->parts[0].text = 0;
855 infoPtr->parts[0].x = -1;
856 infoPtr->parts[0].style = 0;
857 infoPtr->parts[0].hIcon = 0;
858
859 if (infoPtr->header.fUnicode)
860 {
861 if (lpCreate->lpszName && (len = lstrlenW ((LPCWSTR)lpCreate->lpszName)))
862 {
863 infoPtr->parts[0].text = (WCHAR*)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
864 lstrcpyW (infoPtr->parts[0].text, (LPCWSTR)lpCreate->lpszName);
865 }
866 } else
867 {
868 if (lpCreate->lpszName && (len = lstrlenA ((LPCSTR)lpCreate->lpszName)))
869 {
870 infoPtr->parts[0].text = (WCHAR*)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
871 lstrcpyAtoW (infoPtr->parts[0].text, (char*)lpCreate->lpszName);
872 }
873 }
874
875 hdc = GetDC(hwnd);
876 if (hdc) {
877 TEXTMETRICA tm;
878 HFONT hOldFont;
879
880 hOldFont = SelectObject (hdc,infoPtr->hDefaultFont);
881 GetTextMetricsA(hdc, &tm);
882 infoPtr->textHeight = tm.tmHeight+tm.tmExternalLeading;
883 SelectObject (hdc, hOldFont);
884 ReleaseDC(hwnd, hdc);
885 }
886
887 if (GetWindowLongA(hwnd,GWL_STYLE) & SBT_TOOLTIPS)
888 infoPtr->hwndToolTip = createToolTip(hwnd,0,FALSE);
889
890 GetClientRect (GetParent (hwnd), &rect);
891 width = rect.right - rect.left;
892 infoPtr->height = infoPtr->textHeight + 4 + VERT_BORDER;
893//CB: todo: find bug in font handling!
894infoPtr->height += 4;
895 MoveWindow(hwnd,lpCreate->x,lpCreate->y-1,width,infoPtr->height,FALSE);
896 STATUSBAR_SetPartBounds (hwnd);
897
898 return 0;
899}
900
901
902static LRESULT
903STATUSBAR_WMDestroy (HWND hwnd)
904{
905 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
906 int i;
907
908 for (i = 0; i < infoPtr->numParts; i++) {
909 if (infoPtr->parts[i].text && !(infoPtr->parts[i].style & SBT_OWNERDRAW))
910 COMCTL32_Free (infoPtr->parts[i].text);
911 }
912 if (infoPtr->part0.text && !(infoPtr->part0.style & SBT_OWNERDRAW))
913 COMCTL32_Free (infoPtr->part0.text);
914 COMCTL32_Free (infoPtr->parts);
915
916 /* delete default font */
917 if (infoPtr->hDefaultFont)
918 DeleteObject (infoPtr->hDefaultFont);
919
920 /* delete tool tip control */
921 destroyToolTip(infoPtr->hwndToolTip);
922
923 doneControl(hwnd);
924
925 return 0;
926}
927
928
929static LRESULT
930STATUSBAR_WMGetFont (HWND hwnd)
931{
932 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
933 return infoPtr->hFont;
934}
935
936
937static LRESULT
938STATUSBAR_WMGetText (HWND hwnd, WPARAM wParam, LPARAM lParam)
939{
940 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
941 INT len;
942
943 if (!(infoPtr->parts[0].text))
944 return 0;
945 len = lstrlenW (infoPtr->parts[0].text);
946 if (wParam > len)
947 {
948 if (infoPtr->header.fUnicode)
949 lstrcpyW ((LPWSTR)lParam, infoPtr->parts[0].text);
950 else
951 lstrcpyWtoA ((LPSTR)lParam, infoPtr->parts[0].text);
952 return len;
953 }
954
955 return -1;
956}
957
958static LRESULT
959STATUSBAR_WMMouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
960{
961 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr(hwnd);
962
963 if (infoPtr->hwndToolTip)
964 STATUSBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
965 WM_MOUSEMOVE, wParam, lParam);
966 return 0;
967}
968
969
970static LRESULT
971STATUSBAR_WMNCHitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
972{
973 if (GetWindowLongA (hwnd,GWL_STYLE) & SBARS_SIZEGRIP)
974 {
975 RECT rect = STATUSBAR_GetSizeBox(hwnd);
976 POINT pt;
977
978 pt.x = (SHORT)LOWORD(lParam);
979 pt.y = (SHORT)HIWORD(lParam);
980 ScreenToClient(hwnd,&pt);
981
982 if (PtInRect(&rect,pt))
983 return HTBOTTOMRIGHT;
984 }
985
986 return DefWindowProcA (hwnd, WM_NCHITTEST, wParam, lParam);
987}
988
989
990static LRESULT
991STATUSBAR_WMNCLButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
992{
993 PostMessageA (GetParent (hwnd), WM_NCLBUTTONDOWN, wParam, lParam);
994 return 0;
995}
996
997
998static LRESULT
999STATUSBAR_WMNCLButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
1000{
1001 PostMessageA (GetParent (hwnd), WM_NCLBUTTONUP, wParam, lParam);
1002 return 0;
1003}
1004
1005
1006static LRESULT
1007STATUSBAR_WMPaint (HWND hwnd, WPARAM wParam)
1008{
1009 HDC hdc;
1010 PAINTSTRUCT ps;
1011
1012 hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
1013 STATUSBAR_Refresh (hwnd, hdc);
1014 if (!wParam)
1015 EndPaint (hwnd, &ps);
1016
1017 return 0;
1018}
1019
1020
1021static LRESULT
1022STATUSBAR_WMSetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
1023{
1024 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1025
1026 infoPtr->hFont = (HFONT)wParam;
1027 if (LOWORD(lParam) == TRUE)
1028 {
1029 HDC hdc = GetDC (hwnd);
1030 TEXTMETRICA tm;
1031 HFONT hOldFont;
1032
1033 hOldFont = SelectObject(hdc,infoPtr->hFont);
1034 GetTextMetricsA(hdc,&tm);
1035 infoPtr->textHeight = tm.tmHeight+tm.tmExternalLeading;
1036 SelectObject(hdc,hOldFont);
1037
1038 //CB: todo: move window
1039
1040 STATUSBAR_Refresh (hwnd, hdc);
1041 ReleaseDC (hwnd, hdc);
1042 }
1043
1044 return 0;
1045}
1046
1047
1048static LRESULT
1049STATUSBAR_WMSetText (HWND hwnd, WPARAM wParam, LPARAM lParam)
1050{
1051 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1052 STATUSWINDOWPART *part;
1053 int len;
1054 HDC hdc;
1055
1056 if (!infoPtr) return DefWindowProcA(hwnd,WM_SETTEXT,wParam,lParam);
1057
1058 if (infoPtr->numParts == 0)
1059 return FALSE;
1060
1061 part = &infoPtr->parts[0];
1062 /* duplicate string */
1063 if (part->text)
1064 COMCTL32_Free (part->text);
1065 part->text = 0;
1066 if (infoPtr->header.fUnicode) {
1067 if (lParam && (len = lstrlenW((LPCWSTR)lParam))) {
1068 part->text = (WCHAR*)COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1069 lstrcpyW (part->text, (LPCWSTR)lParam);
1070 }
1071 }
1072 else {
1073 if (lParam && (len = lstrlenA((LPCSTR)lParam))) {
1074 part->text = (WCHAR*)COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1075 lstrcpyAtoW (part->text, (char*)lParam);
1076 }
1077 }
1078
1079 hdc = GetDC (hwnd);
1080 STATUSBAR_RefreshPart (hwnd, part, hdc);
1081 ReleaseDC (hwnd, hdc);
1082
1083 return TRUE;
1084}
1085
1086
1087static LRESULT
1088STATUSBAR_WMSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1089{
1090 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1091 INT width, x, y, flags;
1092 RECT parent_rect;
1093 HWND parent;
1094
1095 /* Need to resize width to match parent */
1096 flags = (INT) wParam;
1097
1098 /* FIXME for flags =
1099 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED, SIZE_RESTORED
1100 */
1101
1102 if (flags == SIZE_RESTORED) {
1103 /* width and height don't apply */
1104 parent = GetParent (hwnd);
1105 GetClientRect (parent, &parent_rect);
1106 width = parent_rect.right - parent_rect.left;
1107 x = parent_rect.left;
1108 y = parent_rect.bottom - infoPtr->height;
1109 MoveWindow (hwnd, parent_rect.left,
1110 parent_rect.bottom - infoPtr->height,
1111 width, infoPtr->height, TRUE);
1112 STATUSBAR_SetPartBounds (hwnd);
1113 }
1114 return 0;
1115}
1116
1117static LRESULT WINAPI
1118StatusWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
1119{
1120 switch (msg) {
1121 case SB_GETBORDERS:
1122 return STATUSBAR_GetBorders (lParam);
1123
1124 case SB_GETICON:
1125 return STATUSBAR_GetIcon (hwnd, wParam);
1126
1127 case SB_GETPARTS:
1128 return STATUSBAR_GetParts (hwnd, wParam, lParam);
1129
1130 case SB_GETRECT:
1131 return STATUSBAR_GetRect (hwnd, wParam, lParam);
1132
1133 case SB_GETTEXTA:
1134 return STATUSBAR_GetTextA (hwnd, wParam, lParam);
1135
1136 case SB_GETTEXTW:
1137 return STATUSBAR_GetTextW (hwnd, wParam, lParam);
1138
1139 case SB_GETTEXTLENGTHA:
1140 case SB_GETTEXTLENGTHW:
1141 return STATUSBAR_GetTextLength (hwnd, wParam);
1142
1143 case SB_GETTIPTEXTA:
1144 return STATUSBAR_GetTipTextA (hwnd, wParam, lParam);
1145
1146 case SB_GETTIPTEXTW:
1147 return STATUSBAR_GetTipTextW (hwnd, wParam, lParam);
1148
1149 case SB_ISSIMPLE:
1150 return STATUSBAR_IsSimple (hwnd);
1151
1152 case SB_SETBKCOLOR:
1153 return STATUSBAR_SetBkColor (hwnd, wParam, lParam);
1154
1155 case SB_SETICON:
1156 return STATUSBAR_SetIcon (hwnd, wParam, lParam);
1157
1158 case SB_SETMINHEIGHT:
1159 return STATUSBAR_SetMinHeight (hwnd, wParam, lParam);
1160
1161 case SB_SETPARTS:
1162 return STATUSBAR_SetParts (hwnd, wParam, lParam);
1163
1164 case SB_SETTEXTA:
1165 return STATUSBAR_SetTextA (hwnd, wParam, lParam);
1166
1167 case SB_SETTEXTW:
1168 return STATUSBAR_SetTextW (hwnd, wParam, lParam);
1169
1170 case SB_SETTIPTEXTA:
1171 return STATUSBAR_SetTipTextA (hwnd, wParam, lParam);
1172
1173 case SB_SETTIPTEXTW:
1174 return STATUSBAR_SetTipTextW (hwnd, wParam, lParam);
1175
1176 case SB_SIMPLE:
1177 return STATUSBAR_Simple (hwnd, wParam, lParam);
1178
1179
1180 case WM_CREATE:
1181 return STATUSBAR_WMCreate (hwnd, wParam, lParam);
1182
1183 case WM_DESTROY:
1184 return STATUSBAR_WMDestroy (hwnd);
1185
1186 case WM_GETFONT:
1187 return STATUSBAR_WMGetFont (hwnd);
1188
1189 case WM_GETTEXT:
1190 return STATUSBAR_WMGetText (hwnd, wParam, lParam);
1191
1192 case WM_GETTEXTLENGTH:
1193 return STATUSBAR_GetTextLength (hwnd, 0);
1194
1195 case WM_LBUTTONDBLCLK:
1196 return sendNotify(hwnd,NM_DBLCLK);
1197
1198 case WM_LBUTTONUP:
1199 return sendNotify(hwnd,NM_CLICK);
1200
1201 case WM_MOUSEMOVE:
1202 return STATUSBAR_WMMouseMove (hwnd, wParam, lParam);
1203
1204 case WM_NCHITTEST:
1205 return STATUSBAR_WMNCHitTest (hwnd, wParam, lParam);
1206
1207 case WM_NCLBUTTONDOWN:
1208 return STATUSBAR_WMNCLButtonDown (hwnd, wParam, lParam);
1209
1210 case WM_NCLBUTTONUP:
1211 return STATUSBAR_WMNCLButtonUp (hwnd, wParam, lParam);
1212
1213 case WM_PAINT:
1214 return STATUSBAR_WMPaint (hwnd, wParam);
1215
1216 case WM_RBUTTONDBLCLK:
1217 return sendNotify(hwnd,NM_RDBLCLK);
1218
1219 case WM_RBUTTONUP:
1220 return sendNotify(hwnd,NM_RCLICK);
1221
1222 case WM_SETFONT:
1223 return STATUSBAR_WMSetFont (hwnd, wParam, lParam);
1224
1225 case WM_SETTEXT:
1226 return STATUSBAR_WMSetText (hwnd, wParam, lParam);
1227
1228 case WM_SIZE:
1229 return STATUSBAR_WMSize (hwnd, wParam, lParam);
1230
1231 default:
1232// if (msg >= WM_USER)
1233// ERR (statusbar, "unknown msg %04x wp=%04x lp=%08lx\n",
1234// msg, wParam, lParam);
1235 return defComCtl32ProcA (hwnd, msg, wParam, lParam);
1236 }
1237 return 0;
1238}
1239
1240
1241/***********************************************************************
1242 * STATUS_Register [Internal]
1243 *
1244 * Registers the status window class.
1245 */
1246
1247VOID
1248STATUS_Register (VOID)
1249{
1250 WNDCLASSA wndClass;
1251
1252 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
1253 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_HREDRAW;
1254 wndClass.lpfnWndProc = (WNDPROC)StatusWindowProc;
1255 wndClass.cbClsExtra = 0;
1256 wndClass.cbWndExtra = sizeof(STATUSWINDOWINFO *);
1257 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
1258 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
1259 wndClass.lpszClassName = STATUSCLASSNAMEA;
1260
1261 RegisterClassA (&wndClass);
1262}
1263
1264
1265/***********************************************************************
1266 * STATUS_Unregister [Internal]
1267 *
1268 * Unregisters the status window class.
1269 */
1270
1271VOID
1272STATUS_Unregister (VOID)
1273{
1274 UnregisterClassA (STATUSCLASSNAMEA, (HINSTANCE)NULL);
1275}
1276
Note: See TracBrowser for help on using the repository browser.