Release 960717
[wine/multimedia.git] / windows / defwnd.c
blob87dc7d487a8b49ef160a32948026deb6b16f77c2
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 "string32.h"
16 #include "syscolor.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;
32 /***********************************************************************
33 * DEFWND_InitSysMenuPopup
35 * Handle the WM_INITMENUPOPUP message on the system menu.
37 static void DEFWND_InitSysMenuPopup( HMENU hmenu, DWORD style, DWORD clsStyle )
39 BOOL gray;
41 gray = !(style & WS_THICKFRAME) || (style & (WS_MAXIMIZE | WS_MINIMIZE));
42 EnableMenuItem( hmenu, SC_SIZE, (gray ? MF_GRAYED : MF_ENABLED) );
43 gray = ((style & WS_MAXIMIZE) != 0);
44 EnableMenuItem( hmenu, SC_MOVE, (gray ? MF_GRAYED : MF_ENABLED) );
45 gray = !(style & WS_MINIMIZEBOX) || (style & WS_MINIMIZE);
46 EnableMenuItem( hmenu, SC_MINIMIZE, (gray ? MF_GRAYED : MF_ENABLED) );
47 gray = !(style & WS_MAXIMIZEBOX) || (style & WS_MAXIMIZE);
48 EnableMenuItem( hmenu, SC_MAXIMIZE, (gray ? MF_GRAYED : MF_ENABLED) );
49 gray = !(style & (WS_MAXIMIZE | WS_MINIMIZE));
50 EnableMenuItem( hmenu, SC_RESTORE, (gray ? MF_GRAYED : MF_ENABLED) );
51 gray = (clsStyle & CS_NOCLOSE) != 0;
52 EnableMenuItem( hmenu, SC_CLOSE, (gray ? MF_GRAYED : MF_ENABLED) );
56 /***********************************************************************
57 * DEFWND_HandleWindowPosChanged
59 * Handle the WM_WINDOWPOSCHANGED message.
61 static void DEFWND_HandleWindowPosChanged( WND *wndPtr, UINT32 flags )
63 WPARAM16 wp = SIZE_RESTORED;
65 if (!(flags & SWP_NOCLIENTMOVE))
66 SendMessage16( wndPtr->hwndSelf, WM_MOVE, 0,
67 MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top));
68 if (!(flags & SWP_NOCLIENTSIZE))
70 if (wndPtr->dwStyle & WS_MAXIMIZE) wp = SIZE_MAXIMIZED;
71 else if (wndPtr->dwStyle & WS_MINIMIZE) wp = SIZE_MINIMIZED;
73 SendMessage16( wndPtr->hwndSelf, WM_SIZE, wp,
74 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
75 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
80 /***********************************************************************
81 * DEFWND_SetText
83 * Set the window text.
85 void DEFWND_SetText( WND *wndPtr, LPCSTR text )
87 if (!text) text = "";
88 if (wndPtr->text) HeapFree( SystemHeap, 0, wndPtr->text );
89 wndPtr->text = HEAP_strdupA( SystemHeap, 0, text );
90 if (wndPtr->window) XStoreName( display, wndPtr->window, wndPtr->text );
94 /***********************************************************************
95 * DEFWND_DefWinProc
97 * Default window procedure for messages that are the same in Win16 and Win32.
99 static LRESULT DEFWND_DefWinProc( WND *wndPtr, UINT32 msg, WPARAM32 wParam,
100 LPARAM lParam )
102 switch(msg)
104 case WM_PAINTICON:
105 case WM_NCPAINT:
106 return NC_HandleNCPaint( wndPtr->hwndSelf, (HRGN)wParam );
108 case WM_NCHITTEST:
109 return NC_HandleNCHitTest( wndPtr->hwndSelf, MAKEPOINT16(lParam) );
111 case WM_NCLBUTTONDOWN:
112 return NC_HandleNCLButtonDown( wndPtr->hwndSelf, wParam, lParam );
114 case WM_LBUTTONDBLCLK:
115 case WM_NCLBUTTONDBLCLK:
116 return NC_HandleNCLButtonDblClk( wndPtr, wParam, lParam );
118 case WM_NCACTIVATE:
119 return NC_HandleNCActivate( wndPtr->hwndSelf, wParam );
121 case WM_NCDESTROY:
122 if (wndPtr->text) HeapFree( SystemHeap, 0, wndPtr->text );
123 wndPtr->text = NULL;
124 if (wndPtr->pVScroll) HeapFree( SystemHeap, 0, wndPtr->pVScroll );
125 if (wndPtr->pHScroll) HeapFree( SystemHeap, 0, wndPtr->pHScroll );
126 wndPtr->pVScroll = wndPtr->pHScroll = NULL;
127 return 0;
129 case WM_PAINT:
131 PAINTSTRUCT16 paintstruct;
132 BeginPaint16( wndPtr->hwndSelf, &paintstruct );
133 EndPaint16( wndPtr->hwndSelf, &paintstruct );
134 return 0;
137 case WM_SETREDRAW:
138 if (!wParam)
140 ValidateRect32( wndPtr->hwndSelf, NULL );
141 wndPtr->flags |= WIN_NO_REDRAW;
143 else wndPtr->flags &= ~WIN_NO_REDRAW;
144 return 0;
146 case WM_CLOSE:
147 DestroyWindow( wndPtr->hwndSelf );
148 return 0;
150 case WM_MOUSEACTIVATE:
151 if (wndPtr->dwStyle & WS_CHILD)
153 LONG ret = SendMessage16( wndPtr->parent->hwndSelf,
154 WM_MOUSEACTIVATE, wParam, lParam );
155 if (ret) return ret;
157 return MA_ACTIVATE;
159 case WM_ACTIVATE:
160 if (LOWORD(wParam) != WA_INACTIVE) SetFocus( wndPtr->hwndSelf );
161 break;
163 case WM_ERASEBKGND:
164 case WM_ICONERASEBKGND:
166 if (!wndPtr->class->hbrBackground) return 0;
167 if (wndPtr->class->hbrBackground <= (HBRUSH)(COLOR_MAX+1))
169 HBRUSH hbrush;
170 hbrush = CreateSolidBrush(
171 GetSysColor(((DWORD)wndPtr->class->hbrBackground)-1));
172 FillWindow( GetParent(wndPtr->hwndSelf), wndPtr->hwndSelf,
173 (HDC)wParam, hbrush);
174 DeleteObject (hbrush);
176 else
177 FillWindow( GetParent(wndPtr->hwndSelf), wndPtr->hwndSelf,
178 (HDC)wParam, wndPtr->class->hbrBackground );
179 return 1;
182 case WM_GETDLGCODE:
183 return 0;
185 case WM_CTLCOLORMSGBOX:
186 case WM_CTLCOLOREDIT:
187 case WM_CTLCOLORLISTBOX:
188 case WM_CTLCOLORBTN:
189 case WM_CTLCOLORDLG:
190 case WM_CTLCOLORSTATIC:
191 SetBkColor( (HDC)wParam, GetSysColor(COLOR_WINDOW) );
192 SetTextColor( (HDC)wParam, GetSysColor(COLOR_WINDOWTEXT) );
193 return (LRESULT)sysColorObjects.hbrushWindow;
195 case WM_CTLCOLORSCROLLBAR:
196 SetBkColor( (HDC)wParam, RGB(255, 255, 255) );
197 SetTextColor( (HDC)wParam, RGB(0, 0, 0) );
198 UnrealizeObject( sysColorObjects.hbrushScrollbar );
199 return (LRESULT)sysColorObjects.hbrushScrollbar;
201 case WM_CTLCOLOR:
203 if (HIWORD(lParam) == CTLCOLOR_SCROLLBAR)
205 SetBkColor( (HDC)wParam, RGB(255, 255, 255) );
206 SetTextColor( (HDC)wParam, RGB(0, 0, 0) );
207 UnrealizeObject( sysColorObjects.hbrushScrollbar );
208 return (LRESULT)sysColorObjects.hbrushScrollbar;
210 else
212 SetBkColor( (HDC)wParam, GetSysColor(COLOR_WINDOW) );
213 SetTextColor( (HDC)wParam, GetSysColor(COLOR_WINDOWTEXT) );
214 return (LRESULT)sysColorObjects.hbrushWindow;
218 case WM_GETTEXTLENGTH:
219 if (wndPtr->text) return (LRESULT)strlen(wndPtr->text);
220 return 0;
222 case WM_SETCURSOR:
223 if (wndPtr->dwStyle & WS_CHILD)
224 if (SendMessage16(wndPtr->parent->hwndSelf, WM_SETCURSOR,
225 wParam, lParam))
226 return TRUE;
227 return NC_HandleSetCursor( wndPtr->hwndSelf, wParam, lParam );
229 case WM_SYSCOMMAND:
230 return NC_HandleSysCommand( wndPtr->hwndSelf, wParam,
231 MAKEPOINT16(lParam) );
233 case WM_KEYDOWN:
234 if(wParam == VK_F10) iF10Key = VK_F10;
235 break;
237 case WM_SYSKEYDOWN:
238 if( HIWORD(lParam) & KEYDATA_ALT )
240 /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */
241 if( wParam == VK_MENU && !iMenuSysKey )
242 iMenuSysKey = 1;
243 else
244 iMenuSysKey = 0;
246 iF10Key = 0;
249 else if( wParam == VK_F10 )
250 iF10Key = 1;
251 else
252 if( wParam == VK_ESCAPE && GetKeyState(VK_SHIFT) < 0 )
253 SendMessage16( wndPtr->hwndSelf, WM_SYSCOMMAND,
254 (WPARAM)SC_KEYMENU, (LPARAM)VK_SPACE);
255 break;
257 case WM_KEYUP:
258 case WM_SYSKEYUP:
259 /* Press and release F10 or ALT */
260 if (((wParam == VK_MENU) && iMenuSysKey) ||
261 ((wParam == VK_F10) && iF10Key))
262 SendMessage16( WIN_GetTopParent(wndPtr->hwndSelf),
263 WM_SYSCOMMAND, SC_KEYMENU, 0L );
264 iMenuSysKey = iF10Key = 0;
265 break;
267 case WM_SYSCHAR:
268 iMenuSysKey = 0;
269 if (wParam == VK_RETURN && (wndPtr->dwStyle & WS_MINIMIZE))
271 PostMessage( wndPtr->hwndSelf, WM_SYSCOMMAND,
272 (WPARAM)SC_RESTORE, 0L );
273 break;
275 if ((HIWORD(lParam) & KEYDATA_ALT) && wParam)
277 if (wParam == VK_TAB || wParam == VK_ESCAPE) break;
278 if (wParam == VK_SPACE && (wndPtr->dwStyle & WS_CHILD))
279 SendMessage16( wndPtr->parent->hwndSelf, msg, wParam, lParam );
280 else
281 SendMessage16( wndPtr->hwndSelf, WM_SYSCOMMAND,
282 (WPARAM)SC_KEYMENU, (LPARAM)(DWORD)wParam );
284 else /* check for Ctrl-Esc */
285 if (wParam != VK_ESCAPE) MessageBeep(0);
286 break;
288 case WM_SHOWWINDOW:
289 if (!lParam) return 0; /* sent from ShowWindow */
290 if (!(wndPtr->dwStyle & WS_POPUP) || !wndPtr->owner) return 0;
291 if ((wndPtr->dwStyle & WS_VISIBLE) && wParam) return 0;
292 else if (!(wndPtr->dwStyle & WS_VISIBLE) && !wParam) return 0;
293 ShowWindow( wndPtr->hwndSelf, wParam ? SW_SHOWNOACTIVATE : SW_HIDE );
294 break;
296 case WM_INITMENUPOPUP:
297 /* Not absolutely sure this belongs here -- AJ */
298 if (HIWORD(lParam)) /* system menu */
299 DEFWND_InitSysMenuPopup( (HMENU)wParam, wndPtr->dwStyle,
300 wndPtr->class->style );
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 (GetCapture() == 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 HICON 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) ) + 1;
384 break;
386 case WM_SETTEXT:
387 DEFWND_SetText( wndPtr, (LPSTR)PTR_SEG_TO_LIN(lParam) );
388 NC_HandleNCPaint( hwnd , (HRGN)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 ) + 1;
450 break;
452 case WM_SETTEXT:
453 DEFWND_SetText( wndPtr, (LPSTR)lParam );
454 NC_HandleNCPaint( hwnd , (HRGN)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 = STRING32_DupUniToAnsi( cs->lpszName );
484 DEFWND_SetText( wndPtr, str );
485 free( str );
487 result = 1;
489 break;
491 case WM_GETTEXT:
493 LPSTR str = malloc( wParam );
494 result = DefWindowProc32A( hwnd, msg, wParam, (LPARAM)str );
495 STRING32_AnsiToUni( (LPWSTR)lParam, str );
496 free( str );
498 break;
500 case WM_SETTEXT:
502 LPSTR str = STRING32_DupUniToAnsi( (LPWSTR)lParam );
503 result = DefWindowProc32A( hwnd, msg, wParam, (LPARAM)str );
504 free( str );
506 break;
508 default:
509 result = DefWindowProc32A( hwnd, msg, wParam, lParam );
510 break;
512 return result;