Fix subclassing to support nested messages.
[wine] / dlls / richedit / richedit.c
1 /*
2  * RichEdit32  functions
3  *
4  * This module is a simple wrapper for the edit controls.
5  * At the point, it is good only for application who use the RICHEDIT
6  * control to display RTF text.
7  *
8  * Copyright 2000 by Jean-Claude Batista
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23  */
24
25 #include <stdarg.h>
26 #include <string.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #include "wingdi.h"
30 #include "winreg.h"
31 #include "winerror.h"
32 #include "riched32.h"
33 #include "richedit.h"
34 #include "charlist.h"
35 #define NO_SHLWAPI_STREAM
36 #include "shlwapi.h"
37
38 #include "rtf.h"
39 #include "rtf2text.h"
40 #include "wine/debug.h"
41
42 #define ID_EDIT      1
43
44 WINE_DEFAULT_DEBUG_CHANNEL(richedit);
45
46 HANDLE RICHED32_hHeap = NULL;
47 /* LPSTR  RICHED32_aSubclass = NULL; */
48
49 #define TRACE_EDIT_MSG32(str) \
50         TRACE(\
51                      "32 bit : " str ": hwnd=%p, wParam=%08x, lParam=%08x\n"\
52                      , \
53                      hwnd, (UINT)wParam, (UINT)lParam)
54
55 LPVOID* WINAPI CreateIRichEditOle();
56
57 /***********************************************************************
58  * DllMain [Internal] Initializes the internal 'RICHED32.DLL'.
59  *
60  * PARAMS
61  *     hinstDLL    [I] handle to the DLL's instance
62  *     fdwReason   [I]
63  *     lpvReserved [I] reserved, must be NULL
64  *
65  * RETURNS
66  *     Success: TRUE
67  *     Failure: FALSE
68  */
69
70 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
71 {
72     TRACE("\n");
73     switch (fdwReason)
74     {
75     case DLL_PROCESS_ATTACH:
76         DisableThreadLibraryCalls(hinstDLL);
77         /* create private heap */
78         RICHED32_hHeap = HeapCreate (0, 0x10000, 0);
79         /* register the Rich Edit class */
80         RICHED32_Register ();
81         break;
82
83     case DLL_PROCESS_DETACH:
84         /* unregister all common control classes */
85         RICHED32_Unregister ();
86         HeapDestroy (RICHED32_hHeap);
87         RICHED32_hHeap = NULL;
88         break;
89     }
90     return TRUE;
91 }
92
93 /* Support routines for window procedure */
94    INT RICHEDIT_GetTextRange(HWND hwnd,TEXTRANGEA *tr);
95    INT RICHEDIT_GetSelText(HWND hwnd,LPSTR lpstrBuffer);
96
97
98 const WCHAR RichEditInfoStr[] = { '_','R','T','F','_','I','n','f','o', 0 };
99
100 typedef struct _RTFControl_info
101 {
102     HWND hwndEdit;
103     HWND hwndParent;
104     char* rtfBuffer;
105     RTF_Info *parser;
106 } RTFControl_Info;
107
108 /*
109  *
110  * DESCRIPTION:
111  * Window procedure of the RichEdit control.
112  *
113  */
114 static LRESULT WINAPI RICHED32_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
115                                    LPARAM lParam)
116 {
117     int RTFToBuffer(RTF_Info *parser, char* pBuffer, int nBufferSize);
118     LONG newstyle = 0;
119     LONG style = 0;
120     RTFControl_Info *info;
121     int rtfBufferSize;
122     CHARRANGE *cr;
123
124     info = GetPropW( hwnd, RichEditInfoStr );
125     TRACE("uMsg: 0x%x hwnd: %p\n",uMsg,hwnd);
126
127     switch (uMsg)
128     {
129
130     case WM_CREATE:
131             TRACE_EDIT_MSG32("WM_CREATE Passed to default");
132             DefWindowProcA( hwnd,uMsg,wParam,lParam);
133             return 0 ;
134         
135     case WM_NCCREATE :
136             TRACE_EDIT_MSG32("WM_NCCREATE");
137
138             info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
139                               sizeof (RTFControl_Info));
140             info->parser = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
141                               sizeof (RTF_Info));
142             SetPropW(hwnd, RichEditInfoStr, (HANDLE)info);
143
144             /* remove SCROLLBARS from the current window style */
145             info->hwndParent = ((LPCREATESTRUCTA) lParam)->hwndParent;
146
147             newstyle = style = ((LPCREATESTRUCTA) lParam)->style;
148             newstyle &= ~WS_HSCROLL;
149             newstyle &= ~WS_VSCROLL;
150             newstyle &= ~ES_AUTOHSCROLL;
151             newstyle &= ~ES_AUTOVSCROLL;
152             SetWindowLongA(hwnd,GWL_STYLE, newstyle);
153
154             TRACE("previous hwndEdit: %p\n",info->hwndEdit);
155             info->hwndEdit = CreateWindowA ("edit", ((LPCREATESTRUCTA) lParam)->lpszName,
156                                    style, 0, 0, 0, 0,
157                                    hwnd, (HMENU) ID_EDIT,
158                                    ((LPCREATESTRUCTA) lParam)->hInstance, NULL) ;
159             TRACE("hwndEdit: %p hwnd: %p\n",info->hwndEdit,hwnd);
160
161             if (info->hwndEdit)
162                 return TRUE ;
163             else
164                 return FALSE ;
165
166     case WM_SETFOCUS :
167             TRACE_EDIT_MSG32("WM_SETFOCUS");
168             SetFocus (info->hwndEdit) ;
169             return 0 ;
170
171     case WM_SIZE :
172             TRACE_EDIT_MSG32("WM_SIZE");
173             MoveWindow (info->hwndEdit, 0, 0, LOWORD (lParam), HIWORD (lParam), TRUE) ;
174             return 0 ;
175
176     case WM_COMMAND :
177         TRACE_EDIT_MSG32("WM_COMMAND");
178         switch(HIWORD(wParam)) {
179                 case EN_CHANGE:
180                 case EN_HSCROLL:
181                 case EN_KILLFOCUS:
182                 case EN_SETFOCUS:
183                 case EN_UPDATE:
184                 case EN_VSCROLL:
185                         return SendMessageA(info->hwndParent, WM_COMMAND,
186                                 wParam, (LPARAM)(hwnd));
187
188                 case EN_ERRSPACE:
189                 case EN_MAXTEXT:
190                         MessageBoxA (hwnd, "RichEdit control out of space.",
191                                   "ERROR", MB_OK | MB_ICONSTOP) ;
192                         return 0 ;
193                 }
194
195     case EM_STREAMIN:
196             TRACE_EDIT_MSG32("EM_STREAMIN");
197
198             /* setup the RTF parser */
199             RTFSetEditStream(info->parser,( EDITSTREAM*)lParam);
200             info->parser->rtfFormat = wParam&(SF_TEXT|SF_RTF);
201             WriterInit(info->parser);
202             RTFInit (info->parser);
203             BeginFile(info->parser);
204
205             /* do the parsing */
206             RTFRead (info->parser);
207
208             rtfBufferSize = RTFToBuffer(info->parser,NULL, 0);
209             info->rtfBuffer = HeapAlloc(RICHED32_hHeap, 0,rtfBufferSize*sizeof(char));
210             if(info->rtfBuffer)
211             {
212                 RTFToBuffer(info->parser,info->rtfBuffer, rtfBufferSize);
213                 SetWindowTextA(info->hwndEdit,info->rtfBuffer);
214                 HeapFree(RICHED32_hHeap, 0,info->rtfBuffer);
215             }
216             else
217                 WARN("Not enough memory for a allocating rtfBuffer\n");
218
219             return 0;
220
221 /* Messages specific to Richedit controls */
222
223     case EM_AUTOURLDETECT:
224             TRACE_EDIT_MSG32("EM_AUTOURLDETECT Ignored");
225             return 0;
226
227     case EM_CANPASTE:
228             TRACE_EDIT_MSG32("EM_CANPASTE Ignored");
229             return 0;
230
231     case EM_CANREDO:
232             TRACE_EDIT_MSG32("EM_CANREDO Ignored");
233             return 0;
234
235     case EM_DISPLAYBAND:
236             TRACE_EDIT_MSG32("EM_DISPLAYBAND Ignored");
237             return 0;
238
239     case EM_EXGETSEL:
240             TRACE_EDIT_MSG32("EM_EXGETSEL -> EM_GETSEL");
241             cr = (VOID *) lParam;
242             if (info->hwndEdit) SendMessageA( info->hwndEdit, EM_GETSEL, (INT)&cr->cpMin, (INT)&cr->cpMax);
243             TRACE("cpMin: 0x%x cpMax: 0x%x\n",(INT)cr->cpMin,(INT)cr->cpMax);
244             return 0;
245
246     case EM_EXLIMITTEXT:
247         {
248            DWORD limit = lParam;
249            TRACE_EDIT_MSG32("EM_EXLIMITTEXT");
250            if (limit > 65534)
251            {
252                 limit = 0xFFFFFFFF;
253            }
254            return SendMessageA(info->hwndEdit,EM_SETLIMITTEXT,limit,0);
255         }
256
257     case EM_EXLINEFROMCHAR:
258             TRACE_EDIT_MSG32("EM_EXLINEFROMCHAR -> LINEFROMCHAR");
259             if (info->hwndEdit) return SendMessageA( info->hwndEdit, EM_LINEFROMCHAR, lParam, wParam);
260             return 0;
261
262     case EM_EXSETSEL:
263             TRACE_EDIT_MSG32("EM_EXSETSEL -> EM_SETSEL");
264             cr = (VOID *) lParam;
265             if (info->hwndEdit) SendMessageA( info->hwndEdit, EM_SETSEL, cr->cpMin, cr->cpMax);
266             return 0;
267
268     case EM_FINDTEXT:
269             TRACE_EDIT_MSG32("EM_FINDTEXT Ignored");
270             return 0;
271
272     case EM_FINDTEXTEX:
273             TRACE_EDIT_MSG32("EM_FINDTEXTEX Ignored");
274             return 0;
275
276     case EM_FINDTEXTEXW:
277             TRACE_EDIT_MSG32("EM_FINDTEXTEXW Ignored");
278             return 0;
279
280     case EM_FINDTEXTW:
281             TRACE_EDIT_MSG32("EM_FINDTEXTW Ignored");
282             return 0;
283
284     case EM_FINDWORDBREAK:
285             TRACE_EDIT_MSG32("EM_FINDWORDBREAK Ignored");
286             return 0;
287
288     case EM_FORMATRANGE:
289             TRACE_EDIT_MSG32("EM_FORMATRANGE Ignored");
290             return 0;
291
292     case EM_GETAUTOURLDETECT:
293             TRACE_EDIT_MSG32("EM_GETAUTOURLDETECT Ignored");
294             return 0;
295
296     case EM_GETBIDIOPTIONS:
297             TRACE_EDIT_MSG32("EM_GETBIDIOPTIONS Ignored");
298             return 0;
299
300     case EM_GETCHARFORMAT:
301             TRACE_EDIT_MSG32("EM_GETCHARFORMAT Ignored");
302             return 0;
303
304     case EM_GETEDITSTYLE:
305             TRACE_EDIT_MSG32("EM_GETEDITSTYLE Ignored");
306             return 0;
307
308     case EM_GETEVENTMASK:
309             TRACE_EDIT_MSG32("EM_GETEVENTMASK Ignored");
310             return 0;
311
312     case EM_GETIMECOLOR:
313             TRACE_EDIT_MSG32("EM_GETIMECOLOR Ignored");
314             return 0;
315
316     case EM_GETIMECOMPMODE:
317             TRACE_EDIT_MSG32("EM_GETIMECOMPMODE Ignored");
318             return 0;
319
320     case EM_GETIMEOPTIONS:
321             TRACE_EDIT_MSG32("EM_GETIMEOPTIONS Ignored");
322             return 0;
323
324     case EM_GETLANGOPTIONS:
325             TRACE_EDIT_MSG32("STUB: EM_GETLANGOPTIONS");
326             return 0;
327
328     case EM_GETOLEINTERFACE:
329             TRACE_EDIT_MSG32("EM_GETOLEINTERFACE Ignored");
330             return 0;
331
332     case EM_GETOPTIONS:
333             TRACE_EDIT_MSG32("EM_GETOPTIONS Ignored");
334             return 0;
335
336     case EM_GETPARAFORMAT:
337             TRACE_EDIT_MSG32("EM_GETPARAFORMAT Ignored");
338             return 0;
339
340     case EM_GETPUNCTUATION:
341             TRACE_EDIT_MSG32("EM_GETPUNCTUATION Ignored");
342             return 0;
343
344     case EM_GETREDONAME:
345             TRACE_EDIT_MSG32("EM_GETREDONAME Ignored");
346             return 0;
347
348     case EM_GETSCROLLPOS:
349             TRACE_EDIT_MSG32("EM_GETSCROLLPOS Ignored");
350             return 0;
351
352     case EM_GETSELTEXT:
353             TRACE_EDIT_MSG32("EM_GETSELTEXT");
354             return RICHEDIT_GetSelText(info->hwndEdit,(void *)lParam);
355
356     case EM_GETTEXTEX:
357             TRACE_EDIT_MSG32("EM_GETTEXTEX Ignored");
358             return 0;
359
360     case EM_GETTEXTLENGTHEX:
361             TRACE_EDIT_MSG32("EM_GETTEXTLENGTHEX Ignored");
362             return 0;
363
364     case EM_GETTEXTMODE:
365             TRACE_EDIT_MSG32("EM_GETTEXTMODE Ignored");
366             return 0;
367
368     case EM_GETTEXTRANGE:
369             TRACE_EDIT_MSG32("EM_GETTEXTRANGE");
370             return RICHEDIT_GetTextRange(info->hwndEdit,(TEXTRANGEA *)lParam);
371
372     case EM_GETTYPOGRAPHYOPTIONS:
373             TRACE_EDIT_MSG32("EM_GETTYPOGRAPHYOPTIONS Ignored");
374             return 0;
375
376     case EM_GETUNDONAME:
377             TRACE_EDIT_MSG32("EM_GETUNDONAME Ignored");
378             return 0;
379
380     case EM_GETWORDBREAKPROCEX:
381             TRACE_EDIT_MSG32("EM_GETWORDBREAKPROCEX Ignored");
382             return 0;
383
384     case EM_GETWORDWRAPMODE:
385             TRACE_EDIT_MSG32("EM_GETWORDWRAPMODE Ignored");
386             return 0;
387
388     case EM_GETZOOM:
389             TRACE_EDIT_MSG32("EM_GETZOOM Ignored");
390             return 0;
391
392     case EM_HIDESELECTION:
393             TRACE_EDIT_MSG32("EM_HIDESELECTION Ignored");
394             return 0;
395
396     case EM_PASTESPECIAL:
397             TRACE_EDIT_MSG32("EM_PASTESPECIAL Ignored");
398             return 0;
399
400     case EM_RECONVERSION:
401             TRACE_EDIT_MSG32("EM_RECONVERSION Ignored");
402             return 0;
403
404     case EM_REDO:
405             TRACE_EDIT_MSG32("EM_REDO Ignored");
406             return 0;
407
408     case EM_REQUESTRESIZE:
409             TRACE_EDIT_MSG32("EM_REQUESTRESIZE Ignored");
410             return 0;
411
412     case EM_SELECTIONTYPE:
413             TRACE_EDIT_MSG32("EM_SELECTIONTYPE Ignored");
414             return 0;
415
416     case EM_SETBIDIOPTIONS:
417             TRACE_EDIT_MSG32("EM_SETBIDIOPTIONS Ignored");
418             return 0;
419
420     case EM_SETBKGNDCOLOR:
421             TRACE_EDIT_MSG32("EM_SETBKGNDCOLOR Ignored");
422             return 0;
423
424     case EM_SETCHARFORMAT:
425             TRACE_EDIT_MSG32("EM_SETCHARFORMAT Ignored");
426             return 0;
427
428     case EM_SETEDITSTYLE:
429             TRACE_EDIT_MSG32("EM_SETEDITSTYLE Ignored");
430             return 0;
431
432     case EM_SETEVENTMASK:
433             TRACE_EDIT_MSG32("EM_SETEVENTMASK Ignored");
434             return 0;
435
436     case EM_SETFONTSIZE:
437             TRACE_EDIT_MSG32("EM_SETFONTSIZE Ignored");
438             return 0;
439
440     case EM_SETIMECOLOR:
441             TRACE_EDIT_MSG32("EM_SETIMECOLO Ignored");
442             return 0;
443
444     case EM_SETIMEOPTIONS:
445             TRACE_EDIT_MSG32("EM_SETIMEOPTIONS Ignored");
446             return 0;
447
448     case EM_SETLANGOPTIONS:
449             TRACE_EDIT_MSG32("EM_SETLANGOPTIONS Ignored");
450             return 0;
451
452     case EM_SETOLECALLBACK:
453             TRACE_EDIT_MSG32("EM_SETOLECALLBACK Ignored");
454             return 0;
455
456     case EM_SETOPTIONS:
457             TRACE_EDIT_MSG32("EM_SETOPTIONS Ignored");
458             return 0;
459
460     case EM_SETPALETTE:
461             TRACE_EDIT_MSG32("EM_SETPALETTE Ignored");
462             return 0;
463
464     case EM_SETPARAFORMAT:
465             TRACE_EDIT_MSG32("EM_SETPARAFORMAT Ignored");
466             return 0;
467
468     case EM_SETPUNCTUATION:
469             TRACE_EDIT_MSG32("EM_SETPUNCTUATION Ignored");
470             return 0;
471
472     case EM_SETSCROLLPOS:
473             TRACE_EDIT_MSG32("EM_SETSCROLLPOS Ignored");
474             return 0;
475
476     case EM_SETTARGETDEVICE:
477             TRACE_EDIT_MSG32("EM_SETTARGETDEVICE Ignored");
478             return 0;
479
480     case EM_SETTEXTEX:
481             TRACE_EDIT_MSG32("EM_SETTEXTEX Ignored");
482             return 0;
483
484     case EM_SETTEXTMODE:
485             TRACE_EDIT_MSG32("EM_SETTEXTMODE Ignored");
486             return 0;
487
488     case EM_SETTYPOGRAPHYOPTIONS:
489             TRACE_EDIT_MSG32("EM_SETTYPOGRAPHYOPTIONS Ignored");
490             return 0;
491
492     case EM_SETUNDOLIMIT:
493             TRACE_EDIT_MSG32("EM_SETUNDOLIMIT Ignored");
494             return 0;
495
496     case EM_SETWORDBREAKPROCEX:
497             TRACE_EDIT_MSG32("EM_SETWORDBREAKPROCEX Ignored");
498             return 0;
499
500     case EM_SETWORDWRAPMODE:
501             TRACE_EDIT_MSG32("EM_SETWORDWRAPMODE Ignored");
502             return 0;
503
504     case EM_SETZOOM:
505             TRACE_EDIT_MSG32("EM_SETZOOM Ignored");
506             return 0;
507
508     case EM_SHOWSCROLLBAR:
509             TRACE_EDIT_MSG32("EM_SHOWSCROLLBAR Ignored");
510             return 0;
511
512     case EM_STOPGROUPTYPING:
513             TRACE_EDIT_MSG32("EM_STOPGROUPTYPING Ignored");
514             return 0;
515
516     case EM_STREAMOUT:
517             TRACE_EDIT_MSG32("EM_STREAMOUT Ignored");
518             return 0;
519
520 /* Messages dispatched to the edit control */
521      case EM_CANUNDO:
522             TRACE_EDIT_MSG32("EM_CANUNDO Passed to edit control");
523             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
524      case EM_CHARFROMPOS:
525             TRACE_EDIT_MSG32("EM_CHARFROMPOS Passed to edit control");
526             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
527      case EM_EMPTYUNDOBUFFER:
528             TRACE_EDIT_MSG32("EM_EMPTYUNDOBUFFER Passed to edit control");
529             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
530      case EM_FMTLINES:
531             TRACE_EDIT_MSG32("EM_FMTLINES Passed to edit control");
532             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
533      case EM_GETFIRSTVISIBLELINE:
534             TRACE_EDIT_MSG32("EM_GETFIRSTVISIBLELINE Passed to edit control");
535             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
536      case EM_GETHANDLE:
537             TRACE_EDIT_MSG32("EM_GETHANDLE Passed to edit control");
538             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
539  /*    case EM_GETIMESTATUS:*/
540      case EM_GETLIMITTEXT:
541             TRACE_EDIT_MSG32("EM_GETLIMITTEXT Passed to edit control");
542             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
543      case EM_GETLINE:
544             TRACE_EDIT_MSG32("EM_GETLINE Passed to edit control");
545             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
546      case EM_GETLINECOUNT:
547             TRACE_EDIT_MSG32("EM_GETLINECOUNT Passed to edit control");
548             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
549      case EM_GETMARGINS:
550             TRACE_EDIT_MSG32("EM_GETMARGINS Passed to edit control");
551             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
552      case EM_GETMODIFY:
553             TRACE_EDIT_MSG32("EM_GETMODIFY Passed to edit control");
554             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
555      case EM_GETPASSWORDCHAR:
556             TRACE_EDIT_MSG32("EM_GETPASSWORDCHAR Passed to edit control");
557             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
558      case EM_GETRECT:
559             TRACE_EDIT_MSG32("EM_GETRECT Passed to edit control");
560             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
561      case EM_GETSEL:
562             TRACE_EDIT_MSG32("EM_GETSEL Passed to edit control");
563             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
564      case EM_GETTHUMB:
565             TRACE_EDIT_MSG32("EM_GETTHUMB Passed to edit control");
566             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
567      case EM_GETWORDBREAKPROC:
568             TRACE_EDIT_MSG32("EM_GETWORDBREAKPROC Passed to edit control");
569             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
570      case EM_LINEFROMCHAR:
571             TRACE_EDIT_MSG32("EM_LINEFROMCHAR Passed to edit control");
572             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
573      case EM_LINEINDEX:
574             TRACE_EDIT_MSG32("EM_LINEINDEX Passed to edit control");
575             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
576      case EM_LINELENGTH:
577             TRACE_EDIT_MSG32("EM_LINELENGTH Passed to edit control");
578             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
579      case EM_LINESCROLL:
580             TRACE_EDIT_MSG32("EM_LINESCROLL Passed to edit control");
581             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
582      case EM_POSFROMCHAR:
583             TRACE_EDIT_MSG32("EM_POSFROMCHAR Passed to edit control");
584             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
585      case EM_REPLACESEL:
586             TRACE_EDIT_MSG32("case EM_REPLACESEL Passed to edit control");
587             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
588      case EM_SCROLL:
589             TRACE_EDIT_MSG32("case EM_SCROLL Passed to edit control");
590             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
591      case EM_SCROLLCARET:
592             TRACE_EDIT_MSG32("EM_SCROLLCARET Passed to edit control");
593             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
594      case EM_SETHANDLE:
595             TRACE_EDIT_MSG32("EM_SETHANDLE Passed to edit control");
596             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
597  /*    case EM_SETIMESTATUS:*/
598      case EM_SETLIMITTEXT:
599             TRACE_EDIT_MSG32("EM_SETLIMITTEXT Passed to edit control");
600             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
601      case EM_SETMARGINS:
602             TRACE_EDIT_MSG32("case EM_SETMARGINS Passed to edit control");
603             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
604      case EM_SETMODIFY:
605             TRACE_EDIT_MSG32("EM_SETMODIFY Passed to edit control");
606             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
607      case EM_SETPASSWORDCHAR:
608             TRACE_EDIT_MSG32("EM_SETPASSWORDCHAR Passed to edit control");
609             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
610      case EM_SETREADONLY:
611             TRACE_EDIT_MSG32("EM_SETREADONLY Passed to edit control");
612             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
613      case EM_SETRECT:
614             TRACE_EDIT_MSG32("EM_SETRECT Passed to edit control");
615             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
616      case EM_SETRECTNP:
617             TRACE_EDIT_MSG32("EM_SETRECTNP Passed to edit control");
618             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
619      case EM_SETSEL:
620             TRACE_EDIT_MSG32("EM_SETSEL Passed to edit control");
621             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
622      case EM_SETTABSTOPS:
623             TRACE_EDIT_MSG32("EM_SETTABSTOPS Passed to edit control");
624             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
625      case EM_SETWORDBREAKPROC:
626             TRACE_EDIT_MSG32("EM_SETWORDBREAKPROC Passed to edit control");
627             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
628      case EM_UNDO:
629             TRACE_EDIT_MSG32("EM_UNDO Passed to edit control");
630             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
631
632      case WM_STYLECHANGING:
633             TRACE_EDIT_MSG32("WM_STYLECHANGING Passed to edit control");
634             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
635      case WM_STYLECHANGED:
636             TRACE_EDIT_MSG32("WM_STYLECHANGED Passed to edit control");
637             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
638      case WM_GETTEXT:
639             TRACE_EDIT_MSG32("WM_GETTEXT Passed to edit control");
640             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
641      case WM_GETTEXTLENGTH:
642             TRACE_EDIT_MSG32("WM_GETTEXTLENGTH Passed to edit control");
643             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
644      case WM_SETTEXT:
645             TRACE_EDIT_MSG32("WM_SETTEXT Passed to edit control");
646             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
647      case WM_CUT:
648             TRACE_EDIT_MSG32("WM_CUT Passed to edit control");
649             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
650      case WM_COPY:
651             TRACE_EDIT_MSG32("WM_COPY Passed to edit control");
652             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
653     case WM_PASTE:
654             TRACE_EDIT_MSG32("WM_PASTE Passed to edit control");
655             return SendMessageA( info->hwndEdit, uMsg, wParam, lParam);
656
657     /* Messages passed to default handler. */
658     case WM_NCCALCSIZE:
659         /* A fundamental problem with embedding an edit control within another
660            window to emulate the richedit control, is that normally, the 
661            WM_NCCALCSIZE message window would return the client area of the 
662            edit control.
663            
664            While we could send a message to the edit control here to get that size
665            and return that value, this causes problems with the WM_SIZE message.
666            That is because the WM_SIZE message uses the returned value of
667            WM_NCCALCSIZE (via X11DRV_SetWindowSize) to determine the size to make 
668            the edit control. If we return the size of the edit control client area
669            here, the result is the symptom of the edit control being inset on the 
670            right and bottom by the width of any existing scrollbars.
671            
672            The easy fix is to have WM_NCCALCSIZE return the true size of this 
673            enclosing window, which is what we have done here. The more difficult 
674            fix is to create a custom Richedit MoveWindow procedure for use in the 
675            WM_SIZE message above. Since it is very unlikely that an app would call
676            and use the WM_NCCALCSIZE message, we stick with the easy fix for now.
677          */
678         TRACE_EDIT_MSG32("WM_NCCALCSIZE Passed to default");
679         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
680     case WM_NCPAINT:
681         TRACE_EDIT_MSG32("WM_NCPAINT Passed to default");
682         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
683     case WM_PAINT:
684         TRACE_EDIT_MSG32("WM_PAINT Passed to default");
685         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
686     case WM_ERASEBKGND:
687         TRACE_EDIT_MSG32("WM_ERASEBKGND Passed to default");
688         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
689     case WM_KILLFOCUS:
690         TRACE_EDIT_MSG32("WM_KILLFOCUS Passed to default");
691         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
692     case WM_DESTROY:
693         TRACE_EDIT_MSG32("WM_DESTROY Passed to default");
694         HeapFree( GetProcessHeap(), 0, info->parser );
695         HeapFree( GetProcessHeap(), 0, info );
696         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
697     case WM_CHILDACTIVATE:
698         TRACE_EDIT_MSG32("WM_CHILDACTIVATE Passed to default");
699         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
700
701     case WM_WINDOWPOSCHANGING:
702         TRACE_EDIT_MSG32("WM_WINDOWPOSCHANGING Passed to default");
703         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
704     case WM_WINDOWPOSCHANGED:
705         TRACE_EDIT_MSG32("WM_WINDOWPOSCHANGED Passed to default");
706         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
707 /*    case WM_INITIALUPDATE:
708         TRACE_EDIT_MSG32("WM_INITIALUPDATE Passed to default");
709         return DefWindowProcA( hwnd,uMsg,wParam,lParam); */
710     case WM_CTLCOLOREDIT:
711         TRACE_EDIT_MSG32("WM_CTLCOLOREDIT Passed to default");
712         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
713     case WM_SETCURSOR:
714         TRACE_EDIT_MSG32("WM_SETCURSOR Passed to default");
715         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
716     case WM_MOVE:
717         TRACE_EDIT_MSG32("WM_MOVE Passed to default");
718         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
719     case WM_SHOWWINDOW:
720         TRACE_EDIT_MSG32("WM_SHOWWINDOW Passed to default");
721         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
722     case WM_PARENTNOTIFY:
723         TRACE_EDIT_MSG32("WM_PARENTNOTIFY Passed to default");
724         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
725     case WM_SETREDRAW:
726         TRACE_EDIT_MSG32("WM_SETREDRAW Passed to default");
727         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
728     case WM_NCDESTROY:
729         TRACE_EDIT_MSG32("WM_NCDESTROY Passed to default");
730         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
731     case WM_NCHITTEST:
732         TRACE_EDIT_MSG32("WM_NCHITTEST Passed to default");
733         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
734     case WM_CTLCOLORSTATIC:
735         TRACE_EDIT_MSG32("WM_CTLCOLORSTATIC Passed to default");
736         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
737     case WM_NCMOUSEMOVE:
738         TRACE_EDIT_MSG32("WM_NCMOUSEMOVE Passed to default");
739         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
740     case WM_CLEAR:
741         TRACE_EDIT_MSG32("WM_CLEAR Passed to default");
742         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
743    /*
744     * used by IE in the EULA box
745     */
746     case WM_ALTTABACTIVE:
747         TRACE_EDIT_MSG32("WM_ALTTABACTIVE");
748         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
749     case WM_GETDLGCODE:
750         TRACE_EDIT_MSG32("WM_GETDLGCODE");
751         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
752     case WM_SETFONT:
753         TRACE_EDIT_MSG32("WM_SETFONT");
754         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
755
756     }
757
758     if ((uMsg >= WM_USER) && (uMsg < WM_APP)) {
759         FIXME("Unknown message 0x%x Passed to default hwnd=%p, wParam=%08x, lParam=%08x\n",
760                uMsg, hwnd, (UINT)wParam, (UINT)lParam);
761     }
762
763    return DefWindowProcA( hwnd,uMsg,wParam,lParam);
764 }
765
766 /***********************************************************************
767  * DllGetVersion [RICHED32.2]
768  *
769  * Retrieves version information of the 'RICHED32.DLL'
770  *
771  * PARAMS
772  *     pdvi [O] pointer to version information structure.
773  *
774  * RETURNS
775  *     Success: S_OK
776  *     Failure: E_INVALIDARG
777  *
778  * NOTES
779  *     Returns version of a comctl32.dll from IE4.01 SP1.
780  */
781
782 HRESULT WINAPI
783 RICHED32_DllGetVersion (DLLVERSIONINFO *pdvi)
784 {
785     TRACE("\n");
786
787     if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
788
789         return E_INVALIDARG;
790     }
791
792     pdvi->dwMajorVersion = 4;
793     pdvi->dwMinorVersion = 0;
794     pdvi->dwBuildNumber = 0;
795     pdvi->dwPlatformID = 0;
796
797     return S_OK;
798 }
799
800 /***
801  * DESCRIPTION:
802  * Registers the window class.
803  *
804  * PARAMETER(S):
805  * None
806  *
807  * RETURN:
808  * None
809  */
810 VOID RICHED32_Register(void)
811 {
812     WNDCLASSA wndClass;
813
814     TRACE("\n");
815
816     ZeroMemory(&wndClass, sizeof(WNDCLASSA));
817     wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
818     wndClass.lpfnWndProc = (WNDPROC)RICHED32_WindowProc;
819     wndClass.cbClsExtra = 0;
820     wndClass.cbWndExtra = 0; /*(sizeof(RICHED32_INFO *);*/
821     wndClass.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
822     wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
823     wndClass.lpszClassName = RICHEDIT_CLASS10A; /* WC_RICHED32A; */
824
825     RegisterClassA (&wndClass);
826 }
827
828 /***
829  * DESCRIPTION:
830  * Unregisters the window class.
831  *
832  * PARAMETER(S):
833  * None
834  *
835  * RETURN:
836  * None
837  */
838 VOID RICHED32_Unregister(void)
839 {
840     TRACE("\n");
841
842     UnregisterClassA(RICHEDIT_CLASS10A, NULL);
843 }
844
845 INT RICHEDIT_GetTextRange(HWND hwnd,TEXTRANGEA *tr)
846 {
847     UINT alloc_size, text_size, range_size;
848     char *text;
849
850     TRACE("start: 0x%x stop: 0x%x\n",(INT)tr->chrg.cpMin,(INT)tr->chrg.cpMax);
851
852     if (!(alloc_size = SendMessageA(hwnd,WM_GETTEXTLENGTH,0,0))) return FALSE;
853     if (!(text = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (alloc_size+1))))
854                 return FALSE;
855     text_size = SendMessageA(hwnd,WM_GETTEXT,alloc_size,(INT)text);
856
857     if (text_size > tr->chrg.cpMin)
858     {
859        range_size = (text_size> tr->chrg.cpMax) ? (tr->chrg.cpMax - tr->chrg.cpMin) : (text_size - tr->chrg.cpMin);
860        TRACE("EditText: %.30s ...\n",text+tr->chrg.cpMin);
861        memcpy(tr->lpstrText,text+tr->chrg.cpMin,range_size);
862     }
863     else range_size = 0;
864     HeapFree(GetProcessHeap(), 0, text);
865
866     return range_size;
867 }
868
869 INT RICHEDIT_GetSelText(HWND hwnd,LPSTR lpstrBuffer)
870 {
871     TEXTRANGEA textrange;
872
873     textrange.lpstrText = lpstrBuffer;
874     SendMessageA(hwnd,EM_GETSEL,(INT)&textrange.chrg.cpMin,(INT)&textrange.chrg.cpMax);
875     return RICHEDIT_GetTextRange(hwnd,&textrange);
876 }