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

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

Fixed Unicode<->Ascii issues partially

File size: 28.6 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 }
373 return result;
374}
375
376
377static LRESULT
378STATUSBAR_GetTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
379{
380 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
381 STATUSWINDOWPART *part;
382 INT nPart;
383 LRESULT result;
384
385 nPart = ((INT)wParam) & 0x00ff;
386 if (infoPtr->simple)
387 part = &infoPtr->part0;
388 else
389 part = &infoPtr->parts[nPart];
390
391 if (part->style == SBT_OWNERDRAW)
392 result = (LRESULT)part->text;
393 else {
394 result = part->text ? lstrlenW (part->text) : 0;
395 result |= (part->style << 16);
396 if (lParam)
397 lstrcpyW ((LPWSTR)lParam, part->text);
398 }
399 return result;
400}
401
402
403static LRESULT
404STATUSBAR_GetTextLength (HWND hwnd, WPARAM wParam)
405{
406 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
407 STATUSWINDOWPART *part;
408 INT part_num;
409 DWORD result;
410
411 part_num = ((INT) wParam) & 0x00ff;
412
413 if (infoPtr->simple)
414 part = &infoPtr->part0;
415 else
416 part = &infoPtr->parts[part_num];
417
418 if (part->text)
419 result = lstrlenW(part->text);
420 else
421 result = 0;
422
423 result |= (part->style << 16);
424 return result;
425}
426
427
428static LRESULT
429STATUSBAR_GetTipTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
430{
431 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
432
433 if (infoPtr->hwndToolTip) {
434 TTTOOLINFOA ti;
435 ti.cbSize = sizeof(TTTOOLINFOA);
436 ti.hwnd = hwnd;
437 ti.uId = LOWORD(wParam);
438 SendMessageA (infoPtr->hwndToolTip, TTM_GETTEXTA, 0, (LPARAM)&ti);
439
440 if (ti.lpszText)
441 lstrcpynA ((LPSTR)lParam, ti.lpszText, HIWORD(wParam));
442 }
443
444 return 0;
445}
446
447
448static LRESULT
449STATUSBAR_GetTipTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
450{
451 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
452
453 if (infoPtr->hwndToolTip) {
454 TTTOOLINFOW ti;
455 ti.cbSize = sizeof(TTTOOLINFOW);
456 ti.hwnd = hwnd;
457 ti.uId = LOWORD(wParam);
458 SendMessageW (infoPtr->hwndToolTip, TTM_GETTEXTW, 0, (LPARAM)&ti);
459
460 if (ti.lpszText)
461 lstrcpynW ((LPWSTR)lParam, ti.lpszText, HIWORD(wParam));
462 }
463
464 return 0;
465}
466
467
468static LRESULT
469STATUSBAR_GetUnicodeFormat (HWND hwnd)
470{
471 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
472 return infoPtr->bUnicode;
473}
474
475
476static LRESULT
477STATUSBAR_IsSimple (HWND hwnd)
478{
479 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
480 return infoPtr->simple;
481}
482
483
484static LRESULT
485STATUSBAR_SetBkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
486{
487 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
488 COLORREF oldBkColor;
489 HDC hdc;
490
491 oldBkColor = self->clrBk;
492 self->clrBk = (COLORREF)lParam;
493 hdc = GetDC (hwnd);
494 STATUSBAR_Refresh (hwnd, hdc);
495 ReleaseDC (hwnd, hdc);
496
497 return oldBkColor;
498}
499
500
501static LRESULT
502STATUSBAR_SetIcon (HWND hwnd, WPARAM wParam, LPARAM lParam)
503{
504 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
505 INT nPart = (INT)wParam & 0x00ff;
506 HDC hdc;
507
508 if ((nPart < -1) || (nPart >= self->numParts))
509 return FALSE;
510
511 hdc = GetDC (hwnd);
512 if (nPart == -1) {
513 self->part0.hIcon = (HICON)lParam;
514 if (self->simple)
515 STATUSBAR_RefreshPart (hwnd, &self->part0, hdc);
516 }
517 else {
518 self->parts[nPart].hIcon = (HICON)lParam;
519 if (!(self->simple))
520 STATUSBAR_RefreshPart (hwnd, &self->parts[nPart], hdc);
521 }
522 ReleaseDC (hwnd, hdc);
523
524 return TRUE;
525}
526
527
528static LRESULT
529STATUSBAR_SetMinHeight (HWND hwnd, WPARAM wParam, LPARAM lParam)
530{
531 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
532
533 if (IsWindowVisible (hwnd)) {
534 HWND parent = GetParent (hwnd);
535 INT width, x, y;
536 RECT parent_rect;
537
538 GetClientRect (parent, &parent_rect);
539 self->height = (INT)wParam + VERT_BORDER;
540 width = parent_rect.right - parent_rect.left;
541 x = parent_rect.left;
542 y = parent_rect.bottom - self->height;
543 MoveWindow (hwnd, parent_rect.left,
544 parent_rect.bottom - self->height,
545 width, self->height, TRUE);
546 STATUSBAR_SetPartBounds (hwnd);
547 }
548
549 return TRUE;
550}
551
552
553static LRESULT
554STATUSBAR_SetParts (HWND hwnd, WPARAM wParam, LPARAM lParam)
555{
556 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
557 STATUSWINDOWPART *tmp;
558 HDC hdc;
559 LPINT parts;
560 int i;
561 int oldNumParts;
562
563 if (self->simple)
564 self->simple = FALSE;
565
566 oldNumParts = self->numParts;
567 self->numParts = (INT) wParam;
568 parts = (LPINT) lParam;
569 if (oldNumParts > self->numParts) {
570 for (i = self->numParts ; i < oldNumParts; i++) {
571 if (self->parts[i].text && (self->parts[i].style != SBT_OWNERDRAW))
572 COMCTL32_Free (self->parts[i].text);
573 }
574 }
575 else if (oldNumParts < self->numParts) {
576 tmp = COMCTL32_Alloc (sizeof(STATUSWINDOWPART) * self->numParts);
577 for (i = 0; i < oldNumParts; i++) {
578 tmp[i] = self->parts[i];
579 }
580 if (self->parts)
581 COMCTL32_Free (self->parts);
582 self->parts = tmp;
583 }
584
585 for (i = 0; i < self->numParts; i++) {
586 self->parts[i].x = parts[i];
587 }
588
589 if (self->hwndToolTip) {
590 INT nTipCount =
591 SendMessageA (self->hwndToolTip, TTM_GETTOOLCOUNT, 0, 0);
592
593 if (nTipCount < self->numParts) {
594 /* add tools */
595 TTTOOLINFOA ti;
596 INT i;
597
598 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
599 ti.cbSize = sizeof(TTTOOLINFOA);
600 ti.hwnd = hwnd;
601 for (i = nTipCount; i < self->numParts; i++) {
602// TRACE (statusbar, "add tool %d\n", i);
603 ti.uId = i;
604 SendMessageA (self->hwndToolTip, TTM_ADDTOOLA,
605 0, (LPARAM)&ti);
606 }
607 }
608 else if (nTipCount > self->numParts) {
609 /* delete tools */
610 INT i;
611
612 for (i = nTipCount - 1; i >= self->numParts; i--) {
613
614// FIXME (statusbar, "delete tool %d\n", i);
615
616 }
617 }
618 }
619
620 STATUSBAR_SetPartBounds (hwnd);
621
622 hdc = GetDC (hwnd);
623 STATUSBAR_Refresh (hwnd, hdc);
624 ReleaseDC (hwnd, hdc);
625
626 return TRUE;
627}
628
629
630static LRESULT
631STATUSBAR_SetTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
632{
633 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
634 STATUSWINDOWPART *part;
635 int part_num;
636 int style;
637 LPSTR text;
638 int len;
639 HDC hdc;
640
641 text = (LPSTR) lParam;
642 part_num = ((INT) wParam) & 0x00ff;
643 style = ((INT) wParam) & 0xff00;
644
645 if ((self->simple) || (self->parts==NULL) || (part_num==255))
646 part = &self->part0;
647 else
648 part = &self->parts[part_num];
649 if (!part) return FALSE;
650 part->style = style;
651 if (style == SBT_OWNERDRAW) {
652 part->text = (LPWSTR)text;
653 }
654 else {
655 /* duplicate string */
656 if (part->text)
657 COMCTL32_Free (part->text);
658 part->text = 0;
659 if (text && (len = lstrlenA(text))) {
660 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
661 lstrcpyAtoW (part->text, text);
662 }
663 }
664
665 hdc = GetDC (hwnd);
666 STATUSBAR_RefreshPart (hwnd, part, hdc);
667 ReleaseDC (hwnd, hdc);
668
669 return TRUE;
670}
671
672
673static LRESULT
674STATUSBAR_SetTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
675{
676 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
677 STATUSWINDOWPART *part;
678 INT part_num, style, len;
679 LPWSTR text;
680 HDC hdc;
681
682 text = (LPWSTR) lParam;
683 part_num = ((INT) wParam) & 0x00ff;
684 style = ((INT) wParam) & 0xff00;
685
686 if ((self->simple) || (self->parts==NULL) || (part_num==255))
687 part = &self->part0;
688 else
689 part = &self->parts[part_num];
690 if (!part) return FALSE;
691 part->style = style;
692 if (style == SBT_OWNERDRAW) {
693 part->text = text;
694 }
695 else {
696 /* duplicate string */
697 if (part->text)
698 COMCTL32_Free (part->text);
699 part->text = 0;
700 if (text && (len = lstrlenW(text))) {
701 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
702 lstrcpyW(part->text, text);
703 }
704 }
705
706 hdc = GetDC (hwnd);
707 STATUSBAR_RefreshPart (hwnd, part, hdc);
708 ReleaseDC (hwnd, hdc);
709
710 return TRUE;
711}
712
713
714static LRESULT
715STATUSBAR_SetTipTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
716{
717 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
718
719// TRACE (statusbar, "part %d: \"%s\"\n", (INT)wParam, (LPSTR)lParam);
720 if (infoPtr->hwndToolTip) {
721 TTTOOLINFOA ti;
722 ti.cbSize = sizeof(TTTOOLINFOA);
723 ti.hwnd = hwnd;
724 ti.uId = (INT)wParam;
725 ti.hinst = 0;
726 ti.lpszText = (LPSTR)lParam;
727 SendMessageA (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTA,
728 0, (LPARAM)&ti);
729 }
730
731 return 0;
732}
733
734
735static LRESULT
736STATUSBAR_SetTipTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
737{
738 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
739
740// TRACE (statusbar, "part %d: \"%s\"\n", (INT)wParam, (LPSTR)lParam);
741 if (infoPtr->hwndToolTip) {
742 TTTOOLINFOW ti;
743 ti.cbSize = sizeof(TTTOOLINFOW);
744 ti.hwnd = hwnd;
745 ti.uId = (INT)wParam;
746 ti.hinst = 0;
747 ti.lpszText = (LPWSTR)lParam;
748 SendMessageW (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTW,
749 0, (LPARAM)&ti);
750 }
751
752 return 0;
753}
754
755
756static LRESULT
757STATUSBAR_SetUnicodeFormat (HWND hwnd, WPARAM wParam)
758{
759 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
760 BOOL bTemp = infoPtr->bUnicode;
761
762// TRACE (statusbar, "(0x%x)\n", (BOOL)wParam);
763 infoPtr->bUnicode = (BOOL)wParam;
764
765 return bTemp;
766}
767
768
769static LRESULT
770STATUSBAR_Simple (HWND hwnd, WPARAM wParam, LPARAM lParam)
771{
772 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
773 HDC hdc;
774 NMHDR nmhdr;
775
776 infoPtr->simple = (BOOL)wParam;
777
778 /* send notification */
779 nmhdr.hwndFrom = hwnd;
780 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
781 nmhdr.code = SBN_SIMPLEMODECHANGE;
782 SendMessageA (GetParent (hwnd), WM_NOTIFY, 0, (LPARAM)&nmhdr);
783
784 hdc = GetDC (hwnd);
785 STATUSBAR_Refresh (hwnd, hdc);
786 ReleaseDC (hwnd, hdc);
787
788 return TRUE;
789}
790
791
792static LRESULT
793STATUSBAR_WMCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
794{
795 LPCREATESTRUCTA lpCreate = (LPCREATESTRUCTA)lParam;
796 NONCLIENTMETRICSA nclm;
797 RECT rect;
798 int width, len;
799 HDC hdc;
800 STATUSWINDOWINFO *self;
801
802 self = (STATUSWINDOWINFO*)COMCTL32_Alloc (sizeof(STATUSWINDOWINFO));
803 SetWindowLongA (hwnd, 0, (DWORD)self);
804
805 self->numParts = 1;
806 self->parts = 0;
807 self->simple = FALSE;
808 self->clrBk = CLR_DEFAULT;
809 self->hFont = 0;
810 GetClientRect (hwnd, &rect);
811
812 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
813 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
814 self->hDefaultFont = CreateFontIndirectA (&nclm.lfStatusFont);
815
816 /* initialize simple case */
817 self->part0.bound = rect;
818 self->part0.text = 0;
819 self->part0.x = 0;
820 self->part0.style = 0;
821 self->part0.hIcon = 0;
822
823 /* initialize first part */
824 self->parts = COMCTL32_Alloc (sizeof(STATUSWINDOWPART));
825 self->parts[0].bound = rect;
826 self->parts[0].text = 0;
827 self->parts[0].x = -1;
828 self->parts[0].style = 0;
829 self->parts[0].hIcon = 0;
830
831 if (IsWindowUnicode (hwnd)) {
832 self->bUnicode = TRUE;
833 if ((len = lstrlenW ((LPCWSTR)lpCreate->lpszName))) {
834 self->parts[0].text = COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
835 lstrcpyW (self->parts[0].text, (LPCWSTR)lpCreate->lpszName);
836 }
837 }
838 else {
839 if ((len = lstrlenA ((LPCSTR)lpCreate->lpszName))) {
840 self->parts[0].text = COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
841 lstrcpyAtoW (self->parts[0].text, (LPCSTR)lpCreate->lpszName);
842 }
843 }
844
845 if ((hdc = GetDC (0))) {
846 TEXTMETRICA tm;
847 HFONT hOldFont;
848
849 hOldFont = SelectObject (hdc,self->hDefaultFont);
850 GetTextMetricsA(hdc, &tm);
851 self->textHeight = tm.tmHeight;
852 SelectObject (hdc, hOldFont);
853 ReleaseDC(0, hdc);
854 }
855
856 if (GetWindowLongA (hwnd, GWL_STYLE) & SBT_TOOLTIPS) {
857 self->hwndToolTip =
858 CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
859 CW_USEDEFAULT, CW_USEDEFAULT,
860 CW_USEDEFAULT, CW_USEDEFAULT,
861 hwnd, 0,
862 GetWindowLongA (hwnd, GWL_HINSTANCE), NULL);
863
864 if (self->hwndToolTip) {
865 NMTOOLTIPSCREATED nmttc;
866
867 nmttc.hdr.hwndFrom = hwnd;
868 nmttc.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
869 nmttc.hdr.code = NM_TOOLTIPSCREATED;
870 nmttc.hwndToolTips = self->hwndToolTip;
871
872 SendMessageA (GetParent (hwnd), WM_NOTIFY,
873 (WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc);
874 }
875 }
876
877 GetClientRect (GetParent (hwnd), &rect);
878 width = rect.right - rect.left;
879 self->height = self->textHeight + 4 + VERT_BORDER;
880 MoveWindow (hwnd, lpCreate->x, lpCreate->y-1,
881 width, self->height, FALSE);
882 STATUSBAR_SetPartBounds (hwnd);
883
884 return 0;
885}
886
887
888static LRESULT
889STATUSBAR_WMDestroy (HWND hwnd)
890{
891 STATUSWINDOWINFO *self = STATUSBAR_GetInfoPtr (hwnd);
892 int i;
893
894 for (i = 0; i < self->numParts; i++) {
895 if (self->parts[i].text && (self->parts[i].style != SBT_OWNERDRAW))
896 COMCTL32_Free (self->parts[i].text);
897 }
898 if (self->part0.text && (self->part0.style != SBT_OWNERDRAW))
899 COMCTL32_Free (self->part0.text);
900 COMCTL32_Free (self->parts);
901
902 /* delete default font */
903 if (self->hDefaultFont)
904 DeleteObject (self->hDefaultFont);
905
906 /* delete tool tip control */
907 if (self->hwndToolTip)
908 DestroyWindow (self->hwndToolTip);
909
910 COMCTL32_Free (self);
911
912 return 0;
913}
914
915
916static LRESULT
917STATUSBAR_WMGetFont (HWND hwnd)
918{
919 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
920 return infoPtr->hFont;
921}
922
923
924static LRESULT
925STATUSBAR_WMGetText (HWND hwnd, WPARAM wParam, LPARAM lParam)
926{
927 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
928 INT len;
929
930 if (!(infoPtr->parts[0].text))
931 return 0;
932 len = lstrlenW (infoPtr->parts[0].text);
933 if (wParam > len) {
934 if (infoPtr->bUnicode)
935 lstrcpyW ((LPWSTR)lParam, infoPtr->parts[0].text);
936 else
937 lstrcpyWtoA ((LPSTR)lParam, infoPtr->parts[0].text);
938 return len;
939 }
940
941 return -1;
942}
943
944
945static LRESULT
946STATUSBAR_WMMouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
947{
948 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
949
950 if (infoPtr->hwndToolTip)
951 STATUSBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
952 WM_MOUSEMOVE, wParam, lParam);
953 return 0;
954}
955
956
957static LRESULT
958STATUSBAR_WMNCHitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
959{
960 if (GetWindowLongA (hwnd, GWL_STYLE) & SBARS_SIZEGRIP) {
961 RECT rect;
962 POINT pt;
963
964 GetClientRect (hwnd, &rect);
965
966 pt.x = (INT)LOWORD(lParam);
967 pt.y = (INT)HIWORD(lParam);
968 ScreenToClient (hwnd, &pt);
969
970 rect.left = rect.right - 13;
971 rect.top += 2;
972
973 if (PtInRect (&rect, pt))
974 return HTBOTTOMRIGHT;
975 }
976
977 return DefWindowProcA (hwnd, WM_NCHITTEST, wParam, lParam);
978}
979
980
981static LRESULT
982STATUSBAR_WMNCLButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
983{
984 PostMessageA (GetParent (hwnd), WM_NCLBUTTONDOWN, wParam, lParam);
985 return 0;
986}
987
988
989static LRESULT
990STATUSBAR_WMNCLButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
991{
992 PostMessageA (GetParent (hwnd), WM_NCLBUTTONUP, wParam, lParam);
993 return 0;
994}
995
996
997static LRESULT
998STATUSBAR_WMPaint (HWND hwnd, WPARAM wParam)
999{
1000 HDC hdc;
1001 PAINTSTRUCT ps;
1002
1003 hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
1004 STATUSBAR_Refresh (hwnd, hdc);
1005 if (!wParam)
1006 EndPaint (hwnd, &ps);
1007
1008 return 0;
1009}
1010
1011
1012static LRESULT
1013STATUSBAR_WMSetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
1014{
1015 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1016
1017 infoPtr->hFont = (HFONT)wParam;
1018 if (LOWORD(lParam) == TRUE) {
1019 HDC hdc = GetDC (hwnd);
1020 STATUSBAR_Refresh (hwnd, hdc);
1021 ReleaseDC (hwnd, hdc);
1022 }
1023
1024 return 0;
1025}
1026
1027
1028static LRESULT
1029STATUSBAR_WMSetText (HWND hwnd, WPARAM wParam, LPARAM lParam)
1030{
1031 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1032 STATUSWINDOWPART *part;
1033 int len;
1034 HDC hdc;
1035
1036 if (infoPtr->numParts == 0)
1037 return FALSE;
1038
1039 part = &infoPtr->parts[0];
1040 /* duplicate string */
1041 if (part->text)
1042 COMCTL32_Free (part->text);
1043 part->text = 0;
1044 if (infoPtr->bUnicode) {
1045 if (lParam && (len = lstrlenW((LPCWSTR)lParam))) {
1046 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1047 lstrcpyW (part->text, (LPCWSTR)lParam);
1048 }
1049 }
1050 else {
1051 if (lParam && (len = lstrlenA((LPCSTR)lParam))) {
1052 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1053 lstrcpyAtoW (part->text, (LPCSTR)lParam);
1054 }
1055 }
1056
1057 hdc = GetDC (hwnd);
1058 STATUSBAR_RefreshPart (hwnd, part, hdc);
1059 ReleaseDC (hwnd, hdc);
1060
1061 return TRUE;
1062}
1063
1064
1065static LRESULT
1066STATUSBAR_WMSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1067{
1068 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr (hwnd);
1069 INT width, x, y, flags;
1070 RECT parent_rect;
1071 HWND parent;
1072
1073 /* Need to resize width to match parent */
1074 flags = (INT) wParam;
1075
1076 /* FIXME for flags =
1077 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED, SIZE_RESTORED
1078 */
1079
1080 if (flags == SIZE_RESTORED) {
1081 /* width and height don't apply */
1082 parent = GetParent (hwnd);
1083 GetClientRect (parent, &parent_rect);
1084 width = parent_rect.right - parent_rect.left;
1085 x = parent_rect.left;
1086 y = parent_rect.bottom - infoPtr->height;
1087 MoveWindow (hwnd, parent_rect.left,
1088 parent_rect.bottom - infoPtr->height,
1089 width, infoPtr->height, TRUE);
1090 STATUSBAR_SetPartBounds (hwnd);
1091 }
1092 return 0;
1093}
1094
1095
1096static LRESULT
1097STATUSBAR_SendNotify (HWND hwnd, UINT code)
1098{
1099 NMHDR nmhdr;
1100
1101 nmhdr.hwndFrom = hwnd;
1102 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1103 nmhdr.code = code;
1104 SendMessageA (GetParent (hwnd), WM_NOTIFY, 0, (LPARAM)&nmhdr);
1105 return 0;
1106}
1107
1108
1109
1110LRESULT WINAPI
1111StatusWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
1112{
1113 switch (msg) {
1114 case SB_GETBORDERS:
1115 return STATUSBAR_GetBorders (lParam);
1116
1117 case SB_GETICON:
1118 return STATUSBAR_GetIcon (hwnd, wParam);
1119
1120 case SB_GETPARTS:
1121 return STATUSBAR_GetParts (hwnd, wParam, lParam);
1122
1123 case SB_GETRECT:
1124 return STATUSBAR_GetRect (hwnd, wParam, lParam);
1125
1126 case SB_GETTEXTA:
1127 return STATUSBAR_GetTextA (hwnd, wParam, lParam);
1128
1129 case SB_GETTEXTW:
1130 return STATUSBAR_GetTextW (hwnd, wParam, lParam);
1131
1132 case SB_GETTEXTLENGTHA:
1133 case SB_GETTEXTLENGTHW:
1134 return STATUSBAR_GetTextLength (hwnd, wParam);
1135
1136 case SB_GETTIPTEXTA:
1137 return STATUSBAR_GetTipTextA (hwnd, wParam, lParam);
1138
1139 case SB_GETTIPTEXTW:
1140 return STATUSBAR_GetTipTextW (hwnd, wParam, lParam);
1141
1142 case SB_GETUNICODEFORMAT:
1143 return STATUSBAR_GetUnicodeFormat (hwnd);
1144
1145 case SB_ISSIMPLE:
1146 return STATUSBAR_IsSimple (hwnd);
1147
1148 case SB_SETBKCOLOR:
1149 return STATUSBAR_SetBkColor (hwnd, wParam, lParam);
1150
1151 case SB_SETICON:
1152 return STATUSBAR_SetIcon (hwnd, wParam, lParam);
1153
1154 case SB_SETMINHEIGHT:
1155 return STATUSBAR_SetMinHeight (hwnd, wParam, lParam);
1156
1157 case SB_SETPARTS:
1158 return STATUSBAR_SetParts (hwnd, wParam, lParam);
1159
1160 case SB_SETTEXTA:
1161 return STATUSBAR_SetTextA (hwnd, wParam, lParam);
1162
1163 case SB_SETTEXTW:
1164 return STATUSBAR_SetTextW (hwnd, wParam, lParam);
1165
1166 case SB_SETTIPTEXTA:
1167 return STATUSBAR_SetTipTextA (hwnd, wParam, lParam);
1168
1169 case SB_SETTIPTEXTW:
1170 return STATUSBAR_SetTipTextW (hwnd, wParam, lParam);
1171
1172 case SB_SETUNICODEFORMAT:
1173 return STATUSBAR_SetUnicodeFormat (hwnd, wParam);
1174
1175 case SB_SIMPLE:
1176 return STATUSBAR_Simple (hwnd, wParam, lParam);
1177
1178
1179 case WM_CREATE:
1180 return STATUSBAR_WMCreate (hwnd, wParam, lParam);
1181
1182 case WM_DESTROY:
1183 return STATUSBAR_WMDestroy (hwnd);
1184
1185 case WM_GETFONT:
1186 return STATUSBAR_WMGetFont (hwnd);
1187
1188 case WM_GETTEXT:
1189 return STATUSBAR_WMGetText (hwnd, wParam, lParam);
1190
1191 case WM_GETTEXTLENGTH:
1192 return STATUSBAR_GetTextLength (hwnd, 0);
1193
1194 case WM_LBUTTONDBLCLK:
1195 return STATUSBAR_SendNotify (hwnd, NM_DBLCLK);
1196
1197 case WM_LBUTTONUP:
1198 return STATUSBAR_SendNotify (hwnd, NM_CLICK);
1199
1200 case WM_MOUSEMOVE:
1201 return STATUSBAR_WMMouseMove (hwnd, wParam, lParam);
1202
1203 case WM_NCHITTEST:
1204 return STATUSBAR_WMNCHitTest (hwnd, wParam, lParam);
1205
1206 case WM_NCLBUTTONDOWN:
1207 return STATUSBAR_WMNCLButtonDown (hwnd, wParam, lParam);
1208
1209 case WM_NCLBUTTONUP:
1210 return STATUSBAR_WMNCLButtonUp (hwnd, wParam, lParam);
1211
1212 case WM_PAINT:
1213 return STATUSBAR_WMPaint (hwnd, wParam);
1214
1215 case WM_RBUTTONDBLCLK:
1216 return STATUSBAR_SendNotify (hwnd, NM_RDBLCLK);
1217
1218 case WM_RBUTTONUP:
1219 return STATUSBAR_SendNotify (hwnd, NM_RCLICK);
1220
1221 case WM_SETFONT:
1222 return STATUSBAR_WMSetFont (hwnd, wParam, lParam);
1223
1224 case WM_SETTEXT:
1225 return STATUSBAR_WMSetText (hwnd, wParam, lParam);
1226
1227 case WM_SIZE:
1228 return STATUSBAR_WMSize (hwnd, wParam, lParam);
1229
1230 default:
1231 if (msg >= WM_USER)
1232// ERR (statusbar, "unknown msg %04x wp=%04x lp=%08lx\n",
1233// msg, wParam, lParam);
1234 return DefWindowProcA (hwnd, msg, wParam, lParam);
1235 }
1236 return 0;
1237}
1238
1239
1240/***********************************************************************
1241 * STATUS_Register [Internal]
1242 *
1243 * Registers the status window class.
1244 */
1245
1246VOID
1247STATUS_Register (VOID)
1248{
1249 WNDCLASSA wndClass;
1250
1251 if (GlobalFindAtomA (STATUSCLASSNAMEA)) return;
1252
1253 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
1254 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW;
1255 wndClass.lpfnWndProc = (WNDPROC)StatusWindowProc;
1256 wndClass.cbClsExtra = 0;
1257 wndClass.cbWndExtra = sizeof(STATUSWINDOWINFO *);
1258 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
1259 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
1260 wndClass.lpszClassName = STATUSCLASSNAMEA;
1261
1262 RegisterClassA (&wndClass);
1263}
1264
1265
1266/***********************************************************************
1267 * STATUS_Unregister [Internal]
1268 *
1269 * Unregisters the status window class.
1270 */
1271
1272VOID
1273STATUS_Unregister (VOID)
1274{
1275 if (GlobalFindAtomA (STATUSCLASSNAMEA))
1276 UnregisterClassA (STATUSCLASSNAMEA, (HINSTANCE)NULL);
1277}
1278
Note: See TracBrowser for help on using the repository browser.