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

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

* empty log message *

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