Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenstatus.c
Go to the documentation of this file.
00001 /* 00002 * Interface code to StatusWindow widget/control 00003 * 00004 * Copyright 1996 Bruce Milner 00005 * Copyright 1998, 1999 Eric Kohl 00006 * Copyright 2002 Dimitrie O. Paun 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00021 * 00022 * NOTE 00023 * 00024 * This code was audited for completeness against the documented features 00025 * of Comctl32.dll version 6.0 on Sep. 24, 2002, by Dimitrie O. Paun. 00026 * 00027 * Unless otherwise noted, we believe this code to be complete, as per 00028 * the specification mentioned above. 00029 * If you discover missing features, or bugs, please note them below. 00030 * 00031 * TODO: 00032 * -- CCS_BOTTOM (default) 00033 * -- CCS_LEFT 00034 * -- CCS_NODIVIDER 00035 * -- CCS_NOMOVEX 00036 * -- CCS_NOMOVEY 00037 * -- CCS_NOPARENTALIGN 00038 * -- CCS_RIGHT 00039 * -- CCS_TOP 00040 * -- CCS_VERT (defaults to RIGHT) 00041 */ 00042 00043 #include <stdarg.h> 00044 #include <string.h> 00045 00046 #include "windef.h" 00047 #include "winbase.h" 00048 #include "wine/unicode.h" 00049 #include "wingdi.h" 00050 #include "winuser.h" 00051 #include "winnls.h" 00052 #include "commctrl.h" 00053 #include "comctl32.h" 00054 #include "uxtheme.h" 00055 #include "vssym32.h" 00056 #include "wine/debug.h" 00057 00058 WINE_DEFAULT_DEBUG_CHANNEL(statusbar); 00059 00060 typedef struct 00061 { 00062 INT x; 00063 INT style; 00064 RECT bound; 00065 LPWSTR text; 00066 HICON hIcon; 00067 } STATUSWINDOWPART; 00068 00069 typedef struct 00070 { 00071 HWND Self; 00072 HWND Notify; 00073 WORD numParts; 00074 UINT height; 00075 UINT minHeight; /* at least MIN_PANE_HEIGHT, can be increased by SB_SETMINHEIGHT */ 00076 BOOL simple; 00077 HWND hwndToolTip; 00078 HFONT hFont; 00079 HFONT hDefaultFont; 00080 COLORREF clrBk; /* background color */ 00081 BOOL bUnicode; /* notify format. TRUE if notifies in Unicode */ 00082 STATUSWINDOWPART part0; /* simple window */ 00083 STATUSWINDOWPART* parts; 00084 INT horizontalBorder; 00085 INT verticalBorder; 00086 INT horizontalGap; 00087 } STATUS_INFO; 00088 00089 /* 00090 * Run tests using Waite Group Windows95 API Bible Vol. 1&2 00091 * The second cdrom contains executables drawstat.exe, gettext.exe, 00092 * simple.exe, getparts.exe, setparts.exe, statwnd.exe 00093 */ 00094 00095 #define HORZ_BORDER 0 00096 #define VERT_BORDER 2 00097 #define HORZ_GAP 2 00098 00099 static const WCHAR themeClass[] = { 'S','t','a','t','u','s',0 }; 00100 00101 /* prototype */ 00102 static void 00103 STATUSBAR_SetPartBounds (STATUS_INFO *infoPtr); 00104 static LRESULT 00105 STATUSBAR_NotifyFormat (STATUS_INFO *infoPtr, HWND from, INT cmd); 00106 00107 static inline LPCSTR debugstr_t(LPCWSTR text, BOOL isW) 00108 { 00109 return isW ? debugstr_w(text) : debugstr_a((LPCSTR)text); 00110 } 00111 00112 static UINT 00113 STATUSBAR_ComputeHeight(STATUS_INFO *infoPtr) 00114 { 00115 HTHEME theme; 00116 UINT height; 00117 TEXTMETRICW tm; 00118 int margin; 00119 00120 COMCTL32_GetFontMetrics(infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont, &tm); 00121 margin = (tm.tmInternalLeading ? tm.tmInternalLeading : 2); 00122 height = max(tm.tmHeight + margin + 2*GetSystemMetrics(SM_CYBORDER), infoPtr->minHeight) + infoPtr->verticalBorder; 00123 00124 if ((theme = GetWindowTheme(infoPtr->Self))) 00125 { 00126 /* Determine bar height from theme such that the content area is 00127 * textHeight pixels large */ 00128 HDC hdc = GetDC(infoPtr->Self); 00129 RECT r; 00130 memset (&r, 0, sizeof (r)); 00131 r.bottom = max(infoPtr->minHeight, tm.tmHeight); 00132 if (SUCCEEDED(GetThemeBackgroundExtent(theme, hdc, SP_PANE, 0, &r, &r))) 00133 { 00134 height = r.bottom - r.top; 00135 } 00136 ReleaseDC(infoPtr->Self, hdc); 00137 } 00138 00139 TRACE(" textHeight=%d+%d, final height=%d\n", tm.tmHeight, tm.tmInternalLeading, height); 00140 return height; 00141 } 00142 00143 static void 00144 STATUSBAR_DrawSizeGrip (HTHEME theme, HDC hdc, LPRECT lpRect) 00145 { 00146 HPEN hPenFace, hPenShadow, hPenHighlight, hOldPen; 00147 POINT pt; 00148 INT i; 00149 00150 TRACE("draw size grip %s\n", wine_dbgstr_rect(lpRect)); 00151 00152 if (theme) 00153 { 00154 RECT gripperRect; 00155 SIZE gripperSize; 00156 gripperRect = *lpRect; 00157 if (SUCCEEDED (GetThemePartSize (theme, hdc, SP_GRIPPER, 0, lpRect, 00158 TS_DRAW, &gripperSize))) 00159 { 00160 gripperRect.left = gripperRect.right - gripperSize.cx; 00161 gripperRect.top = gripperRect.bottom - gripperSize.cy; 00162 if (SUCCEEDED (DrawThemeBackground(theme, hdc, SP_GRIPPER, 0, &gripperRect, NULL))) 00163 return; 00164 } 00165 } 00166 00167 pt.x = lpRect->right - 1; 00168 pt.y = lpRect->bottom - 1; 00169 00170 hPenFace = CreatePen( PS_SOLID, 1, comctl32_color.clr3dFace); 00171 hOldPen = SelectObject( hdc, hPenFace ); 00172 MoveToEx (hdc, pt.x - 12, pt.y, NULL); 00173 LineTo (hdc, pt.x, pt.y); 00174 LineTo (hdc, pt.x, pt.y - 13); 00175 00176 pt.x--; 00177 pt.y--; 00178 00179 hPenShadow = CreatePen( PS_SOLID, 1, comctl32_color.clr3dShadow); 00180 SelectObject( hdc, hPenShadow ); 00181 for (i = 1; i < 11; i += 4) { 00182 MoveToEx (hdc, pt.x - i, pt.y, NULL); 00183 LineTo (hdc, pt.x + 1, pt.y - i - 1); 00184 00185 MoveToEx (hdc, pt.x - i - 1, pt.y, NULL); 00186 LineTo (hdc, pt.x + 1, pt.y - i - 2); 00187 } 00188 00189 hPenHighlight = CreatePen( PS_SOLID, 1, comctl32_color.clr3dHilight); 00190 SelectObject( hdc, hPenHighlight ); 00191 for (i = 3; i < 13; i += 4) { 00192 MoveToEx (hdc, pt.x - i, pt.y, NULL); 00193 LineTo (hdc, pt.x + 1, pt.y - i - 1); 00194 } 00195 00196 SelectObject (hdc, hOldPen); 00197 DeleteObject( hPenFace ); 00198 DeleteObject( hPenShadow ); 00199 DeleteObject( hPenHighlight ); 00200 } 00201 00202 00203 static void 00204 STATUSBAR_DrawPart (const STATUS_INFO *infoPtr, HDC hdc, const STATUSWINDOWPART *part, int itemID) 00205 { 00206 RECT r = part->bound; 00207 UINT border = BDR_SUNKENOUTER; 00208 HTHEME theme = GetWindowTheme (infoPtr->Self); 00209 int themePart = SP_PANE; 00210 int x = 0; 00211 00212 TRACE("part bound %s\n", wine_dbgstr_rect(&r)); 00213 if (part->style & SBT_POPOUT) 00214 border = BDR_RAISEDOUTER; 00215 else if (part->style & SBT_NOBORDERS) 00216 border = 0; 00217 00218 if (theme) 00219 { 00220 if ((GetWindowLongW (infoPtr->Self, GWL_STYLE) & SBARS_SIZEGRIP) 00221 && (infoPtr->simple || (itemID == (infoPtr->numParts-1)))) 00222 themePart = SP_GRIPPERPANE; 00223 DrawThemeBackground(theme, hdc, themePart, 0, &r, NULL); 00224 } 00225 else 00226 DrawEdge(hdc, &r, border, BF_RECT|BF_ADJUST); 00227 00228 if (part->hIcon) { 00229 INT cy = r.bottom - r.top; 00230 DrawIconEx (hdc, r.left + 2, r.top, part->hIcon, cy, cy, 0, 0, DI_NORMAL); 00231 x = 2 + cy; 00232 } 00233 00234 if (part->style & SBT_OWNERDRAW) { 00235 DRAWITEMSTRUCT dis; 00236 00237 dis.CtlID = GetWindowLongPtrW (infoPtr->Self, GWLP_ID); 00238 dis.itemID = itemID; 00239 dis.hwndItem = infoPtr->Self; 00240 dis.hDC = hdc; 00241 dis.rcItem = r; 00242 dis.itemData = (ULONG_PTR)part->text; 00243 SendMessageW (infoPtr->Notify, WM_DRAWITEM, dis.CtlID, (LPARAM)&dis); 00244 } else { 00245 r.left += x; 00246 DrawStatusTextW (hdc, &r, part->text, SBT_NOBORDERS); 00247 } 00248 } 00249 00250 00251 static void 00252 STATUSBAR_RefreshPart (const STATUS_INFO *infoPtr, HDC hdc, const STATUSWINDOWPART *part, int itemID) 00253 { 00254 HBRUSH hbrBk; 00255 HTHEME theme; 00256 00257 TRACE("item %d\n", itemID); 00258 00259 if (part->bound.right < part->bound.left) return; 00260 00261 if (!RectVisible(hdc, &part->bound)) 00262 return; 00263 00264 if ((theme = GetWindowTheme (infoPtr->Self))) 00265 { 00266 RECT cr; 00267 GetClientRect (infoPtr->Self, &cr); 00268 DrawThemeBackground(theme, hdc, 0, 0, &cr, &part->bound); 00269 } 00270 else 00271 { 00272 if (infoPtr->clrBk != CLR_DEFAULT) 00273 hbrBk = CreateSolidBrush (infoPtr->clrBk); 00274 else 00275 hbrBk = GetSysColorBrush (COLOR_3DFACE); 00276 FillRect(hdc, &part->bound, hbrBk); 00277 if (infoPtr->clrBk != CLR_DEFAULT) 00278 DeleteObject (hbrBk); 00279 } 00280 00281 STATUSBAR_DrawPart (infoPtr, hdc, part, itemID); 00282 } 00283 00284 00285 static LRESULT 00286 STATUSBAR_Refresh (STATUS_INFO *infoPtr, HDC hdc) 00287 { 00288 int i; 00289 RECT rect; 00290 HBRUSH hbrBk; 00291 HFONT hOldFont; 00292 HTHEME theme; 00293 00294 TRACE("\n"); 00295 if (!IsWindowVisible(infoPtr->Self)) 00296 return 0; 00297 00298 STATUSBAR_SetPartBounds(infoPtr); 00299 00300 GetClientRect (infoPtr->Self, &rect); 00301 00302 if ((theme = GetWindowTheme (infoPtr->Self))) 00303 { 00304 DrawThemeBackground(theme, hdc, 0, 0, &rect, NULL); 00305 } 00306 else 00307 { 00308 if (infoPtr->clrBk != CLR_DEFAULT) 00309 hbrBk = CreateSolidBrush (infoPtr->clrBk); 00310 else 00311 hbrBk = GetSysColorBrush (COLOR_3DFACE); 00312 FillRect(hdc, &rect, hbrBk); 00313 if (infoPtr->clrBk != CLR_DEFAULT) 00314 DeleteObject (hbrBk); 00315 } 00316 00317 hOldFont = SelectObject (hdc, infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont); 00318 00319 if (infoPtr->simple) { 00320 STATUSBAR_RefreshPart (infoPtr, hdc, &infoPtr->part0, 0); 00321 } else { 00322 for (i = 0; i < infoPtr->numParts; i++) { 00323 STATUSBAR_RefreshPart (infoPtr, hdc, &infoPtr->parts[i], i); 00324 } 00325 } 00326 00327 SelectObject (hdc, hOldFont); 00328 00329 if (GetWindowLongW (infoPtr->Self, GWL_STYLE) & SBARS_SIZEGRIP) 00330 STATUSBAR_DrawSizeGrip (theme, hdc, &rect); 00331 00332 return 0; 00333 } 00334 00335 00336 static int 00337 STATUSBAR_InternalHitTest(const STATUS_INFO *infoPtr, const POINT *pt) 00338 { 00339 int i; 00340 if (infoPtr->simple) 00341 return 255; 00342 00343 for (i = 0; i < infoPtr->numParts; i++) 00344 if (pt->x >= infoPtr->parts[i].bound.left && pt->x <= infoPtr->parts[i].bound.right) 00345 return i; 00346 return -2; 00347 } 00348 00349 00350 static void 00351 STATUSBAR_SetPartBounds (STATUS_INFO *infoPtr) 00352 { 00353 STATUSWINDOWPART *part; 00354 RECT rect, *r; 00355 int i; 00356 00357 /* get our window size */ 00358 GetClientRect (infoPtr->Self, &rect); 00359 TRACE("client wnd size is %s\n", wine_dbgstr_rect(&rect)); 00360 00361 rect.left += infoPtr->horizontalBorder; 00362 rect.top += infoPtr->verticalBorder; 00363 00364 /* set bounds for simple rectangle */ 00365 infoPtr->part0.bound = rect; 00366 00367 /* set bounds for non-simple rectangles */ 00368 for (i = 0; i < infoPtr->numParts; i++) { 00369 part = &infoPtr->parts[i]; 00370 r = &infoPtr->parts[i].bound; 00371 r->top = rect.top; 00372 r->bottom = rect.bottom; 00373 if (i == 0) 00374 r->left = 0; 00375 else 00376 r->left = infoPtr->parts[i-1].bound.right + infoPtr->horizontalGap; 00377 if (part->x == -1) 00378 r->right = rect.right; 00379 else 00380 r->right = part->x; 00381 00382 if (infoPtr->hwndToolTip) { 00383 TTTOOLINFOW ti; 00384 00385 ti.cbSize = sizeof(TTTOOLINFOW); 00386 ti.hwnd = infoPtr->Self; 00387 ti.uId = i; 00388 ti.rect = *r; 00389 SendMessageW (infoPtr->hwndToolTip, TTM_NEWTOOLRECTW, 00390 0, (LPARAM)&ti); 00391 } 00392 } 00393 } 00394 00395 00396 static LRESULT 00397 STATUSBAR_Relay2Tip (const STATUS_INFO *infoPtr, UINT uMsg, 00398 WPARAM wParam, LPARAM lParam) 00399 { 00400 MSG msg; 00401 00402 msg.hwnd = infoPtr->Self; 00403 msg.message = uMsg; 00404 msg.wParam = wParam; 00405 msg.lParam = lParam; 00406 msg.time = GetMessageTime (); 00407 msg.pt.x = (short)LOWORD(GetMessagePos ()); 00408 msg.pt.y = (short)HIWORD(GetMessagePos ()); 00409 00410 return SendMessageW (infoPtr->hwndToolTip, TTM_RELAYEVENT, 0, (LPARAM)&msg); 00411 } 00412 00413 00414 static BOOL 00415 STATUSBAR_GetBorders (const STATUS_INFO *infoPtr, INT out[]) 00416 { 00417 TRACE("\n"); 00418 out[0] = infoPtr->horizontalBorder; 00419 out[1] = infoPtr->verticalBorder; 00420 out[2] = infoPtr->horizontalGap; 00421 00422 return TRUE; 00423 } 00424 00425 00426 static BOOL 00427 STATUSBAR_SetBorders (STATUS_INFO *infoPtr, const INT in[]) 00428 { 00429 TRACE("\n"); 00430 infoPtr->horizontalBorder = in[0]; 00431 infoPtr->verticalBorder = in[1]; 00432 infoPtr->horizontalGap = in[2]; 00433 InvalidateRect(infoPtr->Self, NULL, FALSE); 00434 00435 return TRUE; 00436 } 00437 00438 00439 static HICON 00440 STATUSBAR_GetIcon (const STATUS_INFO *infoPtr, INT nPart) 00441 { 00442 TRACE("%d\n", nPart); 00443 /* MSDN says: "simple parts are indexed with -1" */ 00444 if ((nPart < -1) || (nPart >= infoPtr->numParts)) 00445 return 0; 00446 00447 if (nPart == -1) 00448 return (infoPtr->part0.hIcon); 00449 else 00450 return (infoPtr->parts[nPart].hIcon); 00451 } 00452 00453 00454 static INT 00455 STATUSBAR_GetParts (const STATUS_INFO *infoPtr, INT num_parts, INT parts[]) 00456 { 00457 INT i; 00458 00459 TRACE("(%d)\n", num_parts); 00460 if (parts) { 00461 for (i = 0; i < num_parts; i++) { 00462 parts[i] = infoPtr->parts[i].x; 00463 } 00464 } 00465 return infoPtr->numParts; 00466 } 00467 00468 00469 static BOOL 00470 STATUSBAR_GetRect (const STATUS_INFO *infoPtr, INT nPart, LPRECT rect) 00471 { 00472 TRACE("part %d\n", nPart); 00473 if(nPart >= infoPtr->numParts || nPart < 0) 00474 return FALSE; 00475 if (infoPtr->simple) 00476 *rect = infoPtr->part0.bound; 00477 else 00478 *rect = infoPtr->parts[nPart].bound; 00479 return TRUE; 00480 } 00481 00482 00483 static LRESULT 00484 STATUSBAR_GetTextA (STATUS_INFO *infoPtr, INT nPart, LPSTR buf) 00485 { 00486 STATUSWINDOWPART *part; 00487 LRESULT result; 00488 00489 TRACE("part %d\n", nPart); 00490 00491 /* MSDN says: "simple parts use index of 0", so this check is ok. */ 00492 if (nPart < 0 || nPart >= infoPtr->numParts) return 0; 00493 00494 if (infoPtr->simple) 00495 part = &infoPtr->part0; 00496 else 00497 part = &infoPtr->parts[nPart]; 00498 00499 if (part->style & SBT_OWNERDRAW) 00500 result = (LRESULT)part->text; 00501 else { 00502 DWORD len = part->text ? WideCharToMultiByte( CP_ACP, 0, part->text, -1, 00503 NULL, 0, NULL, NULL ) - 1 : 0; 00504 result = MAKELONG( len, part->style ); 00505 if (part->text && buf) 00506 WideCharToMultiByte( CP_ACP, 0, part->text, -1, buf, len+1, NULL, NULL ); 00507 } 00508 return result; 00509 } 00510 00511 00512 static LRESULT 00513 STATUSBAR_GetTextW (STATUS_INFO *infoPtr, INT nPart, LPWSTR buf) 00514 { 00515 STATUSWINDOWPART *part; 00516 LRESULT result; 00517 00518 TRACE("part %d\n", nPart); 00519 if (nPart < 0 || nPart >= infoPtr->numParts) return 0; 00520 00521 if (infoPtr->simple) 00522 part = &infoPtr->part0; 00523 else 00524 part = &infoPtr->parts[nPart]; 00525 00526 if (part->style & SBT_OWNERDRAW) 00527 result = (LRESULT)part->text; 00528 else { 00529 result = part->text ? strlenW (part->text) : 0; 00530 result |= (part->style << 16); 00531 if (part->text && buf) 00532 strcpyW (buf, part->text); 00533 } 00534 return result; 00535 } 00536 00537 00538 static LRESULT 00539 STATUSBAR_GetTextLength (STATUS_INFO *infoPtr, INT nPart) 00540 { 00541 STATUSWINDOWPART *part; 00542 DWORD result; 00543 00544 TRACE("part %d\n", nPart); 00545 00546 /* MSDN says: "simple parts use index of 0", so this check is ok. */ 00547 if (nPart < 0 || nPart >= infoPtr->numParts) return 0; 00548 00549 if (infoPtr->simple) 00550 part = &infoPtr->part0; 00551 else 00552 part = &infoPtr->parts[nPart]; 00553 00554 if ((~part->style & SBT_OWNERDRAW) && part->text) 00555 result = strlenW(part->text); 00556 else 00557 result = 0; 00558 00559 result |= (part->style << 16); 00560 return result; 00561 } 00562 00563 static LRESULT 00564 STATUSBAR_GetTipTextA (const STATUS_INFO *infoPtr, INT id, LPSTR tip, INT size) 00565 { 00566 TRACE("\n"); 00567 if (tip) { 00568 CHAR buf[INFOTIPSIZE]; 00569 buf[0]='\0'; 00570 00571 if (infoPtr->hwndToolTip) { 00572 TTTOOLINFOA ti; 00573 ti.cbSize = sizeof(TTTOOLINFOA); 00574 ti.hwnd = infoPtr->Self; 00575 ti.uId = id; 00576 ti.lpszText = buf; 00577 SendMessageA (infoPtr->hwndToolTip, TTM_GETTEXTA, 0, (LPARAM)&ti); 00578 } 00579 lstrcpynA (tip, buf, size); 00580 } 00581 return 0; 00582 } 00583 00584 00585 static LRESULT 00586 STATUSBAR_GetTipTextW (const STATUS_INFO *infoPtr, INT id, LPWSTR tip, INT size) 00587 { 00588 TRACE("\n"); 00589 if (tip) { 00590 WCHAR buf[INFOTIPSIZE]; 00591 buf[0]=0; 00592 00593 if (infoPtr->hwndToolTip) { 00594 TTTOOLINFOW ti; 00595 ti.cbSize = sizeof(TTTOOLINFOW); 00596 ti.hwnd = infoPtr->Self; 00597 ti.uId = id; 00598 ti.lpszText = buf; 00599 SendMessageW(infoPtr->hwndToolTip, TTM_GETTEXTW, 0, (LPARAM)&ti); 00600 } 00601 lstrcpynW(tip, buf, size); 00602 } 00603 00604 return 0; 00605 } 00606 00607 00608 static COLORREF 00609 STATUSBAR_SetBkColor (STATUS_INFO *infoPtr, COLORREF color) 00610 { 00611 COLORREF oldBkColor; 00612 00613 oldBkColor = infoPtr->clrBk; 00614 infoPtr->clrBk = color; 00615 InvalidateRect(infoPtr->Self, NULL, FALSE); 00616 00617 TRACE("CREF: %08x -> %08x\n", oldBkColor, infoPtr->clrBk); 00618 return oldBkColor; 00619 } 00620 00621 00622 static BOOL 00623 STATUSBAR_SetIcon (STATUS_INFO *infoPtr, INT nPart, HICON hIcon) 00624 { 00625 if ((nPart < -1) || (nPart >= infoPtr->numParts)) 00626 return FALSE; 00627 00628 TRACE("setting part %d\n", nPart); 00629 00630 /* FIXME: MSDN says "if nPart is -1, the status bar is assumed simple" */ 00631 if (nPart == -1) { 00632 if (infoPtr->part0.hIcon == hIcon) /* same as - no redraw */ 00633 return TRUE; 00634 infoPtr->part0.hIcon = hIcon; 00635 if (infoPtr->simple) 00636 InvalidateRect(infoPtr->Self, &infoPtr->part0.bound, FALSE); 00637 } else { 00638 if (infoPtr->parts[nPart].hIcon == hIcon) /* same as - no redraw */ 00639 return TRUE; 00640 00641 infoPtr->parts[nPart].hIcon = hIcon; 00642 if (!(infoPtr->simple)) 00643 InvalidateRect(infoPtr->Self, &infoPtr->parts[nPart].bound, FALSE); 00644 } 00645 return TRUE; 00646 } 00647 00648 00649 static BOOL 00650 STATUSBAR_SetMinHeight (STATUS_INFO *infoPtr, INT height) 00651 { 00652 DWORD ysize = GetSystemMetrics(SM_CYSIZE); 00653 if (ysize & 1) ysize--; 00654 infoPtr->minHeight = max(height, ysize); 00655 infoPtr->height = STATUSBAR_ComputeHeight(infoPtr); 00656 /* like native, don't resize the control */ 00657 return TRUE; 00658 } 00659 00660 00661 static BOOL 00662 STATUSBAR_SetParts (STATUS_INFO *infoPtr, INT count, LPINT parts) 00663 { 00664 STATUSWINDOWPART *tmp; 00665 INT i, oldNumParts; 00666 00667 TRACE("(%d,%p)\n", count, parts); 00668 00669 if(!count) return FALSE; 00670 00671 oldNumParts = infoPtr->numParts; 00672 infoPtr->numParts = count; 00673 if (oldNumParts > infoPtr->numParts) { 00674 for (i = infoPtr->numParts ; i < oldNumParts; i++) { 00675 if (!(infoPtr->parts[i].style & SBT_OWNERDRAW)) 00676 Free (infoPtr->parts[i].text); 00677 } 00678 } else if (oldNumParts < infoPtr->numParts) { 00679 tmp = Alloc (sizeof(STATUSWINDOWPART) * infoPtr->numParts); 00680 if (!tmp) return FALSE; 00681 for (i = 0; i < oldNumParts; i++) { 00682 tmp[i] = infoPtr->parts[i]; 00683 } 00684 Free (infoPtr->parts); 00685 infoPtr->parts = tmp; 00686 } 00687 if (oldNumParts == infoPtr->numParts) { 00688 for (i=0; i < oldNumParts; i++) 00689 if (infoPtr->parts[i].x != parts[i]) 00690 break; 00691 if (i==oldNumParts) /* Unchanged? no need to redraw! */ 00692 return TRUE; 00693 } 00694 00695 for (i = 0; i < infoPtr->numParts; i++) 00696 infoPtr->parts[i].x = parts[i]; 00697 00698 if (infoPtr->hwndToolTip) { 00699 INT nTipCount; 00700 TTTOOLINFOW ti; 00701 00702 ZeroMemory (&ti, sizeof(TTTOOLINFOW)); 00703 ti.cbSize = sizeof(TTTOOLINFOW); 00704 ti.hwnd = infoPtr->Self; 00705 00706 nTipCount = SendMessageW (infoPtr->hwndToolTip, TTM_GETTOOLCOUNT, 0, 0); 00707 if (nTipCount < infoPtr->numParts) { 00708 /* add tools */ 00709 for (i = nTipCount; i < infoPtr->numParts; i++) { 00710 TRACE("add tool %d\n", i); 00711 ti.uId = i; 00712 SendMessageW (infoPtr->hwndToolTip, TTM_ADDTOOLW, 00713 0, (LPARAM)&ti); 00714 } 00715 } 00716 else if (nTipCount > infoPtr->numParts) { 00717 /* delete tools */ 00718 for (i = nTipCount - 1; i >= infoPtr->numParts; i--) { 00719 TRACE("delete tool %d\n", i); 00720 ti.uId = i; 00721 SendMessageW (infoPtr->hwndToolTip, TTM_DELTOOLW, 00722 0, (LPARAM)&ti); 00723 } 00724 } 00725 } 00726 STATUSBAR_SetPartBounds (infoPtr); 00727 InvalidateRect(infoPtr->Self, NULL, FALSE); 00728 return TRUE; 00729 } 00730 00731 00732 static BOOL 00733 STATUSBAR_SetTextT (STATUS_INFO *infoPtr, INT nPart, WORD style, 00734 LPWSTR text, BOOL isW) 00735 { 00736 STATUSWINDOWPART *part=NULL; 00737 BOOL changed = FALSE; 00738 INT oldStyle; 00739 00740 if (style & SBT_OWNERDRAW) { 00741 TRACE("part %d, text %p\n",nPart,text); 00742 } 00743 else TRACE("part %d, text %s\n", nPart, debugstr_t(text, isW)); 00744 00745 /* MSDN says: "If the parameter is set to SB_SIMPLEID (255), the status 00746 * window is assumed to be a simple window */ 00747 00748 if (nPart == 0x00ff) { 00749 part = &infoPtr->part0; 00750 } else { 00751 if (infoPtr->parts && nPart >= 0 && nPart < infoPtr->numParts) { 00752 part = &infoPtr->parts[nPart]; 00753 } 00754 } 00755 if (!part) return FALSE; 00756 00757 if (part->style != style) 00758 changed = TRUE; 00759 00760 oldStyle = part->style; 00761 part->style = style; 00762 if (style & SBT_OWNERDRAW) { 00763 if (!(oldStyle & SBT_OWNERDRAW)) 00764 Free (part->text); 00765 part->text = text; 00766 } else { 00767 LPWSTR ntext; 00768 WCHAR *idx; 00769 00770 if (text && !isW) { 00771 LPCSTR atxt = (LPCSTR)text; 00772 DWORD len = MultiByteToWideChar( CP_ACP, 0, atxt, -1, NULL, 0 ); 00773 ntext = Alloc( (len + 1)*sizeof(WCHAR) ); 00774 if (!ntext) return FALSE; 00775 MultiByteToWideChar( CP_ACP, 0, atxt, -1, ntext, len ); 00776 } else if (text) { 00777 ntext = Alloc( (strlenW(text) + 1)*sizeof(WCHAR) ); 00778 if (!ntext) return FALSE; 00779 strcpyW (ntext, text); 00780 } else ntext = 0; 00781 00782 /* replace nonprintable characters with spaces */ 00783 if (ntext) { 00784 idx = ntext; 00785 while (*idx) { 00786 if(!isprintW(*idx)) 00787 *idx = ' '; 00788 idx++; 00789 } 00790 } 00791 00792 /* check if text is unchanged -> no need to redraw */ 00793 if (text) { 00794 if (!changed && part->text && !lstrcmpW(ntext, part->text)) { 00795 Free(ntext); 00796 return TRUE; 00797 } 00798 } else { 00799 if (!changed && !part->text) 00800 return TRUE; 00801 } 00802 00803 if (!(oldStyle & SBT_OWNERDRAW)) 00804 Free (part->text); 00805 part->text = ntext; 00806 } 00807 InvalidateRect(infoPtr->Self, &part->bound, FALSE); 00808 UpdateWindow(infoPtr->Self); 00809 00810 return TRUE; 00811 } 00812 00813 00814 static LRESULT 00815 STATUSBAR_SetTipTextA (const STATUS_INFO *infoPtr, INT id, LPSTR text) 00816 { 00817 TRACE("part %d: \"%s\"\n", id, text); 00818 if (infoPtr->hwndToolTip) { 00819 TTTOOLINFOA ti; 00820 ti.cbSize = sizeof(TTTOOLINFOA); 00821 ti.hwnd = infoPtr->Self; 00822 ti.uId = id; 00823 ti.hinst = 0; 00824 ti.lpszText = text; 00825 SendMessageA (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTA, 0, (LPARAM)&ti); 00826 } 00827 00828 return 0; 00829 } 00830 00831 00832 static LRESULT 00833 STATUSBAR_SetTipTextW (const STATUS_INFO *infoPtr, INT id, LPWSTR text) 00834 { 00835 TRACE("part %d: \"%s\"\n", id, debugstr_w(text)); 00836 if (infoPtr->hwndToolTip) { 00837 TTTOOLINFOW ti; 00838 ti.cbSize = sizeof(TTTOOLINFOW); 00839 ti.hwnd = infoPtr->Self; 00840 ti.uId = id; 00841 ti.hinst = 0; 00842 ti.lpszText = text; 00843 SendMessageW (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTW, 0, (LPARAM)&ti); 00844 } 00845 00846 return 0; 00847 } 00848 00849 00850 static inline LRESULT 00851 STATUSBAR_SetUnicodeFormat (STATUS_INFO *infoPtr, BOOL bUnicode) 00852 { 00853 BOOL bOld = infoPtr->bUnicode; 00854 00855 TRACE("(0x%x)\n", bUnicode); 00856 infoPtr->bUnicode = bUnicode; 00857 00858 return bOld; 00859 } 00860 00861 00862 static BOOL 00863 STATUSBAR_Simple (STATUS_INFO *infoPtr, BOOL simple) 00864 { 00865 NMHDR nmhdr; 00866 00867 TRACE("(simple=%d)\n", simple); 00868 if (infoPtr->simple == simple) /* no need to change */ 00869 return TRUE; 00870 00871 infoPtr->simple = simple; 00872 00873 /* send notification */ 00874 nmhdr.hwndFrom = infoPtr->Self; 00875 nmhdr.idFrom = GetWindowLongPtrW (infoPtr->Self, GWLP_ID); 00876 nmhdr.code = SBN_SIMPLEMODECHANGE; 00877 SendMessageW (infoPtr->Notify, WM_NOTIFY, 0, (LPARAM)&nmhdr); 00878 InvalidateRect(infoPtr->Self, NULL, FALSE); 00879 return TRUE; 00880 } 00881 00882 00883 static LRESULT 00884 STATUSBAR_WMDestroy (STATUS_INFO *infoPtr) 00885 { 00886 int i; 00887 00888 TRACE("\n"); 00889 for (i = 0; i < infoPtr->numParts; i++) { 00890 if (!(infoPtr->parts[i].style & SBT_OWNERDRAW)) 00891 Free (infoPtr->parts[i].text); 00892 } 00893 if (!(infoPtr->part0.style & SBT_OWNERDRAW)) 00894 Free (infoPtr->part0.text); 00895 Free (infoPtr->parts); 00896 00897 /* delete default font */ 00898 if (infoPtr->hDefaultFont) 00899 DeleteObject (infoPtr->hDefaultFont); 00900 00901 /* delete tool tip control */ 00902 if (infoPtr->hwndToolTip) 00903 DestroyWindow (infoPtr->hwndToolTip); 00904 00905 CloseThemeData (GetWindowTheme (infoPtr->Self)); 00906 00907 SetWindowLongPtrW(infoPtr->Self, 0, 0); 00908 Free (infoPtr); 00909 return 0; 00910 } 00911 00912 00913 static LRESULT 00914 STATUSBAR_WMCreate (HWND hwnd, const CREATESTRUCTA *lpCreate) 00915 { 00916 STATUS_INFO *infoPtr; 00917 NONCLIENTMETRICSW nclm; 00918 DWORD dwStyle; 00919 RECT rect; 00920 int len; 00921 00922 TRACE("\n"); 00923 infoPtr = Alloc (sizeof(STATUS_INFO)); 00924 if (!infoPtr) goto create_fail; 00925 SetWindowLongPtrW (hwnd, 0, (DWORD_PTR)infoPtr); 00926 00927 infoPtr->Self = hwnd; 00928 infoPtr->Notify = lpCreate->hwndParent; 00929 infoPtr->numParts = 1; 00930 infoPtr->parts = 0; 00931 infoPtr->simple = FALSE; 00932 infoPtr->clrBk = CLR_DEFAULT; 00933 infoPtr->hFont = 0; 00934 infoPtr->horizontalBorder = HORZ_BORDER; 00935 infoPtr->verticalBorder = VERT_BORDER; 00936 infoPtr->horizontalGap = HORZ_GAP; 00937 infoPtr->minHeight = GetSystemMetrics(SM_CYSIZE); 00938 if (infoPtr->minHeight & 1) infoPtr->minHeight--; 00939 00940 STATUSBAR_NotifyFormat(infoPtr, infoPtr->Notify, NF_REQUERY); 00941 00942 ZeroMemory (&nclm, sizeof(nclm)); 00943 nclm.cbSize = sizeof(nclm); 00944 SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, nclm.cbSize, &nclm, 0); 00945 infoPtr->hDefaultFont = CreateFontIndirectW (&nclm.lfStatusFont); 00946 00947 GetClientRect (hwnd, &rect); 00948 00949 /* initialize simple case */ 00950 infoPtr->part0.bound = rect; 00951 infoPtr->part0.text = 0; 00952 infoPtr->part0.x = 0; 00953 infoPtr->part0.style = 0; 00954 infoPtr->part0.hIcon = 0; 00955 00956 /* initialize first part */ 00957 infoPtr->parts = Alloc (sizeof(STATUSWINDOWPART)); 00958 if (!infoPtr->parts) goto create_fail; 00959 infoPtr->parts[0].bound = rect; 00960 infoPtr->parts[0].text = 0; 00961 infoPtr->parts[0].x = -1; 00962 infoPtr->parts[0].style = 0; 00963 infoPtr->parts[0].hIcon = 0; 00964 00965 OpenThemeData (hwnd, themeClass); 00966 00967 if (lpCreate->lpszName && (len = strlenW ((LPCWSTR)lpCreate->lpszName))) 00968 { 00969 infoPtr->parts[0].text = Alloc ((len + 1)*sizeof(WCHAR)); 00970 if (!infoPtr->parts[0].text) goto create_fail; 00971 strcpyW (infoPtr->parts[0].text, (LPCWSTR)lpCreate->lpszName); 00972 } 00973 00974 dwStyle = GetWindowLongW (hwnd, GWL_STYLE); 00975 /* native seems to clear WS_BORDER, too */ 00976 dwStyle &= ~WS_BORDER; 00977 SetWindowLongW (hwnd, GWL_STYLE, dwStyle); 00978 00979 infoPtr->height = STATUSBAR_ComputeHeight(infoPtr); 00980 00981 if (dwStyle & SBT_TOOLTIPS) { 00982 infoPtr->hwndToolTip = 00983 CreateWindowExW (0, TOOLTIPS_CLASSW, NULL, WS_POPUP | TTS_ALWAYSTIP, 00984 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 00985 CW_USEDEFAULT, hwnd, 0, 00986 (HINSTANCE)GetWindowLongPtrW(hwnd, GWLP_HINSTANCE), NULL); 00987 00988 if (infoPtr->hwndToolTip) { 00989 NMTOOLTIPSCREATED nmttc; 00990 00991 nmttc.hdr.hwndFrom = hwnd; 00992 nmttc.hdr.idFrom = GetWindowLongPtrW (hwnd, GWLP_ID); 00993 nmttc.hdr.code = NM_TOOLTIPSCREATED; 00994 nmttc.hwndToolTips = infoPtr->hwndToolTip; 00995 00996 SendMessageW (lpCreate->hwndParent, WM_NOTIFY, nmttc.hdr.idFrom, (LPARAM)&nmttc); 00997 } 00998 } 00999 01000 return 0; 01001 01002 create_fail: 01003 TRACE(" failed!\n"); 01004 if (infoPtr) STATUSBAR_WMDestroy(infoPtr); 01005 return -1; 01006 } 01007 01008 01009 /* in contrast to SB_GETTEXT*, WM_GETTEXT handles the text 01010 * of the first part only (usual behaviour) */ 01011 static INT 01012 STATUSBAR_WMGetText (const STATUS_INFO *infoPtr, INT size, LPWSTR buf) 01013 { 01014 INT len; 01015 01016 TRACE("\n"); 01017 if (!(infoPtr->parts[0].text)) 01018 return 0; 01019 01020 len = strlenW (infoPtr->parts[0].text); 01021 01022 if (!size) 01023 return len; 01024 else if (size > len) { 01025 strcpyW (buf, infoPtr->parts[0].text); 01026 return len; 01027 } 01028 else { 01029 memcpy (buf, infoPtr->parts[0].text, (size - 1) * sizeof(WCHAR)); 01030 buf[size - 1] = 0; 01031 return size - 1; 01032 } 01033 } 01034 01035 01036 static BOOL 01037 STATUSBAR_WMNCHitTest (const STATUS_INFO *infoPtr, INT x, INT y) 01038 { 01039 if (GetWindowLongW (infoPtr->Self, GWL_STYLE) & SBARS_SIZEGRIP) { 01040 RECT rect; 01041 POINT pt; 01042 01043 GetClientRect (infoPtr->Self, &rect); 01044 01045 pt.x = x; 01046 pt.y = y; 01047 ScreenToClient (infoPtr->Self, &pt); 01048 01049 rect.left = rect.right - 13; 01050 rect.top += 2; 01051 01052 if (PtInRect (&rect, pt)) 01053 { 01054 if (GetWindowLongW( infoPtr->Self, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) return HTBOTTOMLEFT; 01055 else return HTBOTTOMRIGHT; 01056 } 01057 } 01058 01059 return HTERROR; 01060 } 01061 01062 01063 static LRESULT 01064 STATUSBAR_WMPaint (STATUS_INFO *infoPtr, HDC hdc) 01065 { 01066 PAINTSTRUCT ps; 01067 01068 TRACE("\n"); 01069 if (hdc) return STATUSBAR_Refresh (infoPtr, hdc); 01070 hdc = BeginPaint (infoPtr->Self, &ps); 01071 STATUSBAR_Refresh (infoPtr, hdc); 01072 EndPaint (infoPtr->Self, &ps); 01073 01074 return 0; 01075 } 01076 01077 01078 static LRESULT 01079 STATUSBAR_WMSetFont (STATUS_INFO *infoPtr, HFONT font, BOOL redraw) 01080 { 01081 infoPtr->hFont = font; 01082 TRACE("%p\n", infoPtr->hFont); 01083 01084 infoPtr->height = STATUSBAR_ComputeHeight(infoPtr); 01085 SendMessageW(infoPtr->Self, WM_SIZE, 0, 0); /* update size */ 01086 if (redraw) 01087 InvalidateRect(infoPtr->Self, NULL, FALSE); 01088 01089 return 0; 01090 } 01091 01092 01093 static BOOL 01094 STATUSBAR_WMSetText (const STATUS_INFO *infoPtr, LPCSTR text) 01095 { 01096 STATUSWINDOWPART *part; 01097 int len; 01098 01099 TRACE("\n"); 01100 if (infoPtr->numParts == 0) 01101 return FALSE; 01102 01103 part = &infoPtr->parts[0]; 01104 /* duplicate string */ 01105 Free (part->text); 01106 part->text = 0; 01107 01108 if (text && (len = strlenW((LPCWSTR)text))) { 01109 part->text = Alloc ((len+1)*sizeof(WCHAR)); 01110 if (!part->text) return FALSE; 01111 strcpyW (part->text, (LPCWSTR)text); 01112 } 01113 01114 InvalidateRect(infoPtr->Self, &part->bound, FALSE); 01115 01116 return TRUE; 01117 } 01118 01119 01120 static BOOL 01121 STATUSBAR_WMSize (STATUS_INFO *infoPtr, WORD flags) 01122 { 01123 INT width, x, y; 01124 RECT parent_rect; 01125 01126 /* Need to resize width to match parent */ 01127 TRACE("flags %04x\n", flags); 01128 01129 if (flags != SIZE_RESTORED && flags != SIZE_MAXIMIZED) { 01130 WARN("flags MUST be SIZE_RESTORED or SIZE_MAXIMIZED\n"); 01131 return FALSE; 01132 } 01133 01134 if (GetWindowLongW(infoPtr->Self, GWL_STYLE) & CCS_NORESIZE) return FALSE; 01135 01136 /* width and height don't apply */ 01137 if (!GetClientRect (infoPtr->Notify, &parent_rect)) 01138 return FALSE; 01139 01140 width = parent_rect.right - parent_rect.left; 01141 x = parent_rect.left; 01142 y = parent_rect.bottom - infoPtr->height; 01143 MoveWindow (infoPtr->Self, x, y, width, infoPtr->height, TRUE); 01144 STATUSBAR_SetPartBounds (infoPtr); 01145 return TRUE; 01146 } 01147 01148 01149 /* update theme after a WM_THEMECHANGED message */ 01150 static LRESULT theme_changed (const STATUS_INFO* infoPtr) 01151 { 01152 HTHEME theme = GetWindowTheme (infoPtr->Self); 01153 CloseThemeData (theme); 01154 OpenThemeData (infoPtr->Self, themeClass); 01155 return 0; 01156 } 01157 01158 01159 static LRESULT 01160 STATUSBAR_NotifyFormat (STATUS_INFO *infoPtr, HWND from, INT cmd) 01161 { 01162 if (cmd == NF_REQUERY) { 01163 INT i = SendMessageW(from, WM_NOTIFYFORMAT, (WPARAM)infoPtr->Self, NF_QUERY); 01164 infoPtr->bUnicode = (i == NFR_UNICODE); 01165 } 01166 return infoPtr->bUnicode ? NFR_UNICODE : NFR_ANSI; 01167 } 01168 01169 01170 static LRESULT 01171 STATUSBAR_SendMouseNotify(const STATUS_INFO *infoPtr, UINT code, UINT msg, WPARAM wParam, LPARAM lParam) 01172 { 01173 NMMOUSE nm; 01174 01175 TRACE("code %04x, lParam=%lx\n", code, lParam); 01176 nm.hdr.hwndFrom = infoPtr->Self; 01177 nm.hdr.idFrom = GetWindowLongPtrW(infoPtr->Self, GWLP_ID); 01178 nm.hdr.code = code; 01179 nm.pt.x = (short)LOWORD(lParam); 01180 nm.pt.y = (short)HIWORD(lParam); 01181 nm.dwItemSpec = STATUSBAR_InternalHitTest(infoPtr, &nm.pt); 01182 nm.dwItemData = 0; 01183 nm.dwHitInfo = 0x30000; /* seems constant */ 01184 01185 /* Do default processing if WM_NOTIFY returns zero */ 01186 if(!SendMessageW(infoPtr->Notify, WM_NOTIFY, nm.hdr.idFrom, (LPARAM)&nm)) 01187 { 01188 return DefWindowProcW(infoPtr->Self, msg, wParam, lParam); 01189 } 01190 return 0; 01191 } 01192 01193 01194 01195 static LRESULT WINAPI 01196 StatusWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 01197 { 01198 STATUS_INFO *infoPtr = (STATUS_INFO *)GetWindowLongPtrW (hwnd, 0); 01199 INT nPart = ((INT) wParam) & 0x00ff; 01200 LRESULT res; 01201 01202 TRACE("hwnd=%p msg=%x wparam=%lx lparam=%lx\n", hwnd, msg, wParam, lParam); 01203 if (!infoPtr && msg != WM_CREATE) 01204 return DefWindowProcW (hwnd, msg, wParam, lParam); 01205 01206 switch (msg) { 01207 case SB_GETBORDERS: 01208 return STATUSBAR_GetBorders (infoPtr, (INT *)lParam); 01209 01210 case SB_GETICON: 01211 return (LRESULT)STATUSBAR_GetIcon (infoPtr, nPart); 01212 01213 case SB_GETPARTS: 01214 return STATUSBAR_GetParts (infoPtr, (INT)wParam, (INT *)lParam); 01215 01216 case SB_GETRECT: 01217 return STATUSBAR_GetRect (infoPtr, nPart, (LPRECT)lParam); 01218 01219 case SB_GETTEXTA: 01220 return STATUSBAR_GetTextA (infoPtr, nPart, (LPSTR)lParam); 01221 01222 case SB_GETTEXTW: 01223 return STATUSBAR_GetTextW (infoPtr, nPart, (LPWSTR)lParam); 01224 01225 case SB_GETTEXTLENGTHA: 01226 case SB_GETTEXTLENGTHW: 01227 return STATUSBAR_GetTextLength (infoPtr, nPart); 01228 01229 case SB_GETTIPTEXTA: 01230 return STATUSBAR_GetTipTextA (infoPtr, LOWORD(wParam), (LPSTR)lParam, HIWORD(wParam)); 01231 01232 case SB_GETTIPTEXTW: 01233 return STATUSBAR_GetTipTextW (infoPtr, LOWORD(wParam), (LPWSTR)lParam, HIWORD(wParam)); 01234 01235 case SB_GETUNICODEFORMAT: 01236 return infoPtr->bUnicode; 01237 01238 case SB_ISSIMPLE: 01239 return infoPtr->simple; 01240 01241 case SB_SETBORDERS: 01242 return STATUSBAR_SetBorders (infoPtr, (INT *)lParam); 01243 01244 case SB_SETBKCOLOR: 01245 return STATUSBAR_SetBkColor (infoPtr, (COLORREF)lParam); 01246 01247 case SB_SETICON: 01248 return STATUSBAR_SetIcon (infoPtr, nPart, (HICON)lParam); 01249 01250 case SB_SETMINHEIGHT: 01251 return STATUSBAR_SetMinHeight (infoPtr, (INT)wParam); 01252 01253 case SB_SETPARTS: 01254 return STATUSBAR_SetParts (infoPtr, (INT)wParam, (LPINT)lParam); 01255 01256 case SB_SETTEXTA: 01257 return STATUSBAR_SetTextT (infoPtr, nPart, wParam & 0xff00, (LPWSTR)lParam, FALSE); 01258 01259 case SB_SETTEXTW: 01260 return STATUSBAR_SetTextT (infoPtr, nPart, wParam & 0xff00, (LPWSTR)lParam, TRUE); 01261 01262 case SB_SETTIPTEXTA: 01263 return STATUSBAR_SetTipTextA (infoPtr, (INT)wParam, (LPSTR)lParam); 01264 01265 case SB_SETTIPTEXTW: 01266 return STATUSBAR_SetTipTextW (infoPtr, (INT)wParam, (LPWSTR)lParam); 01267 01268 case SB_SETUNICODEFORMAT: 01269 return STATUSBAR_SetUnicodeFormat (infoPtr, (BOOL)wParam); 01270 01271 case SB_SIMPLE: 01272 return STATUSBAR_Simple (infoPtr, (BOOL)wParam); 01273 01274 case WM_CREATE: 01275 return STATUSBAR_WMCreate (hwnd, (LPCREATESTRUCTA)lParam); 01276 01277 case WM_DESTROY: 01278 return STATUSBAR_WMDestroy (infoPtr); 01279 01280 case WM_GETFONT: 01281 return (LRESULT)(infoPtr->hFont? infoPtr->hFont : infoPtr->hDefaultFont); 01282 01283 case WM_GETTEXT: 01284 return STATUSBAR_WMGetText (infoPtr, (INT)wParam, (LPWSTR)lParam); 01285 01286 case WM_GETTEXTLENGTH: 01287 return STATUSBAR_GetTextLength (infoPtr, 0); 01288 01289 case WM_LBUTTONDBLCLK: 01290 return STATUSBAR_SendMouseNotify(infoPtr, NM_DBLCLK, msg, wParam, lParam); 01291 01292 case WM_LBUTTONUP: 01293 return STATUSBAR_SendMouseNotify(infoPtr, NM_CLICK, msg, wParam, lParam); 01294 01295 case WM_MOUSEMOVE: 01296 return STATUSBAR_Relay2Tip (infoPtr, msg, wParam, lParam); 01297 01298 case WM_NCHITTEST: 01299 res = STATUSBAR_WMNCHitTest(infoPtr, (short)LOWORD(lParam), 01300 (short)HIWORD(lParam)); 01301 if (res != HTERROR) return res; 01302 return DefWindowProcW (hwnd, msg, wParam, lParam); 01303 01304 case WM_NCLBUTTONUP: 01305 case WM_NCLBUTTONDOWN: 01306 PostMessageW (infoPtr->Notify, msg, wParam, lParam); 01307 return 0; 01308 01309 case WM_NOTIFYFORMAT: 01310 return STATUSBAR_NotifyFormat(infoPtr, (HWND)wParam, (INT)lParam); 01311 01312 case WM_PRINTCLIENT: 01313 case WM_PAINT: 01314 return STATUSBAR_WMPaint (infoPtr, (HDC)wParam); 01315 01316 case WM_RBUTTONDBLCLK: 01317 return STATUSBAR_SendMouseNotify(infoPtr, NM_RDBLCLK, msg, wParam, lParam); 01318 01319 case WM_RBUTTONUP: 01320 return STATUSBAR_SendMouseNotify(infoPtr, NM_RCLICK, msg, wParam, lParam); 01321 01322 case WM_SETFONT: 01323 return STATUSBAR_WMSetFont (infoPtr, (HFONT)wParam, LOWORD(lParam)); 01324 01325 case WM_SETTEXT: 01326 return STATUSBAR_WMSetText (infoPtr, (LPCSTR)lParam); 01327 01328 case WM_SIZE: 01329 if (STATUSBAR_WMSize (infoPtr, (WORD)wParam)) return 0; 01330 return DefWindowProcW (hwnd, msg, wParam, lParam); 01331 01332 case WM_SYSCOLORCHANGE: 01333 COMCTL32_RefreshSysColors(); 01334 return 0; 01335 01336 case WM_THEMECHANGED: 01337 return theme_changed (infoPtr); 01338 01339 default: 01340 if ((msg >= WM_USER) && (msg < WM_APP) && !COMCTL32_IsReflectedMessage(msg)) 01341 ERR("unknown msg %04x wp=%04lx lp=%08lx\n", 01342 msg, wParam, lParam); 01343 return DefWindowProcW (hwnd, msg, wParam, lParam); 01344 } 01345 } 01346 01347 01348 /*********************************************************************** 01349 * STATUS_Register [Internal] 01350 * 01351 * Registers the status window class. 01352 */ 01353 01354 void 01355 STATUS_Register (void) 01356 { 01357 WNDCLASSW wndClass; 01358 01359 ZeroMemory (&wndClass, sizeof(WNDCLASSW)); 01360 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW; 01361 wndClass.lpfnWndProc = StatusWindowProc; 01362 wndClass.cbClsExtra = 0; 01363 wndClass.cbWndExtra = sizeof(STATUS_INFO *); 01364 wndClass.hCursor = LoadCursorW (0, (LPWSTR)IDC_ARROW); 01365 wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); 01366 wndClass.lpszClassName = STATUSCLASSNAMEW; 01367 01368 RegisterClassW (&wndClass); 01369 } 01370 01371 01372 /*********************************************************************** 01373 * STATUS_Unregister [Internal] 01374 * 01375 * Unregisters the status window class. 01376 */ 01377 01378 void 01379 STATUS_Unregister (void) 01380 { 01381 UnregisterClassW (STATUSCLASSNAMEW, NULL); 01382 } Generated on Sat May 26 2012 04:21:37 for ReactOS by
1.7.6.1
|