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