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