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