richedit: GTL_PRECISE to GETTEXTLENGTHEX implies GTL_NUMBYTES.
[wine] / dlls / riched20 / richole.c
1 /*
2  * RichEdit GUIDs and OLE interface
3  *
4  * Copyright 2004 by Krzysztof Foltman
5  * Copyright 2004 Aric Stewart
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include <stdarg.h>
23
24 #define NONAMELESSUNION
25 #define NONAMELESSSTRUCT
26 #define COBJMACROS
27
28 #include "windef.h"
29 #include "winbase.h"
30 #include "wingdi.h"
31 #include "winuser.h"
32 #include "ole2.h"
33 #include "richole.h"
34 #include "editor.h"
35 #include "tom.h"
36 #include "wine/debug.h"
37
38 WINE_DEFAULT_DEBUG_CHANNEL(richedit);
39
40 /* there is no way to be consistent across different sets of headers - mingw, Wine, Win32 SDK*/
41
42 /* FIXME: the next 6 lines should be in textserv.h */
43 #include "initguid.h"
44 #define TEXTSERV_GUID(name, l, w1, w2, b1, b2) \
45     DEFINE_GUID(name, l, w1, w2, b1, b2, 0x00, 0xaa, 0x00, 0x6c, 0xad, 0xc5)
46
47 TEXTSERV_GUID(IID_ITextServices, 0x8d33f740, 0xcf58, 0x11ce, 0xa8, 0x9d);
48 TEXTSERV_GUID(IID_ITextHost, 0xc5bdd8d0, 0xd26e, 0x11ce, 0xa8, 0x9e);
49 TEXTSERV_GUID(IID_ITextHost2, 0xc5bdd8d0, 0xd26e, 0x11ce, 0xa8, 0x9e);
50 DEFINE_GUID(IID_ITextDocument, 0x8cc497c0, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
51 DEFINE_GUID(IID_ITextRange, 0x8cc497c2, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
52 DEFINE_GUID(IID_ITextSelection, 0x8cc497c1, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
53
54 typedef struct ITextSelectionImpl ITextSelectionImpl;
55 typedef struct IOleClientSiteImpl IOleClientSiteImpl;
56
57 typedef struct IRichEditOleImpl {
58     const IRichEditOleVtbl *lpRichEditOleVtbl;
59     const ITextDocumentVtbl *lpTextDocumentVtbl;
60     LONG ref;
61
62     ME_TextEditor *editor;
63     ITextSelectionImpl *txtSel;
64     IOleClientSiteImpl *clientSite;
65 } IRichEditOleImpl;
66
67 struct ITextSelectionImpl {
68     const ITextSelectionVtbl *lpVtbl;
69     LONG ref;
70
71     IRichEditOleImpl *reOle;
72 };
73
74 struct IOleClientSiteImpl {
75     const IOleClientSiteVtbl *lpVtbl;
76     LONG ref;
77
78     IRichEditOleImpl *reOle;
79 };
80
81 static inline IRichEditOleImpl *impl_from_IRichEditOle(IRichEditOle *iface)
82 {
83     return (IRichEditOleImpl *)((BYTE*)iface - FIELD_OFFSET(IRichEditOleImpl, lpRichEditOleVtbl));
84 }
85
86 static inline IRichEditOleImpl *impl_from_ITextDocument(ITextDocument *iface)
87 {
88     return (IRichEditOleImpl *)((BYTE*)iface - FIELD_OFFSET(IRichEditOleImpl, lpTextDocumentVtbl));
89 }
90
91 static HRESULT WINAPI
92 IRichEditOle_fnQueryInterface(IRichEditOle *me, REFIID riid, LPVOID *ppvObj)
93 {
94     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
95
96     TRACE("%p %s\n", This, debugstr_guid(riid) );
97
98     *ppvObj = NULL;
99     if (IsEqualGUID(riid, &IID_IUnknown) ||
100         IsEqualGUID(riid, &IID_IRichEditOle))
101         *ppvObj = &This->lpRichEditOleVtbl;
102     else if (IsEqualGUID(riid, &IID_ITextDocument))
103         *ppvObj = &This->lpTextDocumentVtbl;
104     if (*ppvObj)
105     {
106         IRichEditOle_AddRef(me);
107         return S_OK;
108     }
109     FIXME("%p: unhandled interface %s\n", This, debugstr_guid(riid) );
110  
111     return E_NOINTERFACE;   
112 }
113
114 static ULONG WINAPI
115 IRichEditOle_fnAddRef(IRichEditOle *me)
116 {
117     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
118     ULONG ref = InterlockedIncrement( &This->ref );
119
120     TRACE("%p ref = %u\n", This, ref);
121
122     return ref;
123 }
124
125 static ULONG WINAPI
126 IRichEditOle_fnRelease(IRichEditOle *me)
127 {
128     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
129     ULONG ref = InterlockedDecrement(&This->ref);
130
131     TRACE ("%p ref=%u\n", This, ref);
132
133     if (!ref)
134     {
135         TRACE ("Destroying %p\n", This);
136         This->txtSel->reOle = NULL;
137         ITextSelection_Release((ITextSelection *) This->txtSel);
138         IOleClientSite_Release((IOleClientSite *) This->clientSite);
139         heap_free(This);
140     }
141     return ref;
142 }
143
144 static HRESULT WINAPI
145 IRichEditOle_fnActivateAs(IRichEditOle *me, REFCLSID rclsid, REFCLSID rclsidAs)
146 {
147     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
148     FIXME("stub %p\n",This);
149     return E_NOTIMPL;
150 }
151
152 static HRESULT WINAPI
153 IRichEditOle_fnContextSensitiveHelp(IRichEditOle *me, BOOL fEnterMode)
154 {
155     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
156     FIXME("stub %p\n",This);
157     return E_NOTIMPL;
158 }
159
160 static HRESULT WINAPI
161 IRichEditOle_fnConvertObject(IRichEditOle *me, LONG iob,
162                REFCLSID rclsidNew, LPCSTR lpstrUserTypeNew)
163 {
164     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
165     FIXME("stub %p\n",This);
166     return E_NOTIMPL;
167 }
168
169 static HRESULT WINAPI
170 IOleClientSite_fnQueryInterface(IOleClientSite *me, REFIID riid, LPVOID *ppvObj)
171 {
172     TRACE("%p %s\n", me, debugstr_guid(riid) );
173
174     *ppvObj = NULL;
175     if (IsEqualGUID(riid, &IID_IUnknown) ||
176         IsEqualGUID(riid, &IID_IOleClientSite))
177         *ppvObj = me;
178     if (*ppvObj)
179     {
180         IOleClientSite_AddRef(me);
181         return S_OK;
182     }
183     FIXME("%p: unhandled interface %s\n", me, debugstr_guid(riid) );
184
185     return E_NOINTERFACE;
186 }
187
188 static ULONG WINAPI
189 IOleClientSite_fnAddRef(IOleClientSite *me)
190 {
191     IOleClientSiteImpl *This = (IOleClientSiteImpl *) me;
192     return InterlockedIncrement(&This->ref);
193 }
194
195 static ULONG WINAPI
196 IOleClientSite_fnRelease(IOleClientSite *me)
197 {
198     IOleClientSiteImpl *This = (IOleClientSiteImpl *) me;
199     ULONG ref = InterlockedDecrement(&This->ref);
200     if (ref == 0)
201         heap_free(This);
202     return ref;
203 }
204
205 static HRESULT WINAPI
206 IOleClientSite_fnSaveObject(IOleClientSite *me)
207 {
208     IOleClientSiteImpl *This = (IOleClientSiteImpl *) me;
209     if (!This->reOle)
210         return CO_E_RELEASED;
211
212     FIXME("stub %p\n",me);
213     return E_NOTIMPL;
214 }
215
216
217 static HRESULT WINAPI
218 IOleClientSite_fnGetMoniker(IOleClientSite *me, DWORD dwAssign, DWORD dwWhichMoniker,
219     IMoniker **ppmk)
220 {
221     IOleClientSiteImpl *This = (IOleClientSiteImpl *) me;
222     if (!This->reOle)
223         return CO_E_RELEASED;
224
225     FIXME("stub %p\n",me);
226     return E_NOTIMPL;
227 }
228
229 static HRESULT WINAPI
230 IOleClientSite_fnGetContainer(IOleClientSite *me, IOleContainer **ppContainer)
231 {
232     IOleClientSiteImpl *This = (IOleClientSiteImpl *) me;
233     if (!This->reOle)
234         return CO_E_RELEASED;
235
236     FIXME("stub %p\n",me);
237     return E_NOTIMPL;
238 }
239
240 static HRESULT WINAPI
241 IOleClientSite_fnShowObject(IOleClientSite *me)
242 {
243     IOleClientSiteImpl *This = (IOleClientSiteImpl *) me;
244     if (!This->reOle)
245         return CO_E_RELEASED;
246
247     FIXME("stub %p\n",me);
248     return E_NOTIMPL;
249 }
250
251 static HRESULT WINAPI
252 IOleClientSite_fnOnShowWindow(IOleClientSite *me, BOOL fShow)
253 {
254     IOleClientSiteImpl *This = (IOleClientSiteImpl *) me;
255     if (!This->reOle)
256         return CO_E_RELEASED;
257
258     FIXME("stub %p\n",me);
259     return E_NOTIMPL;
260 }
261
262 static HRESULT WINAPI
263 IOleClientSite_fnRequestNewObjectLayout(IOleClientSite *me)
264 {
265     IOleClientSiteImpl *This = (IOleClientSiteImpl *) me;
266     if (!This->reOle)
267         return CO_E_RELEASED;
268
269     FIXME("stub %p\n",me);
270     return E_NOTIMPL;
271 }
272
273 static const IOleClientSiteVtbl ocst = {
274     IOleClientSite_fnQueryInterface,
275     IOleClientSite_fnAddRef,
276     IOleClientSite_fnRelease,
277     IOleClientSite_fnSaveObject,
278     IOleClientSite_fnGetMoniker,
279     IOleClientSite_fnGetContainer,
280     IOleClientSite_fnShowObject,
281     IOleClientSite_fnOnShowWindow,
282     IOleClientSite_fnRequestNewObjectLayout
283 };
284
285 static IOleClientSiteImpl *
286 CreateOleClientSite(IRichEditOleImpl *reOle)
287 {
288     IOleClientSiteImpl *clientSite = heap_alloc(sizeof *clientSite);
289     if (!clientSite)
290         return NULL;
291
292     clientSite->lpVtbl = &ocst;
293     clientSite->ref = 1;
294     clientSite->reOle = reOle;
295     return clientSite;
296 }
297
298 static HRESULT WINAPI
299 IRichEditOle_fnGetClientSite(IRichEditOle *me,
300                LPOLECLIENTSITE *lplpolesite)
301 {
302     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
303
304     TRACE("%p,%p\n",This, lplpolesite);
305
306     if(!lplpolesite)
307         return E_INVALIDARG;
308     *lplpolesite = (IOleClientSite *) This->clientSite;
309     IOleClientSite_fnAddRef(*lplpolesite);
310     return S_OK;
311 }
312
313 static HRESULT WINAPI
314 IRichEditOle_fnGetClipboardData(IRichEditOle *me, CHARRANGE *lpchrg,
315                DWORD reco, LPDATAOBJECT *lplpdataobj)
316 {
317     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
318     ME_Cursor start;
319     int nChars;
320
321     TRACE("(%p,%p,%d)\n",This, lpchrg, reco);
322     if(!lplpdataobj)
323         return E_INVALIDARG;
324     if(!lpchrg) {
325         int nFrom, nTo, nStartCur = ME_GetSelectionOfs(This->editor, &nFrom, &nTo);
326         start = This->editor->pCursors[nStartCur];
327         nChars = nTo - nFrom;
328     } else {
329         ME_CursorFromCharOfs(This->editor, lpchrg->cpMin, &start);
330         nChars = lpchrg->cpMax - lpchrg->cpMin;
331     }
332     return ME_GetDataObject(This->editor, &start, nChars, lplpdataobj);
333 }
334
335 static LONG WINAPI IRichEditOle_fnGetLinkCount(IRichEditOle *me)
336 {
337     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
338     FIXME("stub %p\n",This);
339     return E_NOTIMPL;
340 }
341
342 static HRESULT WINAPI
343 IRichEditOle_fnGetObject(IRichEditOle *me, LONG iob,
344                REOBJECT *lpreobject, DWORD dwFlags)
345 {
346     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
347     FIXME("stub %p\n",This);
348     return E_NOTIMPL;
349 }
350
351 static LONG WINAPI
352 IRichEditOle_fnGetObjectCount(IRichEditOle *me)
353 {
354     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
355     FIXME("stub %p\n",This);
356     return 0;
357 }
358
359 static HRESULT WINAPI
360 IRichEditOle_fnHandsOffStorage(IRichEditOle *me, LONG iob)
361 {
362     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
363     FIXME("stub %p\n",This);
364     return E_NOTIMPL;
365 }
366
367 static HRESULT WINAPI
368 IRichEditOle_fnImportDataObject(IRichEditOle *me, LPDATAOBJECT lpdataobj,
369                CLIPFORMAT cf, HGLOBAL hMetaPict)
370 {
371     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
372     FIXME("stub %p\n",This);
373     return E_NOTIMPL;
374 }
375
376 static HRESULT WINAPI
377 IRichEditOle_fnInPlaceDeactivate(IRichEditOle *me)
378 {
379     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
380     FIXME("stub %p\n",This);
381     return E_NOTIMPL;
382 }
383
384 static HRESULT WINAPI
385 IRichEditOle_fnInsertObject(IRichEditOle *me, REOBJECT *reo)
386 {
387     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
388     TRACE("(%p,%p)\n", This, reo);
389
390     if (reo->cbStruct < sizeof(*reo)) return STG_E_INVALIDPARAMETER;
391
392     ME_InsertOLEFromCursor(This->editor, reo, 0);
393     ME_CommitUndo(This->editor);
394     ME_UpdateRepaint(This->editor);
395     return S_OK;
396 }
397
398 static HRESULT WINAPI IRichEditOle_fnSaveCompleted(IRichEditOle *me, LONG iob,
399                LPSTORAGE lpstg)
400 {
401     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
402     FIXME("stub %p\n",This);
403     return E_NOTIMPL;
404 }
405
406 static HRESULT WINAPI
407 IRichEditOle_fnSetDvaspect(IRichEditOle *me, LONG iob, DWORD dvaspect)
408 {
409     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
410     FIXME("stub %p\n",This);
411     return E_NOTIMPL;
412 }
413
414 static HRESULT WINAPI IRichEditOle_fnSetHostNames(IRichEditOle *me,
415                LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj)
416 {
417     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
418     FIXME("stub %p %s %s\n",This, lpstrContainerApp, lpstrContainerObj);
419     return E_NOTIMPL;
420 }
421
422 static HRESULT WINAPI
423 IRichEditOle_fnSetLinkAvailable(IRichEditOle *me, LONG iob, BOOL fAvailable)
424 {
425     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
426     FIXME("stub %p\n",This);
427     return E_NOTIMPL;
428 }
429
430 static const IRichEditOleVtbl revt = {
431     IRichEditOle_fnQueryInterface,
432     IRichEditOle_fnAddRef,
433     IRichEditOle_fnRelease,
434     IRichEditOle_fnGetClientSite,
435     IRichEditOle_fnGetObjectCount,
436     IRichEditOle_fnGetLinkCount,
437     IRichEditOle_fnGetObject,
438     IRichEditOle_fnInsertObject,
439     IRichEditOle_fnConvertObject,
440     IRichEditOle_fnActivateAs,
441     IRichEditOle_fnSetHostNames,
442     IRichEditOle_fnSetLinkAvailable,
443     IRichEditOle_fnSetDvaspect,
444     IRichEditOle_fnHandsOffStorage,
445     IRichEditOle_fnSaveCompleted,
446     IRichEditOle_fnInPlaceDeactivate,
447     IRichEditOle_fnContextSensitiveHelp,
448     IRichEditOle_fnGetClipboardData,
449     IRichEditOle_fnImportDataObject
450 };
451
452 static HRESULT WINAPI
453 ITextDocument_fnQueryInterface(ITextDocument* me, REFIID riid,
454     void** ppvObject)
455 {
456     IRichEditOleImpl *This = impl_from_ITextDocument(me);
457     return IRichEditOle_fnQueryInterface((IRichEditOle*)&This->lpRichEditOleVtbl,
458             riid, ppvObject);
459 }
460
461 static ULONG WINAPI
462 ITextDocument_fnAddRef(ITextDocument* me)
463 {
464     IRichEditOleImpl *This = impl_from_ITextDocument(me);
465     return IRichEditOle_fnAddRef((IRichEditOle*)&This->lpRichEditOleVtbl);
466 }
467
468 static ULONG WINAPI
469 ITextDocument_fnRelease(ITextDocument* me)
470 {
471     IRichEditOleImpl *This = impl_from_ITextDocument(me);
472     return IRichEditOle_fnRelease((IRichEditOle*)&This->lpRichEditOleVtbl);
473 }
474
475 static HRESULT WINAPI
476 ITextDocument_fnGetTypeInfoCount(ITextDocument* me,
477     UINT* pctinfo)
478 {
479     IRichEditOleImpl *This = impl_from_ITextDocument(me);
480     FIXME("stub %p\n",This);
481     return E_NOTIMPL;
482 }
483
484 static HRESULT WINAPI
485 ITextDocument_fnGetTypeInfo(ITextDocument* me, UINT iTInfo, LCID lcid,
486     ITypeInfo** ppTInfo)
487 {
488     IRichEditOleImpl *This = impl_from_ITextDocument(me);
489     FIXME("stub %p\n",This);
490     return E_NOTIMPL;
491 }
492
493 static HRESULT WINAPI
494 ITextDocument_fnGetIDsOfNames(ITextDocument* me, REFIID riid,
495     LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId)
496 {
497     IRichEditOleImpl *This = impl_from_ITextDocument(me);
498     FIXME("stub %p\n",This);
499     return E_NOTIMPL;
500 }
501
502 static HRESULT WINAPI
503 ITextDocument_fnInvoke(ITextDocument* me, DISPID dispIdMember,
504     REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
505     VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
506 {
507     IRichEditOleImpl *This = impl_from_ITextDocument(me);
508     FIXME("stub %p\n",This);
509     return E_NOTIMPL;
510 }
511
512 static HRESULT WINAPI
513 ITextDocument_fnGetName(ITextDocument* me, BSTR* pName)
514 {
515     IRichEditOleImpl *This = impl_from_ITextDocument(me);
516     FIXME("stub %p\n",This);
517     return E_NOTIMPL;
518 }
519
520 static HRESULT WINAPI
521 ITextDocument_fnGetSelection(ITextDocument* me, ITextSelection** ppSel)
522 {
523     IRichEditOleImpl *This = impl_from_ITextDocument(me);
524     TRACE("(%p)\n", me);
525     *ppSel = (ITextSelection *) This->txtSel;
526     ITextSelection_AddRef(*ppSel);
527     return S_OK;
528 }
529
530 static HRESULT WINAPI
531 ITextDocument_fnGetStoryCount(ITextDocument* me, LONG* pCount)
532 {
533     IRichEditOleImpl *This = impl_from_ITextDocument(me);
534     FIXME("stub %p\n",This);
535     return E_NOTIMPL;
536 }
537
538 static HRESULT WINAPI
539 ITextDocument_fnGetStoryRanges(ITextDocument* me,
540     ITextStoryRanges** ppStories)
541 {
542     IRichEditOleImpl *This = impl_from_ITextDocument(me);
543     FIXME("stub %p\n",This);
544     return E_NOTIMPL;
545 }
546
547 static HRESULT WINAPI
548 ITextDocument_fnGetSaved(ITextDocument* me, LONG* pValue)
549 {
550     IRichEditOleImpl *This = impl_from_ITextDocument(me);
551     FIXME("stub %p\n",This);
552     return E_NOTIMPL;
553 }
554
555 static HRESULT WINAPI
556 ITextDocument_fnSetSaved(ITextDocument* me, LONG Value)
557 {
558     IRichEditOleImpl *This = impl_from_ITextDocument(me);
559     FIXME("stub %p\n",This);
560     return E_NOTIMPL;
561 }
562
563 static HRESULT WINAPI
564 ITextDocument_fnGetDefaultTabStop(ITextDocument* me, float* pValue)
565 {
566     IRichEditOleImpl *This = impl_from_ITextDocument(me);
567     FIXME("stub %p\n",This);
568     return E_NOTIMPL;
569 }
570
571 static HRESULT WINAPI
572 ITextDocument_fnSetDefaultTabStop(ITextDocument* me, float Value)
573 {
574     IRichEditOleImpl *This = impl_from_ITextDocument(me);
575     FIXME("stub %p\n",This);
576     return E_NOTIMPL;
577 }
578
579 static HRESULT WINAPI
580 ITextDocument_fnNew(ITextDocument* me)
581 {
582     IRichEditOleImpl *This = impl_from_ITextDocument(me);
583     FIXME("stub %p\n",This);
584     return E_NOTIMPL;
585 }
586
587 static HRESULT WINAPI
588 ITextDocument_fnOpen(ITextDocument* me, VARIANT* pVar, LONG Flags,
589     LONG CodePage)
590 {
591     IRichEditOleImpl *This = impl_from_ITextDocument(me);
592     FIXME("stub %p\n",This);
593     return E_NOTIMPL;
594 }
595
596 static HRESULT WINAPI
597 ITextDocument_fnSave(ITextDocument* me, VARIANT* pVar, LONG Flags,
598     LONG CodePage)
599 {
600     IRichEditOleImpl *This = impl_from_ITextDocument(me);
601     FIXME("stub %p\n",This);
602     return E_NOTIMPL;
603 }
604
605 static HRESULT WINAPI
606 ITextDocument_fnFreeze(ITextDocument* me, LONG* pCount)
607 {
608     IRichEditOleImpl *This = impl_from_ITextDocument(me);
609     FIXME("stub %p\n",This);
610     return E_NOTIMPL;
611 }
612
613 static HRESULT WINAPI
614 ITextDocument_fnUnfreeze(ITextDocument* me, LONG* pCount)
615 {
616     IRichEditOleImpl *This = impl_from_ITextDocument(me);
617     FIXME("stub %p\n",This);
618     return E_NOTIMPL;
619 }
620
621 static HRESULT WINAPI
622 ITextDocument_fnBeginEditCollection(ITextDocument* me)
623 {
624     IRichEditOleImpl *This = impl_from_ITextDocument(me);
625     FIXME("stub %p\n",This);
626     return E_NOTIMPL;
627 }
628
629 static HRESULT WINAPI
630 ITextDocument_fnEndEditCollection(ITextDocument* me)
631 {
632     IRichEditOleImpl *This = impl_from_ITextDocument(me);
633     FIXME("stub %p\n",This);
634     return E_NOTIMPL;
635 }
636
637 static HRESULT WINAPI
638 ITextDocument_fnUndo(ITextDocument* me, LONG Count, LONG* prop)
639 {
640     IRichEditOleImpl *This = impl_from_ITextDocument(me);
641     FIXME("stub %p\n",This);
642     return E_NOTIMPL;
643 }
644
645 static HRESULT WINAPI
646 ITextDocument_fnRedo(ITextDocument* me, LONG Count, LONG* prop)
647 {
648     IRichEditOleImpl *This = impl_from_ITextDocument(me);
649     FIXME("stub %p\n",This);
650     return E_NOTIMPL;
651 }
652
653 static HRESULT WINAPI
654 ITextDocument_fnRange(ITextDocument* me, LONG cp1, LONG cp2,
655     ITextRange** ppRange)
656 {
657     IRichEditOleImpl *This = impl_from_ITextDocument(me);
658     FIXME("stub %p\n",This);
659     return E_NOTIMPL;
660 }
661
662 static HRESULT WINAPI
663 ITextDocument_fnRangeFromPoint(ITextDocument* me, LONG x, LONG y,
664     ITextRange** ppRange)
665 {
666     IRichEditOleImpl *This = impl_from_ITextDocument(me);
667     FIXME("stub %p\n",This);
668     return E_NOTIMPL;
669 }
670
671 static const ITextDocumentVtbl tdvt = {
672     ITextDocument_fnQueryInterface,
673     ITextDocument_fnAddRef,
674     ITextDocument_fnRelease,
675     ITextDocument_fnGetTypeInfoCount,
676     ITextDocument_fnGetTypeInfo,
677     ITextDocument_fnGetIDsOfNames,
678     ITextDocument_fnInvoke,
679     ITextDocument_fnGetName,
680     ITextDocument_fnGetSelection,
681     ITextDocument_fnGetStoryCount,
682     ITextDocument_fnGetStoryRanges,
683     ITextDocument_fnGetSaved,
684     ITextDocument_fnSetSaved,
685     ITextDocument_fnGetDefaultTabStop,
686     ITextDocument_fnSetDefaultTabStop,
687     ITextDocument_fnNew,
688     ITextDocument_fnOpen,
689     ITextDocument_fnSave,
690     ITextDocument_fnFreeze,
691     ITextDocument_fnUnfreeze,
692     ITextDocument_fnBeginEditCollection,
693     ITextDocument_fnEndEditCollection,
694     ITextDocument_fnUndo,
695     ITextDocument_fnRedo,
696     ITextDocument_fnRange,
697     ITextDocument_fnRangeFromPoint
698 };
699
700 static HRESULT WINAPI ITextSelection_fnQueryInterface(
701     ITextSelection *me,
702     REFIID riid,
703     void **ppvObj)
704 {
705     *ppvObj = NULL;
706     if (IsEqualGUID(riid, &IID_IUnknown)
707         || IsEqualGUID(riid, &IID_IDispatch)
708         || IsEqualGUID(riid, &IID_ITextRange)
709         || IsEqualGUID(riid, &IID_ITextSelection))
710     {
711         *ppvObj = me;
712         ITextSelection_AddRef(me);
713         return S_OK;
714     }
715
716     return E_NOINTERFACE;
717 }
718
719 static ULONG WINAPI ITextSelection_fnAddRef(
720     ITextSelection *me)
721 {
722     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
723     return InterlockedIncrement(&This->ref);
724 }
725
726 static ULONG WINAPI ITextSelection_fnRelease(
727     ITextSelection *me)
728 {
729     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
730     ULONG ref = InterlockedDecrement(&This->ref);
731     if (ref == 0)
732         heap_free(This);
733     return ref;
734 }
735
736 static HRESULT WINAPI ITextSelection_fnGetTypeInfoCount(
737     ITextSelection *me,
738     UINT *pctinfo)
739 {
740     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
741     if (!This->reOle)
742         return CO_E_RELEASED;
743
744     FIXME("not implemented\n");
745     return E_NOTIMPL;
746 }
747
748 static HRESULT WINAPI ITextSelection_fnGetTypeInfo(
749     ITextSelection *me,
750     UINT iTInfo,
751     LCID lcid,
752     ITypeInfo **ppTInfo)
753 {
754     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
755     if (!This->reOle)
756         return CO_E_RELEASED;
757
758     FIXME("not implemented\n");
759     return E_NOTIMPL;
760 }
761
762 static HRESULT WINAPI ITextSelection_fnGetIDsOfNames(
763     ITextSelection *me,
764     REFIID riid,
765     LPOLESTR *rgszNames,
766     UINT cNames,
767     LCID lcid,
768     DISPID *rgDispId)
769 {
770     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
771     if (!This->reOle)
772         return CO_E_RELEASED;
773
774     FIXME("not implemented\n");
775     return E_NOTIMPL;
776 }
777
778 static HRESULT WINAPI ITextSelection_fnInvoke(
779     ITextSelection *me,
780     DISPID dispIdMember,
781     REFIID riid,
782     LCID lcid,
783     WORD wFlags,
784     DISPPARAMS *pDispParams,
785     VARIANT *pVarResult,
786     EXCEPINFO *pExcepInfo,
787     UINT *puArgErr)
788 {
789     FIXME("not implemented\n");
790     return E_NOTIMPL;
791 }
792
793 /*** ITextRange methods ***/
794 static HRESULT WINAPI ITextSelection_fnGetText(
795     ITextSelection *me,
796     BSTR *pbstr)
797 {
798     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
799     if (!This->reOle)
800         return CO_E_RELEASED;
801
802     FIXME("not implemented\n");
803     return E_NOTIMPL;
804 }
805
806 static HRESULT WINAPI ITextSelection_fnSetText(
807     ITextSelection *me,
808     BSTR bstr)
809 {
810     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
811     if (!This->reOle)
812         return CO_E_RELEASED;
813
814     FIXME("not implemented\n");
815     return E_NOTIMPL;
816 }
817
818 static HRESULT WINAPI ITextSelection_fnGetChar(
819     ITextSelection *me,
820     LONG *pch)
821 {
822     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
823     if (!This->reOle)
824         return CO_E_RELEASED;
825
826     FIXME("not implemented\n");
827     return E_NOTIMPL;
828 }
829
830 static HRESULT WINAPI ITextSelection_fnSetChar(
831     ITextSelection *me,
832     LONG ch)
833 {
834     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
835     if (!This->reOle)
836         return CO_E_RELEASED;
837
838     FIXME("not implemented\n");
839     return E_NOTIMPL;
840 }
841
842 static HRESULT WINAPI ITextSelection_fnGetDuplicate(
843     ITextSelection *me,
844     ITextRange **ppRange)
845 {
846     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
847     if (!This->reOle)
848         return CO_E_RELEASED;
849
850     FIXME("not implemented\n");
851     return E_NOTIMPL;
852 }
853
854 static HRESULT WINAPI ITextSelection_fnGetFormattedText(
855     ITextSelection *me,
856     ITextRange **ppRange)
857 {
858     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
859     if (!This->reOle)
860         return CO_E_RELEASED;
861
862     FIXME("not implemented\n");
863     return E_NOTIMPL;
864 }
865
866 static HRESULT WINAPI ITextSelection_fnSetFormattedText(
867     ITextSelection *me,
868     ITextRange *pRange)
869 {
870     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
871     if (!This->reOle)
872         return CO_E_RELEASED;
873
874     FIXME("not implemented\n");
875     return E_NOTIMPL;
876 }
877
878 static HRESULT WINAPI ITextSelection_fnGetStart(
879     ITextSelection *me,
880     LONG *pcpFirst)
881 {
882     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
883     if (!This->reOle)
884         return CO_E_RELEASED;
885
886     FIXME("not implemented\n");
887     return E_NOTIMPL;
888 }
889
890 static HRESULT WINAPI ITextSelection_fnSetStart(
891     ITextSelection *me,
892     LONG cpFirst)
893 {
894     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
895     if (!This->reOle)
896         return CO_E_RELEASED;
897
898     FIXME("not implemented\n");
899     return E_NOTIMPL;
900 }
901
902 static HRESULT WINAPI ITextSelection_fnGetEnd(
903     ITextSelection *me,
904     LONG *pcpLim)
905 {
906     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
907     if (!This->reOle)
908         return CO_E_RELEASED;
909
910     FIXME("not implemented\n");
911     return E_NOTIMPL;
912 }
913
914 static HRESULT WINAPI ITextSelection_fnSetEnd(
915     ITextSelection *me,
916     LONG cpLim)
917 {
918     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
919     if (!This->reOle)
920         return CO_E_RELEASED;
921
922     FIXME("not implemented\n");
923     return E_NOTIMPL;
924 }
925
926 static HRESULT WINAPI ITextSelection_fnGetFont(
927     ITextSelection *me,
928     ITextFont **pFont)
929 {
930     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
931     if (!This->reOle)
932         return CO_E_RELEASED;
933
934     FIXME("not implemented\n");
935     return E_NOTIMPL;
936 }
937
938 static HRESULT WINAPI ITextSelection_fnSetFont(
939     ITextSelection *me,
940     ITextFont *pFont)
941 {
942     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
943     if (!This->reOle)
944         return CO_E_RELEASED;
945
946     FIXME("not implemented\n");
947     return E_NOTIMPL;
948 }
949
950 static HRESULT WINAPI ITextSelection_fnGetPara(
951     ITextSelection *me,
952     ITextPara **ppPara)
953 {
954     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
955     if (!This->reOle)
956         return CO_E_RELEASED;
957
958     FIXME("not implemented\n");
959     return E_NOTIMPL;
960 }
961
962 static HRESULT WINAPI ITextSelection_fnSetPara(
963     ITextSelection *me,
964     ITextPara *pPara)
965 {
966     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
967     if (!This->reOle)
968         return CO_E_RELEASED;
969
970     FIXME("not implemented\n");
971     return E_NOTIMPL;
972 }
973
974 static HRESULT WINAPI ITextSelection_fnGetStoryLength(
975     ITextSelection *me,
976     LONG *pcch)
977 {
978     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
979     if (!This->reOle)
980         return CO_E_RELEASED;
981
982     FIXME("not implemented\n");
983     return E_NOTIMPL;
984 }
985
986 static HRESULT WINAPI ITextSelection_fnGetStoryType(
987     ITextSelection *me,
988     LONG *pValue)
989 {
990     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
991     if (!This->reOle)
992         return CO_E_RELEASED;
993
994     FIXME("not implemented\n");
995     return E_NOTIMPL;
996 }
997
998 static HRESULT WINAPI ITextSelection_fnCollapse(
999     ITextSelection *me,
1000     LONG bStart)
1001 {
1002     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1003     if (!This->reOle)
1004         return CO_E_RELEASED;
1005
1006     FIXME("not implemented\n");
1007     return E_NOTIMPL;
1008 }
1009
1010 static HRESULT WINAPI ITextSelection_fnExpand(
1011     ITextSelection *me,
1012     LONG Unit,
1013     LONG *pDelta)
1014 {
1015     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1016     if (!This->reOle)
1017         return CO_E_RELEASED;
1018
1019     FIXME("not implemented\n");
1020     return E_NOTIMPL;
1021 }
1022
1023 static HRESULT WINAPI ITextSelection_fnGetIndex(
1024     ITextSelection *me,
1025     LONG Unit,
1026     LONG *pIndex)
1027 {
1028     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1029     if (!This->reOle)
1030         return CO_E_RELEASED;
1031
1032     FIXME("not implemented\n");
1033     return E_NOTIMPL;
1034 }
1035
1036 static HRESULT WINAPI ITextSelection_fnSetIndex(
1037     ITextSelection *me,
1038     LONG Unit,
1039     LONG Index,
1040     LONG Extend)
1041 {
1042     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1043     if (!This->reOle)
1044         return CO_E_RELEASED;
1045
1046     FIXME("not implemented\n");
1047     return E_NOTIMPL;
1048 }
1049
1050 static HRESULT WINAPI ITextSelection_fnSetRange(
1051     ITextSelection *me,
1052     LONG cpActive,
1053     LONG cpOther)
1054 {
1055     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1056     if (!This->reOle)
1057         return CO_E_RELEASED;
1058
1059     FIXME("not implemented\n");
1060     return E_NOTIMPL;
1061 }
1062
1063 static HRESULT WINAPI ITextSelection_fnInRange(
1064     ITextSelection *me,
1065     ITextRange *pRange,
1066     LONG *pb)
1067 {
1068     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1069     if (!This->reOle)
1070         return CO_E_RELEASED;
1071
1072     FIXME("not implemented\n");
1073     return E_NOTIMPL;
1074 }
1075
1076 static HRESULT WINAPI ITextSelection_fnInStory(
1077     ITextSelection *me,
1078     ITextRange *pRange,
1079     LONG *pb)
1080 {
1081     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1082     if (!This->reOle)
1083         return CO_E_RELEASED;
1084
1085     FIXME("not implemented\n");
1086     return E_NOTIMPL;
1087 }
1088
1089 static HRESULT WINAPI ITextSelection_fnIsEqual(
1090     ITextSelection *me,
1091     ITextRange *pRange,
1092     LONG *pb)
1093 {
1094     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1095     if (!This->reOle)
1096         return CO_E_RELEASED;
1097
1098     FIXME("not implemented\n");
1099     return E_NOTIMPL;
1100 }
1101
1102 static HRESULT WINAPI ITextSelection_fnSelect(
1103     ITextSelection *me)
1104 {
1105     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1106     if (!This->reOle)
1107         return CO_E_RELEASED;
1108
1109     FIXME("not implemented\n");
1110     return E_NOTIMPL;
1111 }
1112
1113 static HRESULT WINAPI ITextSelection_fnStartOf(
1114     ITextSelection *me,
1115     LONG Unit,
1116     LONG Extend,
1117     LONG *pDelta)
1118 {
1119     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1120     if (!This->reOle)
1121         return CO_E_RELEASED;
1122
1123     FIXME("not implemented\n");
1124     return E_NOTIMPL;
1125 }
1126
1127 static HRESULT WINAPI ITextSelection_fnEndOf(
1128     ITextSelection *me,
1129     LONG Unit,
1130     LONG Extend,
1131     LONG *pDelta)
1132 {
1133     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1134     if (!This->reOle)
1135         return CO_E_RELEASED;
1136
1137     FIXME("not implemented\n");
1138     return E_NOTIMPL;
1139 }
1140
1141 static HRESULT WINAPI ITextSelection_fnMove(
1142     ITextSelection *me,
1143     LONG Unit,
1144     LONG Count,
1145     LONG *pDelta)
1146 {
1147     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1148     if (!This->reOle)
1149         return CO_E_RELEASED;
1150
1151     FIXME("not implemented\n");
1152     return E_NOTIMPL;
1153 }
1154
1155 static HRESULT WINAPI ITextSelection_fnMoveStart(
1156     ITextSelection *me,
1157     LONG Unit,
1158     LONG Count,
1159     LONG *pDelta)
1160 {
1161     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1162     if (!This->reOle)
1163         return CO_E_RELEASED;
1164
1165     FIXME("not implemented\n");
1166     return E_NOTIMPL;
1167 }
1168
1169 static HRESULT WINAPI ITextSelection_fnMoveEnd(
1170     ITextSelection *me,
1171     LONG Unit,
1172     LONG Count,
1173     LONG *pDelta)
1174 {
1175     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1176     if (!This->reOle)
1177         return CO_E_RELEASED;
1178
1179     FIXME("not implemented\n");
1180     return E_NOTIMPL;
1181 }
1182
1183 static HRESULT WINAPI ITextSelection_fnMoveWhile(
1184     ITextSelection *me,
1185     VARIANT *Cset,
1186     LONG Count,
1187     LONG *pDelta)
1188 {
1189     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1190     if (!This->reOle)
1191         return CO_E_RELEASED;
1192
1193     FIXME("not implemented\n");
1194     return E_NOTIMPL;
1195 }
1196
1197 static HRESULT WINAPI ITextSelection_fnMoveStartWhile(
1198     ITextSelection *me,
1199     VARIANT *Cset,
1200     LONG Count,
1201     LONG *pDelta)
1202 {
1203     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1204     if (!This->reOle)
1205         return CO_E_RELEASED;
1206
1207     FIXME("not implemented\n");
1208     return E_NOTIMPL;
1209 }
1210
1211 static HRESULT WINAPI ITextSelection_fnMoveEndWhile(
1212     ITextSelection *me,
1213     VARIANT *Cset,
1214     LONG Count,
1215     LONG *pDelta)
1216 {
1217     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1218     if (!This->reOle)
1219         return CO_E_RELEASED;
1220
1221     FIXME("not implemented\n");
1222     return E_NOTIMPL;
1223 }
1224
1225 static HRESULT WINAPI ITextSelection_fnMoveUntil(
1226     ITextSelection *me,
1227     VARIANT *Cset,
1228     LONG Count,
1229     LONG *pDelta)
1230 {
1231     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1232     if (!This->reOle)
1233         return CO_E_RELEASED;
1234
1235     FIXME("not implemented\n");
1236     return E_NOTIMPL;
1237 }
1238
1239 static HRESULT WINAPI ITextSelection_fnMoveStartUntil(
1240     ITextSelection *me,
1241     VARIANT *Cset,
1242     LONG Count,
1243     LONG *pDelta)
1244 {
1245     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1246     if (!This->reOle)
1247         return CO_E_RELEASED;
1248
1249     FIXME("not implemented\n");
1250     return E_NOTIMPL;
1251 }
1252
1253 static HRESULT WINAPI ITextSelection_fnMoveEndUntil(
1254     ITextSelection *me,
1255     VARIANT *Cset,
1256     LONG Count,
1257     LONG *pDelta)
1258 {
1259     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1260     if (!This->reOle)
1261         return CO_E_RELEASED;
1262
1263     FIXME("not implemented\n");
1264     return E_NOTIMPL;
1265 }
1266
1267 static HRESULT WINAPI ITextSelection_fnFindText(
1268     ITextSelection *me,
1269     BSTR bstr,
1270     LONG cch,
1271     LONG Flags,
1272     LONG *pLength)
1273 {
1274     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1275     if (!This->reOle)
1276         return CO_E_RELEASED;
1277
1278     FIXME("not implemented\n");
1279     return E_NOTIMPL;
1280 }
1281
1282 static HRESULT WINAPI ITextSelection_fnFindTextStart(
1283     ITextSelection *me,
1284     BSTR bstr,
1285     LONG cch,
1286     LONG Flags,
1287     LONG *pLength)
1288 {
1289     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1290     if (!This->reOle)
1291         return CO_E_RELEASED;
1292
1293     FIXME("not implemented\n");
1294     return E_NOTIMPL;
1295 }
1296
1297 static HRESULT WINAPI ITextSelection_fnFindTextEnd(
1298     ITextSelection *me,
1299     BSTR bstr,
1300     LONG cch,
1301     LONG Flags,
1302     LONG *pLength)
1303 {
1304     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1305     if (!This->reOle)
1306         return CO_E_RELEASED;
1307
1308     FIXME("not implemented\n");
1309     return E_NOTIMPL;
1310 }
1311
1312 static HRESULT WINAPI ITextSelection_fnDelete(
1313     ITextSelection *me,
1314     LONG Unit,
1315     LONG Count,
1316     LONG *pDelta)
1317 {
1318     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1319     if (!This->reOle)
1320         return CO_E_RELEASED;
1321
1322     FIXME("not implemented\n");
1323     return E_NOTIMPL;
1324 }
1325
1326 static HRESULT WINAPI ITextSelection_fnCut(
1327     ITextSelection *me,
1328     VARIANT *pVar)
1329 {
1330     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1331     if (!This->reOle)
1332         return CO_E_RELEASED;
1333
1334     FIXME("not implemented\n");
1335     return E_NOTIMPL;
1336 }
1337
1338 static HRESULT WINAPI ITextSelection_fnCopy(
1339     ITextSelection *me,
1340     VARIANT *pVar)
1341 {
1342     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1343     if (!This->reOle)
1344         return CO_E_RELEASED;
1345
1346     FIXME("not implemented\n");
1347     return E_NOTIMPL;
1348 }
1349
1350 static HRESULT WINAPI ITextSelection_fnPaste(
1351     ITextSelection *me,
1352     VARIANT *pVar,
1353     LONG Format)
1354 {
1355     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1356     if (!This->reOle)
1357         return CO_E_RELEASED;
1358
1359     FIXME("not implemented\n");
1360     return E_NOTIMPL;
1361 }
1362
1363 static HRESULT WINAPI ITextSelection_fnCanPaste(
1364     ITextSelection *me,
1365     VARIANT *pVar,
1366     LONG Format,
1367     LONG *pb)
1368 {
1369     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1370     if (!This->reOle)
1371         return CO_E_RELEASED;
1372
1373     FIXME("not implemented\n");
1374     return E_NOTIMPL;
1375 }
1376
1377 static HRESULT WINAPI ITextSelection_fnCanEdit(
1378     ITextSelection *me,
1379     LONG *pb)
1380 {
1381     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1382     if (!This->reOle)
1383         return CO_E_RELEASED;
1384
1385     FIXME("not implemented\n");
1386     return E_NOTIMPL;
1387 }
1388
1389 static HRESULT WINAPI ITextSelection_fnChangeCase(
1390     ITextSelection *me,
1391     LONG Type)
1392 {
1393     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1394     if (!This->reOle)
1395         return CO_E_RELEASED;
1396
1397     FIXME("not implemented\n");
1398     return E_NOTIMPL;
1399 }
1400
1401 static HRESULT WINAPI ITextSelection_fnGetPoint(
1402     ITextSelection *me,
1403     LONG Type,
1404     LONG *cx,
1405     LONG *cy)
1406 {
1407     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1408     if (!This->reOle)
1409         return CO_E_RELEASED;
1410
1411     FIXME("not implemented\n");
1412     return E_NOTIMPL;
1413 }
1414
1415 static HRESULT WINAPI ITextSelection_fnSetPoint(
1416     ITextSelection *me,
1417     LONG x,
1418     LONG y,
1419     LONG Type,
1420     LONG Extend)
1421 {
1422     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1423     if (!This->reOle)
1424         return CO_E_RELEASED;
1425
1426     FIXME("not implemented\n");
1427     return E_NOTIMPL;
1428 }
1429
1430 static HRESULT WINAPI ITextSelection_fnScrollIntoView(
1431     ITextSelection *me,
1432     LONG Value)
1433 {
1434     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1435     if (!This->reOle)
1436         return CO_E_RELEASED;
1437
1438     FIXME("not implemented\n");
1439     return E_NOTIMPL;
1440 }
1441
1442 static HRESULT WINAPI ITextSelection_fnGetEmbeddedObject(
1443     ITextSelection *me,
1444     IUnknown **ppv)
1445 {
1446     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1447     if (!This->reOle)
1448         return CO_E_RELEASED;
1449
1450     FIXME("not implemented\n");
1451     return E_NOTIMPL;
1452 }
1453
1454 /*** ITextSelection methods ***/
1455 static HRESULT WINAPI ITextSelection_fnGetFlags(
1456     ITextSelection *me,
1457     LONG *pFlags)
1458 {
1459     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1460     if (!This->reOle)
1461         return CO_E_RELEASED;
1462
1463     FIXME("not implemented\n");
1464     return E_NOTIMPL;
1465 }
1466
1467 static HRESULT WINAPI ITextSelection_fnSetFlags(
1468     ITextSelection *me,
1469     LONG Flags)
1470 {
1471     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1472     if (!This->reOle)
1473         return CO_E_RELEASED;
1474
1475     FIXME("not implemented\n");
1476     return E_NOTIMPL;
1477 }
1478
1479 static HRESULT WINAPI ITextSelection_fnGetType(
1480     ITextSelection *me,
1481     LONG *pType)
1482 {
1483     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1484     if (!This->reOle)
1485         return CO_E_RELEASED;
1486
1487     FIXME("not implemented\n");
1488     return E_NOTIMPL;
1489 }
1490
1491 static HRESULT WINAPI ITextSelection_fnMoveLeft(
1492     ITextSelection *me,
1493     LONG Unit,
1494     LONG Count,
1495     LONG Extend,
1496     LONG *pDelta)
1497 {
1498     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1499     if (!This->reOle)
1500         return CO_E_RELEASED;
1501
1502     FIXME("not implemented\n");
1503     return E_NOTIMPL;
1504 }
1505
1506 static HRESULT WINAPI ITextSelection_fnMoveRight(
1507     ITextSelection *me,
1508     LONG Unit,
1509     LONG Count,
1510     LONG Extend,
1511     LONG *pDelta)
1512 {
1513     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1514     if (!This->reOle)
1515         return CO_E_RELEASED;
1516
1517     FIXME("not implemented\n");
1518     return E_NOTIMPL;
1519 }
1520
1521 static HRESULT WINAPI ITextSelection_fnMoveUp(
1522     ITextSelection *me,
1523     LONG Unit,
1524     LONG Count,
1525     LONG Extend,
1526     LONG *pDelta)
1527 {
1528     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1529     if (!This->reOle)
1530         return CO_E_RELEASED;
1531
1532     FIXME("not implemented\n");
1533     return E_NOTIMPL;
1534 }
1535
1536 static HRESULT WINAPI ITextSelection_fnMoveDown(
1537     ITextSelection *me,
1538     LONG Unit,
1539     LONG Count,
1540     LONG Extend,
1541     LONG *pDelta)
1542 {
1543     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1544     if (!This->reOle)
1545         return CO_E_RELEASED;
1546
1547     FIXME("not implemented\n");
1548     return E_NOTIMPL;
1549 }
1550
1551 static HRESULT WINAPI ITextSelection_fnHomeKey(
1552     ITextSelection *me,
1553     LONG Unit,
1554     LONG Extend,
1555     LONG *pDelta)
1556 {
1557     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1558     if (!This->reOle)
1559         return CO_E_RELEASED;
1560
1561     FIXME("not implemented\n");
1562     return E_NOTIMPL;
1563 }
1564
1565 static HRESULT WINAPI ITextSelection_fnEndKey(
1566     ITextSelection *me,
1567     LONG Unit,
1568     LONG Extend,
1569     LONG *pDelta)
1570 {
1571     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1572     if (!This->reOle)
1573         return CO_E_RELEASED;
1574
1575     FIXME("not implemented\n");
1576     return E_NOTIMPL;
1577 }
1578
1579 static HRESULT WINAPI ITextSelection_fnTypeText(
1580     ITextSelection *me,
1581     BSTR bstr)
1582 {
1583     ITextSelectionImpl *This = (ITextSelectionImpl *) me;
1584     if (!This->reOle)
1585         return CO_E_RELEASED;
1586
1587     FIXME("not implemented\n");
1588     return E_NOTIMPL;
1589 }
1590
1591 static const ITextSelectionVtbl tsvt = {
1592     ITextSelection_fnQueryInterface,
1593     ITextSelection_fnAddRef,
1594     ITextSelection_fnRelease,
1595     ITextSelection_fnGetTypeInfoCount,
1596     ITextSelection_fnGetTypeInfo,
1597     ITextSelection_fnGetIDsOfNames,
1598     ITextSelection_fnInvoke,
1599     ITextSelection_fnGetText,
1600     ITextSelection_fnSetText,
1601     ITextSelection_fnGetChar,
1602     ITextSelection_fnSetChar,
1603     ITextSelection_fnGetDuplicate,
1604     ITextSelection_fnGetFormattedText,
1605     ITextSelection_fnSetFormattedText,
1606     ITextSelection_fnGetStart,
1607     ITextSelection_fnSetStart,
1608     ITextSelection_fnGetEnd,
1609     ITextSelection_fnSetEnd,
1610     ITextSelection_fnGetFont,
1611     ITextSelection_fnSetFont,
1612     ITextSelection_fnGetPara,
1613     ITextSelection_fnSetPara,
1614     ITextSelection_fnGetStoryLength,
1615     ITextSelection_fnGetStoryType,
1616     ITextSelection_fnCollapse,
1617     ITextSelection_fnExpand,
1618     ITextSelection_fnGetIndex,
1619     ITextSelection_fnSetIndex,
1620     ITextSelection_fnSetRange,
1621     ITextSelection_fnInRange,
1622     ITextSelection_fnInStory,
1623     ITextSelection_fnIsEqual,
1624     ITextSelection_fnSelect,
1625     ITextSelection_fnStartOf,
1626     ITextSelection_fnEndOf,
1627     ITextSelection_fnMove,
1628     ITextSelection_fnMoveStart,
1629     ITextSelection_fnMoveEnd,
1630     ITextSelection_fnMoveWhile,
1631     ITextSelection_fnMoveStartWhile,
1632     ITextSelection_fnMoveEndWhile,
1633     ITextSelection_fnMoveUntil,
1634     ITextSelection_fnMoveStartUntil,
1635     ITextSelection_fnMoveEndUntil,
1636     ITextSelection_fnFindText,
1637     ITextSelection_fnFindTextStart,
1638     ITextSelection_fnFindTextEnd,
1639     ITextSelection_fnDelete,
1640     ITextSelection_fnCut,
1641     ITextSelection_fnCopy,
1642     ITextSelection_fnPaste,
1643     ITextSelection_fnCanPaste,
1644     ITextSelection_fnCanEdit,
1645     ITextSelection_fnChangeCase,
1646     ITextSelection_fnGetPoint,
1647     ITextSelection_fnSetPoint,
1648     ITextSelection_fnScrollIntoView,
1649     ITextSelection_fnGetEmbeddedObject,
1650     ITextSelection_fnGetFlags,
1651     ITextSelection_fnSetFlags,
1652     ITextSelection_fnGetType,
1653     ITextSelection_fnMoveLeft,
1654     ITextSelection_fnMoveRight,
1655     ITextSelection_fnMoveUp,
1656     ITextSelection_fnMoveDown,
1657     ITextSelection_fnHomeKey,
1658     ITextSelection_fnEndKey,
1659     ITextSelection_fnTypeText
1660 };
1661
1662 static ITextSelectionImpl *
1663 CreateTextSelection(IRichEditOleImpl *reOle)
1664 {
1665     ITextSelectionImpl *txtSel = heap_alloc(sizeof *txtSel);
1666     if (!txtSel)
1667         return NULL;
1668
1669     txtSel->lpVtbl = &tsvt;
1670     txtSel->ref = 1;
1671     txtSel->reOle = reOle;
1672     return txtSel;
1673 }
1674
1675 LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *ppObj)
1676 {
1677     IRichEditOleImpl *reo;
1678
1679     reo = heap_alloc(sizeof(IRichEditOleImpl));
1680     if (!reo)
1681         return 0;
1682
1683     reo->lpRichEditOleVtbl = &revt;
1684     reo->lpTextDocumentVtbl = &tdvt;
1685     reo->ref = 1;
1686     reo->editor = editor;
1687     reo->txtSel = CreateTextSelection(reo);
1688     if (!reo->txtSel)
1689     {
1690         heap_free(reo);
1691         return 0;
1692     }
1693     reo->clientSite = CreateOleClientSite(reo);
1694     if (!reo->txtSel)
1695     {
1696         ITextSelection_Release((ITextSelection *) reo->txtSel);
1697         heap_free(reo);
1698         return 0;
1699     }
1700     TRACE("Created %p\n",reo);
1701     *ppObj = reo;
1702
1703     return 1;
1704 }
1705
1706 static void convert_sizel(ME_Context *c, const SIZEL* szl, SIZE* sz)
1707 {
1708   /* sizel is in .01 millimeters, sz in pixels */
1709   sz->cx = MulDiv(szl->cx, c->dpi.cx, 2540);
1710   sz->cy = MulDiv(szl->cy, c->dpi.cy, 2540);
1711 }
1712
1713 /******************************************************************************
1714  * ME_GetOLEObjectSize
1715  *
1716  * Sets run extent for OLE objects.
1717  */
1718 void ME_GetOLEObjectSize(ME_Context *c, ME_Run *run, SIZE *pSize)
1719 {
1720   IDataObject*  ido;
1721   FORMATETC     fmt;
1722   STGMEDIUM     stgm;
1723   DIBSECTION    dibsect;
1724   ENHMETAHEADER emh;
1725
1726   assert(run->nFlags & MERF_GRAPHICS);
1727   assert(run->ole_obj);
1728
1729   if (run->ole_obj->sizel.cx != 0 || run->ole_obj->sizel.cy != 0)
1730   {
1731     convert_sizel(c, &run->ole_obj->sizel, pSize);
1732     if (c->editor->nZoomNumerator != 0)
1733     {
1734       pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
1735       pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
1736     }
1737     return;
1738   }
1739
1740   IOleObject_QueryInterface(run->ole_obj->poleobj, &IID_IDataObject, (void**)&ido);
1741   fmt.cfFormat = CF_BITMAP;
1742   fmt.ptd = NULL;
1743   fmt.dwAspect = DVASPECT_CONTENT;
1744   fmt.lindex = -1;
1745   fmt.tymed = TYMED_GDI;
1746   if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
1747   {
1748     fmt.cfFormat = CF_ENHMETAFILE;
1749     fmt.tymed = TYMED_ENHMF;
1750     if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
1751     {
1752       FIXME("unsupported format\n");
1753       pSize->cx = pSize->cy = 0;
1754       IDataObject_Release(ido);
1755       return;
1756     }
1757   }
1758
1759   switch (stgm.tymed)
1760   {
1761   case TYMED_GDI:
1762     GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
1763     pSize->cx = dibsect.dsBm.bmWidth;
1764     pSize->cy = dibsect.dsBm.bmHeight;
1765     if (!stgm.pUnkForRelease) DeleteObject(stgm.u.hBitmap);
1766     break;
1767   case TYMED_ENHMF:
1768     GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
1769     pSize->cx = emh.rclBounds.right - emh.rclBounds.left;
1770     pSize->cy = emh.rclBounds.bottom - emh.rclBounds.top;
1771     if (!stgm.pUnkForRelease) DeleteEnhMetaFile(stgm.u.hEnhMetaFile);
1772     break;
1773   default:
1774     FIXME("Unsupported tymed %d\n", stgm.tymed);
1775     break;
1776   }
1777   IDataObject_Release(ido);
1778   if (c->editor->nZoomNumerator != 0)
1779   {
1780     pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
1781     pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
1782   }
1783 }
1784
1785 void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run,
1786                 ME_Paragraph *para, BOOL selected)
1787 {
1788   IDataObject*  ido;
1789   FORMATETC     fmt;
1790   STGMEDIUM     stgm;
1791   DIBSECTION    dibsect;
1792   ENHMETAHEADER emh;
1793   HDC           hMemDC;
1794   SIZE          sz;
1795   BOOL          has_size;
1796
1797   assert(run->nFlags & MERF_GRAPHICS);
1798   assert(run->ole_obj);
1799   if (IOleObject_QueryInterface(run->ole_obj->poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
1800   {
1801     FIXME("Couldn't get interface\n");
1802     return;
1803   }
1804   has_size = run->ole_obj->sizel.cx != 0 || run->ole_obj->sizel.cy != 0;
1805   fmt.cfFormat = CF_BITMAP;
1806   fmt.ptd = NULL;
1807   fmt.dwAspect = DVASPECT_CONTENT;
1808   fmt.lindex = -1;
1809   fmt.tymed = TYMED_GDI;
1810   if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
1811   {
1812     fmt.cfFormat = CF_ENHMETAFILE;
1813     fmt.tymed = TYMED_ENHMF;
1814     if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
1815     {
1816       FIXME("Couldn't get storage medium\n");
1817       IDataObject_Release(ido);
1818       return;
1819     }
1820   }
1821   switch (stgm.tymed)
1822   {
1823   case TYMED_GDI:
1824     GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
1825     hMemDC = CreateCompatibleDC(c->hDC);
1826     SelectObject(hMemDC, stgm.u.hBitmap);
1827     if (has_size)
1828     {
1829       convert_sizel(c, &run->ole_obj->sizel, &sz);
1830     } else {
1831       sz.cx = MulDiv(dibsect.dsBm.bmWidth, c->dpi.cx, 96);
1832       sz.cy = MulDiv(dibsect.dsBm.bmHeight, c->dpi.cy, 96);
1833     }
1834     if (c->editor->nZoomNumerator != 0)
1835     {
1836       sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
1837       sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
1838     }
1839     if (sz.cx == dibsect.dsBm.bmWidth && sz.cy == dibsect.dsBm.bmHeight)
1840     {
1841       BitBlt(c->hDC, x, y - sz.cy,
1842              dibsect.dsBm.bmWidth, dibsect.dsBm.bmHeight,
1843              hMemDC, 0, 0, SRCCOPY);
1844     } else {
1845       StretchBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy,
1846                  hMemDC, 0, 0, dibsect.dsBm.bmWidth,
1847                  dibsect.dsBm.bmHeight, SRCCOPY);
1848     }
1849     if (!stgm.pUnkForRelease) DeleteObject(stgm.u.hBitmap);
1850     break;
1851   case TYMED_ENHMF:
1852     GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
1853     if (has_size)
1854     {
1855       convert_sizel(c, &run->ole_obj->sizel, &sz);
1856     } else {
1857       sz.cy = MulDiv(emh.rclBounds.bottom - emh.rclBounds.top, c->dpi.cx, 96);
1858       sz.cx = MulDiv(emh.rclBounds.right - emh.rclBounds.left, c->dpi.cy, 96);
1859     }
1860     if (c->editor->nZoomNumerator != 0)
1861     {
1862       sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
1863       sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
1864     }
1865
1866     {
1867       RECT    rc;
1868
1869       rc.left = x;
1870       rc.top = y - sz.cy;
1871       rc.right = x + sz.cx;
1872       rc.bottom = y;
1873       PlayEnhMetaFile(c->hDC, stgm.u.hEnhMetaFile, &rc);
1874     }
1875     if (!stgm.pUnkForRelease) DeleteEnhMetaFile(stgm.u.hEnhMetaFile);
1876     break;
1877   default:
1878     FIXME("Unsupported tymed %d\n", stgm.tymed);
1879     selected = FALSE;
1880     break;
1881   }
1882   if (selected && !c->editor->bHideSelection)
1883     PatBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy, DSTINVERT);
1884   IDataObject_Release(ido);
1885 }
1886
1887 void ME_DeleteReObject(REOBJECT* reo)
1888 {
1889     if (reo->poleobj)   IOleObject_Release(reo->poleobj);
1890     if (reo->pstg)      IStorage_Release(reo->pstg);
1891     if (reo->polesite)  IOleClientSite_Release(reo->polesite);
1892     FREE_OBJ(reo);
1893 }
1894
1895 void ME_CopyReObject(REOBJECT* dst, const REOBJECT* src)
1896 {
1897     *dst = *src;
1898
1899     if (dst->poleobj)   IOleObject_AddRef(dst->poleobj);
1900     if (dst->pstg)      IStorage_AddRef(dst->pstg);
1901     if (dst->polesite)  IOleClientSite_AddRef(dst->polesite);
1902 }