Height calculation was 1 off in ImageList_Read.
[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 "tweak.h"
19 #include "cache.h"
20 #include "wine/winuser16.h"
21
22 DEFAULT_DEBUG_CHANNEL(win)
23
24   /* bits in the dwKeyData */
25 #define KEYDATA_ALT             0x2000
26 #define KEYDATA_PREVSTATE       0x4000
27
28 static short iF10Key = 0;
29 static short iMenuSysKey = 0;
30
31 /***********************************************************************
32  *           DEFWND_HandleWindowPosChanged
33  *
34  * Handle the WM_WINDOWPOSCHANGED message.
35  */
36 static void DEFWND_HandleWindowPosChanged( WND *wndPtr, UINT flags )
37 {
38     WPARAM16 wp = SIZE_RESTORED;
39
40     if (!(flags & SWP_NOCLIENTMOVE))
41         SendMessage16( wndPtr->hwndSelf, WM_MOVE, 0,
42                     MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top));
43     if (!(flags & SWP_NOCLIENTSIZE))
44     {
45         if (wndPtr->dwStyle & WS_MAXIMIZE) wp = SIZE_MAXIMIZED;
46         else if (wndPtr->dwStyle & WS_MINIMIZE) wp = SIZE_MINIMIZED;
47
48         SendMessage16( wndPtr->hwndSelf, WM_SIZE, wp, 
49                      MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
50                             wndPtr->rectClient.bottom-wndPtr->rectClient.top));
51     }
52 }
53
54
55 /***********************************************************************
56  *           DEFWND_SetText
57  *
58  * Set the window text.
59  */
60 void DEFWND_SetText( WND *wndPtr, LPCSTR text )
61 {
62     if (!text) text = "";
63     if (wndPtr->text) HeapFree( SystemHeap, 0, wndPtr->text );
64     wndPtr->text = HEAP_strdupA( SystemHeap, 0, text );    
65     wndPtr->pDriver->pSetText(wndPtr, wndPtr->text);
66 }
67
68 /***********************************************************************
69  *           DEFWND_ControlColor
70  *
71  * Default colors for control painting.
72  */
73 HBRUSH DEFWND_ControlColor( HDC hDC, UINT16 ctlType )
74 {
75     if( ctlType == CTLCOLOR_SCROLLBAR)
76     {
77         HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR);
78         if (TWEAK_WineLook == WIN31_LOOK) {
79            SetTextColor( hDC, RGB(0, 0, 0) );
80            SetBkColor( hDC, RGB(255, 255, 255) );
81         } else {
82            COLORREF bk = GetSysColor(COLOR_3DHILIGHT);
83            SetTextColor( hDC, GetSysColor(COLOR_3DFACE));
84            SetBkColor( hDC, bk);
85
86            /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT 
87             * we better use 0x55aa bitmap brush to make scrollbar's background
88             * look different from the window background. 
89             */
90            if (bk == GetSysColor(COLOR_WINDOW)) {
91                return CACHE_GetPattern55AABrush();
92            }
93         }
94         UnrealizeObject( hb );
95         return hb;
96     }
97
98     SetTextColor( hDC, GetSysColor(COLOR_WINDOWTEXT));
99
100     if (TWEAK_WineLook > WIN31_LOOK) {
101         if ((ctlType == CTLCOLOR_EDIT) || (ctlType == CTLCOLOR_LISTBOX))
102             SetBkColor( hDC, GetSysColor(COLOR_WINDOW) );
103         else {
104             SetBkColor( hDC, GetSysColor(COLOR_3DFACE) );
105             return GetSysColorBrush(COLOR_3DFACE);
106         }
107     }
108     else
109         SetBkColor( hDC, GetSysColor(COLOR_WINDOW) );
110     return GetSysColorBrush(COLOR_WINDOW);
111 }
112
113
114 /***********************************************************************
115  *           DEFWND_SetRedraw
116  */
117 static void DEFWND_SetRedraw( WND* wndPtr, WPARAM wParam )
118 {
119     BOOL bVisible = wndPtr->dwStyle & WS_VISIBLE;
120
121     TRACE("%04x %i\n", wndPtr->hwndSelf, (wParam!=0) );
122
123     if( wParam )
124     {
125         if( !bVisible )
126         {
127             wndPtr->dwStyle |= WS_VISIBLE;
128             DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow );
129         }
130     }
131     else if( bVisible )
132     {
133         if( wndPtr->dwStyle & WS_MINIMIZE ) wParam = RDW_VALIDATE;
134         else wParam = RDW_ALLCHILDREN | RDW_VALIDATE;
135
136         PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, 0, wParam, 0 );
137         DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow );
138         wndPtr->dwStyle &= ~WS_VISIBLE;
139     }
140 }
141
142 /***********************************************************************
143  *           DEFWND_Print
144  *
145  * This method handles the default behavior for the WM_PRINT message.
146  */
147 static void DEFWND_Print(
148   WND*  wndPtr,
149   HDC   hdc,
150   ULONG uFlags)
151 {
152   /*
153    * Visibility flag.
154    */
155   if ( (uFlags & PRF_CHECKVISIBLE) &&
156        !IsWindowVisible(wndPtr->hwndSelf) )
157       return;
158
159   /*
160    * Unimplemented flags.
161    */
162   if ( (uFlags & PRF_CHILDREN) ||
163        (uFlags & PRF_OWNED)    ||
164        (uFlags & PRF_NONCLIENT) )
165   {
166     WARN("WM_PRINT message with unsupported flags\n");
167   }
168
169   /*
170    * Background
171    */
172   if ( uFlags & PRF_ERASEBKGND)
173     SendMessageA(wndPtr->hwndSelf, WM_ERASEBKGND, (WPARAM)hdc, 0);
174
175   /*
176    * Client area
177    */
178   if ( uFlags & PRF_CLIENT)
179     SendMessageA(wndPtr->hwndSelf, WM_PRINTCLIENT, (WPARAM)hdc, PRF_CLIENT);
180 }
181
182 /***********************************************************************
183  *           DEFWND_DefWinProc
184  *
185  * Default window procedure for messages that are the same in Win16 and Win32.
186  */
187 static LRESULT DEFWND_DefWinProc( WND *wndPtr, UINT msg, WPARAM wParam,
188                                   LPARAM lParam )
189 {
190     switch(msg)
191     {
192     case WM_NCPAINT:
193         return NC_HandleNCPaint( wndPtr->hwndSelf, (HRGN)wParam );
194
195     case WM_NCHITTEST:
196         return NC_HandleNCHitTest( wndPtr->hwndSelf, MAKEPOINT16(lParam) );
197
198     case WM_NCLBUTTONDOWN:
199         return NC_HandleNCLButtonDown( wndPtr, wParam, lParam );
200
201     case WM_LBUTTONDBLCLK:
202     case WM_NCLBUTTONDBLCLK:
203         return NC_HandleNCLButtonDblClk( wndPtr, wParam, lParam );
204
205     case WM_RBUTTONUP:
206     case WM_NCRBUTTONUP:
207         if ((wndPtr->flags & WIN_ISWIN32) || (TWEAK_WineLook > WIN31_LOOK))
208         {
209             ClientToScreen16(wndPtr->hwndSelf, (LPPOINT16)&lParam);
210             SendMessageA( wndPtr->hwndSelf, WM_CONTEXTMENU,
211                             wndPtr->hwndSelf, lParam);
212         }
213         break;
214
215     case WM_CONTEXTMENU:
216         if( wndPtr->dwStyle & WS_CHILD )
217             SendMessageA( wndPtr->parent->hwndSelf, msg, wParam, lParam );
218         else
219           if (wndPtr->hSysMenu)
220           { /*
221             TrackPopupMenu32(wndPtr->hSysMenu,TPM_LEFTALIGN | TPM_RETURNCMD,LOWORD(lParam),HIWORD(lParam),0,wndPtr->hwndSelf,NULL);
222             DestroyMenu32(wndPtr->hSysMenu);
223             */
224             FIXME("Display default popup menu\n");
225           /* Track system popup if click was in the caption area. */
226           }
227         break;
228
229     case WM_NCACTIVATE:
230         return NC_HandleNCActivate( wndPtr, wParam );
231
232     case WM_NCDESTROY:
233         if (wndPtr->text) HeapFree( SystemHeap, 0, wndPtr->text );
234         wndPtr->text = NULL;
235         if (wndPtr->pVScroll) HeapFree( SystemHeap, 0, wndPtr->pVScroll );
236         if (wndPtr->pHScroll) HeapFree( SystemHeap, 0, wndPtr->pHScroll );
237         wndPtr->pVScroll = wndPtr->pHScroll = NULL;
238         return 0;
239
240     case WM_PRINT:
241         DEFWND_Print(wndPtr, (HDC)wParam, lParam);
242         return 0;
243
244     case WM_PAINTICON:
245     case WM_PAINT:
246         {
247             PAINTSTRUCT16 ps;
248             HDC16 hdc = BeginPaint16( wndPtr->hwndSelf, &ps );
249             if( hdc ) 
250             {
251               if( (wndPtr->dwStyle & WS_MINIMIZE) && wndPtr->class->hIcon )
252               {
253                 int x = (wndPtr->rectWindow.right - wndPtr->rectWindow.left -
254                         GetSystemMetrics(SM_CXICON))/2;
255                 int y = (wndPtr->rectWindow.bottom - wndPtr->rectWindow.top -
256                         GetSystemMetrics(SM_CYICON))/2;
257                 TRACE("Painting class icon: vis rect=(%i,%i - %i,%i)\n",
258                 ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom );
259                 DrawIcon( hdc, x, y, wndPtr->class->hIcon );
260               }
261               EndPaint16( wndPtr->hwndSelf, &ps );
262             }
263             return 0;
264         }
265
266     case WM_SETREDRAW:
267         DEFWND_SetRedraw( wndPtr, wParam );
268         return 0;
269
270     case WM_CLOSE:
271         DestroyWindow( wndPtr->hwndSelf );
272         return 0;
273
274     case WM_MOUSEACTIVATE:
275         if (wndPtr->dwStyle & WS_CHILD)
276         {
277             LONG ret = SendMessage16( wndPtr->parent->hwndSelf,
278                                       WM_MOUSEACTIVATE, wParam, lParam );
279             if (ret) return ret;
280         }
281
282         /* Caption clicks are handled by the NC_HandleNCLButtonDown() */ 
283         return (LOWORD(lParam) >= HTCLIENT) ? MA_ACTIVATE : MA_NOACTIVATE;
284
285     case WM_ACTIVATE:
286         /* The default action in Windows is to set the keyboard focus to
287          * the window, if it's being activated and not minimized */
288         if (LOWORD(wParam) != WA_INACTIVE) {
289                 /* I don't know who put this SetWindowPos here, it does not
290                  * seem very logical to have it here... (FIXME?) */
291                 SetWindowPos(wndPtr->hwndSelf, HWND_TOP, 0, 0, 0, 0,
292                          SWP_NOMOVE | SWP_NOSIZE);
293                 if (!(wndPtr->dwStyle & WS_MINIMIZE))
294                         SetFocus(wndPtr->hwndSelf);
295         }
296         break;
297
298     case WM_ERASEBKGND:
299     case WM_ICONERASEBKGND:
300         {
301             RECT rect;
302
303             if (!wndPtr->class->hbrBackground) return 0;
304
305             /*  Since WM_ERASEBKGND may receive either a window dc or a    */ 
306             /*  client dc, the area to be erased has to be retrieved from  */
307             /*  the device context.                                        */
308             GetClipBox( (HDC)wParam, &rect );
309
310             /* Always call the Win32 variant of FillRect even on Win16,
311              * since despite the fact that Win16, as well as Win32,
312              * supports special background brushes for a window class,
313              * the Win16 variant of FillRect does not.
314              */
315             FillRect( (HDC) wParam, &rect, wndPtr->class->hbrBackground);
316             return 1;
317         }
318
319     case WM_GETDLGCODE:
320         return 0;
321
322     case WM_CTLCOLORMSGBOX:
323     case WM_CTLCOLOREDIT:
324     case WM_CTLCOLORLISTBOX:
325     case WM_CTLCOLORBTN:
326     case WM_CTLCOLORDLG:
327     case WM_CTLCOLORSTATIC:
328     case WM_CTLCOLORSCROLLBAR:
329         return (LRESULT)DEFWND_ControlColor( (HDC)wParam, msg - WM_CTLCOLORMSGBOX );
330
331     case WM_CTLCOLOR:
332         return (LRESULT)DEFWND_ControlColor( (HDC)wParam, HIWORD(lParam) );
333         
334     case WM_GETTEXTLENGTH:
335         if (wndPtr->text) return (LRESULT)strlen(wndPtr->text);
336         return 0;
337
338     case WM_SETCURSOR:
339         if (wndPtr->dwStyle & WS_CHILD)
340             if (SendMessage16(wndPtr->parent->hwndSelf, WM_SETCURSOR,
341                             wParam, lParam))
342                 return TRUE;
343         return NC_HandleSetCursor( wndPtr->hwndSelf, wParam, lParam );
344
345     case WM_SYSCOMMAND:
346         return NC_HandleSysCommand( wndPtr->hwndSelf, wParam,
347                                     MAKEPOINT16(lParam) );
348
349     case WM_KEYDOWN:
350         if(wParam == VK_F10) iF10Key = VK_F10;
351         break;
352
353     case WM_SYSKEYDOWN:
354         if( HIWORD(lParam) & KEYDATA_ALT )
355         {
356             /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */
357               if( wParam == VK_MENU && !iMenuSysKey )
358                 iMenuSysKey = 1;
359               else
360                 iMenuSysKey = 0;
361             
362             iF10Key = 0;
363
364             if( wParam == VK_F4 )       /* try to close the window */
365             {
366                 HWND hWnd = WIN_GetTopParent( wndPtr->hwndSelf );
367                 wndPtr = WIN_FindWndPtr( hWnd );
368                 if( wndPtr && !(wndPtr->class->style & CS_NOCLOSE) )
369                     PostMessage16( hWnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
370                 WIN_ReleaseWndPtr(wndPtr);
371             }
372         } 
373         else if( wParam == VK_F10 )
374                 iF10Key = 1;
375              else
376                 if( wParam == VK_ESCAPE && (GetKeyState(VK_SHIFT) & 0x8000))
377                     SendMessage16( wndPtr->hwndSelf, WM_SYSCOMMAND,
378                                   (WPARAM16)SC_KEYMENU, (LPARAM)VK_SPACE);
379         break;
380
381     case WM_KEYUP:
382     case WM_SYSKEYUP:
383         /* Press and release F10 or ALT */
384         if (((wParam == VK_MENU) && iMenuSysKey) ||
385             ((wParam == VK_F10) && iF10Key))
386               SendMessage16( WIN_GetTopParent(wndPtr->hwndSelf),
387                              WM_SYSCOMMAND, SC_KEYMENU, 0L );
388         iMenuSysKey = iF10Key = 0;
389         break;
390
391     case WM_SYSCHAR:
392         iMenuSysKey = 0;
393         if (wParam == VK_RETURN && (wndPtr->dwStyle & WS_MINIMIZE))
394         {
395             PostMessage16( wndPtr->hwndSelf, WM_SYSCOMMAND,
396                            (WPARAM16)SC_RESTORE, 0L ); 
397             break;
398         } 
399         if ((HIWORD(lParam) & KEYDATA_ALT) && wParam)
400         {
401             if (wParam == VK_TAB || wParam == VK_ESCAPE) break;
402             if (wParam == VK_SPACE && (wndPtr->dwStyle & WS_CHILD))
403                 SendMessage16( wndPtr->parent->hwndSelf, msg, wParam, lParam );
404             else
405                 SendMessage16( wndPtr->hwndSelf, WM_SYSCOMMAND,
406                                (WPARAM16)SC_KEYMENU, (LPARAM)(DWORD)wParam );
407         } 
408         else /* check for Ctrl-Esc */
409             if (wParam != VK_ESCAPE) MessageBeep(0);
410         break;
411
412     case WM_SHOWWINDOW:
413         if (!lParam) return 0; /* sent from ShowWindow */
414         if (!(wndPtr->dwStyle & WS_POPUP) || !wndPtr->owner) return 0;
415         if ((wndPtr->dwStyle & WS_VISIBLE) && wParam) return 0;
416         else if (!(wndPtr->dwStyle & WS_VISIBLE) && !wParam) return 0;
417         ShowWindow( wndPtr->hwndSelf, wParam ? SW_SHOWNOACTIVATE : SW_HIDE );
418         break; 
419
420     case WM_CANCELMODE:
421         if (wndPtr->parent == WIN_GetDesktop()) EndMenu();
422         if (GetCapture() == wndPtr->hwndSelf) ReleaseCapture();
423         WIN_ReleaseDesktop();
424         break;
425
426     case WM_VKEYTOITEM:
427     case WM_CHARTOITEM:
428         return -1;
429
430     case WM_DROPOBJECT:
431         return DRAG_FILE;  
432
433     case WM_QUERYDROPOBJECT:
434         if (wndPtr->dwExStyle & WS_EX_ACCEPTFILES) return 1;
435         break;
436
437     case WM_QUERYDRAGICON:
438         {
439             HICON16 hIcon=0;
440             UINT16 len;
441
442             if( (hIcon=wndPtr->class->hCursor) ) return (LRESULT)hIcon;
443             for(len=1; len<64; len++)
444                 if((hIcon=LoadIcon16(wndPtr->hInstance,MAKEINTRESOURCE16(len))))
445                     return (LRESULT)hIcon;
446             return (LRESULT)LoadIcon16(0,IDI_APPLICATION16);
447         }
448         break;
449
450     case WM_ISACTIVEICON:
451         return ((wndPtr->flags & WIN_NCACTIVATED) != 0);
452
453     case WM_NOTIFYFORMAT:
454       if (IsWindowUnicode(wndPtr->hwndSelf)) return NFR_UNICODE;
455       else return NFR_ANSI;
456         
457     case WM_QUERYOPEN:
458     case WM_QUERYENDSESSION:
459         return 1;
460
461     case WM_SETICON:
462     case WM_GETICON:
463         {
464             LRESULT result = 0;
465             int index = GCL_HICON;
466
467             if (wParam == ICON_SMALL)
468                 index = GCL_HICONSM;
469
470             result = GetClassLongA(wndPtr->hwndSelf, index);
471
472             if (msg == WM_SETICON)
473                 SetClassLongA(wndPtr->hwndSelf, index, lParam);
474
475             return result;
476         }
477     }
478
479     return 0;
480 }
481
482
483
484 /***********************************************************************
485  *           DefWindowProc16   (USER.107)
486  */
487 LRESULT WINAPI DefWindowProc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
488                                 LPARAM lParam )
489 {
490     WND * wndPtr = WIN_FindWndPtr( hwnd );
491     LRESULT result = 0;
492
493     if (!wndPtr) return 0;
494     SPY_EnterMessage( SPY_DEFWNDPROC16, hwnd, msg, wParam, lParam );
495
496     switch(msg)
497     {
498     case WM_NCCREATE:
499         {
500             CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
501             if (cs->lpszName)
502                 DEFWND_SetText( wndPtr, (LPSTR)PTR_SEG_TO_LIN(cs->lpszName) );
503             result = 1;
504         }
505         break;
506
507     case WM_NCCALCSIZE:
508         {
509             RECT rect32;
510             CONV_RECT16TO32( (RECT16 *)PTR_SEG_TO_LIN(lParam), &rect32 );
511             result = NC_HandleNCCalcSize( wndPtr, &rect32 );
512             CONV_RECT32TO16( &rect32, (RECT16 *)PTR_SEG_TO_LIN(lParam) );
513         }
514         break;
515
516     case WM_WINDOWPOSCHANGING:
517         result = WINPOS_HandleWindowPosChanging16( wndPtr,
518                                        (WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam) );
519         break;
520
521     case WM_WINDOWPOSCHANGED:
522         {
523             WINDOWPOS16 * winPos = (WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam);
524             DEFWND_HandleWindowPosChanged( wndPtr, winPos->flags );
525         }
526         break;
527
528     case WM_GETTEXT:
529         if (wParam && wndPtr->text)
530         {
531             lstrcpynA( (LPSTR)PTR_SEG_TO_LIN(lParam), wndPtr->text, wParam );
532             result = (LRESULT)strlen( (LPSTR)PTR_SEG_TO_LIN(lParam) );
533         }
534         break;
535
536     case WM_SETTEXT:
537         DEFWND_SetText( wndPtr, (LPSTR)PTR_SEG_TO_LIN(lParam) );
538         if( wndPtr->dwStyle & WS_CAPTION ) NC_HandleNCPaint( hwnd , (HRGN)1 );
539         break;
540
541     default:
542         result = DEFWND_DefWinProc( wndPtr, msg, wParam, lParam );
543         break;
544     }
545
546     WIN_ReleaseWndPtr(wndPtr);
547     SPY_ExitMessage( SPY_RESULT_DEFWND16, hwnd, msg, result );
548     return result;
549 }
550
551
552 /***********************************************************************
553  *  DefWindowProc32A [USER32.126] 
554  *
555  */
556 LRESULT WINAPI DefWindowProcA( HWND hwnd, UINT msg, WPARAM wParam,
557                                  LPARAM lParam )
558 {
559     WND * wndPtr = WIN_FindWndPtr( hwnd );
560     LRESULT result = 0;
561
562     if (!wndPtr) return 0;
563     SPY_EnterMessage( SPY_DEFWNDPROC, hwnd, msg, wParam, lParam );
564
565     switch(msg)
566     {
567     case WM_NCCREATE:
568         {
569             CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
570             if (cs->lpszName) DEFWND_SetText( wndPtr, cs->lpszName );
571             result = 1;
572         }
573         break;
574
575     case WM_NCCALCSIZE:
576         result = NC_HandleNCCalcSize( wndPtr, (RECT *)lParam );
577         break;
578
579     case WM_WINDOWPOSCHANGING:
580         result = WINPOS_HandleWindowPosChanging( wndPtr,
581                                                    (WINDOWPOS *)lParam );
582         break;
583
584     case WM_WINDOWPOSCHANGED:
585         {
586             WINDOWPOS * winPos = (WINDOWPOS *)lParam;
587             DEFWND_HandleWindowPosChanged( wndPtr, winPos->flags );
588         }
589         break;
590
591     case WM_GETTEXT:
592         if (wParam && wndPtr->text)
593         {
594             lstrcpynA( (LPSTR)lParam, wndPtr->text, wParam );
595             result = (LRESULT)strlen( (LPSTR)lParam );
596         }
597         break;
598
599     case WM_SETTEXT:
600         DEFWND_SetText( wndPtr, (LPSTR)lParam );
601         NC_HandleNCPaint( hwnd , (HRGN)1 );  /* Repaint caption */
602         break;
603
604     default:
605         result = DEFWND_DefWinProc( wndPtr, msg, wParam, lParam );
606         break;
607     }
608
609     WIN_ReleaseWndPtr(wndPtr);
610     SPY_ExitMessage( SPY_RESULT_DEFWND, hwnd, msg, result );
611     return result;
612 }
613
614
615 /***********************************************************************
616  * DefWindowProc32W [USER32.127] Calls default window message handler
617  * 
618  * Calls default window procedure for messages not processed 
619  *  by application.
620  *
621  *  RETURNS
622  *     Return value is dependent upon the message.
623 */
624 LRESULT WINAPI DefWindowProcW( 
625     HWND hwnd,      /* [in] window procedure recieving message */
626     UINT msg,       /* [in] message identifier */
627     WPARAM wParam,  /* [in] first message parameter */
628     LPARAM lParam )   /* [in] second message parameter */
629 {
630     LRESULT result;
631
632     switch(msg)
633     {
634     case WM_NCCREATE:
635         {
636             CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
637             if (cs->lpszName)
638             {
639                 WND *wndPtr = WIN_FindWndPtr( hwnd );
640                 LPSTR str = HEAP_strdupWtoA(GetProcessHeap(), 0, cs->lpszName);
641                 DEFWND_SetText( wndPtr, str );
642                 HeapFree( GetProcessHeap(), 0, str );
643                 WIN_ReleaseWndPtr(wndPtr);
644             }
645             result = 1;
646         }
647         break;
648
649     case WM_GETTEXT:
650         {
651             LPSTR str = HeapAlloc( GetProcessHeap(), 0, wParam );
652             result = DefWindowProcA( hwnd, msg, wParam, (LPARAM)str );
653             lstrcpynAtoW( (LPWSTR)lParam, str, wParam );
654             HeapFree( GetProcessHeap(), 0, str );
655         }
656         break;
657
658     case WM_SETTEXT:
659         {
660             LPSTR str = HEAP_strdupWtoA( GetProcessHeap(), 0, (LPWSTR)lParam );
661             result = DefWindowProcA( hwnd, msg, wParam, (LPARAM)str );
662             HeapFree( GetProcessHeap(), 0, str );
663         }
664         break;
665
666     default:
667         result = DefWindowProcA( hwnd, msg, wParam, lParam );
668         break;
669     }
670     return result;
671 }