Use DrawFrameControl instead of bitmaps in certain cases.
[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  */
11  
12 #include <string.h>
13 #include "windef.h"
14 #include "winbase.h"
15 #include "wingdi.h"
16 #include "winreg.h"
17 #include "winerror.h"
18 #include "riched32.h"
19 #include "richedit.h"
20 #include "charlist.h"
21 #define NO_SHLWAPI_STREAM
22 #include "shlwapi.h"
23
24 #include "rtf.h"
25 #include "rtf2text.h"
26 #include "debugtools.h"
27
28 #define ID_EDIT      1
29
30 DEFAULT_DEBUG_CHANNEL(richedit);
31
32 HANDLE RICHED32_hHeap = (HANDLE)NULL;
33 /* LPSTR  RICHED32_aSubclass = (LPSTR)NULL; */
34
35 /***********************************************************************
36  * RICHED32_LibMain [Internal] Initializes the internal 'RICHED32.DLL'.
37  *
38  * PARAMS
39  *     hinstDLL    [I] handle to the DLL's instance
40  *     fdwReason   [I]
41  *     lpvReserved [I] reserved, must be NULL
42  *
43  * RETURNS
44  *     Success: TRUE
45  *     Failure: FALSE
46  */
47
48 BOOL WINAPI
49 RICHED32_LibMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
50 {
51     switch (fdwReason)
52     {
53     case DLL_PROCESS_ATTACH:
54         /* create private heap */
55         RICHED32_hHeap = HeapCreate (0, 0x10000, 0);
56         /* register the Rich Edit class */
57         RICHED32_Register ();
58         break;
59
60     case DLL_PROCESS_DETACH:
61         /* unregister all common control classes */
62         RICHED32_Unregister ();
63         HeapDestroy (RICHED32_hHeap);
64         RICHED32_hHeap = (HANDLE)NULL;
65         break;
66     }
67     return TRUE;
68 }
69
70 /*
71  *
72  * DESCRIPTION:
73  * Window procedure of the RichEdit control.
74  *
75  */
76 static LRESULT WINAPI RICHED32_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
77                                    LPARAM lParam)
78 {
79     int RTFToBuffer(char* pBuffer, int nBufferSize);
80     LONG newstyle = 0;
81     LONG style = 0;  
82
83     static HWND hwndEdit;
84     static char* rtfBuffer;
85     int rtfBufferSize;
86     
87     switch (uMsg)
88     {
89  
90     case WM_CREATE :           
91             
92             /* remove SCROLLBARS from the current window style */
93             newstyle = style = ((LPCREATESTRUCTA) lParam)->style;
94             newstyle &= ~WS_HSCROLL;
95             newstyle &= ~WS_VSCROLL;
96             newstyle &= ~ES_AUTOHSCROLL;
97             newstyle &= ~ES_AUTOVSCROLL;
98                                   
99             hwndEdit = CreateWindowA ("edit", ((LPCREATESTRUCTA) lParam)->lpszName,
100                                    style, 0, 0, 0, 0,
101                                    hwnd, (HMENU) ID_EDIT,
102                                    ((LPCREATESTRUCTA) lParam)->hInstance, NULL) ;
103         
104             SetWindowLongA(hwnd,GWL_STYLE, newstyle);              
105             return 0 ;
106           
107     case WM_SETFOCUS :            
108             SetFocus (hwndEdit) ;
109             return 0 ;
110           
111     case WM_SIZE :             
112             MoveWindow (hwndEdit, 0, 0, LOWORD (lParam), HIWORD (lParam), TRUE) ;
113             return 0 ;
114           
115     case WM_COMMAND :
116             if (LOWORD (wParam) == ID_EDIT)
117                  if (HIWORD (wParam) == EN_ERRSPACE || 
118                            HIWORD (wParam) == EN_MAXTEXT)
119
120                       MessageBoxA (hwnd, "RichEdit control out of space.",
121                                   "ERROR", MB_OK | MB_ICONSTOP) ;
122             return 0 ;
123      
124     case EM_STREAMIN:                               
125             
126             /* setup the RTF parser */
127             RTFSetEditStream(( EDITSTREAM*)lParam);
128             WriterInit();
129             RTFInit ();
130             BeginFile();            
131
132             /* do the parsing */
133             RTFRead ();
134             
135             rtfBufferSize = RTFToBuffer(NULL, 0);
136             rtfBuffer = HeapAlloc(RICHED32_hHeap, 0,rtfBufferSize*sizeof(char));
137             if(rtfBuffer)
138             {
139                 RTFToBuffer(rtfBuffer, rtfBufferSize);
140                 SetWindowTextA(hwndEdit,rtfBuffer);
141                 HeapFree(RICHED32_hHeap, 0,rtfBuffer);
142             }
143             else
144                 WARN("Not enough memory for a allocating rtfBuffer\n");
145                 
146             return 0;   
147     }
148     /*return SendMessageA( hwndEdit,uMsg,wParam,lParam);*/
149     return DefWindowProcA( hwnd,uMsg,wParam,lParam);
150 }
151
152 /***********************************************************************
153  * DllGetVersion [RICHED32.2]
154  *
155  * Retrieves version information of the 'RICHED32.DLL'
156  *
157  * PARAMS
158  *     pdvi [O] pointer to version information structure.
159  *
160  * RETURNS
161  *     Success: S_OK
162  *     Failure: E_INVALIDARG
163  *
164  * NOTES
165  *     Returns version of a comctl32.dll from IE4.01 SP1.
166  */
167
168 HRESULT WINAPI
169 RICHED32_DllGetVersion (DLLVERSIONINFO *pdvi)
170 {
171     if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
172  
173         return E_INVALIDARG;
174     }
175
176     pdvi->dwMajorVersion = 4;
177     pdvi->dwMinorVersion = 0;
178     pdvi->dwBuildNumber = 0;
179     pdvi->dwPlatformID = 0;
180
181     return S_OK;
182 }
183
184 /***
185  * DESCRIPTION:
186  * Registers the window class.
187  * 
188  * PARAMETER(S):
189  * None
190  *
191  * RETURN:
192  * None
193  */
194 VOID RICHED32_Register(void)
195 {
196     WNDCLASSA wndClass; 
197
198     ZeroMemory(&wndClass, sizeof(WNDCLASSA));
199     wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
200     wndClass.lpfnWndProc = (WNDPROC)RICHED32_WindowProc;
201     wndClass.cbClsExtra = 0;
202     wndClass.cbWndExtra = 0; /*(sizeof(RICHED32_INFO *);*/
203     wndClass.hCursor = LoadCursorA(0, IDC_ARROWA);
204     wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
205     wndClass.lpszClassName = RICHEDIT_CLASS10A;//WC_RICHED32A;
206
207     RegisterClassA (&wndClass);
208 }
209
210 /***
211  * DESCRIPTION:
212  * Unregisters the window class.
213  * 
214  * PARAMETER(S):
215  * None
216  *
217  * RETURN:
218  * None
219  */
220 VOID RICHED32_Unregister(void)
221 {
222     UnregisterClassA(RICHEDIT_CLASS10A, (HINSTANCE)NULL);
223 }