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

Last change on this file since 164 was 164, checked in by achimha, 26 years ago

updated comctl32 with the latest WINE bugfixes. Listview is much better now and tab control doesn't have the wrong color anymore. Many small improvements

File size: 31.4 KB
Line 
1/* $Id: status.c,v 1.5 1999-06-23 19:45:01 achimha 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, HIWORD(wParam));
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, HIWORD(wParam));
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.