ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

status.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.