riched20: Improve error handling in SetFont (Coverity).
[wine.git] / dlls / riched20 / richole.c
blobd39bce7bd0db02b93eb472123e6ba91e545add02
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 IOleWindow IOleWindow_iface;
262 IOleInPlaceSite IOleInPlaceSite_iface;
263 LONG ref;
266 static inline IRichEditOleImpl *impl_from_IRichEditOle(IRichEditOle *iface)
268 return CONTAINING_RECORD(iface, IRichEditOleImpl, IRichEditOle_iface);
271 static inline IRichEditOleImpl *impl_from_ITextDocument(ITextDocument *iface)
273 return CONTAINING_RECORD(iface, IRichEditOleImpl, ITextDocument_iface);
276 static inline IRichEditOleImpl *impl_from_IUnknown(IUnknown *iface)
278 return CONTAINING_RECORD(iface, IRichEditOleImpl, IUnknown_inner);
281 static inline IOleClientSiteImpl *impl_from_IOleWindow(IOleWindow *iface)
283 return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleWindow_iface);
286 static inline IOleClientSiteImpl *impl_from_IOleInPlaceSite(IOleInPlaceSite *iface)
288 return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleInPlaceSite_iface);
291 static inline ITextRangeImpl *impl_from_ITextRange(ITextRange *iface)
293 return CONTAINING_RECORD(iface, ITextRangeImpl, ITextRange_iface);
296 static inline ITextSelectionImpl *impl_from_ITextSelection(ITextSelection *iface)
298 return CONTAINING_RECORD(iface, ITextSelectionImpl, ITextSelection_iface);
301 static inline ITextFontImpl *impl_from_ITextFont(ITextFont *iface)
303 return CONTAINING_RECORD(iface, ITextFontImpl, ITextFont_iface);
306 static inline ITextParaImpl *impl_from_ITextPara(ITextPara *iface)
308 return CONTAINING_RECORD(iface, ITextParaImpl, ITextPara_iface);
311 static HRESULT create_textfont(ITextRange*, const ITextFontImpl*, ITextFont**);
312 static HRESULT create_textpara(ITextRange*, ITextPara**);
313 static ITextSelectionImpl *CreateTextSelection(IRichEditOleImpl*);
315 static HRESULT textrange_get_storylength(ME_TextEditor *editor, LONG *length)
317 if (!length)
318 return E_INVALIDARG;
320 *length = ME_GetTextLength(editor) + 1;
321 return S_OK;
324 static void textranges_update_ranges(IRichEditOleImpl *reole, LONG start, LONG end, enum range_update_op op)
326 ITextRangeImpl *range;
328 LIST_FOR_EACH_ENTRY(range, &reole->rangelist, ITextRangeImpl, child.entry) {
329 switch (op)
331 case RANGE_UPDATE_DELETE:
332 /* range fully covered by deleted range - collapse to insertion point */
333 if (range->start >= start && range->end <= end)
334 range->start = range->end = start;
335 /* deleted range cuts from the right */
336 else if (range->start < start && range->end <= end)
337 range->end = start;
338 /* deleted range cuts from the left */
339 else if (range->start >= start && range->end > end) {
340 range->start = start;
341 range->end -= end - start;
343 /* deleted range cuts within */
344 else
345 range->end -= end - start;
346 break;
347 default:
348 FIXME("unknown update op, %d\n", op);
353 static inline BOOL is_equal_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *left,
354 textfont_prop_val *right)
356 switch (propid)
358 case FONT_ALLCAPS:
359 case FONT_ANIMATION:
360 case FONT_BACKCOLOR:
361 case FONT_BOLD:
362 case FONT_EMBOSS:
363 case FONT_FORECOLOR:
364 case FONT_HIDDEN:
365 case FONT_ENGRAVE:
366 case FONT_ITALIC:
367 case FONT_KERNING:
368 case FONT_LANGID:
369 case FONT_OUTLINE:
370 case FONT_PROTECTED:
371 case FONT_SHADOW:
372 case FONT_SMALLCAPS:
373 case FONT_STRIKETHROUGH:
374 case FONT_SUBSCRIPT:
375 case FONT_SUPERSCRIPT:
376 case FONT_UNDERLINE:
377 case FONT_WEIGHT:
378 return left->l == right->l;
379 case FONT_NAME:
380 return !strcmpW(left->str, right->str);
381 case FONT_POSITION:
382 case FONT_SIZE:
383 case FONT_SPACING:
384 return left->f == right->f;
385 default:
386 FIXME("unhandled font property %d\n", propid);
387 return FALSE;
391 static inline void init_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *v)
393 switch (propid)
395 case FONT_ALLCAPS:
396 case FONT_ANIMATION:
397 case FONT_BACKCOLOR:
398 case FONT_BOLD:
399 case FONT_EMBOSS:
400 case FONT_FORECOLOR:
401 case FONT_HIDDEN:
402 case FONT_ENGRAVE:
403 case FONT_ITALIC:
404 case FONT_KERNING:
405 case FONT_LANGID:
406 case FONT_OUTLINE:
407 case FONT_PROTECTED:
408 case FONT_SHADOW:
409 case FONT_SMALLCAPS:
410 case FONT_STRIKETHROUGH:
411 case FONT_SUBSCRIPT:
412 case FONT_SUPERSCRIPT:
413 case FONT_UNDERLINE:
414 case FONT_WEIGHT:
415 v->l = tomUndefined;
416 return;
417 case FONT_NAME:
418 v->str = NULL;
419 return;
420 case FONT_POSITION:
421 case FONT_SIZE:
422 case FONT_SPACING:
423 v->f = tomUndefined;
424 return;
425 default:
426 FIXME("unhandled font property %d\n", propid);
427 v->l = tomUndefined;
428 return;
432 static inline FLOAT twips_to_points(LONG value)
434 return value * 72.0 / 1440;
437 static inline FLOAT points_to_twips(FLOAT value)
439 return value * 1440 / 72.0;
442 static HRESULT get_textfont_prop_for_pos(const IRichEditOleImpl *reole, int pos, enum textfont_prop_id propid,
443 textfont_prop_val *value)
445 ME_Cursor from, to;
446 CHARFORMAT2W fmt;
448 memset(&fmt, 0, sizeof(fmt));
449 fmt.cbSize = sizeof(fmt);
450 fmt.dwMask = textfont_prop_masks[propid][0];
452 ME_CursorFromCharOfs(reole->editor, pos, &from);
453 to = from;
454 ME_MoveCursorChars(reole->editor, &to, 1);
455 ME_GetCharFormat(reole->editor, &from, &to, &fmt);
457 switch (propid)
459 case FONT_ALLCAPS:
460 case FONT_BOLD:
461 case FONT_EMBOSS:
462 case FONT_HIDDEN:
463 case FONT_ENGRAVE:
464 case FONT_ITALIC:
465 case FONT_OUTLINE:
466 case FONT_PROTECTED:
467 case FONT_SHADOW:
468 case FONT_SMALLCAPS:
469 case FONT_STRIKETHROUGH:
470 case FONT_SUBSCRIPT:
471 case FONT_SUPERSCRIPT:
472 case FONT_UNDERLINE:
473 value->l = fmt.dwEffects & textfont_prop_masks[propid][1] ? tomTrue : tomFalse;
474 break;
475 case FONT_ANIMATION:
476 value->l = fmt.bAnimation;
477 break;
478 case FONT_BACKCOLOR:
479 value->l = fmt.dwEffects & CFE_AUTOBACKCOLOR ? GetSysColor(COLOR_WINDOW) : fmt.crBackColor;
480 break;
481 case FONT_FORECOLOR:
482 value->l = fmt.dwEffects & CFE_AUTOCOLOR ? GetSysColor(COLOR_WINDOWTEXT) : fmt.crTextColor;
483 break;
484 case FONT_KERNING:
485 value->f = twips_to_points(fmt.wKerning);
486 break;
487 case FONT_LANGID:
488 value->l = fmt.lcid;
489 break;
490 case FONT_NAME:
491 /* this case is used exclusively by GetName() */
492 value->str = SysAllocString(fmt.szFaceName);
493 if (!value->str)
494 return E_OUTOFMEMORY;
495 break;
496 case FONT_POSITION:
497 value->f = twips_to_points(fmt.yOffset);
498 break;
499 case FONT_SIZE:
500 value->f = twips_to_points(fmt.yHeight);
501 break;
502 case FONT_SPACING:
503 value->f = fmt.sSpacing;
504 break;
505 case FONT_WEIGHT:
506 value->l = fmt.wWeight;
507 break;
508 default:
509 FIXME("unhandled font property %d\n", propid);
510 return E_FAIL;
513 return S_OK;
516 static inline const IRichEditOleImpl *get_range_reole(ITextRange *range)
518 IRichEditOleImpl *reole = NULL;
519 ITextRange_QueryInterface(range, &IID_Igetrichole, (void**)&reole);
520 return reole;
523 static void textrange_set_font(ITextRange *range, ITextFont *font)
525 CHARFORMAT2W fmt;
526 HRESULT hr;
527 LONG value;
528 BSTR str;
529 FLOAT f;
531 #define CHARFORMAT_SET_B_FIELD(mask, value) \
532 if (hr == S_OK && value != tomUndefined) { \
533 fmt.dwMask |= CFM_##mask; \
534 if (value == tomTrue) fmt.dwEffects |= CFE_##mask; \
537 /* fill format data from font */
538 memset(&fmt, 0, sizeof(fmt));
539 fmt.cbSize = sizeof(fmt);
541 value = tomUndefined;
542 hr = ITextFont_GetAllCaps(font, &value);
543 CHARFORMAT_SET_B_FIELD(ALLCAPS, value);
545 value = tomUndefined;
546 hr = ITextFont_GetBold(font, &value);
547 CHARFORMAT_SET_B_FIELD(BOLD, value);
549 value = tomUndefined;
550 hr = ITextFont_GetEmboss(font, &value);
551 CHARFORMAT_SET_B_FIELD(EMBOSS, value);
553 value = tomUndefined;
554 hr = ITextFont_GetHidden(font, &value);
555 CHARFORMAT_SET_B_FIELD(HIDDEN, value);
557 value = tomUndefined;
558 hr = ITextFont_GetEngrave(font, &value);
559 CHARFORMAT_SET_B_FIELD(IMPRINT, value);
561 value = tomUndefined;
562 hr = ITextFont_GetItalic(font, &value);
563 CHARFORMAT_SET_B_FIELD(ITALIC, value);
565 value = tomUndefined;
566 hr = ITextFont_GetOutline(font, &value);
567 CHARFORMAT_SET_B_FIELD(OUTLINE, value);
569 value = tomUndefined;
570 hr = ITextFont_GetProtected(font, &value);
571 CHARFORMAT_SET_B_FIELD(PROTECTED, value);
573 value = tomUndefined;
574 hr = ITextFont_GetShadow(font, &value);
575 CHARFORMAT_SET_B_FIELD(SHADOW, value);
577 value = tomUndefined;
578 hr = ITextFont_GetSmallCaps(font, &value);
579 CHARFORMAT_SET_B_FIELD(SMALLCAPS, value);
581 value = tomUndefined;
582 hr = ITextFont_GetStrikeThrough(font, &value);
583 CHARFORMAT_SET_B_FIELD(STRIKEOUT, value);
585 value = tomUndefined;
586 hr = ITextFont_GetSubscript(font, &value);
587 CHARFORMAT_SET_B_FIELD(SUBSCRIPT, value);
589 value = tomUndefined;
590 hr = ITextFont_GetSuperscript(font, &value);
591 CHARFORMAT_SET_B_FIELD(SUPERSCRIPT, value);
593 value = tomUndefined;
594 hr = ITextFont_GetUnderline(font, &value);
595 CHARFORMAT_SET_B_FIELD(UNDERLINE, value);
597 #undef CHARFORMAT_SET_B_FIELD
599 value = tomUndefined;
600 hr = ITextFont_GetAnimation(font, &value);
601 if (hr == S_OK && value != tomUndefined) {
602 fmt.dwMask |= CFM_ANIMATION;
603 fmt.bAnimation = value;
606 value = tomUndefined;
607 hr = ITextFont_GetBackColor(font, &value);
608 if (hr == S_OK && value != tomUndefined) {
609 fmt.dwMask |= CFM_BACKCOLOR;
610 if (value == tomAutoColor)
611 fmt.dwEffects |= CFE_AUTOBACKCOLOR;
612 else
613 fmt.crBackColor = value;
616 value = tomUndefined;
617 hr = ITextFont_GetForeColor(font, &value);
618 if (hr == S_OK && value != tomUndefined) {
619 fmt.dwMask |= CFM_COLOR;
620 if (value == tomAutoColor)
621 fmt.dwEffects |= CFE_AUTOCOLOR;
622 else
623 fmt.crTextColor = value;
626 value = tomUndefined;
627 hr = ITextFont_GetKerning(font, &f);
628 if (hr == S_OK && f != tomUndefined) {
629 fmt.dwMask |= CFM_KERNING;
630 fmt.wKerning = points_to_twips(f);
633 value = tomUndefined;
634 hr = ITextFont_GetLanguageID(font, &value);
635 if (hr == S_OK && value != tomUndefined) {
636 fmt.dwMask |= CFM_LCID;
637 fmt.lcid = value;
640 if (ITextFont_GetName(font, &str) == S_OK) {
641 fmt.dwMask |= CFM_FACE;
642 lstrcpynW(fmt.szFaceName, str, sizeof(fmt.szFaceName)/sizeof(WCHAR));
643 SysFreeString(str);
646 hr = ITextFont_GetPosition(font, &f);
647 if (hr == S_OK && f != tomUndefined) {
648 fmt.dwMask |= CFM_OFFSET;
649 fmt.yOffset = points_to_twips(f);
652 hr = ITextFont_GetSize(font, &f);
653 if (hr == S_OK && f != tomUndefined) {
654 fmt.dwMask |= CFM_SIZE;
655 fmt.yHeight = points_to_twips(f);
658 hr = ITextFont_GetSpacing(font, &f);
659 if (hr == S_OK && f != tomUndefined) {
660 fmt.dwMask |= CFM_SPACING;
661 fmt.sSpacing = f;
664 hr = ITextFont_GetWeight(font, &value);
665 if (hr == S_OK && value != tomUndefined) {
666 fmt.dwMask |= CFM_WEIGHT;
667 fmt.wWeight = value;
670 if (fmt.dwMask) {
671 const IRichEditOleImpl *reole = get_range_reole(range);
672 ME_Cursor from, to;
673 LONG start, end;
675 ITextRange_GetStart(range, &start);
676 ITextRange_GetEnd(range, &end);
678 ME_CursorFromCharOfs(reole->editor, start, &from);
679 ME_CursorFromCharOfs(reole->editor, end, &to);
680 ME_SetCharFormat(reole->editor, &from, &to, &fmt);
684 static HRESULT get_textfont_prop(const ITextFontImpl *font, enum textfont_prop_id propid, textfont_prop_val *value)
686 const IRichEditOleImpl *reole;
687 textfont_prop_val v;
688 LONG start, end, i;
689 HRESULT hr;
691 /* when font is not attached to any range use cached values */
692 if (!font->range || font->get_cache_enabled) {
693 *value = font->props[propid];
694 return S_OK;
697 if (!(reole = get_range_reole(font->range)))
698 return CO_E_RELEASED;
700 init_textfont_prop_value(propid, value);
702 ITextRange_GetStart(font->range, &start);
703 ITextRange_GetEnd(font->range, &end);
705 /* iterate trough a range to see if property value is consistent */
706 hr = get_textfont_prop_for_pos(reole, start, propid, &v);
707 if (FAILED(hr))
708 return hr;
710 for (i = start + 1; i < end; i++) {
711 textfont_prop_val cur;
713 hr = get_textfont_prop_for_pos(reole, i, propid, &cur);
714 if (FAILED(hr))
715 return hr;
717 if (!is_equal_textfont_prop_value(propid, &v, &cur))
718 return S_OK;
721 *value = v;
722 return S_OK;
725 static HRESULT get_textfont_propf(const ITextFontImpl *font, enum textfont_prop_id propid, FLOAT *value)
727 textfont_prop_val v;
728 HRESULT hr;
730 if (!value)
731 return E_INVALIDARG;
733 hr = get_textfont_prop(font, propid, &v);
734 *value = v.f;
735 return hr;
738 static HRESULT get_textfont_propl(const ITextFontImpl *font, enum textfont_prop_id propid, LONG *value)
740 textfont_prop_val v;
741 HRESULT hr;
743 if (!value)
744 return E_INVALIDARG;
746 hr = get_textfont_prop(font, propid, &v);
747 *value = v.l;
748 return hr;
751 /* Value should already have a terminal value, for boolean properties it means tomToggle is not handled */
752 static HRESULT set_textfont_prop(ITextFontImpl *font, enum textfont_prop_id propid, const textfont_prop_val *value)
754 const IRichEditOleImpl *reole;
755 ME_Cursor from, to;
756 CHARFORMAT2W fmt;
757 LONG start, end;
759 /* when font is not attached to any range use cache */
760 if (!font->range || font->set_cache_enabled) {
761 if (propid == FONT_NAME) {
762 SysFreeString(font->props[propid].str);
763 font->props[propid].str = SysAllocString(value->str);
765 else
766 font->props[propid] = *value;
767 return S_OK;
770 if (!(reole = get_range_reole(font->range)))
771 return CO_E_RELEASED;
773 memset(&fmt, 0, sizeof(fmt));
774 fmt.cbSize = sizeof(fmt);
775 fmt.dwMask = textfont_prop_masks[propid][0];
777 switch (propid)
779 case FONT_ALLCAPS:
780 case FONT_BOLD:
781 case FONT_EMBOSS:
782 case FONT_HIDDEN:
783 case FONT_ENGRAVE:
784 case FONT_ITALIC:
785 case FONT_OUTLINE:
786 case FONT_PROTECTED:
787 case FONT_SHADOW:
788 case FONT_SMALLCAPS:
789 case FONT_STRIKETHROUGH:
790 case FONT_SUBSCRIPT:
791 case FONT_SUPERSCRIPT:
792 case FONT_UNDERLINE:
793 fmt.dwEffects = value->l == tomTrue ? textfont_prop_masks[propid][1] : 0;
794 break;
795 case FONT_ANIMATION:
796 fmt.bAnimation = value->l;
797 break;
798 case FONT_BACKCOLOR:
799 case FONT_FORECOLOR:
800 if (value->l == tomAutoColor)
801 fmt.dwEffects = textfont_prop_masks[propid][1];
802 else if (propid == FONT_BACKCOLOR)
803 fmt.crBackColor = value->l;
804 else
805 fmt.crTextColor = value->l;
806 break;
807 case FONT_KERNING:
808 fmt.wKerning = value->f;
809 break;
810 case FONT_LANGID:
811 fmt.lcid = value->l;
812 break;
813 case FONT_POSITION:
814 fmt.yOffset = value->f;
815 break;
816 case FONT_SIZE:
817 fmt.yHeight = value->f;
818 break;
819 case FONT_SPACING:
820 fmt.sSpacing = value->f;
821 break;
822 case FONT_WEIGHT:
823 fmt.wWeight = value->l;
824 break;
825 case FONT_NAME:
826 lstrcpynW(fmt.szFaceName, value->str, sizeof(fmt.szFaceName)/sizeof(WCHAR));
827 break;
828 default:
829 FIXME("unhandled font property %d\n", propid);
830 return E_FAIL;
833 ITextRange_GetStart(font->range, &start);
834 ITextRange_GetEnd(font->range, &end);
836 ME_CursorFromCharOfs(reole->editor, start, &from);
837 ME_CursorFromCharOfs(reole->editor, end, &to);
838 ME_SetCharFormat(reole->editor, &from, &to, &fmt);
840 return S_OK;
843 static inline HRESULT set_textfont_propl(ITextFontImpl *font, enum textfont_prop_id propid, LONG value)
845 textfont_prop_val v;
846 v.l = value;
847 return set_textfont_prop(font, propid, &v);
850 static inline HRESULT set_textfont_propf(ITextFontImpl *font, enum textfont_prop_id propid, FLOAT value)
852 textfont_prop_val v;
853 v.f = value;
854 return set_textfont_prop(font, propid, &v);
857 static HRESULT set_textfont_propd(ITextFontImpl *font, enum textfont_prop_id propid, LONG value)
859 textfont_prop_val v;
861 switch (value)
863 case tomUndefined:
864 return S_OK;
865 case tomToggle: {
866 LONG oldvalue;
867 get_textfont_propl(font, propid, &oldvalue);
868 if (oldvalue == tomFalse)
869 value = tomTrue;
870 else if (oldvalue == tomTrue)
871 value = tomFalse;
872 else
873 return E_INVALIDARG;
874 /* fallthrough */
876 case tomTrue:
877 case tomFalse:
878 v.l = value;
879 return set_textfont_prop(font, propid, &v);
880 default:
881 return E_INVALIDARG;
885 static HRESULT textfont_getname_from_range(ITextRange *range, BSTR *ret)
887 const IRichEditOleImpl *reole;
888 textfont_prop_val v;
889 HRESULT hr;
890 LONG start;
892 if (!(reole = get_range_reole(range)))
893 return CO_E_RELEASED;
895 ITextRange_GetStart(range, &start);
896 hr = get_textfont_prop_for_pos(reole, start, FONT_NAME, &v);
897 *ret = v.str;
898 return hr;
901 static void textfont_cache_range_props(ITextFontImpl *font)
903 enum textfont_prop_id propid;
904 for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++) {
905 if (propid == FONT_NAME)
906 textfont_getname_from_range(font->range, &font->props[propid].str);
907 else
908 get_textfont_prop(font, propid, &font->props[propid]);
912 static HRESULT WINAPI IRichEditOleImpl_inner_fnQueryInterface(IUnknown *iface, REFIID riid, LPVOID *ppvObj)
914 IRichEditOleImpl *This = impl_from_IUnknown(iface);
916 TRACE("%p %s\n", This, debugstr_guid(riid));
918 *ppvObj = NULL;
919 if (IsEqualGUID(riid, &IID_IUnknown))
920 *ppvObj = &This->IUnknown_inner;
921 else if (IsEqualGUID(riid, &IID_IRichEditOle))
922 *ppvObj = &This->IRichEditOle_iface;
923 else if (IsEqualGUID(riid, &IID_ITextDocument))
924 *ppvObj = &This->ITextDocument_iface;
925 if (*ppvObj)
927 IUnknown_AddRef((IUnknown *)*ppvObj);
928 return S_OK;
930 FIXME("%p: unhandled interface %s\n", This, debugstr_guid(riid));
932 return E_NOINTERFACE;
935 static ULONG WINAPI IRichEditOleImpl_inner_fnAddRef(IUnknown *iface)
937 IRichEditOleImpl *This = impl_from_IUnknown(iface);
938 ULONG ref = InterlockedIncrement(&This->ref);
940 TRACE("%p ref = %u\n", This, ref);
942 return ref;
945 static ULONG WINAPI IRichEditOleImpl_inner_fnRelease(IUnknown *iface)
947 IRichEditOleImpl *This = impl_from_IUnknown(iface);
948 ULONG ref = InterlockedDecrement(&This->ref);
950 TRACE ("%p ref=%u\n", This, ref);
952 if (!ref)
954 IOleClientSiteImpl *clientsite;
955 ITextRangeImpl *txtRge;
957 This->editor->reOle = NULL;
958 if (This->txtSel) {
959 This->txtSel->reOle = NULL;
960 ITextSelection_Release(&This->txtSel->ITextSelection_iface);
963 LIST_FOR_EACH_ENTRY(txtRge, &This->rangelist, ITextRangeImpl, child.entry)
964 txtRge->child.reole = NULL;
966 LIST_FOR_EACH_ENTRY(clientsite, &This->clientsites, IOleClientSiteImpl, child.entry)
967 clientsite->child.reole = NULL;
969 heap_free(This);
971 return ref;
974 static const IUnknownVtbl reo_unk_vtbl =
976 IRichEditOleImpl_inner_fnQueryInterface,
977 IRichEditOleImpl_inner_fnAddRef,
978 IRichEditOleImpl_inner_fnRelease
981 static HRESULT WINAPI
982 IRichEditOle_fnQueryInterface(IRichEditOle *me, REFIID riid, LPVOID *ppvObj)
984 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
985 return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj);
988 static ULONG WINAPI
989 IRichEditOle_fnAddRef(IRichEditOle *me)
991 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
992 return IUnknown_AddRef(This->outer_unk);
995 static ULONG WINAPI
996 IRichEditOle_fnRelease(IRichEditOle *me)
998 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
999 return IUnknown_Release(This->outer_unk);
1002 static HRESULT WINAPI
1003 IRichEditOle_fnActivateAs(IRichEditOle *me, REFCLSID rclsid, REFCLSID rclsidAs)
1005 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1006 FIXME("stub %p\n",This);
1007 return E_NOTIMPL;
1010 static HRESULT WINAPI
1011 IRichEditOle_fnContextSensitiveHelp(IRichEditOle *me, BOOL fEnterMode)
1013 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1014 FIXME("stub %p\n",This);
1015 return E_NOTIMPL;
1018 static HRESULT WINAPI
1019 IRichEditOle_fnConvertObject(IRichEditOle *me, LONG iob,
1020 REFCLSID rclsidNew, LPCSTR lpstrUserTypeNew)
1022 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1023 FIXME("stub %p\n",This);
1024 return E_NOTIMPL;
1027 static inline IOleClientSiteImpl *impl_from_IOleClientSite(IOleClientSite *iface)
1029 return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleClientSite_iface);
1032 static HRESULT WINAPI
1033 IOleClientSite_fnQueryInterface(IOleClientSite *me, REFIID riid, LPVOID *ppvObj)
1035 IOleClientSiteImpl *This = impl_from_IOleClientSite(me);
1036 TRACE("%p %s\n", me, debugstr_guid(riid) );
1038 *ppvObj = NULL;
1039 if (IsEqualGUID(riid, &IID_IUnknown) ||
1040 IsEqualGUID(riid, &IID_IOleClientSite))
1041 *ppvObj = me;
1042 else if (IsEqualGUID(riid, &IID_IOleWindow))
1043 *ppvObj = &This->IOleWindow_iface;
1044 else if (IsEqualGUID(riid, &IID_IOleInPlaceSite))
1045 *ppvObj = &This->IOleInPlaceSite_iface;
1046 if (*ppvObj)
1048 IOleClientSite_AddRef(me);
1049 return S_OK;
1051 FIXME("%p: unhandled interface %s\n", me, debugstr_guid(riid) );
1053 return E_NOINTERFACE;
1056 static ULONG WINAPI IOleClientSite_fnAddRef(IOleClientSite *iface)
1058 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1059 ULONG ref = InterlockedIncrement(&This->ref);
1060 TRACE("(%p)->(%u)\n", This, ref);
1061 return ref;
1064 static ULONG WINAPI IOleClientSite_fnRelease(IOleClientSite *iface)
1066 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1067 ULONG ref = InterlockedDecrement(&This->ref);
1069 TRACE("(%p)->(%u)\n", This, ref);
1071 if (ref == 0) {
1072 if (This->child.reole) {
1073 list_remove(&This->child.entry);
1074 This->child.reole = NULL;
1076 heap_free(This);
1078 return ref;
1081 static HRESULT WINAPI IOleClientSite_fnSaveObject(IOleClientSite *iface)
1083 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1084 if (!This->child.reole)
1085 return CO_E_RELEASED;
1087 FIXME("stub %p\n", iface);
1088 return E_NOTIMPL;
1091 static HRESULT WINAPI IOleClientSite_fnGetMoniker(IOleClientSite *iface, DWORD dwAssign,
1092 DWORD dwWhichMoniker, IMoniker **ppmk)
1094 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1095 if (!This->child.reole)
1096 return CO_E_RELEASED;
1098 FIXME("stub %p\n", iface);
1099 return E_NOTIMPL;
1102 static HRESULT WINAPI IOleClientSite_fnGetContainer(IOleClientSite *iface,
1103 IOleContainer **ppContainer)
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_fnShowObject(IOleClientSite *iface)
1115 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1116 if (!This->child.reole)
1117 return CO_E_RELEASED;
1119 FIXME("stub %p\n", iface);
1120 return E_NOTIMPL;
1123 static HRESULT WINAPI IOleClientSite_fnOnShowWindow(IOleClientSite *iface, BOOL fShow)
1125 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1126 if (!This->child.reole)
1127 return CO_E_RELEASED;
1129 FIXME("stub %p\n", iface);
1130 return E_NOTIMPL;
1133 static HRESULT WINAPI IOleClientSite_fnRequestNewObjectLayout(IOleClientSite *iface)
1135 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1136 if (!This->child.reole)
1137 return CO_E_RELEASED;
1139 FIXME("stub %p\n", iface);
1140 return E_NOTIMPL;
1143 static const IOleClientSiteVtbl ocst = {
1144 IOleClientSite_fnQueryInterface,
1145 IOleClientSite_fnAddRef,
1146 IOleClientSite_fnRelease,
1147 IOleClientSite_fnSaveObject,
1148 IOleClientSite_fnGetMoniker,
1149 IOleClientSite_fnGetContainer,
1150 IOleClientSite_fnShowObject,
1151 IOleClientSite_fnOnShowWindow,
1152 IOleClientSite_fnRequestNewObjectLayout
1155 /* IOleWindow interface */
1156 static HRESULT WINAPI IOleWindow_fnQueryInterface(IOleWindow *iface, REFIID riid, void **ppvObj)
1158 IOleClientSiteImpl *This = impl_from_IOleWindow(iface);
1159 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppvObj);
1162 static ULONG WINAPI IOleWindow_fnAddRef(IOleWindow *iface)
1164 IOleClientSiteImpl *This = impl_from_IOleWindow(iface);
1165 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1168 static ULONG WINAPI IOleWindow_fnRelease(IOleWindow *iface)
1170 IOleClientSiteImpl *This = impl_from_IOleWindow(iface);
1171 return IOleClientSite_Release(&This->IOleClientSite_iface);
1174 static HRESULT WINAPI IOleWindow_fnContextSensitiveHelp(IOleWindow *iface, BOOL fEnterMode)
1176 IOleClientSiteImpl *This = impl_from_IOleWindow(iface);
1177 FIXME("not implemented: (%p)->(%d)\n", This, fEnterMode);
1178 return E_NOTIMPL;
1181 static HRESULT WINAPI IOleWindow_fnGetWindow(IOleWindow *iface, HWND *phwnd)
1183 IOleClientSiteImpl *This = impl_from_IOleWindow(iface);
1185 TRACE("(%p)->(%p)\n", This, phwnd);
1187 if (!This->child.reole)
1188 return CO_E_RELEASED;
1190 if (!phwnd)
1191 return E_INVALIDARG;
1193 *phwnd = This->child.reole->editor->hWnd;
1194 return S_OK;
1197 static const IOleWindowVtbl olewinvt = {
1198 IOleWindow_fnQueryInterface,
1199 IOleWindow_fnAddRef,
1200 IOleWindow_fnRelease,
1201 IOleWindow_fnGetWindow,
1202 IOleWindow_fnContextSensitiveHelp
1205 /* IOleInPlaceSite interface */
1206 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnQueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppvObj)
1208 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1209 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppvObj);
1212 static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnAddRef(IOleInPlaceSite *iface)
1214 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1215 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1218 static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnRelease(IOleInPlaceSite *iface)
1220 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1221 return IOleClientSite_Release(&This->IOleClientSite_iface);
1224 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindow(IOleInPlaceSite *iface, HWND *phwnd)
1226 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1227 return IOleWindow_GetWindow(&This->IOleWindow_iface, phwnd);
1230 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode)
1232 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1233 return IOleWindow_ContextSensitiveHelp(&This->IOleWindow_iface, fEnterMode);
1236 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnCanInPlaceActivate(IOleInPlaceSite *iface)
1238 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1239 FIXME("not implemented: (%p)\n", This);
1240 return E_NOTIMPL;
1243 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceActivate(IOleInPlaceSite *iface)
1245 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1246 FIXME("not implemented: (%p)\n", This);
1247 return E_NOTIMPL;
1250 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIActivate(IOleInPlaceSite *iface)
1252 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1253 FIXME("not implemented: (%p)\n", This);
1254 return E_NOTIMPL;
1257 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindowContext(IOleInPlaceSite *iface, IOleInPlaceFrame **ppFrame,
1258 IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
1259 LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
1261 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1262 FIXME("not implemented: (%p)->(%p %p %p %p %p)\n", This, ppFrame, ppDoc, lprcPosRect, lprcClipRect, lpFrameInfo);
1263 return E_NOTIMPL;
1266 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnScroll(IOleInPlaceSite *iface, SIZE scrollExtent)
1268 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1269 FIXME("not implemented: (%p)\n", This);
1270 return E_NOTIMPL;
1273 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable)
1275 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1276 FIXME("not implemented: (%p)->(%d)\n", This, fUndoable);
1277 return E_NOTIMPL;
1280 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceDeactivate(IOleInPlaceSite *iface)
1282 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1283 FIXME("not implemented: (%p)\n", This);
1284 return E_NOTIMPL;
1287 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDiscardUndoState(IOleInPlaceSite *iface)
1289 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1290 FIXME("not implemented: (%p)\n", This);
1291 return E_NOTIMPL;
1294 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDeactivateAndUndo(IOleInPlaceSite *iface)
1296 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1297 FIXME("not implemented: (%p)\n", This);
1298 return E_NOTIMPL;
1301 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect)
1303 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1304 FIXME("not implemented: (%p)->(%p)\n", This, lprcPosRect);
1305 return E_NOTIMPL;
1308 static const IOleInPlaceSiteVtbl olestvt =
1310 IOleInPlaceSite_fnQueryInterface,
1311 IOleInPlaceSite_fnAddRef,
1312 IOleInPlaceSite_fnRelease,
1313 IOleInPlaceSite_fnGetWindow,
1314 IOleInPlaceSite_fnContextSensitiveHelp,
1315 IOleInPlaceSite_fnCanInPlaceActivate,
1316 IOleInPlaceSite_fnOnInPlaceActivate,
1317 IOleInPlaceSite_fnOnUIActivate,
1318 IOleInPlaceSite_fnGetWindowContext,
1319 IOleInPlaceSite_fnScroll,
1320 IOleInPlaceSite_fnOnUIDeactivate,
1321 IOleInPlaceSite_fnOnInPlaceDeactivate,
1322 IOleInPlaceSite_fnDiscardUndoState,
1323 IOleInPlaceSite_fnDeactivateAndUndo,
1324 IOleInPlaceSite_fnOnPosRectChange
1327 static HRESULT CreateOleClientSite(IRichEditOleImpl *reOle, IOleClientSite **ret)
1329 IOleClientSiteImpl *clientSite = heap_alloc(sizeof *clientSite);
1331 if (!clientSite)
1332 return E_OUTOFMEMORY;
1334 clientSite->IOleClientSite_iface.lpVtbl = &ocst;
1335 clientSite->IOleWindow_iface.lpVtbl = &olewinvt;
1336 clientSite->IOleInPlaceSite_iface.lpVtbl = &olestvt;
1337 clientSite->ref = 1;
1338 clientSite->child.reole = reOle;
1339 list_add_head(&reOle->clientsites, &clientSite->child.entry);
1341 *ret = &clientSite->IOleClientSite_iface;
1342 return S_OK;
1345 static HRESULT WINAPI
1346 IRichEditOle_fnGetClientSite(IRichEditOle *me, IOleClientSite **clientsite)
1348 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1350 TRACE("(%p)->(%p)\n", This, clientsite);
1352 if (!clientsite)
1353 return E_INVALIDARG;
1355 return CreateOleClientSite(This, clientsite);
1358 static HRESULT WINAPI
1359 IRichEditOle_fnGetClipboardData(IRichEditOle *me, CHARRANGE *lpchrg,
1360 DWORD reco, LPDATAOBJECT *lplpdataobj)
1362 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1363 ME_Cursor start;
1364 int nChars;
1366 TRACE("(%p,%p,%d)\n",This, lpchrg, reco);
1367 if(!lplpdataobj)
1368 return E_INVALIDARG;
1369 if(!lpchrg) {
1370 int nFrom, nTo, nStartCur = ME_GetSelectionOfs(This->editor, &nFrom, &nTo);
1371 start = This->editor->pCursors[nStartCur];
1372 nChars = nTo - nFrom;
1373 } else {
1374 ME_CursorFromCharOfs(This->editor, lpchrg->cpMin, &start);
1375 nChars = lpchrg->cpMax - lpchrg->cpMin;
1377 return ME_GetDataObject(This->editor, &start, nChars, lplpdataobj);
1380 static LONG WINAPI IRichEditOle_fnGetLinkCount(IRichEditOle *me)
1382 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1383 FIXME("stub %p\n",This);
1384 return E_NOTIMPL;
1387 static HRESULT WINAPI
1388 IRichEditOle_fnGetObject(IRichEditOle *me, LONG iob,
1389 REOBJECT *lpreobject, DWORD dwFlags)
1391 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1392 FIXME("stub %p\n",This);
1393 return E_NOTIMPL;
1396 static LONG WINAPI
1397 IRichEditOle_fnGetObjectCount(IRichEditOle *me)
1399 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1400 FIXME("stub %p\n",This);
1401 return 0;
1404 static HRESULT WINAPI
1405 IRichEditOle_fnHandsOffStorage(IRichEditOle *me, LONG iob)
1407 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1408 FIXME("stub %p\n",This);
1409 return E_NOTIMPL;
1412 static HRESULT WINAPI
1413 IRichEditOle_fnImportDataObject(IRichEditOle *me, LPDATAOBJECT lpdataobj,
1414 CLIPFORMAT cf, HGLOBAL hMetaPict)
1416 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1417 FIXME("stub %p\n",This);
1418 return E_NOTIMPL;
1421 static HRESULT WINAPI
1422 IRichEditOle_fnInPlaceDeactivate(IRichEditOle *me)
1424 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1425 FIXME("stub %p\n",This);
1426 return E_NOTIMPL;
1429 static HRESULT WINAPI
1430 IRichEditOle_fnInsertObject(IRichEditOle *me, REOBJECT *reo)
1432 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1434 TRACE("(%p,%p)\n", This, reo);
1436 if (!reo)
1437 return E_INVALIDARG;
1439 if (reo->cbStruct < sizeof(*reo)) return STG_E_INVALIDPARAMETER;
1441 ME_InsertOLEFromCursor(This->editor, reo, 0);
1442 ME_CommitUndo(This->editor);
1443 ME_UpdateRepaint(This->editor, FALSE);
1444 return S_OK;
1447 static HRESULT WINAPI IRichEditOle_fnSaveCompleted(IRichEditOle *me, LONG iob,
1448 LPSTORAGE lpstg)
1450 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1451 FIXME("stub %p\n",This);
1452 return E_NOTIMPL;
1455 static HRESULT WINAPI
1456 IRichEditOle_fnSetDvaspect(IRichEditOle *me, LONG iob, DWORD dvaspect)
1458 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1459 FIXME("stub %p\n",This);
1460 return E_NOTIMPL;
1463 static HRESULT WINAPI IRichEditOle_fnSetHostNames(IRichEditOle *me,
1464 LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj)
1466 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1467 FIXME("stub %p %s %s\n",This, lpstrContainerApp, lpstrContainerObj);
1468 return E_NOTIMPL;
1471 static HRESULT WINAPI
1472 IRichEditOle_fnSetLinkAvailable(IRichEditOle *me, LONG iob, BOOL fAvailable)
1474 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1475 FIXME("stub %p\n",This);
1476 return E_NOTIMPL;
1479 static const IRichEditOleVtbl revt = {
1480 IRichEditOle_fnQueryInterface,
1481 IRichEditOle_fnAddRef,
1482 IRichEditOle_fnRelease,
1483 IRichEditOle_fnGetClientSite,
1484 IRichEditOle_fnGetObjectCount,
1485 IRichEditOle_fnGetLinkCount,
1486 IRichEditOle_fnGetObject,
1487 IRichEditOle_fnInsertObject,
1488 IRichEditOle_fnConvertObject,
1489 IRichEditOle_fnActivateAs,
1490 IRichEditOle_fnSetHostNames,
1491 IRichEditOle_fnSetLinkAvailable,
1492 IRichEditOle_fnSetDvaspect,
1493 IRichEditOle_fnHandsOffStorage,
1494 IRichEditOle_fnSaveCompleted,
1495 IRichEditOle_fnInPlaceDeactivate,
1496 IRichEditOle_fnContextSensitiveHelp,
1497 IRichEditOle_fnGetClipboardData,
1498 IRichEditOle_fnImportDataObject
1501 /* ITextRange interface */
1502 static HRESULT WINAPI ITextRange_fnQueryInterface(ITextRange *me, REFIID riid, void **ppvObj)
1504 ITextRangeImpl *This = impl_from_ITextRange(me);
1506 *ppvObj = NULL;
1507 if (IsEqualGUID(riid, &IID_IUnknown)
1508 || IsEqualGUID(riid, &IID_IDispatch)
1509 || IsEqualGUID(riid, &IID_ITextRange))
1511 *ppvObj = me;
1512 ITextRange_AddRef(me);
1513 return S_OK;
1515 else if (IsEqualGUID(riid, &IID_Igetrichole))
1517 *ppvObj = This->child.reole;
1518 return S_OK;
1521 return E_NOINTERFACE;
1524 static ULONG WINAPI ITextRange_fnAddRef(ITextRange *me)
1526 ITextRangeImpl *This = impl_from_ITextRange(me);
1527 return InterlockedIncrement(&This->ref);
1530 static ULONG WINAPI ITextRange_fnRelease(ITextRange *me)
1532 ITextRangeImpl *This = impl_from_ITextRange(me);
1533 ULONG ref = InterlockedDecrement(&This->ref);
1535 TRACE ("%p ref=%u\n", This, ref);
1536 if (ref == 0)
1538 if (This->child.reole)
1540 list_remove(&This->child.entry);
1541 This->child.reole = NULL;
1543 heap_free(This);
1545 return ref;
1548 static HRESULT WINAPI ITextRange_fnGetTypeInfoCount(ITextRange *me, UINT *pctinfo)
1550 ITextRangeImpl *This = impl_from_ITextRange(me);
1551 TRACE("(%p)->(%p)\n", This, pctinfo);
1552 *pctinfo = 1;
1553 return S_OK;
1556 static HRESULT WINAPI ITextRange_fnGetTypeInfo(ITextRange *me, UINT iTInfo, LCID lcid,
1557 ITypeInfo **ppTInfo)
1559 ITextRangeImpl *This = impl_from_ITextRange(me);
1560 HRESULT hr;
1562 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
1564 hr = get_typeinfo(ITextRange_tid, ppTInfo);
1565 if (SUCCEEDED(hr))
1566 ITypeInfo_AddRef(*ppTInfo);
1567 return hr;
1570 static HRESULT WINAPI ITextRange_fnGetIDsOfNames(ITextRange *me, REFIID riid, LPOLESTR *rgszNames,
1571 UINT cNames, LCID lcid, DISPID *rgDispId)
1573 ITextRangeImpl *This = impl_from_ITextRange(me);
1574 ITypeInfo *ti;
1575 HRESULT hr;
1577 TRACE("(%p)->(%p,%p,%u,%d,%p)\n", This, riid, rgszNames, cNames, lcid,
1578 rgDispId);
1580 hr = get_typeinfo(ITextRange_tid, &ti);
1581 if (SUCCEEDED(hr))
1582 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
1583 return hr;
1586 static HRESULT WINAPI ITextRange_fnInvoke(ITextRange *me, DISPID dispIdMember, REFIID riid,
1587 LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1588 VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
1589 UINT *puArgErr)
1591 ITextRangeImpl *This = impl_from_ITextRange(me);
1592 ITypeInfo *ti;
1593 HRESULT hr;
1595 TRACE("(%p)->(%d,%p,%d,%u,%p,%p,%p,%p)\n", This, dispIdMember, riid, lcid,
1596 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1598 hr = get_typeinfo(ITextRange_tid, &ti);
1599 if (SUCCEEDED(hr))
1600 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1601 return hr;
1604 static HRESULT WINAPI ITextRange_fnGetText(ITextRange *me, BSTR *str)
1606 ITextRangeImpl *This = impl_from_ITextRange(me);
1607 ME_TextEditor *editor;
1608 ME_Cursor start, end;
1609 int length;
1610 BOOL bEOP;
1612 TRACE("(%p)->(%p)\n", This, str);
1614 if (!This->child.reole)
1615 return CO_E_RELEASED;
1617 if (!str)
1618 return E_INVALIDARG;
1620 /* return early for degenerate range */
1621 if (This->start == This->end) {
1622 *str = NULL;
1623 return S_OK;
1626 editor = This->child.reole->editor;
1627 ME_CursorFromCharOfs(editor, This->start, &start);
1628 ME_CursorFromCharOfs(editor, This->end, &end);
1630 length = This->end - This->start;
1631 *str = SysAllocStringLen(NULL, length);
1632 if (!*str)
1633 return E_OUTOFMEMORY;
1635 bEOP = (end.pRun->next->type == diTextEnd && This->end > ME_GetTextLength(editor));
1636 ME_GetTextW(editor, *str, length, &start, length, FALSE, bEOP);
1637 return S_OK;
1640 static HRESULT WINAPI ITextRange_fnSetText(ITextRange *me, BSTR str)
1642 ITextRangeImpl *This = impl_from_ITextRange(me);
1643 ME_TextEditor *editor;
1644 ME_Cursor cursor;
1645 ME_Style *style;
1646 int len;
1648 TRACE("(%p)->(%s)\n", This, debugstr_w(str));
1650 if (!This->child.reole)
1651 return CO_E_RELEASED;
1653 editor = This->child.reole->editor;
1655 /* delete only where's something to delete */
1656 if (This->start != This->end) {
1657 ME_CursorFromCharOfs(editor, This->start, &cursor);
1658 ME_InternalDeleteText(editor, &cursor, This->end - This->start, FALSE);
1661 if (!str || !*str) {
1662 /* will update this range as well */
1663 textranges_update_ranges(This->child.reole, This->start, This->end, RANGE_UPDATE_DELETE);
1664 return S_OK;
1667 /* it's safer not to rely on stored BSTR length */
1668 len = strlenW(str);
1669 cursor = editor->pCursors[0];
1670 ME_CursorFromCharOfs(editor, This->start, &editor->pCursors[0]);
1671 style = ME_GetInsertStyle(editor, 0);
1672 ME_InsertTextFromCursor(editor, 0, str, len, style);
1673 ME_ReleaseStyle(style);
1674 editor->pCursors[0] = cursor;
1676 if (len < This->end - This->start)
1677 textranges_update_ranges(This->child.reole, This->start + len, This->end, RANGE_UPDATE_DELETE);
1678 else
1679 This->end = len - This->start;
1681 return S_OK;
1684 static HRESULT range_GetChar(ME_TextEditor *editor, ME_Cursor *cursor, LONG *pch)
1686 WCHAR wch[2];
1688 ME_GetTextW(editor, wch, 1, cursor, 1, FALSE, cursor->pRun->next->type == diTextEnd);
1689 *pch = wch[0];
1691 return S_OK;
1694 static HRESULT WINAPI ITextRange_fnGetChar(ITextRange *me, LONG *pch)
1696 ITextRangeImpl *This = impl_from_ITextRange(me);
1697 ME_TextEditor *editor;
1698 ME_Cursor cursor;
1700 TRACE("(%p)->(%p)\n", This, pch);
1702 if (!This->child.reole)
1703 return CO_E_RELEASED;
1705 if (!pch)
1706 return E_INVALIDARG;
1708 editor = This->child.reole->editor;
1709 ME_CursorFromCharOfs(editor, This->start, &cursor);
1710 return range_GetChar(editor, &cursor, pch);
1713 static HRESULT WINAPI ITextRange_fnSetChar(ITextRange *me, LONG ch)
1715 ITextRangeImpl *This = impl_from_ITextRange(me);
1716 if (!This->child.reole)
1717 return CO_E_RELEASED;
1719 FIXME("not implemented %p\n", This);
1720 return E_NOTIMPL;
1723 static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, ITextRange** ppRange);
1725 static HRESULT WINAPI ITextRange_fnGetDuplicate(ITextRange *me, ITextRange **ppRange)
1727 ITextRangeImpl *This = impl_from_ITextRange(me);
1729 TRACE("(%p)->(%p)\n", This, ppRange);
1731 if (!This->child.reole)
1732 return CO_E_RELEASED;
1734 if (!ppRange)
1735 return E_INVALIDARG;
1737 return CreateITextRange(This->child.reole, This->start, This->end, ppRange);
1740 static HRESULT WINAPI ITextRange_fnGetFormattedText(ITextRange *me, ITextRange **ppRange)
1742 ITextRangeImpl *This = impl_from_ITextRange(me);
1743 if (!This->child.reole)
1744 return CO_E_RELEASED;
1746 FIXME("not implemented %p\n", This);
1747 return E_NOTIMPL;
1750 static HRESULT WINAPI ITextRange_fnSetFormattedText(ITextRange *me, ITextRange *pRange)
1752 ITextRangeImpl *This = impl_from_ITextRange(me);
1753 if (!This->child.reole)
1754 return CO_E_RELEASED;
1756 FIXME("not implemented %p\n", This);
1757 return E_NOTIMPL;
1760 static HRESULT WINAPI ITextRange_fnGetStart(ITextRange *me, LONG *start)
1762 ITextRangeImpl *This = impl_from_ITextRange(me);
1764 TRACE("(%p)->(%p)\n", This, start);
1766 if (!This->child.reole)
1767 return CO_E_RELEASED;
1769 if (!start)
1770 return E_INVALIDARG;
1772 *start = This->start;
1773 return S_OK;
1776 static HRESULT textrange_setstart(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end)
1778 int len;
1780 if (value < 0)
1781 value = 0;
1783 if (value == *start)
1784 return S_FALSE;
1786 if (value <= *end) {
1787 *start = value;
1788 return S_OK;
1791 len = ME_GetTextLength(reole->editor);
1792 *start = *end = value > len ? len : value;
1793 return S_OK;
1796 static HRESULT WINAPI ITextRange_fnSetStart(ITextRange *me, LONG value)
1798 ITextRangeImpl *This = impl_from_ITextRange(me);
1800 TRACE("(%p)->(%d)\n", This, value);
1802 if (!This->child.reole)
1803 return CO_E_RELEASED;
1805 return textrange_setstart(This->child.reole, value, &This->start, &This->end);
1808 static HRESULT WINAPI ITextRange_fnGetEnd(ITextRange *me, LONG *end)
1810 ITextRangeImpl *This = impl_from_ITextRange(me);
1812 TRACE("(%p)->(%p)\n", This, end);
1814 if (!This->child.reole)
1815 return CO_E_RELEASED;
1817 if (!end)
1818 return E_INVALIDARG;
1820 *end = This->end;
1821 return S_OK;
1824 static HRESULT textrange_setend(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end)
1826 int len;
1828 if (value == *end)
1829 return S_FALSE;
1831 if (value < *start) {
1832 *start = *end = max(0, value);
1833 return S_OK;
1836 len = ME_GetTextLength(reole->editor);
1837 *end = value > len ? len + 1 : value;
1838 return S_OK;
1841 static HRESULT WINAPI ITextRange_fnSetEnd(ITextRange *me, LONG value)
1843 ITextRangeImpl *This = impl_from_ITextRange(me);
1845 TRACE("(%p)->(%d)\n", This, value);
1847 if (!This->child.reole)
1848 return CO_E_RELEASED;
1850 return textrange_setend(This->child.reole, value, &This->start, &This->end);
1853 static HRESULT WINAPI ITextRange_fnGetFont(ITextRange *me, ITextFont **font)
1855 ITextRangeImpl *This = impl_from_ITextRange(me);
1857 TRACE("(%p)->(%p)\n", This, font);
1859 if (!This->child.reole)
1860 return CO_E_RELEASED;
1862 if (!font)
1863 return E_INVALIDARG;
1865 return create_textfont(me, NULL, font);
1868 static HRESULT WINAPI ITextRange_fnSetFont(ITextRange *me, ITextFont *font)
1870 ITextRangeImpl *This = impl_from_ITextRange(me);
1872 TRACE("(%p)->(%p)\n", This, font);
1874 if (!font)
1875 return E_INVALIDARG;
1877 if (!This->child.reole)
1878 return CO_E_RELEASED;
1880 textrange_set_font(me, font);
1881 return S_OK;
1884 static HRESULT WINAPI ITextRange_fnGetPara(ITextRange *me, ITextPara **para)
1886 ITextRangeImpl *This = impl_from_ITextRange(me);
1888 TRACE("(%p)->(%p)\n", This, para);
1890 if (!This->child.reole)
1891 return CO_E_RELEASED;
1893 if (!para)
1894 return E_INVALIDARG;
1896 return create_textpara(me, para);
1899 static HRESULT WINAPI ITextRange_fnSetPara(ITextRange *me, ITextPara *pPara)
1901 ITextRangeImpl *This = impl_from_ITextRange(me);
1903 if (!This->child.reole)
1904 return CO_E_RELEASED;
1906 FIXME("not implemented %p\n", This);
1907 return E_NOTIMPL;
1910 static HRESULT WINAPI ITextRange_fnGetStoryLength(ITextRange *me, LONG *length)
1912 ITextRangeImpl *This = impl_from_ITextRange(me);
1914 TRACE("(%p)->(%p)\n", This, length);
1916 if (!This->child.reole)
1917 return CO_E_RELEASED;
1919 return textrange_get_storylength(This->child.reole->editor, length);
1922 static HRESULT WINAPI ITextRange_fnGetStoryType(ITextRange *me, LONG *value)
1924 ITextRangeImpl *This = impl_from_ITextRange(me);
1926 TRACE("(%p)->(%p)\n", This, value);
1928 if (!This->child.reole)
1929 return CO_E_RELEASED;
1931 if (!value)
1932 return E_INVALIDARG;
1934 *value = tomUnknownStory;
1935 return S_OK;
1938 static HRESULT range_Collapse(LONG bStart, LONG *start, LONG *end)
1940 if (*end == *start)
1941 return S_FALSE;
1943 if (bStart == tomEnd || bStart == tomFalse)
1944 *start = *end;
1945 else
1946 *end = *start;
1947 return S_OK;
1950 static HRESULT WINAPI ITextRange_fnCollapse(ITextRange *me, LONG bStart)
1952 ITextRangeImpl *This = impl_from_ITextRange(me);
1954 TRACE("(%p)->(%d)\n", This, bStart);
1956 if (!This->child.reole)
1957 return CO_E_RELEASED;
1959 return range_Collapse(bStart, &This->start, &This->end);
1962 static HRESULT WINAPI ITextRange_fnExpand(ITextRange *me, LONG Unit, LONG *pDelta)
1964 ITextRangeImpl *This = impl_from_ITextRange(me);
1965 if (!This->child.reole)
1966 return CO_E_RELEASED;
1968 FIXME("not implemented %p\n", This);
1969 return E_NOTIMPL;
1972 static HRESULT WINAPI ITextRange_fnGetIndex(ITextRange *me, LONG Unit, LONG *pIndex)
1974 ITextRangeImpl *This = impl_from_ITextRange(me);
1975 if (!This->child.reole)
1976 return CO_E_RELEASED;
1978 FIXME("not implemented %p\n", This);
1979 return E_NOTIMPL;
1982 static HRESULT WINAPI ITextRange_fnSetIndex(ITextRange *me, LONG Unit, LONG Index,
1983 LONG Extend)
1985 ITextRangeImpl *This = impl_from_ITextRange(me);
1986 if (!This->child.reole)
1987 return CO_E_RELEASED;
1989 FIXME("not implemented %p\n", This);
1990 return E_NOTIMPL;
1993 static HRESULT WINAPI ITextRange_fnSetRange(ITextRange *me, LONG cpActive, LONG cpOther)
1995 ITextRangeImpl *This = impl_from_ITextRange(me);
1996 if (!This->child.reole)
1997 return CO_E_RELEASED;
1999 FIXME("not implemented %p\n", This);
2000 return E_NOTIMPL;
2003 static HRESULT textrange_inrange(LONG start, LONG end, ITextRange *range, LONG *ret)
2005 LONG from, to, v;
2007 if (!ret)
2008 ret = &v;
2010 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
2011 *ret = tomFalse;
2013 else
2014 *ret = (start >= from && end <= to) ? tomTrue : tomFalse;
2015 return *ret == tomTrue ? S_OK : S_FALSE;
2018 static HRESULT WINAPI ITextRange_fnInRange(ITextRange *me, ITextRange *range, LONG *ret)
2020 ITextRangeImpl *This = impl_from_ITextRange(me);
2022 TRACE("(%p)->(%p %p)\n", This, range, ret);
2024 if (ret)
2025 *ret = tomFalse;
2027 if (!This->child.reole)
2028 return CO_E_RELEASED;
2030 if (!range)
2031 return S_FALSE;
2033 return textrange_inrange(This->start, This->end, range, ret);
2036 static HRESULT WINAPI ITextRange_fnInStory(ITextRange *me, ITextRange *pRange, LONG *pb)
2038 ITextRangeImpl *This = impl_from_ITextRange(me);
2039 if (!This->child.reole)
2040 return CO_E_RELEASED;
2042 FIXME("not implemented %p\n", This);
2043 return E_NOTIMPL;
2046 static HRESULT textrange_isequal(LONG start, LONG end, ITextRange *range, LONG *ret)
2048 LONG from, to, v;
2050 if (!ret)
2051 ret = &v;
2053 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
2054 *ret = tomFalse;
2056 else
2057 *ret = (start == from && end == to) ? tomTrue : tomFalse;
2058 return *ret == tomTrue ? S_OK : S_FALSE;
2061 static HRESULT WINAPI ITextRange_fnIsEqual(ITextRange *me, ITextRange *range, LONG *ret)
2063 ITextRangeImpl *This = impl_from_ITextRange(me);
2065 TRACE("(%p)->(%p %p)\n", This, range, ret);
2067 if (ret)
2068 *ret = tomFalse;
2070 if (!This->child.reole)
2071 return CO_E_RELEASED;
2073 if (!range)
2074 return S_FALSE;
2076 return textrange_isequal(This->start, This->end, range, ret);
2079 static HRESULT WINAPI ITextRange_fnSelect(ITextRange *me)
2081 ITextRangeImpl *This = impl_from_ITextRange(me);
2083 TRACE("(%p)\n", This);
2085 if (!This->child.reole)
2086 return CO_E_RELEASED;
2088 ME_SetSelection(This->child.reole->editor, This->start, This->end);
2089 return S_OK;
2092 static HRESULT WINAPI ITextRange_fnStartOf(ITextRange *me, LONG Unit, LONG Extend,
2093 LONG *pDelta)
2095 ITextRangeImpl *This = impl_from_ITextRange(me);
2096 if (!This->child.reole)
2097 return CO_E_RELEASED;
2099 FIXME("not implemented %p\n", This);
2100 return E_NOTIMPL;
2103 static HRESULT WINAPI ITextRange_fnEndOf(ITextRange *me, LONG Unit, LONG Extend,
2104 LONG *pDelta)
2106 ITextRangeImpl *This = impl_from_ITextRange(me);
2107 if (!This->child.reole)
2108 return CO_E_RELEASED;
2110 FIXME("not implemented %p\n", This);
2111 return E_NOTIMPL;
2114 static HRESULT WINAPI ITextRange_fnMove(ITextRange *me, LONG Unit, LONG Count, LONG *pDelta)
2116 ITextRangeImpl *This = impl_from_ITextRange(me);
2117 if (!This->child.reole)
2118 return CO_E_RELEASED;
2120 FIXME("not implemented %p\n", This);
2121 return E_NOTIMPL;
2124 static HRESULT WINAPI ITextRange_fnMoveStart(ITextRange *me, LONG Unit, LONG Count,
2125 LONG *pDelta)
2127 ITextRangeImpl *This = impl_from_ITextRange(me);
2128 if (!This->child.reole)
2129 return CO_E_RELEASED;
2131 FIXME("not implemented %p\n", This);
2132 return E_NOTIMPL;
2135 static HRESULT WINAPI ITextRange_fnMoveEnd(ITextRange *me, LONG Unit, LONG Count,
2136 LONG *pDelta)
2138 ITextRangeImpl *This = impl_from_ITextRange(me);
2139 if (!This->child.reole)
2140 return CO_E_RELEASED;
2142 FIXME("not implemented %p\n", This);
2143 return E_NOTIMPL;
2146 static HRESULT WINAPI ITextRange_fnMoveWhile(ITextRange *me, VARIANT *Cset, LONG Count,
2147 LONG *pDelta)
2149 ITextRangeImpl *This = impl_from_ITextRange(me);
2150 if (!This->child.reole)
2151 return CO_E_RELEASED;
2153 FIXME("not implemented %p\n", This);
2154 return E_NOTIMPL;
2157 static HRESULT WINAPI ITextRange_fnMoveStartWhile(ITextRange *me, VARIANT *Cset, LONG Count,
2158 LONG *pDelta)
2160 ITextRangeImpl *This = impl_from_ITextRange(me);
2161 if (!This->child.reole)
2162 return CO_E_RELEASED;
2164 FIXME("not implemented %p\n", This);
2165 return E_NOTIMPL;
2168 static HRESULT WINAPI ITextRange_fnMoveEndWhile(ITextRange *me, VARIANT *Cset, LONG Count,
2169 LONG *pDelta)
2171 ITextRangeImpl *This = impl_from_ITextRange(me);
2172 if (!This->child.reole)
2173 return CO_E_RELEASED;
2175 FIXME("not implemented %p\n", This);
2176 return E_NOTIMPL;
2179 static HRESULT WINAPI ITextRange_fnMoveUntil(ITextRange *me, VARIANT *Cset, LONG Count,
2180 LONG *pDelta)
2182 ITextRangeImpl *This = impl_from_ITextRange(me);
2183 if (!This->child.reole)
2184 return CO_E_RELEASED;
2186 FIXME("not implemented %p\n", This);
2187 return E_NOTIMPL;
2190 static HRESULT WINAPI ITextRange_fnMoveStartUntil(ITextRange *me, VARIANT *Cset, LONG Count,
2191 LONG *pDelta)
2193 ITextRangeImpl *This = impl_from_ITextRange(me);
2194 if (!This->child.reole)
2195 return CO_E_RELEASED;
2197 FIXME("not implemented %p\n", This);
2198 return E_NOTIMPL;
2201 static HRESULT WINAPI ITextRange_fnMoveEndUntil(ITextRange *me, VARIANT *Cset, LONG Count,
2202 LONG *pDelta)
2204 ITextRangeImpl *This = impl_from_ITextRange(me);
2205 if (!This->child.reole)
2206 return CO_E_RELEASED;
2208 FIXME("not implemented %p\n", This);
2209 return E_NOTIMPL;
2212 static HRESULT WINAPI ITextRange_fnFindText(ITextRange *me, BSTR bstr, LONG cch, LONG Flags,
2213 LONG *pLength)
2215 ITextRangeImpl *This = impl_from_ITextRange(me);
2216 if (!This->child.reole)
2217 return CO_E_RELEASED;
2219 FIXME("not implemented %p\n", This);
2220 return E_NOTIMPL;
2223 static HRESULT WINAPI ITextRange_fnFindTextStart(ITextRange *me, BSTR bstr, LONG cch,
2224 LONG Flags, LONG *pLength)
2226 ITextRangeImpl *This = impl_from_ITextRange(me);
2227 if (!This->child.reole)
2228 return CO_E_RELEASED;
2230 FIXME("not implemented %p\n", This);
2231 return E_NOTIMPL;
2234 static HRESULT WINAPI ITextRange_fnFindTextEnd(ITextRange *me, BSTR bstr, LONG cch,
2235 LONG Flags, LONG *pLength)
2237 ITextRangeImpl *This = impl_from_ITextRange(me);
2238 if (!This->child.reole)
2239 return CO_E_RELEASED;
2241 FIXME("not implemented %p\n", This);
2242 return E_NOTIMPL;
2245 static HRESULT WINAPI ITextRange_fnDelete(ITextRange *me, LONG Unit, LONG Count,
2246 LONG *pDelta)
2248 ITextRangeImpl *This = impl_from_ITextRange(me);
2249 if (!This->child.reole)
2250 return CO_E_RELEASED;
2252 FIXME("not implemented %p\n", This);
2253 return E_NOTIMPL;
2256 static HRESULT WINAPI ITextRange_fnCut(ITextRange *me, VARIANT *pVar)
2258 ITextRangeImpl *This = impl_from_ITextRange(me);
2259 if (!This->child.reole)
2260 return CO_E_RELEASED;
2262 FIXME("not implemented %p\n", This);
2263 return E_NOTIMPL;
2266 static HRESULT WINAPI ITextRange_fnCopy(ITextRange *me, VARIANT *pVar)
2268 ITextRangeImpl *This = impl_from_ITextRange(me);
2269 if (!This->child.reole)
2270 return CO_E_RELEASED;
2272 FIXME("not implemented %p\n", This);
2273 return E_NOTIMPL;
2276 static HRESULT WINAPI ITextRange_fnPaste(ITextRange *me, VARIANT *pVar, LONG Format)
2278 ITextRangeImpl *This = impl_from_ITextRange(me);
2279 if (!This->child.reole)
2280 return CO_E_RELEASED;
2282 FIXME("not implemented %p\n", This);
2283 return E_NOTIMPL;
2286 static HRESULT WINAPI ITextRange_fnCanPaste(ITextRange *me, VARIANT *pVar, LONG Format,
2287 LONG *pb)
2289 ITextRangeImpl *This = impl_from_ITextRange(me);
2290 if (!This->child.reole)
2291 return CO_E_RELEASED;
2293 FIXME("not implemented %p\n", This);
2294 return E_NOTIMPL;
2297 static HRESULT WINAPI ITextRange_fnCanEdit(ITextRange *me, LONG *pb)
2299 ITextRangeImpl *This = impl_from_ITextRange(me);
2300 if (!This->child.reole)
2301 return CO_E_RELEASED;
2303 FIXME("not implemented %p\n", This);
2304 return E_NOTIMPL;
2307 static HRESULT WINAPI ITextRange_fnChangeCase(ITextRange *me, LONG Type)
2309 ITextRangeImpl *This = impl_from_ITextRange(me);
2310 if (!This->child.reole)
2311 return CO_E_RELEASED;
2313 FIXME("not implemented %p\n", This);
2314 return E_NOTIMPL;
2317 static HRESULT WINAPI ITextRange_fnGetPoint(ITextRange *me, LONG Type, LONG *cx, LONG *cy)
2319 ITextRangeImpl *This = impl_from_ITextRange(me);
2320 if (!This->child.reole)
2321 return CO_E_RELEASED;
2323 FIXME("not implemented %p\n", This);
2324 return E_NOTIMPL;
2327 static HRESULT WINAPI ITextRange_fnSetPoint(ITextRange *me, LONG x, LONG y, LONG Type,
2328 LONG Extend)
2330 ITextRangeImpl *This = impl_from_ITextRange(me);
2331 if (!This->child.reole)
2332 return CO_E_RELEASED;
2334 FIXME("not implemented %p\n", This);
2335 return E_NOTIMPL;
2338 static HRESULT WINAPI ITextRange_fnScrollIntoView(ITextRange *me, LONG Value)
2340 ITextRangeImpl *This = impl_from_ITextRange(me);
2341 if (!This->child.reole)
2342 return CO_E_RELEASED;
2344 FIXME("not implemented %p\n", This);
2345 return E_NOTIMPL;
2348 static HRESULT WINAPI ITextRange_fnGetEmbeddedObject(ITextRange *me, IUnknown **ppv)
2350 ITextRangeImpl *This = impl_from_ITextRange(me);
2351 if (!This->child.reole)
2352 return CO_E_RELEASED;
2354 FIXME("not implemented %p\n", This);
2355 return E_NOTIMPL;
2358 static const ITextRangeVtbl trvt = {
2359 ITextRange_fnQueryInterface,
2360 ITextRange_fnAddRef,
2361 ITextRange_fnRelease,
2362 ITextRange_fnGetTypeInfoCount,
2363 ITextRange_fnGetTypeInfo,
2364 ITextRange_fnGetIDsOfNames,
2365 ITextRange_fnInvoke,
2366 ITextRange_fnGetText,
2367 ITextRange_fnSetText,
2368 ITextRange_fnGetChar,
2369 ITextRange_fnSetChar,
2370 ITextRange_fnGetDuplicate,
2371 ITextRange_fnGetFormattedText,
2372 ITextRange_fnSetFormattedText,
2373 ITextRange_fnGetStart,
2374 ITextRange_fnSetStart,
2375 ITextRange_fnGetEnd,
2376 ITextRange_fnSetEnd,
2377 ITextRange_fnGetFont,
2378 ITextRange_fnSetFont,
2379 ITextRange_fnGetPara,
2380 ITextRange_fnSetPara,
2381 ITextRange_fnGetStoryLength,
2382 ITextRange_fnGetStoryType,
2383 ITextRange_fnCollapse,
2384 ITextRange_fnExpand,
2385 ITextRange_fnGetIndex,
2386 ITextRange_fnSetIndex,
2387 ITextRange_fnSetRange,
2388 ITextRange_fnInRange,
2389 ITextRange_fnInStory,
2390 ITextRange_fnIsEqual,
2391 ITextRange_fnSelect,
2392 ITextRange_fnStartOf,
2393 ITextRange_fnEndOf,
2394 ITextRange_fnMove,
2395 ITextRange_fnMoveStart,
2396 ITextRange_fnMoveEnd,
2397 ITextRange_fnMoveWhile,
2398 ITextRange_fnMoveStartWhile,
2399 ITextRange_fnMoveEndWhile,
2400 ITextRange_fnMoveUntil,
2401 ITextRange_fnMoveStartUntil,
2402 ITextRange_fnMoveEndUntil,
2403 ITextRange_fnFindText,
2404 ITextRange_fnFindTextStart,
2405 ITextRange_fnFindTextEnd,
2406 ITextRange_fnDelete,
2407 ITextRange_fnCut,
2408 ITextRange_fnCopy,
2409 ITextRange_fnPaste,
2410 ITextRange_fnCanPaste,
2411 ITextRange_fnCanEdit,
2412 ITextRange_fnChangeCase,
2413 ITextRange_fnGetPoint,
2414 ITextRange_fnSetPoint,
2415 ITextRange_fnScrollIntoView,
2416 ITextRange_fnGetEmbeddedObject
2419 /* ITextFont */
2420 static HRESULT WINAPI TextFont_QueryInterface(ITextFont *iface, REFIID riid, void **ppv)
2422 ITextFontImpl *This = impl_from_ITextFont(iface);
2424 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
2426 if (IsEqualIID(riid, &IID_ITextFont) ||
2427 IsEqualIID(riid, &IID_IDispatch) ||
2428 IsEqualIID(riid, &IID_IUnknown))
2430 *ppv = iface;
2431 ITextFont_AddRef(iface);
2432 return S_OK;
2435 *ppv = NULL;
2436 return E_NOINTERFACE;
2439 static ULONG WINAPI TextFont_AddRef(ITextFont *iface)
2441 ITextFontImpl *This = impl_from_ITextFont(iface);
2442 ULONG ref = InterlockedIncrement(&This->ref);
2443 TRACE("(%p)->(%u)\n", This, ref);
2444 return ref;
2447 static ULONG WINAPI TextFont_Release(ITextFont *iface)
2449 ITextFontImpl *This = impl_from_ITextFont(iface);
2450 ULONG ref = InterlockedDecrement(&This->ref);
2452 TRACE("(%p)->(%u)\n", This, ref);
2454 if (!ref)
2456 if (This->range)
2457 ITextRange_Release(This->range);
2458 SysFreeString(This->props[FONT_NAME].str);
2459 heap_free(This);
2462 return ref;
2465 static HRESULT WINAPI TextFont_GetTypeInfoCount(ITextFont *iface, UINT *pctinfo)
2467 ITextFontImpl *This = impl_from_ITextFont(iface);
2468 TRACE("(%p)->(%p)\n", This, pctinfo);
2469 *pctinfo = 1;
2470 return S_OK;
2473 static HRESULT WINAPI TextFont_GetTypeInfo(ITextFont *iface, UINT iTInfo, LCID lcid,
2474 ITypeInfo **ppTInfo)
2476 ITextFontImpl *This = impl_from_ITextFont(iface);
2477 HRESULT hr;
2479 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
2481 hr = get_typeinfo(ITextFont_tid, ppTInfo);
2482 if (SUCCEEDED(hr))
2483 ITypeInfo_AddRef(*ppTInfo);
2484 return hr;
2487 static HRESULT WINAPI TextFont_GetIDsOfNames(ITextFont *iface, REFIID riid,
2488 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
2490 ITextFontImpl *This = impl_from_ITextFont(iface);
2491 ITypeInfo *ti;
2492 HRESULT hr;
2494 TRACE("(%p)->(%p,%p,%u,%d,%p)\n", This, riid, rgszNames, cNames, lcid,
2495 rgDispId);
2497 hr = get_typeinfo(ITextFont_tid, &ti);
2498 if (SUCCEEDED(hr))
2499 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
2500 return hr;
2503 static HRESULT WINAPI TextFont_Invoke(
2504 ITextFont *iface,
2505 DISPID dispIdMember,
2506 REFIID riid,
2507 LCID lcid,
2508 WORD wFlags,
2509 DISPPARAMS *pDispParams,
2510 VARIANT *pVarResult,
2511 EXCEPINFO *pExcepInfo,
2512 UINT *puArgErr)
2514 ITextFontImpl *This = impl_from_ITextFont(iface);
2515 ITypeInfo *ti;
2516 HRESULT hr;
2518 TRACE("(%p)->(%d,%p,%d,%u,%p,%p,%p,%p)\n", This, dispIdMember, riid, lcid,
2519 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2521 hr = get_typeinfo(ITextFont_tid, &ti);
2522 if (SUCCEEDED(hr))
2523 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2524 return hr;
2527 static HRESULT WINAPI TextFont_GetDuplicate(ITextFont *iface, ITextFont **ret)
2529 ITextFontImpl *This = impl_from_ITextFont(iface);
2531 TRACE("(%p)->(%p)\n", This, ret);
2533 if (!ret)
2534 return E_INVALIDARG;
2536 *ret = NULL;
2537 if (This->range && !get_range_reole(This->range))
2538 return CO_E_RELEASED;
2540 return create_textfont(NULL, This, ret);
2543 static HRESULT WINAPI TextFont_SetDuplicate(ITextFont *iface, ITextFont *pFont)
2545 ITextFontImpl *This = impl_from_ITextFont(iface);
2546 FIXME("(%p)->(%p): stub\n", This, pFont);
2547 return E_NOTIMPL;
2550 static HRESULT WINAPI TextFont_CanChange(ITextFont *iface, LONG *ret)
2552 ITextFontImpl *This = impl_from_ITextFont(iface);
2553 FIXME("(%p)->(%p): stub\n", This, ret);
2554 return E_NOTIMPL;
2557 static HRESULT WINAPI TextFont_IsEqual(ITextFont *iface, ITextFont *font, LONG *ret)
2559 ITextFontImpl *This = impl_from_ITextFont(iface);
2560 FIXME("(%p)->(%p %p): stub\n", This, font, ret);
2561 return E_NOTIMPL;
2564 static void textfont_reset_to_default(ITextFontImpl *font)
2566 enum textfont_prop_id id;
2568 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2569 switch (id)
2571 case FONT_ALLCAPS:
2572 case FONT_ANIMATION:
2573 case FONT_BOLD:
2574 case FONT_EMBOSS:
2575 case FONT_HIDDEN:
2576 case FONT_ENGRAVE:
2577 case FONT_ITALIC:
2578 case FONT_OUTLINE:
2579 case FONT_PROTECTED:
2580 case FONT_SHADOW:
2581 case FONT_SMALLCAPS:
2582 case FONT_STRIKETHROUGH:
2583 case FONT_SUBSCRIPT:
2584 case FONT_SUPERSCRIPT:
2585 case FONT_UNDERLINE:
2586 font->props[id].l = tomFalse;
2587 break;
2588 case FONT_BACKCOLOR:
2589 case FONT_FORECOLOR:
2590 font->props[id].l = tomAutoColor;
2591 break;
2592 case FONT_KERNING:
2593 case FONT_POSITION:
2594 case FONT_SIZE:
2595 case FONT_SPACING:
2596 font->props[id].f = 0.0;
2597 break;
2598 case FONT_LANGID:
2599 font->props[id].l = GetSystemDefaultLCID();
2600 break;
2601 case FONT_NAME: {
2602 static const WCHAR sysW[] = {'S','y','s','t','e','m',0};
2603 SysFreeString(font->props[id].str);
2604 font->props[id].str = SysAllocString(sysW);
2605 break;
2607 case FONT_WEIGHT:
2608 font->props[id].l = FW_NORMAL;
2609 break;
2610 default:
2611 FIXME("font property %d not handled\n", id);
2616 static void textfont_reset_to_undefined(ITextFontImpl *font)
2618 enum textfont_prop_id id;
2620 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2621 switch (id)
2623 case FONT_ALLCAPS:
2624 case FONT_ANIMATION:
2625 case FONT_BOLD:
2626 case FONT_EMBOSS:
2627 case FONT_HIDDEN:
2628 case FONT_ENGRAVE:
2629 case FONT_ITALIC:
2630 case FONT_OUTLINE:
2631 case FONT_PROTECTED:
2632 case FONT_SHADOW:
2633 case FONT_SMALLCAPS:
2634 case FONT_STRIKETHROUGH:
2635 case FONT_SUBSCRIPT:
2636 case FONT_SUPERSCRIPT:
2637 case FONT_UNDERLINE:
2638 case FONT_BACKCOLOR:
2639 case FONT_FORECOLOR:
2640 case FONT_LANGID:
2641 case FONT_WEIGHT:
2642 font->props[id].l = tomUndefined;
2643 break;
2644 case FONT_KERNING:
2645 case FONT_POSITION:
2646 case FONT_SIZE:
2647 case FONT_SPACING:
2648 font->props[id].f = tomUndefined;
2649 break;
2650 case FONT_NAME:
2651 break;
2652 default:
2653 FIXME("font property %d not handled\n", id);
2658 static void textfont_apply_range_props(ITextFontImpl *font)
2660 enum textfont_prop_id propid;
2661 for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++)
2662 set_textfont_prop(font, propid, &font->props[propid]);
2665 static HRESULT WINAPI TextFont_Reset(ITextFont *iface, LONG value)
2667 ITextFontImpl *This = impl_from_ITextFont(iface);
2669 TRACE("(%p)->(%d)\n", This, value);
2671 /* If font is attached to a range, released or not, we can't
2672 reset to undefined */
2673 if (This->range) {
2674 if (!get_range_reole(This->range))
2675 return CO_E_RELEASED;
2677 switch (value)
2679 case tomUndefined:
2680 return E_INVALIDARG;
2681 case tomCacheParms:
2682 textfont_cache_range_props(This);
2683 This->get_cache_enabled = TRUE;
2684 break;
2685 case tomTrackParms:
2686 This->get_cache_enabled = FALSE;
2687 break;
2688 case tomApplyLater:
2689 This->set_cache_enabled = TRUE;
2690 break;
2691 case tomApplyNow:
2692 This->set_cache_enabled = FALSE;
2693 textfont_apply_range_props(This);
2694 break;
2695 case tomUsePoints:
2696 case tomUseTwips:
2697 return E_INVALIDARG;
2698 default:
2699 FIXME("reset mode %d not supported\n", value);
2702 return S_OK;
2704 else {
2705 switch (value)
2707 /* reset to global defaults */
2708 case tomDefault:
2709 textfont_reset_to_default(This);
2710 return S_OK;
2711 /* all properties are set to tomUndefined, font name is retained */
2712 case tomUndefined:
2713 textfont_reset_to_undefined(This);
2714 return S_OK;
2715 case tomApplyNow:
2716 case tomApplyLater:
2717 case tomTrackParms:
2718 case tomCacheParms:
2719 return S_OK;
2720 case tomUsePoints:
2721 case tomUseTwips:
2722 return E_INVALIDARG;
2726 FIXME("reset mode %d not supported\n", value);
2727 return E_NOTIMPL;
2730 static HRESULT WINAPI TextFont_GetStyle(ITextFont *iface, LONG *value)
2732 ITextFontImpl *This = impl_from_ITextFont(iface);
2733 FIXME("(%p)->(%p): stub\n", This, value);
2734 return E_NOTIMPL;
2737 static HRESULT WINAPI TextFont_SetStyle(ITextFont *iface, LONG value)
2739 ITextFontImpl *This = impl_from_ITextFont(iface);
2740 FIXME("(%p)->(%d): stub\n", This, value);
2741 return E_NOTIMPL;
2744 static HRESULT WINAPI TextFont_GetAllCaps(ITextFont *iface, LONG *value)
2746 ITextFontImpl *This = impl_from_ITextFont(iface);
2747 TRACE("(%p)->(%p)\n", This, value);
2748 return get_textfont_propl(This, FONT_ALLCAPS, value);
2751 static HRESULT WINAPI TextFont_SetAllCaps(ITextFont *iface, LONG value)
2753 ITextFontImpl *This = impl_from_ITextFont(iface);
2754 TRACE("(%p)->(%d)\n", This, value);
2755 return set_textfont_propd(This, FONT_ALLCAPS, value);
2758 static HRESULT WINAPI TextFont_GetAnimation(ITextFont *iface, LONG *value)
2760 ITextFontImpl *This = impl_from_ITextFont(iface);
2761 TRACE("(%p)->(%p)\n", This, value);
2762 return get_textfont_propl(This, FONT_ANIMATION, value);
2765 static HRESULT WINAPI TextFont_SetAnimation(ITextFont *iface, LONG value)
2767 ITextFontImpl *This = impl_from_ITextFont(iface);
2769 TRACE("(%p)->(%d)\n", This, value);
2771 if (value < tomNoAnimation || value > tomAnimationMax)
2772 return E_INVALIDARG;
2774 return set_textfont_propl(This, FONT_ANIMATION, value);
2777 static HRESULT WINAPI TextFont_GetBackColor(ITextFont *iface, LONG *value)
2779 ITextFontImpl *This = impl_from_ITextFont(iface);
2780 TRACE("(%p)->(%p)\n", This, value);
2781 return get_textfont_propl(This, FONT_BACKCOLOR, value);
2784 static HRESULT WINAPI TextFont_SetBackColor(ITextFont *iface, LONG value)
2786 ITextFontImpl *This = impl_from_ITextFont(iface);
2787 TRACE("(%p)->(%d)\n", This, value);
2788 return set_textfont_propl(This, FONT_BACKCOLOR, value);
2791 static HRESULT WINAPI TextFont_GetBold(ITextFont *iface, LONG *value)
2793 ITextFontImpl *This = impl_from_ITextFont(iface);
2794 TRACE("(%p)->(%p)\n", This, value);
2795 return get_textfont_propl(This, FONT_BOLD, value);
2798 static HRESULT WINAPI TextFont_SetBold(ITextFont *iface, LONG value)
2800 ITextFontImpl *This = impl_from_ITextFont(iface);
2801 TRACE("(%p)->(%d)\n", This, value);
2802 return set_textfont_propd(This, FONT_BOLD, value);
2805 static HRESULT WINAPI TextFont_GetEmboss(ITextFont *iface, LONG *value)
2807 ITextFontImpl *This = impl_from_ITextFont(iface);
2808 TRACE("(%p)->(%p)\n", This, value);
2809 return get_textfont_propl(This, FONT_EMBOSS, value);
2812 static HRESULT WINAPI TextFont_SetEmboss(ITextFont *iface, LONG value)
2814 ITextFontImpl *This = impl_from_ITextFont(iface);
2815 TRACE("(%p)->(%d)\n", This, value);
2816 return set_textfont_propd(This, FONT_EMBOSS, value);
2819 static HRESULT WINAPI TextFont_GetForeColor(ITextFont *iface, LONG *value)
2821 ITextFontImpl *This = impl_from_ITextFont(iface);
2822 TRACE("(%p)->(%p)\n", This, value);
2823 return get_textfont_propl(This, FONT_FORECOLOR, value);
2826 static HRESULT WINAPI TextFont_SetForeColor(ITextFont *iface, LONG value)
2828 ITextFontImpl *This = impl_from_ITextFont(iface);
2829 TRACE("(%p)->(%d)\n", This, value);
2830 return set_textfont_propl(This, FONT_FORECOLOR, value);
2833 static HRESULT WINAPI TextFont_GetHidden(ITextFont *iface, LONG *value)
2835 ITextFontImpl *This = impl_from_ITextFont(iface);
2836 TRACE("(%p)->(%p)\n", This, value);
2837 return get_textfont_propl(This, FONT_HIDDEN, value);
2840 static HRESULT WINAPI TextFont_SetHidden(ITextFont *iface, LONG value)
2842 ITextFontImpl *This = impl_from_ITextFont(iface);
2843 TRACE("(%p)->(%d)\n", This, value);
2844 return set_textfont_propd(This, FONT_HIDDEN, value);
2847 static HRESULT WINAPI TextFont_GetEngrave(ITextFont *iface, LONG *value)
2849 ITextFontImpl *This = impl_from_ITextFont(iface);
2850 TRACE("(%p)->(%p)\n", This, value);
2851 return get_textfont_propl(This, FONT_ENGRAVE, value);
2854 static HRESULT WINAPI TextFont_SetEngrave(ITextFont *iface, LONG value)
2856 ITextFontImpl *This = impl_from_ITextFont(iface);
2857 TRACE("(%p)->(%d)\n", This, value);
2858 return set_textfont_propd(This, FONT_ENGRAVE, value);
2861 static HRESULT WINAPI TextFont_GetItalic(ITextFont *iface, LONG *value)
2863 ITextFontImpl *This = impl_from_ITextFont(iface);
2864 TRACE("(%p)->(%p)\n", This, value);
2865 return get_textfont_propl(This, FONT_ITALIC, value);
2868 static HRESULT WINAPI TextFont_SetItalic(ITextFont *iface, LONG value)
2870 ITextFontImpl *This = impl_from_ITextFont(iface);
2871 TRACE("(%p)->(%d)\n", This, value);
2872 return set_textfont_propd(This, FONT_ITALIC, value);
2875 static HRESULT WINAPI TextFont_GetKerning(ITextFont *iface, FLOAT *value)
2877 ITextFontImpl *This = impl_from_ITextFont(iface);
2878 TRACE("(%p)->(%p)\n", This, value);
2879 return get_textfont_propf(This, FONT_KERNING, value);
2882 static HRESULT WINAPI TextFont_SetKerning(ITextFont *iface, FLOAT value)
2884 ITextFontImpl *This = impl_from_ITextFont(iface);
2885 TRACE("(%p)->(%.2f)\n", This, value);
2886 return set_textfont_propf(This, FONT_KERNING, value);
2889 static HRESULT WINAPI TextFont_GetLanguageID(ITextFont *iface, LONG *value)
2891 ITextFontImpl *This = impl_from_ITextFont(iface);
2892 TRACE("(%p)->(%p)\n", This, value);
2893 return get_textfont_propl(This, FONT_LANGID, value);
2896 static HRESULT WINAPI TextFont_SetLanguageID(ITextFont *iface, LONG value)
2898 ITextFontImpl *This = impl_from_ITextFont(iface);
2899 TRACE("(%p)->(%d)\n", This, value);
2900 return set_textfont_propl(This, FONT_LANGID, value);
2903 static HRESULT WINAPI TextFont_GetName(ITextFont *iface, BSTR *value)
2905 ITextFontImpl *This = impl_from_ITextFont(iface);
2907 TRACE("(%p)->(%p)\n", This, value);
2909 if (!value)
2910 return E_INVALIDARG;
2912 *value = NULL;
2914 if (!This->range) {
2915 if (This->props[FONT_NAME].str)
2916 *value = SysAllocString(This->props[FONT_NAME].str);
2917 else
2918 *value = SysAllocStringLen(NULL, 0);
2919 return *value ? S_OK : E_OUTOFMEMORY;
2922 return textfont_getname_from_range(This->range, value);
2925 static HRESULT WINAPI TextFont_SetName(ITextFont *iface, BSTR value)
2927 ITextFontImpl *This = impl_from_ITextFont(iface);
2928 textfont_prop_val v;
2930 TRACE("(%p)->(%s)\n", This, debugstr_w(value));
2932 v.str = value;
2933 return set_textfont_prop(This, FONT_NAME, &v);
2936 static HRESULT WINAPI TextFont_GetOutline(ITextFont *iface, LONG *value)
2938 ITextFontImpl *This = impl_from_ITextFont(iface);
2939 TRACE("(%p)->(%p)\n", This, value);
2940 return get_textfont_propl(This, FONT_OUTLINE, value);
2943 static HRESULT WINAPI TextFont_SetOutline(ITextFont *iface, LONG value)
2945 ITextFontImpl *This = impl_from_ITextFont(iface);
2946 TRACE("(%p)->(%d)\n", This, value);
2947 return set_textfont_propd(This, FONT_OUTLINE, value);
2950 static HRESULT WINAPI TextFont_GetPosition(ITextFont *iface, FLOAT *value)
2952 ITextFontImpl *This = impl_from_ITextFont(iface);
2953 TRACE("(%p)->(%p)\n", This, value);
2954 return get_textfont_propf(This, FONT_POSITION, value);
2957 static HRESULT WINAPI TextFont_SetPosition(ITextFont *iface, FLOAT value)
2959 ITextFontImpl *This = impl_from_ITextFont(iface);
2960 TRACE("(%p)->(%.2f)\n", This, value);
2961 return set_textfont_propf(This, FONT_POSITION, value);
2964 static HRESULT WINAPI TextFont_GetProtected(ITextFont *iface, LONG *value)
2966 ITextFontImpl *This = impl_from_ITextFont(iface);
2967 TRACE("(%p)->(%p)\n", This, value);
2968 return get_textfont_propl(This, FONT_PROTECTED, value);
2971 static HRESULT WINAPI TextFont_SetProtected(ITextFont *iface, LONG value)
2973 ITextFontImpl *This = impl_from_ITextFont(iface);
2974 TRACE("(%p)->(%d)\n", This, value);
2975 return set_textfont_propd(This, FONT_PROTECTED, value);
2978 static HRESULT WINAPI TextFont_GetShadow(ITextFont *iface, LONG *value)
2980 ITextFontImpl *This = impl_from_ITextFont(iface);
2981 TRACE("(%p)->(%p)\n", This, value);
2982 return get_textfont_propl(This, FONT_SHADOW, value);
2985 static HRESULT WINAPI TextFont_SetShadow(ITextFont *iface, LONG value)
2987 ITextFontImpl *This = impl_from_ITextFont(iface);
2988 TRACE("(%p)->(%d)\n", This, value);
2989 return set_textfont_propd(This, FONT_SHADOW, value);
2992 static HRESULT WINAPI TextFont_GetSize(ITextFont *iface, FLOAT *value)
2994 ITextFontImpl *This = impl_from_ITextFont(iface);
2995 TRACE("(%p)->(%p)\n", This, value);
2996 return get_textfont_propf(This, FONT_SIZE, value);
2999 static HRESULT WINAPI TextFont_SetSize(ITextFont *iface, FLOAT value)
3001 ITextFontImpl *This = impl_from_ITextFont(iface);
3002 TRACE("(%p)->(%.2f)\n", This, value);
3003 return set_textfont_propf(This, FONT_SIZE, value);
3006 static HRESULT WINAPI TextFont_GetSmallCaps(ITextFont *iface, LONG *value)
3008 ITextFontImpl *This = impl_from_ITextFont(iface);
3009 TRACE("(%p)->(%p)\n", This, value);
3010 return get_textfont_propl(This, FONT_SMALLCAPS, value);
3013 static HRESULT WINAPI TextFont_SetSmallCaps(ITextFont *iface, LONG value)
3015 ITextFontImpl *This = impl_from_ITextFont(iface);
3016 TRACE("(%p)->(%d)\n", This, value);
3017 return set_textfont_propd(This, FONT_SMALLCAPS, value);
3020 static HRESULT WINAPI TextFont_GetSpacing(ITextFont *iface, FLOAT *value)
3022 ITextFontImpl *This = impl_from_ITextFont(iface);
3023 TRACE("(%p)->(%p)\n", This, value);
3024 return get_textfont_propf(This, FONT_SPACING, value);
3027 static HRESULT WINAPI TextFont_SetSpacing(ITextFont *iface, FLOAT value)
3029 ITextFontImpl *This = impl_from_ITextFont(iface);
3030 TRACE("(%p)->(%.2f)\n", This, value);
3031 return set_textfont_propf(This, FONT_SPACING, value);
3034 static HRESULT WINAPI TextFont_GetStrikeThrough(ITextFont *iface, LONG *value)
3036 ITextFontImpl *This = impl_from_ITextFont(iface);
3037 TRACE("(%p)->(%p)\n", This, value);
3038 return get_textfont_propl(This, FONT_STRIKETHROUGH, value);
3041 static HRESULT WINAPI TextFont_SetStrikeThrough(ITextFont *iface, LONG value)
3043 ITextFontImpl *This = impl_from_ITextFont(iface);
3044 TRACE("(%p)->(%d)\n", This, value);
3045 return set_textfont_propd(This, FONT_STRIKETHROUGH, value);
3048 static HRESULT WINAPI TextFont_GetSubscript(ITextFont *iface, LONG *value)
3050 ITextFontImpl *This = impl_from_ITextFont(iface);
3051 TRACE("(%p)->(%p)\n", This, value);
3052 return get_textfont_propl(This, FONT_SUBSCRIPT, value);
3055 static HRESULT WINAPI TextFont_SetSubscript(ITextFont *iface, LONG value)
3057 ITextFontImpl *This = impl_from_ITextFont(iface);
3058 TRACE("(%p)->(%d)\n", This, value);
3059 return set_textfont_propd(This, FONT_SUBSCRIPT, value);
3062 static HRESULT WINAPI TextFont_GetSuperscript(ITextFont *iface, LONG *value)
3064 ITextFontImpl *This = impl_from_ITextFont(iface);
3065 TRACE("(%p)->(%p)\n", This, value);
3066 return get_textfont_propl(This, FONT_SUPERSCRIPT, value);
3069 static HRESULT WINAPI TextFont_SetSuperscript(ITextFont *iface, LONG value)
3071 ITextFontImpl *This = impl_from_ITextFont(iface);
3072 TRACE("(%p)->(%d)\n", This, value);
3073 return set_textfont_propd(This, FONT_SUPERSCRIPT, value);
3076 static HRESULT WINAPI TextFont_GetUnderline(ITextFont *iface, LONG *value)
3078 ITextFontImpl *This = impl_from_ITextFont(iface);
3079 TRACE("(%p)->(%p)\n", This, value);
3080 return get_textfont_propl(This, FONT_UNDERLINE, value);
3083 static HRESULT WINAPI TextFont_SetUnderline(ITextFont *iface, LONG value)
3085 ITextFontImpl *This = impl_from_ITextFont(iface);
3086 TRACE("(%p)->(%d)\n", This, value);
3087 return set_textfont_propd(This, FONT_UNDERLINE, value);
3090 static HRESULT WINAPI TextFont_GetWeight(ITextFont *iface, LONG *value)
3092 ITextFontImpl *This = impl_from_ITextFont(iface);
3093 TRACE("(%p)->(%p)\n", This, value);
3094 return get_textfont_propl(This, FONT_WEIGHT, value);
3097 static HRESULT WINAPI TextFont_SetWeight(ITextFont *iface, LONG value)
3099 ITextFontImpl *This = impl_from_ITextFont(iface);
3100 TRACE("(%p)->(%d)\n", This, value);
3101 return set_textfont_propl(This, FONT_WEIGHT, value);
3104 static ITextFontVtbl textfontvtbl = {
3105 TextFont_QueryInterface,
3106 TextFont_AddRef,
3107 TextFont_Release,
3108 TextFont_GetTypeInfoCount,
3109 TextFont_GetTypeInfo,
3110 TextFont_GetIDsOfNames,
3111 TextFont_Invoke,
3112 TextFont_GetDuplicate,
3113 TextFont_SetDuplicate,
3114 TextFont_CanChange,
3115 TextFont_IsEqual,
3116 TextFont_Reset,
3117 TextFont_GetStyle,
3118 TextFont_SetStyle,
3119 TextFont_GetAllCaps,
3120 TextFont_SetAllCaps,
3121 TextFont_GetAnimation,
3122 TextFont_SetAnimation,
3123 TextFont_GetBackColor,
3124 TextFont_SetBackColor,
3125 TextFont_GetBold,
3126 TextFont_SetBold,
3127 TextFont_GetEmboss,
3128 TextFont_SetEmboss,
3129 TextFont_GetForeColor,
3130 TextFont_SetForeColor,
3131 TextFont_GetHidden,
3132 TextFont_SetHidden,
3133 TextFont_GetEngrave,
3134 TextFont_SetEngrave,
3135 TextFont_GetItalic,
3136 TextFont_SetItalic,
3137 TextFont_GetKerning,
3138 TextFont_SetKerning,
3139 TextFont_GetLanguageID,
3140 TextFont_SetLanguageID,
3141 TextFont_GetName,
3142 TextFont_SetName,
3143 TextFont_GetOutline,
3144 TextFont_SetOutline,
3145 TextFont_GetPosition,
3146 TextFont_SetPosition,
3147 TextFont_GetProtected,
3148 TextFont_SetProtected,
3149 TextFont_GetShadow,
3150 TextFont_SetShadow,
3151 TextFont_GetSize,
3152 TextFont_SetSize,
3153 TextFont_GetSmallCaps,
3154 TextFont_SetSmallCaps,
3155 TextFont_GetSpacing,
3156 TextFont_SetSpacing,
3157 TextFont_GetStrikeThrough,
3158 TextFont_SetStrikeThrough,
3159 TextFont_GetSubscript,
3160 TextFont_SetSubscript,
3161 TextFont_GetSuperscript,
3162 TextFont_SetSuperscript,
3163 TextFont_GetUnderline,
3164 TextFont_SetUnderline,
3165 TextFont_GetWeight,
3166 TextFont_SetWeight
3169 static HRESULT create_textfont(ITextRange *range, const ITextFontImpl *src, ITextFont **ret)
3171 ITextFontImpl *font;
3173 *ret = NULL;
3174 font = heap_alloc(sizeof(*font));
3175 if (!font)
3176 return E_OUTOFMEMORY;
3178 font->ITextFont_iface.lpVtbl = &textfontvtbl;
3179 font->ref = 1;
3181 if (src) {
3182 font->range = NULL;
3183 font->get_cache_enabled = TRUE;
3184 font->set_cache_enabled = TRUE;
3185 memcpy(&font->props, &src->props, sizeof(font->props));
3186 if (font->props[FONT_NAME].str)
3187 font->props[FONT_NAME].str = SysAllocString(font->props[FONT_NAME].str);
3189 else {
3190 font->range = range;
3191 ITextRange_AddRef(range);
3193 /* cache current properties */
3194 font->get_cache_enabled = FALSE;
3195 font->set_cache_enabled = FALSE;
3196 textfont_cache_range_props(font);
3199 *ret = &font->ITextFont_iface;
3200 return S_OK;
3203 /* ITextPara */
3204 static HRESULT WINAPI TextPara_QueryInterface(ITextPara *iface, REFIID riid, void **ppv)
3206 ITextParaImpl *This = impl_from_ITextPara(iface);
3208 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
3210 if (IsEqualIID(riid, &IID_ITextPara) ||
3211 IsEqualIID(riid, &IID_IDispatch) ||
3212 IsEqualIID(riid, &IID_IUnknown))
3214 *ppv = iface;
3215 ITextPara_AddRef(iface);
3216 return S_OK;
3219 *ppv = NULL;
3220 return E_NOINTERFACE;
3223 static ULONG WINAPI TextPara_AddRef(ITextPara *iface)
3225 ITextParaImpl *This = impl_from_ITextPara(iface);
3226 ULONG ref = InterlockedIncrement(&This->ref);
3227 TRACE("(%p)->(%u)\n", This, ref);
3228 return ref;
3231 static ULONG WINAPI TextPara_Release(ITextPara *iface)
3233 ITextParaImpl *This = impl_from_ITextPara(iface);
3234 ULONG ref = InterlockedDecrement(&This->ref);
3236 TRACE("(%p)->(%u)\n", This, ref);
3238 if (!ref)
3240 ITextRange_Release(This->range);
3241 heap_free(This);
3244 return ref;
3247 static HRESULT WINAPI TextPara_GetTypeInfoCount(ITextPara *iface, UINT *pctinfo)
3249 ITextParaImpl *This = impl_from_ITextPara(iface);
3250 TRACE("(%p)->(%p)\n", This, pctinfo);
3251 *pctinfo = 1;
3252 return S_OK;
3255 static HRESULT WINAPI TextPara_GetTypeInfo(ITextPara *iface, UINT iTInfo, LCID lcid,
3256 ITypeInfo **ppTInfo)
3258 ITextParaImpl *This = impl_from_ITextPara(iface);
3259 HRESULT hr;
3261 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
3263 hr = get_typeinfo(ITextPara_tid, ppTInfo);
3264 if (SUCCEEDED(hr))
3265 ITypeInfo_AddRef(*ppTInfo);
3266 return hr;
3269 static HRESULT WINAPI TextPara_GetIDsOfNames(ITextPara *iface, REFIID riid,
3270 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
3272 ITextParaImpl *This = impl_from_ITextPara(iface);
3273 ITypeInfo *ti;
3274 HRESULT hr;
3276 TRACE("(%p)->(%p,%p,%u,%d,%p)\n", This, riid, rgszNames, cNames, lcid,
3277 rgDispId);
3279 hr = get_typeinfo(ITextPara_tid, &ti);
3280 if (SUCCEEDED(hr))
3281 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
3282 return hr;
3285 static HRESULT WINAPI TextPara_Invoke(
3286 ITextPara *iface,
3287 DISPID dispIdMember,
3288 REFIID riid,
3289 LCID lcid,
3290 WORD wFlags,
3291 DISPPARAMS *pDispParams,
3292 VARIANT *pVarResult,
3293 EXCEPINFO *pExcepInfo,
3294 UINT *puArgErr)
3296 ITextParaImpl *This = impl_from_ITextPara(iface);
3297 ITypeInfo *ti;
3298 HRESULT hr;
3300 TRACE("(%p)->(%d,%p,%d,%u,%p,%p,%p,%p)\n", This, dispIdMember, riid, lcid,
3301 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3303 hr = get_typeinfo(ITextPara_tid, &ti);
3304 if (SUCCEEDED(hr))
3305 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3306 return hr;
3309 static HRESULT WINAPI TextPara_GetDuplicate(ITextPara *iface, ITextPara **ret)
3311 ITextParaImpl *This = impl_from_ITextPara(iface);
3312 FIXME("(%p)->(%p)\n", This, ret);
3313 return E_NOTIMPL;
3316 static HRESULT WINAPI TextPara_SetDuplicate(ITextPara *iface, ITextPara *para)
3318 ITextParaImpl *This = impl_from_ITextPara(iface);
3319 FIXME("(%p)->(%p)\n", This, para);
3320 return E_NOTIMPL;
3323 static HRESULT WINAPI TextPara_CanChange(ITextPara *iface, LONG *ret)
3325 ITextParaImpl *This = impl_from_ITextPara(iface);
3326 FIXME("(%p)->(%p)\n", This, ret);
3327 return E_NOTIMPL;
3330 static HRESULT WINAPI TextPara_IsEqual(ITextPara *iface, ITextPara *para, LONG *ret)
3332 ITextParaImpl *This = impl_from_ITextPara(iface);
3333 FIXME("(%p)->(%p %p)\n", This, para, ret);
3334 return E_NOTIMPL;
3337 static HRESULT WINAPI TextPara_Reset(ITextPara *iface, LONG value)
3339 ITextParaImpl *This = impl_from_ITextPara(iface);
3340 FIXME("(%p)->(%d)\n", This, value);
3341 return E_NOTIMPL;
3344 static HRESULT WINAPI TextPara_GetStyle(ITextPara *iface, LONG *value)
3346 ITextParaImpl *This = impl_from_ITextPara(iface);
3347 FIXME("(%p)->(%p)\n", This, value);
3348 return E_NOTIMPL;
3351 static HRESULT WINAPI TextPara_SetStyle(ITextPara *iface, LONG value)
3353 ITextParaImpl *This = impl_from_ITextPara(iface);
3354 FIXME("(%p)->(%d)\n", This, value);
3355 return E_NOTIMPL;
3358 static HRESULT WINAPI TextPara_GetAlignment(ITextPara *iface, LONG *value)
3360 ITextParaImpl *This = impl_from_ITextPara(iface);
3361 FIXME("(%p)->(%p)\n", This, value);
3362 return E_NOTIMPL;
3365 static HRESULT WINAPI TextPara_SetAlignment(ITextPara *iface, LONG value)
3367 ITextParaImpl *This = impl_from_ITextPara(iface);
3368 FIXME("(%p)->(%d)\n", This, value);
3369 return E_NOTIMPL;
3372 static HRESULT WINAPI TextPara_GetHyphenation(ITextPara *iface, LONG *value)
3374 ITextParaImpl *This = impl_from_ITextPara(iface);
3375 FIXME("(%p)->(%p)\n", This, value);
3376 return E_NOTIMPL;
3379 static HRESULT WINAPI TextPara_SetHyphenation(ITextPara *iface, LONG value)
3381 ITextParaImpl *This = impl_from_ITextPara(iface);
3382 FIXME("(%p)->(%d)\n", This, value);
3383 return E_NOTIMPL;
3386 static HRESULT WINAPI TextPara_GetFirstLineIndent(ITextPara *iface, FLOAT *value)
3388 ITextParaImpl *This = impl_from_ITextPara(iface);
3389 FIXME("(%p)->(%p)\n", This, value);
3390 return E_NOTIMPL;
3393 static HRESULT WINAPI TextPara_GetKeepTogether(ITextPara *iface, LONG *value)
3395 ITextParaImpl *This = impl_from_ITextPara(iface);
3396 FIXME("(%p)->(%p)\n", This, value);
3397 return E_NOTIMPL;
3400 static HRESULT WINAPI TextPara_SetKeepTogether(ITextPara *iface, LONG value)
3402 ITextParaImpl *This = impl_from_ITextPara(iface);
3403 FIXME("(%p)->(%d)\n", This, value);
3404 return E_NOTIMPL;
3407 static HRESULT WINAPI TextPara_GetKeepWithNext(ITextPara *iface, LONG *value)
3409 ITextParaImpl *This = impl_from_ITextPara(iface);
3410 FIXME("(%p)->(%p)\n", This, value);
3411 return E_NOTIMPL;
3414 static HRESULT WINAPI TextPara_SetKeepWithNext(ITextPara *iface, LONG value)
3416 ITextParaImpl *This = impl_from_ITextPara(iface);
3417 FIXME("(%p)->(%d)\n", This, value);
3418 return E_NOTIMPL;
3421 static HRESULT WINAPI TextPara_GetLeftIndent(ITextPara *iface, FLOAT *value)
3423 ITextParaImpl *This = impl_from_ITextPara(iface);
3424 FIXME("(%p)->(%p)\n", This, value);
3425 return E_NOTIMPL;
3428 static HRESULT WINAPI TextPara_GetLineSpacing(ITextPara *iface, FLOAT *value)
3430 ITextParaImpl *This = impl_from_ITextPara(iface);
3431 FIXME("(%p)->(%p)\n", This, value);
3432 return E_NOTIMPL;
3435 static HRESULT WINAPI TextPara_GetLineSpacingRule(ITextPara *iface, LONG *value)
3437 ITextParaImpl *This = impl_from_ITextPara(iface);
3438 FIXME("(%p)->(%p)\n", This, value);
3439 return E_NOTIMPL;
3442 static HRESULT WINAPI TextPara_GetListAlignment(ITextPara *iface, LONG *value)
3444 ITextParaImpl *This = impl_from_ITextPara(iface);
3445 FIXME("(%p)->(%p)\n", This, value);
3446 return E_NOTIMPL;
3449 static HRESULT WINAPI TextPara_SetListAlignment(ITextPara *iface, LONG value)
3451 ITextParaImpl *This = impl_from_ITextPara(iface);
3452 FIXME("(%p)->(%d)\n", This, value);
3453 return E_NOTIMPL;
3456 static HRESULT WINAPI TextPara_GetListLevelIndex(ITextPara *iface, LONG *value)
3458 ITextParaImpl *This = impl_from_ITextPara(iface);
3459 FIXME("(%p)->(%p)\n", This, value);
3460 return E_NOTIMPL;
3463 static HRESULT WINAPI TextPara_SetListLevelIndex(ITextPara *iface, LONG value)
3465 ITextParaImpl *This = impl_from_ITextPara(iface);
3466 FIXME("(%p)->(%d)\n", This, value);
3467 return E_NOTIMPL;
3470 static HRESULT WINAPI TextPara_GetListStart(ITextPara *iface, LONG *value)
3472 ITextParaImpl *This = impl_from_ITextPara(iface);
3473 FIXME("(%p)->(%p)\n", This, value);
3474 return E_NOTIMPL;
3477 static HRESULT WINAPI TextPara_SetListStart(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_GetListTab(ITextPara *iface, FLOAT *value)
3486 ITextParaImpl *This = impl_from_ITextPara(iface);
3487 FIXME("(%p)->(%p)\n", This, value);
3488 return E_NOTIMPL;
3491 static HRESULT WINAPI TextPara_SetListTab(ITextPara *iface, FLOAT value)
3493 ITextParaImpl *This = impl_from_ITextPara(iface);
3494 FIXME("(%p)->(%.2f)\n", This, value);
3495 return E_NOTIMPL;
3498 static HRESULT WINAPI TextPara_GetListType(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_SetListType(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_GetNoLineNumber(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_SetNoLineNumber(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_GetPageBreakBefore(ITextPara *iface, LONG *value)
3528 ITextParaImpl *This = impl_from_ITextPara(iface);
3529 FIXME("(%p)->(%p)\n", This, value);
3530 return E_NOTIMPL;
3533 static HRESULT WINAPI TextPara_SetPageBreakBefore(ITextPara *iface, LONG value)
3535 ITextParaImpl *This = impl_from_ITextPara(iface);
3536 FIXME("(%p)->(%d)\n", This, value);
3537 return E_NOTIMPL;
3540 static HRESULT WINAPI TextPara_GetRightIndent(ITextPara *iface, FLOAT *value)
3542 ITextParaImpl *This = impl_from_ITextPara(iface);
3543 FIXME("(%p)->(%p)\n", This, value);
3544 return E_NOTIMPL;
3547 static HRESULT WINAPI TextPara_SetRightIndent(ITextPara *iface, FLOAT value)
3549 ITextParaImpl *This = impl_from_ITextPara(iface);
3550 FIXME("(%p)->(%.2f)\n", This, value);
3551 return E_NOTIMPL;
3554 static HRESULT WINAPI TextPara_SetIndents(ITextPara *iface, FLOAT StartIndent, FLOAT LeftIndent, FLOAT RightIndent)
3556 ITextParaImpl *This = impl_from_ITextPara(iface);
3557 FIXME("(%p)->(%.2f %.2f %.2f)\n", This, StartIndent, LeftIndent, RightIndent);
3558 return E_NOTIMPL;
3561 static HRESULT WINAPI TextPara_SetLineSpacing(ITextPara *iface, LONG LineSpacingRule, FLOAT LineSpacing)
3563 ITextParaImpl *This = impl_from_ITextPara(iface);
3564 FIXME("(%p)->(%d %.2f)\n", This, LineSpacingRule, LineSpacing);
3565 return E_NOTIMPL;
3568 static HRESULT WINAPI TextPara_GetSpaceAfter(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_SetSpaceAfter(ITextPara *iface, FLOAT value)
3577 ITextParaImpl *This = impl_from_ITextPara(iface);
3578 FIXME("(%p)->(%.2f)\n", This, value);
3579 return E_NOTIMPL;
3582 static HRESULT WINAPI TextPara_GetSpaceBefore(ITextPara *iface, FLOAT *value)
3584 ITextParaImpl *This = impl_from_ITextPara(iface);
3585 FIXME("(%p)->(%p)\n", This, value);
3586 return E_NOTIMPL;
3589 static HRESULT WINAPI TextPara_SetSpaceBefore(ITextPara *iface, FLOAT value)
3591 ITextParaImpl *This = impl_from_ITextPara(iface);
3592 FIXME("(%p)->(%.2f)\n", This, value);
3593 return E_NOTIMPL;
3596 static HRESULT WINAPI TextPara_GetWidowControl(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_SetWidowControl(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_GetTabCount(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_AddTab(ITextPara *iface, FLOAT tbPos, LONG tbAlign, LONG tbLeader)
3619 ITextParaImpl *This = impl_from_ITextPara(iface);
3620 FIXME("(%p)->(%.2f %d %d)\n", This, tbPos, tbAlign, tbLeader);
3621 return E_NOTIMPL;
3624 static HRESULT WINAPI TextPara_ClearAllTabs(ITextPara *iface)
3626 ITextParaImpl *This = impl_from_ITextPara(iface);
3627 FIXME("(%p)\n", This);
3628 return E_NOTIMPL;
3631 static HRESULT WINAPI TextPara_DeleteTab(ITextPara *iface, FLOAT pos)
3633 ITextParaImpl *This = impl_from_ITextPara(iface);
3634 FIXME("(%p)->(%.2f)\n", This, pos);
3635 return E_NOTIMPL;
3638 static HRESULT WINAPI TextPara_GetTab(ITextPara *iface, LONG iTab, FLOAT *ptbPos, LONG *ptbAlign, LONG *ptbLeader)
3640 ITextParaImpl *This = impl_from_ITextPara(iface);
3641 FIXME("(%p)->(%d %p %p %p)\n", This, iTab, ptbPos, ptbAlign, ptbLeader);
3642 return E_NOTIMPL;
3645 static ITextParaVtbl textparavtbl = {
3646 TextPara_QueryInterface,
3647 TextPara_AddRef,
3648 TextPara_Release,
3649 TextPara_GetTypeInfoCount,
3650 TextPara_GetTypeInfo,
3651 TextPara_GetIDsOfNames,
3652 TextPara_Invoke,
3653 TextPara_GetDuplicate,
3654 TextPara_SetDuplicate,
3655 TextPara_CanChange,
3656 TextPara_IsEqual,
3657 TextPara_Reset,
3658 TextPara_GetStyle,
3659 TextPara_SetStyle,
3660 TextPara_GetAlignment,
3661 TextPara_SetAlignment,
3662 TextPara_GetHyphenation,
3663 TextPara_SetHyphenation,
3664 TextPara_GetFirstLineIndent,
3665 TextPara_GetKeepTogether,
3666 TextPara_SetKeepTogether,
3667 TextPara_GetKeepWithNext,
3668 TextPara_SetKeepWithNext,
3669 TextPara_GetLeftIndent,
3670 TextPara_GetLineSpacing,
3671 TextPara_GetLineSpacingRule,
3672 TextPara_GetListAlignment,
3673 TextPara_SetListAlignment,
3674 TextPara_GetListLevelIndex,
3675 TextPara_SetListLevelIndex,
3676 TextPara_GetListStart,
3677 TextPara_SetListStart,
3678 TextPara_GetListTab,
3679 TextPara_SetListTab,
3680 TextPara_GetListType,
3681 TextPara_SetListType,
3682 TextPara_GetNoLineNumber,
3683 TextPara_SetNoLineNumber,
3684 TextPara_GetPageBreakBefore,
3685 TextPara_SetPageBreakBefore,
3686 TextPara_GetRightIndent,
3687 TextPara_SetRightIndent,
3688 TextPara_SetIndents,
3689 TextPara_SetLineSpacing,
3690 TextPara_GetSpaceAfter,
3691 TextPara_SetSpaceAfter,
3692 TextPara_GetSpaceBefore,
3693 TextPara_SetSpaceBefore,
3694 TextPara_GetWidowControl,
3695 TextPara_SetWidowControl,
3696 TextPara_GetTabCount,
3697 TextPara_AddTab,
3698 TextPara_ClearAllTabs,
3699 TextPara_DeleteTab,
3700 TextPara_GetTab
3703 static HRESULT create_textpara(ITextRange *range, ITextPara **ret)
3705 ITextParaImpl *para;
3707 *ret = NULL;
3708 para = heap_alloc(sizeof(*para));
3709 if (!para)
3710 return E_OUTOFMEMORY;
3712 para->ITextPara_iface.lpVtbl = &textparavtbl;
3713 para->ref = 1;
3714 para->range = range;
3715 ITextRange_AddRef(range);
3717 *ret = &para->ITextPara_iface;
3718 return S_OK;
3721 /* ITextDocument */
3722 static HRESULT WINAPI
3723 ITextDocument_fnQueryInterface(ITextDocument* me, REFIID riid,
3724 void** ppvObject)
3726 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3727 return IRichEditOle_QueryInterface(&This->IRichEditOle_iface, riid, ppvObject);
3730 static ULONG WINAPI
3731 ITextDocument_fnAddRef(ITextDocument* me)
3733 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3734 return IRichEditOle_AddRef(&This->IRichEditOle_iface);
3737 static ULONG WINAPI
3738 ITextDocument_fnRelease(ITextDocument* me)
3740 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3741 return IRichEditOle_Release(&This->IRichEditOle_iface);
3744 static HRESULT WINAPI
3745 ITextDocument_fnGetTypeInfoCount(ITextDocument* me,
3746 UINT* pctinfo)
3748 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3749 TRACE("(%p)->(%p)\n", This, pctinfo);
3750 *pctinfo = 1;
3751 return S_OK;
3754 static HRESULT WINAPI
3755 ITextDocument_fnGetTypeInfo(ITextDocument* me, UINT iTInfo, LCID lcid,
3756 ITypeInfo** ppTInfo)
3758 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3759 HRESULT hr;
3761 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
3763 hr = get_typeinfo(ITextDocument_tid, ppTInfo);
3764 if (SUCCEEDED(hr))
3765 ITypeInfo_AddRef(*ppTInfo);
3766 return hr;
3769 static HRESULT WINAPI
3770 ITextDocument_fnGetIDsOfNames(ITextDocument* me, REFIID riid,
3771 LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId)
3773 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3774 ITypeInfo *ti;
3775 HRESULT hr;
3777 TRACE("(%p)->(%p,%p,%u,%d,%p)\n", This, riid, rgszNames, cNames, lcid,
3778 rgDispId);
3780 hr = get_typeinfo(ITextDocument_tid, &ti);
3781 if (SUCCEEDED(hr))
3782 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
3783 return hr;
3786 static HRESULT WINAPI
3787 ITextDocument_fnInvoke(ITextDocument* me, DISPID dispIdMember,
3788 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
3789 VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
3791 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3792 ITypeInfo *ti;
3793 HRESULT hr;
3795 TRACE("(%p)->(%d,%p,%d,%u,%p,%p,%p,%p)\n", This, dispIdMember, riid, lcid,
3796 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3798 hr = get_typeinfo(ITextDocument_tid, &ti);
3799 if (SUCCEEDED(hr))
3800 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3801 return hr;
3804 static HRESULT WINAPI
3805 ITextDocument_fnGetName(ITextDocument* me, BSTR* pName)
3807 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3808 FIXME("stub %p\n",This);
3809 return E_NOTIMPL;
3812 static HRESULT WINAPI
3813 ITextDocument_fnGetSelection(ITextDocument *me, ITextSelection **selection)
3815 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3817 TRACE("(%p)->(%p)\n", me, selection);
3819 if (!selection)
3820 return E_INVALIDARG;
3822 if (!This->txtSel) {
3823 This->txtSel = CreateTextSelection(This);
3824 if (!This->txtSel) {
3825 *selection = NULL;
3826 return E_OUTOFMEMORY;
3830 *selection = &This->txtSel->ITextSelection_iface;
3831 ITextSelection_AddRef(*selection);
3832 return S_OK;
3835 static HRESULT WINAPI
3836 ITextDocument_fnGetStoryCount(ITextDocument* me, LONG* pCount)
3838 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3839 FIXME("stub %p\n",This);
3840 return E_NOTIMPL;
3843 static HRESULT WINAPI
3844 ITextDocument_fnGetStoryRanges(ITextDocument* me,
3845 ITextStoryRanges** ppStories)
3847 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3848 FIXME("stub %p\n",This);
3849 return E_NOTIMPL;
3852 static HRESULT WINAPI
3853 ITextDocument_fnGetSaved(ITextDocument* me, LONG* pValue)
3855 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3856 FIXME("stub %p\n",This);
3857 return E_NOTIMPL;
3860 static HRESULT WINAPI
3861 ITextDocument_fnSetSaved(ITextDocument* me, LONG Value)
3863 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3864 FIXME("stub %p\n",This);
3865 return E_NOTIMPL;
3868 static HRESULT WINAPI
3869 ITextDocument_fnGetDefaultTabStop(ITextDocument* me, float* pValue)
3871 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3872 FIXME("stub %p\n",This);
3873 return E_NOTIMPL;
3876 static HRESULT WINAPI
3877 ITextDocument_fnSetDefaultTabStop(ITextDocument* me, float Value)
3879 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3880 FIXME("stub %p\n",This);
3881 return E_NOTIMPL;
3884 static HRESULT WINAPI
3885 ITextDocument_fnNew(ITextDocument* me)
3887 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3888 FIXME("stub %p\n",This);
3889 return E_NOTIMPL;
3892 static HRESULT WINAPI
3893 ITextDocument_fnOpen(ITextDocument* me, VARIANT* pVar, LONG Flags,
3894 LONG CodePage)
3896 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3897 FIXME("stub %p\n",This);
3898 return E_NOTIMPL;
3901 static HRESULT WINAPI
3902 ITextDocument_fnSave(ITextDocument* me, VARIANT* pVar, LONG Flags,
3903 LONG CodePage)
3905 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3906 FIXME("stub %p\n",This);
3907 return E_NOTIMPL;
3910 static HRESULT WINAPI
3911 ITextDocument_fnFreeze(ITextDocument* me, LONG* pCount)
3913 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3914 FIXME("stub %p\n",This);
3915 return E_NOTIMPL;
3918 static HRESULT WINAPI
3919 ITextDocument_fnUnfreeze(ITextDocument* me, LONG* pCount)
3921 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3922 FIXME("stub %p\n",This);
3923 return E_NOTIMPL;
3926 static HRESULT WINAPI
3927 ITextDocument_fnBeginEditCollection(ITextDocument* me)
3929 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3930 FIXME("stub %p\n",This);
3931 return E_NOTIMPL;
3934 static HRESULT WINAPI
3935 ITextDocument_fnEndEditCollection(ITextDocument* me)
3937 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3938 FIXME("stub %p\n",This);
3939 return E_NOTIMPL;
3942 static HRESULT WINAPI
3943 ITextDocument_fnUndo(ITextDocument* me, LONG Count, LONG* prop)
3945 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3946 FIXME("stub %p\n",This);
3947 return E_NOTIMPL;
3950 static HRESULT WINAPI
3951 ITextDocument_fnRedo(ITextDocument* me, LONG Count, LONG* prop)
3953 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3954 FIXME("stub %p\n",This);
3955 return E_NOTIMPL;
3958 static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, ITextRange** ppRange)
3960 ITextRangeImpl *txtRge = heap_alloc(sizeof(ITextRangeImpl));
3962 if (!txtRge)
3963 return E_OUTOFMEMORY;
3964 txtRge->ITextRange_iface.lpVtbl = &trvt;
3965 txtRge->ref = 1;
3966 txtRge->child.reole = reOle;
3967 txtRge->start = start;
3968 txtRge->end = end;
3969 list_add_head(&reOle->rangelist, &txtRge->child.entry);
3970 *ppRange = &txtRge->ITextRange_iface;
3971 return S_OK;
3974 static HRESULT WINAPI
3975 ITextDocument_fnRange(ITextDocument* me, LONG cp1, LONG cp2,
3976 ITextRange** ppRange)
3978 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3979 const int len = ME_GetTextLength(This->editor) + 1;
3981 TRACE("%p %p %d %d\n", This, ppRange, cp1, cp2);
3982 if (!ppRange)
3983 return E_INVALIDARG;
3985 cp1 = max(cp1, 0);
3986 cp2 = max(cp2, 0);
3987 cp1 = min(cp1, len);
3988 cp2 = min(cp2, len);
3989 if (cp1 > cp2)
3991 LONG tmp;
3992 tmp = cp1;
3993 cp1 = cp2;
3994 cp2 = tmp;
3996 if (cp1 == len)
3997 cp1 = cp2 = len - 1;
3999 return CreateITextRange(This, cp1, cp2, ppRange);
4002 static HRESULT WINAPI
4003 ITextDocument_fnRangeFromPoint(ITextDocument* me, LONG x, LONG y,
4004 ITextRange** ppRange)
4006 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4007 FIXME("stub %p\n",This);
4008 return E_NOTIMPL;
4011 static const ITextDocumentVtbl tdvt = {
4012 ITextDocument_fnQueryInterface,
4013 ITextDocument_fnAddRef,
4014 ITextDocument_fnRelease,
4015 ITextDocument_fnGetTypeInfoCount,
4016 ITextDocument_fnGetTypeInfo,
4017 ITextDocument_fnGetIDsOfNames,
4018 ITextDocument_fnInvoke,
4019 ITextDocument_fnGetName,
4020 ITextDocument_fnGetSelection,
4021 ITextDocument_fnGetStoryCount,
4022 ITextDocument_fnGetStoryRanges,
4023 ITextDocument_fnGetSaved,
4024 ITextDocument_fnSetSaved,
4025 ITextDocument_fnGetDefaultTabStop,
4026 ITextDocument_fnSetDefaultTabStop,
4027 ITextDocument_fnNew,
4028 ITextDocument_fnOpen,
4029 ITextDocument_fnSave,
4030 ITextDocument_fnFreeze,
4031 ITextDocument_fnUnfreeze,
4032 ITextDocument_fnBeginEditCollection,
4033 ITextDocument_fnEndEditCollection,
4034 ITextDocument_fnUndo,
4035 ITextDocument_fnRedo,
4036 ITextDocument_fnRange,
4037 ITextDocument_fnRangeFromPoint
4040 /* ITextSelection */
4041 static HRESULT WINAPI ITextSelection_fnQueryInterface(
4042 ITextSelection *me,
4043 REFIID riid,
4044 void **ppvObj)
4046 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4048 *ppvObj = NULL;
4049 if (IsEqualGUID(riid, &IID_IUnknown)
4050 || IsEqualGUID(riid, &IID_IDispatch)
4051 || IsEqualGUID(riid, &IID_ITextRange)
4052 || IsEqualGUID(riid, &IID_ITextSelection))
4054 *ppvObj = me;
4055 ITextSelection_AddRef(me);
4056 return S_OK;
4058 else if (IsEqualGUID(riid, &IID_Igetrichole))
4060 *ppvObj = This->reOle;
4061 return S_OK;
4064 return E_NOINTERFACE;
4067 static ULONG WINAPI ITextSelection_fnAddRef(ITextSelection *me)
4069 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4070 return InterlockedIncrement(&This->ref);
4073 static ULONG WINAPI ITextSelection_fnRelease(ITextSelection *me)
4075 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4076 ULONG ref = InterlockedDecrement(&This->ref);
4077 if (ref == 0)
4078 heap_free(This);
4079 return ref;
4082 static HRESULT WINAPI ITextSelection_fnGetTypeInfoCount(ITextSelection *me, UINT *pctinfo)
4084 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4085 TRACE("(%p)->(%p)\n", This, pctinfo);
4086 *pctinfo = 1;
4087 return S_OK;
4090 static HRESULT WINAPI ITextSelection_fnGetTypeInfo(ITextSelection *me, UINT iTInfo, LCID lcid,
4091 ITypeInfo **ppTInfo)
4093 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4094 HRESULT hr;
4096 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
4098 hr = get_typeinfo(ITextSelection_tid, ppTInfo);
4099 if (SUCCEEDED(hr))
4100 ITypeInfo_AddRef(*ppTInfo);
4101 return hr;
4104 static HRESULT WINAPI ITextSelection_fnGetIDsOfNames(ITextSelection *me, REFIID riid,
4105 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
4107 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4108 ITypeInfo *ti;
4109 HRESULT hr;
4111 TRACE("(%p)->(%p,%p,%u,%d,%p)\n", This, riid, rgszNames, cNames, lcid,
4112 rgDispId);
4114 hr = get_typeinfo(ITextSelection_tid, &ti);
4115 if (SUCCEEDED(hr))
4116 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
4117 return hr;
4120 static HRESULT WINAPI ITextSelection_fnInvoke(
4121 ITextSelection *me,
4122 DISPID dispIdMember,
4123 REFIID riid,
4124 LCID lcid,
4125 WORD wFlags,
4126 DISPPARAMS *pDispParams,
4127 VARIANT *pVarResult,
4128 EXCEPINFO *pExcepInfo,
4129 UINT *puArgErr)
4131 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4132 ITypeInfo *ti;
4133 HRESULT hr;
4135 TRACE("(%p)->(%d,%p,%d,%u,%p,%p,%p,%p)\n", This, dispIdMember, riid, lcid,
4136 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4138 hr = get_typeinfo(ITextSelection_tid, &ti);
4139 if (SUCCEEDED(hr))
4140 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4141 return hr;
4144 /*** ITextRange methods ***/
4145 static HRESULT WINAPI ITextSelection_fnGetText(ITextSelection *me, BSTR *pbstr)
4147 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4148 ME_Cursor *start = NULL, *end = NULL;
4149 int nChars, endOfs;
4150 BOOL bEOP;
4152 TRACE("(%p)->(%p)\n", This, pbstr);
4154 if (!This->reOle)
4155 return CO_E_RELEASED;
4157 if (!pbstr)
4158 return E_INVALIDARG;
4160 ME_GetSelection(This->reOle->editor, &start, &end);
4161 endOfs = ME_GetCursorOfs(end);
4162 nChars = endOfs - ME_GetCursorOfs(start);
4163 if (!nChars)
4165 *pbstr = NULL;
4166 return S_OK;
4169 *pbstr = SysAllocStringLen(NULL, nChars);
4170 if (!*pbstr)
4171 return E_OUTOFMEMORY;
4173 bEOP = (end->pRun->next->type == diTextEnd && endOfs > ME_GetTextLength(This->reOle->editor));
4174 ME_GetTextW(This->reOle->editor, *pbstr, nChars, start, nChars, FALSE, bEOP);
4175 TRACE("%s\n", wine_dbgstr_w(*pbstr));
4177 return S_OK;
4180 static HRESULT WINAPI ITextSelection_fnSetText(ITextSelection *me, BSTR str)
4182 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4183 ME_TextEditor *editor;
4184 int len, to, from;
4186 TRACE("(%p)->(%s)\n", This, debugstr_w(str));
4188 if (!This->reOle)
4189 return CO_E_RELEASED;
4191 editor = This->reOle->editor;
4192 len = strlenW(str);
4193 ME_GetSelectionOfs(editor, &from, &to);
4194 ME_ReplaceSel(editor, FALSE, str, len);
4196 if (len < to - from)
4197 textranges_update_ranges(This->reOle, from, len, RANGE_UPDATE_DELETE);
4199 return S_OK;
4202 static HRESULT WINAPI ITextSelection_fnGetChar(ITextSelection *me, LONG *pch)
4204 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4205 ME_Cursor *start = NULL, *end = NULL;
4207 TRACE("(%p)->(%p)\n", This, pch);
4209 if (!This->reOle)
4210 return CO_E_RELEASED;
4212 if (!pch)
4213 return E_INVALIDARG;
4215 ME_GetSelection(This->reOle->editor, &start, &end);
4216 return range_GetChar(This->reOle->editor, start, pch);
4219 static HRESULT WINAPI ITextSelection_fnSetChar(ITextSelection *me, LONG ch)
4221 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4222 if (!This->reOle)
4223 return CO_E_RELEASED;
4225 FIXME("not implemented\n");
4226 return E_NOTIMPL;
4229 static HRESULT WINAPI ITextSelection_fnGetDuplicate(ITextSelection *me, ITextRange **range)
4231 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4232 LONG start, end;
4234 TRACE("(%p)->(%p)\n", This, range);
4236 if (!This->reOle)
4237 return CO_E_RELEASED;
4239 if (!range)
4240 return E_INVALIDARG;
4242 ITextSelection_GetStart(me, &start);
4243 ITextSelection_GetEnd(me, &end);
4244 return CreateITextRange(This->reOle, start, end, range);
4247 static HRESULT WINAPI ITextSelection_fnGetFormattedText(ITextSelection *me, ITextRange **ppRange)
4249 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4250 if (!This->reOle)
4251 return CO_E_RELEASED;
4253 FIXME("not implemented\n");
4254 return E_NOTIMPL;
4257 static HRESULT WINAPI ITextSelection_fnSetFormattedText(ITextSelection *me, ITextRange *pRange)
4259 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4260 if (!This->reOle)
4261 return CO_E_RELEASED;
4263 FIXME("not implemented\n");
4264 return E_NOTIMPL;
4267 static HRESULT WINAPI ITextSelection_fnGetStart(ITextSelection *me, LONG *pcpFirst)
4269 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4270 LONG lim;
4271 if (!This->reOle)
4272 return CO_E_RELEASED;
4274 if (!pcpFirst)
4275 return E_INVALIDARG;
4276 ME_GetSelectionOfs(This->reOle->editor, pcpFirst, &lim);
4277 TRACE("%d\n", *pcpFirst);
4278 return S_OK;
4281 static HRESULT WINAPI ITextSelection_fnSetStart(ITextSelection *me, LONG value)
4283 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4284 LONG start, end;
4285 HRESULT hr;
4287 TRACE("(%p)->(%d)\n", This, value);
4289 if (!This->reOle)
4290 return CO_E_RELEASED;
4292 ME_GetSelectionOfs(This->reOle->editor, &start, &end);
4293 hr = textrange_setstart(This->reOle, value, &start, &end);
4294 if (hr == S_OK)
4295 ME_SetSelection(This->reOle->editor, start, end);
4297 return hr;
4300 static HRESULT WINAPI ITextSelection_fnGetEnd(ITextSelection *me, LONG *pcpLim)
4302 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4303 LONG first;
4304 if (!This->reOle)
4305 return CO_E_RELEASED;
4307 if (!pcpLim)
4308 return E_INVALIDARG;
4309 ME_GetSelectionOfs(This->reOle->editor, &first, pcpLim);
4310 TRACE("%d\n", *pcpLim);
4311 return S_OK;
4314 static HRESULT WINAPI ITextSelection_fnSetEnd(ITextSelection *me, LONG value)
4316 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4317 LONG start, end;
4318 HRESULT hr;
4320 TRACE("(%p)->(%d)\n", This, value);
4322 if (!This->reOle)
4323 return CO_E_RELEASED;
4325 ME_GetSelectionOfs(This->reOle->editor, &start, &end);
4326 hr = textrange_setend(This->reOle, value, &start, &end);
4327 if (hr == S_OK)
4328 ME_SetSelection(This->reOle->editor, start, end);
4330 return hr;
4333 static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **font)
4335 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4337 TRACE("(%p)->(%p)\n", This, font);
4339 if (!This->reOle)
4340 return CO_E_RELEASED;
4342 if (!font)
4343 return E_INVALIDARG;
4345 return create_textfont((ITextRange*)me, NULL, font);
4348 static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *font)
4350 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4352 TRACE("(%p)->(%p)\n", This, font);
4354 if (!font)
4355 return E_INVALIDARG;
4357 if (!This->reOle)
4358 return CO_E_RELEASED;
4360 textrange_set_font((ITextRange*)me, font);
4361 return S_OK;
4364 static HRESULT WINAPI ITextSelection_fnGetPara(ITextSelection *me, ITextPara **para)
4366 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4368 TRACE("(%p)->(%p)\n", This, para);
4370 if (!This->reOle)
4371 return CO_E_RELEASED;
4373 if (!para)
4374 return E_INVALIDARG;
4376 return create_textpara((ITextRange*)me, para);
4379 static HRESULT WINAPI ITextSelection_fnSetPara(ITextSelection *me, ITextPara *pPara)
4381 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4382 if (!This->reOle)
4383 return CO_E_RELEASED;
4385 FIXME("not implemented\n");
4386 return E_NOTIMPL;
4389 static HRESULT WINAPI ITextSelection_fnGetStoryLength(ITextSelection *me, LONG *length)
4391 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4393 TRACE("(%p)->(%p)\n", This, length);
4395 if (!This->reOle)
4396 return CO_E_RELEASED;
4398 return textrange_get_storylength(This->reOle->editor, length);
4401 static HRESULT WINAPI ITextSelection_fnGetStoryType(ITextSelection *me, LONG *value)
4403 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4405 TRACE("(%p)->(%p)\n", This, value);
4407 if (!This->reOle)
4408 return CO_E_RELEASED;
4410 if (!value)
4411 return E_INVALIDARG;
4413 *value = tomUnknownStory;
4414 return S_OK;
4417 static HRESULT WINAPI ITextSelection_fnCollapse(ITextSelection *me, LONG bStart)
4419 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4420 LONG start, end;
4421 HRESULT hres;
4422 if (!This->reOle)
4423 return CO_E_RELEASED;
4425 ME_GetSelectionOfs(This->reOle->editor, &start, &end);
4426 hres = range_Collapse(bStart, &start, &end);
4427 if (SUCCEEDED(hres))
4428 ME_SetSelection(This->reOle->editor, start, end);
4429 return hres;
4432 static HRESULT WINAPI ITextSelection_fnExpand(ITextSelection *me, LONG Unit, LONG *pDelta)
4434 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4435 if (!This->reOle)
4436 return CO_E_RELEASED;
4438 FIXME("not implemented\n");
4439 return E_NOTIMPL;
4442 static HRESULT WINAPI ITextSelection_fnGetIndex(ITextSelection *me, LONG Unit, LONG *pIndex)
4444 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4445 if (!This->reOle)
4446 return CO_E_RELEASED;
4448 FIXME("not implemented\n");
4449 return E_NOTIMPL;
4452 static HRESULT WINAPI ITextSelection_fnSetIndex(ITextSelection *me, LONG Unit, LONG Index,
4453 LONG Extend)
4455 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4456 if (!This->reOle)
4457 return CO_E_RELEASED;
4459 FIXME("not implemented\n");
4460 return E_NOTIMPL;
4463 static HRESULT WINAPI ITextSelection_fnSetRange(ITextSelection *me, LONG cpActive, LONG cpOther)
4465 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4466 if (!This->reOle)
4467 return CO_E_RELEASED;
4469 FIXME("not implemented\n");
4470 return E_NOTIMPL;
4473 static HRESULT WINAPI ITextSelection_fnInRange(ITextSelection *me, ITextRange *range, LONG *ret)
4475 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4476 ITextSelection *selection = NULL;
4477 LONG start, end;
4479 TRACE("(%p)->(%p %p)\n", This, range, ret);
4481 if (ret)
4482 *ret = tomFalse;
4484 if (!This->reOle)
4485 return CO_E_RELEASED;
4487 if (!range)
4488 return S_FALSE;
4490 ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection);
4491 if (!selection)
4492 return S_FALSE;
4493 ITextSelection_Release(selection);
4495 ITextSelection_GetStart(me, &start);
4496 ITextSelection_GetEnd(me, &end);
4497 return textrange_inrange(start, end, range, ret);
4500 static HRESULT WINAPI ITextSelection_fnInStory(ITextSelection *me, ITextRange *pRange, LONG *pb)
4502 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4503 if (!This->reOle)
4504 return CO_E_RELEASED;
4506 FIXME("not implemented\n");
4507 return E_NOTIMPL;
4510 static HRESULT WINAPI ITextSelection_fnIsEqual(ITextSelection *me, ITextRange *range, LONG *ret)
4512 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4513 ITextSelection *selection = NULL;
4514 LONG start, end;
4516 TRACE("(%p)->(%p %p)\n", This, range, ret);
4518 if (ret)
4519 *ret = tomFalse;
4521 if (!This->reOle)
4522 return CO_E_RELEASED;
4524 if (!range)
4525 return S_FALSE;
4527 ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection);
4528 if (!selection)
4529 return S_FALSE;
4530 ITextSelection_Release(selection);
4532 ITextSelection_GetStart(me, &start);
4533 ITextSelection_GetEnd(me, &end);
4534 return textrange_isequal(start, end, range, ret);
4537 static HRESULT WINAPI ITextSelection_fnSelect(ITextSelection *me)
4539 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4541 TRACE("(%p)\n", This);
4543 if (!This->reOle)
4544 return CO_E_RELEASED;
4546 /* nothing to do */
4547 return S_OK;
4550 static HRESULT WINAPI ITextSelection_fnStartOf(ITextSelection *me, LONG Unit, LONG Extend,
4551 LONG *pDelta)
4553 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4554 if (!This->reOle)
4555 return CO_E_RELEASED;
4557 FIXME("not implemented\n");
4558 return E_NOTIMPL;
4561 static HRESULT WINAPI ITextSelection_fnEndOf(ITextSelection *me, LONG Unit, LONG Extend,
4562 LONG *pDelta)
4564 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4565 if (!This->reOle)
4566 return CO_E_RELEASED;
4568 FIXME("not implemented\n");
4569 return E_NOTIMPL;
4572 static HRESULT WINAPI ITextSelection_fnMove(ITextSelection *me, LONG Unit, LONG Count, LONG *pDelta)
4574 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4575 if (!This->reOle)
4576 return CO_E_RELEASED;
4578 FIXME("not implemented\n");
4579 return E_NOTIMPL;
4582 static HRESULT WINAPI ITextSelection_fnMoveStart(ITextSelection *me, LONG Unit, LONG Count,
4583 LONG *pDelta)
4585 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4586 if (!This->reOle)
4587 return CO_E_RELEASED;
4589 FIXME("not implemented\n");
4590 return E_NOTIMPL;
4593 static HRESULT WINAPI ITextSelection_fnMoveEnd(ITextSelection *me, LONG Unit, LONG Count,
4594 LONG *pDelta)
4596 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4597 if (!This->reOle)
4598 return CO_E_RELEASED;
4600 FIXME("not implemented\n");
4601 return E_NOTIMPL;
4604 static HRESULT WINAPI ITextSelection_fnMoveWhile(ITextSelection *me, VARIANT *Cset, LONG Count,
4605 LONG *pDelta)
4607 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4608 if (!This->reOle)
4609 return CO_E_RELEASED;
4611 FIXME("not implemented\n");
4612 return E_NOTIMPL;
4615 static HRESULT WINAPI ITextSelection_fnMoveStartWhile(ITextSelection *me, VARIANT *Cset, LONG Count,
4616 LONG *pDelta)
4618 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4619 if (!This->reOle)
4620 return CO_E_RELEASED;
4622 FIXME("not implemented\n");
4623 return E_NOTIMPL;
4626 static HRESULT WINAPI ITextSelection_fnMoveEndWhile(ITextSelection *me, VARIANT *Cset, LONG Count,
4627 LONG *pDelta)
4629 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4630 if (!This->reOle)
4631 return CO_E_RELEASED;
4633 FIXME("not implemented\n");
4634 return E_NOTIMPL;
4637 static HRESULT WINAPI ITextSelection_fnMoveUntil(ITextSelection *me, VARIANT *Cset, LONG Count,
4638 LONG *pDelta)
4640 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4641 if (!This->reOle)
4642 return CO_E_RELEASED;
4644 FIXME("not implemented\n");
4645 return E_NOTIMPL;
4648 static HRESULT WINAPI ITextSelection_fnMoveStartUntil(ITextSelection *me, VARIANT *Cset, LONG Count,
4649 LONG *pDelta)
4651 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4652 if (!This->reOle)
4653 return CO_E_RELEASED;
4655 FIXME("not implemented\n");
4656 return E_NOTIMPL;
4659 static HRESULT WINAPI ITextSelection_fnMoveEndUntil(ITextSelection *me, VARIANT *Cset, LONG Count,
4660 LONG *pDelta)
4662 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4663 if (!This->reOle)
4664 return CO_E_RELEASED;
4666 FIXME("not implemented\n");
4667 return E_NOTIMPL;
4670 static HRESULT WINAPI ITextSelection_fnFindText(ITextSelection *me, BSTR bstr, LONG cch, LONG Flags,
4671 LONG *pLength)
4673 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4674 if (!This->reOle)
4675 return CO_E_RELEASED;
4677 FIXME("not implemented\n");
4678 return E_NOTIMPL;
4681 static HRESULT WINAPI ITextSelection_fnFindTextStart(ITextSelection *me, BSTR bstr, LONG cch,
4682 LONG Flags, LONG *pLength)
4684 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4685 if (!This->reOle)
4686 return CO_E_RELEASED;
4688 FIXME("not implemented\n");
4689 return E_NOTIMPL;
4692 static HRESULT WINAPI ITextSelection_fnFindTextEnd(ITextSelection *me, BSTR bstr, LONG cch,
4693 LONG Flags, LONG *pLength)
4695 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4696 if (!This->reOle)
4697 return CO_E_RELEASED;
4699 FIXME("not implemented\n");
4700 return E_NOTIMPL;
4703 static HRESULT WINAPI ITextSelection_fnDelete(ITextSelection *me, LONG Unit, LONG Count,
4704 LONG *pDelta)
4706 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4707 if (!This->reOle)
4708 return CO_E_RELEASED;
4710 FIXME("not implemented\n");
4711 return E_NOTIMPL;
4714 static HRESULT WINAPI ITextSelection_fnCut(ITextSelection *me, VARIANT *pVar)
4716 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4717 if (!This->reOle)
4718 return CO_E_RELEASED;
4720 FIXME("not implemented\n");
4721 return E_NOTIMPL;
4724 static HRESULT WINAPI ITextSelection_fnCopy(ITextSelection *me, VARIANT *pVar)
4726 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4727 if (!This->reOle)
4728 return CO_E_RELEASED;
4730 FIXME("not implemented\n");
4731 return E_NOTIMPL;
4734 static HRESULT WINAPI ITextSelection_fnPaste(ITextSelection *me, VARIANT *pVar, LONG Format)
4736 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4737 if (!This->reOle)
4738 return CO_E_RELEASED;
4740 FIXME("not implemented\n");
4741 return E_NOTIMPL;
4744 static HRESULT WINAPI ITextSelection_fnCanPaste(ITextSelection *me, VARIANT *pVar, LONG Format,
4745 LONG *pb)
4747 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4748 if (!This->reOle)
4749 return CO_E_RELEASED;
4751 FIXME("not implemented\n");
4752 return E_NOTIMPL;
4755 static HRESULT WINAPI ITextSelection_fnCanEdit(ITextSelection *me, LONG *pb)
4757 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4758 if (!This->reOle)
4759 return CO_E_RELEASED;
4761 FIXME("not implemented\n");
4762 return E_NOTIMPL;
4765 static HRESULT WINAPI ITextSelection_fnChangeCase(ITextSelection *me, LONG Type)
4767 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4768 if (!This->reOle)
4769 return CO_E_RELEASED;
4771 FIXME("not implemented\n");
4772 return E_NOTIMPL;
4775 static HRESULT WINAPI ITextSelection_fnGetPoint(ITextSelection *me, LONG Type, LONG *cx, LONG *cy)
4777 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4778 if (!This->reOle)
4779 return CO_E_RELEASED;
4781 FIXME("not implemented\n");
4782 return E_NOTIMPL;
4785 static HRESULT WINAPI ITextSelection_fnSetPoint(ITextSelection *me, LONG x, LONG y, LONG Type,
4786 LONG Extend)
4788 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4789 if (!This->reOle)
4790 return CO_E_RELEASED;
4792 FIXME("not implemented\n");
4793 return E_NOTIMPL;
4796 static HRESULT WINAPI ITextSelection_fnScrollIntoView(ITextSelection *me, LONG Value)
4798 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4799 if (!This->reOle)
4800 return CO_E_RELEASED;
4802 FIXME("not implemented\n");
4803 return E_NOTIMPL;
4806 static HRESULT WINAPI ITextSelection_fnGetEmbeddedObject(ITextSelection *me, IUnknown **ppv)
4808 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4809 if (!This->reOle)
4810 return CO_E_RELEASED;
4812 FIXME("not implemented\n");
4813 return E_NOTIMPL;
4816 /*** ITextSelection methods ***/
4817 static HRESULT WINAPI ITextSelection_fnGetFlags(ITextSelection *me, LONG *pFlags)
4819 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4820 if (!This->reOle)
4821 return CO_E_RELEASED;
4823 FIXME("not implemented\n");
4824 return E_NOTIMPL;
4827 static HRESULT WINAPI ITextSelection_fnSetFlags(ITextSelection *me, LONG Flags)
4829 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4830 if (!This->reOle)
4831 return CO_E_RELEASED;
4833 FIXME("not implemented\n");
4834 return E_NOTIMPL;
4837 static HRESULT WINAPI ITextSelection_fnGetType(ITextSelection *me, LONG *pType)
4839 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4840 if (!This->reOle)
4841 return CO_E_RELEASED;
4843 FIXME("not implemented\n");
4844 return E_NOTIMPL;
4847 static HRESULT WINAPI ITextSelection_fnMoveLeft(ITextSelection *me, LONG Unit, LONG Count,
4848 LONG Extend, LONG *pDelta)
4850 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4851 if (!This->reOle)
4852 return CO_E_RELEASED;
4854 FIXME("not implemented\n");
4855 return E_NOTIMPL;
4858 static HRESULT WINAPI ITextSelection_fnMoveRight(ITextSelection *me, LONG Unit, LONG Count,
4859 LONG Extend, LONG *pDelta)
4861 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4862 if (!This->reOle)
4863 return CO_E_RELEASED;
4865 FIXME("not implemented\n");
4866 return E_NOTIMPL;
4869 static HRESULT WINAPI ITextSelection_fnMoveUp(ITextSelection *me, LONG Unit, LONG Count,
4870 LONG Extend, LONG *pDelta)
4872 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4873 if (!This->reOle)
4874 return CO_E_RELEASED;
4876 FIXME("not implemented\n");
4877 return E_NOTIMPL;
4880 static HRESULT WINAPI ITextSelection_fnMoveDown(ITextSelection *me, LONG Unit, LONG Count,
4881 LONG Extend, LONG *pDelta)
4883 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4884 if (!This->reOle)
4885 return CO_E_RELEASED;
4887 FIXME("not implemented\n");
4888 return E_NOTIMPL;
4891 static HRESULT WINAPI ITextSelection_fnHomeKey(ITextSelection *me, LONG Unit, LONG Extend,
4892 LONG *pDelta)
4894 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4895 if (!This->reOle)
4896 return CO_E_RELEASED;
4898 FIXME("not implemented\n");
4899 return E_NOTIMPL;
4902 static HRESULT WINAPI ITextSelection_fnEndKey(ITextSelection *me, LONG Unit, LONG Extend,
4903 LONG *pDelta)
4905 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4906 if (!This->reOle)
4907 return CO_E_RELEASED;
4909 FIXME("not implemented\n");
4910 return E_NOTIMPL;
4913 static HRESULT WINAPI ITextSelection_fnTypeText(ITextSelection *me, BSTR bstr)
4915 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4916 if (!This->reOle)
4917 return CO_E_RELEASED;
4919 FIXME("not implemented\n");
4920 return E_NOTIMPL;
4923 static const ITextSelectionVtbl tsvt = {
4924 ITextSelection_fnQueryInterface,
4925 ITextSelection_fnAddRef,
4926 ITextSelection_fnRelease,
4927 ITextSelection_fnGetTypeInfoCount,
4928 ITextSelection_fnGetTypeInfo,
4929 ITextSelection_fnGetIDsOfNames,
4930 ITextSelection_fnInvoke,
4931 ITextSelection_fnGetText,
4932 ITextSelection_fnSetText,
4933 ITextSelection_fnGetChar,
4934 ITextSelection_fnSetChar,
4935 ITextSelection_fnGetDuplicate,
4936 ITextSelection_fnGetFormattedText,
4937 ITextSelection_fnSetFormattedText,
4938 ITextSelection_fnGetStart,
4939 ITextSelection_fnSetStart,
4940 ITextSelection_fnGetEnd,
4941 ITextSelection_fnSetEnd,
4942 ITextSelection_fnGetFont,
4943 ITextSelection_fnSetFont,
4944 ITextSelection_fnGetPara,
4945 ITextSelection_fnSetPara,
4946 ITextSelection_fnGetStoryLength,
4947 ITextSelection_fnGetStoryType,
4948 ITextSelection_fnCollapse,
4949 ITextSelection_fnExpand,
4950 ITextSelection_fnGetIndex,
4951 ITextSelection_fnSetIndex,
4952 ITextSelection_fnSetRange,
4953 ITextSelection_fnInRange,
4954 ITextSelection_fnInStory,
4955 ITextSelection_fnIsEqual,
4956 ITextSelection_fnSelect,
4957 ITextSelection_fnStartOf,
4958 ITextSelection_fnEndOf,
4959 ITextSelection_fnMove,
4960 ITextSelection_fnMoveStart,
4961 ITextSelection_fnMoveEnd,
4962 ITextSelection_fnMoveWhile,
4963 ITextSelection_fnMoveStartWhile,
4964 ITextSelection_fnMoveEndWhile,
4965 ITextSelection_fnMoveUntil,
4966 ITextSelection_fnMoveStartUntil,
4967 ITextSelection_fnMoveEndUntil,
4968 ITextSelection_fnFindText,
4969 ITextSelection_fnFindTextStart,
4970 ITextSelection_fnFindTextEnd,
4971 ITextSelection_fnDelete,
4972 ITextSelection_fnCut,
4973 ITextSelection_fnCopy,
4974 ITextSelection_fnPaste,
4975 ITextSelection_fnCanPaste,
4976 ITextSelection_fnCanEdit,
4977 ITextSelection_fnChangeCase,
4978 ITextSelection_fnGetPoint,
4979 ITextSelection_fnSetPoint,
4980 ITextSelection_fnScrollIntoView,
4981 ITextSelection_fnGetEmbeddedObject,
4982 ITextSelection_fnGetFlags,
4983 ITextSelection_fnSetFlags,
4984 ITextSelection_fnGetType,
4985 ITextSelection_fnMoveLeft,
4986 ITextSelection_fnMoveRight,
4987 ITextSelection_fnMoveUp,
4988 ITextSelection_fnMoveDown,
4989 ITextSelection_fnHomeKey,
4990 ITextSelection_fnEndKey,
4991 ITextSelection_fnTypeText
4994 static ITextSelectionImpl *
4995 CreateTextSelection(IRichEditOleImpl *reOle)
4997 ITextSelectionImpl *txtSel = heap_alloc(sizeof *txtSel);
4998 if (!txtSel)
4999 return NULL;
5001 txtSel->ITextSelection_iface.lpVtbl = &tsvt;
5002 txtSel->ref = 1;
5003 txtSel->reOle = reOle;
5004 return txtSel;
5007 LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *ppvObj)
5009 IRichEditOleImpl *reo;
5011 reo = heap_alloc(sizeof(IRichEditOleImpl));
5012 if (!reo)
5013 return 0;
5015 reo->IUnknown_inner.lpVtbl = &reo_unk_vtbl;
5016 reo->IRichEditOle_iface.lpVtbl = &revt;
5017 reo->ITextDocument_iface.lpVtbl = &tdvt;
5018 reo->ref = 1;
5019 reo->editor = editor;
5020 reo->txtSel = NULL;
5022 TRACE("Created %p\n",reo);
5023 list_init(&reo->rangelist);
5024 list_init(&reo->clientsites);
5025 if (outer_unk)
5026 reo->outer_unk = outer_unk;
5027 else
5028 reo->outer_unk = &reo->IUnknown_inner;
5029 *ppvObj = &reo->IRichEditOle_iface;
5031 return 1;
5034 static void convert_sizel(const ME_Context *c, const SIZEL* szl, SIZE* sz)
5036 /* sizel is in .01 millimeters, sz in pixels */
5037 sz->cx = MulDiv(szl->cx, c->dpi.cx, 2540);
5038 sz->cy = MulDiv(szl->cy, c->dpi.cy, 2540);
5041 /******************************************************************************
5042 * ME_GetOLEObjectSize
5044 * Sets run extent for OLE objects.
5046 void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize)
5048 IDataObject* ido;
5049 FORMATETC fmt;
5050 STGMEDIUM stgm;
5051 DIBSECTION dibsect;
5052 ENHMETAHEADER emh;
5054 assert(run->nFlags & MERF_GRAPHICS);
5055 assert(run->ole_obj);
5057 if (run->ole_obj->sizel.cx != 0 || run->ole_obj->sizel.cy != 0)
5059 convert_sizel(c, &run->ole_obj->sizel, pSize);
5060 if (c->editor->nZoomNumerator != 0)
5062 pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5063 pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5065 return;
5068 if (!run->ole_obj->poleobj)
5070 pSize->cx = pSize->cy = 0;
5071 return;
5074 if (IOleObject_QueryInterface(run->ole_obj->poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
5076 FIXME("Query Interface IID_IDataObject failed!\n");
5077 pSize->cx = pSize->cy = 0;
5078 return;
5080 fmt.cfFormat = CF_BITMAP;
5081 fmt.ptd = NULL;
5082 fmt.dwAspect = DVASPECT_CONTENT;
5083 fmt.lindex = -1;
5084 fmt.tymed = TYMED_GDI;
5085 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5087 fmt.cfFormat = CF_ENHMETAFILE;
5088 fmt.tymed = TYMED_ENHMF;
5089 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5091 FIXME("unsupported format\n");
5092 pSize->cx = pSize->cy = 0;
5093 IDataObject_Release(ido);
5094 return;
5098 switch (stgm.tymed)
5100 case TYMED_GDI:
5101 GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
5102 pSize->cx = dibsect.dsBm.bmWidth;
5103 pSize->cy = dibsect.dsBm.bmHeight;
5104 if (!stgm.pUnkForRelease) DeleteObject(stgm.u.hBitmap);
5105 break;
5106 case TYMED_ENHMF:
5107 GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
5108 pSize->cx = emh.rclBounds.right - emh.rclBounds.left;
5109 pSize->cy = emh.rclBounds.bottom - emh.rclBounds.top;
5110 if (!stgm.pUnkForRelease) DeleteEnhMetaFile(stgm.u.hEnhMetaFile);
5111 break;
5112 default:
5113 FIXME("Unsupported tymed %d\n", stgm.tymed);
5114 break;
5116 IDataObject_Release(ido);
5117 if (c->editor->nZoomNumerator != 0)
5119 pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5120 pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5124 void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run,
5125 ME_Paragraph *para, BOOL selected)
5127 IDataObject* ido;
5128 FORMATETC fmt;
5129 STGMEDIUM stgm;
5130 DIBSECTION dibsect;
5131 ENHMETAHEADER emh;
5132 HDC hMemDC;
5133 SIZE sz;
5134 BOOL has_size;
5136 assert(run->nFlags & MERF_GRAPHICS);
5137 assert(run->ole_obj);
5138 if (IOleObject_QueryInterface(run->ole_obj->poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
5140 FIXME("Couldn't get interface\n");
5141 return;
5143 has_size = run->ole_obj->sizel.cx != 0 || run->ole_obj->sizel.cy != 0;
5144 fmt.cfFormat = CF_BITMAP;
5145 fmt.ptd = NULL;
5146 fmt.dwAspect = DVASPECT_CONTENT;
5147 fmt.lindex = -1;
5148 fmt.tymed = TYMED_GDI;
5149 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5151 fmt.cfFormat = CF_ENHMETAFILE;
5152 fmt.tymed = TYMED_ENHMF;
5153 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5155 FIXME("Couldn't get storage medium\n");
5156 IDataObject_Release(ido);
5157 return;
5160 switch (stgm.tymed)
5162 case TYMED_GDI:
5163 GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
5164 hMemDC = CreateCompatibleDC(c->hDC);
5165 SelectObject(hMemDC, stgm.u.hBitmap);
5166 if (has_size)
5168 convert_sizel(c, &run->ole_obj->sizel, &sz);
5169 } else {
5170 sz.cx = MulDiv(dibsect.dsBm.bmWidth, c->dpi.cx, 96);
5171 sz.cy = MulDiv(dibsect.dsBm.bmHeight, c->dpi.cy, 96);
5173 if (c->editor->nZoomNumerator != 0)
5175 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5176 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5178 if (sz.cx == dibsect.dsBm.bmWidth && sz.cy == dibsect.dsBm.bmHeight)
5180 BitBlt(c->hDC, x, y - sz.cy,
5181 dibsect.dsBm.bmWidth, dibsect.dsBm.bmHeight,
5182 hMemDC, 0, 0, SRCCOPY);
5183 } else {
5184 StretchBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy,
5185 hMemDC, 0, 0, dibsect.dsBm.bmWidth,
5186 dibsect.dsBm.bmHeight, SRCCOPY);
5188 DeleteDC(hMemDC);
5189 if (!stgm.pUnkForRelease) DeleteObject(stgm.u.hBitmap);
5190 break;
5191 case TYMED_ENHMF:
5192 GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
5193 if (has_size)
5195 convert_sizel(c, &run->ole_obj->sizel, &sz);
5196 } else {
5197 sz.cy = MulDiv(emh.rclBounds.bottom - emh.rclBounds.top, c->dpi.cx, 96);
5198 sz.cx = MulDiv(emh.rclBounds.right - emh.rclBounds.left, c->dpi.cy, 96);
5200 if (c->editor->nZoomNumerator != 0)
5202 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5203 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5207 RECT rc;
5209 rc.left = x;
5210 rc.top = y - sz.cy;
5211 rc.right = x + sz.cx;
5212 rc.bottom = y;
5213 PlayEnhMetaFile(c->hDC, stgm.u.hEnhMetaFile, &rc);
5215 if (!stgm.pUnkForRelease) DeleteEnhMetaFile(stgm.u.hEnhMetaFile);
5216 break;
5217 default:
5218 FIXME("Unsupported tymed %d\n", stgm.tymed);
5219 selected = FALSE;
5220 break;
5222 if (selected && !c->editor->bHideSelection)
5223 PatBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy, DSTINVERT);
5224 IDataObject_Release(ido);
5227 void ME_DeleteReObject(REOBJECT* reo)
5229 if (reo->poleobj) IOleObject_Release(reo->poleobj);
5230 if (reo->pstg) IStorage_Release(reo->pstg);
5231 if (reo->polesite) IOleClientSite_Release(reo->polesite);
5232 FREE_OBJ(reo);
5235 void ME_CopyReObject(REOBJECT* dst, const REOBJECT* src)
5237 *dst = *src;
5239 if (dst->poleobj) IOleObject_AddRef(dst->poleobj);
5240 if (dst->pstg) IStorage_AddRef(dst->pstg);
5241 if (dst->polesite) IOleClientSite_AddRef(dst->polesite);
5244 void ME_GetITextDocumentInterface(IRichEditOle *iface, LPVOID *ppvObj)
5246 IRichEditOleImpl *This = impl_from_IRichEditOle(iface);
5247 *ppvObj = &This->ITextDocument_iface;