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

static.c
Go to the documentation of this file.
00001 /*
00002  * Static control
00003  *
00004  * Copyright  David W. Metcalfe, 1993
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  *
00020  * NOTES
00021  *
00022  * This code was audited for completeness against the documented features
00023  * of Comctl32.dll version 6.0 on Oct. 4, 2004, by Dimitrie O. Paun.
00024  *
00025  * Unless otherwise noted, we believe this code to be complete, as per
00026  * the specification mentioned above.
00027  * If you discover missing features, or bugs, please note them below.
00028  *
00029  * Notes:
00030  *   - Windows XP introduced new behavior: The background of centered
00031  *     icons and bitmaps is painted differently. This is only done if
00032  *     a manifest is present.
00033  *     Because it has not yet been decided how to implement the two
00034  *     different modes in Wine, only the Windows XP mode is implemented.
00035  *   - Controls with SS_SIMPLE but without SS_NOPREFIX:
00036  *     The text should not be changed. Windows doesn't clear the
00037  *     client rectangle, so the new text must be larger than the old one.
00038  *   - The SS_RIGHTJUST style is currently not implemented by Windows
00039  *     (or it does something different than documented).
00040  *
00041  * TODO:
00042  *   - Animated cursors
00043  */
00044 
00045 #include <user32.h>
00046 
00047 #include <wine/debug.h>
00048 
00049 WINE_DEFAULT_DEBUG_CHANNEL(static);
00050 
00051 static void STATIC_PaintOwnerDrawfn( HWND hwnd, HDC hdc, DWORD style );
00052 static void STATIC_PaintTextfn( HWND hwnd, HDC hdc, DWORD style );
00053 static void STATIC_PaintRectfn( HWND hwnd, HDC hdc, DWORD style );
00054 static void STATIC_PaintIconfn( HWND hwnd, HDC hdc, DWORD style );
00055 static void STATIC_PaintBitmapfn( HWND hwnd, HDC hdc, DWORD style );
00056 static void STATIC_PaintEnhMetafn( HWND hwnd, HDC hdc, DWORD style );
00057 static void STATIC_PaintEtchedfn( HWND hwnd, HDC hdc, DWORD style );
00058 
00059 static COLORREF color_3dshadow, color_3ddkshadow, color_3dhighlight;
00060 
00061 /* offsets for GetWindowLong for static private information */
00062 #define HFONT_GWL_OFFSET    0
00063 #define HICON_GWL_OFFSET    (sizeof(HFONT))
00064 #define UISTATE_GWL_OFFSET (HICON_GWL_OFFSET+sizeof(HICON)) // ReactOS: keep in sync with STATIC_UISTATE_GWL_OFFSET
00065 #define STATIC_EXTRA_BYTES  (UISTATE_GWL_OFFSET + sizeof(LONG))
00066 
00067 typedef void (*pfPaint)( HWND hwnd, HDC hdc, DWORD style );
00068 
00069 static const pfPaint staticPaintFunc[SS_TYPEMASK+1] =
00070 {
00071     STATIC_PaintTextfn,      /* SS_LEFT */
00072     STATIC_PaintTextfn,      /* SS_CENTER */
00073     STATIC_PaintTextfn,      /* SS_RIGHT */
00074     STATIC_PaintIconfn,      /* SS_ICON */
00075     STATIC_PaintRectfn,      /* SS_BLACKRECT */
00076     STATIC_PaintRectfn,      /* SS_GRAYRECT */
00077     STATIC_PaintRectfn,      /* SS_WHITERECT */
00078     STATIC_PaintRectfn,      /* SS_BLACKFRAME */
00079     STATIC_PaintRectfn,      /* SS_GRAYFRAME */
00080     STATIC_PaintRectfn,      /* SS_WHITEFRAME */
00081     NULL,                    /* SS_USERITEM */
00082     STATIC_PaintTextfn,      /* SS_SIMPLE */
00083     STATIC_PaintTextfn,      /* SS_LEFTNOWORDWRAP */
00084     STATIC_PaintOwnerDrawfn, /* SS_OWNERDRAW */
00085     STATIC_PaintBitmapfn,    /* SS_BITMAP */
00086     STATIC_PaintEnhMetafn,   /* SS_ENHMETAFILE */
00087     STATIC_PaintEtchedfn,    /* SS_ETCHEDHORZ */
00088     STATIC_PaintEtchedfn,    /* SS_ETCHEDVERT */
00089     STATIC_PaintEtchedfn,    /* SS_ETCHEDFRAME */
00090 };
00091 
00092 
00093 /*********************************************************************
00094  * static class descriptor
00095  */
00096 static const WCHAR staticW[] = {'S','t','a','t','i','c',0};
00097 const struct builtin_class_descr STATIC_builtin_class =
00098 {
00099     staticW,             /* name */
00100     CS_DBLCLKS | CS_PARENTDC, /* style  */
00101     StaticWndProcA,      /* procA */
00102     StaticWndProcW,      /* procW */
00103     STATIC_EXTRA_BYTES,  /* extra */
00104     IDC_ARROW,           /* cursor */
00105     0                    /* brush */
00106 };
00107 
00108 /***********************************************************************
00109  *           STATIC_SetIcon
00110  *
00111  * Set the icon for an SS_ICON control.
00112  */
00113 static HICON STATIC_SetIcon( HWND hwnd, HICON hicon, DWORD style )
00114 {
00115     HICON prevIcon;
00116     SIZE size;
00117 
00118     if ((style & SS_TYPEMASK) != SS_ICON) return 0;
00119     if (hicon && !get_icon_size( hicon, &size ))
00120     {
00121         WARN("hicon != 0, but invalid\n");
00122         return 0;
00123     }
00124     prevIcon = (HICON)SetWindowLongPtrW( hwnd, HICON_GWL_OFFSET, (LONG_PTR)hicon );
00125     if (hicon && !(style & SS_CENTERIMAGE) && !(style & SS_REALSIZECONTROL))
00126     {
00127         /* Windows currently doesn't implement SS_RIGHTJUST */
00128         /*
00129         if ((style & SS_RIGHTJUST) != 0)
00130         {
00131             RECT wr;
00132             GetWindowRect(hwnd, &wr);
00133             SetWindowPos( hwnd, 0, wr.right - info->nWidth, wr.bottom - info->nHeight,
00134                           info->nWidth, info->nHeight, SWP_NOACTIVATE | SWP_NOZORDER );
00135         }
00136         else */
00137         {
00138             SetWindowPos( hwnd, 0, 0, 0, size.cx, size.cy, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER );
00139         }
00140     }
00141     return prevIcon;
00142 }
00143 
00144 /***********************************************************************
00145  *           STATIC_SetBitmap
00146  *
00147  * Set the bitmap for an SS_BITMAP control.
00148  */
00149 static HBITMAP STATIC_SetBitmap( HWND hwnd, HBITMAP hBitmap, DWORD style )
00150 {
00151     HBITMAP hOldBitmap;
00152 
00153     if ((style & SS_TYPEMASK) != SS_BITMAP) return 0;
00154     if (hBitmap && GetObjectType(hBitmap) != OBJ_BITMAP) {
00155         WARN("hBitmap != 0, but it's not a bitmap\n");
00156         return 0;
00157     }
00158     hOldBitmap = (HBITMAP)SetWindowLongPtrW( hwnd, HICON_GWL_OFFSET, (LONG_PTR)hBitmap );
00159     if (hBitmap && !(style & SS_CENTERIMAGE) && !(style & SS_REALSIZECONTROL))
00160     {
00161         BITMAP bm;
00162         GetObjectW(hBitmap, sizeof(bm), &bm);
00163         /* Windows currently doesn't implement SS_RIGHTJUST */
00164         /*
00165         if ((style & SS_RIGHTJUST) != 0)
00166         {
00167             RECT wr;
00168             GetWindowRect(hwnd, &wr);
00169             SetWindowPos( hwnd, 0, wr.right - bm.bmWidth, wr.bottom - bm.bmHeight,
00170                           bm.bmWidth, bm.bmHeight, SWP_NOACTIVATE | SWP_NOZORDER );
00171         }
00172         else */
00173         {
00174             SetWindowPos( hwnd, 0, 0, 0, bm.bmWidth, bm.bmHeight,
00175                           SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER );
00176         }
00177 
00178     }
00179     return hOldBitmap;
00180 }
00181 
00182 /***********************************************************************
00183  *           STATIC_SetEnhMetaFile
00184  *
00185  * Set the enhanced metafile for an SS_ENHMETAFILE control.
00186  */
00187 static HENHMETAFILE STATIC_SetEnhMetaFile( HWND hwnd, HENHMETAFILE hEnhMetaFile, DWORD style )
00188 {
00189     if ((style & SS_TYPEMASK) != SS_ENHMETAFILE) return 0;
00190     if (hEnhMetaFile && GetObjectType(hEnhMetaFile) != OBJ_ENHMETAFILE) {
00191         WARN("hEnhMetaFile != 0, but it's not an enhanced metafile\n");
00192         return 0;
00193     }
00194     return (HENHMETAFILE)SetWindowLongPtrW( hwnd, HICON_GWL_OFFSET, (LONG_PTR)hEnhMetaFile );
00195 }
00196 
00197 /***********************************************************************
00198  *           STATIC_GetImage
00199  *
00200  * Gets the bitmap for an SS_BITMAP control, the icon/cursor for an
00201  * SS_ICON control or the enhanced metafile for an SS_ENHMETAFILE control.
00202  */
00203 static HANDLE STATIC_GetImage( HWND hwnd, WPARAM wParam, DWORD style )
00204 {
00205     switch(style & SS_TYPEMASK)
00206     {
00207         case SS_ICON:
00208             if ((wParam != IMAGE_ICON) &&
00209                 (wParam != IMAGE_CURSOR)) return NULL;
00210             break;
00211         case SS_BITMAP:
00212             if (wParam != IMAGE_BITMAP) return NULL;
00213             break;
00214         case SS_ENHMETAFILE:
00215             if (wParam != IMAGE_ENHMETAFILE) return NULL;
00216             break;
00217         default:
00218             return NULL;
00219     }
00220     return (HANDLE)GetWindowLongPtrW( hwnd, HICON_GWL_OFFSET );
00221 }
00222 
00223 /***********************************************************************
00224  *           STATIC_LoadIconA
00225  *
00226  * Load the icon for an SS_ICON control.
00227  */
00228 static HICON STATIC_LoadIconA( HINSTANCE hInstance, LPCSTR name, DWORD style )
00229 {
00230     HICON hicon = 0;
00231 
00232     if (hInstance && ((ULONG_PTR)hInstance >> 16))
00233     {
00234         if ((style & SS_REALSIZEIMAGE) != 0)
00235             hicon = LoadImageA(hInstance, name, IMAGE_ICON, 0, 0, LR_SHARED);
00236         else
00237         {
00238             hicon = LoadIconA( hInstance, name );
00239             if (!hicon) hicon = LoadCursorA( hInstance, name );
00240         }
00241     }
00242     if (!hicon) hicon = LoadIconA( 0, name );
00243     /* Windows doesn't try to load a standard cursor,
00244        probably because most IDs for standard cursors conflict
00245        with the IDs for standard icons anyway */
00246     return hicon;
00247 }
00248 
00249 /***********************************************************************
00250  *           STATIC_LoadIconW
00251  *
00252  * Load the icon for an SS_ICON control.
00253  */
00254 static HICON STATIC_LoadIconW( HINSTANCE hInstance, LPCWSTR name, DWORD style )
00255 {
00256     HICON hicon = 0;
00257 
00258     if (hInstance && ((ULONG_PTR)hInstance >> 16))
00259     {
00260         if ((style & SS_REALSIZEIMAGE) != 0)
00261             hicon = LoadImageW(hInstance, name, IMAGE_ICON, 0, 0, LR_SHARED);
00262         else
00263         {
00264             hicon = LoadIconW( hInstance, name );
00265             if (!hicon) hicon = LoadCursorW( hInstance, name );
00266         }
00267     }
00268     if (!hicon) hicon = LoadIconW( 0, name );
00269     /* Windows doesn't try to load a standard cursor,
00270        probably because most IDs for standard cursors conflict
00271        with the IDs for standard icons anyway */
00272     return hicon;
00273 }
00274 
00275 /***********************************************************************
00276  *           STATIC_TryPaintFcn
00277  *
00278  * Try to immediately paint the control.
00279  */
00280 static VOID STATIC_TryPaintFcn(HWND hwnd, LONG full_style)
00281 {
00282     LONG style = full_style & SS_TYPEMASK;
00283     RECT rc;
00284 
00285     GetClientRect( hwnd, &rc );
00286     if (!IsRectEmpty(&rc) && IsWindowVisible(hwnd) && staticPaintFunc[style])
00287     {
00288     HDC hdc;
00289         HRGN hrgn;
00290 
00291     hdc = GetDC( hwnd );
00292         hrgn = set_control_clipping( hdc, &rc );
00293     (staticPaintFunc[style])( hwnd, hdc, full_style );
00294         SelectClipRgn( hdc, hrgn );
00295         if (hrgn) DeleteObject( hrgn );
00296     ReleaseDC( hwnd, hdc );
00297     }
00298 }
00299 
00300 static HBRUSH STATIC_SendWmCtlColorStatic(HWND hwnd, HDC hdc)
00301 {
00302     return GetControlBrush( hwnd, hdc, WM_CTLCOLORSTATIC);
00303 }
00304 
00305 static VOID STATIC_InitColours(void)
00306 {
00307     color_3ddkshadow  = GetSysColor(COLOR_3DDKSHADOW);
00308     color_3dshadow    = GetSysColor(COLOR_3DSHADOW);
00309     color_3dhighlight = GetSysColor(COLOR_3DHIGHLIGHT);
00310 }
00311 
00312 /***********************************************************************
00313  *           hasTextStyle
00314  *
00315  * Tests if the control displays text.
00316  */
00317 static BOOL hasTextStyle( DWORD style )
00318 {
00319     switch(style & SS_TYPEMASK)
00320     {
00321         case SS_SIMPLE:
00322         case SS_LEFT:
00323         case SS_LEFTNOWORDWRAP:
00324         case SS_CENTER:
00325         case SS_RIGHT:
00326         case SS_OWNERDRAW:
00327             return TRUE;
00328     }
00329 
00330     return FALSE;
00331 }
00332 
00333 /***********************************************************************
00334  *           StaticWndProc_common
00335  */
00336 LRESULT WINAPI StaticWndProc_common( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL unicode ) // ReactOS
00337 {
00338     LRESULT lResult = 0;
00339     LONG full_style = GetWindowLongW( hwnd, GWL_STYLE );
00340     LONG style = full_style & SS_TYPEMASK;
00341 #ifdef __REACTOS__
00342     PWND pWnd;
00343 
00344     pWnd = ValidateHwnd(hwnd);
00345     if (pWnd)
00346     {
00347        if (!pWnd->fnid)
00348        {
00349           NtUserSetWindowFNID(hwnd, FNID_STATIC);
00350        }
00351        else
00352        {
00353           if (pWnd->fnid != FNID_STATIC)
00354           {
00355              ERR("Wrong window class for Static! fnId 0x%x\n",pWnd->fnid);
00356              return 0;
00357           }
00358        }
00359     }
00360 #endif
00361 
00362     if (!IsWindow( hwnd )) return 0;
00363 
00364     switch (uMsg)
00365     {
00366     case WM_CREATE:
00367         if (style < 0L || style > SS_TYPEMASK)
00368         {
00369             ERR("Unknown style 0x%02lx\n", style );
00370             return -1;
00371         }
00372         STATIC_update_uistate(hwnd, unicode); // ReactOS r30727
00373         STATIC_InitColours();
00374         break;
00375 
00376     case WM_NCDESTROY:
00377 #ifdef __REACTOS__
00378         NtUserSetWindowFNID(hwnd, FNID_DESTROY);
00379 #endif
00380         if (style == SS_ICON) {
00381 /*
00382  * FIXME
00383  *           DestroyIcon32( STATIC_SetIcon( wndPtr, 0 ) );
00384  *
00385  * We don't want to do this yet because DestroyIcon32 is broken. If the icon
00386  * had already been loaded by the application the last thing we want to do is
00387  * GlobalFree16 the handle.
00388  */
00389             break;
00390         }
00391         else return unicode ? DefWindowProcW(hwnd, uMsg, wParam, lParam) :
00392                               DefWindowProcA(hwnd, uMsg, wParam, lParam);
00393 
00394     case WM_ERASEBKGND:
00395         /* do all painting in WM_PAINT like Windows does */
00396         return 1;
00397 
00398     case WM_PRINTCLIENT:
00399     case WM_PAINT:
00400         {
00401             PAINTSTRUCT ps;
00402             RECT rect;
00403             HDC hdc = wParam ? (HDC)wParam : BeginPaint(hwnd, &ps);
00404             GetClientRect( hwnd, &rect );
00405             if (staticPaintFunc[style])
00406             {
00407                 HRGN hrgn = set_control_clipping( hdc, &rect );
00408                 (staticPaintFunc[style])( hwnd, hdc, full_style );
00409                 SelectClipRgn( hdc, hrgn );
00410                 if (hrgn) DeleteObject( hrgn );
00411             }
00412             if (!wParam) EndPaint(hwnd, &ps);
00413         }
00414         break;
00415 
00416     case WM_ENABLE:
00417         STATIC_TryPaintFcn( hwnd, full_style );
00418         if (full_style & SS_NOTIFY) {
00419             if (wParam) {
00420                 SendMessageW( GetParent(hwnd), WM_COMMAND,
00421                               MAKEWPARAM( GetWindowLongPtrW(hwnd,GWLP_ID), STN_ENABLE ), (LPARAM)hwnd);
00422             }
00423             else {
00424                 SendMessageW( GetParent(hwnd), WM_COMMAND,
00425                               MAKEWPARAM( GetWindowLongPtrW(hwnd,GWLP_ID), STN_DISABLE ), (LPARAM)hwnd);
00426             }
00427         }
00428         break;
00429 
00430     case WM_SYSCOLORCHANGE:
00431         STATIC_InitColours();
00432         STATIC_TryPaintFcn( hwnd, full_style );
00433         break;
00434 
00435     case WM_NCCREATE:
00436         {
00437             CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
00438 
00439             if (full_style & SS_SUNKEN)
00440                 SetWindowLongW( hwnd, GWL_EXSTYLE,
00441                                 GetWindowLongW( hwnd, GWL_EXSTYLE ) | WS_EX_STATICEDGE );
00442 
00443             switch (style) {
00444             case SS_ICON:
00445                 {
00446                     HICON hIcon;
00447                     if (unicode || IS_INTRESOURCE(cs->lpszName))
00448                        hIcon = STATIC_LoadIconW(cs->hInstance, cs->lpszName, full_style);
00449                     else
00450                        hIcon = STATIC_LoadIconA(cs->hInstance, (LPCSTR)cs->lpszName, full_style);
00451                     STATIC_SetIcon(hwnd, hIcon, full_style);
00452                 }
00453                 break;
00454             case SS_BITMAP:
00455                 if ((ULONG_PTR)cs->hInstance >> 16)
00456                 {
00457                     HBITMAP hBitmap;
00458                     if (unicode || IS_INTRESOURCE(cs->lpszName))
00459                         hBitmap = LoadBitmapW(cs->hInstance, cs->lpszName);
00460                     else
00461                         hBitmap = LoadBitmapA(cs->hInstance, (LPCSTR)cs->lpszName);
00462                     STATIC_SetBitmap(hwnd, hBitmap, full_style);
00463                 }
00464                 break;
00465             }
00466             /* SS_ENHMETAFILE: Despite what MSDN says, Windows does not load
00467                the enhanced metafile that was specified as the window text. */
00468         }
00469         return unicode ? DefWindowProcW(hwnd, uMsg, wParam, lParam) :
00470                          DefWindowProcA(hwnd, uMsg, wParam, lParam);
00471 
00472     case WM_SETTEXT:
00473         if (hasTextStyle( full_style ))
00474         {
00475         if (HIWORD(lParam))
00476         {
00477             if(unicode)
00478                     lResult = DefWindowProcW( hwnd, uMsg, wParam, lParam );
00479                 else
00480                     lResult = DefWindowProcA( hwnd, uMsg, wParam, lParam );
00481                 STATIC_TryPaintFcn( hwnd, full_style );
00482         }
00483     }
00484         break;
00485 
00486     case WM_SETFONT:
00487         if (hasTextStyle( full_style ))
00488         {
00489             SetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET, wParam );
00490             if (LOWORD(lParam))
00491                 RedrawWindow( hwnd, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN );
00492         }
00493         break;
00494 
00495     case WM_GETFONT:
00496         return GetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET );
00497 
00498     case WM_NCHITTEST:
00499         if (full_style & SS_NOTIFY)
00500            return HTCLIENT;
00501         else
00502            return HTTRANSPARENT;
00503 
00504     case WM_GETDLGCODE:
00505         return DLGC_STATIC;
00506 
00507     case WM_LBUTTONDOWN:
00508     case WM_NCLBUTTONDOWN:
00509         if (full_style & SS_NOTIFY)
00510             SendMessageW( GetParent(hwnd), WM_COMMAND,
00511                           MAKEWPARAM( GetWindowLongPtrW(hwnd,GWLP_ID), STN_CLICKED ), (LPARAM)hwnd);
00512         return 0;
00513 
00514     case WM_LBUTTONDBLCLK:
00515     case WM_NCLBUTTONDBLCLK:
00516         if (full_style & SS_NOTIFY)
00517             SendMessageW( GetParent(hwnd), WM_COMMAND,
00518                           MAKEWPARAM( GetWindowLongPtrW(hwnd,GWLP_ID), STN_DBLCLK ), (LPARAM)hwnd);
00519         return 0;
00520 
00521     case STM_GETIMAGE:
00522         return (LRESULT)STATIC_GetImage( hwnd, wParam, full_style );
00523 
00524     case STM_GETICON:
00525         return (LRESULT)STATIC_GetImage( hwnd, IMAGE_ICON, full_style );
00526 
00527     case STM_SETIMAGE:
00528         switch(wParam) {
00529     case IMAGE_BITMAP:
00530         if (style != SS_BITMAP) return 0; // ReactOS r43158
00531         lResult = (LRESULT)STATIC_SetBitmap( hwnd, (HBITMAP)lParam, full_style );
00532         break;
00533     case IMAGE_ENHMETAFILE:
00534         if (style != SS_ENHMETAFILE) return 0; // ReactOS r43158
00535         lResult = (LRESULT)STATIC_SetEnhMetaFile( hwnd, (HENHMETAFILE)lParam, full_style );
00536         break;
00537     case IMAGE_ICON:
00538     case IMAGE_CURSOR:
00539         if (style != SS_ICON) return 0; // ReactOS r43158
00540         lResult = (LRESULT)STATIC_SetIcon( hwnd, (HICON)lParam, full_style );
00541         break;
00542     default:
00543         FIXME("STM_SETIMAGE: Unhandled type %lx\n", wParam);
00544         break;
00545     }
00546         STATIC_TryPaintFcn( hwnd, full_style );
00547     break;
00548 
00549     case STM_SETICON:
00550         lResult = (LRESULT)STATIC_SetIcon( hwnd, (HICON)wParam, full_style );
00551         STATIC_TryPaintFcn( hwnd, full_style );
00552         break;
00553 
00554 #ifdef __REACTOS__
00555     case WM_UPDATEUISTATE:
00556         if (unicode)
00557             DefWindowProcW(hwnd, uMsg, wParam, lParam);
00558         else
00559             DefWindowProcA(hwnd, uMsg, wParam, lParam);
00560 
00561         if (STATIC_update_uistate(hwnd, unicode) && hasTextStyle( full_style ))
00562         {
00563             RedrawWindow( hwnd, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN );
00564         }
00565         break;
00566 #endif
00567 
00568     default:
00569         return unicode ? DefWindowProcW(hwnd, uMsg, wParam, lParam) :
00570                          DefWindowProcA(hwnd, uMsg, wParam, lParam);
00571     }
00572     return lResult;
00573 }
00574 
00575 /***********************************************************************
00576  *           StaticWndProcA
00577  */
00578 LRESULT WINAPI StaticWndProcA( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
00579 {
00580     if (!IsWindow( hWnd )) return 0;
00581     return StaticWndProc_common(hWnd, uMsg, wParam, lParam, FALSE);
00582 }
00583 
00584 /***********************************************************************
00585  *           StaticWndProcW
00586  */
00587 LRESULT WINAPI StaticWndProcW( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
00588 {
00589     if (!IsWindow( hWnd )) return 0;
00590     return StaticWndProc_common(hWnd, uMsg, wParam, lParam, TRUE);
00591 }
00592 
00593 static void STATIC_PaintOwnerDrawfn( HWND hwnd, HDC hdc, DWORD style )
00594 {
00595   DRAWITEMSTRUCT dis;
00596   HBRUSH hBrush;
00597   HFONT font, oldFont = NULL;
00598   UINT id = (UINT)GetWindowLongPtrW( hwnd, GWLP_ID );
00599 
00600   dis.CtlType    = ODT_STATIC;
00601   dis.CtlID      = id;
00602   dis.itemID     = 0;
00603   dis.itemAction = ODA_DRAWENTIRE;
00604   dis.itemState  = IsWindowEnabled(hwnd) ? 0 : ODS_DISABLED;
00605   dis.hwndItem   = hwnd;
00606   dis.hDC        = hdc;
00607   dis.itemData   = 0;
00608   GetClientRect( hwnd, &dis.rcItem );
00609 
00610   font = (HFONT)GetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET );
00611   if (font) oldFont = SelectObject( hdc, font );
00612   hBrush = STATIC_SendWmCtlColorStatic(hwnd, hdc);
00613   SendMessageW( GetParent(hwnd), WM_DRAWITEM, id, (LPARAM)&dis );
00614   if (font) SelectObject( hdc, oldFont );
00615 }
00616 
00617 static void STATIC_PaintTextfn( HWND hwnd, HDC hdc, DWORD style )
00618 {
00619     RECT rc;
00620     HBRUSH hBrush;
00621     HFONT hFont, hOldFont = NULL;
00622     WORD wFormat;
00623     INT len, buf_size;
00624     WCHAR *text;
00625 
00626     GetClientRect( hwnd, &rc);
00627 
00628     switch (style & SS_TYPEMASK)
00629     {
00630     case SS_LEFT:
00631     wFormat = DT_LEFT | DT_EXPANDTABS | DT_WORDBREAK;
00632     break;
00633 
00634     case SS_CENTER:
00635     wFormat = DT_CENTER | DT_EXPANDTABS | DT_WORDBREAK;
00636     break;
00637 
00638     case SS_RIGHT:
00639     wFormat = DT_RIGHT | DT_EXPANDTABS | DT_WORDBREAK;
00640     break;
00641 
00642     case SS_SIMPLE:
00643         wFormat = DT_LEFT | DT_SINGLELINE;
00644     break;
00645 
00646     case SS_LEFTNOWORDWRAP:
00647         wFormat = DT_LEFT | DT_EXPANDTABS;
00648     break;
00649 
00650     default:
00651         return;
00652     }
00653 
00654     if (GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_RIGHT)
00655         wFormat = DT_RIGHT | (wFormat & ~(DT_LEFT | DT_CENTER));
00656 
00657     if (style & SS_NOPREFIX)
00658         wFormat |= DT_NOPREFIX;
00659     else if (GetWindowLongW(hwnd, UISTATE_GWL_OFFSET) & UISF_HIDEACCEL) // ReactOS r30727
00660         wFormat |= DT_HIDEPREFIX;
00661 
00662     if ((style & SS_TYPEMASK) != SS_SIMPLE)
00663     {
00664         if (style & SS_CENTERIMAGE)
00665             wFormat |= DT_SINGLELINE | DT_VCENTER;
00666         if (style & SS_EDITCONTROL)
00667             wFormat |= DT_EDITCONTROL;
00668         if (style & SS_ENDELLIPSIS)
00669             wFormat |= DT_SINGLELINE | DT_END_ELLIPSIS;
00670         if (style & SS_PATHELLIPSIS)
00671             wFormat |= DT_SINGLELINE | DT_PATH_ELLIPSIS;
00672         if (style & SS_WORDELLIPSIS)
00673             wFormat |= DT_SINGLELINE | DT_WORD_ELLIPSIS;
00674     }
00675 
00676     if ((hFont = (HFONT)GetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET )))
00677         hOldFont = SelectObject( hdc, hFont );
00678 
00679     /* SS_SIMPLE controls: WM_CTLCOLORSTATIC is sent, but the returned
00680                            brush is not used */
00681     hBrush = STATIC_SendWmCtlColorStatic(hwnd, hdc);
00682 
00683     if ((style & SS_TYPEMASK) != SS_SIMPLE)
00684     {
00685         FillRect( hdc, &rc, hBrush );
00686         if (!IsWindowEnabled(hwnd)) SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT));
00687     }
00688 
00689     buf_size = 256;
00690     if (!(text = HeapAlloc( GetProcessHeap(), 0, buf_size * sizeof(WCHAR) )))
00691         goto no_TextOut;
00692 
00693     while ((len = InternalGetWindowText( hwnd, text, buf_size )) == buf_size - 1)
00694     {
00695         buf_size *= 2;
00696         if (!(text = HeapReAlloc( GetProcessHeap(), 0, text, buf_size * sizeof(WCHAR) )))
00697             goto no_TextOut;
00698     }
00699 
00700     if (!len) goto no_TextOut;
00701 
00702     if (((style & SS_TYPEMASK) == SS_SIMPLE) && (style & SS_NOPREFIX))
00703     {
00704         /* Windows uses the faster ExtTextOut() to draw the text and
00705            to paint the whole client rectangle with the text background
00706            color. Reference: "Static Controls" by Kyle Marsh, 1992 */
00707         ExtTextOutW( hdc, rc.left, rc.top, ETO_CLIPPED | ETO_OPAQUE,
00708                      &rc, text, len, NULL );
00709     }
00710     else
00711     {
00712         DrawTextW( hdc, text, -1, &rc, wFormat );
00713     }
00714 
00715 no_TextOut:
00716     HeapFree( GetProcessHeap(), 0, text );
00717 
00718     if (hFont)
00719         SelectObject( hdc, hOldFont );
00720 }
00721 
00722 static void STATIC_PaintRectfn( HWND hwnd, HDC hdc, DWORD style )
00723 {
00724     RECT rc;
00725     HBRUSH hBrush;
00726 
00727     GetClientRect( hwnd, &rc);
00728 
00729     /* FIXME: send WM_CTLCOLORSTATIC */
00730 #ifdef __REACTOS__
00731     hBrush = STATIC_SendWmCtlColorStatic(hwnd, hdc); // Always sent....
00732 #endif
00733     switch (style & SS_TYPEMASK)
00734     {
00735     case SS_BLACKRECT:
00736     hBrush = CreateSolidBrush(color_3ddkshadow);
00737         FillRect( hdc, &rc, hBrush );
00738     break;
00739     case SS_GRAYRECT:
00740     hBrush = CreateSolidBrush(color_3dshadow);
00741         FillRect( hdc, &rc, hBrush );
00742     break;
00743     case SS_WHITERECT:
00744     hBrush = CreateSolidBrush(color_3dhighlight);
00745         FillRect( hdc, &rc, hBrush );
00746     break;
00747     case SS_BLACKFRAME:
00748     hBrush = CreateSolidBrush(color_3ddkshadow);
00749         FrameRect( hdc, &rc, hBrush );
00750     break;
00751     case SS_GRAYFRAME:
00752     hBrush = CreateSolidBrush(color_3dshadow);
00753         FrameRect( hdc, &rc, hBrush );
00754     break;
00755     case SS_WHITEFRAME:
00756     hBrush = CreateSolidBrush(color_3dhighlight);
00757         FrameRect( hdc, &rc, hBrush );
00758     break;
00759     default:
00760         return;
00761     }
00762     DeleteObject( hBrush );
00763 }
00764 
00765 
00766 static void STATIC_PaintIconfn( HWND hwnd, HDC hdc, DWORD style )
00767 {
00768     RECT rc, iconRect;
00769     HBRUSH hbrush;
00770     HICON hIcon;
00771     SIZE size;
00772 
00773     GetClientRect( hwnd, &rc );
00774     hbrush = STATIC_SendWmCtlColorStatic(hwnd, hdc);
00775     hIcon = (HICON)GetWindowLongPtrW( hwnd, HICON_GWL_OFFSET );
00776     if (!hIcon || !get_icon_size( hIcon, &size ))
00777     {
00778         FillRect(hdc, &rc, hbrush);
00779     }
00780     else
00781     {
00782         if (style & SS_CENTERIMAGE)
00783         {
00784             iconRect.left = (rc.right - rc.left) / 2 - size.cx / 2;
00785             iconRect.top = (rc.bottom - rc.top) / 2 - size.cy / 2;
00786             iconRect.right = iconRect.left + size.cx;
00787             iconRect.bottom = iconRect.top + size.cy;
00788         }
00789         else
00790             iconRect = rc;
00791         FillRect( hdc, &rc, hbrush );
00792         DrawIconEx( hdc, iconRect.left, iconRect.top, hIcon, iconRect.right - iconRect.left,
00793                     iconRect.bottom - iconRect.top, 0, NULL, DI_NORMAL );
00794     }
00795 }
00796 
00797 static void STATIC_PaintBitmapfn(HWND hwnd, HDC hdc, DWORD style )
00798 {
00799     HDC hMemDC;
00800     HBITMAP hBitmap, oldbitmap;
00801     HBRUSH hbrush;
00802 
00803     /* message is still sent, even if the returned brush is not used */
00804     hbrush = STATIC_SendWmCtlColorStatic(hwnd, hdc);
00805 
00806     if ((hBitmap = (HBITMAP)GetWindowLongPtrW( hwnd, HICON_GWL_OFFSET ))
00807          && (GetObjectType(hBitmap) == OBJ_BITMAP)
00808          && (hMemDC = CreateCompatibleDC( hdc )))
00809     {
00810         BITMAP bm;
00811         RECT rcClient;
00812         LOGBRUSH brush;
00813 
00814         GetObjectW(hBitmap, sizeof(bm), &bm);
00815         oldbitmap = SelectObject(hMemDC, hBitmap);
00816 
00817         /* Set the background color for monochrome bitmaps
00818            to the color of the background brush */
00819         if (GetObjectW( hbrush, sizeof(brush), &brush ))
00820         {
00821             if (brush.lbStyle == BS_SOLID)
00822                 SetBkColor(hdc, brush.lbColor);
00823         }
00824         GetClientRect(hwnd, &rcClient);
00825         if (style & SS_CENTERIMAGE)
00826         {
00827             INT x, y;
00828             x = (rcClient.right - rcClient.left)/2 - bm.bmWidth/2;
00829             y = (rcClient.bottom - rcClient.top)/2 - bm.bmHeight/2;
00830             FillRect( hdc, &rcClient, hbrush );
00831             BitBlt(hdc, x, y, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0,
00832                    SRCCOPY);
00833         }
00834         else
00835         {
00836             StretchBlt(hdc, 0, 0, rcClient.right - rcClient.left,
00837                        rcClient.bottom - rcClient.top, hMemDC,
00838                        0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
00839         }
00840         SelectObject(hMemDC, oldbitmap);
00841         DeleteDC(hMemDC);
00842     }
00843 }
00844 
00845 
00846 static void STATIC_PaintEnhMetafn(HWND hwnd, HDC hdc, DWORD style )
00847 {
00848     HENHMETAFILE hEnhMetaFile;
00849     RECT rc;
00850     HBRUSH hbrush;
00851 
00852     GetClientRect(hwnd, &rc);
00853     hbrush = STATIC_SendWmCtlColorStatic(hwnd, hdc);
00854     FillRect(hdc, &rc, hbrush);
00855     if ((hEnhMetaFile = (HENHMETAFILE)GetWindowLongPtrW( hwnd, HICON_GWL_OFFSET )))
00856     {
00857         /* The control's current font is not selected into the
00858            device context! */
00859         if (GetObjectType(hEnhMetaFile) == OBJ_ENHMETAFILE)
00860             PlayEnhMetaFile(hdc, hEnhMetaFile, &rc);
00861     }
00862 }
00863 
00864 
00865 static void STATIC_PaintEtchedfn( HWND hwnd, HDC hdc, DWORD style )
00866 {
00867     RECT rc;
00868 
00869     /* FIXME: sometimes (not always) sends WM_CTLCOLORSTATIC */
00870     GetClientRect( hwnd, &rc );
00871     switch (style & SS_TYPEMASK)
00872     {
00873     case SS_ETCHEDHORZ:
00874         DrawEdge(hdc,&rc,EDGE_ETCHED,BF_TOP|BF_BOTTOM);
00875         break;
00876     case SS_ETCHEDVERT:
00877         DrawEdge(hdc,&rc,EDGE_ETCHED,BF_LEFT|BF_RIGHT);
00878         break;
00879     case SS_ETCHEDFRAME:
00880         DrawEdge (hdc, &rc, EDGE_ETCHED, BF_RECT);
00881         break;
00882     }
00883 }

Generated on Thu May 24 2012 04:38:49 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.