Release 960324
[wine] / controls / static.c
1 /*
2  * Static control
3  *
4  * Copyright  David W. Metcalfe, 1993
5  *
6 static char Copyright[] = "Copyright  David W. Metcalfe, 1993";
7 */
8
9 #include <stdio.h>
10 #include <windows.h>
11 #include "win.h"
12 #include "user.h"
13 #include "static.h"
14
15 extern void DEFWND_SetText( HWND hwnd, LPSTR text );  /* windows/defwnd.c */
16
17 static void PaintTextfn( HWND hwnd, HDC hdc );
18 static void PaintRectfn( HWND hwnd, HDC hdc );
19 static void PaintIconfn( HWND hwnd, HDC hdc );
20
21
22 static COLORREF color_windowframe, color_background, color_window;
23
24
25 typedef void (*pfPaint)(HWND, HDC);
26
27 #define LAST_STATIC_TYPE  SS_LEFTNOWORDWRAP
28
29 static pfPaint staticPaintFunc[LAST_STATIC_TYPE+1] =
30 {
31     PaintTextfn,             /* SS_LEFT */
32     PaintTextfn,             /* SS_CENTER */
33     PaintTextfn,             /* SS_RIGHT */
34     PaintIconfn,             /* SS_ICON */
35     PaintRectfn,             /* SS_BLACKRECT */
36     PaintRectfn,             /* SS_GRAYRECT */
37     PaintRectfn,             /* SS_WHITERECT */
38     PaintRectfn,             /* SS_BLACKFRAME */
39     PaintRectfn,             /* SS_GRAYFRAME */
40     PaintRectfn,             /* SS_WHITEFRAME */
41     NULL,                    /* Not defined */
42     PaintTextfn,             /* SS_SIMPLE */
43     PaintTextfn              /* SS_LEFTNOWORDWRAP */
44 };
45
46
47 /***********************************************************************
48  *           STATIC_SetIcon
49  *
50  * Set the icon for an SS_ICON control.
51  */
52 static HICON STATIC_SetIcon( HWND hwnd, HICON hicon )
53 {
54     HICON prevIcon;
55     WND *wndPtr = WIN_FindWndPtr( hwnd );
56     STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
57
58     if ((wndPtr->dwStyle & 0x0f) != SS_ICON) return 0;
59     prevIcon = infoPtr->hIcon;
60     infoPtr->hIcon = hicon;
61     if (hicon)
62     {
63         CURSORICONINFO *info = (CURSORICONINFO *) GlobalLock( hicon );
64         SetWindowPos( hwnd, 0, 0, 0, info->nWidth, info->nHeight,
65                      SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER );
66         GlobalUnlock( hicon );
67     }
68     return prevIcon;
69 }
70
71
72 /***********************************************************************
73  *           StaticWndProc
74  */
75 LONG StaticWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
76 {
77         LONG lResult = 0;
78         WND *wndPtr = WIN_FindWndPtr(hWnd);
79         LONG style = wndPtr->dwStyle & 0x0000000F;
80         STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
81
82         switch (uMsg) {
83         case WM_ENABLE:
84             InvalidateRect(hWnd, NULL, FALSE);
85             break;
86
87         case WM_NCCREATE:
88             if (style == SS_ICON)
89             {
90                 CREATESTRUCT * createStruct = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam);
91                 if (createStruct->lpszName)
92                 {
93                     HICON hicon = LoadIcon( createStruct->hInstance,
94                                             createStruct->lpszName );
95                     if (!hicon)  /* Try OEM icon (FIXME: is this right?) */
96                         hicon = LoadIcon( 0, createStruct->lpszName );
97                     STATIC_SetIcon( hWnd, hicon );
98                 }
99                 return 1;
100             }
101             return DefWindowProc(hWnd, uMsg, wParam, lParam);
102
103         case WM_CREATE:
104             if (style < 0L || style > LAST_STATIC_TYPE)
105             {
106                 fprintf( stderr, "STATIC: Unknown style 0x%02lx\n", style );
107                 lResult = -1L;
108                 break;
109             }
110             /* initialise colours */
111             color_windowframe  = GetSysColor(COLOR_WINDOWFRAME);
112             color_background   = GetSysColor(COLOR_BACKGROUND);
113             color_window       = GetSysColor(COLOR_WINDOW);
114             break;
115
116         case WM_NCDESTROY:
117             if (style == SS_ICON)
118                 DestroyIcon( STATIC_SetIcon( hWnd, 0 ) );
119             else 
120                 lResult = DefWindowProc(hWnd, uMsg, wParam, lParam);
121             break;
122
123         case WM_PAINT:
124             {
125                 PAINTSTRUCT ps;
126                 BeginPaint( hWnd, &ps );
127                 if (staticPaintFunc[style])
128                     (staticPaintFunc[style])( hWnd, ps.hdc );
129                 EndPaint( hWnd, &ps );
130             }
131             break;
132
133         case WM_SYSCOLORCHANGE:
134             color_windowframe  = GetSysColor(COLOR_WINDOWFRAME);
135             color_background   = GetSysColor(COLOR_BACKGROUND);
136             color_window       = GetSysColor(COLOR_WINDOW);
137             InvalidateRect(hWnd, NULL, TRUE);
138             break;
139
140         case WM_SETTEXT:
141             if (style == SS_ICON)
142                 /* FIXME : should we also return the previous hIcon here ??? */
143                 STATIC_SetIcon( hWnd, LoadIcon( wndPtr->hInstance,
144                                                 (SEGPTR)lParam ));
145             else
146                 DEFWND_SetText( hWnd, (LPSTR)PTR_SEG_TO_LIN(lParam) );
147             InvalidateRect( hWnd, NULL, FALSE );
148             UpdateWindow( hWnd );
149             break;
150
151         case WM_SETFONT:
152             if (style == SS_ICON) return 0;
153             infoPtr->hFont = (HFONT)wParam;
154             if (LOWORD(lParam))
155             {
156                 InvalidateRect( hWnd, NULL, FALSE );
157                 UpdateWindow( hWnd );
158             }
159             break;
160
161         case WM_GETFONT:
162             return infoPtr->hFont;
163
164         case WM_NCHITTEST:
165             return HTTRANSPARENT;
166
167         case WM_GETDLGCODE:
168             return DLGC_STATIC;
169
170         case STM_GETICON:
171             return infoPtr->hIcon;
172
173         case STM_SETICON:
174             lResult = STATIC_SetIcon( hWnd, (HICON)wParam );
175             InvalidateRect( hWnd, NULL, FALSE );
176             UpdateWindow( hWnd );
177             break;
178
179         default:
180                 lResult = DefWindowProc(hWnd, uMsg, wParam, lParam);
181                 break;
182         }
183
184         return lResult;
185 }
186
187
188 static void PaintTextfn( HWND hwnd, HDC hdc )
189 {
190     RECT rc;
191     HBRUSH hBrush;
192     char *text;
193     WORD wFormat;
194
195     WND *wndPtr = WIN_FindWndPtr(hwnd);
196     LONG style = wndPtr->dwStyle;
197     STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
198
199     GetClientRect(hwnd, &rc);
200     text = USER_HEAP_LIN_ADDR( wndPtr->hText );
201
202     switch (style & 0x0000000F)
203     {
204     case SS_LEFT:
205         wFormat = DT_LEFT | DT_EXPANDTABS | DT_WORDBREAK | DT_NOCLIP;
206         break;
207
208     case SS_CENTER:
209         wFormat = DT_CENTER | DT_EXPANDTABS | DT_WORDBREAK | DT_NOCLIP;
210         break;
211
212     case SS_RIGHT:
213         wFormat = DT_RIGHT | DT_EXPANDTABS | DT_WORDBREAK | DT_NOCLIP;
214         break;
215
216     case SS_SIMPLE:
217         wFormat = DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_NOCLIP;
218         break;
219
220     case SS_LEFTNOWORDWRAP:
221         wFormat = DT_LEFT | DT_SINGLELINE | DT_EXPANDTABS | DT_VCENTER | DT_NOCLIP;
222         break;
223
224     default:
225         return;
226     }
227
228     if (style & SS_NOPREFIX)
229         wFormat |= DT_NOPREFIX;
230
231     if (infoPtr->hFont) SelectObject( hdc, infoPtr->hFont );
232 #ifdef WINELIB32
233     hBrush = SendMessage( GetParent(hwnd), WM_CTLCOLORSTATIC, hdc, hwnd );
234 #else
235     hBrush = SendMessage( GetParent(hwnd), WM_CTLCOLOR, (WORD)hdc,
236                           MAKELONG(hwnd, CTLCOLOR_STATIC));
237 #endif
238     if (!hBrush) hBrush = GetStockObject(WHITE_BRUSH);
239     FillRect(hdc, &rc, hBrush);
240     if (text) DrawText( hdc, text, -1, &rc, wFormat );
241 }
242
243 static void PaintRectfn( HWND hwnd, HDC hdc )
244 {
245     RECT rc;
246     HBRUSH hBrush;
247
248     WND *wndPtr = WIN_FindWndPtr(hwnd);
249
250     GetClientRect(hwnd, &rc);
251     
252     switch (wndPtr->dwStyle & 0x0f)
253     {
254     case SS_BLACKRECT:
255         hBrush = CreateSolidBrush(color_windowframe);
256         FillRect( hdc, &rc, hBrush );
257         break;
258     case SS_GRAYRECT:
259         hBrush = CreateSolidBrush(color_background);
260         FillRect( hdc, &rc, hBrush );
261         break;
262     case SS_WHITERECT:
263         hBrush = CreateSolidBrush(color_window);
264         FillRect( hdc, &rc, hBrush );
265         break;
266     case SS_BLACKFRAME:
267         hBrush = CreateSolidBrush(color_windowframe);
268         FrameRect( hdc, &rc, hBrush );
269         break;
270     case SS_GRAYFRAME:
271         hBrush = CreateSolidBrush(color_background);
272         FrameRect( hdc, &rc, hBrush );
273         break;
274     case SS_WHITEFRAME:
275         hBrush = CreateSolidBrush(color_window);
276         FrameRect( hdc, &rc, hBrush );
277         break;
278     default:
279         return;
280     }
281     DeleteObject( hBrush );
282 }
283
284
285 static void PaintIconfn( HWND hwnd, HDC hdc )
286 {
287     RECT        rc;
288     HBRUSH      hbrush;
289     WND *wndPtr = WIN_FindWndPtr(hwnd);
290     STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
291
292     GetClientRect(hwnd, &rc);
293 #ifdef WINELIB32
294     hbrush = SendMessage( GetParent(hwnd), WM_CTLCOLORSTATIC, hdc, hwnd );
295 #else
296     hbrush = SendMessage( GetParent(hwnd), WM_CTLCOLOR, hdc,
297                           MAKELONG(hwnd, CTLCOLOR_STATIC));
298 #endif
299     FillRect( hdc, &rc, hbrush );
300     if (infoPtr->hIcon) DrawIcon( hdc, rc.left, rc.top, infoPtr->hIcon );
301 }