Some broken games do not put the TEXTURE flags in the surface caps.
[wine/multimedia.git] / windows / defwnd.c
blobbe2864c49f6521467a1bb638749618e8d9a7ec9a
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <string.h>
24 #include "win.h"
25 #include "user.h"
26 #include "nonclient.h"
27 #include "winpos.h"
28 #include "dce.h"
29 #include "windef.h"
30 #include "wingdi.h"
31 #include "winnls.h"
32 #include "imm.h"
33 #include "message.h"
34 #include "wine/unicode.h"
35 #include "wine/winuser16.h"
36 #include "wine/server.h"
37 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(win);
41 /* bits in the dwKeyData */
42 #define KEYDATA_ALT 0x2000
43 #define KEYDATA_PREVSTATE 0x4000
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, UINT flags )
55 RECT rect;
56 WND *wndPtr = WIN_GetPtr( hwnd );
58 rect = wndPtr->rectClient;
59 WIN_ReleasePtr( wndPtr );
61 if (!(flags & SWP_NOCLIENTMOVE))
62 SendMessageW( hwnd, WM_MOVE, 0, MAKELONG(rect.left, rect.top));
64 if (!(flags & SWP_NOCLIENTSIZE))
66 WPARAM wp = SIZE_RESTORED;
67 if (IsZoomed(hwnd)) wp = SIZE_MAXIMIZED;
68 else if (IsIconic(hwnd)) wp = SIZE_MINIMIZED;
70 SendMessageW( hwnd, WM_SIZE, wp, MAKELONG(rect.right-rect.left, rect.bottom-rect.top) );
75 /***********************************************************************
76 * DEFWND_SetTextA
78 * Set the window text.
80 static void DEFWND_SetTextA( HWND hwnd, LPCSTR text )
82 int count;
83 WCHAR *textW;
84 WND *wndPtr;
86 if (!text) text = "";
87 count = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 );
89 if (!(wndPtr = WIN_GetPtr( hwnd ))) return;
90 if ((textW = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR))))
92 if (wndPtr->text) HeapFree(GetProcessHeap(), 0, wndPtr->text);
93 wndPtr->text = textW;
94 MultiByteToWideChar( CP_ACP, 0, text, -1, textW, count );
95 SERVER_START_REQ( set_window_text )
97 req->handle = hwnd;
98 wine_server_add_data( req, textW, (count-1) * sizeof(WCHAR) );
99 wine_server_call( req );
101 SERVER_END_REQ;
103 else
104 ERR("Not enough memory for window text\n");
105 WIN_ReleasePtr( wndPtr );
107 if (USER_Driver.pSetWindowText) USER_Driver.pSetWindowText( hwnd, textW );
110 /***********************************************************************
111 * DEFWND_SetTextW
113 * Set the window text.
115 static void DEFWND_SetTextW( HWND hwnd, LPCWSTR text )
117 static const WCHAR empty_string[] = {0};
118 WND *wndPtr;
119 int count;
121 if (!text) text = empty_string;
122 count = strlenW(text) + 1;
124 if (!(wndPtr = WIN_GetPtr( hwnd ))) return;
125 if (wndPtr->text) HeapFree(GetProcessHeap(), 0, wndPtr->text);
126 if ((wndPtr->text = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR))))
128 strcpyW( wndPtr->text, text );
129 SERVER_START_REQ( set_window_text )
131 req->handle = hwnd;
132 wine_server_add_data( req, wndPtr->text, (count-1) * sizeof(WCHAR) );
133 wine_server_call( req );
135 SERVER_END_REQ;
137 else
138 ERR("Not enough memory for window text\n");
139 text = wndPtr->text;
140 WIN_ReleasePtr( wndPtr );
142 if (USER_Driver.pSetWindowText) USER_Driver.pSetWindowText( hwnd, text );
145 /***********************************************************************
146 * DEFWND_ControlColor
148 * Default colors for control painting.
150 HBRUSH DEFWND_ControlColor( HDC hDC, UINT ctlType )
152 if( ctlType == CTLCOLOR_SCROLLBAR)
154 HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR);
155 if (TWEAK_WineLook == WIN31_LOOK) {
156 SetTextColor( hDC, RGB(0, 0, 0) );
157 SetBkColor( hDC, RGB(255, 255, 255) );
158 } else {
159 COLORREF bk = GetSysColor(COLOR_3DHILIGHT);
160 SetTextColor( hDC, GetSysColor(COLOR_3DFACE));
161 SetBkColor( hDC, bk);
163 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
164 * we better use 0x55aa bitmap brush to make scrollbar's background
165 * look different from the window background.
167 if (bk == GetSysColor(COLOR_WINDOW)) {
168 return CACHE_GetPattern55AABrush();
171 UnrealizeObject( hb );
172 return hb;
175 SetTextColor( hDC, GetSysColor(COLOR_WINDOWTEXT));
177 if (TWEAK_WineLook > WIN31_LOOK) {
178 if ((ctlType == CTLCOLOR_EDIT) || (ctlType == CTLCOLOR_LISTBOX))
179 SetBkColor( hDC, GetSysColor(COLOR_WINDOW) );
180 else {
181 SetBkColor( hDC, GetSysColor(COLOR_3DFACE) );
182 return GetSysColorBrush(COLOR_3DFACE);
185 else
186 SetBkColor( hDC, GetSysColor(COLOR_WINDOW) );
187 return GetSysColorBrush(COLOR_WINDOW);
191 /***********************************************************************
192 * DEFWND_SetRedraw
194 static void DEFWND_SetRedraw( HWND hwnd, WPARAM wParam )
196 WND *wndPtr = WIN_FindWndPtr( hwnd );
197 BOOL bVisible = wndPtr->dwStyle & WS_VISIBLE;
199 TRACE("%p %i\n", hwnd, (wParam!=0) );
201 if( wParam )
203 if( !bVisible )
205 WIN_SetStyle( hwnd, wndPtr->dwStyle | WS_VISIBLE );
206 DCE_InvalidateDCE( hwnd, &wndPtr->rectWindow );
209 else if( bVisible )
211 if( wndPtr->dwStyle & WS_MINIMIZE ) wParam = RDW_VALIDATE;
212 else wParam = RDW_ALLCHILDREN | RDW_VALIDATE;
214 RedrawWindow( hwnd, NULL, 0, wParam );
215 DCE_InvalidateDCE( hwnd, &wndPtr->rectWindow );
216 WIN_SetStyle( hwnd, wndPtr->dwStyle & ~WS_VISIBLE );
218 WIN_ReleaseWndPtr( wndPtr );
221 /***********************************************************************
222 * DEFWND_Print
224 * This method handles the default behavior for the WM_PRINT message.
226 static void DEFWND_Print( HWND hwnd, HDC hdc, ULONG uFlags)
229 * Visibility flag.
231 if ( (uFlags & PRF_CHECKVISIBLE) &&
232 !IsWindowVisible(hwnd) )
233 return;
236 * Unimplemented flags.
238 if ( (uFlags & PRF_CHILDREN) ||
239 (uFlags & PRF_OWNED) ||
240 (uFlags & PRF_NONCLIENT) )
242 WARN("WM_PRINT message with unsupported flags\n");
246 * Background
248 if ( uFlags & PRF_ERASEBKGND)
249 SendMessageW(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0);
252 * Client area
254 if ( uFlags & PRF_CLIENT)
255 SendMessageW(hwnd, WM_PRINTCLIENT, (WPARAM)hdc, PRF_CLIENT);
260 * helpers for calling IMM32
262 * WM_IME_* messages are generated only by IMM32,
263 * so I assume imm32 is already LoadLibrary-ed.
265 static HWND DEFWND_ImmGetDefaultIMEWnd( HWND hwnd )
267 HINSTANCE hInstIMM = GetModuleHandleA( "imm32" );
268 HWND (WINAPI *pFunc)(HWND);
269 HWND hwndRet = 0;
271 if (!hInstIMM)
273 ERR( "cannot get IMM32 handle\n" );
274 return 0;
277 pFunc = (void*)GetProcAddress(hInstIMM,"ImmGetDefaultIMEWnd");
278 if ( pFunc != NULL )
279 hwndRet = (*pFunc)( hwnd );
281 return hwndRet;
284 static BOOL DEFWND_ImmIsUIMessageA( HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam )
286 HINSTANCE hInstIMM = GetModuleHandleA( "imm32" );
287 BOOL (WINAPI *pFunc)(HWND,UINT,WPARAM,LPARAM);
288 BOOL fRet = FALSE;
290 if (!hInstIMM)
292 ERR( "cannot get IMM32 handle\n" );
293 return FALSE;
296 pFunc = (void*)GetProcAddress(hInstIMM,"ImmIsUIMessageA");
297 if ( pFunc != NULL )
298 fRet = (*pFunc)( hwndIME, msg, wParam, lParam );
300 return fRet;
303 static BOOL DEFWND_ImmIsUIMessageW( HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam )
305 HINSTANCE hInstIMM = GetModuleHandleA( "imm32" );
306 BOOL (WINAPI *pFunc)(HWND,UINT,WPARAM,LPARAM);
307 BOOL fRet = FALSE;
309 if (!hInstIMM)
311 ERR( "cannot get IMM32 handle\n" );
312 return FALSE;
315 pFunc = (void*)GetProcAddress(hInstIMM,"ImmIsUIMessageW");
316 if ( pFunc != NULL )
317 fRet = (*pFunc)( hwndIME, msg, wParam, lParam );
319 return fRet;
324 /***********************************************************************
325 * DEFWND_DefWinProc
327 * Default window procedure for messages that are the same in Win16 and Win32.
329 static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
331 switch(msg)
333 case WM_NCPAINT:
334 return NC_HandleNCPaint( hwnd, (HRGN)wParam );
336 case WM_NCHITTEST:
338 POINT pt;
339 pt.x = SLOWORD(lParam);
340 pt.y = SHIWORD(lParam);
341 return NC_HandleNCHitTest( hwnd, pt );
344 case WM_NCLBUTTONDOWN:
345 return NC_HandleNCLButtonDown( hwnd, wParam, lParam );
347 case WM_LBUTTONDBLCLK:
348 case WM_NCLBUTTONDBLCLK:
349 return NC_HandleNCLButtonDblClk( hwnd, wParam, lParam );
351 case WM_NCRBUTTONDOWN:
352 /* in Windows, capture is taken when right-clicking on the caption bar */
353 if (wParam==HTCAPTION)
355 SetCapture(hwnd);
357 break;
359 case WM_RBUTTONUP:
361 POINT pt;
363 if (hwnd == GetCapture())
364 /* release capture if we took it on WM_NCRBUTTONDOWN */
365 ReleaseCapture();
367 pt.x = SLOWORD(lParam);
368 pt.y = SHIWORD(lParam);
369 ClientToScreen(hwnd, &pt);
370 SendMessageW( hwnd, WM_CONTEXTMENU, (WPARAM)hwnd, MAKELPARAM(pt.x, pt.y) );
372 break;
374 case WM_NCRBUTTONUP:
376 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
377 * in Windows), but what _should_ we do? According to MSDN :
378 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
379 * message to the window". When is it appropriate?
381 break;
383 case WM_CONTEXTMENU:
384 if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD)
385 SendMessageW( GetParent(hwnd), msg, wParam, lParam );
386 else
388 LONG hitcode;
389 POINT pt;
390 WND *wndPtr = WIN_GetPtr( hwnd );
391 HMENU hMenu = wndPtr->hSysMenu;
392 WIN_ReleasePtr( wndPtr );
393 if (!hMenu) return 0;
394 pt.x = SLOWORD(lParam);
395 pt.y = SHIWORD(lParam);
396 hitcode = NC_HandleNCHitTest(hwnd, pt);
398 /* Track system popup if click was in the caption area. */
399 if (hitcode==HTCAPTION || hitcode==HTSYSMENU)
400 TrackPopupMenu(GetSystemMenu(hwnd, FALSE),
401 TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
402 pt.x, pt.y, 0, hwnd, NULL);
404 break;
406 case WM_NCACTIVATE:
407 return NC_HandleNCActivate( hwnd, wParam );
409 case WM_NCDESTROY:
411 WND *wndPtr = WIN_GetPtr( hwnd );
412 if (!wndPtr) return 0;
413 if (wndPtr->text) HeapFree( GetProcessHeap(), 0, wndPtr->text );
414 wndPtr->text = NULL;
415 if (wndPtr->pVScroll) HeapFree( GetProcessHeap(), 0, wndPtr->pVScroll );
416 if (wndPtr->pHScroll) HeapFree( GetProcessHeap(), 0, wndPtr->pHScroll );
417 wndPtr->pVScroll = wndPtr->pHScroll = NULL;
418 WIN_ReleasePtr( wndPtr );
419 return 0;
422 case WM_PRINT:
423 DEFWND_Print(hwnd, (HDC)wParam, lParam);
424 return 0;
426 case WM_PAINTICON:
427 case WM_PAINT:
429 PAINTSTRUCT ps;
430 HDC hdc = BeginPaint( hwnd, &ps );
431 if( hdc )
433 HICON hIcon;
434 if (IsIconic(hwnd) && ((hIcon = (HICON)GetClassLongW( hwnd, GCL_HICON))) )
436 RECT rc;
437 int x, y;
439 GetClientRect( hwnd, &rc );
440 x = (rc.right - rc.left - GetSystemMetrics(SM_CXICON))/2;
441 y = (rc.bottom - rc.top - GetSystemMetrics(SM_CYICON))/2;
442 TRACE("Painting class icon: vis rect=(%ld,%ld - %ld,%ld)\n",
443 ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom );
444 DrawIcon( hdc, x, y, hIcon );
446 EndPaint( hwnd, &ps );
448 return 0;
451 case WM_SYNCPAINT:
452 RedrawWindow ( hwnd, NULL, 0, RDW_ERASENOW | RDW_ERASE | RDW_ALLCHILDREN );
453 return 0;
455 case WM_SETREDRAW:
456 DEFWND_SetRedraw( hwnd, wParam );
457 return 0;
459 case WM_CLOSE:
460 DestroyWindow( hwnd );
461 return 0;
463 case WM_MOUSEACTIVATE:
464 if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD)
466 LONG ret = SendMessageW( GetParent(hwnd), WM_MOUSEACTIVATE, wParam, lParam );
467 if (ret) return ret;
470 /* Caption clicks are handled by the NC_HandleNCLButtonDown() */
471 return (LOWORD(lParam) >= HTCLIENT) ? MA_ACTIVATE : MA_NOACTIVATE;
473 case WM_ACTIVATE:
474 /* The default action in Windows is to set the keyboard focus to
475 * the window, if it's being activated and not minimized */
476 if (LOWORD(wParam) != WA_INACTIVE) {
477 if (!IsIconic(hwnd)) SetFocus(hwnd);
479 break;
481 case WM_MOUSEWHEEL:
482 if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD)
483 return SendMessageW( GetParent(hwnd), WM_MOUSEWHEEL, wParam, lParam );
484 break;
486 case WM_ERASEBKGND:
487 case WM_ICONERASEBKGND:
489 RECT rect;
490 HDC hdc = (HDC)wParam;
491 HBRUSH hbr = (HBRUSH)GetClassLongW( hwnd, GCL_HBRBACKGROUND );
492 if (!hbr) return 0;
494 if (GetClassLongW( hwnd, GCL_STYLE ) & CS_PARENTDC)
496 /* can't use GetClipBox with a parent DC or we fill the whole parent */
497 GetClientRect( hwnd, &rect );
498 DPtoLP( hdc, (LPPOINT)&rect, 2 );
500 else GetClipBox( hdc, &rect );
501 FillRect( hdc, &rect, hbr );
502 return 1;
505 case WM_GETDLGCODE:
506 return 0;
508 case WM_CTLCOLORMSGBOX:
509 case WM_CTLCOLOREDIT:
510 case WM_CTLCOLORLISTBOX:
511 case WM_CTLCOLORBTN:
512 case WM_CTLCOLORDLG:
513 case WM_CTLCOLORSTATIC:
514 case WM_CTLCOLORSCROLLBAR:
515 return (LRESULT)DEFWND_ControlColor( (HDC)wParam, msg - WM_CTLCOLORMSGBOX );
517 case WM_CTLCOLOR:
518 return (LRESULT)DEFWND_ControlColor( (HDC)wParam, HIWORD(lParam) );
520 case WM_SETCURSOR:
521 if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD)
523 /* with the exception of the border around a resizable wnd,
524 * give the parent first chance to set the cursor */
525 if ((LOWORD(lParam) < HTSIZEFIRST) || (LOWORD(lParam) > HTSIZELAST))
527 if (SendMessageW(GetParent(hwnd), WM_SETCURSOR, wParam, lParam)) return TRUE;
530 NC_HandleSetCursor( hwnd, wParam, lParam );
531 break;
533 case WM_SYSCOMMAND:
534 return NC_HandleSysCommand( hwnd, wParam, lParam );
536 case WM_KEYDOWN:
537 if(wParam == VK_F10) iF10Key = VK_F10;
538 break;
540 case WM_SYSKEYDOWN:
541 if( HIWORD(lParam) & KEYDATA_ALT )
543 /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */
544 if( wParam == VK_MENU && !iMenuSysKey )
545 iMenuSysKey = 1;
546 else
547 iMenuSysKey = 0;
549 iF10Key = 0;
551 if( wParam == VK_F4 ) /* try to close the window */
553 HWND top = GetAncestor( hwnd, GA_ROOT );
554 if (!(GetClassLongW( top, GCL_STYLE ) & CS_NOCLOSE))
555 PostMessageW( top, WM_SYSCOMMAND, SC_CLOSE, 0 );
558 else if( wParam == VK_F10 )
559 iF10Key = 1;
560 else
561 if( wParam == VK_ESCAPE && (GetKeyState(VK_SHIFT) & 0x8000))
562 SendMessageW( hwnd, WM_SYSCOMMAND, SC_KEYMENU, VK_SPACE );
563 break;
565 case WM_KEYUP:
566 case WM_SYSKEYUP:
567 /* Press and release F10 or ALT */
568 if (((wParam == VK_MENU) && iMenuSysKey) ||
569 ((wParam == VK_F10) && iF10Key))
570 SendMessageW( GetAncestor( hwnd, GA_ROOT ), WM_SYSCOMMAND, SC_KEYMENU, 0L );
571 iMenuSysKey = iF10Key = 0;
572 break;
574 case WM_SYSCHAR:
575 iMenuSysKey = 0;
576 if (wParam == VK_RETURN && IsIconic(hwnd))
578 PostMessageW( hwnd, WM_SYSCOMMAND, SC_RESTORE, 0L );
579 break;
581 if ((HIWORD(lParam) & KEYDATA_ALT) && wParam)
583 if (wParam == VK_TAB || wParam == VK_ESCAPE) break;
584 if (wParam == VK_SPACE && (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD))
585 SendMessageW( GetParent(hwnd), msg, wParam, lParam );
586 else
587 SendMessageW( hwnd, WM_SYSCOMMAND, SC_KEYMENU, wParam );
589 else /* check for Ctrl-Esc */
590 if (wParam != VK_ESCAPE) MessageBeep(0);
591 break;
593 case WM_SHOWWINDOW:
595 LONG style = GetWindowLongW( hwnd, GWL_STYLE );
596 if (!lParam) return 0; /* sent from ShowWindow */
597 if (!(style & WS_POPUP)) return 0;
598 if ((style & WS_VISIBLE) && wParam) return 0;
599 if (!(style & WS_VISIBLE) && !wParam) return 0;
600 if (!GetWindow( hwnd, GW_OWNER )) return 0;
601 ShowWindow( hwnd, wParam ? SW_SHOWNOACTIVATE : SW_HIDE );
602 break;
605 case WM_CANCELMODE:
606 if (!(GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD)) EndMenu();
607 if (GetCapture() == hwnd) ReleaseCapture();
608 break;
610 case WM_VKEYTOITEM:
611 case WM_CHARTOITEM:
612 return -1;
614 case WM_DROPOBJECT:
615 return DRAG_FILE;
617 case WM_QUERYDROPOBJECT:
618 return (GetWindowLongA( hwnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES) != 0;
620 case WM_QUERYDRAGICON:
622 UINT len;
624 HICON hIcon = (HICON)GetClassLongW( hwnd, GCL_HICON );
625 HINSTANCE instance = (HINSTANCE)GetWindowLongW( hwnd, GWL_HINSTANCE );
626 if (hIcon) return (LRESULT)hIcon;
627 for(len=1; len<64; len++)
628 if((hIcon = LoadIconW(instance, MAKEINTRESOURCEW(len))))
629 return (LRESULT)hIcon;
630 return (LRESULT)LoadIconW(0, IDI_APPLICATIONW);
632 break;
634 case WM_ISACTIVEICON:
636 WND *wndPtr = WIN_GetPtr( hwnd );
637 BOOL ret = (wndPtr->flags & WIN_NCACTIVATED) != 0;
638 WIN_ReleasePtr( wndPtr );
639 return ret;
642 case WM_NOTIFYFORMAT:
643 if (IsWindowUnicode(hwnd)) return NFR_UNICODE;
644 else return NFR_ANSI;
646 case WM_QUERYOPEN:
647 case WM_QUERYENDSESSION:
648 return 1;
650 case WM_SETICON:
651 if (USER_Driver.pSetWindowIcon)
652 return (LRESULT)USER_Driver.pSetWindowIcon( hwnd, (HICON)lParam, (wParam != ICON_SMALL) );
653 else
655 HICON hOldIcon = (HICON)SetClassLongW( hwnd, (wParam != ICON_SMALL) ? GCL_HICON : GCL_HICONSM,
656 lParam);
657 SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE |
658 SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
659 return (LRESULT)hOldIcon;
662 case WM_GETICON:
663 return GetClassLongW( hwnd, (wParam != ICON_SMALL) ? GCL_HICON : GCL_HICONSM );
665 case WM_HELP:
666 SendMessageW( GetParent(hwnd), msg, wParam, lParam );
667 break;
670 return 0;
675 /***********************************************************************
676 * DefWindowProc (USER.107)
678 LRESULT WINAPI DefWindowProc16( HWND16 hwnd16, UINT16 msg, WPARAM16 wParam,
679 LPARAM lParam )
681 LRESULT result = 0;
682 HWND hwnd = WIN_Handle32( hwnd16 );
684 if (!WIN_IsCurrentProcess( hwnd ))
686 if (!IsWindow( hwnd )) return 0;
687 ERR( "called for other process window %p\n", hwnd );
688 return 0;
690 SPY_EnterMessage( SPY_DEFWNDPROC16, hwnd, msg, wParam, lParam );
692 switch(msg)
694 case WM_NCCREATE:
696 CREATESTRUCT16 *cs = MapSL(lParam);
697 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
698 * may have child window IDs instead of window name */
699 if (HIWORD(cs->lpszName))
700 DEFWND_SetTextA( hwnd, MapSL(cs->lpszName) );
701 result = 1;
703 break;
705 case WM_NCCALCSIZE:
707 RECT rect32;
708 CONV_RECT16TO32( MapSL(lParam), &rect32 );
709 result = NC_HandleNCCalcSize( hwnd, &rect32 );
710 CONV_RECT32TO16( &rect32, MapSL(lParam) );
712 break;
714 case WM_WINDOWPOSCHANGING:
715 result = WINPOS_HandleWindowPosChanging16( hwnd, MapSL(lParam) );
716 break;
718 case WM_WINDOWPOSCHANGED:
720 WINDOWPOS16 * winPos = MapSL(lParam);
721 DEFWND_HandleWindowPosChanged( hwnd, winPos->flags );
723 break;
725 case WM_GETTEXT:
726 case WM_SETTEXT:
727 result = DefWindowProcA( hwnd, msg, wParam, (LPARAM)MapSL(lParam) );
728 break;
730 default:
731 result = DefWindowProcA( hwnd, msg, wParam, lParam );
732 break;
735 SPY_ExitMessage( SPY_RESULT_DEFWND16, hwnd, msg, result, wParam, lParam );
736 return result;
740 /***********************************************************************
741 * DefWindowProcA (USER32.@)
744 LRESULT WINAPI DefWindowProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
746 LRESULT result = 0;
747 HWND full_handle;
749 if (!(full_handle = WIN_IsCurrentProcess( hwnd )))
751 if (!IsWindow( hwnd )) return 0;
752 ERR( "called for other process window %p\n", hwnd );
753 return 0;
755 hwnd = full_handle;
757 SPY_EnterMessage( SPY_DEFWNDPROC, hwnd, msg, wParam, lParam );
759 switch(msg)
761 case WM_NCCREATE:
763 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
764 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
765 * may have child window IDs instead of window name */
766 if (HIWORD(cs->lpszName))
767 DEFWND_SetTextA( hwnd, cs->lpszName );
768 result = 1;
770 break;
772 case WM_NCCALCSIZE:
773 result = NC_HandleNCCalcSize( hwnd, (RECT *)lParam );
774 break;
776 case WM_WINDOWPOSCHANGING:
777 result = WINPOS_HandleWindowPosChanging( hwnd, (WINDOWPOS *)lParam );
778 break;
780 case WM_WINDOWPOSCHANGED:
782 WINDOWPOS * winPos = (WINDOWPOS *)lParam;
783 DEFWND_HandleWindowPosChanged( hwnd, winPos->flags );
785 break;
787 case WM_GETTEXTLENGTH:
789 WND *wndPtr = WIN_GetPtr( hwnd );
790 if (wndPtr && wndPtr->text)
791 result = WideCharToMultiByte( CP_ACP, 0, wndPtr->text, strlenW(wndPtr->text),
792 NULL, 0, NULL, NULL );
793 WIN_ReleasePtr( wndPtr );
795 break;
797 case WM_GETTEXT:
798 if (wParam)
800 LPSTR dest = (LPSTR)lParam;
801 WND *wndPtr = WIN_GetPtr( hwnd );
803 if (!wndPtr) break;
804 if (wndPtr->text)
806 if (!WideCharToMultiByte( CP_ACP, 0, wndPtr->text, -1,
807 dest, wParam, NULL, NULL )) dest[wParam-1] = 0;
808 result = strlen( dest );
810 else dest[0] = '\0';
811 WIN_ReleasePtr( wndPtr );
813 break;
815 case WM_SETTEXT:
816 DEFWND_SetTextA( hwnd, (LPCSTR)lParam );
817 if( (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CAPTION) == WS_CAPTION )
818 NC_HandleNCPaint( hwnd , (HRGN)1 ); /* Repaint caption */
819 result = 1; /* success. FIXME: check text length */
820 break;
822 /* for far east users (IMM32) - <hidenori@a2.ctktv.ne.jp> */
823 case WM_IME_CHAR:
825 CHAR chChar1 = (CHAR)( (wParam>>8) & 0xff );
826 CHAR chChar2 = (CHAR)( wParam & 0xff );
828 SendMessageA( hwnd, WM_CHAR, (WPARAM)chChar1, lParam );
829 if ( IsDBCSLeadByte( chChar1 ) )
830 SendMessageA( hwnd, WM_CHAR, (WPARAM)chChar2, lParam );
832 break;
833 case WM_IME_KEYDOWN:
834 result = SendMessageA( hwnd, WM_KEYDOWN, wParam, lParam );
835 break;
836 case WM_IME_KEYUP:
837 result = SendMessageA( hwnd, WM_KEYUP, wParam, lParam );
838 break;
840 case WM_IME_STARTCOMPOSITION:
841 case WM_IME_COMPOSITION:
842 case WM_IME_ENDCOMPOSITION:
843 case WM_IME_SELECT:
845 HWND hwndIME;
847 hwndIME = DEFWND_ImmGetDefaultIMEWnd( hwnd );
848 if (hwndIME)
849 result = SendMessageA( hwndIME, msg, wParam, lParam );
851 break;
852 case WM_IME_SETCONTEXT:
854 HWND hwndIME;
856 hwndIME = DEFWND_ImmGetDefaultIMEWnd( hwnd );
857 if (hwndIME)
858 result = DEFWND_ImmIsUIMessageA( hwndIME, msg, wParam, lParam );
860 break;
862 default:
863 result = DEFWND_DefWinProc( hwnd, msg, wParam, lParam );
864 break;
867 SPY_ExitMessage( SPY_RESULT_DEFWND, hwnd, msg, result, wParam, lParam );
868 return result;
872 /***********************************************************************
873 * DefWindowProcW (USER32.@) Calls default window message handler
875 * Calls default window procedure for messages not processed
876 * by application.
878 * RETURNS
879 * Return value is dependent upon the message.
881 LRESULT WINAPI DefWindowProcW(
882 HWND hwnd, /* [in] window procedure receiving message */
883 UINT msg, /* [in] message identifier */
884 WPARAM wParam, /* [in] first message parameter */
885 LPARAM lParam ) /* [in] second message parameter */
887 LRESULT result = 0;
888 HWND full_handle;
890 if (!(full_handle = WIN_IsCurrentProcess( hwnd )))
892 if (!IsWindow( hwnd )) return 0;
893 ERR( "called for other process window %p\n", hwnd );
894 return 0;
896 hwnd = full_handle;
897 SPY_EnterMessage( SPY_DEFWNDPROC, hwnd, msg, wParam, lParam );
899 switch(msg)
901 case WM_NCCREATE:
903 CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
904 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
905 * may have child window IDs instead of window name */
906 if (HIWORD(cs->lpszName))
907 DEFWND_SetTextW( hwnd, cs->lpszName );
908 result = 1;
910 break;
912 case WM_NCCALCSIZE:
913 result = NC_HandleNCCalcSize( hwnd, (RECT *)lParam );
914 break;
916 case WM_WINDOWPOSCHANGING:
917 result = WINPOS_HandleWindowPosChanging( hwnd, (WINDOWPOS *)lParam );
918 break;
920 case WM_WINDOWPOSCHANGED:
922 WINDOWPOS * winPos = (WINDOWPOS *)lParam;
923 DEFWND_HandleWindowPosChanged( hwnd, winPos->flags );
925 break;
927 case WM_GETTEXTLENGTH:
929 WND *wndPtr = WIN_GetPtr( hwnd );
930 if (wndPtr && wndPtr->text) result = (LRESULT)strlenW(wndPtr->text);
931 WIN_ReleasePtr( wndPtr );
933 break;
935 case WM_GETTEXT:
936 if (wParam)
938 LPWSTR dest = (LPWSTR)lParam;
939 WND *wndPtr = WIN_GetPtr( hwnd );
941 if (!wndPtr) break;
942 if (wndPtr->text)
944 lstrcpynW( dest, wndPtr->text, wParam );
945 result = strlenW( dest );
947 else dest[0] = '\0';
948 WIN_ReleasePtr( wndPtr );
950 break;
952 case WM_SETTEXT:
953 DEFWND_SetTextW( hwnd, (LPCWSTR)lParam );
954 if( (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CAPTION) == WS_CAPTION )
955 NC_HandleNCPaint( hwnd , (HRGN)1 ); /* Repaint caption */
956 result = 1; /* success. FIXME: check text length */
957 break;
959 /* for far east users (IMM32) - <hidenori@a2.ctktv.ne.jp> */
960 case WM_IME_CHAR:
961 SendMessageW( hwnd, WM_CHAR, wParam, lParam );
962 break;
963 case WM_IME_SETCONTEXT:
965 HWND hwndIME;
967 hwndIME = DEFWND_ImmGetDefaultIMEWnd( hwnd );
968 if (hwndIME)
969 result = DEFWND_ImmIsUIMessageW( hwndIME, msg, wParam, lParam );
971 break;
973 default:
974 result = DEFWND_DefWinProc( hwnd, msg, wParam, lParam );
975 break;
977 SPY_ExitMessage( SPY_RESULT_DEFWND, hwnd, msg, result, wParam, lParam );
978 return result;