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