user32: Don't wait for other threads to process WM_NCDESTROY.
[wine.git] / dlls / riched20 / richole.c
blob5c7be5eaa96e5d21b5f22d725ab7bb9f40032521
1 /*
2 * RichEdit GUIDs and OLE interface
4 * Copyright 2004 by Krzysztof Foltman
5 * Copyright 2004 Aric Stewart
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.
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.
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
22 #include <stdarg.h>
24 #define NONAMELESSUNION
25 #define COBJMACROS
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"
38 WINE_DEFAULT_DEBUG_CHANNEL(richedit);
40 /* there is no way to be consistent across different sets of headers - mingw, Wine, Win32 SDK*/
42 #include "initguid.h"
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_ITextRange, 0x8cc497c2, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
50 DEFINE_GUID(IID_ITextSelection, 0x8cc497c1, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
51 DEFINE_GUID(IID_ITextFont, 0x8cc497c3, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
52 DEFINE_GUID(IID_ITextPara, 0x8cc497c4, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
54 static ITypeLib *typelib;
56 enum tid_t {
57 NULL_tid,
58 ITextDocument_tid,
59 ITextRange_tid,
60 ITextSelection_tid,
61 ITextFont_tid,
62 ITextPara_tid,
63 LAST_tid
66 static const IID * const tid_ids[] =
68 &IID_NULL,
69 &IID_ITextDocument,
70 &IID_ITextRange,
71 &IID_ITextSelection,
72 &IID_ITextFont,
73 &IID_ITextPara,
75 static ITypeInfo *typeinfos[LAST_tid];
77 static HRESULT load_typelib(void)
79 ITypeLib *tl;
80 HRESULT hr;
82 hr = LoadRegTypeLib(&LIBID_tom, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
83 if (FAILED(hr)) {
84 ERR("LoadRegTypeLib failed: %08x\n", hr);
85 return hr;
88 if (InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
89 ITypeLib_Release(tl);
90 return hr;
93 void release_typelib(void)
95 unsigned i;
97 if (!typelib)
98 return;
100 for (i = 0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++)
101 if (typeinfos[i])
102 ITypeInfo_Release(typeinfos[i]);
104 ITypeLib_Release(typelib);
107 static HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo)
109 HRESULT hr;
111 if (!typelib)
112 hr = load_typelib();
113 if (!typelib)
114 return hr;
116 if (!typeinfos[tid])
118 ITypeInfo *ti;
120 hr = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
121 if (FAILED(hr))
123 ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hr);
124 return hr;
127 if (InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
128 ITypeInfo_Release(ti);
131 *typeinfo = typeinfos[tid];
132 return S_OK;
135 /* private IID used to get back IRichEditOleImpl pointer */
136 DEFINE_GUID(IID_Igetrichole, 0xe3ce5c7a, 0x8247, 0x4622, 0x81, 0xad, 0x11, 0x81, 0x02, 0xaa, 0x01, 0x30);
138 typedef struct ITextSelectionImpl ITextSelectionImpl;
139 typedef struct IOleClientSiteImpl IOleClientSiteImpl;
140 typedef struct ITextRangeImpl ITextRangeImpl;
142 enum textfont_prop_id {
143 FONT_ALLCAPS = 0,
144 FONT_ANIMATION,
145 FONT_BACKCOLOR,
146 FONT_BOLD,
147 FONT_EMBOSS,
148 FONT_FORECOLOR,
149 FONT_HIDDEN,
150 FONT_ENGRAVE,
151 FONT_ITALIC,
152 FONT_KERNING,
153 FONT_LANGID,
154 FONT_NAME,
155 FONT_OUTLINE,
156 FONT_POSITION,
157 FONT_PROTECTED,
158 FONT_SHADOW,
159 FONT_SIZE,
160 FONT_SMALLCAPS,
161 FONT_SPACING,
162 FONT_STRIKETHROUGH,
163 FONT_SUBSCRIPT,
164 FONT_SUPERSCRIPT,
165 FONT_UNDERLINE,
166 FONT_WEIGHT,
167 FONT_PROPID_LAST,
168 FONT_PROPID_FIRST = FONT_ALLCAPS
171 static const DWORD textfont_prop_masks[][2] = {
172 { CFM_ALLCAPS, CFE_ALLCAPS },
173 { CFM_ANIMATION },
174 { CFM_BACKCOLOR, CFE_AUTOBACKCOLOR },
175 { CFM_BOLD, CFE_BOLD },
176 { CFM_EMBOSS, CFE_EMBOSS },
177 { CFM_COLOR, CFE_AUTOCOLOR },
178 { CFM_HIDDEN, CFE_HIDDEN },
179 { CFM_IMPRINT, CFE_IMPRINT },
180 { CFM_ITALIC, CFE_ITALIC },
181 { CFM_KERNING },
182 { CFM_LCID },
183 { CFM_FACE },
184 { CFM_OUTLINE, CFE_OUTLINE },
185 { CFM_OFFSET },
186 { CFM_PROTECTED, CFE_PROTECTED },
187 { CFM_SHADOW, CFE_SHADOW },
188 { CFM_SIZE },
189 { CFM_SMALLCAPS, CFE_SMALLCAPS },
190 { CFM_SPACING },
191 { CFM_STRIKEOUT, CFE_STRIKEOUT },
192 { CFM_SUBSCRIPT, CFE_SUBSCRIPT },
193 { CFM_SUPERSCRIPT, CFE_SUPERSCRIPT },
194 { CFM_UNDERLINE, CFE_UNDERLINE },
195 { CFM_WEIGHT }
198 typedef union {
199 FLOAT f;
200 LONG l;
201 BSTR str;
202 } textfont_prop_val;
204 enum range_update_op {
205 RANGE_UPDATE_DELETE
208 typedef struct IRichEditOleImpl {
209 IUnknown IUnknown_inner;
210 IRichEditOle IRichEditOle_iface;
211 ITextDocument ITextDocument_iface;
212 IUnknown *outer_unk;
213 LONG ref;
215 ME_TextEditor *editor;
216 ITextSelectionImpl *txtSel;
218 struct list rangelist;
219 struct list clientsites;
220 } IRichEditOleImpl;
222 struct reole_child {
223 struct list entry;
224 IRichEditOleImpl *reole;
227 struct ITextRangeImpl {
228 struct reole_child child;
229 ITextRange ITextRange_iface;
230 LONG ref;
231 LONG start, end;
234 struct ITextSelectionImpl {
235 ITextSelection ITextSelection_iface;
236 LONG ref;
238 IRichEditOleImpl *reOle;
241 typedef struct ITextFontImpl {
242 ITextFont ITextFont_iface;
243 LONG ref;
245 ITextRange *range;
246 textfont_prop_val props[FONT_PROPID_LAST];
247 BOOL get_cache_enabled;
248 BOOL set_cache_enabled;
249 } ITextFontImpl;
251 typedef struct ITextParaImpl {
252 ITextPara ITextPara_iface;
253 LONG ref;
255 ITextRange *range;
256 } ITextParaImpl;
258 struct IOleClientSiteImpl {
259 struct reole_child child;
260 IOleClientSite IOleClientSite_iface;
261 IOleInPlaceSite IOleInPlaceSite_iface;
262 LONG ref;
265 static inline IRichEditOleImpl *impl_from_IRichEditOle(IRichEditOle *iface)
267 return CONTAINING_RECORD(iface, IRichEditOleImpl, IRichEditOle_iface);
270 static inline IRichEditOleImpl *impl_from_ITextDocument(ITextDocument *iface)
272 return CONTAINING_RECORD(iface, IRichEditOleImpl, ITextDocument_iface);
275 static inline IRichEditOleImpl *impl_from_IUnknown(IUnknown *iface)
277 return CONTAINING_RECORD(iface, IRichEditOleImpl, IUnknown_inner);
280 static inline IOleClientSiteImpl *impl_from_IOleInPlaceSite(IOleInPlaceSite *iface)
282 return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleInPlaceSite_iface);
285 static inline ITextRangeImpl *impl_from_ITextRange(ITextRange *iface)
287 return CONTAINING_RECORD(iface, ITextRangeImpl, ITextRange_iface);
290 static inline ITextSelectionImpl *impl_from_ITextSelection(ITextSelection *iface)
292 return CONTAINING_RECORD(iface, ITextSelectionImpl, ITextSelection_iface);
295 static inline ITextFontImpl *impl_from_ITextFont(ITextFont *iface)
297 return CONTAINING_RECORD(iface, ITextFontImpl, ITextFont_iface);
300 static inline ITextParaImpl *impl_from_ITextPara(ITextPara *iface)
302 return CONTAINING_RECORD(iface, ITextParaImpl, ITextPara_iface);
305 static HRESULT create_textfont(ITextRange*, const ITextFontImpl*, ITextFont**);
306 static HRESULT create_textpara(ITextRange*, ITextPara**);
307 static ITextSelectionImpl *CreateTextSelection(IRichEditOleImpl*);
309 static HRESULT textrange_get_storylength(ME_TextEditor *editor, LONG *length)
311 if (!length)
312 return E_INVALIDARG;
314 *length = ME_GetTextLength(editor) + 1;
315 return S_OK;
318 static void textranges_update_ranges(IRichEditOleImpl *reole, LONG start, LONG end, enum range_update_op op)
320 ITextRangeImpl *range;
322 LIST_FOR_EACH_ENTRY(range, &reole->rangelist, ITextRangeImpl, child.entry) {
323 switch (op)
325 case RANGE_UPDATE_DELETE:
326 /* range fully covered by deleted range - collapse to insertion point */
327 if (range->start >= start && range->end <= end)
328 range->start = range->end = start;
329 /* deleted range cuts from the right */
330 else if (range->start < start && range->end <= end)
331 range->end = start;
332 /* deleted range cuts from the left */
333 else if (range->start >= start && range->end > end) {
334 range->start = start;
335 range->end -= end - start;
337 /* deleted range cuts within */
338 else
339 range->end -= end - start;
340 break;
341 default:
342 FIXME("unknown update op, %d\n", op);
347 static inline BOOL is_equal_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *left,
348 textfont_prop_val *right)
350 switch (propid)
352 case FONT_ALLCAPS:
353 case FONT_ANIMATION:
354 case FONT_BACKCOLOR:
355 case FONT_BOLD:
356 case FONT_EMBOSS:
357 case FONT_FORECOLOR:
358 case FONT_HIDDEN:
359 case FONT_ENGRAVE:
360 case FONT_ITALIC:
361 case FONT_KERNING:
362 case FONT_LANGID:
363 case FONT_OUTLINE:
364 case FONT_PROTECTED:
365 case FONT_SHADOW:
366 case FONT_SMALLCAPS:
367 case FONT_STRIKETHROUGH:
368 case FONT_SUBSCRIPT:
369 case FONT_SUPERSCRIPT:
370 case FONT_UNDERLINE:
371 case FONT_WEIGHT:
372 return left->l == right->l;
373 case FONT_NAME:
374 return !strcmpW(left->str, right->str);
375 case FONT_POSITION:
376 case FONT_SIZE:
377 case FONT_SPACING:
378 return left->f == right->f;
379 default:
380 FIXME("unhandled font property %d\n", propid);
381 return FALSE;
385 static inline void init_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *v)
387 switch (propid)
389 case FONT_ALLCAPS:
390 case FONT_ANIMATION:
391 case FONT_BACKCOLOR:
392 case FONT_BOLD:
393 case FONT_EMBOSS:
394 case FONT_FORECOLOR:
395 case FONT_HIDDEN:
396 case FONT_ENGRAVE:
397 case FONT_ITALIC:
398 case FONT_KERNING:
399 case FONT_LANGID:
400 case FONT_OUTLINE:
401 case FONT_PROTECTED:
402 case FONT_SHADOW:
403 case FONT_SMALLCAPS:
404 case FONT_STRIKETHROUGH:
405 case FONT_SUBSCRIPT:
406 case FONT_SUPERSCRIPT:
407 case FONT_UNDERLINE:
408 case FONT_WEIGHT:
409 v->l = tomUndefined;
410 return;
411 case FONT_NAME:
412 v->str = NULL;
413 return;
414 case FONT_POSITION:
415 case FONT_SIZE:
416 case FONT_SPACING:
417 v->f = tomUndefined;
418 return;
419 default:
420 FIXME("unhandled font property %d\n", propid);
421 v->l = tomUndefined;
422 return;
426 static inline FLOAT twips_to_points(LONG value)
428 return value * 72.0 / 1440;
431 static inline FLOAT points_to_twips(FLOAT value)
433 return value * 1440 / 72.0;
436 static HRESULT get_textfont_prop_for_pos(const IRichEditOleImpl *reole, int pos, enum textfont_prop_id propid,
437 textfont_prop_val *value)
439 ME_Cursor from, to;
440 CHARFORMAT2W fmt;
442 memset(&fmt, 0, sizeof(fmt));
443 fmt.cbSize = sizeof(fmt);
444 fmt.dwMask = textfont_prop_masks[propid][0];
446 ME_CursorFromCharOfs(reole->editor, pos, &from);
447 to = from;
448 ME_MoveCursorChars(reole->editor, &to, 1, FALSE);
449 ME_GetCharFormat(reole->editor, &from, &to, &fmt);
451 switch (propid)
453 case FONT_ALLCAPS:
454 case FONT_BOLD:
455 case FONT_EMBOSS:
456 case FONT_HIDDEN:
457 case FONT_ENGRAVE:
458 case FONT_ITALIC:
459 case FONT_OUTLINE:
460 case FONT_PROTECTED:
461 case FONT_SHADOW:
462 case FONT_SMALLCAPS:
463 case FONT_STRIKETHROUGH:
464 case FONT_SUBSCRIPT:
465 case FONT_SUPERSCRIPT:
466 case FONT_UNDERLINE:
467 value->l = fmt.dwEffects & textfont_prop_masks[propid][1] ? tomTrue : tomFalse;
468 break;
469 case FONT_ANIMATION:
470 value->l = fmt.bAnimation;
471 break;
472 case FONT_BACKCOLOR:
473 value->l = fmt.dwEffects & CFE_AUTOBACKCOLOR ? GetSysColor(COLOR_WINDOW) : fmt.crBackColor;
474 break;
475 case FONT_FORECOLOR:
476 value->l = fmt.dwEffects & CFE_AUTOCOLOR ? GetSysColor(COLOR_WINDOWTEXT) : fmt.crTextColor;
477 break;
478 case FONT_KERNING:
479 value->f = twips_to_points(fmt.wKerning);
480 break;
481 case FONT_LANGID:
482 value->l = fmt.lcid;
483 break;
484 case FONT_NAME:
485 /* this case is used exclusively by GetName() */
486 value->str = SysAllocString(fmt.szFaceName);
487 if (!value->str)
488 return E_OUTOFMEMORY;
489 break;
490 case FONT_POSITION:
491 value->f = twips_to_points(fmt.yOffset);
492 break;
493 case FONT_SIZE:
494 value->f = twips_to_points(fmt.yHeight);
495 break;
496 case FONT_SPACING:
497 value->f = fmt.sSpacing;
498 break;
499 case FONT_WEIGHT:
500 value->l = fmt.wWeight;
501 break;
502 default:
503 FIXME("unhandled font property %d\n", propid);
504 return E_FAIL;
507 return S_OK;
510 static inline const IRichEditOleImpl *get_range_reole(ITextRange *range)
512 IRichEditOleImpl *reole = NULL;
513 ITextRange_QueryInterface(range, &IID_Igetrichole, (void**)&reole);
514 return reole;
517 static void textrange_set_font(ITextRange *range, ITextFont *font)
519 CHARFORMAT2W fmt;
520 HRESULT hr;
521 LONG value;
522 BSTR str;
523 FLOAT f;
525 #define CHARFORMAT_SET_B_FIELD(mask, value) \
526 if (hr == S_OK && value != tomUndefined) { \
527 fmt.dwMask |= CFM_##mask; \
528 if (value == tomTrue) fmt.dwEffects |= CFE_##mask; \
531 /* fill format data from font */
532 memset(&fmt, 0, sizeof(fmt));
533 fmt.cbSize = sizeof(fmt);
535 value = tomUndefined;
536 hr = ITextFont_GetAllCaps(font, &value);
537 CHARFORMAT_SET_B_FIELD(ALLCAPS, value);
539 value = tomUndefined;
540 hr = ITextFont_GetBold(font, &value);
541 CHARFORMAT_SET_B_FIELD(BOLD, value);
543 value = tomUndefined;
544 hr = ITextFont_GetEmboss(font, &value);
545 CHARFORMAT_SET_B_FIELD(EMBOSS, value);
547 value = tomUndefined;
548 hr = ITextFont_GetHidden(font, &value);
549 CHARFORMAT_SET_B_FIELD(HIDDEN, value);
551 value = tomUndefined;
552 hr = ITextFont_GetEngrave(font, &value);
553 CHARFORMAT_SET_B_FIELD(IMPRINT, value);
555 value = tomUndefined;
556 hr = ITextFont_GetItalic(font, &value);
557 CHARFORMAT_SET_B_FIELD(ITALIC, value);
559 value = tomUndefined;
560 hr = ITextFont_GetOutline(font, &value);
561 CHARFORMAT_SET_B_FIELD(OUTLINE, value);
563 value = tomUndefined;
564 hr = ITextFont_GetProtected(font, &value);
565 CHARFORMAT_SET_B_FIELD(PROTECTED, value);
567 value = tomUndefined;
568 hr = ITextFont_GetShadow(font, &value);
569 CHARFORMAT_SET_B_FIELD(SHADOW, value);
571 value = tomUndefined;
572 hr = ITextFont_GetSmallCaps(font, &value);
573 CHARFORMAT_SET_B_FIELD(SMALLCAPS, value);
575 value = tomUndefined;
576 hr = ITextFont_GetStrikeThrough(font, &value);
577 CHARFORMAT_SET_B_FIELD(STRIKEOUT, value);
579 value = tomUndefined;
580 hr = ITextFont_GetSubscript(font, &value);
581 CHARFORMAT_SET_B_FIELD(SUBSCRIPT, value);
583 value = tomUndefined;
584 hr = ITextFont_GetSuperscript(font, &value);
585 CHARFORMAT_SET_B_FIELD(SUPERSCRIPT, value);
587 value = tomUndefined;
588 hr = ITextFont_GetUnderline(font, &value);
589 CHARFORMAT_SET_B_FIELD(UNDERLINE, value);
591 #undef CHARFORMAT_SET_B_FIELD
593 value = tomUndefined;
594 hr = ITextFont_GetAnimation(font, &value);
595 if (hr == S_OK && value != tomUndefined) {
596 fmt.dwMask |= CFM_ANIMATION;
597 fmt.bAnimation = value;
600 value = tomUndefined;
601 hr = ITextFont_GetBackColor(font, &value);
602 if (hr == S_OK && value != tomUndefined) {
603 fmt.dwMask |= CFM_BACKCOLOR;
604 if (value == tomAutoColor)
605 fmt.dwEffects |= CFE_AUTOBACKCOLOR;
606 else
607 fmt.crBackColor = value;
610 value = tomUndefined;
611 hr = ITextFont_GetForeColor(font, &value);
612 if (hr == S_OK && value != tomUndefined) {
613 fmt.dwMask |= CFM_COLOR;
614 if (value == tomAutoColor)
615 fmt.dwEffects |= CFE_AUTOCOLOR;
616 else
617 fmt.crTextColor = value;
620 value = tomUndefined;
621 hr = ITextFont_GetKerning(font, &f);
622 if (hr == S_OK && f != tomUndefined) {
623 fmt.dwMask |= CFM_KERNING;
624 fmt.wKerning = points_to_twips(f);
627 value = tomUndefined;
628 hr = ITextFont_GetLanguageID(font, &value);
629 if (hr == S_OK && value != tomUndefined) {
630 fmt.dwMask |= CFM_LCID;
631 fmt.lcid = value;
634 if (ITextFont_GetName(font, &str) == S_OK) {
635 fmt.dwMask |= CFM_FACE;
636 lstrcpynW(fmt.szFaceName, str, sizeof(fmt.szFaceName)/sizeof(WCHAR));
637 SysFreeString(str);
640 hr = ITextFont_GetPosition(font, &f);
641 if (hr == S_OK && f != tomUndefined) {
642 fmt.dwMask |= CFM_OFFSET;
643 fmt.yOffset = points_to_twips(f);
646 hr = ITextFont_GetSize(font, &f);
647 if (hr == S_OK && f != tomUndefined) {
648 fmt.dwMask |= CFM_SIZE;
649 fmt.yHeight = points_to_twips(f);
652 hr = ITextFont_GetSpacing(font, &f);
653 if (hr == S_OK && f != tomUndefined) {
654 fmt.dwMask |= CFM_SPACING;
655 fmt.sSpacing = f;
658 hr = ITextFont_GetWeight(font, &value);
659 if (hr == S_OK && value != tomUndefined) {
660 fmt.dwMask |= CFM_WEIGHT;
661 fmt.wWeight = value;
664 if (fmt.dwMask) {
665 const IRichEditOleImpl *reole = get_range_reole(range);
666 ME_Cursor from, to;
667 LONG start, end;
669 ITextRange_GetStart(range, &start);
670 ITextRange_GetEnd(range, &end);
672 ME_CursorFromCharOfs(reole->editor, start, &from);
673 ME_CursorFromCharOfs(reole->editor, end, &to);
674 ME_SetCharFormat(reole->editor, &from, &to, &fmt);
678 static HRESULT get_textfont_prop(const ITextFontImpl *font, enum textfont_prop_id propid, textfont_prop_val *value)
680 const IRichEditOleImpl *reole;
681 textfont_prop_val v;
682 LONG start, end, i;
683 HRESULT hr;
685 /* when font is not attached to any range use cached values */
686 if (!font->range || font->get_cache_enabled) {
687 *value = font->props[propid];
688 return S_OK;
691 if (!(reole = get_range_reole(font->range)))
692 return CO_E_RELEASED;
694 init_textfont_prop_value(propid, value);
696 ITextRange_GetStart(font->range, &start);
697 ITextRange_GetEnd(font->range, &end);
699 /* iterate trough a range to see if property value is consistent */
700 hr = get_textfont_prop_for_pos(reole, start, propid, &v);
701 if (FAILED(hr))
702 return hr;
704 for (i = start + 1; i < end; i++) {
705 textfont_prop_val cur;
707 hr = get_textfont_prop_for_pos(reole, i, propid, &cur);
708 if (FAILED(hr))
709 return hr;
711 if (!is_equal_textfont_prop_value(propid, &v, &cur))
712 return S_OK;
715 *value = v;
716 return S_OK;
719 static HRESULT get_textfont_propf(const ITextFontImpl *font, enum textfont_prop_id propid, FLOAT *value)
721 textfont_prop_val v;
722 HRESULT hr;
724 if (!value)
725 return E_INVALIDARG;
727 hr = get_textfont_prop(font, propid, &v);
728 *value = v.f;
729 return hr;
732 static HRESULT get_textfont_propl(const ITextFontImpl *font, enum textfont_prop_id propid, LONG *value)
734 textfont_prop_val v;
735 HRESULT hr;
737 if (!value)
738 return E_INVALIDARG;
740 hr = get_textfont_prop(font, propid, &v);
741 *value = v.l;
742 return hr;
745 /* Value should already have a terminal value, for boolean properties it means tomToggle is not handled */
746 static HRESULT set_textfont_prop(ITextFontImpl *font, enum textfont_prop_id propid, const textfont_prop_val *value)
748 const IRichEditOleImpl *reole;
749 ME_Cursor from, to;
750 CHARFORMAT2W fmt;
751 LONG start, end;
753 /* when font is not attached to any range use cache */
754 if (!font->range || font->set_cache_enabled) {
755 if (propid == FONT_NAME) {
756 SysFreeString(font->props[propid].str);
757 font->props[propid].str = SysAllocString(value->str);
759 else
760 font->props[propid] = *value;
761 return S_OK;
764 if (!(reole = get_range_reole(font->range)))
765 return CO_E_RELEASED;
767 memset(&fmt, 0, sizeof(fmt));
768 fmt.cbSize = sizeof(fmt);
769 fmt.dwMask = textfont_prop_masks[propid][0];
771 switch (propid)
773 case FONT_ALLCAPS:
774 case FONT_BOLD:
775 case FONT_EMBOSS:
776 case FONT_HIDDEN:
777 case FONT_ENGRAVE:
778 case FONT_ITALIC:
779 case FONT_OUTLINE:
780 case FONT_PROTECTED:
781 case FONT_SHADOW:
782 case FONT_SMALLCAPS:
783 case FONT_STRIKETHROUGH:
784 case FONT_SUBSCRIPT:
785 case FONT_SUPERSCRIPT:
786 case FONT_UNDERLINE:
787 fmt.dwEffects = value->l == tomTrue ? textfont_prop_masks[propid][1] : 0;
788 break;
789 case FONT_ANIMATION:
790 fmt.bAnimation = value->l;
791 break;
792 case FONT_BACKCOLOR:
793 case FONT_FORECOLOR:
794 if (value->l == tomAutoColor)
795 fmt.dwEffects = textfont_prop_masks[propid][1];
796 else if (propid == FONT_BACKCOLOR)
797 fmt.crBackColor = value->l;
798 else
799 fmt.crTextColor = value->l;
800 break;
801 case FONT_KERNING:
802 fmt.wKerning = value->f;
803 break;
804 case FONT_LANGID:
805 fmt.lcid = value->l;
806 break;
807 case FONT_POSITION:
808 fmt.yOffset = value->f;
809 break;
810 case FONT_SIZE:
811 fmt.yHeight = value->f;
812 break;
813 case FONT_SPACING:
814 fmt.sSpacing = value->f;
815 break;
816 case FONT_WEIGHT:
817 fmt.wWeight = value->l;
818 break;
819 case FONT_NAME:
820 lstrcpynW(fmt.szFaceName, value->str, sizeof(fmt.szFaceName)/sizeof(WCHAR));
821 break;
822 default:
823 FIXME("unhandled font property %d\n", propid);
824 return E_FAIL;
827 ITextRange_GetStart(font->range, &start);
828 ITextRange_GetEnd(font->range, &end);
830 ME_CursorFromCharOfs(reole->editor, start, &from);
831 ME_CursorFromCharOfs(reole->editor, end, &to);
832 ME_SetCharFormat(reole->editor, &from, &to, &fmt);
834 return S_OK;
837 static inline HRESULT set_textfont_propl(ITextFontImpl *font, enum textfont_prop_id propid, LONG value)
839 textfont_prop_val v;
840 v.l = value;
841 return set_textfont_prop(font, propid, &v);
844 static inline HRESULT set_textfont_propf(ITextFontImpl *font, enum textfont_prop_id propid, FLOAT value)
846 textfont_prop_val v;
847 v.f = value;
848 return set_textfont_prop(font, propid, &v);
851 static HRESULT set_textfont_propd(ITextFontImpl *font, enum textfont_prop_id propid, LONG value)
853 textfont_prop_val v;
855 switch (value)
857 case tomUndefined:
858 return S_OK;
859 case tomToggle: {
860 LONG oldvalue;
861 get_textfont_propl(font, propid, &oldvalue);
862 if (oldvalue == tomFalse)
863 value = tomTrue;
864 else if (oldvalue == tomTrue)
865 value = tomFalse;
866 else
867 return E_INVALIDARG;
868 /* fallthrough */
870 case tomTrue:
871 case tomFalse:
872 v.l = value;
873 return set_textfont_prop(font, propid, &v);
874 default:
875 return E_INVALIDARG;
879 static HRESULT textfont_getname_from_range(ITextRange *range, BSTR *ret)
881 const IRichEditOleImpl *reole;
882 textfont_prop_val v;
883 HRESULT hr;
884 LONG start;
886 if (!(reole = get_range_reole(range)))
887 return CO_E_RELEASED;
889 ITextRange_GetStart(range, &start);
890 hr = get_textfont_prop_for_pos(reole, start, FONT_NAME, &v);
891 *ret = v.str;
892 return hr;
895 static void textfont_cache_range_props(ITextFontImpl *font)
897 enum textfont_prop_id propid;
898 for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++) {
899 if (propid == FONT_NAME)
900 textfont_getname_from_range(font->range, &font->props[propid].str);
901 else
902 get_textfont_prop(font, propid, &font->props[propid]);
906 static HRESULT textrange_expand(ITextRange *range, LONG unit, LONG *delta)
908 LONG expand_start, expand_end;
910 switch (unit)
912 case tomStory:
913 expand_start = 0;
914 ITextRange_GetStoryLength(range, &expand_end);
915 break;
916 default:
917 FIXME("unit %d is not supported\n", unit);
918 return E_NOTIMPL;
921 if (delta) {
922 LONG start, end;
924 ITextRange_GetStart(range, &start);
925 ITextRange_GetEnd(range, &end);
926 *delta = expand_end - expand_start - (end - start);
929 ITextRange_SetStart(range, expand_start);
930 ITextRange_SetEnd(range, expand_end);
932 return S_OK;
935 static HRESULT WINAPI IRichEditOleImpl_inner_fnQueryInterface(IUnknown *iface, REFIID riid, LPVOID *ppvObj)
937 IRichEditOleImpl *This = impl_from_IUnknown(iface);
939 TRACE("%p %s\n", This, debugstr_guid(riid));
941 *ppvObj = NULL;
942 if (IsEqualGUID(riid, &IID_IUnknown))
943 *ppvObj = &This->IUnknown_inner;
944 else if (IsEqualGUID(riid, &IID_IRichEditOle))
945 *ppvObj = &This->IRichEditOle_iface;
946 else if (IsEqualGUID(riid, &IID_ITextDocument))
947 *ppvObj = &This->ITextDocument_iface;
948 if (*ppvObj)
950 IUnknown_AddRef((IUnknown *)*ppvObj);
951 return S_OK;
953 FIXME("%p: unhandled interface %s\n", This, debugstr_guid(riid));
955 return E_NOINTERFACE;
958 static ULONG WINAPI IRichEditOleImpl_inner_fnAddRef(IUnknown *iface)
960 IRichEditOleImpl *This = impl_from_IUnknown(iface);
961 ULONG ref = InterlockedIncrement(&This->ref);
963 TRACE("%p ref = %u\n", This, ref);
965 return ref;
968 static ULONG WINAPI IRichEditOleImpl_inner_fnRelease(IUnknown *iface)
970 IRichEditOleImpl *This = impl_from_IUnknown(iface);
971 ULONG ref = InterlockedDecrement(&This->ref);
973 TRACE ("%p ref=%u\n", This, ref);
975 if (!ref)
977 IOleClientSiteImpl *clientsite;
978 ITextRangeImpl *txtRge;
980 This->editor->reOle = NULL;
981 if (This->txtSel) {
982 This->txtSel->reOle = NULL;
983 ITextSelection_Release(&This->txtSel->ITextSelection_iface);
986 LIST_FOR_EACH_ENTRY(txtRge, &This->rangelist, ITextRangeImpl, child.entry)
987 txtRge->child.reole = NULL;
989 LIST_FOR_EACH_ENTRY(clientsite, &This->clientsites, IOleClientSiteImpl, child.entry)
990 clientsite->child.reole = NULL;
992 heap_free(This);
994 return ref;
997 static const IUnknownVtbl reo_unk_vtbl =
999 IRichEditOleImpl_inner_fnQueryInterface,
1000 IRichEditOleImpl_inner_fnAddRef,
1001 IRichEditOleImpl_inner_fnRelease
1004 static HRESULT WINAPI
1005 IRichEditOle_fnQueryInterface(IRichEditOle *me, REFIID riid, LPVOID *ppvObj)
1007 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1008 return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj);
1011 static ULONG WINAPI
1012 IRichEditOle_fnAddRef(IRichEditOle *me)
1014 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1015 return IUnknown_AddRef(This->outer_unk);
1018 static ULONG WINAPI
1019 IRichEditOle_fnRelease(IRichEditOle *me)
1021 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1022 return IUnknown_Release(This->outer_unk);
1025 static HRESULT WINAPI
1026 IRichEditOle_fnActivateAs(IRichEditOle *me, REFCLSID rclsid, REFCLSID rclsidAs)
1028 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1029 FIXME("stub %p\n",This);
1030 return E_NOTIMPL;
1033 static HRESULT WINAPI
1034 IRichEditOle_fnContextSensitiveHelp(IRichEditOle *me, BOOL fEnterMode)
1036 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1037 FIXME("stub %p\n",This);
1038 return E_NOTIMPL;
1041 static HRESULT WINAPI
1042 IRichEditOle_fnConvertObject(IRichEditOle *me, LONG iob,
1043 REFCLSID rclsidNew, LPCSTR lpstrUserTypeNew)
1045 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1046 FIXME("stub %p\n",This);
1047 return E_NOTIMPL;
1050 static inline IOleClientSiteImpl *impl_from_IOleClientSite(IOleClientSite *iface)
1052 return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleClientSite_iface);
1055 static HRESULT WINAPI
1056 IOleClientSite_fnQueryInterface(IOleClientSite *me, REFIID riid, LPVOID *ppvObj)
1058 IOleClientSiteImpl *This = impl_from_IOleClientSite(me);
1059 TRACE("%p %s\n", me, debugstr_guid(riid) );
1061 *ppvObj = NULL;
1062 if (IsEqualGUID(riid, &IID_IUnknown) ||
1063 IsEqualGUID(riid, &IID_IOleClientSite))
1064 *ppvObj = me;
1065 else if (IsEqualGUID(riid, &IID_IOleWindow) ||
1066 IsEqualGUID(riid, &IID_IOleInPlaceSite))
1067 *ppvObj = &This->IOleInPlaceSite_iface;
1068 if (*ppvObj)
1070 IOleClientSite_AddRef(me);
1071 return S_OK;
1073 FIXME("%p: unhandled interface %s\n", me, debugstr_guid(riid) );
1075 return E_NOINTERFACE;
1078 static ULONG WINAPI IOleClientSite_fnAddRef(IOleClientSite *iface)
1080 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1081 ULONG ref = InterlockedIncrement(&This->ref);
1082 TRACE("(%p)->(%u)\n", This, ref);
1083 return ref;
1086 static ULONG WINAPI IOleClientSite_fnRelease(IOleClientSite *iface)
1088 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1089 ULONG ref = InterlockedDecrement(&This->ref);
1091 TRACE("(%p)->(%u)\n", This, ref);
1093 if (ref == 0) {
1094 if (This->child.reole) {
1095 list_remove(&This->child.entry);
1096 This->child.reole = NULL;
1098 heap_free(This);
1100 return ref;
1103 static HRESULT WINAPI IOleClientSite_fnSaveObject(IOleClientSite *iface)
1105 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1106 if (!This->child.reole)
1107 return CO_E_RELEASED;
1109 FIXME("stub %p\n", iface);
1110 return E_NOTIMPL;
1113 static HRESULT WINAPI IOleClientSite_fnGetMoniker(IOleClientSite *iface, DWORD dwAssign,
1114 DWORD dwWhichMoniker, IMoniker **ppmk)
1116 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1117 if (!This->child.reole)
1118 return CO_E_RELEASED;
1120 FIXME("stub %p\n", iface);
1121 return E_NOTIMPL;
1124 static HRESULT WINAPI IOleClientSite_fnGetContainer(IOleClientSite *iface,
1125 IOleContainer **ppContainer)
1127 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1128 if (!This->child.reole)
1129 return CO_E_RELEASED;
1131 FIXME("stub %p\n", iface);
1132 return E_NOTIMPL;
1135 static HRESULT WINAPI IOleClientSite_fnShowObject(IOleClientSite *iface)
1137 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1138 if (!This->child.reole)
1139 return CO_E_RELEASED;
1141 FIXME("stub %p\n", iface);
1142 return E_NOTIMPL;
1145 static HRESULT WINAPI IOleClientSite_fnOnShowWindow(IOleClientSite *iface, BOOL fShow)
1147 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1148 if (!This->child.reole)
1149 return CO_E_RELEASED;
1151 FIXME("stub %p\n", iface);
1152 return E_NOTIMPL;
1155 static HRESULT WINAPI IOleClientSite_fnRequestNewObjectLayout(IOleClientSite *iface)
1157 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1158 if (!This->child.reole)
1159 return CO_E_RELEASED;
1161 FIXME("stub %p\n", iface);
1162 return E_NOTIMPL;
1165 static const IOleClientSiteVtbl ocst = {
1166 IOleClientSite_fnQueryInterface,
1167 IOleClientSite_fnAddRef,
1168 IOleClientSite_fnRelease,
1169 IOleClientSite_fnSaveObject,
1170 IOleClientSite_fnGetMoniker,
1171 IOleClientSite_fnGetContainer,
1172 IOleClientSite_fnShowObject,
1173 IOleClientSite_fnOnShowWindow,
1174 IOleClientSite_fnRequestNewObjectLayout
1177 /* IOleInPlaceSite interface */
1178 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnQueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppvObj)
1180 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1181 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppvObj);
1184 static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnAddRef(IOleInPlaceSite *iface)
1186 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1187 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1190 static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnRelease(IOleInPlaceSite *iface)
1192 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1193 return IOleClientSite_Release(&This->IOleClientSite_iface);
1196 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindow(IOleInPlaceSite *iface, HWND *phwnd)
1198 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1200 TRACE("(%p)->(%p)\n", This, phwnd);
1202 if (!This->child.reole)
1203 return CO_E_RELEASED;
1205 if (!phwnd)
1206 return E_INVALIDARG;
1208 *phwnd = This->child.reole->editor->hWnd;
1209 return S_OK;
1212 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode)
1214 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1215 FIXME("not implemented: (%p)->(%d)\n", This, fEnterMode);
1216 return E_NOTIMPL;
1219 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnCanInPlaceActivate(IOleInPlaceSite *iface)
1221 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1222 FIXME("not implemented: (%p)\n", This);
1223 return E_NOTIMPL;
1226 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceActivate(IOleInPlaceSite *iface)
1228 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1229 FIXME("not implemented: (%p)\n", This);
1230 return E_NOTIMPL;
1233 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIActivate(IOleInPlaceSite *iface)
1235 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1236 FIXME("not implemented: (%p)\n", This);
1237 return E_NOTIMPL;
1240 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindowContext(IOleInPlaceSite *iface, IOleInPlaceFrame **ppFrame,
1241 IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
1242 LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
1244 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1245 FIXME("not implemented: (%p)->(%p %p %p %p %p)\n", This, ppFrame, ppDoc, lprcPosRect, lprcClipRect, lpFrameInfo);
1246 return E_NOTIMPL;
1249 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnScroll(IOleInPlaceSite *iface, SIZE scrollExtent)
1251 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1252 FIXME("not implemented: (%p)\n", This);
1253 return E_NOTIMPL;
1256 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable)
1258 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1259 FIXME("not implemented: (%p)->(%d)\n", This, fUndoable);
1260 return E_NOTIMPL;
1263 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceDeactivate(IOleInPlaceSite *iface)
1265 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1266 FIXME("not implemented: (%p)\n", This);
1267 return E_NOTIMPL;
1270 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDiscardUndoState(IOleInPlaceSite *iface)
1272 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1273 FIXME("not implemented: (%p)\n", This);
1274 return E_NOTIMPL;
1277 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDeactivateAndUndo(IOleInPlaceSite *iface)
1279 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1280 FIXME("not implemented: (%p)\n", This);
1281 return E_NOTIMPL;
1284 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect)
1286 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1287 FIXME("not implemented: (%p)->(%p)\n", This, lprcPosRect);
1288 return E_NOTIMPL;
1291 static const IOleInPlaceSiteVtbl olestvt =
1293 IOleInPlaceSite_fnQueryInterface,
1294 IOleInPlaceSite_fnAddRef,
1295 IOleInPlaceSite_fnRelease,
1296 IOleInPlaceSite_fnGetWindow,
1297 IOleInPlaceSite_fnContextSensitiveHelp,
1298 IOleInPlaceSite_fnCanInPlaceActivate,
1299 IOleInPlaceSite_fnOnInPlaceActivate,
1300 IOleInPlaceSite_fnOnUIActivate,
1301 IOleInPlaceSite_fnGetWindowContext,
1302 IOleInPlaceSite_fnScroll,
1303 IOleInPlaceSite_fnOnUIDeactivate,
1304 IOleInPlaceSite_fnOnInPlaceDeactivate,
1305 IOleInPlaceSite_fnDiscardUndoState,
1306 IOleInPlaceSite_fnDeactivateAndUndo,
1307 IOleInPlaceSite_fnOnPosRectChange
1310 static HRESULT CreateOleClientSite(IRichEditOleImpl *reOle, IOleClientSite **ret)
1312 IOleClientSiteImpl *clientSite = heap_alloc(sizeof *clientSite);
1314 if (!clientSite)
1315 return E_OUTOFMEMORY;
1317 clientSite->IOleClientSite_iface.lpVtbl = &ocst;
1318 clientSite->IOleInPlaceSite_iface.lpVtbl = &olestvt;
1319 clientSite->ref = 1;
1320 clientSite->child.reole = reOle;
1321 list_add_head(&reOle->clientsites, &clientSite->child.entry);
1323 *ret = &clientSite->IOleClientSite_iface;
1324 return S_OK;
1327 static HRESULT WINAPI
1328 IRichEditOle_fnGetClientSite(IRichEditOle *me, IOleClientSite **clientsite)
1330 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1332 TRACE("(%p)->(%p)\n", This, clientsite);
1334 if (!clientsite)
1335 return E_INVALIDARG;
1337 return CreateOleClientSite(This, clientsite);
1340 static HRESULT WINAPI
1341 IRichEditOle_fnGetClipboardData(IRichEditOle *me, CHARRANGE *lpchrg,
1342 DWORD reco, LPDATAOBJECT *lplpdataobj)
1344 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1345 ME_Cursor start;
1346 int nChars;
1348 TRACE("(%p,%p,%d)\n",This, lpchrg, reco);
1349 if(!lplpdataobj)
1350 return E_INVALIDARG;
1351 if(!lpchrg) {
1352 int nFrom, nTo, nStartCur = ME_GetSelectionOfs(This->editor, &nFrom, &nTo);
1353 start = This->editor->pCursors[nStartCur];
1354 nChars = nTo - nFrom;
1355 } else {
1356 ME_CursorFromCharOfs(This->editor, lpchrg->cpMin, &start);
1357 nChars = lpchrg->cpMax - lpchrg->cpMin;
1359 return ME_GetDataObject(This->editor, &start, nChars, lplpdataobj);
1362 static LONG WINAPI IRichEditOle_fnGetLinkCount(IRichEditOle *me)
1364 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1365 FIXME("stub %p\n",This);
1366 return E_NOTIMPL;
1369 static HRESULT WINAPI
1370 IRichEditOle_fnGetObject(IRichEditOle *me, LONG iob,
1371 REOBJECT *lpreobject, DWORD dwFlags)
1373 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1374 struct re_object *reobj = NULL;
1375 LONG count = 0;
1377 TRACE("(%p)->(%x, %p, %x)\n", This, iob, lpreobject, dwFlags);
1379 if (!lpreobject || !lpreobject->cbStruct)
1380 return E_INVALIDARG;
1382 if (iob == REO_IOB_USE_CP)
1384 ME_Cursor cursor;
1386 TRACE("character offset: %d\n", lpreobject->cp);
1387 ME_CursorFromCharOfs(This->editor, lpreobject->cp, &cursor);
1388 if (!cursor.pRun->member.run.reobj)
1389 return E_INVALIDARG;
1390 else
1391 reobj = cursor.pRun->member.run.reobj;
1393 else
1395 if (iob > IRichEditOle_GetObjectCount(me))
1396 return E_INVALIDARG;
1397 LIST_FOR_EACH_ENTRY(reobj, &This->editor->reobj_list, struct re_object, entry)
1399 if (count == iob)
1400 break;
1401 count++;
1404 ME_CopyReObject(lpreobject, &reobj->obj, dwFlags);
1405 return S_OK;
1408 static LONG WINAPI
1409 IRichEditOle_fnGetObjectCount(IRichEditOle *me)
1411 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1412 TRACE("(%p)\n",This);
1413 return list_count(&This->editor->reobj_list);
1416 static HRESULT WINAPI
1417 IRichEditOle_fnHandsOffStorage(IRichEditOle *me, LONG iob)
1419 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1420 FIXME("stub %p\n",This);
1421 return E_NOTIMPL;
1424 static HRESULT WINAPI
1425 IRichEditOle_fnImportDataObject(IRichEditOle *me, LPDATAOBJECT lpdataobj,
1426 CLIPFORMAT cf, HGLOBAL hMetaPict)
1428 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1429 FIXME("stub %p\n",This);
1430 return E_NOTIMPL;
1433 static HRESULT WINAPI
1434 IRichEditOle_fnInPlaceDeactivate(IRichEditOle *me)
1436 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1437 FIXME("stub %p\n",This);
1438 return E_NOTIMPL;
1441 static HRESULT WINAPI
1442 IRichEditOle_fnInsertObject(IRichEditOle *me, REOBJECT *reo)
1444 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1446 TRACE("(%p,%p)\n", This, reo);
1448 if (!reo)
1449 return E_INVALIDARG;
1451 if (reo->cbStruct < sizeof(*reo)) return STG_E_INVALIDPARAMETER;
1453 ME_InsertOLEFromCursor(This->editor, reo, 0);
1454 ME_CommitUndo(This->editor);
1455 ME_UpdateRepaint(This->editor, FALSE);
1456 return S_OK;
1459 static HRESULT WINAPI IRichEditOle_fnSaveCompleted(IRichEditOle *me, LONG iob,
1460 LPSTORAGE lpstg)
1462 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1463 FIXME("stub %p\n",This);
1464 return E_NOTIMPL;
1467 static HRESULT WINAPI
1468 IRichEditOle_fnSetDvaspect(IRichEditOle *me, LONG iob, DWORD dvaspect)
1470 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1471 FIXME("stub %p\n",This);
1472 return E_NOTIMPL;
1475 static HRESULT WINAPI IRichEditOle_fnSetHostNames(IRichEditOle *me,
1476 LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj)
1478 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1479 FIXME("stub %p %s %s\n",This, lpstrContainerApp, lpstrContainerObj);
1480 return E_NOTIMPL;
1483 static HRESULT WINAPI
1484 IRichEditOle_fnSetLinkAvailable(IRichEditOle *me, LONG iob, BOOL fAvailable)
1486 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1487 FIXME("stub %p\n",This);
1488 return E_NOTIMPL;
1491 static const IRichEditOleVtbl revt = {
1492 IRichEditOle_fnQueryInterface,
1493 IRichEditOle_fnAddRef,
1494 IRichEditOle_fnRelease,
1495 IRichEditOle_fnGetClientSite,
1496 IRichEditOle_fnGetObjectCount,
1497 IRichEditOle_fnGetLinkCount,
1498 IRichEditOle_fnGetObject,
1499 IRichEditOle_fnInsertObject,
1500 IRichEditOle_fnConvertObject,
1501 IRichEditOle_fnActivateAs,
1502 IRichEditOle_fnSetHostNames,
1503 IRichEditOle_fnSetLinkAvailable,
1504 IRichEditOle_fnSetDvaspect,
1505 IRichEditOle_fnHandsOffStorage,
1506 IRichEditOle_fnSaveCompleted,
1507 IRichEditOle_fnInPlaceDeactivate,
1508 IRichEditOle_fnContextSensitiveHelp,
1509 IRichEditOle_fnGetClipboardData,
1510 IRichEditOle_fnImportDataObject
1513 /* ITextRange interface */
1514 static HRESULT WINAPI ITextRange_fnQueryInterface(ITextRange *me, REFIID riid, void **ppvObj)
1516 ITextRangeImpl *This = impl_from_ITextRange(me);
1518 *ppvObj = NULL;
1519 if (IsEqualGUID(riid, &IID_IUnknown)
1520 || IsEqualGUID(riid, &IID_IDispatch)
1521 || IsEqualGUID(riid, &IID_ITextRange))
1523 *ppvObj = me;
1524 ITextRange_AddRef(me);
1525 return S_OK;
1527 else if (IsEqualGUID(riid, &IID_Igetrichole))
1529 *ppvObj = This->child.reole;
1530 return S_OK;
1533 return E_NOINTERFACE;
1536 static ULONG WINAPI ITextRange_fnAddRef(ITextRange *me)
1538 ITextRangeImpl *This = impl_from_ITextRange(me);
1539 return InterlockedIncrement(&This->ref);
1542 static ULONG WINAPI ITextRange_fnRelease(ITextRange *me)
1544 ITextRangeImpl *This = impl_from_ITextRange(me);
1545 ULONG ref = InterlockedDecrement(&This->ref);
1547 TRACE ("%p ref=%u\n", This, ref);
1548 if (ref == 0)
1550 if (This->child.reole)
1552 list_remove(&This->child.entry);
1553 This->child.reole = NULL;
1555 heap_free(This);
1557 return ref;
1560 static HRESULT WINAPI ITextRange_fnGetTypeInfoCount(ITextRange *me, UINT *pctinfo)
1562 ITextRangeImpl *This = impl_from_ITextRange(me);
1563 TRACE("(%p)->(%p)\n", This, pctinfo);
1564 *pctinfo = 1;
1565 return S_OK;
1568 static HRESULT WINAPI ITextRange_fnGetTypeInfo(ITextRange *me, UINT iTInfo, LCID lcid,
1569 ITypeInfo **ppTInfo)
1571 ITextRangeImpl *This = impl_from_ITextRange(me);
1572 HRESULT hr;
1574 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
1576 hr = get_typeinfo(ITextRange_tid, ppTInfo);
1577 if (SUCCEEDED(hr))
1578 ITypeInfo_AddRef(*ppTInfo);
1579 return hr;
1582 static HRESULT WINAPI ITextRange_fnGetIDsOfNames(ITextRange *me, REFIID riid, LPOLESTR *rgszNames,
1583 UINT cNames, LCID lcid, DISPID *rgDispId)
1585 ITextRangeImpl *This = impl_from_ITextRange(me);
1586 ITypeInfo *ti;
1587 HRESULT hr;
1589 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
1590 rgDispId);
1592 hr = get_typeinfo(ITextRange_tid, &ti);
1593 if (SUCCEEDED(hr))
1594 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
1595 return hr;
1598 static HRESULT WINAPI ITextRange_fnInvoke(ITextRange *me, DISPID dispIdMember, REFIID riid,
1599 LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1600 VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
1601 UINT *puArgErr)
1603 ITextRangeImpl *This = impl_from_ITextRange(me);
1604 ITypeInfo *ti;
1605 HRESULT hr;
1607 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
1608 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1610 hr = get_typeinfo(ITextRange_tid, &ti);
1611 if (SUCCEEDED(hr))
1612 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1613 return hr;
1616 static HRESULT WINAPI ITextRange_fnGetText(ITextRange *me, BSTR *str)
1618 ITextRangeImpl *This = impl_from_ITextRange(me);
1619 ME_TextEditor *editor;
1620 ME_Cursor start, end;
1621 int length;
1622 BOOL bEOP;
1624 TRACE("(%p)->(%p)\n", This, str);
1626 if (!This->child.reole)
1627 return CO_E_RELEASED;
1629 if (!str)
1630 return E_INVALIDARG;
1632 /* return early for degenerate range */
1633 if (This->start == This->end) {
1634 *str = NULL;
1635 return S_OK;
1638 editor = This->child.reole->editor;
1639 ME_CursorFromCharOfs(editor, This->start, &start);
1640 ME_CursorFromCharOfs(editor, This->end, &end);
1642 length = This->end - This->start;
1643 *str = SysAllocStringLen(NULL, length);
1644 if (!*str)
1645 return E_OUTOFMEMORY;
1647 bEOP = (end.pRun->next->type == diTextEnd && This->end > ME_GetTextLength(editor));
1648 ME_GetTextW(editor, *str, length, &start, length, FALSE, bEOP);
1649 return S_OK;
1652 static HRESULT WINAPI ITextRange_fnSetText(ITextRange *me, BSTR str)
1654 ITextRangeImpl *This = impl_from_ITextRange(me);
1655 ME_TextEditor *editor;
1656 ME_Cursor cursor;
1657 ME_Style *style;
1658 int len;
1660 TRACE("(%p)->(%s)\n", This, debugstr_w(str));
1662 if (!This->child.reole)
1663 return CO_E_RELEASED;
1665 editor = This->child.reole->editor;
1667 /* delete only where's something to delete */
1668 if (This->start != This->end) {
1669 ME_CursorFromCharOfs(editor, This->start, &cursor);
1670 ME_InternalDeleteText(editor, &cursor, This->end - This->start, FALSE);
1673 if (!str || !*str) {
1674 /* will update this range as well */
1675 textranges_update_ranges(This->child.reole, This->start, This->end, RANGE_UPDATE_DELETE);
1676 return S_OK;
1679 /* it's safer not to rely on stored BSTR length */
1680 len = strlenW(str);
1681 cursor = editor->pCursors[0];
1682 ME_CursorFromCharOfs(editor, This->start, &editor->pCursors[0]);
1683 style = ME_GetInsertStyle(editor, 0);
1684 ME_InsertTextFromCursor(editor, 0, str, len, style);
1685 ME_ReleaseStyle(style);
1686 editor->pCursors[0] = cursor;
1688 if (len < This->end - This->start)
1689 textranges_update_ranges(This->child.reole, This->start + len, This->end, RANGE_UPDATE_DELETE);
1690 else
1691 This->end = len - This->start;
1693 return S_OK;
1696 static HRESULT range_GetChar(ME_TextEditor *editor, ME_Cursor *cursor, LONG *pch)
1698 WCHAR wch[2];
1700 ME_GetTextW(editor, wch, 1, cursor, 1, FALSE, cursor->pRun->next->type == diTextEnd);
1701 *pch = wch[0];
1703 return S_OK;
1706 static HRESULT WINAPI ITextRange_fnGetChar(ITextRange *me, LONG *pch)
1708 ITextRangeImpl *This = impl_from_ITextRange(me);
1709 ME_TextEditor *editor;
1710 ME_Cursor cursor;
1712 TRACE("(%p)->(%p)\n", This, pch);
1714 if (!This->child.reole)
1715 return CO_E_RELEASED;
1717 if (!pch)
1718 return E_INVALIDARG;
1720 editor = This->child.reole->editor;
1721 ME_CursorFromCharOfs(editor, This->start, &cursor);
1722 return range_GetChar(editor, &cursor, pch);
1725 static HRESULT WINAPI ITextRange_fnSetChar(ITextRange *me, LONG ch)
1727 ITextRangeImpl *This = impl_from_ITextRange(me);
1729 FIXME("(%p)->(%x): stub\n", This, ch);
1731 if (!This->child.reole)
1732 return CO_E_RELEASED;
1734 return E_NOTIMPL;
1737 static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, ITextRange** ppRange);
1739 static HRESULT WINAPI ITextRange_fnGetDuplicate(ITextRange *me, ITextRange **ppRange)
1741 ITextRangeImpl *This = impl_from_ITextRange(me);
1743 TRACE("(%p)->(%p)\n", This, ppRange);
1745 if (!This->child.reole)
1746 return CO_E_RELEASED;
1748 if (!ppRange)
1749 return E_INVALIDARG;
1751 return CreateITextRange(This->child.reole, This->start, This->end, ppRange);
1754 static HRESULT WINAPI ITextRange_fnGetFormattedText(ITextRange *me, ITextRange **range)
1756 ITextRangeImpl *This = impl_from_ITextRange(me);
1758 FIXME("(%p)->(%p): stub\n", This, range);
1760 if (!This->child.reole)
1761 return CO_E_RELEASED;
1763 return E_NOTIMPL;
1766 static HRESULT WINAPI ITextRange_fnSetFormattedText(ITextRange *me, ITextRange *range)
1768 ITextRangeImpl *This = impl_from_ITextRange(me);
1770 FIXME("(%p)->(%p): stub\n", This, range);
1772 if (!This->child.reole)
1773 return CO_E_RELEASED;
1775 return E_NOTIMPL;
1778 static HRESULT WINAPI ITextRange_fnGetStart(ITextRange *me, LONG *start)
1780 ITextRangeImpl *This = impl_from_ITextRange(me);
1782 TRACE("(%p)->(%p)\n", This, start);
1784 if (!This->child.reole)
1785 return CO_E_RELEASED;
1787 if (!start)
1788 return E_INVALIDARG;
1790 *start = This->start;
1791 return S_OK;
1794 static HRESULT textrange_setstart(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end)
1796 int len;
1798 if (value < 0)
1799 value = 0;
1801 if (value == *start)
1802 return S_FALSE;
1804 if (value <= *end) {
1805 *start = value;
1806 return S_OK;
1809 len = ME_GetTextLength(reole->editor);
1810 *start = *end = value > len ? len : value;
1811 return S_OK;
1814 static HRESULT WINAPI ITextRange_fnSetStart(ITextRange *me, LONG value)
1816 ITextRangeImpl *This = impl_from_ITextRange(me);
1818 TRACE("(%p)->(%d)\n", This, value);
1820 if (!This->child.reole)
1821 return CO_E_RELEASED;
1823 return textrange_setstart(This->child.reole, value, &This->start, &This->end);
1826 static HRESULT WINAPI ITextRange_fnGetEnd(ITextRange *me, LONG *end)
1828 ITextRangeImpl *This = impl_from_ITextRange(me);
1830 TRACE("(%p)->(%p)\n", This, end);
1832 if (!This->child.reole)
1833 return CO_E_RELEASED;
1835 if (!end)
1836 return E_INVALIDARG;
1838 *end = This->end;
1839 return S_OK;
1842 static HRESULT textrange_setend(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end)
1844 int len;
1846 if (value == *end)
1847 return S_FALSE;
1849 if (value < *start) {
1850 *start = *end = max(0, value);
1851 return S_OK;
1854 len = ME_GetTextLength(reole->editor);
1855 *end = value > len ? len + 1 : value;
1856 return S_OK;
1859 static HRESULT WINAPI ITextRange_fnSetEnd(ITextRange *me, LONG value)
1861 ITextRangeImpl *This = impl_from_ITextRange(me);
1863 TRACE("(%p)->(%d)\n", This, value);
1865 if (!This->child.reole)
1866 return CO_E_RELEASED;
1868 return textrange_setend(This->child.reole, value, &This->start, &This->end);
1871 static HRESULT WINAPI ITextRange_fnGetFont(ITextRange *me, ITextFont **font)
1873 ITextRangeImpl *This = impl_from_ITextRange(me);
1875 TRACE("(%p)->(%p)\n", This, font);
1877 if (!This->child.reole)
1878 return CO_E_RELEASED;
1880 if (!font)
1881 return E_INVALIDARG;
1883 return create_textfont(me, NULL, font);
1886 static HRESULT WINAPI ITextRange_fnSetFont(ITextRange *me, ITextFont *font)
1888 ITextRangeImpl *This = impl_from_ITextRange(me);
1890 TRACE("(%p)->(%p)\n", This, font);
1892 if (!font)
1893 return E_INVALIDARG;
1895 if (!This->child.reole)
1896 return CO_E_RELEASED;
1898 textrange_set_font(me, font);
1899 return S_OK;
1902 static HRESULT WINAPI ITextRange_fnGetPara(ITextRange *me, ITextPara **para)
1904 ITextRangeImpl *This = impl_from_ITextRange(me);
1906 TRACE("(%p)->(%p)\n", This, para);
1908 if (!This->child.reole)
1909 return CO_E_RELEASED;
1911 if (!para)
1912 return E_INVALIDARG;
1914 return create_textpara(me, para);
1917 static HRESULT WINAPI ITextRange_fnSetPara(ITextRange *me, ITextPara *para)
1919 ITextRangeImpl *This = impl_from_ITextRange(me);
1921 FIXME("(%p)->(%p): stub\n", This, para);
1923 if (!This->child.reole)
1924 return CO_E_RELEASED;
1926 return E_NOTIMPL;
1929 static HRESULT WINAPI ITextRange_fnGetStoryLength(ITextRange *me, LONG *length)
1931 ITextRangeImpl *This = impl_from_ITextRange(me);
1933 TRACE("(%p)->(%p)\n", This, length);
1935 if (!This->child.reole)
1936 return CO_E_RELEASED;
1938 return textrange_get_storylength(This->child.reole->editor, length);
1941 static HRESULT WINAPI ITextRange_fnGetStoryType(ITextRange *me, LONG *value)
1943 ITextRangeImpl *This = impl_from_ITextRange(me);
1945 TRACE("(%p)->(%p)\n", This, value);
1947 if (!This->child.reole)
1948 return CO_E_RELEASED;
1950 if (!value)
1951 return E_INVALIDARG;
1953 *value = tomUnknownStory;
1954 return S_OK;
1957 static HRESULT range_Collapse(LONG bStart, LONG *start, LONG *end)
1959 if (*end == *start)
1960 return S_FALSE;
1962 if (bStart == tomEnd)
1963 *start = *end;
1964 else
1965 *end = *start;
1966 return S_OK;
1969 static HRESULT WINAPI ITextRange_fnCollapse(ITextRange *me, LONG bStart)
1971 ITextRangeImpl *This = impl_from_ITextRange(me);
1973 TRACE("(%p)->(%d)\n", This, bStart);
1975 if (!This->child.reole)
1976 return CO_E_RELEASED;
1978 return range_Collapse(bStart, &This->start, &This->end);
1981 static HRESULT WINAPI ITextRange_fnExpand(ITextRange *me, LONG unit, LONG *delta)
1983 ITextRangeImpl *This = impl_from_ITextRange(me);
1985 TRACE("(%p)->(%d %p)\n", This, unit, delta);
1987 if (!This->child.reole)
1988 return CO_E_RELEASED;
1990 return textrange_expand(me, unit, delta);
1993 static HRESULT WINAPI ITextRange_fnGetIndex(ITextRange *me, LONG unit, LONG *index)
1995 ITextRangeImpl *This = impl_from_ITextRange(me);
1997 FIXME("(%p)->(%d %p): stub\n", This, unit, index);
1999 if (!This->child.reole)
2000 return CO_E_RELEASED;
2002 return E_NOTIMPL;
2005 static HRESULT WINAPI ITextRange_fnSetIndex(ITextRange *me, LONG unit, LONG index,
2006 LONG extend)
2008 ITextRangeImpl *This = impl_from_ITextRange(me);
2010 FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend);
2012 if (!This->child.reole)
2013 return CO_E_RELEASED;
2015 return E_NOTIMPL;
2018 static HRESULT WINAPI ITextRange_fnSetRange(ITextRange *me, LONG anchor, LONG active)
2020 ITextRangeImpl *This = impl_from_ITextRange(me);
2022 FIXME("(%p)->(%d %d): stub\n", This, anchor, active);
2024 if (!This->child.reole)
2025 return CO_E_RELEASED;
2027 return E_NOTIMPL;
2030 static HRESULT textrange_inrange(LONG start, LONG end, ITextRange *range, LONG *ret)
2032 LONG from, to, v;
2034 if (!ret)
2035 ret = &v;
2037 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
2038 *ret = tomFalse;
2040 else
2041 *ret = (start >= from && end <= to) ? tomTrue : tomFalse;
2042 return *ret == tomTrue ? S_OK : S_FALSE;
2045 static HRESULT WINAPI ITextRange_fnInRange(ITextRange *me, ITextRange *range, LONG *ret)
2047 ITextRangeImpl *This = impl_from_ITextRange(me);
2049 TRACE("(%p)->(%p %p)\n", This, range, ret);
2051 if (ret)
2052 *ret = tomFalse;
2054 if (!This->child.reole)
2055 return CO_E_RELEASED;
2057 if (!range)
2058 return S_FALSE;
2060 return textrange_inrange(This->start, This->end, range, ret);
2063 static HRESULT WINAPI ITextRange_fnInStory(ITextRange *me, ITextRange *pRange, LONG *ret)
2065 ITextRangeImpl *This = impl_from_ITextRange(me);
2067 FIXME("(%p)->(%p): stub\n", This, ret);
2069 if (!This->child.reole)
2070 return CO_E_RELEASED;
2072 return E_NOTIMPL;
2075 static HRESULT textrange_isequal(LONG start, LONG end, ITextRange *range, LONG *ret)
2077 LONG from, to, v;
2079 if (!ret)
2080 ret = &v;
2082 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
2083 *ret = tomFalse;
2085 else
2086 *ret = (start == from && end == to) ? tomTrue : tomFalse;
2087 return *ret == tomTrue ? S_OK : S_FALSE;
2090 static HRESULT WINAPI ITextRange_fnIsEqual(ITextRange *me, ITextRange *range, LONG *ret)
2092 ITextRangeImpl *This = impl_from_ITextRange(me);
2094 TRACE("(%p)->(%p %p)\n", This, range, ret);
2096 if (ret)
2097 *ret = tomFalse;
2099 if (!This->child.reole)
2100 return CO_E_RELEASED;
2102 if (!range)
2103 return S_FALSE;
2105 return textrange_isequal(This->start, This->end, range, ret);
2108 static HRESULT WINAPI ITextRange_fnSelect(ITextRange *me)
2110 ITextRangeImpl *This = impl_from_ITextRange(me);
2112 TRACE("(%p)\n", This);
2114 if (!This->child.reole)
2115 return CO_E_RELEASED;
2117 ME_SetSelection(This->child.reole->editor, This->start, This->end);
2118 return S_OK;
2121 static HRESULT WINAPI ITextRange_fnStartOf(ITextRange *me, LONG unit, LONG extend,
2122 LONG *delta)
2124 ITextRangeImpl *This = impl_from_ITextRange(me);
2126 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
2128 if (!This->child.reole)
2129 return CO_E_RELEASED;
2131 return E_NOTIMPL;
2134 static HRESULT WINAPI ITextRange_fnEndOf(ITextRange *me, LONG unit, LONG extend,
2135 LONG *delta)
2137 ITextRangeImpl *This = impl_from_ITextRange(me);
2139 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
2141 if (!This->child.reole)
2142 return CO_E_RELEASED;
2144 return E_NOTIMPL;
2147 static HRESULT WINAPI ITextRange_fnMove(ITextRange *me, LONG unit, LONG count, LONG *delta)
2149 ITextRangeImpl *This = impl_from_ITextRange(me);
2151 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2153 if (!This->child.reole)
2154 return CO_E_RELEASED;
2156 return E_NOTIMPL;
2159 static HRESULT WINAPI ITextRange_fnMoveStart(ITextRange *me, LONG unit, LONG count,
2160 LONG *delta)
2162 ITextRangeImpl *This = impl_from_ITextRange(me);
2164 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2166 if (!This->child.reole)
2167 return CO_E_RELEASED;
2169 return E_NOTIMPL;
2172 static HRESULT textrange_moveend(ITextRange *range, LONG unit, LONG count, LONG *delta)
2174 LONG old_start, old_end, new_start, new_end;
2175 HRESULT hr = S_OK;
2177 if (!count)
2179 if (delta)
2180 *delta = 0;
2181 return S_FALSE;
2184 ITextRange_GetStart(range, &old_start);
2185 ITextRange_GetEnd(range, &old_end);
2186 switch (unit)
2188 case tomStory:
2189 if (count < 0)
2190 new_start = new_end = 0;
2191 else
2193 new_start = old_start;
2194 ITextRange_GetStoryLength(range, &new_end);
2196 if (delta)
2198 if (new_end < old_end)
2199 *delta = -1;
2200 else if (new_end == old_end)
2201 *delta = 0;
2202 else
2203 *delta = 1;
2205 break;
2206 default:
2207 FIXME("unit %d is not supported\n", unit);
2208 return E_NOTIMPL;
2210 if (new_end == old_end)
2211 hr = S_FALSE;
2212 ITextRange_SetStart(range, new_start);
2213 ITextRange_SetEnd(range, new_end);
2215 return hr;
2218 static HRESULT WINAPI ITextRange_fnMoveEnd(ITextRange *me, LONG unit, LONG count,
2219 LONG *delta)
2221 ITextRangeImpl *This = impl_from_ITextRange(me);
2223 TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta);
2225 if (!This->child.reole)
2226 return CO_E_RELEASED;
2228 return textrange_moveend(me, unit, count, delta);
2231 static HRESULT WINAPI ITextRange_fnMoveWhile(ITextRange *me, VARIANT *charset, LONG count,
2232 LONG *delta)
2234 ITextRangeImpl *This = impl_from_ITextRange(me);
2236 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2238 if (!This->child.reole)
2239 return CO_E_RELEASED;
2241 return E_NOTIMPL;
2244 static HRESULT WINAPI ITextRange_fnMoveStartWhile(ITextRange *me, VARIANT *charset, LONG count,
2245 LONG *delta)
2247 ITextRangeImpl *This = impl_from_ITextRange(me);
2249 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2251 if (!This->child.reole)
2252 return CO_E_RELEASED;
2254 return E_NOTIMPL;
2257 static HRESULT WINAPI ITextRange_fnMoveEndWhile(ITextRange *me, VARIANT *charset, LONG count,
2258 LONG *delta)
2260 ITextRangeImpl *This = impl_from_ITextRange(me);
2262 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2264 if (!This->child.reole)
2265 return CO_E_RELEASED;
2267 return E_NOTIMPL;
2270 static HRESULT WINAPI ITextRange_fnMoveUntil(ITextRange *me, VARIANT *charset, LONG count,
2271 LONG *delta)
2273 ITextRangeImpl *This = impl_from_ITextRange(me);
2275 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2277 if (!This->child.reole)
2278 return CO_E_RELEASED;
2280 return E_NOTIMPL;
2283 static HRESULT WINAPI ITextRange_fnMoveStartUntil(ITextRange *me, VARIANT *charset, LONG count,
2284 LONG *delta)
2286 ITextRangeImpl *This = impl_from_ITextRange(me);
2288 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2290 if (!This->child.reole)
2291 return CO_E_RELEASED;
2293 return E_NOTIMPL;
2296 static HRESULT WINAPI ITextRange_fnMoveEndUntil(ITextRange *me, VARIANT *charset, LONG count,
2297 LONG *delta)
2299 ITextRangeImpl *This = impl_from_ITextRange(me);
2301 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2303 if (!This->child.reole)
2304 return CO_E_RELEASED;
2306 return E_NOTIMPL;
2309 static HRESULT WINAPI ITextRange_fnFindText(ITextRange *me, BSTR text, LONG count, LONG flags,
2310 LONG *length)
2312 ITextRangeImpl *This = impl_from_ITextRange(me);
2314 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2316 if (!This->child.reole)
2317 return CO_E_RELEASED;
2319 return E_NOTIMPL;
2322 static HRESULT WINAPI ITextRange_fnFindTextStart(ITextRange *me, BSTR text, LONG count,
2323 LONG flags, LONG *length)
2325 ITextRangeImpl *This = impl_from_ITextRange(me);
2327 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2329 if (!This->child.reole)
2330 return CO_E_RELEASED;
2332 return E_NOTIMPL;
2335 static HRESULT WINAPI ITextRange_fnFindTextEnd(ITextRange *me, BSTR text, LONG count,
2336 LONG flags, LONG *length)
2338 ITextRangeImpl *This = impl_from_ITextRange(me);
2340 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2342 if (!This->child.reole)
2343 return CO_E_RELEASED;
2345 return E_NOTIMPL;
2348 static HRESULT WINAPI ITextRange_fnDelete(ITextRange *me, LONG unit, LONG count, LONG *delta)
2350 ITextRangeImpl *This = impl_from_ITextRange(me);
2352 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2354 if (!This->child.reole)
2355 return CO_E_RELEASED;
2357 return E_NOTIMPL;
2360 static HRESULT WINAPI ITextRange_fnCut(ITextRange *me, VARIANT *v)
2362 ITextRangeImpl *This = impl_from_ITextRange(me);
2364 FIXME("(%p)->(%p): stub\n", This, v);
2366 if (!This->child.reole)
2367 return CO_E_RELEASED;
2369 return E_NOTIMPL;
2372 static HRESULT WINAPI ITextRange_fnCopy(ITextRange *me, VARIANT *v)
2374 ITextRangeImpl *This = impl_from_ITextRange(me);
2376 FIXME("(%p)->(%p): stub\n", This, v);
2378 if (!This->child.reole)
2379 return CO_E_RELEASED;
2381 return E_NOTIMPL;
2384 static HRESULT WINAPI ITextRange_fnPaste(ITextRange *me, VARIANT *v, LONG format)
2386 ITextRangeImpl *This = impl_from_ITextRange(me);
2388 FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format);
2390 if (!This->child.reole)
2391 return CO_E_RELEASED;
2393 return E_NOTIMPL;
2396 static HRESULT WINAPI ITextRange_fnCanPaste(ITextRange *me, VARIANT *v, LONG format, LONG *ret)
2398 ITextRangeImpl *This = impl_from_ITextRange(me);
2400 FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret);
2402 if (!This->child.reole)
2403 return CO_E_RELEASED;
2405 return E_NOTIMPL;
2408 static HRESULT WINAPI ITextRange_fnCanEdit(ITextRange *me, LONG *ret)
2410 ITextRangeImpl *This = impl_from_ITextRange(me);
2412 FIXME("(%p)->(%p): stub\n", This, ret);
2414 if (!This->child.reole)
2415 return CO_E_RELEASED;
2417 return E_NOTIMPL;
2420 static HRESULT WINAPI ITextRange_fnChangeCase(ITextRange *me, LONG type)
2422 ITextRangeImpl *This = impl_from_ITextRange(me);
2424 FIXME("(%p)->(%d): stub\n", This, type);
2426 if (!This->child.reole)
2427 return CO_E_RELEASED;
2429 return E_NOTIMPL;
2432 static HRESULT WINAPI ITextRange_fnGetPoint(ITextRange *me, LONG type, LONG *cx, LONG *cy)
2434 ITextRangeImpl *This = impl_from_ITextRange(me);
2436 FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy);
2438 if (!This->child.reole)
2439 return CO_E_RELEASED;
2441 return E_NOTIMPL;
2444 static HRESULT WINAPI ITextRange_fnSetPoint(ITextRange *me, LONG x, LONG y, LONG type,
2445 LONG extend)
2447 ITextRangeImpl *This = impl_from_ITextRange(me);
2449 FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend);
2451 if (!This->child.reole)
2452 return CO_E_RELEASED;
2454 return E_NOTIMPL;
2457 static HRESULT WINAPI ITextRange_fnScrollIntoView(ITextRange *me, LONG value)
2459 ITextRangeImpl *This = impl_from_ITextRange(me);
2460 ME_TextEditor *editor;
2461 ME_Cursor cursor;
2462 int x, y, height;
2464 TRACE("(%p)->(%d)\n", This, value);
2466 if (!This->child.reole)
2467 return CO_E_RELEASED;
2469 editor = This->child.reole->editor;
2471 switch (value)
2473 case tomStart:
2474 ME_CursorFromCharOfs(editor, This->start, &cursor);
2475 ME_GetCursorCoordinates(editor, &cursor, &x, &y, &height);
2476 break;
2477 default:
2478 FIXME("bStart value %d not handled\n", value);
2479 return E_NOTIMPL;
2481 ME_ScrollAbs(editor, x, y);
2482 return S_OK;
2485 static HRESULT WINAPI ITextRange_fnGetEmbeddedObject(ITextRange *me, IUnknown **ppv)
2487 ITextRangeImpl *This = impl_from_ITextRange(me);
2489 FIXME("(%p)->(%p): stub\n", This, ppv);
2491 if (!This->child.reole)
2492 return CO_E_RELEASED;
2494 return E_NOTIMPL;
2497 static const ITextRangeVtbl trvt = {
2498 ITextRange_fnQueryInterface,
2499 ITextRange_fnAddRef,
2500 ITextRange_fnRelease,
2501 ITextRange_fnGetTypeInfoCount,
2502 ITextRange_fnGetTypeInfo,
2503 ITextRange_fnGetIDsOfNames,
2504 ITextRange_fnInvoke,
2505 ITextRange_fnGetText,
2506 ITextRange_fnSetText,
2507 ITextRange_fnGetChar,
2508 ITextRange_fnSetChar,
2509 ITextRange_fnGetDuplicate,
2510 ITextRange_fnGetFormattedText,
2511 ITextRange_fnSetFormattedText,
2512 ITextRange_fnGetStart,
2513 ITextRange_fnSetStart,
2514 ITextRange_fnGetEnd,
2515 ITextRange_fnSetEnd,
2516 ITextRange_fnGetFont,
2517 ITextRange_fnSetFont,
2518 ITextRange_fnGetPara,
2519 ITextRange_fnSetPara,
2520 ITextRange_fnGetStoryLength,
2521 ITextRange_fnGetStoryType,
2522 ITextRange_fnCollapse,
2523 ITextRange_fnExpand,
2524 ITextRange_fnGetIndex,
2525 ITextRange_fnSetIndex,
2526 ITextRange_fnSetRange,
2527 ITextRange_fnInRange,
2528 ITextRange_fnInStory,
2529 ITextRange_fnIsEqual,
2530 ITextRange_fnSelect,
2531 ITextRange_fnStartOf,
2532 ITextRange_fnEndOf,
2533 ITextRange_fnMove,
2534 ITextRange_fnMoveStart,
2535 ITextRange_fnMoveEnd,
2536 ITextRange_fnMoveWhile,
2537 ITextRange_fnMoveStartWhile,
2538 ITextRange_fnMoveEndWhile,
2539 ITextRange_fnMoveUntil,
2540 ITextRange_fnMoveStartUntil,
2541 ITextRange_fnMoveEndUntil,
2542 ITextRange_fnFindText,
2543 ITextRange_fnFindTextStart,
2544 ITextRange_fnFindTextEnd,
2545 ITextRange_fnDelete,
2546 ITextRange_fnCut,
2547 ITextRange_fnCopy,
2548 ITextRange_fnPaste,
2549 ITextRange_fnCanPaste,
2550 ITextRange_fnCanEdit,
2551 ITextRange_fnChangeCase,
2552 ITextRange_fnGetPoint,
2553 ITextRange_fnSetPoint,
2554 ITextRange_fnScrollIntoView,
2555 ITextRange_fnGetEmbeddedObject
2558 /* ITextFont */
2559 static HRESULT WINAPI TextFont_QueryInterface(ITextFont *iface, REFIID riid, void **ppv)
2561 ITextFontImpl *This = impl_from_ITextFont(iface);
2563 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
2565 if (IsEqualIID(riid, &IID_ITextFont) ||
2566 IsEqualIID(riid, &IID_IDispatch) ||
2567 IsEqualIID(riid, &IID_IUnknown))
2569 *ppv = iface;
2570 ITextFont_AddRef(iface);
2571 return S_OK;
2574 *ppv = NULL;
2575 return E_NOINTERFACE;
2578 static ULONG WINAPI TextFont_AddRef(ITextFont *iface)
2580 ITextFontImpl *This = impl_from_ITextFont(iface);
2581 ULONG ref = InterlockedIncrement(&This->ref);
2582 TRACE("(%p)->(%u)\n", This, ref);
2583 return ref;
2586 static ULONG WINAPI TextFont_Release(ITextFont *iface)
2588 ITextFontImpl *This = impl_from_ITextFont(iface);
2589 ULONG ref = InterlockedDecrement(&This->ref);
2591 TRACE("(%p)->(%u)\n", This, ref);
2593 if (!ref)
2595 if (This->range)
2596 ITextRange_Release(This->range);
2597 SysFreeString(This->props[FONT_NAME].str);
2598 heap_free(This);
2601 return ref;
2604 static HRESULT WINAPI TextFont_GetTypeInfoCount(ITextFont *iface, UINT *pctinfo)
2606 ITextFontImpl *This = impl_from_ITextFont(iface);
2607 TRACE("(%p)->(%p)\n", This, pctinfo);
2608 *pctinfo = 1;
2609 return S_OK;
2612 static HRESULT WINAPI TextFont_GetTypeInfo(ITextFont *iface, UINT iTInfo, LCID lcid,
2613 ITypeInfo **ppTInfo)
2615 ITextFontImpl *This = impl_from_ITextFont(iface);
2616 HRESULT hr;
2618 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
2620 hr = get_typeinfo(ITextFont_tid, ppTInfo);
2621 if (SUCCEEDED(hr))
2622 ITypeInfo_AddRef(*ppTInfo);
2623 return hr;
2626 static HRESULT WINAPI TextFont_GetIDsOfNames(ITextFont *iface, REFIID riid,
2627 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
2629 ITextFontImpl *This = impl_from_ITextFont(iface);
2630 ITypeInfo *ti;
2631 HRESULT hr;
2633 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid),
2634 rgszNames, cNames, lcid, rgDispId);
2636 hr = get_typeinfo(ITextFont_tid, &ti);
2637 if (SUCCEEDED(hr))
2638 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
2639 return hr;
2642 static HRESULT WINAPI TextFont_Invoke(
2643 ITextFont *iface,
2644 DISPID dispIdMember,
2645 REFIID riid,
2646 LCID lcid,
2647 WORD wFlags,
2648 DISPPARAMS *pDispParams,
2649 VARIANT *pVarResult,
2650 EXCEPINFO *pExcepInfo,
2651 UINT *puArgErr)
2653 ITextFontImpl *This = impl_from_ITextFont(iface);
2654 ITypeInfo *ti;
2655 HRESULT hr;
2657 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
2658 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2660 hr = get_typeinfo(ITextFont_tid, &ti);
2661 if (SUCCEEDED(hr))
2662 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2663 return hr;
2666 static HRESULT WINAPI TextFont_GetDuplicate(ITextFont *iface, ITextFont **ret)
2668 ITextFontImpl *This = impl_from_ITextFont(iface);
2670 TRACE("(%p)->(%p)\n", This, ret);
2672 if (!ret)
2673 return E_INVALIDARG;
2675 *ret = NULL;
2676 if (This->range && !get_range_reole(This->range))
2677 return CO_E_RELEASED;
2679 return create_textfont(NULL, This, ret);
2682 static HRESULT WINAPI TextFont_SetDuplicate(ITextFont *iface, ITextFont *pFont)
2684 ITextFontImpl *This = impl_from_ITextFont(iface);
2685 FIXME("(%p)->(%p): stub\n", This, pFont);
2686 return E_NOTIMPL;
2689 static HRESULT WINAPI TextFont_CanChange(ITextFont *iface, LONG *ret)
2691 ITextFontImpl *This = impl_from_ITextFont(iface);
2692 FIXME("(%p)->(%p): stub\n", This, ret);
2693 return E_NOTIMPL;
2696 static HRESULT WINAPI TextFont_IsEqual(ITextFont *iface, ITextFont *font, LONG *ret)
2698 ITextFontImpl *This = impl_from_ITextFont(iface);
2699 FIXME("(%p)->(%p %p): stub\n", This, font, ret);
2700 return E_NOTIMPL;
2703 static void textfont_reset_to_default(ITextFontImpl *font)
2705 enum textfont_prop_id id;
2707 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2708 switch (id)
2710 case FONT_ALLCAPS:
2711 case FONT_ANIMATION:
2712 case FONT_BOLD:
2713 case FONT_EMBOSS:
2714 case FONT_HIDDEN:
2715 case FONT_ENGRAVE:
2716 case FONT_ITALIC:
2717 case FONT_OUTLINE:
2718 case FONT_PROTECTED:
2719 case FONT_SHADOW:
2720 case FONT_SMALLCAPS:
2721 case FONT_STRIKETHROUGH:
2722 case FONT_SUBSCRIPT:
2723 case FONT_SUPERSCRIPT:
2724 case FONT_UNDERLINE:
2725 font->props[id].l = tomFalse;
2726 break;
2727 case FONT_BACKCOLOR:
2728 case FONT_FORECOLOR:
2729 font->props[id].l = tomAutoColor;
2730 break;
2731 case FONT_KERNING:
2732 case FONT_POSITION:
2733 case FONT_SIZE:
2734 case FONT_SPACING:
2735 font->props[id].f = 0.0;
2736 break;
2737 case FONT_LANGID:
2738 font->props[id].l = GetSystemDefaultLCID();
2739 break;
2740 case FONT_NAME: {
2741 static const WCHAR sysW[] = {'S','y','s','t','e','m',0};
2742 SysFreeString(font->props[id].str);
2743 font->props[id].str = SysAllocString(sysW);
2744 break;
2746 case FONT_WEIGHT:
2747 font->props[id].l = FW_NORMAL;
2748 break;
2749 default:
2750 FIXME("font property %d not handled\n", id);
2755 static void textfont_reset_to_undefined(ITextFontImpl *font)
2757 enum textfont_prop_id id;
2759 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2760 switch (id)
2762 case FONT_ALLCAPS:
2763 case FONT_ANIMATION:
2764 case FONT_BOLD:
2765 case FONT_EMBOSS:
2766 case FONT_HIDDEN:
2767 case FONT_ENGRAVE:
2768 case FONT_ITALIC:
2769 case FONT_OUTLINE:
2770 case FONT_PROTECTED:
2771 case FONT_SHADOW:
2772 case FONT_SMALLCAPS:
2773 case FONT_STRIKETHROUGH:
2774 case FONT_SUBSCRIPT:
2775 case FONT_SUPERSCRIPT:
2776 case FONT_UNDERLINE:
2777 case FONT_BACKCOLOR:
2778 case FONT_FORECOLOR:
2779 case FONT_LANGID:
2780 case FONT_WEIGHT:
2781 font->props[id].l = tomUndefined;
2782 break;
2783 case FONT_KERNING:
2784 case FONT_POSITION:
2785 case FONT_SIZE:
2786 case FONT_SPACING:
2787 font->props[id].f = tomUndefined;
2788 break;
2789 case FONT_NAME:
2790 break;
2791 default:
2792 FIXME("font property %d not handled\n", id);
2797 static void textfont_apply_range_props(ITextFontImpl *font)
2799 enum textfont_prop_id propid;
2800 for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++)
2801 set_textfont_prop(font, propid, &font->props[propid]);
2804 static HRESULT WINAPI TextFont_Reset(ITextFont *iface, LONG value)
2806 ITextFontImpl *This = impl_from_ITextFont(iface);
2808 TRACE("(%p)->(%d)\n", This, value);
2810 /* If font is attached to a range, released or not, we can't
2811 reset to undefined */
2812 if (This->range) {
2813 if (!get_range_reole(This->range))
2814 return CO_E_RELEASED;
2816 switch (value)
2818 case tomUndefined:
2819 return E_INVALIDARG;
2820 case tomCacheParms:
2821 textfont_cache_range_props(This);
2822 This->get_cache_enabled = TRUE;
2823 break;
2824 case tomTrackParms:
2825 This->get_cache_enabled = FALSE;
2826 break;
2827 case tomApplyLater:
2828 This->set_cache_enabled = TRUE;
2829 break;
2830 case tomApplyNow:
2831 This->set_cache_enabled = FALSE;
2832 textfont_apply_range_props(This);
2833 break;
2834 case tomUsePoints:
2835 case tomUseTwips:
2836 return E_INVALIDARG;
2837 default:
2838 FIXME("reset mode %d not supported\n", value);
2841 return S_OK;
2843 else {
2844 switch (value)
2846 /* reset to global defaults */
2847 case tomDefault:
2848 textfont_reset_to_default(This);
2849 return S_OK;
2850 /* all properties are set to tomUndefined, font name is retained */
2851 case tomUndefined:
2852 textfont_reset_to_undefined(This);
2853 return S_OK;
2854 case tomApplyNow:
2855 case tomApplyLater:
2856 case tomTrackParms:
2857 case tomCacheParms:
2858 return S_OK;
2859 case tomUsePoints:
2860 case tomUseTwips:
2861 return E_INVALIDARG;
2865 FIXME("reset mode %d not supported\n", value);
2866 return E_NOTIMPL;
2869 static HRESULT WINAPI TextFont_GetStyle(ITextFont *iface, LONG *value)
2871 ITextFontImpl *This = impl_from_ITextFont(iface);
2872 FIXME("(%p)->(%p): stub\n", This, value);
2873 return E_NOTIMPL;
2876 static HRESULT WINAPI TextFont_SetStyle(ITextFont *iface, LONG value)
2878 ITextFontImpl *This = impl_from_ITextFont(iface);
2879 FIXME("(%p)->(%d): stub\n", This, value);
2880 return E_NOTIMPL;
2883 static HRESULT WINAPI TextFont_GetAllCaps(ITextFont *iface, LONG *value)
2885 ITextFontImpl *This = impl_from_ITextFont(iface);
2886 TRACE("(%p)->(%p)\n", This, value);
2887 return get_textfont_propl(This, FONT_ALLCAPS, value);
2890 static HRESULT WINAPI TextFont_SetAllCaps(ITextFont *iface, LONG value)
2892 ITextFontImpl *This = impl_from_ITextFont(iface);
2893 TRACE("(%p)->(%d)\n", This, value);
2894 return set_textfont_propd(This, FONT_ALLCAPS, value);
2897 static HRESULT WINAPI TextFont_GetAnimation(ITextFont *iface, LONG *value)
2899 ITextFontImpl *This = impl_from_ITextFont(iface);
2900 TRACE("(%p)->(%p)\n", This, value);
2901 return get_textfont_propl(This, FONT_ANIMATION, value);
2904 static HRESULT WINAPI TextFont_SetAnimation(ITextFont *iface, LONG value)
2906 ITextFontImpl *This = impl_from_ITextFont(iface);
2908 TRACE("(%p)->(%d)\n", This, value);
2910 if (value < tomNoAnimation || value > tomAnimationMax)
2911 return E_INVALIDARG;
2913 return set_textfont_propl(This, FONT_ANIMATION, value);
2916 static HRESULT WINAPI TextFont_GetBackColor(ITextFont *iface, LONG *value)
2918 ITextFontImpl *This = impl_from_ITextFont(iface);
2919 TRACE("(%p)->(%p)\n", This, value);
2920 return get_textfont_propl(This, FONT_BACKCOLOR, value);
2923 static HRESULT WINAPI TextFont_SetBackColor(ITextFont *iface, LONG value)
2925 ITextFontImpl *This = impl_from_ITextFont(iface);
2926 TRACE("(%p)->(%d)\n", This, value);
2927 return set_textfont_propl(This, FONT_BACKCOLOR, value);
2930 static HRESULT WINAPI TextFont_GetBold(ITextFont *iface, LONG *value)
2932 ITextFontImpl *This = impl_from_ITextFont(iface);
2933 TRACE("(%p)->(%p)\n", This, value);
2934 return get_textfont_propl(This, FONT_BOLD, value);
2937 static HRESULT WINAPI TextFont_SetBold(ITextFont *iface, LONG value)
2939 ITextFontImpl *This = impl_from_ITextFont(iface);
2940 TRACE("(%p)->(%d)\n", This, value);
2941 return set_textfont_propd(This, FONT_BOLD, value);
2944 static HRESULT WINAPI TextFont_GetEmboss(ITextFont *iface, LONG *value)
2946 ITextFontImpl *This = impl_from_ITextFont(iface);
2947 TRACE("(%p)->(%p)\n", This, value);
2948 return get_textfont_propl(This, FONT_EMBOSS, value);
2951 static HRESULT WINAPI TextFont_SetEmboss(ITextFont *iface, LONG value)
2953 ITextFontImpl *This = impl_from_ITextFont(iface);
2954 TRACE("(%p)->(%d)\n", This, value);
2955 return set_textfont_propd(This, FONT_EMBOSS, value);
2958 static HRESULT WINAPI TextFont_GetForeColor(ITextFont *iface, LONG *value)
2960 ITextFontImpl *This = impl_from_ITextFont(iface);
2961 TRACE("(%p)->(%p)\n", This, value);
2962 return get_textfont_propl(This, FONT_FORECOLOR, value);
2965 static HRESULT WINAPI TextFont_SetForeColor(ITextFont *iface, LONG value)
2967 ITextFontImpl *This = impl_from_ITextFont(iface);
2968 TRACE("(%p)->(%d)\n", This, value);
2969 return set_textfont_propl(This, FONT_FORECOLOR, value);
2972 static HRESULT WINAPI TextFont_GetHidden(ITextFont *iface, LONG *value)
2974 ITextFontImpl *This = impl_from_ITextFont(iface);
2975 TRACE("(%p)->(%p)\n", This, value);
2976 return get_textfont_propl(This, FONT_HIDDEN, value);
2979 static HRESULT WINAPI TextFont_SetHidden(ITextFont *iface, LONG value)
2981 ITextFontImpl *This = impl_from_ITextFont(iface);
2982 TRACE("(%p)->(%d)\n", This, value);
2983 return set_textfont_propd(This, FONT_HIDDEN, value);
2986 static HRESULT WINAPI TextFont_GetEngrave(ITextFont *iface, LONG *value)
2988 ITextFontImpl *This = impl_from_ITextFont(iface);
2989 TRACE("(%p)->(%p)\n", This, value);
2990 return get_textfont_propl(This, FONT_ENGRAVE, value);
2993 static HRESULT WINAPI TextFont_SetEngrave(ITextFont *iface, LONG value)
2995 ITextFontImpl *This = impl_from_ITextFont(iface);
2996 TRACE("(%p)->(%d)\n", This, value);
2997 return set_textfont_propd(This, FONT_ENGRAVE, value);
3000 static HRESULT WINAPI TextFont_GetItalic(ITextFont *iface, LONG *value)
3002 ITextFontImpl *This = impl_from_ITextFont(iface);
3003 TRACE("(%p)->(%p)\n", This, value);
3004 return get_textfont_propl(This, FONT_ITALIC, value);
3007 static HRESULT WINAPI TextFont_SetItalic(ITextFont *iface, LONG value)
3009 ITextFontImpl *This = impl_from_ITextFont(iface);
3010 TRACE("(%p)->(%d)\n", This, value);
3011 return set_textfont_propd(This, FONT_ITALIC, value);
3014 static HRESULT WINAPI TextFont_GetKerning(ITextFont *iface, FLOAT *value)
3016 ITextFontImpl *This = impl_from_ITextFont(iface);
3017 TRACE("(%p)->(%p)\n", This, value);
3018 return get_textfont_propf(This, FONT_KERNING, value);
3021 static HRESULT WINAPI TextFont_SetKerning(ITextFont *iface, FLOAT value)
3023 ITextFontImpl *This = impl_from_ITextFont(iface);
3024 TRACE("(%p)->(%.2f)\n", This, value);
3025 return set_textfont_propf(This, FONT_KERNING, value);
3028 static HRESULT WINAPI TextFont_GetLanguageID(ITextFont *iface, LONG *value)
3030 ITextFontImpl *This = impl_from_ITextFont(iface);
3031 TRACE("(%p)->(%p)\n", This, value);
3032 return get_textfont_propl(This, FONT_LANGID, value);
3035 static HRESULT WINAPI TextFont_SetLanguageID(ITextFont *iface, LONG value)
3037 ITextFontImpl *This = impl_from_ITextFont(iface);
3038 TRACE("(%p)->(%d)\n", This, value);
3039 return set_textfont_propl(This, FONT_LANGID, value);
3042 static HRESULT WINAPI TextFont_GetName(ITextFont *iface, BSTR *value)
3044 ITextFontImpl *This = impl_from_ITextFont(iface);
3046 TRACE("(%p)->(%p)\n", This, value);
3048 if (!value)
3049 return E_INVALIDARG;
3051 *value = NULL;
3053 if (!This->range) {
3054 if (This->props[FONT_NAME].str)
3055 *value = SysAllocString(This->props[FONT_NAME].str);
3056 else
3057 *value = SysAllocStringLen(NULL, 0);
3058 return *value ? S_OK : E_OUTOFMEMORY;
3061 return textfont_getname_from_range(This->range, value);
3064 static HRESULT WINAPI TextFont_SetName(ITextFont *iface, BSTR value)
3066 ITextFontImpl *This = impl_from_ITextFont(iface);
3067 textfont_prop_val v;
3069 TRACE("(%p)->(%s)\n", This, debugstr_w(value));
3071 v.str = value;
3072 return set_textfont_prop(This, FONT_NAME, &v);
3075 static HRESULT WINAPI TextFont_GetOutline(ITextFont *iface, LONG *value)
3077 ITextFontImpl *This = impl_from_ITextFont(iface);
3078 TRACE("(%p)->(%p)\n", This, value);
3079 return get_textfont_propl(This, FONT_OUTLINE, value);
3082 static HRESULT WINAPI TextFont_SetOutline(ITextFont *iface, LONG value)
3084 ITextFontImpl *This = impl_from_ITextFont(iface);
3085 TRACE("(%p)->(%d)\n", This, value);
3086 return set_textfont_propd(This, FONT_OUTLINE, value);
3089 static HRESULT WINAPI TextFont_GetPosition(ITextFont *iface, FLOAT *value)
3091 ITextFontImpl *This = impl_from_ITextFont(iface);
3092 TRACE("(%p)->(%p)\n", This, value);
3093 return get_textfont_propf(This, FONT_POSITION, value);
3096 static HRESULT WINAPI TextFont_SetPosition(ITextFont *iface, FLOAT value)
3098 ITextFontImpl *This = impl_from_ITextFont(iface);
3099 TRACE("(%p)->(%.2f)\n", This, value);
3100 return set_textfont_propf(This, FONT_POSITION, value);
3103 static HRESULT WINAPI TextFont_GetProtected(ITextFont *iface, LONG *value)
3105 ITextFontImpl *This = impl_from_ITextFont(iface);
3106 TRACE("(%p)->(%p)\n", This, value);
3107 return get_textfont_propl(This, FONT_PROTECTED, value);
3110 static HRESULT WINAPI TextFont_SetProtected(ITextFont *iface, LONG value)
3112 ITextFontImpl *This = impl_from_ITextFont(iface);
3113 TRACE("(%p)->(%d)\n", This, value);
3114 return set_textfont_propd(This, FONT_PROTECTED, value);
3117 static HRESULT WINAPI TextFont_GetShadow(ITextFont *iface, LONG *value)
3119 ITextFontImpl *This = impl_from_ITextFont(iface);
3120 TRACE("(%p)->(%p)\n", This, value);
3121 return get_textfont_propl(This, FONT_SHADOW, value);
3124 static HRESULT WINAPI TextFont_SetShadow(ITextFont *iface, LONG value)
3126 ITextFontImpl *This = impl_from_ITextFont(iface);
3127 TRACE("(%p)->(%d)\n", This, value);
3128 return set_textfont_propd(This, FONT_SHADOW, value);
3131 static HRESULT WINAPI TextFont_GetSize(ITextFont *iface, FLOAT *value)
3133 ITextFontImpl *This = impl_from_ITextFont(iface);
3134 TRACE("(%p)->(%p)\n", This, value);
3135 return get_textfont_propf(This, FONT_SIZE, value);
3138 static HRESULT WINAPI TextFont_SetSize(ITextFont *iface, FLOAT value)
3140 ITextFontImpl *This = impl_from_ITextFont(iface);
3141 TRACE("(%p)->(%.2f)\n", This, value);
3142 return set_textfont_propf(This, FONT_SIZE, value);
3145 static HRESULT WINAPI TextFont_GetSmallCaps(ITextFont *iface, LONG *value)
3147 ITextFontImpl *This = impl_from_ITextFont(iface);
3148 TRACE("(%p)->(%p)\n", This, value);
3149 return get_textfont_propl(This, FONT_SMALLCAPS, value);
3152 static HRESULT WINAPI TextFont_SetSmallCaps(ITextFont *iface, LONG value)
3154 ITextFontImpl *This = impl_from_ITextFont(iface);
3155 TRACE("(%p)->(%d)\n", This, value);
3156 return set_textfont_propd(This, FONT_SMALLCAPS, value);
3159 static HRESULT WINAPI TextFont_GetSpacing(ITextFont *iface, FLOAT *value)
3161 ITextFontImpl *This = impl_from_ITextFont(iface);
3162 TRACE("(%p)->(%p)\n", This, value);
3163 return get_textfont_propf(This, FONT_SPACING, value);
3166 static HRESULT WINAPI TextFont_SetSpacing(ITextFont *iface, FLOAT value)
3168 ITextFontImpl *This = impl_from_ITextFont(iface);
3169 TRACE("(%p)->(%.2f)\n", This, value);
3170 return set_textfont_propf(This, FONT_SPACING, value);
3173 static HRESULT WINAPI TextFont_GetStrikeThrough(ITextFont *iface, LONG *value)
3175 ITextFontImpl *This = impl_from_ITextFont(iface);
3176 TRACE("(%p)->(%p)\n", This, value);
3177 return get_textfont_propl(This, FONT_STRIKETHROUGH, value);
3180 static HRESULT WINAPI TextFont_SetStrikeThrough(ITextFont *iface, LONG value)
3182 ITextFontImpl *This = impl_from_ITextFont(iface);
3183 TRACE("(%p)->(%d)\n", This, value);
3184 return set_textfont_propd(This, FONT_STRIKETHROUGH, value);
3187 static HRESULT WINAPI TextFont_GetSubscript(ITextFont *iface, LONG *value)
3189 ITextFontImpl *This = impl_from_ITextFont(iface);
3190 TRACE("(%p)->(%p)\n", This, value);
3191 return get_textfont_propl(This, FONT_SUBSCRIPT, value);
3194 static HRESULT WINAPI TextFont_SetSubscript(ITextFont *iface, LONG value)
3196 ITextFontImpl *This = impl_from_ITextFont(iface);
3197 TRACE("(%p)->(%d)\n", This, value);
3198 return set_textfont_propd(This, FONT_SUBSCRIPT, value);
3201 static HRESULT WINAPI TextFont_GetSuperscript(ITextFont *iface, LONG *value)
3203 ITextFontImpl *This = impl_from_ITextFont(iface);
3204 TRACE("(%p)->(%p)\n", This, value);
3205 return get_textfont_propl(This, FONT_SUPERSCRIPT, value);
3208 static HRESULT WINAPI TextFont_SetSuperscript(ITextFont *iface, LONG value)
3210 ITextFontImpl *This = impl_from_ITextFont(iface);
3211 TRACE("(%p)->(%d)\n", This, value);
3212 return set_textfont_propd(This, FONT_SUPERSCRIPT, value);
3215 static HRESULT WINAPI TextFont_GetUnderline(ITextFont *iface, LONG *value)
3217 ITextFontImpl *This = impl_from_ITextFont(iface);
3218 TRACE("(%p)->(%p)\n", This, value);
3219 return get_textfont_propl(This, FONT_UNDERLINE, value);
3222 static HRESULT WINAPI TextFont_SetUnderline(ITextFont *iface, LONG value)
3224 ITextFontImpl *This = impl_from_ITextFont(iface);
3225 TRACE("(%p)->(%d)\n", This, value);
3226 return set_textfont_propd(This, FONT_UNDERLINE, value);
3229 static HRESULT WINAPI TextFont_GetWeight(ITextFont *iface, LONG *value)
3231 ITextFontImpl *This = impl_from_ITextFont(iface);
3232 TRACE("(%p)->(%p)\n", This, value);
3233 return get_textfont_propl(This, FONT_WEIGHT, value);
3236 static HRESULT WINAPI TextFont_SetWeight(ITextFont *iface, LONG value)
3238 ITextFontImpl *This = impl_from_ITextFont(iface);
3239 TRACE("(%p)->(%d)\n", This, value);
3240 return set_textfont_propl(This, FONT_WEIGHT, value);
3243 static ITextFontVtbl textfontvtbl = {
3244 TextFont_QueryInterface,
3245 TextFont_AddRef,
3246 TextFont_Release,
3247 TextFont_GetTypeInfoCount,
3248 TextFont_GetTypeInfo,
3249 TextFont_GetIDsOfNames,
3250 TextFont_Invoke,
3251 TextFont_GetDuplicate,
3252 TextFont_SetDuplicate,
3253 TextFont_CanChange,
3254 TextFont_IsEqual,
3255 TextFont_Reset,
3256 TextFont_GetStyle,
3257 TextFont_SetStyle,
3258 TextFont_GetAllCaps,
3259 TextFont_SetAllCaps,
3260 TextFont_GetAnimation,
3261 TextFont_SetAnimation,
3262 TextFont_GetBackColor,
3263 TextFont_SetBackColor,
3264 TextFont_GetBold,
3265 TextFont_SetBold,
3266 TextFont_GetEmboss,
3267 TextFont_SetEmboss,
3268 TextFont_GetForeColor,
3269 TextFont_SetForeColor,
3270 TextFont_GetHidden,
3271 TextFont_SetHidden,
3272 TextFont_GetEngrave,
3273 TextFont_SetEngrave,
3274 TextFont_GetItalic,
3275 TextFont_SetItalic,
3276 TextFont_GetKerning,
3277 TextFont_SetKerning,
3278 TextFont_GetLanguageID,
3279 TextFont_SetLanguageID,
3280 TextFont_GetName,
3281 TextFont_SetName,
3282 TextFont_GetOutline,
3283 TextFont_SetOutline,
3284 TextFont_GetPosition,
3285 TextFont_SetPosition,
3286 TextFont_GetProtected,
3287 TextFont_SetProtected,
3288 TextFont_GetShadow,
3289 TextFont_SetShadow,
3290 TextFont_GetSize,
3291 TextFont_SetSize,
3292 TextFont_GetSmallCaps,
3293 TextFont_SetSmallCaps,
3294 TextFont_GetSpacing,
3295 TextFont_SetSpacing,
3296 TextFont_GetStrikeThrough,
3297 TextFont_SetStrikeThrough,
3298 TextFont_GetSubscript,
3299 TextFont_SetSubscript,
3300 TextFont_GetSuperscript,
3301 TextFont_SetSuperscript,
3302 TextFont_GetUnderline,
3303 TextFont_SetUnderline,
3304 TextFont_GetWeight,
3305 TextFont_SetWeight
3308 static HRESULT create_textfont(ITextRange *range, const ITextFontImpl *src, ITextFont **ret)
3310 ITextFontImpl *font;
3312 *ret = NULL;
3313 font = heap_alloc(sizeof(*font));
3314 if (!font)
3315 return E_OUTOFMEMORY;
3317 font->ITextFont_iface.lpVtbl = &textfontvtbl;
3318 font->ref = 1;
3320 if (src) {
3321 font->range = NULL;
3322 font->get_cache_enabled = TRUE;
3323 font->set_cache_enabled = TRUE;
3324 memcpy(&font->props, &src->props, sizeof(font->props));
3325 if (font->props[FONT_NAME].str)
3326 font->props[FONT_NAME].str = SysAllocString(font->props[FONT_NAME].str);
3328 else {
3329 font->range = range;
3330 ITextRange_AddRef(range);
3332 /* cache current properties */
3333 font->get_cache_enabled = FALSE;
3334 font->set_cache_enabled = FALSE;
3335 textfont_cache_range_props(font);
3338 *ret = &font->ITextFont_iface;
3339 return S_OK;
3342 /* ITextPara */
3343 static HRESULT WINAPI TextPara_QueryInterface(ITextPara *iface, REFIID riid, void **ppv)
3345 ITextParaImpl *This = impl_from_ITextPara(iface);
3347 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
3349 if (IsEqualIID(riid, &IID_ITextPara) ||
3350 IsEqualIID(riid, &IID_IDispatch) ||
3351 IsEqualIID(riid, &IID_IUnknown))
3353 *ppv = iface;
3354 ITextPara_AddRef(iface);
3355 return S_OK;
3358 *ppv = NULL;
3359 return E_NOINTERFACE;
3362 static ULONG WINAPI TextPara_AddRef(ITextPara *iface)
3364 ITextParaImpl *This = impl_from_ITextPara(iface);
3365 ULONG ref = InterlockedIncrement(&This->ref);
3366 TRACE("(%p)->(%u)\n", This, ref);
3367 return ref;
3370 static ULONG WINAPI TextPara_Release(ITextPara *iface)
3372 ITextParaImpl *This = impl_from_ITextPara(iface);
3373 ULONG ref = InterlockedDecrement(&This->ref);
3375 TRACE("(%p)->(%u)\n", This, ref);
3377 if (!ref)
3379 ITextRange_Release(This->range);
3380 heap_free(This);
3383 return ref;
3386 static HRESULT WINAPI TextPara_GetTypeInfoCount(ITextPara *iface, UINT *pctinfo)
3388 ITextParaImpl *This = impl_from_ITextPara(iface);
3389 TRACE("(%p)->(%p)\n", This, pctinfo);
3390 *pctinfo = 1;
3391 return S_OK;
3394 static HRESULT WINAPI TextPara_GetTypeInfo(ITextPara *iface, UINT iTInfo, LCID lcid,
3395 ITypeInfo **ppTInfo)
3397 ITextParaImpl *This = impl_from_ITextPara(iface);
3398 HRESULT hr;
3400 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
3402 hr = get_typeinfo(ITextPara_tid, ppTInfo);
3403 if (SUCCEEDED(hr))
3404 ITypeInfo_AddRef(*ppTInfo);
3405 return hr;
3408 static HRESULT WINAPI TextPara_GetIDsOfNames(ITextPara *iface, REFIID riid,
3409 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
3411 ITextParaImpl *This = impl_from_ITextPara(iface);
3412 ITypeInfo *ti;
3413 HRESULT hr;
3415 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames,
3416 cNames, lcid, rgDispId);
3418 hr = get_typeinfo(ITextPara_tid, &ti);
3419 if (SUCCEEDED(hr))
3420 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
3421 return hr;
3424 static HRESULT WINAPI TextPara_Invoke(
3425 ITextPara *iface,
3426 DISPID dispIdMember,
3427 REFIID riid,
3428 LCID lcid,
3429 WORD wFlags,
3430 DISPPARAMS *pDispParams,
3431 VARIANT *pVarResult,
3432 EXCEPINFO *pExcepInfo,
3433 UINT *puArgErr)
3435 ITextParaImpl *This = impl_from_ITextPara(iface);
3436 ITypeInfo *ti;
3437 HRESULT hr;
3439 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember,
3440 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
3441 pExcepInfo, puArgErr);
3443 hr = get_typeinfo(ITextPara_tid, &ti);
3444 if (SUCCEEDED(hr))
3445 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3446 return hr;
3449 static HRESULT WINAPI TextPara_GetDuplicate(ITextPara *iface, ITextPara **ret)
3451 ITextParaImpl *This = impl_from_ITextPara(iface);
3452 FIXME("(%p)->(%p)\n", This, ret);
3453 return E_NOTIMPL;
3456 static HRESULT WINAPI TextPara_SetDuplicate(ITextPara *iface, ITextPara *para)
3458 ITextParaImpl *This = impl_from_ITextPara(iface);
3459 FIXME("(%p)->(%p)\n", This, para);
3460 return E_NOTIMPL;
3463 static HRESULT WINAPI TextPara_CanChange(ITextPara *iface, LONG *ret)
3465 ITextParaImpl *This = impl_from_ITextPara(iface);
3466 FIXME("(%p)->(%p)\n", This, ret);
3467 return E_NOTIMPL;
3470 static HRESULT WINAPI TextPara_IsEqual(ITextPara *iface, ITextPara *para, LONG *ret)
3472 ITextParaImpl *This = impl_from_ITextPara(iface);
3473 FIXME("(%p)->(%p %p)\n", This, para, ret);
3474 return E_NOTIMPL;
3477 static HRESULT WINAPI TextPara_Reset(ITextPara *iface, LONG value)
3479 ITextParaImpl *This = impl_from_ITextPara(iface);
3480 FIXME("(%p)->(%d)\n", This, value);
3481 return E_NOTIMPL;
3484 static HRESULT WINAPI TextPara_GetStyle(ITextPara *iface, LONG *value)
3486 ITextParaImpl *This = impl_from_ITextPara(iface);
3487 FIXME("(%p)->(%p)\n", This, value);
3488 return E_NOTIMPL;
3491 static HRESULT WINAPI TextPara_SetStyle(ITextPara *iface, LONG value)
3493 ITextParaImpl *This = impl_from_ITextPara(iface);
3494 FIXME("(%p)->(%d)\n", This, value);
3495 return E_NOTIMPL;
3498 static HRESULT WINAPI TextPara_GetAlignment(ITextPara *iface, LONG *value)
3500 ITextParaImpl *This = impl_from_ITextPara(iface);
3501 FIXME("(%p)->(%p)\n", This, value);
3502 return E_NOTIMPL;
3505 static HRESULT WINAPI TextPara_SetAlignment(ITextPara *iface, LONG value)
3507 ITextParaImpl *This = impl_from_ITextPara(iface);
3508 FIXME("(%p)->(%d)\n", This, value);
3509 return E_NOTIMPL;
3512 static HRESULT WINAPI TextPara_GetHyphenation(ITextPara *iface, LONG *value)
3514 ITextParaImpl *This = impl_from_ITextPara(iface);
3515 FIXME("(%p)->(%p)\n", This, value);
3516 return E_NOTIMPL;
3519 static HRESULT WINAPI TextPara_SetHyphenation(ITextPara *iface, LONG value)
3521 ITextParaImpl *This = impl_from_ITextPara(iface);
3522 FIXME("(%p)->(%d)\n", This, value);
3523 return E_NOTIMPL;
3526 static HRESULT WINAPI TextPara_GetFirstLineIndent(ITextPara *iface, FLOAT *value)
3528 ITextParaImpl *This = impl_from_ITextPara(iface);
3529 FIXME("(%p)->(%p)\n", This, value);
3530 return E_NOTIMPL;
3533 static HRESULT WINAPI TextPara_GetKeepTogether(ITextPara *iface, LONG *value)
3535 ITextParaImpl *This = impl_from_ITextPara(iface);
3536 FIXME("(%p)->(%p)\n", This, value);
3537 return E_NOTIMPL;
3540 static HRESULT WINAPI TextPara_SetKeepTogether(ITextPara *iface, LONG value)
3542 ITextParaImpl *This = impl_from_ITextPara(iface);
3543 FIXME("(%p)->(%d)\n", This, value);
3544 return E_NOTIMPL;
3547 static HRESULT WINAPI TextPara_GetKeepWithNext(ITextPara *iface, LONG *value)
3549 ITextParaImpl *This = impl_from_ITextPara(iface);
3550 FIXME("(%p)->(%p)\n", This, value);
3551 return E_NOTIMPL;
3554 static HRESULT WINAPI TextPara_SetKeepWithNext(ITextPara *iface, LONG value)
3556 ITextParaImpl *This = impl_from_ITextPara(iface);
3557 FIXME("(%p)->(%d)\n", This, value);
3558 return E_NOTIMPL;
3561 static HRESULT WINAPI TextPara_GetLeftIndent(ITextPara *iface, FLOAT *value)
3563 ITextParaImpl *This = impl_from_ITextPara(iface);
3564 FIXME("(%p)->(%p)\n", This, value);
3565 return E_NOTIMPL;
3568 static HRESULT WINAPI TextPara_GetLineSpacing(ITextPara *iface, FLOAT *value)
3570 ITextParaImpl *This = impl_from_ITextPara(iface);
3571 FIXME("(%p)->(%p)\n", This, value);
3572 return E_NOTIMPL;
3575 static HRESULT WINAPI TextPara_GetLineSpacingRule(ITextPara *iface, LONG *value)
3577 ITextParaImpl *This = impl_from_ITextPara(iface);
3578 FIXME("(%p)->(%p)\n", This, value);
3579 return E_NOTIMPL;
3582 static HRESULT WINAPI TextPara_GetListAlignment(ITextPara *iface, LONG *value)
3584 ITextParaImpl *This = impl_from_ITextPara(iface);
3585 FIXME("(%p)->(%p)\n", This, value);
3586 return E_NOTIMPL;
3589 static HRESULT WINAPI TextPara_SetListAlignment(ITextPara *iface, LONG value)
3591 ITextParaImpl *This = impl_from_ITextPara(iface);
3592 FIXME("(%p)->(%d)\n", This, value);
3593 return E_NOTIMPL;
3596 static HRESULT WINAPI TextPara_GetListLevelIndex(ITextPara *iface, LONG *value)
3598 ITextParaImpl *This = impl_from_ITextPara(iface);
3599 FIXME("(%p)->(%p)\n", This, value);
3600 return E_NOTIMPL;
3603 static HRESULT WINAPI TextPara_SetListLevelIndex(ITextPara *iface, LONG value)
3605 ITextParaImpl *This = impl_from_ITextPara(iface);
3606 FIXME("(%p)->(%d)\n", This, value);
3607 return E_NOTIMPL;
3610 static HRESULT WINAPI TextPara_GetListStart(ITextPara *iface, LONG *value)
3612 ITextParaImpl *This = impl_from_ITextPara(iface);
3613 FIXME("(%p)->(%p)\n", This, value);
3614 return E_NOTIMPL;
3617 static HRESULT WINAPI TextPara_SetListStart(ITextPara *iface, LONG value)
3619 ITextParaImpl *This = impl_from_ITextPara(iface);
3620 FIXME("(%p)->(%d)\n", This, value);
3621 return E_NOTIMPL;
3624 static HRESULT WINAPI TextPara_GetListTab(ITextPara *iface, FLOAT *value)
3626 ITextParaImpl *This = impl_from_ITextPara(iface);
3627 FIXME("(%p)->(%p)\n", This, value);
3628 return E_NOTIMPL;
3631 static HRESULT WINAPI TextPara_SetListTab(ITextPara *iface, FLOAT value)
3633 ITextParaImpl *This = impl_from_ITextPara(iface);
3634 FIXME("(%p)->(%.2f)\n", This, value);
3635 return E_NOTIMPL;
3638 static HRESULT WINAPI TextPara_GetListType(ITextPara *iface, LONG *value)
3640 ITextParaImpl *This = impl_from_ITextPara(iface);
3641 FIXME("(%p)->(%p)\n", This, value);
3642 return E_NOTIMPL;
3645 static HRESULT WINAPI TextPara_SetListType(ITextPara *iface, LONG value)
3647 ITextParaImpl *This = impl_from_ITextPara(iface);
3648 FIXME("(%p)->(%d)\n", This, value);
3649 return E_NOTIMPL;
3652 static HRESULT WINAPI TextPara_GetNoLineNumber(ITextPara *iface, LONG *value)
3654 ITextParaImpl *This = impl_from_ITextPara(iface);
3655 FIXME("(%p)->(%p)\n", This, value);
3656 return E_NOTIMPL;
3659 static HRESULT WINAPI TextPara_SetNoLineNumber(ITextPara *iface, LONG value)
3661 ITextParaImpl *This = impl_from_ITextPara(iface);
3662 FIXME("(%p)->(%d)\n", This, value);
3663 return E_NOTIMPL;
3666 static HRESULT WINAPI TextPara_GetPageBreakBefore(ITextPara *iface, LONG *value)
3668 ITextParaImpl *This = impl_from_ITextPara(iface);
3669 FIXME("(%p)->(%p)\n", This, value);
3670 return E_NOTIMPL;
3673 static HRESULT WINAPI TextPara_SetPageBreakBefore(ITextPara *iface, LONG value)
3675 ITextParaImpl *This = impl_from_ITextPara(iface);
3676 FIXME("(%p)->(%d)\n", This, value);
3677 return E_NOTIMPL;
3680 static HRESULT WINAPI TextPara_GetRightIndent(ITextPara *iface, FLOAT *value)
3682 ITextParaImpl *This = impl_from_ITextPara(iface);
3683 FIXME("(%p)->(%p)\n", This, value);
3684 return E_NOTIMPL;
3687 static HRESULT WINAPI TextPara_SetRightIndent(ITextPara *iface, FLOAT value)
3689 ITextParaImpl *This = impl_from_ITextPara(iface);
3690 FIXME("(%p)->(%.2f)\n", This, value);
3691 return E_NOTIMPL;
3694 static HRESULT WINAPI TextPara_SetIndents(ITextPara *iface, FLOAT StartIndent, FLOAT LeftIndent, FLOAT RightIndent)
3696 ITextParaImpl *This = impl_from_ITextPara(iface);
3697 FIXME("(%p)->(%.2f %.2f %.2f)\n", This, StartIndent, LeftIndent, RightIndent);
3698 return E_NOTIMPL;
3701 static HRESULT WINAPI TextPara_SetLineSpacing(ITextPara *iface, LONG LineSpacingRule, FLOAT LineSpacing)
3703 ITextParaImpl *This = impl_from_ITextPara(iface);
3704 FIXME("(%p)->(%d %.2f)\n", This, LineSpacingRule, LineSpacing);
3705 return E_NOTIMPL;
3708 static HRESULT WINAPI TextPara_GetSpaceAfter(ITextPara *iface, FLOAT *value)
3710 ITextParaImpl *This = impl_from_ITextPara(iface);
3711 FIXME("(%p)->(%p)\n", This, value);
3712 return E_NOTIMPL;
3715 static HRESULT WINAPI TextPara_SetSpaceAfter(ITextPara *iface, FLOAT value)
3717 ITextParaImpl *This = impl_from_ITextPara(iface);
3718 FIXME("(%p)->(%.2f)\n", This, value);
3719 return E_NOTIMPL;
3722 static HRESULT WINAPI TextPara_GetSpaceBefore(ITextPara *iface, FLOAT *value)
3724 ITextParaImpl *This = impl_from_ITextPara(iface);
3725 FIXME("(%p)->(%p)\n", This, value);
3726 return E_NOTIMPL;
3729 static HRESULT WINAPI TextPara_SetSpaceBefore(ITextPara *iface, FLOAT value)
3731 ITextParaImpl *This = impl_from_ITextPara(iface);
3732 FIXME("(%p)->(%.2f)\n", This, value);
3733 return E_NOTIMPL;
3736 static HRESULT WINAPI TextPara_GetWidowControl(ITextPara *iface, LONG *value)
3738 ITextParaImpl *This = impl_from_ITextPara(iface);
3739 FIXME("(%p)->(%p)\n", This, value);
3740 return E_NOTIMPL;
3743 static HRESULT WINAPI TextPara_SetWidowControl(ITextPara *iface, LONG value)
3745 ITextParaImpl *This = impl_from_ITextPara(iface);
3746 FIXME("(%p)->(%d)\n", This, value);
3747 return E_NOTIMPL;
3750 static HRESULT WINAPI TextPara_GetTabCount(ITextPara *iface, LONG *value)
3752 ITextParaImpl *This = impl_from_ITextPara(iface);
3753 FIXME("(%p)->(%p)\n", This, value);
3754 return E_NOTIMPL;
3757 static HRESULT WINAPI TextPara_AddTab(ITextPara *iface, FLOAT tbPos, LONG tbAlign, LONG tbLeader)
3759 ITextParaImpl *This = impl_from_ITextPara(iface);
3760 FIXME("(%p)->(%.2f %d %d)\n", This, tbPos, tbAlign, tbLeader);
3761 return E_NOTIMPL;
3764 static HRESULT WINAPI TextPara_ClearAllTabs(ITextPara *iface)
3766 ITextParaImpl *This = impl_from_ITextPara(iface);
3767 FIXME("(%p)\n", This);
3768 return E_NOTIMPL;
3771 static HRESULT WINAPI TextPara_DeleteTab(ITextPara *iface, FLOAT pos)
3773 ITextParaImpl *This = impl_from_ITextPara(iface);
3774 FIXME("(%p)->(%.2f)\n", This, pos);
3775 return E_NOTIMPL;
3778 static HRESULT WINAPI TextPara_GetTab(ITextPara *iface, LONG iTab, FLOAT *ptbPos, LONG *ptbAlign, LONG *ptbLeader)
3780 ITextParaImpl *This = impl_from_ITextPara(iface);
3781 FIXME("(%p)->(%d %p %p %p)\n", This, iTab, ptbPos, ptbAlign, ptbLeader);
3782 return E_NOTIMPL;
3785 static ITextParaVtbl textparavtbl = {
3786 TextPara_QueryInterface,
3787 TextPara_AddRef,
3788 TextPara_Release,
3789 TextPara_GetTypeInfoCount,
3790 TextPara_GetTypeInfo,
3791 TextPara_GetIDsOfNames,
3792 TextPara_Invoke,
3793 TextPara_GetDuplicate,
3794 TextPara_SetDuplicate,
3795 TextPara_CanChange,
3796 TextPara_IsEqual,
3797 TextPara_Reset,
3798 TextPara_GetStyle,
3799 TextPara_SetStyle,
3800 TextPara_GetAlignment,
3801 TextPara_SetAlignment,
3802 TextPara_GetHyphenation,
3803 TextPara_SetHyphenation,
3804 TextPara_GetFirstLineIndent,
3805 TextPara_GetKeepTogether,
3806 TextPara_SetKeepTogether,
3807 TextPara_GetKeepWithNext,
3808 TextPara_SetKeepWithNext,
3809 TextPara_GetLeftIndent,
3810 TextPara_GetLineSpacing,
3811 TextPara_GetLineSpacingRule,
3812 TextPara_GetListAlignment,
3813 TextPara_SetListAlignment,
3814 TextPara_GetListLevelIndex,
3815 TextPara_SetListLevelIndex,
3816 TextPara_GetListStart,
3817 TextPara_SetListStart,
3818 TextPara_GetListTab,
3819 TextPara_SetListTab,
3820 TextPara_GetListType,
3821 TextPara_SetListType,
3822 TextPara_GetNoLineNumber,
3823 TextPara_SetNoLineNumber,
3824 TextPara_GetPageBreakBefore,
3825 TextPara_SetPageBreakBefore,
3826 TextPara_GetRightIndent,
3827 TextPara_SetRightIndent,
3828 TextPara_SetIndents,
3829 TextPara_SetLineSpacing,
3830 TextPara_GetSpaceAfter,
3831 TextPara_SetSpaceAfter,
3832 TextPara_GetSpaceBefore,
3833 TextPara_SetSpaceBefore,
3834 TextPara_GetWidowControl,
3835 TextPara_SetWidowControl,
3836 TextPara_GetTabCount,
3837 TextPara_AddTab,
3838 TextPara_ClearAllTabs,
3839 TextPara_DeleteTab,
3840 TextPara_GetTab
3843 static HRESULT create_textpara(ITextRange *range, ITextPara **ret)
3845 ITextParaImpl *para;
3847 *ret = NULL;
3848 para = heap_alloc(sizeof(*para));
3849 if (!para)
3850 return E_OUTOFMEMORY;
3852 para->ITextPara_iface.lpVtbl = &textparavtbl;
3853 para->ref = 1;
3854 para->range = range;
3855 ITextRange_AddRef(range);
3857 *ret = &para->ITextPara_iface;
3858 return S_OK;
3861 /* ITextDocument */
3862 static HRESULT WINAPI
3863 ITextDocument_fnQueryInterface(ITextDocument* me, REFIID riid,
3864 void** ppvObject)
3866 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3867 return IRichEditOle_QueryInterface(&This->IRichEditOle_iface, riid, ppvObject);
3870 static ULONG WINAPI
3871 ITextDocument_fnAddRef(ITextDocument* me)
3873 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3874 return IRichEditOle_AddRef(&This->IRichEditOle_iface);
3877 static ULONG WINAPI
3878 ITextDocument_fnRelease(ITextDocument* me)
3880 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3881 return IRichEditOle_Release(&This->IRichEditOle_iface);
3884 static HRESULT WINAPI
3885 ITextDocument_fnGetTypeInfoCount(ITextDocument* me,
3886 UINT* pctinfo)
3888 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3889 TRACE("(%p)->(%p)\n", This, pctinfo);
3890 *pctinfo = 1;
3891 return S_OK;
3894 static HRESULT WINAPI
3895 ITextDocument_fnGetTypeInfo(ITextDocument* me, UINT iTInfo, LCID lcid,
3896 ITypeInfo** ppTInfo)
3898 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3899 HRESULT hr;
3901 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
3903 hr = get_typeinfo(ITextDocument_tid, ppTInfo);
3904 if (SUCCEEDED(hr))
3905 ITypeInfo_AddRef(*ppTInfo);
3906 return hr;
3909 static HRESULT WINAPI
3910 ITextDocument_fnGetIDsOfNames(ITextDocument* me, REFIID riid,
3911 LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId)
3913 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3914 ITypeInfo *ti;
3915 HRESULT hr;
3917 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid),
3918 rgszNames, cNames, lcid, rgDispId);
3920 hr = get_typeinfo(ITextDocument_tid, &ti);
3921 if (SUCCEEDED(hr))
3922 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
3923 return hr;
3926 static HRESULT WINAPI
3927 ITextDocument_fnInvoke(ITextDocument* me, DISPID dispIdMember,
3928 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
3929 VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
3931 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3932 ITypeInfo *ti;
3933 HRESULT hr;
3935 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember,
3936 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
3937 pExcepInfo, puArgErr);
3939 hr = get_typeinfo(ITextDocument_tid, &ti);
3940 if (SUCCEEDED(hr))
3941 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3942 return hr;
3945 static HRESULT WINAPI
3946 ITextDocument_fnGetName(ITextDocument* me, BSTR* pName)
3948 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3949 FIXME("stub %p\n",This);
3950 return E_NOTIMPL;
3953 static HRESULT WINAPI
3954 ITextDocument_fnGetSelection(ITextDocument *me, ITextSelection **selection)
3956 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3958 TRACE("(%p)->(%p)\n", me, selection);
3960 if (!selection)
3961 return E_INVALIDARG;
3963 if (!This->txtSel) {
3964 This->txtSel = CreateTextSelection(This);
3965 if (!This->txtSel) {
3966 *selection = NULL;
3967 return E_OUTOFMEMORY;
3971 *selection = &This->txtSel->ITextSelection_iface;
3972 ITextSelection_AddRef(*selection);
3973 return S_OK;
3976 static HRESULT WINAPI
3977 ITextDocument_fnGetStoryCount(ITextDocument* me, LONG* pCount)
3979 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3980 FIXME("stub %p\n",This);
3981 return E_NOTIMPL;
3984 static HRESULT WINAPI
3985 ITextDocument_fnGetStoryRanges(ITextDocument* me,
3986 ITextStoryRanges** ppStories)
3988 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3989 FIXME("stub %p\n",This);
3990 return E_NOTIMPL;
3993 static HRESULT WINAPI
3994 ITextDocument_fnGetSaved(ITextDocument* me, LONG* pValue)
3996 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3997 FIXME("stub %p\n",This);
3998 return E_NOTIMPL;
4001 static HRESULT WINAPI
4002 ITextDocument_fnSetSaved(ITextDocument* me, LONG Value)
4004 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4005 FIXME("stub %p\n",This);
4006 return E_NOTIMPL;
4009 static HRESULT WINAPI
4010 ITextDocument_fnGetDefaultTabStop(ITextDocument* me, float* pValue)
4012 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4013 FIXME("stub %p\n",This);
4014 return E_NOTIMPL;
4017 static HRESULT WINAPI
4018 ITextDocument_fnSetDefaultTabStop(ITextDocument* me, float Value)
4020 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4021 FIXME("stub %p\n",This);
4022 return E_NOTIMPL;
4025 static HRESULT WINAPI
4026 ITextDocument_fnNew(ITextDocument* me)
4028 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4029 FIXME("stub %p\n",This);
4030 return E_NOTIMPL;
4033 static HRESULT WINAPI
4034 ITextDocument_fnOpen(ITextDocument* me, VARIANT* pVar, LONG Flags,
4035 LONG CodePage)
4037 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4038 FIXME("stub %p\n",This);
4039 return E_NOTIMPL;
4042 static HRESULT WINAPI
4043 ITextDocument_fnSave(ITextDocument* me, VARIANT* pVar, LONG Flags,
4044 LONG CodePage)
4046 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4047 FIXME("stub %p\n",This);
4048 return E_NOTIMPL;
4051 static HRESULT WINAPI
4052 ITextDocument_fnFreeze(ITextDocument* me, LONG* pCount)
4054 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4055 FIXME("stub %p\n",This);
4056 return E_NOTIMPL;
4059 static HRESULT WINAPI
4060 ITextDocument_fnUnfreeze(ITextDocument* me, LONG* pCount)
4062 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4063 FIXME("stub %p\n",This);
4064 return E_NOTIMPL;
4067 static HRESULT WINAPI
4068 ITextDocument_fnBeginEditCollection(ITextDocument* me)
4070 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4071 FIXME("stub %p\n",This);
4072 return E_NOTIMPL;
4075 static HRESULT WINAPI
4076 ITextDocument_fnEndEditCollection(ITextDocument* me)
4078 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4079 FIXME("stub %p\n",This);
4080 return E_NOTIMPL;
4083 static HRESULT WINAPI
4084 ITextDocument_fnUndo(ITextDocument* me, LONG Count, LONG* prop)
4086 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4087 FIXME("stub %p\n",This);
4088 return E_NOTIMPL;
4091 static HRESULT WINAPI
4092 ITextDocument_fnRedo(ITextDocument* me, LONG Count, LONG* prop)
4094 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4095 FIXME("stub %p\n",This);
4096 return E_NOTIMPL;
4099 static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, ITextRange** ppRange)
4101 ITextRangeImpl *txtRge = heap_alloc(sizeof(ITextRangeImpl));
4103 if (!txtRge)
4104 return E_OUTOFMEMORY;
4105 txtRge->ITextRange_iface.lpVtbl = &trvt;
4106 txtRge->ref = 1;
4107 txtRge->child.reole = reOle;
4108 txtRge->start = start;
4109 txtRge->end = end;
4110 list_add_head(&reOle->rangelist, &txtRge->child.entry);
4111 *ppRange = &txtRge->ITextRange_iface;
4112 return S_OK;
4115 static HRESULT WINAPI
4116 ITextDocument_fnRange(ITextDocument* me, LONG cp1, LONG cp2,
4117 ITextRange** ppRange)
4119 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4120 const int len = ME_GetTextLength(This->editor) + 1;
4122 TRACE("%p %p %d %d\n", This, ppRange, cp1, cp2);
4123 if (!ppRange)
4124 return E_INVALIDARG;
4126 cp1 = max(cp1, 0);
4127 cp2 = max(cp2, 0);
4128 cp1 = min(cp1, len);
4129 cp2 = min(cp2, len);
4130 if (cp1 > cp2)
4132 LONG tmp;
4133 tmp = cp1;
4134 cp1 = cp2;
4135 cp2 = tmp;
4137 if (cp1 == len)
4138 cp1 = cp2 = len - 1;
4140 return CreateITextRange(This, cp1, cp2, ppRange);
4143 static HRESULT WINAPI
4144 ITextDocument_fnRangeFromPoint(ITextDocument* me, LONG x, LONG y,
4145 ITextRange** ppRange)
4147 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4148 FIXME("stub %p\n",This);
4149 return E_NOTIMPL;
4152 static const ITextDocumentVtbl tdvt = {
4153 ITextDocument_fnQueryInterface,
4154 ITextDocument_fnAddRef,
4155 ITextDocument_fnRelease,
4156 ITextDocument_fnGetTypeInfoCount,
4157 ITextDocument_fnGetTypeInfo,
4158 ITextDocument_fnGetIDsOfNames,
4159 ITextDocument_fnInvoke,
4160 ITextDocument_fnGetName,
4161 ITextDocument_fnGetSelection,
4162 ITextDocument_fnGetStoryCount,
4163 ITextDocument_fnGetStoryRanges,
4164 ITextDocument_fnGetSaved,
4165 ITextDocument_fnSetSaved,
4166 ITextDocument_fnGetDefaultTabStop,
4167 ITextDocument_fnSetDefaultTabStop,
4168 ITextDocument_fnNew,
4169 ITextDocument_fnOpen,
4170 ITextDocument_fnSave,
4171 ITextDocument_fnFreeze,
4172 ITextDocument_fnUnfreeze,
4173 ITextDocument_fnBeginEditCollection,
4174 ITextDocument_fnEndEditCollection,
4175 ITextDocument_fnUndo,
4176 ITextDocument_fnRedo,
4177 ITextDocument_fnRange,
4178 ITextDocument_fnRangeFromPoint
4181 /* ITextSelection */
4182 static HRESULT WINAPI ITextSelection_fnQueryInterface(
4183 ITextSelection *me,
4184 REFIID riid,
4185 void **ppvObj)
4187 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4189 *ppvObj = NULL;
4190 if (IsEqualGUID(riid, &IID_IUnknown)
4191 || IsEqualGUID(riid, &IID_IDispatch)
4192 || IsEqualGUID(riid, &IID_ITextRange)
4193 || IsEqualGUID(riid, &IID_ITextSelection))
4195 *ppvObj = me;
4196 ITextSelection_AddRef(me);
4197 return S_OK;
4199 else if (IsEqualGUID(riid, &IID_Igetrichole))
4201 *ppvObj = This->reOle;
4202 return S_OK;
4205 return E_NOINTERFACE;
4208 static ULONG WINAPI ITextSelection_fnAddRef(ITextSelection *me)
4210 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4211 return InterlockedIncrement(&This->ref);
4214 static ULONG WINAPI ITextSelection_fnRelease(ITextSelection *me)
4216 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4217 ULONG ref = InterlockedDecrement(&This->ref);
4218 if (ref == 0)
4219 heap_free(This);
4220 return ref;
4223 static HRESULT WINAPI ITextSelection_fnGetTypeInfoCount(ITextSelection *me, UINT *pctinfo)
4225 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4226 TRACE("(%p)->(%p)\n", This, pctinfo);
4227 *pctinfo = 1;
4228 return S_OK;
4231 static HRESULT WINAPI ITextSelection_fnGetTypeInfo(ITextSelection *me, UINT iTInfo, LCID lcid,
4232 ITypeInfo **ppTInfo)
4234 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4235 HRESULT hr;
4237 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
4239 hr = get_typeinfo(ITextSelection_tid, ppTInfo);
4240 if (SUCCEEDED(hr))
4241 ITypeInfo_AddRef(*ppTInfo);
4242 return hr;
4245 static HRESULT WINAPI ITextSelection_fnGetIDsOfNames(ITextSelection *me, REFIID riid,
4246 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
4248 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4249 ITypeInfo *ti;
4250 HRESULT hr;
4252 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
4253 rgDispId);
4255 hr = get_typeinfo(ITextSelection_tid, &ti);
4256 if (SUCCEEDED(hr))
4257 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
4258 return hr;
4261 static HRESULT WINAPI ITextSelection_fnInvoke(
4262 ITextSelection *me,
4263 DISPID dispIdMember,
4264 REFIID riid,
4265 LCID lcid,
4266 WORD wFlags,
4267 DISPPARAMS *pDispParams,
4268 VARIANT *pVarResult,
4269 EXCEPINFO *pExcepInfo,
4270 UINT *puArgErr)
4272 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4273 ITypeInfo *ti;
4274 HRESULT hr;
4276 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid), lcid,
4277 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4279 hr = get_typeinfo(ITextSelection_tid, &ti);
4280 if (SUCCEEDED(hr))
4281 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4282 return hr;
4285 /*** ITextRange methods ***/
4286 static HRESULT WINAPI ITextSelection_fnGetText(ITextSelection *me, BSTR *pbstr)
4288 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4289 ME_Cursor *start = NULL, *end = NULL;
4290 int nChars, endOfs;
4291 BOOL bEOP;
4293 TRACE("(%p)->(%p)\n", This, pbstr);
4295 if (!This->reOle)
4296 return CO_E_RELEASED;
4298 if (!pbstr)
4299 return E_INVALIDARG;
4301 ME_GetSelection(This->reOle->editor, &start, &end);
4302 endOfs = ME_GetCursorOfs(end);
4303 nChars = endOfs - ME_GetCursorOfs(start);
4304 if (!nChars)
4306 *pbstr = NULL;
4307 return S_OK;
4310 *pbstr = SysAllocStringLen(NULL, nChars);
4311 if (!*pbstr)
4312 return E_OUTOFMEMORY;
4314 bEOP = (end->pRun->next->type == diTextEnd && endOfs > ME_GetTextLength(This->reOle->editor));
4315 ME_GetTextW(This->reOle->editor, *pbstr, nChars, start, nChars, FALSE, bEOP);
4316 TRACE("%s\n", wine_dbgstr_w(*pbstr));
4318 return S_OK;
4321 static HRESULT WINAPI ITextSelection_fnSetText(ITextSelection *me, BSTR str)
4323 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4324 ME_TextEditor *editor;
4325 int len, to, from;
4327 TRACE("(%p)->(%s)\n", This, debugstr_w(str));
4329 if (!This->reOle)
4330 return CO_E_RELEASED;
4332 editor = This->reOle->editor;
4333 len = strlenW(str);
4334 ME_GetSelectionOfs(editor, &from, &to);
4335 ME_ReplaceSel(editor, FALSE, str, len);
4337 if (len < to - from)
4338 textranges_update_ranges(This->reOle, from, len, RANGE_UPDATE_DELETE);
4340 return S_OK;
4343 static HRESULT WINAPI ITextSelection_fnGetChar(ITextSelection *me, LONG *pch)
4345 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4346 ME_Cursor *start = NULL, *end = NULL;
4348 TRACE("(%p)->(%p)\n", This, pch);
4350 if (!This->reOle)
4351 return CO_E_RELEASED;
4353 if (!pch)
4354 return E_INVALIDARG;
4356 ME_GetSelection(This->reOle->editor, &start, &end);
4357 return range_GetChar(This->reOle->editor, start, pch);
4360 static HRESULT WINAPI ITextSelection_fnSetChar(ITextSelection *me, LONG ch)
4362 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4364 FIXME("(%p)->(%x): stub\n", This, ch);
4366 if (!This->reOle)
4367 return CO_E_RELEASED;
4369 return E_NOTIMPL;
4372 static HRESULT WINAPI ITextSelection_fnGetDuplicate(ITextSelection *me, ITextRange **range)
4374 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4375 LONG start, end;
4377 TRACE("(%p)->(%p)\n", This, range);
4379 if (!This->reOle)
4380 return CO_E_RELEASED;
4382 if (!range)
4383 return E_INVALIDARG;
4385 ITextSelection_GetStart(me, &start);
4386 ITextSelection_GetEnd(me, &end);
4387 return CreateITextRange(This->reOle, start, end, range);
4390 static HRESULT WINAPI ITextSelection_fnGetFormattedText(ITextSelection *me, ITextRange **range)
4392 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4394 FIXME("(%p)->(%p): stub\n", This, range);
4396 if (!This->reOle)
4397 return CO_E_RELEASED;
4399 return E_NOTIMPL;
4402 static HRESULT WINAPI ITextSelection_fnSetFormattedText(ITextSelection *me, ITextRange *range)
4404 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4406 FIXME("(%p)->(%p): stub\n", This, range);
4408 if (!This->reOle)
4409 return CO_E_RELEASED;
4411 FIXME("not implemented\n");
4412 return E_NOTIMPL;
4415 static HRESULT WINAPI ITextSelection_fnGetStart(ITextSelection *me, LONG *pcpFirst)
4417 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4418 LONG lim;
4420 TRACE("(%p)->(%p)\n", This, pcpFirst);
4422 if (!This->reOle)
4423 return CO_E_RELEASED;
4425 if (!pcpFirst)
4426 return E_INVALIDARG;
4427 ME_GetSelectionOfs(This->reOle->editor, pcpFirst, &lim);
4428 return S_OK;
4431 static HRESULT WINAPI ITextSelection_fnSetStart(ITextSelection *me, LONG value)
4433 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4434 LONG start, end;
4435 HRESULT hr;
4437 TRACE("(%p)->(%d)\n", This, value);
4439 if (!This->reOle)
4440 return CO_E_RELEASED;
4442 ME_GetSelectionOfs(This->reOle->editor, &start, &end);
4443 hr = textrange_setstart(This->reOle, value, &start, &end);
4444 if (hr == S_OK)
4445 ME_SetSelection(This->reOle->editor, start, end);
4447 return hr;
4450 static HRESULT WINAPI ITextSelection_fnGetEnd(ITextSelection *me, LONG *pcpLim)
4452 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4453 LONG first;
4455 TRACE("(%p)->(%p)\n", This, pcpLim);
4457 if (!This->reOle)
4458 return CO_E_RELEASED;
4460 if (!pcpLim)
4461 return E_INVALIDARG;
4462 ME_GetSelectionOfs(This->reOle->editor, &first, pcpLim);
4463 return S_OK;
4466 static HRESULT WINAPI ITextSelection_fnSetEnd(ITextSelection *me, LONG value)
4468 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4469 LONG start, end;
4470 HRESULT hr;
4472 TRACE("(%p)->(%d)\n", This, value);
4474 if (!This->reOle)
4475 return CO_E_RELEASED;
4477 ME_GetSelectionOfs(This->reOle->editor, &start, &end);
4478 hr = textrange_setend(This->reOle, value, &start, &end);
4479 if (hr == S_OK)
4480 ME_SetSelection(This->reOle->editor, start, end);
4482 return hr;
4485 static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **font)
4487 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4488 ITextRange *range = NULL;
4489 HRESULT hr;
4491 TRACE("(%p)->(%p)\n", This, font);
4493 if (!This->reOle)
4494 return CO_E_RELEASED;
4496 if (!font)
4497 return E_INVALIDARG;
4499 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
4500 hr = create_textfont(range, NULL, font);
4501 ITextRange_Release(range);
4502 return hr;
4505 static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *font)
4507 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4508 ITextRange *range = NULL;
4510 TRACE("(%p)->(%p)\n", This, font);
4512 if (!font)
4513 return E_INVALIDARG;
4515 if (!This->reOle)
4516 return CO_E_RELEASED;
4518 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
4519 textrange_set_font(range, font);
4520 ITextRange_Release(range);
4521 return S_OK;
4524 static HRESULT WINAPI ITextSelection_fnGetPara(ITextSelection *me, ITextPara **para)
4526 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4527 ITextRange *range = NULL;
4528 HRESULT hr;
4530 TRACE("(%p)->(%p)\n", This, para);
4532 if (!This->reOle)
4533 return CO_E_RELEASED;
4535 if (!para)
4536 return E_INVALIDARG;
4538 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
4539 hr = create_textpara(range, para);
4540 ITextRange_Release(range);
4541 return hr;
4544 static HRESULT WINAPI ITextSelection_fnSetPara(ITextSelection *me, ITextPara *para)
4546 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4548 FIXME("(%p)->(%p): stub\n", This, para);
4550 if (!This->reOle)
4551 return CO_E_RELEASED;
4553 FIXME("not implemented\n");
4554 return E_NOTIMPL;
4557 static HRESULT WINAPI ITextSelection_fnGetStoryLength(ITextSelection *me, LONG *length)
4559 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4561 TRACE("(%p)->(%p)\n", This, length);
4563 if (!This->reOle)
4564 return CO_E_RELEASED;
4566 return textrange_get_storylength(This->reOle->editor, length);
4569 static HRESULT WINAPI ITextSelection_fnGetStoryType(ITextSelection *me, LONG *value)
4571 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4573 TRACE("(%p)->(%p)\n", This, value);
4575 if (!This->reOle)
4576 return CO_E_RELEASED;
4578 if (!value)
4579 return E_INVALIDARG;
4581 *value = tomUnknownStory;
4582 return S_OK;
4585 static HRESULT WINAPI ITextSelection_fnCollapse(ITextSelection *me, LONG bStart)
4587 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4588 LONG start, end;
4589 HRESULT hres;
4591 TRACE("(%p)->(%d)\n", This, bStart);
4593 if (!This->reOle)
4594 return CO_E_RELEASED;
4596 ME_GetSelectionOfs(This->reOle->editor, &start, &end);
4597 hres = range_Collapse(bStart, &start, &end);
4598 if (SUCCEEDED(hres))
4599 ME_SetSelection(This->reOle->editor, start, end);
4600 return hres;
4603 static HRESULT WINAPI ITextSelection_fnExpand(ITextSelection *me, LONG unit, LONG *delta)
4605 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4606 ITextRange *range = NULL;
4607 HRESULT hr;
4609 TRACE("(%p)->(%d %p)\n", This, unit, delta);
4611 if (!This->reOle)
4612 return CO_E_RELEASED;
4614 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
4615 hr = textrange_expand(range, unit, delta);
4616 ITextRange_Release(range);
4617 return hr;
4620 static HRESULT WINAPI ITextSelection_fnGetIndex(ITextSelection *me, LONG unit, LONG *index)
4622 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4624 FIXME("(%p)->(%d %p): stub\n", This, unit, index);
4626 if (!This->reOle)
4627 return CO_E_RELEASED;
4629 return E_NOTIMPL;
4632 static HRESULT WINAPI ITextSelection_fnSetIndex(ITextSelection *me, LONG unit, LONG index,
4633 LONG extend)
4635 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4637 FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend);
4639 if (!This->reOle)
4640 return CO_E_RELEASED;
4642 return E_NOTIMPL;
4645 static HRESULT WINAPI ITextSelection_fnSetRange(ITextSelection *me, LONG anchor, LONG active)
4647 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4649 FIXME("(%p)->(%d %d): stub\n", This, anchor, active);
4651 if (!This->reOle)
4652 return CO_E_RELEASED;
4654 return E_NOTIMPL;
4657 static HRESULT WINAPI ITextSelection_fnInRange(ITextSelection *me, ITextRange *range, LONG *ret)
4659 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4660 ITextSelection *selection = NULL;
4661 LONG start, end;
4663 TRACE("(%p)->(%p %p)\n", This, range, ret);
4665 if (ret)
4666 *ret = tomFalse;
4668 if (!This->reOle)
4669 return CO_E_RELEASED;
4671 if (!range)
4672 return S_FALSE;
4674 ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection);
4675 if (!selection)
4676 return S_FALSE;
4677 ITextSelection_Release(selection);
4679 ITextSelection_GetStart(me, &start);
4680 ITextSelection_GetEnd(me, &end);
4681 return textrange_inrange(start, end, range, ret);
4684 static HRESULT WINAPI ITextSelection_fnInStory(ITextSelection *me, ITextRange *range, LONG *ret)
4686 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4688 FIXME("(%p)->(%p %p): stub\n", This, range, ret);
4690 if (!This->reOle)
4691 return CO_E_RELEASED;
4693 return E_NOTIMPL;
4696 static HRESULT WINAPI ITextSelection_fnIsEqual(ITextSelection *me, ITextRange *range, LONG *ret)
4698 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4699 ITextSelection *selection = NULL;
4700 LONG start, end;
4702 TRACE("(%p)->(%p %p)\n", This, range, ret);
4704 if (ret)
4705 *ret = tomFalse;
4707 if (!This->reOle)
4708 return CO_E_RELEASED;
4710 if (!range)
4711 return S_FALSE;
4713 ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection);
4714 if (!selection)
4715 return S_FALSE;
4716 ITextSelection_Release(selection);
4718 ITextSelection_GetStart(me, &start);
4719 ITextSelection_GetEnd(me, &end);
4720 return textrange_isequal(start, end, range, ret);
4723 static HRESULT WINAPI ITextSelection_fnSelect(ITextSelection *me)
4725 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4727 TRACE("(%p)\n", This);
4729 if (!This->reOle)
4730 return CO_E_RELEASED;
4732 /* nothing to do */
4733 return S_OK;
4736 static HRESULT WINAPI ITextSelection_fnStartOf(ITextSelection *me, LONG unit, LONG extend,
4737 LONG *delta)
4739 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4741 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
4743 if (!This->reOle)
4744 return CO_E_RELEASED;
4746 return E_NOTIMPL;
4749 static HRESULT WINAPI ITextSelection_fnEndOf(ITextSelection *me, LONG unit, LONG extend,
4750 LONG *delta)
4752 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4754 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
4756 if (!This->reOle)
4757 return CO_E_RELEASED;
4759 return E_NOTIMPL;
4762 static HRESULT WINAPI ITextSelection_fnMove(ITextSelection *me, LONG unit, LONG count, LONG *delta)
4764 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4766 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
4768 if (!This->reOle)
4769 return CO_E_RELEASED;
4771 return E_NOTIMPL;
4774 static HRESULT WINAPI ITextSelection_fnMoveStart(ITextSelection *me, LONG unit, LONG count,
4775 LONG *delta)
4777 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4779 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
4781 if (!This->reOle)
4782 return CO_E_RELEASED;
4784 return E_NOTIMPL;
4787 static HRESULT WINAPI ITextSelection_fnMoveEnd(ITextSelection *me, LONG unit, LONG count,
4788 LONG *delta)
4790 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4791 ITextRange *range = NULL;
4792 HRESULT hr;
4794 TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta);
4796 if (!This->reOle)
4797 return CO_E_RELEASED;
4799 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
4800 hr = textrange_moveend(range, unit, count, delta);
4801 ITextRange_Release(range);
4802 return hr;
4805 static HRESULT WINAPI ITextSelection_fnMoveWhile(ITextSelection *me, VARIANT *charset, LONG count,
4806 LONG *delta)
4808 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4810 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4812 if (!This->reOle)
4813 return CO_E_RELEASED;
4815 return E_NOTIMPL;
4818 static HRESULT WINAPI ITextSelection_fnMoveStartWhile(ITextSelection *me, VARIANT *charset, LONG count,
4819 LONG *delta)
4821 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4823 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4825 if (!This->reOle)
4826 return CO_E_RELEASED;
4828 return E_NOTIMPL;
4831 static HRESULT WINAPI ITextSelection_fnMoveEndWhile(ITextSelection *me, VARIANT *charset, LONG count,
4832 LONG *delta)
4834 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4836 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4838 if (!This->reOle)
4839 return CO_E_RELEASED;
4841 return E_NOTIMPL;
4844 static HRESULT WINAPI ITextSelection_fnMoveUntil(ITextSelection *me, VARIANT *charset, LONG count,
4845 LONG *delta)
4847 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4849 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4851 if (!This->reOle)
4852 return CO_E_RELEASED;
4854 return E_NOTIMPL;
4857 static HRESULT WINAPI ITextSelection_fnMoveStartUntil(ITextSelection *me, VARIANT *charset, LONG count,
4858 LONG *delta)
4860 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4862 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4864 if (!This->reOle)
4865 return CO_E_RELEASED;
4867 return E_NOTIMPL;
4870 static HRESULT WINAPI ITextSelection_fnMoveEndUntil(ITextSelection *me, VARIANT *charset, LONG count,
4871 LONG *delta)
4873 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4875 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4877 if (!This->reOle)
4878 return CO_E_RELEASED;
4880 return E_NOTIMPL;
4883 static HRESULT WINAPI ITextSelection_fnFindText(ITextSelection *me, BSTR text, LONG count, LONG flags,
4884 LONG *length)
4886 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4888 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
4890 if (!This->reOle)
4891 return CO_E_RELEASED;
4893 FIXME("not implemented\n");
4894 return E_NOTIMPL;
4897 static HRESULT WINAPI ITextSelection_fnFindTextStart(ITextSelection *me, BSTR text, LONG count,
4898 LONG flags, LONG *length)
4900 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4902 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
4904 if (!This->reOle)
4905 return CO_E_RELEASED;
4907 return E_NOTIMPL;
4910 static HRESULT WINAPI ITextSelection_fnFindTextEnd(ITextSelection *me, BSTR text, LONG count,
4911 LONG flags, LONG *length)
4913 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4915 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
4917 if (!This->reOle)
4918 return CO_E_RELEASED;
4920 return E_NOTIMPL;
4923 static HRESULT WINAPI ITextSelection_fnDelete(ITextSelection *me, LONG unit, LONG count,
4924 LONG *delta)
4926 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4928 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
4930 if (!This->reOle)
4931 return CO_E_RELEASED;
4933 return E_NOTIMPL;
4936 static HRESULT WINAPI ITextSelection_fnCut(ITextSelection *me, VARIANT *v)
4938 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4940 FIXME("(%p)->(%p): stub\n", This, v);
4942 if (!This->reOle)
4943 return CO_E_RELEASED;
4945 return E_NOTIMPL;
4948 static HRESULT WINAPI ITextSelection_fnCopy(ITextSelection *me, VARIANT *v)
4950 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4952 FIXME("(%p)->(%p): stub\n", This, v);
4954 if (!This->reOle)
4955 return CO_E_RELEASED;
4957 return E_NOTIMPL;
4960 static HRESULT WINAPI ITextSelection_fnPaste(ITextSelection *me, VARIANT *v, LONG format)
4962 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4964 FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format);
4966 if (!This->reOle)
4967 return CO_E_RELEASED;
4969 return E_NOTIMPL;
4972 static HRESULT WINAPI ITextSelection_fnCanPaste(ITextSelection *me, VARIANT *v, LONG format,
4973 LONG *ret)
4975 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4977 FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret);
4979 if (!This->reOle)
4980 return CO_E_RELEASED;
4982 return E_NOTIMPL;
4985 static HRESULT WINAPI ITextSelection_fnCanEdit(ITextSelection *me, LONG *ret)
4987 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4989 FIXME("(%p)->(%p): stub\n", This, ret);
4991 if (!This->reOle)
4992 return CO_E_RELEASED;
4994 return E_NOTIMPL;
4997 static HRESULT WINAPI ITextSelection_fnChangeCase(ITextSelection *me, LONG type)
4999 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5001 FIXME("(%p)->(%d): stub\n", This, type);
5003 if (!This->reOle)
5004 return CO_E_RELEASED;
5006 return E_NOTIMPL;
5009 static HRESULT WINAPI ITextSelection_fnGetPoint(ITextSelection *me, LONG type, LONG *cx, LONG *cy)
5011 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5013 FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy);
5015 if (!This->reOle)
5016 return CO_E_RELEASED;
5018 return E_NOTIMPL;
5021 static HRESULT WINAPI ITextSelection_fnSetPoint(ITextSelection *me, LONG x, LONG y, LONG type,
5022 LONG extend)
5024 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5026 FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend);
5028 if (!This->reOle)
5029 return CO_E_RELEASED;
5031 return E_NOTIMPL;
5034 static HRESULT WINAPI ITextSelection_fnScrollIntoView(ITextSelection *me, LONG value)
5036 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5038 FIXME("(%p)->(%d): stub\n", This, value);
5040 if (!This->reOle)
5041 return CO_E_RELEASED;
5043 return E_NOTIMPL;
5046 static HRESULT WINAPI ITextSelection_fnGetEmbeddedObject(ITextSelection *me, IUnknown **ppv)
5048 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5050 FIXME("(%p)->(%p): stub\n", This, ppv);
5052 if (!This->reOle)
5053 return CO_E_RELEASED;
5055 return E_NOTIMPL;
5058 /*** ITextSelection methods ***/
5059 static HRESULT WINAPI ITextSelection_fnGetFlags(ITextSelection *me, LONG *flags)
5061 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5063 FIXME("(%p)->(%p): stub\n", This, flags);
5065 if (!This->reOle)
5066 return CO_E_RELEASED;
5068 return E_NOTIMPL;
5071 static HRESULT WINAPI ITextSelection_fnSetFlags(ITextSelection *me, LONG flags)
5073 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5075 FIXME("(%p)->(%x): stub\n", This, flags);
5077 if (!This->reOle)
5078 return CO_E_RELEASED;
5080 return E_NOTIMPL;
5083 static HRESULT WINAPI ITextSelection_fnGetType(ITextSelection *me, LONG *type)
5085 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5087 FIXME("(%p)->(%p): stub\n", This, type);
5089 if (!This->reOle)
5090 return CO_E_RELEASED;
5092 return E_NOTIMPL;
5095 static HRESULT WINAPI ITextSelection_fnMoveLeft(ITextSelection *me, LONG unit, LONG count,
5096 LONG extend, LONG *delta)
5098 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5100 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5102 if (!This->reOle)
5103 return CO_E_RELEASED;
5105 return E_NOTIMPL;
5108 static HRESULT WINAPI ITextSelection_fnMoveRight(ITextSelection *me, LONG unit, LONG count,
5109 LONG extend, LONG *delta)
5111 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5113 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5115 if (!This->reOle)
5116 return CO_E_RELEASED;
5118 return E_NOTIMPL;
5121 static HRESULT WINAPI ITextSelection_fnMoveUp(ITextSelection *me, LONG unit, LONG count,
5122 LONG extend, LONG *delta)
5124 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5126 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5128 if (!This->reOle)
5129 return CO_E_RELEASED;
5131 return E_NOTIMPL;
5134 static HRESULT WINAPI ITextSelection_fnMoveDown(ITextSelection *me, LONG unit, LONG count,
5135 LONG extend, LONG *delta)
5137 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5139 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5141 if (!This->reOle)
5142 return CO_E_RELEASED;
5144 return E_NOTIMPL;
5147 static HRESULT WINAPI ITextSelection_fnHomeKey(ITextSelection *me, LONG unit, LONG extend,
5148 LONG *delta)
5150 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5152 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
5154 if (!This->reOle)
5155 return CO_E_RELEASED;
5157 return E_NOTIMPL;
5160 static HRESULT WINAPI ITextSelection_fnEndKey(ITextSelection *me, LONG unit, LONG extend,
5161 LONG *delta)
5163 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5165 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
5167 if (!This->reOle)
5168 return CO_E_RELEASED;
5170 return E_NOTIMPL;
5173 static HRESULT WINAPI ITextSelection_fnTypeText(ITextSelection *me, BSTR text)
5175 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5177 FIXME("(%p)->(%s): stub\n", This, debugstr_w(text));
5179 if (!This->reOle)
5180 return CO_E_RELEASED;
5182 return E_NOTIMPL;
5185 static const ITextSelectionVtbl tsvt = {
5186 ITextSelection_fnQueryInterface,
5187 ITextSelection_fnAddRef,
5188 ITextSelection_fnRelease,
5189 ITextSelection_fnGetTypeInfoCount,
5190 ITextSelection_fnGetTypeInfo,
5191 ITextSelection_fnGetIDsOfNames,
5192 ITextSelection_fnInvoke,
5193 ITextSelection_fnGetText,
5194 ITextSelection_fnSetText,
5195 ITextSelection_fnGetChar,
5196 ITextSelection_fnSetChar,
5197 ITextSelection_fnGetDuplicate,
5198 ITextSelection_fnGetFormattedText,
5199 ITextSelection_fnSetFormattedText,
5200 ITextSelection_fnGetStart,
5201 ITextSelection_fnSetStart,
5202 ITextSelection_fnGetEnd,
5203 ITextSelection_fnSetEnd,
5204 ITextSelection_fnGetFont,
5205 ITextSelection_fnSetFont,
5206 ITextSelection_fnGetPara,
5207 ITextSelection_fnSetPara,
5208 ITextSelection_fnGetStoryLength,
5209 ITextSelection_fnGetStoryType,
5210 ITextSelection_fnCollapse,
5211 ITextSelection_fnExpand,
5212 ITextSelection_fnGetIndex,
5213 ITextSelection_fnSetIndex,
5214 ITextSelection_fnSetRange,
5215 ITextSelection_fnInRange,
5216 ITextSelection_fnInStory,
5217 ITextSelection_fnIsEqual,
5218 ITextSelection_fnSelect,
5219 ITextSelection_fnStartOf,
5220 ITextSelection_fnEndOf,
5221 ITextSelection_fnMove,
5222 ITextSelection_fnMoveStart,
5223 ITextSelection_fnMoveEnd,
5224 ITextSelection_fnMoveWhile,
5225 ITextSelection_fnMoveStartWhile,
5226 ITextSelection_fnMoveEndWhile,
5227 ITextSelection_fnMoveUntil,
5228 ITextSelection_fnMoveStartUntil,
5229 ITextSelection_fnMoveEndUntil,
5230 ITextSelection_fnFindText,
5231 ITextSelection_fnFindTextStart,
5232 ITextSelection_fnFindTextEnd,
5233 ITextSelection_fnDelete,
5234 ITextSelection_fnCut,
5235 ITextSelection_fnCopy,
5236 ITextSelection_fnPaste,
5237 ITextSelection_fnCanPaste,
5238 ITextSelection_fnCanEdit,
5239 ITextSelection_fnChangeCase,
5240 ITextSelection_fnGetPoint,
5241 ITextSelection_fnSetPoint,
5242 ITextSelection_fnScrollIntoView,
5243 ITextSelection_fnGetEmbeddedObject,
5244 ITextSelection_fnGetFlags,
5245 ITextSelection_fnSetFlags,
5246 ITextSelection_fnGetType,
5247 ITextSelection_fnMoveLeft,
5248 ITextSelection_fnMoveRight,
5249 ITextSelection_fnMoveUp,
5250 ITextSelection_fnMoveDown,
5251 ITextSelection_fnHomeKey,
5252 ITextSelection_fnEndKey,
5253 ITextSelection_fnTypeText
5256 static ITextSelectionImpl *
5257 CreateTextSelection(IRichEditOleImpl *reOle)
5259 ITextSelectionImpl *txtSel = heap_alloc(sizeof *txtSel);
5260 if (!txtSel)
5261 return NULL;
5263 txtSel->ITextSelection_iface.lpVtbl = &tsvt;
5264 txtSel->ref = 1;
5265 txtSel->reOle = reOle;
5266 return txtSel;
5269 LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *ppvObj)
5271 IRichEditOleImpl *reo;
5273 reo = heap_alloc(sizeof(IRichEditOleImpl));
5274 if (!reo)
5275 return 0;
5277 reo->IUnknown_inner.lpVtbl = &reo_unk_vtbl;
5278 reo->IRichEditOle_iface.lpVtbl = &revt;
5279 reo->ITextDocument_iface.lpVtbl = &tdvt;
5280 reo->ref = 1;
5281 reo->editor = editor;
5282 reo->txtSel = NULL;
5284 TRACE("Created %p\n",reo);
5285 list_init(&reo->rangelist);
5286 list_init(&reo->clientsites);
5287 if (outer_unk)
5288 reo->outer_unk = outer_unk;
5289 else
5290 reo->outer_unk = &reo->IUnknown_inner;
5291 *ppvObj = &reo->IRichEditOle_iface;
5293 return 1;
5296 static void convert_sizel(const ME_Context *c, const SIZEL* szl, SIZE* sz)
5298 /* sizel is in .01 millimeters, sz in pixels */
5299 sz->cx = MulDiv(szl->cx, c->dpi.cx, 2540);
5300 sz->cy = MulDiv(szl->cy, c->dpi.cy, 2540);
5303 /******************************************************************************
5304 * ME_GetOLEObjectSize
5306 * Sets run extent for OLE objects.
5308 void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize)
5310 IDataObject* ido;
5311 FORMATETC fmt;
5312 STGMEDIUM stgm;
5313 DIBSECTION dibsect;
5314 ENHMETAHEADER emh;
5316 assert(run->nFlags & MERF_GRAPHICS);
5317 assert(run->reobj);
5319 if (run->reobj->obj.sizel.cx != 0 || run->reobj->obj.sizel.cy != 0)
5321 convert_sizel(c, &run->reobj->obj.sizel, pSize);
5322 if (c->editor->nZoomNumerator != 0)
5324 pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5325 pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5327 return;
5330 if (!run->reobj->obj.poleobj)
5332 pSize->cx = pSize->cy = 0;
5333 return;
5336 if (IOleObject_QueryInterface(run->reobj->obj.poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
5338 FIXME("Query Interface IID_IDataObject failed!\n");
5339 pSize->cx = pSize->cy = 0;
5340 return;
5342 fmt.cfFormat = CF_BITMAP;
5343 fmt.ptd = NULL;
5344 fmt.dwAspect = DVASPECT_CONTENT;
5345 fmt.lindex = -1;
5346 fmt.tymed = TYMED_GDI;
5347 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5349 fmt.cfFormat = CF_ENHMETAFILE;
5350 fmt.tymed = TYMED_ENHMF;
5351 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5353 FIXME("unsupported format\n");
5354 pSize->cx = pSize->cy = 0;
5355 IDataObject_Release(ido);
5356 return;
5359 IDataObject_Release(ido);
5361 switch (stgm.tymed)
5363 case TYMED_GDI:
5364 GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
5365 pSize->cx = dibsect.dsBm.bmWidth;
5366 pSize->cy = dibsect.dsBm.bmHeight;
5367 break;
5368 case TYMED_ENHMF:
5369 GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
5370 pSize->cx = emh.rclBounds.right - emh.rclBounds.left;
5371 pSize->cy = emh.rclBounds.bottom - emh.rclBounds.top;
5372 break;
5373 default:
5374 FIXME("Unsupported tymed %d\n", stgm.tymed);
5375 break;
5377 ReleaseStgMedium(&stgm);
5378 if (c->editor->nZoomNumerator != 0)
5380 pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5381 pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5385 void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run, BOOL selected)
5387 IDataObject* ido;
5388 FORMATETC fmt;
5389 STGMEDIUM stgm;
5390 DIBSECTION dibsect;
5391 ENHMETAHEADER emh;
5392 HDC hMemDC;
5393 SIZE sz;
5394 BOOL has_size;
5395 HBITMAP old_bm;
5396 RECT rc;
5398 assert(run->nFlags & MERF_GRAPHICS);
5399 assert(run->reobj);
5400 if (IOleObject_QueryInterface(run->reobj->obj.poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
5402 FIXME("Couldn't get interface\n");
5403 return;
5405 has_size = run->reobj->obj.sizel.cx != 0 || run->reobj->obj.sizel.cy != 0;
5406 fmt.cfFormat = CF_BITMAP;
5407 fmt.ptd = NULL;
5408 fmt.dwAspect = DVASPECT_CONTENT;
5409 fmt.lindex = -1;
5410 fmt.tymed = TYMED_GDI;
5411 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5413 fmt.cfFormat = CF_ENHMETAFILE;
5414 fmt.tymed = TYMED_ENHMF;
5415 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5417 FIXME("Couldn't get storage medium\n");
5418 IDataObject_Release(ido);
5419 return;
5422 IDataObject_Release(ido);
5424 switch (stgm.tymed)
5426 case TYMED_GDI:
5427 GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
5428 hMemDC = CreateCompatibleDC(c->hDC);
5429 old_bm = SelectObject(hMemDC, stgm.u.hBitmap);
5430 if (has_size)
5432 convert_sizel(c, &run->reobj->obj.sizel, &sz);
5433 } else {
5434 sz.cx = dibsect.dsBm.bmWidth;
5435 sz.cy = dibsect.dsBm.bmHeight;
5437 if (c->editor->nZoomNumerator != 0)
5439 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5440 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5442 StretchBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy,
5443 hMemDC, 0, 0, dibsect.dsBm.bmWidth, dibsect.dsBm.bmHeight, SRCCOPY);
5445 SelectObject(hMemDC, old_bm);
5446 DeleteDC(hMemDC);
5447 break;
5448 case TYMED_ENHMF:
5449 GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
5450 if (has_size)
5452 convert_sizel(c, &run->reobj->obj.sizel, &sz);
5453 } else {
5454 sz.cx = emh.rclBounds.right - emh.rclBounds.left;
5455 sz.cy = emh.rclBounds.bottom - emh.rclBounds.top;
5457 if (c->editor->nZoomNumerator != 0)
5459 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5460 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5463 rc.left = x;
5464 rc.top = y - sz.cy;
5465 rc.right = x + sz.cx;
5466 rc.bottom = y;
5467 PlayEnhMetaFile(c->hDC, stgm.u.hEnhMetaFile, &rc);
5468 break;
5469 default:
5470 FIXME("Unsupported tymed %d\n", stgm.tymed);
5471 selected = FALSE;
5472 break;
5474 ReleaseStgMedium(&stgm);
5476 if (selected && !c->editor->bHideSelection)
5477 PatBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy, DSTINVERT);
5480 void ME_DeleteReObject(struct re_object *reobj)
5482 if (reobj->obj.poleobj) IOleObject_Release(reobj->obj.poleobj);
5483 if (reobj->obj.pstg) IStorage_Release(reobj->obj.pstg);
5484 if (reobj->obj.polesite) IOleClientSite_Release(reobj->obj.polesite);
5485 heap_free(reobj);
5488 void ME_CopyReObject(REOBJECT *dst, const REOBJECT *src, DWORD flags)
5490 *dst = *src;
5491 dst->poleobj = NULL;
5492 dst->pstg = NULL;
5493 dst->polesite = NULL;
5495 if ((flags & REO_GETOBJ_POLEOBJ) && src->poleobj)
5497 dst->poleobj = src->poleobj;
5498 IOleObject_AddRef(dst->poleobj);
5500 if ((flags & REO_GETOBJ_PSTG) && src->pstg)
5502 dst->pstg = src->pstg;
5503 IStorage_AddRef(dst->pstg);
5505 if ((flags & REO_GETOBJ_POLESITE) && src->polesite)
5507 dst->polesite = src->polesite;
5508 IOleClientSite_AddRef(dst->polesite);
5512 void ME_GetITextDocumentInterface(IRichEditOle *iface, LPVOID *ppvObj)
5514 IRichEditOleImpl *This = impl_from_IRichEditOle(iface);
5515 *ppvObj = &This->ITextDocument_iface;