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

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

merged with Corel WINE 20000513, added new DPA_* functions

File size: 31.1 KB
Line 
1/* $Id: status.cpp,v 1.3 2000-05-22 17:25:11 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/* Corel WINE 20000513 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 doneControl(hwnd);
921
922 return 0;
923}
924
925
926static LRESULT
927STATUSBAR_WMGetFont (HWND hwnd)
928{
929 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
930 return infoPtr->hFont;
931}
932
933
934static LRESULT
935STATUSBAR_WMGetText (HWND hwnd, WPARAM wParam, LPARAM lParam)
936{
937 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
938 INT len;
939
940 if (!(infoPtr->parts[0].text))
941 return 0;
942 len = lstrlenW (infoPtr->parts[0].text);
943 if (wParam > len)
944 {
945 if (infoPtr->header.fUnicode)
946 lstrcpyW ((LPWSTR)lParam, infoPtr->parts[0].text);
947 else
948 lstrcpyWtoA ((LPSTR)lParam, infoPtr->parts[0].text);
949 return len;
950 }
951
952 return -1;
953}
954
955static LRESULT
956STATUSBAR_WMMouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
957{
958 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr(hwnd);
959
960 if (infoPtr->hwndToolTip)
961 STATUSBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
962 WM_MOUSEMOVE, wParam, lParam);
963 return 0;
964}
965
966
967static LRESULT
968STATUSBAR_WMNCHitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
969{
970 if (GetWindowLongA (hwnd,GWL_STYLE) & SBARS_SIZEGRIP)
971 {
972 RECT rect = STATUSBAR_GetSizeBox(hwnd);
973 POINT pt;
974
975 pt.x = (SHORT)LOWORD(lParam);
976 pt.y = (SHORT)HIWORD(lParam);
977 ScreenToClient(hwnd,&pt);
978
979 if (PtInRect(&rect,pt))
980 return HTBOTTOMRIGHT;
981 }
982
983 return DefWindowProcA (hwnd, WM_NCHITTEST, wParam, lParam);
984}
985
986
987static LRESULT
988STATUSBAR_WMNCLButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
989{
990 PostMessageA (GetParent (hwnd), WM_NCLBUTTONDOWN, wParam, lParam);
991 return 0;
992}
993
994
995static LRESULT
996STATUSBAR_WMNCLButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
997{
998 PostMessageA (GetParent (hwnd), WM_NCLBUTTONUP, wParam, lParam);
999 return 0;
1000}
1001
1002
1003static LRESULT
1004STATUSBAR_WMPaint (HWND hwnd, WPARAM wParam)
1005{
1006 HDC hdc;
1007 PAINTSTRUCT ps;
1008
1009 hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
1010 STATUSBAR_Refresh (hwnd, hdc);
1011 if (!wParam)
1012 EndPaint (hwnd, &ps);
1013
1014 return 0;
1015}
1016
1017
1018static LRESULT
1019STATUSBAR_WMSetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
1020{
1021 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1022
1023 infoPtr->hFont = (HFONT)wParam;
1024 if (LOWORD(lParam) == TRUE)
1025 {
1026 HDC hdc = GetDC (hwnd);
1027 TEXTMETRICA tm;
1028 HFONT hOldFont;
1029
1030 hOldFont = SelectObject(hdc,infoPtr->hFont);
1031 GetTextMetricsA(hdc,&tm);
1032 infoPtr->textHeight = tm.tmHeight+tm.tmExternalLeading;
1033 SelectObject(hdc,hOldFont);
1034
1035 //CB: todo: move window
1036
1037 STATUSBAR_Refresh (hwnd, hdc);
1038 ReleaseDC (hwnd, hdc);
1039 }
1040
1041 return 0;
1042}
1043
1044
1045static LRESULT
1046STATUSBAR_WMSetText (HWND hwnd, WPARAM wParam, LPARAM lParam)
1047{
1048 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1049 STATUSWINDOWPART *part;
1050 int len;
1051 HDC hdc;
1052
1053 if (!infoPtr) return DefWindowProcA(hwnd,WM_SETTEXT,wParam,lParam);
1054
1055 if (infoPtr->numParts == 0)
1056 return FALSE;
1057
1058 part = &infoPtr->parts[0];
1059 /* duplicate string */
1060 if (part->text)
1061 COMCTL32_Free (part->text);
1062 part->text = 0;
1063 if (infoPtr->header.fUnicode) {
1064 if (lParam && (len = lstrlenW((LPCWSTR)lParam))) {
1065 part->text = (WCHAR*)COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1066 lstrcpyW (part->text, (LPCWSTR)lParam);
1067 }
1068 }
1069 else {
1070 if (lParam && (len = lstrlenA((LPCSTR)lParam))) {
1071 part->text = (WCHAR*)COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1072 lstrcpyAtoW (part->text, (char*)lParam);
1073 }
1074 }
1075
1076 hdc = GetDC (hwnd);
1077 STATUSBAR_RefreshPart (hwnd, part, hdc);
1078 ReleaseDC (hwnd, hdc);
1079
1080 return TRUE;
1081}
1082
1083
1084static LRESULT
1085STATUSBAR_WMSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1086{
1087 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1088 INT width, x, y, flags;
1089 RECT parent_rect;
1090 HWND parent;
1091
1092 /* Need to resize width to match parent */
1093 flags = (INT) wParam;
1094
1095 /* FIXME for flags =
1096 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED, SIZE_RESTORED
1097 */
1098
1099 if (flags == SIZE_RESTORED) {
1100 /* width and height don't apply */
1101 parent = GetParent (hwnd);
1102 GetClientRect (parent, &parent_rect);
1103 width = parent_rect.right - parent_rect.left;
1104 x = parent_rect.left;
1105 y = parent_rect.bottom - infoPtr->height;
1106 MoveWindow (hwnd, parent_rect.left,
1107 parent_rect.bottom - infoPtr->height,
1108 width, infoPtr->height, TRUE);
1109 STATUSBAR_SetPartBounds (hwnd);
1110 }
1111 return 0;
1112}
1113
1114static LRESULT WINAPI
1115StatusWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
1116{
1117 switch (msg) {
1118 case SB_GETBORDERS:
1119 return STATUSBAR_GetBorders (lParam);
1120
1121 case SB_GETICON:
1122 return STATUSBAR_GetIcon (hwnd, wParam);
1123
1124 case SB_GETPARTS:
1125 return STATUSBAR_GetParts (hwnd, wParam, lParam);
1126
1127 case SB_GETRECT:
1128 return STATUSBAR_GetRect (hwnd, wParam, lParam);
1129
1130 case SB_GETTEXTA:
1131 return STATUSBAR_GetTextA (hwnd, wParam, lParam);
1132
1133 case SB_GETTEXTW:
1134 return STATUSBAR_GetTextW (hwnd, wParam, lParam);
1135
1136 case SB_GETTEXTLENGTHA:
1137 case SB_GETTEXTLENGTHW:
1138 return STATUSBAR_GetTextLength (hwnd, wParam);
1139
1140 case SB_GETTIPTEXTA:
1141 return STATUSBAR_GetTipTextA (hwnd, wParam, lParam);
1142
1143 case SB_GETTIPTEXTW:
1144 return STATUSBAR_GetTipTextW (hwnd, wParam, lParam);
1145
1146 case SB_ISSIMPLE:
1147 return STATUSBAR_IsSimple (hwnd);
1148
1149 case SB_SETBKCOLOR:
1150 return STATUSBAR_SetBkColor (hwnd, wParam, lParam);
1151
1152 case SB_SETICON:
1153 return STATUSBAR_SetIcon (hwnd, wParam, lParam);
1154
1155 case SB_SETMINHEIGHT:
1156 return STATUSBAR_SetMinHeight (hwnd, wParam, lParam);
1157
1158 case SB_SETPARTS:
1159 return STATUSBAR_SetParts (hwnd, wParam, lParam);
1160
1161 case SB_SETTEXTA:
1162 return STATUSBAR_SetTextA (hwnd, wParam, lParam);
1163
1164 case SB_SETTEXTW:
1165 return STATUSBAR_SetTextW (hwnd, wParam, lParam);
1166
1167 case SB_SETTIPTEXTA:
1168 return STATUSBAR_SetTipTextA (hwnd, wParam, lParam);
1169
1170 case SB_SETTIPTEXTW:
1171 return STATUSBAR_SetTipTextW (hwnd, wParam, lParam);
1172
1173 case SB_SIMPLE:
1174 return STATUSBAR_Simple (hwnd, wParam, lParam);
1175
1176
1177 case WM_CREATE:
1178 return STATUSBAR_WMCreate (hwnd, wParam, lParam);
1179
1180 case WM_DESTROY:
1181 return STATUSBAR_WMDestroy (hwnd);
1182
1183 case WM_GETFONT:
1184 return STATUSBAR_WMGetFont (hwnd);
1185
1186 case WM_GETTEXT:
1187 return STATUSBAR_WMGetText (hwnd, wParam, lParam);
1188
1189 case WM_GETTEXTLENGTH:
1190 return STATUSBAR_GetTextLength (hwnd, 0);
1191
1192 case WM_LBUTTONDBLCLK:
1193 return sendNotify(hwnd,NM_DBLCLK);
1194
1195 case WM_LBUTTONUP:
1196 return sendNotify(hwnd,NM_CLICK);
1197
1198 case WM_MOUSEMOVE:
1199 return STATUSBAR_WMMouseMove (hwnd, wParam, lParam);
1200
1201 case WM_NCHITTEST:
1202 return STATUSBAR_WMNCHitTest (hwnd, wParam, lParam);
1203
1204 case WM_NCLBUTTONDOWN:
1205 return STATUSBAR_WMNCLButtonDown (hwnd, wParam, lParam);
1206
1207 case WM_NCLBUTTONUP:
1208 return STATUSBAR_WMNCLButtonUp (hwnd, wParam, lParam);
1209
1210 case WM_PAINT:
1211 return STATUSBAR_WMPaint (hwnd, wParam);
1212
1213 case WM_RBUTTONDBLCLK:
1214 return sendNotify(hwnd,NM_RDBLCLK);
1215
1216 case WM_RBUTTONUP:
1217 return sendNotify(hwnd,NM_RCLICK);
1218
1219 case WM_SETFONT:
1220 return STATUSBAR_WMSetFont (hwnd, wParam, lParam);
1221
1222 case WM_SETTEXT:
1223 return STATUSBAR_WMSetText (hwnd, wParam, lParam);
1224
1225 case WM_SIZE:
1226 return STATUSBAR_WMSize (hwnd, wParam, lParam);
1227
1228 default:
1229// if (msg >= WM_USER)
1230// ERR (statusbar, "unknown msg %04x wp=%04x lp=%08lx\n",
1231// msg, wParam, lParam);
1232 return defComCtl32ProcA (hwnd, msg, wParam, lParam);
1233 }
1234 return 0;
1235}
1236
1237
1238/***********************************************************************
1239 * STATUS_Register [Internal]
1240 *
1241 * Registers the status window class.
1242 */
1243
1244VOID
1245STATUS_Register (VOID)
1246{
1247 WNDCLASSA wndClass;
1248
1249 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
1250 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_HREDRAW;
1251 wndClass.lpfnWndProc = (WNDPROC)StatusWindowProc;
1252 wndClass.cbClsExtra = 0;
1253 wndClass.cbWndExtra = sizeof(STATUSWINDOWINFO *);
1254 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
1255 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
1256 wndClass.lpszClassName = STATUSCLASSNAMEA;
1257
1258 RegisterClassA (&wndClass);
1259}
1260
1261
1262/***********************************************************************
1263 * STATUS_Unregister [Internal]
1264 *
1265 * Unregisters the status window class.
1266 */
1267
1268VOID
1269STATUS_Unregister (VOID)
1270{
1271 UnregisterClassA (STATUSCLASSNAMEA, (HINSTANCE)NULL);
1272}
1273
Note: See TracBrowser for help on using the repository browser.