2 * Copyright (c) 1999 Greg Haerr <greg@censoft.com>
4 * DefWindowProc implementation for Micro-Windows
5 * This file should ideally only include windows.h, and be built
6 * on top of regular win32 api calls. For speed, however,
7 * certain knowledge of the internal hwnd is known...
12 #include "wintools.h" /* Draw3dBox, etc*/
15 /* desktop wallpaper image*/
16 static PMWIMAGEHDR pImageWallpaper = NULL;
19 static void GetCloseBoxRect(HWND hwnd, LPRECT lprc);
20 static void DrawXORFrame(HWND hwnd,int x, int y, BOOL bDrawCurrent);
24 MwSetDesktopWallpaper(PMWIMAGEHDR pImage)
26 pImageWallpaper = pImage;
27 InvalidateRect(rootwp, NULL, TRUE);
31 /* needed only for XORMOVE repaint algorithm*/
33 DrawXORFrame(HWND hwnd,int x, int y, BOOL bDrawCurrent)
38 hdc = GetDCEx(NULL, NULL, DCX_WINDOW|DCX_EXCLUDEUPDATE);
39 SelectObject(hdc, GetStockObject(NULL_BRUSH));
40 SelectObject(hdc, GetStockObject(WHITE_PEN));
41 GdSetMode(MWMODE_XOR);
42 if(!IsRectEmpty(&lastrc))
43 Rectangle(hdc, lastrc.left, lastrc.top, lastrc.right,
45 GetWindowRect(hwnd, &rc);
46 SetRect(&lastrc, rc.left+x, rc.top+y, rc.right+x, rc.bottom+y);
48 Rectangle(hdc, lastrc.left, lastrc.top, lastrc.right,
51 GdSetMode(MWMODE_COPY);
55 * This procedure implements the messages passed by the window
56 * manager for default processing on behalf of the window.
59 DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
72 LPNCCALCSIZE_PARAMS lpnc;
78 /* calculate client rect from passed window rect in rgrc[0]*/
79 lpnc = (LPNCCALCSIZE_PARAMS)lParam;
80 dwStyle = GetWindowLong(hwnd, GWL_STYLE);
81 if(dwStyle & WS_BORDER) {
82 if((dwStyle & WS_CAPTION) == WS_CAPTION) {
83 InflateRect(&lpnc->rgrc[0],
84 -mwSYSMETRICS_CXFRAME,
85 -mwSYSMETRICS_CYFRAME);
86 lpnc->rgrc[0].top += mwSYSMETRICS_CYCAPTION + 1;
88 InflateRect(&lpnc->rgrc[0], -1, -1);
93 /* repaint all non-client area*/
94 dwStyle = GetWindowLong(hwnd, GWL_STYLE);
96 if(dwStyle & WS_BORDER) {
97 hdc = GetWindowDC(hwnd);
98 GetWindowRect(hwnd, &rc);
100 if((dwStyle & WS_CAPTION) == WS_CAPTION) {
101 /* draw 2-line 3d border around window*/
102 Draw3dOutset(hdc, rc.left, rc.top,
103 rc.right-rc.left, rc.bottom-rc.top);
104 InflateRect(&rc, -2, -2);
106 /* draw 1-line inset inside border*/
107 hpen = CreatePen(PS_SOLID, 1,
108 GetSysColor(COLOR_BTNFACE));
109 holdpen = SelectObject(hdc, hpen);
110 SelectObject(hdc, GetStockObject(NULL_BRUSH));
111 Rectangle(hdc, rc.left, rc.top, rc.right,
113 InflateRect(&rc, -1, -1);
116 rc.bottom = rc.top + mwSYSMETRICS_CYCAPTION;
117 crCaption = GetActiveWindow()==hwnd?
118 GetSysColor(COLOR_ACTIVECAPTION):
119 GetSysColor(COLOR_INACTIVECAPTION);
120 hbr = CreateSolidBrush(crCaption);
121 FillRect(hdc, &rc, hbr);
124 /* draw 1 line under caption*/
125 MoveToEx(hdc, rc.left, rc.bottom, NULL);
126 LineTo(hdc, rc.right, rc.bottom);
127 DeleteObject(SelectObject(hdc, holdpen));
129 /* draw caption text*/
130 if(GetWindowText(hwnd, szTitle,
132 SetBkMode(hdc, TRANSPARENT);
133 /* set background color even though
134 * transparent in case GdArea is used
135 * to draw text which compares
136 * gr_foreground != gr_background
137 * when transparent...
139 SetBkColor(hdc, crCaption);
141 GetActiveWindow()==hwnd?
142 GetSysColor(COLOR_CAPTIONTEXT):
143 GetSysColor(COLOR_INACTIVECAPTIONTEXT));
145 GetStockObject(DEFAULT_GUI_FONT));
146 GetWindowRect(hwnd, &rc);
147 TextOut(hdc, rc.left+4, rc.top+2,
148 szTitle, strlen(szTitle));
152 GetCloseBoxRect(hwnd, &rc);
153 /*DrawDIB(hdc, rc.right-XSIZE_CLOSEBOX-3,
154 rc.top+3, &image_close4);*/
155 Draw3dBox(hdc, rc.left, rc.top,
156 rc.right-rc.left, rc.bottom-rc.top,
157 GetSysColor(COLOR_BTNHIGHLIGHT),
158 GetSysColor(COLOR_WINDOWFRAME));
159 InflateRect(&rc, -1, -1);
160 hbr = CreateSolidBrush(
161 GetSysColor(COLOR_BTNFACE));
162 FillRect(hdc, &rc, hbr);
165 InflateRect(&rc, -1, -1);
166 MoveToEx(hdc, rc.left, rc.top, NULL);
167 LineTo(hdc, rc.right-1, rc.bottom-1);
168 MoveToEx(hdc, rc.left, rc.bottom-1, NULL);
169 LineTo(hdc, rc.right-1, rc.top);
171 SelectObject(hdc, GetStockObject(NULL_BRUSH));
172 Rectangle(hdc, rc.left, rc.top, rc.right,
175 ReleaseDC(hwnd, hdc);
180 /* if system is dragging a window, always return caption*/
184 /* Determine what part of the window the mouse is over*/
185 POINTSTOPOINT(curpt, lParam);
187 if(PtInRect(&hwnd->clirect, curpt))
190 if(PtInRect(&hwnd->vscroll.rc, curpt))
192 if(PtInRect(&hwnd->hscroll.rc, curpt))
195 dwStyle = GetWindowLong(hwnd, GWL_STYLE);
196 if((dwStyle & WS_CAPTION) == WS_CAPTION) {
197 GetCloseBoxRect(hwnd, &rc);
198 if(PtInRect(&rc, curpt))
201 GetWindowRect(hwnd, &rc);
202 InflateRect(&rc, -2, -2);
203 rc.bottom = rc.top + mwSYSMETRICS_CYCAPTION;
204 if(PtInRect(&rc, curpt))
207 GetWindowRect(hwnd, &rc);
208 InflateRect(&rc, -2, -2);
209 rc.top += mwSYSMETRICS_CYCAPTION;
210 if(PtInRect(&rc, curpt))
217 case WM_NCLBUTTONDOWN:
218 /* Handle default actions for mouse down on window*/
219 if(wParam == HTCLOSE) {
220 SendMessage(hwnd, WM_CLOSE, 0, 0L);
224 /* set focus on mouse down, repaint if necessary*/
225 oldActive = GetActiveWindow();
226 if(wParam == HTCLIENT || wParam == HTVSCROLL ||
228 /* activate and raise window if in client area*/
229 /* kaffe port requires this commented out*/
230 SetForegroundWindow(hwnd);
232 /* otherwise just change focus window, same z order*/
233 /* this will activate it's top level parent*/
236 /* repaint captions now because of activation change*/
237 UpdateWindow(oldActive);
240 if(wParam == HTVSCROLL || wParam == HTHSCROLL) {
241 MwHandleNCMessageScrollbar(hwnd, msg, wParam, lParam);
245 /* start window drag if in caption area*/
246 if(wParam == HTCAPTION && hwnd != rootwp) {
247 POINTSTOPOINT(startpt, lParam);
248 if(!(GetWindowLong(hwnd, GWL_STYLE) & WS_MAXIMIZE))
250 SetRectEmpty(&lastrc); /* XORMOVE only*/
255 if(wParam == HTVSCROLL || wParam == HTHSCROLL) {
256 MwHandleNCMessageScrollbar(hwnd, msg, wParam, lParam);
260 /* drag window with mousemove after mousedown*/
262 POINTSTOPOINT(curpt, lParam);
263 x = curpt.x - startpt.x;
264 y = curpt.y - startpt.y;
267 GetWindowRect(hwnd, &rc);
268 MoveWindow(hwnd, rc.left+x, rc.top+y,
269 rc.right-rc.left, rc.bottom-rc.top,
273 DrawXORFrame(hwnd, x, y, TRUE);
278 /* stop window drag*/
284 * User stopped moving window, repaint
285 * windows previously queued for painting.
287 for(wp=listwp; wp; wp=wp->next)
288 if(wp->gotPaintMsg == PAINT_DELAYPAINT)
289 wp->gotPaintMsg = PAINT_NEEDSPAINT;
291 POINTSTOPOINT(curpt, lParam);
292 x = curpt.x - startpt.x;
293 y = curpt.y - startpt.y;
294 DrawXORFrame(hwnd, x, y, FALSE);
295 GetWindowRect(hwnd, &rc);
296 MoveWindow(hwnd, rc.left+x, rc.top+y,
297 rc.right-rc.left, rc.bottom-rc.top, TRUE);
301 if(wParam == HTVSCROLL || wParam == HTHSCROLL) {
302 MwHandleNCMessageScrollbar(hwnd, msg, wParam, lParam);
307 case WM_NCLBUTTONDBLCLK:
308 if(wParam == HTVSCROLL || wParam == HTHSCROLL) {
309 MwHandleNCMessageScrollbar(hwnd, msg, wParam, lParam);
313 /* maximize/restore processing*/
314 if(wParam != HTCAPTION)
317 if((hwnd->style & WS_CAPTION) == WS_CAPTION) {
318 if(hwnd->style & WS_MAXIMIZE) {
319 rc = hwnd->restorerc;
320 MoveWindow(hwnd, rc.left, rc.top,
321 rc.right-rc.left, rc.bottom-rc.top,
323 hwnd->style &= ~WS_MAXIMIZE;
325 hwnd->restorerc = hwnd->winrect;
326 GetWindowRect(rootwp, &rc);
327 MoveWindow(hwnd, -mwSYSMETRICS_CXFRAME,
328 -mwSYSMETRICS_CYFRAME,
329 rc.right+2*mwSYSMETRICS_CXFRAME,
330 rc.bottom+2*mwSYSMETRICS_CYFRAME, TRUE);
331 hwnd->style |= WS_MAXIMIZE;
336 case WM_GETTEXTLENGTH:
337 /* Get window text length. This routine requires
338 * knowledge of the internal window structure
340 return strlen(hwnd->szTitle);
343 /* Get window text. This routine requires
344 * knowledge of the internal window structure
346 return strzcpy((LPSTR)lParam, hwnd->szTitle, wParam);
349 /* Set window text. This routine requires
350 * knowledge of the internal window structure.
351 * Note that setting text doesn't invalidate the window.
353 strzcpy(hwnd->szTitle, (LPSTR)lParam, sizeof(hwnd->szTitle));
363 /* erase background with class background brush*/
364 hbr = (HBRUSH)GetClassLong(hwnd, GCL_HBRBACKGROUND);
367 /* don't exclude update region*/
368 hdc = GetDCEx(hwnd, NULL, DCX_DEFAULTCLIP);
369 FillRect(hdc, NULL, hbr);
370 ReleaseDC(hwnd, hdc);
374 /* required to send erasebkgnd for desktop window*/
375 hdc = BeginPaint(hwnd, &ps);
377 /* draw desktop wallpaper*/
378 if(hwnd == rootwp && pImageWallpaper) {
379 GetWindowRect(hwnd, &rc);
381 (rc.right-rc.left-pImageWallpaper->width)/2,
382 (rc.bottom-rc.top-pImageWallpaper->height)/2,
393 GetCloseBoxRect(HWND hwnd, LPRECT lprc)
395 #define XSIZE_CLOSEBOX 9
396 #define YSIZE_CLOSEBOX 9
397 GetWindowRect(hwnd, lprc);
398 lprc->left = lprc->right - XSIZE_CLOSEBOX - 5;
399 lprc->top = lprc->top + 5;
400 lprc->right = lprc->left + XSIZE_CLOSEBOX;
401 lprc->bottom = lprc->top + YSIZE_CLOSEBOX;