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