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