source: trunk/src/comctl32/status.c@ 496

Last change on this file since 496 was 496, checked in by cbratschi, 26 years ago

wine-990731 update

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