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