Release 961222
[wine/gsoc-2012-control.git] / windows / defwnd.c
blobb666cca4a861c99220ccedbea0ae5cb5f7a0844a
1 /*
2 * Default window procedure
4 * Copyright 1993, 1996 Alexandre Julliard
5 * 1995 Alex Korobka
6 */
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include "win.h"
11 #include "user.h"
12 #include "heap.h"
13 #include "nonclient.h"
14 #include "winpos.h"
15 #include "syscolor.h"
16 #include "sysmetrics.h"
17 #include "stddebug.h"
18 #include "debug.h"
19 #include "spy.h"
21 /* Last COLOR id */
22 #define COLOR_MAX COLOR_BTNHIGHLIGHT
24 /* bits in the dwKeyData */
25 #define KEYDATA_ALT 0x2000
26 #define KEYDATA_PREVSTATE 0x4000
28 static short iF10Key = 0;
29 static short iMenuSysKey = 0;
31 /***********************************************************************
32 * DEFWND_HandleWindowPosChanged
34 * Handle the WM_WINDOWPOSCHANGED message.
36 static void DEFWND_HandleWindowPosChanged( WND *wndPtr, UINT32 flags )
38 WPARAM16 wp = SIZE_RESTORED;
40 if (!(flags & SWP_NOCLIENTMOVE))
41 SendMessage16( wndPtr->hwndSelf, WM_MOVE, 0,
42 MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top));
43 if (!(flags & SWP_NOCLIENTSIZE))
45 if (wndPtr->dwStyle & WS_MAXIMIZE) wp = SIZE_MAXIMIZED;
46 else if (wndPtr->dwStyle & WS_MINIMIZE) wp = SIZE_MINIMIZED;
48 SendMessage16( wndPtr->hwndSelf, WM_SIZE, wp,
49 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
50 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
55 /***********************************************************************
56 * DEFWND_SetText
58 * Set the window text.
60 void DEFWND_SetText( WND *wndPtr, LPCSTR text )
62 if (!text) text = "";
63 if (wndPtr->text) HeapFree( SystemHeap, 0, wndPtr->text );
64 wndPtr->text = HEAP_strdupA( SystemHeap, 0, text );
65 if (wndPtr->window)
67 XStoreName( display, wndPtr->window, wndPtr->text );
68 XSetIconName( display, wndPtr->window, wndPtr->text );
73 /***********************************************************************
74 * DEFWND_DefWinProc
76 * Default window procedure for messages that are the same in Win16 and Win32.
78 static LRESULT DEFWND_DefWinProc( WND *wndPtr, UINT32 msg, WPARAM32 wParam,
79 LPARAM lParam )
81 switch(msg)
83 case WM_NCPAINT:
84 return NC_HandleNCPaint( wndPtr->hwndSelf, (HRGN32)wParam );
86 case WM_NCHITTEST:
87 return NC_HandleNCHitTest( wndPtr->hwndSelf, MAKEPOINT16(lParam) );
89 case WM_NCLBUTTONDOWN:
90 return NC_HandleNCLButtonDown( wndPtr->hwndSelf, wParam, lParam );
92 case WM_LBUTTONDBLCLK:
93 case WM_NCLBUTTONDBLCLK:
94 return NC_HandleNCLButtonDblClk( wndPtr, wParam, lParam );
96 case WM_NCACTIVATE:
97 return NC_HandleNCActivate( wndPtr, wParam );
99 case WM_NCDESTROY:
100 if (wndPtr->text) HeapFree( SystemHeap, 0, wndPtr->text );
101 wndPtr->text = NULL;
102 if (wndPtr->pVScroll) HeapFree( SystemHeap, 0, wndPtr->pVScroll );
103 if (wndPtr->pHScroll) HeapFree( SystemHeap, 0, wndPtr->pHScroll );
104 wndPtr->pVScroll = wndPtr->pHScroll = NULL;
105 return 0;
107 case WM_PAINTICON:
108 case WM_PAINT:
110 PAINTSTRUCT16 ps;
111 HDC16 hdc = BeginPaint16( wndPtr->hwndSelf, &ps );
112 if( hdc )
114 if( (wndPtr->dwStyle & WS_MINIMIZE) && wndPtr->class->hIcon )
116 int x = (wndPtr->rectWindow.right - wndPtr->rectWindow.left -
117 SYSMETRICS_CXICON)/2;
118 int y = (wndPtr->rectWindow.bottom - wndPtr->rectWindow.top -
119 SYSMETRICS_CYICON)/2;
120 dprintf_win(stddeb,"Painting class icon: vis rect=(%i,%i - %i,%i)\n",
121 ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom );
122 DrawIcon( hdc, x, y, wndPtr->class->hIcon );
124 EndPaint16( wndPtr->hwndSelf, &ps );
126 return 0;
129 case WM_SETREDRAW:
130 if (!wParam)
132 ValidateRect32( wndPtr->hwndSelf, NULL );
133 wndPtr->flags |= WIN_NO_REDRAW;
135 else wndPtr->flags &= ~WIN_NO_REDRAW;
136 return 0;
138 case WM_CLOSE:
139 DestroyWindow( wndPtr->hwndSelf );
140 return 0;
142 case WM_MOUSEACTIVATE:
143 if (wndPtr->dwStyle & WS_CHILD)
145 LONG ret = SendMessage16( wndPtr->parent->hwndSelf,
146 WM_MOUSEACTIVATE, wParam, lParam );
147 if (ret) return ret;
149 return MA_ACTIVATE;
151 case WM_ACTIVATE:
152 if (LOWORD(wParam) != WA_INACTIVE) SetFocus32( wndPtr->hwndSelf );
153 break;
155 case WM_ERASEBKGND:
156 case WM_ICONERASEBKGND:
158 if (!wndPtr->class->hbrBackground) return 0;
160 /* FIXME: should fill icon text with hbrushActiveCaption
161 instead of this */
163 if (wndPtr->dwStyle & WS_MINIMIZE )
165 if( wndPtr->flags & WIN_NCACTIVATED )
167 FillWindow( GetParent16(wndPtr->hwndSelf), wndPtr->hwndSelf,
168 (HDC16)wParam, sysColorObjects.hbrushActiveCaption );
169 return 1;
172 /* FIXME: should draw parent' background somehow
173 (e.g for textured desktop) ? */
176 if (wndPtr->class->hbrBackground <= (HBRUSH16)(COLOR_MAX+1))
178 HBRUSH32 hbrush = CreateSolidBrush32(
179 GetSysColor(((DWORD)wndPtr->class->hbrBackground)-1));
180 FillWindow( GetParent16(wndPtr->hwndSelf), wndPtr->hwndSelf,
181 (HDC16)wParam, hbrush);
182 DeleteObject32( hbrush );
184 else FillWindow( GetParent16(wndPtr->hwndSelf), wndPtr->hwndSelf,
185 (HDC16)wParam, wndPtr->class->hbrBackground );
186 return 1;
189 case WM_GETDLGCODE:
190 return 0;
192 case WM_CTLCOLORMSGBOX:
193 case WM_CTLCOLOREDIT:
194 case WM_CTLCOLORLISTBOX:
195 case WM_CTLCOLORBTN:
196 case WM_CTLCOLORDLG:
197 case WM_CTLCOLORSTATIC:
198 SetBkColor( (HDC32)wParam, GetSysColor(COLOR_WINDOW) );
199 SetTextColor( (HDC32)wParam, GetSysColor(COLOR_WINDOWTEXT) );
200 return (LRESULT)sysColorObjects.hbrushWindow;
202 case WM_CTLCOLORSCROLLBAR:
203 SetBkColor( (HDC32)wParam, RGB(255, 255, 255) );
204 SetTextColor( (HDC32)wParam, RGB(0, 0, 0) );
205 UnrealizeObject32( sysColorObjects.hbrushScrollbar );
206 return (LRESULT)sysColorObjects.hbrushScrollbar;
208 case WM_CTLCOLOR:
210 if (HIWORD(lParam) == CTLCOLOR_SCROLLBAR)
212 SetBkColor( (HDC32)wParam, RGB(255, 255, 255) );
213 SetTextColor( (HDC32)wParam, RGB(0, 0, 0) );
214 UnrealizeObject32( sysColorObjects.hbrushScrollbar );
215 return (LRESULT)sysColorObjects.hbrushScrollbar;
217 else
219 SetBkColor( (HDC32)wParam, GetSysColor(COLOR_WINDOW) );
220 SetTextColor( (HDC32)wParam, GetSysColor(COLOR_WINDOWTEXT) );
221 return (LRESULT)sysColorObjects.hbrushWindow;
225 case WM_GETTEXTLENGTH:
226 if (wndPtr->text) return (LRESULT)strlen(wndPtr->text);
227 return 0;
229 case WM_SETCURSOR:
230 if (wndPtr->dwStyle & WS_CHILD)
231 if (SendMessage16(wndPtr->parent->hwndSelf, WM_SETCURSOR,
232 wParam, lParam))
233 return TRUE;
234 return NC_HandleSetCursor( wndPtr->hwndSelf, wParam, lParam );
236 case WM_SYSCOMMAND:
237 return NC_HandleSysCommand( wndPtr->hwndSelf, wParam,
238 MAKEPOINT16(lParam) );
240 case WM_KEYDOWN:
241 if(wParam == VK_F10) iF10Key = VK_F10;
242 break;
244 case WM_SYSKEYDOWN:
245 if( HIWORD(lParam) & KEYDATA_ALT )
247 /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */
248 if( wParam == VK_MENU && !iMenuSysKey )
249 iMenuSysKey = 1;
250 else
251 iMenuSysKey = 0;
253 iF10Key = 0;
256 else if( wParam == VK_F10 )
257 iF10Key = 1;
258 else
259 if( wParam == VK_ESCAPE && GetKeyState(VK_SHIFT) < 0 )
260 SendMessage16( wndPtr->hwndSelf, WM_SYSCOMMAND,
261 (WPARAM16)SC_KEYMENU, (LPARAM)VK_SPACE);
262 break;
264 case WM_KEYUP:
265 case WM_SYSKEYUP:
266 /* Press and release F10 or ALT */
267 if (((wParam == VK_MENU) && iMenuSysKey) ||
268 ((wParam == VK_F10) && iF10Key))
269 SendMessage16( WIN_GetTopParent(wndPtr->hwndSelf),
270 WM_SYSCOMMAND, SC_KEYMENU, 0L );
271 iMenuSysKey = iF10Key = 0;
272 break;
274 case WM_SYSCHAR:
275 iMenuSysKey = 0;
276 if (wParam == VK_RETURN && (wndPtr->dwStyle & WS_MINIMIZE))
278 PostMessage( wndPtr->hwndSelf, WM_SYSCOMMAND,
279 (WPARAM16)SC_RESTORE, 0L );
280 break;
282 if ((HIWORD(lParam) & KEYDATA_ALT) && wParam)
284 if (wParam == VK_TAB || wParam == VK_ESCAPE) break;
285 if (wParam == VK_SPACE && (wndPtr->dwStyle & WS_CHILD))
286 SendMessage16( wndPtr->parent->hwndSelf, msg, wParam, lParam );
287 else
288 SendMessage16( wndPtr->hwndSelf, WM_SYSCOMMAND,
289 (WPARAM16)SC_KEYMENU, (LPARAM)(DWORD)wParam );
291 else /* check for Ctrl-Esc */
292 if (wParam != VK_ESCAPE) MessageBeep(0);
293 break;
295 case WM_SHOWWINDOW:
296 if (!lParam) return 0; /* sent from ShowWindow */
297 if (!(wndPtr->dwStyle & WS_POPUP) || !wndPtr->owner) return 0;
298 if ((wndPtr->dwStyle & WS_VISIBLE) && wParam) return 0;
299 else if (!(wndPtr->dwStyle & WS_VISIBLE) && !wParam) return 0;
300 ShowWindow( wndPtr->hwndSelf, wParam ? SW_SHOWNOACTIVATE : SW_HIDE );
301 break;
303 case WM_CANCELMODE:
304 /* EndMenu() should be called if in menu state but currently it's
305 impossible to detect - menu code should be updated*/
306 if (GetCapture32() == wndPtr->hwndSelf) ReleaseCapture();
307 break;
309 case WM_VKEYTOITEM:
310 case WM_CHARTOITEM:
311 return -1;
313 case WM_DROPOBJECT:
314 return DRAG_FILE;
316 case WM_QUERYDROPOBJECT:
317 if (wndPtr->dwExStyle & WS_EX_ACCEPTFILES) return 1;
318 break;
320 case WM_QUERYDRAGICON:
322 HICON16 hI = 0;
323 UINT16 len = 1;
324 while(len < 64)
325 if( (hI = LoadIcon16(wndPtr->hInstance,MAKEINTRESOURCE(len))) )
326 return (LRESULT)hI;
328 break;
330 case WM_QUERYOPEN:
331 case WM_QUERYENDSESSION:
332 return 1;
334 return 0;
339 /***********************************************************************
340 * DefWindowProc16 (USER.107)
342 LRESULT DefWindowProc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
343 LPARAM lParam )
345 WND * wndPtr = WIN_FindWndPtr( hwnd );
346 LRESULT result = 0;
348 if (!wndPtr) return 0;
349 SPY_EnterMessage( SPY_DEFWNDPROC16, hwnd, msg, wParam, lParam );
351 switch(msg)
353 case WM_NCCREATE:
355 CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
356 if (cs->lpszName)
357 DEFWND_SetText( wndPtr, (LPSTR)PTR_SEG_TO_LIN(cs->lpszName) );
358 result = 1;
360 break;
362 case WM_NCCALCSIZE:
363 result = NC_HandleNCCalcSize(wndPtr, (RECT16 *)PTR_SEG_TO_LIN(lParam));
364 break;
366 case WM_WINDOWPOSCHANGING:
367 result = WINPOS_HandleWindowPosChanging16( wndPtr,
368 (WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam) );
369 break;
371 case WM_WINDOWPOSCHANGED:
373 WINDOWPOS16 * winPos = (WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam);
374 DEFWND_HandleWindowPosChanged( wndPtr, winPos->flags );
376 break;
378 case WM_GETTEXT:
379 if (wParam && wndPtr->text)
381 lstrcpyn32A( (LPSTR)PTR_SEG_TO_LIN(lParam), wndPtr->text, wParam );
382 result = (LRESULT)strlen( (LPSTR)PTR_SEG_TO_LIN(lParam) );
384 break;
386 case WM_SETTEXT:
387 DEFWND_SetText( wndPtr, (LPSTR)PTR_SEG_TO_LIN(lParam) );
388 NC_HandleNCPaint( hwnd , (HRGN32)1 ); /* Repaint caption */
389 break;
391 default:
392 result = DEFWND_DefWinProc( wndPtr, msg, wParam, lParam );
393 break;
396 SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg, result );
397 return result;
401 /***********************************************************************
402 * DefWindowProc32A (USER32.125)
404 LRESULT DefWindowProc32A( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
405 LPARAM lParam )
407 WND * wndPtr = WIN_FindWndPtr( hwnd );
408 LRESULT result = 0;
410 if (!wndPtr) return 0;
411 SPY_EnterMessage( SPY_DEFWNDPROC32, hwnd, msg, wParam, lParam );
413 switch(msg)
415 case WM_NCCREATE:
417 CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
418 if (cs->lpszName) DEFWND_SetText( wndPtr, cs->lpszName );
419 result = 1;
421 break;
423 case WM_NCCALCSIZE:
425 RECT16 rect16;
426 CONV_RECT32TO16( (RECT32 *)lParam, &rect16 );
427 result = NC_HandleNCCalcSize( wndPtr, &rect16 );
428 CONV_RECT16TO32( &rect16, (RECT32 *)lParam );
430 break;
432 case WM_WINDOWPOSCHANGING:
433 result = WINPOS_HandleWindowPosChanging32( wndPtr,
434 (WINDOWPOS32 *)lParam );
435 break;
437 case WM_WINDOWPOSCHANGED:
439 WINDOWPOS32 * winPos = (WINDOWPOS32 *)lParam;
440 DEFWND_HandleWindowPosChanged( wndPtr, winPos->flags );
442 break;
444 case WM_GETTEXT:
445 if (wParam && wndPtr->text)
447 lstrcpyn32A( (LPSTR)lParam, wndPtr->text, wParam );
448 result = (LRESULT)strlen( (LPSTR)lParam );
450 break;
452 case WM_SETTEXT:
453 DEFWND_SetText( wndPtr, (LPSTR)lParam );
454 NC_HandleNCPaint( hwnd , (HRGN32)1 ); /* Repaint caption */
455 break;
457 default:
458 result = DEFWND_DefWinProc( wndPtr, msg, wParam, lParam );
459 break;
462 SPY_ExitMessage( SPY_RESULT_OK32, hwnd, msg, result );
463 return result;
467 /***********************************************************************
468 * DefWindowProc32W (USER32.126)
470 LRESULT DefWindowProc32W( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
471 LPARAM lParam )
473 LRESULT result;
475 switch(msg)
477 case WM_NCCREATE:
479 CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
480 if (cs->lpszName)
482 WND *wndPtr = WIN_FindWndPtr( hwnd );
483 LPSTR str = HEAP_strdupWtoA(GetProcessHeap(), 0, cs->lpszName);
484 DEFWND_SetText( wndPtr, str );
485 HeapFree( GetProcessHeap(), 0, str );
487 result = 1;
489 break;
491 case WM_GETTEXT:
493 LPSTR str = HeapAlloc( GetProcessHeap(), 0, wParam );
494 result = DefWindowProc32A( hwnd, msg, wParam, (LPARAM)str );
495 lstrcpynAtoW( (LPWSTR)lParam, str, wParam );
496 HeapFree( GetProcessHeap(), 0, str );
498 break;
500 case WM_SETTEXT:
502 LPSTR str = HEAP_strdupWtoA( GetProcessHeap(), 0, (LPWSTR)lParam );
503 result = DefWindowProc32A( hwnd, msg, wParam, (LPARAM)str );
504 HeapFree( GetProcessHeap(), 0, str );
506 break;
508 default:
509 result = DefWindowProc32A( hwnd, msg, wParam, lParam );
510 break;
512 return result;