xref: /reactos/dll/win32/riched20/richole.c (revision 661b8a2a)
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 COBJMACROS
26 
27 #include "windef.h"
28 #include "winbase.h"
29 #include "wingdi.h"
30 #include "winuser.h"
31 #include "ole2.h"
32 #include "richole.h"
33 #include "editor.h"
34 #include "richedit.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 #include "initguid.h"
43 
44 DEFINE_GUID(LIBID_tom, 0x8cc497c9, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
45 DEFINE_GUID(IID_ITextServices, 0x8d33f740, 0xcf58, 0x11ce, 0xa8, 0x9d, 0x00, 0xaa, 0x00, 0x6c, 0xad, 0xc5);
46 DEFINE_GUID(IID_ITextHost, 0x13e670f4,0x1a5a,0x11cf,0xab,0xeb,0x00,0xaa,0x00,0xb6,0x5e,0xa1);
47 DEFINE_GUID(IID_ITextHost2, 0x13e670f5,0x1a5a,0x11cf,0xab,0xeb,0x00,0xaa,0x00,0xb6,0x5e,0xa1);
48 DEFINE_GUID(IID_ITextDocument, 0x8cc497c0, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
49 DEFINE_GUID(IID_ITextDocument2Old, 0x01c25500, 0x4268, 0x11d1, 0x88, 0x3a, 0x3c, 0x8b, 0x00, 0xc1, 0x00, 0x00);
50 DEFINE_GUID(IID_ITextRange, 0x8cc497c2, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
51 DEFINE_GUID(IID_ITextSelection, 0x8cc497c1, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
52 DEFINE_GUID(IID_ITextFont, 0x8cc497c3, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
53 DEFINE_GUID(IID_ITextPara, 0x8cc497c4, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
54 
55 static ITypeLib *typelib;
56 
57 enum tid_t {
58     NULL_tid,
59     ITextDocument_tid,
60     ITextRange_tid,
61     ITextSelection_tid,
62     ITextFont_tid,
63     ITextPara_tid,
64     LAST_tid
65 };
66 
67 static const IID * const tid_ids[] =
68 {
69     &IID_NULL,
70     &IID_ITextDocument,
71     &IID_ITextRange,
72     &IID_ITextSelection,
73     &IID_ITextFont,
74     &IID_ITextPara,
75 };
76 static ITypeInfo *typeinfos[LAST_tid];
77 
load_typelib(void)78 static HRESULT load_typelib(void)
79 {
80     ITypeLib *tl;
81     HRESULT hr;
82 
83     hr = LoadRegTypeLib(&LIBID_tom, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
84     if (FAILED(hr)) {
85         ERR("LoadRegTypeLib failed: %08x\n", hr);
86         return hr;
87     }
88 
89     if (InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
90         ITypeLib_Release(tl);
91     return hr;
92 }
93 
release_typelib(void)94 void release_typelib(void)
95 {
96     unsigned i;
97 
98     if (!typelib)
99         return;
100 
101     for (i = 0; i < ARRAY_SIZE(typeinfos); i++)
102         if (typeinfos[i])
103             ITypeInfo_Release(typeinfos[i]);
104 
105     ITypeLib_Release(typelib);
106 }
107 
get_typeinfo(enum tid_t tid,ITypeInfo ** typeinfo)108 static HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo)
109 {
110     HRESULT hr;
111 
112     if (!typelib)
113         hr = load_typelib();
114     if (!typelib)
115         return hr;
116 
117     if (!typeinfos[tid])
118     {
119         ITypeInfo *ti;
120 
121         hr = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
122         if (FAILED(hr))
123         {
124             ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hr);
125             return hr;
126         }
127 
128         if (InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
129             ITypeInfo_Release(ti);
130     }
131 
132     *typeinfo = typeinfos[tid];
133     return S_OK;
134 }
135 
136 /* private IID used to get back IRichEditOleImpl pointer */
137 DEFINE_GUID(IID_Igetrichole, 0xe3ce5c7a, 0x8247, 0x4622, 0x81, 0xad, 0x11, 0x81, 0x02, 0xaa, 0x01, 0x30);
138 
139 typedef struct ITextSelectionImpl ITextSelectionImpl;
140 typedef struct IOleClientSiteImpl IOleClientSiteImpl;
141 typedef struct ITextRangeImpl ITextRangeImpl;
142 
143 enum textfont_prop_id {
144     FONT_ALLCAPS = 0,
145     FONT_ANIMATION,
146     FONT_BACKCOLOR,
147     FONT_BOLD,
148     FONT_EMBOSS,
149     FONT_FORECOLOR,
150     FONT_HIDDEN,
151     FONT_ENGRAVE,
152     FONT_ITALIC,
153     FONT_KERNING,
154     FONT_LANGID,
155     FONT_NAME,
156     FONT_OUTLINE,
157     FONT_POSITION,
158     FONT_PROTECTED,
159     FONT_SHADOW,
160     FONT_SIZE,
161     FONT_SMALLCAPS,
162     FONT_SPACING,
163     FONT_STRIKETHROUGH,
164     FONT_SUBSCRIPT,
165     FONT_SUPERSCRIPT,
166     FONT_UNDERLINE,
167     FONT_WEIGHT,
168     FONT_PROPID_LAST,
169     FONT_PROPID_FIRST = FONT_ALLCAPS
170 };
171 
172 static const DWORD textfont_prop_masks[][2] = {
173     { CFM_ALLCAPS,     CFE_ALLCAPS },
174     { CFM_ANIMATION },
175     { CFM_BACKCOLOR,   CFE_AUTOBACKCOLOR },
176     { CFM_BOLD,        CFE_BOLD },
177     { CFM_EMBOSS,      CFE_EMBOSS },
178     { CFM_COLOR,       CFE_AUTOCOLOR },
179     { CFM_HIDDEN,      CFE_HIDDEN },
180     { CFM_IMPRINT,     CFE_IMPRINT },
181     { CFM_ITALIC,      CFE_ITALIC },
182     { CFM_KERNING },
183     { CFM_LCID },
184     { CFM_FACE },
185     { CFM_OUTLINE,     CFE_OUTLINE },
186     { CFM_OFFSET },
187     { CFM_PROTECTED,   CFE_PROTECTED },
188     { CFM_SHADOW,      CFE_SHADOW },
189     { CFM_SIZE },
190     { CFM_SMALLCAPS,   CFE_SMALLCAPS },
191     { CFM_SPACING },
192     { CFM_STRIKEOUT,   CFE_STRIKEOUT },
193     { CFM_SUBSCRIPT,   CFE_SUBSCRIPT },
194     { CFM_SUPERSCRIPT, CFE_SUPERSCRIPT },
195     { CFM_UNDERLINE,   CFE_UNDERLINE },
196     { CFM_WEIGHT }
197 };
198 
199 typedef union {
200     FLOAT f;
201     LONG  l;
202     BSTR  str;
203 } textfont_prop_val;
204 
205 enum range_update_op {
206     RANGE_UPDATE_DELETE
207 };
208 
209 typedef struct IRichEditOleImpl {
210     IUnknown IUnknown_inner;
211     IRichEditOle IRichEditOle_iface;
212     ITextDocument2Old ITextDocument2Old_iface;
213     IUnknown *outer_unk;
214     LONG ref;
215 
216     ME_TextEditor *editor;
217     ITextSelectionImpl *txtSel;
218 
219     struct list rangelist;
220     struct list clientsites;
221 } IRichEditOleImpl;
222 
223 struct reole_child {
224     struct list entry;
225     IRichEditOleImpl *reole;
226 };
227 
228 struct ITextRangeImpl {
229     struct reole_child child;
230     ITextRange ITextRange_iface;
231     LONG ref;
232     LONG start, end;
233 };
234 
235 struct ITextSelectionImpl {
236     ITextSelection ITextSelection_iface;
237     LONG ref;
238 
239     IRichEditOleImpl *reOle;
240 };
241 
242 typedef struct ITextFontImpl {
243     ITextFont ITextFont_iface;
244     LONG ref;
245 
246     ITextRange *range;
247     textfont_prop_val props[FONT_PROPID_LAST];
248     BOOL get_cache_enabled;
249     BOOL set_cache_enabled;
250 } ITextFontImpl;
251 
252 typedef struct ITextParaImpl {
253     ITextPara ITextPara_iface;
254     LONG ref;
255 
256     ITextRange *range;
257 } ITextParaImpl;
258 
259 struct IOleClientSiteImpl {
260     struct reole_child child;
261     IOleClientSite IOleClientSite_iface;
262     IOleInPlaceSite IOleInPlaceSite_iface;
263     LONG ref;
264 };
265 
impl_from_IRichEditOle(IRichEditOle * iface)266 static inline IRichEditOleImpl *impl_from_IRichEditOle(IRichEditOle *iface)
267 {
268     return CONTAINING_RECORD(iface, IRichEditOleImpl, IRichEditOle_iface);
269 }
270 
impl_from_ITextDocument2Old(ITextDocument2Old * iface)271 static inline IRichEditOleImpl *impl_from_ITextDocument2Old(ITextDocument2Old *iface)
272 {
273     return CONTAINING_RECORD(iface, IRichEditOleImpl, ITextDocument2Old_iface);
274 }
275 
impl_from_IUnknown(IUnknown * iface)276 static inline IRichEditOleImpl *impl_from_IUnknown(IUnknown *iface)
277 {
278     return CONTAINING_RECORD(iface, IRichEditOleImpl, IUnknown_inner);
279 }
280 
impl_from_IOleInPlaceSite(IOleInPlaceSite * iface)281 static inline IOleClientSiteImpl *impl_from_IOleInPlaceSite(IOleInPlaceSite *iface)
282 {
283     return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleInPlaceSite_iface);
284 }
285 
impl_from_ITextRange(ITextRange * iface)286 static inline ITextRangeImpl *impl_from_ITextRange(ITextRange *iface)
287 {
288     return CONTAINING_RECORD(iface, ITextRangeImpl, ITextRange_iface);
289 }
290 
impl_from_ITextSelection(ITextSelection * iface)291 static inline ITextSelectionImpl *impl_from_ITextSelection(ITextSelection *iface)
292 {
293     return CONTAINING_RECORD(iface, ITextSelectionImpl, ITextSelection_iface);
294 }
295 
impl_from_ITextFont(ITextFont * iface)296 static inline ITextFontImpl *impl_from_ITextFont(ITextFont *iface)
297 {
298     return CONTAINING_RECORD(iface, ITextFontImpl, ITextFont_iface);
299 }
300 
impl_from_ITextPara(ITextPara * iface)301 static inline ITextParaImpl *impl_from_ITextPara(ITextPara *iface)
302 {
303     return CONTAINING_RECORD(iface, ITextParaImpl, ITextPara_iface);
304 }
305 
306 static HRESULT create_textfont(ITextRange*, const ITextFontImpl*, ITextFont**);
307 static HRESULT create_textpara(ITextRange*, ITextPara**);
308 static ITextSelectionImpl *CreateTextSelection(IRichEditOleImpl*);
309 
textrange_get_storylength(ME_TextEditor * editor,LONG * length)310 static HRESULT textrange_get_storylength(ME_TextEditor *editor, LONG *length)
311 {
312     if (!length)
313         return E_INVALIDARG;
314 
315     *length = ME_GetTextLength(editor) + 1;
316     return S_OK;
317 }
318 
textranges_update_ranges(IRichEditOleImpl * reole,LONG start,LONG end,enum range_update_op op)319 static void textranges_update_ranges(IRichEditOleImpl *reole, LONG start, LONG end, enum range_update_op op)
320 {
321     ITextRangeImpl *range;
322 
323     LIST_FOR_EACH_ENTRY(range, &reole->rangelist, ITextRangeImpl, child.entry) {
324         switch (op)
325         {
326         case RANGE_UPDATE_DELETE:
327             /* range fully covered by deleted range - collapse to insertion point */
328             if (range->start >= start && range->end <= end)
329                 range->start = range->end = start;
330             /* deleted range cuts from the right */
331             else if (range->start < start && range->end <= end)
332                 range->end = start;
333             /* deleted range cuts from the left */
334             else if (range->start >= start && range->end > end) {
335                 range->start = start;
336                 range->end -= end - start;
337             }
338             /* deleted range cuts within */
339             else
340                 range->end -= end - start;
341             break;
342         default:
343             FIXME("unknown update op, %d\n", op);
344         }
345     }
346 }
347 
is_equal_textfont_prop_value(enum textfont_prop_id propid,textfont_prop_val * left,textfont_prop_val * right)348 static inline BOOL is_equal_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *left,
349     textfont_prop_val *right)
350 {
351     switch (propid)
352     {
353     case FONT_ALLCAPS:
354     case FONT_ANIMATION:
355     case FONT_BACKCOLOR:
356     case FONT_BOLD:
357     case FONT_EMBOSS:
358     case FONT_FORECOLOR:
359     case FONT_HIDDEN:
360     case FONT_ENGRAVE:
361     case FONT_ITALIC:
362     case FONT_KERNING:
363     case FONT_LANGID:
364     case FONT_OUTLINE:
365     case FONT_PROTECTED:
366     case FONT_SHADOW:
367     case FONT_SMALLCAPS:
368     case FONT_STRIKETHROUGH:
369     case FONT_SUBSCRIPT:
370     case FONT_SUPERSCRIPT:
371     case FONT_UNDERLINE:
372     case FONT_WEIGHT:
373         return left->l == right->l;
374     case FONT_NAME:
375         return !wcscmp(left->str, right->str);
376     case FONT_POSITION:
377     case FONT_SIZE:
378     case FONT_SPACING:
379        return left->f == right->f;
380     default:
381         FIXME("unhandled font property %d\n", propid);
382         return FALSE;
383     }
384 }
385 
init_textfont_prop_value(enum textfont_prop_id propid,textfont_prop_val * v)386 static inline void init_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *v)
387 {
388     switch (propid)
389     {
390     case FONT_ALLCAPS:
391     case FONT_ANIMATION:
392     case FONT_BACKCOLOR:
393     case FONT_BOLD:
394     case FONT_EMBOSS:
395     case FONT_FORECOLOR:
396     case FONT_HIDDEN:
397     case FONT_ENGRAVE:
398     case FONT_ITALIC:
399     case FONT_KERNING:
400     case FONT_LANGID:
401     case FONT_OUTLINE:
402     case FONT_PROTECTED:
403     case FONT_SHADOW:
404     case FONT_SMALLCAPS:
405     case FONT_STRIKETHROUGH:
406     case FONT_SUBSCRIPT:
407     case FONT_SUPERSCRIPT:
408     case FONT_UNDERLINE:
409     case FONT_WEIGHT:
410         v->l = tomUndefined;
411         return;
412     case FONT_NAME:
413         v->str = NULL;
414         return;
415     case FONT_POSITION:
416     case FONT_SIZE:
417     case FONT_SPACING:
418         v->f = tomUndefined;
419         return;
420     default:
421         FIXME("unhandled font property %d\n", propid);
422         v->l = tomUndefined;
423         return;
424     }
425 }
426 
twips_to_points(LONG value)427 static inline FLOAT twips_to_points(LONG value)
428 {
429     return value * 72.0 / 1440;
430 }
431 
points_to_twips(FLOAT value)432 static inline FLOAT points_to_twips(FLOAT value)
433 {
434     return value * 1440 / 72.0;
435 }
436 
get_textfont_prop_for_pos(const IRichEditOleImpl * reole,int pos,enum textfont_prop_id propid,textfont_prop_val * value)437 static HRESULT get_textfont_prop_for_pos(const IRichEditOleImpl *reole, int pos, enum textfont_prop_id propid,
438     textfont_prop_val *value)
439 {
440     ME_Cursor from, to;
441     CHARFORMAT2W fmt;
442 
443     memset(&fmt, 0, sizeof(fmt));
444     fmt.cbSize = sizeof(fmt);
445     fmt.dwMask = textfont_prop_masks[propid][0];
446 
447     ME_CursorFromCharOfs(reole->editor, pos, &from);
448     to = from;
449     ME_MoveCursorChars(reole->editor, &to, 1, FALSE);
450     ME_GetCharFormat(reole->editor, &from, &to, &fmt);
451 
452     switch (propid)
453     {
454     case FONT_ALLCAPS:
455     case FONT_BOLD:
456     case FONT_EMBOSS:
457     case FONT_HIDDEN:
458     case FONT_ENGRAVE:
459     case FONT_ITALIC:
460     case FONT_OUTLINE:
461     case FONT_PROTECTED:
462     case FONT_SHADOW:
463     case FONT_SMALLCAPS:
464     case FONT_STRIKETHROUGH:
465     case FONT_SUBSCRIPT:
466     case FONT_SUPERSCRIPT:
467     case FONT_UNDERLINE:
468         value->l = fmt.dwEffects & textfont_prop_masks[propid][1] ? tomTrue : tomFalse;
469         break;
470     case FONT_ANIMATION:
471         value->l = fmt.bAnimation;
472         break;
473     case FONT_BACKCOLOR:
474         value->l = fmt.dwEffects & CFE_AUTOBACKCOLOR ? GetSysColor(COLOR_WINDOW) : fmt.crBackColor;
475         break;
476     case FONT_FORECOLOR:
477         value->l = fmt.dwEffects & CFE_AUTOCOLOR ? GetSysColor(COLOR_WINDOWTEXT) : fmt.crTextColor;
478         break;
479     case FONT_KERNING:
480         value->f = twips_to_points(fmt.wKerning);
481         break;
482     case FONT_LANGID:
483         value->l = fmt.lcid;
484         break;
485     case FONT_NAME:
486         /* this case is used exclusively by GetName() */
487         value->str = SysAllocString(fmt.szFaceName);
488         if (!value->str)
489             return E_OUTOFMEMORY;
490         break;
491     case FONT_POSITION:
492         value->f = twips_to_points(fmt.yOffset);
493         break;
494     case FONT_SIZE:
495         value->f = twips_to_points(fmt.yHeight);
496         break;
497     case FONT_SPACING:
498         value->f = fmt.sSpacing;
499         break;
500     case FONT_WEIGHT:
501         value->l = fmt.wWeight;
502         break;
503     default:
504         FIXME("unhandled font property %d\n", propid);
505         return E_FAIL;
506     }
507 
508     return S_OK;
509 }
510 
get_range_reole(ITextRange * range)511 static inline const IRichEditOleImpl *get_range_reole(ITextRange *range)
512 {
513     IRichEditOleImpl *reole = NULL;
514     ITextRange_QueryInterface(range, &IID_Igetrichole, (void**)&reole);
515     return reole;
516 }
517 
textrange_set_font(ITextRange * range,ITextFont * font)518 static void textrange_set_font(ITextRange *range, ITextFont *font)
519 {
520     CHARFORMAT2W fmt;
521     HRESULT hr;
522     LONG value;
523     BSTR str;
524     FLOAT f;
525 
526 #define CHARFORMAT_SET_B_FIELD(mask, value) \
527     if (hr == S_OK && value != tomUndefined) { \
528         fmt.dwMask |= CFM_##mask; \
529         if (value == tomTrue) fmt.dwEffects |= CFE_##mask; \
530     } \
531 
532     /* fill format data from font */
533     memset(&fmt, 0, sizeof(fmt));
534     fmt.cbSize = sizeof(fmt);
535 
536     value = tomUndefined;
537     hr = ITextFont_GetAllCaps(font, &value);
538     CHARFORMAT_SET_B_FIELD(ALLCAPS, value);
539 
540     value = tomUndefined;
541     hr = ITextFont_GetBold(font, &value);
542     CHARFORMAT_SET_B_FIELD(BOLD, value);
543 
544     value = tomUndefined;
545     hr = ITextFont_GetEmboss(font, &value);
546     CHARFORMAT_SET_B_FIELD(EMBOSS, value);
547 
548     value = tomUndefined;
549     hr = ITextFont_GetHidden(font, &value);
550     CHARFORMAT_SET_B_FIELD(HIDDEN, value);
551 
552     value = tomUndefined;
553     hr = ITextFont_GetEngrave(font, &value);
554     CHARFORMAT_SET_B_FIELD(IMPRINT, value);
555 
556     value = tomUndefined;
557     hr = ITextFont_GetItalic(font, &value);
558     CHARFORMAT_SET_B_FIELD(ITALIC, value);
559 
560     value = tomUndefined;
561     hr = ITextFont_GetOutline(font, &value);
562     CHARFORMAT_SET_B_FIELD(OUTLINE, value);
563 
564     value = tomUndefined;
565     hr = ITextFont_GetProtected(font, &value);
566     CHARFORMAT_SET_B_FIELD(PROTECTED, value);
567 
568     value = tomUndefined;
569     hr = ITextFont_GetShadow(font, &value);
570     CHARFORMAT_SET_B_FIELD(SHADOW, value);
571 
572     value = tomUndefined;
573     hr = ITextFont_GetSmallCaps(font, &value);
574     CHARFORMAT_SET_B_FIELD(SMALLCAPS, value);
575 
576     value = tomUndefined;
577     hr = ITextFont_GetStrikeThrough(font, &value);
578     CHARFORMAT_SET_B_FIELD(STRIKEOUT, value);
579 
580     value = tomUndefined;
581     hr = ITextFont_GetSubscript(font, &value);
582     CHARFORMAT_SET_B_FIELD(SUBSCRIPT, value);
583 
584     value = tomUndefined;
585     hr = ITextFont_GetSuperscript(font, &value);
586     CHARFORMAT_SET_B_FIELD(SUPERSCRIPT, value);
587 
588     value = tomUndefined;
589     hr = ITextFont_GetUnderline(font, &value);
590     CHARFORMAT_SET_B_FIELD(UNDERLINE, value);
591 
592 #undef CHARFORMAT_SET_B_FIELD
593 
594     value = tomUndefined;
595     hr = ITextFont_GetAnimation(font, &value);
596     if (hr == S_OK && value != tomUndefined) {
597         fmt.dwMask |= CFM_ANIMATION;
598         fmt.bAnimation = value;
599     }
600 
601     value = tomUndefined;
602     hr = ITextFont_GetBackColor(font, &value);
603     if (hr == S_OK && value != tomUndefined) {
604         fmt.dwMask |= CFM_BACKCOLOR;
605         if (value == tomAutoColor)
606             fmt.dwEffects |= CFE_AUTOBACKCOLOR;
607         else
608             fmt.crBackColor = value;
609     }
610 
611     value = tomUndefined;
612     hr = ITextFont_GetForeColor(font, &value);
613     if (hr == S_OK && value != tomUndefined) {
614         fmt.dwMask |= CFM_COLOR;
615         if (value == tomAutoColor)
616             fmt.dwEffects |= CFE_AUTOCOLOR;
617         else
618             fmt.crTextColor = value;
619     }
620 
621     value = tomUndefined;
622     hr = ITextFont_GetKerning(font, &f);
623     if (hr == S_OK && f != tomUndefined) {
624         fmt.dwMask |= CFM_KERNING;
625         fmt.wKerning = points_to_twips(f);
626     }
627 
628     value = tomUndefined;
629     hr = ITextFont_GetLanguageID(font, &value);
630     if (hr == S_OK && value != tomUndefined) {
631         fmt.dwMask |= CFM_LCID;
632         fmt.lcid = value;
633     }
634 
635     if (ITextFont_GetName(font, &str) == S_OK) {
636         fmt.dwMask |= CFM_FACE;
637         lstrcpynW(fmt.szFaceName, str, ARRAY_SIZE(fmt.szFaceName));
638         SysFreeString(str);
639     }
640 
641     hr = ITextFont_GetPosition(font, &f);
642     if (hr == S_OK && f != tomUndefined) {
643         fmt.dwMask |= CFM_OFFSET;
644         fmt.yOffset = points_to_twips(f);
645     }
646 
647     hr = ITextFont_GetSize(font, &f);
648     if (hr == S_OK && f != tomUndefined) {
649         fmt.dwMask |= CFM_SIZE;
650         fmt.yHeight = points_to_twips(f);
651     }
652 
653     hr = ITextFont_GetSpacing(font, &f);
654     if (hr == S_OK && f != tomUndefined) {
655         fmt.dwMask |= CFM_SPACING;
656         fmt.sSpacing = f;
657     }
658 
659     hr = ITextFont_GetWeight(font, &value);
660     if (hr == S_OK && value != tomUndefined) {
661         fmt.dwMask |= CFM_WEIGHT;
662         fmt.wWeight = value;
663     }
664 
665     if (fmt.dwMask) {
666         const IRichEditOleImpl *reole = get_range_reole(range);
667         ME_Cursor from, to;
668         LONG start, end;
669 
670         ITextRange_GetStart(range, &start);
671         ITextRange_GetEnd(range, &end);
672 
673         ME_CursorFromCharOfs(reole->editor, start, &from);
674         ME_CursorFromCharOfs(reole->editor, end, &to);
675         ME_SetCharFormat(reole->editor, &from, &to, &fmt);
676     }
677 }
678 
get_textfont_prop(const ITextFontImpl * font,enum textfont_prop_id propid,textfont_prop_val * value)679 static HRESULT get_textfont_prop(const ITextFontImpl *font, enum textfont_prop_id propid, textfont_prop_val *value)
680 {
681     const IRichEditOleImpl *reole;
682     textfont_prop_val v;
683     LONG start, end, i;
684     HRESULT hr;
685 
686     /* when font is not attached to any range use cached values */
687     if (!font->range || font->get_cache_enabled) {
688         *value = font->props[propid];
689         return S_OK;
690     }
691 
692     if (!(reole = get_range_reole(font->range)))
693         return CO_E_RELEASED;
694 
695     init_textfont_prop_value(propid, value);
696 
697     ITextRange_GetStart(font->range, &start);
698     ITextRange_GetEnd(font->range, &end);
699 
700     /* iterate trough a range to see if property value is consistent */
701     hr = get_textfont_prop_for_pos(reole, start, propid, &v);
702     if (FAILED(hr))
703         return hr;
704 
705     for (i = start + 1; i < end; i++) {
706         textfont_prop_val cur;
707 
708         hr = get_textfont_prop_for_pos(reole, i, propid, &cur);
709         if (FAILED(hr))
710             return hr;
711 
712         if (!is_equal_textfont_prop_value(propid, &v, &cur))
713             return S_OK;
714     }
715 
716     *value = v;
717     return S_OK;
718 }
719 
get_textfont_propf(const ITextFontImpl * font,enum textfont_prop_id propid,FLOAT * value)720 static HRESULT get_textfont_propf(const ITextFontImpl *font, enum textfont_prop_id propid, FLOAT *value)
721 {
722     textfont_prop_val v;
723     HRESULT hr;
724 
725     if (!value)
726         return E_INVALIDARG;
727 
728     hr = get_textfont_prop(font, propid, &v);
729     *value = v.f;
730     return hr;
731 }
732 
get_textfont_propl(const ITextFontImpl * font,enum textfont_prop_id propid,LONG * value)733 static HRESULT get_textfont_propl(const ITextFontImpl *font, enum textfont_prop_id propid, LONG *value)
734 {
735     textfont_prop_val v;
736     HRESULT hr;
737 
738     if (!value)
739         return E_INVALIDARG;
740 
741     hr = get_textfont_prop(font, propid, &v);
742     *value = v.l;
743     return hr;
744 }
745 
746 /* Value should already have a terminal value, for boolean properties it means tomToggle is not handled */
set_textfont_prop(ITextFontImpl * font,enum textfont_prop_id propid,const textfont_prop_val * value)747 static HRESULT set_textfont_prop(ITextFontImpl *font, enum textfont_prop_id propid, const textfont_prop_val *value)
748 {
749     const IRichEditOleImpl *reole;
750     ME_Cursor from, to;
751     CHARFORMAT2W fmt;
752     LONG start, end;
753 
754     /* when font is not attached to any range use cache */
755     if (!font->range || font->set_cache_enabled) {
756         if (propid == FONT_NAME) {
757             SysFreeString(font->props[propid].str);
758             font->props[propid].str = SysAllocString(value->str);
759         }
760         else
761             font->props[propid] = *value;
762         return S_OK;
763     }
764 
765     if (!(reole = get_range_reole(font->range)))
766         return CO_E_RELEASED;
767 
768     memset(&fmt, 0, sizeof(fmt));
769     fmt.cbSize = sizeof(fmt);
770     fmt.dwMask = textfont_prop_masks[propid][0];
771 
772     switch (propid)
773     {
774     case FONT_ALLCAPS:
775     case FONT_BOLD:
776     case FONT_EMBOSS:
777     case FONT_HIDDEN:
778     case FONT_ENGRAVE:
779     case FONT_ITALIC:
780     case FONT_OUTLINE:
781     case FONT_PROTECTED:
782     case FONT_SHADOW:
783     case FONT_SMALLCAPS:
784     case FONT_STRIKETHROUGH:
785     case FONT_SUBSCRIPT:
786     case FONT_SUPERSCRIPT:
787     case FONT_UNDERLINE:
788         fmt.dwEffects = value->l == tomTrue ? textfont_prop_masks[propid][1] : 0;
789         break;
790     case FONT_ANIMATION:
791         fmt.bAnimation = value->l;
792         break;
793     case FONT_BACKCOLOR:
794     case FONT_FORECOLOR:
795         if (value->l == tomAutoColor)
796             fmt.dwEffects = textfont_prop_masks[propid][1];
797         else if (propid == FONT_BACKCOLOR)
798             fmt.crBackColor = value->l;
799         else
800             fmt.crTextColor = value->l;
801         break;
802     case FONT_KERNING:
803         fmt.wKerning = value->f;
804         break;
805     case FONT_LANGID:
806         fmt.lcid = value->l;
807         break;
808     case FONT_POSITION:
809         fmt.yOffset = value->f;
810         break;
811     case FONT_SIZE:
812         fmt.yHeight = value->f;
813         break;
814     case FONT_SPACING:
815         fmt.sSpacing = value->f;
816         break;
817     case FONT_WEIGHT:
818         fmt.wWeight = value->l;
819         break;
820     case FONT_NAME:
821         lstrcpynW(fmt.szFaceName, value->str, ARRAY_SIZE(fmt.szFaceName));
822         break;
823     default:
824         FIXME("unhandled font property %d\n", propid);
825         return E_FAIL;
826     }
827 
828     ITextRange_GetStart(font->range, &start);
829     ITextRange_GetEnd(font->range, &end);
830 
831     ME_CursorFromCharOfs(reole->editor, start, &from);
832     ME_CursorFromCharOfs(reole->editor, end, &to);
833     ME_SetCharFormat(reole->editor, &from, &to, &fmt);
834 
835     return S_OK;
836 }
837 
set_textfont_propl(ITextFontImpl * font,enum textfont_prop_id propid,LONG value)838 static inline HRESULT set_textfont_propl(ITextFontImpl *font, enum textfont_prop_id propid, LONG value)
839 {
840     textfont_prop_val v;
841     v.l = value;
842     return set_textfont_prop(font, propid, &v);
843 }
844 
set_textfont_propf(ITextFontImpl * font,enum textfont_prop_id propid,FLOAT value)845 static inline HRESULT set_textfont_propf(ITextFontImpl *font, enum textfont_prop_id propid, FLOAT value)
846 {
847     textfont_prop_val v;
848     v.f = value;
849     return set_textfont_prop(font, propid, &v);
850 }
851 
set_textfont_propd(ITextFontImpl * font,enum textfont_prop_id propid,LONG value)852 static HRESULT set_textfont_propd(ITextFontImpl *font, enum textfont_prop_id propid, LONG value)
853 {
854     textfont_prop_val v;
855 
856     switch (value)
857     {
858     case tomUndefined:
859         return S_OK;
860     case tomToggle: {
861         LONG oldvalue;
862         get_textfont_propl(font, propid, &oldvalue);
863         if (oldvalue == tomFalse)
864             value = tomTrue;
865         else if (oldvalue == tomTrue)
866             value = tomFalse;
867         else
868             return E_INVALIDARG;
869         /* fallthrough */
870     }
871     case tomTrue:
872     case tomFalse:
873         v.l = value;
874         return set_textfont_prop(font, propid, &v);
875     default:
876         return E_INVALIDARG;
877     }
878 }
879 
textfont_getname_from_range(ITextRange * range,BSTR * ret)880 static HRESULT textfont_getname_from_range(ITextRange *range, BSTR *ret)
881 {
882     const IRichEditOleImpl *reole;
883     textfont_prop_val v;
884     HRESULT hr;
885     LONG start;
886 
887     if (!(reole = get_range_reole(range)))
888         return CO_E_RELEASED;
889 
890     ITextRange_GetStart(range, &start);
891     hr = get_textfont_prop_for_pos(reole, start, FONT_NAME, &v);
892     *ret = v.str;
893     return hr;
894 }
895 
textfont_cache_range_props(ITextFontImpl * font)896 static void textfont_cache_range_props(ITextFontImpl *font)
897 {
898     enum textfont_prop_id propid;
899     for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++) {
900         if (propid == FONT_NAME)
901             textfont_getname_from_range(font->range, &font->props[propid].str);
902         else
903             get_textfont_prop(font, propid, &font->props[propid]);
904     }
905 }
906 
textrange_expand(ITextRange * range,LONG unit,LONG * delta)907 static HRESULT textrange_expand(ITextRange *range, LONG unit, LONG *delta)
908 {
909     LONG expand_start, expand_end;
910 
911     switch (unit)
912     {
913     case tomStory:
914         expand_start = 0;
915         ITextRange_GetStoryLength(range, &expand_end);
916         break;
917     default:
918         FIXME("unit %d is not supported\n", unit);
919         return E_NOTIMPL;
920     }
921 
922     if (delta) {
923         LONG start, end;
924 
925         ITextRange_GetStart(range, &start);
926         ITextRange_GetEnd(range, &end);
927         *delta = expand_end - expand_start - (end - start);
928     }
929 
930     ITextRange_SetStart(range, expand_start);
931     ITextRange_SetEnd(range, expand_end);
932 
933     return S_OK;
934 }
935 
IRichEditOleImpl_inner_fnQueryInterface(IUnknown * iface,REFIID riid,LPVOID * ppvObj)936 static HRESULT WINAPI IRichEditOleImpl_inner_fnQueryInterface(IUnknown *iface, REFIID riid, LPVOID *ppvObj)
937 {
938     IRichEditOleImpl *This = impl_from_IUnknown(iface);
939 
940     TRACE("%p %s\n", This, debugstr_guid(riid));
941 
942     *ppvObj = NULL;
943     if (IsEqualGUID(riid, &IID_IUnknown))
944         *ppvObj = &This->IUnknown_inner;
945     else if (IsEqualGUID(riid, &IID_IRichEditOle))
946         *ppvObj = &This->IRichEditOle_iface;
947     else if (IsEqualGUID(riid, &IID_ITextDocument) || IsEqualGUID(riid, &IID_ITextDocument2Old))
948         *ppvObj = &This->ITextDocument2Old_iface;
949     if (*ppvObj)
950     {
951         IUnknown_AddRef((IUnknown *)*ppvObj);
952         return S_OK;
953     }
954 
955     if (IsEqualGUID(riid, &IID_ITextServices))
956     {
957         static int once;
958         if (!once++) FIXME("%p: unhandled interface IID_ITextServices\n", This);
959         return E_NOINTERFACE;
960     }
961 
962     FIXME("%p: unhandled interface %s\n", This, debugstr_guid(riid));
963 
964     return E_NOINTERFACE;
965 }
966 
IRichEditOleImpl_inner_fnAddRef(IUnknown * iface)967 static ULONG WINAPI IRichEditOleImpl_inner_fnAddRef(IUnknown *iface)
968 {
969     IRichEditOleImpl *This = impl_from_IUnknown(iface);
970     ULONG ref = InterlockedIncrement(&This->ref);
971 
972     TRACE("%p ref = %u\n", This, ref);
973 
974     return ref;
975 }
976 
IRichEditOleImpl_inner_fnRelease(IUnknown * iface)977 static ULONG WINAPI IRichEditOleImpl_inner_fnRelease(IUnknown *iface)
978 {
979     IRichEditOleImpl *This = impl_from_IUnknown(iface);
980     ULONG ref = InterlockedDecrement(&This->ref);
981 
982     TRACE ("%p ref=%u\n", This, ref);
983 
984     if (!ref)
985     {
986         IOleClientSiteImpl *clientsite;
987         ITextRangeImpl *txtRge;
988 
989         This->editor->reOle = NULL;
990         if (This->txtSel) {
991             This->txtSel->reOle = NULL;
992             ITextSelection_Release(&This->txtSel->ITextSelection_iface);
993         }
994 
995         LIST_FOR_EACH_ENTRY(txtRge, &This->rangelist, ITextRangeImpl, child.entry)
996             txtRge->child.reole = NULL;
997 
998         LIST_FOR_EACH_ENTRY(clientsite, &This->clientsites, IOleClientSiteImpl, child.entry)
999             clientsite->child.reole = NULL;
1000 
1001         heap_free(This);
1002     }
1003     return ref;
1004 }
1005 
1006 static const IUnknownVtbl reo_unk_vtbl =
1007 {
1008     IRichEditOleImpl_inner_fnQueryInterface,
1009     IRichEditOleImpl_inner_fnAddRef,
1010     IRichEditOleImpl_inner_fnRelease
1011 };
1012 
1013 static HRESULT WINAPI
IRichEditOle_fnQueryInterface(IRichEditOle * me,REFIID riid,LPVOID * ppvObj)1014 IRichEditOle_fnQueryInterface(IRichEditOle *me, REFIID riid, LPVOID *ppvObj)
1015 {
1016     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1017     return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj);
1018 }
1019 
1020 static ULONG WINAPI
IRichEditOle_fnAddRef(IRichEditOle * me)1021 IRichEditOle_fnAddRef(IRichEditOle *me)
1022 {
1023     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1024     return IUnknown_AddRef(This->outer_unk);
1025 }
1026 
1027 static ULONG WINAPI
IRichEditOle_fnRelease(IRichEditOle * me)1028 IRichEditOle_fnRelease(IRichEditOle *me)
1029 {
1030     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1031     return IUnknown_Release(This->outer_unk);
1032 }
1033 
1034 static HRESULT WINAPI
IRichEditOle_fnActivateAs(IRichEditOle * me,REFCLSID rclsid,REFCLSID rclsidAs)1035 IRichEditOle_fnActivateAs(IRichEditOle *me, REFCLSID rclsid, REFCLSID rclsidAs)
1036 {
1037     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1038     FIXME("stub %p\n",This);
1039     return E_NOTIMPL;
1040 }
1041 
1042 static HRESULT WINAPI
IRichEditOle_fnContextSensitiveHelp(IRichEditOle * me,BOOL fEnterMode)1043 IRichEditOle_fnContextSensitiveHelp(IRichEditOle *me, BOOL fEnterMode)
1044 {
1045     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1046     FIXME("stub %p\n",This);
1047     return E_NOTIMPL;
1048 }
1049 
1050 static HRESULT WINAPI
IRichEditOle_fnConvertObject(IRichEditOle * me,LONG iob,REFCLSID rclsidNew,LPCSTR lpstrUserTypeNew)1051 IRichEditOle_fnConvertObject(IRichEditOle *me, LONG iob,
1052                REFCLSID rclsidNew, LPCSTR lpstrUserTypeNew)
1053 {
1054     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1055     FIXME("stub %p\n",This);
1056     return E_NOTIMPL;
1057 }
1058 
impl_from_IOleClientSite(IOleClientSite * iface)1059 static inline IOleClientSiteImpl *impl_from_IOleClientSite(IOleClientSite *iface)
1060 {
1061     return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleClientSite_iface);
1062 }
1063 
1064 static HRESULT WINAPI
IOleClientSite_fnQueryInterface(IOleClientSite * me,REFIID riid,LPVOID * ppvObj)1065 IOleClientSite_fnQueryInterface(IOleClientSite *me, REFIID riid, LPVOID *ppvObj)
1066 {
1067     IOleClientSiteImpl *This = impl_from_IOleClientSite(me);
1068     TRACE("%p %s\n", me, debugstr_guid(riid) );
1069 
1070     *ppvObj = NULL;
1071     if (IsEqualGUID(riid, &IID_IUnknown) ||
1072         IsEqualGUID(riid, &IID_IOleClientSite))
1073         *ppvObj = me;
1074     else if (IsEqualGUID(riid, &IID_IOleWindow) ||
1075              IsEqualGUID(riid, &IID_IOleInPlaceSite))
1076         *ppvObj = &This->IOleInPlaceSite_iface;
1077     if (*ppvObj)
1078     {
1079         IOleClientSite_AddRef(me);
1080         return S_OK;
1081     }
1082     FIXME("%p: unhandled interface %s\n", me, debugstr_guid(riid) );
1083 
1084     return E_NOINTERFACE;
1085 }
1086 
IOleClientSite_fnAddRef(IOleClientSite * iface)1087 static ULONG WINAPI IOleClientSite_fnAddRef(IOleClientSite *iface)
1088 {
1089     IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1090     ULONG ref = InterlockedIncrement(&This->ref);
1091     TRACE("(%p)->(%u)\n", This, ref);
1092     return ref;
1093 }
1094 
IOleClientSite_fnRelease(IOleClientSite * iface)1095 static ULONG WINAPI IOleClientSite_fnRelease(IOleClientSite *iface)
1096 {
1097     IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1098     ULONG ref = InterlockedDecrement(&This->ref);
1099 
1100     TRACE("(%p)->(%u)\n", This, ref);
1101 
1102     if (ref == 0) {
1103         if (This->child.reole) {
1104             list_remove(&This->child.entry);
1105             This->child.reole = NULL;
1106         }
1107         heap_free(This);
1108     }
1109     return ref;
1110 }
1111 
IOleClientSite_fnSaveObject(IOleClientSite * iface)1112 static HRESULT WINAPI IOleClientSite_fnSaveObject(IOleClientSite *iface)
1113 {
1114     IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1115     if (!This->child.reole)
1116         return CO_E_RELEASED;
1117 
1118     FIXME("stub %p\n", iface);
1119     return E_NOTIMPL;
1120 }
1121 
IOleClientSite_fnGetMoniker(IOleClientSite * iface,DWORD dwAssign,DWORD dwWhichMoniker,IMoniker ** ppmk)1122 static HRESULT WINAPI IOleClientSite_fnGetMoniker(IOleClientSite *iface, DWORD dwAssign,
1123         DWORD dwWhichMoniker, IMoniker **ppmk)
1124 {
1125     IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1126     if (!This->child.reole)
1127         return CO_E_RELEASED;
1128 
1129     FIXME("stub %p\n", iface);
1130     return E_NOTIMPL;
1131 }
1132 
IOleClientSite_fnGetContainer(IOleClientSite * iface,IOleContainer ** ppContainer)1133 static HRESULT WINAPI IOleClientSite_fnGetContainer(IOleClientSite *iface,
1134         IOleContainer **ppContainer)
1135 {
1136     IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1137     if (!This->child.reole)
1138         return CO_E_RELEASED;
1139 
1140     FIXME("stub %p\n", iface);
1141     return E_NOTIMPL;
1142 }
1143 
IOleClientSite_fnShowObject(IOleClientSite * iface)1144 static HRESULT WINAPI IOleClientSite_fnShowObject(IOleClientSite *iface)
1145 {
1146     IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1147     if (!This->child.reole)
1148         return CO_E_RELEASED;
1149 
1150     FIXME("stub %p\n", iface);
1151     return E_NOTIMPL;
1152 }
1153 
IOleClientSite_fnOnShowWindow(IOleClientSite * iface,BOOL fShow)1154 static HRESULT WINAPI IOleClientSite_fnOnShowWindow(IOleClientSite *iface, BOOL fShow)
1155 {
1156     IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1157     if (!This->child.reole)
1158         return CO_E_RELEASED;
1159 
1160     FIXME("stub %p\n", iface);
1161     return E_NOTIMPL;
1162 }
1163 
IOleClientSite_fnRequestNewObjectLayout(IOleClientSite * iface)1164 static HRESULT WINAPI IOleClientSite_fnRequestNewObjectLayout(IOleClientSite *iface)
1165 {
1166     IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1167     if (!This->child.reole)
1168         return CO_E_RELEASED;
1169 
1170     FIXME("stub %p\n", iface);
1171     return E_NOTIMPL;
1172 }
1173 
1174 static const IOleClientSiteVtbl ocst = {
1175     IOleClientSite_fnQueryInterface,
1176     IOleClientSite_fnAddRef,
1177     IOleClientSite_fnRelease,
1178     IOleClientSite_fnSaveObject,
1179     IOleClientSite_fnGetMoniker,
1180     IOleClientSite_fnGetContainer,
1181     IOleClientSite_fnShowObject,
1182     IOleClientSite_fnOnShowWindow,
1183     IOleClientSite_fnRequestNewObjectLayout
1184 };
1185 
1186 /* IOleInPlaceSite interface */
IOleInPlaceSite_fnQueryInterface(IOleInPlaceSite * iface,REFIID riid,void ** ppvObj)1187 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnQueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppvObj)
1188 {
1189     IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1190     return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppvObj);
1191 }
1192 
IOleInPlaceSite_fnAddRef(IOleInPlaceSite * iface)1193 static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnAddRef(IOleInPlaceSite *iface)
1194 {
1195     IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1196     return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1197 }
1198 
IOleInPlaceSite_fnRelease(IOleInPlaceSite * iface)1199 static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnRelease(IOleInPlaceSite *iface)
1200 {
1201     IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1202     return IOleClientSite_Release(&This->IOleClientSite_iface);
1203 }
1204 
IOleInPlaceSite_fnGetWindow(IOleInPlaceSite * iface,HWND * phwnd)1205 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindow(IOleInPlaceSite *iface, HWND *phwnd)
1206 {
1207     IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1208 
1209     TRACE("(%p)->(%p)\n", This, phwnd);
1210 
1211     if (!This->child.reole)
1212         return CO_E_RELEASED;
1213 
1214     if (!phwnd)
1215         return E_INVALIDARG;
1216 
1217     *phwnd = This->child.reole->editor->hWnd;
1218     return S_OK;
1219 }
1220 
IOleInPlaceSite_fnContextSensitiveHelp(IOleInPlaceSite * iface,BOOL fEnterMode)1221 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode)
1222 {
1223     IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1224     FIXME("not implemented: (%p)->(%d)\n", This, fEnterMode);
1225     return E_NOTIMPL;
1226 }
1227 
IOleInPlaceSite_fnCanInPlaceActivate(IOleInPlaceSite * iface)1228 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnCanInPlaceActivate(IOleInPlaceSite *iface)
1229 {
1230     IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1231     FIXME("not implemented: (%p)\n", This);
1232     return E_NOTIMPL;
1233 }
1234 
IOleInPlaceSite_fnOnInPlaceActivate(IOleInPlaceSite * iface)1235 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceActivate(IOleInPlaceSite *iface)
1236 {
1237     IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1238     FIXME("not implemented: (%p)\n", This);
1239     return E_NOTIMPL;
1240 }
1241 
IOleInPlaceSite_fnOnUIActivate(IOleInPlaceSite * iface)1242 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIActivate(IOleInPlaceSite *iface)
1243 {
1244     IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1245     FIXME("not implemented: (%p)\n", This);
1246     return E_NOTIMPL;
1247 }
1248 
IOleInPlaceSite_fnGetWindowContext(IOleInPlaceSite * iface,IOleInPlaceFrame ** ppFrame,IOleInPlaceUIWindow ** ppDoc,LPRECT lprcPosRect,LPRECT lprcClipRect,LPOLEINPLACEFRAMEINFO lpFrameInfo)1249 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindowContext(IOleInPlaceSite *iface, IOleInPlaceFrame **ppFrame,
1250                                                                     IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
1251                                                                     LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
1252 {
1253     IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1254     FIXME("not implemented: (%p)->(%p %p %p %p %p)\n", This, ppFrame, ppDoc, lprcPosRect, lprcClipRect, lpFrameInfo);
1255     return E_NOTIMPL;
1256 }
1257 
IOleInPlaceSite_fnScroll(IOleInPlaceSite * iface,SIZE scrollExtent)1258 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnScroll(IOleInPlaceSite *iface, SIZE scrollExtent)
1259 {
1260     IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1261     FIXME("not implemented: (%p)\n", This);
1262     return E_NOTIMPL;
1263 }
1264 
IOleInPlaceSite_fnOnUIDeactivate(IOleInPlaceSite * iface,BOOL fUndoable)1265 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable)
1266 {
1267     IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1268     FIXME("not implemented: (%p)->(%d)\n", This, fUndoable);
1269     return E_NOTIMPL;
1270 }
1271 
IOleInPlaceSite_fnOnInPlaceDeactivate(IOleInPlaceSite * iface)1272 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceDeactivate(IOleInPlaceSite *iface)
1273 {
1274     IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1275     FIXME("not implemented: (%p)\n", This);
1276     return E_NOTIMPL;
1277 }
1278 
IOleInPlaceSite_fnDiscardUndoState(IOleInPlaceSite * iface)1279 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDiscardUndoState(IOleInPlaceSite *iface)
1280 {
1281     IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1282     FIXME("not implemented: (%p)\n", This);
1283     return E_NOTIMPL;
1284 }
1285 
IOleInPlaceSite_fnDeactivateAndUndo(IOleInPlaceSite * iface)1286 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDeactivateAndUndo(IOleInPlaceSite *iface)
1287 {
1288     IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1289     FIXME("not implemented: (%p)\n", This);
1290     return E_NOTIMPL;
1291 }
1292 
IOleInPlaceSite_fnOnPosRectChange(IOleInPlaceSite * iface,LPCRECT lprcPosRect)1293 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect)
1294 {
1295     IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1296     FIXME("not implemented: (%p)->(%p)\n", This, lprcPosRect);
1297     return E_NOTIMPL;
1298 }
1299 
1300 static const IOleInPlaceSiteVtbl olestvt =
1301 {
1302     IOleInPlaceSite_fnQueryInterface,
1303     IOleInPlaceSite_fnAddRef,
1304     IOleInPlaceSite_fnRelease,
1305     IOleInPlaceSite_fnGetWindow,
1306     IOleInPlaceSite_fnContextSensitiveHelp,
1307     IOleInPlaceSite_fnCanInPlaceActivate,
1308     IOleInPlaceSite_fnOnInPlaceActivate,
1309     IOleInPlaceSite_fnOnUIActivate,
1310     IOleInPlaceSite_fnGetWindowContext,
1311     IOleInPlaceSite_fnScroll,
1312     IOleInPlaceSite_fnOnUIDeactivate,
1313     IOleInPlaceSite_fnOnInPlaceDeactivate,
1314     IOleInPlaceSite_fnDiscardUndoState,
1315     IOleInPlaceSite_fnDeactivateAndUndo,
1316     IOleInPlaceSite_fnOnPosRectChange
1317 };
1318 
CreateOleClientSite(IRichEditOleImpl * reOle,IOleClientSite ** ret)1319 static HRESULT CreateOleClientSite(IRichEditOleImpl *reOle, IOleClientSite **ret)
1320 {
1321     IOleClientSiteImpl *clientSite = heap_alloc(sizeof *clientSite);
1322 
1323     if (!clientSite)
1324         return E_OUTOFMEMORY;
1325 
1326     clientSite->IOleClientSite_iface.lpVtbl = &ocst;
1327     clientSite->IOleInPlaceSite_iface.lpVtbl = &olestvt;
1328     clientSite->ref = 1;
1329     clientSite->child.reole = reOle;
1330     list_add_head(&reOle->clientsites, &clientSite->child.entry);
1331 
1332     *ret = &clientSite->IOleClientSite_iface;
1333     return S_OK;
1334 }
1335 
1336 static HRESULT WINAPI
IRichEditOle_fnGetClientSite(IRichEditOle * me,IOleClientSite ** clientsite)1337 IRichEditOle_fnGetClientSite(IRichEditOle *me, IOleClientSite **clientsite)
1338 {
1339     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1340 
1341     TRACE("(%p)->(%p)\n", This, clientsite);
1342 
1343     if (!clientsite)
1344         return E_INVALIDARG;
1345 
1346     return CreateOleClientSite(This, clientsite);
1347 }
1348 
1349 static HRESULT WINAPI
IRichEditOle_fnGetClipboardData(IRichEditOle * me,CHARRANGE * lpchrg,DWORD reco,LPDATAOBJECT * lplpdataobj)1350 IRichEditOle_fnGetClipboardData(IRichEditOle *me, CHARRANGE *lpchrg,
1351                DWORD reco, LPDATAOBJECT *lplpdataobj)
1352 {
1353     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1354     ME_Cursor start;
1355     int nChars;
1356 
1357     TRACE("(%p,%p,%d)\n",This, lpchrg, reco);
1358     if(!lplpdataobj)
1359         return E_INVALIDARG;
1360     if(!lpchrg) {
1361         int nFrom, nTo, nStartCur = ME_GetSelectionOfs(This->editor, &nFrom, &nTo);
1362         start = This->editor->pCursors[nStartCur];
1363         nChars = nTo - nFrom;
1364     } else {
1365         ME_CursorFromCharOfs(This->editor, lpchrg->cpMin, &start);
1366         nChars = lpchrg->cpMax - lpchrg->cpMin;
1367     }
1368     return ME_GetDataObject(This->editor, &start, nChars, lplpdataobj);
1369 }
1370 
IRichEditOle_fnGetLinkCount(IRichEditOle * me)1371 static LONG WINAPI IRichEditOle_fnGetLinkCount(IRichEditOle *me)
1372 {
1373     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1374     FIXME("stub %p\n",This);
1375     return E_NOTIMPL;
1376 }
1377 
1378 static HRESULT WINAPI
IRichEditOle_fnGetObject(IRichEditOle * me,LONG iob,REOBJECT * lpreobject,DWORD dwFlags)1379 IRichEditOle_fnGetObject(IRichEditOle *me, LONG iob,
1380                REOBJECT *lpreobject, DWORD dwFlags)
1381 {
1382     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1383     struct re_object *reobj = NULL;
1384     LONG count = 0;
1385 
1386     TRACE("(%p)->(%x, %p, %x)\n", This, iob, lpreobject, dwFlags);
1387 
1388     if (!lpreobject || !lpreobject->cbStruct)
1389         return E_INVALIDARG;
1390 
1391     if (iob == REO_IOB_USE_CP)
1392     {
1393         ME_Cursor cursor;
1394 
1395         TRACE("character offset: %d\n", lpreobject->cp);
1396         ME_CursorFromCharOfs(This->editor, lpreobject->cp, &cursor);
1397         if (!cursor.pRun->member.run.reobj)
1398             return E_INVALIDARG;
1399         else
1400             reobj = cursor.pRun->member.run.reobj;
1401     }
1402     else if (iob == REO_IOB_SELECTION)
1403     {
1404         ME_Cursor *from, *to;
1405 
1406         ME_GetSelection(This->editor, &from, &to);
1407         if (!from->pRun->member.run.reobj)
1408             return E_INVALIDARG;
1409         else
1410             reobj = from->pRun->member.run.reobj;
1411     }
1412     else
1413     {
1414         if (iob > IRichEditOle_GetObjectCount(me))
1415             return E_INVALIDARG;
1416         LIST_FOR_EACH_ENTRY(reobj, &This->editor->reobj_list, struct re_object, entry)
1417         {
1418             if (count == iob)
1419                 break;
1420             count++;
1421         }
1422     }
1423     ME_CopyReObject(lpreobject, &reobj->obj, dwFlags);
1424     return S_OK;
1425 }
1426 
1427 static LONG WINAPI
IRichEditOle_fnGetObjectCount(IRichEditOle * me)1428 IRichEditOle_fnGetObjectCount(IRichEditOle *me)
1429 {
1430     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1431     TRACE("(%p)\n",This);
1432     return list_count(&This->editor->reobj_list);
1433 }
1434 
1435 static HRESULT WINAPI
IRichEditOle_fnHandsOffStorage(IRichEditOle * me,LONG iob)1436 IRichEditOle_fnHandsOffStorage(IRichEditOle *me, LONG iob)
1437 {
1438     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1439     FIXME("stub %p\n",This);
1440     return E_NOTIMPL;
1441 }
1442 
1443 static HRESULT WINAPI
IRichEditOle_fnImportDataObject(IRichEditOle * me,LPDATAOBJECT lpdataobj,CLIPFORMAT cf,HGLOBAL hMetaPict)1444 IRichEditOle_fnImportDataObject(IRichEditOle *me, LPDATAOBJECT lpdataobj,
1445                CLIPFORMAT cf, HGLOBAL hMetaPict)
1446 {
1447     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1448     FIXME("stub %p\n",This);
1449     return E_NOTIMPL;
1450 }
1451 
1452 static HRESULT WINAPI
IRichEditOle_fnInPlaceDeactivate(IRichEditOle * me)1453 IRichEditOle_fnInPlaceDeactivate(IRichEditOle *me)
1454 {
1455     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1456     FIXME("stub %p\n",This);
1457     return E_NOTIMPL;
1458 }
1459 
1460 static HRESULT WINAPI
IRichEditOle_fnInsertObject(IRichEditOle * me,REOBJECT * reo)1461 IRichEditOle_fnInsertObject(IRichEditOle *me, REOBJECT *reo)
1462 {
1463     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1464 
1465     TRACE("(%p,%p)\n", This, reo);
1466 
1467     if (!reo)
1468         return E_INVALIDARG;
1469 
1470     if (reo->cbStruct < sizeof(*reo)) return STG_E_INVALIDPARAMETER;
1471 
1472     ME_InsertOLEFromCursor(This->editor, reo, 0);
1473     ME_CommitUndo(This->editor);
1474     ME_UpdateRepaint(This->editor, FALSE);
1475     return S_OK;
1476 }
1477 
IRichEditOle_fnSaveCompleted(IRichEditOle * me,LONG iob,LPSTORAGE lpstg)1478 static HRESULT WINAPI IRichEditOle_fnSaveCompleted(IRichEditOle *me, LONG iob,
1479                LPSTORAGE lpstg)
1480 {
1481     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1482     FIXME("stub %p\n",This);
1483     return E_NOTIMPL;
1484 }
1485 
1486 static HRESULT WINAPI
IRichEditOle_fnSetDvaspect(IRichEditOle * me,LONG iob,DWORD dvaspect)1487 IRichEditOle_fnSetDvaspect(IRichEditOle *me, LONG iob, DWORD dvaspect)
1488 {
1489     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1490     FIXME("stub %p\n",This);
1491     return E_NOTIMPL;
1492 }
1493 
IRichEditOle_fnSetHostNames(IRichEditOle * me,LPCSTR lpstrContainerApp,LPCSTR lpstrContainerObj)1494 static HRESULT WINAPI IRichEditOle_fnSetHostNames(IRichEditOle *me,
1495                LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj)
1496 {
1497     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1498     FIXME("stub %p %s %s\n",This, lpstrContainerApp, lpstrContainerObj);
1499     return E_NOTIMPL;
1500 }
1501 
1502 static HRESULT WINAPI
IRichEditOle_fnSetLinkAvailable(IRichEditOle * me,LONG iob,BOOL fAvailable)1503 IRichEditOle_fnSetLinkAvailable(IRichEditOle *me, LONG iob, BOOL fAvailable)
1504 {
1505     IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1506     FIXME("stub %p\n",This);
1507     return E_NOTIMPL;
1508 }
1509 
1510 static const IRichEditOleVtbl revt = {
1511     IRichEditOle_fnQueryInterface,
1512     IRichEditOle_fnAddRef,
1513     IRichEditOle_fnRelease,
1514     IRichEditOle_fnGetClientSite,
1515     IRichEditOle_fnGetObjectCount,
1516     IRichEditOle_fnGetLinkCount,
1517     IRichEditOle_fnGetObject,
1518     IRichEditOle_fnInsertObject,
1519     IRichEditOle_fnConvertObject,
1520     IRichEditOle_fnActivateAs,
1521     IRichEditOle_fnSetHostNames,
1522     IRichEditOle_fnSetLinkAvailable,
1523     IRichEditOle_fnSetDvaspect,
1524     IRichEditOle_fnHandsOffStorage,
1525     IRichEditOle_fnSaveCompleted,
1526     IRichEditOle_fnInPlaceDeactivate,
1527     IRichEditOle_fnContextSensitiveHelp,
1528     IRichEditOle_fnGetClipboardData,
1529     IRichEditOle_fnImportDataObject
1530 };
1531 
1532 /* ITextRange interface */
ITextRange_fnQueryInterface(ITextRange * me,REFIID riid,void ** ppvObj)1533 static HRESULT WINAPI ITextRange_fnQueryInterface(ITextRange *me, REFIID riid, void **ppvObj)
1534 {
1535     ITextRangeImpl *This = impl_from_ITextRange(me);
1536 
1537     *ppvObj = NULL;
1538     if (IsEqualGUID(riid, &IID_IUnknown)
1539         || IsEqualGUID(riid, &IID_IDispatch)
1540         || IsEqualGUID(riid, &IID_ITextRange))
1541     {
1542         *ppvObj = me;
1543         ITextRange_AddRef(me);
1544         return S_OK;
1545     }
1546     else if (IsEqualGUID(riid, &IID_Igetrichole))
1547     {
1548         *ppvObj = This->child.reole;
1549         return S_OK;
1550     }
1551 
1552     return E_NOINTERFACE;
1553 }
1554 
ITextRange_fnAddRef(ITextRange * me)1555 static ULONG WINAPI ITextRange_fnAddRef(ITextRange *me)
1556 {
1557     ITextRangeImpl *This = impl_from_ITextRange(me);
1558     return InterlockedIncrement(&This->ref);
1559 }
1560 
ITextRange_fnRelease(ITextRange * me)1561 static ULONG WINAPI ITextRange_fnRelease(ITextRange *me)
1562 {
1563     ITextRangeImpl *This = impl_from_ITextRange(me);
1564     ULONG ref = InterlockedDecrement(&This->ref);
1565 
1566     TRACE ("%p ref=%u\n", This, ref);
1567     if (ref == 0)
1568     {
1569         if (This->child.reole)
1570         {
1571             list_remove(&This->child.entry);
1572             This->child.reole = NULL;
1573         }
1574         heap_free(This);
1575     }
1576     return ref;
1577 }
1578 
ITextRange_fnGetTypeInfoCount(ITextRange * me,UINT * pctinfo)1579 static HRESULT WINAPI ITextRange_fnGetTypeInfoCount(ITextRange *me, UINT *pctinfo)
1580 {
1581     ITextRangeImpl *This = impl_from_ITextRange(me);
1582     TRACE("(%p)->(%p)\n", This, pctinfo);
1583     *pctinfo = 1;
1584     return S_OK;
1585 }
1586 
ITextRange_fnGetTypeInfo(ITextRange * me,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)1587 static HRESULT WINAPI ITextRange_fnGetTypeInfo(ITextRange *me, UINT iTInfo, LCID lcid,
1588                                                ITypeInfo **ppTInfo)
1589 {
1590     ITextRangeImpl *This = impl_from_ITextRange(me);
1591     HRESULT hr;
1592 
1593     TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
1594 
1595     hr = get_typeinfo(ITextRange_tid, ppTInfo);
1596     if (SUCCEEDED(hr))
1597         ITypeInfo_AddRef(*ppTInfo);
1598     return hr;
1599 }
1600 
ITextRange_fnGetIDsOfNames(ITextRange * me,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)1601 static HRESULT WINAPI ITextRange_fnGetIDsOfNames(ITextRange *me, REFIID riid, LPOLESTR *rgszNames,
1602                                                  UINT cNames, LCID lcid, DISPID *rgDispId)
1603 {
1604     ITextRangeImpl *This = impl_from_ITextRange(me);
1605     ITypeInfo *ti;
1606     HRESULT hr;
1607 
1608     TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
1609             rgDispId);
1610 
1611     hr = get_typeinfo(ITextRange_tid, &ti);
1612     if (SUCCEEDED(hr))
1613         hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
1614     return hr;
1615 }
1616 
ITextRange_fnInvoke(ITextRange * me,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)1617 static HRESULT WINAPI ITextRange_fnInvoke(ITextRange *me, DISPID dispIdMember, REFIID riid,
1618                                           LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1619                                           VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
1620                                           UINT *puArgErr)
1621 {
1622     ITextRangeImpl *This = impl_from_ITextRange(me);
1623     ITypeInfo *ti;
1624     HRESULT hr;
1625 
1626     TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
1627             lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1628 
1629     hr = get_typeinfo(ITextRange_tid, &ti);
1630     if (SUCCEEDED(hr))
1631         hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1632     return hr;
1633 }
1634 
ITextRange_fnGetText(ITextRange * me,BSTR * str)1635 static HRESULT WINAPI ITextRange_fnGetText(ITextRange *me, BSTR *str)
1636 {
1637     ITextRangeImpl *This = impl_from_ITextRange(me);
1638     ME_TextEditor *editor;
1639     ME_Cursor start, end;
1640     int length;
1641     BOOL bEOP;
1642 
1643     TRACE("(%p)->(%p)\n", This, str);
1644 
1645     if (!This->child.reole)
1646         return CO_E_RELEASED;
1647 
1648     if (!str)
1649         return E_INVALIDARG;
1650 
1651     /* return early for degenerate range */
1652     if (This->start == This->end) {
1653         *str = NULL;
1654         return S_OK;
1655     }
1656 
1657     editor = This->child.reole->editor;
1658     ME_CursorFromCharOfs(editor, This->start, &start);
1659     ME_CursorFromCharOfs(editor, This->end, &end);
1660 
1661     length = This->end - This->start;
1662     *str = SysAllocStringLen(NULL, length);
1663     if (!*str)
1664         return E_OUTOFMEMORY;
1665 
1666     bEOP = (end.pRun->next->type == diTextEnd && This->end > ME_GetTextLength(editor));
1667     ME_GetTextW(editor, *str, length, &start, length, FALSE, bEOP);
1668     return S_OK;
1669 }
1670 
ITextRange_fnSetText(ITextRange * me,BSTR str)1671 static HRESULT WINAPI ITextRange_fnSetText(ITextRange *me, BSTR str)
1672 {
1673     ITextRangeImpl *This = impl_from_ITextRange(me);
1674     ME_TextEditor *editor;
1675     ME_Cursor cursor;
1676     ME_Style *style;
1677     int len;
1678 
1679     TRACE("(%p)->(%s)\n", This, debugstr_w(str));
1680 
1681     if (!This->child.reole)
1682         return CO_E_RELEASED;
1683 
1684     editor = This->child.reole->editor;
1685 
1686     /* delete only where's something to delete */
1687     if (This->start != This->end) {
1688         ME_CursorFromCharOfs(editor, This->start, &cursor);
1689         ME_InternalDeleteText(editor, &cursor, This->end - This->start, FALSE);
1690     }
1691 
1692     if (!str || !*str) {
1693         /* will update this range as well */
1694         textranges_update_ranges(This->child.reole, This->start, This->end, RANGE_UPDATE_DELETE);
1695         return S_OK;
1696     }
1697 
1698     /* it's safer not to rely on stored BSTR length */
1699     len = lstrlenW(str);
1700     cursor = editor->pCursors[0];
1701     ME_CursorFromCharOfs(editor, This->start, &editor->pCursors[0]);
1702     style = ME_GetInsertStyle(editor, 0);
1703     ME_InsertTextFromCursor(editor, 0, str, len, style);
1704     ME_ReleaseStyle(style);
1705     editor->pCursors[0] = cursor;
1706 
1707     if (len < This->end - This->start)
1708         textranges_update_ranges(This->child.reole, This->start + len, This->end, RANGE_UPDATE_DELETE);
1709     else
1710         This->end = len - This->start;
1711 
1712     return S_OK;
1713 }
1714 
range_GetChar(ME_TextEditor * editor,ME_Cursor * cursor,LONG * pch)1715 static HRESULT range_GetChar(ME_TextEditor *editor, ME_Cursor *cursor, LONG *pch)
1716 {
1717     WCHAR wch[2];
1718 
1719     ME_GetTextW(editor, wch, 1, cursor, 1, FALSE, cursor->pRun->next->type == diTextEnd);
1720     *pch = wch[0];
1721 
1722     return S_OK;
1723 }
1724 
ITextRange_fnGetChar(ITextRange * me,LONG * pch)1725 static HRESULT WINAPI ITextRange_fnGetChar(ITextRange *me, LONG *pch)
1726 {
1727     ITextRangeImpl *This = impl_from_ITextRange(me);
1728     ME_TextEditor *editor;
1729     ME_Cursor cursor;
1730 
1731     TRACE("(%p)->(%p)\n", This, pch);
1732 
1733     if (!This->child.reole)
1734         return CO_E_RELEASED;
1735 
1736     if (!pch)
1737         return E_INVALIDARG;
1738 
1739     editor = This->child.reole->editor;
1740     ME_CursorFromCharOfs(editor, This->start, &cursor);
1741     return range_GetChar(editor, &cursor, pch);
1742 }
1743 
ITextRange_fnSetChar(ITextRange * me,LONG ch)1744 static HRESULT WINAPI ITextRange_fnSetChar(ITextRange *me, LONG ch)
1745 {
1746     ITextRangeImpl *This = impl_from_ITextRange(me);
1747 
1748     FIXME("(%p)->(%x): stub\n", This, ch);
1749 
1750     if (!This->child.reole)
1751         return CO_E_RELEASED;
1752 
1753     return E_NOTIMPL;
1754 }
1755 
1756 static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, ITextRange** ppRange);
1757 
ITextRange_fnGetDuplicate(ITextRange * me,ITextRange ** ppRange)1758 static HRESULT WINAPI ITextRange_fnGetDuplicate(ITextRange *me, ITextRange **ppRange)
1759 {
1760     ITextRangeImpl *This = impl_from_ITextRange(me);
1761 
1762     TRACE("(%p)->(%p)\n", This, ppRange);
1763 
1764     if (!This->child.reole)
1765         return CO_E_RELEASED;
1766 
1767     if (!ppRange)
1768         return E_INVALIDARG;
1769 
1770     return CreateITextRange(This->child.reole, This->start, This->end, ppRange);
1771 }
1772 
ITextRange_fnGetFormattedText(ITextRange * me,ITextRange ** range)1773 static HRESULT WINAPI ITextRange_fnGetFormattedText(ITextRange *me, ITextRange **range)
1774 {
1775     ITextRangeImpl *This = impl_from_ITextRange(me);
1776 
1777     FIXME("(%p)->(%p): stub\n", This, range);
1778 
1779     if (!This->child.reole)
1780         return CO_E_RELEASED;
1781 
1782     return E_NOTIMPL;
1783 }
1784 
ITextRange_fnSetFormattedText(ITextRange * me,ITextRange * range)1785 static HRESULT WINAPI ITextRange_fnSetFormattedText(ITextRange *me, ITextRange *range)
1786 {
1787     ITextRangeImpl *This = impl_from_ITextRange(me);
1788 
1789     FIXME("(%p)->(%p): stub\n", This, range);
1790 
1791     if (!This->child.reole)
1792         return CO_E_RELEASED;
1793 
1794     return E_NOTIMPL;
1795 }
1796 
ITextRange_fnGetStart(ITextRange * me,LONG * start)1797 static HRESULT WINAPI ITextRange_fnGetStart(ITextRange *me, LONG *start)
1798 {
1799     ITextRangeImpl *This = impl_from_ITextRange(me);
1800 
1801     TRACE("(%p)->(%p)\n", This, start);
1802 
1803     if (!This->child.reole)
1804         return CO_E_RELEASED;
1805 
1806     if (!start)
1807         return E_INVALIDARG;
1808 
1809     *start = This->start;
1810     return S_OK;
1811 }
1812 
textrange_setstart(const IRichEditOleImpl * reole,LONG value,LONG * start,LONG * end)1813 static HRESULT textrange_setstart(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end)
1814 {
1815     int len;
1816 
1817     if (value < 0)
1818         value = 0;
1819 
1820     if (value == *start)
1821         return S_FALSE;
1822 
1823     if (value <= *end) {
1824         *start = value;
1825         return S_OK;
1826     }
1827 
1828     len = ME_GetTextLength(reole->editor);
1829     *start = *end = value > len ? len : value;
1830     return S_OK;
1831 }
1832 
ITextRange_fnSetStart(ITextRange * me,LONG value)1833 static HRESULT WINAPI ITextRange_fnSetStart(ITextRange *me, LONG value)
1834 {
1835     ITextRangeImpl *This = impl_from_ITextRange(me);
1836 
1837     TRACE("(%p)->(%d)\n", This, value);
1838 
1839     if (!This->child.reole)
1840         return CO_E_RELEASED;
1841 
1842     return textrange_setstart(This->child.reole, value, &This->start, &This->end);
1843 }
1844 
ITextRange_fnGetEnd(ITextRange * me,LONG * end)1845 static HRESULT WINAPI ITextRange_fnGetEnd(ITextRange *me, LONG *end)
1846 {
1847     ITextRangeImpl *This = impl_from_ITextRange(me);
1848 
1849     TRACE("(%p)->(%p)\n", This, end);
1850 
1851     if (!This->child.reole)
1852         return CO_E_RELEASED;
1853 
1854     if (!end)
1855         return E_INVALIDARG;
1856 
1857     *end = This->end;
1858     return S_OK;
1859 }
1860 
textrange_setend(const IRichEditOleImpl * reole,LONG value,LONG * start,LONG * end)1861 static HRESULT textrange_setend(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end)
1862 {
1863     int len;
1864 
1865     if (value == *end)
1866         return S_FALSE;
1867 
1868     if (value < *start) {
1869         *start = *end = max(0, value);
1870         return S_OK;
1871     }
1872 
1873     len = ME_GetTextLength(reole->editor);
1874     *end = value > len ? len + 1 : value;
1875     return S_OK;
1876 }
1877 
ITextRange_fnSetEnd(ITextRange * me,LONG value)1878 static HRESULT WINAPI ITextRange_fnSetEnd(ITextRange *me, LONG value)
1879 {
1880     ITextRangeImpl *This = impl_from_ITextRange(me);
1881 
1882     TRACE("(%p)->(%d)\n", This, value);
1883 
1884     if (!This->child.reole)
1885         return CO_E_RELEASED;
1886 
1887     return textrange_setend(This->child.reole, value, &This->start, &This->end);
1888 }
1889 
ITextRange_fnGetFont(ITextRange * me,ITextFont ** font)1890 static HRESULT WINAPI ITextRange_fnGetFont(ITextRange *me, ITextFont **font)
1891 {
1892     ITextRangeImpl *This = impl_from_ITextRange(me);
1893 
1894     TRACE("(%p)->(%p)\n", This, font);
1895 
1896     if (!This->child.reole)
1897         return CO_E_RELEASED;
1898 
1899     if (!font)
1900         return E_INVALIDARG;
1901 
1902     return create_textfont(me, NULL, font);
1903 }
1904 
ITextRange_fnSetFont(ITextRange * me,ITextFont * font)1905 static HRESULT WINAPI ITextRange_fnSetFont(ITextRange *me, ITextFont *font)
1906 {
1907     ITextRangeImpl *This = impl_from_ITextRange(me);
1908 
1909     TRACE("(%p)->(%p)\n", This, font);
1910 
1911     if (!font)
1912         return E_INVALIDARG;
1913 
1914     if (!This->child.reole)
1915         return CO_E_RELEASED;
1916 
1917     textrange_set_font(me, font);
1918     return S_OK;
1919 }
1920 
ITextRange_fnGetPara(ITextRange * me,ITextPara ** para)1921 static HRESULT WINAPI ITextRange_fnGetPara(ITextRange *me, ITextPara **para)
1922 {
1923     ITextRangeImpl *This = impl_from_ITextRange(me);
1924 
1925     TRACE("(%p)->(%p)\n", This, para);
1926 
1927     if (!This->child.reole)
1928         return CO_E_RELEASED;
1929 
1930     if (!para)
1931         return E_INVALIDARG;
1932 
1933     return create_textpara(me, para);
1934 }
1935 
ITextRange_fnSetPara(ITextRange * me,ITextPara * para)1936 static HRESULT WINAPI ITextRange_fnSetPara(ITextRange *me, ITextPara *para)
1937 {
1938     ITextRangeImpl *This = impl_from_ITextRange(me);
1939 
1940     FIXME("(%p)->(%p): stub\n", This, para);
1941 
1942     if (!This->child.reole)
1943         return CO_E_RELEASED;
1944 
1945     return E_NOTIMPL;
1946 }
1947 
ITextRange_fnGetStoryLength(ITextRange * me,LONG * length)1948 static HRESULT WINAPI ITextRange_fnGetStoryLength(ITextRange *me, LONG *length)
1949 {
1950     ITextRangeImpl *This = impl_from_ITextRange(me);
1951 
1952     TRACE("(%p)->(%p)\n", This, length);
1953 
1954     if (!This->child.reole)
1955         return CO_E_RELEASED;
1956 
1957     return textrange_get_storylength(This->child.reole->editor, length);
1958 }
1959 
ITextRange_fnGetStoryType(ITextRange * me,LONG * value)1960 static HRESULT WINAPI ITextRange_fnGetStoryType(ITextRange *me, LONG *value)
1961 {
1962     ITextRangeImpl *This = impl_from_ITextRange(me);
1963 
1964     TRACE("(%p)->(%p)\n", This, value);
1965 
1966     if (!This->child.reole)
1967         return CO_E_RELEASED;
1968 
1969     if (!value)
1970         return E_INVALIDARG;
1971 
1972     *value = tomUnknownStory;
1973     return S_OK;
1974 }
1975 
range_Collapse(LONG bStart,LONG * start,LONG * end)1976 static HRESULT range_Collapse(LONG bStart, LONG *start, LONG *end)
1977 {
1978   if (*end == *start)
1979       return S_FALSE;
1980 
1981   if (bStart == tomEnd)
1982       *start = *end;
1983   else
1984       *end = *start;
1985   return S_OK;
1986 }
1987 
ITextRange_fnCollapse(ITextRange * me,LONG bStart)1988 static HRESULT WINAPI ITextRange_fnCollapse(ITextRange *me, LONG bStart)
1989 {
1990     ITextRangeImpl *This = impl_from_ITextRange(me);
1991 
1992     TRACE("(%p)->(%d)\n", This, bStart);
1993 
1994     if (!This->child.reole)
1995         return CO_E_RELEASED;
1996 
1997     return range_Collapse(bStart, &This->start, &This->end);
1998 }
1999 
ITextRange_fnExpand(ITextRange * me,LONG unit,LONG * delta)2000 static HRESULT WINAPI ITextRange_fnExpand(ITextRange *me, LONG unit, LONG *delta)
2001 {
2002     ITextRangeImpl *This = impl_from_ITextRange(me);
2003 
2004     TRACE("(%p)->(%d %p)\n", This, unit, delta);
2005 
2006     if (!This->child.reole)
2007         return CO_E_RELEASED;
2008 
2009     return textrange_expand(me, unit, delta);
2010 }
2011 
ITextRange_fnGetIndex(ITextRange * me,LONG unit,LONG * index)2012 static HRESULT WINAPI ITextRange_fnGetIndex(ITextRange *me, LONG unit, LONG *index)
2013 {
2014     ITextRangeImpl *This = impl_from_ITextRange(me);
2015 
2016     FIXME("(%p)->(%d %p): stub\n", This, unit, index);
2017 
2018     if (!This->child.reole)
2019         return CO_E_RELEASED;
2020 
2021     return E_NOTIMPL;
2022 }
2023 
ITextRange_fnSetIndex(ITextRange * me,LONG unit,LONG index,LONG extend)2024 static HRESULT WINAPI ITextRange_fnSetIndex(ITextRange *me, LONG unit, LONG index,
2025                                             LONG extend)
2026 {
2027     ITextRangeImpl *This = impl_from_ITextRange(me);
2028 
2029     FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend);
2030 
2031     if (!This->child.reole)
2032         return CO_E_RELEASED;
2033 
2034     return E_NOTIMPL;
2035 }
2036 
cp2range(ME_TextEditor * editor,LONG * cp1,LONG * cp2)2037 static void cp2range(ME_TextEditor *editor, LONG *cp1, LONG *cp2)
2038 {
2039     int len = ME_GetTextLength(editor) + 1;
2040 
2041     *cp1 = max(*cp1, 0);
2042     *cp2 = max(*cp2, 0);
2043     *cp1 = min(*cp1, len);
2044     *cp2 = min(*cp2, len);
2045     if (*cp1 > *cp2)
2046     {
2047         int tmp = *cp1;
2048         *cp1 = *cp2;
2049         *cp2 = tmp;
2050     }
2051     if (*cp1 == len)
2052         *cp1 = *cp2 = len - 1;
2053 }
2054 
ITextRange_fnSetRange(ITextRange * me,LONG anchor,LONG active)2055 static HRESULT WINAPI ITextRange_fnSetRange(ITextRange *me, LONG anchor, LONG active)
2056 {
2057     ITextRangeImpl *This = impl_from_ITextRange(me);
2058 
2059     FIXME("(%p)->(%d %d): stub\n", This, anchor, active);
2060 
2061     if (!This->child.reole)
2062         return CO_E_RELEASED;
2063 
2064     cp2range(This->child.reole->editor, &anchor, &active);
2065     if (anchor == This->start && active == This->end)
2066         return S_FALSE;
2067 
2068     This->start = anchor;
2069     This->end = active;
2070     return S_OK;
2071 }
2072 
textrange_inrange(LONG start,LONG end,ITextRange * range,LONG * ret)2073 static HRESULT textrange_inrange(LONG start, LONG end, ITextRange *range, LONG *ret)
2074 {
2075     LONG from, to, v;
2076 
2077     if (!ret)
2078         ret = &v;
2079 
2080     if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
2081         *ret = tomFalse;
2082     }
2083     else
2084         *ret = (start >= from && end <= to) ? tomTrue : tomFalse;
2085     return *ret == tomTrue ? S_OK : S_FALSE;
2086 }
2087 
ITextRange_fnInRange(ITextRange * me,ITextRange * range,LONG * ret)2088 static HRESULT WINAPI ITextRange_fnInRange(ITextRange *me, ITextRange *range, LONG *ret)
2089 {
2090     ITextRangeImpl *This = impl_from_ITextRange(me);
2091 
2092     TRACE("(%p)->(%p %p)\n", This, range, ret);
2093 
2094     if (ret)
2095         *ret = tomFalse;
2096 
2097     if (!This->child.reole)
2098         return CO_E_RELEASED;
2099 
2100     if (!range)
2101         return S_FALSE;
2102 
2103     return textrange_inrange(This->start, This->end, range, ret);
2104 }
2105 
ITextRange_fnInStory(ITextRange * me,ITextRange * pRange,LONG * ret)2106 static HRESULT WINAPI ITextRange_fnInStory(ITextRange *me, ITextRange *pRange, LONG *ret)
2107 {
2108     ITextRangeImpl *This = impl_from_ITextRange(me);
2109 
2110     FIXME("(%p)->(%p): stub\n", This, ret);
2111 
2112     if (!This->child.reole)
2113         return CO_E_RELEASED;
2114 
2115     return E_NOTIMPL;
2116 }
2117 
textrange_isequal(LONG start,LONG end,ITextRange * range,LONG * ret)2118 static HRESULT textrange_isequal(LONG start, LONG end, ITextRange *range, LONG *ret)
2119 {
2120     LONG from, to, v;
2121 
2122     if (!ret)
2123         ret = &v;
2124 
2125     if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
2126         *ret = tomFalse;
2127     }
2128     else
2129         *ret = (start == from && end == to) ? tomTrue : tomFalse;
2130     return *ret == tomTrue ? S_OK : S_FALSE;
2131 }
2132 
ITextRange_fnIsEqual(ITextRange * me,ITextRange * range,LONG * ret)2133 static HRESULT WINAPI ITextRange_fnIsEqual(ITextRange *me, ITextRange *range, LONG *ret)
2134 {
2135     ITextRangeImpl *This = impl_from_ITextRange(me);
2136 
2137     TRACE("(%p)->(%p %p)\n", This, range, ret);
2138 
2139     if (ret)
2140         *ret = tomFalse;
2141 
2142     if (!This->child.reole)
2143         return CO_E_RELEASED;
2144 
2145     if (!range)
2146         return S_FALSE;
2147 
2148     return textrange_isequal(This->start, This->end, range, ret);
2149 }
2150 
ITextRange_fnSelect(ITextRange * me)2151 static HRESULT WINAPI ITextRange_fnSelect(ITextRange *me)
2152 {
2153     ITextRangeImpl *This = impl_from_ITextRange(me);
2154 
2155     TRACE("(%p)\n", This);
2156 
2157     if (!This->child.reole)
2158         return CO_E_RELEASED;
2159 
2160     set_selection(This->child.reole->editor, This->start, This->end);
2161     return S_OK;
2162 }
2163 
ITextRange_fnStartOf(ITextRange * me,LONG unit,LONG extend,LONG * delta)2164 static HRESULT WINAPI ITextRange_fnStartOf(ITextRange *me, LONG unit, LONG extend,
2165                                            LONG *delta)
2166 {
2167     ITextRangeImpl *This = impl_from_ITextRange(me);
2168 
2169     FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
2170 
2171     if (!This->child.reole)
2172         return CO_E_RELEASED;
2173 
2174     return E_NOTIMPL;
2175 }
2176 
ITextRange_fnEndOf(ITextRange * me,LONG unit,LONG extend,LONG * delta)2177 static HRESULT WINAPI ITextRange_fnEndOf(ITextRange *me, LONG unit, LONG extend,
2178                                          LONG *delta)
2179 {
2180     ITextRangeImpl *This = impl_from_ITextRange(me);
2181 
2182     FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
2183 
2184     if (!This->child.reole)
2185         return CO_E_RELEASED;
2186 
2187     return E_NOTIMPL;
2188 }
2189 
ITextRange_fnMove(ITextRange * me,LONG unit,LONG count,LONG * delta)2190 static HRESULT WINAPI ITextRange_fnMove(ITextRange *me, LONG unit, LONG count, LONG *delta)
2191 {
2192     ITextRangeImpl *This = impl_from_ITextRange(me);
2193 
2194     FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2195 
2196     if (!This->child.reole)
2197         return CO_E_RELEASED;
2198 
2199     return E_NOTIMPL;
2200 }
2201 
ITextRange_fnMoveStart(ITextRange * me,LONG unit,LONG count,LONG * delta)2202 static HRESULT WINAPI ITextRange_fnMoveStart(ITextRange *me, LONG unit, LONG count,
2203                                              LONG *delta)
2204 {
2205     ITextRangeImpl *This = impl_from_ITextRange(me);
2206 
2207     FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2208 
2209     if (!This->child.reole)
2210         return CO_E_RELEASED;
2211 
2212     return E_NOTIMPL;
2213 }
2214 
textrange_moveend(ITextRange * range,LONG unit,LONG count,LONG * delta)2215 static HRESULT textrange_moveend(ITextRange *range, LONG unit, LONG count, LONG *delta)
2216 {
2217     LONG old_start, old_end, new_start, new_end;
2218     HRESULT hr = S_OK;
2219 
2220     if (!count)
2221     {
2222         if (delta)
2223             *delta = 0;
2224         return S_FALSE;
2225     }
2226 
2227     ITextRange_GetStart(range, &old_start);
2228     ITextRange_GetEnd(range, &old_end);
2229     switch (unit)
2230     {
2231     case tomStory:
2232         if (count < 0)
2233             new_start = new_end = 0;
2234         else
2235         {
2236             new_start = old_start;
2237             ITextRange_GetStoryLength(range, &new_end);
2238         }
2239         if (delta)
2240         {
2241             if (new_end < old_end)
2242                 *delta = -1;
2243             else if (new_end == old_end)
2244                 *delta = 0;
2245             else
2246                 *delta = 1;
2247         }
2248         break;
2249     default:
2250         FIXME("unit %d is not supported\n", unit);
2251         return E_NOTIMPL;
2252     }
2253     if (new_end == old_end)
2254         hr = S_FALSE;
2255     ITextRange_SetStart(range, new_start);
2256     ITextRange_SetEnd(range, new_end);
2257 
2258     return hr;
2259 }
2260 
ITextRange_fnMoveEnd(ITextRange * me,LONG unit,LONG count,LONG * delta)2261 static HRESULT WINAPI ITextRange_fnMoveEnd(ITextRange *me, LONG unit, LONG count,
2262                                            LONG *delta)
2263 {
2264     ITextRangeImpl *This = impl_from_ITextRange(me);
2265 
2266     TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta);
2267 
2268     if (!This->child.reole)
2269         return CO_E_RELEASED;
2270 
2271     return textrange_moveend(me, unit, count, delta);
2272 }
2273 
ITextRange_fnMoveWhile(ITextRange * me,VARIANT * charset,LONG count,LONG * delta)2274 static HRESULT WINAPI ITextRange_fnMoveWhile(ITextRange *me, VARIANT *charset, LONG count,
2275                                              LONG *delta)
2276 {
2277     ITextRangeImpl *This = impl_from_ITextRange(me);
2278 
2279     FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2280 
2281     if (!This->child.reole)
2282         return CO_E_RELEASED;
2283 
2284     return E_NOTIMPL;
2285 }
2286 
ITextRange_fnMoveStartWhile(ITextRange * me,VARIANT * charset,LONG count,LONG * delta)2287 static HRESULT WINAPI ITextRange_fnMoveStartWhile(ITextRange *me, VARIANT *charset, LONG count,
2288                                                   LONG *delta)
2289 {
2290     ITextRangeImpl *This = impl_from_ITextRange(me);
2291 
2292     FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2293 
2294     if (!This->child.reole)
2295         return CO_E_RELEASED;
2296 
2297     return E_NOTIMPL;
2298 }
2299 
ITextRange_fnMoveEndWhile(ITextRange * me,VARIANT * charset,LONG count,LONG * delta)2300 static HRESULT WINAPI ITextRange_fnMoveEndWhile(ITextRange *me, VARIANT *charset, LONG count,
2301                                                 LONG *delta)
2302 {
2303     ITextRangeImpl *This = impl_from_ITextRange(me);
2304 
2305     FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2306 
2307     if (!This->child.reole)
2308         return CO_E_RELEASED;
2309 
2310     return E_NOTIMPL;
2311 }
2312 
ITextRange_fnMoveUntil(ITextRange * me,VARIANT * charset,LONG count,LONG * delta)2313 static HRESULT WINAPI ITextRange_fnMoveUntil(ITextRange *me, VARIANT *charset, LONG count,
2314                                              LONG *delta)
2315 {
2316     ITextRangeImpl *This = impl_from_ITextRange(me);
2317 
2318     FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2319 
2320     if (!This->child.reole)
2321         return CO_E_RELEASED;
2322 
2323     return E_NOTIMPL;
2324 }
2325 
ITextRange_fnMoveStartUntil(ITextRange * me,VARIANT * charset,LONG count,LONG * delta)2326 static HRESULT WINAPI ITextRange_fnMoveStartUntil(ITextRange *me, VARIANT *charset, LONG count,
2327                                                   LONG *delta)
2328 {
2329     ITextRangeImpl *This = impl_from_ITextRange(me);
2330 
2331     FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2332 
2333     if (!This->child.reole)
2334         return CO_E_RELEASED;
2335 
2336     return E_NOTIMPL;
2337 }
2338 
ITextRange_fnMoveEndUntil(ITextRange * me,VARIANT * charset,LONG count,LONG * delta)2339 static HRESULT WINAPI ITextRange_fnMoveEndUntil(ITextRange *me, VARIANT *charset, LONG count,
2340                                                 LONG *delta)
2341 {
2342     ITextRangeImpl *This = impl_from_ITextRange(me);
2343 
2344     FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2345 
2346     if (!This->child.reole)
2347         return CO_E_RELEASED;
2348 
2349     return E_NOTIMPL;
2350 }
2351 
ITextRange_fnFindText(ITextRange * me,BSTR text,LONG count,LONG flags,LONG * length)2352 static HRESULT WINAPI ITextRange_fnFindText(ITextRange *me, BSTR text, LONG count, LONG flags,
2353                                             LONG *length)
2354 {
2355     ITextRangeImpl *This = impl_from_ITextRange(me);
2356 
2357     FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2358 
2359     if (!This->child.reole)
2360         return CO_E_RELEASED;
2361 
2362     return E_NOTIMPL;
2363 }
2364 
ITextRange_fnFindTextStart(ITextRange * me,BSTR text,LONG count,LONG flags,LONG * length)2365 static HRESULT WINAPI ITextRange_fnFindTextStart(ITextRange *me, BSTR text, LONG count,
2366                                                  LONG flags, LONG *length)
2367 {
2368     ITextRangeImpl *This = impl_from_ITextRange(me);
2369 
2370     FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2371 
2372     if (!This->child.reole)
2373         return CO_E_RELEASED;
2374 
2375     return E_NOTIMPL;
2376 }
2377 
ITextRange_fnFindTextEnd(ITextRange * me,BSTR text,LONG count,LONG flags,LONG * length)2378 static HRESULT WINAPI ITextRange_fnFindTextEnd(ITextRange *me, BSTR text, LONG count,
2379                                                LONG flags, LONG *length)
2380 {
2381     ITextRangeImpl *This = impl_from_ITextRange(me);
2382 
2383     FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2384 
2385     if (!This->child.reole)
2386         return CO_E_RELEASED;
2387 
2388     return E_NOTIMPL;
2389 }
2390 
ITextRange_fnDelete(ITextRange * me,LONG unit,LONG count,LONG * delta)2391 static HRESULT WINAPI ITextRange_fnDelete(ITextRange *me, LONG unit, LONG count, LONG *delta)
2392 {
2393     ITextRangeImpl *This = impl_from_ITextRange(me);
2394 
2395     FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2396 
2397     if (!This->child.reole)
2398         return CO_E_RELEASED;
2399 
2400     return E_NOTIMPL;
2401 }
2402 
ITextRange_fnCut(ITextRange * me,VARIANT * v)2403 static HRESULT WINAPI ITextRange_fnCut(ITextRange *me, VARIANT *v)
2404 {
2405     ITextRangeImpl *This = impl_from_ITextRange(me);
2406 
2407     FIXME("(%p)->(%p): stub\n", This, v);
2408 
2409     if (!This->child.reole)
2410         return CO_E_RELEASED;
2411 
2412     return E_NOTIMPL;
2413 }
2414 
ITextRange_fnCopy(ITextRange * me,VARIANT * v)2415 static HRESULT WINAPI ITextRange_fnCopy(ITextRange *me, VARIANT *v)
2416 {
2417     ITextRangeImpl *This = impl_from_ITextRange(me);
2418 
2419     FIXME("(%p)->(%p): stub\n", This, v);
2420 
2421     if (!This->child.reole)
2422         return CO_E_RELEASED;
2423 
2424     return E_NOTIMPL;
2425 }
2426 
ITextRange_fnPaste(ITextRange * me,VARIANT * v,LONG format)2427 static HRESULT WINAPI ITextRange_fnPaste(ITextRange *me, VARIANT *v, LONG format)
2428 {
2429     ITextRangeImpl *This = impl_from_ITextRange(me);
2430 
2431     FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format);
2432 
2433     if (!This->child.reole)
2434         return CO_E_RELEASED;
2435 
2436     return E_NOTIMPL;
2437 }
2438 
ITextRange_fnCanPaste(ITextRange * me,VARIANT * v,LONG format,LONG * ret)2439 static HRESULT WINAPI ITextRange_fnCanPaste(ITextRange *me, VARIANT *v, LONG format, LONG *ret)
2440 {
2441     ITextRangeImpl *This = impl_from_ITextRange(me);
2442 
2443     FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret);
2444 
2445     if (!This->child.reole)
2446         return CO_E_RELEASED;
2447 
2448     return E_NOTIMPL;
2449 }
2450 
ITextRange_fnCanEdit(ITextRange * me,LONG * ret)2451 static HRESULT WINAPI ITextRange_fnCanEdit(ITextRange *me, LONG *ret)
2452 {
2453     ITextRangeImpl *This = impl_from_ITextRange(me);
2454 
2455     FIXME("(%p)->(%p): stub\n", This, ret);
2456 
2457     if (!This->child.reole)
2458         return CO_E_RELEASED;
2459 
2460     return E_NOTIMPL;
2461 }
2462 
ITextRange_fnChangeCase(ITextRange * me,LONG type)2463 static HRESULT WINAPI ITextRange_fnChangeCase(ITextRange *me, LONG type)
2464 {
2465     ITextRangeImpl *This = impl_from_ITextRange(me);
2466 
2467     FIXME("(%p)->(%d): stub\n", This, type);
2468 
2469     if (!This->child.reole)
2470         return CO_E_RELEASED;
2471 
2472     return E_NOTIMPL;
2473 }
2474 
ITextRange_fnGetPoint(ITextRange * me,LONG type,LONG * cx,LONG * cy)2475 static HRESULT WINAPI ITextRange_fnGetPoint(ITextRange *me, LONG type, LONG *cx, LONG *cy)
2476 {
2477     ITextRangeImpl *This = impl_from_ITextRange(me);
2478 
2479     FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy);
2480 
2481     if (!This->child.reole)
2482         return CO_E_RELEASED;
2483 
2484     return E_NOTIMPL;
2485 }
2486 
ITextRange_fnSetPoint(ITextRange * me,LONG x,LONG y,LONG type,LONG extend)2487 static HRESULT WINAPI ITextRange_fnSetPoint(ITextRange *me, LONG x, LONG y, LONG type,
2488                                             LONG extend)
2489 {
2490     ITextRangeImpl *This = impl_from_ITextRange(me);
2491 
2492     FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend);
2493 
2494     if (!This->child.reole)
2495         return CO_E_RELEASED;
2496 
2497     return E_NOTIMPL;
2498 }
2499 
ITextRange_fnScrollIntoView(ITextRange * me,LONG value)2500 static HRESULT WINAPI ITextRange_fnScrollIntoView(ITextRange *me, LONG value)
2501 {
2502     ITextRangeImpl *This = impl_from_ITextRange(me);
2503     ME_TextEditor *editor;
2504     ME_Cursor cursor;
2505     int x, y, height;
2506 
2507     TRACE("(%p)->(%d)\n", This, value);
2508 
2509     if (!This->child.reole)
2510         return CO_E_RELEASED;
2511 
2512     editor = This->child.reole->editor;
2513 
2514     switch (value)
2515     {
2516     case tomStart:
2517         ME_CursorFromCharOfs(editor, This->start, &cursor);
2518         ME_GetCursorCoordinates(editor, &cursor, &x, &y, &height);
2519         break;
2520     case tomEnd:
2521         ME_CursorFromCharOfs(editor, This->end, &cursor);
2522         ME_GetCursorCoordinates(editor, &cursor, &x, &y, &height);
2523         break;
2524     default:
2525         FIXME("bStart value %d not handled\n", value);
2526         return E_NOTIMPL;
2527     }
2528     ME_ScrollAbs(editor, x, y);
2529     return S_OK;
2530 }
2531 
ITextRange_fnGetEmbeddedObject(ITextRange * me,IUnknown ** ppv)2532 static HRESULT WINAPI ITextRange_fnGetEmbeddedObject(ITextRange *me, IUnknown **ppv)
2533 {
2534     ITextRangeImpl *This = impl_from_ITextRange(me);
2535 
2536     FIXME("(%p)->(%p): stub\n", This, ppv);
2537 
2538     if (!This->child.reole)
2539         return CO_E_RELEASED;
2540 
2541     return E_NOTIMPL;
2542 }
2543 
2544 static const ITextRangeVtbl trvt = {
2545     ITextRange_fnQueryInterface,
2546     ITextRange_fnAddRef,
2547     ITextRange_fnRelease,
2548     ITextRange_fnGetTypeInfoCount,
2549     ITextRange_fnGetTypeInfo,
2550     ITextRange_fnGetIDsOfNames,
2551     ITextRange_fnInvoke,
2552     ITextRange_fnGetText,
2553     ITextRange_fnSetText,
2554     ITextRange_fnGetChar,
2555     ITextRange_fnSetChar,
2556     ITextRange_fnGetDuplicate,
2557     ITextRange_fnGetFormattedText,
2558     ITextRange_fnSetFormattedText,
2559     ITextRange_fnGetStart,
2560     ITextRange_fnSetStart,
2561     ITextRange_fnGetEnd,
2562     ITextRange_fnSetEnd,
2563     ITextRange_fnGetFont,
2564     ITextRange_fnSetFont,
2565     ITextRange_fnGetPara,
2566     ITextRange_fnSetPara,
2567     ITextRange_fnGetStoryLength,
2568     ITextRange_fnGetStoryType,
2569     ITextRange_fnCollapse,
2570     ITextRange_fnExpand,
2571     ITextRange_fnGetIndex,
2572     ITextRange_fnSetIndex,
2573     ITextRange_fnSetRange,
2574     ITextRange_fnInRange,
2575     ITextRange_fnInStory,
2576     ITextRange_fnIsEqual,
2577     ITextRange_fnSelect,
2578     ITextRange_fnStartOf,
2579     ITextRange_fnEndOf,
2580     ITextRange_fnMove,
2581     ITextRange_fnMoveStart,
2582     ITextRange_fnMoveEnd,
2583     ITextRange_fnMoveWhile,
2584     ITextRange_fnMoveStartWhile,
2585     ITextRange_fnMoveEndWhile,
2586     ITextRange_fnMoveUntil,
2587     ITextRange_fnMoveStartUntil,
2588     ITextRange_fnMoveEndUntil,
2589     ITextRange_fnFindText,
2590     ITextRange_fnFindTextStart,
2591     ITextRange_fnFindTextEnd,
2592     ITextRange_fnDelete,
2593     ITextRange_fnCut,
2594     ITextRange_fnCopy,
2595     ITextRange_fnPaste,
2596     ITextRange_fnCanPaste,
2597     ITextRange_fnCanEdit,
2598     ITextRange_fnChangeCase,
2599     ITextRange_fnGetPoint,
2600     ITextRange_fnSetPoint,
2601     ITextRange_fnScrollIntoView,
2602     ITextRange_fnGetEmbeddedObject
2603 };
2604 
2605 /* ITextFont */
TextFont_QueryInterface(ITextFont * iface,REFIID riid,void ** ppv)2606 static HRESULT WINAPI TextFont_QueryInterface(ITextFont *iface, REFIID riid, void **ppv)
2607 {
2608     ITextFontImpl *This = impl_from_ITextFont(iface);
2609 
2610     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
2611 
2612     if (IsEqualIID(riid, &IID_ITextFont) ||
2613         IsEqualIID(riid, &IID_IDispatch) ||
2614         IsEqualIID(riid, &IID_IUnknown))
2615     {
2616         *ppv = iface;
2617         ITextFont_AddRef(iface);
2618         return S_OK;
2619     }
2620 
2621     *ppv = NULL;
2622     return E_NOINTERFACE;
2623 }
2624 
TextFont_AddRef(ITextFont * iface)2625 static ULONG WINAPI TextFont_AddRef(ITextFont *iface)
2626 {
2627     ITextFontImpl *This = impl_from_ITextFont(iface);
2628     ULONG ref = InterlockedIncrement(&This->ref);
2629     TRACE("(%p)->(%u)\n", This, ref);
2630     return ref;
2631 }
2632 
TextFont_Release(ITextFont * iface)2633 static ULONG WINAPI TextFont_Release(ITextFont *iface)
2634 {
2635     ITextFontImpl *This = impl_from_ITextFont(iface);
2636     ULONG ref = InterlockedDecrement(&This->ref);
2637 
2638     TRACE("(%p)->(%u)\n", This, ref);
2639 
2640     if (!ref)
2641     {
2642         if (This->range)
2643             ITextRange_Release(This->range);
2644         SysFreeString(This->props[FONT_NAME].str);
2645         heap_free(This);
2646     }
2647 
2648     return ref;
2649 }
2650 
TextFont_GetTypeInfoCount(ITextFont * iface,UINT * pctinfo)2651 static HRESULT WINAPI TextFont_GetTypeInfoCount(ITextFont *iface, UINT *pctinfo)
2652 {
2653     ITextFontImpl *This = impl_from_ITextFont(iface);
2654     TRACE("(%p)->(%p)\n", This, pctinfo);
2655     *pctinfo = 1;
2656     return S_OK;
2657 }
2658 
TextFont_GetTypeInfo(ITextFont * iface,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)2659 static HRESULT WINAPI TextFont_GetTypeInfo(ITextFont *iface, UINT iTInfo, LCID lcid,
2660     ITypeInfo **ppTInfo)
2661 {
2662     ITextFontImpl *This = impl_from_ITextFont(iface);
2663     HRESULT hr;
2664 
2665     TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
2666 
2667     hr = get_typeinfo(ITextFont_tid, ppTInfo);
2668     if (SUCCEEDED(hr))
2669         ITypeInfo_AddRef(*ppTInfo);
2670     return hr;
2671 }
2672 
TextFont_GetIDsOfNames(ITextFont * iface,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)2673 static HRESULT WINAPI TextFont_GetIDsOfNames(ITextFont *iface, REFIID riid,
2674     LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
2675 {
2676     ITextFontImpl *This = impl_from_ITextFont(iface);
2677     ITypeInfo *ti;
2678     HRESULT hr;
2679 
2680     TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid),
2681             rgszNames, cNames, lcid, rgDispId);
2682 
2683     hr = get_typeinfo(ITextFont_tid, &ti);
2684     if (SUCCEEDED(hr))
2685         hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
2686     return hr;
2687 }
2688 
TextFont_Invoke(ITextFont * iface,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)2689 static HRESULT WINAPI TextFont_Invoke(
2690     ITextFont *iface,
2691     DISPID dispIdMember,
2692     REFIID riid,
2693     LCID lcid,
2694     WORD wFlags,
2695     DISPPARAMS *pDispParams,
2696     VARIANT *pVarResult,
2697     EXCEPINFO *pExcepInfo,
2698     UINT *puArgErr)
2699 {
2700     ITextFontImpl *This = impl_from_ITextFont(iface);
2701     ITypeInfo *ti;
2702     HRESULT hr;
2703 
2704     TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
2705             lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2706 
2707     hr = get_typeinfo(ITextFont_tid, &ti);
2708     if (SUCCEEDED(hr))
2709         hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2710     return hr;
2711 }
2712 
TextFont_GetDuplicate(ITextFont * iface,ITextFont ** ret)2713 static HRESULT WINAPI TextFont_GetDuplicate(ITextFont *iface, ITextFont **ret)
2714 {
2715     ITextFontImpl *This = impl_from_ITextFont(iface);
2716 
2717     TRACE("(%p)->(%p)\n", This, ret);
2718 
2719     if (!ret)
2720         return E_INVALIDARG;
2721 
2722     *ret = NULL;
2723     if (This->range && !get_range_reole(This->range))
2724         return CO_E_RELEASED;
2725 
2726     return create_textfont(NULL, This, ret);
2727 }
2728 
TextFont_SetDuplicate(ITextFont * iface,ITextFont * pFont)2729 static HRESULT WINAPI TextFont_SetDuplicate(ITextFont *iface, ITextFont *pFont)
2730 {
2731     ITextFontImpl *This = impl_from_ITextFont(iface);
2732     FIXME("(%p)->(%p): stub\n", This, pFont);
2733     return E_NOTIMPL;
2734 }
2735 
TextFont_CanChange(ITextFont * iface,LONG * ret)2736 static HRESULT WINAPI TextFont_CanChange(ITextFont *iface, LONG *ret)
2737 {
2738     ITextFontImpl *This = impl_from_ITextFont(iface);
2739     FIXME("(%p)->(%p): stub\n", This, ret);
2740     return E_NOTIMPL;
2741 }
2742 
TextFont_IsEqual(ITextFont * iface,ITextFont * font,LONG * ret)2743 static HRESULT WINAPI TextFont_IsEqual(ITextFont *iface, ITextFont *font, LONG *ret)
2744 {
2745     ITextFontImpl *This = impl_from_ITextFont(iface);
2746     FIXME("(%p)->(%p %p): stub\n", This, font, ret);
2747     return E_NOTIMPL;
2748 }
2749 
textfont_reset_to_default(ITextFontImpl * font)2750 static void textfont_reset_to_default(ITextFontImpl *font)
2751 {
2752     enum textfont_prop_id id;
2753 
2754     for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2755         switch (id)
2756         {
2757         case FONT_ALLCAPS:
2758         case FONT_ANIMATION:
2759         case FONT_BOLD:
2760         case FONT_EMBOSS:
2761         case FONT_HIDDEN:
2762         case FONT_ENGRAVE:
2763         case FONT_ITALIC:
2764         case FONT_OUTLINE:
2765         case FONT_PROTECTED:
2766         case FONT_SHADOW:
2767         case FONT_SMALLCAPS:
2768         case FONT_STRIKETHROUGH:
2769         case FONT_SUBSCRIPT:
2770         case FONT_SUPERSCRIPT:
2771         case FONT_UNDERLINE:
2772             font->props[id].l = tomFalse;
2773             break;
2774         case FONT_BACKCOLOR:
2775         case FONT_FORECOLOR:
2776             font->props[id].l = tomAutoColor;
2777             break;
2778         case FONT_KERNING:
2779         case FONT_POSITION:
2780         case FONT_SIZE:
2781         case FONT_SPACING:
2782             font->props[id].f = 0.0;
2783             break;
2784         case FONT_LANGID:
2785             font->props[id].l = GetSystemDefaultLCID();
2786             break;
2787         case FONT_NAME: {
2788             static const WCHAR sysW[] = {'S','y','s','t','e','m',0};
2789             SysFreeString(font->props[id].str);
2790             font->props[id].str = SysAllocString(sysW);
2791             break;
2792         }
2793         case FONT_WEIGHT:
2794             font->props[id].l = FW_NORMAL;
2795             break;
2796         default:
2797             FIXME("font property %d not handled\n", id);
2798         }
2799     }
2800 }
2801 
textfont_reset_to_undefined(ITextFontImpl * font)2802 static void textfont_reset_to_undefined(ITextFontImpl *font)
2803 {
2804     enum textfont_prop_id id;
2805 
2806     for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2807         switch (id)
2808         {
2809         case FONT_ALLCAPS:
2810         case FONT_ANIMATION:
2811         case FONT_BOLD:
2812         case FONT_EMBOSS:
2813         case FONT_HIDDEN:
2814         case FONT_ENGRAVE:
2815         case FONT_ITALIC:
2816         case FONT_OUTLINE:
2817         case FONT_PROTECTED:
2818         case FONT_SHADOW:
2819         case FONT_SMALLCAPS:
2820         case FONT_STRIKETHROUGH:
2821         case FONT_SUBSCRIPT:
2822         case FONT_SUPERSCRIPT:
2823         case FONT_UNDERLINE:
2824         case FONT_BACKCOLOR:
2825         case FONT_FORECOLOR:
2826         case FONT_LANGID:
2827         case FONT_WEIGHT:
2828             font->props[id].l = tomUndefined;
2829             break;
2830         case FONT_KERNING:
2831         case FONT_POSITION:
2832         case FONT_SIZE:
2833         case FONT_SPACING:
2834             font->props[id].f = tomUndefined;
2835             break;
2836         case FONT_NAME:
2837             break;
2838         default:
2839             FIXME("font property %d not handled\n", id);
2840         }
2841     }
2842 }
2843 
textfont_apply_range_props(ITextFontImpl * font)2844 static void textfont_apply_range_props(ITextFontImpl *font)
2845 {
2846     enum textfont_prop_id propid;
2847     for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++)
2848         set_textfont_prop(font, propid, &font->props[propid]);
2849 }
2850 
TextFont_Reset(ITextFont * iface,LONG value)2851 static HRESULT WINAPI TextFont_Reset(ITextFont *iface, LONG value)
2852 {
2853     ITextFontImpl *This = impl_from_ITextFont(iface);
2854 
2855     TRACE("(%p)->(%d)\n", This, value);
2856 
2857     /* If font is attached to a range, released or not, we can't
2858        reset to undefined */
2859     if (This->range) {
2860         if (!get_range_reole(This->range))
2861             return CO_E_RELEASED;
2862 
2863         switch (value)
2864         {
2865         case tomUndefined:
2866             return E_INVALIDARG;
2867         case tomCacheParms:
2868             textfont_cache_range_props(This);
2869             This->get_cache_enabled = TRUE;
2870             break;
2871         case tomTrackParms:
2872             This->get_cache_enabled = FALSE;
2873             break;
2874         case tomApplyLater:
2875             This->set_cache_enabled = TRUE;
2876             break;
2877         case tomApplyNow:
2878             This->set_cache_enabled = FALSE;
2879             textfont_apply_range_props(This);
2880             break;
2881         case tomUsePoints:
2882         case tomUseTwips:
2883             return E_INVALIDARG;
2884         default:
2885             FIXME("reset mode %d not supported\n", value);
2886         }
2887 
2888         return S_OK;
2889     }
2890     else {
2891         switch (value)
2892         {
2893         /* reset to global defaults */
2894         case tomDefault:
2895             textfont_reset_to_default(This);
2896             return S_OK;
2897         /* all properties are set to tomUndefined, font name is retained */
2898         case tomUndefined:
2899             textfont_reset_to_undefined(This);
2900             return S_OK;
2901         case tomApplyNow:
2902         case tomApplyLater:
2903         case tomTrackParms:
2904         case tomCacheParms:
2905             return S_OK;
2906         case tomUsePoints:
2907         case tomUseTwips:
2908             return E_INVALIDARG;
2909         }
2910     }
2911 
2912     FIXME("reset mode %d not supported\n", value);
2913     return E_NOTIMPL;
2914 }
2915 
TextFont_GetStyle(ITextFont * iface,LONG * value)2916 static HRESULT WINAPI TextFont_GetStyle(ITextFont *iface, LONG *value)
2917 {
2918     ITextFontImpl *This = impl_from_ITextFont(iface);
2919     FIXME("(%p)->(%p): stub\n", This, value);
2920     return E_NOTIMPL;
2921 }
2922 
TextFont_SetStyle(ITextFont * iface,LONG value)2923 static HRESULT WINAPI TextFont_SetStyle(ITextFont *iface, LONG value)
2924 {
2925     ITextFontImpl *This = impl_from_ITextFont(iface);
2926     FIXME("(%p)->(%d): stub\n", This, value);
2927     return E_NOTIMPL;
2928 }
2929 
TextFont_GetAllCaps(ITextFont * iface,LONG * value)2930 static HRESULT WINAPI TextFont_GetAllCaps(ITextFont *iface, LONG *value)
2931 {
2932     ITextFontImpl *This = impl_from_ITextFont(iface);
2933     TRACE("(%p)->(%p)\n", This, value);
2934     return get_textfont_propl(This, FONT_ALLCAPS, value);
2935 }
2936 
TextFont_SetAllCaps(ITextFont * iface,LONG value)2937 static HRESULT WINAPI TextFont_SetAllCaps(ITextFont *iface, LONG value)
2938 {
2939     ITextFontImpl *This = impl_from_ITextFont(iface);
2940     TRACE("(%p)->(%d)\n", This, value);
2941     return set_textfont_propd(This, FONT_ALLCAPS, value);
2942 }
2943 
TextFont_GetAnimation(ITextFont * iface,LONG * value)2944 static HRESULT WINAPI TextFont_GetAnimation(ITextFont *iface, LONG *value)
2945 {
2946     ITextFontImpl *This = impl_from_ITextFont(iface);
2947     TRACE("(%p)->(%p)\n", This, value);
2948     return get_textfont_propl(This, FONT_ANIMATION, value);
2949 }
2950 
TextFont_SetAnimation(ITextFont * iface,LONG value)2951 static HRESULT WINAPI TextFont_SetAnimation(ITextFont *iface, LONG value)
2952 {
2953     ITextFontImpl *This = impl_from_ITextFont(iface);
2954 
2955     TRACE("(%p)->(%d)\n", This, value);
2956 
2957     if (value < tomNoAnimation || value > tomAnimationMax)
2958         return E_INVALIDARG;
2959 
2960     return set_textfont_propl(This, FONT_ANIMATION, value);
2961 }
2962 
TextFont_GetBackColor(ITextFont * iface,LONG * value)2963 static HRESULT WINAPI TextFont_GetBackColor(ITextFont *iface, LONG *value)
2964 {
2965     ITextFontImpl *This = impl_from_ITextFont(iface);
2966     TRACE("(%p)->(%p)\n", This, value);
2967     return get_textfont_propl(This, FONT_BACKCOLOR, value);
2968 }
2969 
TextFont_SetBackColor(ITextFont * iface,LONG value)2970 static HRESULT WINAPI TextFont_SetBackColor(ITextFont *iface, LONG value)
2971 {
2972     ITextFontImpl *This = impl_from_ITextFont(iface);
2973     TRACE("(%p)->(%d)\n", This, value);
2974     return set_textfont_propl(This, FONT_BACKCOLOR, value);
2975 }
2976 
TextFont_GetBold(ITextFont * iface,LONG * value)2977 static HRESULT WINAPI TextFont_GetBold(ITextFont *iface, LONG *value)
2978 {
2979     ITextFontImpl *This = impl_from_ITextFont(iface);
2980     TRACE("(%p)->(%p)\n", This, value);
2981     return get_textfont_propl(This, FONT_BOLD, value);
2982 }
2983 
TextFont_SetBold(ITextFont * iface,LONG value)2984 static HRESULT WINAPI TextFont_SetBold(ITextFont *iface, LONG value)
2985 {
2986     ITextFontImpl *This = impl_from_ITextFont(iface);
2987     TRACE("(%p)->(%d)\n", This, value);
2988     return set_textfont_propd(This, FONT_BOLD, value);
2989 }
2990 
TextFont_GetEmboss(ITextFont * iface,LONG * value)2991 static HRESULT WINAPI TextFont_GetEmboss(ITextFont *iface, LONG *value)
2992 {
2993     ITextFontImpl *This = impl_from_ITextFont(iface);
2994     TRACE("(%p)->(%p)\n", This, value);
2995     return get_textfont_propl(This, FONT_EMBOSS, value);
2996 }
2997 
TextFont_SetEmboss(ITextFont * iface,LONG value)2998 static HRESULT WINAPI TextFont_SetEmboss(ITextFont *iface, LONG value)
2999 {
3000     ITextFontImpl *This = impl_from_ITextFont(iface);
3001     TRACE("(%p)->(%d)\n", This, value);
3002     return set_textfont_propd(This, FONT_EMBOSS, value);
3003 }
3004 
TextFont_GetForeColor(ITextFont * iface,LONG * value)3005 static HRESULT WINAPI TextFont_GetForeColor(ITextFont *iface, LONG *value)
3006 {
3007     ITextFontImpl *This = impl_from_ITextFont(iface);
3008     TRACE("(%p)->(%p)\n", This, value);
3009     return get_textfont_propl(This, FONT_FORECOLOR, value);
3010 }
3011 
TextFont_SetForeColor(ITextFont * iface,LONG value)3012 static HRESULT WINAPI TextFont_SetForeColor(ITextFont *iface, LONG value)
3013 {
3014     ITextFontImpl *This = impl_from_ITextFont(iface);
3015     TRACE("(%p)->(%d)\n", This, value);
3016     return set_textfont_propl(This, FONT_FORECOLOR, value);
3017 }
3018 
TextFont_GetHidden(ITextFont * iface,LONG * value)3019 static HRESULT WINAPI TextFont_GetHidden(ITextFont *iface, LONG *value)
3020 {
3021     ITextFontImpl *This = impl_from_ITextFont(iface);
3022     TRACE("(%p)->(%p)\n", This, value);
3023     return get_textfont_propl(This, FONT_HIDDEN, value);
3024 }
3025 
TextFont_SetHidden(ITextFont * iface,LONG value)3026 static HRESULT WINAPI TextFont_SetHidden(ITextFont *iface, LONG value)
3027 {
3028     ITextFontImpl *This = impl_from_ITextFont(iface);
3029     TRACE("(%p)->(%d)\n", This, value);
3030     return set_textfont_propd(This, FONT_HIDDEN, value);
3031 }
3032 
TextFont_GetEngrave(ITextFont * iface,LONG * value)3033 static HRESULT WINAPI TextFont_GetEngrave(ITextFont *iface, LONG *value)
3034 {
3035     ITextFontImpl *This = impl_from_ITextFont(iface);
3036     TRACE("(%p)->(%p)\n", This, value);
3037     return get_textfont_propl(This, FONT_ENGRAVE, value);
3038 }
3039 
TextFont_SetEngrave(ITextFont * iface,LONG value)3040 static HRESULT WINAPI TextFont_SetEngrave(ITextFont *iface, LONG value)
3041 {
3042     ITextFontImpl *This = impl_from_ITextFont(iface);
3043     TRACE("(%p)->(%d)\n", This, value);
3044     return set_textfont_propd(This, FONT_ENGRAVE, value);
3045 }
3046 
TextFont_GetItalic(ITextFont * iface,LONG * value)3047 static HRESULT WINAPI TextFont_GetItalic(ITextFont *iface, LONG *value)
3048 {
3049     ITextFontImpl *This = impl_from_ITextFont(iface);
3050     TRACE("(%p)->(%p)\n", This, value);
3051     return get_textfont_propl(This, FONT_ITALIC, value);
3052 }
3053 
TextFont_SetItalic(ITextFont * iface,LONG value)3054 static HRESULT WINAPI TextFont_SetItalic(ITextFont *iface, LONG value)
3055 {
3056     ITextFontImpl *This = impl_from_ITextFont(iface);
3057     TRACE("(%p)->(%d)\n", This, value);
3058     return set_textfont_propd(This, FONT_ITALIC, value);
3059 }
3060 
TextFont_GetKerning(ITextFont * iface,FLOAT * value)3061 static HRESULT WINAPI TextFont_GetKerning(ITextFont *iface, FLOAT *value)
3062 {
3063     ITextFontImpl *This = impl_from_ITextFont(iface);
3064     TRACE("(%p)->(%p)\n", This, value);
3065     return get_textfont_propf(This, FONT_KERNING, value);
3066 }
3067 
TextFont_SetKerning(ITextFont * iface,FLOAT value)3068 static HRESULT WINAPI TextFont_SetKerning(ITextFont *iface, FLOAT value)
3069 {
3070     ITextFontImpl *This = impl_from_ITextFont(iface);
3071     TRACE("(%p)->(%.2f)\n", This, value);
3072     return set_textfont_propf(This, FONT_KERNING, value);
3073 }
3074 
TextFont_GetLanguageID(ITextFont * iface,LONG * value)3075 static HRESULT WINAPI TextFont_GetLanguageID(ITextFont *iface, LONG *value)
3076 {
3077     ITextFontImpl *This = impl_from_ITextFont(iface);
3078     TRACE("(%p)->(%p)\n", This, value);
3079     return get_textfont_propl(This, FONT_LANGID, value);
3080 }
3081 
TextFont_SetLanguageID(ITextFont * iface,LONG value)3082 static HRESULT WINAPI TextFont_SetLanguageID(ITextFont *iface, LONG value)
3083 {
3084     ITextFontImpl *This = impl_from_ITextFont(iface);
3085     TRACE("(%p)->(%d)\n", This, value);
3086     return set_textfont_propl(This, FONT_LANGID, value);
3087 }
3088 
TextFont_GetName(ITextFont * iface,BSTR * value)3089 static HRESULT WINAPI TextFont_GetName(ITextFont *iface, BSTR *value)
3090 {
3091     ITextFontImpl *This = impl_from_ITextFont(iface);
3092 
3093     TRACE("(%p)->(%p)\n", This, value);
3094 
3095     if (!value)
3096         return E_INVALIDARG;
3097 
3098     *value = NULL;
3099 
3100     if (!This->range) {
3101         if (This->props[FONT_NAME].str)
3102             *value = SysAllocString(This->props[FONT_NAME].str);
3103         else
3104             *value = SysAllocStringLen(NULL, 0);
3105         return *value ? S_OK : E_OUTOFMEMORY;
3106     }
3107 
3108     return textfont_getname_from_range(This->range, value);
3109 }
3110 
TextFont_SetName(ITextFont * iface,BSTR value)3111 static HRESULT WINAPI TextFont_SetName(ITextFont *iface, BSTR value)
3112 {
3113     ITextFontImpl *This = impl_from_ITextFont(iface);
3114     textfont_prop_val v;
3115 
3116     TRACE("(%p)->(%s)\n", This, debugstr_w(value));
3117 
3118     v.str = value;
3119     return set_textfont_prop(This, FONT_NAME, &v);
3120 }
3121 
TextFont_GetOutline(ITextFont * iface,LONG * value)3122 static HRESULT WINAPI TextFont_GetOutline(ITextFont *iface, LONG *value)
3123 {
3124     ITextFontImpl *This = impl_from_ITextFont(iface);
3125     TRACE("(%p)->(%p)\n", This, value);
3126     return get_textfont_propl(This, FONT_OUTLINE, value);
3127 }
3128 
TextFont_SetOutline(ITextFont * iface,LONG value)3129 static HRESULT WINAPI TextFont_SetOutline(ITextFont *iface, LONG value)
3130 {
3131     ITextFontImpl *This = impl_from_ITextFont(iface);
3132     TRACE("(%p)->(%d)\n", This, value);
3133     return set_textfont_propd(This, FONT_OUTLINE, value);
3134 }
3135 
TextFont_GetPosition(ITextFont * iface,FLOAT * value)3136 static HRESULT WINAPI TextFont_GetPosition(ITextFont *iface, FLOAT *value)
3137 {
3138     ITextFontImpl *This = impl_from_ITextFont(iface);
3139     TRACE("(%p)->(%p)\n", This, value);
3140     return get_textfont_propf(This, FONT_POSITION, value);
3141 }
3142 
TextFont_SetPosition(ITextFont * iface,FLOAT value)3143 static HRESULT WINAPI TextFont_SetPosition(ITextFont *iface, FLOAT value)
3144 {
3145     ITextFontImpl *This = impl_from_ITextFont(iface);
3146     TRACE("(%p)->(%.2f)\n", This, value);
3147     return set_textfont_propf(This, FONT_POSITION, value);
3148 }
3149 
TextFont_GetProtected(ITextFont * iface,LONG * value)3150 static HRESULT WINAPI TextFont_GetProtected(ITextFont *iface, LONG *value)
3151 {
3152     ITextFontImpl *This = impl_from_ITextFont(iface);
3153     TRACE("(%p)->(%p)\n", This, value);
3154     return get_textfont_propl(This, FONT_PROTECTED, value);
3155 }
3156 
TextFont_SetProtected(ITextFont * iface,LONG value)3157 static HRESULT WINAPI TextFont_SetProtected(ITextFont *iface, LONG value)
3158 {
3159     ITextFontImpl *This = impl_from_ITextFont(iface);
3160     TRACE("(%p)->(%d)\n", This, value);
3161     return set_textfont_propd(This, FONT_PROTECTED, value);
3162 }
3163 
TextFont_GetShadow(ITextFont * iface,LONG * value)3164 static HRESULT WINAPI TextFont_GetShadow(ITextFont *iface, LONG *value)
3165 {
3166     ITextFontImpl *This = impl_from_ITextFont(iface);
3167     TRACE("(%p)->(%p)\n", This, value);
3168     return get_textfont_propl(This, FONT_SHADOW, value);
3169 }
3170 
TextFont_SetShadow(ITextFont * iface,LONG value)3171 static HRESULT WINAPI TextFont_SetShadow(ITextFont *iface, LONG value)
3172 {
3173     ITextFontImpl *This = impl_from_ITextFont(iface);
3174     TRACE("(%p)->(%d)\n", This, value);
3175     return set_textfont_propd(This, FONT_SHADOW, value);
3176 }
3177 
TextFont_GetSize(ITextFont * iface,FLOAT * value)3178 static HRESULT WINAPI TextFont_GetSize(ITextFont *iface, FLOAT *value)
3179 {
3180     ITextFontImpl *This = impl_from_ITextFont(iface);
3181     TRACE("(%p)->(%p)\n", This, value);
3182     return get_textfont_propf(This, FONT_SIZE, value);
3183 }
3184 
TextFont_SetSize(ITextFont * iface,FLOAT value)3185 static HRESULT WINAPI TextFont_SetSize(ITextFont *iface, FLOAT value)
3186 {
3187     ITextFontImpl *This = impl_from_ITextFont(iface);
3188     TRACE("(%p)->(%.2f)\n", This, value);
3189     return set_textfont_propf(This, FONT_SIZE, value);
3190 }
3191 
TextFont_GetSmallCaps(ITextFont * iface,LONG * value)3192 static HRESULT WINAPI TextFont_GetSmallCaps(ITextFont *iface, LONG *value)
3193 {
3194     ITextFontImpl *This = impl_from_ITextFont(iface);
3195     TRACE("(%p)->(%p)\n", This, value);
3196     return get_textfont_propl(This, FONT_SMALLCAPS, value);
3197 }
3198 
TextFont_SetSmallCaps(ITextFont * iface,LONG value)3199 static HRESULT WINAPI TextFont_SetSmallCaps(ITextFont *iface, LONG value)
3200 {
3201     ITextFontImpl *This = impl_from_ITextFont(iface);
3202     TRACE("(%p)->(%d)\n", This, value);
3203     return set_textfont_propd(This, FONT_SMALLCAPS, value);
3204 }
3205 
TextFont_GetSpacing(ITextFont * iface,FLOAT * value)3206 static HRESULT WINAPI TextFont_GetSpacing(ITextFont *iface, FLOAT *value)
3207 {
3208     ITextFontImpl *This = impl_from_ITextFont(iface);
3209     TRACE("(%p)->(%p)\n", This, value);
3210     return get_textfont_propf(This, FONT_SPACING, value);
3211 }
3212 
TextFont_SetSpacing(ITextFont * iface,FLOAT value)3213 static HRESULT WINAPI TextFont_SetSpacing(ITextFont *iface, FLOAT value)
3214 {
3215     ITextFontImpl *This = impl_from_ITextFont(iface);
3216     TRACE("(%p)->(%.2f)\n", This, value);
3217     return set_textfont_propf(This, FONT_SPACING, value);
3218 }
3219 
TextFont_GetStrikeThrough(ITextFont * iface,LONG * value)3220 static HRESULT WINAPI TextFont_GetStrikeThrough(ITextFont *iface, LONG *value)
3221 {
3222     ITextFontImpl *This = impl_from_ITextFont(iface);
3223     TRACE("(%p)->(%p)\n", This, value);
3224     return get_textfont_propl(This, FONT_STRIKETHROUGH, value);
3225 }
3226 
TextFont_SetStrikeThrough(ITextFont * iface,LONG value)3227 static HRESULT WINAPI TextFont_SetStrikeThrough(ITextFont *iface, LONG value)
3228 {
3229     ITextFontImpl *This = impl_from_ITextFont(iface);
3230     TRACE("(%p)->(%d)\n", This, value);
3231     return set_textfont_propd(This, FONT_STRIKETHROUGH, value);
3232 }
3233 
TextFont_GetSubscript(ITextFont * iface,LONG * value)3234 static HRESULT WINAPI TextFont_GetSubscript(ITextFont *iface, LONG *value)
3235 {
3236     ITextFontImpl *This = impl_from_ITextFont(iface);
3237     TRACE("(%p)->(%p)\n", This, value);
3238     return get_textfont_propl(This, FONT_SUBSCRIPT, value);
3239 }
3240 
TextFont_SetSubscript(ITextFont * iface,LONG value)3241 static HRESULT WINAPI TextFont_SetSubscript(ITextFont *iface, LONG value)
3242 {
3243     ITextFontImpl *This = impl_from_ITextFont(iface);
3244     TRACE("(%p)->(%d)\n", This, value);
3245     return set_textfont_propd(This, FONT_SUBSCRIPT, value);
3246 }
3247 
TextFont_GetSuperscript(ITextFont * iface,LONG * value)3248 static HRESULT WINAPI TextFont_GetSuperscript(ITextFont *iface, LONG *value)
3249 {
3250     ITextFontImpl *This = impl_from_ITextFont(iface);
3251     TRACE("(%p)->(%p)\n", This, value);
3252     return get_textfont_propl(This, FONT_SUPERSCRIPT, value);
3253 }
3254 
TextFont_SetSuperscript(ITextFont * iface,LONG value)3255 static HRESULT WINAPI TextFont_SetSuperscript(ITextFont *iface, LONG value)
3256 {
3257     ITextFontImpl *This = impl_from_ITextFont(iface);
3258     TRACE("(%p)->(%d)\n", This, value);
3259     return set_textfont_propd(This, FONT_SUPERSCRIPT, value);
3260 }
3261 
TextFont_GetUnderline(ITextFont * iface,LONG * value)3262 static HRESULT WINAPI TextFont_GetUnderline(ITextFont *iface, LONG *value)
3263 {
3264     ITextFontImpl *This = impl_from_ITextFont(iface);
3265     TRACE("(%p)->(%p)\n", This, value);
3266     return get_textfont_propl(This, FONT_UNDERLINE, value);
3267 }
3268 
TextFont_SetUnderline(ITextFont * iface,LONG value)3269 static HRESULT WINAPI TextFont_SetUnderline(ITextFont *iface, LONG value)
3270 {
3271     ITextFontImpl *This = impl_from_ITextFont(iface);
3272     TRACE("(%p)->(%d)\n", This, value);
3273     return set_textfont_propd(This, FONT_UNDERLINE, value);
3274 }
3275 
TextFont_GetWeight(ITextFont * iface,LONG * value)3276 static HRESULT WINAPI TextFont_GetWeight(ITextFont *iface, LONG *value)
3277 {
3278     ITextFontImpl *This = impl_from_ITextFont(iface);
3279     TRACE("(%p)->(%p)\n", This, value);
3280     return get_textfont_propl(This, FONT_WEIGHT, value);
3281 }
3282 
TextFont_SetWeight(ITextFont * iface,LONG value)3283 static HRESULT WINAPI TextFont_SetWeight(ITextFont *iface, LONG value)
3284 {
3285     ITextFontImpl *This = impl_from_ITextFont(iface);
3286     TRACE("(%p)->(%d)\n", This, value);
3287     return set_textfont_propl(This, FONT_WEIGHT, value);
3288 }
3289 
3290 static ITextFontVtbl textfontvtbl = {
3291     TextFont_QueryInterface,
3292     TextFont_AddRef,
3293     TextFont_Release,
3294     TextFont_GetTypeInfoCount,
3295     TextFont_GetTypeInfo,
3296     TextFont_GetIDsOfNames,
3297     TextFont_Invoke,
3298     TextFont_GetDuplicate,
3299     TextFont_SetDuplicate,
3300     TextFont_CanChange,
3301     TextFont_IsEqual,
3302     TextFont_Reset,
3303     TextFont_GetStyle,
3304     TextFont_SetStyle,
3305     TextFont_GetAllCaps,
3306     TextFont_SetAllCaps,
3307     TextFont_GetAnimation,
3308     TextFont_SetAnimation,
3309     TextFont_GetBackColor,
3310     TextFont_SetBackColor,
3311     TextFont_GetBold,
3312     TextFont_SetBold,
3313     TextFont_GetEmboss,
3314     TextFont_SetEmboss,
3315     TextFont_GetForeColor,
3316     TextFont_SetForeColor,
3317     TextFont_GetHidden,
3318     TextFont_SetHidden,
3319     TextFont_GetEngrave,
3320     TextFont_SetEngrave,
3321     TextFont_GetItalic,
3322     TextFont_SetItalic,
3323     TextFont_GetKerning,
3324     TextFont_SetKerning,
3325     TextFont_GetLanguageID,
3326     TextFont_SetLanguageID,
3327     TextFont_GetName,
3328     TextFont_SetName,
3329     TextFont_GetOutline,
3330     TextFont_SetOutline,
3331     TextFont_GetPosition,
3332     TextFont_SetPosition,
3333     TextFont_GetProtected,
3334     TextFont_SetProtected,
3335     TextFont_GetShadow,
3336     TextFont_SetShadow,
3337     TextFont_GetSize,
3338     TextFont_SetSize,
3339     TextFont_GetSmallCaps,
3340     TextFont_SetSmallCaps,
3341     TextFont_GetSpacing,
3342     TextFont_SetSpacing,
3343     TextFont_GetStrikeThrough,
3344     TextFont_SetStrikeThrough,
3345     TextFont_GetSubscript,
3346     TextFont_SetSubscript,
3347     TextFont_GetSuperscript,
3348     TextFont_SetSuperscript,
3349     TextFont_GetUnderline,
3350     TextFont_SetUnderline,
3351     TextFont_GetWeight,
3352     TextFont_SetWeight
3353 };
3354 
create_textfont(ITextRange * range,const ITextFontImpl * src,ITextFont ** ret)3355 static HRESULT create_textfont(ITextRange *range, const ITextFontImpl *src, ITextFont **ret)
3356 {
3357     ITextFontImpl *font;
3358 
3359     *ret = NULL;
3360     font = heap_alloc(sizeof(*font));
3361     if (!font)
3362         return E_OUTOFMEMORY;
3363 
3364     font->ITextFont_iface.lpVtbl = &textfontvtbl;
3365     font->ref = 1;
3366 
3367     if (src) {
3368         font->range = NULL;
3369         font->get_cache_enabled = TRUE;
3370         font->set_cache_enabled = TRUE;
3371         memcpy(&font->props, &src->props, sizeof(font->props));
3372         if (font->props[FONT_NAME].str)
3373             font->props[FONT_NAME].str = SysAllocString(font->props[FONT_NAME].str);
3374     }
3375     else {
3376         font->range = range;
3377         ITextRange_AddRef(range);
3378 
3379         /* cache current properties */
3380         font->get_cache_enabled = FALSE;
3381         font->set_cache_enabled = FALSE;
3382         textfont_cache_range_props(font);
3383     }
3384 
3385     *ret = &font->ITextFont_iface;
3386     return S_OK;
3387 }
3388 
3389 /* ITextPara */
TextPara_QueryInterface(ITextPara * iface,REFIID riid,void ** ppv)3390 static HRESULT WINAPI TextPara_QueryInterface(ITextPara *iface, REFIID riid, void **ppv)
3391 {
3392     ITextParaImpl *This = impl_from_ITextPara(iface);
3393 
3394     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
3395 
3396     if (IsEqualIID(riid, &IID_ITextPara) ||
3397         IsEqualIID(riid, &IID_IDispatch) ||
3398         IsEqualIID(riid, &IID_IUnknown))
3399     {
3400         *ppv = iface;
3401         ITextPara_AddRef(iface);
3402         return S_OK;
3403     }
3404 
3405     *ppv = NULL;
3406     return E_NOINTERFACE;
3407 }
3408 
TextPara_AddRef(ITextPara * iface)3409 static ULONG WINAPI TextPara_AddRef(ITextPara *iface)
3410 {
3411     ITextParaImpl *This = impl_from_ITextPara(iface);
3412     ULONG ref = InterlockedIncrement(&This->ref);
3413     TRACE("(%p)->(%u)\n", This, ref);
3414     return ref;
3415 }
3416 
TextPara_Release(ITextPara * iface)3417 static ULONG WINAPI TextPara_Release(ITextPara *iface)
3418 {
3419     ITextParaImpl *This = impl_from_ITextPara(iface);
3420     ULONG ref = InterlockedDecrement(&This->ref);
3421 
3422     TRACE("(%p)->(%u)\n", This, ref);
3423 
3424     if (!ref)
3425     {
3426         ITextRange_Release(This->range);
3427         heap_free(This);
3428     }
3429 
3430     return ref;
3431 }
3432 
para_get_reole(ITextParaImpl * This)3433 static IRichEditOleImpl *para_get_reole(ITextParaImpl *This)
3434 {
3435     if (This->range)
3436     {
3437         ITextRangeImpl *rng = impl_from_ITextRange(This->range);
3438         return rng->child.reole;
3439     }
3440     return NULL;
3441 }
3442 
TextPara_GetTypeInfoCount(ITextPara * iface,UINT * pctinfo)3443 static HRESULT WINAPI TextPara_GetTypeInfoCount(ITextPara *iface, UINT *pctinfo)
3444 {
3445     ITextParaImpl *This = impl_from_ITextPara(iface);
3446     TRACE("(%p)->(%p)\n", This, pctinfo);
3447     *pctinfo = 1;
3448     return S_OK;
3449 }
3450 
TextPara_GetTypeInfo(ITextPara * iface,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)3451 static HRESULT WINAPI TextPara_GetTypeInfo(ITextPara *iface, UINT iTInfo, LCID lcid,
3452     ITypeInfo **ppTInfo)
3453 {
3454     ITextParaImpl *This = impl_from_ITextPara(iface);
3455     HRESULT hr;
3456 
3457     TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
3458 
3459     hr = get_typeinfo(ITextPara_tid, ppTInfo);
3460     if (SUCCEEDED(hr))
3461         ITypeInfo_AddRef(*ppTInfo);
3462     return hr;
3463 }
3464 
TextPara_GetIDsOfNames(ITextPara * iface,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)3465 static HRESULT WINAPI TextPara_GetIDsOfNames(ITextPara *iface, REFIID riid,
3466     LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
3467 {
3468     ITextParaImpl *This = impl_from_ITextPara(iface);
3469     ITypeInfo *ti;
3470     HRESULT hr;
3471 
3472     TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames,
3473             cNames, lcid, rgDispId);
3474 
3475     hr = get_typeinfo(ITextPara_tid, &ti);
3476     if (SUCCEEDED(hr))
3477         hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
3478     return hr;
3479 }
3480 
TextPara_Invoke(ITextPara * iface,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)3481 static HRESULT WINAPI TextPara_Invoke(
3482     ITextPara *iface,
3483     DISPID dispIdMember,
3484     REFIID riid,
3485     LCID lcid,
3486     WORD wFlags,
3487     DISPPARAMS *pDispParams,
3488     VARIANT *pVarResult,
3489     EXCEPINFO *pExcepInfo,
3490     UINT *puArgErr)
3491 {
3492     ITextParaImpl *This = impl_from_ITextPara(iface);
3493     ITypeInfo *ti;
3494     HRESULT hr;
3495 
3496     TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember,
3497             debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
3498             pExcepInfo, puArgErr);
3499 
3500     hr = get_typeinfo(ITextPara_tid, &ti);
3501     if (SUCCEEDED(hr))
3502         hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3503     return hr;
3504 }
3505 
TextPara_GetDuplicate(ITextPara * iface,ITextPara ** ret)3506 static HRESULT WINAPI TextPara_GetDuplicate(ITextPara *iface, ITextPara **ret)
3507 {
3508     ITextParaImpl *This = impl_from_ITextPara(iface);
3509     FIXME("(%p)->(%p)\n", This, ret);
3510 
3511     if (!para_get_reole(This))
3512         return CO_E_RELEASED;
3513 
3514     return E_NOTIMPL;
3515 }
3516 
TextPara_SetDuplicate(ITextPara * iface,ITextPara * para)3517 static HRESULT WINAPI TextPara_SetDuplicate(ITextPara *iface, ITextPara *para)
3518 {
3519     ITextParaImpl *This = impl_from_ITextPara(iface);
3520     FIXME("(%p)->(%p)\n", This, para);
3521 
3522     if (!para_get_reole(This))
3523         return CO_E_RELEASED;
3524 
3525     return E_NOTIMPL;
3526 }
3527 
TextPara_CanChange(ITextPara * iface,LONG * ret)3528 static HRESULT WINAPI TextPara_CanChange(ITextPara *iface, LONG *ret)
3529 {
3530     ITextParaImpl *This = impl_from_ITextPara(iface);
3531     FIXME("(%p)->(%p)\n", This, ret);
3532 
3533     if (!para_get_reole(This))
3534         return CO_E_RELEASED;
3535 
3536     return E_NOTIMPL;
3537 }
3538 
TextPara_IsEqual(ITextPara * iface,ITextPara * para,LONG * ret)3539 static HRESULT WINAPI TextPara_IsEqual(ITextPara *iface, ITextPara *para, LONG *ret)
3540 {
3541     ITextParaImpl *This = impl_from_ITextPara(iface);
3542     FIXME("(%p)->(%p %p)\n", This, para, ret);
3543 
3544     if (!para_get_reole(This))
3545         return CO_E_RELEASED;
3546 
3547     return E_NOTIMPL;
3548 }
3549 
TextPara_Reset(ITextPara * iface,LONG value)3550 static HRESULT WINAPI TextPara_Reset(ITextPara *iface, LONG value)
3551 {
3552     ITextParaImpl *This = impl_from_ITextPara(iface);
3553     FIXME("(%p)->(%d)\n", This, value);
3554 
3555     if (!para_get_reole(This))
3556         return CO_E_RELEASED;
3557 
3558     return E_NOTIMPL;
3559 }
3560 
TextPara_GetStyle(ITextPara * iface,LONG * value)3561 static HRESULT WINAPI TextPara_GetStyle(ITextPara *iface, LONG *value)
3562 {
3563     ITextParaImpl *This = impl_from_ITextPara(iface);
3564     FIXME("(%p)->(%p)\n", This, value);
3565 
3566     if (!para_get_reole(This))
3567         return CO_E_RELEASED;
3568 
3569     return E_NOTIMPL;
3570 }
3571 
TextPara_SetStyle(ITextPara * iface,LONG value)3572 static HRESULT WINAPI TextPara_SetStyle(ITextPara *iface, LONG value)
3573 {
3574     ITextParaImpl *This = impl_from_ITextPara(iface);
3575     FIXME("(%p)->(%d)\n", This, value);
3576 
3577     if (!para_get_reole(This))
3578         return CO_E_RELEASED;
3579 
3580     return E_NOTIMPL;
3581 }
3582 
TextPara_GetAlignment(ITextPara * iface,LONG * value)3583 static HRESULT WINAPI TextPara_GetAlignment(ITextPara *iface, LONG *value)
3584 {
3585     ITextParaImpl *This = impl_from_ITextPara(iface);
3586     static int once;
3587 
3588     if (!once++) FIXME("(%p)->(%p)\n", This, value);
3589 
3590     if (!para_get_reole(This))
3591         return CO_E_RELEASED;
3592 
3593     return E_NOTIMPL;
3594 }
3595 
TextPara_SetAlignment(ITextPara * iface,LONG value)3596 static HRESULT WINAPI TextPara_SetAlignment(ITextPara *iface, LONG value)
3597 {
3598     ITextParaImpl *This = impl_from_ITextPara(iface);
3599     FIXME("(%p)->(%d)\n", This, value);
3600 
3601     if (!para_get_reole(This))
3602         return CO_E_RELEASED;
3603 
3604     return E_NOTIMPL;
3605 }
3606 
TextPara_GetHyphenation(ITextPara * iface,LONG * value)3607 static HRESULT WINAPI TextPara_GetHyphenation(ITextPara *iface, LONG *value)
3608 {
3609     ITextParaImpl *This = impl_from_ITextPara(iface);
3610     FIXME("(%p)->(%p)\n", This, value);
3611 
3612     if (!para_get_reole(This))
3613         return CO_E_RELEASED;
3614 
3615     return E_NOTIMPL;
3616 }
3617 
TextPara_SetHyphenation(ITextPara * iface,LONG value)3618 static HRESULT WINAPI TextPara_SetHyphenation(ITextPara *iface, LONG value)
3619 {
3620     ITextParaImpl *This = impl_from_ITextPara(iface);
3621     FIXME("(%p)->(%d)\n", This, value);
3622 
3623     if (!para_get_reole(This))
3624         return CO_E_RELEASED;
3625 
3626     return E_NOTIMPL;
3627 }
3628 
TextPara_GetFirstLineIndent(ITextPara * iface,FLOAT * value)3629 static HRESULT WINAPI TextPara_GetFirstLineIndent(ITextPara *iface, FLOAT *value)
3630 {
3631     ITextParaImpl *This = impl_from_ITextPara(iface);
3632     FIXME("(%p)->(%p)\n", This, value);
3633 
3634     if (!para_get_reole(This))
3635         return CO_E_RELEASED;
3636 
3637     return E_NOTIMPL;
3638 }
3639 
TextPara_GetKeepTogether(ITextPara * iface,LONG * value)3640 static HRESULT WINAPI TextPara_GetKeepTogether(ITextPara *iface, LONG *value)
3641 {
3642     ITextParaImpl *This = impl_from_ITextPara(iface);
3643     FIXME("(%p)->(%p)\n", This, value);
3644 
3645     if (!para_get_reole(This))
3646         return CO_E_RELEASED;
3647 
3648     return E_NOTIMPL;
3649 }
3650 
TextPara_SetKeepTogether(ITextPara * iface,LONG value)3651 static HRESULT WINAPI TextPara_SetKeepTogether(ITextPara *iface, LONG value)
3652 {
3653     ITextParaImpl *This = impl_from_ITextPara(iface);
3654     FIXME("(%p)->(%d)\n", This, value);
3655 
3656     if (!para_get_reole(This))
3657         return CO_E_RELEASED;
3658 
3659     return E_NOTIMPL;
3660 }
3661 
TextPara_GetKeepWithNext(ITextPara * iface,LONG * value)3662 static HRESULT WINAPI TextPara_GetKeepWithNext(ITextPara *iface, LONG *value)
3663 {
3664     ITextParaImpl *This = impl_from_ITextPara(iface);
3665     FIXME("(%p)->(%p)\n", This, value);
3666 
3667     if (!para_get_reole(This))
3668         return CO_E_RELEASED;
3669 
3670     return E_NOTIMPL;
3671 }
3672 
TextPara_SetKeepWithNext(ITextPara * iface,LONG value)3673 static HRESULT WINAPI TextPara_SetKeepWithNext(ITextPara *iface, LONG value)
3674 {
3675     ITextParaImpl *This = impl_from_ITextPara(iface);
3676     FIXME("(%p)->(%d)\n", This, value);
3677 
3678     if (!para_get_reole(This))
3679         return CO_E_RELEASED;
3680 
3681     return E_NOTIMPL;
3682 }
3683 
TextPara_GetLeftIndent(ITextPara * iface,FLOAT * value)3684 static HRESULT WINAPI TextPara_GetLeftIndent(ITextPara *iface, FLOAT *value)
3685 {
3686     ITextParaImpl *This = impl_from_ITextPara(iface);
3687     FIXME("(%p)->(%p)\n", This, value);
3688 
3689     if (!para_get_reole(This))
3690         return CO_E_RELEASED;
3691 
3692     return E_NOTIMPL;
3693 }
3694 
TextPara_GetLineSpacing(ITextPara * iface,FLOAT * value)3695 static HRESULT WINAPI TextPara_GetLineSpacing(ITextPara *iface, FLOAT *value)
3696 {
3697     ITextParaImpl *This = impl_from_ITextPara(iface);
3698     FIXME("(%p)->(%p)\n", This, value);
3699 
3700     if (!para_get_reole(This))
3701         return CO_E_RELEASED;
3702 
3703     return E_NOTIMPL;
3704 }
3705 
TextPara_GetLineSpacingRule(ITextPara * iface,LONG * value)3706 static HRESULT WINAPI TextPara_GetLineSpacingRule(ITextPara *iface, LONG *value)
3707 {
3708     ITextParaImpl *This = impl_from_ITextPara(iface);
3709     FIXME("(%p)->(%p)\n", This, value);
3710 
3711     if (!para_get_reole(This))
3712         return CO_E_RELEASED;
3713 
3714     return E_NOTIMPL;
3715 }
3716 
TextPara_GetListAlignment(ITextPara * iface,LONG * value)3717 static HRESULT WINAPI TextPara_GetListAlignment(ITextPara *iface, LONG *value)
3718 {
3719     ITextParaImpl *This = impl_from_ITextPara(iface);
3720     FIXME("(%p)->(%p)\n", This, value);
3721 
3722     if (!para_get_reole(This))
3723         return CO_E_RELEASED;
3724 
3725     return E_NOTIMPL;
3726 }
3727 
TextPara_SetListAlignment(ITextPara * iface,LONG value)3728 static HRESULT WINAPI TextPara_SetListAlignment(ITextPara *iface, LONG value)
3729 {
3730     ITextParaImpl *This = impl_from_ITextPara(iface);
3731     FIXME("(%p)->(%d)\n", This, value);
3732 
3733     if (!para_get_reole(This))
3734         return CO_E_RELEASED;
3735 
3736     return E_NOTIMPL;
3737 }
3738 
TextPara_GetListLevelIndex(ITextPara * iface,LONG * value)3739 static HRESULT WINAPI TextPara_GetListLevelIndex(ITextPara *iface, LONG *value)
3740 {
3741     ITextParaImpl *This = impl_from_ITextPara(iface);
3742     FIXME("(%p)->(%p)\n", This, value);
3743 
3744     if (!para_get_reole(This))
3745         return CO_E_RELEASED;
3746 
3747     return E_NOTIMPL;
3748 }
3749 
TextPara_SetListLevelIndex(ITextPara * iface,LONG value)3750 static HRESULT WINAPI TextPara_SetListLevelIndex(ITextPara *iface, LONG value)
3751 {
3752     ITextParaImpl *This = impl_from_ITextPara(iface);
3753     FIXME("(%p)->(%d)\n", This, value);
3754 
3755     if (!para_get_reole(This))
3756         return CO_E_RELEASED;
3757 
3758     return E_NOTIMPL;
3759 }
3760 
TextPara_GetListStart(ITextPara * iface,LONG * value)3761 static HRESULT WINAPI TextPara_GetListStart(ITextPara *iface, LONG *value)
3762 {
3763     ITextParaImpl *This = impl_from_ITextPara(iface);
3764     FIXME("(%p)->(%p)\n", This, value);
3765 
3766     if (!para_get_reole(This))
3767         return CO_E_RELEASED;
3768 
3769     return E_NOTIMPL;
3770 }
3771 
TextPara_SetListStart(ITextPara * iface,LONG value)3772 static HRESULT WINAPI TextPara_SetListStart(ITextPara *iface, LONG value)
3773 {
3774     ITextParaImpl *This = impl_from_ITextPara(iface);
3775     FIXME("(%p)->(%d)\n", This, value);
3776 
3777     if (!para_get_reole(This))
3778         return CO_E_RELEASED;
3779 
3780     return E_NOTIMPL;
3781 }
3782 
TextPara_GetListTab(ITextPara * iface,FLOAT * value)3783 static HRESULT WINAPI TextPara_GetListTab(ITextPara *iface, FLOAT *value)
3784 {
3785     ITextParaImpl *This = impl_from_ITextPara(iface);
3786     FIXME("(%p)->(%p)\n", This, value);
3787 
3788     if (!para_get_reole(This))
3789         return CO_E_RELEASED;
3790 
3791     return E_NOTIMPL;
3792 }
3793 
TextPara_SetListTab(ITextPara * iface,FLOAT value)3794 static HRESULT WINAPI TextPara_SetListTab(ITextPara *iface, FLOAT value)
3795 {
3796     ITextParaImpl *This = impl_from_ITextPara(iface);
3797     FIXME("(%p)->(%.2f)\n", This, value);
3798 
3799     if (!para_get_reole(This))
3800         return CO_E_RELEASED;
3801 
3802     return E_NOTIMPL;
3803 }
3804 
TextPara_GetListType(ITextPara * iface,LONG * value)3805 static HRESULT WINAPI TextPara_GetListType(ITextPara *iface, LONG *value)
3806 {
3807     ITextParaImpl *This = impl_from_ITextPara(iface);
3808     FIXME("(%p)->(%p)\n", This, value);
3809 
3810     if (!para_get_reole(This))
3811         return CO_E_RELEASED;
3812 
3813     return E_NOTIMPL;
3814 }
3815 
TextPara_SetListType(ITextPara * iface,LONG value)3816 static HRESULT WINAPI TextPara_SetListType(ITextPara *iface, LONG value)
3817 {
3818     ITextParaImpl *This = impl_from_ITextPara(iface);
3819     FIXME("(%p)->(%d)\n", This, value);
3820 
3821     if (!para_get_reole(This))
3822         return CO_E_RELEASED;
3823 
3824     return E_NOTIMPL;
3825 }
3826 
TextPara_GetNoLineNumber(ITextPara * iface,LONG * value)3827 static HRESULT WINAPI TextPara_GetNoLineNumber(ITextPara *iface, LONG *value)
3828 {
3829     ITextParaImpl *This = impl_from_ITextPara(iface);
3830     FIXME("(%p)->(%p)\n", This, value);
3831 
3832     if (!para_get_reole(This))
3833         return CO_E_RELEASED;
3834 
3835     return E_NOTIMPL;
3836 }
3837 
TextPara_SetNoLineNumber(ITextPara * iface,LONG value)3838 static HRESULT WINAPI TextPara_SetNoLineNumber(ITextPara *iface, LONG value)
3839 {
3840     ITextParaImpl *This = impl_from_ITextPara(iface);
3841     FIXME("(%p)->(%d)\n", This, value);
3842 
3843     if (!para_get_reole(This))
3844         return CO_E_RELEASED;
3845 
3846     return E_NOTIMPL;
3847 }
3848 
TextPara_GetPageBreakBefore(ITextPara * iface,LONG * value)3849 static HRESULT WINAPI TextPara_GetPageBreakBefore(ITextPara *iface, LONG *value)
3850 {
3851     ITextParaImpl *This = impl_from_ITextPara(iface);
3852     FIXME("(%p)->(%p)\n", This, value);
3853 
3854     if (!para_get_reole(This))
3855         return CO_E_RELEASED;
3856 
3857     return E_NOTIMPL;
3858 }
3859 
TextPara_SetPageBreakBefore(ITextPara * iface,LONG value)3860 static HRESULT WINAPI TextPara_SetPageBreakBefore(ITextPara *iface, LONG value)
3861 {
3862     ITextParaImpl *This = impl_from_ITextPara(iface);
3863     FIXME("(%p)->(%d)\n", This, value);
3864 
3865     if (!para_get_reole(This))
3866         return CO_E_RELEASED;
3867 
3868     return E_NOTIMPL;
3869 }
3870 
TextPara_GetRightIndent(ITextPara * iface,FLOAT * value)3871 static HRESULT WINAPI TextPara_GetRightIndent(ITextPara *iface, FLOAT *value)
3872 {
3873     ITextParaImpl *This = impl_from_ITextPara(iface);
3874     FIXME("(%p)->(%p)\n", This, value);
3875 
3876     if (!para_get_reole(This))
3877         return CO_E_RELEASED;
3878 
3879     return E_NOTIMPL;
3880 }
3881 
TextPara_SetRightIndent(ITextPara * iface,FLOAT value)3882 static HRESULT WINAPI TextPara_SetRightIndent(ITextPara *iface, FLOAT value)
3883 {
3884     ITextParaImpl *This = impl_from_ITextPara(iface);
3885     FIXME("(%p)->(%.2f)\n", This, value);
3886 
3887     if (!para_get_reole(This))
3888         return CO_E_RELEASED;
3889 
3890     return E_NOTIMPL;
3891 }
3892 
TextPara_SetIndents(ITextPara * iface,FLOAT StartIndent,FLOAT LeftIndent,FLOAT RightIndent)3893 static HRESULT WINAPI TextPara_SetIndents(ITextPara *iface, FLOAT StartIndent, FLOAT LeftIndent, FLOAT RightIndent)
3894 {
3895     ITextParaImpl *This = impl_from_ITextPara(iface);
3896     FIXME("(%p)->(%.2f %.2f %.2f)\n", This, StartIndent, LeftIndent, RightIndent);
3897 
3898     if (!para_get_reole(This))
3899         return CO_E_RELEASED;
3900 
3901     return E_NOTIMPL;
3902 }
3903 
TextPara_SetLineSpacing(ITextPara * iface,LONG LineSpacingRule,FLOAT LineSpacing)3904 static HRESULT WINAPI TextPara_SetLineSpacing(ITextPara *iface, LONG LineSpacingRule, FLOAT LineSpacing)
3905 {
3906     ITextParaImpl *This = impl_from_ITextPara(iface);
3907     FIXME("(%p)->(%d %.2f)\n", This, LineSpacingRule, LineSpacing);
3908 
3909     if (!para_get_reole(This))
3910         return CO_E_RELEASED;
3911 
3912     return E_NOTIMPL;
3913 }
3914 
TextPara_GetSpaceAfter(ITextPara * iface,FLOAT * value)3915 static HRESULT WINAPI TextPara_GetSpaceAfter(ITextPara *iface, FLOAT *value)
3916 {
3917     ITextParaImpl *This = impl_from_ITextPara(iface);
3918     FIXME("(%p)->(%p)\n", This, value);
3919 
3920     if (!para_get_reole(This))
3921         return CO_E_RELEASED;
3922 
3923     return E_NOTIMPL;
3924 }
3925 
TextPara_SetSpaceAfter(ITextPara * iface,FLOAT value)3926 static HRESULT WINAPI TextPara_SetSpaceAfter(ITextPara *iface, FLOAT value)
3927 {
3928     ITextParaImpl *This = impl_from_ITextPara(iface);
3929     FIXME("(%p)->(%.2f)\n", This, value);
3930 
3931     if (!para_get_reole(This))
3932         return CO_E_RELEASED;
3933 
3934     return E_NOTIMPL;
3935 }
3936 
TextPara_GetSpaceBefore(ITextPara * iface,FLOAT * value)3937 static HRESULT WINAPI TextPara_GetSpaceBefore(ITextPara *iface, FLOAT *value)
3938 {
3939     ITextParaImpl *This = impl_from_ITextPara(iface);
3940     FIXME("(%p)->(%p)\n", This, value);
3941 
3942     if (!para_get_reole(This))
3943         return CO_E_RELEASED;
3944 
3945     return E_NOTIMPL;
3946 }
3947 
TextPara_SetSpaceBefore(ITextPara * iface,FLOAT value)3948 static HRESULT WINAPI TextPara_SetSpaceBefore(ITextPara *iface, FLOAT value)
3949 {
3950     ITextParaImpl *This = impl_from_ITextPara(iface);
3951     FIXME("(%p)->(%.2f)\n", This, value);
3952 
3953     if (!para_get_reole(This))
3954         return CO_E_RELEASED;
3955 
3956     return E_NOTIMPL;
3957 }
3958 
TextPara_GetWidowControl(ITextPara * iface,LONG * value)3959 static HRESULT WINAPI TextPara_GetWidowControl(ITextPara *iface, LONG *value)
3960 {
3961     ITextParaImpl *This = impl_from_ITextPara(iface);
3962     FIXME("(%p)->(%p)\n", This, value);
3963 
3964     if (!para_get_reole(This))
3965         return CO_E_RELEASED;
3966 
3967     return E_NOTIMPL;
3968 }
3969 
TextPara_SetWidowControl(ITextPara * iface,LONG value)3970 static HRESULT WINAPI TextPara_SetWidowControl(ITextPara *iface, LONG value)
3971 {
3972     ITextParaImpl *This = impl_from_ITextPara(iface);
3973     FIXME("(%p)->(%d)\n", This, value);
3974 
3975     if (!para_get_reole(This))
3976         return CO_E_RELEASED;
3977 
3978     return E_NOTIMPL;
3979 }
3980 
TextPara_GetTabCount(ITextPara * iface,LONG * value)3981 static HRESULT WINAPI TextPara_GetTabCount(ITextPara *iface, LONG *value)
3982 {
3983     ITextParaImpl *This = impl_from_ITextPara(iface);
3984     FIXME("(%p)->(%p)\n", This, value);
3985 
3986     if (!para_get_reole(This))
3987         return CO_E_RELEASED;
3988 
3989     return E_NOTIMPL;
3990 }
3991 
TextPara_AddTab(ITextPara * iface,FLOAT tbPos,LONG tbAlign,LONG tbLeader)3992 static HRESULT WINAPI TextPara_AddTab(ITextPara *iface, FLOAT tbPos, LONG tbAlign, LONG tbLeader)
3993 {
3994     ITextParaImpl *This = impl_from_ITextPara(iface);
3995     FIXME("(%p)->(%.2f %d %d)\n", This, tbPos, tbAlign, tbLeader);
3996 
3997     if (!para_get_reole(This))
3998         return CO_E_RELEASED;
3999 
4000     return E_NOTIMPL;
4001 }
4002 
TextPara_ClearAllTabs(ITextPara * iface)4003 static HRESULT WINAPI TextPara_ClearAllTabs(ITextPara *iface)
4004 {
4005     ITextParaImpl *This = impl_from_ITextPara(iface);
4006     FIXME("(%p)\n", This);
4007 
4008     if (!para_get_reole(This))
4009         return CO_E_RELEASED;
4010 
4011     return E_NOTIMPL;
4012 }
4013 
TextPara_DeleteTab(ITextPara * iface,FLOAT pos)4014 static HRESULT WINAPI TextPara_DeleteTab(ITextPara *iface, FLOAT pos)
4015 {
4016     ITextParaImpl *This = impl_from_ITextPara(iface);
4017     FIXME("(%p)->(%.2f)\n", This, pos);
4018 
4019     if (!para_get_reole(This))
4020         return CO_E_RELEASED;
4021 
4022     return E_NOTIMPL;
4023 }
4024 
TextPara_GetTab(ITextPara * iface,LONG iTab,FLOAT * ptbPos,LONG * ptbAlign,LONG * ptbLeader)4025 static HRESULT WINAPI TextPara_GetTab(ITextPara *iface, LONG iTab, FLOAT *ptbPos, LONG *ptbAlign, LONG *ptbLeader)
4026 {
4027     ITextParaImpl *This = impl_from_ITextPara(iface);
4028     FIXME("(%p)->(%d %p %p %p)\n", This, iTab, ptbPos, ptbAlign, ptbLeader);
4029 
4030     if (!para_get_reole(This))
4031         return CO_E_RELEASED;
4032 
4033     return E_NOTIMPL;
4034 }
4035 
4036 static ITextParaVtbl textparavtbl = {
4037     TextPara_QueryInterface,
4038     TextPara_AddRef,
4039     TextPara_Release,
4040     TextPara_GetTypeInfoCount,
4041     TextPara_GetTypeInfo,
4042     TextPara_GetIDsOfNames,
4043     TextPara_Invoke,
4044     TextPara_GetDuplicate,
4045     TextPara_SetDuplicate,
4046     TextPara_CanChange,
4047     TextPara_IsEqual,
4048     TextPara_Reset,
4049     TextPara_GetStyle,
4050     TextPara_SetStyle,
4051     TextPara_GetAlignment,
4052     TextPara_SetAlignment,
4053     TextPara_GetHyphenation,
4054     TextPara_SetHyphenation,
4055     TextPara_GetFirstLineIndent,
4056     TextPara_GetKeepTogether,
4057     TextPara_SetKeepTogether,
4058     TextPara_GetKeepWithNext,
4059     TextPara_SetKeepWithNext,
4060     TextPara_GetLeftIndent,
4061     TextPara_GetLineSpacing,
4062     TextPara_GetLineSpacingRule,
4063     TextPara_GetListAlignment,
4064     TextPara_SetListAlignment,
4065     TextPara_GetListLevelIndex,
4066     TextPara_SetListLevelIndex,
4067     TextPara_GetListStart,
4068     TextPara_SetListStart,
4069     TextPara_GetListTab,
4070     TextPara_SetListTab,
4071     TextPara_GetListType,
4072     TextPara_SetListType,
4073     TextPara_GetNoLineNumber,
4074     TextPara_SetNoLineNumber,
4075     TextPara_GetPageBreakBefore,
4076     TextPara_SetPageBreakBefore,
4077     TextPara_GetRightIndent,
4078     TextPara_SetRightIndent,
4079     TextPara_SetIndents,
4080     TextPara_SetLineSpacing,
4081     TextPara_GetSpaceAfter,
4082     TextPara_SetSpaceAfter,
4083     TextPara_GetSpaceBefore,
4084     TextPara_SetSpaceBefore,
4085     TextPara_GetWidowControl,
4086     TextPara_SetWidowControl,
4087     TextPara_GetTabCount,
4088     TextPara_AddTab,
4089     TextPara_ClearAllTabs,
4090     TextPara_DeleteTab,
4091     TextPara_GetTab
4092 };
4093 
create_textpara(ITextRange * range,ITextPara ** ret)4094 static HRESULT create_textpara(ITextRange *range, ITextPara **ret)
4095 {
4096     ITextParaImpl *para;
4097 
4098     *ret = NULL;
4099     para = heap_alloc(sizeof(*para));
4100     if (!para)
4101         return E_OUTOFMEMORY;
4102 
4103     para->ITextPara_iface.lpVtbl = &textparavtbl;
4104     para->ref = 1;
4105     para->range = range;
4106     ITextRange_AddRef(range);
4107 
4108     *ret = &para->ITextPara_iface;
4109     return S_OK;
4110 }
4111 
4112 /* ITextDocument */
ITextDocument2Old_fnQueryInterface(ITextDocument2Old * iface,REFIID riid,void ** ppvObject)4113 static HRESULT WINAPI ITextDocument2Old_fnQueryInterface(ITextDocument2Old* iface, REFIID riid,
4114                                                          void **ppvObject)
4115 {
4116     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4117     return IRichEditOle_QueryInterface(&This->IRichEditOle_iface, riid, ppvObject);
4118 }
4119 
ITextDocument2Old_fnAddRef(ITextDocument2Old * iface)4120 static ULONG WINAPI ITextDocument2Old_fnAddRef(ITextDocument2Old *iface)
4121 {
4122     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4123     return IRichEditOle_AddRef(&This->IRichEditOle_iface);
4124 }
4125 
ITextDocument2Old_fnRelease(ITextDocument2Old * iface)4126 static ULONG WINAPI ITextDocument2Old_fnRelease(ITextDocument2Old *iface)
4127 {
4128     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4129     return IRichEditOle_Release(&This->IRichEditOle_iface);
4130 }
4131 
ITextDocument2Old_fnGetTypeInfoCount(ITextDocument2Old * iface,UINT * pctinfo)4132 static HRESULT WINAPI ITextDocument2Old_fnGetTypeInfoCount(ITextDocument2Old *iface,
4133                                                            UINT *pctinfo)
4134 {
4135     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4136     TRACE("(%p)->(%p)\n", This, pctinfo);
4137     *pctinfo = 1;
4138     return S_OK;
4139 }
4140 
ITextDocument2Old_fnGetTypeInfo(ITextDocument2Old * iface,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)4141 static HRESULT WINAPI ITextDocument2Old_fnGetTypeInfo(ITextDocument2Old *iface, UINT iTInfo, LCID lcid,
4142                                                       ITypeInfo **ppTInfo)
4143 {
4144     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4145     HRESULT hr;
4146 
4147     TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
4148 
4149     hr = get_typeinfo(ITextDocument_tid, ppTInfo);
4150     if (SUCCEEDED(hr))
4151         ITypeInfo_AddRef(*ppTInfo);
4152     return hr;
4153 }
4154 
ITextDocument2Old_fnGetIDsOfNames(ITextDocument2Old * iface,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)4155 static HRESULT WINAPI ITextDocument2Old_fnGetIDsOfNames(ITextDocument2Old *iface, REFIID riid,
4156                                                         LPOLESTR *rgszNames, UINT cNames,
4157                                                         LCID lcid, DISPID *rgDispId)
4158 {
4159     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4160     ITypeInfo *ti;
4161     HRESULT hr;
4162 
4163     TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid),
4164             rgszNames, cNames, lcid, rgDispId);
4165 
4166     hr = get_typeinfo(ITextDocument_tid, &ti);
4167     if (SUCCEEDED(hr))
4168         hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
4169     return hr;
4170 }
4171 
ITextDocument2Old_fnInvoke(ITextDocument2Old * iface,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)4172 static HRESULT WINAPI ITextDocument2Old_fnInvoke(ITextDocument2Old *iface, DISPID dispIdMember,
4173                                                  REFIID riid, LCID lcid, WORD wFlags,
4174                                                  DISPPARAMS *pDispParams, VARIANT *pVarResult,
4175                                                  EXCEPINFO *pExcepInfo, UINT *puArgErr)
4176 {
4177     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4178     ITypeInfo *ti;
4179     HRESULT hr;
4180 
4181     TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember,
4182             debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
4183             pExcepInfo, puArgErr);
4184 
4185     hr = get_typeinfo(ITextDocument_tid, &ti);
4186     if (SUCCEEDED(hr))
4187         hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4188     return hr;
4189 }
4190 
ITextDocument2Old_fnGetName(ITextDocument2Old * iface,BSTR * pName)4191 static HRESULT WINAPI ITextDocument2Old_fnGetName(ITextDocument2Old *iface, BSTR *pName)
4192 {
4193     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4194     FIXME("stub %p\n",This);
4195     return E_NOTIMPL;
4196 }
4197 
ITextDocument2Old_fnGetSelection(ITextDocument2Old * iface,ITextSelection ** selection)4198 static HRESULT WINAPI ITextDocument2Old_fnGetSelection(ITextDocument2Old *iface, ITextSelection **selection)
4199 {
4200     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4201 
4202     TRACE("(%p)->(%p)\n", iface, selection);
4203 
4204     if (!selection)
4205       return E_INVALIDARG;
4206 
4207     if (!This->txtSel) {
4208       This->txtSel = CreateTextSelection(This);
4209       if (!This->txtSel) {
4210         *selection = NULL;
4211         return E_OUTOFMEMORY;
4212       }
4213     }
4214 
4215     *selection = &This->txtSel->ITextSelection_iface;
4216     ITextSelection_AddRef(*selection);
4217     return S_OK;
4218 }
4219 
ITextDocument2Old_fnGetStoryCount(ITextDocument2Old * iface,LONG * pCount)4220 static HRESULT WINAPI ITextDocument2Old_fnGetStoryCount(ITextDocument2Old *iface, LONG *pCount)
4221 {
4222     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4223     FIXME("stub %p\n",This);
4224     return E_NOTIMPL;
4225 }
4226 
ITextDocument2Old_fnGetStoryRanges(ITextDocument2Old * iface,ITextStoryRanges ** ppStories)4227 static HRESULT WINAPI ITextDocument2Old_fnGetStoryRanges(ITextDocument2Old *iface,
4228                                                          ITextStoryRanges **ppStories)
4229 {
4230     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4231     FIXME("stub %p\n",This);
4232     return E_NOTIMPL;
4233 }
4234 
ITextDocument2Old_fnGetSaved(ITextDocument2Old * iface,LONG * pValue)4235 static HRESULT WINAPI ITextDocument2Old_fnGetSaved(ITextDocument2Old *iface, LONG *pValue)
4236 {
4237     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4238     FIXME("stub %p\n",This);
4239     return E_NOTIMPL;
4240 }
4241 
ITextDocument2Old_fnSetSaved(ITextDocument2Old * iface,LONG Value)4242 static HRESULT WINAPI ITextDocument2Old_fnSetSaved(ITextDocument2Old *iface, LONG Value)
4243 {
4244     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4245     FIXME("stub %p\n",This);
4246     return E_NOTIMPL;
4247 }
4248 
ITextDocument2Old_fnGetDefaultTabStop(ITextDocument2Old * iface,float * pValue)4249 static HRESULT WINAPI ITextDocument2Old_fnGetDefaultTabStop(ITextDocument2Old *iface, float *pValue)
4250 {
4251     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4252     FIXME("stub %p\n",This);
4253     return E_NOTIMPL;
4254 }
4255 
ITextDocument2Old_fnSetDefaultTabStop(ITextDocument2Old * iface,float Value)4256 static HRESULT WINAPI ITextDocument2Old_fnSetDefaultTabStop(ITextDocument2Old *iface, float Value)
4257 {
4258     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4259     FIXME("stub %p\n",This);
4260     return E_NOTIMPL;
4261 }
4262 
ITextDocument2Old_fnNew(ITextDocument2Old * iface)4263 static HRESULT WINAPI ITextDocument2Old_fnNew(ITextDocument2Old *iface)
4264 {
4265     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4266     FIXME("stub %p\n",This);
4267     return E_NOTIMPL;
4268 }
4269 
ITextDocument2Old_fnOpen(ITextDocument2Old * iface,VARIANT * pVar,LONG Flags,LONG CodePage)4270 static HRESULT WINAPI ITextDocument2Old_fnOpen(ITextDocument2Old *iface, VARIANT *pVar,
4271                                                LONG Flags, LONG CodePage)
4272 {
4273     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4274     FIXME("stub %p\n",This);
4275     return E_NOTIMPL;
4276 }
4277 
ITextDocument2Old_fnSave(ITextDocument2Old * iface,VARIANT * pVar,LONG Flags,LONG CodePage)4278 static HRESULT WINAPI ITextDocument2Old_fnSave(ITextDocument2Old *iface, VARIANT *pVar,
4279                                                LONG Flags, LONG CodePage)
4280 {
4281     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4282     FIXME("stub %p\n",This);
4283     return E_NOTIMPL;
4284 }
4285 
ITextDocument2Old_fnFreeze(ITextDocument2Old * iface,LONG * pCount)4286 static HRESULT WINAPI ITextDocument2Old_fnFreeze(ITextDocument2Old *iface, LONG *pCount)
4287 {
4288     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4289     FIXME("stub %p\n",This);
4290     return E_NOTIMPL;
4291 }
4292 
ITextDocument2Old_fnUnfreeze(ITextDocument2Old * iface,LONG * pCount)4293 static HRESULT WINAPI ITextDocument2Old_fnUnfreeze(ITextDocument2Old *iface, LONG *pCount)
4294 {
4295     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4296     FIXME("stub %p\n",This);
4297     return E_NOTIMPL;
4298 }
4299 
ITextDocument2Old_fnBeginEditCollection(ITextDocument2Old * iface)4300 static HRESULT WINAPI ITextDocument2Old_fnBeginEditCollection(ITextDocument2Old *iface)
4301 {
4302     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4303     FIXME("stub %p\n",This);
4304     return E_NOTIMPL;
4305 }
4306 
ITextDocument2Old_fnEndEditCollection(ITextDocument2Old * iface)4307 static HRESULT WINAPI ITextDocument2Old_fnEndEditCollection(ITextDocument2Old *iface)
4308 {
4309     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4310     FIXME("stub %p\n",This);
4311     return E_NOTIMPL;
4312 }
4313 
ITextDocument2Old_fnUndo(ITextDocument2Old * iface,LONG Count,LONG * prop)4314 static HRESULT WINAPI ITextDocument2Old_fnUndo(ITextDocument2Old *iface, LONG Count, LONG *prop)
4315 {
4316     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4317     FIXME("stub %p\n",This);
4318     return E_NOTIMPL;
4319 }
4320 
ITextDocument2Old_fnRedo(ITextDocument2Old * iface,LONG Count,LONG * prop)4321 static HRESULT WINAPI ITextDocument2Old_fnRedo(ITextDocument2Old *iface, LONG Count, LONG *prop)
4322 {
4323     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4324     FIXME("stub %p\n",This);
4325     return E_NOTIMPL;
4326 }
4327 
CreateITextRange(IRichEditOleImpl * reOle,LONG start,LONG end,ITextRange ** ppRange)4328 static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, ITextRange** ppRange)
4329 {
4330     ITextRangeImpl *txtRge = heap_alloc(sizeof(ITextRangeImpl));
4331 
4332     if (!txtRge)
4333         return E_OUTOFMEMORY;
4334     txtRge->ITextRange_iface.lpVtbl = &trvt;
4335     txtRge->ref = 1;
4336     txtRge->child.reole = reOle;
4337     txtRge->start = start;
4338     txtRge->end = end;
4339     list_add_head(&reOle->rangelist, &txtRge->child.entry);
4340     *ppRange = &txtRge->ITextRange_iface;
4341     return S_OK;
4342 }
4343 
ITextDocument2Old_fnRange(ITextDocument2Old * iface,LONG cp1,LONG cp2,ITextRange ** ppRange)4344 static HRESULT WINAPI ITextDocument2Old_fnRange(ITextDocument2Old *iface, LONG cp1, LONG cp2,
4345                                                 ITextRange **ppRange)
4346 {
4347     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4348 
4349     TRACE("%p %p %d %d\n", This, ppRange, cp1, cp2);
4350     if (!ppRange)
4351         return E_INVALIDARG;
4352 
4353     cp2range(This->editor, &cp1, &cp2);
4354     return CreateITextRange(This, cp1, cp2, ppRange);
4355 }
4356 
ITextDocument2Old_fnRangeFromPoint(ITextDocument2Old * iface,LONG x,LONG y,ITextRange ** ppRange)4357 static HRESULT WINAPI ITextDocument2Old_fnRangeFromPoint(ITextDocument2Old *iface, LONG x, LONG y,
4358                                                          ITextRange **ppRange)
4359 {
4360     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4361     FIXME("stub %p\n",This);
4362     return E_NOTIMPL;
4363 }
4364 
4365 /* ITextDocument2Old methods */
ITextDocument2Old_fnAttachMsgFilter(ITextDocument2Old * iface,IUnknown * filter)4366 static HRESULT WINAPI ITextDocument2Old_fnAttachMsgFilter(ITextDocument2Old *iface, IUnknown *filter)
4367 {
4368     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4369 
4370     FIXME("(%p)->(%p): stub\n", This, filter);
4371 
4372     return E_NOTIMPL;
4373 }
4374 
ITextDocument2Old_fnSetEffectColor(ITextDocument2Old * iface,LONG index,COLORREF cr)4375 static HRESULT WINAPI ITextDocument2Old_fnSetEffectColor(ITextDocument2Old *iface, LONG index, COLORREF cr)
4376 {
4377     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4378 
4379     FIXME("(%p)->(%d, 0x%x): stub\n", This, index, cr);
4380 
4381     return E_NOTIMPL;
4382 }
4383 
ITextDocument2Old_fnGetEffectColor(ITextDocument2Old * iface,LONG index,COLORREF * cr)4384 static HRESULT WINAPI ITextDocument2Old_fnGetEffectColor(ITextDocument2Old *iface, LONG index, COLORREF *cr)
4385 {
4386     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4387 
4388     FIXME("(%p)->(%d, %p): stub\n", This, index, cr);
4389 
4390     return E_NOTIMPL;
4391 }
4392 
ITextDocument2Old_fnGetCaretType(ITextDocument2Old * iface,LONG * type)4393 static HRESULT WINAPI ITextDocument2Old_fnGetCaretType(ITextDocument2Old *iface, LONG *type)
4394 {
4395     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4396 
4397     FIXME("(%p)->(%p): stub\n", This, type);
4398 
4399     return E_NOTIMPL;
4400 }
4401 
ITextDocument2Old_fnSetCaretType(ITextDocument2Old * iface,LONG type)4402 static HRESULT WINAPI ITextDocument2Old_fnSetCaretType(ITextDocument2Old *iface, LONG type)
4403 {
4404     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4405 
4406     FIXME("(%p)->(%d): stub\n", This, type);
4407 
4408     return E_NOTIMPL;
4409 }
4410 
ITextDocument2Old_fnGetImmContext(ITextDocument2Old * iface,LONG * context)4411 static HRESULT WINAPI ITextDocument2Old_fnGetImmContext(ITextDocument2Old *iface, LONG *context)
4412 {
4413     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4414 
4415     FIXME("(%p)->(%p): stub\n", This, context);
4416 
4417     return E_NOTIMPL;
4418 }
4419 
ITextDocument2Old_fnReleaseImmContext(ITextDocument2Old * iface,LONG context)4420 static HRESULT WINAPI ITextDocument2Old_fnReleaseImmContext(ITextDocument2Old *iface, LONG context)
4421 {
4422     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4423 
4424     FIXME("(%p)->(%d): stub\n", This, context);
4425 
4426     return E_NOTIMPL;
4427 }
4428 
ITextDocument2Old_fnGetPreferredFont(ITextDocument2Old * iface,LONG cp,LONG charrep,LONG options,LONG current_charrep,LONG current_fontsize,BSTR * bstr,LONG * pitch_family,LONG * new_fontsize)4429 static HRESULT WINAPI ITextDocument2Old_fnGetPreferredFont(ITextDocument2Old *iface, LONG cp, LONG charrep,
4430                                                            LONG options, LONG current_charrep, LONG current_fontsize,
4431                                                            BSTR *bstr, LONG *pitch_family, LONG *new_fontsize)
4432 {
4433     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4434 
4435     FIXME("(%p)->(%d, %d, %d, %d, %d, %p, %p, %p): stub\n", This, cp, charrep, options, current_charrep,
4436           current_fontsize, bstr, pitch_family, new_fontsize);
4437 
4438     return E_NOTIMPL;
4439 }
4440 
ITextDocument2Old_fnGetNotificationMode(ITextDocument2Old * iface,LONG * mode)4441 static HRESULT WINAPI ITextDocument2Old_fnGetNotificationMode(ITextDocument2Old *iface, LONG *mode)
4442 {
4443     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4444 
4445     FIXME("(%p)->(%p): stub\n", This, mode);
4446 
4447     return E_NOTIMPL;
4448 }
4449 
ITextDocument2Old_fnSetNotificationMode(ITextDocument2Old * iface,LONG mode)4450 static HRESULT WINAPI ITextDocument2Old_fnSetNotificationMode(ITextDocument2Old *iface, LONG mode)
4451 {
4452     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4453 
4454     FIXME("(%p)->(0x%x): stub\n", This, mode);
4455 
4456     return E_NOTIMPL;
4457 }
4458 
ITextDocument2Old_fnGetClientRect(ITextDocument2Old * iface,LONG type,LONG * left,LONG * top,LONG * right,LONG * bottom)4459 static HRESULT WINAPI ITextDocument2Old_fnGetClientRect(ITextDocument2Old *iface, LONG type, LONG *left, LONG *top,
4460                                                         LONG *right, LONG *bottom)
4461 {
4462     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4463 
4464     FIXME("(%p)->(%d, %p, %p, %p, %p): stub\n", This, type, left, top, right, bottom);
4465 
4466     return E_NOTIMPL;
4467 }
4468 
ITextDocument2Old_fnGetSelectionEx(ITextDocument2Old * iface,ITextSelection ** selection)4469 static HRESULT WINAPI ITextDocument2Old_fnGetSelectionEx(ITextDocument2Old *iface, ITextSelection **selection)
4470 {
4471     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4472 
4473     FIXME("(%p)->(%p): stub\n", This, selection);
4474 
4475     return E_NOTIMPL;
4476 }
4477 
ITextDocument2Old_fnGetWindow(ITextDocument2Old * iface,LONG * hwnd)4478 static HRESULT WINAPI ITextDocument2Old_fnGetWindow(ITextDocument2Old *iface, LONG *hwnd)
4479 {
4480     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4481 
4482     FIXME("(%p)->(%p): stub\n", This, hwnd);
4483 
4484     return E_NOTIMPL;
4485 }
4486 
ITextDocument2Old_fnGetFEFlags(ITextDocument2Old * iface,LONG * flags)4487 static HRESULT WINAPI ITextDocument2Old_fnGetFEFlags(ITextDocument2Old *iface, LONG *flags)
4488 {
4489     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4490 
4491     FIXME("(%p)->(%p): stub\n", This, flags);
4492 
4493     return E_NOTIMPL;
4494 }
4495 
ITextDocument2Old_fnUpdateWindow(ITextDocument2Old * iface)4496 static HRESULT WINAPI ITextDocument2Old_fnUpdateWindow(ITextDocument2Old *iface)
4497 {
4498     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4499 
4500     FIXME("(%p): stub\n", This);
4501 
4502     return E_NOTIMPL;
4503 }
4504 
ITextDocument2Old_fnCheckTextLimit(ITextDocument2Old * iface,LONG cch,LONG * exceed)4505 static HRESULT WINAPI ITextDocument2Old_fnCheckTextLimit(ITextDocument2Old *iface, LONG cch, LONG *exceed)
4506 {
4507     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4508 
4509     FIXME("(%p)->(%d, %p): stub\n", This, cch, exceed);
4510 
4511     return E_NOTIMPL;
4512 }
4513 
ITextDocument2Old_fnIMEInProgress(ITextDocument2Old * iface,LONG mode)4514 static HRESULT WINAPI ITextDocument2Old_fnIMEInProgress(ITextDocument2Old *iface, LONG mode)
4515 {
4516     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4517 
4518     FIXME("(%p)->(0x%x): stub\n", This, mode);
4519 
4520     return E_NOTIMPL;
4521 }
4522 
ITextDocument2Old_fnSysBeep(ITextDocument2Old * iface)4523 static HRESULT WINAPI ITextDocument2Old_fnSysBeep(ITextDocument2Old *iface)
4524 {
4525     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4526 
4527     FIXME("(%p): stub\n", This);
4528 
4529     return E_NOTIMPL;
4530 }
4531 
ITextDocument2Old_fnUpdate(ITextDocument2Old * iface,LONG mode)4532 static HRESULT WINAPI ITextDocument2Old_fnUpdate(ITextDocument2Old *iface, LONG mode)
4533 {
4534     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4535 
4536     FIXME("(%p)->(0x%x): stub\n", This, mode);
4537 
4538     return E_NOTIMPL;
4539 }
4540 
ITextDocument2Old_fnNotify(ITextDocument2Old * iface,LONG notify)4541 static HRESULT WINAPI ITextDocument2Old_fnNotify(ITextDocument2Old *iface, LONG notify)
4542 {
4543     IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4544 
4545     FIXME("(%p)->(%d): stub\n", This, notify);
4546 
4547     return E_NOTIMPL;
4548 }
4549 
4550 static const ITextDocument2OldVtbl tdvt = {
4551     ITextDocument2Old_fnQueryInterface,
4552     ITextDocument2Old_fnAddRef,
4553     ITextDocument2Old_fnRelease,
4554     ITextDocument2Old_fnGetTypeInfoCount,
4555     ITextDocument2Old_fnGetTypeInfo,
4556     ITextDocument2Old_fnGetIDsOfNames,
4557     ITextDocument2Old_fnInvoke,
4558     ITextDocument2Old_fnGetName,
4559     ITextDocument2Old_fnGetSelection,
4560     ITextDocument2Old_fnGetStoryCount,
4561     ITextDocument2Old_fnGetStoryRanges,
4562     ITextDocument2Old_fnGetSaved,
4563     ITextDocument2Old_fnSetSaved,
4564     ITextDocument2Old_fnGetDefaultTabStop,
4565     ITextDocument2Old_fnSetDefaultTabStop,
4566     ITextDocument2Old_fnNew,
4567     ITextDocument2Old_fnOpen,
4568     ITextDocument2Old_fnSave,
4569     ITextDocument2Old_fnFreeze,
4570     ITextDocument2Old_fnUnfreeze,
4571     ITextDocument2Old_fnBeginEditCollection,
4572     ITextDocument2Old_fnEndEditCollection,
4573     ITextDocument2Old_fnUndo,
4574     ITextDocument2Old_fnRedo,
4575     ITextDocument2Old_fnRange,
4576     ITextDocument2Old_fnRangeFromPoint,
4577     /* ITextDocument2Old methods */
4578     ITextDocument2Old_fnAttachMsgFilter,
4579     ITextDocument2Old_fnSetEffectColor,
4580     ITextDocument2Old_fnGetEffectColor,
4581     ITextDocument2Old_fnGetCaretType,
4582     ITextDocument2Old_fnSetCaretType,
4583     ITextDocument2Old_fnGetImmContext,
4584     ITextDocument2Old_fnReleaseImmContext,
4585     ITextDocument2Old_fnGetPreferredFont,
4586     ITextDocument2Old_fnGetNotificationMode,
4587     ITextDocument2Old_fnSetNotificationMode,
4588     ITextDocument2Old_fnGetClientRect,
4589     ITextDocument2Old_fnGetSelectionEx,
4590     ITextDocument2Old_fnGetWindow,
4591     ITextDocument2Old_fnGetFEFlags,
4592     ITextDocument2Old_fnUpdateWindow,
4593     ITextDocument2Old_fnCheckTextLimit,
4594     ITextDocument2Old_fnIMEInProgress,
4595     ITextDocument2Old_fnSysBeep,
4596     ITextDocument2Old_fnUpdate,
4597     ITextDocument2Old_fnNotify
4598 };
4599 
4600 /* ITextSelection */
ITextSelection_fnQueryInterface(ITextSelection * me,REFIID riid,void ** ppvObj)4601 static HRESULT WINAPI ITextSelection_fnQueryInterface(
4602     ITextSelection *me,
4603     REFIID riid,
4604     void **ppvObj)
4605 {
4606     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4607 
4608     *ppvObj = NULL;
4609     if (IsEqualGUID(riid, &IID_IUnknown)
4610         || IsEqualGUID(riid, &IID_IDispatch)
4611         || IsEqualGUID(riid, &IID_ITextRange)
4612         || IsEqualGUID(riid, &IID_ITextSelection))
4613     {
4614         *ppvObj = me;
4615         ITextSelection_AddRef(me);
4616         return S_OK;
4617     }
4618     else if (IsEqualGUID(riid, &IID_Igetrichole))
4619     {
4620         *ppvObj = This->reOle;
4621         return S_OK;
4622     }
4623 
4624     return E_NOINTERFACE;
4625 }
4626 
ITextSelection_fnAddRef(ITextSelection * me)4627 static ULONG WINAPI ITextSelection_fnAddRef(ITextSelection *me)
4628 {
4629     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4630     return InterlockedIncrement(&This->ref);
4631 }
4632 
ITextSelection_fnRelease(ITextSelection * me)4633 static ULONG WINAPI ITextSelection_fnRelease(ITextSelection *me)
4634 {
4635     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4636     ULONG ref = InterlockedDecrement(&This->ref);
4637     if (ref == 0)
4638         heap_free(This);
4639     return ref;
4640 }
4641 
ITextSelection_fnGetTypeInfoCount(ITextSelection * me,UINT * pctinfo)4642 static HRESULT WINAPI ITextSelection_fnGetTypeInfoCount(ITextSelection *me, UINT *pctinfo)
4643 {
4644     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4645     TRACE("(%p)->(%p)\n", This, pctinfo);
4646     *pctinfo = 1;
4647     return S_OK;
4648 }
4649 
ITextSelection_fnGetTypeInfo(ITextSelection * me,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)4650 static HRESULT WINAPI ITextSelection_fnGetTypeInfo(ITextSelection *me, UINT iTInfo, LCID lcid,
4651     ITypeInfo **ppTInfo)
4652 {
4653     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4654     HRESULT hr;
4655 
4656     TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
4657 
4658     hr = get_typeinfo(ITextSelection_tid, ppTInfo);
4659     if (SUCCEEDED(hr))
4660         ITypeInfo_AddRef(*ppTInfo);
4661     return hr;
4662 }
4663 
ITextSelection_fnGetIDsOfNames(ITextSelection * me,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)4664 static HRESULT WINAPI ITextSelection_fnGetIDsOfNames(ITextSelection *me, REFIID riid,
4665     LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
4666 {
4667     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4668     ITypeInfo *ti;
4669     HRESULT hr;
4670 
4671     TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
4672             rgDispId);
4673 
4674     hr = get_typeinfo(ITextSelection_tid, &ti);
4675     if (SUCCEEDED(hr))
4676         hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
4677     return hr;
4678 }
4679 
ITextSelection_fnInvoke(ITextSelection * me,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)4680 static HRESULT WINAPI ITextSelection_fnInvoke(
4681     ITextSelection *me,
4682     DISPID dispIdMember,
4683     REFIID riid,
4684     LCID lcid,
4685     WORD wFlags,
4686     DISPPARAMS *pDispParams,
4687     VARIANT *pVarResult,
4688     EXCEPINFO *pExcepInfo,
4689     UINT *puArgErr)
4690 {
4691     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4692     ITypeInfo *ti;
4693     HRESULT hr;
4694 
4695     TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid), lcid,
4696             wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4697 
4698     hr = get_typeinfo(ITextSelection_tid, &ti);
4699     if (SUCCEEDED(hr))
4700         hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4701     return hr;
4702 }
4703 
4704 /*** ITextRange methods ***/
ITextSelection_fnGetText(ITextSelection * me,BSTR * pbstr)4705 static HRESULT WINAPI ITextSelection_fnGetText(ITextSelection *me, BSTR *pbstr)
4706 {
4707     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4708     ME_Cursor *start = NULL, *end = NULL;
4709     int nChars, endOfs;
4710     BOOL bEOP;
4711 
4712     TRACE("(%p)->(%p)\n", This, pbstr);
4713 
4714     if (!This->reOle)
4715         return CO_E_RELEASED;
4716 
4717     if (!pbstr)
4718         return E_INVALIDARG;
4719 
4720     ME_GetSelection(This->reOle->editor, &start, &end);
4721     endOfs = ME_GetCursorOfs(end);
4722     nChars = endOfs - ME_GetCursorOfs(start);
4723     if (!nChars)
4724     {
4725         *pbstr = NULL;
4726         return S_OK;
4727     }
4728 
4729     *pbstr = SysAllocStringLen(NULL, nChars);
4730     if (!*pbstr)
4731         return E_OUTOFMEMORY;
4732 
4733     bEOP = (end->pRun->next->type == diTextEnd && endOfs > ME_GetTextLength(This->reOle->editor));
4734     ME_GetTextW(This->reOle->editor, *pbstr, nChars, start, nChars, FALSE, bEOP);
4735     TRACE("%s\n", wine_dbgstr_w(*pbstr));
4736 
4737     return S_OK;
4738 }
4739 
ITextSelection_fnSetText(ITextSelection * me,BSTR str)4740 static HRESULT WINAPI ITextSelection_fnSetText(ITextSelection *me, BSTR str)
4741 {
4742     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4743     ME_TextEditor *editor;
4744     int len, to, from;
4745 
4746     TRACE("(%p)->(%s)\n", This, debugstr_w(str));
4747 
4748     if (!This->reOle)
4749         return CO_E_RELEASED;
4750 
4751     editor = This->reOle->editor;
4752     len = lstrlenW(str);
4753     ME_GetSelectionOfs(editor, &from, &to);
4754     ME_ReplaceSel(editor, FALSE, str, len);
4755 
4756     if (len < to - from)
4757         textranges_update_ranges(This->reOle, from, len, RANGE_UPDATE_DELETE);
4758 
4759     return S_OK;
4760 }
4761 
ITextSelection_fnGetChar(ITextSelection * me,LONG * pch)4762 static HRESULT WINAPI ITextSelection_fnGetChar(ITextSelection *me, LONG *pch)
4763 {
4764     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4765     ME_Cursor *start = NULL, *end = NULL;
4766 
4767     TRACE("(%p)->(%p)\n", This, pch);
4768 
4769     if (!This->reOle)
4770         return CO_E_RELEASED;
4771 
4772     if (!pch)
4773         return E_INVALIDARG;
4774 
4775     ME_GetSelection(This->reOle->editor, &start, &end);
4776     return range_GetChar(This->reOle->editor, start, pch);
4777 }
4778 
ITextSelection_fnSetChar(ITextSelection * me,LONG ch)4779 static HRESULT WINAPI ITextSelection_fnSetChar(ITextSelection *me, LONG ch)
4780 {
4781     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4782 
4783     FIXME("(%p)->(%x): stub\n", This, ch);
4784 
4785     if (!This->reOle)
4786         return CO_E_RELEASED;
4787 
4788     return E_NOTIMPL;
4789 }
4790 
ITextSelection_fnGetDuplicate(ITextSelection * me,ITextRange ** range)4791 static HRESULT WINAPI ITextSelection_fnGetDuplicate(ITextSelection *me, ITextRange **range)
4792 {
4793     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4794     LONG start, end;
4795 
4796     TRACE("(%p)->(%p)\n", This, range);
4797 
4798     if (!This->reOle)
4799         return CO_E_RELEASED;
4800 
4801     if (!range)
4802         return E_INVALIDARG;
4803 
4804     ITextSelection_GetStart(me, &start);
4805     ITextSelection_GetEnd(me, &end);
4806     return CreateITextRange(This->reOle, start, end, range);
4807 }
4808 
ITextSelection_fnGetFormattedText(ITextSelection * me,ITextRange ** range)4809 static HRESULT WINAPI ITextSelection_fnGetFormattedText(ITextSelection *me, ITextRange **range)
4810 {
4811     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4812 
4813     FIXME("(%p)->(%p): stub\n", This, range);
4814 
4815     if (!This->reOle)
4816         return CO_E_RELEASED;
4817 
4818     return E_NOTIMPL;
4819 }
4820 
ITextSelection_fnSetFormattedText(ITextSelection * me,ITextRange * range)4821 static HRESULT WINAPI ITextSelection_fnSetFormattedText(ITextSelection *me, ITextRange *range)
4822 {
4823     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4824 
4825     FIXME("(%p)->(%p): stub\n", This, range);
4826 
4827     if (!This->reOle)
4828         return CO_E_RELEASED;
4829 
4830     FIXME("not implemented\n");
4831     return E_NOTIMPL;
4832 }
4833 
ITextSelection_fnGetStart(ITextSelection * me,LONG * pcpFirst)4834 static HRESULT WINAPI ITextSelection_fnGetStart(ITextSelection *me, LONG *pcpFirst)
4835 {
4836     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4837     LONG lim;
4838 
4839     TRACE("(%p)->(%p)\n", This, pcpFirst);
4840 
4841     if (!This->reOle)
4842         return CO_E_RELEASED;
4843 
4844     if (!pcpFirst)
4845         return E_INVALIDARG;
4846     ME_GetSelectionOfs(This->reOle->editor, pcpFirst, &lim);
4847     return S_OK;
4848 }
4849 
ITextSelection_fnSetStart(ITextSelection * me,LONG value)4850 static HRESULT WINAPI ITextSelection_fnSetStart(ITextSelection *me, LONG value)
4851 {
4852     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4853     LONG start, end;
4854     HRESULT hr;
4855 
4856     TRACE("(%p)->(%d)\n", This, value);
4857 
4858     if (!This->reOle)
4859         return CO_E_RELEASED;
4860 
4861     ME_GetSelectionOfs(This->reOle->editor, &start, &end);
4862     hr = textrange_setstart(This->reOle, value, &start, &end);
4863     if (hr == S_OK)
4864         set_selection(This->reOle->editor, start, end);
4865 
4866     return hr;
4867 }
4868 
ITextSelection_fnGetEnd(ITextSelection * me,LONG * pcpLim)4869 static HRESULT WINAPI ITextSelection_fnGetEnd(ITextSelection *me, LONG *pcpLim)
4870 {
4871     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4872     LONG first;
4873 
4874     TRACE("(%p)->(%p)\n", This, pcpLim);
4875 
4876     if (!This->reOle)
4877         return CO_E_RELEASED;
4878 
4879     if (!pcpLim)
4880         return E_INVALIDARG;
4881     ME_GetSelectionOfs(This->reOle->editor, &first, pcpLim);
4882     return S_OK;
4883 }
4884 
ITextSelection_fnSetEnd(ITextSelection * me,LONG value)4885 static HRESULT WINAPI ITextSelection_fnSetEnd(ITextSelection *me, LONG value)
4886 {
4887     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4888     LONG start, end;
4889     HRESULT hr;
4890 
4891     TRACE("(%p)->(%d)\n", This, value);
4892 
4893     if (!This->reOle)
4894         return CO_E_RELEASED;
4895 
4896     ME_GetSelectionOfs(This->reOle->editor, &start, &end);
4897     hr = textrange_setend(This->reOle, value, &start, &end);
4898     if (hr == S_OK)
4899         set_selection(This->reOle->editor, start, end);
4900 
4901     return hr;
4902 }
4903 
ITextSelection_fnGetFont(ITextSelection * me,ITextFont ** font)4904 static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **font)
4905 {
4906     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4907     ITextRange *range = NULL;
4908     HRESULT hr;
4909 
4910     TRACE("(%p)->(%p)\n", This, font);
4911 
4912     if (!This->reOle)
4913         return CO_E_RELEASED;
4914 
4915     if (!font)
4916         return E_INVALIDARG;
4917 
4918     ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
4919     hr = create_textfont(range, NULL, font);
4920     ITextRange_Release(range);
4921     return hr;
4922 }
4923 
ITextSelection_fnSetFont(ITextSelection * me,ITextFont * font)4924 static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *font)
4925 {
4926     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4927     ITextRange *range = NULL;
4928 
4929     TRACE("(%p)->(%p)\n", This, font);
4930 
4931     if (!font)
4932         return E_INVALIDARG;
4933 
4934     if (!This->reOle)
4935         return CO_E_RELEASED;
4936 
4937     ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
4938     textrange_set_font(range, font);
4939     ITextRange_Release(range);
4940     return S_OK;
4941 }
4942 
ITextSelection_fnGetPara(ITextSelection * me,ITextPara ** para)4943 static HRESULT WINAPI ITextSelection_fnGetPara(ITextSelection *me, ITextPara **para)
4944 {
4945     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4946     ITextRange *range = NULL;
4947     HRESULT hr;
4948 
4949     TRACE("(%p)->(%p)\n", This, para);
4950 
4951     if (!This->reOle)
4952         return CO_E_RELEASED;
4953 
4954     if (!para)
4955         return E_INVALIDARG;
4956 
4957     ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
4958     hr = create_textpara(range, para);
4959     ITextRange_Release(range);
4960     return hr;
4961 }
4962 
ITextSelection_fnSetPara(ITextSelection * me,ITextPara * para)4963 static HRESULT WINAPI ITextSelection_fnSetPara(ITextSelection *me, ITextPara *para)
4964 {
4965     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4966 
4967     FIXME("(%p)->(%p): stub\n", This, para);
4968 
4969     if (!This->reOle)
4970         return CO_E_RELEASED;
4971 
4972     FIXME("not implemented\n");
4973     return E_NOTIMPL;
4974 }
4975 
ITextSelection_fnGetStoryLength(ITextSelection * me,LONG * length)4976 static HRESULT WINAPI ITextSelection_fnGetStoryLength(ITextSelection *me, LONG *length)
4977 {
4978     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4979 
4980     TRACE("(%p)->(%p)\n", This, length);
4981 
4982     if (!This->reOle)
4983         return CO_E_RELEASED;
4984 
4985     return textrange_get_storylength(This->reOle->editor, length);
4986 }
4987 
ITextSelection_fnGetStoryType(ITextSelection * me,LONG * value)4988 static HRESULT WINAPI ITextSelection_fnGetStoryType(ITextSelection *me, LONG *value)
4989 {
4990     ITextSelectionImpl *This = impl_from_ITextSelection(me);
4991 
4992     TRACE("(%p)->(%p)\n", This, value);
4993 
4994     if (!This->reOle)
4995         return CO_E_RELEASED;
4996 
4997     if (!value)
4998         return E_INVALIDARG;
4999 
5000     *value = tomUnknownStory;
5001     return S_OK;
5002 }
5003 
ITextSelection_fnCollapse(ITextSelection * me,LONG bStart)5004 static HRESULT WINAPI ITextSelection_fnCollapse(ITextSelection *me, LONG bStart)
5005 {
5006     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5007     LONG start, end;
5008     HRESULT hres;
5009 
5010     TRACE("(%p)->(%d)\n", This, bStart);
5011 
5012     if (!This->reOle)
5013         return CO_E_RELEASED;
5014 
5015     ME_GetSelectionOfs(This->reOle->editor, &start, &end);
5016     hres = range_Collapse(bStart, &start, &end);
5017     if (SUCCEEDED(hres))
5018         set_selection(This->reOle->editor, start, end);
5019     return hres;
5020 }
5021 
ITextSelection_fnExpand(ITextSelection * me,LONG unit,LONG * delta)5022 static HRESULT WINAPI ITextSelection_fnExpand(ITextSelection *me, LONG unit, LONG *delta)
5023 {
5024     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5025     ITextRange *range = NULL;
5026     HRESULT hr;
5027 
5028     TRACE("(%p)->(%d %p)\n", This, unit, delta);
5029 
5030     if (!This->reOle)
5031         return CO_E_RELEASED;
5032 
5033     ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5034     hr = textrange_expand(range, unit, delta);
5035     ITextRange_Release(range);
5036     return hr;
5037 }
5038 
ITextSelection_fnGetIndex(ITextSelection * me,LONG unit,LONG * index)5039 static HRESULT WINAPI ITextSelection_fnGetIndex(ITextSelection *me, LONG unit, LONG *index)
5040 {
5041     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5042 
5043     FIXME("(%p)->(%d %p): stub\n", This, unit, index);
5044 
5045     if (!This->reOle)
5046         return CO_E_RELEASED;
5047 
5048     return E_NOTIMPL;
5049 }
5050 
ITextSelection_fnSetIndex(ITextSelection * me,LONG unit,LONG index,LONG extend)5051 static HRESULT WINAPI ITextSelection_fnSetIndex(ITextSelection *me, LONG unit, LONG index,
5052     LONG extend)
5053 {
5054     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5055 
5056     FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend);
5057 
5058     if (!This->reOle)
5059         return CO_E_RELEASED;
5060 
5061     return E_NOTIMPL;
5062 }
5063 
ITextSelection_fnSetRange(ITextSelection * me,LONG anchor,LONG active)5064 static HRESULT WINAPI ITextSelection_fnSetRange(ITextSelection *me, LONG anchor, LONG active)
5065 {
5066     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5067 
5068     FIXME("(%p)->(%d %d): stub\n", This, anchor, active);
5069 
5070     if (!This->reOle)
5071         return CO_E_RELEASED;
5072 
5073     return E_NOTIMPL;
5074 }
5075 
ITextSelection_fnInRange(ITextSelection * me,ITextRange * range,LONG * ret)5076 static HRESULT WINAPI ITextSelection_fnInRange(ITextSelection *me, ITextRange *range, LONG *ret)
5077 {
5078     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5079     ITextSelection *selection = NULL;
5080     LONG start, end;
5081 
5082     TRACE("(%p)->(%p %p)\n", This, range, ret);
5083 
5084     if (ret)
5085         *ret = tomFalse;
5086 
5087     if (!This->reOle)
5088         return CO_E_RELEASED;
5089 
5090     if (!range)
5091         return S_FALSE;
5092 
5093     ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection);
5094     if (!selection)
5095         return S_FALSE;
5096     ITextSelection_Release(selection);
5097 
5098     ITextSelection_GetStart(me, &start);
5099     ITextSelection_GetEnd(me, &end);
5100     return textrange_inrange(start, end, range, ret);
5101 }
5102 
ITextSelection_fnInStory(ITextSelection * me,ITextRange * range,LONG * ret)5103 static HRESULT WINAPI ITextSelection_fnInStory(ITextSelection *me, ITextRange *range, LONG *ret)
5104 {
5105     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5106 
5107     FIXME("(%p)->(%p %p): stub\n", This, range, ret);
5108 
5109     if (!This->reOle)
5110         return CO_E_RELEASED;
5111 
5112     return E_NOTIMPL;
5113 }
5114 
ITextSelection_fnIsEqual(ITextSelection * me,ITextRange * range,LONG * ret)5115 static HRESULT WINAPI ITextSelection_fnIsEqual(ITextSelection *me, ITextRange *range, LONG *ret)
5116 {
5117     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5118     ITextSelection *selection = NULL;
5119     LONG start, end;
5120 
5121     TRACE("(%p)->(%p %p)\n", This, range, ret);
5122 
5123     if (ret)
5124         *ret = tomFalse;
5125 
5126     if (!This->reOle)
5127         return CO_E_RELEASED;
5128 
5129     if (!range)
5130         return S_FALSE;
5131 
5132     ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection);
5133     if (!selection)
5134         return S_FALSE;
5135     ITextSelection_Release(selection);
5136 
5137     ITextSelection_GetStart(me, &start);
5138     ITextSelection_GetEnd(me, &end);
5139     return textrange_isequal(start, end, range, ret);
5140 }
5141 
ITextSelection_fnSelect(ITextSelection * me)5142 static HRESULT WINAPI ITextSelection_fnSelect(ITextSelection *me)
5143 {
5144     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5145 
5146     TRACE("(%p)\n", This);
5147 
5148     if (!This->reOle)
5149         return CO_E_RELEASED;
5150 
5151     /* nothing to do */
5152     return S_OK;
5153 }
5154 
ITextSelection_fnStartOf(ITextSelection * me,LONG unit,LONG extend,LONG * delta)5155 static HRESULT WINAPI ITextSelection_fnStartOf(ITextSelection *me, LONG unit, LONG extend,
5156     LONG *delta)
5157 {
5158     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5159 
5160     FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
5161 
5162     if (!This->reOle)
5163         return CO_E_RELEASED;
5164 
5165     return E_NOTIMPL;
5166 }
5167 
ITextSelection_fnEndOf(ITextSelection * me,LONG unit,LONG extend,LONG * delta)5168 static HRESULT WINAPI ITextSelection_fnEndOf(ITextSelection *me, LONG unit, LONG extend,
5169     LONG *delta)
5170 {
5171     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5172 
5173     FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
5174 
5175     if (!This->reOle)
5176         return CO_E_RELEASED;
5177 
5178     return E_NOTIMPL;
5179 }
5180 
ITextSelection_fnMove(ITextSelection * me,LONG unit,LONG count,LONG * delta)5181 static HRESULT WINAPI ITextSelection_fnMove(ITextSelection *me, LONG unit, LONG count, LONG *delta)
5182 {
5183     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5184 
5185     FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
5186 
5187     if (!This->reOle)
5188         return CO_E_RELEASED;
5189 
5190     return E_NOTIMPL;
5191 }
5192 
ITextSelection_fnMoveStart(ITextSelection * me,LONG unit,LONG count,LONG * delta)5193 static HRESULT WINAPI ITextSelection_fnMoveStart(ITextSelection *me, LONG unit, LONG count,
5194     LONG *delta)
5195 {
5196     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5197 
5198     FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
5199 
5200     if (!This->reOle)
5201         return CO_E_RELEASED;
5202 
5203     return E_NOTIMPL;
5204 }
5205 
ITextSelection_fnMoveEnd(ITextSelection * me,LONG unit,LONG count,LONG * delta)5206 static HRESULT WINAPI ITextSelection_fnMoveEnd(ITextSelection *me, LONG unit, LONG count,
5207     LONG *delta)
5208 {
5209     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5210     ITextRange *range = NULL;
5211     HRESULT hr;
5212 
5213     TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta);
5214 
5215     if (!This->reOle)
5216         return CO_E_RELEASED;
5217 
5218     ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5219     hr = textrange_moveend(range, unit, count, delta);
5220     ITextRange_Release(range);
5221     return hr;
5222 }
5223 
ITextSelection_fnMoveWhile(ITextSelection * me,VARIANT * charset,LONG count,LONG * delta)5224 static HRESULT WINAPI ITextSelection_fnMoveWhile(ITextSelection *me, VARIANT *charset, LONG count,
5225     LONG *delta)
5226 {
5227     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5228 
5229     FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
5230 
5231     if (!This->reOle)
5232         return CO_E_RELEASED;
5233 
5234     return E_NOTIMPL;
5235 }
5236 
ITextSelection_fnMoveStartWhile(ITextSelection * me,VARIANT * charset,LONG count,LONG * delta)5237 static HRESULT WINAPI ITextSelection_fnMoveStartWhile(ITextSelection *me, VARIANT *charset, LONG count,
5238     LONG *delta)
5239 {
5240     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5241 
5242     FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
5243 
5244     if (!This->reOle)
5245         return CO_E_RELEASED;
5246 
5247     return E_NOTIMPL;
5248 }
5249 
ITextSelection_fnMoveEndWhile(ITextSelection * me,VARIANT * charset,LONG count,LONG * delta)5250 static HRESULT WINAPI ITextSelection_fnMoveEndWhile(ITextSelection *me, VARIANT *charset, LONG count,
5251     LONG *delta)
5252 {
5253     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5254 
5255     FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
5256 
5257     if (!This->reOle)
5258         return CO_E_RELEASED;
5259 
5260     return E_NOTIMPL;
5261 }
5262 
ITextSelection_fnMoveUntil(ITextSelection * me,VARIANT * charset,LONG count,LONG * delta)5263 static HRESULT WINAPI ITextSelection_fnMoveUntil(ITextSelection *me, VARIANT *charset, LONG count,
5264     LONG *delta)
5265 {
5266     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5267 
5268     FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
5269 
5270     if (!This->reOle)
5271         return CO_E_RELEASED;
5272 
5273     return E_NOTIMPL;
5274 }
5275 
ITextSelection_fnMoveStartUntil(ITextSelection * me,VARIANT * charset,LONG count,LONG * delta)5276 static HRESULT WINAPI ITextSelection_fnMoveStartUntil(ITextSelection *me, VARIANT *charset, LONG count,
5277     LONG *delta)
5278 {
5279     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5280 
5281     FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
5282 
5283     if (!This->reOle)
5284         return CO_E_RELEASED;
5285 
5286     return E_NOTIMPL;
5287 }
5288 
ITextSelection_fnMoveEndUntil(ITextSelection * me,VARIANT * charset,LONG count,LONG * delta)5289 static HRESULT WINAPI ITextSelection_fnMoveEndUntil(ITextSelection *me, VARIANT *charset, LONG count,
5290     LONG *delta)
5291 {
5292     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5293 
5294     FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
5295 
5296     if (!This->reOle)
5297         return CO_E_RELEASED;
5298 
5299     return E_NOTIMPL;
5300 }
5301 
ITextSelection_fnFindText(ITextSelection * me,BSTR text,LONG count,LONG flags,LONG * length)5302 static HRESULT WINAPI ITextSelection_fnFindText(ITextSelection *me, BSTR text, LONG count, LONG flags,
5303     LONG *length)
5304 {
5305     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5306 
5307     FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
5308 
5309     if (!This->reOle)
5310         return CO_E_RELEASED;
5311 
5312     FIXME("not implemented\n");
5313     return E_NOTIMPL;
5314 }
5315 
ITextSelection_fnFindTextStart(ITextSelection * me,BSTR text,LONG count,LONG flags,LONG * length)5316 static HRESULT WINAPI ITextSelection_fnFindTextStart(ITextSelection *me, BSTR text, LONG count,
5317     LONG flags, LONG *length)
5318 {
5319     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5320 
5321     FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
5322 
5323     if (!This->reOle)
5324         return CO_E_RELEASED;
5325 
5326     return E_NOTIMPL;
5327 }
5328 
ITextSelection_fnFindTextEnd(ITextSelection * me,BSTR text,LONG count,LONG flags,LONG * length)5329 static HRESULT WINAPI ITextSelection_fnFindTextEnd(ITextSelection *me, BSTR text, LONG count,
5330     LONG flags, LONG *length)
5331 {
5332     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5333 
5334     FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
5335 
5336     if (!This->reOle)
5337         return CO_E_RELEASED;
5338 
5339     return E_NOTIMPL;
5340 }
5341 
ITextSelection_fnDelete(ITextSelection * me,LONG unit,LONG count,LONG * delta)5342 static HRESULT WINAPI ITextSelection_fnDelete(ITextSelection *me, LONG unit, LONG count,
5343     LONG *delta)
5344 {
5345     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5346 
5347     FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
5348 
5349     if (!This->reOle)
5350         return CO_E_RELEASED;
5351 
5352     return E_NOTIMPL;
5353 }
5354 
ITextSelection_fnCut(ITextSelection * me,VARIANT * v)5355 static HRESULT WINAPI ITextSelection_fnCut(ITextSelection *me, VARIANT *v)
5356 {
5357     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5358 
5359     FIXME("(%p)->(%p): stub\n", This, v);
5360 
5361     if (!This->reOle)
5362         return CO_E_RELEASED;
5363 
5364     return E_NOTIMPL;
5365 }
5366 
ITextSelection_fnCopy(ITextSelection * me,VARIANT * v)5367 static HRESULT WINAPI ITextSelection_fnCopy(ITextSelection *me, VARIANT *v)
5368 {
5369     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5370 
5371     FIXME("(%p)->(%p): stub\n", This, v);
5372 
5373     if (!This->reOle)
5374         return CO_E_RELEASED;
5375 
5376     return E_NOTIMPL;
5377 }
5378 
ITextSelection_fnPaste(ITextSelection * me,VARIANT * v,LONG format)5379 static HRESULT WINAPI ITextSelection_fnPaste(ITextSelection *me, VARIANT *v, LONG format)
5380 {
5381     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5382 
5383     FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format);
5384 
5385     if (!This->reOle)
5386         return CO_E_RELEASED;
5387 
5388     return E_NOTIMPL;
5389 }
5390 
ITextSelection_fnCanPaste(ITextSelection * me,VARIANT * v,LONG format,LONG * ret)5391 static HRESULT WINAPI ITextSelection_fnCanPaste(ITextSelection *me, VARIANT *v, LONG format,
5392     LONG *ret)
5393 {
5394     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5395 
5396     FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret);
5397 
5398     if (!This->reOle)
5399         return CO_E_RELEASED;
5400 
5401     return E_NOTIMPL;
5402 }
5403 
ITextSelection_fnCanEdit(ITextSelection * me,LONG * ret)5404 static HRESULT WINAPI ITextSelection_fnCanEdit(ITextSelection *me, LONG *ret)
5405 {
5406     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5407 
5408     FIXME("(%p)->(%p): stub\n", This, ret);
5409 
5410     if (!This->reOle)
5411         return CO_E_RELEASED;
5412 
5413     return E_NOTIMPL;
5414 }
5415 
ITextSelection_fnChangeCase(ITextSelection * me,LONG type)5416 static HRESULT WINAPI ITextSelection_fnChangeCase(ITextSelection *me, LONG type)
5417 {
5418     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5419 
5420     FIXME("(%p)->(%d): stub\n", This, type);
5421 
5422     if (!This->reOle)
5423         return CO_E_RELEASED;
5424 
5425     return E_NOTIMPL;
5426 }
5427 
ITextSelection_fnGetPoint(ITextSelection * me,LONG type,LONG * cx,LONG * cy)5428 static HRESULT WINAPI ITextSelection_fnGetPoint(ITextSelection *me, LONG type, LONG *cx, LONG *cy)
5429 {
5430     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5431 
5432     FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy);
5433 
5434     if (!This->reOle)
5435         return CO_E_RELEASED;
5436 
5437     return E_NOTIMPL;
5438 }
5439 
ITextSelection_fnSetPoint(ITextSelection * me,LONG x,LONG y,LONG type,LONG extend)5440 static HRESULT WINAPI ITextSelection_fnSetPoint(ITextSelection *me, LONG x, LONG y, LONG type,
5441     LONG extend)
5442 {
5443     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5444 
5445     FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend);
5446 
5447     if (!This->reOle)
5448         return CO_E_RELEASED;
5449 
5450     return E_NOTIMPL;
5451 }
5452 
ITextSelection_fnScrollIntoView(ITextSelection * me,LONG value)5453 static HRESULT WINAPI ITextSelection_fnScrollIntoView(ITextSelection *me, LONG value)
5454 {
5455     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5456 
5457     FIXME("(%p)->(%d): stub\n", This, value);
5458 
5459     if (!This->reOle)
5460         return CO_E_RELEASED;
5461 
5462     return E_NOTIMPL;
5463 }
5464 
ITextSelection_fnGetEmbeddedObject(ITextSelection * me,IUnknown ** ppv)5465 static HRESULT WINAPI ITextSelection_fnGetEmbeddedObject(ITextSelection *me, IUnknown **ppv)
5466 {
5467     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5468 
5469     FIXME("(%p)->(%p): stub\n", This, ppv);
5470 
5471     if (!This->reOle)
5472         return CO_E_RELEASED;
5473 
5474     return E_NOTIMPL;
5475 }
5476 
5477 /*** ITextSelection methods ***/
ITextSelection_fnGetFlags(ITextSelection * me,LONG * flags)5478 static HRESULT WINAPI ITextSelection_fnGetFlags(ITextSelection *me, LONG *flags)
5479 {
5480     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5481 
5482     FIXME("(%p)->(%p): stub\n", This, flags);
5483 
5484     if (!This->reOle)
5485         return CO_E_RELEASED;
5486 
5487     return E_NOTIMPL;
5488 }
5489 
ITextSelection_fnSetFlags(ITextSelection * me,LONG flags)5490 static HRESULT WINAPI ITextSelection_fnSetFlags(ITextSelection *me, LONG flags)
5491 {
5492     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5493 
5494     FIXME("(%p)->(%x): stub\n", This, flags);
5495 
5496     if (!This->reOle)
5497         return CO_E_RELEASED;
5498 
5499     return E_NOTIMPL;
5500 }
5501 
ITextSelection_fnGetType(ITextSelection * me,LONG * type)5502 static HRESULT WINAPI ITextSelection_fnGetType(ITextSelection *me, LONG *type)
5503 {
5504     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5505 
5506     FIXME("(%p)->(%p): stub\n", This, type);
5507 
5508     if (!This->reOle)
5509         return CO_E_RELEASED;
5510 
5511     return E_NOTIMPL;
5512 }
5513 
ITextSelection_fnMoveLeft(ITextSelection * me,LONG unit,LONG count,LONG extend,LONG * delta)5514 static HRESULT WINAPI ITextSelection_fnMoveLeft(ITextSelection *me, LONG unit, LONG count,
5515     LONG extend, LONG *delta)
5516 {
5517     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5518 
5519     FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5520 
5521     if (!This->reOle)
5522         return CO_E_RELEASED;
5523 
5524     return E_NOTIMPL;
5525 }
5526 
ITextSelection_fnMoveRight(ITextSelection * me,LONG unit,LONG count,LONG extend,LONG * delta)5527 static HRESULT WINAPI ITextSelection_fnMoveRight(ITextSelection *me, LONG unit, LONG count,
5528     LONG extend, LONG *delta)
5529 {
5530     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5531 
5532     FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5533 
5534     if (!This->reOle)
5535         return CO_E_RELEASED;
5536 
5537     return E_NOTIMPL;
5538 }
5539 
ITextSelection_fnMoveUp(ITextSelection * me,LONG unit,LONG count,LONG extend,LONG * delta)5540 static HRESULT WINAPI ITextSelection_fnMoveUp(ITextSelection *me, LONG unit, LONG count,
5541     LONG extend, LONG *delta)
5542 {
5543     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5544 
5545     FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5546 
5547     if (!This->reOle)
5548         return CO_E_RELEASED;
5549 
5550     return E_NOTIMPL;
5551 }
5552 
ITextSelection_fnMoveDown(ITextSelection * me,LONG unit,LONG count,LONG extend,LONG * delta)5553 static HRESULT WINAPI ITextSelection_fnMoveDown(ITextSelection *me, LONG unit, LONG count,
5554     LONG extend, LONG *delta)
5555 {
5556     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5557 
5558     FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5559 
5560     if (!This->reOle)
5561         return CO_E_RELEASED;
5562 
5563     return E_NOTIMPL;
5564 }
5565 
ITextSelection_fnHomeKey(ITextSelection * me,LONG unit,LONG extend,LONG * delta)5566 static HRESULT WINAPI ITextSelection_fnHomeKey(ITextSelection *me, LONG unit, LONG extend,
5567     LONG *delta)
5568 {
5569     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5570 
5571     FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
5572 
5573     if (!This->reOle)
5574         return CO_E_RELEASED;
5575 
5576     return E_NOTIMPL;
5577 }
5578 
ITextSelection_fnEndKey(ITextSelection * me,LONG unit,LONG extend,LONG * delta)5579 static HRESULT WINAPI ITextSelection_fnEndKey(ITextSelection *me, LONG unit, LONG extend,
5580     LONG *delta)
5581 {
5582     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5583 
5584     FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
5585 
5586     if (!This->reOle)
5587         return CO_E_RELEASED;
5588 
5589     return E_NOTIMPL;
5590 }
5591 
ITextSelection_fnTypeText(ITextSelection * me,BSTR text)5592 static HRESULT WINAPI ITextSelection_fnTypeText(ITextSelection *me, BSTR text)
5593 {
5594     ITextSelectionImpl *This = impl_from_ITextSelection(me);
5595 
5596     FIXME("(%p)->(%s): stub\n", This, debugstr_w(text));
5597 
5598     if (!This->reOle)
5599         return CO_E_RELEASED;
5600 
5601     return E_NOTIMPL;
5602 }
5603 
5604 static const ITextSelectionVtbl tsvt = {
5605     ITextSelection_fnQueryInterface,
5606     ITextSelection_fnAddRef,
5607     ITextSelection_fnRelease,
5608     ITextSelection_fnGetTypeInfoCount,
5609     ITextSelection_fnGetTypeInfo,
5610     ITextSelection_fnGetIDsOfNames,
5611     ITextSelection_fnInvoke,
5612     ITextSelection_fnGetText,
5613     ITextSelection_fnSetText,
5614     ITextSelection_fnGetChar,
5615     ITextSelection_fnSetChar,
5616     ITextSelection_fnGetDuplicate,
5617     ITextSelection_fnGetFormattedText,
5618     ITextSelection_fnSetFormattedText,
5619     ITextSelection_fnGetStart,
5620     ITextSelection_fnSetStart,
5621     ITextSelection_fnGetEnd,
5622     ITextSelection_fnSetEnd,
5623     ITextSelection_fnGetFont,
5624     ITextSelection_fnSetFont,
5625     ITextSelection_fnGetPara,
5626     ITextSelection_fnSetPara,
5627     ITextSelection_fnGetStoryLength,
5628     ITextSelection_fnGetStoryType,
5629     ITextSelection_fnCollapse,
5630     ITextSelection_fnExpand,
5631     ITextSelection_fnGetIndex,
5632     ITextSelection_fnSetIndex,
5633     ITextSelection_fnSetRange,
5634     ITextSelection_fnInRange,
5635     ITextSelection_fnInStory,
5636     ITextSelection_fnIsEqual,
5637     ITextSelection_fnSelect,
5638     ITextSelection_fnStartOf,
5639     ITextSelection_fnEndOf,
5640     ITextSelection_fnMove,
5641     ITextSelection_fnMoveStart,
5642     ITextSelection_fnMoveEnd,
5643     ITextSelection_fnMoveWhile,
5644     ITextSelection_fnMoveStartWhile,
5645     ITextSelection_fnMoveEndWhile,
5646     ITextSelection_fnMoveUntil,
5647     ITextSelection_fnMoveStartUntil,
5648     ITextSelection_fnMoveEndUntil,
5649     ITextSelection_fnFindText,
5650     ITextSelection_fnFindTextStart,
5651     ITextSelection_fnFindTextEnd,
5652     ITextSelection_fnDelete,
5653     ITextSelection_fnCut,
5654     ITextSelection_fnCopy,
5655     ITextSelection_fnPaste,
5656     ITextSelection_fnCanPaste,
5657     ITextSelection_fnCanEdit,
5658     ITextSelection_fnChangeCase,
5659     ITextSelection_fnGetPoint,
5660     ITextSelection_fnSetPoint,
5661     ITextSelection_fnScrollIntoView,
5662     ITextSelection_fnGetEmbeddedObject,
5663     ITextSelection_fnGetFlags,
5664     ITextSelection_fnSetFlags,
5665     ITextSelection_fnGetType,
5666     ITextSelection_fnMoveLeft,
5667     ITextSelection_fnMoveRight,
5668     ITextSelection_fnMoveUp,
5669     ITextSelection_fnMoveDown,
5670     ITextSelection_fnHomeKey,
5671     ITextSelection_fnEndKey,
5672     ITextSelection_fnTypeText
5673 };
5674 
5675 static ITextSelectionImpl *
CreateTextSelection(IRichEditOleImpl * reOle)5676 CreateTextSelection(IRichEditOleImpl *reOle)
5677 {
5678     ITextSelectionImpl *txtSel = heap_alloc(sizeof *txtSel);
5679     if (!txtSel)
5680         return NULL;
5681 
5682     txtSel->ITextSelection_iface.lpVtbl = &tsvt;
5683     txtSel->ref = 1;
5684     txtSel->reOle = reOle;
5685     return txtSel;
5686 }
5687 
CreateIRichEditOle(IUnknown * outer_unk,ME_TextEditor * editor,LPVOID * ppvObj)5688 LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *ppvObj)
5689 {
5690     IRichEditOleImpl *reo;
5691 
5692     reo = heap_alloc(sizeof(IRichEditOleImpl));
5693     if (!reo)
5694         return 0;
5695 
5696     reo->IUnknown_inner.lpVtbl = &reo_unk_vtbl;
5697     reo->IRichEditOle_iface.lpVtbl = &revt;
5698     reo->ITextDocument2Old_iface.lpVtbl = &tdvt;
5699     reo->ref = 1;
5700     reo->editor = editor;
5701     reo->txtSel = NULL;
5702 
5703     TRACE("Created %p\n",reo);
5704     list_init(&reo->rangelist);
5705     list_init(&reo->clientsites);
5706     if (outer_unk)
5707         reo->outer_unk = outer_unk;
5708     else
5709         reo->outer_unk = &reo->IUnknown_inner;
5710     *ppvObj = &reo->IUnknown_inner;
5711 
5712     return 1;
5713 }
5714 
convert_sizel(const ME_Context * c,const SIZEL * szl,SIZE * sz)5715 static void convert_sizel(const ME_Context *c, const SIZEL* szl, SIZE* sz)
5716 {
5717   /* sizel is in .01 millimeters, sz in pixels */
5718   sz->cx = MulDiv(szl->cx, c->dpi.cx, 2540);
5719   sz->cy = MulDiv(szl->cy, c->dpi.cy, 2540);
5720 }
5721 
5722 /******************************************************************************
5723  * ME_GetOLEObjectSize
5724  *
5725  * Sets run extent for OLE objects.
5726  */
ME_GetOLEObjectSize(const ME_Context * c,ME_Run * run,SIZE * pSize)5727 void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize)
5728 {
5729   IDataObject*  ido;
5730   FORMATETC     fmt;
5731   STGMEDIUM     stgm;
5732   DIBSECTION    dibsect;
5733   ENHMETAHEADER emh;
5734 
5735   assert(run->nFlags & MERF_GRAPHICS);
5736   assert(run->reobj);
5737 
5738   if (run->reobj->obj.sizel.cx != 0 || run->reobj->obj.sizel.cy != 0)
5739   {
5740     convert_sizel(c, &run->reobj->obj.sizel, pSize);
5741     if (c->editor->nZoomNumerator != 0)
5742     {
5743       pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5744       pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5745     }
5746     return;
5747   }
5748 
5749   if (!run->reobj->obj.poleobj)
5750   {
5751     pSize->cx = pSize->cy = 0;
5752     return;
5753   }
5754 
5755   if (IOleObject_QueryInterface(run->reobj->obj.poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
5756   {
5757       FIXME("Query Interface IID_IDataObject failed!\n");
5758       pSize->cx = pSize->cy = 0;
5759       return;
5760   }
5761   fmt.cfFormat = CF_BITMAP;
5762   fmt.ptd = NULL;
5763   fmt.dwAspect = DVASPECT_CONTENT;
5764   fmt.lindex = -1;
5765   fmt.tymed = TYMED_GDI;
5766   if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5767   {
5768     fmt.cfFormat = CF_ENHMETAFILE;
5769     fmt.tymed = TYMED_ENHMF;
5770     if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5771     {
5772       FIXME("unsupported format\n");
5773       pSize->cx = pSize->cy = 0;
5774       IDataObject_Release(ido);
5775       return;
5776     }
5777   }
5778   IDataObject_Release(ido);
5779 
5780   switch (stgm.tymed)
5781   {
5782   case TYMED_GDI:
5783     GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
5784     pSize->cx = dibsect.dsBm.bmWidth;
5785     pSize->cy = dibsect.dsBm.bmHeight;
5786     break;
5787   case TYMED_ENHMF:
5788     GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
5789     pSize->cx = emh.rclBounds.right - emh.rclBounds.left;
5790     pSize->cy = emh.rclBounds.bottom - emh.rclBounds.top;
5791     break;
5792   default:
5793     FIXME("Unsupported tymed %d\n", stgm.tymed);
5794     break;
5795   }
5796   ReleaseStgMedium(&stgm);
5797   if (c->editor->nZoomNumerator != 0)
5798   {
5799     pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5800     pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5801   }
5802 }
5803 
ME_DrawOLE(ME_Context * c,int x,int y,ME_Run * run,BOOL selected)5804 void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run, BOOL selected)
5805 {
5806   IDataObject*  ido;
5807   FORMATETC     fmt;
5808   STGMEDIUM     stgm;
5809   DIBSECTION    dibsect;
5810   ENHMETAHEADER emh;
5811   HDC           hMemDC;
5812   SIZE          sz;
5813   BOOL          has_size;
5814   HBITMAP       old_bm;
5815   RECT          rc;
5816 
5817   assert(run->nFlags & MERF_GRAPHICS);
5818   assert(run->reobj);
5819   if (IOleObject_QueryInterface(run->reobj->obj.poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
5820   {
5821     FIXME("Couldn't get interface\n");
5822     return;
5823   }
5824   has_size = run->reobj->obj.sizel.cx != 0 || run->reobj->obj.sizel.cy != 0;
5825   fmt.cfFormat = CF_BITMAP;
5826   fmt.ptd = NULL;
5827   fmt.dwAspect = DVASPECT_CONTENT;
5828   fmt.lindex = -1;
5829   fmt.tymed = TYMED_GDI;
5830   if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5831   {
5832     fmt.cfFormat = CF_ENHMETAFILE;
5833     fmt.tymed = TYMED_ENHMF;
5834     if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5835     {
5836       FIXME("Couldn't get storage medium\n");
5837       IDataObject_Release(ido);
5838       return;
5839     }
5840   }
5841   IDataObject_Release(ido);
5842 
5843   switch (stgm.tymed)
5844   {
5845   case TYMED_GDI:
5846     GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
5847     hMemDC = CreateCompatibleDC(c->hDC);
5848     old_bm = SelectObject(hMemDC, stgm.u.hBitmap);
5849     if (has_size)
5850     {
5851       convert_sizel(c, &run->reobj->obj.sizel, &sz);
5852     } else {
5853       sz.cx = dibsect.dsBm.bmWidth;
5854       sz.cy = dibsect.dsBm.bmHeight;
5855     }
5856     if (c->editor->nZoomNumerator != 0)
5857     {
5858       sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5859       sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5860     }
5861     StretchBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy,
5862                hMemDC, 0, 0, dibsect.dsBm.bmWidth, dibsect.dsBm.bmHeight, SRCCOPY);
5863 
5864     SelectObject(hMemDC, old_bm);
5865     DeleteDC(hMemDC);
5866     break;
5867   case TYMED_ENHMF:
5868     GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
5869     if (has_size)
5870     {
5871       convert_sizel(c, &run->reobj->obj.sizel, &sz);
5872     } else {
5873       sz.cx = emh.rclBounds.right - emh.rclBounds.left;
5874       sz.cy = emh.rclBounds.bottom - emh.rclBounds.top;
5875     }
5876     if (c->editor->nZoomNumerator != 0)
5877     {
5878       sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5879       sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5880     }
5881 
5882     rc.left = x;
5883     rc.top = y - sz.cy;
5884     rc.right = x + sz.cx;
5885     rc.bottom = y;
5886     PlayEnhMetaFile(c->hDC, stgm.u.hEnhMetaFile, &rc);
5887     break;
5888   default:
5889     FIXME("Unsupported tymed %d\n", stgm.tymed);
5890     selected = FALSE;
5891     break;
5892   }
5893   ReleaseStgMedium(&stgm);
5894 
5895   if (selected && !c->editor->bHideSelection)
5896     PatBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy, DSTINVERT);
5897 }
5898 
ME_DeleteReObject(struct re_object * reobj)5899 void ME_DeleteReObject(struct re_object *reobj)
5900 {
5901     if (reobj->obj.poleobj)   IOleObject_Release(reobj->obj.poleobj);
5902     if (reobj->obj.pstg)      IStorage_Release(reobj->obj.pstg);
5903     if (reobj->obj.polesite)  IOleClientSite_Release(reobj->obj.polesite);
5904     heap_free(reobj);
5905 }
5906 
ME_CopyReObject(REOBJECT * dst,const REOBJECT * src,DWORD flags)5907 void ME_CopyReObject(REOBJECT *dst, const REOBJECT *src, DWORD flags)
5908 {
5909     *dst = *src;
5910     dst->poleobj = NULL;
5911     dst->pstg = NULL;
5912     dst->polesite = NULL;
5913 
5914     if ((flags & REO_GETOBJ_POLEOBJ) && src->poleobj)
5915     {
5916         dst->poleobj = src->poleobj;
5917         IOleObject_AddRef(dst->poleobj);
5918     }
5919     if ((flags & REO_GETOBJ_PSTG) && src->pstg)
5920     {
5921         dst->pstg = src->pstg;
5922         IStorage_AddRef(dst->pstg);
5923     }
5924     if ((flags & REO_GETOBJ_POLESITE) && src->polesite)
5925     {
5926         dst->polesite = src->polesite;
5927         IOleClientSite_AddRef(dst->polesite);
5928     }
5929 }
5930