Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenstatic.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
1.7.6.1
|