2 * Default window procedure
4 * Copyright 1993, 1996 Alexandre Julliard
13 #include "nonclient.h"
17 #include "sysmetrics.h"
23 #define COLOR_MAX COLOR_BTNHIGHLIGHT
25 /* bits in the dwKeyData */
26 #define KEYDATA_ALT 0x2000
27 #define KEYDATA_PREVSTATE 0x4000
29 static short iF10Key
= 0;
30 static short iMenuSysKey
= 0;
33 /***********************************************************************
34 * DEFWND_InitSysMenuPopup
36 * Handle the WM_INITMENUPOPUP message on the system menu.
38 static void DEFWND_InitSysMenuPopup( HMENU hmenu
, DWORD style
, DWORD clsStyle
)
42 gray
= !(style
& WS_THICKFRAME
) || (style
& (WS_MAXIMIZE
| WS_MINIMIZE
));
43 EnableMenuItem( hmenu
, SC_SIZE
, (gray
? MF_GRAYED
: MF_ENABLED
) );
44 gray
= ((style
& WS_MAXIMIZE
) != 0);
45 EnableMenuItem( hmenu
, SC_MOVE
, (gray
? MF_GRAYED
: MF_ENABLED
) );
46 gray
= !(style
& WS_MINIMIZEBOX
) || (style
& WS_MINIMIZE
);
47 EnableMenuItem( hmenu
, SC_MINIMIZE
, (gray
? MF_GRAYED
: MF_ENABLED
) );
48 gray
= !(style
& WS_MAXIMIZEBOX
) || (style
& WS_MAXIMIZE
);
49 EnableMenuItem( hmenu
, SC_MAXIMIZE
, (gray
? MF_GRAYED
: MF_ENABLED
) );
50 gray
= !(style
& (WS_MAXIMIZE
| WS_MINIMIZE
));
51 EnableMenuItem( hmenu
, SC_RESTORE
, (gray
? MF_GRAYED
: MF_ENABLED
) );
52 gray
= (clsStyle
& CS_NOCLOSE
) != 0;
53 EnableMenuItem( hmenu
, SC_CLOSE
, (gray
? MF_GRAYED
: MF_ENABLED
) );
57 /***********************************************************************
58 * DEFWND_HandleWindowPosChanged
60 * Handle the WM_WINDOWPOSCHANGED message.
62 static void DEFWND_HandleWindowPosChanged( WND
*wndPtr
, UINT32 flags
)
64 WPARAM16 wp
= SIZE_RESTORED
;
66 if (!(flags
& SWP_NOCLIENTMOVE
))
67 SendMessage16( wndPtr
->hwndSelf
, WM_MOVE
, 0,
68 MAKELONG(wndPtr
->rectClient
.left
, wndPtr
->rectClient
.top
));
69 if (!(flags
& SWP_NOCLIENTSIZE
))
71 if (wndPtr
->dwStyle
& WS_MAXIMIZE
) wp
= SIZE_MAXIMIZED
;
72 else if (wndPtr
->dwStyle
& WS_MINIMIZE
) wp
= SIZE_MINIMIZED
;
74 SendMessage16( wndPtr
->hwndSelf
, WM_SIZE
, wp
,
75 MAKELONG(wndPtr
->rectClient
.right
-wndPtr
->rectClient
.left
,
76 wndPtr
->rectClient
.bottom
-wndPtr
->rectClient
.top
));
81 /***********************************************************************
84 * Set the window text.
86 void DEFWND_SetText( WND
*wndPtr
, LPCSTR text
)
89 if (wndPtr
->text
) HeapFree( SystemHeap
, 0, wndPtr
->text
);
90 wndPtr
->text
= HEAP_strdupA( SystemHeap
, 0, text
);
91 if (wndPtr
->window
) XStoreName( display
, wndPtr
->window
, wndPtr
->text
);
95 /***********************************************************************
98 * Default window procedure for messages that are the same in Win16 and Win32.
100 static LRESULT
DEFWND_DefWinProc( WND
*wndPtr
, UINT32 msg
, WPARAM32 wParam
,
106 return NC_HandleNCPaint( wndPtr
->hwndSelf
, (HRGN
)wParam
);
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
);
119 return NC_HandleNCActivate( wndPtr
, wParam
);
122 if (wndPtr
->text
) HeapFree( SystemHeap
, 0, wndPtr
->text
);
124 if (wndPtr
->pVScroll
) HeapFree( SystemHeap
, 0, wndPtr
->pVScroll
);
125 if (wndPtr
->pHScroll
) HeapFree( SystemHeap
, 0, wndPtr
->pHScroll
);
126 wndPtr
->pVScroll
= wndPtr
->pHScroll
= NULL
;
133 HDC hdc
= BeginPaint16( wndPtr
->hwndSelf
, &ps
);
136 if( (wndPtr
->dwStyle
& WS_MINIMIZE
) && wndPtr
->class->hIcon
)
138 int x
= (wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
-
139 SYSMETRICS_CXICON
)/2;
140 int y
= (wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
-
141 SYSMETRICS_CYICON
)/2;
142 dprintf_win(stddeb
,"Painting class icon: vis rect=(%i,%i - %i,%i)\n",
143 ps
.rcPaint
.left
, ps
.rcPaint
.top
, ps
.rcPaint
.right
, ps
.rcPaint
.bottom
);
144 DrawIcon( hdc
, x
, y
, wndPtr
->class->hIcon
);
146 EndPaint16( wndPtr
->hwndSelf
, &ps
);
154 ValidateRect32( wndPtr
->hwndSelf
, NULL
);
155 wndPtr
->flags
|= WIN_NO_REDRAW
;
157 else wndPtr
->flags
&= ~WIN_NO_REDRAW
;
161 DestroyWindow( wndPtr
->hwndSelf
);
164 case WM_MOUSEACTIVATE
:
165 if (wndPtr
->dwStyle
& WS_CHILD
)
167 LONG ret
= SendMessage16( wndPtr
->parent
->hwndSelf
,
168 WM_MOUSEACTIVATE
, wParam
, lParam
);
174 if (LOWORD(wParam
) != WA_INACTIVE
) SetFocus32( wndPtr
->hwndSelf
);
178 case WM_ICONERASEBKGND
:
180 if (!wndPtr
->class->hbrBackground
) return 0;
182 /* FIXME: should fill icon text with hbrushActiveCaption
185 if (wndPtr
->dwStyle
& WS_MINIMIZE
)
187 if( wndPtr
->flags
& WIN_NCACTIVATED
)
189 FillWindow( GetParent16(wndPtr
->hwndSelf
), wndPtr
->hwndSelf
,
190 (HDC
)wParam
, sysColorObjects
.hbrushActiveCaption
);
194 /* FIXME: should draw parent' background somehow
195 (e.g for textured desktop) ? */
198 if (wndPtr
->class->hbrBackground
<= (HBRUSH
)(COLOR_MAX
+1))
200 HBRUSH hbrush
= CreateSolidBrush(
201 GetSysColor(((DWORD
)wndPtr
->class->hbrBackground
)-1));
202 FillWindow( GetParent16(wndPtr
->hwndSelf
), wndPtr
->hwndSelf
,
203 (HDC
)wParam
, hbrush
);
204 DeleteObject (hbrush
);
206 else FillWindow( GetParent16(wndPtr
->hwndSelf
), wndPtr
->hwndSelf
,
207 (HDC
)wParam
, wndPtr
->class->hbrBackground
);
214 case WM_CTLCOLORMSGBOX
:
215 case WM_CTLCOLOREDIT
:
216 case WM_CTLCOLORLISTBOX
:
219 case WM_CTLCOLORSTATIC
:
220 SetBkColor( (HDC
)wParam
, GetSysColor(COLOR_WINDOW
) );
221 SetTextColor( (HDC
)wParam
, GetSysColor(COLOR_WINDOWTEXT
) );
222 return (LRESULT
)sysColorObjects
.hbrushWindow
;
224 case WM_CTLCOLORSCROLLBAR
:
225 SetBkColor( (HDC
)wParam
, RGB(255, 255, 255) );
226 SetTextColor( (HDC
)wParam
, RGB(0, 0, 0) );
227 UnrealizeObject( sysColorObjects
.hbrushScrollbar
);
228 return (LRESULT
)sysColorObjects
.hbrushScrollbar
;
232 if (HIWORD(lParam
) == CTLCOLOR_SCROLLBAR
)
234 SetBkColor( (HDC
)wParam
, RGB(255, 255, 255) );
235 SetTextColor( (HDC
)wParam
, RGB(0, 0, 0) );
236 UnrealizeObject( sysColorObjects
.hbrushScrollbar
);
237 return (LRESULT
)sysColorObjects
.hbrushScrollbar
;
241 SetBkColor( (HDC
)wParam
, GetSysColor(COLOR_WINDOW
) );
242 SetTextColor( (HDC
)wParam
, GetSysColor(COLOR_WINDOWTEXT
) );
243 return (LRESULT
)sysColorObjects
.hbrushWindow
;
247 case WM_GETTEXTLENGTH
:
248 if (wndPtr
->text
) return (LRESULT
)strlen(wndPtr
->text
);
252 if (wndPtr
->dwStyle
& WS_CHILD
)
253 if (SendMessage16(wndPtr
->parent
->hwndSelf
, WM_SETCURSOR
,
256 return NC_HandleSetCursor( wndPtr
->hwndSelf
, wParam
, lParam
);
259 return NC_HandleSysCommand( wndPtr
->hwndSelf
, wParam
,
260 MAKEPOINT16(lParam
) );
263 if(wParam
== VK_F10
) iF10Key
= VK_F10
;
267 if( HIWORD(lParam
) & KEYDATA_ALT
)
269 /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */
270 if( wParam
== VK_MENU
&& !iMenuSysKey
)
278 else if( wParam
== VK_F10
)
281 if( wParam
== VK_ESCAPE
&& GetKeyState(VK_SHIFT
) < 0 )
282 SendMessage16( wndPtr
->hwndSelf
, WM_SYSCOMMAND
,
283 (WPARAM
)SC_KEYMENU
, (LPARAM
)VK_SPACE
);
288 /* Press and release F10 or ALT */
289 if (((wParam
== VK_MENU
) && iMenuSysKey
) ||
290 ((wParam
== VK_F10
) && iF10Key
))
291 SendMessage16( WIN_GetTopParent(wndPtr
->hwndSelf
),
292 WM_SYSCOMMAND
, SC_KEYMENU
, 0L );
293 iMenuSysKey
= iF10Key
= 0;
298 if (wParam
== VK_RETURN
&& (wndPtr
->dwStyle
& WS_MINIMIZE
))
300 PostMessage( wndPtr
->hwndSelf
, WM_SYSCOMMAND
,
301 (WPARAM
)SC_RESTORE
, 0L );
304 if ((HIWORD(lParam
) & KEYDATA_ALT
) && wParam
)
306 if (wParam
== VK_TAB
|| wParam
== VK_ESCAPE
) break;
307 if (wParam
== VK_SPACE
&& (wndPtr
->dwStyle
& WS_CHILD
))
308 SendMessage16( wndPtr
->parent
->hwndSelf
, msg
, wParam
, lParam
);
310 SendMessage16( wndPtr
->hwndSelf
, WM_SYSCOMMAND
,
311 (WPARAM
)SC_KEYMENU
, (LPARAM
)(DWORD
)wParam
);
313 else /* check for Ctrl-Esc */
314 if (wParam
!= VK_ESCAPE
) MessageBeep(0);
318 if (!lParam
) return 0; /* sent from ShowWindow */
319 if (!(wndPtr
->dwStyle
& WS_POPUP
) || !wndPtr
->owner
) return 0;
320 if ((wndPtr
->dwStyle
& WS_VISIBLE
) && wParam
) return 0;
321 else if (!(wndPtr
->dwStyle
& WS_VISIBLE
) && !wParam
) return 0;
322 ShowWindow( wndPtr
->hwndSelf
, wParam
? SW_SHOWNOACTIVATE
: SW_HIDE
);
325 case WM_INITMENUPOPUP
:
326 /* Not absolutely sure this belongs here -- AJ */
327 if (HIWORD(lParam
)) /* system menu */
328 DEFWND_InitSysMenuPopup( (HMENU
)wParam
, wndPtr
->dwStyle
,
329 wndPtr
->class->style
);
333 /* EndMenu() should be called if in menu state but currently it's
334 impossible to detect - menu code should be updated*/
335 if (GetCapture() == wndPtr
->hwndSelf
) ReleaseCapture();
345 case WM_QUERYDROPOBJECT
:
346 if (wndPtr
->dwExStyle
& WS_EX_ACCEPTFILES
) return 1;
349 case WM_QUERYDRAGICON
:
354 if( (hI
= LoadIcon16(wndPtr
->hInstance
,MAKEINTRESOURCE(len
))) )
360 case WM_QUERYENDSESSION
:
368 /***********************************************************************
369 * DefWindowProc16 (USER.107)
371 LRESULT
DefWindowProc16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wParam
,
374 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
377 if (!wndPtr
) return 0;
378 SPY_EnterMessage( SPY_DEFWNDPROC16
, hwnd
, msg
, wParam
, lParam
);
384 CREATESTRUCT16
*cs
= (CREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
);
386 DEFWND_SetText( wndPtr
, (LPSTR
)PTR_SEG_TO_LIN(cs
->lpszName
) );
392 result
= NC_HandleNCCalcSize(wndPtr
, (RECT16
*)PTR_SEG_TO_LIN(lParam
));
395 case WM_WINDOWPOSCHANGING
:
396 result
= WINPOS_HandleWindowPosChanging16( wndPtr
,
397 (WINDOWPOS16
*)PTR_SEG_TO_LIN(lParam
) );
400 case WM_WINDOWPOSCHANGED
:
402 WINDOWPOS16
* winPos
= (WINDOWPOS16
*)PTR_SEG_TO_LIN(lParam
);
403 DEFWND_HandleWindowPosChanged( wndPtr
, winPos
->flags
);
408 if (wParam
&& wndPtr
->text
)
410 lstrcpyn32A( (LPSTR
)PTR_SEG_TO_LIN(lParam
), wndPtr
->text
, wParam
);
411 result
= (LRESULT
)strlen( (LPSTR
)PTR_SEG_TO_LIN(lParam
) ) + 1;
416 DEFWND_SetText( wndPtr
, (LPSTR
)PTR_SEG_TO_LIN(lParam
) );
417 NC_HandleNCPaint( hwnd
, (HRGN
)1 ); /* Repaint caption */
421 result
= DEFWND_DefWinProc( wndPtr
, msg
, wParam
, lParam
);
425 SPY_ExitMessage( SPY_RESULT_OK16
, hwnd
, msg
, result
);
430 /***********************************************************************
431 * DefWindowProc32A (USER32.125)
433 LRESULT
DefWindowProc32A( HWND32 hwnd
, UINT32 msg
, WPARAM32 wParam
,
436 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
439 if (!wndPtr
) return 0;
440 SPY_EnterMessage( SPY_DEFWNDPROC32
, hwnd
, msg
, wParam
, lParam
);
446 CREATESTRUCT32A
*cs
= (CREATESTRUCT32A
*)lParam
;
447 if (cs
->lpszName
) DEFWND_SetText( wndPtr
, cs
->lpszName
);
455 CONV_RECT32TO16( (RECT32
*)lParam
, &rect16
);
456 result
= NC_HandleNCCalcSize( wndPtr
, &rect16
);
457 CONV_RECT16TO32( &rect16
, (RECT32
*)lParam
);
461 case WM_WINDOWPOSCHANGING
:
462 result
= WINPOS_HandleWindowPosChanging32( wndPtr
,
463 (WINDOWPOS32
*)lParam
);
466 case WM_WINDOWPOSCHANGED
:
468 WINDOWPOS32
* winPos
= (WINDOWPOS32
*)lParam
;
469 DEFWND_HandleWindowPosChanged( wndPtr
, winPos
->flags
);
474 if (wParam
&& wndPtr
->text
)
476 lstrcpyn32A( (LPSTR
)lParam
, wndPtr
->text
, wParam
);
477 result
= (LRESULT
)strlen( (LPSTR
)lParam
) + 1;
482 DEFWND_SetText( wndPtr
, (LPSTR
)lParam
);
483 NC_HandleNCPaint( hwnd
, (HRGN
)1 ); /* Repaint caption */
487 result
= DEFWND_DefWinProc( wndPtr
, msg
, wParam
, lParam
);
491 SPY_ExitMessage( SPY_RESULT_OK32
, hwnd
, msg
, result
);
496 /***********************************************************************
497 * DefWindowProc32W (USER32.126)
499 LRESULT
DefWindowProc32W( HWND32 hwnd
, UINT32 msg
, WPARAM32 wParam
,
508 CREATESTRUCT32W
*cs
= (CREATESTRUCT32W
*)lParam
;
511 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
512 LPSTR str
= STRING32_DupUniToAnsi( cs
->lpszName
);
513 DEFWND_SetText( wndPtr
, str
);
522 LPSTR str
= malloc( wParam
);
523 result
= DefWindowProc32A( hwnd
, msg
, wParam
, (LPARAM
)str
);
524 STRING32_AnsiToUni( (LPWSTR
)lParam
, str
);
531 LPSTR str
= STRING32_DupUniToAnsi( (LPWSTR
)lParam
);
532 result
= DefWindowProc32A( hwnd
, msg
, wParam
, (LPARAM
)str
);
538 result
= DefWindowProc32A( hwnd
, msg
, wParam
, lParam
);