Release 960131
[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 void STATIC_SetIcon( HWND hwnd, HICON hicon )
53 {
54     WND *wndPtr = WIN_FindWndPtr( hwnd );
55     STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
56
57     if ((wndPtr->dwStyle & 0x0f) != SS_ICON) return;
58 /*  FIXME: is this OK?
59     if (infoPtr->hIcon) DestroyIcon( 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 }
69
70
71 /***********************************************************************
72  *           StaticWndProc
73  */
74 LONG StaticWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
75 {
76         LONG lResult = 0;
77         WND *wndPtr = WIN_FindWndPtr(hWnd);
78         LONG style = wndPtr->dwStyle & 0x0000000F;
79         STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
80
81         switch (uMsg) {
82         case WM_ENABLE:
83             InvalidateRect(hWnd, NULL, FALSE);
84             break;
85
86         case WM_NCCREATE:
87             if (style == SS_ICON)
88             {
89                 CREATESTRUCT * createStruct = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam);
90                 if (createStruct->lpszName)
91                 {
92                     HICON hicon = LoadIcon( createStruct->hInstance,
93                                             (SEGPTR)createStruct->lpszName );
94                     if (!hicon)  /* Try OEM icon (FIXME: is this right?) */
95                         hicon = LoadIcon( 0, (SEGPTR)createStruct->lpszName );
96                     STATIC_SetIcon( hWnd, hicon );
97                 }
98                 return 1;
99             }
100             return DefWindowProc(hWnd, uMsg, wParam, lParam);
101
102         case WM_CREATE:
103             if (style < 0L || style > LAST_STATIC_TYPE)
104             {
105                 fprintf( stderr, "STATIC: Unknown style 0x%02lx\n", style );
106                 lResult = -1L;
107                 break;
108             }
109             /* initialise colours */
110             color_windowframe  = GetSysColor(COLOR_WINDOWFRAME);
111             color_background   = GetSysColor(COLOR_BACKGROUND);
112             color_window       = GetSysColor(COLOR_WINDOW);
113             break;
114
115         case WM_NCDESTROY:
116             if (style == SS_ICON)
117                 STATIC_SetIcon( hWnd, 0 );  /* Destroy the current icon */
118             else 
119                 lResult = DefWindowProc(hWnd, uMsg, wParam, lParam);
120             break;
121
122         case WM_PAINT:
123             {
124                 PAINTSTRUCT ps;
125                 BeginPaint( hWnd, &ps );
126                 if (staticPaintFunc[style])
127                     (staticPaintFunc[style])( hWnd, ps.hdc );
128                 EndPaint( hWnd, &ps );
129             }
130             break;
131
132         case WM_SYSCOLORCHANGE:
133             color_windowframe  = GetSysColor(COLOR_WINDOWFRAME);
134             color_background   = GetSysColor(COLOR_BACKGROUND);
135             color_window       = GetSysColor(COLOR_WINDOW);
136             InvalidateRect(hWnd, NULL, TRUE);
137             break;
138
139         case WM_SETTEXT:
140             if (style == SS_ICON)
141                 STATIC_SetIcon( hWnd, LoadIcon( wndPtr->hInstance,
142                                                 (SEGPTR)lParam ));
143             else
144                 DEFWND_SetText( hWnd, (LPSTR)PTR_SEG_TO_LIN(lParam) );
145             InvalidateRect( hWnd, NULL, FALSE );
146             UpdateWindow( hWnd );
147             break;
148
149         case WM_SETFONT:
150             if (style == SS_ICON) return 0;
151             infoPtr->hFont = (HFONT)wParam;
152             if (LOWORD(lParam))
153             {
154                 InvalidateRect( hWnd, NULL, FALSE );
155                 UpdateWindow( hWnd );
156             }
157             break;
158
159         case WM_GETFONT:
160             return (LONG)infoPtr->hFont;
161
162         case WM_NCHITTEST:
163             return HTTRANSPARENT;
164
165         case WM_GETDLGCODE:
166             return DLGC_STATIC;
167
168         case STM_GETICON:
169             return (LONG)infoPtr->hIcon;
170
171         case STM_SETICON:
172             STATIC_SetIcon( hWnd, (HICON)wParam );
173             InvalidateRect( hWnd, NULL, FALSE );
174             UpdateWindow( hWnd );
175             return 0;
176
177         default:
178                 lResult = DefWindowProc(hWnd, uMsg, wParam, lParam);
179                 break;
180         }
181
182         return lResult;
183 }
184
185
186 static void PaintTextfn( HWND hwnd, HDC hdc )
187 {
188     RECT rc;
189     HBRUSH hBrush;
190     char *text;
191     WORD wFormat;
192
193     WND *wndPtr = WIN_FindWndPtr(hwnd);
194     LONG style = wndPtr->dwStyle;
195     STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
196
197     GetClientRect(hwnd, &rc);
198     text = USER_HEAP_LIN_ADDR( wndPtr->hText );
199
200     switch (style & 0x0000000F)
201     {
202     case SS_LEFT:
203         wFormat = DT_LEFT | DT_EXPANDTABS | DT_WORDBREAK | DT_NOCLIP;
204         break;
205
206     case SS_CENTER:
207         wFormat = DT_CENTER | DT_EXPANDTABS | DT_WORDBREAK | DT_NOCLIP;
208         break;
209
210     case SS_RIGHT:
211         wFormat = DT_RIGHT | DT_EXPANDTABS | DT_WORDBREAK | DT_NOCLIP;
212         break;
213
214     case SS_SIMPLE:
215         wFormat = DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_NOCLIP;
216         break;
217
218     case SS_LEFTNOWORDWRAP:
219         wFormat = DT_LEFT | DT_SINGLELINE | DT_EXPANDTABS | DT_VCENTER | DT_NOCLIP;
220         break;
221
222     default:
223         return;
224     }
225
226     if (style & SS_NOPREFIX)
227         wFormat |= DT_NOPREFIX;
228
229     if (infoPtr->hFont) SelectObject( hdc, infoPtr->hFont );
230 #ifdef WINELIB32
231     hBrush = (HBRUSH)SendMessage( wndPtr->hwndParent, WM_CTLCOLORSTATIC,
232                                   (WPARAM)hdc, (LPARAM)hwnd );
233 #else
234     hBrush = SendMessage( wndPtr->hwndParent, WM_CTLCOLOR, (WORD)hdc,
235                           MAKELONG(hwnd, CTLCOLOR_STATIC));
236 #endif
237     if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(WHITE_BRUSH);
238     FillRect(hdc, &rc, hBrush);
239     if (text)
240         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 = (HBRUSH)SendMessage( wndPtr->hwndParent, WM_CTLCOLORSTATIC, 
295                                   (WPARAM)hdc, (LPARAM)hwnd );
296 #else
297     hbrush = SendMessage( wndPtr->hwndParent, WM_CTLCOLOR, hdc,
298                           MAKELONG(hwnd, CTLCOLOR_STATIC));
299 #endif
300     FillRect( hdc, &rc, hbrush );
301     if (infoPtr->hIcon) DrawIcon( hdc, rc.left, rc.top, infoPtr->hIcon );
302 }