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