Don't reinitialize the VGA on an enable surface if it is already initialized
[reactos.git] / reactos / lib / user32 / windows / defwnd.c
1 /* $Id: defwnd.c,v 1.6 2002/09/01 20:39:55 dwelch Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS user32.dll
5 * FILE: lib/user32/windows/window.c
6 * PURPOSE: Window management
7 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * UPDATE HISTORY:
9 * 06-06-2001 CSH Created
10 */
11
12 /* INCLUDES ******************************************************************/
13
14 #include <windows.h>
15 #include <user32.h>
16 #include <window.h>
17 #include <debug.h>
18 #include <user32/wininternal.h>
19
20 /* GLOBALS *******************************************************************/
21
22 static HBITMAP hbitmapClose;
23 static HBITMAP hbitmapMinimize;
24 static HBITMAP hbitmapMinimizeD;
25 static HBITMAP hbitmapMaximize;
26 static HBITMAP hbitmapMaximizeD;
27 static HBITMAP hbitmapRestore;
28 static HBITMAP hbitmapRestoreD;
29
30 static COLORREF SysColours[] =
31 {
32 RGB(224, 224, 224) /* COLOR_SCROLLBAR */,
33 RGB(192, 192, 192) /* COLOR_BACKGROUND */,
34 RGB(0, 64, 128) /* COLOR_ACTIVECAPTION */,
35 RGB(255, 255, 255) /* COLOR_INACTIVECAPTION */,
36 RGB(255, 255, 255) /* COLOR_MENU */,
37 RGB(255, 255, 255) /* COLOR_WINDOW */,
38 RGB(0, 0, 0) /* COLOR_WINDOWFRAME */,
39 RGB(0, 0, 0) /* COLOR_MENUTEXT */,
40 RGB(0, 0, 0) /* COLOR_WINDOWTEXT */,
41 RGB(255, 255, 255) /* COLOR_CAPTIONTEXT */,
42 RGB(128, 128, 128) /* COLOR_ACTIVEBORDER */,
43 RGB(255, 255, 255) /* COLOR_INACTIVEBORDER */,
44 RGB(255, 255, 232) /* COLOR_APPWORKSPACE */,
45 RGB(224, 224, 224) /* COLOR_HILIGHT */,
46 RGB(0, 0, 0) /* COLOR_HILIGHTTEXT */,
47 RGB(192, 192, 192) /* COLOR_BTNFACE */,
48 RGB(128, 128, 128) /* COLOR_BTNSHADOW */,
49 RGB(192, 192, 192) /* COLOR_GRAYTEXT */,
50 RGB(0, 0, 0) /* COLOR_BTNTEXT */,
51 RGB(0, 0, 0) /* COLOR_INACTIVECAPTIONTEXT */,
52 RGB(255, 255, 255) /* COLOR_BTNHILIGHT */,
53 RGB(32, 32, 32) /* COLOR_3DDKSHADOW */,
54 RGB(192, 192, 192) /* COLOR_3DLIGHT */,
55 RGB(0, 0, 0) /* COLOR_INFOTEXT */,
56 RGB(255, 255, 192) /* COLOR_INFOBK */,
57 RGB(184, 180, 184) /* COLOR_ALTERNATEBTNFACE */,
58 RGB(0, 0, 255) /* COLOR_HOTLIGHT */,
59 RGB(16, 132, 208) /* COLOR_GRADIENTACTIVECAPTION */,
60 RGB(181, 181, 181) /* COLOR_GRADIENTINACTIVECAPTION */,
61 };
62
63 /* FUNCTIONS *****************************************************************/
64
65 /* ReactOS extension */
66 HPEN STDCALL
67 GetSysColorPen(int nIndex)
68 {
69 return(CreatePen(PS_SOLID, 1, SysColours[nIndex]));
70 }
71
72 HBRUSH STDCALL
73 GetSysColorBrush(int nIndex)
74 {
75 return(CreateSolidBrush(SysColours[nIndex]));
76 }
77
78
79 LRESULT STDCALL
80 DefFrameProcA(HWND hWnd,
81 HWND hWndMDIClient,
82 UINT uMsg,
83 WPARAM wParam,
84 LPARAM lParam)
85 {
86 return((LRESULT)0);
87 }
88
89 LRESULT STDCALL
90 DefFrameProcW(HWND hWnd,
91 HWND hWndMDIClient,
92 UINT uMsg,
93 WPARAM wParam,
94 LPARAM lParam)
95 {
96 return((LRESULT)0);
97 }
98
99
100 BOOL
101 DefWndRedrawIconTitle(HWND hWnd)
102 {
103 }
104
105 ULONG
106 UserHasAnyFrameStyle(ULONG Style, ULONG ExStyle)
107 {
108 return((Style & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) ||
109 (ExStyle & WS_EX_DLGMODALFRAME) ||
110 (!(Style & (WS_CHILD | WS_POPUP))));
111 }
112
113 ULONG
114 UserHasDlgFrameStyle(ULONG Style, ULONG ExStyle)
115 {
116 return((ExStyle & WS_EX_DLGMODALFRAME) ||
117 ((Style & WS_DLGFRAME) && (!(Style & WS_THICKFRAME))));
118 }
119
120 ULONG
121 UserHasThickFrameStyle(ULONG Style, ULONG ExStyle)
122 {
123 return((Style & WS_THICKFRAME) &&
124 (!((Style & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)));
125 }
126
127 ULONG
128 UserHasThinFrameStyle(ULONG Style, ULONG ExStyle)
129 {
130 return((Style & WS_BORDER) ||
131 (!(Style & (WS_CHILD | WS_POPUP))));
132 }
133
134 ULONG
135 UserHasBigFrameStyle(ULONG Style, ULONG ExStyle)
136 {
137 return((Style & (WS_THICKFRAME | WS_DLGFRAME)) ||
138 (ExStyle & WS_EX_DLGMODALFRAME));
139 }
140
141 static void UserGetInsideRectNC( HWND hwnd, RECT *rect )
142 {
143 RECT WindowRect;
144 ULONG Style;
145 ULONG ExStyle;
146
147 Style = GetWindowLong(hwnd, GWL_STYLE);
148 ExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
149 GetWindowRect(hwnd, &WindowRect);
150 rect->top = rect->left = 0;
151 rect->right = WindowRect.right - WindowRect.left;
152 rect->bottom = WindowRect.bottom - WindowRect.top;
153
154 if (Style & WS_ICONIC)
155 {
156 return;
157 }
158
159 /* Remove frame from rectangle */
160 if (UserHasThickFrameStyle(Style, ExStyle ))
161 {
162 InflateRect( rect, -GetSystemMetrics(SM_CXFRAME),
163 -GetSystemMetrics(SM_CYFRAME) );
164 }
165 else
166 {
167 if (UserHasDlgFrameStyle(Style, ExStyle ))
168 {
169 InflateRect( rect, -GetSystemMetrics(SM_CXDLGFRAME),
170 -GetSystemMetrics(SM_CYDLGFRAME));
171 /* FIXME: this isn't in NC_AdjustRect? why not? */
172 if (ExStyle & WS_EX_DLGMODALFRAME)
173 InflateRect( rect, -1, 0 );
174 }
175 else
176 {
177 if (UserHasThinFrameStyle(Style, ExStyle))
178 {
179 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
180 }
181 }
182 }
183 }
184
185 void UserDrawSysButton( HWND hwnd, HDC hdc, BOOL down )
186 {
187 RECT rect;
188 HDC hdcMem;
189 HBITMAP hbitmap;
190 ULONG Style;
191
192 Style = GetWindowLong(hwnd, GWL_STYLE);
193 UserGetInsideRectNC( hwnd, &rect );
194 hdcMem = CreateCompatibleDC( hdc );
195 hbitmap = SelectObject( hdcMem, hbitmapClose );
196 BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE), GetSystemMetrics(SM_CYSIZE),
197 hdcMem, (Style & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE) : 0, 0,
198 down ? NOTSRCCOPY : SRCCOPY );
199 SelectObject( hdcMem, hbitmap );
200 DeleteDC( hdcMem );
201 }
202
203 static void UserDrawMaxButton( HWND hwnd, HDC hdc, BOOL down )
204 {
205 RECT rect;
206 HDC hdcMem;
207
208 UserGetInsideRectNC( hwnd, &rect );
209 hdcMem = CreateCompatibleDC( hdc );
210 SelectObject( hdcMem, (IsZoomed(hwnd)
211 ? (down ? hbitmapRestoreD : hbitmapRestore)
212 : (down ? hbitmapMaximizeD : hbitmapMaximize)) );
213 BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
214 GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
215 SRCCOPY );
216 DeleteDC( hdcMem );
217 }
218
219 static void UserDrawMinButton( HWND hwnd, HDC hdc, BOOL down)
220 {
221 RECT rect;
222 HDC hdcMem;
223
224 UserGetInsideRectNC(hwnd, &rect);
225 hdcMem = CreateCompatibleDC(hdc);
226 SelectObject(hdcMem, (down ? hbitmapMinimizeD : hbitmapMinimize));
227 if (GetWindowLong(hwnd, GWL_STYLE) & WS_MAXIMIZEBOX)
228 {
229 rect.right -= GetSystemMetrics(SM_CXSIZE)+1;
230 }
231 BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
232 GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE),
233 hdcMem, 0, 0,
234 SRCCOPY );
235 DeleteDC( hdcMem );
236 }
237
238 static void UserDrawCaptionNC( HDC hdc, RECT *rect, HWND hwnd,
239 DWORD style, BOOL active )
240 {
241 RECT r = *rect;
242 char buffer[256];
243
244 if (!hbitmapClose)
245 {
246 if (!(hbitmapClose = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_CLOSE) )))
247 {
248 return;
249 }
250 hbitmapMinimize = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_REDUCE) );
251 hbitmapMinimizeD = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_REDUCED) );
252 hbitmapMaximize = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_ZOOM) );
253 hbitmapMaximizeD = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_ZOOMD) );
254 hbitmapRestore = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_RESTORE) );
255 hbitmapRestoreD = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_RESTORED) );
256 }
257
258 if (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_DLGMODALFRAME)
259 {
260 HBRUSH hbrushOld = SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW) );
261 PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
262 PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
263 PatBlt( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
264 r.left++;
265 r.right--;
266 SelectObject( hdc, hbrushOld );
267 }
268
269 MoveToEx( hdc, r.left, r.bottom, NULL );
270 LineTo( hdc, r.right, r.bottom );
271
272 if (style & WS_SYSMENU)
273 {
274 UserDrawSysButton( hwnd, hdc, FALSE );
275 r.left += GetSystemMetrics(SM_CXSIZE) + 1;
276 MoveToEx( hdc, r.left - 1, r.top, NULL );
277 LineTo( hdc, r.left - 1, r.bottom );
278 }
279 if (style & WS_MAXIMIZEBOX)
280 {
281 UserDrawMaxButton( hwnd, hdc, FALSE );
282 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
283 }
284 if (style & WS_MINIMIZEBOX)
285 {
286 UserDrawMinButton( hwnd, hdc, FALSE );
287 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
288 }
289
290 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
291 COLOR_INACTIVECAPTION) );
292
293 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) ))
294 {
295 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
296 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
297 SetBkMode( hdc, TRANSPARENT );
298 DrawTextA( hdc, buffer, -1, &r,
299 DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );
300 }
301 }
302
303 VOID
304 UserDrawFrameNC(HDC hdc, RECT* rect, BOOL dlgFrame, BOOL active)
305 {
306 INT width, height;
307
308 if (dlgFrame)
309 {
310 width = GetSystemMetrics(SM_CXDLGFRAME) - 1;
311 height = GetSystemMetrics(SM_CYDLGFRAME) - 1;
312 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
313 COLOR_INACTIVECAPTION) );
314 }
315 else
316 {
317 width = GetSystemMetrics(SM_CXFRAME) - 2;
318 height = GetSystemMetrics(SM_CYFRAME) - 2;
319 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
320 COLOR_INACTIVEBORDER) );
321 }
322
323 /* Draw frame */
324 PatBlt( hdc, rect->left, rect->top,
325 rect->right - rect->left, height, PATCOPY );
326 PatBlt( hdc, rect->left, rect->top,
327 width, rect->bottom - rect->top, PATCOPY );
328 PatBlt( hdc, rect->left, rect->bottom - 1,
329 rect->right - rect->left, -height, PATCOPY );
330 PatBlt( hdc, rect->right - 1, rect->top,
331 -width, rect->bottom - rect->top, PATCOPY );
332
333 if (dlgFrame)
334 {
335 InflateRect( rect, -width, -height );
336 }
337 else
338 {
339 INT decYOff = GetSystemMetrics(SM_CXFRAME) +
340 GetSystemMetrics(SM_CXSIZE) - 1;
341 INT decXOff = GetSystemMetrics(SM_CYFRAME) +
342 GetSystemMetrics(SM_CYSIZE) - 1;
343
344 /* Draw inner rectangle */
345
346 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
347 Rectangle( hdc, rect->left + width, rect->top + height,
348 rect->right - width , rect->bottom - height );
349
350 /* Draw the decorations */
351
352 MoveToEx( hdc, rect->left, rect->top + decYOff, NULL );
353 LineTo( hdc, rect->left + width, rect->top + decYOff );
354 MoveToEx( hdc, rect->right - 1, rect->top + decYOff, NULL );
355 LineTo( hdc, rect->right - width - 1, rect->top + decYOff );
356 MoveToEx( hdc, rect->left, rect->bottom - decYOff, NULL );
357 LineTo( hdc, rect->left + width, rect->bottom - decYOff );
358 MoveToEx( hdc, rect->right - 1, rect->bottom - decYOff, NULL );
359 LineTo( hdc, rect->right - width - 1, rect->bottom - decYOff );
360
361 MoveToEx( hdc, rect->left + decXOff, rect->top, NULL );
362 LineTo( hdc, rect->left + decXOff, rect->top + height);
363 MoveToEx( hdc, rect->left + decXOff, rect->bottom - 1, NULL );
364 LineTo( hdc, rect->left + decXOff, rect->bottom - height - 1 );
365 MoveToEx( hdc, rect->right - decXOff, rect->top, NULL );
366 LineTo( hdc, rect->right - decXOff, rect->top + height );
367 MoveToEx( hdc, rect->right - decXOff, rect->bottom - 1, NULL );
368 LineTo( hdc, rect->right - decXOff, rect->bottom - height - 1 );
369
370 InflateRect( rect, -width - 1, -height - 1 );
371 }
372 }
373
374 VOID
375 DefWndDoPaintNC(HWND hWnd, HRGN clip)
376 {
377 ULONG Active;
378 HDC hDc;
379 RECT rect;
380 ULONG Style;
381 ULONG ExStyle;
382
383 Active = GetWindowLongW(hWnd, GWL_STYLE) & WIN_NCACTIVATED;
384 Style = GetWindowLong(hWnd, GWL_STYLE);
385 ExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
386
387 hDc = GetDCEx(hWnd, (clip > (HRGN)1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
388 ((clip > (HRGN)1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0));
389 if (hDc == 0)
390 {
391 return;
392 }
393
394 /* FIXME: Test whether we need to draw anything at all. */
395
396 GetWindowRect(hWnd, &rect);
397 rect.right = rect.right - rect.left;
398 rect.bottom = rect.bottom - rect.top;
399 rect.top = rect.left = 0;
400
401 SelectObject(hDc, GetSysColorPen(COLOR_WINDOWFRAME));
402 if (UserHasAnyFrameStyle(Style, ExStyle))
403 {
404 SelectObject(hDc, GetStockObject(NULL_BRUSH));
405 Rectangle(hDc, 0, 0, rect.right, rect.bottom);
406 InflateRect(&rect, -1, -1);
407 }
408
409 if (UserHasThickFrameStyle(Style, ExStyle))
410 {
411 UserDrawFrameNC(hDc, &rect, FALSE, Active);
412 }
413 else if (UserHasDlgFrameStyle(Style, ExStyle))
414 {
415 UserDrawFrameNC(hDc, &rect, TRUE, Active);
416 }
417
418 if (Style & WS_CAPTION)
419 {
420 RECT r = rect;
421 r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
422 rect.top += GetSystemMetrics(SM_CYSIZE) +
423 GetSystemMetrics(SM_CYBORDER);
424 UserDrawCaptionNC(hDc, &r, hWnd, Style, Active);
425 }
426
427 /* FIXME: Draw menu bar. */
428
429 /* FIXME: Draw scroll bars. */
430
431 /* FIXME: Draw size box. */
432
433 ReleaseDC(hWnd, hDc);
434 }
435
436 LRESULT
437 DefWndPaintNC(HWND hWnd, HRGN clip)
438 {
439 if (IsWindowVisible(hWnd))
440 {
441 if (IsIconic(hWnd))
442 {
443 DefWndRedrawIconTitle(hWnd);
444 }
445 else
446 {
447 DefWndDoPaintNC(hWnd, clip);
448 }
449 }
450 return(0);
451 }
452
453 LRESULT
454 DefWndHitTestNC(HWND hWnd, POINT Point)
455 {
456 }
457
458 LRESULT
459 DefWndHandleLButtonDownNC(HWND hWnd, WPARAM wParam, LPARAM lParam)
460 {
461 }
462
463 LRESULT
464 DefWndHandleLButtonDblClkNC(HWND hWnd, WPARAM wParam, LPARAM lParam)
465 {
466 }
467
468 LRESULT
469 DefWndHandleActiveNC(HWND hWnd, WPARAM wParam)
470 {
471 }
472
473 VOID
474 DefWndSetRedraw(HWND hWnd, WPARAM wParam)
475 {
476 }
477
478 LRESULT
479 DefWndHandleSetCursor(HWND hWnd, WPARAM wParam, LPARAM lParam)
480 {
481 /* Not for child windows. */
482 if (hWnd != (HWND)wParam)
483 {
484 return(0);
485 }
486
487 switch(LOWORD(lParam))
488 {
489 case HTERROR:
490 {
491 WORD Msg = HIWORD(lParam);
492 if (Msg == WM_LBUTTONDOWN || Msg == WM_MBUTTONDOWN ||
493 Msg == WM_RBUTTONDOWN)
494 {
495 MessageBeep(0);
496 }
497 break;
498 }
499
500 case HTCLIENT:
501 {
502 HICON hCursor = (HICON)GetClassLong(hWnd, GCL_HCURSOR);
503 if (hCursor)
504 {
505 SetCursor(hCursor);
506 return(TRUE);
507 }
508 return(FALSE);
509 }
510
511 case HTLEFT:
512 case HTRIGHT:
513 {
514 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZEWE)));
515 }
516
517 case HTTOP:
518 case HTBOTTOM:
519 {
520 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENS)));
521 }
522
523 case HTTOPLEFT:
524 case HTBOTTOMRIGHT:
525 {
526 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENWSE)));
527 }
528
529 case HTBOTTOMLEFT:
530 case HTTOPRIGHT:
531 {
532 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENESW)));
533 }
534 }
535 return((LRESULT)SetCursor(LoadCursorW(0, IDC_ARROW)));
536 }
537
538 LRESULT
539 DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, POINT Pt)
540 {
541 /* FIXME: Implement system commands. */
542 return(0);
543 }
544
545 VOID
546 DefWndAdjustRect(RECT* Rect, ULONG Style, BOOL Menu, ULONG ExStyle)
547 {
548 if (Style & WS_ICONIC)
549 {
550 return;
551 }
552
553 if (UserHasThickFrameStyle(Style, ExStyle))
554 {
555 InflateRect(Rect, GetSystemMetrics(SM_CXFRAME),
556 GetSystemMetrics(SM_CYFRAME));
557 }
558 else if (UserHasDlgFrameStyle(Style, ExStyle))
559 {
560 InflateRect(Rect, GetSystemMetrics(SM_CXDLGFRAME),
561 GetSystemMetrics(SM_CYDLGFRAME));
562 }
563 else if (UserHasThinFrameStyle(Style, ExStyle))
564 {
565 InflateRect(Rect, GetSystemMetrics(SM_CXBORDER),
566 GetSystemMetrics(SM_CYBORDER));
567 }
568 if (Style & WS_CAPTION)
569 {
570 Rect->top -= GetSystemMetrics(SM_CYCAPTION) -
571 GetSystemMetrics(SM_CYBORDER);
572 }
573 if (Menu)
574 {
575 Rect->top -= GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYBORDER);
576 }
577 if (Style & WS_VSCROLL)
578 {
579 Rect->right += GetSystemMetrics(SM_CXVSCROLL) - 1;
580 if (UserHasAnyFrameStyle(Style, ExStyle))
581 {
582 Rect->right++;
583 }
584 }
585 if (Style & WS_HSCROLL)
586 {
587 Rect->bottom += GetSystemMetrics(SM_CYHSCROLL) - 1;
588 if (UserHasAnyFrameStyle(Style, ExStyle))
589 {
590 Rect->bottom++;
591 }
592 }
593 }
594
595 LRESULT STDCALL
596 DefWndNCCalcSize(HWND hWnd, RECT* Rect)
597 {
598 LRESULT Result;
599 LONG Style = GetClassLongW(hWnd, GCL_STYLE);
600 RECT TmpRect = {0, 0, 0, 0};
601
602 if (Style & CS_VREDRAW)
603 {
604 Result |= WVR_VREDRAW;
605 }
606 if (Style & CS_HREDRAW)
607 {
608 Result |= WVR_HREDRAW;
609 }
610
611 if (!(GetWindowLong(hWnd, GWL_STYLE) & WS_MINIMIZE))
612 {
613 DefWndAdjustRect(&TmpRect, GetWindowLong(hWnd, GWL_STYLE),
614 FALSE, GetWindowLong(hWnd, GWL_EXSTYLE));
615 Rect->left -= TmpRect.left;
616 Rect->top -= TmpRect.top;
617 Rect->right -= TmpRect.right;
618 Rect->bottom -= TmpRect.bottom;
619 /* FIXME: Adjust if the window has a menu. */
620 Rect->bottom = max(Rect->top, Rect->bottom);
621 Rect->right = max(Rect->left, Rect->right);
622 }
623 return(Result);
624 }
625
626 LRESULT
627 DefWndHandleWindowPosChanging(HWND hWnd, WINDOWPOS* Pos)
628 {
629 /* FIXME: Implement this. */
630 }
631
632 LRESULT STDCALL
633 User32DefWindowProc(HWND hWnd,
634 UINT Msg,
635 WPARAM wParam,
636 LPARAM lParam,
637 BOOL bUnicode)
638 {
639 switch (Msg)
640 {
641 case WM_NCPAINT:
642 {
643 return(DefWndPaintNC(hWnd, (HRGN)wParam));
644 }
645
646 case WM_NCHITTEST:
647 {
648 POINT Point;
649 Point.x = SLOWORD(lParam);
650 Point.y = SHIWORD(lParam);
651 return(DefWndHitTestNC(hWnd, Point));
652 }
653
654 case WM_NCLBUTTONDOWN:
655 {
656 return(DefWndHandleLButtonDownNC(hWnd, wParam, lParam));
657 }
658
659 case WM_LBUTTONDBLCLK:
660 case WM_NCLBUTTONDBLCLK:
661 {
662 return(DefWndHandleLButtonDblClkNC(hWnd, wParam, lParam));
663 }
664
665 case WM_NCRBUTTONDOWN:
666 {
667 if (wParam == HTCAPTION)
668 {
669 SetCapture(hWnd);
670 }
671 break;
672 }
673
674 case WM_RBUTTONUP:
675 {
676 POINT Pt;
677 if (hWnd == GetCapture())
678 {
679 ReleaseCapture();
680 }
681 Pt.x = SLOWORD(lParam);
682 Pt.y = SHIWORD(lParam);
683 ClientToScreen(hWnd, &Pt);
684 lParam = MAKELPARAM(Pt.x, Pt.y);
685 if (bUnicode)
686 {
687 SendMessageW(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
688 }
689 else
690 {
691 SendMessageA (hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
692 }
693 break;
694 }
695
696 case WM_NCRBUTTONUP:
697 {
698 /* Wine does nothing here. */
699 break;
700 }
701
702 case WM_CONTEXTMENU:
703 {
704 if (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD)
705 {
706 if (bUnicode)
707 {
708 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
709 }
710 else
711 {
712 SendMessageA(hWnd, WM_CONTEXTMENU, wParam, lParam);
713 }
714 }
715 else
716 {
717 LONG HitCode;
718 POINT Pt;
719
720 Pt.x = SLOWORD(lParam);
721 Pt.y = SHIWORD(lParam);
722
723 if (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD)
724 {
725 ScreenToClient(GetParent(hWnd), &Pt);
726 }
727
728 HitCode = DefWndHitTestNC(hWnd, Pt);
729
730 if (HitCode == HTCAPTION || HitCode == HTSYSMENU)
731 {
732 TrackPopupMenu(GetSystemMenu(hWnd, FALSE),
733 TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
734 Pt.x, Pt.y, 0, hWnd, NULL);
735 }
736 }
737 break;
738 }
739
740 case WM_NCACTIVATE:
741 {
742 return(DefWndHandleActiveNC(hWnd, wParam));
743 }
744
745 case WM_NCDESTROY:
746 {
747 return(0);
748 }
749
750 case WM_PRINT:
751 {
752 return(0);
753 }
754
755 case WM_PAINTICON:
756 case WM_PAINT:
757 {
758 PAINTSTRUCT Ps;
759 HDC hDc = BeginPaint(hWnd, &Ps);
760 if (hDc)
761 {
762 HICON hIcon;
763 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE &&
764 (hIcon = (HICON)GetClassLongW(hWnd, GCL_HICON)) != NULL)
765 {
766 RECT WindowRect;
767 INT x, y;
768 GetWindowRect(hWnd, &WindowRect);
769 x = (WindowRect.right - WindowRect.left -
770 GetSystemMetrics(SM_CXICON)) / 2;
771 y = (WindowRect.bottom - WindowRect.top -
772 GetSystemMetrics(SM_CYICON)) / 2;
773 DrawIcon(hDc, x, y, hIcon);
774 }
775 EndPaint(hWnd, &Ps);
776 }
777 return(0);
778 }
779
780 case WM_SYNCPAINT:
781 {
782 HRGN hRgn;
783 hRgn = CreateRectRgn(0, 0, 0, 0);
784 if (GetUpdateRgn(hWnd, hRgn, FALSE) != NULLREGION)
785 {
786 RedrawWindow(hWnd, NULL, hRgn,
787 RDW_ERASENOW | RDW_ERASE | RDW_FRAME |
788 RDW_ALLCHILDREN);
789 }
790 DeleteObject(hRgn);
791 return(0);
792 }
793
794 case WM_SETREDRAW:
795 {
796 DefWndSetRedraw(hWnd, wParam);
797 return(0);
798 }
799
800 case WM_CLOSE:
801 {
802 DestroyWindow(hWnd);
803 return(0);
804 }
805
806 case WM_MOUSEACTIVATE:
807 {
808 if (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD)
809 {
810 LONG Ret;
811 if (bUnicode)
812 {
813 Ret = SendMessageW(GetParent(hWnd), WM_MOUSEACTIVATE,
814 wParam, lParam);
815 }
816 else
817 {
818 Ret = SendMessageA(GetParent(hWnd), WM_MOUSEACTIVATE,
819 wParam, lParam);
820 }
821 if (Ret)
822 {
823 return(Ret);
824 }
825 }
826 return((LOWORD(lParam) >= HTCLIENT) ? MA_ACTIVATE : MA_NOACTIVATE);
827 }
828
829 case WM_ACTIVATE:
830 {
831 if (LOWORD(lParam) != WA_INACTIVE &&
832 GetWindowLong(hWnd, GWL_STYLE) & WS_MINIMIZE)
833 {
834 /* Check if the window is minimized. */
835 SetFocus(hWnd);
836 }
837 break;
838 }
839
840 case WM_MOUSEWHEEL:
841 {
842 if (GetWindowLong(hWnd, GWL_STYLE & WS_CHILD))
843 {
844 if (bUnicode)
845 {
846 return(SendMessageW(GetParent(hWnd), WM_MOUSEWHEEL,
847 wParam, lParam));
848 }
849 else
850 {
851 return(SendMessageA(GetParent(hWnd), WM_MOUSEWHEEL,
852 wParam, lParam));
853 }
854 }
855 break;
856 }
857
858 case WM_ERASEBKGND:
859 case WM_ICONERASEBKGND:
860 {
861 RECT Rect;
862 HBRUSH hBrush = (HBRUSH)GetClassLongW(hWnd, GCL_HBRBACKGROUND);
863 GetClipBox((HDC)wParam, &Rect);
864 FillRect((HDC)wParam, &Rect, hBrush);
865 return(1);
866 }
867
868 case WM_GETDLGCODE:
869 {
870 return(0);
871 }
872
873 /* FIXME: Implement colour controls. */
874
875 case WM_SETCURSOR:
876 {
877 if (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD)
878 {
879 if (LOWORD(lParam) < HTLEFT || LOWORD(lParam) > HTBOTTOMRIGHT)
880 {
881 BOOL bResult;
882 if (bUnicode)
883 {
884 bResult = SendMessageW(GetParent(hWnd), WM_SETCURSOR,
885 wParam, lParam);
886 }
887 else
888 {
889 bResult = SendMessageA(GetParent(hWnd), WM_SETCURSOR,
890 wParam, lParam);
891 }
892 if (bResult)
893 {
894 return(TRUE);
895 }
896 }
897 }
898 return(DefWndHandleSetCursor(hWnd, wParam, lParam));
899 }
900
901 case WM_SYSCOMMAND:
902 {
903 POINT Pt;
904 Pt.x = SLOWORD(lParam);
905 Pt.y = SHIWORD(lParam);
906 return(DefWndHandleSysCommand(hWnd, wParam, Pt));
907 }
908
909 /* FIXME: Handle key messages. */
910
911 case WM_SHOWWINDOW:
912 {
913 if (lParam)
914 {
915 return(0);
916 }
917 /* FIXME: Check for a popup window. */
918 if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_VISIBLE && !wParam) ||
919 (!(GetWindowLongW(hWnd, GWL_STYLE) & WS_VISIBLE) && wParam))
920 {
921 return(0);
922 }
923 ShowWindow(hWnd, wParam ? SW_SHOWNOACTIVATE : SW_HIDE);
924 break;
925 }
926
927 case WM_CANCELMODE:
928 {
929 /* FIXME: Check for a desktop. */
930 if (GetCapture() == hWnd)
931 {
932 ReleaseCapture();
933 }
934 break;
935 }
936
937 case WM_VKEYTOITEM:
938 case WM_CHARTOITEM:
939 return(-1);
940
941 case WM_DROPOBJECT:
942 /* FIXME: Implement this. */
943 break;
944
945 case WM_QUERYDROPOBJECT:
946 {
947 if (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_ACCEPTFILES)
948 {
949 return(1);
950 }
951 break;
952 }
953
954 case WM_QUERYDRAGICON:
955 {
956 UINT Len;
957 HICON hIcon;
958
959 hIcon = (HICON)GetClassLongW(hWnd, GCL_HICON);
960 if (hIcon)
961 {
962 return((LRESULT)hIcon);
963 }
964 for (Len = 1; Len < 64; Len++)
965 {
966 if ((hIcon = LoadIconW(NULL, MAKEINTRESOURCE(Len))) != NULL)
967 {
968 return((LRESULT)hIcon);
969 }
970 }
971 return((LRESULT)LoadIconW(0, IDI_APPLICATION));
972 }
973
974 /* FIXME: WM_ISACTIVEICON */
975
976 case WM_NOTIFYFORMAT:
977 {
978 if (IsWindowUnicode(hWnd))
979 {
980 return(NFR_UNICODE);
981 }
982 else
983 {
984 return(NFR_ANSI);
985 }
986 }
987
988 case WM_SETICON:
989 {
990 INT Index = (wParam != 0) ? GCL_HICON : GCL_HICONSM;
991 HICON hOldIcon = (HICON)GetClassLongW(hWnd, Index);
992 SetClassLongW(hWnd, Index, lParam);
993 SetWindowPos(hWnd, 0, 0, 0, 0, 0,
994 SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
995 SWP_NOACTIVATE | SWP_NOZORDER);
996 return((LRESULT)hOldIcon);
997 }
998
999 case WM_GETICON:
1000 {
1001 INT Index = (wParam != 0) ? GCL_HICON : GCL_HICONSM;
1002 return(GetClassLongW(hWnd, Index));
1003 }
1004
1005 case WM_HELP:
1006 {
1007 if (bUnicode)
1008 {
1009 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
1010 }
1011 else
1012 {
1013 SendMessageA(GetParent(hWnd), Msg, wParam, lParam);
1014 }
1015 break;
1016 }
1017 }
1018 return 0;
1019 }
1020
1021 LRESULT STDCALL
1022 DefWindowProcA(HWND hWnd,
1023 UINT Msg,
1024 WPARAM wParam,
1025 LPARAM lParam)
1026 {
1027 LRESULT Result;
1028 static ATOM WindowTextAtom = 0;
1029 PSTR WindowText;
1030
1031 switch (Msg)
1032 {
1033 case WM_NCCREATE:
1034 {
1035 CREATESTRUCTA* Cs = (CREATESTRUCTA*)lParam;
1036 if (HIWORD(Cs->lpszName))
1037 {
1038 WindowTextAtom = GlobalAddAtomA("USER32!WindowTextAtomA");
1039 WindowText = User32AllocHeap(strlen(Cs->lpszName) * sizeof(CHAR));
1040 strcpy(WindowText, Cs->lpszName);
1041 SetPropA(hWnd, WindowTextAtom, WindowText);
1042 }
1043 return(1);
1044 }
1045
1046 case WM_NCCALCSIZE:
1047 {
1048 return(DefWndNCCalcSize(hWnd, (RECT*)lParam));
1049 }
1050
1051 case WM_WINDOWPOSCHANGING:
1052 {
1053 return(DefWndHandleWindowPosChanging(hWnd, (WINDOWPOS*)lParam));
1054 }
1055
1056 case WM_GETTEXTLENGTH:
1057 {
1058 if (WindowTextAtom == 0 ||
1059 (WindowText = GetPropA(hWnd, WindowTextAtom)) == NULL)
1060 {
1061 return(0);
1062 }
1063 return(wcslen(WindowText));
1064 }
1065
1066 case WM_GETTEXT:
1067 {
1068 if (WindowTextAtom == 0 ||
1069 (WindowText = GetPropA(hWnd, WindowTextAtom)) == NULL)
1070 {
1071 if (wParam > 1)
1072 {
1073 ((PSTR)lParam) = '\0';
1074 }
1075 return(0);
1076 }
1077 strncpy((PWSTR)lParam, WindowText, wParam);
1078 return(min(wParam, wcslen(WindowText)));
1079 }
1080
1081 case WM_SETTEXT:
1082 {
1083 if (WindowTextAtom != 0)
1084 {
1085 WindowTextAtom = GlobalAddAtomA("USER32!WindowTextAtomW");
1086 }
1087 if (WindowTextAtom != 0 &&
1088 (WindowText = GetPropA(hWnd, WindowTextAtom)) == NULL)
1089 {
1090 User32FreeHeap(WindowText);
1091 }
1092 WindowText = User32AllocHeap(strlen((PSTR)lParam) * sizeof(CHAR));
1093 strcpy(WindowText, (PSTR)lParam);
1094 SetPropA(hWnd, WindowTextAtom, WindowText);
1095 }
1096
1097 case WM_NCDESTROY:
1098 {
1099 if (WindowTextAtom != 0 &&
1100 (WindowText = RemovePropA(hWnd, WindowTextAtom)) == NULL)
1101 {
1102 User32FreeHeap(WindowText);
1103 }
1104 if (WindowTextAtom != 0)
1105 {
1106 GlobalDeleteAtom(WindowTextAtom);
1107 }
1108 /* FIXME: Destroy scroll bars here as well. */
1109 return(0);
1110 }
1111
1112 default:
1113 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, FALSE);
1114 break;
1115 }
1116
1117 return(Result);
1118 }
1119
1120 LRESULT STDCALL
1121 DefWindowProcW(HWND hWnd,
1122 UINT Msg,
1123 WPARAM wParam,
1124 LPARAM lParam)
1125 {
1126 LRESULT Result;
1127 static ATOM WindowTextAtom = 0;
1128 PWSTR WindowText;
1129
1130 switch (Msg)
1131 {
1132 case WM_NCCREATE:
1133 {
1134 CREATESTRUCTW* Cs = (CREATESTRUCTW*)lParam;
1135 if (HIWORD(Cs->lpszName))
1136 {
1137 WindowTextAtom = GlobalAddAtomW(L"USER32!WindowTextAtomW");
1138 WindowText = User32AllocHeap(wcslen(Cs->lpszName) * sizeof(WCHAR));
1139 wcscpy(WindowText, Cs->lpszName);
1140 SetPropW(hWnd, WindowTextAtom, WindowText);
1141 }
1142 return(1);
1143 }
1144
1145 case WM_NCCALCSIZE:
1146 {
1147 return(DefWndNCCalcSize(hWnd, (RECT*)lParam));
1148 }
1149
1150 case WM_WINDOWPOSCHANGING:
1151 {
1152 return(DefWndHandleWindowPosChanging(hWnd, (WINDOWPOS*)lParam));
1153 }
1154
1155 case WM_GETTEXTLENGTH:
1156 {
1157 if (WindowTextAtom == 0 ||
1158 (WindowText = GetPropW(hWnd, WindowTextAtom)) == NULL)
1159 {
1160 return(0);
1161 }
1162 return(wcslen(WindowText));
1163 }
1164
1165 case WM_GETTEXT:
1166 {
1167 if (WindowTextAtom == 0 ||
1168 (WindowText = GetPropW(hWnd, WindowTextAtom)) == NULL)
1169 {
1170 if (wParam > 1)
1171 {
1172 ((PWSTR)lParam) = '\0';
1173 }
1174 return(0);
1175 }
1176 wcsncpy((PWSTR)lParam, WindowText, wParam);
1177 return(min(wParam, wcslen(WindowText)));
1178 }
1179
1180 case WM_SETTEXT:
1181 {
1182 if (WindowTextAtom != 0)
1183 {
1184 WindowTextAtom = GlobalAddAtom(L"USER32!WindowTextAtomW");
1185 }
1186 if (WindowTextAtom != 0 &&
1187 (WindowText = GetPropW(hWnd, WindowTextAtom)) == NULL)
1188 {
1189 User32FreeHeap(WindowText);
1190 }
1191 WindowText = User32AllocHeap(wcslen((PWSTR)lParam) * sizeof(WCHAR));
1192 wcscpy(WindowText, (PWSTR)lParam);
1193 SetPropW(hWnd, WindowTextAtom, WindowText);
1194 }
1195
1196 case WM_NCDESTROY:
1197 {
1198 if (WindowTextAtom != 0 &&
1199 (WindowText = RemovePropW(hWnd, WindowTextAtom)) == NULL)
1200 {
1201 User32FreeHeap(WindowText);
1202 }
1203 if (WindowTextAtom != 0)
1204 {
1205 GlobalDeleteAtom(WindowTextAtom);
1206 }
1207 /* FIXME: Destroy scroll bars here as well. */
1208 return(0);
1209 }
1210
1211 default:
1212 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, TRUE);
1213 break;
1214 }
1215
1216 return(Result);
1217 }