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

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

bug fixes (unicode) and improvements

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