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