Audit the static control code.
[wine] / dlls / user / static.c
1 /*
2  * Static control
3  *
4  * Copyright  David W. Metcalfe, 1993
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * NOTES
21  *
22  * This code was audited for completeness against the documented features
23  * of Comctl32.dll version 6.0 on Oct. 4, 2004, by Dimitrie O. Paun.
24  * 
25  * Unless otherwise noted, we believe this code to be complete, as per
26  * the specification mentioned above.
27  * If you discover missing features, or bugs, please note them below.
28  * 
29  * TODO:
30  *
31  *   Styles
32  *   - SS_CENTERIMAGE
33  *   - SS_EDITCONTROL
34  *   - SS_ENDELLIPSIS
35  *   - SS_ENHMETAFILE
36  *   - SS_PATHELLIPSIS
37  *   - SS_REALSIZECONTROL
38  *   - SS_REALSIZEIMAGE
39  *   - SS_RIGHTJUST
40  *   - SS_WORDELLIPSIS
41  *
42  *   Notifications
43  *   - STN_DISABLE
44  *   - STN_ENABLE
45  *
46  *   Messages
47  *   - STM_SETIMAGE: IMAGE_CURSOR, IMAGE_ENHMETAFILE
48  */
49
50 #include <stdarg.h>
51
52 #include "windef.h"
53 #include "winbase.h"
54 #include "wingdi.h"
55 #include "wine/winuser16.h"
56 #include "wownt32.h"
57 #include "cursoricon.h"
58 #include "controls.h"
59 #include "user.h"
60 #include "wine/debug.h"
61
62 WINE_DEFAULT_DEBUG_CHANNEL(static);
63
64 static void STATIC_PaintOwnerDrawfn( HWND hwnd, HDC hdc, DWORD style );
65 static void STATIC_PaintTextfn( HWND hwnd, HDC hdc, DWORD style );
66 static void STATIC_PaintRectfn( HWND hwnd, HDC hdc, DWORD style );
67 static void STATIC_PaintIconfn( HWND hwnd, HDC hdc, DWORD style );
68 static void STATIC_PaintBitmapfn( HWND hwnd, HDC hdc, DWORD style );
69 static void STATIC_PaintEtchedfn( HWND hwnd, HDC hdc, DWORD style );
70 static LRESULT WINAPI StaticWndProcA( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
71 static LRESULT WINAPI StaticWndProcW( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
72
73 static COLORREF color_windowframe, color_background, color_window;
74
75 /* offsets for GetWindowLong for static private information */
76 #define HFONT_GWL_OFFSET    0
77 #define HICON_GWL_OFFSET    (sizeof(HFONT))
78 #define STATIC_EXTRA_BYTES  (HICON_GWL_OFFSET + sizeof(HICON))
79
80 typedef void (*pfPaint)( HWND hwnd, HDC hdc, DWORD style );
81
82 static pfPaint staticPaintFunc[SS_TYPEMASK+1] =
83 {
84     STATIC_PaintTextfn,      /* SS_LEFT */
85     STATIC_PaintTextfn,      /* SS_CENTER */
86     STATIC_PaintTextfn,      /* SS_RIGHT */
87     STATIC_PaintIconfn,      /* SS_ICON */
88     STATIC_PaintRectfn,      /* SS_BLACKRECT */
89     STATIC_PaintRectfn,      /* SS_GRAYRECT */
90     STATIC_PaintRectfn,      /* SS_WHITERECT */
91     STATIC_PaintRectfn,      /* SS_BLACKFRAME */
92     STATIC_PaintRectfn,      /* SS_GRAYFRAME */
93     STATIC_PaintRectfn,      /* SS_WHITEFRAME */
94     NULL,                    /* SS_USERITEM */
95     STATIC_PaintTextfn,      /* SS_SIMPLE */
96     STATIC_PaintTextfn,      /* SS_LEFTNOWORDWRAP */
97     STATIC_PaintOwnerDrawfn, /* SS_OWNERDRAW */
98     STATIC_PaintBitmapfn,    /* SS_BITMAP */
99     NULL,                    /* SS_ENHMETAFILE */
100     STATIC_PaintEtchedfn,    /* SS_ETCHEDHORZ */
101     STATIC_PaintEtchedfn,    /* SS_ETCHEDVERT */
102     STATIC_PaintEtchedfn,    /* SS_ETCHEDFRAME */
103 };
104
105
106 /*********************************************************************
107  * static class descriptor
108  */
109 const struct builtin_class_descr STATIC_builtin_class =
110 {
111     "Static",            /* name */
112     CS_DBLCLKS | CS_PARENTDC, /* style  */
113     StaticWndProcA,      /* procA */
114     StaticWndProcW,      /* procW */
115     STATIC_EXTRA_BYTES,  /* extra */
116     IDC_ARROW,           /* cursor */
117     0                    /* brush */
118 };
119
120
121 /***********************************************************************
122  *           STATIC_SetIcon
123  *
124  * Set the icon for an SS_ICON control.
125  */
126 static HICON STATIC_SetIcon( HWND hwnd, HICON hicon, DWORD style )
127 {
128     HICON prevIcon;
129     CURSORICONINFO *info = hicon?(CURSORICONINFO *) GlobalLock16(HICON_16(hicon)):NULL;
130
131     if ((style & SS_TYPEMASK) != SS_ICON) return 0;
132     if (hicon && !info) {
133         ERR("huh? hicon!=0, but info=0???\n");
134         return 0;
135     }
136     prevIcon = (HICON)SetWindowLongPtrW( hwnd, HICON_GWL_OFFSET, (LONG_PTR)hicon );
137     if (hicon)
138     {
139         SetWindowPos( hwnd, 0, 0, 0, info->nWidth, info->nHeight,
140                         SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER );
141         GlobalUnlock16(HICON_16(hicon));
142     }
143     return prevIcon;
144 }
145
146 /***********************************************************************
147  *           STATIC_SetBitmap
148  *
149  * Set the bitmap for an SS_BITMAP control.
150  */
151 static HBITMAP STATIC_SetBitmap( HWND hwnd, HBITMAP hBitmap, DWORD style )
152 {
153     HBITMAP hOldBitmap;
154
155     if ((style & SS_TYPEMASK) != SS_BITMAP) return 0;
156     if (hBitmap && GetObjectType(hBitmap) != OBJ_BITMAP) {
157         ERR("huh? hBitmap!=0, but not bitmap\n");
158         return 0;
159     }
160     hOldBitmap = (HBITMAP)SetWindowLongPtrW( hwnd, HICON_GWL_OFFSET, (LONG_PTR)hBitmap );
161     if (hBitmap)
162     {
163         BITMAP bm;
164         GetObjectW(hBitmap, sizeof(bm), &bm);
165         SetWindowPos( hwnd, 0, 0, 0, bm.bmWidth, bm.bmHeight,
166                       SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER );
167     }
168     return hOldBitmap;
169 }
170
171 /***********************************************************************
172  *           STATIC_LoadIconA
173  *
174  * Load the icon for an SS_ICON control.
175  */
176 static HICON STATIC_LoadIconA( HWND hwnd, LPCSTR name )
177 {
178     HINSTANCE hInstance = (HINSTANCE)GetWindowLongPtrW( hwnd, GWLP_HINSTANCE );
179     HICON hicon = LoadIconA( hInstance, name );
180     if (!hicon) hicon = LoadIconA( 0, name );
181     return hicon;
182 }
183
184 /***********************************************************************
185  *           STATIC_LoadIconW
186  *
187  * Load the icon for an SS_ICON control.
188  */
189 static HICON STATIC_LoadIconW( HWND hwnd, LPCWSTR name )
190 {
191     HINSTANCE hInstance = (HINSTANCE)GetWindowLongPtrW( hwnd, GWLP_HINSTANCE );
192     HICON hicon = LoadIconW( hInstance, name );
193     if (!hicon) hicon = LoadIconW( 0, name );
194     return hicon;
195 }
196
197 /***********************************************************************
198  *           STATIC_LoadBitmapA
199  *
200  * Load the bitmap for an SS_BITMAP control.
201  */
202 static HBITMAP STATIC_LoadBitmapA( HWND hwnd, LPCSTR name )
203 {
204     HINSTANCE hInstance = (HINSTANCE)GetWindowLongPtrW( hwnd, GWLP_HINSTANCE );
205     HBITMAP hbitmap = LoadBitmapA( hInstance, name );
206     if (!hbitmap)  /* Try OEM icon (FIXME: is this right?) */
207         hbitmap = LoadBitmapA( 0, name );
208     return hbitmap;
209 }
210
211 /***********************************************************************
212  *           STATIC_LoadBitmapW
213  *
214  * Load the bitmap for an SS_BITMAP control.
215  */
216 static HBITMAP STATIC_LoadBitmapW( HWND hwnd, LPCWSTR name )
217 {
218     HINSTANCE hInstance = (HINSTANCE)GetWindowLongPtrW( hwnd, GWLP_HINSTANCE );
219     HBITMAP hbitmap = LoadBitmapW( hInstance, name );
220     if (!hbitmap)  /* Try OEM icon (FIXME: is this right?) */
221         hbitmap = LoadBitmapW( 0, name );
222     return hbitmap;
223 }
224
225 /***********************************************************************
226  *           STATIC_TryPaintFcn
227  *
228  * Try to immediately paint the control.
229  */
230 static VOID STATIC_TryPaintFcn(HWND hwnd, LONG full_style)
231 {
232     LONG style = full_style & SS_TYPEMASK;
233     RECT rc;
234
235     GetClientRect( hwnd, &rc );
236     if (!IsRectEmpty(&rc) && IsWindowVisible(hwnd) && staticPaintFunc[style])
237     {
238         HDC hdc;
239         hdc = GetDC( hwnd );
240         (staticPaintFunc[style])( hwnd, hdc, full_style );
241         ReleaseDC( hwnd, hdc );
242     }
243 }
244
245 /***********************************************************************
246  *           StaticWndProc_common
247  */
248 static LRESULT StaticWndProc_common( HWND hwnd, UINT uMsg, WPARAM wParam,
249                                      LPARAM lParam, BOOL unicode )
250 {
251     LRESULT lResult = 0;
252     LONG full_style = GetWindowLongW( hwnd, GWL_STYLE );
253     LONG style = full_style & SS_TYPEMASK;
254
255     switch (uMsg)
256     {
257     case WM_CREATE:
258         if (style < 0L || style > SS_TYPEMASK)
259         {
260             ERR("Unknown style 0x%02lx\n", style );
261             return -1;
262         }
263         /* initialise colours */
264         color_windowframe  = GetSysColor(COLOR_WINDOWFRAME);
265         color_background   = GetSysColor(COLOR_BACKGROUND);
266         color_window       = GetSysColor(COLOR_WINDOW);
267         break;
268
269     case WM_NCDESTROY:
270         if (style == SS_ICON) {
271 /*
272  * FIXME
273  *           DestroyIcon32( STATIC_SetIcon( wndPtr, 0 ) );
274  *
275  * We don't want to do this yet because DestroyIcon32 is broken. If the icon
276  * had already been loaded by the application the last thing we want to do is
277  * GlobalFree16 the handle.
278  */
279             break;
280         }
281         else return unicode ? DefWindowProcW(hwnd, uMsg, wParam, lParam) :
282                               DefWindowProcA(hwnd, uMsg, wParam, lParam);
283
284     case WM_PAINT:
285         {
286             PAINTSTRUCT ps;
287             HDC hdc = wParam ? (HDC)wParam : BeginPaint(hwnd, &ps);
288             if (staticPaintFunc[style])
289                 (staticPaintFunc[style])( hwnd, hdc, full_style );
290             if (!wParam) EndPaint(hwnd, &ps);
291         }
292         break;
293
294     case WM_ENABLE:
295         InvalidateRect(hwnd, NULL, TRUE);
296         break;
297
298     case WM_SYSCOLORCHANGE:
299         color_windowframe  = GetSysColor(COLOR_WINDOWFRAME);
300         color_background   = GetSysColor(COLOR_BACKGROUND);
301         color_window       = GetSysColor(COLOR_WINDOW);
302         InvalidateRect(hwnd, NULL, TRUE);
303         break;
304
305     case WM_NCCREATE:
306         if (full_style & SS_SUNKEN)
307             SetWindowLongW( hwnd, GWL_EXSTYLE,
308                             GetWindowLongW( hwnd, GWL_EXSTYLE ) | WS_EX_STATICEDGE );
309
310         if(unicode)
311             lParam = (LPARAM)(((LPCREATESTRUCTW)lParam)->lpszName);
312         else
313             lParam = (LPARAM)(((LPCREATESTRUCTA)lParam)->lpszName);
314         /* fall through */
315     case WM_SETTEXT:
316         switch (style) {
317         case SS_ICON:
318         {
319             HICON hIcon;
320             if(unicode)
321                 hIcon = STATIC_LoadIconW(hwnd, (LPCWSTR)lParam);
322             else
323                 hIcon = STATIC_LoadIconA(hwnd, (LPCSTR)lParam);
324             /* FIXME : should we also return the previous hIcon here ??? */
325             STATIC_SetIcon(hwnd, hIcon, style);
326             break;
327         }
328         case SS_BITMAP:
329         {
330             HBITMAP hBitmap;
331             if(unicode)
332                 hBitmap = STATIC_LoadBitmapW(hwnd, (LPCWSTR)lParam);
333             else
334                 hBitmap = STATIC_LoadBitmapA(hwnd, (LPCSTR)lParam);
335             STATIC_SetBitmap(hwnd, hBitmap, style);
336             break;
337         }
338         case SS_LEFT:
339         case SS_CENTER:
340         case SS_RIGHT:
341         case SS_SIMPLE:
342         case SS_LEFTNOWORDWRAP:
343         {
344             if (HIWORD(lParam))
345             {
346                 if(unicode)
347                     lResult = DefWindowProcW( hwnd, WM_SETTEXT, wParam, lParam );
348                 else
349                     lResult = DefWindowProcA( hwnd, WM_SETTEXT, wParam, lParam );
350             }
351             if (uMsg == WM_SETTEXT)
352                 STATIC_TryPaintFcn( hwnd, full_style );
353             break;
354         }
355         default:
356             if (HIWORD(lParam))
357             {
358                 if(unicode)
359                     lResult = DefWindowProcW( hwnd, WM_SETTEXT, wParam, lParam );
360                 else
361                     lResult = DefWindowProcA( hwnd, WM_SETTEXT, wParam, lParam );
362             }
363             if(uMsg == WM_SETTEXT)
364                 InvalidateRect(hwnd, NULL, TRUE);
365         }
366         return 1; /* success. FIXME: check text length */
367
368     case WM_SETFONT:
369         if ((style == SS_ICON) || (style == SS_BITMAP)) return 0;
370         SetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET, wParam );
371         if (LOWORD(lParam))
372             InvalidateRect( hwnd, NULL, TRUE );
373         break;
374
375     case WM_GETFONT:
376         return GetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET );
377
378     case WM_NCHITTEST:
379         if (full_style & SS_NOTIFY)
380            return HTCLIENT;
381         else
382            return HTTRANSPARENT;
383
384     case WM_GETDLGCODE:
385         return DLGC_STATIC;
386
387     case WM_LBUTTONDOWN:
388     case WM_NCLBUTTONDOWN:
389         if (full_style & SS_NOTIFY)
390             SendMessageW( GetParent(hwnd), WM_COMMAND,
391                           MAKEWPARAM( GetWindowLongPtrW(hwnd,GWLP_ID), STN_CLICKED ), (LPARAM)hwnd);
392         return 0;
393
394     case WM_LBUTTONDBLCLK:
395     case WM_NCLBUTTONDBLCLK:
396         if (full_style & SS_NOTIFY)
397             SendMessageW( GetParent(hwnd), WM_COMMAND,
398                           MAKEWPARAM( GetWindowLongPtrW(hwnd,GWLP_ID), STN_DBLCLK ), (LPARAM)hwnd);
399         return 0;
400
401     case STM_GETIMAGE:
402     case STM_GETICON16:
403     case STM_GETICON:
404         return GetWindowLongPtrW( hwnd, HICON_GWL_OFFSET );
405
406     case STM_SETIMAGE:
407         switch(wParam) {
408         case IMAGE_BITMAP:
409             lResult = (LRESULT)STATIC_SetBitmap( hwnd, (HBITMAP)lParam, style );
410             break;
411         case IMAGE_CURSOR:
412             FIXME("STM_SETIMAGE: Unhandled type IMAGE_CURSOR\n");
413             break;
414         case IMAGE_ENHMETAFILE:
415             FIXME("STM_SETIMAGE: Unhandled type IMAGE_ENHMETAFILE\n");
416             break;
417         case IMAGE_ICON:
418             lResult = (LRESULT)STATIC_SetIcon( hwnd, (HICON)lParam, style );
419             break;
420         default:
421             FIXME("STM_SETIMAGE: Unhandled type %x\n", wParam);
422             break;
423         }
424         InvalidateRect( hwnd, NULL, TRUE );
425         break;
426
427     case STM_SETICON16:
428     case STM_SETICON:
429         lResult = (LRESULT)STATIC_SetIcon( hwnd, (HICON)wParam, style );
430         InvalidateRect( hwnd, NULL, TRUE );
431         break;
432
433     default:
434         return unicode ? DefWindowProcW(hwnd, uMsg, wParam, lParam) :
435                          DefWindowProcA(hwnd, uMsg, wParam, lParam);
436     }
437     return lResult;
438 }
439
440 /***********************************************************************
441  *           StaticWndProcA
442  */
443 static LRESULT WINAPI StaticWndProcA( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
444 {
445     if (!IsWindow( hWnd )) return 0;
446     return StaticWndProc_common(hWnd, uMsg, wParam, lParam, FALSE);
447 }
448
449 /***********************************************************************
450  *           StaticWndProcW
451  */
452 static LRESULT WINAPI StaticWndProcW( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
453 {
454     if (!IsWindow( hWnd )) return 0;
455     return StaticWndProc_common(hWnd, uMsg, wParam, lParam, TRUE);
456 }
457
458 static void STATIC_PaintOwnerDrawfn( HWND hwnd, HDC hdc, DWORD style )
459 {
460   DRAWITEMSTRUCT dis;
461   UINT id = (UINT)GetWindowLongPtrW( hwnd, GWLP_ID );
462
463   dis.CtlType    = ODT_STATIC;
464   dis.CtlID      = id;
465   dis.itemID     = 0;
466   dis.itemAction = ODA_DRAWENTIRE;
467   dis.itemState  = 0;
468   dis.hwndItem   = hwnd;
469   dis.hDC        = hdc;
470   dis.itemData   = 0;
471   GetClientRect( hwnd, &dis.rcItem );
472
473   SendMessageW( GetParent(hwnd), WM_CTLCOLORSTATIC, (WPARAM)hdc, (LPARAM)hwnd );
474   SendMessageW( GetParent(hwnd), WM_DRAWITEM, id, (LPARAM)&dis );
475 }
476
477 static void STATIC_PaintTextfn( HWND hwnd, HDC hdc, DWORD style )
478 {
479     RECT rc;
480     HBRUSH hBrush;
481     HFONT hFont;
482     WORD wFormat;
483     INT len;
484     WCHAR *text;
485
486     GetClientRect( hwnd, &rc);
487
488     switch (style & SS_TYPEMASK)
489     {
490     case SS_LEFT:
491         wFormat = DT_LEFT | DT_EXPANDTABS | DT_WORDBREAK;
492         break;
493
494     case SS_CENTER:
495         wFormat = DT_CENTER | DT_EXPANDTABS | DT_WORDBREAK;
496         break;
497
498     case SS_RIGHT:
499         wFormat = DT_RIGHT | DT_EXPANDTABS | DT_WORDBREAK;
500         break;
501
502     case SS_SIMPLE:
503         wFormat = DT_LEFT | DT_SINGLELINE | DT_VCENTER;
504         break;
505
506     case SS_LEFTNOWORDWRAP:
507         wFormat = DT_LEFT | DT_EXPANDTABS | DT_VCENTER;
508         break;
509
510     default:
511         return;
512     }
513
514     if (style & SS_NOPREFIX)
515         wFormat |= DT_NOPREFIX;
516
517     if ((hFont = (HFONT)GetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET ))) SelectObject( hdc, hFont );
518
519     if ((style & SS_NOPREFIX) || ((style & SS_TYPEMASK) != SS_SIMPLE))
520     {
521         hBrush = (HBRUSH)SendMessageW( GetParent(hwnd), WM_CTLCOLORSTATIC,
522                                        (WPARAM)hdc, (LPARAM)hwnd );
523         if (!hBrush) /* did the app forget to call defwindowproc ? */
524             hBrush = (HBRUSH)DefWindowProcW(GetParent(hwnd), WM_CTLCOLORSTATIC,
525                                             (WPARAM)hdc, (LPARAM)hwnd);
526         FillRect( hdc, &rc, hBrush );
527     }
528     if (!IsWindowEnabled(hwnd)) SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT));
529
530     if (!(len = SendMessageW( hwnd, WM_GETTEXTLENGTH, 0, 0 ))) return;
531     if (!(text = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) return;
532     SendMessageW( hwnd, WM_GETTEXT, len + 1, (LPARAM)text );
533     DrawTextW( hdc, text, -1, &rc, wFormat );
534     HeapFree( GetProcessHeap(), 0, text );
535 }
536
537 static void STATIC_PaintRectfn( HWND hwnd, HDC hdc, DWORD style )
538 {
539     RECT rc;
540     HBRUSH hBrush;
541
542     GetClientRect( hwnd, &rc);
543
544     switch (style & SS_TYPEMASK)
545     {
546     case SS_BLACKRECT:
547         hBrush = CreateSolidBrush(color_windowframe);
548         FillRect( hdc, &rc, hBrush );
549         break;
550     case SS_GRAYRECT:
551         hBrush = CreateSolidBrush(color_background);
552         FillRect( hdc, &rc, hBrush );
553         break;
554     case SS_WHITERECT:
555         hBrush = CreateSolidBrush(color_window);
556         FillRect( hdc, &rc, hBrush );
557         break;
558     case SS_BLACKFRAME:
559         hBrush = CreateSolidBrush(color_windowframe);
560         FrameRect( hdc, &rc, hBrush );
561         break;
562     case SS_GRAYFRAME:
563         hBrush = CreateSolidBrush(color_background);
564         FrameRect( hdc, &rc, hBrush );
565         break;
566     case SS_WHITEFRAME:
567         hBrush = CreateSolidBrush(color_window);
568         FrameRect( hdc, &rc, hBrush );
569         break;
570     default:
571         return;
572     }
573     DeleteObject( hBrush );
574 }
575
576
577 static void STATIC_PaintIconfn( HWND hwnd, HDC hdc, DWORD style )
578 {
579     RECT rc;
580     HBRUSH hbrush;
581     HICON hIcon;
582
583     GetClientRect( hwnd, &rc );
584     hbrush = (HBRUSH)SendMessageW( GetParent(hwnd), WM_CTLCOLORSTATIC,
585                                    (WPARAM)hdc, (LPARAM)hwnd );
586     FillRect( hdc, &rc, hbrush );
587     if ((hIcon = (HICON)GetWindowLongPtrW( hwnd, HICON_GWL_OFFSET )))
588         DrawIcon( hdc, rc.left, rc.top, hIcon );
589 }
590
591 static void STATIC_PaintBitmapfn(HWND hwnd, HDC hdc, DWORD style )
592 {
593     HDC hMemDC;
594     HBITMAP hBitmap, oldbitmap;
595
596     /* message is still sent, even if the returned brush is not used */
597     SendMessageW( GetParent(hwnd), WM_CTLCOLORSTATIC,
598                                    (WPARAM)hdc, (LPARAM)hwnd );
599
600     if ((hBitmap = (HBITMAP)GetWindowLongPtrW( hwnd, HICON_GWL_OFFSET )))
601     {
602         BITMAP bm;
603
604         if(GetObjectType(hBitmap) != OBJ_BITMAP) return;
605         if (!(hMemDC = CreateCompatibleDC( hdc ))) return;
606         GetObjectW(hBitmap, sizeof(bm), &bm);
607         oldbitmap = SelectObject(hMemDC, hBitmap);
608         BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0,
609                SRCCOPY);
610         SelectObject(hMemDC, oldbitmap);
611         DeleteDC(hMemDC);
612     }
613 }
614
615
616 static void STATIC_PaintEtchedfn( HWND hwnd, HDC hdc, DWORD style )
617 {
618     RECT rc;
619
620     GetClientRect( hwnd, &rc );
621     switch (style & SS_TYPEMASK)
622     {
623         case SS_ETCHEDHORZ:
624             DrawEdge(hdc,&rc,EDGE_ETCHED,BF_TOP|BF_BOTTOM);
625             break;
626         case SS_ETCHEDVERT:
627             DrawEdge(hdc,&rc,EDGE_ETCHED,BF_LEFT|BF_RIGHT);
628             break;
629         case SS_ETCHEDFRAME:
630             DrawEdge (hdc, &rc, EDGE_ETCHED, BF_RECT);
631             break;
632     }
633 }