[user32]
[reactos.git] / dll / win32 / user32 / windows / defwnd.c
1 /*
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS user32.dll
5 * FILE: dll/win32/user32/windows/defwnd.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 <user32.h>
15
16 #include <wine/debug.h>
17 WINE_DEFAULT_DEBUG_CHANNEL(user32);
18
19 LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active);
20 LRESULT DefWndNCCalcSize(HWND hWnd, BOOL CalcSizeStruct, RECT *Rect);
21 LRESULT DefWndNCActivate(HWND hWnd, WPARAM wParam);
22 LRESULT DefWndNCHitTest(HWND hWnd, POINT Point);
23 LRESULT DefWndNCLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam);
24 LRESULT DefWndNCLButtonDblClk(HWND hWnd, WPARAM wParam, LPARAM lParam);
25 void FASTCALL MenuInitSysMenuPopup(HMENU Menu, DWORD Style, DWORD ClsStyle, LONG HitTest );
26 void MENU_EndMenu( HWND );
27
28 /* GLOBALS *******************************************************************/
29
30 static short iF10Key = 0;
31 static short iMenuSysKey = 0;
32
33 /* FUNCTIONS *****************************************************************/
34
35 void
36 InitStockObjects(void)
37 {
38 /* FIXME - Instead of copying the stuff to usermode we should map the tables to
39 userland. The current implementation has one big flaw: the system color
40 table doesn't get updated when another process changes them. That's why
41 we should rather map the table into usermode. But it only affects the
42 SysColors table - the pens, brushes and stock objects are not affected
43 as their handles never change. But it'd be faster to map them, too. */
44
45 // Done! gpsi!
46 }
47
48 /*
49 * @implemented
50 */
51 DWORD WINAPI
52 GetSysColor(int nIndex)
53 {
54 if(nIndex >= 0 && nIndex < NUM_SYSCOLORS)
55 {
56 return gpsi->argbSystem[nIndex];
57 }
58
59 SetLastError(ERROR_INVALID_PARAMETER);
60 return 0;
61 }
62
63 /*
64 * @implemented
65 */
66 HBRUSH WINAPI
67 GetSysColorBrush(int nIndex)
68 {
69 if(nIndex >= 0 && nIndex < NUM_SYSCOLORS)
70 {
71 return gpsi->ahbrSystem[nIndex];
72 }
73
74 SetLastError(ERROR_INVALID_PARAMETER);
75 return NULL;
76 }
77
78 /*
79 * @implemented
80 */
81 BOOL
82 WINAPI
83 SetSysColors(
84 int cElements,
85 CONST INT *lpaElements,
86 CONST COLORREF *lpaRgbValues)
87 {
88 return NtUserSetSysColors(cElements, lpaElements, lpaRgbValues, 0);
89 }
90
91 BOOL
92 FASTCALL
93 DefSetText(HWND hWnd, PCWSTR String, BOOL Ansi)
94 {
95 BOOL Ret;
96 LARGE_STRING lsString;
97
98 if ( String )
99 {
100 if ( Ansi )
101 RtlInitLargeAnsiString((PLARGE_ANSI_STRING)&lsString, (PCSZ)String, 0);
102 else
103 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&lsString, String, 0);
104 }
105 Ret = NtUserDefSetText(hWnd, (String ? &lsString : NULL));
106
107 if (Ret)
108 IntNotifyWinEvent(EVENT_OBJECT_NAMECHANGE, hWnd, OBJID_WINDOW, CHILDID_SELF, 0);
109
110 return Ret;
111 }
112
113 void
114 UserGetInsideRectNC(PWND Wnd, RECT *rect)
115 {
116 ULONG Style;
117 ULONG ExStyle;
118
119 Style = Wnd->style;
120 ExStyle = Wnd->ExStyle;
121
122 rect->top = rect->left = 0;
123 rect->right = Wnd->rcWindow.right - Wnd->rcWindow.left;
124 rect->bottom = Wnd->rcWindow.bottom - Wnd->rcWindow.top;
125
126 if (Style & WS_ICONIC)
127 {
128 return;
129 }
130
131 /* Remove frame from rectangle */
132 if (UserHasThickFrameStyle(Style, ExStyle ))
133 {
134 InflateRect(rect, -GetSystemMetrics(SM_CXFRAME),
135 -GetSystemMetrics(SM_CYFRAME));
136 }
137 else
138 {
139 if (UserHasDlgFrameStyle(Style, ExStyle ))
140 {
141 InflateRect(rect, -GetSystemMetrics(SM_CXDLGFRAME),
142 -GetSystemMetrics(SM_CYDLGFRAME));
143 /* FIXME: this isn't in NC_AdjustRect? why not? */
144 if (ExStyle & WS_EX_DLGMODALFRAME)
145 InflateRect( rect, -1, 0 );
146 }
147 else
148 {
149 if (UserHasThinFrameStyle(Style, ExStyle))
150 {
151 InflateRect(rect, -GetSystemMetrics(SM_CXBORDER),
152 -GetSystemMetrics(SM_CYBORDER));
153 }
154 }
155 }
156 }
157
158
159 VOID
160 DefWndSetRedraw(HWND hWnd, WPARAM wParam)
161 {
162 LONG Style = GetWindowLongPtr(hWnd, GWL_STYLE);
163 /* Content can be redrawn after a change. */
164 if (wParam)
165 {
166 if (!(Style & WS_VISIBLE)) /* Not Visible */
167 {
168 SetWindowLongPtr(hWnd, GWL_STYLE, WS_VISIBLE);
169 }
170 }
171 else /* Content cannot be redrawn after a change. */
172 {
173 if (Style & WS_VISIBLE) /* Visible */
174 {
175 RedrawWindow( hWnd, NULL, 0, RDW_ALLCHILDREN | RDW_VALIDATE );
176 Style &= ~WS_VISIBLE;
177 SetWindowLongPtr(hWnd, GWL_STYLE, Style); /* clear bits */
178 }
179 }
180 return;
181 }
182
183
184 LRESULT
185 DefWndHandleSetCursor(HWND hWnd, WPARAM wParam, LPARAM lParam, ULONG Style)
186 {
187 /* Not for child windows. */
188 if (hWnd != (HWND)wParam)
189 {
190 return(0);
191 }
192
193 switch((INT_PTR) LOWORD(lParam))
194 {
195 case HTERROR:
196 {
197 WORD Msg = HIWORD(lParam);
198 if (Msg == WM_LBUTTONDOWN || Msg == WM_MBUTTONDOWN ||
199 Msg == WM_RBUTTONDOWN || Msg == WM_XBUTTONDOWN)
200 {
201 MessageBeep(0);
202 }
203 break;
204 }
205
206 case HTCLIENT:
207 {
208 HICON hCursor = (HICON)GetClassLongPtrW(hWnd, GCL_HCURSOR);
209 if (hCursor)
210 {
211 SetCursor(hCursor);
212 return(TRUE);
213 }
214 return(FALSE);
215 }
216
217 case HTLEFT:
218 case HTRIGHT:
219 {
220 if (Style & WS_MAXIMIZE)
221 {
222 break;
223 }
224 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZEWE)));
225 }
226
227 case HTTOP:
228 case HTBOTTOM:
229 {
230 if (Style & WS_MAXIMIZE)
231 {
232 break;
233 }
234 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENS)));
235 }
236
237 case HTTOPLEFT:
238 case HTBOTTOMRIGHT:
239 {
240 if (Style & WS_MAXIMIZE)
241 {
242 break;
243 }
244 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENWSE)));
245 }
246
247 case HTBOTTOMLEFT:
248 case HTTOPRIGHT:
249 {
250 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MAXIMIZE)
251 {
252 break;
253 }
254 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENESW)));
255 }
256 }
257 return((LRESULT)SetCursor(LoadCursorW(0, IDC_ARROW)));
258 }
259
260 static LONG
261 DefWndStartSizeMove(HWND hWnd, PWND Wnd, WPARAM wParam, POINT *capturePoint)
262 {
263 LONG hittest = 0;
264 POINT pt;
265 MSG msg;
266 RECT rectWindow;
267 ULONG Style = Wnd->style;
268
269 rectWindow = Wnd->rcWindow;
270
271 if ((wParam & 0xfff0) == SC_MOVE)
272 {
273 /* Move pointer at the center of the caption */
274 RECT rect;
275 UserGetInsideRectNC(Wnd, &rect);
276 if (Style & WS_SYSMENU)
277 rect.left += GetSystemMetrics(SM_CXSIZE) + 1;
278 if (Style & WS_MINIMIZEBOX)
279 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
280 if (Style & WS_MAXIMIZEBOX)
281 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
282 pt.x = rectWindow.left + (rect.right - rect.left) / 2;
283 pt.y = rectWindow.top + rect.top + GetSystemMetrics(SM_CYSIZE)/2;
284 hittest = HTCAPTION;
285 *capturePoint = pt;
286 }
287 else /* SC_SIZE */
288 {
289 pt.x = pt.y = 0;
290 while(!hittest)
291 {
292 if (!GetMessageW(&msg, NULL, 0, 0)) break; //return 0;
293 if (CallMsgFilterW( &msg, MSGF_SIZE )) continue;
294
295 switch(msg.message)
296 {
297 case WM_MOUSEMOVE:
298 hittest = DefWndNCHitTest(hWnd, msg.pt);
299 if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
300 hittest = 0;
301 break;
302
303 case WM_LBUTTONUP:
304 return 0;
305
306 case WM_KEYDOWN:
307 switch(msg.wParam)
308 {
309 case VK_UP:
310 hittest = HTTOP;
311 pt.x =(rectWindow.left+rectWindow.right)/2;
312 pt.y = rectWindow.top + GetSystemMetrics(SM_CYFRAME) / 2;
313 break;
314 case VK_DOWN:
315 hittest = HTBOTTOM;
316 pt.x =(rectWindow.left+rectWindow.right)/2;
317 pt.y = rectWindow.bottom - GetSystemMetrics(SM_CYFRAME) / 2;
318 break;
319 case VK_LEFT:
320 hittest = HTLEFT;
321 pt.x = rectWindow.left + GetSystemMetrics(SM_CXFRAME) / 2;
322 pt.y =(rectWindow.top+rectWindow.bottom)/2;
323 break;
324 case VK_RIGHT:
325 hittest = HTRIGHT;
326 pt.x = rectWindow.right - GetSystemMetrics(SM_CXFRAME) / 2;
327 pt.y =(rectWindow.top+rectWindow.bottom)/2;
328 break;
329 case VK_RETURN:
330 case VK_ESCAPE:
331 return 0;
332 }
333 default:
334 TranslateMessage( &msg );
335 DispatchMessageW( &msg );
336 break;
337 }
338 }
339 *capturePoint = pt;
340 }
341 SetCursorPos( pt.x, pt.y );
342 DefWndHandleSetCursor(hWnd, (WPARAM)hWnd, MAKELONG(hittest, WM_MOUSEMOVE), Style);
343 return hittest;
344 }
345
346 #define ON_LEFT_BORDER(hit) \
347 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
348 #define ON_RIGHT_BORDER(hit) \
349 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
350 #define ON_TOP_BORDER(hit) \
351 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
352 #define ON_BOTTOM_BORDER(hit) \
353 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
354
355 static VOID
356 UserDrawWindowFrame(HDC hdc, const RECT *rect,
357 ULONG width, ULONG height)
358 {
359 static HBRUSH hDraggingRectBrush = NULL;
360 HBRUSH hbrush;
361
362 if(!hDraggingRectBrush)
363 {
364 static HBITMAP hDraggingPattern = NULL;
365 const DWORD Pattern[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA};
366
367 hDraggingPattern = CreateBitmap(8, 8, 1, 1, Pattern);
368 hDraggingRectBrush = CreatePatternBrush(hDraggingPattern);
369 }
370
371 hbrush = SelectObject( hdc, hDraggingRectBrush );
372 PatBlt( hdc, rect->left, rect->top,
373 rect->right - rect->left - width, height, PATINVERT );
374 PatBlt( hdc, rect->left, rect->top + height, width,
375 rect->bottom - rect->top - height, PATINVERT );
376 PatBlt( hdc, rect->left + width, rect->bottom - 1,
377 rect->right - rect->left - width, -height, PATINVERT );
378 PatBlt( hdc, rect->right - 1, rect->top, -width,
379 rect->bottom - rect->top - height, PATINVERT );
380 SelectObject( hdc, hbrush );
381 }
382
383 static VOID
384 UserDrawMovingFrame(HDC hdc, RECT *rect, BOOL thickframe)
385 {
386 if(thickframe)
387 {
388 UserDrawWindowFrame(hdc, rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME));
389 }
390 else
391 {
392 UserDrawWindowFrame(hdc, rect, 1, 1);
393 }
394 }
395
396 static VOID
397 DefWndDoSizeMove(HWND hwnd, WORD wParam)
398 {
399 HRGN DesktopRgn;
400 MSG msg;
401 RECT sizingRect, mouseRect, origRect, clipRect, unmodRect;
402 HDC hdc;
403 LONG hittest = (LONG)(wParam & 0x0f);
404 HCURSOR hDragCursor = 0, hOldCursor = 0;
405 POINT minTrack, maxTrack;
406 POINT capturePoint, pt;
407 ULONG Style, ExStyle;
408 BOOL thickframe;
409 BOOL iconic;
410 BOOL moved = FALSE;
411 DWORD dwPoint = GetMessagePos();
412 BOOL DragFullWindows = FALSE;
413 HWND hWndParent = NULL;
414 PWND Wnd;
415
416 Wnd = ValidateHwnd(hwnd);
417 if (!Wnd)
418 return;
419
420 Style = Wnd->style;
421 ExStyle = Wnd->ExStyle;
422 iconic = (Style & WS_MINIMIZE) != 0;
423
424 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS, 0, &DragFullWindows, 0);
425
426 pt.x = GET_X_LPARAM(dwPoint);
427 pt.y = GET_Y_LPARAM(dwPoint);
428 capturePoint = pt;
429
430 if ((Style & WS_MAXIMIZE) || !IsWindowVisible(hwnd))
431 {
432 return;
433 }
434
435 thickframe = UserHasThickFrameStyle(Style, ExStyle) && !(Style & WS_MINIMIZE);
436 if ((wParam & 0xfff0) == SC_MOVE)
437 {
438 if (!hittest)
439 {
440 hittest = DefWndStartSizeMove(hwnd, Wnd, wParam, &capturePoint);
441 }
442 if (!hittest)
443 {
444 return;
445 }
446 }
447 else /* SC_SIZE */
448 {
449 if (!thickframe)
450 {
451 return;
452 }
453 if (hittest && ((wParam & 0xfff0) != SC_MOUSEMENU))
454 {
455 hittest += (HTLEFT - WMSZ_LEFT);
456 }
457 else
458 {
459 SetCapture(hwnd);
460 hittest = DefWndStartSizeMove(hwnd, Wnd, wParam, &capturePoint);
461 if (!hittest)
462 {
463 ReleaseCapture();
464 return;
465 }
466 }
467 }
468
469 /* Get min/max info */
470
471 WinPosGetMinMaxInfo(hwnd, NULL, NULL, &minTrack, &maxTrack);
472 sizingRect = Wnd->rcWindow;
473 if (Style & WS_CHILD)
474 {
475 hWndParent = GetParent(hwnd);
476 MapWindowPoints( 0, hWndParent, (LPPOINT)&sizingRect, 2 );
477 unmodRect = sizingRect;
478 GetClientRect(hWndParent, &mouseRect );
479 clipRect = mouseRect;
480 MapWindowPoints(hWndParent, HWND_DESKTOP, (LPPOINT)&clipRect, 2);
481 }
482 else
483 {
484 if(!(ExStyle & WS_EX_TOPMOST))
485 {
486 SystemParametersInfoW(SPI_GETWORKAREA, 0, &clipRect, 0);
487 mouseRect = clipRect;
488 }
489 else
490 {
491 SetRect(&mouseRect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
492 clipRect = mouseRect;
493 }
494 unmodRect = sizingRect;
495 }
496 ClipCursor(&clipRect);
497
498 origRect = sizingRect;
499 if (ON_LEFT_BORDER(hittest))
500 {
501 mouseRect.left = max( mouseRect.left, sizingRect.right-maxTrack.x );
502 mouseRect.right = min( mouseRect.right, sizingRect.right-minTrack.x );
503 }
504 else if (ON_RIGHT_BORDER(hittest))
505 {
506 mouseRect.left = max( mouseRect.left, sizingRect.left+minTrack.x );
507 mouseRect.right = min( mouseRect.right, sizingRect.left+maxTrack.x );
508 }
509 if (ON_TOP_BORDER(hittest))
510 {
511 mouseRect.top = max( mouseRect.top, sizingRect.bottom-maxTrack.y );
512 mouseRect.bottom = min( mouseRect.bottom,sizingRect.bottom-minTrack.y);
513 }
514 else if (ON_BOTTOM_BORDER(hittest))
515 {
516 mouseRect.top = max( mouseRect.top, sizingRect.top+minTrack.y );
517 mouseRect.bottom = min( mouseRect.bottom, sizingRect.top+maxTrack.y );
518 }
519 if (Style & WS_CHILD)
520 {
521 MapWindowPoints( hWndParent, 0, (LPPOINT)&mouseRect, 2 );
522 }
523
524 SendMessageA( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
525 (void)NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE, hwnd);
526 if (GetCapture() != hwnd) SetCapture( hwnd );
527
528 if (Style & WS_CHILD)
529 {
530 /* Retrieve a default cache DC (without using the window style) */
531 hdc = GetDCEx(hWndParent, 0, DCX_CACHE);
532 DesktopRgn = NULL;
533 }
534 else
535 {
536 hdc = GetDC( 0 );
537 DesktopRgn = CreateRectRgnIndirect(&clipRect);
538 }
539
540 SelectObject(hdc, DesktopRgn);
541
542 if( iconic ) /* create a cursor for dragging */
543 {
544 HICON hIcon = (HICON)GetClassLongPtrW(hwnd, GCL_HICON);
545 if(!hIcon) hIcon = (HICON)SendMessageW( hwnd, WM_QUERYDRAGICON, 0, 0L);
546 if( hIcon ) hDragCursor = CursorIconToCursor( hIcon, TRUE );
547 if( !hDragCursor ) iconic = FALSE;
548 }
549
550 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
551 if( !iconic && !DragFullWindows)
552 {
553 UserDrawMovingFrame( hdc, &sizingRect, thickframe);
554 }
555
556 for(;;)
557 {
558 int dx = 0, dy = 0;
559
560 if (!GetMessageW(&msg, 0, 0, 0)) break;
561 if (CallMsgFilterW( &msg, MSGF_SIZE )) continue;
562
563 /* Exit on button-up, Return, or Esc */
564 if ((msg.message == WM_LBUTTONUP) ||
565 ((msg.message == WM_KEYDOWN) &&
566 ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
567
568 if (msg.message == WM_PAINT)
569 {
570 if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
571 UpdateWindow( msg.hwnd );
572 if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
573 continue;
574 }
575
576 if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
577 {
578 TranslateMessage( &msg );
579 DispatchMessageW( &msg );
580 continue; /* We are not interested in other messages */
581 }
582
583 pt = msg.pt;
584
585 if (msg.message == WM_KEYDOWN) switch(msg.wParam)
586 {
587 case VK_UP: pt.y -= 8; break;
588 case VK_DOWN: pt.y += 8; break;
589 case VK_LEFT: pt.x -= 8; break;
590 case VK_RIGHT: pt.x += 8; break;
591 }
592
593 pt.x = max( pt.x, mouseRect.left );
594 pt.x = min( pt.x, mouseRect.right );
595 pt.y = max( pt.y, mouseRect.top );
596 pt.y = min( pt.y, mouseRect.bottom );
597
598 dx = pt.x - capturePoint.x;
599 dy = pt.y - capturePoint.y;
600
601 if (dx || dy)
602 {
603 if( !moved )
604 {
605 moved = TRUE;
606
607 if( iconic ) /* ok, no system popup tracking */
608 {
609 hOldCursor = SetCursor(hDragCursor);
610 ShowCursor( TRUE );
611 }
612 }
613
614 if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
615 else
616 {
617 RECT newRect = unmodRect;
618 WPARAM wpSizingHit = 0;
619
620 if (hittest == HTCAPTION) OffsetRect( &newRect, dx, dy );
621 if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
622 else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
623 if (ON_TOP_BORDER(hittest)) newRect.top += dy;
624 else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
625 if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
626 capturePoint = pt;
627
628 /* determine the hit location */
629 if (hittest >= HTLEFT && hittest <= HTBOTTOMRIGHT)
630 wpSizingHit = WMSZ_LEFT + (hittest - HTLEFT);
631 unmodRect = newRect;
632 SendMessageA( hwnd, WM_SIZING, wpSizingHit, (LPARAM)&newRect );
633
634 if (!iconic)
635 {
636 if(!DragFullWindows)
637 UserDrawMovingFrame( hdc, &newRect, thickframe );
638 else {
639 /* To avoid any deadlocks, all the locks on the windows
640 structures must be suspended before the SetWindowPos */
641 SetWindowPos( hwnd, 0, newRect.left, newRect.top,
642 newRect.right - newRect.left,
643 newRect.bottom - newRect.top,
644 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
645 }
646 }
647 sizingRect = newRect;
648 }
649 }
650 }
651
652 ReleaseCapture();
653 ClipCursor(NULL);
654 if( iconic )
655 {
656 if( moved ) /* restore cursors, show icon title later on */
657 {
658 ShowCursor( FALSE );
659 SetCursor( hOldCursor );
660 }
661 DestroyCursor( hDragCursor );
662 }
663 else if(!DragFullWindows)
664 UserDrawMovingFrame( hdc, &sizingRect, thickframe );
665
666 if (Style & WS_CHILD)
667 ReleaseDC( hWndParent, hdc );
668 else
669 {
670 ReleaseDC( 0, hdc );
671 if(DesktopRgn)
672 {
673 DeleteObject(DesktopRgn);
674 }
675 }
676
677 if (ISITHOOKED(WH_CBT))
678 {
679 LRESULT lResult;
680 NtUserMessageCall( hwnd, WM_CBT, HCBT_MOVESIZE, (LPARAM)&sizingRect, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE);
681 if (lResult) moved = FALSE;
682 }
683
684 (void)NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE, NULL);
685 SendMessageA( hwnd, WM_EXITSIZEMOVE, 0, 0 );
686 SendMessageA( hwnd, WM_SETVISIBLE, !IsIconic(hwnd), 0L);
687
688 /* window moved or resized */
689 if (moved)
690 {
691 /* if the moving/resizing isn't canceled call SetWindowPos
692 * with the new position or the new size of the window
693 */
694 if (!((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
695 {
696 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
697 if(!DragFullWindows)
698 SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top,
699 sizingRect.right - sizingRect.left,
700 sizingRect.bottom - sizingRect.top,
701 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
702 }
703 else { /* restore previous size/position */
704 if(DragFullWindows)
705 SetWindowPos( hwnd, 0, origRect.left, origRect.top,
706 origRect.right - origRect.left,
707 origRect.bottom - origRect.top,
708 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
709 }
710 }
711
712 if( IsWindow(hwnd) )
713 if( Style & WS_MINIMIZE )
714 {
715 /* Single click brings up the system menu when iconized */
716
717 if( !moved )
718 {
719 if( Style & WS_SYSMENU )
720 SendMessageA( hwnd, WM_SYSCOMMAND,
721 SC_MOUSEMENU + HTSYSMENU, MAKELONG(pt.x,pt.y));
722 }
723 }
724 }
725
726
727 /***********************************************************************
728 * DefWndTrackScrollBar
729 *
730 * Track a mouse button press on the horizontal or vertical scroll-bar.
731 */
732 static VOID
733 DefWndTrackScrollBar(HWND Wnd, WPARAM wParam, POINT Pt)
734 {
735 INT ScrollBar;
736
737 if (SC_HSCROLL == (wParam & 0xfff0))
738 {
739 if (HTHSCROLL != (wParam & 0x0f))
740 {
741 return;
742 }
743 ScrollBar = SB_HORZ;
744 }
745 else /* SC_VSCROLL */
746 {
747 if (HTVSCROLL != (wParam & 0x0f))
748 {
749 return;
750 }
751 ScrollBar = SB_VERT;
752 }
753 ScrollTrackScrollBar(Wnd, ScrollBar, Pt );
754 }
755
756 LRESULT WINAPI DoAppSwitch( WPARAM wParam, LPARAM lParam);
757
758 LRESULT
759 DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
760 {
761 WINDOWPLACEMENT wp;
762 POINT Pt;
763 LRESULT lResult;
764
765 if (!IsWindowEnabled( hWnd )) return 0;
766
767 if (ISITHOOKED(WH_CBT))
768 {
769 NtUserMessageCall( hWnd, WM_SYSCOMMAND, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE);
770 if (lResult) return 0;
771 }
772
773 switch (wParam & 0xfff0)
774 {
775 case SC_MOVE:
776 case SC_SIZE:
777 DefWndDoSizeMove(hWnd, wParam);
778 break;
779 case SC_MINIMIZE:
780 wp.length = sizeof(WINDOWPLACEMENT);
781 if(GetWindowPlacement(hWnd, &wp))
782 {
783 wp.showCmd = SW_MINIMIZE;
784 SetWindowPlacement(hWnd, &wp);
785 }
786 break;
787 case SC_MAXIMIZE:
788 wp.length = sizeof(WINDOWPLACEMENT);
789 if(GetWindowPlacement(hWnd, &wp))
790 {
791 wp.showCmd = SW_MAXIMIZE;
792 SetWindowPlacement(hWnd, &wp);
793 }
794 break;
795 case SC_RESTORE:
796 wp.length = sizeof(WINDOWPLACEMENT);
797 if(GetWindowPlacement(hWnd, &wp))
798 {
799 wp.showCmd = SW_RESTORE;
800 SetWindowPlacement(hWnd, &wp);
801 }
802 break;
803 case SC_CLOSE:
804 return SendMessageW(hWnd, WM_CLOSE, 0, 0);
805 // case SC_DEFAULT:
806 case SC_MOUSEMENU:
807 {
808 Pt.x = (short)LOWORD(lParam);
809 Pt.y = (short)HIWORD(lParam);
810 MenuTrackMouseMenuBar(hWnd, wParam & 0x000f, Pt);
811 }
812 break;
813 case SC_KEYMENU:
814 MenuTrackKbdMenuBar(hWnd, wParam, (WCHAR)lParam);
815 break;
816 case SC_VSCROLL:
817 case SC_HSCROLL:
818 {
819 Pt.x = (short)LOWORD(lParam);
820 Pt.y = (short)HIWORD(lParam);
821 DefWndTrackScrollBar(hWnd, wParam, Pt);
822 }
823 break;
824
825 case SC_SCREENSAVE:
826 NtUserMessageCall( hWnd, WM_SYSCOMMAND, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE);
827 break;
828
829 case SC_NEXTWINDOW:
830 case SC_PREVWINDOW:
831 DoAppSwitch( wParam, lParam);
832 break;
833
834 case SC_HOTKEY:
835 {
836 HWND hwnd, hWndLastActive;
837 PWND pWnd;
838
839 hwnd = (HWND)lParam;
840 pWnd = ValidateHwnd(hwnd);
841 if (pWnd)
842 {
843 hWndLastActive = GetLastActivePopup(hwnd);
844 if (hWndLastActive)
845 {
846 hwnd = hWndLastActive;
847 pWnd = ValidateHwnd(hwnd);
848 }
849 SetForegroundWindow(hwnd);
850 if (pWnd->style & WS_MINIMIZE)
851 {
852 PostMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0);
853 }
854 }
855 }
856 break;
857
858 default:
859 FIXME("Unimplemented DefWndHandleSysCommand wParam 0x%x\n",wParam);
860 break;
861 }
862
863 return(0);
864 }
865
866 LRESULT
867 DefWndHandleWindowPosChanging(HWND hWnd, WINDOWPOS* Pos)
868 {
869 POINT maxTrack, minTrack;
870 LONG style = GetWindowLongPtrA(hWnd, GWL_STYLE);
871
872 if (Pos->flags & SWP_NOSIZE) return 0;
873 if ((style & WS_THICKFRAME) || ((style & (WS_POPUP | WS_CHILD)) == 0))
874 {
875 WinPosGetMinMaxInfo(hWnd, NULL, NULL, &minTrack, &maxTrack);
876 Pos->cx = min(Pos->cx, maxTrack.x);
877 Pos->cy = min(Pos->cy, maxTrack.y);
878 if (!(style & WS_MINIMIZE))
879 {
880 if (Pos->cx < minTrack.x) Pos->cx = minTrack.x;
881 if (Pos->cy < minTrack.y) Pos->cy = minTrack.y;
882 }
883 }
884 else
885 {
886 Pos->cx = max(Pos->cx, 0);
887 Pos->cy = max(Pos->cy, 0);
888 }
889 return 0;
890 }
891
892 LRESULT
893 DefWndHandleWindowPosChanged(HWND hWnd, WINDOWPOS* Pos)
894 {
895 RECT Rect;
896
897 GetClientRect(hWnd, &Rect);
898 MapWindowPoints(hWnd, (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD ?
899 GetParent(hWnd) : NULL), (LPPOINT) &Rect, 2);
900
901 if (! (Pos->flags & SWP_NOCLIENTMOVE))
902 {
903 SendMessageW(hWnd, WM_MOVE, 0, MAKELONG(Rect.left, Rect.top));
904 }
905
906 if (! (Pos->flags & SWP_NOCLIENTSIZE))
907 {
908 WPARAM wp = SIZE_RESTORED;
909 if (IsZoomed(hWnd))
910 {
911 wp = SIZE_MAXIMIZED;
912 }
913 else if (IsIconic(hWnd))
914 {
915 wp = SIZE_MINIMIZED;
916 }
917 SendMessageW(hWnd, WM_SIZE, wp,
918 MAKELONG(Rect.right - Rect.left, Rect.bottom - Rect.top));
919 }
920
921 return 0;
922 }
923
924 /***********************************************************************
925 * DefWndControlColor
926 *
927 * Default colors for control painting.
928 */
929 HBRUSH
930 DefWndControlColor(HDC hDC, UINT ctlType)
931 {
932 if (ctlType == CTLCOLOR_SCROLLBAR)
933 {
934 HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR);
935 COLORREF bk = GetSysColor(COLOR_3DHILIGHT);
936 SetTextColor(hDC, GetSysColor(COLOR_3DFACE));
937 SetBkColor(hDC, bk);
938
939 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
940 * we better use 0x55aa bitmap brush to make scrollbar's background
941 * look different from the window background.
942 */
943 if ( bk == GetSysColor(COLOR_WINDOW))
944 return gpsi->hbrGray;
945
946 UnrealizeObject( hb );
947 return hb;
948 }
949
950 SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
951
952 if ((ctlType == CTLCOLOR_EDIT) || (ctlType == CTLCOLOR_LISTBOX))
953 {
954 SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
955 }
956 else
957 {
958 SetBkColor(hDC, GetSysColor(COLOR_3DFACE));
959 return GetSysColorBrush(COLOR_3DFACE);
960 }
961
962 return GetSysColorBrush(COLOR_WINDOW);
963 }
964
965 static void DefWndPrint( HWND hwnd, HDC hdc, ULONG uFlags)
966 {
967 /*
968 * Visibility flag.
969 */
970 if ( (uFlags & PRF_CHECKVISIBLE) &&
971 !IsWindowVisible(hwnd) )
972 return;
973
974 /*
975 * Unimplemented flags.
976 */
977 if ( (uFlags & PRF_CHILDREN) ||
978 (uFlags & PRF_OWNED) ||
979 (uFlags & PRF_NONCLIENT) )
980 {
981 FIXME("WM_PRINT message with unsupported flags\n");
982 }
983
984 /*
985 * Background
986 */
987 if ( uFlags & PRF_ERASEBKGND)
988 SendMessageW(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0);
989
990 /*
991 * Client area
992 */
993 if ( uFlags & PRF_CLIENT)
994 SendMessageW(hwnd, WM_PRINTCLIENT, (WPARAM)hdc, uFlags);
995 }
996
997 static BOOL CALLBACK
998 UserSendUiUpdateMsg(HWND hwnd, LPARAM lParam)
999 {
1000 SendMessageW(hwnd, WM_UPDATEUISTATE, (WPARAM)lParam, 0);
1001 return TRUE;
1002 }
1003
1004
1005 VOID FASTCALL
1006 DefWndScreenshot(HWND hWnd)
1007 {
1008 RECT rect;
1009 HDC hdc;
1010 INT w;
1011 INT h;
1012 HBITMAP hbitmap;
1013 HDC hdc2;
1014
1015 OpenClipboard(hWnd);
1016 EmptyClipboard();
1017
1018 hdc = GetWindowDC(hWnd);
1019 GetWindowRect(hWnd, &rect);
1020 w = rect.right - rect.left;
1021 h = rect.bottom - rect.top;
1022
1023 hbitmap = CreateCompatibleBitmap(hdc, w, h);
1024 hdc2 = CreateCompatibleDC(hdc);
1025 SelectObject(hdc2, hbitmap);
1026
1027 BitBlt(hdc2, 0, 0, w, h,
1028 hdc, 0, 0,
1029 SRCCOPY);
1030
1031 SetClipboardData(CF_BITMAP, hbitmap);
1032
1033 ReleaseDC(hWnd, hdc);
1034 ReleaseDC(hWnd, hdc2);
1035
1036 CloseClipboard();
1037
1038 }
1039
1040
1041
1042 LRESULT WINAPI
1043 User32DefWindowProc(HWND hWnd,
1044 UINT Msg,
1045 WPARAM wParam,
1046 LPARAM lParam,
1047 BOOL bUnicode)
1048 {
1049 switch (Msg)
1050 {
1051 case WM_NCPAINT:
1052 {
1053 return DefWndNCPaint(hWnd, (HRGN)wParam, -1);
1054 }
1055
1056 case WM_NCCALCSIZE:
1057 {
1058 return DefWndNCCalcSize(hWnd, (BOOL)wParam, (RECT*)lParam);
1059 }
1060
1061 case WM_POPUPSYSTEMMENU:
1062 {
1063 /* This is an undocumented message used by the windows taskbar to
1064 display the system menu of windows that belong to other processes. */
1065 HMENU menu = GetSystemMenu(hWnd, FALSE);
1066
1067 if (menu)
1068 TrackPopupMenu(menu, TPM_LEFTBUTTON|TPM_RIGHTBUTTON,
1069 LOWORD(lParam), HIWORD(lParam), 0, hWnd, NULL);
1070 return 0;
1071 }
1072
1073 case WM_NCACTIVATE:
1074 {
1075 return DefWndNCActivate(hWnd, wParam);
1076 }
1077
1078 case WM_NCHITTEST:
1079 {
1080 POINT Point;
1081 Point.x = GET_X_LPARAM(lParam);
1082 Point.y = GET_Y_LPARAM(lParam);
1083 return (DefWndNCHitTest(hWnd, Point));
1084 }
1085
1086 case WM_LBUTTONDOWN:
1087 case WM_RBUTTONDOWN:
1088 case WM_MBUTTONDOWN:
1089 iF10Key = iMenuSysKey = 0;
1090 break;
1091
1092 case WM_NCLBUTTONDOWN:
1093 {
1094 return (DefWndNCLButtonDown(hWnd, wParam, lParam));
1095 }
1096
1097 case WM_LBUTTONDBLCLK:
1098 return (DefWndNCLButtonDblClk(hWnd, HTCLIENT, lParam));
1099
1100 case WM_NCLBUTTONDBLCLK:
1101 {
1102 return (DefWndNCLButtonDblClk(hWnd, wParam, lParam));
1103 }
1104
1105 case WM_WINDOWPOSCHANGING:
1106 {
1107 return (DefWndHandleWindowPosChanging(hWnd, (WINDOWPOS*)lParam));
1108 }
1109
1110 case WM_WINDOWPOSCHANGED:
1111 {
1112 return (DefWndHandleWindowPosChanged(hWnd, (WINDOWPOS*)lParam));
1113 }
1114
1115 case WM_NCRBUTTONDOWN:
1116 {
1117 /* in Windows, capture is taken when right-clicking on the caption bar */
1118 if (wParam == HTCAPTION)
1119 {
1120 SetCapture(hWnd);
1121 }
1122 break;
1123 }
1124
1125 case WM_RBUTTONUP:
1126 {
1127 POINT Pt;
1128 if (hWnd == GetCapture())
1129 {
1130 ReleaseCapture();
1131 }
1132 Pt.x = GET_X_LPARAM(lParam);
1133 Pt.y = GET_Y_LPARAM(lParam);
1134 ClientToScreen(hWnd, &Pt);
1135 lParam = MAKELPARAM(Pt.x, Pt.y);
1136 if (bUnicode)
1137 {
1138 SendMessageW(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
1139 }
1140 else
1141 {
1142 SendMessageA(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
1143 }
1144 break;
1145 }
1146
1147 case WM_NCRBUTTONUP:
1148 /*
1149 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
1150 * in Windows), but what _should_ we do? According to MSDN :
1151 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
1152 * message to the window". When is it appropriate?
1153 */
1154 break;
1155
1156 case WM_CONTEXTMENU:
1157 {
1158 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD)
1159 {
1160 if (bUnicode)
1161 {
1162 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
1163 }
1164 else
1165 {
1166 SendMessageA(GetParent(hWnd), WM_CONTEXTMENU, wParam, lParam);
1167 }
1168 }
1169 else
1170 {
1171 POINT Pt;
1172 LONG_PTR Style;
1173 LONG HitCode;
1174
1175 Style = GetWindowLongPtrW(hWnd, GWL_STYLE);
1176
1177 Pt.x = GET_X_LPARAM(lParam);
1178 Pt.y = GET_Y_LPARAM(lParam);
1179 if (Style & WS_CHILD)
1180 {
1181 ScreenToClient(GetParent(hWnd), &Pt);
1182 }
1183
1184 HitCode = DefWndNCHitTest(hWnd, Pt);
1185
1186 if (HitCode == HTCAPTION || HitCode == HTSYSMENU)
1187 {
1188 HMENU SystemMenu;
1189 UINT Flags;
1190
1191 if((SystemMenu = GetSystemMenu(hWnd, FALSE)))
1192 {
1193 MenuInitSysMenuPopup(SystemMenu, GetWindowLongPtrW(hWnd, GWL_STYLE),
1194 GetClassLongPtrW(hWnd, GCL_STYLE), HitCode);
1195
1196 if(HitCode == HTCAPTION)
1197 Flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON;
1198 else
1199 Flags = TPM_LEFTBUTTON;
1200
1201 TrackPopupMenu(SystemMenu, Flags,
1202 Pt.x, Pt.y, 0, hWnd, NULL);
1203 }
1204 }
1205 }
1206 break;
1207 }
1208
1209 case WM_PRINT:
1210 {
1211 DefWndPrint(hWnd, (HDC)wParam, lParam);
1212 return (0);
1213 }
1214
1215 case WM_SYSCOLORCHANGE:
1216 {
1217 /* force to redraw non-client area */
1218 DefWndNCPaint(hWnd, HRGN_WINDOW, -1);
1219 /* Use InvalidateRect to redraw client area, enable
1220 * erase to redraw all subcontrols otherwise send the
1221 * WM_SYSCOLORCHANGE to child windows/controls is required
1222 */
1223 InvalidateRect(hWnd,NULL,TRUE);
1224 return (0);
1225 }
1226
1227 case WM_PAINTICON:
1228 case WM_PAINT:
1229 {
1230 PAINTSTRUCT Ps;
1231 HDC hDC = BeginPaint(hWnd, &Ps);
1232 if (hDC)
1233 {
1234 HICON hIcon;
1235
1236 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MINIMIZE &&
1237 (hIcon = (HICON)GetClassLongPtrW(hWnd, GCL_HICON)) != NULL)
1238 {
1239 RECT ClientRect;
1240 INT x, y;
1241 GetClientRect(hWnd, &ClientRect);
1242 x = (ClientRect.right - ClientRect.left -
1243 GetSystemMetrics(SM_CXICON)) / 2;
1244 y = (ClientRect.bottom - ClientRect.top -
1245 GetSystemMetrics(SM_CYICON)) / 2;
1246 DrawIcon(hDC, x, y, hIcon);
1247 }
1248 EndPaint(hWnd, &Ps);
1249 }
1250 return (0);
1251 }
1252
1253 case WM_SYNCPAINT:
1254 {
1255 HRGN hRgn;
1256 hRgn = CreateRectRgn(0, 0, 0, 0);
1257 if (GetUpdateRgn(hWnd, hRgn, FALSE) != NULLREGION)
1258 {
1259 RedrawWindow(hWnd, NULL, hRgn,
1260 RDW_ERASENOW | RDW_ERASE | RDW_FRAME |
1261 RDW_ALLCHILDREN);
1262 }
1263 DeleteObject(hRgn);
1264 return (0);
1265 }
1266
1267 case WM_SETREDRAW:
1268 {
1269 LONG_PTR Style = GetWindowLongPtrW(hWnd, GWL_STYLE);
1270 if (wParam) SetWindowLongPtr(hWnd, GWL_STYLE, Style | WS_VISIBLE);
1271 else
1272 {
1273 RedrawWindow(hWnd, NULL, 0, RDW_ALLCHILDREN | RDW_VALIDATE);
1274 Style &= ~WS_VISIBLE;
1275 SetWindowLongPtr(hWnd, GWL_STYLE, Style);
1276 }
1277 return (0);
1278 }
1279
1280 case WM_CLOSE:
1281 {
1282 DestroyWindow(hWnd);
1283 return (0);
1284 }
1285
1286 case WM_MOUSEACTIVATE:
1287 {
1288 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD)
1289 {
1290 LONG Ret;
1291 if (bUnicode)
1292 {
1293 Ret = SendMessageW(GetParent(hWnd), WM_MOUSEACTIVATE,
1294 wParam, lParam);
1295 }
1296 else
1297 {
1298 Ret = SendMessageA(GetParent(hWnd), WM_MOUSEACTIVATE,
1299 wParam, lParam);
1300 }
1301 if (Ret)
1302 {
1303 return (Ret);
1304 }
1305 }
1306 return ((LOWORD(lParam) >= HTCLIENT) ? MA_ACTIVATE : MA_NOACTIVATE);
1307 }
1308
1309 case WM_ACTIVATE:
1310 {
1311 /* Check if the window is minimized. */
1312 if (LOWORD(wParam) != WA_INACTIVE &&
1313 !(GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MINIMIZE))
1314 {
1315 SetFocus(hWnd);
1316 }
1317 break;
1318 }
1319
1320 case WM_MOUSEWHEEL:
1321 {
1322 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD)
1323 {
1324 if (bUnicode)
1325 {
1326 return (SendMessageW(GetParent(hWnd), WM_MOUSEWHEEL,
1327 wParam, lParam));
1328 }
1329 else
1330 {
1331 return (SendMessageA(GetParent(hWnd), WM_MOUSEWHEEL,
1332 wParam, lParam));
1333 }
1334 }
1335 break;
1336 }
1337
1338 case WM_ERASEBKGND:
1339 case WM_ICONERASEBKGND:
1340 {
1341 RECT Rect;
1342 HBRUSH hBrush = (HBRUSH)GetClassLongPtrW(hWnd, GCL_HBRBACKGROUND);
1343
1344 if (NULL == hBrush)
1345 {
1346 return 0;
1347 }
1348 if (GetClassLongPtrW(hWnd, GCL_STYLE) & CS_PARENTDC)
1349 {
1350 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1351 GetClientRect(hWnd, &Rect);
1352 DPtoLP((HDC)wParam, (LPPOINT)&Rect, 2);
1353 }
1354 else
1355 {
1356 GetClipBox((HDC)wParam, &Rect);
1357 }
1358 FillRect((HDC)wParam, &Rect, hBrush);
1359 return (1);
1360 }
1361
1362 case WM_CTLCOLORMSGBOX:
1363 case WM_CTLCOLOREDIT:
1364 case WM_CTLCOLORLISTBOX:
1365 case WM_CTLCOLORBTN:
1366 case WM_CTLCOLORDLG:
1367 case WM_CTLCOLORSTATIC:
1368 case WM_CTLCOLORSCROLLBAR:
1369 return (LRESULT) DefWndControlColor((HDC)wParam, Msg - WM_CTLCOLORMSGBOX);
1370
1371 case WM_CTLCOLOR:
1372 return (LRESULT) DefWndControlColor((HDC)wParam, HIWORD(lParam));
1373
1374 case WM_SETCURSOR:
1375 {
1376 LONG_PTR Style = GetWindowLongPtrW(hWnd, GWL_STYLE);
1377
1378 if (Style & WS_CHILD)
1379 {
1380 /* with the exception of the border around a resizable wnd,
1381 * give the parent first chance to set the cursor */
1382 if (LOWORD(lParam) < HTLEFT || LOWORD(lParam) > HTBOTTOMRIGHT)
1383 {
1384 HWND parent = GetParent( hWnd );
1385 if (bUnicode)
1386 {
1387 if (parent != GetDesktopWindow() &&
1388 SendMessageW( parent, WM_SETCURSOR, wParam, lParam))
1389 return TRUE;
1390 }
1391 else
1392 {
1393 if (parent != GetDesktopWindow() &&
1394 SendMessageA( parent, WM_SETCURSOR, wParam, lParam))
1395 return TRUE;
1396 }
1397 }
1398 }
1399 return (DefWndHandleSetCursor(hWnd, wParam, lParam, Style));
1400 }
1401
1402 case WM_SYSCOMMAND:
1403 return (DefWndHandleSysCommand(hWnd, wParam, lParam));
1404
1405 case WM_KEYDOWN:
1406 if(wParam == VK_F10) iF10Key = VK_F10;
1407 break;
1408
1409 case WM_SYSKEYDOWN:
1410 {
1411 if (HIWORD(lParam) & KF_ALTDOWN)
1412 { /* Previous state, if the key was down before this message,
1413 this is a cheap way to ignore autorepeat keys. */
1414 if ( !(HIWORD(lParam) & KF_REPEAT) )
1415 {
1416 if ( ( wParam == VK_MENU ||
1417 wParam == VK_LMENU ||
1418 wParam == VK_RMENU ) && !iMenuSysKey )
1419 iMenuSysKey = 1;
1420 else
1421 iMenuSysKey = 0;
1422 }
1423
1424 iF10Key = 0;
1425
1426 if (wParam == VK_F4) /* Try to close the window */
1427 {
1428 HWND top = GetAncestor(hWnd, GA_ROOT);
1429 if (!(GetClassLongPtrW(top, GCL_STYLE) & CS_NOCLOSE))
1430 PostMessageW(top, WM_SYSCOMMAND, SC_CLOSE, 0);
1431 }
1432 else if (wParam == VK_SNAPSHOT) // Alt-VK_SNAPSHOT?
1433 {
1434 HWND hwnd = hWnd;
1435 while (GetParent(hwnd) != NULL)
1436 {
1437 hwnd = GetParent(hwnd);
1438 }
1439 DefWndScreenshot(hwnd);
1440 }
1441 else if ( wParam == VK_ESCAPE || wParam == VK_TAB ) // Alt-Tab/ESC Alt-Shift-Tab/ESC
1442 {
1443 WPARAM wParamTmp;
1444 HWND Active = GetActiveWindow(); // Noticed MDI problem.
1445 if (!Active)
1446 {
1447 FIXME("WM_SYSKEYDOWN VK_ESCAPE no active\n");
1448 break;
1449 }
1450 wParamTmp = GetKeyState(VK_SHIFT) & 0x8000 ? SC_PREVWINDOW : SC_NEXTWINDOW;
1451 SendMessageW( Active, WM_SYSCOMMAND, wParamTmp, wParam );
1452 }
1453 }
1454 else if( wParam == VK_F10 )
1455 {
1456 if (GetKeyState(VK_SHIFT) & 0x8000)
1457 SendMessageW( hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, MAKELPARAM(-1, -1) );
1458 iF10Key = 1;
1459 }
1460 break;
1461 }
1462
1463 case WM_KEYUP:
1464 case WM_SYSKEYUP:
1465 {
1466 /* Press and release F10 or ALT */
1467 if (((wParam == VK_MENU || wParam == VK_LMENU || wParam == VK_RMENU)
1468 && iMenuSysKey) || ((wParam == VK_F10) && iF10Key))
1469 SendMessageW( GetAncestor( hWnd, GA_ROOT ), WM_SYSCOMMAND, SC_KEYMENU, 0L );
1470 iMenuSysKey = iF10Key = 0;
1471 break;
1472 }
1473
1474 case WM_SYSCHAR:
1475 {
1476 iMenuSysKey = 0;
1477 if (wParam == VK_RETURN && IsIconic(hWnd))
1478 {
1479 PostMessageW( hWnd, WM_SYSCOMMAND, SC_RESTORE, 0L );
1480 break;
1481 }
1482 if ((HIWORD(lParam) & KF_ALTDOWN) && wParam)
1483 {
1484 if (wParam == VK_TAB || wParam == VK_ESCAPE) break;
1485 if (wParam == VK_SPACE && (GetWindowLongPtrW( hWnd, GWL_STYLE ) & WS_CHILD))
1486 SendMessageW( GetParent(hWnd), Msg, wParam, lParam );
1487 else
1488 SendMessageW( hWnd, WM_SYSCOMMAND, SC_KEYMENU, wParam );
1489 }
1490 else /* check for Ctrl-Esc */
1491 if (wParam != VK_ESCAPE) MessageBeep(0);
1492 break;
1493 }
1494
1495 case WM_CANCELMODE:
1496 {
1497 iMenuSysKey = 0;
1498 /* FIXME: Check for a desktop. */
1499 //if (!(GetWindowLongPtrW( hWnd, GWL_STYLE ) & WS_CHILD)) EndMenu();
1500 MENU_EndMenu( hWnd );
1501 if (GetCapture() == hWnd)
1502 {
1503 ReleaseCapture();
1504 }
1505 break;
1506 }
1507
1508 case WM_VKEYTOITEM:
1509 case WM_CHARTOITEM:
1510 return (-1);
1511 /*
1512 case WM_DROPOBJECT:
1513 return DRAG_FILE;
1514 */
1515 case WM_QUERYDROPOBJECT:
1516 {
1517 if (GetWindowLongPtrW(hWnd, GWL_EXSTYLE) & WS_EX_ACCEPTFILES)
1518 {
1519 return(1);
1520 }
1521 break;
1522 }
1523
1524 case WM_QUERYDRAGICON:
1525 {
1526 UINT Len;
1527 HICON hIcon;
1528
1529 hIcon = (HICON)GetClassLongPtrW(hWnd, GCL_HICON);
1530 if (hIcon)
1531 {
1532 return ((LRESULT)hIcon);
1533 }
1534 for (Len = 1; Len < 64; Len++)
1535 {
1536 if ((hIcon = LoadIconW(NULL, MAKEINTRESOURCEW(Len))) != NULL)
1537 {
1538 return((LRESULT)hIcon);
1539 }
1540 }
1541 return ((LRESULT)LoadIconW(0, IDI_APPLICATION));
1542 }
1543
1544 case WM_ISACTIVEICON:
1545 {
1546 PWND pWnd;
1547 BOOL isai;
1548 pWnd = ValidateHwnd(hWnd);
1549 if (!pWnd) return 0;
1550 isai = (pWnd->state & WNDS_ACTIVEFRAME) != 0;
1551 return isai;
1552 }
1553
1554 case WM_NOTIFYFORMAT:
1555 {
1556 if (lParam == NF_QUERY)
1557 return IsWindowUnicode(hWnd) ? NFR_UNICODE : NFR_ANSI;
1558 break;
1559 }
1560
1561 case WM_SETICON:
1562 {
1563 INT Index = (wParam != 0) ? GCL_HICON : GCL_HICONSM;
1564 HICON hOldIcon = (HICON)GetClassLongPtrW(hWnd, Index);
1565 SetClassLongPtrW(hWnd, Index, lParam);
1566 SetWindowPos(hWnd, 0, 0, 0, 0, 0,
1567 SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
1568 SWP_NOACTIVATE | SWP_NOZORDER);
1569 return ((LRESULT)hOldIcon);
1570 }
1571
1572 case WM_GETICON:
1573 {
1574 INT Index = (wParam == ICON_BIG) ? GCL_HICON : GCL_HICONSM;
1575 return (GetClassLongPtrW(hWnd, Index));
1576 }
1577
1578 case WM_HELP:
1579 {
1580 if (bUnicode)
1581 {
1582 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
1583 }
1584 else
1585 {
1586 SendMessageA(GetParent(hWnd), Msg, wParam, lParam);
1587 }
1588 break;
1589 }
1590
1591 case WM_SYSTIMER:
1592 {
1593 THRDCARETINFO CaretInfo;
1594 switch(wParam)
1595 {
1596 case 0xffff: /* Caret timer */
1597 /* switch showing byte in win32k and get information about the caret */
1598 if(NtUserSwitchCaretShowing(&CaretInfo) && (CaretInfo.hWnd == hWnd))
1599 {
1600 DrawCaret(hWnd, &CaretInfo);
1601 }
1602 break;
1603 }
1604 break;
1605 }
1606
1607 case WM_QUERYOPEN:
1608 case WM_QUERYENDSESSION:
1609 {
1610 return (1);
1611 }
1612
1613 case WM_INPUTLANGCHANGEREQUEST:
1614 {
1615 HKL NewHkl;
1616
1617 if(wParam & INPUTLANGCHANGE_BACKWARD
1618 && wParam & INPUTLANGCHANGE_FORWARD)
1619 {
1620 return FALSE;
1621 }
1622
1623 //FIXME: What to do with INPUTLANGCHANGE_SYSCHARSET ?
1624
1625 if(wParam & INPUTLANGCHANGE_BACKWARD) NewHkl = (HKL) HKL_PREV;
1626 else if(wParam & INPUTLANGCHANGE_FORWARD) NewHkl = (HKL) HKL_NEXT;
1627 else NewHkl = (HKL) lParam;
1628
1629 NtUserActivateKeyboardLayout(NewHkl, 0);
1630
1631 return TRUE;
1632 }
1633
1634 case WM_INPUTLANGCHANGE:
1635 {
1636 int count = 0;
1637 HWND *win_array = WIN_ListChildren( hWnd );
1638
1639 if (!win_array)
1640 break;
1641 while (win_array[count])
1642 SendMessageW( win_array[count++], WM_INPUTLANGCHANGE, wParam, lParam);
1643 HeapFree(GetProcessHeap(),0,win_array);
1644 break;
1645 }
1646
1647 case WM_QUERYUISTATE:
1648 {
1649 LRESULT Ret = 0;
1650 PWND Wnd = ValidateHwnd(hWnd);
1651 if (Wnd != NULL)
1652 {
1653 if (Wnd->HideFocus)
1654 Ret |= UISF_HIDEFOCUS;
1655 if (Wnd->HideAccel)
1656 Ret |= UISF_HIDEACCEL;
1657 }
1658 return Ret;
1659 }
1660
1661 case WM_CHANGEUISTATE:
1662 {
1663 BOOL AlwaysShowCues = FALSE;
1664 WORD Action = LOWORD(wParam);
1665 WORD Flags = HIWORD(wParam);
1666 PWND Wnd;
1667
1668 SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0);
1669 if (AlwaysShowCues)
1670 break;
1671
1672 Wnd= ValidateHwnd(hWnd);
1673 if (!Wnd || lParam != 0)
1674 break;
1675
1676 if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE))
1677 break;
1678
1679 if (Flags & UISF_ACTIVE)
1680 {
1681 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n");
1682 }
1683
1684 if (Action == UIS_INITIALIZE)
1685 {
1686 PDESKTOPINFO Desk = GetThreadDesktopInfo();
1687 if (Desk == NULL)
1688 break;
1689
1690 Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET;
1691 Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL;
1692
1693 /* We need to update wParam in case we need to send out messages */
1694 wParam = MAKEWPARAM(Action, Flags);
1695 }
1696
1697 switch (Action)
1698 {
1699 case UIS_SET:
1700 /* See if we actually need to change something */
1701 if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus)
1702 break;
1703 if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel)
1704 break;
1705
1706 /* Don't need to do anything... */
1707 return 0;
1708
1709 case UIS_CLEAR:
1710 /* See if we actually need to change something */
1711 if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus)
1712 break;
1713 if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel)
1714 break;
1715
1716 /* Don't need to do anything... */
1717 return 0;
1718
1719 default:
1720 WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action);
1721 break;
1722 }
1723
1724 if ((Wnd->style & WS_CHILD) && Wnd->spwndParent != NULL)
1725 {
1726 /* We're a child window and we need to pass this message down until
1727 we reach the root */
1728 hWnd = UserHMGetHandle((PWND)DesktopPtrToUser(Wnd->spwndParent));
1729 }
1730 else
1731 {
1732 /* We're a top level window, we need to change the UI state */
1733 Msg = WM_UPDATEUISTATE;
1734 }
1735
1736 if (bUnicode)
1737 return SendMessageW(hWnd, Msg, wParam, lParam);
1738 else
1739 return SendMessageA(hWnd, Msg, wParam, lParam);
1740 }
1741
1742 case WM_UPDATEUISTATE:
1743 {
1744 BOOL Change = TRUE;
1745 BOOL AlwaysShowCues = FALSE;
1746 WORD Action = LOWORD(wParam);
1747 WORD Flags = HIWORD(wParam);
1748 PWND Wnd;
1749
1750 SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0);
1751 if (AlwaysShowCues)
1752 break;
1753
1754 Wnd = ValidateHwnd(hWnd);
1755 if (!Wnd || lParam != 0)
1756 break;
1757
1758 if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE))
1759 break;
1760
1761 if (Flags & UISF_ACTIVE)
1762 {
1763 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n");
1764 }
1765
1766 if (Action == UIS_INITIALIZE)
1767 {
1768 PDESKTOPINFO Desk = GetThreadDesktopInfo();
1769 if (Desk == NULL)
1770 break;
1771
1772 Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET;
1773 Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL;
1774
1775 /* We need to update wParam for broadcasting the update */
1776 wParam = MAKEWPARAM(Action, Flags);
1777 }
1778
1779 switch (Action)
1780 {
1781 case UIS_SET:
1782 /* See if we actually need to change something */
1783 if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus)
1784 break;
1785 if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel)
1786 break;
1787
1788 /* Don't need to do anything... */
1789 Change = FALSE;
1790 break;
1791
1792 case UIS_CLEAR:
1793 /* See if we actually need to change something */
1794 if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus)
1795 break;
1796 if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel)
1797 break;
1798
1799 /* Don't need to do anything... */
1800 Change = FALSE;
1801 break;
1802
1803 default:
1804 WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action);
1805 return 0;
1806 }
1807
1808 /* Pack the information and call win32k */
1809 if (Change)
1810 {
1811 if (!NtUserCallTwoParam((DWORD_PTR)hWnd, (DWORD_PTR)Flags | ((DWORD_PTR)Action << 3), TWOPARAM_ROUTINE_ROS_UPDATEUISTATE))
1812 break;
1813 }
1814
1815 /* Always broadcast the update to all children */
1816 EnumChildWindows(hWnd,
1817 UserSendUiUpdateMsg,
1818 (LPARAM)wParam);
1819
1820 break;
1821 }
1822
1823 /* Move to win32k !*/
1824 case WM_SHOWWINDOW:
1825 if (!lParam) break; // Call when it is necessary.
1826 case WM_CLIENTSHUTDOWN:
1827 case WM_GETHOTKEY:
1828 case WM_SETHOTKEY:
1829 {
1830 LRESULT lResult;
1831 NtUserMessageCall( hWnd, Msg, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, !bUnicode);
1832 return lResult;
1833 }
1834 }
1835 return 0;
1836 }
1837
1838
1839 /*
1840 * helpers for calling IMM32 (from Wine 10/22/2008)
1841 *
1842 * WM_IME_* messages are generated only by IMM32,
1843 * so I assume imm32 is already LoadLibrary-ed.
1844 */
1845 static HWND
1846 DefWndImmGetDefaultIMEWnd(HWND hwnd)
1847 {
1848 HINSTANCE hInstIMM = GetModuleHandleW(L"imm32\0");
1849 HWND (WINAPI *pFunc)(HWND);
1850 HWND hwndRet = 0;
1851
1852 if (!hInstIMM)
1853 {
1854 ERR("cannot get IMM32 handle\n");
1855 return 0;
1856 }
1857
1858 pFunc = (void*) GetProcAddress(hInstIMM, "ImmGetDefaultIMEWnd");
1859 if (pFunc != NULL)
1860 hwndRet = (*pFunc)(hwnd);
1861
1862 return hwndRet;
1863 }
1864
1865
1866 static BOOL
1867 DefWndImmIsUIMessageA(HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1868 {
1869 HINSTANCE hInstIMM = GetModuleHandleW(L"imm32\0");
1870 BOOL (WINAPI *pFunc)(HWND,UINT,WPARAM,LPARAM);
1871 BOOL fRet = FALSE;
1872
1873 if (!hInstIMM)
1874 {
1875 ERR("cannot get IMM32 handle\n");
1876 return FALSE;
1877 }
1878
1879 pFunc = (void*) GetProcAddress(hInstIMM, "ImmIsUIMessageA");
1880 if (pFunc != NULL)
1881 fRet = (*pFunc)(hwndIME, msg, wParam, lParam);
1882
1883 return fRet;
1884 }
1885
1886
1887 static BOOL
1888 DefWndImmIsUIMessageW(HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1889 {
1890 HINSTANCE hInstIMM = GetModuleHandleW(L"imm32\0");
1891 BOOL (WINAPI *pFunc)(HWND,UINT,WPARAM,LPARAM);
1892 BOOL fRet = FALSE;
1893
1894 if (!hInstIMM)
1895 {
1896 ERR("cannot get IMM32 handle\n");
1897 return FALSE;
1898 }
1899
1900 pFunc = (void*) GetProcAddress(hInstIMM, "ImmIsUIMessageW");
1901 if (pFunc != NULL)
1902 fRet = (*pFunc)(hwndIME, msg, wParam, lParam);
1903
1904 return fRet;
1905 }
1906
1907
1908 LRESULT WINAPI
1909 RealDefWindowProcA(HWND hWnd,
1910 UINT Msg,
1911 WPARAM wParam,
1912 LPARAM lParam)
1913 {
1914 LRESULT Result = 0;
1915 PWND Wnd;
1916
1917 SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam);
1918 switch (Msg)
1919 {
1920 case WM_NCCREATE:
1921 {
1922 if (lParam)
1923 {
1924 LPCREATESTRUCTA cs = (LPCREATESTRUCTA)lParam;
1925 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1926 * may have child window IDs instead of window name */
1927 if (HIWORD(cs->lpszName))
1928 {
1929 DefSetText(hWnd, (PCWSTR)cs->lpszName, TRUE);
1930 }
1931 Result = 1;
1932 }
1933 break;
1934 }
1935
1936 case WM_GETTEXTLENGTH:
1937 {
1938 PWSTR buf;
1939 ULONG len;
1940
1941 Wnd = ValidateHwnd(hWnd);
1942 if (Wnd != NULL && Wnd->strName.Length != 0)
1943 {
1944 buf = DesktopPtrToUser(Wnd->strName.Buffer);
1945 if (buf != NULL &&
1946 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len,
1947 buf,
1948 Wnd->strName.Length)))
1949 {
1950 Result = (LRESULT) len;
1951 }
1952 }
1953 else Result = 0L;
1954
1955 break;
1956 }
1957
1958 case WM_GETTEXT:
1959 {
1960 PWSTR buf = NULL;
1961 PSTR outbuf = (PSTR)lParam;
1962 UINT copy;
1963
1964 Wnd = ValidateHwnd(hWnd);
1965 if (Wnd != NULL && wParam != 0)
1966 {
1967 if (Wnd->strName.Buffer != NULL)
1968 buf = DesktopPtrToUser(Wnd->strName.Buffer);
1969 else
1970 outbuf[0] = L'\0';
1971
1972 if (buf != NULL)
1973 {
1974 if (Wnd->strName.Length != 0)
1975 {
1976 copy = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1);
1977 Result = WideCharToMultiByte(CP_ACP,
1978 0,
1979 buf,
1980 copy,
1981 outbuf,
1982 wParam,
1983 NULL,
1984 NULL);
1985 outbuf[Result] = '\0';
1986 }
1987 else
1988 outbuf[0] = '\0';
1989 }
1990 }
1991 break;
1992 }
1993
1994 case WM_SETTEXT:
1995 {
1996 DefSetText(hWnd, (PCWSTR)lParam, TRUE);
1997
1998 if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1999 {
2000 DefWndNCPaint(hWnd, HRGN_WINDOW, -1);
2001 }
2002 Result = 1;
2003 break;
2004 }
2005
2006 case WM_IME_KEYDOWN:
2007 {
2008 Result = PostMessageA(hWnd, WM_KEYDOWN, wParam, lParam);
2009 break;
2010 }
2011
2012 case WM_IME_KEYUP:
2013 {
2014 Result = PostMessageA(hWnd, WM_KEYUP, wParam, lParam);
2015 break;
2016 }
2017
2018 case WM_IME_CHAR:
2019 {
2020 if (HIBYTE(wParam))
2021 PostMessageA(hWnd, WM_CHAR, HIBYTE(wParam), lParam);
2022 PostMessageA(hWnd, WM_CHAR, LOBYTE(wParam), lParam);
2023 break;
2024 }
2025
2026 case WM_IME_STARTCOMPOSITION:
2027 case WM_IME_COMPOSITION:
2028 case WM_IME_ENDCOMPOSITION:
2029 case WM_IME_SELECT:
2030 case WM_IME_NOTIFY:
2031 {
2032 HWND hwndIME;
2033
2034 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
2035 if (hwndIME)
2036 Result = SendMessageA(hwndIME, Msg, wParam, lParam);
2037 break;
2038 }
2039
2040 case WM_IME_SETCONTEXT:
2041 {
2042 HWND hwndIME;
2043
2044 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
2045 if (hwndIME)
2046 Result = DefWndImmIsUIMessageA(hwndIME, Msg, wParam, lParam);
2047 break;
2048 }
2049
2050 /* fall through */
2051 default:
2052 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, FALSE);
2053 }
2054
2055 SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam);
2056 return Result;
2057 }
2058
2059
2060 LRESULT WINAPI
2061 RealDefWindowProcW(HWND hWnd,
2062 UINT Msg,
2063 WPARAM wParam,
2064 LPARAM lParam)
2065 {
2066 LRESULT Result = 0;
2067 PWND Wnd;
2068
2069 SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam);
2070 switch (Msg)
2071 {
2072 case WM_NCCREATE:
2073 {
2074 if (lParam)
2075 {
2076 LPCREATESTRUCTW cs = (LPCREATESTRUCTW)lParam;
2077 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
2078 * may have child window IDs instead of window name */
2079 if (HIWORD(cs->lpszName))
2080 {
2081 DefSetText(hWnd, cs->lpszName, FALSE);
2082 }
2083 Result = 1;
2084 }
2085 break;
2086 }
2087
2088 case WM_GETTEXTLENGTH:
2089 {
2090 PWSTR buf;
2091 ULONG len;
2092
2093 Wnd = ValidateHwnd(hWnd);
2094 if (Wnd != NULL && Wnd->strName.Length != 0)
2095 {
2096 buf = DesktopPtrToUser(Wnd->strName.Buffer);
2097 if (buf != NULL &&
2098 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len,
2099 buf,
2100 Wnd->strName.Length)))
2101 {
2102 Result = (LRESULT) (Wnd->strName.Length / sizeof(WCHAR));
2103 }
2104 }
2105 else Result = 0L;
2106
2107 break;
2108 }
2109
2110 case WM_GETTEXT:
2111 {
2112 PWSTR buf = NULL;
2113 PWSTR outbuf = (PWSTR)lParam;
2114
2115 Wnd = ValidateHwnd(hWnd);
2116 if (Wnd != NULL && wParam != 0)
2117 {
2118 if (Wnd->strName.Buffer != NULL)
2119 buf = DesktopPtrToUser(Wnd->strName.Buffer);
2120 else
2121 outbuf[0] = L'\0';
2122
2123 if (buf != NULL)
2124 {
2125 if (Wnd->strName.Length != 0)
2126 {
2127 Result = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1);
2128 RtlCopyMemory(outbuf,
2129 buf,
2130 Result * sizeof(WCHAR));
2131 outbuf[Result] = L'\0';
2132 }
2133 else
2134 outbuf[0] = L'\0';
2135 }
2136 }
2137 break;
2138 }
2139
2140 case WM_SETTEXT:
2141 {
2142 DefSetText(hWnd, (PCWSTR)lParam, FALSE);
2143
2144 if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
2145 {
2146 DefWndNCPaint(hWnd, HRGN_WINDOW, -1);
2147 }
2148 Result = 1;
2149 break;
2150 }
2151
2152 case WM_IME_CHAR:
2153 {
2154 PostMessageW(hWnd, WM_CHAR, wParam, lParam);
2155 Result = 0;
2156 break;
2157 }
2158
2159 case WM_IME_KEYDOWN:
2160 {
2161 Result = PostMessageW(hWnd, WM_KEYDOWN, wParam, lParam);
2162 break;
2163 }
2164
2165 case WM_IME_KEYUP:
2166 {
2167 Result = PostMessageW(hWnd, WM_KEYUP, wParam, lParam);
2168 break;
2169 }
2170
2171 case WM_IME_STARTCOMPOSITION:
2172 case WM_IME_COMPOSITION:
2173 case WM_IME_ENDCOMPOSITION:
2174 case WM_IME_SELECT:
2175 case WM_IME_NOTIFY:
2176 {
2177 HWND hwndIME;
2178
2179 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
2180 if (hwndIME)
2181 Result = SendMessageW(hwndIME, Msg, wParam, lParam);
2182 break;
2183 }
2184
2185 case WM_IME_SETCONTEXT:
2186 {
2187 HWND hwndIME;
2188
2189 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
2190 if (hwndIME)
2191 Result = DefWndImmIsUIMessageW(hwndIME, Msg, wParam, lParam);
2192 break;
2193 }
2194
2195 default:
2196 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, TRUE);
2197 }
2198 SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam);
2199
2200 return Result;
2201 }
2202
2203 LRESULT WINAPI
2204 DefWindowProcA(HWND hWnd,
2205 UINT Msg,
2206 WPARAM wParam,
2207 LPARAM lParam)
2208 {
2209 BOOL Hook, msgOverride = FALSE;
2210 LRESULT Result = 0;
2211
2212 LoadUserApiHook();
2213
2214 Hook = BeginIfHookedUserApiHook();
2215 if (Hook)
2216 msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray);
2217
2218 /* Bypass SEH and go direct. */
2219 if (!Hook || !msgOverride)
2220 return RealDefWindowProcA(hWnd, Msg, wParam, lParam);
2221
2222 _SEH2_TRY
2223 {
2224 Result = guah.DefWindowProcA(hWnd, Msg, wParam, lParam);
2225 }
2226 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2227 {
2228 }
2229 _SEH2_END;
2230
2231 EndUserApiHook();
2232
2233 return Result;
2234 }
2235
2236 LRESULT WINAPI
2237 DefWindowProcW(HWND hWnd,
2238 UINT Msg,
2239 WPARAM wParam,
2240 LPARAM lParam)
2241 {
2242 BOOL Hook, msgOverride = FALSE;
2243 LRESULT Result = 0;
2244
2245 LoadUserApiHook();
2246
2247 Hook = BeginIfHookedUserApiHook();
2248 if (Hook)
2249 msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray);
2250
2251 /* Bypass SEH and go direct. */
2252 if (!Hook || !msgOverride)
2253 return RealDefWindowProcW(hWnd, Msg, wParam, lParam);
2254
2255 _SEH2_TRY
2256 {
2257 Result = guah.DefWindowProcW(hWnd, Msg, wParam, lParam);
2258 }
2259 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2260 {
2261 }
2262 _SEH2_END;
2263
2264 EndUserApiHook();
2265
2266 return Result;
2267 }