include: Make sure __int64 is correctly defined on PPC64.
[wine.git] / dlls / user32 / defwnd.c
blobd00fc8584c685e4571c1a35a0f6e0951c4d609ed
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_SetTextA
80 * Set the window text.
82 static LRESULT DEFWND_SetTextA( HWND hwnd, LPCSTR text )
84 int count;
85 WCHAR *textW;
86 WND *wndPtr;
88 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
89 * may have child window IDs instead of window name */
90 if (text && IS_INTRESOURCE(text))
91 return 0;
93 if (!text) text = "";
94 count = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 );
96 if (!(wndPtr = WIN_GetPtr( hwnd ))) return 0;
97 if ((textW = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR))))
99 HeapFree(GetProcessHeap(), 0, wndPtr->text);
100 wndPtr->text = textW;
101 MultiByteToWideChar( CP_ACP, 0, text, -1, textW, count );
102 SERVER_START_REQ( set_window_text )
104 req->handle = wine_server_user_handle( hwnd );
105 wine_server_add_data( req, textW, (count-1) * sizeof(WCHAR) );
106 wine_server_call( req );
108 SERVER_END_REQ;
110 else
111 ERR("Not enough memory for window text\n");
112 WIN_ReleasePtr( wndPtr );
114 USER_Driver->pSetWindowText( hwnd, textW );
116 return 1;
119 /***********************************************************************
120 * DEFWND_SetTextW
122 * Set the window text.
124 static LRESULT DEFWND_SetTextW( HWND hwnd, LPCWSTR text )
126 WND *wndPtr;
127 int count;
129 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
130 * may have child window IDs instead of window name */
131 if (text && IS_INTRESOURCE(text))
132 return 0;
134 if (!text) text = L"";
135 count = lstrlenW(text) + 1;
137 if (!(wndPtr = WIN_GetPtr( hwnd ))) return 0;
138 HeapFree(GetProcessHeap(), 0, wndPtr->text);
139 if ((wndPtr->text = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR))))
141 lstrcpyW( wndPtr->text, text );
142 SERVER_START_REQ( set_window_text )
144 req->handle = wine_server_user_handle( hwnd );
145 wine_server_add_data( req, wndPtr->text, (count-1) * sizeof(WCHAR) );
146 wine_server_call( req );
148 SERVER_END_REQ;
150 else
151 ERR("Not enough memory for window text\n");
152 text = wndPtr->text;
153 WIN_ReleasePtr( wndPtr );
155 USER_Driver->pSetWindowText( hwnd, text );
157 return 1;
160 /***********************************************************************
161 * DEFWND_ControlColor
163 * Default colors for control painting.
165 HBRUSH DEFWND_ControlColor( HDC hDC, UINT ctlType )
167 if( ctlType == CTLCOLOR_SCROLLBAR)
169 HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR);
170 COLORREF bk = GetSysColor(COLOR_3DHILIGHT);
171 SetTextColor( hDC, GetSysColor(COLOR_3DFACE));
172 SetBkColor( hDC, bk);
174 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
175 * we better use 0x55aa bitmap brush to make scrollbar's background
176 * look different from the window background.
178 if (bk == GetSysColor(COLOR_WINDOW))
179 return SYSCOLOR_Get55AABrush();
181 UnrealizeObject( hb );
182 return hb;
185 SetTextColor( hDC, GetSysColor(COLOR_WINDOWTEXT));
187 if ((ctlType == CTLCOLOR_EDIT) || (ctlType == CTLCOLOR_LISTBOX))
188 SetBkColor( hDC, GetSysColor(COLOR_WINDOW) );
189 else {
190 SetBkColor( hDC, GetSysColor(COLOR_3DFACE) );
191 return GetSysColorBrush(COLOR_3DFACE);
193 return GetSysColorBrush(COLOR_WINDOW);
197 /***********************************************************************
198 * DEFWND_Print
200 * This method handles the default behavior for the WM_PRINT message.
202 static void DEFWND_Print( HWND hwnd, HDC hdc, ULONG uFlags)
205 * Visibility flag.
207 if ( (uFlags & PRF_CHECKVISIBLE) &&
208 !IsWindowVisible(hwnd) )
209 return;
212 * Unimplemented flags.
214 if ( (uFlags & PRF_CHILDREN) ||
215 (uFlags & PRF_OWNED) ||
216 (uFlags & PRF_NONCLIENT) )
218 WARN("WM_PRINT message with unsupported flags\n");
222 * Background
224 if ( uFlags & PRF_ERASEBKGND)
225 SendMessageW(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0);
228 * Client area
230 if ( uFlags & PRF_CLIENT)
231 SendMessageW(hwnd, WM_PRINTCLIENT, (WPARAM)hdc, uFlags);
236 /***********************************************************************
237 * DEFWND_DefWinProc
239 * Default window procedure for messages that are the same in Ansi and Unicode.
241 static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
243 switch(msg)
245 case WM_NCPAINT:
246 return NC_HandleNCPaint( hwnd, (HRGN)wParam );
248 case WM_NCHITTEST:
250 POINT pt;
251 pt.x = (short)LOWORD(lParam);
252 pt.y = (short)HIWORD(lParam);
253 return NC_HandleNCHitTest( hwnd, pt );
256 case WM_NCCALCSIZE:
257 return NC_HandleNCCalcSize( hwnd, wParam, (RECT *)lParam );
259 case WM_WINDOWPOSCHANGING:
260 return WINPOS_HandleWindowPosChanging( hwnd, (WINDOWPOS *)lParam );
262 case WM_WINDOWPOSCHANGED:
263 DEFWND_HandleWindowPosChanged( hwnd, (const WINDOWPOS *)lParam );
264 break;
266 case WM_LBUTTONDOWN:
267 case WM_RBUTTONDOWN:
268 case WM_MBUTTONDOWN:
269 iF10Key = iMenuSysKey = 0;
270 break;
272 case WM_NCLBUTTONDOWN:
273 return NC_HandleNCLButtonDown( hwnd, wParam, lParam );
275 case WM_LBUTTONDBLCLK:
276 return NC_HandleNCLButtonDblClk( hwnd, HTCLIENT, lParam );
278 case WM_NCLBUTTONDBLCLK:
279 return NC_HandleNCLButtonDblClk( hwnd, wParam, lParam );
281 case WM_NCRBUTTONDOWN:
282 return NC_HandleNCRButtonDown( hwnd, wParam, lParam );
284 case WM_RBUTTONUP:
286 POINT pt;
287 pt.x = (short)LOWORD(lParam);
288 pt.y = (short)HIWORD(lParam);
289 ClientToScreen(hwnd, &pt);
290 SendMessageW( hwnd, WM_CONTEXTMENU, (WPARAM)hwnd, MAKELPARAM(pt.x, pt.y) );
292 break;
294 case WM_NCRBUTTONUP:
296 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
297 * in Windows), but what _should_ we do? According to MSDN :
298 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
299 * message to the window". When is it appropriate?
301 break;
303 case WM_XBUTTONUP:
304 case WM_NCXBUTTONUP:
305 if (HIWORD(wParam) == XBUTTON1 || HIWORD(wParam) == XBUTTON2)
307 SendMessageW(hwnd, WM_APPCOMMAND, (WPARAM)hwnd,
308 MAKELPARAM(LOWORD(wParam), FAPPCOMMAND_MOUSE | HIWORD(wParam)));
310 break;
312 case WM_CONTEXTMENU:
313 if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD)
314 SendMessageW( GetParent(hwnd), msg, wParam, lParam );
315 else
317 LONG hitcode;
318 POINT pt;
319 pt.x = (short)LOWORD(lParam);
320 pt.y = (short)HIWORD(lParam);
321 hitcode = NC_HandleNCHitTest(hwnd, pt);
323 /* Track system popup if click was in the caption area. */
324 if (hitcode==HTCAPTION || hitcode==HTSYSMENU)
325 TrackPopupMenu(GetSystemMenu(hwnd, FALSE),
326 TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
327 pt.x, pt.y, 0, hwnd, NULL);
329 break;
331 case WM_POPUPSYSTEMMENU:
332 /* This is an undocumented message used by the windows taskbar to
333 display the system menu of windows that belong to other processes. */
334 TrackPopupMenu( GetSystemMenu(hwnd, FALSE), TPM_LEFTBUTTON|TPM_RIGHTBUTTON,
335 (short)LOWORD(lParam), (short)HIWORD(lParam), 0, hwnd, NULL );
336 return 0;
338 case WM_NCACTIVATE:
339 return NC_HandleNCActivate( hwnd, wParam, lParam );
341 case WM_NCDESTROY:
343 WND *wndPtr = WIN_GetPtr( hwnd );
344 if (!wndPtr) return 0;
345 HeapFree( GetProcessHeap(), 0, wndPtr->text );
346 wndPtr->text = NULL;
347 HeapFree( GetProcessHeap(), 0, wndPtr->pScroll );
348 wndPtr->pScroll = NULL;
349 WIN_ReleasePtr( wndPtr );
350 return 0;
353 case WM_PRINT:
354 DEFWND_Print(hwnd, (HDC)wParam, lParam);
355 return 0;
357 case WM_PAINTICON:
358 case WM_PAINT:
360 PAINTSTRUCT ps;
361 HDC hdc = BeginPaint( hwnd, &ps );
362 if( hdc )
364 HICON hIcon;
365 if (IsIconic(hwnd) && ((hIcon = (HICON)GetClassLongPtrW( hwnd, GCLP_HICON))) )
367 RECT rc;
368 int x, y;
370 GetClientRect( hwnd, &rc );
371 x = (rc.right - rc.left - GetSystemMetrics(SM_CXICON))/2;
372 y = (rc.bottom - rc.top - GetSystemMetrics(SM_CYICON))/2;
373 TRACE("Painting class icon: vis rect=(%s)\n",
374 wine_dbgstr_rect(&ps.rcPaint));
375 DrawIcon( hdc, x, y, hIcon );
377 EndPaint( hwnd, &ps );
379 return 0;
382 case WM_SYNCPAINT:
383 RedrawWindow ( hwnd, NULL, 0, RDW_ERASENOW | RDW_ERASE | RDW_ALLCHILDREN );
384 return 0;
386 case WM_SETREDRAW:
387 if (wParam) WIN_SetStyle( hwnd, WS_VISIBLE, 0 );
388 else
390 RedrawWindow( hwnd, NULL, 0, RDW_ALLCHILDREN | RDW_VALIDATE );
391 WIN_SetStyle( hwnd, 0, WS_VISIBLE );
393 return 0;
395 case WM_CLOSE:
396 DestroyWindow( hwnd );
397 return 0;
399 case WM_MOUSEACTIVATE:
400 if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD)
402 LONG ret = SendMessageW( GetParent(hwnd), WM_MOUSEACTIVATE, wParam, lParam );
403 if (ret) return ret;
406 /* Caption clicks are handled by NC_HandleNCLButtonDown() */
407 return ( HIWORD(lParam) == WM_LBUTTONDOWN && LOWORD(lParam) == HTCAPTION ? MA_NOACTIVATE : MA_ACTIVATE );
409 case WM_ACTIVATE:
410 /* The default action in Windows is to set the keyboard focus to
411 * the window, if it's being activated and not minimized */
412 if (LOWORD(wParam) != WA_INACTIVE) {
413 if (!IsIconic(hwnd)) SetFocus(hwnd);
415 break;
417 case WM_MOUSEWHEEL:
418 if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD)
419 return SendMessageW( GetParent(hwnd), WM_MOUSEWHEEL, wParam, lParam );
420 break;
422 case WM_ERASEBKGND:
423 case WM_ICONERASEBKGND:
425 RECT rect;
426 HDC hdc = (HDC)wParam;
427 HBRUSH hbr = (HBRUSH)GetClassLongPtrW( hwnd, GCLP_HBRBACKGROUND );
428 if (!hbr) return 0;
430 if (GetClassLongW( hwnd, GCL_STYLE ) & CS_PARENTDC)
432 /* can't use GetClipBox with a parent DC or we fill the whole parent */
433 GetClientRect( hwnd, &rect );
434 DPtoLP( hdc, (LPPOINT)&rect, 2 );
436 else GetClipBox( hdc, &rect );
437 FillRect( hdc, &rect, hbr );
438 return 1;
441 case WM_GETDLGCODE:
442 return 0;
444 case WM_CTLCOLORMSGBOX:
445 case WM_CTLCOLOREDIT:
446 case WM_CTLCOLORLISTBOX:
447 case WM_CTLCOLORBTN:
448 case WM_CTLCOLORDLG:
449 case WM_CTLCOLORSTATIC:
450 case WM_CTLCOLORSCROLLBAR:
451 return (LRESULT)DEFWND_ControlColor( (HDC)wParam, msg - WM_CTLCOLORMSGBOX );
453 case WM_CTLCOLOR:
454 return (LRESULT)DEFWND_ControlColor( (HDC)wParam, HIWORD(lParam) );
456 case WM_SETCURSOR:
457 if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD)
459 /* with the exception of the border around a resizable wnd,
460 * give the parent first chance to set the cursor */
461 if ((LOWORD(lParam) < HTSIZEFIRST) || (LOWORD(lParam) > HTSIZELAST))
463 HWND parent = GetParent( hwnd );
464 if (parent != GetDesktopWindow() &&
465 SendMessageW( parent, WM_SETCURSOR, wParam, lParam )) return TRUE;
468 NC_HandleSetCursor( hwnd, wParam, lParam );
469 break;
471 case WM_SYSCOMMAND:
472 return NC_HandleSysCommand( hwnd, wParam, lParam );
474 case WM_KEYDOWN:
475 if(wParam == VK_F10) iF10Key = VK_F10;
476 break;
478 case WM_SYSKEYDOWN:
479 if( HIWORD(lParam) & KEYDATA_ALT )
481 /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */
482 if ( (wParam == VK_MENU || wParam == VK_LMENU
483 || wParam == VK_RMENU) && !iMenuSysKey )
484 iMenuSysKey = 1;
485 else
486 iMenuSysKey = 0;
488 iF10Key = 0;
490 if( wParam == VK_F4 ) /* try to close the window */
492 HWND top = GetAncestor( hwnd, GA_ROOT );
493 if (!(GetClassLongW( top, GCL_STYLE ) & CS_NOCLOSE))
494 PostMessageW( top, WM_SYSCOMMAND, SC_CLOSE, 0 );
497 else if( wParam == VK_F10 )
499 if (GetKeyState(VK_SHIFT) & 0x8000)
500 SendMessageW( hwnd, WM_CONTEXTMENU, (WPARAM)hwnd, -1 );
501 iF10Key = 1;
503 else if( wParam == VK_ESCAPE && (GetKeyState(VK_SHIFT) & 0x8000))
504 SendMessageW( hwnd, WM_SYSCOMMAND, SC_KEYMENU, ' ' );
505 break;
507 case WM_KEYUP:
508 case WM_SYSKEYUP:
509 /* Press and release F10 or ALT */
510 if (((wParam == VK_MENU || wParam == VK_LMENU || wParam == VK_RMENU)
511 && iMenuSysKey) || ((wParam == VK_F10) && iF10Key))
512 SendMessageW( GetAncestor( hwnd, GA_ROOT ), WM_SYSCOMMAND, SC_KEYMENU, 0L );
513 iMenuSysKey = iF10Key = 0;
514 break;
516 case WM_SYSCHAR:
518 iMenuSysKey = 0;
519 if (wParam == '\r' && IsIconic(hwnd))
521 PostMessageW( hwnd, WM_SYSCOMMAND, SC_RESTORE, 0L );
522 break;
524 if ((HIWORD(lParam) & KEYDATA_ALT) && wParam)
526 if (wParam == '\t' || wParam == '\x1b') break;
527 if (wParam == ' ' && (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD))
528 SendMessageW( GetParent(hwnd), msg, wParam, lParam );
529 else
530 SendMessageW( hwnd, WM_SYSCOMMAND, SC_KEYMENU, wParam );
532 else /* check for Ctrl-Esc */
533 if (wParam != '\x1b') MessageBeep(0);
534 break;
537 case WM_SHOWWINDOW:
539 LONG style = GetWindowLongW( hwnd, GWL_STYLE );
540 WND *pWnd;
541 if (!lParam) return 0; /* sent from ShowWindow */
542 if ((style & WS_VISIBLE) && wParam) return 0;
543 if (!(style & WS_VISIBLE) && !wParam) return 0;
544 if (!GetWindow( hwnd, GW_OWNER )) return 0;
545 if (!(pWnd = WIN_GetPtr( hwnd ))) return 0;
546 if (pWnd == WND_OTHER_PROCESS) return 0;
547 if (wParam)
549 if (!(pWnd->flags & WIN_NEEDS_SHOW_OWNEDPOPUP))
551 WIN_ReleasePtr( pWnd );
552 return 0;
554 pWnd->flags &= ~WIN_NEEDS_SHOW_OWNEDPOPUP;
556 else pWnd->flags |= WIN_NEEDS_SHOW_OWNEDPOPUP;
557 WIN_ReleasePtr( pWnd );
558 ShowWindow( hwnd, wParam ? SW_SHOWNOACTIVATE : SW_HIDE );
559 break;
562 case WM_CANCELMODE:
563 iMenuSysKey = 0;
564 MENU_EndMenu( hwnd );
565 if (GetCapture() == hwnd) ReleaseCapture();
566 break;
568 case WM_VKEYTOITEM:
569 case WM_CHARTOITEM:
570 return -1;
572 case WM_DROPOBJECT:
573 return DRAG_FILE;
575 case WM_QUERYDROPOBJECT:
576 return (GetWindowLongA( hwnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES) != 0;
578 case WM_QUERYDRAGICON:
580 UINT len;
582 HICON hIcon = (HICON)GetClassLongPtrW( hwnd, GCLP_HICON );
583 HINSTANCE instance = (HINSTANCE)GetWindowLongPtrW( hwnd, GWLP_HINSTANCE );
584 if (hIcon) return (LRESULT)hIcon;
585 for(len=1; len<64; len++)
586 if((hIcon = LoadIconW(instance, MAKEINTRESOURCEW(len))))
587 return (LRESULT)hIcon;
588 return (LRESULT)LoadIconW(0, (LPWSTR)IDI_APPLICATION);
590 break;
592 case WM_ISACTIVEICON:
593 return (win_get_flags( hwnd ) & WIN_NCACTIVATED) != 0;
595 case WM_NOTIFYFORMAT:
596 if (IsWindowUnicode(hwnd)) return NFR_UNICODE;
597 else return NFR_ANSI;
599 case WM_QUERYOPEN:
600 case WM_QUERYENDSESSION:
601 return 1;
603 case WM_SETICON:
605 HICON ret;
606 WND *wndPtr = WIN_GetPtr( hwnd );
608 switch(wParam)
610 case ICON_SMALL:
611 ret = wndPtr->hIconSmall;
612 if (ret && !lParam && wndPtr->hIcon)
614 wndPtr->hIconSmall2 = CopyImage( wndPtr->hIcon, IMAGE_ICON,
615 GetSystemMetrics( SM_CXSMICON ),
616 GetSystemMetrics( SM_CYSMICON ), 0 );
618 else if (lParam && wndPtr->hIconSmall2)
620 DestroyIcon( wndPtr->hIconSmall2 );
621 wndPtr->hIconSmall2 = NULL;
623 wndPtr->hIconSmall = (HICON)lParam;
624 break;
625 case ICON_BIG:
626 ret = wndPtr->hIcon;
627 if (wndPtr->hIconSmall2)
629 DestroyIcon( wndPtr->hIconSmall2 );
630 wndPtr->hIconSmall2 = NULL;
632 if (lParam && !wndPtr->hIconSmall)
634 wndPtr->hIconSmall2 = CopyImage( (HICON)lParam, IMAGE_ICON,
635 GetSystemMetrics( SM_CXSMICON ),
636 GetSystemMetrics( SM_CYSMICON ), 0 );
638 wndPtr->hIcon = (HICON)lParam;
639 break;
640 default:
641 ret = 0;
642 break;
644 WIN_ReleasePtr( wndPtr );
646 USER_Driver->pSetWindowIcon( hwnd, wParam, (HICON)lParam );
648 if( (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CAPTION) == WS_CAPTION )
649 NC_HandleNCPaint( hwnd , (HRGN)1 ); /* Repaint caption */
651 return (LRESULT)ret;
654 case WM_GETICON:
656 HICON ret;
657 WND *wndPtr = WIN_GetPtr( hwnd );
659 switch(wParam)
661 case ICON_SMALL:
662 ret = wndPtr->hIconSmall;
663 break;
664 case ICON_BIG:
665 ret = wndPtr->hIcon;
666 break;
667 case ICON_SMALL2:
668 ret = wndPtr->hIconSmall ? wndPtr->hIconSmall : wndPtr->hIconSmall2;
669 break;
670 default:
671 ret = 0;
672 break;
674 WIN_ReleasePtr( wndPtr );
675 return (LRESULT)ret;
678 case WM_HELP:
679 SendMessageW( GetParent(hwnd), msg, wParam, lParam );
680 break;
682 case WM_STYLECHANGED:
683 if (wParam == GWL_STYLE && (GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYERED))
685 STYLESTRUCT *style = (STYLESTRUCT *)lParam;
686 if ((style->styleOld ^ style->styleNew) & (WS_CAPTION|WS_THICKFRAME|WS_VSCROLL|WS_HSCROLL))
687 SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER |
688 SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE );
690 break;
692 case WM_APPCOMMAND:
694 HWND parent = GetParent(hwnd);
695 if(!parent)
696 HOOK_CallHooks(WH_SHELL, HSHELL_APPCOMMAND, wParam, lParam, TRUE);
697 else
698 SendMessageW( parent, msg, wParam, lParam );
699 break;
701 case WM_KEYF1:
703 HELPINFO hi;
705 hi.cbSize = sizeof(HELPINFO);
706 GetCursorPos( &hi.MousePos );
707 if (MENU_IsMenuActive())
709 hi.iContextType = HELPINFO_MENUITEM;
710 hi.hItemHandle = MENU_IsMenuActive();
711 hi.iCtrlId = MenuItemFromPoint( hwnd, hi.hItemHandle, hi.MousePos );
712 hi.dwContextId = GetMenuContextHelpId( hi.hItemHandle );
714 else
716 hi.iContextType = HELPINFO_WINDOW;
717 hi.hItemHandle = hwnd;
718 hi.iCtrlId = GetWindowLongPtrA( hwnd, GWLP_ID );
719 hi.dwContextId = GetWindowContextHelpId( hwnd );
721 SendMessageW( hwnd, WM_HELP, 0, (LPARAM)&hi );
722 break;
725 case WM_INPUTLANGCHANGEREQUEST:
726 ActivateKeyboardLayout( (HKL)lParam, 0 );
727 break;
729 case WM_INPUTLANGCHANGE:
731 int count = 0;
732 HWND *win_array = WIN_ListChildren( hwnd );
734 if (!win_array)
735 break;
736 while (win_array[count])
737 SendMessageW( win_array[count++], WM_INPUTLANGCHANGE, wParam, lParam);
738 HeapFree(GetProcessHeap(),0,win_array);
739 break;
744 return 0;
747 static LPARAM DEFWND_GetTextA( WND *wndPtr, LPSTR dest, WPARAM wParam )
749 LPARAM result = 0;
751 __TRY
753 if (wndPtr->text)
755 if (!WideCharToMultiByte( CP_ACP, 0, wndPtr->text, -1,
756 dest, wParam, NULL, NULL )) dest[wParam-1] = 0;
757 result = strlen( dest );
759 else dest[0] = '\0';
761 __EXCEPT_PAGE_FAULT
763 return 0;
765 __ENDTRY
766 return result;
769 /***********************************************************************
770 * DefWindowProcA (USER32.@)
772 * See DefWindowProcW.
774 LRESULT WINAPI DefWindowProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
776 LRESULT result = 0;
777 HWND full_handle;
779 if (!(full_handle = WIN_IsCurrentProcess( hwnd )))
781 if (!IsWindow( hwnd )) return 0;
782 ERR( "called for other process window %p\n", hwnd );
783 return 0;
785 hwnd = full_handle;
787 SPY_EnterMessage( SPY_DEFWNDPROC, hwnd, msg, wParam, lParam );
789 switch(msg)
791 case WM_NCCREATE:
792 if (lParam)
794 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
796 DEFWND_SetTextA( hwnd, cs->lpszName );
797 result = 1;
799 if(cs->style & (WS_HSCROLL | WS_VSCROLL))
801 SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0};
802 SetScrollInfo( hwnd, SB_HORZ, &si, FALSE );
803 SetScrollInfo( hwnd, SB_VERT, &si, FALSE );
806 break;
808 case WM_GETTEXTLENGTH:
810 WND *wndPtr = WIN_GetPtr( hwnd );
811 if (wndPtr && wndPtr->text)
812 result = WideCharToMultiByte( CP_ACP, 0, wndPtr->text, lstrlenW(wndPtr->text),
813 NULL, 0, NULL, NULL );
814 WIN_ReleasePtr( wndPtr );
816 break;
818 case WM_GETTEXT:
819 if (wParam)
821 LPSTR dest = (LPSTR)lParam;
822 WND *wndPtr = WIN_GetPtr( hwnd );
824 if (!wndPtr) break;
825 result = DEFWND_GetTextA( wndPtr, dest, wParam );
827 WIN_ReleasePtr( wndPtr );
829 break;
831 case WM_SETTEXT:
832 if (!DEFWND_SetTextA( hwnd, (LPCSTR)lParam ))
833 break;
834 if( (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CAPTION) == WS_CAPTION )
835 NC_HandleNCPaint( hwnd , (HRGN)1 ); /* Repaint caption */
836 result = 1; /* success. FIXME: check text length */
837 break;
839 case WM_IME_CHAR:
840 if (HIBYTE(wParam)) PostMessageA( hwnd, WM_CHAR, HIBYTE(wParam), lParam );
841 PostMessageA( hwnd, WM_CHAR, LOBYTE(wParam), lParam );
842 break;
844 case WM_IME_KEYDOWN:
845 result = PostMessageA( hwnd, WM_KEYDOWN, wParam, lParam );
846 break;
848 case WM_IME_KEYUP:
849 result = PostMessageA( hwnd, WM_KEYUP, wParam, lParam );
850 break;
852 case WM_IME_COMPOSITION:
853 if (lParam & GCS_RESULTSTR)
855 LONG size, i;
856 unsigned char lead = 0;
857 char *buf = NULL;
858 HIMC himc = ImmGetContext( hwnd );
860 if (himc)
862 if ((size = ImmGetCompositionStringA( himc, GCS_RESULTSTR, NULL, 0 )))
864 if (!(buf = HeapAlloc( GetProcessHeap(), 0, size ))) size = 0;
865 else size = ImmGetCompositionStringA( himc, GCS_RESULTSTR, buf, size );
867 ImmReleaseContext( hwnd, himc );
869 for (i = 0; i < size; i++)
871 unsigned char c = buf[i];
872 if (!lead)
874 if (IsDBCSLeadByte( c ))
875 lead = c;
876 else
877 SendMessageA( hwnd, WM_IME_CHAR, c, 1 );
879 else
881 SendMessageA( hwnd, WM_IME_CHAR, MAKEWORD(c, lead), 1 );
882 lead = 0;
885 HeapFree( GetProcessHeap(), 0, buf );
888 /* fall through */
889 case WM_IME_STARTCOMPOSITION:
890 case WM_IME_ENDCOMPOSITION:
891 case WM_IME_SELECT:
892 case WM_IME_NOTIFY:
893 case WM_IME_CONTROL:
895 HWND hwndIME = ImmGetDefaultIMEWnd( hwnd );
896 if (hwndIME)
897 result = SendMessageA( hwndIME, msg, wParam, lParam );
899 break;
900 case WM_IME_SETCONTEXT:
902 HWND hwndIME = ImmGetDefaultIMEWnd( hwnd );
903 if (hwndIME) result = ImmIsUIMessageA( hwndIME, msg, wParam, lParam );
905 break;
907 case WM_SYSCHAR:
909 CHAR ch = LOWORD(wParam);
910 WCHAR wch;
911 MultiByteToWideChar(CP_ACP, 0, &ch, 1, &wch, 1);
912 wParam = MAKEWPARAM( wch, HIWORD(wParam) );
914 /* fall through */
915 default:
916 result = DEFWND_DefWinProc( hwnd, msg, wParam, lParam );
917 break;
920 SPY_ExitMessage( SPY_RESULT_DEFWND, hwnd, msg, result, wParam, lParam );
921 return result;
925 static LPARAM DEFWND_GetTextW( WND *wndPtr, LPWSTR dest, WPARAM wParam )
927 LPARAM result = 0;
929 __TRY
931 if (wndPtr->text)
933 lstrcpynW( dest, wndPtr->text, wParam );
934 result = lstrlenW( dest );
936 else dest[0] = '\0';
938 __EXCEPT_PAGE_FAULT
940 return 0;
942 __ENDTRY
944 return result;
947 /***********************************************************************
948 * DefWindowProcW (USER32.@) Calls default window message handler
950 * Calls default window procedure for messages not processed
951 * by application.
953 * RETURNS
954 * Return value is dependent upon the message.
956 LRESULT WINAPI DefWindowProcW(
957 HWND hwnd, /* [in] window procedure receiving message */
958 UINT msg, /* [in] message identifier */
959 WPARAM wParam, /* [in] first message parameter */
960 LPARAM lParam ) /* [in] second message parameter */
962 LRESULT result = 0;
963 HWND full_handle;
965 if (!(full_handle = WIN_IsCurrentProcess( hwnd )))
967 if (!IsWindow( hwnd )) return 0;
968 ERR( "called for other process window %p\n", hwnd );
969 return 0;
971 hwnd = full_handle;
972 SPY_EnterMessage( SPY_DEFWNDPROC, hwnd, msg, wParam, lParam );
974 switch(msg)
976 case WM_NCCREATE:
977 if (lParam)
979 CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
981 DEFWND_SetTextW( hwnd, cs->lpszName );
982 result = 1;
984 if(cs->style & (WS_HSCROLL | WS_VSCROLL))
986 SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0};
987 SetScrollInfo( hwnd, SB_HORZ, &si, FALSE );
988 SetScrollInfo( hwnd, SB_VERT, &si, FALSE );
991 break;
993 case WM_GETTEXTLENGTH:
995 WND *wndPtr = WIN_GetPtr( hwnd );
996 if (wndPtr && wndPtr->text) result = (LRESULT)lstrlenW(wndPtr->text);
997 WIN_ReleasePtr( wndPtr );
999 break;
1001 case WM_GETTEXT:
1002 if (wParam)
1004 LPWSTR dest = (LPWSTR)lParam;
1005 WND *wndPtr = WIN_GetPtr( hwnd );
1007 if (!wndPtr) break;
1008 result = DEFWND_GetTextW( wndPtr, dest, wParam );
1009 WIN_ReleasePtr( wndPtr );
1011 break;
1013 case WM_SETTEXT:
1014 if (!DEFWND_SetTextW( hwnd, (LPCWSTR)lParam ))
1015 break;
1016 if( (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CAPTION) == WS_CAPTION )
1017 NC_HandleNCPaint( hwnd , (HRGN)1 ); /* Repaint caption */
1018 result = 1; /* success. FIXME: check text length */
1019 break;
1021 case WM_IME_CHAR:
1022 PostMessageW( hwnd, WM_CHAR, wParam, lParam );
1023 break;
1025 case WM_IME_KEYDOWN:
1026 result = PostMessageW( hwnd, WM_KEYDOWN, wParam, lParam );
1027 break;
1029 case WM_IME_KEYUP:
1030 result = PostMessageW( hwnd, WM_KEYUP, wParam, lParam );
1031 break;
1033 case WM_IME_SETCONTEXT:
1035 HWND hwndIME = ImmGetDefaultIMEWnd( hwnd );
1036 if (hwndIME) result = ImmIsUIMessageW( hwndIME, msg, wParam, lParam );
1038 break;
1040 case WM_IME_COMPOSITION:
1041 if (lParam & GCS_RESULTSTR)
1043 LONG size, i;
1044 WCHAR *buf = NULL;
1045 HIMC himc = ImmGetContext( hwnd );
1047 if (himc)
1049 if ((size = ImmGetCompositionStringW( himc, GCS_RESULTSTR, NULL, 0 )))
1051 if (!(buf = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) size = 0;
1052 else size = ImmGetCompositionStringW( himc, GCS_RESULTSTR, buf, size * sizeof(WCHAR) );
1054 ImmReleaseContext( hwnd, himc );
1056 for (i = 0; i < size / sizeof(WCHAR); i++)
1057 SendMessageW( hwnd, WM_IME_CHAR, buf[i], 1 );
1058 HeapFree( GetProcessHeap(), 0, buf );
1061 /* fall through */
1062 case WM_IME_STARTCOMPOSITION:
1063 case WM_IME_ENDCOMPOSITION:
1064 case WM_IME_SELECT:
1065 case WM_IME_NOTIFY:
1066 case WM_IME_CONTROL:
1068 HWND hwndIME = ImmGetDefaultIMEWnd( hwnd );
1069 if (hwndIME)
1070 result = SendMessageW( hwndIME, msg, wParam, lParam );
1072 break;
1074 default:
1075 result = DEFWND_DefWinProc( hwnd, msg, wParam, lParam );
1076 break;
1078 SPY_ExitMessage( SPY_RESULT_DEFWND, hwnd, msg, result, wParam, lParam );
1079 return result;