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