Slightly improve keyboard tracking in combobox.
[wine/testsucceed.git] / dlls / comctl32 / status.c
blob6935334531e7ad2907baa3c1530805925e33b404
1 /*
2 * Interface code to StatusWindow widget/control
4 * Copyright 1996 Bruce Milner
5 * Copyright 1998, 1999 Eric Kohl
6 */
7 /*
8 * FIXME/TODO
9 * 1) Don't hard code bar to bottom of window, allow CCS_TOP also.
10 * 2) Tooltip support (almost done).
11 * 3) where else should we use infoPtr->hwndParent instead of GetParent() ?
12 * 4) send WM_QUERYFORMAT
15 #include <string.h>
16 #include "winbase.h"
17 #include "wine/unicode.h"
18 #include "commctrl.h"
19 #include "debugtools.h"
21 DEFAULT_DEBUG_CHANNEL(statusbar);
23 typedef struct
25 INT x;
26 INT style;
27 RECT bound;
28 LPWSTR text;
29 HICON hIcon;
30 } STATUSWINDOWPART;
32 typedef struct
34 HWND hwndParent;
35 WORD numParts;
36 WORD textHeight;
37 UINT height;
38 BOOL simple;
39 HWND hwndToolTip;
40 HFONT hFont;
41 HFONT hDefaultFont;
42 COLORREF clrBk; /* background color */
43 BOOL bUnicode; /* unicode flag */
44 STATUSWINDOWPART part0; /* simple window */
45 STATUSWINDOWPART *parts;
46 } STATUSWINDOWINFO;
49 * Run tests using Waite Group Windows95 API Bible Vol. 1&2
50 * The second cdrom contains executables drawstat.exe, gettext.exe,
51 * simple.exe, getparts.exe, setparts.exe, statwnd.exe
55 #define _MAX(a,b) (((a)>(b))?(a):(b))
56 #define _MIN(a,b) (((a)>(b))?(b):(a))
58 #define HORZ_BORDER 0
59 #define VERT_BORDER 2
60 #define HORZ_GAP 2
62 #define STATUSBAR_GetInfoPtr(hwnd) ((STATUSWINDOWINFO *)GetWindowLongA (hwnd, 0))
64 /* prototype */
65 static void
66 STATUSBAR_SetPartBounds (STATUSWINDOWINFO *infoPtr, HWND hwnd);
68 static void
69 STATUSBAR_DrawSizeGrip (HDC hdc, LPRECT lpRect)
71 HPEN hOldPen;
72 POINT pt;
73 INT i;
75 TRACE("draw size grip %d,%d - %d,%d\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
76 pt.x = lpRect->right - 1;
77 pt.y = lpRect->bottom - 1;
79 hOldPen = SelectObject (hdc, GetSysColorPen (COLOR_3DFACE));
80 MoveToEx (hdc, pt.x - 12, pt.y, NULL);
81 LineTo (hdc, pt.x, pt.y);
82 LineTo (hdc, pt.x, pt.y - 12);
84 pt.x--;
85 pt.y--;
87 SelectObject (hdc, GetSysColorPen (COLOR_3DSHADOW));
88 for (i = 1; i < 11; i += 4) {
89 MoveToEx (hdc, pt.x - i, pt.y, NULL);
90 LineTo (hdc, pt.x, pt.y - i);
92 MoveToEx (hdc, pt.x - i-1, pt.y, NULL);
93 LineTo (hdc, pt.x, pt.y - i-1);
96 SelectObject (hdc, GetSysColorPen (COLOR_3DHIGHLIGHT));
97 for (i = 3; i < 13; i += 4) {
98 MoveToEx (hdc, pt.x - i, pt.y, NULL);
99 LineTo (hdc, pt.x, pt.y - i);
102 SelectObject (hdc, hOldPen);
106 static void
107 STATUSBAR_DrawPart (HDC hdc, STATUSWINDOWPART *part)
109 RECT r = part->bound;
110 UINT border = BDR_SUNKENOUTER;
112 TRACE("part bound %d,%d - %d,%d\n", r.left, r.top, r.right, r.bottom);
113 if (part->style & SBT_POPOUT)
114 border = BDR_RAISEDOUTER;
115 else if (part->style & SBT_NOBORDERS)
116 border = 0;
118 DrawEdge(hdc, &r, border, BF_RECT|BF_ADJUST);
120 /* draw the icon */
121 if (part->hIcon) {
122 INT cy = r.bottom - r.top;
124 r.left += 2;
125 DrawIconEx (hdc, r.left, r.top, part->hIcon, cy, cy, 0, 0, DI_NORMAL);
126 r.left += cy;
129 /* now draw text */
130 if (part->text) {
131 int oldbkmode = SetBkMode(hdc, TRANSPARENT);
132 LPWSTR p = (LPWSTR)part->text;
133 UINT align = DT_LEFT;
134 if (*p == L'\t') {
135 p++;
136 align = DT_CENTER;
138 if (*p == L'\t') {
139 p++;
140 align = DT_RIGHT;
143 r.left += 3;
144 TRACE("%s at %d,%d - %d,%d\n", debugstr_w(p), r.left, r.top, r.right, r.bottom);
145 DrawTextW (hdc, p, -1, &r, align|DT_VCENTER|DT_SINGLELINE);
146 if (oldbkmode != TRANSPARENT)
147 SetBkMode(hdc, oldbkmode);
152 static VOID
153 STATUSBAR_RefreshPart (STATUSWINDOWINFO *infoPtr, HWND hwnd, STATUSWINDOWPART *part, HDC hdc, int itemID)
155 HBRUSH hbrBk;
156 HFONT hOldFont;
158 TRACE("item %d\n", itemID);
159 if (!IsWindowVisible (hwnd))
160 return;
162 if (part->bound.right < part->bound.left) return;
164 if (infoPtr->clrBk != CLR_DEFAULT)
165 hbrBk = CreateSolidBrush (infoPtr->clrBk);
166 else
167 hbrBk = GetSysColorBrush (COLOR_3DFACE);
168 FillRect(hdc, &part->bound, hbrBk);
170 hOldFont = SelectObject (hdc, infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont);
172 if (part->style & SBT_OWNERDRAW) {
173 DRAWITEMSTRUCT dis;
175 dis.CtlID = GetWindowLongA (hwnd, GWL_ID);
176 dis.itemID = itemID;
177 dis.hwndItem = hwnd;
178 dis.hDC = hdc;
179 dis.rcItem = part->bound;
180 dis.itemData = (INT)part->text;
181 SendMessageA (GetParent (hwnd), WM_DRAWITEM,
182 (WPARAM)dis.CtlID, (LPARAM)&dis);
183 } else
184 STATUSBAR_DrawPart (hdc, part);
186 SelectObject (hdc, hOldFont);
188 if (infoPtr->clrBk != CLR_DEFAULT)
189 DeleteObject (hbrBk);
191 if (GetWindowLongA (hwnd, GWL_STYLE) & SBARS_SIZEGRIP) {
192 RECT rect;
194 GetClientRect (hwnd, &rect);
195 STATUSBAR_DrawSizeGrip (hdc, &rect);
200 static BOOL
201 STATUSBAR_Refresh (STATUSWINDOWINFO *infoPtr, HWND hwnd, HDC hdc)
203 int i;
204 RECT rect;
205 HBRUSH hbrBk;
206 HFONT hOldFont;
208 TRACE("\n");
209 if (!IsWindowVisible(hwnd))
210 return (TRUE);
212 STATUSBAR_SetPartBounds(infoPtr, hwnd);
214 GetClientRect (hwnd, &rect);
216 if (infoPtr->clrBk != CLR_DEFAULT)
217 hbrBk = CreateSolidBrush (infoPtr->clrBk);
218 else
219 hbrBk = GetSysColorBrush (COLOR_3DFACE);
220 FillRect(hdc, &rect, hbrBk);
222 hOldFont = SelectObject (hdc, infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont);
224 if (infoPtr->simple) {
225 STATUSBAR_RefreshPart (infoPtr, hwnd, &infoPtr->part0, hdc, 0);
226 } else {
227 for (i = 0; i < infoPtr->numParts; i++) {
228 if (infoPtr->parts[i].style & SBT_OWNERDRAW) {
229 DRAWITEMSTRUCT dis;
231 dis.CtlID = GetWindowLongA (hwnd, GWL_ID);
232 dis.itemID = i;
233 dis.hwndItem = hwnd;
234 dis.hDC = hdc;
235 dis.rcItem = infoPtr->parts[i].bound;
236 dis.itemData = (INT)infoPtr->parts[i].text;
237 SendMessageA (GetParent (hwnd), WM_DRAWITEM,
238 (WPARAM)dis.CtlID, (LPARAM)&dis);
239 } else
240 STATUSBAR_RefreshPart (infoPtr, hwnd, &infoPtr->parts[i], hdc, i);
244 SelectObject (hdc, hOldFont);
246 if (infoPtr->clrBk != CLR_DEFAULT)
247 DeleteObject (hbrBk);
249 if (GetWindowLongA(hwnd, GWL_STYLE) & SBARS_SIZEGRIP)
250 STATUSBAR_DrawSizeGrip (hdc, &rect);
252 return TRUE;
256 static void
257 STATUSBAR_SetPartBounds (STATUSWINDOWINFO *infoPtr, HWND hwnd)
259 STATUSWINDOWPART *part;
260 RECT rect, *r;
261 int i;
263 /* get our window size */
264 GetClientRect (hwnd, &rect);
265 TRACE("client wnd size is %d,%d - %d,%d\n", rect.left, rect.top, rect.right, rect.bottom);
267 rect.top += VERT_BORDER;
269 /* set bounds for simple rectangle */
270 infoPtr->part0.bound = rect;
272 /* set bounds for non-simple rectangles */
273 for (i = 0; i < infoPtr->numParts; i++) {
274 part = &infoPtr->parts[i];
275 r = &infoPtr->parts[i].bound;
276 r->top = rect.top;
277 r->bottom = rect.bottom;
278 if (i == 0)
279 r->left = 0;
280 else
281 r->left = infoPtr->parts[i-1].bound.right + HORZ_GAP;
282 if (part->x == -1)
283 r->right = rect.right;
284 else
285 r->right = part->x;
287 if (infoPtr->hwndToolTip) {
288 TTTOOLINFOA ti;
290 ti.cbSize = sizeof(TTTOOLINFOA);
291 ti.hwnd = hwnd;
292 ti.uId = i;
293 ti.rect = *r;
294 SendMessageA (infoPtr->hwndToolTip, TTM_NEWTOOLRECTA,
295 0, (LPARAM)&ti);
301 static VOID
302 STATUSBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
303 WPARAM wParam, LPARAM lParam)
305 MSG msg;
307 msg.hwnd = hwndMsg;
308 msg.message = uMsg;
309 msg.wParam = wParam;
310 msg.lParam = lParam;
311 msg.time = GetMessageTime ();
312 msg.pt.x = LOWORD(GetMessagePos ());
313 msg.pt.y = HIWORD(GetMessagePos ());
315 SendMessageA (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
319 inline static LRESULT
320 STATUSBAR_GetBorders (LPARAM lParam)
322 LPINT out = (LPINT) lParam;
324 TRACE("\n");
325 out[0] = HORZ_BORDER; /* horizontal border width */
326 out[1] = VERT_BORDER; /* vertical border width */
327 out[2] = HORZ_GAP; /* width of border between rectangles */
329 return TRUE;
333 static LRESULT
334 STATUSBAR_GetIcon (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam)
336 INT nPart;
338 nPart = (INT)wParam & 0x00ff;
339 TRACE("%d\n", nPart);
340 if ((nPart < -1) || (nPart >= infoPtr->numParts))
341 return 0;
343 if (nPart == -1)
344 return (infoPtr->part0.hIcon);
345 else
346 return (infoPtr->parts[nPart].hIcon);
350 static LRESULT
351 STATUSBAR_GetParts (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam, LPARAM lParam)
353 LPINT parts;
354 INT num_parts;
355 INT i;
357 num_parts = (INT) wParam;
358 TRACE("(%d)\n", num_parts);
359 parts = (LPINT) lParam;
360 if (parts) {
361 for (i = 0; i < num_parts; i++) {
362 parts[i] = infoPtr->parts[i].x;
365 return (infoPtr->numParts);
369 static LRESULT
370 STATUSBAR_GetRect (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam, LPARAM lParam)
372 int nPart;
373 LPRECT rect;
375 nPart = ((INT) wParam) & 0x00ff;
376 TRACE("part %d\n", nPart);
377 rect = (LPRECT) lParam;
378 if (infoPtr->simple)
379 *rect = infoPtr->part0.bound;
380 else
381 *rect = infoPtr->parts[nPart].bound;
382 return TRUE;
386 static LRESULT
387 STATUSBAR_GetTextA (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam, LPARAM lParam)
389 STATUSWINDOWPART *part;
390 INT nPart;
391 LRESULT result;
393 nPart = ((INT) wParam) & 0x00ff;
394 TRACE("part %d\n", nPart);
395 if (infoPtr->simple)
396 part = &infoPtr->part0;
397 else
398 part = &infoPtr->parts[nPart];
400 if (part->style & SBT_OWNERDRAW)
401 result = (LRESULT)part->text;
402 else {
403 DWORD len = part->text ? WideCharToMultiByte( CP_ACP, 0, part->text, -1,
404 NULL, 0, NULL, NULL ) - 1 : 0;
405 result = MAKELONG( len, part->style );
406 if (lParam && len)
407 WideCharToMultiByte( CP_ACP, 0, part->text, -1, (LPSTR)lParam, len+1, NULL, NULL );
409 return result;
413 static LRESULT
414 STATUSBAR_GetTextW (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam, LPARAM lParam)
416 STATUSWINDOWPART *part;
417 INT nPart;
418 LRESULT result;
420 nPart = ((INT)wParam) & 0x00ff;
421 TRACE("part %d\n", nPart);
422 if (infoPtr->simple)
423 part = &infoPtr->part0;
424 else
425 part = &infoPtr->parts[nPart];
427 if (part->style & SBT_OWNERDRAW)
428 result = (LRESULT)part->text;
429 else {
430 result = part->text ? strlenW (part->text) : 0;
431 result |= (part->style << 16);
432 if (part->text && lParam)
433 strcpyW ((LPWSTR)lParam, part->text);
435 return result;
439 static LRESULT
440 STATUSBAR_GetTextLength (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam)
442 STATUSWINDOWPART *part;
443 INT nPart;
444 DWORD result;
446 nPart = ((INT) wParam) & 0x00ff;
448 TRACE("part %d\n", nPart);
449 if (infoPtr->simple)
450 part = &infoPtr->part0;
451 else
452 part = &infoPtr->parts[nPart];
454 if (part->text)
455 result = strlenW(part->text);
456 else
457 result = 0;
459 result |= (part->style << 16);
460 return result;
464 static LRESULT
465 STATUSBAR_GetTipTextA (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam, LPARAM lParam)
467 LPSTR tip = (LPSTR)lParam;
469 if (tip) {
470 CHAR buf[INFOTIPSIZE];
471 buf[0]='\0';
473 if (infoPtr->hwndToolTip) {
474 TTTOOLINFOA ti;
475 ti.cbSize = sizeof(TTTOOLINFOA);
476 ti.hwnd = hwnd;
477 ti.uId = LOWORD(wParam);
478 ti.lpszText = buf;
479 SendMessageA(infoPtr->hwndToolTip, TTM_GETTEXTA, 0, (LPARAM)&ti);
481 lstrcpynA(tip, buf, HIWORD(wParam));
483 return 0;
487 static LRESULT
488 STATUSBAR_GetTipTextW (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam, LPARAM lParam)
490 LPWSTR tip = (LPWSTR)lParam;
492 TRACE("\n");
493 if (tip) {
494 WCHAR buf[INFOTIPSIZE];
495 buf[0]=0;
497 if (infoPtr->hwndToolTip) {
498 TTTOOLINFOW ti;
499 ti.cbSize = sizeof(TTTOOLINFOW);
500 ti.hwnd = hwnd;
501 ti.uId = LOWORD(wParam);
502 ti.lpszText = buf;
503 SendMessageW(infoPtr->hwndToolTip, TTM_GETTEXTW, 0, (LPARAM)&ti);
505 lstrcpynW(tip, buf, HIWORD(wParam));
508 return 0;
512 inline static LRESULT
513 STATUSBAR_GetUnicodeFormat (STATUSWINDOWINFO *infoPtr, HWND hwnd)
515 return infoPtr->bUnicode;
519 inline static LRESULT
520 STATUSBAR_IsSimple (STATUSWINDOWINFO *infoPtr, HWND hwnd)
522 return infoPtr->simple;
526 static LRESULT
527 STATUSBAR_SetBkColor (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam, LPARAM lParam)
529 COLORREF oldBkColor;
531 oldBkColor = infoPtr->clrBk;
532 infoPtr->clrBk = (COLORREF)lParam;
533 InvalidateRect(hwnd, NULL, FALSE);
535 TRACE("CREF: %08lx -> %08lx\n", oldBkColor, infoPtr->clrBk);
536 return oldBkColor;
540 static LRESULT
541 STATUSBAR_SetIcon (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam, LPARAM lParam)
543 INT nPart = (INT)wParam & 0x00ff;
545 if ((nPart < -1) || (nPart >= infoPtr->numParts))
546 return FALSE;
548 TRACE("setting part %d, icon %lx\n",nPart,lParam);
550 if (nPart == -1) {
551 if (infoPtr->part0.hIcon == (HICON)lParam) /* same as - no redraw */
552 return TRUE;
553 infoPtr->part0.hIcon = (HICON)lParam;
554 if (infoPtr->simple)
555 InvalidateRect(hwnd, &infoPtr->part0.bound, FALSE);
556 } else {
557 if (infoPtr->parts[nPart].hIcon == (HICON)lParam) /* same as - no redraw */
558 return TRUE;
560 infoPtr->parts[nPart].hIcon = (HICON)lParam;
561 if (!(infoPtr->simple))
562 InvalidateRect(hwnd, &infoPtr->parts[nPart].bound, FALSE);
564 return TRUE;
568 static LRESULT
569 STATUSBAR_SetMinHeight (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam, LPARAM lParam)
572 TRACE("\n");
573 if (IsWindowVisible (hwnd)) {
574 HWND parent = GetParent (hwnd);
575 INT width, x, y;
576 RECT parent_rect;
578 GetClientRect (parent, &parent_rect);
579 infoPtr->height = (INT)wParam + VERT_BORDER;
580 width = parent_rect.right - parent_rect.left;
581 x = parent_rect.left;
582 y = parent_rect.bottom - infoPtr->height;
583 MoveWindow (hwnd, parent_rect.left,
584 parent_rect.bottom - infoPtr->height,
585 width, infoPtr->height, TRUE);
586 STATUSBAR_SetPartBounds (infoPtr, hwnd);
589 return TRUE;
593 static LRESULT
594 STATUSBAR_SetParts (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam, LPARAM lParam)
596 STATUSWINDOWPART *tmp;
597 LPINT parts;
598 int i;
599 int oldNumParts;
601 TRACE("(%d,%p)\n",wParam,(LPVOID)lParam);
603 /* FIXME: should return FALSE sometimes (maybe when wParam == 0 ?) */
604 if (infoPtr->simple)
605 infoPtr->simple = FALSE;
607 oldNumParts = infoPtr->numParts;
608 infoPtr->numParts = (INT) wParam;
609 parts = (LPINT) lParam;
610 if (oldNumParts > infoPtr->numParts) {
611 for (i = infoPtr->numParts ; i < oldNumParts; i++) {
612 if (infoPtr->parts[i].text && !(infoPtr->parts[i].style & SBT_OWNERDRAW))
613 COMCTL32_Free (infoPtr->parts[i].text);
616 if (oldNumParts < infoPtr->numParts) {
617 tmp = COMCTL32_Alloc (sizeof(STATUSWINDOWPART) * infoPtr->numParts);
618 for (i = 0; i < oldNumParts; i++) {
619 tmp[i] = infoPtr->parts[i];
621 if (infoPtr->parts)
622 COMCTL32_Free (infoPtr->parts);
623 infoPtr->parts = tmp;
625 if (oldNumParts == infoPtr->numParts) {
626 for (i=0;i<oldNumParts;i++)
627 if (infoPtr->parts[i].x != parts[i])
628 break;
629 if (i==oldNumParts) /* Unchanged? no need to redraw! */
630 return TRUE;
633 for (i = 0; i < infoPtr->numParts; i++)
634 infoPtr->parts[i].x = parts[i];
636 if (infoPtr->hwndToolTip) {
637 INT nTipCount =
638 SendMessageA (infoPtr->hwndToolTip, TTM_GETTOOLCOUNT, 0, 0);
640 if (nTipCount < infoPtr->numParts) {
641 /* add tools */
642 TTTOOLINFOA ti;
643 INT i;
645 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
646 ti.cbSize = sizeof(TTTOOLINFOA);
647 ti.hwnd = hwnd;
648 for (i = nTipCount; i < infoPtr->numParts; i++) {
649 TRACE("add tool %d\n", i);
650 ti.uId = i;
651 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
652 0, (LPARAM)&ti);
655 else if (nTipCount > infoPtr->numParts) {
656 /* delete tools */
657 INT i;
659 for (i = nTipCount - 1; i >= infoPtr->numParts; i--) {
660 FIXME("delete tool %d\n", i);
664 STATUSBAR_SetPartBounds (infoPtr, hwnd);
665 InvalidateRect(hwnd, NULL, FALSE);
666 return TRUE;
670 static LRESULT
671 STATUSBAR_SetTextA (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam, LPARAM lParam)
673 STATUSWINDOWPART *part=NULL;
674 int nPart;
675 int style;
676 LPSTR text;
677 BOOL changed = FALSE;
679 text = (LPSTR) lParam;
680 nPart = ((INT) wParam) & 0x00ff;
681 style = ((INT) wParam) & 0xff00;
683 TRACE("part %d, text %s\n",nPart,debugstr_a(text));
685 if (nPart==255)
686 part = &infoPtr->part0;
687 else if (!infoPtr->simple && infoPtr->parts!=NULL)
688 part = &infoPtr->parts[nPart];
689 if (!part) return FALSE;
691 if (part->style != style)
692 changed = TRUE;
694 part->style = style;
695 if (style & SBT_OWNERDRAW) {
696 if (part->text == (LPWSTR)text)
697 return TRUE;
698 part->text = (LPWSTR)text;
699 } else {
700 LPWSTR ntext;
702 /* check if text is unchanged -> no need to redraw */
703 if (text) {
704 DWORD len = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 );
705 LPWSTR tmptext = COMCTL32_Alloc(len*sizeof(WCHAR));
706 MultiByteToWideChar( CP_ACP, 0, text, -1, tmptext, len );
708 if (!changed && part->text && !lstrcmpW(tmptext,part->text)) {
709 COMCTL32_Free(tmptext);
710 return TRUE;
712 ntext = tmptext;
713 } else {
714 if (!changed && !part->text)
715 return TRUE;
716 ntext = 0;
719 if (part->text)
720 COMCTL32_Free (part->text);
721 part->text = ntext;
723 InvalidateRect(hwnd, &part->bound, FALSE);
725 return TRUE;
729 static LRESULT
730 STATUSBAR_SetTextW (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam, LPARAM lParam)
732 STATUSWINDOWPART *part;
733 INT nPart, style, len;
734 LPWSTR text;
735 BOOL bRedraw = FALSE;
737 text = (LPWSTR) lParam;
738 nPart = ((INT) wParam) & 0x00ff;
739 style = ((INT) wParam) & 0xff00;
741 TRACE("part %d -> '%s' with style %04x\n", nPart, debugstr_w(text), style);
742 if ((infoPtr->simple) || (infoPtr->parts==NULL) || (nPart==255))
743 part = &infoPtr->part0;
744 else
745 part = &infoPtr->parts[nPart];
746 if (!part) return FALSE;
748 if(part->style != style)
749 bRedraw = TRUE;
751 part->style = style;
753 /* FIXME: not sure how/if we can check for change in string with ownerdraw(remove this if we can't)... */
754 if (style & SBT_OWNERDRAW)
756 part->text = text;
757 bRedraw = TRUE;
758 } else if(!text)
760 if(part->text)
762 COMCTL32_Free(part->text);
763 bRedraw = TRUE;
765 part->text = 0;
766 } else if(!part->text || strcmpW(part->text, text)) /* see if the new string differs from the existing string */
768 if(part->text) COMCTL32_Free(part->text);
770 len = strlenW(text);
771 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
772 strcpyW(part->text, text);
773 bRedraw = TRUE;
776 if(bRedraw)
777 InvalidateRect(hwnd, &part->bound, FALSE);
779 return TRUE;
783 static LRESULT
784 STATUSBAR_SetTipTextA (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam, LPARAM lParam)
786 TRACE("part %d: \"%s\"\n", (INT)wParam, (LPSTR)lParam);
787 if (infoPtr->hwndToolTip) {
788 TTTOOLINFOA ti;
789 ti.cbSize = sizeof(TTTOOLINFOA);
790 ti.hwnd = hwnd;
791 ti.uId = (INT)wParam;
792 ti.hinst = 0;
793 ti.lpszText = (LPSTR)lParam;
794 SendMessageA (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTA,
795 0, (LPARAM)&ti);
798 return 0;
802 static LRESULT
803 STATUSBAR_SetTipTextW (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam, LPARAM lParam)
805 TRACE("part %d: \"%s\"\n", (INT)wParam, (LPSTR)lParam);
806 if (infoPtr->hwndToolTip) {
807 TTTOOLINFOW ti;
808 ti.cbSize = sizeof(TTTOOLINFOW);
809 ti.hwnd = hwnd;
810 ti.uId = (INT)wParam;
811 ti.hinst = 0;
812 ti.lpszText = (LPWSTR)lParam;
813 SendMessageW (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTW,
814 0, (LPARAM)&ti);
817 return 0;
821 inline static LRESULT
822 STATUSBAR_SetUnicodeFormat (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam)
824 BOOL bOld = infoPtr->bUnicode;
826 TRACE("(0x%x)\n", (BOOL)wParam);
827 infoPtr->bUnicode = (BOOL)wParam;
829 return bOld;
833 static LRESULT
834 STATUSBAR_Simple (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam, LPARAM lParam)
836 NMHDR nmhdr;
838 TRACE("(is simple: %d)\n", wParam);
839 if (infoPtr->simple == wParam) /* no need to change */
840 return TRUE;
842 infoPtr->simple = (BOOL)wParam;
844 /* send notification */
845 nmhdr.hwndFrom = hwnd;
846 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
847 nmhdr.code = SBN_SIMPLEMODECHANGE;
848 SendMessageA (GetParent (hwnd), WM_NOTIFY, 0, (LPARAM)&nmhdr);
849 InvalidateRect(hwnd, NULL, FALSE);
850 return TRUE;
854 static LRESULT
855 STATUSBAR_WMCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
857 LPCREATESTRUCTA lpCreate = (LPCREATESTRUCTA)lParam;
858 NONCLIENTMETRICSA nclm;
859 DWORD dwStyle;
860 RECT rect;
861 int width, len;
862 HDC hdc;
863 STATUSWINDOWINFO *infoPtr;
865 TRACE("\n");
866 infoPtr = (STATUSWINDOWINFO*)COMCTL32_Alloc (sizeof(STATUSWINDOWINFO));
867 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
869 infoPtr->hwndParent = lpCreate->hwndParent;
870 infoPtr->numParts = 1;
871 infoPtr->parts = 0;
872 infoPtr->simple = FALSE;
873 infoPtr->clrBk = CLR_DEFAULT;
874 infoPtr->hFont = 0;
876 /* TODO: send unicode parent notification query (WM_QUERYFORMAT) here */
878 GetClientRect (hwnd, &rect);
879 InvalidateRect (hwnd, &rect, 0);
880 UpdateWindow(hwnd);
882 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
883 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, nclm.cbSize, &nclm, 0);
884 infoPtr->hDefaultFont = CreateFontIndirectA (&nclm.lfStatusFont);
886 /* initialize simple case */
887 infoPtr->part0.bound = rect;
888 infoPtr->part0.text = 0;
889 infoPtr->part0.x = 0;
890 infoPtr->part0.style = 0;
891 infoPtr->part0.hIcon = 0;
893 /* initialize first part */
894 infoPtr->parts = COMCTL32_Alloc (sizeof(STATUSWINDOWPART));
895 infoPtr->parts[0].bound = rect;
896 infoPtr->parts[0].text = 0;
897 infoPtr->parts[0].x = -1;
898 infoPtr->parts[0].style = 0;
899 infoPtr->parts[0].hIcon = 0;
901 if (IsWindowUnicode (hwnd)) {
902 infoPtr->bUnicode = TRUE;
903 if (lpCreate->lpszName &&
904 (len = strlenW ((LPCWSTR)lpCreate->lpszName))) {
905 infoPtr->parts[0].text = COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
906 strcpyW (infoPtr->parts[0].text, (LPCWSTR)lpCreate->lpszName);
909 else {
910 if (lpCreate->lpszName &&
911 (len = strlen((LPCSTR)lpCreate->lpszName))) {
912 DWORD lenW = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)lpCreate->lpszName, -1, NULL, 0 );
913 infoPtr->parts[0].text = COMCTL32_Alloc (lenW*sizeof(WCHAR));
914 MultiByteToWideChar( CP_ACP, 0, (LPCSTR)lpCreate->lpszName, -1,
915 infoPtr->parts[0].text, lenW );
919 dwStyle = GetWindowLongA(hwnd, GWL_STYLE);
921 /* statusbars on managed windows should not have SIZEGRIP style */
922 if ((dwStyle & SBARS_SIZEGRIP) && lpCreate->hwndParent)
923 if (GetWindowLongA(lpCreate->hwndParent, GWL_EXSTYLE) & WS_EX_MANAGED)
924 SetWindowLongA (hwnd, GWL_STYLE, dwStyle & ~SBARS_SIZEGRIP);
926 if ((hdc = GetDC (0))) {
927 TEXTMETRICA tm;
928 HFONT hOldFont;
930 hOldFont = SelectObject (hdc,infoPtr->hDefaultFont);
931 GetTextMetricsA(hdc, &tm);
932 infoPtr->textHeight = tm.tmHeight;
933 SelectObject (hdc, hOldFont);
934 ReleaseDC(0, hdc);
937 if (dwStyle & SBT_TOOLTIPS) {
938 infoPtr->hwndToolTip =
939 CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
940 CW_USEDEFAULT, CW_USEDEFAULT,
941 CW_USEDEFAULT, CW_USEDEFAULT,
942 hwnd, 0,
943 GetWindowLongA (hwnd, GWL_HINSTANCE), NULL);
945 if (infoPtr->hwndToolTip) {
946 NMTOOLTIPSCREATED nmttc;
948 nmttc.hdr.hwndFrom = hwnd;
949 nmttc.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
950 nmttc.hdr.code = NM_TOOLTIPSCREATED;
951 nmttc.hwndToolTips = infoPtr->hwndToolTip;
953 SendMessageA (lpCreate->hwndParent, WM_NOTIFY,
954 (WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc);
958 if (!dwStyle & CCS_NORESIZE) /* don't resize wnd if it doesn't want it ! */
960 GetClientRect (GetParent (hwnd), &rect);
961 width = rect.right - rect.left;
962 infoPtr->height = infoPtr->textHeight + 4 + VERT_BORDER;
963 SetWindowPos(hwnd, 0, lpCreate->x, lpCreate->y - 1,
964 width, infoPtr->height, SWP_NOZORDER);
965 STATUSBAR_SetPartBounds (infoPtr, hwnd);
968 return 0;
972 static LRESULT
973 STATUSBAR_WMDestroy (STATUSWINDOWINFO *infoPtr, HWND hwnd)
975 int i;
977 TRACE("\n");
978 for (i = 0; i < infoPtr->numParts; i++) {
979 if (infoPtr->parts[i].text && !(infoPtr->parts[i].style & SBT_OWNERDRAW))
980 COMCTL32_Free (infoPtr->parts[i].text);
982 if (infoPtr->part0.text && !(infoPtr->part0.style & SBT_OWNERDRAW))
983 COMCTL32_Free (infoPtr->part0.text);
984 COMCTL32_Free (infoPtr->parts);
986 /* delete default font */
987 if (infoPtr->hDefaultFont)
988 DeleteObject (infoPtr->hDefaultFont);
990 /* delete tool tip control */
991 if (infoPtr->hwndToolTip)
992 DestroyWindow (infoPtr->hwndToolTip);
994 COMCTL32_Free (infoPtr);
995 SetWindowLongA(hwnd, 0, 0);
996 return 0;
1000 static inline LRESULT
1001 STATUSBAR_WMGetFont (STATUSWINDOWINFO *infoPtr, HWND hwnd)
1003 TRACE("\n");
1004 return infoPtr->hFont? infoPtr->hFont : infoPtr->hDefaultFont;
1008 /* in contrast to SB_GETTEXT*, WM_GETTEXT handles the text
1009 * of the first part only (usual behaviour) */
1010 static LRESULT
1011 STATUSBAR_WMGetText (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam, LPARAM lParam)
1013 INT len;
1015 TRACE("\n");
1016 if (!(infoPtr->parts[0].text))
1017 return 0;
1018 if (infoPtr->bUnicode)
1019 len = strlenW (infoPtr->parts[0].text);
1020 else
1021 len = WideCharToMultiByte( CP_ACP, 0, infoPtr->parts[0].text, -1, NULL, 0, NULL, NULL )-1;
1023 if (wParam > len) {
1024 if (infoPtr->bUnicode)
1025 strcpyW ((LPWSTR)lParam, infoPtr->parts[0].text);
1026 else
1027 WideCharToMultiByte( CP_ACP, 0, infoPtr->parts[0].text, -1,
1028 (LPSTR)lParam, len+1, NULL, NULL );
1029 return len;
1032 return -1;
1036 inline static LRESULT
1037 STATUSBAR_WMMouseMove (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam, LPARAM lParam)
1039 if (infoPtr->hwndToolTip)
1040 STATUSBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
1041 WM_MOUSEMOVE, wParam, lParam);
1042 return 0;
1046 static LRESULT
1047 STATUSBAR_WMNCHitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
1049 if (GetWindowLongA (hwnd, GWL_STYLE) & SBARS_SIZEGRIP) {
1050 RECT rect;
1051 POINT pt;
1053 GetClientRect (hwnd, &rect);
1055 pt.x = (INT)LOWORD(lParam);
1056 pt.y = (INT)HIWORD(lParam);
1057 ScreenToClient (hwnd, &pt);
1059 rect.left = rect.right - 13;
1060 rect.top += 2;
1062 if (PtInRect (&rect, pt))
1063 return HTBOTTOMRIGHT;
1066 /* FIXME: instead check result in StatusWindowProc and call if needed ? */
1067 return DefWindowProcA (hwnd, WM_NCHITTEST, wParam, lParam);
1071 static inline LRESULT
1072 STATUSBAR_WMNCLButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
1074 TRACE("\n");
1075 PostMessageA (GetParent (hwnd), WM_NCLBUTTONDOWN, wParam, lParam);
1076 return 0;
1080 static inline LRESULT
1081 STATUSBAR_WMNCLButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
1083 TRACE("\n");
1084 PostMessageA (GetParent (hwnd), WM_NCLBUTTONUP, wParam, lParam);
1085 return 0;
1089 static LRESULT
1090 STATUSBAR_WMPaint (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam)
1092 HDC hdc;
1093 PAINTSTRUCT ps;
1095 TRACE("\n");
1096 hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
1097 STATUSBAR_Refresh (infoPtr, hwnd, hdc);
1098 if (!wParam)
1099 EndPaint (hwnd, &ps);
1101 return 0;
1105 static LRESULT
1106 STATUSBAR_WMSetFont (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam, LPARAM lParam)
1108 infoPtr->hFont = (HFONT)wParam;
1109 TRACE("%04x\n", infoPtr->hFont);
1110 if (LOWORD(lParam) == TRUE)
1111 InvalidateRect(hwnd, NULL, FALSE);
1113 return 0;
1117 static LRESULT
1118 STATUSBAR_WMSetText (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam, LPARAM lParam)
1120 STATUSWINDOWPART *part;
1121 int len;
1123 TRACE("\n");
1124 if (infoPtr->numParts == 0)
1125 return FALSE;
1127 part = &infoPtr->parts[0];
1128 /* duplicate string */
1129 if (part->text)
1130 COMCTL32_Free (part->text);
1131 part->text = 0;
1132 if (infoPtr->bUnicode) {
1133 if (lParam && (len = strlenW((LPCWSTR)lParam))) {
1134 part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1135 strcpyW (part->text, (LPCWSTR)lParam);
1138 else {
1139 if (lParam && (len = lstrlenA((LPCSTR)lParam))) {
1140 DWORD lenW = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)lParam, -1, NULL, 0 );
1141 part->text = COMCTL32_Alloc (lenW*sizeof(WCHAR));
1142 MultiByteToWideChar( CP_ACP, 0, (LPCSTR)lParam, -1, part->text, lenW );
1146 InvalidateRect(hwnd, &part->bound, FALSE);
1148 return TRUE;
1152 static LRESULT
1153 STATUSBAR_WMSize (STATUSWINDOWINFO *infoPtr, HWND hwnd, WPARAM wParam, LPARAM lParam)
1155 INT width, x, y, flags;
1156 RECT parent_rect;
1157 DWORD dwStyle;
1159 /* Need to resize width to match parent */
1160 flags = (INT) wParam;
1162 TRACE("flags %04x\n", flags);
1163 /* FIXME for flags =
1164 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED, SIZE_RESTORED
1167 dwStyle = GetWindowLongA(hwnd, GWL_STYLE);
1168 if (!dwStyle & CCS_NORESIZE) /* don't resize wnd if it doesn't want it ! */
1170 if (flags == SIZE_RESTORED) {
1171 /* width and height don't apply */
1172 GetClientRect (infoPtr->hwndParent, &parent_rect);
1173 width = parent_rect.right - parent_rect.left;
1174 x = parent_rect.left;
1175 y = parent_rect.bottom - infoPtr->height;
1176 MoveWindow (hwnd, parent_rect.left,
1177 parent_rect.bottom - infoPtr->height,
1178 width, infoPtr->height, TRUE);
1179 STATUSBAR_SetPartBounds (infoPtr, hwnd);
1181 return 0; /* FIXME: ok to return here ? */
1184 /* FIXME: instead check result in StatusWindowProc and call if needed ? */
1185 return DefWindowProcA (hwnd, WM_SIZE, wParam, lParam);
1189 static LRESULT
1190 STATUSBAR_SendNotify (HWND hwnd, UINT code)
1192 NMHDR nmhdr;
1194 TRACE("code %04x\n", code);
1195 nmhdr.hwndFrom = hwnd;
1196 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1197 nmhdr.code = code;
1198 SendMessageA (GetParent (hwnd), WM_NOTIFY, 0, (LPARAM)&nmhdr);
1199 return 0;
1204 static LRESULT WINAPI
1205 StatusWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
1207 STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr(hwnd);
1209 TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hwnd, msg, wParam, lParam);
1210 if (!(infoPtr) && (msg != WM_CREATE))
1211 return DefWindowProcA (hwnd, msg, wParam, lParam);
1213 switch (msg) {
1214 case SB_GETBORDERS:
1215 return STATUSBAR_GetBorders (lParam);
1217 case SB_GETICON:
1218 return STATUSBAR_GetIcon (infoPtr, hwnd, wParam);
1220 case SB_GETPARTS:
1221 return STATUSBAR_GetParts (infoPtr, hwnd, wParam, lParam);
1223 case SB_GETRECT:
1224 return STATUSBAR_GetRect (infoPtr, hwnd, wParam, lParam);
1226 case SB_GETTEXTA:
1227 return STATUSBAR_GetTextA (infoPtr, hwnd, wParam, lParam);
1229 case SB_GETTEXTW:
1230 return STATUSBAR_GetTextW (infoPtr, hwnd, wParam, lParam);
1232 case SB_GETTEXTLENGTHA:
1233 case SB_GETTEXTLENGTHW:
1234 return STATUSBAR_GetTextLength (infoPtr, hwnd, wParam);
1236 case SB_GETTIPTEXTA:
1237 return STATUSBAR_GetTipTextA (infoPtr, hwnd, wParam, lParam);
1239 case SB_GETTIPTEXTW:
1240 return STATUSBAR_GetTipTextW (infoPtr, hwnd, wParam, lParam);
1242 case SB_GETUNICODEFORMAT:
1243 return STATUSBAR_GetUnicodeFormat (infoPtr, hwnd);
1245 case SB_ISSIMPLE:
1246 return STATUSBAR_IsSimple (infoPtr, hwnd);
1248 case SB_SETBKCOLOR:
1249 return STATUSBAR_SetBkColor (infoPtr, hwnd, wParam, lParam);
1251 case SB_SETICON:
1252 return STATUSBAR_SetIcon (infoPtr, hwnd, wParam, lParam);
1254 case SB_SETMINHEIGHT:
1255 return STATUSBAR_SetMinHeight (infoPtr, hwnd, wParam, lParam);
1257 case SB_SETPARTS:
1258 return STATUSBAR_SetParts (infoPtr, hwnd, wParam, lParam);
1260 case SB_SETTEXTA:
1261 return STATUSBAR_SetTextA (infoPtr, hwnd, wParam, lParam);
1263 case SB_SETTEXTW:
1264 return STATUSBAR_SetTextW (infoPtr, hwnd, wParam, lParam);
1266 case SB_SETTIPTEXTA:
1267 return STATUSBAR_SetTipTextA (infoPtr, hwnd, wParam, lParam);
1269 case SB_SETTIPTEXTW:
1270 return STATUSBAR_SetTipTextW (infoPtr, hwnd, wParam, lParam);
1272 case SB_SETUNICODEFORMAT:
1273 return STATUSBAR_SetUnicodeFormat (infoPtr, hwnd, wParam);
1275 case SB_SIMPLE:
1276 return STATUSBAR_Simple (infoPtr, hwnd, wParam, lParam);
1279 case WM_CREATE:
1280 return STATUSBAR_WMCreate (hwnd, wParam, lParam);
1282 case WM_DESTROY:
1283 return STATUSBAR_WMDestroy (infoPtr, hwnd);
1285 case WM_GETFONT:
1286 return STATUSBAR_WMGetFont (infoPtr, hwnd);
1288 case WM_GETTEXT:
1289 return STATUSBAR_WMGetText (infoPtr, hwnd, wParam, lParam);
1291 case WM_GETTEXTLENGTH:
1292 return STATUSBAR_GetTextLength (infoPtr, hwnd, 0);
1294 case WM_LBUTTONDBLCLK:
1295 return STATUSBAR_SendNotify (hwnd, NM_DBLCLK);
1297 case WM_LBUTTONUP:
1298 return STATUSBAR_SendNotify (hwnd, NM_CLICK);
1300 case WM_MOUSEMOVE:
1301 return STATUSBAR_WMMouseMove (infoPtr, hwnd, wParam, lParam);
1303 case WM_NCHITTEST:
1304 return STATUSBAR_WMNCHitTest (hwnd, wParam, lParam);
1306 case WM_NCLBUTTONDOWN:
1307 return STATUSBAR_WMNCLButtonDown (hwnd, wParam, lParam);
1309 case WM_NCLBUTTONUP:
1310 return STATUSBAR_WMNCLButtonUp (hwnd, wParam, lParam);
1312 case WM_PAINT:
1313 return STATUSBAR_WMPaint (infoPtr, hwnd, wParam);
1315 case WM_RBUTTONDBLCLK:
1316 return STATUSBAR_SendNotify (hwnd, NM_RDBLCLK);
1318 case WM_RBUTTONUP:
1319 return STATUSBAR_SendNotify (hwnd, NM_RCLICK);
1321 case WM_SETFONT:
1322 return STATUSBAR_WMSetFont (infoPtr, hwnd, wParam, lParam);
1324 case WM_SETTEXT:
1325 return STATUSBAR_WMSetText (infoPtr, hwnd, wParam, lParam);
1327 case WM_SIZE:
1328 return STATUSBAR_WMSize (infoPtr, hwnd, wParam, lParam);
1330 default:
1331 if (msg >= WM_USER)
1332 ERR("unknown msg %04x wp=%04x lp=%08lx\n",
1333 msg, wParam, lParam);
1334 return DefWindowProcA (hwnd, msg, wParam, lParam);
1336 return 0;
1340 /***********************************************************************
1341 * STATUS_Register [Internal]
1343 * Registers the status window class.
1346 VOID
1347 STATUS_Register (void)
1349 WNDCLASSA wndClass;
1351 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
1352 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW;
1353 wndClass.lpfnWndProc = (WNDPROC)StatusWindowProc;
1354 wndClass.cbClsExtra = 0;
1355 wndClass.cbWndExtra = sizeof(STATUSWINDOWINFO *);
1356 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
1357 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
1358 wndClass.lpszClassName = STATUSCLASSNAMEA;
1360 RegisterClassA (&wndClass);
1364 /***********************************************************************
1365 * STATUS_Unregister [Internal]
1367 * Unregisters the status window class.
1370 VOID
1371 STATUS_Unregister (void)
1373 UnregisterClassA (STATUSCLASSNAMEA, (HINSTANCE)NULL);