Implement ResetDC and PHYSICALOFFSET[X|Y] devcaps.
[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 <string.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "winreg.h"
30 #include "winerror.h"
31 #include "riched32.h"
32 #include "richedit.h"
33 #include "charlist.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 = (HANDLE)NULL;
46 /* LPSTR  RICHED32_aSubclass = (LPSTR)NULL; */
47
48 #define DPRINTF_EDIT_MSG32(str) \
49         TRACE(\
50                      "32 bit : " str ": hwnd=%08x, wParam=%08x, lParam=%08x\n"\
51                      , \
52                      hwnd, (UINT)wParam, (UINT)lParam)
53
54
55 /***********************************************************************
56  * RICHED32_LibMain [Internal] Initializes the internal 'RICHED32.DLL'.
57  *
58  * PARAMS
59  *     hinstDLL    [I] handle to the DLL's instance
60  *     fdwReason   [I]
61  *     lpvReserved [I] reserved, must be NULL
62  *
63  * RETURNS
64  *     Success: TRUE
65  *     Failure: FALSE
66  */
67
68 BOOL WINAPI
69 RICHED32_LibMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
70 {
71     TRACE("\n");
72     switch (fdwReason)
73     {
74     case DLL_PROCESS_ATTACH:
75         /* create private heap */
76         RICHED32_hHeap = HeapCreate (0, 0x10000, 0);
77         /* register the Rich Edit class */
78         RICHED32_Register ();
79         break;
80
81     case DLL_PROCESS_DETACH:
82         /* unregister all common control classes */
83         RICHED32_Unregister ();
84         HeapDestroy (RICHED32_hHeap);
85         RICHED32_hHeap = (HANDLE)NULL;
86         break;
87     }
88     return TRUE;
89 }
90
91 /*
92  *
93  * DESCRIPTION:
94  * Window procedure of the RichEdit control.
95  *
96  */
97 static LRESULT WINAPI RICHED32_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
98                                    LPARAM lParam)
99 {
100     int RTFToBuffer(char* pBuffer, int nBufferSize);
101     LONG newstyle = 0;
102     LONG style = 0;  
103
104     static HWND hwndEdit;
105     static HWND hwndParent;
106     static char* rtfBuffer;
107     int rtfBufferSize;
108
109     TRACE("\n"); 
110    
111     switch (uMsg)
112     {
113  
114     case WM_CREATE :           
115             DPRINTF_EDIT_MSG32("WM_CREATE");
116                      
117             /* remove SCROLLBARS from the current window style */
118             hwndParent = ((LPCREATESTRUCTA) lParam)->hwndParent;
119
120             newstyle = style = ((LPCREATESTRUCTA) lParam)->style;
121             newstyle &= ~WS_HSCROLL;
122             newstyle &= ~WS_VSCROLL;
123             newstyle &= ~ES_AUTOHSCROLL;
124             newstyle &= ~ES_AUTOVSCROLL;
125                                   
126             hwndEdit = CreateWindowA ("edit", ((LPCREATESTRUCTA) lParam)->lpszName,
127                                    style, 0, 0, 0, 0,
128                                    hwnd, (HMENU) ID_EDIT,
129                                    ((LPCREATESTRUCTA) lParam)->hInstance, NULL) ;
130         
131             SetWindowLongA(hwnd,GWL_STYLE, newstyle);              
132             return 0 ;
133           
134     case WM_SETFOCUS :
135             DPRINTF_EDIT_MSG32("WM_SETFOCUS");            
136             SetFocus (hwndEdit) ;
137             return 0 ;
138
139     case WM_SIZE :             
140             DPRINTF_EDIT_MSG32("WM_SIZE");
141             MoveWindow (hwndEdit, 0, 0, LOWORD (lParam), HIWORD (lParam), TRUE) ;
142             return 0 ;
143           
144     case WM_COMMAND :
145         DPRINTF_EDIT_MSG32("WM_COMMAND");
146         switch(HIWORD(wParam)) {
147                 case EN_CHANGE:
148                 case EN_HSCROLL:
149                 case EN_KILLFOCUS:
150                 case EN_SETFOCUS:
151                 case EN_UPDATE:
152                 case EN_VSCROLL:
153                         return SendMessageA(hwndParent, WM_COMMAND, 
154                                 wParam, (LPARAM)(hwnd));
155                 
156                 case EN_ERRSPACE:
157                 case EN_MAXTEXT:
158                         MessageBoxA (hwnd, "RichEdit control out of space.",
159                                   "ERROR", MB_OK | MB_ICONSTOP) ;
160                         return 0 ;
161                 }
162      
163     case EM_STREAMIN:                           
164             DPRINTF_EDIT_MSG32("EM_STREAMIN");
165             
166             /* setup the RTF parser */
167             RTFSetEditStream(( EDITSTREAM*)lParam);
168             WriterInit();
169             RTFInit ();
170             BeginFile();            
171
172             /* do the parsing */
173             RTFRead ();
174             
175             rtfBufferSize = RTFToBuffer(NULL, 0);
176             rtfBuffer = HeapAlloc(RICHED32_hHeap, 0,rtfBufferSize*sizeof(char));
177             if(rtfBuffer)
178             {
179                 RTFToBuffer(rtfBuffer, rtfBufferSize);
180                 SetWindowTextA(hwndEdit,rtfBuffer);
181                 HeapFree(RICHED32_hHeap, 0,rtfBuffer);
182             }
183             else
184                 WARN("Not enough memory for a allocating rtfBuffer\n");
185                 
186             return 0;   
187
188 /* Message specific to Richedit controls */
189
190     case EM_AUTOURLDETECT:
191             DPRINTF_EDIT_MSG32("EM_AUTOURLDETECT");
192             return 0;
193
194     case EM_CANPASTE:
195             DPRINTF_EDIT_MSG32("EM_CANPASTE");
196             return 0;
197
198     case EM_CANREDO:
199             DPRINTF_EDIT_MSG32("EM_CANREDO");
200             return 0;
201
202     case EM_DISPLAYBAND:
203             DPRINTF_EDIT_MSG32("EM_DISPLAYBAND");
204             return 0;
205
206     case EM_EXGETSEL:
207             DPRINTF_EDIT_MSG32("EM_EXGETSEL");
208             return 0;
209
210     case EM_EXLIMITTEXT:
211             DPRINTF_EDIT_MSG32("EM_EXLIMITTEXT");
212             return 0;
213
214     case EM_EXLINEFROMCHAR:
215             DPRINTF_EDIT_MSG32("EM_EXLINEFROMCHAR");
216             return 0;
217
218     case EM_EXSETSEL:
219             DPRINTF_EDIT_MSG32("EM_EXSETSEL");
220             return 0;
221
222     case EM_FINDTEXT:
223             DPRINTF_EDIT_MSG32("EM_FINDTEXT");
224             return 0;
225
226     case EM_FINDTEXTEX:
227             DPRINTF_EDIT_MSG32("EM_FINDTEXTEX");
228             return 0;
229
230     case EM_FINDTEXTEXW:
231             DPRINTF_EDIT_MSG32("EM_FINDTEXTEXW");
232             return 0;
233
234     case EM_FINDTEXTW:
235             DPRINTF_EDIT_MSG32("EM_FINDTEXTW");
236             return 0;
237
238     case EM_FINDWORDBREAK:
239             DPRINTF_EDIT_MSG32("EM_FINDWORDBREAK");
240             return 0;
241
242     case EM_FORMATRANGE:
243             DPRINTF_EDIT_MSG32("EM_FORMATRANGE");
244             return 0;
245
246     case EM_GETAUTOURLDETECT:
247             DPRINTF_EDIT_MSG32("EM_GETAUTOURLDETECT");
248             return 0;
249
250     case EM_GETBIDIOPTIONS:
251             DPRINTF_EDIT_MSG32("EM_GETBIDIOPTIONS");
252             return 0;
253
254     case EM_GETCHARFORMAT:
255             DPRINTF_EDIT_MSG32("EM_GETCHARFORMAT");
256             return 0;
257
258     case EM_GETEDITSTYLE:
259             DPRINTF_EDIT_MSG32("EM_GETEDITSTYLE");
260             return 0;
261
262     case EM_GETEVENTMASK:
263             DPRINTF_EDIT_MSG32("EM_GETEVENTMASK");
264             return 0;
265
266     case EM_GETIMECOLOR:
267             DPRINTF_EDIT_MSG32("EM_GETIMECOLOR");
268             return 0;
269
270     case EM_GETIMECOMPMODE:
271             DPRINTF_EDIT_MSG32("EM_GETIMECOMPMODE");
272             return 0;
273
274     case EM_GETIMEOPTIONS:
275             DPRINTF_EDIT_MSG32("EM_GETIMEOPTIONS");
276             return 0;
277
278     case EM_GETLANGOPTIONS:
279             DPRINTF_EDIT_MSG32("EM_GETLANGOPTIONS");
280             return 0;
281
282     case EM_GETOLEINTERFACE:
283             DPRINTF_EDIT_MSG32("EM_GETOLEINTERFACE");
284             return 0;
285
286     case EM_GETOPTIONS:
287             DPRINTF_EDIT_MSG32("EM_GETOPTIONS");
288             return 0;
289
290     case EM_GETPARAFORMAT:
291             DPRINTF_EDIT_MSG32("EM_GETPARAFORMAT");
292             return 0;
293
294     case EM_GETPUNCTUATION:
295             DPRINTF_EDIT_MSG32("EM_GETPUNCTUATION");
296             return 0;
297
298     case EM_GETREDONAME:
299             DPRINTF_EDIT_MSG32("EM_GETREDONAME");
300             return 0;
301
302     case EM_GETSCROLLPOS:
303             DPRINTF_EDIT_MSG32("EM_GETSCROLLPOS");
304             return 0;
305
306     case EM_GETSELTEXT:
307             DPRINTF_EDIT_MSG32("EM_GETSELTEXT");
308             return 0;
309
310     case EM_GETTEXTEX:
311             DPRINTF_EDIT_MSG32("EM_GETTEXTEX");
312             return 0;
313
314     case EM_GETTEXTLENGTHEX:
315             DPRINTF_EDIT_MSG32("EM_GETTEXTLENGTHEX");
316             return 0;
317
318     case EM_GETTEXTMODE:
319             DPRINTF_EDIT_MSG32("EM_GETTEXTMODE");
320             return 0;
321
322     case EM_GETTEXTRANGE:
323             DPRINTF_EDIT_MSG32("EM_GETTEXTRANGE");
324             return 0;
325
326     case EM_GETTYPOGRAPHYOPTIONS:
327             DPRINTF_EDIT_MSG32("EM_GETTYPOGRAPHYOPTIONS");
328             return 0;
329
330     case EM_GETUNDONAME:
331             DPRINTF_EDIT_MSG32("EM_GETUNDONAME");
332             return 0;
333
334     case EM_GETWORDBREAKPROCEX:
335             DPRINTF_EDIT_MSG32("EM_GETWORDBREAKPROCEX");
336             return 0;
337
338     case EM_GETWORDWRAPMODE:
339             DPRINTF_EDIT_MSG32("EM_GETWORDWRAPMODE");
340             return 0;
341
342     case EM_GETZOOM:
343             DPRINTF_EDIT_MSG32("EM_GETZOOM");
344             return 0;
345
346     case EM_HIDESELECTION:
347             DPRINTF_EDIT_MSG32("EM_HIDESELECTION");
348             return 0;
349
350     case EM_PASTESPECIAL:
351             DPRINTF_EDIT_MSG32("EM_PASTESPECIAL");
352             return 0;
353
354     case EM_RECONVERSION:
355             DPRINTF_EDIT_MSG32("EM_RECONVERSION");
356             return 0;
357
358     case EM_REDO:
359             DPRINTF_EDIT_MSG32("EM_REDO");
360             return 0;
361
362     case EM_REQUESTRESIZE:
363             DPRINTF_EDIT_MSG32("EM_REQUESTRESIZE");
364             return 0;
365
366     case EM_SELECTIONTYPE:
367             DPRINTF_EDIT_MSG32("EM_SELECTIONTYPE");
368             return 0;
369
370     case EM_SETBIDIOPTIONS:
371             DPRINTF_EDIT_MSG32("EM_SETBIDIOPTIONS");
372             return 0;
373
374     case EM_SETBKGNDCOLOR:
375             DPRINTF_EDIT_MSG32("EM_SETBKGNDCOLOR");
376             return 0;
377
378     case EM_SETCHARFORMAT:
379             DPRINTF_EDIT_MSG32("EM_SETCHARFORMAT");
380             return 0;
381
382     case EM_SETEDITSTYLE:
383             DPRINTF_EDIT_MSG32("EM_SETEDITSTYLE");
384             return 0;
385
386     case EM_SETEVENTMASK:
387             DPRINTF_EDIT_MSG32("EM_SETEVENTMASK");
388             return 0;
389
390     case EM_SETFONTSIZE:
391             DPRINTF_EDIT_MSG32("EM_SETFONTSIZE");
392             return 0;
393
394     case EM_SETIMECOLOR:
395             DPRINTF_EDIT_MSG32("EM_SETIMECOLO");
396             return 0;
397
398     case EM_SETIMEOPTIONS:
399             DPRINTF_EDIT_MSG32("EM_SETIMEOPTIONS");
400             return 0;
401
402     case EM_SETLANGOPTIONS:
403             DPRINTF_EDIT_MSG32("EM_SETLANGOPTIONS");
404             return 0;
405
406     case EM_SETOLECALLBACK:
407             DPRINTF_EDIT_MSG32("EM_SETOLECALLBACK");
408             return 0;
409
410     case EM_SETOPTIONS:
411             DPRINTF_EDIT_MSG32("EM_SETOPTIONS");
412             return 0;
413
414     case EM_SETPALETTE:
415             DPRINTF_EDIT_MSG32("EM_SETPALETTE");
416             return 0;
417
418     case EM_SETPARAFORMAT:
419             DPRINTF_EDIT_MSG32("EM_SETPARAFORMAT");
420             return 0;
421
422     case EM_SETPUNCTUATION:
423             DPRINTF_EDIT_MSG32("EM_SETPUNCTUATION");
424             return 0;
425
426     case EM_SETSCROLLPOS:
427             DPRINTF_EDIT_MSG32("EM_SETSCROLLPOS");
428             return 0;
429
430     case EM_SETTARGETDEVICE:
431             DPRINTF_EDIT_MSG32("EM_SETTARGETDEVICE");
432             return 0;
433
434     case EM_SETTEXTEX:
435             DPRINTF_EDIT_MSG32("EM_SETTEXTEX");
436             return 0;
437
438     case EM_SETTEXTMODE:
439             DPRINTF_EDIT_MSG32("EM_SETTEXTMODE");
440             return 0;
441
442     case EM_SETTYPOGRAPHYOPTIONS:
443             DPRINTF_EDIT_MSG32("EM_SETTYPOGRAPHYOPTIONS");
444             return 0;
445
446     case EM_SETUNDOLIMIT:
447             DPRINTF_EDIT_MSG32("EM_SETUNDOLIMIT");
448             return 0;
449
450     case EM_SETWORDBREAKPROCEX:
451             DPRINTF_EDIT_MSG32("EM_SETWORDBREAKPROCEX");
452             return 0;
453
454     case EM_SETWORDWRAPMODE:
455             DPRINTF_EDIT_MSG32("EM_SETWORDWRAPMODE");
456             return 0;
457
458     case EM_SETZOOM:
459             DPRINTF_EDIT_MSG32("EM_SETZOOM");
460             return 0;
461
462     case EM_SHOWSCROLLBAR:
463             DPRINTF_EDIT_MSG32("EM_SHOWSCROLLBAR");
464             return 0;
465
466     case EM_STOPGROUPTYPING:
467             DPRINTF_EDIT_MSG32("EM_STOPGROUPTYPING");
468             return 0;
469
470     case EM_STREAMOUT:
471             DPRINTF_EDIT_MSG32("EM_STREAMOUT");
472             return 0;
473
474 /* Messaged dispatched to the edit control */
475     case EM_CANUNDO:
476     case EM_CHARFROMPOS:
477     case EM_EMPTYUNDOBUFFER:
478     case EM_FMTLINES:
479     case EM_GETFIRSTVISIBLELINE:
480     case EM_GETHANDLE:
481 /*    case EM_GETIMESTATUS:*/
482     case EM_GETLIMITTEXT:
483     case EM_GETLINE:
484     case EM_GETLINECOUNT:
485     case EM_GETMARGINS:
486     case EM_GETMODIFY:
487     case EM_GETPASSWORDCHAR:
488     case EM_GETRECT:
489     case EM_GETSEL:
490     case EM_GETTHUMB:
491     case EM_GETWORDBREAKPROC:
492     case EM_LINEFROMCHAR:
493     case EM_LINEINDEX:
494     case EM_LINELENGTH:
495     case EM_LINESCROLL:
496     case EM_POSFROMCHAR:
497     case EM_REPLACESEL:
498     case EM_SCROLL:
499     case EM_SCROLLCARET:
500     case EM_SETHANDLE:
501 /*    case EM_SETIMESTATUS:*/
502     case EM_SETLIMITTEXT:
503     case EM_SETMARGINS:
504     case EM_SETMODIFY:
505     case EM_SETPASSWORDCHAR:
506     case EM_SETREADONLY:
507     case EM_SETRECT:
508     case EM_SETRECTNP:
509     case EM_SETSEL:
510     case EM_SETTABSTOPS:
511     case EM_SETWORDBREAKPROC:
512     case EM_UNDO:
513
514     case WM_STYLECHANGING:
515     case WM_STYLECHANGED:
516     case WM_NCCALCSIZE:
517     case WM_GETTEXT:
518     case WM_GETTEXTLENGTH:
519     case WM_SETTEXT:
520             return SendMessageA( hwndEdit, uMsg, wParam, lParam);
521
522     /* Messages known , but ignored. */ 
523     case WM_NCPAINT:
524         DPRINTF_EDIT_MSG32("WM_NCPAINT");
525         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
526     case WM_PAINT:
527         DPRINTF_EDIT_MSG32("WM_PAINT");
528         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
529     case WM_ERASEBKGND:
530         DPRINTF_EDIT_MSG32("WM_ERASEBKGND");
531         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
532     case WM_KILLFOCUS:
533         DPRINTF_EDIT_MSG32("WM_KILLFOCUS");
534         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
535     case WM_DESTROY:
536         DPRINTF_EDIT_MSG32("WM_DESTROY");
537         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
538     case WM_CHILDACTIVATE:             
539         DPRINTF_EDIT_MSG32("WM_CHILDACTIVATE");
540         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
541
542     case WM_WINDOWPOSCHANGING:
543         DPRINTF_EDIT_MSG32("WM_WINDOWPOSCHANGING");
544         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
545     case WM_WINDOWPOSCHANGED:
546         DPRINTF_EDIT_MSG32("WM_WINDOWPOSCHANGED");
547         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
548 /*    case WM_INITIALUPDATE:
549         DPRINTF_EDIT_MSG32("WM_INITIALUPDATE");
550         return DefWindowProcA( hwnd,uMsg,wParam,lParam); */
551     case WM_CTLCOLOREDIT:
552         DPRINTF_EDIT_MSG32("WM_CTLCOLOREDIT");
553         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
554     case WM_SETCURSOR:
555         DPRINTF_EDIT_MSG32("WM_SETCURSOR");
556         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
557     case WM_MOVE:
558         DPRINTF_EDIT_MSG32("WM_MOVE");
559         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
560     case WM_SHOWWINDOW:
561         DPRINTF_EDIT_MSG32("WM_SHOWWINDOW");
562         return DefWindowProcA( hwnd,uMsg,wParam,lParam);
563
564     }
565
566
567     FIXME("Unknown message 0x%04x\n", uMsg);
568     return DefWindowProcA( hwnd,uMsg,wParam,lParam);
569 }
570
571 /***********************************************************************
572  * DllGetVersion [RICHED32.2]
573  *
574  * Retrieves version information of the 'RICHED32.DLL'
575  *
576  * PARAMS
577  *     pdvi [O] pointer to version information structure.
578  *
579  * RETURNS
580  *     Success: S_OK
581  *     Failure: E_INVALIDARG
582  *
583  * NOTES
584  *     Returns version of a comctl32.dll from IE4.01 SP1.
585  */
586
587 HRESULT WINAPI
588 RICHED32_DllGetVersion (DLLVERSIONINFO *pdvi)
589 {
590     TRACE("\n");
591
592     if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
593  
594         return E_INVALIDARG;
595     }
596
597     pdvi->dwMajorVersion = 4;
598     pdvi->dwMinorVersion = 0;
599     pdvi->dwBuildNumber = 0;
600     pdvi->dwPlatformID = 0;
601
602     return S_OK;
603 }
604
605 /***
606  * DESCRIPTION:
607  * Registers the window class.
608  * 
609  * PARAMETER(S):
610  * None
611  *
612  * RETURN:
613  * None
614  */
615 VOID RICHED32_Register(void)
616 {
617     WNDCLASSA wndClass; 
618
619     TRACE("\n");
620
621     ZeroMemory(&wndClass, sizeof(WNDCLASSA));
622     wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
623     wndClass.lpfnWndProc = (WNDPROC)RICHED32_WindowProc;
624     wndClass.cbClsExtra = 0;
625     wndClass.cbWndExtra = 0; /*(sizeof(RICHED32_INFO *);*/
626     wndClass.hCursor = LoadCursorA(0, IDC_ARROWA);
627     wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
628     wndClass.lpszClassName = RICHEDIT_CLASS10A;//WC_RICHED32A;
629
630     RegisterClassA (&wndClass);
631 }
632
633 /***
634  * DESCRIPTION:
635  * Unregisters the window class.
636  * 
637  * PARAMETER(S):
638  * None
639  *
640  * RETURN:
641  * None
642  */
643 VOID RICHED32_Unregister(void)
644 {
645     TRACE("\n");
646
647     UnregisterClassA(RICHEDIT_CLASS10A, (HINSTANCE)NULL);
648 }