include: Add ID2D1PathGeometry1 definition.
[wine.git] / dlls / user32 / defwnd.c
blobc4263edac93693e073336854bf738b78c5d34924
1 /*
2 * Default window procedure
4 * Copyright 1993, 1996 Alexandre Julliard
5 * 1995 Alex Korobka
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <string.h>
23 #include <stdarg.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wingdi.h"
28 #include "winnls.h"
29 #include "imm.h"
30 #include "win.h"
31 #include "user_private.h"
32 #include "controls.h"
33 #include "wine/server.h"
34 #include "wine/exception.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(win);
39 /* bits in the dwKeyData */
40 #define KEYDATA_ALT 0x2000
41 #define KEYDATA_PREVSTATE 0x4000
43 #define DRAG_FILE 0x454C4946
45 static short iF10Key = 0;
46 static short iMenuSysKey = 0;
48 /***********************************************************************
49 * DEFWND_HandleWindowPosChanged
51 * Handle the WM_WINDOWPOSCHANGED message.
53 static void DEFWND_HandleWindowPosChanged( HWND hwnd, const WINDOWPOS *winpos )
55 RECT rect;
57 WIN_GetRectangles( hwnd, COORDS_PARENT, NULL, &rect );
58 if (!(winpos->flags & SWP_NOCLIENTMOVE))
59 SendMessageW( hwnd, WM_MOVE, 0, MAKELONG(rect.left, rect.top));
61 if (!(winpos->flags & SWP_NOCLIENTSIZE) || (winpos->flags & SWP_STATECHANGED))
63 if (IsIconic( hwnd ))
65 SendMessageW( hwnd, WM_SIZE, SIZE_MINIMIZED, 0 );
67 else
69 WPARAM wp = IsZoomed( hwnd ) ? SIZE_MAXIMIZED : SIZE_RESTORED;
71 SendMessageW( hwnd, WM_SIZE, wp, MAKELONG(rect.right-rect.left, rect.bottom-rect.top) );
77 /***********************************************************************
78 * DEFWND_ControlColor
80 * Default colors for control painting.
82 HBRUSH DEFWND_ControlColor( HDC hDC, UINT ctlType )
84 if( ctlType == CTLCOLOR_SCROLLBAR)
86 HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR);
87 COLORREF bk = GetSysColor(COLOR_3DHILIGHT);
88 SetTextColor( hDC, GetSysColor(COLOR_3DFACE));
89 SetBkColor( hDC, bk);
91 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
92 * we better use 0x55aa bitmap brush to make scrollbar's background
93 * look different from the window background.
95 if (bk == GetSysColor(COLOR_WINDOW))
96 return SYSCOLOR_Get55AABrush();
98 UnrealizeObject( hb );
99 return hb;
102 SetTextColor( hDC, GetSysColor(COLOR_WINDOWTEXT));
104 if ((ctlType == CTLCOLOR_EDIT) || (ctlType == CTLCOLOR_LISTBOX))
105 SetBkColor( hDC, GetSysColor(COLOR_WINDOW) );
106 else {
107 SetBkColor( hDC, GetSysColor(COLOR_3DFACE) );
108 return GetSysColorBrush(COLOR_3DFACE);
110 return GetSysColorBrush(COLOR_WINDOW);
114 /***********************************************************************
115 * DEFWND_Print
117 * This method handles the default behavior for the WM_PRINT message.
119 static void DEFWND_Print( HWND hwnd, HDC hdc, ULONG uFlags)
122 * Visibility flag.
124 if ( (uFlags & PRF_CHECKVISIBLE) &&
125 !IsWindowVisible(hwnd) )
126 return;
129 * Unimplemented flags.
131 if ( (uFlags & PRF_CHILDREN) ||
132 (uFlags & PRF_OWNED) ||
133 (uFlags & PRF_NONCLIENT) )
135 WARN("WM_PRINT message with unsupported flags\n");
139 * Background
141 if ( uFlags & PRF_ERASEBKGND)
142 SendMessageW(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0);
145 * Client area
147 if ( uFlags & PRF_CLIENT)
148 SendMessageW(hwnd, WM_PRINTCLIENT, (WPARAM)hdc, uFlags);
153 /***********************************************************************
154 * DEFWND_DefWinProc
156 * Default window procedure for messages that are the same in Ansi and Unicode.
158 static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
160 switch(msg)
162 case WM_NCPAINT:
163 return NC_HandleNCPaint( hwnd, (HRGN)wParam );
165 case WM_NCMOUSEMOVE:
166 return NC_HandleNCMouseMove( hwnd, wParam, lParam );
168 case WM_NCMOUSELEAVE:
169 return NC_HandleNCMouseLeave( hwnd );
171 case WM_NCHITTEST:
173 POINT pt;
174 pt.x = (short)LOWORD(lParam);
175 pt.y = (short)HIWORD(lParam);
176 return NC_HandleNCHitTest( hwnd, pt );
179 case WM_NCCALCSIZE:
180 NC_HandleNCCalcSize( hwnd, wParam, (RECT *)lParam );
181 break;
183 case WM_WINDOWPOSCHANGED:
184 DEFWND_HandleWindowPosChanged( hwnd, (const WINDOWPOS *)lParam );
185 break;
187 case WM_LBUTTONDOWN:
188 case WM_RBUTTONDOWN:
189 case WM_MBUTTONDOWN:
190 iF10Key = iMenuSysKey = 0;
191 break;
193 case WM_NCLBUTTONDOWN:
194 return NC_HandleNCLButtonDown( hwnd, wParam, lParam );
196 case WM_LBUTTONDBLCLK:
197 return NC_HandleNCLButtonDblClk( hwnd, HTCLIENT, lParam );
199 case WM_NCLBUTTONDBLCLK:
200 return NC_HandleNCLButtonDblClk( hwnd, wParam, lParam );
202 case WM_NCRBUTTONDOWN:
203 return NC_HandleNCRButtonDown( hwnd, wParam, lParam );
205 case WM_RBUTTONUP:
207 POINT pt;
208 pt.x = (short)LOWORD(lParam);
209 pt.y = (short)HIWORD(lParam);
210 ClientToScreen(hwnd, &pt);
211 SendMessageW( hwnd, WM_CONTEXTMENU, (WPARAM)hwnd, MAKELPARAM(pt.x, pt.y) );
213 break;
215 case WM_NCRBUTTONUP:
217 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
218 * in Windows), but what _should_ we do? According to MSDN :
219 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
220 * message to the window". When is it appropriate?
222 break;
224 case WM_XBUTTONUP:
225 case WM_NCXBUTTONUP:
226 if (HIWORD(wParam) == XBUTTON1 || HIWORD(wParam) == XBUTTON2)
228 SendMessageW(hwnd, WM_APPCOMMAND, (WPARAM)hwnd,
229 MAKELPARAM(LOWORD(wParam), FAPPCOMMAND_MOUSE | HIWORD(wParam)));
231 break;
233 case WM_CONTEXTMENU:
234 if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD)
235 SendMessageW( GetParent(hwnd), msg, (WPARAM)hwnd, lParam );
236 else
238 LONG hitcode;
239 POINT pt;
240 pt.x = (short)LOWORD(lParam);
241 pt.y = (short)HIWORD(lParam);
242 hitcode = NC_HandleNCHitTest(hwnd, pt);
244 /* Track system popup if click was in the caption area. */
245 if (hitcode==HTCAPTION || hitcode==HTSYSMENU)
246 TrackPopupMenu( NtUserGetSystemMenu(hwnd, FALSE),
247 TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
248 pt.x, pt.y, 0, hwnd, NULL );
250 break;
252 case WM_POPUPSYSTEMMENU:
253 /* This is an undocumented message used by the windows taskbar to
254 display the system menu of windows that belong to other processes. */
255 TrackPopupMenu( NtUserGetSystemMenu(hwnd, FALSE), TPM_LEFTBUTTON|TPM_RIGHTBUTTON,
256 (short)LOWORD(lParam), (short)HIWORD(lParam), 0, hwnd, NULL );
257 return 0;
259 case WM_NCACTIVATE:
260 return NC_HandleNCActivate( hwnd, wParam, lParam );
262 case WM_PRINT:
263 DEFWND_Print(hwnd, (HDC)wParam, lParam);
264 return 0;
266 case WM_CTLCOLORMSGBOX:
267 case WM_CTLCOLOREDIT:
268 case WM_CTLCOLORLISTBOX:
269 case WM_CTLCOLORBTN:
270 case WM_CTLCOLORDLG:
271 case WM_CTLCOLORSTATIC:
272 case WM_CTLCOLORSCROLLBAR:
273 return (LRESULT)DEFWND_ControlColor( (HDC)wParam, msg - WM_CTLCOLORMSGBOX );
275 case WM_CTLCOLOR:
276 return (LRESULT)DEFWND_ControlColor( (HDC)wParam, HIWORD(lParam) );
278 case WM_SETCURSOR:
279 if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD)
281 /* with the exception of the border around a resizable wnd,
282 * give the parent first chance to set the cursor */
283 if ((LOWORD(lParam) < HTSIZEFIRST) || (LOWORD(lParam) > HTSIZELAST))
285 HWND parent = GetParent( hwnd );
286 if (parent != GetDesktopWindow() &&
287 SendMessageW( parent, WM_SETCURSOR, wParam, lParam )) return TRUE;
290 NC_HandleSetCursor( hwnd, wParam, lParam );
291 break;
293 case WM_SYSCOMMAND:
294 return NC_HandleSysCommand( hwnd, wParam, lParam );
296 case WM_KEYDOWN:
297 if(wParam == VK_F10) iF10Key = VK_F10;
298 break;
300 case WM_SYSKEYDOWN:
301 if( HIWORD(lParam) & KEYDATA_ALT )
303 /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */
304 if ( (wParam == VK_MENU || wParam == VK_LMENU
305 || wParam == VK_RMENU) && !iMenuSysKey )
306 iMenuSysKey = 1;
307 else
308 iMenuSysKey = 0;
310 iF10Key = 0;
312 if( wParam == VK_F4 ) /* try to close the window */
314 HWND top = NtUserGetAncestor( hwnd, GA_ROOT );
315 if (!(GetClassLongW( top, GCL_STYLE ) & CS_NOCLOSE))
316 PostMessageW( top, WM_SYSCOMMAND, SC_CLOSE, 0 );
319 else if( wParam == VK_F10 )
321 if (NtUserGetKeyState(VK_SHIFT) & 0x8000)
322 SendMessageW( hwnd, WM_CONTEXTMENU, (WPARAM)hwnd, -1 );
323 iF10Key = 1;
325 else if (wParam == VK_ESCAPE && (NtUserGetKeyState(VK_SHIFT) & 0x8000))
326 SendMessageW( hwnd, WM_SYSCOMMAND, SC_KEYMENU, ' ' );
327 break;
329 case WM_KEYUP:
330 case WM_SYSKEYUP:
331 /* Press and release F10 or ALT */
332 if (((wParam == VK_MENU || wParam == VK_LMENU || wParam == VK_RMENU)
333 && iMenuSysKey) || ((wParam == VK_F10) && iF10Key))
334 SendMessageW( NtUserGetAncestor( hwnd, GA_ROOT ), WM_SYSCOMMAND, SC_KEYMENU, 0L );
335 iMenuSysKey = iF10Key = 0;
336 break;
338 case WM_SYSCHAR:
340 iMenuSysKey = 0;
341 if (wParam == '\r' && IsIconic(hwnd))
343 PostMessageW( hwnd, WM_SYSCOMMAND, SC_RESTORE, 0L );
344 break;
346 if ((HIWORD(lParam) & KEYDATA_ALT) && wParam)
348 if (wParam == '\t' || wParam == '\x1b') break;
349 if (wParam == ' ' && (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD))
350 SendMessageW( GetParent(hwnd), msg, wParam, lParam );
351 else
352 SendMessageW( hwnd, WM_SYSCOMMAND, SC_KEYMENU, wParam );
354 else /* check for Ctrl-Esc */
355 if (wParam != '\x1b') MessageBeep(0);
356 break;
359 case WM_SHOWWINDOW:
361 LONG style = GetWindowLongW( hwnd, GWL_STYLE );
362 WND *pWnd;
363 if (!lParam) return 0; /* sent from ShowWindow */
364 if ((style & WS_VISIBLE) && wParam) return 0;
365 if (!(style & WS_VISIBLE) && !wParam) return 0;
366 if (!GetWindow( hwnd, GW_OWNER )) return 0;
367 if (!(pWnd = WIN_GetPtr( hwnd ))) return 0;
368 if (pWnd == WND_OTHER_PROCESS) return 0;
369 if (wParam)
371 if (!(pWnd->flags & WIN_NEEDS_SHOW_OWNEDPOPUP))
373 WIN_ReleasePtr( pWnd );
374 return 0;
376 pWnd->flags &= ~WIN_NEEDS_SHOW_OWNEDPOPUP;
378 else pWnd->flags |= WIN_NEEDS_SHOW_OWNEDPOPUP;
379 WIN_ReleasePtr( pWnd );
380 NtUserShowWindow( hwnd, wParam ? SW_SHOWNOACTIVATE : SW_HIDE );
381 break;
384 case WM_CANCELMODE:
385 iMenuSysKey = 0;
386 MENU_EndMenu( hwnd );
387 if (GetCapture() == hwnd) ReleaseCapture();
388 break;
390 case WM_VKEYTOITEM:
391 case WM_CHARTOITEM:
392 return -1;
394 case WM_DROPOBJECT:
395 return DRAG_FILE;
397 case WM_QUERYDROPOBJECT:
398 return (GetWindowLongA( hwnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES) != 0;
400 case WM_QUERYDRAGICON:
402 UINT len;
404 HICON hIcon = (HICON)GetClassLongPtrW( hwnd, GCLP_HICON );
405 HINSTANCE instance = (HINSTANCE)GetWindowLongPtrW( hwnd, GWLP_HINSTANCE );
406 if (hIcon) return (LRESULT)hIcon;
407 for(len=1; len<64; len++)
408 if((hIcon = LoadIconW(instance, MAKEINTRESOURCEW(len))))
409 return (LRESULT)hIcon;
410 return (LRESULT)LoadIconW(0, (LPWSTR)IDI_APPLICATION);
412 break;
414 case WM_ISACTIVEICON:
415 return (win_get_flags( hwnd ) & WIN_NCACTIVATED) != 0;
417 case WM_NOTIFYFORMAT:
418 if (IsWindowUnicode(hwnd)) return NFR_UNICODE;
419 else return NFR_ANSI;
421 case WM_QUERYOPEN:
422 case WM_QUERYENDSESSION:
423 return 1;
425 case WM_SETICON:
427 LRESULT res = NtUserMessageCall( hwnd, msg, wParam, lParam,
428 0, NtUserDefWindowProc, FALSE );
429 if( (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CAPTION) == WS_CAPTION )
430 NC_HandleNCPaint( hwnd , (HRGN)1 ); /* Repaint caption */
431 return res;
434 case WM_HELP:
435 SendMessageW( GetParent(hwnd), msg, wParam, lParam );
436 break;
438 case WM_STYLECHANGED:
439 if (wParam == GWL_STYLE && (GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYERED))
441 STYLESTRUCT *style = (STYLESTRUCT *)lParam;
442 if ((style->styleOld ^ style->styleNew) & (WS_CAPTION|WS_THICKFRAME|WS_VSCROLL|WS_HSCROLL))
443 NtUserSetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER |
444 SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE );
446 break;
448 case WM_APPCOMMAND:
450 HWND parent = GetParent(hwnd);
451 if(!parent)
452 HOOK_CallHooks(WH_SHELL, HSHELL_APPCOMMAND, wParam, lParam, TRUE);
453 else
454 SendMessageW( parent, msg, wParam, lParam );
455 break;
457 case WM_KEYF1:
459 HELPINFO hi;
461 hi.cbSize = sizeof(HELPINFO);
462 GetCursorPos( &hi.MousePos );
463 if (MENU_IsMenuActive())
465 hi.iContextType = HELPINFO_MENUITEM;
466 hi.hItemHandle = MENU_IsMenuActive();
467 hi.iCtrlId = MenuItemFromPoint( hwnd, hi.hItemHandle, hi.MousePos );
468 hi.dwContextId = GetMenuContextHelpId( hi.hItemHandle );
470 else
472 hi.iContextType = HELPINFO_WINDOW;
473 hi.hItemHandle = hwnd;
474 hi.iCtrlId = GetWindowLongPtrA( hwnd, GWLP_ID );
475 hi.dwContextId = GetWindowContextHelpId( hwnd );
477 SendMessageW( hwnd, WM_HELP, 0, (LPARAM)&hi );
478 break;
481 case WM_INPUTLANGCHANGEREQUEST:
482 NtUserActivateKeyboardLayout( (HKL)lParam, 0 );
483 break;
485 case WM_INPUTLANGCHANGE:
487 struct user_thread_info *info = get_user_thread_info();
488 int count = 0;
489 HWND *win_array = WIN_ListChildren( hwnd );
490 info->kbd_layout = (HKL)lParam;
492 if (!win_array)
493 break;
494 while (win_array[count])
495 SendMessageW( win_array[count++], WM_INPUTLANGCHANGE, wParam, lParam);
496 HeapFree(GetProcessHeap(),0,win_array);
497 break;
500 default:
501 return NtUserMessageCall( hwnd, msg, wParam, lParam, 0, NtUserDefWindowProc, FALSE );
505 return 0;
508 static LPARAM DEFWND_GetTextA( WND *wndPtr, LPSTR dest, WPARAM wParam )
510 LPARAM result = 0;
512 __TRY
514 if (wndPtr->text)
516 if (!WideCharToMultiByte( CP_ACP, 0, wndPtr->text, -1,
517 dest, wParam, NULL, NULL )) dest[wParam-1] = 0;
518 result = strlen( dest );
520 else dest[0] = '\0';
522 __EXCEPT_PAGE_FAULT
524 return 0;
526 __ENDTRY
527 return result;
530 /***********************************************************************
531 * DefWindowProcA (USER32.@)
533 * See DefWindowProcW.
535 LRESULT WINAPI DefWindowProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
537 LRESULT result = 0;
538 HWND full_handle;
540 if (!(full_handle = WIN_IsCurrentProcess( hwnd )))
542 if (!IsWindow( hwnd )) return 0;
543 ERR( "called for other process window %p\n", hwnd );
544 return 0;
546 hwnd = full_handle;
548 SPY_EnterMessage( SPY_DEFWNDPROC, hwnd, msg, wParam, lParam );
550 switch(msg)
552 case WM_NCCREATE:
553 if (lParam)
555 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
557 result = NtUserMessageCall( hwnd, msg, wParam, lParam, 0, NtUserDefWindowProc, TRUE );
559 if(cs->style & (WS_HSCROLL | WS_VSCROLL))
561 SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0};
562 SetScrollInfo( hwnd, SB_HORZ, &si, FALSE );
563 SetScrollInfo( hwnd, SB_VERT, &si, FALSE );
566 break;
568 case WM_GETTEXTLENGTH:
570 WND *wndPtr = WIN_GetPtr( hwnd );
571 if (wndPtr && wndPtr->text)
572 result = WideCharToMultiByte( CP_ACP, 0, wndPtr->text, lstrlenW(wndPtr->text),
573 NULL, 0, NULL, NULL );
574 WIN_ReleasePtr( wndPtr );
576 break;
578 case WM_GETTEXT:
579 if (wParam)
581 LPSTR dest = (LPSTR)lParam;
582 WND *wndPtr = WIN_GetPtr( hwnd );
584 if (!wndPtr) break;
585 result = DEFWND_GetTextA( wndPtr, dest, wParam );
587 WIN_ReleasePtr( wndPtr );
589 break;
591 case WM_SETTEXT:
592 result = NtUserMessageCall( hwnd, msg, wParam, lParam, 0, NtUserDefWindowProc, TRUE );
593 if (result && (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CAPTION) == WS_CAPTION)
594 NC_HandleNCPaint( hwnd , (HRGN)1 ); /* Repaint caption */
595 break;
597 case WM_IME_CHAR:
598 if (HIBYTE(wParam)) PostMessageA( hwnd, WM_CHAR, HIBYTE(wParam), lParam );
599 PostMessageA( hwnd, WM_CHAR, LOBYTE(wParam), lParam );
600 break;
602 case WM_IME_KEYDOWN:
603 result = PostMessageA( hwnd, WM_KEYDOWN, wParam, lParam );
604 break;
606 case WM_IME_KEYUP:
607 result = PostMessageA( hwnd, WM_KEYUP, wParam, lParam );
608 break;
610 case WM_IME_COMPOSITION:
611 if (lParam & GCS_RESULTSTR)
613 LONG size, i;
614 unsigned char lead = 0;
615 char *buf = NULL;
616 HIMC himc = ImmGetContext( hwnd );
618 if (himc)
620 if ((size = ImmGetCompositionStringA( himc, GCS_RESULTSTR, NULL, 0 )))
622 if (!(buf = HeapAlloc( GetProcessHeap(), 0, size ))) size = 0;
623 else size = ImmGetCompositionStringA( himc, GCS_RESULTSTR, buf, size );
625 ImmReleaseContext( hwnd, himc );
627 for (i = 0; i < size; i++)
629 unsigned char c = buf[i];
630 if (!lead)
632 if (IsDBCSLeadByte( c ))
633 lead = c;
634 else
635 SendMessageA( hwnd, WM_IME_CHAR, c, 1 );
637 else
639 SendMessageA( hwnd, WM_IME_CHAR, MAKEWORD(c, lead), 1 );
640 lead = 0;
643 HeapFree( GetProcessHeap(), 0, buf );
646 /* fall through */
647 case WM_IME_STARTCOMPOSITION:
648 case WM_IME_ENDCOMPOSITION:
649 case WM_IME_SELECT:
650 case WM_IME_NOTIFY:
651 case WM_IME_CONTROL:
653 HWND hwndIME = ImmGetDefaultIMEWnd( hwnd );
654 if (hwndIME)
655 result = SendMessageA( hwndIME, msg, wParam, lParam );
657 break;
658 case WM_IME_SETCONTEXT:
660 HWND hwndIME = ImmGetDefaultIMEWnd( hwnd );
661 if (hwndIME) result = ImmIsUIMessageA( hwndIME, msg, wParam, lParam );
663 break;
665 case WM_SYSCHAR:
667 CHAR ch = LOWORD(wParam);
668 WCHAR wch;
669 MultiByteToWideChar(CP_ACP, 0, &ch, 1, &wch, 1);
670 wParam = MAKEWPARAM( wch, HIWORD(wParam) );
672 /* fall through */
673 default:
674 result = DEFWND_DefWinProc( hwnd, msg, wParam, lParam );
675 break;
678 SPY_ExitMessage( SPY_RESULT_DEFWND, hwnd, msg, result, wParam, lParam );
679 return result;
683 static LPARAM DEFWND_GetTextW( WND *wndPtr, LPWSTR dest, WPARAM wParam )
685 LPARAM result = 0;
687 __TRY
689 if (wndPtr->text)
691 lstrcpynW( dest, wndPtr->text, wParam );
692 result = lstrlenW( dest );
694 else dest[0] = '\0';
696 __EXCEPT_PAGE_FAULT
698 return 0;
700 __ENDTRY
702 return result;
705 /***********************************************************************
706 * DefWindowProcW (USER32.@) Calls default window message handler
708 * Calls default window procedure for messages not processed
709 * by application.
711 * RETURNS
712 * Return value is dependent upon the message.
714 LRESULT WINAPI DefWindowProcW(
715 HWND hwnd, /* [in] window procedure receiving message */
716 UINT msg, /* [in] message identifier */
717 WPARAM wParam, /* [in] first message parameter */
718 LPARAM lParam ) /* [in] second message parameter */
720 LRESULT result = 0;
721 HWND full_handle;
723 if (!(full_handle = WIN_IsCurrentProcess( hwnd )))
725 if (!IsWindow( hwnd )) return 0;
726 ERR( "called for other process window %p\n", hwnd );
727 return 0;
729 hwnd = full_handle;
730 SPY_EnterMessage( SPY_DEFWNDPROC, hwnd, msg, wParam, lParam );
732 switch(msg)
734 case WM_NCCREATE:
735 if (lParam)
737 CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
739 result = NtUserMessageCall( hwnd, msg, wParam, lParam, 0, NtUserDefWindowProc, FALSE );
741 if(cs->style & (WS_HSCROLL | WS_VSCROLL))
743 SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0};
744 SetScrollInfo( hwnd, SB_HORZ, &si, FALSE );
745 SetScrollInfo( hwnd, SB_VERT, &si, FALSE );
748 break;
750 case WM_GETTEXTLENGTH:
752 WND *wndPtr = WIN_GetPtr( hwnd );
753 if (wndPtr && wndPtr->text) result = (LRESULT)lstrlenW(wndPtr->text);
754 WIN_ReleasePtr( wndPtr );
756 break;
758 case WM_GETTEXT:
759 if (wParam)
761 LPWSTR dest = (LPWSTR)lParam;
762 WND *wndPtr = WIN_GetPtr( hwnd );
764 if (!wndPtr) break;
765 result = DEFWND_GetTextW( wndPtr, dest, wParam );
766 WIN_ReleasePtr( wndPtr );
768 break;
770 case WM_SETTEXT:
771 result = NtUserMessageCall( hwnd, msg, wParam, lParam, 0, NtUserDefWindowProc, FALSE );
772 if (result && (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CAPTION) == WS_CAPTION)
773 NC_HandleNCPaint( hwnd , (HRGN)1 ); /* Repaint caption */
774 break;
776 case WM_IME_CHAR:
777 PostMessageW( hwnd, WM_CHAR, wParam, lParam );
778 break;
780 case WM_IME_KEYDOWN:
781 result = PostMessageW( hwnd, WM_KEYDOWN, wParam, lParam );
782 break;
784 case WM_IME_KEYUP:
785 result = PostMessageW( hwnd, WM_KEYUP, wParam, lParam );
786 break;
788 case WM_IME_SETCONTEXT:
790 HWND hwndIME = ImmGetDefaultIMEWnd( hwnd );
791 if (hwndIME) result = ImmIsUIMessageW( hwndIME, msg, wParam, lParam );
793 break;
795 case WM_IME_COMPOSITION:
796 if (lParam & GCS_RESULTSTR)
798 LONG size, i;
799 WCHAR *buf = NULL;
800 HIMC himc = ImmGetContext( hwnd );
802 if (himc)
804 if ((size = ImmGetCompositionStringW( himc, GCS_RESULTSTR, NULL, 0 )))
806 if (!(buf = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) size = 0;
807 else size = ImmGetCompositionStringW( himc, GCS_RESULTSTR, buf, size * sizeof(WCHAR) );
809 ImmReleaseContext( hwnd, himc );
811 for (i = 0; i < size / sizeof(WCHAR); i++)
812 SendMessageW( hwnd, WM_IME_CHAR, buf[i], 1 );
813 HeapFree( GetProcessHeap(), 0, buf );
816 /* fall through */
817 case WM_IME_STARTCOMPOSITION:
818 case WM_IME_ENDCOMPOSITION:
819 case WM_IME_SELECT:
820 case WM_IME_NOTIFY:
821 case WM_IME_CONTROL:
823 HWND hwndIME = ImmGetDefaultIMEWnd( hwnd );
824 if (hwndIME)
825 result = SendMessageW( hwndIME, msg, wParam, lParam );
827 break;
829 default:
830 result = DEFWND_DefWinProc( hwnd, msg, wParam, lParam );
831 break;
833 SPY_ExitMessage( SPY_RESULT_DEFWND, hwnd, msg, result, wParam, lParam );
834 return result;