wined3d: Rename WINED3D_RS_CCW_STENCIL* render states to WINED3D_RS_BACK_STENCIL*.
[wine.git] / dlls / riched20 / richole.c
blobc5f04412e26b77d96cb2bdba09d7c9b1106fa16e
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, FALSE);
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 textrange_expand(ITextRange *range, LONG unit, LONG *delta)
914 LONG expand_start, expand_end;
916 switch (unit)
918 case tomStory:
919 expand_start = 0;
920 ITextRange_GetStoryLength(range, &expand_end);
921 break;
922 default:
923 FIXME("unit %d is not supported\n", unit);
924 return E_NOTIMPL;
927 if (delta) {
928 LONG start, end;
930 ITextRange_GetStart(range, &start);
931 ITextRange_GetEnd(range, &end);
932 *delta = expand_end - expand_start - (end - start);
935 ITextRange_SetStart(range, expand_start);
936 ITextRange_SetEnd(range, expand_end);
938 return S_OK;
941 static HRESULT WINAPI IRichEditOleImpl_inner_fnQueryInterface(IUnknown *iface, REFIID riid, LPVOID *ppvObj)
943 IRichEditOleImpl *This = impl_from_IUnknown(iface);
945 TRACE("%p %s\n", This, debugstr_guid(riid));
947 *ppvObj = NULL;
948 if (IsEqualGUID(riid, &IID_IUnknown))
949 *ppvObj = &This->IUnknown_inner;
950 else if (IsEqualGUID(riid, &IID_IRichEditOle))
951 *ppvObj = &This->IRichEditOle_iface;
952 else if (IsEqualGUID(riid, &IID_ITextDocument))
953 *ppvObj = &This->ITextDocument_iface;
954 if (*ppvObj)
956 IUnknown_AddRef((IUnknown *)*ppvObj);
957 return S_OK;
959 FIXME("%p: unhandled interface %s\n", This, debugstr_guid(riid));
961 return E_NOINTERFACE;
964 static ULONG WINAPI IRichEditOleImpl_inner_fnAddRef(IUnknown *iface)
966 IRichEditOleImpl *This = impl_from_IUnknown(iface);
967 ULONG ref = InterlockedIncrement(&This->ref);
969 TRACE("%p ref = %u\n", This, ref);
971 return ref;
974 static ULONG WINAPI IRichEditOleImpl_inner_fnRelease(IUnknown *iface)
976 IRichEditOleImpl *This = impl_from_IUnknown(iface);
977 ULONG ref = InterlockedDecrement(&This->ref);
979 TRACE ("%p ref=%u\n", This, ref);
981 if (!ref)
983 IOleClientSiteImpl *clientsite;
984 ITextRangeImpl *txtRge;
986 This->editor->reOle = NULL;
987 if (This->txtSel) {
988 This->txtSel->reOle = NULL;
989 ITextSelection_Release(&This->txtSel->ITextSelection_iface);
992 LIST_FOR_EACH_ENTRY(txtRge, &This->rangelist, ITextRangeImpl, child.entry)
993 txtRge->child.reole = NULL;
995 LIST_FOR_EACH_ENTRY(clientsite, &This->clientsites, IOleClientSiteImpl, child.entry)
996 clientsite->child.reole = NULL;
998 heap_free(This);
1000 return ref;
1003 static const IUnknownVtbl reo_unk_vtbl =
1005 IRichEditOleImpl_inner_fnQueryInterface,
1006 IRichEditOleImpl_inner_fnAddRef,
1007 IRichEditOleImpl_inner_fnRelease
1010 static HRESULT WINAPI
1011 IRichEditOle_fnQueryInterface(IRichEditOle *me, REFIID riid, LPVOID *ppvObj)
1013 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1014 return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj);
1017 static ULONG WINAPI
1018 IRichEditOle_fnAddRef(IRichEditOle *me)
1020 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1021 return IUnknown_AddRef(This->outer_unk);
1024 static ULONG WINAPI
1025 IRichEditOle_fnRelease(IRichEditOle *me)
1027 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1028 return IUnknown_Release(This->outer_unk);
1031 static HRESULT WINAPI
1032 IRichEditOle_fnActivateAs(IRichEditOle *me, REFCLSID rclsid, REFCLSID rclsidAs)
1034 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1035 FIXME("stub %p\n",This);
1036 return E_NOTIMPL;
1039 static HRESULT WINAPI
1040 IRichEditOle_fnContextSensitiveHelp(IRichEditOle *me, BOOL fEnterMode)
1042 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1043 FIXME("stub %p\n",This);
1044 return E_NOTIMPL;
1047 static HRESULT WINAPI
1048 IRichEditOle_fnConvertObject(IRichEditOle *me, LONG iob,
1049 REFCLSID rclsidNew, LPCSTR lpstrUserTypeNew)
1051 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1052 FIXME("stub %p\n",This);
1053 return E_NOTIMPL;
1056 static inline IOleClientSiteImpl *impl_from_IOleClientSite(IOleClientSite *iface)
1058 return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleClientSite_iface);
1061 static HRESULT WINAPI
1062 IOleClientSite_fnQueryInterface(IOleClientSite *me, REFIID riid, LPVOID *ppvObj)
1064 IOleClientSiteImpl *This = impl_from_IOleClientSite(me);
1065 TRACE("%p %s\n", me, debugstr_guid(riid) );
1067 *ppvObj = NULL;
1068 if (IsEqualGUID(riid, &IID_IUnknown) ||
1069 IsEqualGUID(riid, &IID_IOleClientSite))
1070 *ppvObj = me;
1071 else if (IsEqualGUID(riid, &IID_IOleWindow))
1072 *ppvObj = &This->IOleWindow_iface;
1073 else if (IsEqualGUID(riid, &IID_IOleInPlaceSite))
1074 *ppvObj = &This->IOleInPlaceSite_iface;
1075 if (*ppvObj)
1077 IOleClientSite_AddRef(me);
1078 return S_OK;
1080 FIXME("%p: unhandled interface %s\n", me, debugstr_guid(riid) );
1082 return E_NOINTERFACE;
1085 static ULONG WINAPI IOleClientSite_fnAddRef(IOleClientSite *iface)
1087 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1088 ULONG ref = InterlockedIncrement(&This->ref);
1089 TRACE("(%p)->(%u)\n", This, ref);
1090 return ref;
1093 static ULONG WINAPI IOleClientSite_fnRelease(IOleClientSite *iface)
1095 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1096 ULONG ref = InterlockedDecrement(&This->ref);
1098 TRACE("(%p)->(%u)\n", This, ref);
1100 if (ref == 0) {
1101 if (This->child.reole) {
1102 list_remove(&This->child.entry);
1103 This->child.reole = NULL;
1105 heap_free(This);
1107 return ref;
1110 static HRESULT WINAPI IOleClientSite_fnSaveObject(IOleClientSite *iface)
1112 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1113 if (!This->child.reole)
1114 return CO_E_RELEASED;
1116 FIXME("stub %p\n", iface);
1117 return E_NOTIMPL;
1120 static HRESULT WINAPI IOleClientSite_fnGetMoniker(IOleClientSite *iface, DWORD dwAssign,
1121 DWORD dwWhichMoniker, IMoniker **ppmk)
1123 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1124 if (!This->child.reole)
1125 return CO_E_RELEASED;
1127 FIXME("stub %p\n", iface);
1128 return E_NOTIMPL;
1131 static HRESULT WINAPI IOleClientSite_fnGetContainer(IOleClientSite *iface,
1132 IOleContainer **ppContainer)
1134 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1135 if (!This->child.reole)
1136 return CO_E_RELEASED;
1138 FIXME("stub %p\n", iface);
1139 return E_NOTIMPL;
1142 static HRESULT WINAPI IOleClientSite_fnShowObject(IOleClientSite *iface)
1144 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1145 if (!This->child.reole)
1146 return CO_E_RELEASED;
1148 FIXME("stub %p\n", iface);
1149 return E_NOTIMPL;
1152 static HRESULT WINAPI IOleClientSite_fnOnShowWindow(IOleClientSite *iface, BOOL fShow)
1154 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1155 if (!This->child.reole)
1156 return CO_E_RELEASED;
1158 FIXME("stub %p\n", iface);
1159 return E_NOTIMPL;
1162 static HRESULT WINAPI IOleClientSite_fnRequestNewObjectLayout(IOleClientSite *iface)
1164 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1165 if (!This->child.reole)
1166 return CO_E_RELEASED;
1168 FIXME("stub %p\n", iface);
1169 return E_NOTIMPL;
1172 static const IOleClientSiteVtbl ocst = {
1173 IOleClientSite_fnQueryInterface,
1174 IOleClientSite_fnAddRef,
1175 IOleClientSite_fnRelease,
1176 IOleClientSite_fnSaveObject,
1177 IOleClientSite_fnGetMoniker,
1178 IOleClientSite_fnGetContainer,
1179 IOleClientSite_fnShowObject,
1180 IOleClientSite_fnOnShowWindow,
1181 IOleClientSite_fnRequestNewObjectLayout
1184 /* IOleWindow interface */
1185 static HRESULT WINAPI IOleWindow_fnQueryInterface(IOleWindow *iface, REFIID riid, void **ppvObj)
1187 IOleClientSiteImpl *This = impl_from_IOleWindow(iface);
1188 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppvObj);
1191 static ULONG WINAPI IOleWindow_fnAddRef(IOleWindow *iface)
1193 IOleClientSiteImpl *This = impl_from_IOleWindow(iface);
1194 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1197 static ULONG WINAPI IOleWindow_fnRelease(IOleWindow *iface)
1199 IOleClientSiteImpl *This = impl_from_IOleWindow(iface);
1200 return IOleClientSite_Release(&This->IOleClientSite_iface);
1203 static HRESULT WINAPI IOleWindow_fnContextSensitiveHelp(IOleWindow *iface, BOOL fEnterMode)
1205 IOleClientSiteImpl *This = impl_from_IOleWindow(iface);
1206 FIXME("not implemented: (%p)->(%d)\n", This, fEnterMode);
1207 return E_NOTIMPL;
1210 static HRESULT WINAPI IOleWindow_fnGetWindow(IOleWindow *iface, HWND *phwnd)
1212 IOleClientSiteImpl *This = impl_from_IOleWindow(iface);
1214 TRACE("(%p)->(%p)\n", This, phwnd);
1216 if (!This->child.reole)
1217 return CO_E_RELEASED;
1219 if (!phwnd)
1220 return E_INVALIDARG;
1222 *phwnd = This->child.reole->editor->hWnd;
1223 return S_OK;
1226 static const IOleWindowVtbl olewinvt = {
1227 IOleWindow_fnQueryInterface,
1228 IOleWindow_fnAddRef,
1229 IOleWindow_fnRelease,
1230 IOleWindow_fnGetWindow,
1231 IOleWindow_fnContextSensitiveHelp
1234 /* IOleInPlaceSite interface */
1235 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnQueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppvObj)
1237 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1238 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppvObj);
1241 static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnAddRef(IOleInPlaceSite *iface)
1243 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1244 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1247 static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnRelease(IOleInPlaceSite *iface)
1249 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1250 return IOleClientSite_Release(&This->IOleClientSite_iface);
1253 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindow(IOleInPlaceSite *iface, HWND *phwnd)
1255 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1256 return IOleWindow_GetWindow(&This->IOleWindow_iface, phwnd);
1259 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode)
1261 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1262 return IOleWindow_ContextSensitiveHelp(&This->IOleWindow_iface, fEnterMode);
1265 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnCanInPlaceActivate(IOleInPlaceSite *iface)
1267 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1268 FIXME("not implemented: (%p)\n", This);
1269 return E_NOTIMPL;
1272 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceActivate(IOleInPlaceSite *iface)
1274 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1275 FIXME("not implemented: (%p)\n", This);
1276 return E_NOTIMPL;
1279 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIActivate(IOleInPlaceSite *iface)
1281 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1282 FIXME("not implemented: (%p)\n", This);
1283 return E_NOTIMPL;
1286 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindowContext(IOleInPlaceSite *iface, IOleInPlaceFrame **ppFrame,
1287 IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
1288 LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
1290 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1291 FIXME("not implemented: (%p)->(%p %p %p %p %p)\n", This, ppFrame, ppDoc, lprcPosRect, lprcClipRect, lpFrameInfo);
1292 return E_NOTIMPL;
1295 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnScroll(IOleInPlaceSite *iface, SIZE scrollExtent)
1297 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1298 FIXME("not implemented: (%p)\n", This);
1299 return E_NOTIMPL;
1302 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable)
1304 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1305 FIXME("not implemented: (%p)->(%d)\n", This, fUndoable);
1306 return E_NOTIMPL;
1309 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceDeactivate(IOleInPlaceSite *iface)
1311 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1312 FIXME("not implemented: (%p)\n", This);
1313 return E_NOTIMPL;
1316 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDiscardUndoState(IOleInPlaceSite *iface)
1318 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1319 FIXME("not implemented: (%p)\n", This);
1320 return E_NOTIMPL;
1323 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDeactivateAndUndo(IOleInPlaceSite *iface)
1325 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1326 FIXME("not implemented: (%p)\n", This);
1327 return E_NOTIMPL;
1330 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect)
1332 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1333 FIXME("not implemented: (%p)->(%p)\n", This, lprcPosRect);
1334 return E_NOTIMPL;
1337 static const IOleInPlaceSiteVtbl olestvt =
1339 IOleInPlaceSite_fnQueryInterface,
1340 IOleInPlaceSite_fnAddRef,
1341 IOleInPlaceSite_fnRelease,
1342 IOleInPlaceSite_fnGetWindow,
1343 IOleInPlaceSite_fnContextSensitiveHelp,
1344 IOleInPlaceSite_fnCanInPlaceActivate,
1345 IOleInPlaceSite_fnOnInPlaceActivate,
1346 IOleInPlaceSite_fnOnUIActivate,
1347 IOleInPlaceSite_fnGetWindowContext,
1348 IOleInPlaceSite_fnScroll,
1349 IOleInPlaceSite_fnOnUIDeactivate,
1350 IOleInPlaceSite_fnOnInPlaceDeactivate,
1351 IOleInPlaceSite_fnDiscardUndoState,
1352 IOleInPlaceSite_fnDeactivateAndUndo,
1353 IOleInPlaceSite_fnOnPosRectChange
1356 static HRESULT CreateOleClientSite(IRichEditOleImpl *reOle, IOleClientSite **ret)
1358 IOleClientSiteImpl *clientSite = heap_alloc(sizeof *clientSite);
1360 if (!clientSite)
1361 return E_OUTOFMEMORY;
1363 clientSite->IOleClientSite_iface.lpVtbl = &ocst;
1364 clientSite->IOleWindow_iface.lpVtbl = &olewinvt;
1365 clientSite->IOleInPlaceSite_iface.lpVtbl = &olestvt;
1366 clientSite->ref = 1;
1367 clientSite->child.reole = reOle;
1368 list_add_head(&reOle->clientsites, &clientSite->child.entry);
1370 *ret = &clientSite->IOleClientSite_iface;
1371 return S_OK;
1374 static HRESULT WINAPI
1375 IRichEditOle_fnGetClientSite(IRichEditOle *me, IOleClientSite **clientsite)
1377 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1379 TRACE("(%p)->(%p)\n", This, clientsite);
1381 if (!clientsite)
1382 return E_INVALIDARG;
1384 return CreateOleClientSite(This, clientsite);
1387 static HRESULT WINAPI
1388 IRichEditOle_fnGetClipboardData(IRichEditOle *me, CHARRANGE *lpchrg,
1389 DWORD reco, LPDATAOBJECT *lplpdataobj)
1391 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1392 ME_Cursor start;
1393 int nChars;
1395 TRACE("(%p,%p,%d)\n",This, lpchrg, reco);
1396 if(!lplpdataobj)
1397 return E_INVALIDARG;
1398 if(!lpchrg) {
1399 int nFrom, nTo, nStartCur = ME_GetSelectionOfs(This->editor, &nFrom, &nTo);
1400 start = This->editor->pCursors[nStartCur];
1401 nChars = nTo - nFrom;
1402 } else {
1403 ME_CursorFromCharOfs(This->editor, lpchrg->cpMin, &start);
1404 nChars = lpchrg->cpMax - lpchrg->cpMin;
1406 return ME_GetDataObject(This->editor, &start, nChars, lplpdataobj);
1409 static LONG WINAPI IRichEditOle_fnGetLinkCount(IRichEditOle *me)
1411 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1412 FIXME("stub %p\n",This);
1413 return E_NOTIMPL;
1416 static HRESULT WINAPI
1417 IRichEditOle_fnGetObject(IRichEditOle *me, LONG iob,
1418 REOBJECT *lpreobject, DWORD dwFlags)
1420 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1421 FIXME("stub %p\n",This);
1422 return E_NOTIMPL;
1425 static LONG WINAPI
1426 IRichEditOle_fnGetObjectCount(IRichEditOle *me)
1428 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1429 FIXME("stub %p\n",This);
1430 return 0;
1433 static HRESULT WINAPI
1434 IRichEditOle_fnHandsOffStorage(IRichEditOle *me, LONG iob)
1436 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1437 FIXME("stub %p\n",This);
1438 return E_NOTIMPL;
1441 static HRESULT WINAPI
1442 IRichEditOle_fnImportDataObject(IRichEditOle *me, LPDATAOBJECT lpdataobj,
1443 CLIPFORMAT cf, HGLOBAL hMetaPict)
1445 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1446 FIXME("stub %p\n",This);
1447 return E_NOTIMPL;
1450 static HRESULT WINAPI
1451 IRichEditOle_fnInPlaceDeactivate(IRichEditOle *me)
1453 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1454 FIXME("stub %p\n",This);
1455 return E_NOTIMPL;
1458 static HRESULT WINAPI
1459 IRichEditOle_fnInsertObject(IRichEditOle *me, REOBJECT *reo)
1461 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1463 TRACE("(%p,%p)\n", This, reo);
1465 if (!reo)
1466 return E_INVALIDARG;
1468 if (reo->cbStruct < sizeof(*reo)) return STG_E_INVALIDPARAMETER;
1470 ME_InsertOLEFromCursor(This->editor, reo, 0);
1471 ME_CommitUndo(This->editor);
1472 ME_UpdateRepaint(This->editor, FALSE);
1473 return S_OK;
1476 static HRESULT WINAPI IRichEditOle_fnSaveCompleted(IRichEditOle *me, LONG iob,
1477 LPSTORAGE lpstg)
1479 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1480 FIXME("stub %p\n",This);
1481 return E_NOTIMPL;
1484 static HRESULT WINAPI
1485 IRichEditOle_fnSetDvaspect(IRichEditOle *me, LONG iob, DWORD dvaspect)
1487 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1488 FIXME("stub %p\n",This);
1489 return E_NOTIMPL;
1492 static HRESULT WINAPI IRichEditOle_fnSetHostNames(IRichEditOle *me,
1493 LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj)
1495 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1496 FIXME("stub %p %s %s\n",This, lpstrContainerApp, lpstrContainerObj);
1497 return E_NOTIMPL;
1500 static HRESULT WINAPI
1501 IRichEditOle_fnSetLinkAvailable(IRichEditOle *me, LONG iob, BOOL fAvailable)
1503 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1504 FIXME("stub %p\n",This);
1505 return E_NOTIMPL;
1508 static const IRichEditOleVtbl revt = {
1509 IRichEditOle_fnQueryInterface,
1510 IRichEditOle_fnAddRef,
1511 IRichEditOle_fnRelease,
1512 IRichEditOle_fnGetClientSite,
1513 IRichEditOle_fnGetObjectCount,
1514 IRichEditOle_fnGetLinkCount,
1515 IRichEditOle_fnGetObject,
1516 IRichEditOle_fnInsertObject,
1517 IRichEditOle_fnConvertObject,
1518 IRichEditOle_fnActivateAs,
1519 IRichEditOle_fnSetHostNames,
1520 IRichEditOle_fnSetLinkAvailable,
1521 IRichEditOle_fnSetDvaspect,
1522 IRichEditOle_fnHandsOffStorage,
1523 IRichEditOle_fnSaveCompleted,
1524 IRichEditOle_fnInPlaceDeactivate,
1525 IRichEditOle_fnContextSensitiveHelp,
1526 IRichEditOle_fnGetClipboardData,
1527 IRichEditOle_fnImportDataObject
1530 /* ITextRange interface */
1531 static HRESULT WINAPI ITextRange_fnQueryInterface(ITextRange *me, REFIID riid, void **ppvObj)
1533 ITextRangeImpl *This = impl_from_ITextRange(me);
1535 *ppvObj = NULL;
1536 if (IsEqualGUID(riid, &IID_IUnknown)
1537 || IsEqualGUID(riid, &IID_IDispatch)
1538 || IsEqualGUID(riid, &IID_ITextRange))
1540 *ppvObj = me;
1541 ITextRange_AddRef(me);
1542 return S_OK;
1544 else if (IsEqualGUID(riid, &IID_Igetrichole))
1546 *ppvObj = This->child.reole;
1547 return S_OK;
1550 return E_NOINTERFACE;
1553 static ULONG WINAPI ITextRange_fnAddRef(ITextRange *me)
1555 ITextRangeImpl *This = impl_from_ITextRange(me);
1556 return InterlockedIncrement(&This->ref);
1559 static ULONG WINAPI ITextRange_fnRelease(ITextRange *me)
1561 ITextRangeImpl *This = impl_from_ITextRange(me);
1562 ULONG ref = InterlockedDecrement(&This->ref);
1564 TRACE ("%p ref=%u\n", This, ref);
1565 if (ref == 0)
1567 if (This->child.reole)
1569 list_remove(&This->child.entry);
1570 This->child.reole = NULL;
1572 heap_free(This);
1574 return ref;
1577 static HRESULT WINAPI ITextRange_fnGetTypeInfoCount(ITextRange *me, UINT *pctinfo)
1579 ITextRangeImpl *This = impl_from_ITextRange(me);
1580 TRACE("(%p)->(%p)\n", This, pctinfo);
1581 *pctinfo = 1;
1582 return S_OK;
1585 static HRESULT WINAPI ITextRange_fnGetTypeInfo(ITextRange *me, UINT iTInfo, LCID lcid,
1586 ITypeInfo **ppTInfo)
1588 ITextRangeImpl *This = impl_from_ITextRange(me);
1589 HRESULT hr;
1591 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
1593 hr = get_typeinfo(ITextRange_tid, ppTInfo);
1594 if (SUCCEEDED(hr))
1595 ITypeInfo_AddRef(*ppTInfo);
1596 return hr;
1599 static HRESULT WINAPI ITextRange_fnGetIDsOfNames(ITextRange *me, REFIID riid, LPOLESTR *rgszNames,
1600 UINT cNames, LCID lcid, DISPID *rgDispId)
1602 ITextRangeImpl *This = impl_from_ITextRange(me);
1603 ITypeInfo *ti;
1604 HRESULT hr;
1606 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
1607 rgDispId);
1609 hr = get_typeinfo(ITextRange_tid, &ti);
1610 if (SUCCEEDED(hr))
1611 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
1612 return hr;
1615 static HRESULT WINAPI ITextRange_fnInvoke(ITextRange *me, DISPID dispIdMember, REFIID riid,
1616 LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1617 VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
1618 UINT *puArgErr)
1620 ITextRangeImpl *This = impl_from_ITextRange(me);
1621 ITypeInfo *ti;
1622 HRESULT hr;
1624 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
1625 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1627 hr = get_typeinfo(ITextRange_tid, &ti);
1628 if (SUCCEEDED(hr))
1629 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1630 return hr;
1633 static HRESULT WINAPI ITextRange_fnGetText(ITextRange *me, BSTR *str)
1635 ITextRangeImpl *This = impl_from_ITextRange(me);
1636 ME_TextEditor *editor;
1637 ME_Cursor start, end;
1638 int length;
1639 BOOL bEOP;
1641 TRACE("(%p)->(%p)\n", This, str);
1643 if (!This->child.reole)
1644 return CO_E_RELEASED;
1646 if (!str)
1647 return E_INVALIDARG;
1649 /* return early for degenerate range */
1650 if (This->start == This->end) {
1651 *str = NULL;
1652 return S_OK;
1655 editor = This->child.reole->editor;
1656 ME_CursorFromCharOfs(editor, This->start, &start);
1657 ME_CursorFromCharOfs(editor, This->end, &end);
1659 length = This->end - This->start;
1660 *str = SysAllocStringLen(NULL, length);
1661 if (!*str)
1662 return E_OUTOFMEMORY;
1664 bEOP = (end.pRun->next->type == diTextEnd && This->end > ME_GetTextLength(editor));
1665 ME_GetTextW(editor, *str, length, &start, length, FALSE, bEOP);
1666 return S_OK;
1669 static HRESULT WINAPI ITextRange_fnSetText(ITextRange *me, BSTR str)
1671 ITextRangeImpl *This = impl_from_ITextRange(me);
1672 ME_TextEditor *editor;
1673 ME_Cursor cursor;
1674 ME_Style *style;
1675 int len;
1677 TRACE("(%p)->(%s)\n", This, debugstr_w(str));
1679 if (!This->child.reole)
1680 return CO_E_RELEASED;
1682 editor = This->child.reole->editor;
1684 /* delete only where's something to delete */
1685 if (This->start != This->end) {
1686 ME_CursorFromCharOfs(editor, This->start, &cursor);
1687 ME_InternalDeleteText(editor, &cursor, This->end - This->start, FALSE);
1690 if (!str || !*str) {
1691 /* will update this range as well */
1692 textranges_update_ranges(This->child.reole, This->start, This->end, RANGE_UPDATE_DELETE);
1693 return S_OK;
1696 /* it's safer not to rely on stored BSTR length */
1697 len = strlenW(str);
1698 cursor = editor->pCursors[0];
1699 ME_CursorFromCharOfs(editor, This->start, &editor->pCursors[0]);
1700 style = ME_GetInsertStyle(editor, 0);
1701 ME_InsertTextFromCursor(editor, 0, str, len, style);
1702 ME_ReleaseStyle(style);
1703 editor->pCursors[0] = cursor;
1705 if (len < This->end - This->start)
1706 textranges_update_ranges(This->child.reole, This->start + len, This->end, RANGE_UPDATE_DELETE);
1707 else
1708 This->end = len - This->start;
1710 return S_OK;
1713 static HRESULT range_GetChar(ME_TextEditor *editor, ME_Cursor *cursor, LONG *pch)
1715 WCHAR wch[2];
1717 ME_GetTextW(editor, wch, 1, cursor, 1, FALSE, cursor->pRun->next->type == diTextEnd);
1718 *pch = wch[0];
1720 return S_OK;
1723 static HRESULT WINAPI ITextRange_fnGetChar(ITextRange *me, LONG *pch)
1725 ITextRangeImpl *This = impl_from_ITextRange(me);
1726 ME_TextEditor *editor;
1727 ME_Cursor cursor;
1729 TRACE("(%p)->(%p)\n", This, pch);
1731 if (!This->child.reole)
1732 return CO_E_RELEASED;
1734 if (!pch)
1735 return E_INVALIDARG;
1737 editor = This->child.reole->editor;
1738 ME_CursorFromCharOfs(editor, This->start, &cursor);
1739 return range_GetChar(editor, &cursor, pch);
1742 static HRESULT WINAPI ITextRange_fnSetChar(ITextRange *me, LONG ch)
1744 ITextRangeImpl *This = impl_from_ITextRange(me);
1746 FIXME("(%p)->(%x): stub\n", This, ch);
1748 if (!This->child.reole)
1749 return CO_E_RELEASED;
1751 return E_NOTIMPL;
1754 static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, ITextRange** ppRange);
1756 static HRESULT WINAPI ITextRange_fnGetDuplicate(ITextRange *me, ITextRange **ppRange)
1758 ITextRangeImpl *This = impl_from_ITextRange(me);
1760 TRACE("(%p)->(%p)\n", This, ppRange);
1762 if (!This->child.reole)
1763 return CO_E_RELEASED;
1765 if (!ppRange)
1766 return E_INVALIDARG;
1768 return CreateITextRange(This->child.reole, This->start, This->end, ppRange);
1771 static HRESULT WINAPI ITextRange_fnGetFormattedText(ITextRange *me, ITextRange **range)
1773 ITextRangeImpl *This = impl_from_ITextRange(me);
1775 FIXME("(%p)->(%p): stub\n", This, range);
1777 if (!This->child.reole)
1778 return CO_E_RELEASED;
1780 return E_NOTIMPL;
1783 static HRESULT WINAPI ITextRange_fnSetFormattedText(ITextRange *me, ITextRange *range)
1785 ITextRangeImpl *This = impl_from_ITextRange(me);
1787 FIXME("(%p)->(%p): stub\n", This, range);
1789 if (!This->child.reole)
1790 return CO_E_RELEASED;
1792 return E_NOTIMPL;
1795 static HRESULT WINAPI ITextRange_fnGetStart(ITextRange *me, LONG *start)
1797 ITextRangeImpl *This = impl_from_ITextRange(me);
1799 TRACE("(%p)->(%p)\n", This, start);
1801 if (!This->child.reole)
1802 return CO_E_RELEASED;
1804 if (!start)
1805 return E_INVALIDARG;
1807 *start = This->start;
1808 return S_OK;
1811 static HRESULT textrange_setstart(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end)
1813 int len;
1815 if (value < 0)
1816 value = 0;
1818 if (value == *start)
1819 return S_FALSE;
1821 if (value <= *end) {
1822 *start = value;
1823 return S_OK;
1826 len = ME_GetTextLength(reole->editor);
1827 *start = *end = value > len ? len : value;
1828 return S_OK;
1831 static HRESULT WINAPI ITextRange_fnSetStart(ITextRange *me, LONG value)
1833 ITextRangeImpl *This = impl_from_ITextRange(me);
1835 TRACE("(%p)->(%d)\n", This, value);
1837 if (!This->child.reole)
1838 return CO_E_RELEASED;
1840 return textrange_setstart(This->child.reole, value, &This->start, &This->end);
1843 static HRESULT WINAPI ITextRange_fnGetEnd(ITextRange *me, LONG *end)
1845 ITextRangeImpl *This = impl_from_ITextRange(me);
1847 TRACE("(%p)->(%p)\n", This, end);
1849 if (!This->child.reole)
1850 return CO_E_RELEASED;
1852 if (!end)
1853 return E_INVALIDARG;
1855 *end = This->end;
1856 return S_OK;
1859 static HRESULT textrange_setend(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end)
1861 int len;
1863 if (value == *end)
1864 return S_FALSE;
1866 if (value < *start) {
1867 *start = *end = max(0, value);
1868 return S_OK;
1871 len = ME_GetTextLength(reole->editor);
1872 *end = value > len ? len + 1 : value;
1873 return S_OK;
1876 static HRESULT WINAPI ITextRange_fnSetEnd(ITextRange *me, LONG value)
1878 ITextRangeImpl *This = impl_from_ITextRange(me);
1880 TRACE("(%p)->(%d)\n", This, value);
1882 if (!This->child.reole)
1883 return CO_E_RELEASED;
1885 return textrange_setend(This->child.reole, value, &This->start, &This->end);
1888 static HRESULT WINAPI ITextRange_fnGetFont(ITextRange *me, ITextFont **font)
1890 ITextRangeImpl *This = impl_from_ITextRange(me);
1892 TRACE("(%p)->(%p)\n", This, font);
1894 if (!This->child.reole)
1895 return CO_E_RELEASED;
1897 if (!font)
1898 return E_INVALIDARG;
1900 return create_textfont(me, NULL, font);
1903 static HRESULT WINAPI ITextRange_fnSetFont(ITextRange *me, ITextFont *font)
1905 ITextRangeImpl *This = impl_from_ITextRange(me);
1907 TRACE("(%p)->(%p)\n", This, font);
1909 if (!font)
1910 return E_INVALIDARG;
1912 if (!This->child.reole)
1913 return CO_E_RELEASED;
1915 textrange_set_font(me, font);
1916 return S_OK;
1919 static HRESULT WINAPI ITextRange_fnGetPara(ITextRange *me, ITextPara **para)
1921 ITextRangeImpl *This = impl_from_ITextRange(me);
1923 TRACE("(%p)->(%p)\n", This, para);
1925 if (!This->child.reole)
1926 return CO_E_RELEASED;
1928 if (!para)
1929 return E_INVALIDARG;
1931 return create_textpara(me, para);
1934 static HRESULT WINAPI ITextRange_fnSetPara(ITextRange *me, ITextPara *para)
1936 ITextRangeImpl *This = impl_from_ITextRange(me);
1938 FIXME("(%p)->(%p): stub\n", This, para);
1940 if (!This->child.reole)
1941 return CO_E_RELEASED;
1943 return E_NOTIMPL;
1946 static HRESULT WINAPI ITextRange_fnGetStoryLength(ITextRange *me, LONG *length)
1948 ITextRangeImpl *This = impl_from_ITextRange(me);
1950 TRACE("(%p)->(%p)\n", This, length);
1952 if (!This->child.reole)
1953 return CO_E_RELEASED;
1955 return textrange_get_storylength(This->child.reole->editor, length);
1958 static HRESULT WINAPI ITextRange_fnGetStoryType(ITextRange *me, LONG *value)
1960 ITextRangeImpl *This = impl_from_ITextRange(me);
1962 TRACE("(%p)->(%p)\n", This, value);
1964 if (!This->child.reole)
1965 return CO_E_RELEASED;
1967 if (!value)
1968 return E_INVALIDARG;
1970 *value = tomUnknownStory;
1971 return S_OK;
1974 static HRESULT range_Collapse(LONG bStart, LONG *start, LONG *end)
1976 if (*end == *start)
1977 return S_FALSE;
1979 if (bStart == tomEnd)
1980 *start = *end;
1981 else
1982 *end = *start;
1983 return S_OK;
1986 static HRESULT WINAPI ITextRange_fnCollapse(ITextRange *me, LONG bStart)
1988 ITextRangeImpl *This = impl_from_ITextRange(me);
1990 TRACE("(%p)->(%d)\n", This, bStart);
1992 if (!This->child.reole)
1993 return CO_E_RELEASED;
1995 return range_Collapse(bStart, &This->start, &This->end);
1998 static HRESULT WINAPI ITextRange_fnExpand(ITextRange *me, LONG unit, LONG *delta)
2000 ITextRangeImpl *This = impl_from_ITextRange(me);
2002 TRACE("(%p)->(%d %p)\n", This, unit, delta);
2004 if (!This->child.reole)
2005 return CO_E_RELEASED;
2007 return textrange_expand(me, unit, delta);
2010 static HRESULT WINAPI ITextRange_fnGetIndex(ITextRange *me, LONG unit, LONG *index)
2012 ITextRangeImpl *This = impl_from_ITextRange(me);
2014 FIXME("(%p)->(%d %p): stub\n", This, unit, index);
2016 if (!This->child.reole)
2017 return CO_E_RELEASED;
2019 return E_NOTIMPL;
2022 static HRESULT WINAPI ITextRange_fnSetIndex(ITextRange *me, LONG unit, LONG index,
2023 LONG extend)
2025 ITextRangeImpl *This = impl_from_ITextRange(me);
2027 FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend);
2029 if (!This->child.reole)
2030 return CO_E_RELEASED;
2032 return E_NOTIMPL;
2035 static HRESULT WINAPI ITextRange_fnSetRange(ITextRange *me, LONG anchor, LONG active)
2037 ITextRangeImpl *This = impl_from_ITextRange(me);
2039 FIXME("(%p)->(%d %d): stub\n", This, anchor, active);
2041 if (!This->child.reole)
2042 return CO_E_RELEASED;
2044 return E_NOTIMPL;
2047 static HRESULT textrange_inrange(LONG start, LONG end, ITextRange *range, LONG *ret)
2049 LONG from, to, v;
2051 if (!ret)
2052 ret = &v;
2054 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
2055 *ret = tomFalse;
2057 else
2058 *ret = (start >= from && end <= to) ? tomTrue : tomFalse;
2059 return *ret == tomTrue ? S_OK : S_FALSE;
2062 static HRESULT WINAPI ITextRange_fnInRange(ITextRange *me, ITextRange *range, LONG *ret)
2064 ITextRangeImpl *This = impl_from_ITextRange(me);
2066 TRACE("(%p)->(%p %p)\n", This, range, ret);
2068 if (ret)
2069 *ret = tomFalse;
2071 if (!This->child.reole)
2072 return CO_E_RELEASED;
2074 if (!range)
2075 return S_FALSE;
2077 return textrange_inrange(This->start, This->end, range, ret);
2080 static HRESULT WINAPI ITextRange_fnInStory(ITextRange *me, ITextRange *pRange, LONG *ret)
2082 ITextRangeImpl *This = impl_from_ITextRange(me);
2084 FIXME("(%p)->(%p): stub\n", This, ret);
2086 if (!This->child.reole)
2087 return CO_E_RELEASED;
2089 return E_NOTIMPL;
2092 static HRESULT textrange_isequal(LONG start, LONG end, ITextRange *range, LONG *ret)
2094 LONG from, to, v;
2096 if (!ret)
2097 ret = &v;
2099 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
2100 *ret = tomFalse;
2102 else
2103 *ret = (start == from && end == to) ? tomTrue : tomFalse;
2104 return *ret == tomTrue ? S_OK : S_FALSE;
2107 static HRESULT WINAPI ITextRange_fnIsEqual(ITextRange *me, ITextRange *range, LONG *ret)
2109 ITextRangeImpl *This = impl_from_ITextRange(me);
2111 TRACE("(%p)->(%p %p)\n", This, range, ret);
2113 if (ret)
2114 *ret = tomFalse;
2116 if (!This->child.reole)
2117 return CO_E_RELEASED;
2119 if (!range)
2120 return S_FALSE;
2122 return textrange_isequal(This->start, This->end, range, ret);
2125 static HRESULT WINAPI ITextRange_fnSelect(ITextRange *me)
2127 ITextRangeImpl *This = impl_from_ITextRange(me);
2129 TRACE("(%p)\n", This);
2131 if (!This->child.reole)
2132 return CO_E_RELEASED;
2134 ME_SetSelection(This->child.reole->editor, This->start, This->end);
2135 return S_OK;
2138 static HRESULT WINAPI ITextRange_fnStartOf(ITextRange *me, LONG unit, LONG extend,
2139 LONG *delta)
2141 ITextRangeImpl *This = impl_from_ITextRange(me);
2143 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
2145 if (!This->child.reole)
2146 return CO_E_RELEASED;
2148 return E_NOTIMPL;
2151 static HRESULT WINAPI ITextRange_fnEndOf(ITextRange *me, LONG unit, LONG extend,
2152 LONG *delta)
2154 ITextRangeImpl *This = impl_from_ITextRange(me);
2156 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
2158 if (!This->child.reole)
2159 return CO_E_RELEASED;
2161 return E_NOTIMPL;
2164 static HRESULT WINAPI ITextRange_fnMove(ITextRange *me, LONG unit, LONG count, LONG *delta)
2166 ITextRangeImpl *This = impl_from_ITextRange(me);
2168 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2170 if (!This->child.reole)
2171 return CO_E_RELEASED;
2173 return E_NOTIMPL;
2176 static HRESULT WINAPI ITextRange_fnMoveStart(ITextRange *me, LONG unit, LONG count,
2177 LONG *delta)
2179 ITextRangeImpl *This = impl_from_ITextRange(me);
2181 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2183 if (!This->child.reole)
2184 return CO_E_RELEASED;
2186 return E_NOTIMPL;
2189 static HRESULT WINAPI ITextRange_fnMoveEnd(ITextRange *me, LONG unit, LONG count,
2190 LONG *delta)
2192 ITextRangeImpl *This = impl_from_ITextRange(me);
2194 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2196 if (!This->child.reole)
2197 return CO_E_RELEASED;
2199 return E_NOTIMPL;
2202 static HRESULT WINAPI ITextRange_fnMoveWhile(ITextRange *me, VARIANT *charset, LONG count,
2203 LONG *delta)
2205 ITextRangeImpl *This = impl_from_ITextRange(me);
2207 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2209 if (!This->child.reole)
2210 return CO_E_RELEASED;
2212 return E_NOTIMPL;
2215 static HRESULT WINAPI ITextRange_fnMoveStartWhile(ITextRange *me, VARIANT *charset, LONG count,
2216 LONG *delta)
2218 ITextRangeImpl *This = impl_from_ITextRange(me);
2220 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2222 if (!This->child.reole)
2223 return CO_E_RELEASED;
2225 return E_NOTIMPL;
2228 static HRESULT WINAPI ITextRange_fnMoveEndWhile(ITextRange *me, VARIANT *charset, LONG count,
2229 LONG *delta)
2231 ITextRangeImpl *This = impl_from_ITextRange(me);
2233 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2235 if (!This->child.reole)
2236 return CO_E_RELEASED;
2238 return E_NOTIMPL;
2241 static HRESULT WINAPI ITextRange_fnMoveUntil(ITextRange *me, VARIANT *charset, LONG count,
2242 LONG *delta)
2244 ITextRangeImpl *This = impl_from_ITextRange(me);
2246 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2248 if (!This->child.reole)
2249 return CO_E_RELEASED;
2251 return E_NOTIMPL;
2254 static HRESULT WINAPI ITextRange_fnMoveStartUntil(ITextRange *me, VARIANT *charset, LONG count,
2255 LONG *delta)
2257 ITextRangeImpl *This = impl_from_ITextRange(me);
2259 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2261 if (!This->child.reole)
2262 return CO_E_RELEASED;
2264 return E_NOTIMPL;
2267 static HRESULT WINAPI ITextRange_fnMoveEndUntil(ITextRange *me, VARIANT *charset, LONG count,
2268 LONG *delta)
2270 ITextRangeImpl *This = impl_from_ITextRange(me);
2272 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2274 if (!This->child.reole)
2275 return CO_E_RELEASED;
2277 return E_NOTIMPL;
2280 static HRESULT WINAPI ITextRange_fnFindText(ITextRange *me, BSTR text, LONG count, LONG flags,
2281 LONG *length)
2283 ITextRangeImpl *This = impl_from_ITextRange(me);
2285 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2287 if (!This->child.reole)
2288 return CO_E_RELEASED;
2290 return E_NOTIMPL;
2293 static HRESULT WINAPI ITextRange_fnFindTextStart(ITextRange *me, BSTR text, LONG count,
2294 LONG flags, LONG *length)
2296 ITextRangeImpl *This = impl_from_ITextRange(me);
2298 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2300 if (!This->child.reole)
2301 return CO_E_RELEASED;
2303 return E_NOTIMPL;
2306 static HRESULT WINAPI ITextRange_fnFindTextEnd(ITextRange *me, BSTR text, LONG count,
2307 LONG flags, LONG *length)
2309 ITextRangeImpl *This = impl_from_ITextRange(me);
2311 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2313 if (!This->child.reole)
2314 return CO_E_RELEASED;
2316 return E_NOTIMPL;
2319 static HRESULT WINAPI ITextRange_fnDelete(ITextRange *me, LONG unit, LONG count, LONG *delta)
2321 ITextRangeImpl *This = impl_from_ITextRange(me);
2323 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2325 if (!This->child.reole)
2326 return CO_E_RELEASED;
2328 return E_NOTIMPL;
2331 static HRESULT WINAPI ITextRange_fnCut(ITextRange *me, VARIANT *v)
2333 ITextRangeImpl *This = impl_from_ITextRange(me);
2335 FIXME("(%p)->(%p): stub\n", This, v);
2337 if (!This->child.reole)
2338 return CO_E_RELEASED;
2340 return E_NOTIMPL;
2343 static HRESULT WINAPI ITextRange_fnCopy(ITextRange *me, VARIANT *v)
2345 ITextRangeImpl *This = impl_from_ITextRange(me);
2347 FIXME("(%p)->(%p): stub\n", This, v);
2349 if (!This->child.reole)
2350 return CO_E_RELEASED;
2352 return E_NOTIMPL;
2355 static HRESULT WINAPI ITextRange_fnPaste(ITextRange *me, VARIANT *v, LONG format)
2357 ITextRangeImpl *This = impl_from_ITextRange(me);
2359 FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format);
2361 if (!This->child.reole)
2362 return CO_E_RELEASED;
2364 return E_NOTIMPL;
2367 static HRESULT WINAPI ITextRange_fnCanPaste(ITextRange *me, VARIANT *v, LONG format, LONG *ret)
2369 ITextRangeImpl *This = impl_from_ITextRange(me);
2371 FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret);
2373 if (!This->child.reole)
2374 return CO_E_RELEASED;
2376 return E_NOTIMPL;
2379 static HRESULT WINAPI ITextRange_fnCanEdit(ITextRange *me, LONG *ret)
2381 ITextRangeImpl *This = impl_from_ITextRange(me);
2383 FIXME("(%p)->(%p): stub\n", This, ret);
2385 if (!This->child.reole)
2386 return CO_E_RELEASED;
2388 return E_NOTIMPL;
2391 static HRESULT WINAPI ITextRange_fnChangeCase(ITextRange *me, LONG type)
2393 ITextRangeImpl *This = impl_from_ITextRange(me);
2395 FIXME("(%p)->(%d): stub\n", This, type);
2397 if (!This->child.reole)
2398 return CO_E_RELEASED;
2400 return E_NOTIMPL;
2403 static HRESULT WINAPI ITextRange_fnGetPoint(ITextRange *me, LONG type, LONG *cx, LONG *cy)
2405 ITextRangeImpl *This = impl_from_ITextRange(me);
2407 FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy);
2409 if (!This->child.reole)
2410 return CO_E_RELEASED;
2412 return E_NOTIMPL;
2415 static HRESULT WINAPI ITextRange_fnSetPoint(ITextRange *me, LONG x, LONG y, LONG type,
2416 LONG extend)
2418 ITextRangeImpl *This = impl_from_ITextRange(me);
2420 FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend);
2422 if (!This->child.reole)
2423 return CO_E_RELEASED;
2425 return E_NOTIMPL;
2428 static HRESULT WINAPI ITextRange_fnScrollIntoView(ITextRange *me, LONG value)
2430 ITextRangeImpl *This = impl_from_ITextRange(me);
2431 ME_TextEditor *editor;
2432 ME_Cursor cursor;
2433 int x, y, height;
2435 TRACE("(%p)->(%d)\n", This, value);
2437 if (!This->child.reole)
2438 return CO_E_RELEASED;
2440 editor = This->child.reole->editor;
2442 switch (value)
2444 case tomStart:
2445 ME_CursorFromCharOfs(editor, This->start, &cursor);
2446 ME_GetCursorCoordinates(editor, &cursor, &x, &y, &height);
2447 break;
2448 default:
2449 FIXME("bStart value %d not handled\n", value);
2450 return E_NOTIMPL;
2452 ME_ScrollAbs(editor, x, y);
2453 return S_OK;
2456 static HRESULT WINAPI ITextRange_fnGetEmbeddedObject(ITextRange *me, IUnknown **ppv)
2458 ITextRangeImpl *This = impl_from_ITextRange(me);
2460 FIXME("(%p)->(%p): stub\n", This, ppv);
2462 if (!This->child.reole)
2463 return CO_E_RELEASED;
2465 return E_NOTIMPL;
2468 static const ITextRangeVtbl trvt = {
2469 ITextRange_fnQueryInterface,
2470 ITextRange_fnAddRef,
2471 ITextRange_fnRelease,
2472 ITextRange_fnGetTypeInfoCount,
2473 ITextRange_fnGetTypeInfo,
2474 ITextRange_fnGetIDsOfNames,
2475 ITextRange_fnInvoke,
2476 ITextRange_fnGetText,
2477 ITextRange_fnSetText,
2478 ITextRange_fnGetChar,
2479 ITextRange_fnSetChar,
2480 ITextRange_fnGetDuplicate,
2481 ITextRange_fnGetFormattedText,
2482 ITextRange_fnSetFormattedText,
2483 ITextRange_fnGetStart,
2484 ITextRange_fnSetStart,
2485 ITextRange_fnGetEnd,
2486 ITextRange_fnSetEnd,
2487 ITextRange_fnGetFont,
2488 ITextRange_fnSetFont,
2489 ITextRange_fnGetPara,
2490 ITextRange_fnSetPara,
2491 ITextRange_fnGetStoryLength,
2492 ITextRange_fnGetStoryType,
2493 ITextRange_fnCollapse,
2494 ITextRange_fnExpand,
2495 ITextRange_fnGetIndex,
2496 ITextRange_fnSetIndex,
2497 ITextRange_fnSetRange,
2498 ITextRange_fnInRange,
2499 ITextRange_fnInStory,
2500 ITextRange_fnIsEqual,
2501 ITextRange_fnSelect,
2502 ITextRange_fnStartOf,
2503 ITextRange_fnEndOf,
2504 ITextRange_fnMove,
2505 ITextRange_fnMoveStart,
2506 ITextRange_fnMoveEnd,
2507 ITextRange_fnMoveWhile,
2508 ITextRange_fnMoveStartWhile,
2509 ITextRange_fnMoveEndWhile,
2510 ITextRange_fnMoveUntil,
2511 ITextRange_fnMoveStartUntil,
2512 ITextRange_fnMoveEndUntil,
2513 ITextRange_fnFindText,
2514 ITextRange_fnFindTextStart,
2515 ITextRange_fnFindTextEnd,
2516 ITextRange_fnDelete,
2517 ITextRange_fnCut,
2518 ITextRange_fnCopy,
2519 ITextRange_fnPaste,
2520 ITextRange_fnCanPaste,
2521 ITextRange_fnCanEdit,
2522 ITextRange_fnChangeCase,
2523 ITextRange_fnGetPoint,
2524 ITextRange_fnSetPoint,
2525 ITextRange_fnScrollIntoView,
2526 ITextRange_fnGetEmbeddedObject
2529 /* ITextFont */
2530 static HRESULT WINAPI TextFont_QueryInterface(ITextFont *iface, REFIID riid, void **ppv)
2532 ITextFontImpl *This = impl_from_ITextFont(iface);
2534 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
2536 if (IsEqualIID(riid, &IID_ITextFont) ||
2537 IsEqualIID(riid, &IID_IDispatch) ||
2538 IsEqualIID(riid, &IID_IUnknown))
2540 *ppv = iface;
2541 ITextFont_AddRef(iface);
2542 return S_OK;
2545 *ppv = NULL;
2546 return E_NOINTERFACE;
2549 static ULONG WINAPI TextFont_AddRef(ITextFont *iface)
2551 ITextFontImpl *This = impl_from_ITextFont(iface);
2552 ULONG ref = InterlockedIncrement(&This->ref);
2553 TRACE("(%p)->(%u)\n", This, ref);
2554 return ref;
2557 static ULONG WINAPI TextFont_Release(ITextFont *iface)
2559 ITextFontImpl *This = impl_from_ITextFont(iface);
2560 ULONG ref = InterlockedDecrement(&This->ref);
2562 TRACE("(%p)->(%u)\n", This, ref);
2564 if (!ref)
2566 if (This->range)
2567 ITextRange_Release(This->range);
2568 SysFreeString(This->props[FONT_NAME].str);
2569 heap_free(This);
2572 return ref;
2575 static HRESULT WINAPI TextFont_GetTypeInfoCount(ITextFont *iface, UINT *pctinfo)
2577 ITextFontImpl *This = impl_from_ITextFont(iface);
2578 TRACE("(%p)->(%p)\n", This, pctinfo);
2579 *pctinfo = 1;
2580 return S_OK;
2583 static HRESULT WINAPI TextFont_GetTypeInfo(ITextFont *iface, UINT iTInfo, LCID lcid,
2584 ITypeInfo **ppTInfo)
2586 ITextFontImpl *This = impl_from_ITextFont(iface);
2587 HRESULT hr;
2589 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
2591 hr = get_typeinfo(ITextFont_tid, ppTInfo);
2592 if (SUCCEEDED(hr))
2593 ITypeInfo_AddRef(*ppTInfo);
2594 return hr;
2597 static HRESULT WINAPI TextFont_GetIDsOfNames(ITextFont *iface, REFIID riid,
2598 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
2600 ITextFontImpl *This = impl_from_ITextFont(iface);
2601 ITypeInfo *ti;
2602 HRESULT hr;
2604 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid),
2605 rgszNames, cNames, lcid, rgDispId);
2607 hr = get_typeinfo(ITextFont_tid, &ti);
2608 if (SUCCEEDED(hr))
2609 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
2610 return hr;
2613 static HRESULT WINAPI TextFont_Invoke(
2614 ITextFont *iface,
2615 DISPID dispIdMember,
2616 REFIID riid,
2617 LCID lcid,
2618 WORD wFlags,
2619 DISPPARAMS *pDispParams,
2620 VARIANT *pVarResult,
2621 EXCEPINFO *pExcepInfo,
2622 UINT *puArgErr)
2624 ITextFontImpl *This = impl_from_ITextFont(iface);
2625 ITypeInfo *ti;
2626 HRESULT hr;
2628 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
2629 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2631 hr = get_typeinfo(ITextFont_tid, &ti);
2632 if (SUCCEEDED(hr))
2633 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2634 return hr;
2637 static HRESULT WINAPI TextFont_GetDuplicate(ITextFont *iface, ITextFont **ret)
2639 ITextFontImpl *This = impl_from_ITextFont(iface);
2641 TRACE("(%p)->(%p)\n", This, ret);
2643 if (!ret)
2644 return E_INVALIDARG;
2646 *ret = NULL;
2647 if (This->range && !get_range_reole(This->range))
2648 return CO_E_RELEASED;
2650 return create_textfont(NULL, This, ret);
2653 static HRESULT WINAPI TextFont_SetDuplicate(ITextFont *iface, ITextFont *pFont)
2655 ITextFontImpl *This = impl_from_ITextFont(iface);
2656 FIXME("(%p)->(%p): stub\n", This, pFont);
2657 return E_NOTIMPL;
2660 static HRESULT WINAPI TextFont_CanChange(ITextFont *iface, LONG *ret)
2662 ITextFontImpl *This = impl_from_ITextFont(iface);
2663 FIXME("(%p)->(%p): stub\n", This, ret);
2664 return E_NOTIMPL;
2667 static HRESULT WINAPI TextFont_IsEqual(ITextFont *iface, ITextFont *font, LONG *ret)
2669 ITextFontImpl *This = impl_from_ITextFont(iface);
2670 FIXME("(%p)->(%p %p): stub\n", This, font, ret);
2671 return E_NOTIMPL;
2674 static void textfont_reset_to_default(ITextFontImpl *font)
2676 enum textfont_prop_id id;
2678 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2679 switch (id)
2681 case FONT_ALLCAPS:
2682 case FONT_ANIMATION:
2683 case FONT_BOLD:
2684 case FONT_EMBOSS:
2685 case FONT_HIDDEN:
2686 case FONT_ENGRAVE:
2687 case FONT_ITALIC:
2688 case FONT_OUTLINE:
2689 case FONT_PROTECTED:
2690 case FONT_SHADOW:
2691 case FONT_SMALLCAPS:
2692 case FONT_STRIKETHROUGH:
2693 case FONT_SUBSCRIPT:
2694 case FONT_SUPERSCRIPT:
2695 case FONT_UNDERLINE:
2696 font->props[id].l = tomFalse;
2697 break;
2698 case FONT_BACKCOLOR:
2699 case FONT_FORECOLOR:
2700 font->props[id].l = tomAutoColor;
2701 break;
2702 case FONT_KERNING:
2703 case FONT_POSITION:
2704 case FONT_SIZE:
2705 case FONT_SPACING:
2706 font->props[id].f = 0.0;
2707 break;
2708 case FONT_LANGID:
2709 font->props[id].l = GetSystemDefaultLCID();
2710 break;
2711 case FONT_NAME: {
2712 static const WCHAR sysW[] = {'S','y','s','t','e','m',0};
2713 SysFreeString(font->props[id].str);
2714 font->props[id].str = SysAllocString(sysW);
2715 break;
2717 case FONT_WEIGHT:
2718 font->props[id].l = FW_NORMAL;
2719 break;
2720 default:
2721 FIXME("font property %d not handled\n", id);
2726 static void textfont_reset_to_undefined(ITextFontImpl *font)
2728 enum textfont_prop_id id;
2730 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2731 switch (id)
2733 case FONT_ALLCAPS:
2734 case FONT_ANIMATION:
2735 case FONT_BOLD:
2736 case FONT_EMBOSS:
2737 case FONT_HIDDEN:
2738 case FONT_ENGRAVE:
2739 case FONT_ITALIC:
2740 case FONT_OUTLINE:
2741 case FONT_PROTECTED:
2742 case FONT_SHADOW:
2743 case FONT_SMALLCAPS:
2744 case FONT_STRIKETHROUGH:
2745 case FONT_SUBSCRIPT:
2746 case FONT_SUPERSCRIPT:
2747 case FONT_UNDERLINE:
2748 case FONT_BACKCOLOR:
2749 case FONT_FORECOLOR:
2750 case FONT_LANGID:
2751 case FONT_WEIGHT:
2752 font->props[id].l = tomUndefined;
2753 break;
2754 case FONT_KERNING:
2755 case FONT_POSITION:
2756 case FONT_SIZE:
2757 case FONT_SPACING:
2758 font->props[id].f = tomUndefined;
2759 break;
2760 case FONT_NAME:
2761 break;
2762 default:
2763 FIXME("font property %d not handled\n", id);
2768 static void textfont_apply_range_props(ITextFontImpl *font)
2770 enum textfont_prop_id propid;
2771 for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++)
2772 set_textfont_prop(font, propid, &font->props[propid]);
2775 static HRESULT WINAPI TextFont_Reset(ITextFont *iface, LONG value)
2777 ITextFontImpl *This = impl_from_ITextFont(iface);
2779 TRACE("(%p)->(%d)\n", This, value);
2781 /* If font is attached to a range, released or not, we can't
2782 reset to undefined */
2783 if (This->range) {
2784 if (!get_range_reole(This->range))
2785 return CO_E_RELEASED;
2787 switch (value)
2789 case tomUndefined:
2790 return E_INVALIDARG;
2791 case tomCacheParms:
2792 textfont_cache_range_props(This);
2793 This->get_cache_enabled = TRUE;
2794 break;
2795 case tomTrackParms:
2796 This->get_cache_enabled = FALSE;
2797 break;
2798 case tomApplyLater:
2799 This->set_cache_enabled = TRUE;
2800 break;
2801 case tomApplyNow:
2802 This->set_cache_enabled = FALSE;
2803 textfont_apply_range_props(This);
2804 break;
2805 case tomUsePoints:
2806 case tomUseTwips:
2807 return E_INVALIDARG;
2808 default:
2809 FIXME("reset mode %d not supported\n", value);
2812 return S_OK;
2814 else {
2815 switch (value)
2817 /* reset to global defaults */
2818 case tomDefault:
2819 textfont_reset_to_default(This);
2820 return S_OK;
2821 /* all properties are set to tomUndefined, font name is retained */
2822 case tomUndefined:
2823 textfont_reset_to_undefined(This);
2824 return S_OK;
2825 case tomApplyNow:
2826 case tomApplyLater:
2827 case tomTrackParms:
2828 case tomCacheParms:
2829 return S_OK;
2830 case tomUsePoints:
2831 case tomUseTwips:
2832 return E_INVALIDARG;
2836 FIXME("reset mode %d not supported\n", value);
2837 return E_NOTIMPL;
2840 static HRESULT WINAPI TextFont_GetStyle(ITextFont *iface, LONG *value)
2842 ITextFontImpl *This = impl_from_ITextFont(iface);
2843 FIXME("(%p)->(%p): stub\n", This, value);
2844 return E_NOTIMPL;
2847 static HRESULT WINAPI TextFont_SetStyle(ITextFont *iface, LONG value)
2849 ITextFontImpl *This = impl_from_ITextFont(iface);
2850 FIXME("(%p)->(%d): stub\n", This, value);
2851 return E_NOTIMPL;
2854 static HRESULT WINAPI TextFont_GetAllCaps(ITextFont *iface, LONG *value)
2856 ITextFontImpl *This = impl_from_ITextFont(iface);
2857 TRACE("(%p)->(%p)\n", This, value);
2858 return get_textfont_propl(This, FONT_ALLCAPS, value);
2861 static HRESULT WINAPI TextFont_SetAllCaps(ITextFont *iface, LONG value)
2863 ITextFontImpl *This = impl_from_ITextFont(iface);
2864 TRACE("(%p)->(%d)\n", This, value);
2865 return set_textfont_propd(This, FONT_ALLCAPS, value);
2868 static HRESULT WINAPI TextFont_GetAnimation(ITextFont *iface, LONG *value)
2870 ITextFontImpl *This = impl_from_ITextFont(iface);
2871 TRACE("(%p)->(%p)\n", This, value);
2872 return get_textfont_propl(This, FONT_ANIMATION, value);
2875 static HRESULT WINAPI TextFont_SetAnimation(ITextFont *iface, LONG value)
2877 ITextFontImpl *This = impl_from_ITextFont(iface);
2879 TRACE("(%p)->(%d)\n", This, value);
2881 if (value < tomNoAnimation || value > tomAnimationMax)
2882 return E_INVALIDARG;
2884 return set_textfont_propl(This, FONT_ANIMATION, value);
2887 static HRESULT WINAPI TextFont_GetBackColor(ITextFont *iface, LONG *value)
2889 ITextFontImpl *This = impl_from_ITextFont(iface);
2890 TRACE("(%p)->(%p)\n", This, value);
2891 return get_textfont_propl(This, FONT_BACKCOLOR, value);
2894 static HRESULT WINAPI TextFont_SetBackColor(ITextFont *iface, LONG value)
2896 ITextFontImpl *This = impl_from_ITextFont(iface);
2897 TRACE("(%p)->(%d)\n", This, value);
2898 return set_textfont_propl(This, FONT_BACKCOLOR, value);
2901 static HRESULT WINAPI TextFont_GetBold(ITextFont *iface, LONG *value)
2903 ITextFontImpl *This = impl_from_ITextFont(iface);
2904 TRACE("(%p)->(%p)\n", This, value);
2905 return get_textfont_propl(This, FONT_BOLD, value);
2908 static HRESULT WINAPI TextFont_SetBold(ITextFont *iface, LONG value)
2910 ITextFontImpl *This = impl_from_ITextFont(iface);
2911 TRACE("(%p)->(%d)\n", This, value);
2912 return set_textfont_propd(This, FONT_BOLD, value);
2915 static HRESULT WINAPI TextFont_GetEmboss(ITextFont *iface, LONG *value)
2917 ITextFontImpl *This = impl_from_ITextFont(iface);
2918 TRACE("(%p)->(%p)\n", This, value);
2919 return get_textfont_propl(This, FONT_EMBOSS, value);
2922 static HRESULT WINAPI TextFont_SetEmboss(ITextFont *iface, LONG value)
2924 ITextFontImpl *This = impl_from_ITextFont(iface);
2925 TRACE("(%p)->(%d)\n", This, value);
2926 return set_textfont_propd(This, FONT_EMBOSS, value);
2929 static HRESULT WINAPI TextFont_GetForeColor(ITextFont *iface, LONG *value)
2931 ITextFontImpl *This = impl_from_ITextFont(iface);
2932 TRACE("(%p)->(%p)\n", This, value);
2933 return get_textfont_propl(This, FONT_FORECOLOR, value);
2936 static HRESULT WINAPI TextFont_SetForeColor(ITextFont *iface, LONG value)
2938 ITextFontImpl *This = impl_from_ITextFont(iface);
2939 TRACE("(%p)->(%d)\n", This, value);
2940 return set_textfont_propl(This, FONT_FORECOLOR, value);
2943 static HRESULT WINAPI TextFont_GetHidden(ITextFont *iface, LONG *value)
2945 ITextFontImpl *This = impl_from_ITextFont(iface);
2946 TRACE("(%p)->(%p)\n", This, value);
2947 return get_textfont_propl(This, FONT_HIDDEN, value);
2950 static HRESULT WINAPI TextFont_SetHidden(ITextFont *iface, LONG value)
2952 ITextFontImpl *This = impl_from_ITextFont(iface);
2953 TRACE("(%p)->(%d)\n", This, value);
2954 return set_textfont_propd(This, FONT_HIDDEN, value);
2957 static HRESULT WINAPI TextFont_GetEngrave(ITextFont *iface, LONG *value)
2959 ITextFontImpl *This = impl_from_ITextFont(iface);
2960 TRACE("(%p)->(%p)\n", This, value);
2961 return get_textfont_propl(This, FONT_ENGRAVE, value);
2964 static HRESULT WINAPI TextFont_SetEngrave(ITextFont *iface, LONG value)
2966 ITextFontImpl *This = impl_from_ITextFont(iface);
2967 TRACE("(%p)->(%d)\n", This, value);
2968 return set_textfont_propd(This, FONT_ENGRAVE, value);
2971 static HRESULT WINAPI TextFont_GetItalic(ITextFont *iface, LONG *value)
2973 ITextFontImpl *This = impl_from_ITextFont(iface);
2974 TRACE("(%p)->(%p)\n", This, value);
2975 return get_textfont_propl(This, FONT_ITALIC, value);
2978 static HRESULT WINAPI TextFont_SetItalic(ITextFont *iface, LONG value)
2980 ITextFontImpl *This = impl_from_ITextFont(iface);
2981 TRACE("(%p)->(%d)\n", This, value);
2982 return set_textfont_propd(This, FONT_ITALIC, value);
2985 static HRESULT WINAPI TextFont_GetKerning(ITextFont *iface, FLOAT *value)
2987 ITextFontImpl *This = impl_from_ITextFont(iface);
2988 TRACE("(%p)->(%p)\n", This, value);
2989 return get_textfont_propf(This, FONT_KERNING, value);
2992 static HRESULT WINAPI TextFont_SetKerning(ITextFont *iface, FLOAT value)
2994 ITextFontImpl *This = impl_from_ITextFont(iface);
2995 TRACE("(%p)->(%.2f)\n", This, value);
2996 return set_textfont_propf(This, FONT_KERNING, value);
2999 static HRESULT WINAPI TextFont_GetLanguageID(ITextFont *iface, LONG *value)
3001 ITextFontImpl *This = impl_from_ITextFont(iface);
3002 TRACE("(%p)->(%p)\n", This, value);
3003 return get_textfont_propl(This, FONT_LANGID, value);
3006 static HRESULT WINAPI TextFont_SetLanguageID(ITextFont *iface, LONG value)
3008 ITextFontImpl *This = impl_from_ITextFont(iface);
3009 TRACE("(%p)->(%d)\n", This, value);
3010 return set_textfont_propl(This, FONT_LANGID, value);
3013 static HRESULT WINAPI TextFont_GetName(ITextFont *iface, BSTR *value)
3015 ITextFontImpl *This = impl_from_ITextFont(iface);
3017 TRACE("(%p)->(%p)\n", This, value);
3019 if (!value)
3020 return E_INVALIDARG;
3022 *value = NULL;
3024 if (!This->range) {
3025 if (This->props[FONT_NAME].str)
3026 *value = SysAllocString(This->props[FONT_NAME].str);
3027 else
3028 *value = SysAllocStringLen(NULL, 0);
3029 return *value ? S_OK : E_OUTOFMEMORY;
3032 return textfont_getname_from_range(This->range, value);
3035 static HRESULT WINAPI TextFont_SetName(ITextFont *iface, BSTR value)
3037 ITextFontImpl *This = impl_from_ITextFont(iface);
3038 textfont_prop_val v;
3040 TRACE("(%p)->(%s)\n", This, debugstr_w(value));
3042 v.str = value;
3043 return set_textfont_prop(This, FONT_NAME, &v);
3046 static HRESULT WINAPI TextFont_GetOutline(ITextFont *iface, LONG *value)
3048 ITextFontImpl *This = impl_from_ITextFont(iface);
3049 TRACE("(%p)->(%p)\n", This, value);
3050 return get_textfont_propl(This, FONT_OUTLINE, value);
3053 static HRESULT WINAPI TextFont_SetOutline(ITextFont *iface, LONG value)
3055 ITextFontImpl *This = impl_from_ITextFont(iface);
3056 TRACE("(%p)->(%d)\n", This, value);
3057 return set_textfont_propd(This, FONT_OUTLINE, value);
3060 static HRESULT WINAPI TextFont_GetPosition(ITextFont *iface, FLOAT *value)
3062 ITextFontImpl *This = impl_from_ITextFont(iface);
3063 TRACE("(%p)->(%p)\n", This, value);
3064 return get_textfont_propf(This, FONT_POSITION, value);
3067 static HRESULT WINAPI TextFont_SetPosition(ITextFont *iface, FLOAT value)
3069 ITextFontImpl *This = impl_from_ITextFont(iface);
3070 TRACE("(%p)->(%.2f)\n", This, value);
3071 return set_textfont_propf(This, FONT_POSITION, value);
3074 static HRESULT WINAPI TextFont_GetProtected(ITextFont *iface, LONG *value)
3076 ITextFontImpl *This = impl_from_ITextFont(iface);
3077 TRACE("(%p)->(%p)\n", This, value);
3078 return get_textfont_propl(This, FONT_PROTECTED, value);
3081 static HRESULT WINAPI TextFont_SetProtected(ITextFont *iface, LONG value)
3083 ITextFontImpl *This = impl_from_ITextFont(iface);
3084 TRACE("(%p)->(%d)\n", This, value);
3085 return set_textfont_propd(This, FONT_PROTECTED, value);
3088 static HRESULT WINAPI TextFont_GetShadow(ITextFont *iface, LONG *value)
3090 ITextFontImpl *This = impl_from_ITextFont(iface);
3091 TRACE("(%p)->(%p)\n", This, value);
3092 return get_textfont_propl(This, FONT_SHADOW, value);
3095 static HRESULT WINAPI TextFont_SetShadow(ITextFont *iface, LONG value)
3097 ITextFontImpl *This = impl_from_ITextFont(iface);
3098 TRACE("(%p)->(%d)\n", This, value);
3099 return set_textfont_propd(This, FONT_SHADOW, value);
3102 static HRESULT WINAPI TextFont_GetSize(ITextFont *iface, FLOAT *value)
3104 ITextFontImpl *This = impl_from_ITextFont(iface);
3105 TRACE("(%p)->(%p)\n", This, value);
3106 return get_textfont_propf(This, FONT_SIZE, value);
3109 static HRESULT WINAPI TextFont_SetSize(ITextFont *iface, FLOAT value)
3111 ITextFontImpl *This = impl_from_ITextFont(iface);
3112 TRACE("(%p)->(%.2f)\n", This, value);
3113 return set_textfont_propf(This, FONT_SIZE, value);
3116 static HRESULT WINAPI TextFont_GetSmallCaps(ITextFont *iface, LONG *value)
3118 ITextFontImpl *This = impl_from_ITextFont(iface);
3119 TRACE("(%p)->(%p)\n", This, value);
3120 return get_textfont_propl(This, FONT_SMALLCAPS, value);
3123 static HRESULT WINAPI TextFont_SetSmallCaps(ITextFont *iface, LONG value)
3125 ITextFontImpl *This = impl_from_ITextFont(iface);
3126 TRACE("(%p)->(%d)\n", This, value);
3127 return set_textfont_propd(This, FONT_SMALLCAPS, value);
3130 static HRESULT WINAPI TextFont_GetSpacing(ITextFont *iface, FLOAT *value)
3132 ITextFontImpl *This = impl_from_ITextFont(iface);
3133 TRACE("(%p)->(%p)\n", This, value);
3134 return get_textfont_propf(This, FONT_SPACING, value);
3137 static HRESULT WINAPI TextFont_SetSpacing(ITextFont *iface, FLOAT value)
3139 ITextFontImpl *This = impl_from_ITextFont(iface);
3140 TRACE("(%p)->(%.2f)\n", This, value);
3141 return set_textfont_propf(This, FONT_SPACING, value);
3144 static HRESULT WINAPI TextFont_GetStrikeThrough(ITextFont *iface, LONG *value)
3146 ITextFontImpl *This = impl_from_ITextFont(iface);
3147 TRACE("(%p)->(%p)\n", This, value);
3148 return get_textfont_propl(This, FONT_STRIKETHROUGH, value);
3151 static HRESULT WINAPI TextFont_SetStrikeThrough(ITextFont *iface, LONG value)
3153 ITextFontImpl *This = impl_from_ITextFont(iface);
3154 TRACE("(%p)->(%d)\n", This, value);
3155 return set_textfont_propd(This, FONT_STRIKETHROUGH, value);
3158 static HRESULT WINAPI TextFont_GetSubscript(ITextFont *iface, LONG *value)
3160 ITextFontImpl *This = impl_from_ITextFont(iface);
3161 TRACE("(%p)->(%p)\n", This, value);
3162 return get_textfont_propl(This, FONT_SUBSCRIPT, value);
3165 static HRESULT WINAPI TextFont_SetSubscript(ITextFont *iface, LONG value)
3167 ITextFontImpl *This = impl_from_ITextFont(iface);
3168 TRACE("(%p)->(%d)\n", This, value);
3169 return set_textfont_propd(This, FONT_SUBSCRIPT, value);
3172 static HRESULT WINAPI TextFont_GetSuperscript(ITextFont *iface, LONG *value)
3174 ITextFontImpl *This = impl_from_ITextFont(iface);
3175 TRACE("(%p)->(%p)\n", This, value);
3176 return get_textfont_propl(This, FONT_SUPERSCRIPT, value);
3179 static HRESULT WINAPI TextFont_SetSuperscript(ITextFont *iface, LONG value)
3181 ITextFontImpl *This = impl_from_ITextFont(iface);
3182 TRACE("(%p)->(%d)\n", This, value);
3183 return set_textfont_propd(This, FONT_SUPERSCRIPT, value);
3186 static HRESULT WINAPI TextFont_GetUnderline(ITextFont *iface, LONG *value)
3188 ITextFontImpl *This = impl_from_ITextFont(iface);
3189 TRACE("(%p)->(%p)\n", This, value);
3190 return get_textfont_propl(This, FONT_UNDERLINE, value);
3193 static HRESULT WINAPI TextFont_SetUnderline(ITextFont *iface, LONG value)
3195 ITextFontImpl *This = impl_from_ITextFont(iface);
3196 TRACE("(%p)->(%d)\n", This, value);
3197 return set_textfont_propd(This, FONT_UNDERLINE, value);
3200 static HRESULT WINAPI TextFont_GetWeight(ITextFont *iface, LONG *value)
3202 ITextFontImpl *This = impl_from_ITextFont(iface);
3203 TRACE("(%p)->(%p)\n", This, value);
3204 return get_textfont_propl(This, FONT_WEIGHT, value);
3207 static HRESULT WINAPI TextFont_SetWeight(ITextFont *iface, LONG value)
3209 ITextFontImpl *This = impl_from_ITextFont(iface);
3210 TRACE("(%p)->(%d)\n", This, value);
3211 return set_textfont_propl(This, FONT_WEIGHT, value);
3214 static ITextFontVtbl textfontvtbl = {
3215 TextFont_QueryInterface,
3216 TextFont_AddRef,
3217 TextFont_Release,
3218 TextFont_GetTypeInfoCount,
3219 TextFont_GetTypeInfo,
3220 TextFont_GetIDsOfNames,
3221 TextFont_Invoke,
3222 TextFont_GetDuplicate,
3223 TextFont_SetDuplicate,
3224 TextFont_CanChange,
3225 TextFont_IsEqual,
3226 TextFont_Reset,
3227 TextFont_GetStyle,
3228 TextFont_SetStyle,
3229 TextFont_GetAllCaps,
3230 TextFont_SetAllCaps,
3231 TextFont_GetAnimation,
3232 TextFont_SetAnimation,
3233 TextFont_GetBackColor,
3234 TextFont_SetBackColor,
3235 TextFont_GetBold,
3236 TextFont_SetBold,
3237 TextFont_GetEmboss,
3238 TextFont_SetEmboss,
3239 TextFont_GetForeColor,
3240 TextFont_SetForeColor,
3241 TextFont_GetHidden,
3242 TextFont_SetHidden,
3243 TextFont_GetEngrave,
3244 TextFont_SetEngrave,
3245 TextFont_GetItalic,
3246 TextFont_SetItalic,
3247 TextFont_GetKerning,
3248 TextFont_SetKerning,
3249 TextFont_GetLanguageID,
3250 TextFont_SetLanguageID,
3251 TextFont_GetName,
3252 TextFont_SetName,
3253 TextFont_GetOutline,
3254 TextFont_SetOutline,
3255 TextFont_GetPosition,
3256 TextFont_SetPosition,
3257 TextFont_GetProtected,
3258 TextFont_SetProtected,
3259 TextFont_GetShadow,
3260 TextFont_SetShadow,
3261 TextFont_GetSize,
3262 TextFont_SetSize,
3263 TextFont_GetSmallCaps,
3264 TextFont_SetSmallCaps,
3265 TextFont_GetSpacing,
3266 TextFont_SetSpacing,
3267 TextFont_GetStrikeThrough,
3268 TextFont_SetStrikeThrough,
3269 TextFont_GetSubscript,
3270 TextFont_SetSubscript,
3271 TextFont_GetSuperscript,
3272 TextFont_SetSuperscript,
3273 TextFont_GetUnderline,
3274 TextFont_SetUnderline,
3275 TextFont_GetWeight,
3276 TextFont_SetWeight
3279 static HRESULT create_textfont(ITextRange *range, const ITextFontImpl *src, ITextFont **ret)
3281 ITextFontImpl *font;
3283 *ret = NULL;
3284 font = heap_alloc(sizeof(*font));
3285 if (!font)
3286 return E_OUTOFMEMORY;
3288 font->ITextFont_iface.lpVtbl = &textfontvtbl;
3289 font->ref = 1;
3291 if (src) {
3292 font->range = NULL;
3293 font->get_cache_enabled = TRUE;
3294 font->set_cache_enabled = TRUE;
3295 memcpy(&font->props, &src->props, sizeof(font->props));
3296 if (font->props[FONT_NAME].str)
3297 font->props[FONT_NAME].str = SysAllocString(font->props[FONT_NAME].str);
3299 else {
3300 font->range = range;
3301 ITextRange_AddRef(range);
3303 /* cache current properties */
3304 font->get_cache_enabled = FALSE;
3305 font->set_cache_enabled = FALSE;
3306 textfont_cache_range_props(font);
3309 *ret = &font->ITextFont_iface;
3310 return S_OK;
3313 /* ITextPara */
3314 static HRESULT WINAPI TextPara_QueryInterface(ITextPara *iface, REFIID riid, void **ppv)
3316 ITextParaImpl *This = impl_from_ITextPara(iface);
3318 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
3320 if (IsEqualIID(riid, &IID_ITextPara) ||
3321 IsEqualIID(riid, &IID_IDispatch) ||
3322 IsEqualIID(riid, &IID_IUnknown))
3324 *ppv = iface;
3325 ITextPara_AddRef(iface);
3326 return S_OK;
3329 *ppv = NULL;
3330 return E_NOINTERFACE;
3333 static ULONG WINAPI TextPara_AddRef(ITextPara *iface)
3335 ITextParaImpl *This = impl_from_ITextPara(iface);
3336 ULONG ref = InterlockedIncrement(&This->ref);
3337 TRACE("(%p)->(%u)\n", This, ref);
3338 return ref;
3341 static ULONG WINAPI TextPara_Release(ITextPara *iface)
3343 ITextParaImpl *This = impl_from_ITextPara(iface);
3344 ULONG ref = InterlockedDecrement(&This->ref);
3346 TRACE("(%p)->(%u)\n", This, ref);
3348 if (!ref)
3350 ITextRange_Release(This->range);
3351 heap_free(This);
3354 return ref;
3357 static HRESULT WINAPI TextPara_GetTypeInfoCount(ITextPara *iface, UINT *pctinfo)
3359 ITextParaImpl *This = impl_from_ITextPara(iface);
3360 TRACE("(%p)->(%p)\n", This, pctinfo);
3361 *pctinfo = 1;
3362 return S_OK;
3365 static HRESULT WINAPI TextPara_GetTypeInfo(ITextPara *iface, UINT iTInfo, LCID lcid,
3366 ITypeInfo **ppTInfo)
3368 ITextParaImpl *This = impl_from_ITextPara(iface);
3369 HRESULT hr;
3371 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
3373 hr = get_typeinfo(ITextPara_tid, ppTInfo);
3374 if (SUCCEEDED(hr))
3375 ITypeInfo_AddRef(*ppTInfo);
3376 return hr;
3379 static HRESULT WINAPI TextPara_GetIDsOfNames(ITextPara *iface, REFIID riid,
3380 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
3382 ITextParaImpl *This = impl_from_ITextPara(iface);
3383 ITypeInfo *ti;
3384 HRESULT hr;
3386 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames,
3387 cNames, lcid, rgDispId);
3389 hr = get_typeinfo(ITextPara_tid, &ti);
3390 if (SUCCEEDED(hr))
3391 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
3392 return hr;
3395 static HRESULT WINAPI TextPara_Invoke(
3396 ITextPara *iface,
3397 DISPID dispIdMember,
3398 REFIID riid,
3399 LCID lcid,
3400 WORD wFlags,
3401 DISPPARAMS *pDispParams,
3402 VARIANT *pVarResult,
3403 EXCEPINFO *pExcepInfo,
3404 UINT *puArgErr)
3406 ITextParaImpl *This = impl_from_ITextPara(iface);
3407 ITypeInfo *ti;
3408 HRESULT hr;
3410 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember,
3411 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
3412 pExcepInfo, puArgErr);
3414 hr = get_typeinfo(ITextPara_tid, &ti);
3415 if (SUCCEEDED(hr))
3416 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3417 return hr;
3420 static HRESULT WINAPI TextPara_GetDuplicate(ITextPara *iface, ITextPara **ret)
3422 ITextParaImpl *This = impl_from_ITextPara(iface);
3423 FIXME("(%p)->(%p)\n", This, ret);
3424 return E_NOTIMPL;
3427 static HRESULT WINAPI TextPara_SetDuplicate(ITextPara *iface, ITextPara *para)
3429 ITextParaImpl *This = impl_from_ITextPara(iface);
3430 FIXME("(%p)->(%p)\n", This, para);
3431 return E_NOTIMPL;
3434 static HRESULT WINAPI TextPara_CanChange(ITextPara *iface, LONG *ret)
3436 ITextParaImpl *This = impl_from_ITextPara(iface);
3437 FIXME("(%p)->(%p)\n", This, ret);
3438 return E_NOTIMPL;
3441 static HRESULT WINAPI TextPara_IsEqual(ITextPara *iface, ITextPara *para, LONG *ret)
3443 ITextParaImpl *This = impl_from_ITextPara(iface);
3444 FIXME("(%p)->(%p %p)\n", This, para, ret);
3445 return E_NOTIMPL;
3448 static HRESULT WINAPI TextPara_Reset(ITextPara *iface, LONG value)
3450 ITextParaImpl *This = impl_from_ITextPara(iface);
3451 FIXME("(%p)->(%d)\n", This, value);
3452 return E_NOTIMPL;
3455 static HRESULT WINAPI TextPara_GetStyle(ITextPara *iface, LONG *value)
3457 ITextParaImpl *This = impl_from_ITextPara(iface);
3458 FIXME("(%p)->(%p)\n", This, value);
3459 return E_NOTIMPL;
3462 static HRESULT WINAPI TextPara_SetStyle(ITextPara *iface, LONG value)
3464 ITextParaImpl *This = impl_from_ITextPara(iface);
3465 FIXME("(%p)->(%d)\n", This, value);
3466 return E_NOTIMPL;
3469 static HRESULT WINAPI TextPara_GetAlignment(ITextPara *iface, LONG *value)
3471 ITextParaImpl *This = impl_from_ITextPara(iface);
3472 FIXME("(%p)->(%p)\n", This, value);
3473 return E_NOTIMPL;
3476 static HRESULT WINAPI TextPara_SetAlignment(ITextPara *iface, LONG value)
3478 ITextParaImpl *This = impl_from_ITextPara(iface);
3479 FIXME("(%p)->(%d)\n", This, value);
3480 return E_NOTIMPL;
3483 static HRESULT WINAPI TextPara_GetHyphenation(ITextPara *iface, LONG *value)
3485 ITextParaImpl *This = impl_from_ITextPara(iface);
3486 FIXME("(%p)->(%p)\n", This, value);
3487 return E_NOTIMPL;
3490 static HRESULT WINAPI TextPara_SetHyphenation(ITextPara *iface, LONG value)
3492 ITextParaImpl *This = impl_from_ITextPara(iface);
3493 FIXME("(%p)->(%d)\n", This, value);
3494 return E_NOTIMPL;
3497 static HRESULT WINAPI TextPara_GetFirstLineIndent(ITextPara *iface, FLOAT *value)
3499 ITextParaImpl *This = impl_from_ITextPara(iface);
3500 FIXME("(%p)->(%p)\n", This, value);
3501 return E_NOTIMPL;
3504 static HRESULT WINAPI TextPara_GetKeepTogether(ITextPara *iface, LONG *value)
3506 ITextParaImpl *This = impl_from_ITextPara(iface);
3507 FIXME("(%p)->(%p)\n", This, value);
3508 return E_NOTIMPL;
3511 static HRESULT WINAPI TextPara_SetKeepTogether(ITextPara *iface, LONG value)
3513 ITextParaImpl *This = impl_from_ITextPara(iface);
3514 FIXME("(%p)->(%d)\n", This, value);
3515 return E_NOTIMPL;
3518 static HRESULT WINAPI TextPara_GetKeepWithNext(ITextPara *iface, LONG *value)
3520 ITextParaImpl *This = impl_from_ITextPara(iface);
3521 FIXME("(%p)->(%p)\n", This, value);
3522 return E_NOTIMPL;
3525 static HRESULT WINAPI TextPara_SetKeepWithNext(ITextPara *iface, LONG value)
3527 ITextParaImpl *This = impl_from_ITextPara(iface);
3528 FIXME("(%p)->(%d)\n", This, value);
3529 return E_NOTIMPL;
3532 static HRESULT WINAPI TextPara_GetLeftIndent(ITextPara *iface, FLOAT *value)
3534 ITextParaImpl *This = impl_from_ITextPara(iface);
3535 FIXME("(%p)->(%p)\n", This, value);
3536 return E_NOTIMPL;
3539 static HRESULT WINAPI TextPara_GetLineSpacing(ITextPara *iface, FLOAT *value)
3541 ITextParaImpl *This = impl_from_ITextPara(iface);
3542 FIXME("(%p)->(%p)\n", This, value);
3543 return E_NOTIMPL;
3546 static HRESULT WINAPI TextPara_GetLineSpacingRule(ITextPara *iface, LONG *value)
3548 ITextParaImpl *This = impl_from_ITextPara(iface);
3549 FIXME("(%p)->(%p)\n", This, value);
3550 return E_NOTIMPL;
3553 static HRESULT WINAPI TextPara_GetListAlignment(ITextPara *iface, LONG *value)
3555 ITextParaImpl *This = impl_from_ITextPara(iface);
3556 FIXME("(%p)->(%p)\n", This, value);
3557 return E_NOTIMPL;
3560 static HRESULT WINAPI TextPara_SetListAlignment(ITextPara *iface, LONG value)
3562 ITextParaImpl *This = impl_from_ITextPara(iface);
3563 FIXME("(%p)->(%d)\n", This, value);
3564 return E_NOTIMPL;
3567 static HRESULT WINAPI TextPara_GetListLevelIndex(ITextPara *iface, LONG *value)
3569 ITextParaImpl *This = impl_from_ITextPara(iface);
3570 FIXME("(%p)->(%p)\n", This, value);
3571 return E_NOTIMPL;
3574 static HRESULT WINAPI TextPara_SetListLevelIndex(ITextPara *iface, LONG value)
3576 ITextParaImpl *This = impl_from_ITextPara(iface);
3577 FIXME("(%p)->(%d)\n", This, value);
3578 return E_NOTIMPL;
3581 static HRESULT WINAPI TextPara_GetListStart(ITextPara *iface, LONG *value)
3583 ITextParaImpl *This = impl_from_ITextPara(iface);
3584 FIXME("(%p)->(%p)\n", This, value);
3585 return E_NOTIMPL;
3588 static HRESULT WINAPI TextPara_SetListStart(ITextPara *iface, LONG value)
3590 ITextParaImpl *This = impl_from_ITextPara(iface);
3591 FIXME("(%p)->(%d)\n", This, value);
3592 return E_NOTIMPL;
3595 static HRESULT WINAPI TextPara_GetListTab(ITextPara *iface, FLOAT *value)
3597 ITextParaImpl *This = impl_from_ITextPara(iface);
3598 FIXME("(%p)->(%p)\n", This, value);
3599 return E_NOTIMPL;
3602 static HRESULT WINAPI TextPara_SetListTab(ITextPara *iface, FLOAT value)
3604 ITextParaImpl *This = impl_from_ITextPara(iface);
3605 FIXME("(%p)->(%.2f)\n", This, value);
3606 return E_NOTIMPL;
3609 static HRESULT WINAPI TextPara_GetListType(ITextPara *iface, LONG *value)
3611 ITextParaImpl *This = impl_from_ITextPara(iface);
3612 FIXME("(%p)->(%p)\n", This, value);
3613 return E_NOTIMPL;
3616 static HRESULT WINAPI TextPara_SetListType(ITextPara *iface, LONG value)
3618 ITextParaImpl *This = impl_from_ITextPara(iface);
3619 FIXME("(%p)->(%d)\n", This, value);
3620 return E_NOTIMPL;
3623 static HRESULT WINAPI TextPara_GetNoLineNumber(ITextPara *iface, LONG *value)
3625 ITextParaImpl *This = impl_from_ITextPara(iface);
3626 FIXME("(%p)->(%p)\n", This, value);
3627 return E_NOTIMPL;
3630 static HRESULT WINAPI TextPara_SetNoLineNumber(ITextPara *iface, LONG value)
3632 ITextParaImpl *This = impl_from_ITextPara(iface);
3633 FIXME("(%p)->(%d)\n", This, value);
3634 return E_NOTIMPL;
3637 static HRESULT WINAPI TextPara_GetPageBreakBefore(ITextPara *iface, LONG *value)
3639 ITextParaImpl *This = impl_from_ITextPara(iface);
3640 FIXME("(%p)->(%p)\n", This, value);
3641 return E_NOTIMPL;
3644 static HRESULT WINAPI TextPara_SetPageBreakBefore(ITextPara *iface, LONG value)
3646 ITextParaImpl *This = impl_from_ITextPara(iface);
3647 FIXME("(%p)->(%d)\n", This, value);
3648 return E_NOTIMPL;
3651 static HRESULT WINAPI TextPara_GetRightIndent(ITextPara *iface, FLOAT *value)
3653 ITextParaImpl *This = impl_from_ITextPara(iface);
3654 FIXME("(%p)->(%p)\n", This, value);
3655 return E_NOTIMPL;
3658 static HRESULT WINAPI TextPara_SetRightIndent(ITextPara *iface, FLOAT value)
3660 ITextParaImpl *This = impl_from_ITextPara(iface);
3661 FIXME("(%p)->(%.2f)\n", This, value);
3662 return E_NOTIMPL;
3665 static HRESULT WINAPI TextPara_SetIndents(ITextPara *iface, FLOAT StartIndent, FLOAT LeftIndent, FLOAT RightIndent)
3667 ITextParaImpl *This = impl_from_ITextPara(iface);
3668 FIXME("(%p)->(%.2f %.2f %.2f)\n", This, StartIndent, LeftIndent, RightIndent);
3669 return E_NOTIMPL;
3672 static HRESULT WINAPI TextPara_SetLineSpacing(ITextPara *iface, LONG LineSpacingRule, FLOAT LineSpacing)
3674 ITextParaImpl *This = impl_from_ITextPara(iface);
3675 FIXME("(%p)->(%d %.2f)\n", This, LineSpacingRule, LineSpacing);
3676 return E_NOTIMPL;
3679 static HRESULT WINAPI TextPara_GetSpaceAfter(ITextPara *iface, FLOAT *value)
3681 ITextParaImpl *This = impl_from_ITextPara(iface);
3682 FIXME("(%p)->(%p)\n", This, value);
3683 return E_NOTIMPL;
3686 static HRESULT WINAPI TextPara_SetSpaceAfter(ITextPara *iface, FLOAT value)
3688 ITextParaImpl *This = impl_from_ITextPara(iface);
3689 FIXME("(%p)->(%.2f)\n", This, value);
3690 return E_NOTIMPL;
3693 static HRESULT WINAPI TextPara_GetSpaceBefore(ITextPara *iface, FLOAT *value)
3695 ITextParaImpl *This = impl_from_ITextPara(iface);
3696 FIXME("(%p)->(%p)\n", This, value);
3697 return E_NOTIMPL;
3700 static HRESULT WINAPI TextPara_SetSpaceBefore(ITextPara *iface, FLOAT value)
3702 ITextParaImpl *This = impl_from_ITextPara(iface);
3703 FIXME("(%p)->(%.2f)\n", This, value);
3704 return E_NOTIMPL;
3707 static HRESULT WINAPI TextPara_GetWidowControl(ITextPara *iface, LONG *value)
3709 ITextParaImpl *This = impl_from_ITextPara(iface);
3710 FIXME("(%p)->(%p)\n", This, value);
3711 return E_NOTIMPL;
3714 static HRESULT WINAPI TextPara_SetWidowControl(ITextPara *iface, LONG value)
3716 ITextParaImpl *This = impl_from_ITextPara(iface);
3717 FIXME("(%p)->(%d)\n", This, value);
3718 return E_NOTIMPL;
3721 static HRESULT WINAPI TextPara_GetTabCount(ITextPara *iface, LONG *value)
3723 ITextParaImpl *This = impl_from_ITextPara(iface);
3724 FIXME("(%p)->(%p)\n", This, value);
3725 return E_NOTIMPL;
3728 static HRESULT WINAPI TextPara_AddTab(ITextPara *iface, FLOAT tbPos, LONG tbAlign, LONG tbLeader)
3730 ITextParaImpl *This = impl_from_ITextPara(iface);
3731 FIXME("(%p)->(%.2f %d %d)\n", This, tbPos, tbAlign, tbLeader);
3732 return E_NOTIMPL;
3735 static HRESULT WINAPI TextPara_ClearAllTabs(ITextPara *iface)
3737 ITextParaImpl *This = impl_from_ITextPara(iface);
3738 FIXME("(%p)\n", This);
3739 return E_NOTIMPL;
3742 static HRESULT WINAPI TextPara_DeleteTab(ITextPara *iface, FLOAT pos)
3744 ITextParaImpl *This = impl_from_ITextPara(iface);
3745 FIXME("(%p)->(%.2f)\n", This, pos);
3746 return E_NOTIMPL;
3749 static HRESULT WINAPI TextPara_GetTab(ITextPara *iface, LONG iTab, FLOAT *ptbPos, LONG *ptbAlign, LONG *ptbLeader)
3751 ITextParaImpl *This = impl_from_ITextPara(iface);
3752 FIXME("(%p)->(%d %p %p %p)\n", This, iTab, ptbPos, ptbAlign, ptbLeader);
3753 return E_NOTIMPL;
3756 static ITextParaVtbl textparavtbl = {
3757 TextPara_QueryInterface,
3758 TextPara_AddRef,
3759 TextPara_Release,
3760 TextPara_GetTypeInfoCount,
3761 TextPara_GetTypeInfo,
3762 TextPara_GetIDsOfNames,
3763 TextPara_Invoke,
3764 TextPara_GetDuplicate,
3765 TextPara_SetDuplicate,
3766 TextPara_CanChange,
3767 TextPara_IsEqual,
3768 TextPara_Reset,
3769 TextPara_GetStyle,
3770 TextPara_SetStyle,
3771 TextPara_GetAlignment,
3772 TextPara_SetAlignment,
3773 TextPara_GetHyphenation,
3774 TextPara_SetHyphenation,
3775 TextPara_GetFirstLineIndent,
3776 TextPara_GetKeepTogether,
3777 TextPara_SetKeepTogether,
3778 TextPara_GetKeepWithNext,
3779 TextPara_SetKeepWithNext,
3780 TextPara_GetLeftIndent,
3781 TextPara_GetLineSpacing,
3782 TextPara_GetLineSpacingRule,
3783 TextPara_GetListAlignment,
3784 TextPara_SetListAlignment,
3785 TextPara_GetListLevelIndex,
3786 TextPara_SetListLevelIndex,
3787 TextPara_GetListStart,
3788 TextPara_SetListStart,
3789 TextPara_GetListTab,
3790 TextPara_SetListTab,
3791 TextPara_GetListType,
3792 TextPara_SetListType,
3793 TextPara_GetNoLineNumber,
3794 TextPara_SetNoLineNumber,
3795 TextPara_GetPageBreakBefore,
3796 TextPara_SetPageBreakBefore,
3797 TextPara_GetRightIndent,
3798 TextPara_SetRightIndent,
3799 TextPara_SetIndents,
3800 TextPara_SetLineSpacing,
3801 TextPara_GetSpaceAfter,
3802 TextPara_SetSpaceAfter,
3803 TextPara_GetSpaceBefore,
3804 TextPara_SetSpaceBefore,
3805 TextPara_GetWidowControl,
3806 TextPara_SetWidowControl,
3807 TextPara_GetTabCount,
3808 TextPara_AddTab,
3809 TextPara_ClearAllTabs,
3810 TextPara_DeleteTab,
3811 TextPara_GetTab
3814 static HRESULT create_textpara(ITextRange *range, ITextPara **ret)
3816 ITextParaImpl *para;
3818 *ret = NULL;
3819 para = heap_alloc(sizeof(*para));
3820 if (!para)
3821 return E_OUTOFMEMORY;
3823 para->ITextPara_iface.lpVtbl = &textparavtbl;
3824 para->ref = 1;
3825 para->range = range;
3826 ITextRange_AddRef(range);
3828 *ret = &para->ITextPara_iface;
3829 return S_OK;
3832 /* ITextDocument */
3833 static HRESULT WINAPI
3834 ITextDocument_fnQueryInterface(ITextDocument* me, REFIID riid,
3835 void** ppvObject)
3837 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3838 return IRichEditOle_QueryInterface(&This->IRichEditOle_iface, riid, ppvObject);
3841 static ULONG WINAPI
3842 ITextDocument_fnAddRef(ITextDocument* me)
3844 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3845 return IRichEditOle_AddRef(&This->IRichEditOle_iface);
3848 static ULONG WINAPI
3849 ITextDocument_fnRelease(ITextDocument* me)
3851 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3852 return IRichEditOle_Release(&This->IRichEditOle_iface);
3855 static HRESULT WINAPI
3856 ITextDocument_fnGetTypeInfoCount(ITextDocument* me,
3857 UINT* pctinfo)
3859 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3860 TRACE("(%p)->(%p)\n", This, pctinfo);
3861 *pctinfo = 1;
3862 return S_OK;
3865 static HRESULT WINAPI
3866 ITextDocument_fnGetTypeInfo(ITextDocument* me, UINT iTInfo, LCID lcid,
3867 ITypeInfo** ppTInfo)
3869 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3870 HRESULT hr;
3872 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
3874 hr = get_typeinfo(ITextDocument_tid, ppTInfo);
3875 if (SUCCEEDED(hr))
3876 ITypeInfo_AddRef(*ppTInfo);
3877 return hr;
3880 static HRESULT WINAPI
3881 ITextDocument_fnGetIDsOfNames(ITextDocument* me, REFIID riid,
3882 LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId)
3884 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3885 ITypeInfo *ti;
3886 HRESULT hr;
3888 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid),
3889 rgszNames, cNames, lcid, rgDispId);
3891 hr = get_typeinfo(ITextDocument_tid, &ti);
3892 if (SUCCEEDED(hr))
3893 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
3894 return hr;
3897 static HRESULT WINAPI
3898 ITextDocument_fnInvoke(ITextDocument* me, DISPID dispIdMember,
3899 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
3900 VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
3902 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3903 ITypeInfo *ti;
3904 HRESULT hr;
3906 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember,
3907 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
3908 pExcepInfo, puArgErr);
3910 hr = get_typeinfo(ITextDocument_tid, &ti);
3911 if (SUCCEEDED(hr))
3912 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3913 return hr;
3916 static HRESULT WINAPI
3917 ITextDocument_fnGetName(ITextDocument* me, BSTR* pName)
3919 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3920 FIXME("stub %p\n",This);
3921 return E_NOTIMPL;
3924 static HRESULT WINAPI
3925 ITextDocument_fnGetSelection(ITextDocument *me, ITextSelection **selection)
3927 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3929 TRACE("(%p)->(%p)\n", me, selection);
3931 if (!selection)
3932 return E_INVALIDARG;
3934 if (!This->txtSel) {
3935 This->txtSel = CreateTextSelection(This);
3936 if (!This->txtSel) {
3937 *selection = NULL;
3938 return E_OUTOFMEMORY;
3942 *selection = &This->txtSel->ITextSelection_iface;
3943 ITextSelection_AddRef(*selection);
3944 return S_OK;
3947 static HRESULT WINAPI
3948 ITextDocument_fnGetStoryCount(ITextDocument* me, LONG* pCount)
3950 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3951 FIXME("stub %p\n",This);
3952 return E_NOTIMPL;
3955 static HRESULT WINAPI
3956 ITextDocument_fnGetStoryRanges(ITextDocument* me,
3957 ITextStoryRanges** ppStories)
3959 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3960 FIXME("stub %p\n",This);
3961 return E_NOTIMPL;
3964 static HRESULT WINAPI
3965 ITextDocument_fnGetSaved(ITextDocument* me, LONG* pValue)
3967 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3968 FIXME("stub %p\n",This);
3969 return E_NOTIMPL;
3972 static HRESULT WINAPI
3973 ITextDocument_fnSetSaved(ITextDocument* me, LONG Value)
3975 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3976 FIXME("stub %p\n",This);
3977 return E_NOTIMPL;
3980 static HRESULT WINAPI
3981 ITextDocument_fnGetDefaultTabStop(ITextDocument* me, float* pValue)
3983 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3984 FIXME("stub %p\n",This);
3985 return E_NOTIMPL;
3988 static HRESULT WINAPI
3989 ITextDocument_fnSetDefaultTabStop(ITextDocument* me, float Value)
3991 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3992 FIXME("stub %p\n",This);
3993 return E_NOTIMPL;
3996 static HRESULT WINAPI
3997 ITextDocument_fnNew(ITextDocument* me)
3999 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4000 FIXME("stub %p\n",This);
4001 return E_NOTIMPL;
4004 static HRESULT WINAPI
4005 ITextDocument_fnOpen(ITextDocument* me, VARIANT* pVar, LONG Flags,
4006 LONG CodePage)
4008 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4009 FIXME("stub %p\n",This);
4010 return E_NOTIMPL;
4013 static HRESULT WINAPI
4014 ITextDocument_fnSave(ITextDocument* me, VARIANT* pVar, LONG Flags,
4015 LONG CodePage)
4017 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4018 FIXME("stub %p\n",This);
4019 return E_NOTIMPL;
4022 static HRESULT WINAPI
4023 ITextDocument_fnFreeze(ITextDocument* me, LONG* pCount)
4025 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4026 FIXME("stub %p\n",This);
4027 return E_NOTIMPL;
4030 static HRESULT WINAPI
4031 ITextDocument_fnUnfreeze(ITextDocument* me, LONG* pCount)
4033 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4034 FIXME("stub %p\n",This);
4035 return E_NOTIMPL;
4038 static HRESULT WINAPI
4039 ITextDocument_fnBeginEditCollection(ITextDocument* me)
4041 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4042 FIXME("stub %p\n",This);
4043 return E_NOTIMPL;
4046 static HRESULT WINAPI
4047 ITextDocument_fnEndEditCollection(ITextDocument* me)
4049 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4050 FIXME("stub %p\n",This);
4051 return E_NOTIMPL;
4054 static HRESULT WINAPI
4055 ITextDocument_fnUndo(ITextDocument* me, LONG Count, LONG* prop)
4057 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4058 FIXME("stub %p\n",This);
4059 return E_NOTIMPL;
4062 static HRESULT WINAPI
4063 ITextDocument_fnRedo(ITextDocument* me, LONG Count, LONG* prop)
4065 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4066 FIXME("stub %p\n",This);
4067 return E_NOTIMPL;
4070 static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, ITextRange** ppRange)
4072 ITextRangeImpl *txtRge = heap_alloc(sizeof(ITextRangeImpl));
4074 if (!txtRge)
4075 return E_OUTOFMEMORY;
4076 txtRge->ITextRange_iface.lpVtbl = &trvt;
4077 txtRge->ref = 1;
4078 txtRge->child.reole = reOle;
4079 txtRge->start = start;
4080 txtRge->end = end;
4081 list_add_head(&reOle->rangelist, &txtRge->child.entry);
4082 *ppRange = &txtRge->ITextRange_iface;
4083 return S_OK;
4086 static HRESULT WINAPI
4087 ITextDocument_fnRange(ITextDocument* me, LONG cp1, LONG cp2,
4088 ITextRange** ppRange)
4090 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4091 const int len = ME_GetTextLength(This->editor) + 1;
4093 TRACE("%p %p %d %d\n", This, ppRange, cp1, cp2);
4094 if (!ppRange)
4095 return E_INVALIDARG;
4097 cp1 = max(cp1, 0);
4098 cp2 = max(cp2, 0);
4099 cp1 = min(cp1, len);
4100 cp2 = min(cp2, len);
4101 if (cp1 > cp2)
4103 LONG tmp;
4104 tmp = cp1;
4105 cp1 = cp2;
4106 cp2 = tmp;
4108 if (cp1 == len)
4109 cp1 = cp2 = len - 1;
4111 return CreateITextRange(This, cp1, cp2, ppRange);
4114 static HRESULT WINAPI
4115 ITextDocument_fnRangeFromPoint(ITextDocument* me, LONG x, LONG y,
4116 ITextRange** ppRange)
4118 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4119 FIXME("stub %p\n",This);
4120 return E_NOTIMPL;
4123 static const ITextDocumentVtbl tdvt = {
4124 ITextDocument_fnQueryInterface,
4125 ITextDocument_fnAddRef,
4126 ITextDocument_fnRelease,
4127 ITextDocument_fnGetTypeInfoCount,
4128 ITextDocument_fnGetTypeInfo,
4129 ITextDocument_fnGetIDsOfNames,
4130 ITextDocument_fnInvoke,
4131 ITextDocument_fnGetName,
4132 ITextDocument_fnGetSelection,
4133 ITextDocument_fnGetStoryCount,
4134 ITextDocument_fnGetStoryRanges,
4135 ITextDocument_fnGetSaved,
4136 ITextDocument_fnSetSaved,
4137 ITextDocument_fnGetDefaultTabStop,
4138 ITextDocument_fnSetDefaultTabStop,
4139 ITextDocument_fnNew,
4140 ITextDocument_fnOpen,
4141 ITextDocument_fnSave,
4142 ITextDocument_fnFreeze,
4143 ITextDocument_fnUnfreeze,
4144 ITextDocument_fnBeginEditCollection,
4145 ITextDocument_fnEndEditCollection,
4146 ITextDocument_fnUndo,
4147 ITextDocument_fnRedo,
4148 ITextDocument_fnRange,
4149 ITextDocument_fnRangeFromPoint
4152 /* ITextSelection */
4153 static HRESULT WINAPI ITextSelection_fnQueryInterface(
4154 ITextSelection *me,
4155 REFIID riid,
4156 void **ppvObj)
4158 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4160 *ppvObj = NULL;
4161 if (IsEqualGUID(riid, &IID_IUnknown)
4162 || IsEqualGUID(riid, &IID_IDispatch)
4163 || IsEqualGUID(riid, &IID_ITextRange)
4164 || IsEqualGUID(riid, &IID_ITextSelection))
4166 *ppvObj = me;
4167 ITextSelection_AddRef(me);
4168 return S_OK;
4170 else if (IsEqualGUID(riid, &IID_Igetrichole))
4172 *ppvObj = This->reOle;
4173 return S_OK;
4176 return E_NOINTERFACE;
4179 static ULONG WINAPI ITextSelection_fnAddRef(ITextSelection *me)
4181 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4182 return InterlockedIncrement(&This->ref);
4185 static ULONG WINAPI ITextSelection_fnRelease(ITextSelection *me)
4187 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4188 ULONG ref = InterlockedDecrement(&This->ref);
4189 if (ref == 0)
4190 heap_free(This);
4191 return ref;
4194 static HRESULT WINAPI ITextSelection_fnGetTypeInfoCount(ITextSelection *me, UINT *pctinfo)
4196 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4197 TRACE("(%p)->(%p)\n", This, pctinfo);
4198 *pctinfo = 1;
4199 return S_OK;
4202 static HRESULT WINAPI ITextSelection_fnGetTypeInfo(ITextSelection *me, UINT iTInfo, LCID lcid,
4203 ITypeInfo **ppTInfo)
4205 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4206 HRESULT hr;
4208 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
4210 hr = get_typeinfo(ITextSelection_tid, ppTInfo);
4211 if (SUCCEEDED(hr))
4212 ITypeInfo_AddRef(*ppTInfo);
4213 return hr;
4216 static HRESULT WINAPI ITextSelection_fnGetIDsOfNames(ITextSelection *me, REFIID riid,
4217 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
4219 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4220 ITypeInfo *ti;
4221 HRESULT hr;
4223 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
4224 rgDispId);
4226 hr = get_typeinfo(ITextSelection_tid, &ti);
4227 if (SUCCEEDED(hr))
4228 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
4229 return hr;
4232 static HRESULT WINAPI ITextSelection_fnInvoke(
4233 ITextSelection *me,
4234 DISPID dispIdMember,
4235 REFIID riid,
4236 LCID lcid,
4237 WORD wFlags,
4238 DISPPARAMS *pDispParams,
4239 VARIANT *pVarResult,
4240 EXCEPINFO *pExcepInfo,
4241 UINT *puArgErr)
4243 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4244 ITypeInfo *ti;
4245 HRESULT hr;
4247 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid), lcid,
4248 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4250 hr = get_typeinfo(ITextSelection_tid, &ti);
4251 if (SUCCEEDED(hr))
4252 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4253 return hr;
4256 /*** ITextRange methods ***/
4257 static HRESULT WINAPI ITextSelection_fnGetText(ITextSelection *me, BSTR *pbstr)
4259 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4260 ME_Cursor *start = NULL, *end = NULL;
4261 int nChars, endOfs;
4262 BOOL bEOP;
4264 TRACE("(%p)->(%p)\n", This, pbstr);
4266 if (!This->reOle)
4267 return CO_E_RELEASED;
4269 if (!pbstr)
4270 return E_INVALIDARG;
4272 ME_GetSelection(This->reOle->editor, &start, &end);
4273 endOfs = ME_GetCursorOfs(end);
4274 nChars = endOfs - ME_GetCursorOfs(start);
4275 if (!nChars)
4277 *pbstr = NULL;
4278 return S_OK;
4281 *pbstr = SysAllocStringLen(NULL, nChars);
4282 if (!*pbstr)
4283 return E_OUTOFMEMORY;
4285 bEOP = (end->pRun->next->type == diTextEnd && endOfs > ME_GetTextLength(This->reOle->editor));
4286 ME_GetTextW(This->reOle->editor, *pbstr, nChars, start, nChars, FALSE, bEOP);
4287 TRACE("%s\n", wine_dbgstr_w(*pbstr));
4289 return S_OK;
4292 static HRESULT WINAPI ITextSelection_fnSetText(ITextSelection *me, BSTR str)
4294 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4295 ME_TextEditor *editor;
4296 int len, to, from;
4298 TRACE("(%p)->(%s)\n", This, debugstr_w(str));
4300 if (!This->reOle)
4301 return CO_E_RELEASED;
4303 editor = This->reOle->editor;
4304 len = strlenW(str);
4305 ME_GetSelectionOfs(editor, &from, &to);
4306 ME_ReplaceSel(editor, FALSE, str, len);
4308 if (len < to - from)
4309 textranges_update_ranges(This->reOle, from, len, RANGE_UPDATE_DELETE);
4311 return S_OK;
4314 static HRESULT WINAPI ITextSelection_fnGetChar(ITextSelection *me, LONG *pch)
4316 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4317 ME_Cursor *start = NULL, *end = NULL;
4319 TRACE("(%p)->(%p)\n", This, pch);
4321 if (!This->reOle)
4322 return CO_E_RELEASED;
4324 if (!pch)
4325 return E_INVALIDARG;
4327 ME_GetSelection(This->reOle->editor, &start, &end);
4328 return range_GetChar(This->reOle->editor, start, pch);
4331 static HRESULT WINAPI ITextSelection_fnSetChar(ITextSelection *me, LONG ch)
4333 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4335 FIXME("(%p)->(%x): stub\n", This, ch);
4337 if (!This->reOle)
4338 return CO_E_RELEASED;
4340 return E_NOTIMPL;
4343 static HRESULT WINAPI ITextSelection_fnGetDuplicate(ITextSelection *me, ITextRange **range)
4345 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4346 LONG start, end;
4348 TRACE("(%p)->(%p)\n", This, range);
4350 if (!This->reOle)
4351 return CO_E_RELEASED;
4353 if (!range)
4354 return E_INVALIDARG;
4356 ITextSelection_GetStart(me, &start);
4357 ITextSelection_GetEnd(me, &end);
4358 return CreateITextRange(This->reOle, start, end, range);
4361 static HRESULT WINAPI ITextSelection_fnGetFormattedText(ITextSelection *me, ITextRange **range)
4363 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4365 FIXME("(%p)->(%p): stub\n", This, range);
4367 if (!This->reOle)
4368 return CO_E_RELEASED;
4370 return E_NOTIMPL;
4373 static HRESULT WINAPI ITextSelection_fnSetFormattedText(ITextSelection *me, ITextRange *range)
4375 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4377 FIXME("(%p)->(%p): stub\n", This, range);
4379 if (!This->reOle)
4380 return CO_E_RELEASED;
4382 FIXME("not implemented\n");
4383 return E_NOTIMPL;
4386 static HRESULT WINAPI ITextSelection_fnGetStart(ITextSelection *me, LONG *pcpFirst)
4388 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4389 LONG lim;
4391 TRACE("(%p)->(%p)\n", This, pcpFirst);
4393 if (!This->reOle)
4394 return CO_E_RELEASED;
4396 if (!pcpFirst)
4397 return E_INVALIDARG;
4398 ME_GetSelectionOfs(This->reOle->editor, pcpFirst, &lim);
4399 return S_OK;
4402 static HRESULT WINAPI ITextSelection_fnSetStart(ITextSelection *me, LONG value)
4404 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4405 LONG start, end;
4406 HRESULT hr;
4408 TRACE("(%p)->(%d)\n", This, value);
4410 if (!This->reOle)
4411 return CO_E_RELEASED;
4413 ME_GetSelectionOfs(This->reOle->editor, &start, &end);
4414 hr = textrange_setstart(This->reOle, value, &start, &end);
4415 if (hr == S_OK)
4416 ME_SetSelection(This->reOle->editor, start, end);
4418 return hr;
4421 static HRESULT WINAPI ITextSelection_fnGetEnd(ITextSelection *me, LONG *pcpLim)
4423 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4424 LONG first;
4426 TRACE("(%p)->(%p)\n", This, pcpLim);
4428 if (!This->reOle)
4429 return CO_E_RELEASED;
4431 if (!pcpLim)
4432 return E_INVALIDARG;
4433 ME_GetSelectionOfs(This->reOle->editor, &first, pcpLim);
4434 return S_OK;
4437 static HRESULT WINAPI ITextSelection_fnSetEnd(ITextSelection *me, LONG value)
4439 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4440 LONG start, end;
4441 HRESULT hr;
4443 TRACE("(%p)->(%d)\n", This, value);
4445 if (!This->reOle)
4446 return CO_E_RELEASED;
4448 ME_GetSelectionOfs(This->reOle->editor, &start, &end);
4449 hr = textrange_setend(This->reOle, value, &start, &end);
4450 if (hr == S_OK)
4451 ME_SetSelection(This->reOle->editor, start, end);
4453 return hr;
4456 static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **font)
4458 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4460 TRACE("(%p)->(%p)\n", This, font);
4462 if (!This->reOle)
4463 return CO_E_RELEASED;
4465 if (!font)
4466 return E_INVALIDARG;
4468 return create_textfont((ITextRange*)me, NULL, font);
4471 static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *font)
4473 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4475 TRACE("(%p)->(%p)\n", This, font);
4477 if (!font)
4478 return E_INVALIDARG;
4480 if (!This->reOle)
4481 return CO_E_RELEASED;
4483 textrange_set_font((ITextRange*)me, font);
4484 return S_OK;
4487 static HRESULT WINAPI ITextSelection_fnGetPara(ITextSelection *me, ITextPara **para)
4489 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4491 TRACE("(%p)->(%p)\n", This, para);
4493 if (!This->reOle)
4494 return CO_E_RELEASED;
4496 if (!para)
4497 return E_INVALIDARG;
4499 return create_textpara((ITextRange*)me, para);
4502 static HRESULT WINAPI ITextSelection_fnSetPara(ITextSelection *me, ITextPara *para)
4504 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4506 FIXME("(%p)->(%p): stub\n", This, para);
4508 if (!This->reOle)
4509 return CO_E_RELEASED;
4511 FIXME("not implemented\n");
4512 return E_NOTIMPL;
4515 static HRESULT WINAPI ITextSelection_fnGetStoryLength(ITextSelection *me, LONG *length)
4517 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4519 TRACE("(%p)->(%p)\n", This, length);
4521 if (!This->reOle)
4522 return CO_E_RELEASED;
4524 return textrange_get_storylength(This->reOle->editor, length);
4527 static HRESULT WINAPI ITextSelection_fnGetStoryType(ITextSelection *me, LONG *value)
4529 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4531 TRACE("(%p)->(%p)\n", This, value);
4533 if (!This->reOle)
4534 return CO_E_RELEASED;
4536 if (!value)
4537 return E_INVALIDARG;
4539 *value = tomUnknownStory;
4540 return S_OK;
4543 static HRESULT WINAPI ITextSelection_fnCollapse(ITextSelection *me, LONG bStart)
4545 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4546 LONG start, end;
4547 HRESULT hres;
4549 TRACE("(%p)->(%d)\n", This, bStart);
4551 if (!This->reOle)
4552 return CO_E_RELEASED;
4554 ME_GetSelectionOfs(This->reOle->editor, &start, &end);
4555 hres = range_Collapse(bStart, &start, &end);
4556 if (SUCCEEDED(hres))
4557 ME_SetSelection(This->reOle->editor, start, end);
4558 return hres;
4561 static HRESULT WINAPI ITextSelection_fnExpand(ITextSelection *me, LONG unit, LONG *delta)
4563 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4565 TRACE("(%p)->(%d %p)\n", This, unit, delta);
4567 if (!This->reOle)
4568 return CO_E_RELEASED;
4570 return textrange_expand((ITextRange*)me, unit, delta);
4573 static HRESULT WINAPI ITextSelection_fnGetIndex(ITextSelection *me, LONG unit, LONG *index)
4575 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4577 FIXME("(%p)->(%d %p): stub\n", This, unit, index);
4579 if (!This->reOle)
4580 return CO_E_RELEASED;
4582 return E_NOTIMPL;
4585 static HRESULT WINAPI ITextSelection_fnSetIndex(ITextSelection *me, LONG unit, LONG index,
4586 LONG extend)
4588 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4590 FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend);
4592 if (!This->reOle)
4593 return CO_E_RELEASED;
4595 return E_NOTIMPL;
4598 static HRESULT WINAPI ITextSelection_fnSetRange(ITextSelection *me, LONG anchor, LONG active)
4600 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4602 FIXME("(%p)->(%d %d): stub\n", This, anchor, active);
4604 if (!This->reOle)
4605 return CO_E_RELEASED;
4607 return E_NOTIMPL;
4610 static HRESULT WINAPI ITextSelection_fnInRange(ITextSelection *me, ITextRange *range, LONG *ret)
4612 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4613 ITextSelection *selection = NULL;
4614 LONG start, end;
4616 TRACE("(%p)->(%p %p)\n", This, range, ret);
4618 if (ret)
4619 *ret = tomFalse;
4621 if (!This->reOle)
4622 return CO_E_RELEASED;
4624 if (!range)
4625 return S_FALSE;
4627 ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection);
4628 if (!selection)
4629 return S_FALSE;
4630 ITextSelection_Release(selection);
4632 ITextSelection_GetStart(me, &start);
4633 ITextSelection_GetEnd(me, &end);
4634 return textrange_inrange(start, end, range, ret);
4637 static HRESULT WINAPI ITextSelection_fnInStory(ITextSelection *me, ITextRange *range, LONG *ret)
4639 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4641 FIXME("(%p)->(%p %p): stub\n", This, range, ret);
4643 if (!This->reOle)
4644 return CO_E_RELEASED;
4646 return E_NOTIMPL;
4649 static HRESULT WINAPI ITextSelection_fnIsEqual(ITextSelection *me, ITextRange *range, LONG *ret)
4651 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4652 ITextSelection *selection = NULL;
4653 LONG start, end;
4655 TRACE("(%p)->(%p %p)\n", This, range, ret);
4657 if (ret)
4658 *ret = tomFalse;
4660 if (!This->reOle)
4661 return CO_E_RELEASED;
4663 if (!range)
4664 return S_FALSE;
4666 ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection);
4667 if (!selection)
4668 return S_FALSE;
4669 ITextSelection_Release(selection);
4671 ITextSelection_GetStart(me, &start);
4672 ITextSelection_GetEnd(me, &end);
4673 return textrange_isequal(start, end, range, ret);
4676 static HRESULT WINAPI ITextSelection_fnSelect(ITextSelection *me)
4678 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4680 TRACE("(%p)\n", This);
4682 if (!This->reOle)
4683 return CO_E_RELEASED;
4685 /* nothing to do */
4686 return S_OK;
4689 static HRESULT WINAPI ITextSelection_fnStartOf(ITextSelection *me, LONG unit, LONG extend,
4690 LONG *delta)
4692 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4694 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
4696 if (!This->reOle)
4697 return CO_E_RELEASED;
4699 return E_NOTIMPL;
4702 static HRESULT WINAPI ITextSelection_fnEndOf(ITextSelection *me, LONG unit, LONG extend,
4703 LONG *delta)
4705 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4707 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
4709 if (!This->reOle)
4710 return CO_E_RELEASED;
4712 return E_NOTIMPL;
4715 static HRESULT WINAPI ITextSelection_fnMove(ITextSelection *me, LONG unit, LONG count, LONG *delta)
4717 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4719 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
4721 if (!This->reOle)
4722 return CO_E_RELEASED;
4724 return E_NOTIMPL;
4727 static HRESULT WINAPI ITextSelection_fnMoveStart(ITextSelection *me, LONG unit, LONG count,
4728 LONG *delta)
4730 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4732 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
4734 if (!This->reOle)
4735 return CO_E_RELEASED;
4737 return E_NOTIMPL;
4740 static HRESULT WINAPI ITextSelection_fnMoveEnd(ITextSelection *me, LONG unit, LONG count,
4741 LONG *delta)
4743 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4745 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
4747 if (!This->reOle)
4748 return CO_E_RELEASED;
4750 return E_NOTIMPL;
4753 static HRESULT WINAPI ITextSelection_fnMoveWhile(ITextSelection *me, VARIANT *charset, LONG count,
4754 LONG *delta)
4756 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4758 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4760 if (!This->reOle)
4761 return CO_E_RELEASED;
4763 return E_NOTIMPL;
4766 static HRESULT WINAPI ITextSelection_fnMoveStartWhile(ITextSelection *me, VARIANT *charset, LONG count,
4767 LONG *delta)
4769 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4771 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4773 if (!This->reOle)
4774 return CO_E_RELEASED;
4776 return E_NOTIMPL;
4779 static HRESULT WINAPI ITextSelection_fnMoveEndWhile(ITextSelection *me, VARIANT *charset, LONG count,
4780 LONG *delta)
4782 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4784 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4786 if (!This->reOle)
4787 return CO_E_RELEASED;
4789 return E_NOTIMPL;
4792 static HRESULT WINAPI ITextSelection_fnMoveUntil(ITextSelection *me, VARIANT *charset, LONG count,
4793 LONG *delta)
4795 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4797 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4799 if (!This->reOle)
4800 return CO_E_RELEASED;
4802 return E_NOTIMPL;
4805 static HRESULT WINAPI ITextSelection_fnMoveStartUntil(ITextSelection *me, VARIANT *charset, LONG count,
4806 LONG *delta)
4808 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4810 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4812 if (!This->reOle)
4813 return CO_E_RELEASED;
4815 return E_NOTIMPL;
4818 static HRESULT WINAPI ITextSelection_fnMoveEndUntil(ITextSelection *me, VARIANT *charset, LONG count,
4819 LONG *delta)
4821 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4823 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4825 if (!This->reOle)
4826 return CO_E_RELEASED;
4828 return E_NOTIMPL;
4831 static HRESULT WINAPI ITextSelection_fnFindText(ITextSelection *me, BSTR text, LONG count, LONG flags,
4832 LONG *length)
4834 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4836 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
4838 if (!This->reOle)
4839 return CO_E_RELEASED;
4841 FIXME("not implemented\n");
4842 return E_NOTIMPL;
4845 static HRESULT WINAPI ITextSelection_fnFindTextStart(ITextSelection *me, BSTR text, LONG count,
4846 LONG flags, LONG *length)
4848 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4850 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
4852 if (!This->reOle)
4853 return CO_E_RELEASED;
4855 return E_NOTIMPL;
4858 static HRESULT WINAPI ITextSelection_fnFindTextEnd(ITextSelection *me, BSTR text, LONG count,
4859 LONG flags, LONG *length)
4861 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4863 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
4865 if (!This->reOle)
4866 return CO_E_RELEASED;
4868 return E_NOTIMPL;
4871 static HRESULT WINAPI ITextSelection_fnDelete(ITextSelection *me, LONG unit, LONG count,
4872 LONG *delta)
4874 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4876 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
4878 if (!This->reOle)
4879 return CO_E_RELEASED;
4881 return E_NOTIMPL;
4884 static HRESULT WINAPI ITextSelection_fnCut(ITextSelection *me, VARIANT *v)
4886 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4888 FIXME("(%p)->(%p): stub\n", This, v);
4890 if (!This->reOle)
4891 return CO_E_RELEASED;
4893 return E_NOTIMPL;
4896 static HRESULT WINAPI ITextSelection_fnCopy(ITextSelection *me, VARIANT *v)
4898 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4900 FIXME("(%p)->(%p): stub\n", This, v);
4902 if (!This->reOle)
4903 return CO_E_RELEASED;
4905 return E_NOTIMPL;
4908 static HRESULT WINAPI ITextSelection_fnPaste(ITextSelection *me, VARIANT *v, LONG format)
4910 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4912 FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format);
4914 if (!This->reOle)
4915 return CO_E_RELEASED;
4917 return E_NOTIMPL;
4920 static HRESULT WINAPI ITextSelection_fnCanPaste(ITextSelection *me, VARIANT *v, LONG format,
4921 LONG *ret)
4923 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4925 FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret);
4927 if (!This->reOle)
4928 return CO_E_RELEASED;
4930 return E_NOTIMPL;
4933 static HRESULT WINAPI ITextSelection_fnCanEdit(ITextSelection *me, LONG *ret)
4935 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4937 FIXME("(%p)->(%p): stub\n", This, ret);
4939 if (!This->reOle)
4940 return CO_E_RELEASED;
4942 return E_NOTIMPL;
4945 static HRESULT WINAPI ITextSelection_fnChangeCase(ITextSelection *me, LONG type)
4947 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4949 FIXME("(%p)->(%d): stub\n", This, type);
4951 if (!This->reOle)
4952 return CO_E_RELEASED;
4954 return E_NOTIMPL;
4957 static HRESULT WINAPI ITextSelection_fnGetPoint(ITextSelection *me, LONG type, LONG *cx, LONG *cy)
4959 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4961 FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy);
4963 if (!This->reOle)
4964 return CO_E_RELEASED;
4966 return E_NOTIMPL;
4969 static HRESULT WINAPI ITextSelection_fnSetPoint(ITextSelection *me, LONG x, LONG y, LONG type,
4970 LONG extend)
4972 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4974 FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend);
4976 if (!This->reOle)
4977 return CO_E_RELEASED;
4979 return E_NOTIMPL;
4982 static HRESULT WINAPI ITextSelection_fnScrollIntoView(ITextSelection *me, LONG value)
4984 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4986 FIXME("(%p)->(%d): stub\n", This, value);
4988 if (!This->reOle)
4989 return CO_E_RELEASED;
4991 return E_NOTIMPL;
4994 static HRESULT WINAPI ITextSelection_fnGetEmbeddedObject(ITextSelection *me, IUnknown **ppv)
4996 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4998 FIXME("(%p)->(%p): stub\n", This, ppv);
5000 if (!This->reOle)
5001 return CO_E_RELEASED;
5003 return E_NOTIMPL;
5006 /*** ITextSelection methods ***/
5007 static HRESULT WINAPI ITextSelection_fnGetFlags(ITextSelection *me, LONG *flags)
5009 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5011 FIXME("(%p)->(%p): stub\n", This, flags);
5013 if (!This->reOle)
5014 return CO_E_RELEASED;
5016 return E_NOTIMPL;
5019 static HRESULT WINAPI ITextSelection_fnSetFlags(ITextSelection *me, LONG flags)
5021 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5023 FIXME("(%p)->(%x): stub\n", This, flags);
5025 if (!This->reOle)
5026 return CO_E_RELEASED;
5028 return E_NOTIMPL;
5031 static HRESULT WINAPI ITextSelection_fnGetType(ITextSelection *me, LONG *type)
5033 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5035 FIXME("(%p)->(%p): stub\n", This, type);
5037 if (!This->reOle)
5038 return CO_E_RELEASED;
5040 return E_NOTIMPL;
5043 static HRESULT WINAPI ITextSelection_fnMoveLeft(ITextSelection *me, LONG unit, LONG count,
5044 LONG extend, LONG *delta)
5046 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5048 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5050 if (!This->reOle)
5051 return CO_E_RELEASED;
5053 return E_NOTIMPL;
5056 static HRESULT WINAPI ITextSelection_fnMoveRight(ITextSelection *me, LONG unit, LONG count,
5057 LONG extend, LONG *delta)
5059 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5061 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5063 if (!This->reOle)
5064 return CO_E_RELEASED;
5066 return E_NOTIMPL;
5069 static HRESULT WINAPI ITextSelection_fnMoveUp(ITextSelection *me, LONG unit, LONG count,
5070 LONG extend, LONG *delta)
5072 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5074 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5076 if (!This->reOle)
5077 return CO_E_RELEASED;
5079 return E_NOTIMPL;
5082 static HRESULT WINAPI ITextSelection_fnMoveDown(ITextSelection *me, LONG unit, LONG count,
5083 LONG extend, LONG *delta)
5085 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5087 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5089 if (!This->reOle)
5090 return CO_E_RELEASED;
5092 return E_NOTIMPL;
5095 static HRESULT WINAPI ITextSelection_fnHomeKey(ITextSelection *me, LONG unit, LONG extend,
5096 LONG *delta)
5098 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5100 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
5102 if (!This->reOle)
5103 return CO_E_RELEASED;
5105 return E_NOTIMPL;
5108 static HRESULT WINAPI ITextSelection_fnEndKey(ITextSelection *me, LONG unit, LONG extend,
5109 LONG *delta)
5111 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5113 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
5115 if (!This->reOle)
5116 return CO_E_RELEASED;
5118 return E_NOTIMPL;
5121 static HRESULT WINAPI ITextSelection_fnTypeText(ITextSelection *me, BSTR text)
5123 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5125 FIXME("(%p)->(%s): stub\n", This, debugstr_w(text));
5127 if (!This->reOle)
5128 return CO_E_RELEASED;
5130 return E_NOTIMPL;
5133 static const ITextSelectionVtbl tsvt = {
5134 ITextSelection_fnQueryInterface,
5135 ITextSelection_fnAddRef,
5136 ITextSelection_fnRelease,
5137 ITextSelection_fnGetTypeInfoCount,
5138 ITextSelection_fnGetTypeInfo,
5139 ITextSelection_fnGetIDsOfNames,
5140 ITextSelection_fnInvoke,
5141 ITextSelection_fnGetText,
5142 ITextSelection_fnSetText,
5143 ITextSelection_fnGetChar,
5144 ITextSelection_fnSetChar,
5145 ITextSelection_fnGetDuplicate,
5146 ITextSelection_fnGetFormattedText,
5147 ITextSelection_fnSetFormattedText,
5148 ITextSelection_fnGetStart,
5149 ITextSelection_fnSetStart,
5150 ITextSelection_fnGetEnd,
5151 ITextSelection_fnSetEnd,
5152 ITextSelection_fnGetFont,
5153 ITextSelection_fnSetFont,
5154 ITextSelection_fnGetPara,
5155 ITextSelection_fnSetPara,
5156 ITextSelection_fnGetStoryLength,
5157 ITextSelection_fnGetStoryType,
5158 ITextSelection_fnCollapse,
5159 ITextSelection_fnExpand,
5160 ITextSelection_fnGetIndex,
5161 ITextSelection_fnSetIndex,
5162 ITextSelection_fnSetRange,
5163 ITextSelection_fnInRange,
5164 ITextSelection_fnInStory,
5165 ITextSelection_fnIsEqual,
5166 ITextSelection_fnSelect,
5167 ITextSelection_fnStartOf,
5168 ITextSelection_fnEndOf,
5169 ITextSelection_fnMove,
5170 ITextSelection_fnMoveStart,
5171 ITextSelection_fnMoveEnd,
5172 ITextSelection_fnMoveWhile,
5173 ITextSelection_fnMoveStartWhile,
5174 ITextSelection_fnMoveEndWhile,
5175 ITextSelection_fnMoveUntil,
5176 ITextSelection_fnMoveStartUntil,
5177 ITextSelection_fnMoveEndUntil,
5178 ITextSelection_fnFindText,
5179 ITextSelection_fnFindTextStart,
5180 ITextSelection_fnFindTextEnd,
5181 ITextSelection_fnDelete,
5182 ITextSelection_fnCut,
5183 ITextSelection_fnCopy,
5184 ITextSelection_fnPaste,
5185 ITextSelection_fnCanPaste,
5186 ITextSelection_fnCanEdit,
5187 ITextSelection_fnChangeCase,
5188 ITextSelection_fnGetPoint,
5189 ITextSelection_fnSetPoint,
5190 ITextSelection_fnScrollIntoView,
5191 ITextSelection_fnGetEmbeddedObject,
5192 ITextSelection_fnGetFlags,
5193 ITextSelection_fnSetFlags,
5194 ITextSelection_fnGetType,
5195 ITextSelection_fnMoveLeft,
5196 ITextSelection_fnMoveRight,
5197 ITextSelection_fnMoveUp,
5198 ITextSelection_fnMoveDown,
5199 ITextSelection_fnHomeKey,
5200 ITextSelection_fnEndKey,
5201 ITextSelection_fnTypeText
5204 static ITextSelectionImpl *
5205 CreateTextSelection(IRichEditOleImpl *reOle)
5207 ITextSelectionImpl *txtSel = heap_alloc(sizeof *txtSel);
5208 if (!txtSel)
5209 return NULL;
5211 txtSel->ITextSelection_iface.lpVtbl = &tsvt;
5212 txtSel->ref = 1;
5213 txtSel->reOle = reOle;
5214 return txtSel;
5217 LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *ppvObj)
5219 IRichEditOleImpl *reo;
5221 reo = heap_alloc(sizeof(IRichEditOleImpl));
5222 if (!reo)
5223 return 0;
5225 reo->IUnknown_inner.lpVtbl = &reo_unk_vtbl;
5226 reo->IRichEditOle_iface.lpVtbl = &revt;
5227 reo->ITextDocument_iface.lpVtbl = &tdvt;
5228 reo->ref = 1;
5229 reo->editor = editor;
5230 reo->txtSel = NULL;
5232 TRACE("Created %p\n",reo);
5233 list_init(&reo->rangelist);
5234 list_init(&reo->clientsites);
5235 if (outer_unk)
5236 reo->outer_unk = outer_unk;
5237 else
5238 reo->outer_unk = &reo->IUnknown_inner;
5239 *ppvObj = &reo->IRichEditOle_iface;
5241 return 1;
5244 static void convert_sizel(const ME_Context *c, const SIZEL* szl, SIZE* sz)
5246 /* sizel is in .01 millimeters, sz in pixels */
5247 sz->cx = MulDiv(szl->cx, c->dpi.cx, 2540);
5248 sz->cy = MulDiv(szl->cy, c->dpi.cy, 2540);
5251 /******************************************************************************
5252 * ME_GetOLEObjectSize
5254 * Sets run extent for OLE objects.
5256 void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize)
5258 IDataObject* ido;
5259 FORMATETC fmt;
5260 STGMEDIUM stgm;
5261 DIBSECTION dibsect;
5262 ENHMETAHEADER emh;
5264 assert(run->nFlags & MERF_GRAPHICS);
5265 assert(run->ole_obj);
5267 if (run->ole_obj->sizel.cx != 0 || run->ole_obj->sizel.cy != 0)
5269 convert_sizel(c, &run->ole_obj->sizel, pSize);
5270 if (c->editor->nZoomNumerator != 0)
5272 pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5273 pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5275 return;
5278 if (!run->ole_obj->poleobj)
5280 pSize->cx = pSize->cy = 0;
5281 return;
5284 if (IOleObject_QueryInterface(run->ole_obj->poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
5286 FIXME("Query Interface IID_IDataObject failed!\n");
5287 pSize->cx = pSize->cy = 0;
5288 return;
5290 fmt.cfFormat = CF_BITMAP;
5291 fmt.ptd = NULL;
5292 fmt.dwAspect = DVASPECT_CONTENT;
5293 fmt.lindex = -1;
5294 fmt.tymed = TYMED_GDI;
5295 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5297 fmt.cfFormat = CF_ENHMETAFILE;
5298 fmt.tymed = TYMED_ENHMF;
5299 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5301 FIXME("unsupported format\n");
5302 pSize->cx = pSize->cy = 0;
5303 IDataObject_Release(ido);
5304 return;
5308 switch (stgm.tymed)
5310 case TYMED_GDI:
5311 GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
5312 pSize->cx = dibsect.dsBm.bmWidth;
5313 pSize->cy = dibsect.dsBm.bmHeight;
5314 if (!stgm.pUnkForRelease) DeleteObject(stgm.u.hBitmap);
5315 break;
5316 case TYMED_ENHMF:
5317 GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
5318 pSize->cx = emh.rclBounds.right - emh.rclBounds.left;
5319 pSize->cy = emh.rclBounds.bottom - emh.rclBounds.top;
5320 if (!stgm.pUnkForRelease) DeleteEnhMetaFile(stgm.u.hEnhMetaFile);
5321 break;
5322 default:
5323 FIXME("Unsupported tymed %d\n", stgm.tymed);
5324 break;
5326 IDataObject_Release(ido);
5327 if (c->editor->nZoomNumerator != 0)
5329 pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5330 pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5334 void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run,
5335 ME_Paragraph *para, BOOL selected)
5337 IDataObject* ido;
5338 FORMATETC fmt;
5339 STGMEDIUM stgm;
5340 DIBSECTION dibsect;
5341 ENHMETAHEADER emh;
5342 HDC hMemDC;
5343 SIZE sz;
5344 BOOL has_size;
5346 assert(run->nFlags & MERF_GRAPHICS);
5347 assert(run->ole_obj);
5348 if (IOleObject_QueryInterface(run->ole_obj->poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
5350 FIXME("Couldn't get interface\n");
5351 return;
5353 has_size = run->ole_obj->sizel.cx != 0 || run->ole_obj->sizel.cy != 0;
5354 fmt.cfFormat = CF_BITMAP;
5355 fmt.ptd = NULL;
5356 fmt.dwAspect = DVASPECT_CONTENT;
5357 fmt.lindex = -1;
5358 fmt.tymed = TYMED_GDI;
5359 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5361 fmt.cfFormat = CF_ENHMETAFILE;
5362 fmt.tymed = TYMED_ENHMF;
5363 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5365 FIXME("Couldn't get storage medium\n");
5366 IDataObject_Release(ido);
5367 return;
5370 switch (stgm.tymed)
5372 case TYMED_GDI:
5373 GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
5374 hMemDC = CreateCompatibleDC(c->hDC);
5375 SelectObject(hMemDC, stgm.u.hBitmap);
5376 if (has_size)
5378 convert_sizel(c, &run->ole_obj->sizel, &sz);
5379 } else {
5380 sz.cx = MulDiv(dibsect.dsBm.bmWidth, c->dpi.cx, 96);
5381 sz.cy = MulDiv(dibsect.dsBm.bmHeight, c->dpi.cy, 96);
5383 if (c->editor->nZoomNumerator != 0)
5385 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5386 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5388 if (sz.cx == dibsect.dsBm.bmWidth && sz.cy == dibsect.dsBm.bmHeight)
5390 BitBlt(c->hDC, x, y - sz.cy,
5391 dibsect.dsBm.bmWidth, dibsect.dsBm.bmHeight,
5392 hMemDC, 0, 0, SRCCOPY);
5393 } else {
5394 StretchBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy,
5395 hMemDC, 0, 0, dibsect.dsBm.bmWidth,
5396 dibsect.dsBm.bmHeight, SRCCOPY);
5398 DeleteDC(hMemDC);
5399 if (!stgm.pUnkForRelease) DeleteObject(stgm.u.hBitmap);
5400 break;
5401 case TYMED_ENHMF:
5402 GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
5403 if (has_size)
5405 convert_sizel(c, &run->ole_obj->sizel, &sz);
5406 } else {
5407 sz.cy = MulDiv(emh.rclBounds.bottom - emh.rclBounds.top, c->dpi.cx, 96);
5408 sz.cx = MulDiv(emh.rclBounds.right - emh.rclBounds.left, c->dpi.cy, 96);
5410 if (c->editor->nZoomNumerator != 0)
5412 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5413 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5417 RECT rc;
5419 rc.left = x;
5420 rc.top = y - sz.cy;
5421 rc.right = x + sz.cx;
5422 rc.bottom = y;
5423 PlayEnhMetaFile(c->hDC, stgm.u.hEnhMetaFile, &rc);
5425 if (!stgm.pUnkForRelease) DeleteEnhMetaFile(stgm.u.hEnhMetaFile);
5426 break;
5427 default:
5428 FIXME("Unsupported tymed %d\n", stgm.tymed);
5429 selected = FALSE;
5430 break;
5432 if (selected && !c->editor->bHideSelection)
5433 PatBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy, DSTINVERT);
5434 IDataObject_Release(ido);
5437 void ME_DeleteReObject(REOBJECT* reo)
5439 if (reo->poleobj) IOleObject_Release(reo->poleobj);
5440 if (reo->pstg) IStorage_Release(reo->pstg);
5441 if (reo->polesite) IOleClientSite_Release(reo->polesite);
5442 FREE_OBJ(reo);
5445 void ME_CopyReObject(REOBJECT* dst, const REOBJECT* src)
5447 *dst = *src;
5449 if (dst->poleobj) IOleObject_AddRef(dst->poleobj);
5450 if (dst->pstg) IStorage_AddRef(dst->pstg);
5451 if (dst->polesite) IOleClientSite_AddRef(dst->polesite);
5454 void ME_GetITextDocumentInterface(IRichEditOle *iface, LPVOID *ppvObj)
5456 IRichEditOleImpl *This = impl_from_IRichEditOle(iface);
5457 *ppvObj = &This->ITextDocument_iface;