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