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