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

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

Added CVS tag to many files (comctl32 and headers) .

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