Change the callback declarations to a safer format.
[wine] / windows / defwnd.c
1 /*
2  * Default window procedure
3  *
4  * Copyright 1993, 1996 Alexandre Julliard
5  *           1995 Alex Korobka
6  */
7
8 #include <string.h>
9
10 #include "win.h"
11 #include "user.h"
12 #include "heap.h"
13 #include "nonclient.h"
14 #include "winpos.h"
15 #include "dce.h"
16 #include "debugtools.h"
17 #include "spy.h"
18 #include "windef.h"
19 #include "wingdi.h"
20 #include "winnls.h"
21 #include "wine/unicode.h"
22 #include "wine/winuser16.h"
23 #include "imm.h"
24
25 DEFAULT_DEBUG_CHANNEL(win);
26
27   /* bits in the dwKeyData */
28 #define KEYDATA_ALT             0x2000
29 #define KEYDATA_PREVSTATE       0x4000
30
31 static short iF10Key = 0;
32 static short iMenuSysKey = 0;
33
34 /***********************************************************************
35  *           DEFWND_HandleWindowPosChanged
36  *
37  * Handle the WM_WINDOWPOSCHANGED message.
38  */
39 static void DEFWND_HandleWindowPosChanged( WND *wndPtr, UINT flags )
40 {
41     WPARAM wp = SIZE_RESTORED;
42
43     if (!(flags & SWP_NOCLIENTMOVE))
44         SendMessageW( wndPtr->hwndSelf, WM_MOVE, 0,
45                     MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top));
46     if (!(flags & SWP_NOCLIENTSIZE))
47     {
48         if (wndPtr->dwStyle & WS_MAXIMIZE) wp = SIZE_MAXIMIZED;
49         else if (wndPtr->dwStyle & WS_MINIMIZE) wp = SIZE_MINIMIZED;
50
51         SendMessageW( wndPtr->hwndSelf, WM_SIZE, wp, 
52                      MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
53                             wndPtr->rectClient.bottom-wndPtr->rectClient.top));
54     }
55 }
56
57
58 /***********************************************************************
59  *           DEFWND_SetTextA
60  *
61  * Set the window text.
62  */
63 void DEFWND_SetTextA( WND *wndPtr, LPCSTR text )
64 {
65     int count;
66
67     if (!text) text = "";
68     count = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 );
69
70     if (wndPtr->text) HeapFree(SystemHeap, 0, wndPtr->text);
71     if ((wndPtr->text = HeapAlloc(SystemHeap, 0, count * sizeof(WCHAR))))
72         MultiByteToWideChar( CP_ACP, 0, text, -1, wndPtr->text, count );
73     else
74         ERR("Not enough memory for window text");
75
76     wndPtr->pDriver->pSetText(wndPtr, wndPtr->text);
77 }
78
79 /***********************************************************************
80  *           DEFWND_SetTextW
81  *
82  * Set the window text.
83  */
84 void DEFWND_SetTextW( WND *wndPtr, LPCWSTR text )
85 {
86     static const WCHAR empty_string[] = {0};
87     int count;
88
89     if (!text) text = empty_string;
90     count = strlenW(text) + 1;
91
92     if (wndPtr->text) HeapFree(SystemHeap, 0, wndPtr->text);
93     if ((wndPtr->text = HeapAlloc(SystemHeap, 0, count * sizeof(WCHAR))))
94         strcpyW( wndPtr->text, text );
95     else
96         ERR("Not enough memory for window text");
97
98     wndPtr->pDriver->pSetText(wndPtr, wndPtr->text);
99 }
100
101 /***********************************************************************
102  *           DEFWND_ControlColor
103  *
104  * Default colors for control painting.
105  */
106 HBRUSH DEFWND_ControlColor( HDC hDC, UINT ctlType )
107 {
108     if( ctlType == CTLCOLOR_SCROLLBAR)
109     {
110         HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR);
111         if (TWEAK_WineLook == WIN31_LOOK) {
112            SetTextColor( hDC, RGB(0, 0, 0) );
113            SetBkColor( hDC, RGB(255, 255, 255) );
114         } else {
115            COLORREF bk = GetSysColor(COLOR_3DHILIGHT);
116            SetTextColor( hDC, GetSysColor(COLOR_3DFACE));
117            SetBkColor( hDC, bk);
118
119            /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT 
120             * we better use 0x55aa bitmap brush to make scrollbar's background
121             * look different from the window background. 
122             */
123            if (bk == GetSysColor(COLOR_WINDOW)) {
124                return CACHE_GetPattern55AABrush();
125            }
126         }
127         UnrealizeObject( hb );
128         return hb;
129     }
130
131     SetTextColor( hDC, GetSysColor(COLOR_WINDOWTEXT));
132
133     if (TWEAK_WineLook > WIN31_LOOK) {
134         if ((ctlType == CTLCOLOR_EDIT) || (ctlType == CTLCOLOR_LISTBOX))
135             SetBkColor( hDC, GetSysColor(COLOR_WINDOW) );
136         else {
137             SetBkColor( hDC, GetSysColor(COLOR_3DFACE) );
138             return GetSysColorBrush(COLOR_3DFACE);
139         }
140     }
141     else
142         SetBkColor( hDC, GetSysColor(COLOR_WINDOW) );
143     return GetSysColorBrush(COLOR_WINDOW);
144 }
145
146
147 /***********************************************************************
148  *           DEFWND_SetRedraw
149  */
150 static void DEFWND_SetRedraw( WND* wndPtr, WPARAM wParam )
151 {
152     BOOL bVisible = wndPtr->dwStyle & WS_VISIBLE;
153
154     TRACE("%04x %i\n", wndPtr->hwndSelf, (wParam!=0) );
155
156     if( wParam )
157     {
158         if( !bVisible )
159         {
160             wndPtr->dwStyle |= WS_VISIBLE;
161             DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow );
162         }
163     }
164     else if( bVisible )
165     {
166         if( wndPtr->dwStyle & WS_MINIMIZE ) wParam = RDW_VALIDATE;
167         else wParam = RDW_ALLCHILDREN | RDW_VALIDATE;
168
169         PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, 0, wParam, 0 );
170         DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow );
171         wndPtr->dwStyle &= ~WS_VISIBLE;
172     }
173 }
174
175 /***********************************************************************
176  *           DEFWND_Print
177  *
178  * This method handles the default behavior for the WM_PRINT message.
179  */
180 static void DEFWND_Print(
181   WND*  wndPtr,
182   HDC   hdc,
183   ULONG uFlags)
184 {
185   /*
186    * Visibility flag.
187    */
188   if ( (uFlags & PRF_CHECKVISIBLE) &&
189        !IsWindowVisible(wndPtr->hwndSelf) )
190       return;
191
192   /*
193    * Unimplemented flags.
194    */
195   if ( (uFlags & PRF_CHILDREN) ||
196        (uFlags & PRF_OWNED)    ||
197        (uFlags & PRF_NONCLIENT) )
198   {
199     WARN("WM_PRINT message with unsupported flags\n");
200   }
201
202   /*
203    * Background
204    */
205   if ( uFlags & PRF_ERASEBKGND)
206     SendMessageW(wndPtr->hwndSelf, WM_ERASEBKGND, (WPARAM)hdc, 0);
207
208   /*
209    * Client area
210    */
211   if ( uFlags & PRF_CLIENT)
212     SendMessageW(wndPtr->hwndSelf, WM_PRINTCLIENT, (WPARAM)hdc, PRF_CLIENT);
213 }
214
215
216 /*
217  * helpers for calling IMM32
218  *
219  * WM_IME_* messages are generated only by IMM32,
220  * so I assume imm32 is already LoadLibrary-ed.
221  */
222 static HWND DEFWND_ImmGetDefaultIMEWnd( HWND hwnd )
223 {
224     HINSTANCE hInstIMM = GetModuleHandleA( "imm32" );
225     HWND WINAPI (*pFunc)(HWND);
226     HWND hwndRet = 0;
227
228     if (!hInstIMM)
229     {
230         ERR( "cannot get IMM32 handle\n" );
231         return 0;
232     }
233
234     pFunc = (void*)GetProcAddress(hInstIMM,"ImmGetDefaultIMEWnd");
235     if ( pFunc != NULL )
236         hwndRet = (*pFunc)( hwnd );
237
238     return hwndRet;
239 }
240
241 static BOOL DEFWND_ImmIsUIMessageA( HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam )
242 {
243     HINSTANCE hInstIMM = GetModuleHandleA( "imm32" );
244     BOOL WINAPI (*pFunc)(HWND,UINT,WPARAM,LPARAM);
245     BOOL fRet = FALSE;
246
247     if (!hInstIMM)
248     {
249         ERR( "cannot get IMM32 handle\n" );
250         return FALSE;
251     }
252
253     pFunc = (void*)GetProcAddress(hInstIMM,"ImmIsUIMessageA");
254     if ( pFunc != NULL )
255         fRet = (*pFunc)( hwndIME, msg, wParam, lParam );
256
257     return fRet;
258 }
259
260 static BOOL DEFWND_ImmIsUIMessageW( HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam )
261 {
262     HINSTANCE hInstIMM = GetModuleHandleA( "imm32" );
263     BOOL WINAPI (*pFunc)(HWND,UINT,WPARAM,LPARAM);
264     BOOL fRet = FALSE;
265
266     if (!hInstIMM)
267     {
268         ERR( "cannot get IMM32 handle\n" );
269         return FALSE;
270     }
271
272     pFunc = (void*)GetProcAddress(hInstIMM,"ImmIsUIMessageW");
273     if ( pFunc != NULL )
274         fRet = (*pFunc)( hwndIME, msg, wParam, lParam );
275
276     return fRet;
277 }
278
279
280
281 /***********************************************************************
282  *           DEFWND_DefWinProc
283  *
284  * Default window procedure for messages that are the same in Win16 and Win32.
285  */
286 static LRESULT DEFWND_DefWinProc( WND *wndPtr, UINT msg, WPARAM wParam,
287                                   LPARAM lParam, BOOL unicode )
288 {
289     LRESULT (WINAPI *pSendMessage)(HWND, UINT, WPARAM, LPARAM);
290     BOOL (WINAPI *pPostMessage)(HWND, UINT, WPARAM, LPARAM);
291
292     pSendMessage = unicode ? SendMessageW : SendMessageA;
293     pPostMessage = unicode ? PostMessageW : PostMessageA;
294
295     switch(msg)
296     {
297     case WM_NCPAINT:
298         return NC_HandleNCPaint( wndPtr->hwndSelf, (HRGN)wParam );
299
300     case WM_NCHITTEST:
301         {
302             POINT pt;
303             pt.x = SLOWORD(lParam);
304             pt.y = SHIWORD(lParam);
305             return NC_HandleNCHitTest( wndPtr->hwndSelf, pt );
306         }
307
308     case WM_NCLBUTTONDOWN:
309         return NC_HandleNCLButtonDown( wndPtr, wParam, lParam );
310
311     case WM_LBUTTONDBLCLK:
312     case WM_NCLBUTTONDBLCLK:
313         return NC_HandleNCLButtonDblClk( wndPtr, wParam, lParam );
314
315     case WM_NCRBUTTONDOWN:
316         /* in Windows, capture is taken when right-clicking on the caption bar */
317         if (wParam==HTCAPTION)
318         {
319             SetCapture(wndPtr->hwndSelf);
320         }
321         break;
322
323     case WM_RBUTTONUP:
324         if (wndPtr->hwndSelf == GetCapture())
325         {
326             /* release capture if we took it on WM_NCRBUTTONDOWN */
327             ReleaseCapture();
328         }
329         if ((wndPtr->flags & WIN_ISWIN32) || (TWEAK_WineLook > WIN31_LOOK))
330         {
331             POINT pt;
332             pt.x = SLOWORD(lParam);
333             pt.y = SHIWORD(lParam);
334             ClientToScreen(wndPtr->hwndSelf, &pt);
335             lParam = MAKELPARAM(pt.x, pt.y);
336             pSendMessage( wndPtr->hwndSelf, WM_CONTEXTMENU, wndPtr->hwndSelf, lParam );
337         }
338         break;
339
340     case WM_NCRBUTTONUP:
341         /*
342          * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked 
343          * in Windows), but what _should_ we do? According to MSDN : 
344          * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND 
345          * message to the window". When is it appropriate?
346          */
347         break;
348
349     case WM_CONTEXTMENU:
350         if( wndPtr->dwStyle & WS_CHILD )
351             pSendMessage( wndPtr->parent->hwndSelf, msg, wParam, lParam );
352         else if (wndPtr->hSysMenu)
353         {
354             LONG hitcode;
355             POINT pt;
356             pt.x = SLOWORD(lParam);
357             pt.y = SHIWORD(lParam);
358
359             /*
360              * WM_CONTEXTMENU coordinates are relative to screen, but 
361              * NC_HandleNCHitTest expects coordinates relative to the parent's 
362              * client area (to compare with the rectangle returned by 
363              * GetWindowRect)
364              */
365             if (wndPtr->parent)
366                 ScreenToClient(wndPtr->parent->hwndSelf, &pt);
367
368             hitcode = NC_HandleNCHitTest(wndPtr->hwndSelf, pt);
369
370             /* Track system popup if click was in the caption area. */
371             if (hitcode==HTCAPTION || hitcode==HTSYSMENU)
372                TrackPopupMenu(GetSystemMenu(wndPtr->hwndSelf, FALSE),
373                                TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
374                                pt.x, pt.y, 0, wndPtr->hwndSelf, NULL);
375         }
376         break;
377
378     case WM_NCACTIVATE:
379         return NC_HandleNCActivate( wndPtr, wParam );
380
381     case WM_NCDESTROY:
382         if (wndPtr->text) HeapFree( SystemHeap, 0, wndPtr->text );
383         wndPtr->text = NULL;
384         if (wndPtr->pVScroll) HeapFree( SystemHeap, 0, wndPtr->pVScroll );
385         if (wndPtr->pHScroll) HeapFree( SystemHeap, 0, wndPtr->pHScroll );
386         wndPtr->pVScroll = wndPtr->pHScroll = NULL;
387         return 0;
388
389     case WM_PRINT:
390         DEFWND_Print(wndPtr, (HDC)wParam, lParam);
391         return 0;
392
393     case WM_PAINTICON:
394     case WM_PAINT:
395         {
396             PAINTSTRUCT ps;
397             HDC hdc = BeginPaint( wndPtr->hwndSelf, &ps );
398             if( hdc ) 
399             {
400               HICON hIcon;
401               if( (wndPtr->dwStyle & WS_MINIMIZE) && ((hIcon = GetClassLongW( wndPtr->hwndSelf, GCL_HICON))) )
402               {
403                 int x = (wndPtr->rectWindow.right - wndPtr->rectWindow.left -
404                         GetSystemMetrics(SM_CXICON))/2;
405                 int y = (wndPtr->rectWindow.bottom - wndPtr->rectWindow.top -
406                         GetSystemMetrics(SM_CYICON))/2;
407                 TRACE("Painting class icon: vis rect=(%i,%i - %i,%i)\n",
408                 ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom );
409                 DrawIcon( hdc, x, y, hIcon );
410               }
411               EndPaint( wndPtr->hwndSelf, &ps );
412             }
413             return 0;
414         }
415
416     case WM_SYNCPAINT:
417         if (wndPtr->hrgnUpdate) 
418         {
419            RedrawWindow ( wndPtr->hwndSelf, 0, wndPtr->hrgnUpdate,
420                     RDW_ERASENOW | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN );
421         }
422         return 0;
423
424     case WM_SETREDRAW:
425         DEFWND_SetRedraw( wndPtr, wParam );
426         return 0;
427
428     case WM_CLOSE:
429         DestroyWindow( wndPtr->hwndSelf );
430         return 0;
431
432     case WM_MOUSEACTIVATE:
433         if (wndPtr->dwStyle & WS_CHILD)
434         {
435             LONG ret = pSendMessage( wndPtr->parent->hwndSelf,
436                                       WM_MOUSEACTIVATE, wParam, lParam );
437             if (ret) return ret;
438         }
439
440         /* Caption clicks are handled by the NC_HandleNCLButtonDown() */ 
441         return (LOWORD(lParam) >= HTCLIENT) ? MA_ACTIVATE : MA_NOACTIVATE;
442
443     case WM_ACTIVATE:
444         /* The default action in Windows is to set the keyboard focus to
445          * the window, if it's being activated and not minimized */
446         if (LOWORD(wParam) != WA_INACTIVE) {
447                 if (!(wndPtr->dwStyle & WS_MINIMIZE))
448                         SetFocus(wndPtr->hwndSelf);
449         }
450         break;
451
452      case WM_MOUSEWHEEL:
453         if (wndPtr->dwStyle & WS_CHILD)
454         {
455             return pSendMessage( wndPtr->parent->hwndSelf,
456                                  WM_MOUSEWHEEL, wParam, lParam );
457         }
458         break;
459
460     case WM_ERASEBKGND:
461     case WM_ICONERASEBKGND:
462         {
463             RECT rect;
464             HBRUSH hbr = GetClassLongW( wndPtr->hwndSelf, GCL_HBRBACKGROUND );
465             if (!hbr) return 0;
466
467             /*  Since WM_ERASEBKGND may receive either a window dc or a    */ 
468             /*  client dc, the area to be erased has to be retrieved from  */
469             /*  the device context.                                        */
470             GetClipBox( (HDC)wParam, &rect );
471
472             /* Always call the Win32 variant of FillRect even on Win16,
473              * since despite the fact that Win16, as well as Win32,
474              * supports special background brushes for a window class,
475              * the Win16 variant of FillRect does not.
476              */
477             FillRect( (HDC) wParam, &rect, hbr );
478             return 1;
479         }
480
481     case WM_GETDLGCODE:
482         return 0;
483
484     case WM_CTLCOLORMSGBOX:
485     case WM_CTLCOLOREDIT:
486     case WM_CTLCOLORLISTBOX:
487     case WM_CTLCOLORBTN:
488     case WM_CTLCOLORDLG:
489     case WM_CTLCOLORSTATIC:
490     case WM_CTLCOLORSCROLLBAR:
491         return (LRESULT)DEFWND_ControlColor( (HDC)wParam, msg - WM_CTLCOLORMSGBOX );
492
493     case WM_CTLCOLOR:
494         return (LRESULT)DEFWND_ControlColor( (HDC)wParam, HIWORD(lParam) );
495         
496     case WM_GETTEXTLENGTH:
497         if (wndPtr->text) return (LRESULT)strlenW(wndPtr->text);
498         return 0;
499
500     case WM_SETCURSOR:
501         if (wndPtr->dwStyle & WS_CHILD)
502             if (pSendMessage(wndPtr->parent->hwndSelf, WM_SETCURSOR,
503                             wParam, lParam))
504                 return TRUE;
505         return NC_HandleSetCursor( wndPtr->hwndSelf, wParam, lParam );
506
507     case WM_SYSCOMMAND:
508         {
509             POINT pt;
510             pt.x = SLOWORD(lParam);
511             pt.y = SHIWORD(lParam);
512             return NC_HandleSysCommand( wndPtr->hwndSelf, wParam, pt );
513         }
514
515     case WM_KEYDOWN:
516         if(wParam == VK_F10) iF10Key = VK_F10;
517         break;
518
519     case WM_SYSKEYDOWN:
520         if( HIWORD(lParam) & KEYDATA_ALT )
521         {
522             /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */
523               if( wParam == VK_MENU && !iMenuSysKey )
524                 iMenuSysKey = 1;
525               else
526                 iMenuSysKey = 0;
527             
528             iF10Key = 0;
529
530             if( wParam == VK_F4 )       /* try to close the window */
531             {
532                 HWND hWnd = WIN_GetTopParent( wndPtr->hwndSelf );
533                 wndPtr = WIN_FindWndPtr( hWnd );
534                 if( wndPtr && !(wndPtr->clsStyle & CS_NOCLOSE) )
535                     pPostMessage( hWnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
536                 WIN_ReleaseWndPtr(wndPtr);
537             }
538         } 
539         else if( wParam == VK_F10 )
540                 iF10Key = 1;
541              else
542                 if( wParam == VK_ESCAPE && (GetKeyState(VK_SHIFT) & 0x8000))
543                     pSendMessage( wndPtr->hwndSelf, WM_SYSCOMMAND, SC_KEYMENU, VK_SPACE );
544         break;
545
546     case WM_KEYUP:
547     case WM_SYSKEYUP:
548         /* Press and release F10 or ALT */
549         if (((wParam == VK_MENU) && iMenuSysKey) ||
550             ((wParam == VK_F10) && iF10Key))
551               pSendMessage( WIN_GetTopParent(wndPtr->hwndSelf),
552                              WM_SYSCOMMAND, SC_KEYMENU, 0L );
553         iMenuSysKey = iF10Key = 0;
554         break;
555
556     case WM_SYSCHAR:
557         iMenuSysKey = 0;
558         if (wParam == VK_RETURN && (wndPtr->dwStyle & WS_MINIMIZE))
559         {
560             pPostMessage( wndPtr->hwndSelf, WM_SYSCOMMAND, SC_RESTORE, 0L );
561             break;
562         } 
563         if ((HIWORD(lParam) & KEYDATA_ALT) && wParam)
564         {
565             if (wParam == VK_TAB || wParam == VK_ESCAPE) break;
566             if (wParam == VK_SPACE && (wndPtr->dwStyle & WS_CHILD))
567                 pSendMessage( wndPtr->parent->hwndSelf, msg, wParam, lParam );
568             else
569                 pSendMessage( wndPtr->hwndSelf, WM_SYSCOMMAND, SC_KEYMENU, wParam );
570         } 
571         else /* check for Ctrl-Esc */
572             if (wParam != VK_ESCAPE) MessageBeep(0);
573         break;
574
575     case WM_SHOWWINDOW:
576         if (!lParam) return 0; /* sent from ShowWindow */
577         if (!(wndPtr->dwStyle & WS_POPUP) || !wndPtr->owner) return 0;
578         if ((wndPtr->dwStyle & WS_VISIBLE) && wParam) return 0;
579         else if (!(wndPtr->dwStyle & WS_VISIBLE) && !wParam) return 0;
580         ShowWindow( wndPtr->hwndSelf, wParam ? SW_SHOWNOACTIVATE : SW_HIDE );
581         break; 
582
583     case WM_CANCELMODE:
584         if (wndPtr->parent == WIN_GetDesktop()) EndMenu();
585         if (GetCapture() == wndPtr->hwndSelf) ReleaseCapture();
586         WIN_ReleaseDesktop();
587         break;
588
589     case WM_VKEYTOITEM:
590     case WM_CHARTOITEM:
591         return -1;
592
593     case WM_DROPOBJECT:
594         return DRAG_FILE;  
595
596     case WM_QUERYDROPOBJECT:
597         if (wndPtr->dwExStyle & WS_EX_ACCEPTFILES) return 1;
598         break;
599
600     case WM_QUERYDRAGICON:
601         {
602             UINT len;
603
604             HICON hIcon = GetClassLongW( wndPtr->hwndSelf, GCL_HICON );
605             if (hIcon) return hIcon;
606             for(len=1; len<64; len++)
607                 if((hIcon = LoadIconW(wndPtr->hInstance, MAKEINTRESOURCEW(len))))
608                     return (LRESULT)hIcon;
609             return (LRESULT)LoadIconW(0, IDI_APPLICATIONW);
610         }
611         break;
612
613     case WM_ISACTIVEICON:
614         return ((wndPtr->flags & WIN_NCACTIVATED) != 0);
615
616     case WM_NOTIFYFORMAT:
617       if (IsWindowUnicode(wndPtr->hwndSelf)) return NFR_UNICODE;
618       else return NFR_ANSI;
619         
620     case WM_QUERYOPEN:
621     case WM_QUERYENDSESSION:
622         return 1;
623
624     case WM_SETICON:
625         {
626                 int index = (wParam != ICON_SMALL) ? GCL_HICON : GCL_HICONSM;
627                 HICON hOldIcon = GetClassLongW(wndPtr->hwndSelf, index); 
628                 SetClassLongW(wndPtr->hwndSelf, index, lParam);
629
630                 SetWindowPos(wndPtr->hwndSelf, 0, 0, 0, 0, 0, SWP_FRAMECHANGED
631                          | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE
632                          | SWP_NOZORDER);
633
634                 if( wndPtr->flags & WIN_NATIVE )
635                     wndPtr->pDriver->pSetHostAttr(wndPtr, HAK_ICONS, 0);
636
637                 return hOldIcon;
638         }
639
640     case WM_GETICON:
641         {
642                 int index = (wParam != ICON_SMALL) ? GCL_HICON : GCL_HICONSM;
643                 return GetClassLongW(wndPtr->hwndSelf, index); 
644         }
645
646     case WM_HELP:
647         pSendMessage( wndPtr->parent->hwndSelf, msg, wParam, lParam );
648         break;
649     }
650
651     return 0;
652 }
653
654
655
656 /***********************************************************************
657  *              DefWindowProc (USER.107)
658  */
659 LRESULT WINAPI DefWindowProc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
660                                 LPARAM lParam )
661 {
662     WND * wndPtr = WIN_FindWndPtr( hwnd );
663     LRESULT result = 0;
664
665     if (!wndPtr) return 0;
666     SPY_EnterMessage( SPY_DEFWNDPROC16, hwnd, msg, wParam, lParam );
667
668     switch(msg)
669     {
670     case WM_NCCREATE:
671         {
672             CREATESTRUCT16 *cs = MapSL(lParam);
673             /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
674              * may have child window IDs instead of window name */
675             if (HIWORD(cs->lpszName))
676                 DEFWND_SetTextA( wndPtr, MapSL(cs->lpszName) );
677             result = 1;
678         }
679         break;
680
681     case WM_NCCALCSIZE:
682         {
683             RECT rect32;
684             CONV_RECT16TO32( MapSL(lParam), &rect32 );
685             result = NC_HandleNCCalcSize( wndPtr, &rect32 );
686             CONV_RECT32TO16( &rect32, MapSL(lParam) );
687         }
688         break;
689
690     case WM_WINDOWPOSCHANGING:
691         result = WINPOS_HandleWindowPosChanging16( wndPtr, MapSL(lParam) );
692         break;
693
694     case WM_WINDOWPOSCHANGED:
695         {
696             WINDOWPOS16 * winPos = MapSL(lParam);
697             DEFWND_HandleWindowPosChanged( wndPtr, winPos->flags );
698         }
699         break;
700
701     case WM_GETTEXT:
702         if (wParam && wndPtr->text)
703         {
704             LPSTR dest = MapSL(lParam);
705             if (!WideCharToMultiByte( CP_ACP, 0, wndPtr->text, -1, dest, wParam, NULL, NULL ))
706                 dest[wParam-1] = 0;
707             result = strlen(dest);
708         }
709         break;
710
711     case WM_SETTEXT:
712         DEFWND_SetTextA( wndPtr, MapSL(lParam) );
713         if( (wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION )
714             NC_HandleNCPaint( hwnd , (HRGN)1 );
715         result = 1; /* success. FIXME: check text length */
716         break;
717
718     default:
719         result = DEFWND_DefWinProc( wndPtr, msg, wParam, lParam, FALSE );
720         break;
721     }
722
723     WIN_ReleaseWndPtr(wndPtr);
724     SPY_ExitMessage( SPY_RESULT_DEFWND16, hwnd, msg, result, wParam, lParam );
725     return result;
726 }
727
728
729 /***********************************************************************
730  *              DefWindowProcA (USER32.@)
731  *
732  */
733 LRESULT WINAPI DefWindowProcA( HWND hwnd, UINT msg, WPARAM wParam,
734                                  LPARAM lParam )
735 {
736     WND * wndPtr = WIN_FindWndPtr( hwnd );
737     LRESULT result = 0;
738
739     if (!wndPtr) return 0;
740     SPY_EnterMessage( SPY_DEFWNDPROC, hwnd, msg, wParam, lParam );
741
742     switch(msg)
743     {
744     case WM_NCCREATE:
745         {
746             CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
747             /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
748              * may have child window IDs instead of window name */
749             if (HIWORD(cs->lpszName))
750                 DEFWND_SetTextA( wndPtr, cs->lpszName );
751             result = 1;
752         }
753         break;
754
755     case WM_NCCALCSIZE:
756         result = NC_HandleNCCalcSize( wndPtr, (RECT *)lParam );
757         break;
758
759     case WM_WINDOWPOSCHANGING:
760         result = WINPOS_HandleWindowPosChanging( wndPtr,
761                                                    (WINDOWPOS *)lParam );
762         break;
763
764     case WM_WINDOWPOSCHANGED:
765         {
766             WINDOWPOS * winPos = (WINDOWPOS *)lParam;
767             DEFWND_HandleWindowPosChanged( wndPtr, winPos->flags );
768         }
769         break;
770
771     case WM_GETTEXT:
772         if (wParam && wndPtr->text)
773         {
774             if (!WideCharToMultiByte( CP_ACP, 0, wndPtr->text, -1,
775                                       (LPSTR)lParam, wParam, NULL, NULL ))
776                 ((LPSTR)lParam)[wParam-1] = 0;
777             result = (LRESULT)strlen( (LPSTR)lParam );
778         }
779         break;
780
781     case WM_SETTEXT:
782         DEFWND_SetTextA( wndPtr, (LPCSTR)lParam );
783         if( (wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION )
784             NC_HandleNCPaint( hwnd , (HRGN)1 );  /* Repaint caption */
785         result = 1; /* success. FIXME: check text length */
786         break;
787
788     /* for far east users (IMM32) - <hidenori@a2.ctktv.ne.jp> */
789     case WM_IME_CHAR:
790         {
791             CHAR    chChar1 = (CHAR)( (wParam>>8) & 0xff );
792             CHAR    chChar2 = (CHAR)( wParam & 0xff );
793
794             SendMessageA( hwnd, WM_CHAR, (WPARAM)chChar1, lParam );
795             if ( IsDBCSLeadByte( chChar1 ) )
796                 SendMessageA( hwnd, WM_CHAR, (WPARAM)chChar2, lParam );
797         }
798         break;
799     case WM_IME_KEYDOWN:
800         result = SendMessageA( hwnd, WM_KEYDOWN, wParam, lParam );
801         break;
802     case WM_IME_KEYUP:
803         result = SendMessageA( hwnd, WM_KEYUP, wParam, lParam );
804         break;
805
806     case WM_IME_STARTCOMPOSITION:
807     case WM_IME_COMPOSITION:
808     case WM_IME_ENDCOMPOSITION:
809     case WM_IME_SELECT:
810         {
811             HWND hwndIME;
812
813             hwndIME = DEFWND_ImmGetDefaultIMEWnd( hwnd );
814             if (hwndIME)
815                 result = SendMessageA( hwndIME, msg, wParam, lParam );
816         }
817         break;
818     case WM_IME_SETCONTEXT:
819         {
820             HWND hwndIME;
821
822             hwndIME = DEFWND_ImmGetDefaultIMEWnd( hwnd );
823             if (hwndIME)
824                 result = DEFWND_ImmIsUIMessageA( hwndIME, msg, wParam, lParam );
825         }
826         break;
827
828     default:
829         result = DEFWND_DefWinProc( wndPtr, msg, wParam, lParam, FALSE );
830         break;
831     }
832
833     WIN_ReleaseWndPtr(wndPtr);
834     SPY_ExitMessage( SPY_RESULT_DEFWND, hwnd, msg, result, wParam, lParam );
835     return result;
836 }
837
838
839 /***********************************************************************
840  *              DefWindowProcW (USER32.@) Calls default window message handler
841  * 
842  * Calls default window procedure for messages not processed 
843  *  by application.
844  *
845  *  RETURNS
846  *     Return value is dependent upon the message.
847 */
848 LRESULT WINAPI DefWindowProcW( 
849     HWND hwnd,      /* [in] window procedure recieving message */
850     UINT msg,       /* [in] message identifier */
851     WPARAM wParam,  /* [in] first message parameter */
852     LPARAM lParam )   /* [in] second message parameter */
853 {
854     WND * wndPtr = WIN_FindWndPtr( hwnd );
855     LRESULT result = 0;
856
857     if (!wndPtr) return 0;
858     SPY_EnterMessage( SPY_DEFWNDPROC, hwnd, msg, wParam, lParam );
859
860     switch(msg)
861     {
862     case WM_NCCREATE:
863         {
864             CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
865             /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
866              * may have child window IDs instead of window name */
867             if (HIWORD(cs->lpszName))
868                 DEFWND_SetTextW( wndPtr, cs->lpszName );
869             result = 1;
870         }
871         break;
872
873     case WM_NCCALCSIZE:
874         result = NC_HandleNCCalcSize( wndPtr, (RECT *)lParam );
875         break;
876
877     case WM_WINDOWPOSCHANGING:
878         result = WINPOS_HandleWindowPosChanging( wndPtr,
879                                                    (WINDOWPOS *)lParam );
880         break;
881
882     case WM_WINDOWPOSCHANGED:
883         {
884             WINDOWPOS * winPos = (WINDOWPOS *)lParam;
885             DEFWND_HandleWindowPosChanged( wndPtr, winPos->flags );
886         }
887         break;
888
889     case WM_GETTEXT:
890         if (wParam && wndPtr->text)
891         {
892             lstrcpynW( (LPWSTR)lParam, wndPtr->text, wParam );
893             result = strlenW( (LPWSTR)lParam );
894         }
895         break;
896
897     case WM_SETTEXT:
898         DEFWND_SetTextW( wndPtr, (LPCWSTR)lParam );
899         if( (wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION )
900             NC_HandleNCPaint( hwnd , (HRGN)1 );  /* Repaint caption */
901         result = 1; /* success. FIXME: check text length */
902         break;
903
904     /* for far east users (IMM32) - <hidenori@a2.ctktv.ne.jp> */
905     case WM_IME_CHAR:
906         SendMessageW( hwnd, WM_CHAR, wParam, lParam );
907         break;
908     case WM_IME_SETCONTEXT:
909         {
910             HWND hwndIME;
911
912             hwndIME = DEFWND_ImmGetDefaultIMEWnd( hwnd );
913             if (hwndIME)
914                 result = DEFWND_ImmIsUIMessageW( hwndIME, msg, wParam, lParam );
915         }
916         break;
917
918     default:
919         result = DEFWND_DefWinProc( wndPtr, msg, wParam, lParam, TRUE );
920         break;
921     }
922     WIN_ReleaseWndPtr(wndPtr);
923     SPY_ExitMessage( SPY_RESULT_DEFWND, hwnd, msg, result, wParam, lParam );
924     return result;
925 }