-Fixed MESSAGE functions that were thunking down to 16 bits implementation.
[wine] / controls / static.c
1 /*
2  * Static control
3  *
4  * Copyright  David W. Metcalfe, 1993
5  *
6  */
7
8 #include "wine/winuser16.h"
9 #include "win.h"
10 #include "bitmap.h"
11 #include "cursoricon.h"
12 #include "static.h"
13 #include "heap.h"
14 #include "debug.h"
15 #include "tweak.h"
16
17 static void STATIC_PaintTextfn( WND *wndPtr, HDC32 hdc );
18 static void STATIC_PaintRectfn( WND *wndPtr, HDC32 hdc );
19 static void STATIC_PaintIconfn( WND *wndPtr, HDC32 hdc );
20 static void STATIC_PaintBitmapfn( WND *wndPtr, HDC32 hdc );
21 static void STATIC_PaintEtchedfn( WND *wndPtr, HDC32 hdc );
22
23 static COLORREF color_windowframe, color_background, color_window;
24
25
26 typedef void (*pfPaint)( WND *, HDC32 );
27
28 static pfPaint staticPaintFunc[SS_TYPEMASK+1] =
29 {
30     STATIC_PaintTextfn,      /* SS_LEFT */
31     STATIC_PaintTextfn,      /* SS_CENTER */
32     STATIC_PaintTextfn,      /* SS_RIGHT */
33     STATIC_PaintIconfn,      /* SS_ICON */
34     STATIC_PaintRectfn,      /* SS_BLACKRECT */
35     STATIC_PaintRectfn,      /* SS_GRAYRECT */
36     STATIC_PaintRectfn,      /* SS_WHITERECT */
37     STATIC_PaintRectfn,      /* SS_BLACKFRAME */
38     STATIC_PaintRectfn,      /* SS_GRAYFRAME */
39     STATIC_PaintRectfn,      /* SS_WHITEFRAME */
40     NULL,                    /* Not defined */
41     STATIC_PaintTextfn,      /* SS_SIMPLE */
42     STATIC_PaintTextfn,      /* SS_LEFTNOWORDWRAP */
43     NULL,                    /* SS_OWNERDRAW */
44     STATIC_PaintBitmapfn,    /* SS_BITMAP */
45     NULL,                    /* SS_ENHMETAFILE */
46     STATIC_PaintEtchedfn,    /* SS_ETCHEDHORIZ */
47     STATIC_PaintEtchedfn,    /* SS_ETCHEDVERT */
48     STATIC_PaintEtchedfn,    /* SS_ETCHEDFRAME */
49 };
50
51
52 /***********************************************************************
53  *           STATIC_SetIcon
54  *
55  * Set the icon for an SS_ICON control.
56  */
57 static HICON16 STATIC_SetIcon( WND *wndPtr, HICON16 hicon )
58 {
59     HICON16 prevIcon;
60     STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
61     CURSORICONINFO *info = hicon?(CURSORICONINFO *) GlobalLock16( hicon ):NULL;
62
63     if ((wndPtr->dwStyle & SS_TYPEMASK) != SS_ICON) return 0;
64     if (hicon && !info) {
65         ERR(static, "huh? hicon!=0, but info=0???\n");
66         return 0;
67     }
68     prevIcon = infoPtr->hIcon;
69     infoPtr->hIcon = hicon;
70     if (hicon)
71     {
72         SetWindowPos32( wndPtr->hwndSelf, 0, 0, 0, info->nWidth, info->nHeight,
73                         SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER );
74         GlobalUnlock16( hicon );
75     }
76     return prevIcon;
77 }
78
79 /***********************************************************************
80  *           STATIC_SetBitmap
81  *
82  * Set the bitmap for an SS_BITMAP control.
83  */
84 static HICON16 STATIC_SetBitmap( WND *wndPtr, HICON16 hicon )
85 {
86     HICON16 prevIcon;
87     STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
88     BITMAPOBJ *info = (BITMAPOBJ *)GDI_HEAP_LOCK(hicon);
89
90     if ((wndPtr->dwStyle & SS_TYPEMASK) != SS_BITMAP) return 0;
91     if (hicon && !info) {
92         ERR(static, "huh? hicon!=0, but info=0???\n");
93         return 0;
94     }
95     prevIcon = infoPtr->hIcon;
96     infoPtr->hIcon = hicon;
97     if (hicon)
98     {
99         SetWindowPos32( wndPtr->hwndSelf, 0, 0, 0, info->bitmap.bmWidth, info->bitmap.bmHeight,
100                         SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER );
101     }
102     GDI_HEAP_UNLOCK( hicon );
103     return prevIcon;
104 }
105
106
107 /***********************************************************************
108  *           STATIC_LoadIcon
109  *
110  * Load the icon for an SS_ICON control.
111  */
112 static HICON16 STATIC_LoadIcon( WND *wndPtr, LPCSTR name )
113 {
114     HICON16 hicon;
115
116     if (wndPtr->flags & WIN_ISWIN32)
117     {
118         if (!HIWORD(wndPtr->hInstance)) {
119             LPSTR segname = SEGPTR_STRDUP(name);
120             hicon = LoadIcon16( wndPtr->hInstance, SEGPTR_GET(segname) );
121             SEGPTR_FREE(segname);
122         } else
123             hicon = LoadIcon32A( wndPtr->hInstance, name );
124     } else {
125         LPSTR segname = SEGPTR_STRDUP(name);
126
127         if (HIWORD(wndPtr->hInstance))
128                 FIXME(static,"win16 window class, but win32 hinstance??\n");
129         hicon = LoadIcon16( wndPtr->hInstance, SEGPTR_GET(segname) );
130         SEGPTR_FREE(segname);
131     }
132     if (!hicon)
133         hicon = LoadIcon32A( 0, name );
134     return hicon;
135 }
136
137 /***********************************************************************
138  *           STATIC_LoadBitmap
139  *
140  * Load the bitmap for an SS_BITMAP control.
141  */
142 static HBITMAP16 STATIC_LoadBitmap( WND *wndPtr, LPCSTR name )
143 {
144     HBITMAP16 hbitmap;
145
146     if (wndPtr->flags & WIN_ISWIN32)
147     {
148         hbitmap = LoadBitmap32A( wndPtr->hInstance, name );
149         if (!hbitmap)  /* Try OEM icon (FIXME: is this right?) */
150             hbitmap = LoadBitmap32A( 0, name );
151     }
152     else
153     {
154         LPSTR segname = SEGPTR_STRDUP(name);
155         hbitmap = LoadBitmap16( wndPtr->hInstance, SEGPTR_GET(segname) );
156         if (!hbitmap)  /* Try OEM icon (FIXME: is this right?) */
157             hbitmap = LoadBitmap32A( 0, segname );
158         SEGPTR_FREE(segname);
159     }
160     return hbitmap;
161 }
162
163
164 /***********************************************************************
165  *           StaticWndProc
166  */
167 LRESULT WINAPI StaticWndProc( HWND32 hWnd, UINT32 uMsg, WPARAM32 wParam,
168                               LPARAM lParam )
169 {
170     LRESULT lResult = 0;
171     WND *wndPtr = WIN_FindWndPtr(hWnd);
172     LONG style = wndPtr->dwStyle & SS_TYPEMASK;
173     STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
174
175     switch (uMsg)
176     {
177     case WM_NCCREATE: {
178         CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
179
180         if ((TWEAK_WineLook > WIN31_LOOK) && (wndPtr->dwStyle & SS_SUNKEN))
181             wndPtr->dwExStyle |= WS_EX_STATICEDGE;
182
183         if (style == SS_ICON)
184         {
185             if (cs->lpszName) {
186                 if (!HIWORD(cs->lpszName) || cs->lpszName[0])
187                     STATIC_SetIcon( wndPtr,
188                                 STATIC_LoadIcon( wndPtr, cs->lpszName ));
189             }
190             return 1;
191         }
192         if (style == SS_BITMAP)
193         {
194             if (cs->lpszName)
195                 STATIC_SetBitmap( wndPtr,
196                                 STATIC_LoadBitmap( wndPtr, cs->lpszName ));
197             WARN(static, "style SS_BITMAP, dwStyle is 0x%08lx\n",
198                         wndPtr->dwStyle);
199             return 1;
200         }
201         if (!HIWORD(cs->lpszName) && (cs->lpszName)) {
202                 FIXME(static,"windowName is 0x%04x, not doing DefWindowProc\n",
203                     LOWORD(cs->lpszName)
204                 );
205                 return 1;
206         }
207         return DefWindowProc32A( hWnd, uMsg, wParam, lParam );
208     }
209     case WM_CREATE:
210         if (style < 0L || style > SS_TYPEMASK)
211         {
212             ERR(static, "Unknown style 0x%02lx\n", style );
213             lResult = -1L;
214             break;
215         }
216         /* initialise colours */
217         color_windowframe  = GetSysColor32(COLOR_WINDOWFRAME);
218         color_background   = GetSysColor32(COLOR_BACKGROUND);
219         color_window       = GetSysColor32(COLOR_WINDOW);
220         break;
221
222     case WM_NCDESTROY:
223         if (style == SS_ICON) {
224 /*
225  * FIXME
226  *           DestroyIcon32( STATIC_SetIcon( wndPtr, 0 ) );
227  * 
228  * We don't want to do this yet because DestroyIcon32 is broken. If the icon
229  * had already been loaded by the application the last thing we want to do is
230  * GlobalFree16 the handle.
231  */
232         } else {
233             lResult = DefWindowProc32A( hWnd, uMsg, wParam, lParam );
234         }
235         break;
236
237     case WM_PAINT:
238         {
239             PAINTSTRUCT32 ps;
240             BeginPaint32( hWnd, &ps );
241             if (staticPaintFunc[style])
242                 (staticPaintFunc[style])( wndPtr, ps.hdc );
243             EndPaint32( hWnd, &ps );
244         }
245         break;
246
247     case WM_ENABLE:
248         InvalidateRect32( hWnd, NULL, FALSE );
249         break;
250
251     case WM_SYSCOLORCHANGE:
252         color_windowframe  = GetSysColor32(COLOR_WINDOWFRAME);
253         color_background   = GetSysColor32(COLOR_BACKGROUND);
254         color_window       = GetSysColor32(COLOR_WINDOW);
255         InvalidateRect32( hWnd, NULL, TRUE );
256         break;
257
258     case WM_SETTEXT:
259         if (style == SS_ICON)
260             /* FIXME : should we also return the previous hIcon here ??? */
261             STATIC_SetIcon( wndPtr, STATIC_LoadIcon( wndPtr, (LPCSTR)lParam ));
262         else if (style == SS_BITMAP) 
263             STATIC_SetBitmap(wndPtr,STATIC_LoadBitmap(wndPtr,(LPCSTR)lParam ));
264         else
265             DEFWND_SetText( wndPtr, (LPCSTR)lParam );
266         InvalidateRect32( hWnd, NULL, FALSE );
267         UpdateWindow32( hWnd );
268         break;
269
270     case WM_SETFONT:
271         if (style == SS_ICON) return 0;
272         if (style == SS_BITMAP) return 0;
273         infoPtr->hFont = (HFONT16)wParam;
274         if (LOWORD(lParam))
275         {
276             InvalidateRect32( hWnd, NULL, FALSE );
277             UpdateWindow32( hWnd );
278         }
279         break;
280
281     case WM_GETFONT:
282         return infoPtr->hFont;
283
284     case WM_NCHITTEST:
285         return HTTRANSPARENT;
286
287     case WM_GETDLGCODE:
288         return DLGC_STATIC;
289
290     case STM_GETIMAGE:
291     case STM_GETICON16:
292     case STM_GETICON32:
293         return infoPtr->hIcon;
294
295     case STM_SETIMAGE:
296         /* FIXME: handle wParam */
297         lResult = STATIC_SetBitmap( wndPtr, (HBITMAP32)lParam );
298         InvalidateRect32( hWnd, NULL, FALSE );
299         UpdateWindow32( hWnd );
300         break;
301
302     case STM_SETICON16:
303     case STM_SETICON32:
304         lResult = STATIC_SetIcon( wndPtr, (HICON16)wParam );
305         InvalidateRect32( hWnd, NULL, FALSE );
306         UpdateWindow32( hWnd );
307         break;
308
309     default:
310         lResult = DefWindowProc32A(hWnd, uMsg, wParam, lParam);
311         break;
312     }
313     
314     return lResult;
315 }
316
317
318 static void STATIC_PaintTextfn( WND *wndPtr, HDC32 hdc )
319 {
320     RECT32 rc;
321     HBRUSH32 hBrush;
322     WORD wFormat;
323
324     LONG style = wndPtr->dwStyle;
325     STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
326
327     GetClientRect32( wndPtr->hwndSelf, &rc);
328
329     switch (style & SS_TYPEMASK)
330     {
331     case SS_LEFT:
332         wFormat = DT_LEFT | DT_EXPANDTABS | DT_WORDBREAK | DT_NOCLIP;
333         break;
334
335     case SS_CENTER:
336         wFormat = DT_CENTER | DT_EXPANDTABS | DT_WORDBREAK | DT_NOCLIP;
337         break;
338
339     case SS_RIGHT:
340         wFormat = DT_RIGHT | DT_EXPANDTABS | DT_WORDBREAK | DT_NOCLIP;
341         break;
342
343     case SS_SIMPLE:
344         wFormat = DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_NOCLIP;
345         break;
346
347     case SS_LEFTNOWORDWRAP:
348         wFormat = DT_LEFT | DT_EXPANDTABS | DT_VCENTER;
349         break;
350
351     default:
352         return;
353     }
354
355     if (style & SS_NOPREFIX)
356         wFormat |= DT_NOPREFIX;
357
358     if (infoPtr->hFont) SelectObject32( hdc, infoPtr->hFont );
359     hBrush = SendMessage32A( GetParent32(wndPtr->hwndSelf), WM_CTLCOLORSTATIC,
360                              hdc, wndPtr->hwndSelf );
361     if (!hBrush) hBrush = GetStockObject32(WHITE_BRUSH);
362     FillRect32( hdc, &rc, hBrush );
363     if (wndPtr->text) DrawText32A( hdc, wndPtr->text, -1, &rc, wFormat );
364 }
365
366 static void STATIC_PaintRectfn( WND *wndPtr, HDC32 hdc )
367 {
368     RECT32 rc;
369     HBRUSH32 hBrush;
370
371     GetClientRect32( wndPtr->hwndSelf, &rc);
372     
373     switch (wndPtr->dwStyle & SS_TYPEMASK)
374     {
375     case SS_BLACKRECT:
376         hBrush = CreateSolidBrush32(color_windowframe);
377         FillRect32( hdc, &rc, hBrush );
378         break;
379     case SS_GRAYRECT:
380         hBrush = CreateSolidBrush32(color_background);
381         FillRect32( hdc, &rc, hBrush );
382         break;
383     case SS_WHITERECT:
384         hBrush = CreateSolidBrush32(color_window);
385         FillRect32( hdc, &rc, hBrush );
386         break;
387     case SS_BLACKFRAME:
388         hBrush = CreateSolidBrush32(color_windowframe);
389         FrameRect32( hdc, &rc, hBrush );
390         break;
391     case SS_GRAYFRAME:
392         hBrush = CreateSolidBrush32(color_background);
393         FrameRect32( hdc, &rc, hBrush );
394         break;
395     case SS_WHITEFRAME:
396         hBrush = CreateSolidBrush32(color_window);
397         FrameRect32( hdc, &rc, hBrush );
398         break;
399     default:
400         return;
401     }
402     DeleteObject32( hBrush );
403 }
404
405
406 static void STATIC_PaintIconfn( WND *wndPtr, HDC32 hdc )
407 {
408     RECT32 rc;
409     HBRUSH32 hbrush;
410     STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
411
412     GetClientRect32( wndPtr->hwndSelf, &rc );
413     hbrush = SendMessage32A( GetParent32(wndPtr->hwndSelf), WM_CTLCOLORSTATIC,
414                              hdc, wndPtr->hwndSelf );
415     FillRect32( hdc, &rc, hbrush );
416     if (infoPtr->hIcon) DrawIcon32( hdc, rc.left, rc.top, infoPtr->hIcon );
417 }
418
419 static void STATIC_PaintBitmapfn(WND *wndPtr, HDC32 hdc )
420 {
421     RECT32 rc;
422     HBRUSH32 hbrush;
423     STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
424     HDC32 hMemDC;
425     HBITMAP32 oldbitmap;
426
427     GetClientRect32( wndPtr->hwndSelf, &rc );
428     hbrush = SendMessage32A( GetParent32(wndPtr->hwndSelf), WM_CTLCOLORSTATIC,
429                              hdc, wndPtr->hwndSelf );
430     FillRect32( hdc, &rc, hbrush );
431     if (infoPtr->hIcon) {
432         BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_HEAP_LOCK( infoPtr->hIcon );
433
434         if (!bmp) return;
435         if (!(hMemDC = CreateCompatibleDC32( hdc ))) return;
436
437         oldbitmap = SelectObject32(hMemDC,infoPtr->hIcon);
438         BitBlt32(hdc,bmp->size.cx,bmp->size.cy,bmp->bitmap.bmWidth,bmp->bitmap.bmHeight,hMemDC,0,0,SRCCOPY);
439         DeleteDC32(hMemDC);
440         GDI_HEAP_UNLOCK(infoPtr->hIcon);
441     }
442 }
443
444
445 static void STATIC_PaintEtchedfn( WND *wndPtr, HDC32 hdc )
446 {
447     RECT32 rc;
448     HBRUSH32 hbrush;
449     HPEN32 hpen;
450
451     if (TWEAK_WineLook == WIN31_LOOK)
452         return;
453
454     GetClientRect32( wndPtr->hwndSelf, &rc );
455     hbrush = SendMessage32A( GetParent32(wndPtr->hwndSelf), WM_CTLCOLORSTATIC,
456                              hdc, wndPtr->hwndSelf );
457     FillRect32( hdc, &rc, hbrush );
458
459     switch (wndPtr->dwStyle & SS_TYPEMASK)
460     {
461         case SS_ETCHEDHORZ:
462             hpen = SelectObject32 (hdc, GetSysColorPen32 (COLOR_3DSHADOW));
463             MoveToEx32 (hdc, rc.left, rc.bottom / 2 - 1, NULL);
464             LineTo32 (hdc, rc.right - 1, rc.bottom / 2 - 1);
465             SelectObject32 (hdc, GetSysColorPen32 (COLOR_3DHIGHLIGHT));
466             MoveToEx32 (hdc, rc.left, rc.bottom / 2, NULL);
467             LineTo32 (hdc, rc.right, rc.bottom / 2);
468             LineTo32 (hdc, rc.right, rc.bottom / 2 - 1);
469             SelectObject32 (hdc, hpen);
470             break;
471
472         case SS_ETCHEDVERT:
473             hpen = SelectObject32 (hdc, GetSysColorPen32 (COLOR_3DSHADOW));
474             MoveToEx32 (hdc, rc.right / 2 - 1, rc.top, NULL);
475             LineTo32 (hdc, rc.right / 2 - 1, rc.bottom - 1);
476             SelectObject32 (hdc, GetSysColorPen32 (COLOR_3DHIGHLIGHT));
477             MoveToEx32 (hdc, rc.right / 2, rc.top, NULL);
478             LineTo32 (hdc, rc.right / 2, rc.bottom);
479             LineTo32 (hdc, rc.right / 2 -1 , rc.bottom);
480             SelectObject32 (hdc, hpen); 
481             break;
482
483         case SS_ETCHEDFRAME:
484             DrawEdge32 (hdc, &rc, EDGE_ETCHED, BF_RECT);
485             break;
486     }
487 }
488