wined3d: Store the EXT_fbo "renderbuffers" list in the texture instead of the surface.
[wine.git] / dlls / riched20 / richole.c
blob30331572e8dc6bed664af7fed6ac44892ede028b
1 /*
2 * RichEdit GUIDs and OLE interface
4 * Copyright 2004 by Krzysztof Foltman
5 * Copyright 2004 Aric Stewart
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
24 #define NONAMELESSUNION
25 #define COBJMACROS
27 #include "windef.h"
28 #include "winbase.h"
29 #include "wingdi.h"
30 #include "winuser.h"
31 #include "ole2.h"
32 #include "richole.h"
33 #include "editor.h"
34 #include "richedit.h"
35 #include "tom.h"
36 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(richedit);
40 /* there is no way to be consistent across different sets of headers - mingw, Wine, Win32 SDK*/
42 #include "initguid.h"
44 DEFINE_GUID(LIBID_tom, 0x8cc497c9, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
45 DEFINE_GUID(IID_ITextServices, 0x8d33f740, 0xcf58, 0x11ce, 0xa8, 0x9d, 0x00, 0xaa, 0x00, 0x6c, 0xad, 0xc5);
46 DEFINE_GUID(IID_ITextHost, 0x13e670f4,0x1a5a,0x11cf,0xab,0xeb,0x00,0xaa,0x00,0xb6,0x5e,0xa1);
47 DEFINE_GUID(IID_ITextHost2, 0x13e670f5,0x1a5a,0x11cf,0xab,0xeb,0x00,0xaa,0x00,0xb6,0x5e,0xa1);
48 DEFINE_GUID(IID_ITextDocument, 0x8cc497c0, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
49 DEFINE_GUID(IID_ITextRange, 0x8cc497c2, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
50 DEFINE_GUID(IID_ITextSelection, 0x8cc497c1, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
51 DEFINE_GUID(IID_ITextFont, 0x8cc497c3, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
52 DEFINE_GUID(IID_ITextPara, 0x8cc497c4, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
54 static ITypeLib *typelib;
56 enum tid_t {
57 NULL_tid,
58 ITextDocument_tid,
59 ITextRange_tid,
60 ITextSelection_tid,
61 ITextFont_tid,
62 ITextPara_tid,
63 LAST_tid
66 static const IID * const tid_ids[] =
68 &IID_NULL,
69 &IID_ITextDocument,
70 &IID_ITextRange,
71 &IID_ITextSelection,
72 &IID_ITextFont,
73 &IID_ITextPara,
75 static ITypeInfo *typeinfos[LAST_tid];
77 static HRESULT load_typelib(void)
79 ITypeLib *tl;
80 HRESULT hr;
82 hr = LoadRegTypeLib(&LIBID_tom, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
83 if (FAILED(hr)) {
84 ERR("LoadRegTypeLib failed: %08x\n", hr);
85 return hr;
88 if (InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
89 ITypeLib_Release(tl);
90 return hr;
93 void release_typelib(void)
95 unsigned i;
97 if (!typelib)
98 return;
100 for (i = 0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++)
101 if (typeinfos[i])
102 ITypeInfo_Release(typeinfos[i]);
104 ITypeLib_Release(typelib);
107 static HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo)
109 HRESULT hr;
111 if (!typelib)
112 hr = load_typelib();
113 if (!typelib)
114 return hr;
116 if (!typeinfos[tid])
118 ITypeInfo *ti;
120 hr = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
121 if (FAILED(hr))
123 ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hr);
124 return hr;
127 if (InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
128 ITypeInfo_Release(ti);
131 *typeinfo = typeinfos[tid];
132 return S_OK;
135 /* private IID used to get back IRichEditOleImpl pointer */
136 DEFINE_GUID(IID_Igetrichole, 0xe3ce5c7a, 0x8247, 0x4622, 0x81, 0xad, 0x11, 0x81, 0x02, 0xaa, 0x01, 0x30);
138 typedef struct ITextSelectionImpl ITextSelectionImpl;
139 typedef struct IOleClientSiteImpl IOleClientSiteImpl;
140 typedef struct ITextRangeImpl ITextRangeImpl;
142 enum textfont_prop_id {
143 FONT_ALLCAPS = 0,
144 FONT_ANIMATION,
145 FONT_BACKCOLOR,
146 FONT_BOLD,
147 FONT_EMBOSS,
148 FONT_FORECOLOR,
149 FONT_HIDDEN,
150 FONT_ENGRAVE,
151 FONT_ITALIC,
152 FONT_KERNING,
153 FONT_LANGID,
154 FONT_NAME,
155 FONT_OUTLINE,
156 FONT_POSITION,
157 FONT_PROTECTED,
158 FONT_SHADOW,
159 FONT_SIZE,
160 FONT_SMALLCAPS,
161 FONT_SPACING,
162 FONT_STRIKETHROUGH,
163 FONT_SUBSCRIPT,
164 FONT_SUPERSCRIPT,
165 FONT_UNDERLINE,
166 FONT_WEIGHT,
167 FONT_PROPID_LAST,
168 FONT_PROPID_FIRST = FONT_ALLCAPS
171 static const DWORD textfont_prop_masks[][2] = {
172 { CFM_ALLCAPS, CFE_ALLCAPS },
173 { CFM_ANIMATION },
174 { CFM_BACKCOLOR, CFE_AUTOBACKCOLOR },
175 { CFM_BOLD, CFE_BOLD },
176 { CFM_EMBOSS, CFE_EMBOSS },
177 { CFM_COLOR, CFE_AUTOCOLOR },
178 { CFM_HIDDEN, CFE_HIDDEN },
179 { CFM_IMPRINT, CFE_IMPRINT },
180 { CFM_ITALIC, CFE_ITALIC },
181 { CFM_KERNING },
182 { CFM_LCID },
183 { CFM_FACE },
184 { CFM_OUTLINE, CFE_OUTLINE },
185 { CFM_OFFSET },
186 { CFM_PROTECTED, CFE_PROTECTED },
187 { CFM_SHADOW, CFE_SHADOW },
188 { CFM_SIZE },
189 { CFM_SMALLCAPS, CFE_SMALLCAPS },
190 { CFM_SPACING },
191 { CFM_STRIKEOUT, CFE_STRIKEOUT },
192 { CFM_SUBSCRIPT, CFE_SUBSCRIPT },
193 { CFM_SUPERSCRIPT, CFE_SUPERSCRIPT },
194 { CFM_UNDERLINE, CFE_UNDERLINE },
195 { CFM_WEIGHT }
198 typedef union {
199 FLOAT f;
200 LONG l;
201 BSTR str;
202 } textfont_prop_val;
204 enum range_update_op {
205 RANGE_UPDATE_DELETE
208 typedef struct IRichEditOleImpl {
209 IUnknown IUnknown_inner;
210 IRichEditOle IRichEditOle_iface;
211 ITextDocument ITextDocument_iface;
212 IUnknown *outer_unk;
213 LONG ref;
215 ME_TextEditor *editor;
216 ITextSelectionImpl *txtSel;
218 struct list rangelist;
219 struct list clientsites;
220 } IRichEditOleImpl;
222 struct reole_child {
223 struct list entry;
224 IRichEditOleImpl *reole;
227 struct ITextRangeImpl {
228 struct reole_child child;
229 ITextRange ITextRange_iface;
230 LONG ref;
231 LONG start, end;
234 struct ITextSelectionImpl {
235 ITextSelection ITextSelection_iface;
236 LONG ref;
238 IRichEditOleImpl *reOle;
241 typedef struct ITextFontImpl {
242 ITextFont ITextFont_iface;
243 LONG ref;
245 ITextRange *range;
246 textfont_prop_val props[FONT_PROPID_LAST];
247 BOOL get_cache_enabled;
248 BOOL set_cache_enabled;
249 } ITextFontImpl;
251 typedef struct ITextParaImpl {
252 ITextPara ITextPara_iface;
253 LONG ref;
255 ITextRange *range;
256 } ITextParaImpl;
258 struct IOleClientSiteImpl {
259 struct reole_child child;
260 IOleClientSite IOleClientSite_iface;
261 IOleInPlaceSite IOleInPlaceSite_iface;
262 LONG ref;
265 static inline IRichEditOleImpl *impl_from_IRichEditOle(IRichEditOle *iface)
267 return CONTAINING_RECORD(iface, IRichEditOleImpl, IRichEditOle_iface);
270 static inline IRichEditOleImpl *impl_from_ITextDocument(ITextDocument *iface)
272 return CONTAINING_RECORD(iface, IRichEditOleImpl, ITextDocument_iface);
275 static inline IRichEditOleImpl *impl_from_IUnknown(IUnknown *iface)
277 return CONTAINING_RECORD(iface, IRichEditOleImpl, IUnknown_inner);
280 static inline IOleClientSiteImpl *impl_from_IOleInPlaceSite(IOleInPlaceSite *iface)
282 return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleInPlaceSite_iface);
285 static inline ITextRangeImpl *impl_from_ITextRange(ITextRange *iface)
287 return CONTAINING_RECORD(iface, ITextRangeImpl, ITextRange_iface);
290 static inline ITextSelectionImpl *impl_from_ITextSelection(ITextSelection *iface)
292 return CONTAINING_RECORD(iface, ITextSelectionImpl, ITextSelection_iface);
295 static inline ITextFontImpl *impl_from_ITextFont(ITextFont *iface)
297 return CONTAINING_RECORD(iface, ITextFontImpl, ITextFont_iface);
300 static inline ITextParaImpl *impl_from_ITextPara(ITextPara *iface)
302 return CONTAINING_RECORD(iface, ITextParaImpl, ITextPara_iface);
305 static HRESULT create_textfont(ITextRange*, const ITextFontImpl*, ITextFont**);
306 static HRESULT create_textpara(ITextRange*, ITextPara**);
307 static ITextSelectionImpl *CreateTextSelection(IRichEditOleImpl*);
309 static HRESULT textrange_get_storylength(ME_TextEditor *editor, LONG *length)
311 if (!length)
312 return E_INVALIDARG;
314 *length = ME_GetTextLength(editor) + 1;
315 return S_OK;
318 static void textranges_update_ranges(IRichEditOleImpl *reole, LONG start, LONG end, enum range_update_op op)
320 ITextRangeImpl *range;
322 LIST_FOR_EACH_ENTRY(range, &reole->rangelist, ITextRangeImpl, child.entry) {
323 switch (op)
325 case RANGE_UPDATE_DELETE:
326 /* range fully covered by deleted range - collapse to insertion point */
327 if (range->start >= start && range->end <= end)
328 range->start = range->end = start;
329 /* deleted range cuts from the right */
330 else if (range->start < start && range->end <= end)
331 range->end = start;
332 /* deleted range cuts from the left */
333 else if (range->start >= start && range->end > end) {
334 range->start = start;
335 range->end -= end - start;
337 /* deleted range cuts within */
338 else
339 range->end -= end - start;
340 break;
341 default:
342 FIXME("unknown update op, %d\n", op);
347 static inline BOOL is_equal_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *left,
348 textfont_prop_val *right)
350 switch (propid)
352 case FONT_ALLCAPS:
353 case FONT_ANIMATION:
354 case FONT_BACKCOLOR:
355 case FONT_BOLD:
356 case FONT_EMBOSS:
357 case FONT_FORECOLOR:
358 case FONT_HIDDEN:
359 case FONT_ENGRAVE:
360 case FONT_ITALIC:
361 case FONT_KERNING:
362 case FONT_LANGID:
363 case FONT_OUTLINE:
364 case FONT_PROTECTED:
365 case FONT_SHADOW:
366 case FONT_SMALLCAPS:
367 case FONT_STRIKETHROUGH:
368 case FONT_SUBSCRIPT:
369 case FONT_SUPERSCRIPT:
370 case FONT_UNDERLINE:
371 case FONT_WEIGHT:
372 return left->l == right->l;
373 case FONT_NAME:
374 return !strcmpW(left->str, right->str);
375 case FONT_POSITION:
376 case FONT_SIZE:
377 case FONT_SPACING:
378 return left->f == right->f;
379 default:
380 FIXME("unhandled font property %d\n", propid);
381 return FALSE;
385 static inline void init_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *v)
387 switch (propid)
389 case FONT_ALLCAPS:
390 case FONT_ANIMATION:
391 case FONT_BACKCOLOR:
392 case FONT_BOLD:
393 case FONT_EMBOSS:
394 case FONT_FORECOLOR:
395 case FONT_HIDDEN:
396 case FONT_ENGRAVE:
397 case FONT_ITALIC:
398 case FONT_KERNING:
399 case FONT_LANGID:
400 case FONT_OUTLINE:
401 case FONT_PROTECTED:
402 case FONT_SHADOW:
403 case FONT_SMALLCAPS:
404 case FONT_STRIKETHROUGH:
405 case FONT_SUBSCRIPT:
406 case FONT_SUPERSCRIPT:
407 case FONT_UNDERLINE:
408 case FONT_WEIGHT:
409 v->l = tomUndefined;
410 return;
411 case FONT_NAME:
412 v->str = NULL;
413 return;
414 case FONT_POSITION:
415 case FONT_SIZE:
416 case FONT_SPACING:
417 v->f = tomUndefined;
418 return;
419 default:
420 FIXME("unhandled font property %d\n", propid);
421 v->l = tomUndefined;
422 return;
426 static inline FLOAT twips_to_points(LONG value)
428 return value * 72.0 / 1440;
431 static inline FLOAT points_to_twips(FLOAT value)
433 return value * 1440 / 72.0;
436 static HRESULT get_textfont_prop_for_pos(const IRichEditOleImpl *reole, int pos, enum textfont_prop_id propid,
437 textfont_prop_val *value)
439 ME_Cursor from, to;
440 CHARFORMAT2W fmt;
442 memset(&fmt, 0, sizeof(fmt));
443 fmt.cbSize = sizeof(fmt);
444 fmt.dwMask = textfont_prop_masks[propid][0];
446 ME_CursorFromCharOfs(reole->editor, pos, &from);
447 to = from;
448 ME_MoveCursorChars(reole->editor, &to, 1, FALSE);
449 ME_GetCharFormat(reole->editor, &from, &to, &fmt);
451 switch (propid)
453 case FONT_ALLCAPS:
454 case FONT_BOLD:
455 case FONT_EMBOSS:
456 case FONT_HIDDEN:
457 case FONT_ENGRAVE:
458 case FONT_ITALIC:
459 case FONT_OUTLINE:
460 case FONT_PROTECTED:
461 case FONT_SHADOW:
462 case FONT_SMALLCAPS:
463 case FONT_STRIKETHROUGH:
464 case FONT_SUBSCRIPT:
465 case FONT_SUPERSCRIPT:
466 case FONT_UNDERLINE:
467 value->l = fmt.dwEffects & textfont_prop_masks[propid][1] ? tomTrue : tomFalse;
468 break;
469 case FONT_ANIMATION:
470 value->l = fmt.bAnimation;
471 break;
472 case FONT_BACKCOLOR:
473 value->l = fmt.dwEffects & CFE_AUTOBACKCOLOR ? GetSysColor(COLOR_WINDOW) : fmt.crBackColor;
474 break;
475 case FONT_FORECOLOR:
476 value->l = fmt.dwEffects & CFE_AUTOCOLOR ? GetSysColor(COLOR_WINDOWTEXT) : fmt.crTextColor;
477 break;
478 case FONT_KERNING:
479 value->f = twips_to_points(fmt.wKerning);
480 break;
481 case FONT_LANGID:
482 value->l = fmt.lcid;
483 break;
484 case FONT_NAME:
485 /* this case is used exclusively by GetName() */
486 value->str = SysAllocString(fmt.szFaceName);
487 if (!value->str)
488 return E_OUTOFMEMORY;
489 break;
490 case FONT_POSITION:
491 value->f = twips_to_points(fmt.yOffset);
492 break;
493 case FONT_SIZE:
494 value->f = twips_to_points(fmt.yHeight);
495 break;
496 case FONT_SPACING:
497 value->f = fmt.sSpacing;
498 break;
499 case FONT_WEIGHT:
500 value->l = fmt.wWeight;
501 break;
502 default:
503 FIXME("unhandled font property %d\n", propid);
504 return E_FAIL;
507 return S_OK;
510 static inline const IRichEditOleImpl *get_range_reole(ITextRange *range)
512 IRichEditOleImpl *reole = NULL;
513 ITextRange_QueryInterface(range, &IID_Igetrichole, (void**)&reole);
514 return reole;
517 static void textrange_set_font(ITextRange *range, ITextFont *font)
519 CHARFORMAT2W fmt;
520 HRESULT hr;
521 LONG value;
522 BSTR str;
523 FLOAT f;
525 #define CHARFORMAT_SET_B_FIELD(mask, value) \
526 if (hr == S_OK && value != tomUndefined) { \
527 fmt.dwMask |= CFM_##mask; \
528 if (value == tomTrue) fmt.dwEffects |= CFE_##mask; \
531 /* fill format data from font */
532 memset(&fmt, 0, sizeof(fmt));
533 fmt.cbSize = sizeof(fmt);
535 value = tomUndefined;
536 hr = ITextFont_GetAllCaps(font, &value);
537 CHARFORMAT_SET_B_FIELD(ALLCAPS, value);
539 value = tomUndefined;
540 hr = ITextFont_GetBold(font, &value);
541 CHARFORMAT_SET_B_FIELD(BOLD, value);
543 value = tomUndefined;
544 hr = ITextFont_GetEmboss(font, &value);
545 CHARFORMAT_SET_B_FIELD(EMBOSS, value);
547 value = tomUndefined;
548 hr = ITextFont_GetHidden(font, &value);
549 CHARFORMAT_SET_B_FIELD(HIDDEN, value);
551 value = tomUndefined;
552 hr = ITextFont_GetEngrave(font, &value);
553 CHARFORMAT_SET_B_FIELD(IMPRINT, value);
555 value = tomUndefined;
556 hr = ITextFont_GetItalic(font, &value);
557 CHARFORMAT_SET_B_FIELD(ITALIC, value);
559 value = tomUndefined;
560 hr = ITextFont_GetOutline(font, &value);
561 CHARFORMAT_SET_B_FIELD(OUTLINE, value);
563 value = tomUndefined;
564 hr = ITextFont_GetProtected(font, &value);
565 CHARFORMAT_SET_B_FIELD(PROTECTED, value);
567 value = tomUndefined;
568 hr = ITextFont_GetShadow(font, &value);
569 CHARFORMAT_SET_B_FIELD(SHADOW, value);
571 value = tomUndefined;
572 hr = ITextFont_GetSmallCaps(font, &value);
573 CHARFORMAT_SET_B_FIELD(SMALLCAPS, value);
575 value = tomUndefined;
576 hr = ITextFont_GetStrikeThrough(font, &value);
577 CHARFORMAT_SET_B_FIELD(STRIKEOUT, value);
579 value = tomUndefined;
580 hr = ITextFont_GetSubscript(font, &value);
581 CHARFORMAT_SET_B_FIELD(SUBSCRIPT, value);
583 value = tomUndefined;
584 hr = ITextFont_GetSuperscript(font, &value);
585 CHARFORMAT_SET_B_FIELD(SUPERSCRIPT, value);
587 value = tomUndefined;
588 hr = ITextFont_GetUnderline(font, &value);
589 CHARFORMAT_SET_B_FIELD(UNDERLINE, value);
591 #undef CHARFORMAT_SET_B_FIELD
593 value = tomUndefined;
594 hr = ITextFont_GetAnimation(font, &value);
595 if (hr == S_OK && value != tomUndefined) {
596 fmt.dwMask |= CFM_ANIMATION;
597 fmt.bAnimation = value;
600 value = tomUndefined;
601 hr = ITextFont_GetBackColor(font, &value);
602 if (hr == S_OK && value != tomUndefined) {
603 fmt.dwMask |= CFM_BACKCOLOR;
604 if (value == tomAutoColor)
605 fmt.dwEffects |= CFE_AUTOBACKCOLOR;
606 else
607 fmt.crBackColor = value;
610 value = tomUndefined;
611 hr = ITextFont_GetForeColor(font, &value);
612 if (hr == S_OK && value != tomUndefined) {
613 fmt.dwMask |= CFM_COLOR;
614 if (value == tomAutoColor)
615 fmt.dwEffects |= CFE_AUTOCOLOR;
616 else
617 fmt.crTextColor = value;
620 value = tomUndefined;
621 hr = ITextFont_GetKerning(font, &f);
622 if (hr == S_OK && f != tomUndefined) {
623 fmt.dwMask |= CFM_KERNING;
624 fmt.wKerning = points_to_twips(f);
627 value = tomUndefined;
628 hr = ITextFont_GetLanguageID(font, &value);
629 if (hr == S_OK && value != tomUndefined) {
630 fmt.dwMask |= CFM_LCID;
631 fmt.lcid = value;
634 if (ITextFont_GetName(font, &str) == S_OK) {
635 fmt.dwMask |= CFM_FACE;
636 lstrcpynW(fmt.szFaceName, str, sizeof(fmt.szFaceName)/sizeof(WCHAR));
637 SysFreeString(str);
640 hr = ITextFont_GetPosition(font, &f);
641 if (hr == S_OK && f != tomUndefined) {
642 fmt.dwMask |= CFM_OFFSET;
643 fmt.yOffset = points_to_twips(f);
646 hr = ITextFont_GetSize(font, &f);
647 if (hr == S_OK && f != tomUndefined) {
648 fmt.dwMask |= CFM_SIZE;
649 fmt.yHeight = points_to_twips(f);
652 hr = ITextFont_GetSpacing(font, &f);
653 if (hr == S_OK && f != tomUndefined) {
654 fmt.dwMask |= CFM_SPACING;
655 fmt.sSpacing = f;
658 hr = ITextFont_GetWeight(font, &value);
659 if (hr == S_OK && value != tomUndefined) {
660 fmt.dwMask |= CFM_WEIGHT;
661 fmt.wWeight = value;
664 if (fmt.dwMask) {
665 const IRichEditOleImpl *reole = get_range_reole(range);
666 ME_Cursor from, to;
667 LONG start, end;
669 ITextRange_GetStart(range, &start);
670 ITextRange_GetEnd(range, &end);
672 ME_CursorFromCharOfs(reole->editor, start, &from);
673 ME_CursorFromCharOfs(reole->editor, end, &to);
674 ME_SetCharFormat(reole->editor, &from, &to, &fmt);
678 static HRESULT get_textfont_prop(const ITextFontImpl *font, enum textfont_prop_id propid, textfont_prop_val *value)
680 const IRichEditOleImpl *reole;
681 textfont_prop_val v;
682 LONG start, end, i;
683 HRESULT hr;
685 /* when font is not attached to any range use cached values */
686 if (!font->range || font->get_cache_enabled) {
687 *value = font->props[propid];
688 return S_OK;
691 if (!(reole = get_range_reole(font->range)))
692 return CO_E_RELEASED;
694 init_textfont_prop_value(propid, value);
696 ITextRange_GetStart(font->range, &start);
697 ITextRange_GetEnd(font->range, &end);
699 /* iterate trough a range to see if property value is consistent */
700 hr = get_textfont_prop_for_pos(reole, start, propid, &v);
701 if (FAILED(hr))
702 return hr;
704 for (i = start + 1; i < end; i++) {
705 textfont_prop_val cur;
707 hr = get_textfont_prop_for_pos(reole, i, propid, &cur);
708 if (FAILED(hr))
709 return hr;
711 if (!is_equal_textfont_prop_value(propid, &v, &cur))
712 return S_OK;
715 *value = v;
716 return S_OK;
719 static HRESULT get_textfont_propf(const ITextFontImpl *font, enum textfont_prop_id propid, FLOAT *value)
721 textfont_prop_val v;
722 HRESULT hr;
724 if (!value)
725 return E_INVALIDARG;
727 hr = get_textfont_prop(font, propid, &v);
728 *value = v.f;
729 return hr;
732 static HRESULT get_textfont_propl(const ITextFontImpl *font, enum textfont_prop_id propid, LONG *value)
734 textfont_prop_val v;
735 HRESULT hr;
737 if (!value)
738 return E_INVALIDARG;
740 hr = get_textfont_prop(font, propid, &v);
741 *value = v.l;
742 return hr;
745 /* Value should already have a terminal value, for boolean properties it means tomToggle is not handled */
746 static HRESULT set_textfont_prop(ITextFontImpl *font, enum textfont_prop_id propid, const textfont_prop_val *value)
748 const IRichEditOleImpl *reole;
749 ME_Cursor from, to;
750 CHARFORMAT2W fmt;
751 LONG start, end;
753 /* when font is not attached to any range use cache */
754 if (!font->range || font->set_cache_enabled) {
755 if (propid == FONT_NAME) {
756 SysFreeString(font->props[propid].str);
757 font->props[propid].str = SysAllocString(value->str);
759 else
760 font->props[propid] = *value;
761 return S_OK;
764 if (!(reole = get_range_reole(font->range)))
765 return CO_E_RELEASED;
767 memset(&fmt, 0, sizeof(fmt));
768 fmt.cbSize = sizeof(fmt);
769 fmt.dwMask = textfont_prop_masks[propid][0];
771 switch (propid)
773 case FONT_ALLCAPS:
774 case FONT_BOLD:
775 case FONT_EMBOSS:
776 case FONT_HIDDEN:
777 case FONT_ENGRAVE:
778 case FONT_ITALIC:
779 case FONT_OUTLINE:
780 case FONT_PROTECTED:
781 case FONT_SHADOW:
782 case FONT_SMALLCAPS:
783 case FONT_STRIKETHROUGH:
784 case FONT_SUBSCRIPT:
785 case FONT_SUPERSCRIPT:
786 case FONT_UNDERLINE:
787 fmt.dwEffects = value->l == tomTrue ? textfont_prop_masks[propid][1] : 0;
788 break;
789 case FONT_ANIMATION:
790 fmt.bAnimation = value->l;
791 break;
792 case FONT_BACKCOLOR:
793 case FONT_FORECOLOR:
794 if (value->l == tomAutoColor)
795 fmt.dwEffects = textfont_prop_masks[propid][1];
796 else if (propid == FONT_BACKCOLOR)
797 fmt.crBackColor = value->l;
798 else
799 fmt.crTextColor = value->l;
800 break;
801 case FONT_KERNING:
802 fmt.wKerning = value->f;
803 break;
804 case FONT_LANGID:
805 fmt.lcid = value->l;
806 break;
807 case FONT_POSITION:
808 fmt.yOffset = value->f;
809 break;
810 case FONT_SIZE:
811 fmt.yHeight = value->f;
812 break;
813 case FONT_SPACING:
814 fmt.sSpacing = value->f;
815 break;
816 case FONT_WEIGHT:
817 fmt.wWeight = value->l;
818 break;
819 case FONT_NAME:
820 lstrcpynW(fmt.szFaceName, value->str, sizeof(fmt.szFaceName)/sizeof(WCHAR));
821 break;
822 default:
823 FIXME("unhandled font property %d\n", propid);
824 return E_FAIL;
827 ITextRange_GetStart(font->range, &start);
828 ITextRange_GetEnd(font->range, &end);
830 ME_CursorFromCharOfs(reole->editor, start, &from);
831 ME_CursorFromCharOfs(reole->editor, end, &to);
832 ME_SetCharFormat(reole->editor, &from, &to, &fmt);
834 return S_OK;
837 static inline HRESULT set_textfont_propl(ITextFontImpl *font, enum textfont_prop_id propid, LONG value)
839 textfont_prop_val v;
840 v.l = value;
841 return set_textfont_prop(font, propid, &v);
844 static inline HRESULT set_textfont_propf(ITextFontImpl *font, enum textfont_prop_id propid, FLOAT value)
846 textfont_prop_val v;
847 v.f = value;
848 return set_textfont_prop(font, propid, &v);
851 static HRESULT set_textfont_propd(ITextFontImpl *font, enum textfont_prop_id propid, LONG value)
853 textfont_prop_val v;
855 switch (value)
857 case tomUndefined:
858 return S_OK;
859 case tomToggle: {
860 LONG oldvalue;
861 get_textfont_propl(font, propid, &oldvalue);
862 if (oldvalue == tomFalse)
863 value = tomTrue;
864 else if (oldvalue == tomTrue)
865 value = tomFalse;
866 else
867 return E_INVALIDARG;
868 /* fallthrough */
870 case tomTrue:
871 case tomFalse:
872 v.l = value;
873 return set_textfont_prop(font, propid, &v);
874 default:
875 return E_INVALIDARG;
879 static HRESULT textfont_getname_from_range(ITextRange *range, BSTR *ret)
881 const IRichEditOleImpl *reole;
882 textfont_prop_val v;
883 HRESULT hr;
884 LONG start;
886 if (!(reole = get_range_reole(range)))
887 return CO_E_RELEASED;
889 ITextRange_GetStart(range, &start);
890 hr = get_textfont_prop_for_pos(reole, start, FONT_NAME, &v);
891 *ret = v.str;
892 return hr;
895 static void textfont_cache_range_props(ITextFontImpl *font)
897 enum textfont_prop_id propid;
898 for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++) {
899 if (propid == FONT_NAME)
900 textfont_getname_from_range(font->range, &font->props[propid].str);
901 else
902 get_textfont_prop(font, propid, &font->props[propid]);
906 static HRESULT textrange_expand(ITextRange *range, LONG unit, LONG *delta)
908 LONG expand_start, expand_end;
910 switch (unit)
912 case tomStory:
913 expand_start = 0;
914 ITextRange_GetStoryLength(range, &expand_end);
915 break;
916 default:
917 FIXME("unit %d is not supported\n", unit);
918 return E_NOTIMPL;
921 if (delta) {
922 LONG start, end;
924 ITextRange_GetStart(range, &start);
925 ITextRange_GetEnd(range, &end);
926 *delta = expand_end - expand_start - (end - start);
929 ITextRange_SetStart(range, expand_start);
930 ITextRange_SetEnd(range, expand_end);
932 return S_OK;
935 static HRESULT WINAPI IRichEditOleImpl_inner_fnQueryInterface(IUnknown *iface, REFIID riid, LPVOID *ppvObj)
937 IRichEditOleImpl *This = impl_from_IUnknown(iface);
939 TRACE("%p %s\n", This, debugstr_guid(riid));
941 *ppvObj = NULL;
942 if (IsEqualGUID(riid, &IID_IUnknown))
943 *ppvObj = &This->IUnknown_inner;
944 else if (IsEqualGUID(riid, &IID_IRichEditOle))
945 *ppvObj = &This->IRichEditOle_iface;
946 else if (IsEqualGUID(riid, &IID_ITextDocument))
947 *ppvObj = &This->ITextDocument_iface;
948 if (*ppvObj)
950 IUnknown_AddRef((IUnknown *)*ppvObj);
951 return S_OK;
953 FIXME("%p: unhandled interface %s\n", This, debugstr_guid(riid));
955 return E_NOINTERFACE;
958 static ULONG WINAPI IRichEditOleImpl_inner_fnAddRef(IUnknown *iface)
960 IRichEditOleImpl *This = impl_from_IUnknown(iface);
961 ULONG ref = InterlockedIncrement(&This->ref);
963 TRACE("%p ref = %u\n", This, ref);
965 return ref;
968 static ULONG WINAPI IRichEditOleImpl_inner_fnRelease(IUnknown *iface)
970 IRichEditOleImpl *This = impl_from_IUnknown(iface);
971 ULONG ref = InterlockedDecrement(&This->ref);
973 TRACE ("%p ref=%u\n", This, ref);
975 if (!ref)
977 IOleClientSiteImpl *clientsite;
978 ITextRangeImpl *txtRge;
980 This->editor->reOle = NULL;
981 if (This->txtSel) {
982 This->txtSel->reOle = NULL;
983 ITextSelection_Release(&This->txtSel->ITextSelection_iface);
986 LIST_FOR_EACH_ENTRY(txtRge, &This->rangelist, ITextRangeImpl, child.entry)
987 txtRge->child.reole = NULL;
989 LIST_FOR_EACH_ENTRY(clientsite, &This->clientsites, IOleClientSiteImpl, child.entry)
990 clientsite->child.reole = NULL;
992 heap_free(This);
994 return ref;
997 static const IUnknownVtbl reo_unk_vtbl =
999 IRichEditOleImpl_inner_fnQueryInterface,
1000 IRichEditOleImpl_inner_fnAddRef,
1001 IRichEditOleImpl_inner_fnRelease
1004 static HRESULT WINAPI
1005 IRichEditOle_fnQueryInterface(IRichEditOle *me, REFIID riid, LPVOID *ppvObj)
1007 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1008 return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj);
1011 static ULONG WINAPI
1012 IRichEditOle_fnAddRef(IRichEditOle *me)
1014 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1015 return IUnknown_AddRef(This->outer_unk);
1018 static ULONG WINAPI
1019 IRichEditOle_fnRelease(IRichEditOle *me)
1021 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1022 return IUnknown_Release(This->outer_unk);
1025 static HRESULT WINAPI
1026 IRichEditOle_fnActivateAs(IRichEditOle *me, REFCLSID rclsid, REFCLSID rclsidAs)
1028 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1029 FIXME("stub %p\n",This);
1030 return E_NOTIMPL;
1033 static HRESULT WINAPI
1034 IRichEditOle_fnContextSensitiveHelp(IRichEditOle *me, BOOL fEnterMode)
1036 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1037 FIXME("stub %p\n",This);
1038 return E_NOTIMPL;
1041 static HRESULT WINAPI
1042 IRichEditOle_fnConvertObject(IRichEditOle *me, LONG iob,
1043 REFCLSID rclsidNew, LPCSTR lpstrUserTypeNew)
1045 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1046 FIXME("stub %p\n",This);
1047 return E_NOTIMPL;
1050 static inline IOleClientSiteImpl *impl_from_IOleClientSite(IOleClientSite *iface)
1052 return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleClientSite_iface);
1055 static HRESULT WINAPI
1056 IOleClientSite_fnQueryInterface(IOleClientSite *me, REFIID riid, LPVOID *ppvObj)
1058 IOleClientSiteImpl *This = impl_from_IOleClientSite(me);
1059 TRACE("%p %s\n", me, debugstr_guid(riid) );
1061 *ppvObj = NULL;
1062 if (IsEqualGUID(riid, &IID_IUnknown) ||
1063 IsEqualGUID(riid, &IID_IOleClientSite))
1064 *ppvObj = me;
1065 else if (IsEqualGUID(riid, &IID_IOleWindow) ||
1066 IsEqualGUID(riid, &IID_IOleInPlaceSite))
1067 *ppvObj = &This->IOleInPlaceSite_iface;
1068 if (*ppvObj)
1070 IOleClientSite_AddRef(me);
1071 return S_OK;
1073 FIXME("%p: unhandled interface %s\n", me, debugstr_guid(riid) );
1075 return E_NOINTERFACE;
1078 static ULONG WINAPI IOleClientSite_fnAddRef(IOleClientSite *iface)
1080 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1081 ULONG ref = InterlockedIncrement(&This->ref);
1082 TRACE("(%p)->(%u)\n", This, ref);
1083 return ref;
1086 static ULONG WINAPI IOleClientSite_fnRelease(IOleClientSite *iface)
1088 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1089 ULONG ref = InterlockedDecrement(&This->ref);
1091 TRACE("(%p)->(%u)\n", This, ref);
1093 if (ref == 0) {
1094 if (This->child.reole) {
1095 list_remove(&This->child.entry);
1096 This->child.reole = NULL;
1098 heap_free(This);
1100 return ref;
1103 static HRESULT WINAPI IOleClientSite_fnSaveObject(IOleClientSite *iface)
1105 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1106 if (!This->child.reole)
1107 return CO_E_RELEASED;
1109 FIXME("stub %p\n", iface);
1110 return E_NOTIMPL;
1113 static HRESULT WINAPI IOleClientSite_fnGetMoniker(IOleClientSite *iface, DWORD dwAssign,
1114 DWORD dwWhichMoniker, IMoniker **ppmk)
1116 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1117 if (!This->child.reole)
1118 return CO_E_RELEASED;
1120 FIXME("stub %p\n", iface);
1121 return E_NOTIMPL;
1124 static HRESULT WINAPI IOleClientSite_fnGetContainer(IOleClientSite *iface,
1125 IOleContainer **ppContainer)
1127 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1128 if (!This->child.reole)
1129 return CO_E_RELEASED;
1131 FIXME("stub %p\n", iface);
1132 return E_NOTIMPL;
1135 static HRESULT WINAPI IOleClientSite_fnShowObject(IOleClientSite *iface)
1137 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1138 if (!This->child.reole)
1139 return CO_E_RELEASED;
1141 FIXME("stub %p\n", iface);
1142 return E_NOTIMPL;
1145 static HRESULT WINAPI IOleClientSite_fnOnShowWindow(IOleClientSite *iface, BOOL fShow)
1147 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1148 if (!This->child.reole)
1149 return CO_E_RELEASED;
1151 FIXME("stub %p\n", iface);
1152 return E_NOTIMPL;
1155 static HRESULT WINAPI IOleClientSite_fnRequestNewObjectLayout(IOleClientSite *iface)
1157 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1158 if (!This->child.reole)
1159 return CO_E_RELEASED;
1161 FIXME("stub %p\n", iface);
1162 return E_NOTIMPL;
1165 static const IOleClientSiteVtbl ocst = {
1166 IOleClientSite_fnQueryInterface,
1167 IOleClientSite_fnAddRef,
1168 IOleClientSite_fnRelease,
1169 IOleClientSite_fnSaveObject,
1170 IOleClientSite_fnGetMoniker,
1171 IOleClientSite_fnGetContainer,
1172 IOleClientSite_fnShowObject,
1173 IOleClientSite_fnOnShowWindow,
1174 IOleClientSite_fnRequestNewObjectLayout
1177 /* IOleInPlaceSite interface */
1178 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnQueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppvObj)
1180 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1181 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppvObj);
1184 static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnAddRef(IOleInPlaceSite *iface)
1186 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1187 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1190 static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnRelease(IOleInPlaceSite *iface)
1192 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1193 return IOleClientSite_Release(&This->IOleClientSite_iface);
1196 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindow(IOleInPlaceSite *iface, HWND *phwnd)
1198 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1200 TRACE("(%p)->(%p)\n", This, phwnd);
1202 if (!This->child.reole)
1203 return CO_E_RELEASED;
1205 if (!phwnd)
1206 return E_INVALIDARG;
1208 *phwnd = This->child.reole->editor->hWnd;
1209 return S_OK;
1212 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode)
1214 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1215 FIXME("not implemented: (%p)->(%d)\n", This, fEnterMode);
1216 return E_NOTIMPL;
1219 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnCanInPlaceActivate(IOleInPlaceSite *iface)
1221 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1222 FIXME("not implemented: (%p)\n", This);
1223 return E_NOTIMPL;
1226 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceActivate(IOleInPlaceSite *iface)
1228 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1229 FIXME("not implemented: (%p)\n", This);
1230 return E_NOTIMPL;
1233 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIActivate(IOleInPlaceSite *iface)
1235 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1236 FIXME("not implemented: (%p)\n", This);
1237 return E_NOTIMPL;
1240 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindowContext(IOleInPlaceSite *iface, IOleInPlaceFrame **ppFrame,
1241 IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
1242 LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
1244 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1245 FIXME("not implemented: (%p)->(%p %p %p %p %p)\n", This, ppFrame, ppDoc, lprcPosRect, lprcClipRect, lpFrameInfo);
1246 return E_NOTIMPL;
1249 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnScroll(IOleInPlaceSite *iface, SIZE scrollExtent)
1251 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1252 FIXME("not implemented: (%p)\n", This);
1253 return E_NOTIMPL;
1256 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable)
1258 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1259 FIXME("not implemented: (%p)->(%d)\n", This, fUndoable);
1260 return E_NOTIMPL;
1263 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceDeactivate(IOleInPlaceSite *iface)
1265 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1266 FIXME("not implemented: (%p)\n", This);
1267 return E_NOTIMPL;
1270 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDiscardUndoState(IOleInPlaceSite *iface)
1272 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1273 FIXME("not implemented: (%p)\n", This);
1274 return E_NOTIMPL;
1277 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDeactivateAndUndo(IOleInPlaceSite *iface)
1279 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1280 FIXME("not implemented: (%p)\n", This);
1281 return E_NOTIMPL;
1284 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect)
1286 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1287 FIXME("not implemented: (%p)->(%p)\n", This, lprcPosRect);
1288 return E_NOTIMPL;
1291 static const IOleInPlaceSiteVtbl olestvt =
1293 IOleInPlaceSite_fnQueryInterface,
1294 IOleInPlaceSite_fnAddRef,
1295 IOleInPlaceSite_fnRelease,
1296 IOleInPlaceSite_fnGetWindow,
1297 IOleInPlaceSite_fnContextSensitiveHelp,
1298 IOleInPlaceSite_fnCanInPlaceActivate,
1299 IOleInPlaceSite_fnOnInPlaceActivate,
1300 IOleInPlaceSite_fnOnUIActivate,
1301 IOleInPlaceSite_fnGetWindowContext,
1302 IOleInPlaceSite_fnScroll,
1303 IOleInPlaceSite_fnOnUIDeactivate,
1304 IOleInPlaceSite_fnOnInPlaceDeactivate,
1305 IOleInPlaceSite_fnDiscardUndoState,
1306 IOleInPlaceSite_fnDeactivateAndUndo,
1307 IOleInPlaceSite_fnOnPosRectChange
1310 static HRESULT CreateOleClientSite(IRichEditOleImpl *reOle, IOleClientSite **ret)
1312 IOleClientSiteImpl *clientSite = heap_alloc(sizeof *clientSite);
1314 if (!clientSite)
1315 return E_OUTOFMEMORY;
1317 clientSite->IOleClientSite_iface.lpVtbl = &ocst;
1318 clientSite->IOleInPlaceSite_iface.lpVtbl = &olestvt;
1319 clientSite->ref = 1;
1320 clientSite->child.reole = reOle;
1321 list_add_head(&reOle->clientsites, &clientSite->child.entry);
1323 *ret = &clientSite->IOleClientSite_iface;
1324 return S_OK;
1327 static HRESULT WINAPI
1328 IRichEditOle_fnGetClientSite(IRichEditOle *me, IOleClientSite **clientsite)
1330 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1332 TRACE("(%p)->(%p)\n", This, clientsite);
1334 if (!clientsite)
1335 return E_INVALIDARG;
1337 return CreateOleClientSite(This, clientsite);
1340 static HRESULT WINAPI
1341 IRichEditOle_fnGetClipboardData(IRichEditOle *me, CHARRANGE *lpchrg,
1342 DWORD reco, LPDATAOBJECT *lplpdataobj)
1344 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1345 ME_Cursor start;
1346 int nChars;
1348 TRACE("(%p,%p,%d)\n",This, lpchrg, reco);
1349 if(!lplpdataobj)
1350 return E_INVALIDARG;
1351 if(!lpchrg) {
1352 int nFrom, nTo, nStartCur = ME_GetSelectionOfs(This->editor, &nFrom, &nTo);
1353 start = This->editor->pCursors[nStartCur];
1354 nChars = nTo - nFrom;
1355 } else {
1356 ME_CursorFromCharOfs(This->editor, lpchrg->cpMin, &start);
1357 nChars = lpchrg->cpMax - lpchrg->cpMin;
1359 return ME_GetDataObject(This->editor, &start, nChars, lplpdataobj);
1362 static LONG WINAPI IRichEditOle_fnGetLinkCount(IRichEditOle *me)
1364 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1365 FIXME("stub %p\n",This);
1366 return E_NOTIMPL;
1369 static HRESULT WINAPI
1370 IRichEditOle_fnGetObject(IRichEditOle *me, LONG iob,
1371 REOBJECT *lpreobject, DWORD dwFlags)
1373 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1374 FIXME("stub %p\n",This);
1375 return E_NOTIMPL;
1378 static LONG WINAPI
1379 IRichEditOle_fnGetObjectCount(IRichEditOle *me)
1381 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1382 FIXME("stub %p\n",This);
1383 return 0;
1386 static HRESULT WINAPI
1387 IRichEditOle_fnHandsOffStorage(IRichEditOle *me, LONG iob)
1389 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1390 FIXME("stub %p\n",This);
1391 return E_NOTIMPL;
1394 static HRESULT WINAPI
1395 IRichEditOle_fnImportDataObject(IRichEditOle *me, LPDATAOBJECT lpdataobj,
1396 CLIPFORMAT cf, HGLOBAL hMetaPict)
1398 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1399 FIXME("stub %p\n",This);
1400 return E_NOTIMPL;
1403 static HRESULT WINAPI
1404 IRichEditOle_fnInPlaceDeactivate(IRichEditOle *me)
1406 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1407 FIXME("stub %p\n",This);
1408 return E_NOTIMPL;
1411 static HRESULT WINAPI
1412 IRichEditOle_fnInsertObject(IRichEditOle *me, REOBJECT *reo)
1414 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1416 TRACE("(%p,%p)\n", This, reo);
1418 if (!reo)
1419 return E_INVALIDARG;
1421 if (reo->cbStruct < sizeof(*reo)) return STG_E_INVALIDPARAMETER;
1423 ME_InsertOLEFromCursor(This->editor, reo, 0);
1424 ME_CommitUndo(This->editor);
1425 ME_UpdateRepaint(This->editor, FALSE);
1426 return S_OK;
1429 static HRESULT WINAPI IRichEditOle_fnSaveCompleted(IRichEditOle *me, LONG iob,
1430 LPSTORAGE lpstg)
1432 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1433 FIXME("stub %p\n",This);
1434 return E_NOTIMPL;
1437 static HRESULT WINAPI
1438 IRichEditOle_fnSetDvaspect(IRichEditOle *me, LONG iob, DWORD dvaspect)
1440 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1441 FIXME("stub %p\n",This);
1442 return E_NOTIMPL;
1445 static HRESULT WINAPI IRichEditOle_fnSetHostNames(IRichEditOle *me,
1446 LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj)
1448 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1449 FIXME("stub %p %s %s\n",This, lpstrContainerApp, lpstrContainerObj);
1450 return E_NOTIMPL;
1453 static HRESULT WINAPI
1454 IRichEditOle_fnSetLinkAvailable(IRichEditOle *me, LONG iob, BOOL fAvailable)
1456 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1457 FIXME("stub %p\n",This);
1458 return E_NOTIMPL;
1461 static const IRichEditOleVtbl revt = {
1462 IRichEditOle_fnQueryInterface,
1463 IRichEditOle_fnAddRef,
1464 IRichEditOle_fnRelease,
1465 IRichEditOle_fnGetClientSite,
1466 IRichEditOle_fnGetObjectCount,
1467 IRichEditOle_fnGetLinkCount,
1468 IRichEditOle_fnGetObject,
1469 IRichEditOle_fnInsertObject,
1470 IRichEditOle_fnConvertObject,
1471 IRichEditOle_fnActivateAs,
1472 IRichEditOle_fnSetHostNames,
1473 IRichEditOle_fnSetLinkAvailable,
1474 IRichEditOle_fnSetDvaspect,
1475 IRichEditOle_fnHandsOffStorage,
1476 IRichEditOle_fnSaveCompleted,
1477 IRichEditOle_fnInPlaceDeactivate,
1478 IRichEditOle_fnContextSensitiveHelp,
1479 IRichEditOle_fnGetClipboardData,
1480 IRichEditOle_fnImportDataObject
1483 /* ITextRange interface */
1484 static HRESULT WINAPI ITextRange_fnQueryInterface(ITextRange *me, REFIID riid, void **ppvObj)
1486 ITextRangeImpl *This = impl_from_ITextRange(me);
1488 *ppvObj = NULL;
1489 if (IsEqualGUID(riid, &IID_IUnknown)
1490 || IsEqualGUID(riid, &IID_IDispatch)
1491 || IsEqualGUID(riid, &IID_ITextRange))
1493 *ppvObj = me;
1494 ITextRange_AddRef(me);
1495 return S_OK;
1497 else if (IsEqualGUID(riid, &IID_Igetrichole))
1499 *ppvObj = This->child.reole;
1500 return S_OK;
1503 return E_NOINTERFACE;
1506 static ULONG WINAPI ITextRange_fnAddRef(ITextRange *me)
1508 ITextRangeImpl *This = impl_from_ITextRange(me);
1509 return InterlockedIncrement(&This->ref);
1512 static ULONG WINAPI ITextRange_fnRelease(ITextRange *me)
1514 ITextRangeImpl *This = impl_from_ITextRange(me);
1515 ULONG ref = InterlockedDecrement(&This->ref);
1517 TRACE ("%p ref=%u\n", This, ref);
1518 if (ref == 0)
1520 if (This->child.reole)
1522 list_remove(&This->child.entry);
1523 This->child.reole = NULL;
1525 heap_free(This);
1527 return ref;
1530 static HRESULT WINAPI ITextRange_fnGetTypeInfoCount(ITextRange *me, UINT *pctinfo)
1532 ITextRangeImpl *This = impl_from_ITextRange(me);
1533 TRACE("(%p)->(%p)\n", This, pctinfo);
1534 *pctinfo = 1;
1535 return S_OK;
1538 static HRESULT WINAPI ITextRange_fnGetTypeInfo(ITextRange *me, UINT iTInfo, LCID lcid,
1539 ITypeInfo **ppTInfo)
1541 ITextRangeImpl *This = impl_from_ITextRange(me);
1542 HRESULT hr;
1544 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
1546 hr = get_typeinfo(ITextRange_tid, ppTInfo);
1547 if (SUCCEEDED(hr))
1548 ITypeInfo_AddRef(*ppTInfo);
1549 return hr;
1552 static HRESULT WINAPI ITextRange_fnGetIDsOfNames(ITextRange *me, REFIID riid, LPOLESTR *rgszNames,
1553 UINT cNames, LCID lcid, DISPID *rgDispId)
1555 ITextRangeImpl *This = impl_from_ITextRange(me);
1556 ITypeInfo *ti;
1557 HRESULT hr;
1559 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
1560 rgDispId);
1562 hr = get_typeinfo(ITextRange_tid, &ti);
1563 if (SUCCEEDED(hr))
1564 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
1565 return hr;
1568 static HRESULT WINAPI ITextRange_fnInvoke(ITextRange *me, DISPID dispIdMember, REFIID riid,
1569 LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1570 VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
1571 UINT *puArgErr)
1573 ITextRangeImpl *This = impl_from_ITextRange(me);
1574 ITypeInfo *ti;
1575 HRESULT hr;
1577 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
1578 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1580 hr = get_typeinfo(ITextRange_tid, &ti);
1581 if (SUCCEEDED(hr))
1582 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1583 return hr;
1586 static HRESULT WINAPI ITextRange_fnGetText(ITextRange *me, BSTR *str)
1588 ITextRangeImpl *This = impl_from_ITextRange(me);
1589 ME_TextEditor *editor;
1590 ME_Cursor start, end;
1591 int length;
1592 BOOL bEOP;
1594 TRACE("(%p)->(%p)\n", This, str);
1596 if (!This->child.reole)
1597 return CO_E_RELEASED;
1599 if (!str)
1600 return E_INVALIDARG;
1602 /* return early for degenerate range */
1603 if (This->start == This->end) {
1604 *str = NULL;
1605 return S_OK;
1608 editor = This->child.reole->editor;
1609 ME_CursorFromCharOfs(editor, This->start, &start);
1610 ME_CursorFromCharOfs(editor, This->end, &end);
1612 length = This->end - This->start;
1613 *str = SysAllocStringLen(NULL, length);
1614 if (!*str)
1615 return E_OUTOFMEMORY;
1617 bEOP = (end.pRun->next->type == diTextEnd && This->end > ME_GetTextLength(editor));
1618 ME_GetTextW(editor, *str, length, &start, length, FALSE, bEOP);
1619 return S_OK;
1622 static HRESULT WINAPI ITextRange_fnSetText(ITextRange *me, BSTR str)
1624 ITextRangeImpl *This = impl_from_ITextRange(me);
1625 ME_TextEditor *editor;
1626 ME_Cursor cursor;
1627 ME_Style *style;
1628 int len;
1630 TRACE("(%p)->(%s)\n", This, debugstr_w(str));
1632 if (!This->child.reole)
1633 return CO_E_RELEASED;
1635 editor = This->child.reole->editor;
1637 /* delete only where's something to delete */
1638 if (This->start != This->end) {
1639 ME_CursorFromCharOfs(editor, This->start, &cursor);
1640 ME_InternalDeleteText(editor, &cursor, This->end - This->start, FALSE);
1643 if (!str || !*str) {
1644 /* will update this range as well */
1645 textranges_update_ranges(This->child.reole, This->start, This->end, RANGE_UPDATE_DELETE);
1646 return S_OK;
1649 /* it's safer not to rely on stored BSTR length */
1650 len = strlenW(str);
1651 cursor = editor->pCursors[0];
1652 ME_CursorFromCharOfs(editor, This->start, &editor->pCursors[0]);
1653 style = ME_GetInsertStyle(editor, 0);
1654 ME_InsertTextFromCursor(editor, 0, str, len, style);
1655 ME_ReleaseStyle(style);
1656 editor->pCursors[0] = cursor;
1658 if (len < This->end - This->start)
1659 textranges_update_ranges(This->child.reole, This->start + len, This->end, RANGE_UPDATE_DELETE);
1660 else
1661 This->end = len - This->start;
1663 return S_OK;
1666 static HRESULT range_GetChar(ME_TextEditor *editor, ME_Cursor *cursor, LONG *pch)
1668 WCHAR wch[2];
1670 ME_GetTextW(editor, wch, 1, cursor, 1, FALSE, cursor->pRun->next->type == diTextEnd);
1671 *pch = wch[0];
1673 return S_OK;
1676 static HRESULT WINAPI ITextRange_fnGetChar(ITextRange *me, LONG *pch)
1678 ITextRangeImpl *This = impl_from_ITextRange(me);
1679 ME_TextEditor *editor;
1680 ME_Cursor cursor;
1682 TRACE("(%p)->(%p)\n", This, pch);
1684 if (!This->child.reole)
1685 return CO_E_RELEASED;
1687 if (!pch)
1688 return E_INVALIDARG;
1690 editor = This->child.reole->editor;
1691 ME_CursorFromCharOfs(editor, This->start, &cursor);
1692 return range_GetChar(editor, &cursor, pch);
1695 static HRESULT WINAPI ITextRange_fnSetChar(ITextRange *me, LONG ch)
1697 ITextRangeImpl *This = impl_from_ITextRange(me);
1699 FIXME("(%p)->(%x): stub\n", This, ch);
1701 if (!This->child.reole)
1702 return CO_E_RELEASED;
1704 return E_NOTIMPL;
1707 static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, ITextRange** ppRange);
1709 static HRESULT WINAPI ITextRange_fnGetDuplicate(ITextRange *me, ITextRange **ppRange)
1711 ITextRangeImpl *This = impl_from_ITextRange(me);
1713 TRACE("(%p)->(%p)\n", This, ppRange);
1715 if (!This->child.reole)
1716 return CO_E_RELEASED;
1718 if (!ppRange)
1719 return E_INVALIDARG;
1721 return CreateITextRange(This->child.reole, This->start, This->end, ppRange);
1724 static HRESULT WINAPI ITextRange_fnGetFormattedText(ITextRange *me, ITextRange **range)
1726 ITextRangeImpl *This = impl_from_ITextRange(me);
1728 FIXME("(%p)->(%p): stub\n", This, range);
1730 if (!This->child.reole)
1731 return CO_E_RELEASED;
1733 return E_NOTIMPL;
1736 static HRESULT WINAPI ITextRange_fnSetFormattedText(ITextRange *me, ITextRange *range)
1738 ITextRangeImpl *This = impl_from_ITextRange(me);
1740 FIXME("(%p)->(%p): stub\n", This, range);
1742 if (!This->child.reole)
1743 return CO_E_RELEASED;
1745 return E_NOTIMPL;
1748 static HRESULT WINAPI ITextRange_fnGetStart(ITextRange *me, LONG *start)
1750 ITextRangeImpl *This = impl_from_ITextRange(me);
1752 TRACE("(%p)->(%p)\n", This, start);
1754 if (!This->child.reole)
1755 return CO_E_RELEASED;
1757 if (!start)
1758 return E_INVALIDARG;
1760 *start = This->start;
1761 return S_OK;
1764 static HRESULT textrange_setstart(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end)
1766 int len;
1768 if (value < 0)
1769 value = 0;
1771 if (value == *start)
1772 return S_FALSE;
1774 if (value <= *end) {
1775 *start = value;
1776 return S_OK;
1779 len = ME_GetTextLength(reole->editor);
1780 *start = *end = value > len ? len : value;
1781 return S_OK;
1784 static HRESULT WINAPI ITextRange_fnSetStart(ITextRange *me, LONG value)
1786 ITextRangeImpl *This = impl_from_ITextRange(me);
1788 TRACE("(%p)->(%d)\n", This, value);
1790 if (!This->child.reole)
1791 return CO_E_RELEASED;
1793 return textrange_setstart(This->child.reole, value, &This->start, &This->end);
1796 static HRESULT WINAPI ITextRange_fnGetEnd(ITextRange *me, LONG *end)
1798 ITextRangeImpl *This = impl_from_ITextRange(me);
1800 TRACE("(%p)->(%p)\n", This, end);
1802 if (!This->child.reole)
1803 return CO_E_RELEASED;
1805 if (!end)
1806 return E_INVALIDARG;
1808 *end = This->end;
1809 return S_OK;
1812 static HRESULT textrange_setend(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end)
1814 int len;
1816 if (value == *end)
1817 return S_FALSE;
1819 if (value < *start) {
1820 *start = *end = max(0, value);
1821 return S_OK;
1824 len = ME_GetTextLength(reole->editor);
1825 *end = value > len ? len + 1 : value;
1826 return S_OK;
1829 static HRESULT WINAPI ITextRange_fnSetEnd(ITextRange *me, LONG value)
1831 ITextRangeImpl *This = impl_from_ITextRange(me);
1833 TRACE("(%p)->(%d)\n", This, value);
1835 if (!This->child.reole)
1836 return CO_E_RELEASED;
1838 return textrange_setend(This->child.reole, value, &This->start, &This->end);
1841 static HRESULT WINAPI ITextRange_fnGetFont(ITextRange *me, ITextFont **font)
1843 ITextRangeImpl *This = impl_from_ITextRange(me);
1845 TRACE("(%p)->(%p)\n", This, font);
1847 if (!This->child.reole)
1848 return CO_E_RELEASED;
1850 if (!font)
1851 return E_INVALIDARG;
1853 return create_textfont(me, NULL, font);
1856 static HRESULT WINAPI ITextRange_fnSetFont(ITextRange *me, ITextFont *font)
1858 ITextRangeImpl *This = impl_from_ITextRange(me);
1860 TRACE("(%p)->(%p)\n", This, font);
1862 if (!font)
1863 return E_INVALIDARG;
1865 if (!This->child.reole)
1866 return CO_E_RELEASED;
1868 textrange_set_font(me, font);
1869 return S_OK;
1872 static HRESULT WINAPI ITextRange_fnGetPara(ITextRange *me, ITextPara **para)
1874 ITextRangeImpl *This = impl_from_ITextRange(me);
1876 TRACE("(%p)->(%p)\n", This, para);
1878 if (!This->child.reole)
1879 return CO_E_RELEASED;
1881 if (!para)
1882 return E_INVALIDARG;
1884 return create_textpara(me, para);
1887 static HRESULT WINAPI ITextRange_fnSetPara(ITextRange *me, ITextPara *para)
1889 ITextRangeImpl *This = impl_from_ITextRange(me);
1891 FIXME("(%p)->(%p): stub\n", This, para);
1893 if (!This->child.reole)
1894 return CO_E_RELEASED;
1896 return E_NOTIMPL;
1899 static HRESULT WINAPI ITextRange_fnGetStoryLength(ITextRange *me, LONG *length)
1901 ITextRangeImpl *This = impl_from_ITextRange(me);
1903 TRACE("(%p)->(%p)\n", This, length);
1905 if (!This->child.reole)
1906 return CO_E_RELEASED;
1908 return textrange_get_storylength(This->child.reole->editor, length);
1911 static HRESULT WINAPI ITextRange_fnGetStoryType(ITextRange *me, LONG *value)
1913 ITextRangeImpl *This = impl_from_ITextRange(me);
1915 TRACE("(%p)->(%p)\n", This, value);
1917 if (!This->child.reole)
1918 return CO_E_RELEASED;
1920 if (!value)
1921 return E_INVALIDARG;
1923 *value = tomUnknownStory;
1924 return S_OK;
1927 static HRESULT range_Collapse(LONG bStart, LONG *start, LONG *end)
1929 if (*end == *start)
1930 return S_FALSE;
1932 if (bStart == tomEnd)
1933 *start = *end;
1934 else
1935 *end = *start;
1936 return S_OK;
1939 static HRESULT WINAPI ITextRange_fnCollapse(ITextRange *me, LONG bStart)
1941 ITextRangeImpl *This = impl_from_ITextRange(me);
1943 TRACE("(%p)->(%d)\n", This, bStart);
1945 if (!This->child.reole)
1946 return CO_E_RELEASED;
1948 return range_Collapse(bStart, &This->start, &This->end);
1951 static HRESULT WINAPI ITextRange_fnExpand(ITextRange *me, LONG unit, LONG *delta)
1953 ITextRangeImpl *This = impl_from_ITextRange(me);
1955 TRACE("(%p)->(%d %p)\n", This, unit, delta);
1957 if (!This->child.reole)
1958 return CO_E_RELEASED;
1960 return textrange_expand(me, unit, delta);
1963 static HRESULT WINAPI ITextRange_fnGetIndex(ITextRange *me, LONG unit, LONG *index)
1965 ITextRangeImpl *This = impl_from_ITextRange(me);
1967 FIXME("(%p)->(%d %p): stub\n", This, unit, index);
1969 if (!This->child.reole)
1970 return CO_E_RELEASED;
1972 return E_NOTIMPL;
1975 static HRESULT WINAPI ITextRange_fnSetIndex(ITextRange *me, LONG unit, LONG index,
1976 LONG extend)
1978 ITextRangeImpl *This = impl_from_ITextRange(me);
1980 FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend);
1982 if (!This->child.reole)
1983 return CO_E_RELEASED;
1985 return E_NOTIMPL;
1988 static HRESULT WINAPI ITextRange_fnSetRange(ITextRange *me, LONG anchor, LONG active)
1990 ITextRangeImpl *This = impl_from_ITextRange(me);
1992 FIXME("(%p)->(%d %d): stub\n", This, anchor, active);
1994 if (!This->child.reole)
1995 return CO_E_RELEASED;
1997 return E_NOTIMPL;
2000 static HRESULT textrange_inrange(LONG start, LONG end, ITextRange *range, LONG *ret)
2002 LONG from, to, v;
2004 if (!ret)
2005 ret = &v;
2007 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
2008 *ret = tomFalse;
2010 else
2011 *ret = (start >= from && end <= to) ? tomTrue : tomFalse;
2012 return *ret == tomTrue ? S_OK : S_FALSE;
2015 static HRESULT WINAPI ITextRange_fnInRange(ITextRange *me, ITextRange *range, LONG *ret)
2017 ITextRangeImpl *This = impl_from_ITextRange(me);
2019 TRACE("(%p)->(%p %p)\n", This, range, ret);
2021 if (ret)
2022 *ret = tomFalse;
2024 if (!This->child.reole)
2025 return CO_E_RELEASED;
2027 if (!range)
2028 return S_FALSE;
2030 return textrange_inrange(This->start, This->end, range, ret);
2033 static HRESULT WINAPI ITextRange_fnInStory(ITextRange *me, ITextRange *pRange, LONG *ret)
2035 ITextRangeImpl *This = impl_from_ITextRange(me);
2037 FIXME("(%p)->(%p): stub\n", This, ret);
2039 if (!This->child.reole)
2040 return CO_E_RELEASED;
2042 return E_NOTIMPL;
2045 static HRESULT textrange_isequal(LONG start, LONG end, ITextRange *range, LONG *ret)
2047 LONG from, to, v;
2049 if (!ret)
2050 ret = &v;
2052 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
2053 *ret = tomFalse;
2055 else
2056 *ret = (start == from && end == to) ? tomTrue : tomFalse;
2057 return *ret == tomTrue ? S_OK : S_FALSE;
2060 static HRESULT WINAPI ITextRange_fnIsEqual(ITextRange *me, ITextRange *range, LONG *ret)
2062 ITextRangeImpl *This = impl_from_ITextRange(me);
2064 TRACE("(%p)->(%p %p)\n", This, range, ret);
2066 if (ret)
2067 *ret = tomFalse;
2069 if (!This->child.reole)
2070 return CO_E_RELEASED;
2072 if (!range)
2073 return S_FALSE;
2075 return textrange_isequal(This->start, This->end, range, ret);
2078 static HRESULT WINAPI ITextRange_fnSelect(ITextRange *me)
2080 ITextRangeImpl *This = impl_from_ITextRange(me);
2082 TRACE("(%p)\n", This);
2084 if (!This->child.reole)
2085 return CO_E_RELEASED;
2087 ME_SetSelection(This->child.reole->editor, This->start, This->end);
2088 return S_OK;
2091 static HRESULT WINAPI ITextRange_fnStartOf(ITextRange *me, LONG unit, LONG extend,
2092 LONG *delta)
2094 ITextRangeImpl *This = impl_from_ITextRange(me);
2096 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
2098 if (!This->child.reole)
2099 return CO_E_RELEASED;
2101 return E_NOTIMPL;
2104 static HRESULT WINAPI ITextRange_fnEndOf(ITextRange *me, LONG unit, LONG extend,
2105 LONG *delta)
2107 ITextRangeImpl *This = impl_from_ITextRange(me);
2109 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
2111 if (!This->child.reole)
2112 return CO_E_RELEASED;
2114 return E_NOTIMPL;
2117 static HRESULT WINAPI ITextRange_fnMove(ITextRange *me, LONG unit, LONG count, LONG *delta)
2119 ITextRangeImpl *This = impl_from_ITextRange(me);
2121 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2123 if (!This->child.reole)
2124 return CO_E_RELEASED;
2126 return E_NOTIMPL;
2129 static HRESULT WINAPI ITextRange_fnMoveStart(ITextRange *me, LONG unit, LONG count,
2130 LONG *delta)
2132 ITextRangeImpl *This = impl_from_ITextRange(me);
2134 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2136 if (!This->child.reole)
2137 return CO_E_RELEASED;
2139 return E_NOTIMPL;
2142 static HRESULT WINAPI ITextRange_fnMoveEnd(ITextRange *me, LONG unit, LONG count,
2143 LONG *delta)
2145 ITextRangeImpl *This = impl_from_ITextRange(me);
2147 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2149 if (!This->child.reole)
2150 return CO_E_RELEASED;
2152 return E_NOTIMPL;
2155 static HRESULT WINAPI ITextRange_fnMoveWhile(ITextRange *me, VARIANT *charset, LONG count,
2156 LONG *delta)
2158 ITextRangeImpl *This = impl_from_ITextRange(me);
2160 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2162 if (!This->child.reole)
2163 return CO_E_RELEASED;
2165 return E_NOTIMPL;
2168 static HRESULT WINAPI ITextRange_fnMoveStartWhile(ITextRange *me, VARIANT *charset, LONG count,
2169 LONG *delta)
2171 ITextRangeImpl *This = impl_from_ITextRange(me);
2173 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2175 if (!This->child.reole)
2176 return CO_E_RELEASED;
2178 return E_NOTIMPL;
2181 static HRESULT WINAPI ITextRange_fnMoveEndWhile(ITextRange *me, VARIANT *charset, LONG count,
2182 LONG *delta)
2184 ITextRangeImpl *This = impl_from_ITextRange(me);
2186 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2188 if (!This->child.reole)
2189 return CO_E_RELEASED;
2191 return E_NOTIMPL;
2194 static HRESULT WINAPI ITextRange_fnMoveUntil(ITextRange *me, VARIANT *charset, LONG count,
2195 LONG *delta)
2197 ITextRangeImpl *This = impl_from_ITextRange(me);
2199 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2201 if (!This->child.reole)
2202 return CO_E_RELEASED;
2204 return E_NOTIMPL;
2207 static HRESULT WINAPI ITextRange_fnMoveStartUntil(ITextRange *me, VARIANT *charset, LONG count,
2208 LONG *delta)
2210 ITextRangeImpl *This = impl_from_ITextRange(me);
2212 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2214 if (!This->child.reole)
2215 return CO_E_RELEASED;
2217 return E_NOTIMPL;
2220 static HRESULT WINAPI ITextRange_fnMoveEndUntil(ITextRange *me, VARIANT *charset, LONG count,
2221 LONG *delta)
2223 ITextRangeImpl *This = impl_from_ITextRange(me);
2225 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2227 if (!This->child.reole)
2228 return CO_E_RELEASED;
2230 return E_NOTIMPL;
2233 static HRESULT WINAPI ITextRange_fnFindText(ITextRange *me, BSTR text, LONG count, LONG flags,
2234 LONG *length)
2236 ITextRangeImpl *This = impl_from_ITextRange(me);
2238 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2240 if (!This->child.reole)
2241 return CO_E_RELEASED;
2243 return E_NOTIMPL;
2246 static HRESULT WINAPI ITextRange_fnFindTextStart(ITextRange *me, BSTR text, LONG count,
2247 LONG flags, LONG *length)
2249 ITextRangeImpl *This = impl_from_ITextRange(me);
2251 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2253 if (!This->child.reole)
2254 return CO_E_RELEASED;
2256 return E_NOTIMPL;
2259 static HRESULT WINAPI ITextRange_fnFindTextEnd(ITextRange *me, BSTR text, LONG count,
2260 LONG flags, LONG *length)
2262 ITextRangeImpl *This = impl_from_ITextRange(me);
2264 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2266 if (!This->child.reole)
2267 return CO_E_RELEASED;
2269 return E_NOTIMPL;
2272 static HRESULT WINAPI ITextRange_fnDelete(ITextRange *me, LONG unit, LONG count, LONG *delta)
2274 ITextRangeImpl *This = impl_from_ITextRange(me);
2276 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2278 if (!This->child.reole)
2279 return CO_E_RELEASED;
2281 return E_NOTIMPL;
2284 static HRESULT WINAPI ITextRange_fnCut(ITextRange *me, VARIANT *v)
2286 ITextRangeImpl *This = impl_from_ITextRange(me);
2288 FIXME("(%p)->(%p): stub\n", This, v);
2290 if (!This->child.reole)
2291 return CO_E_RELEASED;
2293 return E_NOTIMPL;
2296 static HRESULT WINAPI ITextRange_fnCopy(ITextRange *me, VARIANT *v)
2298 ITextRangeImpl *This = impl_from_ITextRange(me);
2300 FIXME("(%p)->(%p): stub\n", This, v);
2302 if (!This->child.reole)
2303 return CO_E_RELEASED;
2305 return E_NOTIMPL;
2308 static HRESULT WINAPI ITextRange_fnPaste(ITextRange *me, VARIANT *v, LONG format)
2310 ITextRangeImpl *This = impl_from_ITextRange(me);
2312 FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format);
2314 if (!This->child.reole)
2315 return CO_E_RELEASED;
2317 return E_NOTIMPL;
2320 static HRESULT WINAPI ITextRange_fnCanPaste(ITextRange *me, VARIANT *v, LONG format, LONG *ret)
2322 ITextRangeImpl *This = impl_from_ITextRange(me);
2324 FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret);
2326 if (!This->child.reole)
2327 return CO_E_RELEASED;
2329 return E_NOTIMPL;
2332 static HRESULT WINAPI ITextRange_fnCanEdit(ITextRange *me, LONG *ret)
2334 ITextRangeImpl *This = impl_from_ITextRange(me);
2336 FIXME("(%p)->(%p): stub\n", This, ret);
2338 if (!This->child.reole)
2339 return CO_E_RELEASED;
2341 return E_NOTIMPL;
2344 static HRESULT WINAPI ITextRange_fnChangeCase(ITextRange *me, LONG type)
2346 ITextRangeImpl *This = impl_from_ITextRange(me);
2348 FIXME("(%p)->(%d): stub\n", This, type);
2350 if (!This->child.reole)
2351 return CO_E_RELEASED;
2353 return E_NOTIMPL;
2356 static HRESULT WINAPI ITextRange_fnGetPoint(ITextRange *me, LONG type, LONG *cx, LONG *cy)
2358 ITextRangeImpl *This = impl_from_ITextRange(me);
2360 FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy);
2362 if (!This->child.reole)
2363 return CO_E_RELEASED;
2365 return E_NOTIMPL;
2368 static HRESULT WINAPI ITextRange_fnSetPoint(ITextRange *me, LONG x, LONG y, LONG type,
2369 LONG extend)
2371 ITextRangeImpl *This = impl_from_ITextRange(me);
2373 FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend);
2375 if (!This->child.reole)
2376 return CO_E_RELEASED;
2378 return E_NOTIMPL;
2381 static HRESULT WINAPI ITextRange_fnScrollIntoView(ITextRange *me, LONG value)
2383 ITextRangeImpl *This = impl_from_ITextRange(me);
2384 ME_TextEditor *editor;
2385 ME_Cursor cursor;
2386 int x, y, height;
2388 TRACE("(%p)->(%d)\n", This, value);
2390 if (!This->child.reole)
2391 return CO_E_RELEASED;
2393 editor = This->child.reole->editor;
2395 switch (value)
2397 case tomStart:
2398 ME_CursorFromCharOfs(editor, This->start, &cursor);
2399 ME_GetCursorCoordinates(editor, &cursor, &x, &y, &height);
2400 break;
2401 default:
2402 FIXME("bStart value %d not handled\n", value);
2403 return E_NOTIMPL;
2405 ME_ScrollAbs(editor, x, y);
2406 return S_OK;
2409 static HRESULT WINAPI ITextRange_fnGetEmbeddedObject(ITextRange *me, IUnknown **ppv)
2411 ITextRangeImpl *This = impl_from_ITextRange(me);
2413 FIXME("(%p)->(%p): stub\n", This, ppv);
2415 if (!This->child.reole)
2416 return CO_E_RELEASED;
2418 return E_NOTIMPL;
2421 static const ITextRangeVtbl trvt = {
2422 ITextRange_fnQueryInterface,
2423 ITextRange_fnAddRef,
2424 ITextRange_fnRelease,
2425 ITextRange_fnGetTypeInfoCount,
2426 ITextRange_fnGetTypeInfo,
2427 ITextRange_fnGetIDsOfNames,
2428 ITextRange_fnInvoke,
2429 ITextRange_fnGetText,
2430 ITextRange_fnSetText,
2431 ITextRange_fnGetChar,
2432 ITextRange_fnSetChar,
2433 ITextRange_fnGetDuplicate,
2434 ITextRange_fnGetFormattedText,
2435 ITextRange_fnSetFormattedText,
2436 ITextRange_fnGetStart,
2437 ITextRange_fnSetStart,
2438 ITextRange_fnGetEnd,
2439 ITextRange_fnSetEnd,
2440 ITextRange_fnGetFont,
2441 ITextRange_fnSetFont,
2442 ITextRange_fnGetPara,
2443 ITextRange_fnSetPara,
2444 ITextRange_fnGetStoryLength,
2445 ITextRange_fnGetStoryType,
2446 ITextRange_fnCollapse,
2447 ITextRange_fnExpand,
2448 ITextRange_fnGetIndex,
2449 ITextRange_fnSetIndex,
2450 ITextRange_fnSetRange,
2451 ITextRange_fnInRange,
2452 ITextRange_fnInStory,
2453 ITextRange_fnIsEqual,
2454 ITextRange_fnSelect,
2455 ITextRange_fnStartOf,
2456 ITextRange_fnEndOf,
2457 ITextRange_fnMove,
2458 ITextRange_fnMoveStart,
2459 ITextRange_fnMoveEnd,
2460 ITextRange_fnMoveWhile,
2461 ITextRange_fnMoveStartWhile,
2462 ITextRange_fnMoveEndWhile,
2463 ITextRange_fnMoveUntil,
2464 ITextRange_fnMoveStartUntil,
2465 ITextRange_fnMoveEndUntil,
2466 ITextRange_fnFindText,
2467 ITextRange_fnFindTextStart,
2468 ITextRange_fnFindTextEnd,
2469 ITextRange_fnDelete,
2470 ITextRange_fnCut,
2471 ITextRange_fnCopy,
2472 ITextRange_fnPaste,
2473 ITextRange_fnCanPaste,
2474 ITextRange_fnCanEdit,
2475 ITextRange_fnChangeCase,
2476 ITextRange_fnGetPoint,
2477 ITextRange_fnSetPoint,
2478 ITextRange_fnScrollIntoView,
2479 ITextRange_fnGetEmbeddedObject
2482 /* ITextFont */
2483 static HRESULT WINAPI TextFont_QueryInterface(ITextFont *iface, REFIID riid, void **ppv)
2485 ITextFontImpl *This = impl_from_ITextFont(iface);
2487 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
2489 if (IsEqualIID(riid, &IID_ITextFont) ||
2490 IsEqualIID(riid, &IID_IDispatch) ||
2491 IsEqualIID(riid, &IID_IUnknown))
2493 *ppv = iface;
2494 ITextFont_AddRef(iface);
2495 return S_OK;
2498 *ppv = NULL;
2499 return E_NOINTERFACE;
2502 static ULONG WINAPI TextFont_AddRef(ITextFont *iface)
2504 ITextFontImpl *This = impl_from_ITextFont(iface);
2505 ULONG ref = InterlockedIncrement(&This->ref);
2506 TRACE("(%p)->(%u)\n", This, ref);
2507 return ref;
2510 static ULONG WINAPI TextFont_Release(ITextFont *iface)
2512 ITextFontImpl *This = impl_from_ITextFont(iface);
2513 ULONG ref = InterlockedDecrement(&This->ref);
2515 TRACE("(%p)->(%u)\n", This, ref);
2517 if (!ref)
2519 if (This->range)
2520 ITextRange_Release(This->range);
2521 SysFreeString(This->props[FONT_NAME].str);
2522 heap_free(This);
2525 return ref;
2528 static HRESULT WINAPI TextFont_GetTypeInfoCount(ITextFont *iface, UINT *pctinfo)
2530 ITextFontImpl *This = impl_from_ITextFont(iface);
2531 TRACE("(%p)->(%p)\n", This, pctinfo);
2532 *pctinfo = 1;
2533 return S_OK;
2536 static HRESULT WINAPI TextFont_GetTypeInfo(ITextFont *iface, UINT iTInfo, LCID lcid,
2537 ITypeInfo **ppTInfo)
2539 ITextFontImpl *This = impl_from_ITextFont(iface);
2540 HRESULT hr;
2542 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
2544 hr = get_typeinfo(ITextFont_tid, ppTInfo);
2545 if (SUCCEEDED(hr))
2546 ITypeInfo_AddRef(*ppTInfo);
2547 return hr;
2550 static HRESULT WINAPI TextFont_GetIDsOfNames(ITextFont *iface, REFIID riid,
2551 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
2553 ITextFontImpl *This = impl_from_ITextFont(iface);
2554 ITypeInfo *ti;
2555 HRESULT hr;
2557 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid),
2558 rgszNames, cNames, lcid, rgDispId);
2560 hr = get_typeinfo(ITextFont_tid, &ti);
2561 if (SUCCEEDED(hr))
2562 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
2563 return hr;
2566 static HRESULT WINAPI TextFont_Invoke(
2567 ITextFont *iface,
2568 DISPID dispIdMember,
2569 REFIID riid,
2570 LCID lcid,
2571 WORD wFlags,
2572 DISPPARAMS *pDispParams,
2573 VARIANT *pVarResult,
2574 EXCEPINFO *pExcepInfo,
2575 UINT *puArgErr)
2577 ITextFontImpl *This = impl_from_ITextFont(iface);
2578 ITypeInfo *ti;
2579 HRESULT hr;
2581 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
2582 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2584 hr = get_typeinfo(ITextFont_tid, &ti);
2585 if (SUCCEEDED(hr))
2586 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2587 return hr;
2590 static HRESULT WINAPI TextFont_GetDuplicate(ITextFont *iface, ITextFont **ret)
2592 ITextFontImpl *This = impl_from_ITextFont(iface);
2594 TRACE("(%p)->(%p)\n", This, ret);
2596 if (!ret)
2597 return E_INVALIDARG;
2599 *ret = NULL;
2600 if (This->range && !get_range_reole(This->range))
2601 return CO_E_RELEASED;
2603 return create_textfont(NULL, This, ret);
2606 static HRESULT WINAPI TextFont_SetDuplicate(ITextFont *iface, ITextFont *pFont)
2608 ITextFontImpl *This = impl_from_ITextFont(iface);
2609 FIXME("(%p)->(%p): stub\n", This, pFont);
2610 return E_NOTIMPL;
2613 static HRESULT WINAPI TextFont_CanChange(ITextFont *iface, LONG *ret)
2615 ITextFontImpl *This = impl_from_ITextFont(iface);
2616 FIXME("(%p)->(%p): stub\n", This, ret);
2617 return E_NOTIMPL;
2620 static HRESULT WINAPI TextFont_IsEqual(ITextFont *iface, ITextFont *font, LONG *ret)
2622 ITextFontImpl *This = impl_from_ITextFont(iface);
2623 FIXME("(%p)->(%p %p): stub\n", This, font, ret);
2624 return E_NOTIMPL;
2627 static void textfont_reset_to_default(ITextFontImpl *font)
2629 enum textfont_prop_id id;
2631 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2632 switch (id)
2634 case FONT_ALLCAPS:
2635 case FONT_ANIMATION:
2636 case FONT_BOLD:
2637 case FONT_EMBOSS:
2638 case FONT_HIDDEN:
2639 case FONT_ENGRAVE:
2640 case FONT_ITALIC:
2641 case FONT_OUTLINE:
2642 case FONT_PROTECTED:
2643 case FONT_SHADOW:
2644 case FONT_SMALLCAPS:
2645 case FONT_STRIKETHROUGH:
2646 case FONT_SUBSCRIPT:
2647 case FONT_SUPERSCRIPT:
2648 case FONT_UNDERLINE:
2649 font->props[id].l = tomFalse;
2650 break;
2651 case FONT_BACKCOLOR:
2652 case FONT_FORECOLOR:
2653 font->props[id].l = tomAutoColor;
2654 break;
2655 case FONT_KERNING:
2656 case FONT_POSITION:
2657 case FONT_SIZE:
2658 case FONT_SPACING:
2659 font->props[id].f = 0.0;
2660 break;
2661 case FONT_LANGID:
2662 font->props[id].l = GetSystemDefaultLCID();
2663 break;
2664 case FONT_NAME: {
2665 static const WCHAR sysW[] = {'S','y','s','t','e','m',0};
2666 SysFreeString(font->props[id].str);
2667 font->props[id].str = SysAllocString(sysW);
2668 break;
2670 case FONT_WEIGHT:
2671 font->props[id].l = FW_NORMAL;
2672 break;
2673 default:
2674 FIXME("font property %d not handled\n", id);
2679 static void textfont_reset_to_undefined(ITextFontImpl *font)
2681 enum textfont_prop_id id;
2683 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2684 switch (id)
2686 case FONT_ALLCAPS:
2687 case FONT_ANIMATION:
2688 case FONT_BOLD:
2689 case FONT_EMBOSS:
2690 case FONT_HIDDEN:
2691 case FONT_ENGRAVE:
2692 case FONT_ITALIC:
2693 case FONT_OUTLINE:
2694 case FONT_PROTECTED:
2695 case FONT_SHADOW:
2696 case FONT_SMALLCAPS:
2697 case FONT_STRIKETHROUGH:
2698 case FONT_SUBSCRIPT:
2699 case FONT_SUPERSCRIPT:
2700 case FONT_UNDERLINE:
2701 case FONT_BACKCOLOR:
2702 case FONT_FORECOLOR:
2703 case FONT_LANGID:
2704 case FONT_WEIGHT:
2705 font->props[id].l = tomUndefined;
2706 break;
2707 case FONT_KERNING:
2708 case FONT_POSITION:
2709 case FONT_SIZE:
2710 case FONT_SPACING:
2711 font->props[id].f = tomUndefined;
2712 break;
2713 case FONT_NAME:
2714 break;
2715 default:
2716 FIXME("font property %d not handled\n", id);
2721 static void textfont_apply_range_props(ITextFontImpl *font)
2723 enum textfont_prop_id propid;
2724 for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++)
2725 set_textfont_prop(font, propid, &font->props[propid]);
2728 static HRESULT WINAPI TextFont_Reset(ITextFont *iface, LONG value)
2730 ITextFontImpl *This = impl_from_ITextFont(iface);
2732 TRACE("(%p)->(%d)\n", This, value);
2734 /* If font is attached to a range, released or not, we can't
2735 reset to undefined */
2736 if (This->range) {
2737 if (!get_range_reole(This->range))
2738 return CO_E_RELEASED;
2740 switch (value)
2742 case tomUndefined:
2743 return E_INVALIDARG;
2744 case tomCacheParms:
2745 textfont_cache_range_props(This);
2746 This->get_cache_enabled = TRUE;
2747 break;
2748 case tomTrackParms:
2749 This->get_cache_enabled = FALSE;
2750 break;
2751 case tomApplyLater:
2752 This->set_cache_enabled = TRUE;
2753 break;
2754 case tomApplyNow:
2755 This->set_cache_enabled = FALSE;
2756 textfont_apply_range_props(This);
2757 break;
2758 case tomUsePoints:
2759 case tomUseTwips:
2760 return E_INVALIDARG;
2761 default:
2762 FIXME("reset mode %d not supported\n", value);
2765 return S_OK;
2767 else {
2768 switch (value)
2770 /* reset to global defaults */
2771 case tomDefault:
2772 textfont_reset_to_default(This);
2773 return S_OK;
2774 /* all properties are set to tomUndefined, font name is retained */
2775 case tomUndefined:
2776 textfont_reset_to_undefined(This);
2777 return S_OK;
2778 case tomApplyNow:
2779 case tomApplyLater:
2780 case tomTrackParms:
2781 case tomCacheParms:
2782 return S_OK;
2783 case tomUsePoints:
2784 case tomUseTwips:
2785 return E_INVALIDARG;
2789 FIXME("reset mode %d not supported\n", value);
2790 return E_NOTIMPL;
2793 static HRESULT WINAPI TextFont_GetStyle(ITextFont *iface, LONG *value)
2795 ITextFontImpl *This = impl_from_ITextFont(iface);
2796 FIXME("(%p)->(%p): stub\n", This, value);
2797 return E_NOTIMPL;
2800 static HRESULT WINAPI TextFont_SetStyle(ITextFont *iface, LONG value)
2802 ITextFontImpl *This = impl_from_ITextFont(iface);
2803 FIXME("(%p)->(%d): stub\n", This, value);
2804 return E_NOTIMPL;
2807 static HRESULT WINAPI TextFont_GetAllCaps(ITextFont *iface, LONG *value)
2809 ITextFontImpl *This = impl_from_ITextFont(iface);
2810 TRACE("(%p)->(%p)\n", This, value);
2811 return get_textfont_propl(This, FONT_ALLCAPS, value);
2814 static HRESULT WINAPI TextFont_SetAllCaps(ITextFont *iface, LONG value)
2816 ITextFontImpl *This = impl_from_ITextFont(iface);
2817 TRACE("(%p)->(%d)\n", This, value);
2818 return set_textfont_propd(This, FONT_ALLCAPS, value);
2821 static HRESULT WINAPI TextFont_GetAnimation(ITextFont *iface, LONG *value)
2823 ITextFontImpl *This = impl_from_ITextFont(iface);
2824 TRACE("(%p)->(%p)\n", This, value);
2825 return get_textfont_propl(This, FONT_ANIMATION, value);
2828 static HRESULT WINAPI TextFont_SetAnimation(ITextFont *iface, LONG value)
2830 ITextFontImpl *This = impl_from_ITextFont(iface);
2832 TRACE("(%p)->(%d)\n", This, value);
2834 if (value < tomNoAnimation || value > tomAnimationMax)
2835 return E_INVALIDARG;
2837 return set_textfont_propl(This, FONT_ANIMATION, value);
2840 static HRESULT WINAPI TextFont_GetBackColor(ITextFont *iface, LONG *value)
2842 ITextFontImpl *This = impl_from_ITextFont(iface);
2843 TRACE("(%p)->(%p)\n", This, value);
2844 return get_textfont_propl(This, FONT_BACKCOLOR, value);
2847 static HRESULT WINAPI TextFont_SetBackColor(ITextFont *iface, LONG value)
2849 ITextFontImpl *This = impl_from_ITextFont(iface);
2850 TRACE("(%p)->(%d)\n", This, value);
2851 return set_textfont_propl(This, FONT_BACKCOLOR, value);
2854 static HRESULT WINAPI TextFont_GetBold(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_BOLD, value);
2861 static HRESULT WINAPI TextFont_SetBold(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_BOLD, value);
2868 static HRESULT WINAPI TextFont_GetEmboss(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_EMBOSS, value);
2875 static HRESULT WINAPI TextFont_SetEmboss(ITextFont *iface, LONG value)
2877 ITextFontImpl *This = impl_from_ITextFont(iface);
2878 TRACE("(%p)->(%d)\n", This, value);
2879 return set_textfont_propd(This, FONT_EMBOSS, value);
2882 static HRESULT WINAPI TextFont_GetForeColor(ITextFont *iface, LONG *value)
2884 ITextFontImpl *This = impl_from_ITextFont(iface);
2885 TRACE("(%p)->(%p)\n", This, value);
2886 return get_textfont_propl(This, FONT_FORECOLOR, value);
2889 static HRESULT WINAPI TextFont_SetForeColor(ITextFont *iface, LONG value)
2891 ITextFontImpl *This = impl_from_ITextFont(iface);
2892 TRACE("(%p)->(%d)\n", This, value);
2893 return set_textfont_propl(This, FONT_FORECOLOR, value);
2896 static HRESULT WINAPI TextFont_GetHidden(ITextFont *iface, LONG *value)
2898 ITextFontImpl *This = impl_from_ITextFont(iface);
2899 TRACE("(%p)->(%p)\n", This, value);
2900 return get_textfont_propl(This, FONT_HIDDEN, value);
2903 static HRESULT WINAPI TextFont_SetHidden(ITextFont *iface, LONG value)
2905 ITextFontImpl *This = impl_from_ITextFont(iface);
2906 TRACE("(%p)->(%d)\n", This, value);
2907 return set_textfont_propd(This, FONT_HIDDEN, value);
2910 static HRESULT WINAPI TextFont_GetEngrave(ITextFont *iface, LONG *value)
2912 ITextFontImpl *This = impl_from_ITextFont(iface);
2913 TRACE("(%p)->(%p)\n", This, value);
2914 return get_textfont_propl(This, FONT_ENGRAVE, value);
2917 static HRESULT WINAPI TextFont_SetEngrave(ITextFont *iface, LONG value)
2919 ITextFontImpl *This = impl_from_ITextFont(iface);
2920 TRACE("(%p)->(%d)\n", This, value);
2921 return set_textfont_propd(This, FONT_ENGRAVE, value);
2924 static HRESULT WINAPI TextFont_GetItalic(ITextFont *iface, LONG *value)
2926 ITextFontImpl *This = impl_from_ITextFont(iface);
2927 TRACE("(%p)->(%p)\n", This, value);
2928 return get_textfont_propl(This, FONT_ITALIC, value);
2931 static HRESULT WINAPI TextFont_SetItalic(ITextFont *iface, LONG value)
2933 ITextFontImpl *This = impl_from_ITextFont(iface);
2934 TRACE("(%p)->(%d)\n", This, value);
2935 return set_textfont_propd(This, FONT_ITALIC, value);
2938 static HRESULT WINAPI TextFont_GetKerning(ITextFont *iface, FLOAT *value)
2940 ITextFontImpl *This = impl_from_ITextFont(iface);
2941 TRACE("(%p)->(%p)\n", This, value);
2942 return get_textfont_propf(This, FONT_KERNING, value);
2945 static HRESULT WINAPI TextFont_SetKerning(ITextFont *iface, FLOAT value)
2947 ITextFontImpl *This = impl_from_ITextFont(iface);
2948 TRACE("(%p)->(%.2f)\n", This, value);
2949 return set_textfont_propf(This, FONT_KERNING, value);
2952 static HRESULT WINAPI TextFont_GetLanguageID(ITextFont *iface, LONG *value)
2954 ITextFontImpl *This = impl_from_ITextFont(iface);
2955 TRACE("(%p)->(%p)\n", This, value);
2956 return get_textfont_propl(This, FONT_LANGID, value);
2959 static HRESULT WINAPI TextFont_SetLanguageID(ITextFont *iface, LONG value)
2961 ITextFontImpl *This = impl_from_ITextFont(iface);
2962 TRACE("(%p)->(%d)\n", This, value);
2963 return set_textfont_propl(This, FONT_LANGID, value);
2966 static HRESULT WINAPI TextFont_GetName(ITextFont *iface, BSTR *value)
2968 ITextFontImpl *This = impl_from_ITextFont(iface);
2970 TRACE("(%p)->(%p)\n", This, value);
2972 if (!value)
2973 return E_INVALIDARG;
2975 *value = NULL;
2977 if (!This->range) {
2978 if (This->props[FONT_NAME].str)
2979 *value = SysAllocString(This->props[FONT_NAME].str);
2980 else
2981 *value = SysAllocStringLen(NULL, 0);
2982 return *value ? S_OK : E_OUTOFMEMORY;
2985 return textfont_getname_from_range(This->range, value);
2988 static HRESULT WINAPI TextFont_SetName(ITextFont *iface, BSTR value)
2990 ITextFontImpl *This = impl_from_ITextFont(iface);
2991 textfont_prop_val v;
2993 TRACE("(%p)->(%s)\n", This, debugstr_w(value));
2995 v.str = value;
2996 return set_textfont_prop(This, FONT_NAME, &v);
2999 static HRESULT WINAPI TextFont_GetOutline(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_OUTLINE, value);
3006 static HRESULT WINAPI TextFont_SetOutline(ITextFont *iface, LONG value)
3008 ITextFontImpl *This = impl_from_ITextFont(iface);
3009 TRACE("(%p)->(%d)\n", This, value);
3010 return set_textfont_propd(This, FONT_OUTLINE, value);
3013 static HRESULT WINAPI TextFont_GetPosition(ITextFont *iface, FLOAT *value)
3015 ITextFontImpl *This = impl_from_ITextFont(iface);
3016 TRACE("(%p)->(%p)\n", This, value);
3017 return get_textfont_propf(This, FONT_POSITION, value);
3020 static HRESULT WINAPI TextFont_SetPosition(ITextFont *iface, FLOAT value)
3022 ITextFontImpl *This = impl_from_ITextFont(iface);
3023 TRACE("(%p)->(%.2f)\n", This, value);
3024 return set_textfont_propf(This, FONT_POSITION, value);
3027 static HRESULT WINAPI TextFont_GetProtected(ITextFont *iface, LONG *value)
3029 ITextFontImpl *This = impl_from_ITextFont(iface);
3030 TRACE("(%p)->(%p)\n", This, value);
3031 return get_textfont_propl(This, FONT_PROTECTED, value);
3034 static HRESULT WINAPI TextFont_SetProtected(ITextFont *iface, LONG value)
3036 ITextFontImpl *This = impl_from_ITextFont(iface);
3037 TRACE("(%p)->(%d)\n", This, value);
3038 return set_textfont_propd(This, FONT_PROTECTED, value);
3041 static HRESULT WINAPI TextFont_GetShadow(ITextFont *iface, LONG *value)
3043 ITextFontImpl *This = impl_from_ITextFont(iface);
3044 TRACE("(%p)->(%p)\n", This, value);
3045 return get_textfont_propl(This, FONT_SHADOW, value);
3048 static HRESULT WINAPI TextFont_SetShadow(ITextFont *iface, LONG value)
3050 ITextFontImpl *This = impl_from_ITextFont(iface);
3051 TRACE("(%p)->(%d)\n", This, value);
3052 return set_textfont_propd(This, FONT_SHADOW, value);
3055 static HRESULT WINAPI TextFont_GetSize(ITextFont *iface, FLOAT *value)
3057 ITextFontImpl *This = impl_from_ITextFont(iface);
3058 TRACE("(%p)->(%p)\n", This, value);
3059 return get_textfont_propf(This, FONT_SIZE, value);
3062 static HRESULT WINAPI TextFont_SetSize(ITextFont *iface, FLOAT value)
3064 ITextFontImpl *This = impl_from_ITextFont(iface);
3065 TRACE("(%p)->(%.2f)\n", This, value);
3066 return set_textfont_propf(This, FONT_SIZE, value);
3069 static HRESULT WINAPI TextFont_GetSmallCaps(ITextFont *iface, LONG *value)
3071 ITextFontImpl *This = impl_from_ITextFont(iface);
3072 TRACE("(%p)->(%p)\n", This, value);
3073 return get_textfont_propl(This, FONT_SMALLCAPS, value);
3076 static HRESULT WINAPI TextFont_SetSmallCaps(ITextFont *iface, LONG value)
3078 ITextFontImpl *This = impl_from_ITextFont(iface);
3079 TRACE("(%p)->(%d)\n", This, value);
3080 return set_textfont_propd(This, FONT_SMALLCAPS, value);
3083 static HRESULT WINAPI TextFont_GetSpacing(ITextFont *iface, FLOAT *value)
3085 ITextFontImpl *This = impl_from_ITextFont(iface);
3086 TRACE("(%p)->(%p)\n", This, value);
3087 return get_textfont_propf(This, FONT_SPACING, value);
3090 static HRESULT WINAPI TextFont_SetSpacing(ITextFont *iface, FLOAT value)
3092 ITextFontImpl *This = impl_from_ITextFont(iface);
3093 TRACE("(%p)->(%.2f)\n", This, value);
3094 return set_textfont_propf(This, FONT_SPACING, value);
3097 static HRESULT WINAPI TextFont_GetStrikeThrough(ITextFont *iface, LONG *value)
3099 ITextFontImpl *This = impl_from_ITextFont(iface);
3100 TRACE("(%p)->(%p)\n", This, value);
3101 return get_textfont_propl(This, FONT_STRIKETHROUGH, value);
3104 static HRESULT WINAPI TextFont_SetStrikeThrough(ITextFont *iface, LONG value)
3106 ITextFontImpl *This = impl_from_ITextFont(iface);
3107 TRACE("(%p)->(%d)\n", This, value);
3108 return set_textfont_propd(This, FONT_STRIKETHROUGH, value);
3111 static HRESULT WINAPI TextFont_GetSubscript(ITextFont *iface, LONG *value)
3113 ITextFontImpl *This = impl_from_ITextFont(iface);
3114 TRACE("(%p)->(%p)\n", This, value);
3115 return get_textfont_propl(This, FONT_SUBSCRIPT, value);
3118 static HRESULT WINAPI TextFont_SetSubscript(ITextFont *iface, LONG value)
3120 ITextFontImpl *This = impl_from_ITextFont(iface);
3121 TRACE("(%p)->(%d)\n", This, value);
3122 return set_textfont_propd(This, FONT_SUBSCRIPT, value);
3125 static HRESULT WINAPI TextFont_GetSuperscript(ITextFont *iface, LONG *value)
3127 ITextFontImpl *This = impl_from_ITextFont(iface);
3128 TRACE("(%p)->(%p)\n", This, value);
3129 return get_textfont_propl(This, FONT_SUPERSCRIPT, value);
3132 static HRESULT WINAPI TextFont_SetSuperscript(ITextFont *iface, LONG value)
3134 ITextFontImpl *This = impl_from_ITextFont(iface);
3135 TRACE("(%p)->(%d)\n", This, value);
3136 return set_textfont_propd(This, FONT_SUPERSCRIPT, value);
3139 static HRESULT WINAPI TextFont_GetUnderline(ITextFont *iface, LONG *value)
3141 ITextFontImpl *This = impl_from_ITextFont(iface);
3142 TRACE("(%p)->(%p)\n", This, value);
3143 return get_textfont_propl(This, FONT_UNDERLINE, value);
3146 static HRESULT WINAPI TextFont_SetUnderline(ITextFont *iface, LONG value)
3148 ITextFontImpl *This = impl_from_ITextFont(iface);
3149 TRACE("(%p)->(%d)\n", This, value);
3150 return set_textfont_propd(This, FONT_UNDERLINE, value);
3153 static HRESULT WINAPI TextFont_GetWeight(ITextFont *iface, LONG *value)
3155 ITextFontImpl *This = impl_from_ITextFont(iface);
3156 TRACE("(%p)->(%p)\n", This, value);
3157 return get_textfont_propl(This, FONT_WEIGHT, value);
3160 static HRESULT WINAPI TextFont_SetWeight(ITextFont *iface, LONG value)
3162 ITextFontImpl *This = impl_from_ITextFont(iface);
3163 TRACE("(%p)->(%d)\n", This, value);
3164 return set_textfont_propl(This, FONT_WEIGHT, value);
3167 static ITextFontVtbl textfontvtbl = {
3168 TextFont_QueryInterface,
3169 TextFont_AddRef,
3170 TextFont_Release,
3171 TextFont_GetTypeInfoCount,
3172 TextFont_GetTypeInfo,
3173 TextFont_GetIDsOfNames,
3174 TextFont_Invoke,
3175 TextFont_GetDuplicate,
3176 TextFont_SetDuplicate,
3177 TextFont_CanChange,
3178 TextFont_IsEqual,
3179 TextFont_Reset,
3180 TextFont_GetStyle,
3181 TextFont_SetStyle,
3182 TextFont_GetAllCaps,
3183 TextFont_SetAllCaps,
3184 TextFont_GetAnimation,
3185 TextFont_SetAnimation,
3186 TextFont_GetBackColor,
3187 TextFont_SetBackColor,
3188 TextFont_GetBold,
3189 TextFont_SetBold,
3190 TextFont_GetEmboss,
3191 TextFont_SetEmboss,
3192 TextFont_GetForeColor,
3193 TextFont_SetForeColor,
3194 TextFont_GetHidden,
3195 TextFont_SetHidden,
3196 TextFont_GetEngrave,
3197 TextFont_SetEngrave,
3198 TextFont_GetItalic,
3199 TextFont_SetItalic,
3200 TextFont_GetKerning,
3201 TextFont_SetKerning,
3202 TextFont_GetLanguageID,
3203 TextFont_SetLanguageID,
3204 TextFont_GetName,
3205 TextFont_SetName,
3206 TextFont_GetOutline,
3207 TextFont_SetOutline,
3208 TextFont_GetPosition,
3209 TextFont_SetPosition,
3210 TextFont_GetProtected,
3211 TextFont_SetProtected,
3212 TextFont_GetShadow,
3213 TextFont_SetShadow,
3214 TextFont_GetSize,
3215 TextFont_SetSize,
3216 TextFont_GetSmallCaps,
3217 TextFont_SetSmallCaps,
3218 TextFont_GetSpacing,
3219 TextFont_SetSpacing,
3220 TextFont_GetStrikeThrough,
3221 TextFont_SetStrikeThrough,
3222 TextFont_GetSubscript,
3223 TextFont_SetSubscript,
3224 TextFont_GetSuperscript,
3225 TextFont_SetSuperscript,
3226 TextFont_GetUnderline,
3227 TextFont_SetUnderline,
3228 TextFont_GetWeight,
3229 TextFont_SetWeight
3232 static HRESULT create_textfont(ITextRange *range, const ITextFontImpl *src, ITextFont **ret)
3234 ITextFontImpl *font;
3236 *ret = NULL;
3237 font = heap_alloc(sizeof(*font));
3238 if (!font)
3239 return E_OUTOFMEMORY;
3241 font->ITextFont_iface.lpVtbl = &textfontvtbl;
3242 font->ref = 1;
3244 if (src) {
3245 font->range = NULL;
3246 font->get_cache_enabled = TRUE;
3247 font->set_cache_enabled = TRUE;
3248 memcpy(&font->props, &src->props, sizeof(font->props));
3249 if (font->props[FONT_NAME].str)
3250 font->props[FONT_NAME].str = SysAllocString(font->props[FONT_NAME].str);
3252 else {
3253 font->range = range;
3254 ITextRange_AddRef(range);
3256 /* cache current properties */
3257 font->get_cache_enabled = FALSE;
3258 font->set_cache_enabled = FALSE;
3259 textfont_cache_range_props(font);
3262 *ret = &font->ITextFont_iface;
3263 return S_OK;
3266 /* ITextPara */
3267 static HRESULT WINAPI TextPara_QueryInterface(ITextPara *iface, REFIID riid, void **ppv)
3269 ITextParaImpl *This = impl_from_ITextPara(iface);
3271 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
3273 if (IsEqualIID(riid, &IID_ITextPara) ||
3274 IsEqualIID(riid, &IID_IDispatch) ||
3275 IsEqualIID(riid, &IID_IUnknown))
3277 *ppv = iface;
3278 ITextPara_AddRef(iface);
3279 return S_OK;
3282 *ppv = NULL;
3283 return E_NOINTERFACE;
3286 static ULONG WINAPI TextPara_AddRef(ITextPara *iface)
3288 ITextParaImpl *This = impl_from_ITextPara(iface);
3289 ULONG ref = InterlockedIncrement(&This->ref);
3290 TRACE("(%p)->(%u)\n", This, ref);
3291 return ref;
3294 static ULONG WINAPI TextPara_Release(ITextPara *iface)
3296 ITextParaImpl *This = impl_from_ITextPara(iface);
3297 ULONG ref = InterlockedDecrement(&This->ref);
3299 TRACE("(%p)->(%u)\n", This, ref);
3301 if (!ref)
3303 ITextRange_Release(This->range);
3304 heap_free(This);
3307 return ref;
3310 static HRESULT WINAPI TextPara_GetTypeInfoCount(ITextPara *iface, UINT *pctinfo)
3312 ITextParaImpl *This = impl_from_ITextPara(iface);
3313 TRACE("(%p)->(%p)\n", This, pctinfo);
3314 *pctinfo = 1;
3315 return S_OK;
3318 static HRESULT WINAPI TextPara_GetTypeInfo(ITextPara *iface, UINT iTInfo, LCID lcid,
3319 ITypeInfo **ppTInfo)
3321 ITextParaImpl *This = impl_from_ITextPara(iface);
3322 HRESULT hr;
3324 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
3326 hr = get_typeinfo(ITextPara_tid, ppTInfo);
3327 if (SUCCEEDED(hr))
3328 ITypeInfo_AddRef(*ppTInfo);
3329 return hr;
3332 static HRESULT WINAPI TextPara_GetIDsOfNames(ITextPara *iface, REFIID riid,
3333 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
3335 ITextParaImpl *This = impl_from_ITextPara(iface);
3336 ITypeInfo *ti;
3337 HRESULT hr;
3339 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames,
3340 cNames, lcid, rgDispId);
3342 hr = get_typeinfo(ITextPara_tid, &ti);
3343 if (SUCCEEDED(hr))
3344 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
3345 return hr;
3348 static HRESULT WINAPI TextPara_Invoke(
3349 ITextPara *iface,
3350 DISPID dispIdMember,
3351 REFIID riid,
3352 LCID lcid,
3353 WORD wFlags,
3354 DISPPARAMS *pDispParams,
3355 VARIANT *pVarResult,
3356 EXCEPINFO *pExcepInfo,
3357 UINT *puArgErr)
3359 ITextParaImpl *This = impl_from_ITextPara(iface);
3360 ITypeInfo *ti;
3361 HRESULT hr;
3363 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember,
3364 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
3365 pExcepInfo, puArgErr);
3367 hr = get_typeinfo(ITextPara_tid, &ti);
3368 if (SUCCEEDED(hr))
3369 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3370 return hr;
3373 static HRESULT WINAPI TextPara_GetDuplicate(ITextPara *iface, ITextPara **ret)
3375 ITextParaImpl *This = impl_from_ITextPara(iface);
3376 FIXME("(%p)->(%p)\n", This, ret);
3377 return E_NOTIMPL;
3380 static HRESULT WINAPI TextPara_SetDuplicate(ITextPara *iface, ITextPara *para)
3382 ITextParaImpl *This = impl_from_ITextPara(iface);
3383 FIXME("(%p)->(%p)\n", This, para);
3384 return E_NOTIMPL;
3387 static HRESULT WINAPI TextPara_CanChange(ITextPara *iface, LONG *ret)
3389 ITextParaImpl *This = impl_from_ITextPara(iface);
3390 FIXME("(%p)->(%p)\n", This, ret);
3391 return E_NOTIMPL;
3394 static HRESULT WINAPI TextPara_IsEqual(ITextPara *iface, ITextPara *para, LONG *ret)
3396 ITextParaImpl *This = impl_from_ITextPara(iface);
3397 FIXME("(%p)->(%p %p)\n", This, para, ret);
3398 return E_NOTIMPL;
3401 static HRESULT WINAPI TextPara_Reset(ITextPara *iface, LONG value)
3403 ITextParaImpl *This = impl_from_ITextPara(iface);
3404 FIXME("(%p)->(%d)\n", This, value);
3405 return E_NOTIMPL;
3408 static HRESULT WINAPI TextPara_GetStyle(ITextPara *iface, LONG *value)
3410 ITextParaImpl *This = impl_from_ITextPara(iface);
3411 FIXME("(%p)->(%p)\n", This, value);
3412 return E_NOTIMPL;
3415 static HRESULT WINAPI TextPara_SetStyle(ITextPara *iface, LONG value)
3417 ITextParaImpl *This = impl_from_ITextPara(iface);
3418 FIXME("(%p)->(%d)\n", This, value);
3419 return E_NOTIMPL;
3422 static HRESULT WINAPI TextPara_GetAlignment(ITextPara *iface, LONG *value)
3424 ITextParaImpl *This = impl_from_ITextPara(iface);
3425 FIXME("(%p)->(%p)\n", This, value);
3426 return E_NOTIMPL;
3429 static HRESULT WINAPI TextPara_SetAlignment(ITextPara *iface, LONG value)
3431 ITextParaImpl *This = impl_from_ITextPara(iface);
3432 FIXME("(%p)->(%d)\n", This, value);
3433 return E_NOTIMPL;
3436 static HRESULT WINAPI TextPara_GetHyphenation(ITextPara *iface, LONG *value)
3438 ITextParaImpl *This = impl_from_ITextPara(iface);
3439 FIXME("(%p)->(%p)\n", This, value);
3440 return E_NOTIMPL;
3443 static HRESULT WINAPI TextPara_SetHyphenation(ITextPara *iface, LONG value)
3445 ITextParaImpl *This = impl_from_ITextPara(iface);
3446 FIXME("(%p)->(%d)\n", This, value);
3447 return E_NOTIMPL;
3450 static HRESULT WINAPI TextPara_GetFirstLineIndent(ITextPara *iface, FLOAT *value)
3452 ITextParaImpl *This = impl_from_ITextPara(iface);
3453 FIXME("(%p)->(%p)\n", This, value);
3454 return E_NOTIMPL;
3457 static HRESULT WINAPI TextPara_GetKeepTogether(ITextPara *iface, LONG *value)
3459 ITextParaImpl *This = impl_from_ITextPara(iface);
3460 FIXME("(%p)->(%p)\n", This, value);
3461 return E_NOTIMPL;
3464 static HRESULT WINAPI TextPara_SetKeepTogether(ITextPara *iface, LONG value)
3466 ITextParaImpl *This = impl_from_ITextPara(iface);
3467 FIXME("(%p)->(%d)\n", This, value);
3468 return E_NOTIMPL;
3471 static HRESULT WINAPI TextPara_GetKeepWithNext(ITextPara *iface, LONG *value)
3473 ITextParaImpl *This = impl_from_ITextPara(iface);
3474 FIXME("(%p)->(%p)\n", This, value);
3475 return E_NOTIMPL;
3478 static HRESULT WINAPI TextPara_SetKeepWithNext(ITextPara *iface, LONG value)
3480 ITextParaImpl *This = impl_from_ITextPara(iface);
3481 FIXME("(%p)->(%d)\n", This, value);
3482 return E_NOTIMPL;
3485 static HRESULT WINAPI TextPara_GetLeftIndent(ITextPara *iface, FLOAT *value)
3487 ITextParaImpl *This = impl_from_ITextPara(iface);
3488 FIXME("(%p)->(%p)\n", This, value);
3489 return E_NOTIMPL;
3492 static HRESULT WINAPI TextPara_GetLineSpacing(ITextPara *iface, FLOAT *value)
3494 ITextParaImpl *This = impl_from_ITextPara(iface);
3495 FIXME("(%p)->(%p)\n", This, value);
3496 return E_NOTIMPL;
3499 static HRESULT WINAPI TextPara_GetLineSpacingRule(ITextPara *iface, LONG *value)
3501 ITextParaImpl *This = impl_from_ITextPara(iface);
3502 FIXME("(%p)->(%p)\n", This, value);
3503 return E_NOTIMPL;
3506 static HRESULT WINAPI TextPara_GetListAlignment(ITextPara *iface, LONG *value)
3508 ITextParaImpl *This = impl_from_ITextPara(iface);
3509 FIXME("(%p)->(%p)\n", This, value);
3510 return E_NOTIMPL;
3513 static HRESULT WINAPI TextPara_SetListAlignment(ITextPara *iface, LONG value)
3515 ITextParaImpl *This = impl_from_ITextPara(iface);
3516 FIXME("(%p)->(%d)\n", This, value);
3517 return E_NOTIMPL;
3520 static HRESULT WINAPI TextPara_GetListLevelIndex(ITextPara *iface, LONG *value)
3522 ITextParaImpl *This = impl_from_ITextPara(iface);
3523 FIXME("(%p)->(%p)\n", This, value);
3524 return E_NOTIMPL;
3527 static HRESULT WINAPI TextPara_SetListLevelIndex(ITextPara *iface, LONG value)
3529 ITextParaImpl *This = impl_from_ITextPara(iface);
3530 FIXME("(%p)->(%d)\n", This, value);
3531 return E_NOTIMPL;
3534 static HRESULT WINAPI TextPara_GetListStart(ITextPara *iface, LONG *value)
3536 ITextParaImpl *This = impl_from_ITextPara(iface);
3537 FIXME("(%p)->(%p)\n", This, value);
3538 return E_NOTIMPL;
3541 static HRESULT WINAPI TextPara_SetListStart(ITextPara *iface, LONG value)
3543 ITextParaImpl *This = impl_from_ITextPara(iface);
3544 FIXME("(%p)->(%d)\n", This, value);
3545 return E_NOTIMPL;
3548 static HRESULT WINAPI TextPara_GetListTab(ITextPara *iface, FLOAT *value)
3550 ITextParaImpl *This = impl_from_ITextPara(iface);
3551 FIXME("(%p)->(%p)\n", This, value);
3552 return E_NOTIMPL;
3555 static HRESULT WINAPI TextPara_SetListTab(ITextPara *iface, FLOAT value)
3557 ITextParaImpl *This = impl_from_ITextPara(iface);
3558 FIXME("(%p)->(%.2f)\n", This, value);
3559 return E_NOTIMPL;
3562 static HRESULT WINAPI TextPara_GetListType(ITextPara *iface, LONG *value)
3564 ITextParaImpl *This = impl_from_ITextPara(iface);
3565 FIXME("(%p)->(%p)\n", This, value);
3566 return E_NOTIMPL;
3569 static HRESULT WINAPI TextPara_SetListType(ITextPara *iface, LONG value)
3571 ITextParaImpl *This = impl_from_ITextPara(iface);
3572 FIXME("(%p)->(%d)\n", This, value);
3573 return E_NOTIMPL;
3576 static HRESULT WINAPI TextPara_GetNoLineNumber(ITextPara *iface, LONG *value)
3578 ITextParaImpl *This = impl_from_ITextPara(iface);
3579 FIXME("(%p)->(%p)\n", This, value);
3580 return E_NOTIMPL;
3583 static HRESULT WINAPI TextPara_SetNoLineNumber(ITextPara *iface, LONG value)
3585 ITextParaImpl *This = impl_from_ITextPara(iface);
3586 FIXME("(%p)->(%d)\n", This, value);
3587 return E_NOTIMPL;
3590 static HRESULT WINAPI TextPara_GetPageBreakBefore(ITextPara *iface, LONG *value)
3592 ITextParaImpl *This = impl_from_ITextPara(iface);
3593 FIXME("(%p)->(%p)\n", This, value);
3594 return E_NOTIMPL;
3597 static HRESULT WINAPI TextPara_SetPageBreakBefore(ITextPara *iface, LONG value)
3599 ITextParaImpl *This = impl_from_ITextPara(iface);
3600 FIXME("(%p)->(%d)\n", This, value);
3601 return E_NOTIMPL;
3604 static HRESULT WINAPI TextPara_GetRightIndent(ITextPara *iface, FLOAT *value)
3606 ITextParaImpl *This = impl_from_ITextPara(iface);
3607 FIXME("(%p)->(%p)\n", This, value);
3608 return E_NOTIMPL;
3611 static HRESULT WINAPI TextPara_SetRightIndent(ITextPara *iface, FLOAT value)
3613 ITextParaImpl *This = impl_from_ITextPara(iface);
3614 FIXME("(%p)->(%.2f)\n", This, value);
3615 return E_NOTIMPL;
3618 static HRESULT WINAPI TextPara_SetIndents(ITextPara *iface, FLOAT StartIndent, FLOAT LeftIndent, FLOAT RightIndent)
3620 ITextParaImpl *This = impl_from_ITextPara(iface);
3621 FIXME("(%p)->(%.2f %.2f %.2f)\n", This, StartIndent, LeftIndent, RightIndent);
3622 return E_NOTIMPL;
3625 static HRESULT WINAPI TextPara_SetLineSpacing(ITextPara *iface, LONG LineSpacingRule, FLOAT LineSpacing)
3627 ITextParaImpl *This = impl_from_ITextPara(iface);
3628 FIXME("(%p)->(%d %.2f)\n", This, LineSpacingRule, LineSpacing);
3629 return E_NOTIMPL;
3632 static HRESULT WINAPI TextPara_GetSpaceAfter(ITextPara *iface, FLOAT *value)
3634 ITextParaImpl *This = impl_from_ITextPara(iface);
3635 FIXME("(%p)->(%p)\n", This, value);
3636 return E_NOTIMPL;
3639 static HRESULT WINAPI TextPara_SetSpaceAfter(ITextPara *iface, FLOAT value)
3641 ITextParaImpl *This = impl_from_ITextPara(iface);
3642 FIXME("(%p)->(%.2f)\n", This, value);
3643 return E_NOTIMPL;
3646 static HRESULT WINAPI TextPara_GetSpaceBefore(ITextPara *iface, FLOAT *value)
3648 ITextParaImpl *This = impl_from_ITextPara(iface);
3649 FIXME("(%p)->(%p)\n", This, value);
3650 return E_NOTIMPL;
3653 static HRESULT WINAPI TextPara_SetSpaceBefore(ITextPara *iface, FLOAT value)
3655 ITextParaImpl *This = impl_from_ITextPara(iface);
3656 FIXME("(%p)->(%.2f)\n", This, value);
3657 return E_NOTIMPL;
3660 static HRESULT WINAPI TextPara_GetWidowControl(ITextPara *iface, LONG *value)
3662 ITextParaImpl *This = impl_from_ITextPara(iface);
3663 FIXME("(%p)->(%p)\n", This, value);
3664 return E_NOTIMPL;
3667 static HRESULT WINAPI TextPara_SetWidowControl(ITextPara *iface, LONG value)
3669 ITextParaImpl *This = impl_from_ITextPara(iface);
3670 FIXME("(%p)->(%d)\n", This, value);
3671 return E_NOTIMPL;
3674 static HRESULT WINAPI TextPara_GetTabCount(ITextPara *iface, LONG *value)
3676 ITextParaImpl *This = impl_from_ITextPara(iface);
3677 FIXME("(%p)->(%p)\n", This, value);
3678 return E_NOTIMPL;
3681 static HRESULT WINAPI TextPara_AddTab(ITextPara *iface, FLOAT tbPos, LONG tbAlign, LONG tbLeader)
3683 ITextParaImpl *This = impl_from_ITextPara(iface);
3684 FIXME("(%p)->(%.2f %d %d)\n", This, tbPos, tbAlign, tbLeader);
3685 return E_NOTIMPL;
3688 static HRESULT WINAPI TextPara_ClearAllTabs(ITextPara *iface)
3690 ITextParaImpl *This = impl_from_ITextPara(iface);
3691 FIXME("(%p)\n", This);
3692 return E_NOTIMPL;
3695 static HRESULT WINAPI TextPara_DeleteTab(ITextPara *iface, FLOAT pos)
3697 ITextParaImpl *This = impl_from_ITextPara(iface);
3698 FIXME("(%p)->(%.2f)\n", This, pos);
3699 return E_NOTIMPL;
3702 static HRESULT WINAPI TextPara_GetTab(ITextPara *iface, LONG iTab, FLOAT *ptbPos, LONG *ptbAlign, LONG *ptbLeader)
3704 ITextParaImpl *This = impl_from_ITextPara(iface);
3705 FIXME("(%p)->(%d %p %p %p)\n", This, iTab, ptbPos, ptbAlign, ptbLeader);
3706 return E_NOTIMPL;
3709 static ITextParaVtbl textparavtbl = {
3710 TextPara_QueryInterface,
3711 TextPara_AddRef,
3712 TextPara_Release,
3713 TextPara_GetTypeInfoCount,
3714 TextPara_GetTypeInfo,
3715 TextPara_GetIDsOfNames,
3716 TextPara_Invoke,
3717 TextPara_GetDuplicate,
3718 TextPara_SetDuplicate,
3719 TextPara_CanChange,
3720 TextPara_IsEqual,
3721 TextPara_Reset,
3722 TextPara_GetStyle,
3723 TextPara_SetStyle,
3724 TextPara_GetAlignment,
3725 TextPara_SetAlignment,
3726 TextPara_GetHyphenation,
3727 TextPara_SetHyphenation,
3728 TextPara_GetFirstLineIndent,
3729 TextPara_GetKeepTogether,
3730 TextPara_SetKeepTogether,
3731 TextPara_GetKeepWithNext,
3732 TextPara_SetKeepWithNext,
3733 TextPara_GetLeftIndent,
3734 TextPara_GetLineSpacing,
3735 TextPara_GetLineSpacingRule,
3736 TextPara_GetListAlignment,
3737 TextPara_SetListAlignment,
3738 TextPara_GetListLevelIndex,
3739 TextPara_SetListLevelIndex,
3740 TextPara_GetListStart,
3741 TextPara_SetListStart,
3742 TextPara_GetListTab,
3743 TextPara_SetListTab,
3744 TextPara_GetListType,
3745 TextPara_SetListType,
3746 TextPara_GetNoLineNumber,
3747 TextPara_SetNoLineNumber,
3748 TextPara_GetPageBreakBefore,
3749 TextPara_SetPageBreakBefore,
3750 TextPara_GetRightIndent,
3751 TextPara_SetRightIndent,
3752 TextPara_SetIndents,
3753 TextPara_SetLineSpacing,
3754 TextPara_GetSpaceAfter,
3755 TextPara_SetSpaceAfter,
3756 TextPara_GetSpaceBefore,
3757 TextPara_SetSpaceBefore,
3758 TextPara_GetWidowControl,
3759 TextPara_SetWidowControl,
3760 TextPara_GetTabCount,
3761 TextPara_AddTab,
3762 TextPara_ClearAllTabs,
3763 TextPara_DeleteTab,
3764 TextPara_GetTab
3767 static HRESULT create_textpara(ITextRange *range, ITextPara **ret)
3769 ITextParaImpl *para;
3771 *ret = NULL;
3772 para = heap_alloc(sizeof(*para));
3773 if (!para)
3774 return E_OUTOFMEMORY;
3776 para->ITextPara_iface.lpVtbl = &textparavtbl;
3777 para->ref = 1;
3778 para->range = range;
3779 ITextRange_AddRef(range);
3781 *ret = &para->ITextPara_iface;
3782 return S_OK;
3785 /* ITextDocument */
3786 static HRESULT WINAPI
3787 ITextDocument_fnQueryInterface(ITextDocument* me, REFIID riid,
3788 void** ppvObject)
3790 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3791 return IRichEditOle_QueryInterface(&This->IRichEditOle_iface, riid, ppvObject);
3794 static ULONG WINAPI
3795 ITextDocument_fnAddRef(ITextDocument* me)
3797 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3798 return IRichEditOle_AddRef(&This->IRichEditOle_iface);
3801 static ULONG WINAPI
3802 ITextDocument_fnRelease(ITextDocument* me)
3804 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3805 return IRichEditOle_Release(&This->IRichEditOle_iface);
3808 static HRESULT WINAPI
3809 ITextDocument_fnGetTypeInfoCount(ITextDocument* me,
3810 UINT* pctinfo)
3812 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3813 TRACE("(%p)->(%p)\n", This, pctinfo);
3814 *pctinfo = 1;
3815 return S_OK;
3818 static HRESULT WINAPI
3819 ITextDocument_fnGetTypeInfo(ITextDocument* me, UINT iTInfo, LCID lcid,
3820 ITypeInfo** ppTInfo)
3822 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3823 HRESULT hr;
3825 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
3827 hr = get_typeinfo(ITextDocument_tid, ppTInfo);
3828 if (SUCCEEDED(hr))
3829 ITypeInfo_AddRef(*ppTInfo);
3830 return hr;
3833 static HRESULT WINAPI
3834 ITextDocument_fnGetIDsOfNames(ITextDocument* me, REFIID riid,
3835 LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId)
3837 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3838 ITypeInfo *ti;
3839 HRESULT hr;
3841 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid),
3842 rgszNames, cNames, lcid, rgDispId);
3844 hr = get_typeinfo(ITextDocument_tid, &ti);
3845 if (SUCCEEDED(hr))
3846 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
3847 return hr;
3850 static HRESULT WINAPI
3851 ITextDocument_fnInvoke(ITextDocument* me, DISPID dispIdMember,
3852 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
3853 VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
3855 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3856 ITypeInfo *ti;
3857 HRESULT hr;
3859 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember,
3860 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
3861 pExcepInfo, puArgErr);
3863 hr = get_typeinfo(ITextDocument_tid, &ti);
3864 if (SUCCEEDED(hr))
3865 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3866 return hr;
3869 static HRESULT WINAPI
3870 ITextDocument_fnGetName(ITextDocument* me, BSTR* pName)
3872 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3873 FIXME("stub %p\n",This);
3874 return E_NOTIMPL;
3877 static HRESULT WINAPI
3878 ITextDocument_fnGetSelection(ITextDocument *me, ITextSelection **selection)
3880 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3882 TRACE("(%p)->(%p)\n", me, selection);
3884 if (!selection)
3885 return E_INVALIDARG;
3887 if (!This->txtSel) {
3888 This->txtSel = CreateTextSelection(This);
3889 if (!This->txtSel) {
3890 *selection = NULL;
3891 return E_OUTOFMEMORY;
3895 *selection = &This->txtSel->ITextSelection_iface;
3896 ITextSelection_AddRef(*selection);
3897 return S_OK;
3900 static HRESULT WINAPI
3901 ITextDocument_fnGetStoryCount(ITextDocument* me, LONG* pCount)
3903 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3904 FIXME("stub %p\n",This);
3905 return E_NOTIMPL;
3908 static HRESULT WINAPI
3909 ITextDocument_fnGetStoryRanges(ITextDocument* me,
3910 ITextStoryRanges** ppStories)
3912 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3913 FIXME("stub %p\n",This);
3914 return E_NOTIMPL;
3917 static HRESULT WINAPI
3918 ITextDocument_fnGetSaved(ITextDocument* me, LONG* pValue)
3920 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3921 FIXME("stub %p\n",This);
3922 return E_NOTIMPL;
3925 static HRESULT WINAPI
3926 ITextDocument_fnSetSaved(ITextDocument* me, LONG Value)
3928 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3929 FIXME("stub %p\n",This);
3930 return E_NOTIMPL;
3933 static HRESULT WINAPI
3934 ITextDocument_fnGetDefaultTabStop(ITextDocument* me, float* pValue)
3936 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3937 FIXME("stub %p\n",This);
3938 return E_NOTIMPL;
3941 static HRESULT WINAPI
3942 ITextDocument_fnSetDefaultTabStop(ITextDocument* me, float Value)
3944 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3945 FIXME("stub %p\n",This);
3946 return E_NOTIMPL;
3949 static HRESULT WINAPI
3950 ITextDocument_fnNew(ITextDocument* me)
3952 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3953 FIXME("stub %p\n",This);
3954 return E_NOTIMPL;
3957 static HRESULT WINAPI
3958 ITextDocument_fnOpen(ITextDocument* me, VARIANT* pVar, LONG Flags,
3959 LONG CodePage)
3961 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3962 FIXME("stub %p\n",This);
3963 return E_NOTIMPL;
3966 static HRESULT WINAPI
3967 ITextDocument_fnSave(ITextDocument* me, VARIANT* pVar, LONG Flags,
3968 LONG CodePage)
3970 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3971 FIXME("stub %p\n",This);
3972 return E_NOTIMPL;
3975 static HRESULT WINAPI
3976 ITextDocument_fnFreeze(ITextDocument* me, LONG* pCount)
3978 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3979 FIXME("stub %p\n",This);
3980 return E_NOTIMPL;
3983 static HRESULT WINAPI
3984 ITextDocument_fnUnfreeze(ITextDocument* me, LONG* pCount)
3986 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3987 FIXME("stub %p\n",This);
3988 return E_NOTIMPL;
3991 static HRESULT WINAPI
3992 ITextDocument_fnBeginEditCollection(ITextDocument* me)
3994 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3995 FIXME("stub %p\n",This);
3996 return E_NOTIMPL;
3999 static HRESULT WINAPI
4000 ITextDocument_fnEndEditCollection(ITextDocument* me)
4002 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4003 FIXME("stub %p\n",This);
4004 return E_NOTIMPL;
4007 static HRESULT WINAPI
4008 ITextDocument_fnUndo(ITextDocument* me, LONG Count, LONG* prop)
4010 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4011 FIXME("stub %p\n",This);
4012 return E_NOTIMPL;
4015 static HRESULT WINAPI
4016 ITextDocument_fnRedo(ITextDocument* me, LONG Count, LONG* prop)
4018 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4019 FIXME("stub %p\n",This);
4020 return E_NOTIMPL;
4023 static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, ITextRange** ppRange)
4025 ITextRangeImpl *txtRge = heap_alloc(sizeof(ITextRangeImpl));
4027 if (!txtRge)
4028 return E_OUTOFMEMORY;
4029 txtRge->ITextRange_iface.lpVtbl = &trvt;
4030 txtRge->ref = 1;
4031 txtRge->child.reole = reOle;
4032 txtRge->start = start;
4033 txtRge->end = end;
4034 list_add_head(&reOle->rangelist, &txtRge->child.entry);
4035 *ppRange = &txtRge->ITextRange_iface;
4036 return S_OK;
4039 static HRESULT WINAPI
4040 ITextDocument_fnRange(ITextDocument* me, LONG cp1, LONG cp2,
4041 ITextRange** ppRange)
4043 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4044 const int len = ME_GetTextLength(This->editor) + 1;
4046 TRACE("%p %p %d %d\n", This, ppRange, cp1, cp2);
4047 if (!ppRange)
4048 return E_INVALIDARG;
4050 cp1 = max(cp1, 0);
4051 cp2 = max(cp2, 0);
4052 cp1 = min(cp1, len);
4053 cp2 = min(cp2, len);
4054 if (cp1 > cp2)
4056 LONG tmp;
4057 tmp = cp1;
4058 cp1 = cp2;
4059 cp2 = tmp;
4061 if (cp1 == len)
4062 cp1 = cp2 = len - 1;
4064 return CreateITextRange(This, cp1, cp2, ppRange);
4067 static HRESULT WINAPI
4068 ITextDocument_fnRangeFromPoint(ITextDocument* me, LONG x, LONG y,
4069 ITextRange** ppRange)
4071 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4072 FIXME("stub %p\n",This);
4073 return E_NOTIMPL;
4076 static const ITextDocumentVtbl tdvt = {
4077 ITextDocument_fnQueryInterface,
4078 ITextDocument_fnAddRef,
4079 ITextDocument_fnRelease,
4080 ITextDocument_fnGetTypeInfoCount,
4081 ITextDocument_fnGetTypeInfo,
4082 ITextDocument_fnGetIDsOfNames,
4083 ITextDocument_fnInvoke,
4084 ITextDocument_fnGetName,
4085 ITextDocument_fnGetSelection,
4086 ITextDocument_fnGetStoryCount,
4087 ITextDocument_fnGetStoryRanges,
4088 ITextDocument_fnGetSaved,
4089 ITextDocument_fnSetSaved,
4090 ITextDocument_fnGetDefaultTabStop,
4091 ITextDocument_fnSetDefaultTabStop,
4092 ITextDocument_fnNew,
4093 ITextDocument_fnOpen,
4094 ITextDocument_fnSave,
4095 ITextDocument_fnFreeze,
4096 ITextDocument_fnUnfreeze,
4097 ITextDocument_fnBeginEditCollection,
4098 ITextDocument_fnEndEditCollection,
4099 ITextDocument_fnUndo,
4100 ITextDocument_fnRedo,
4101 ITextDocument_fnRange,
4102 ITextDocument_fnRangeFromPoint
4105 /* ITextSelection */
4106 static HRESULT WINAPI ITextSelection_fnQueryInterface(
4107 ITextSelection *me,
4108 REFIID riid,
4109 void **ppvObj)
4111 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4113 *ppvObj = NULL;
4114 if (IsEqualGUID(riid, &IID_IUnknown)
4115 || IsEqualGUID(riid, &IID_IDispatch)
4116 || IsEqualGUID(riid, &IID_ITextRange)
4117 || IsEqualGUID(riid, &IID_ITextSelection))
4119 *ppvObj = me;
4120 ITextSelection_AddRef(me);
4121 return S_OK;
4123 else if (IsEqualGUID(riid, &IID_Igetrichole))
4125 *ppvObj = This->reOle;
4126 return S_OK;
4129 return E_NOINTERFACE;
4132 static ULONG WINAPI ITextSelection_fnAddRef(ITextSelection *me)
4134 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4135 return InterlockedIncrement(&This->ref);
4138 static ULONG WINAPI ITextSelection_fnRelease(ITextSelection *me)
4140 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4141 ULONG ref = InterlockedDecrement(&This->ref);
4142 if (ref == 0)
4143 heap_free(This);
4144 return ref;
4147 static HRESULT WINAPI ITextSelection_fnGetTypeInfoCount(ITextSelection *me, UINT *pctinfo)
4149 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4150 TRACE("(%p)->(%p)\n", This, pctinfo);
4151 *pctinfo = 1;
4152 return S_OK;
4155 static HRESULT WINAPI ITextSelection_fnGetTypeInfo(ITextSelection *me, UINT iTInfo, LCID lcid,
4156 ITypeInfo **ppTInfo)
4158 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4159 HRESULT hr;
4161 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
4163 hr = get_typeinfo(ITextSelection_tid, ppTInfo);
4164 if (SUCCEEDED(hr))
4165 ITypeInfo_AddRef(*ppTInfo);
4166 return hr;
4169 static HRESULT WINAPI ITextSelection_fnGetIDsOfNames(ITextSelection *me, REFIID riid,
4170 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
4172 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4173 ITypeInfo *ti;
4174 HRESULT hr;
4176 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
4177 rgDispId);
4179 hr = get_typeinfo(ITextSelection_tid, &ti);
4180 if (SUCCEEDED(hr))
4181 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
4182 return hr;
4185 static HRESULT WINAPI ITextSelection_fnInvoke(
4186 ITextSelection *me,
4187 DISPID dispIdMember,
4188 REFIID riid,
4189 LCID lcid,
4190 WORD wFlags,
4191 DISPPARAMS *pDispParams,
4192 VARIANT *pVarResult,
4193 EXCEPINFO *pExcepInfo,
4194 UINT *puArgErr)
4196 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4197 ITypeInfo *ti;
4198 HRESULT hr;
4200 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid), lcid,
4201 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4203 hr = get_typeinfo(ITextSelection_tid, &ti);
4204 if (SUCCEEDED(hr))
4205 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4206 return hr;
4209 /*** ITextRange methods ***/
4210 static HRESULT WINAPI ITextSelection_fnGetText(ITextSelection *me, BSTR *pbstr)
4212 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4213 ME_Cursor *start = NULL, *end = NULL;
4214 int nChars, endOfs;
4215 BOOL bEOP;
4217 TRACE("(%p)->(%p)\n", This, pbstr);
4219 if (!This->reOle)
4220 return CO_E_RELEASED;
4222 if (!pbstr)
4223 return E_INVALIDARG;
4225 ME_GetSelection(This->reOle->editor, &start, &end);
4226 endOfs = ME_GetCursorOfs(end);
4227 nChars = endOfs - ME_GetCursorOfs(start);
4228 if (!nChars)
4230 *pbstr = NULL;
4231 return S_OK;
4234 *pbstr = SysAllocStringLen(NULL, nChars);
4235 if (!*pbstr)
4236 return E_OUTOFMEMORY;
4238 bEOP = (end->pRun->next->type == diTextEnd && endOfs > ME_GetTextLength(This->reOle->editor));
4239 ME_GetTextW(This->reOle->editor, *pbstr, nChars, start, nChars, FALSE, bEOP);
4240 TRACE("%s\n", wine_dbgstr_w(*pbstr));
4242 return S_OK;
4245 static HRESULT WINAPI ITextSelection_fnSetText(ITextSelection *me, BSTR str)
4247 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4248 ME_TextEditor *editor;
4249 int len, to, from;
4251 TRACE("(%p)->(%s)\n", This, debugstr_w(str));
4253 if (!This->reOle)
4254 return CO_E_RELEASED;
4256 editor = This->reOle->editor;
4257 len = strlenW(str);
4258 ME_GetSelectionOfs(editor, &from, &to);
4259 ME_ReplaceSel(editor, FALSE, str, len);
4261 if (len < to - from)
4262 textranges_update_ranges(This->reOle, from, len, RANGE_UPDATE_DELETE);
4264 return S_OK;
4267 static HRESULT WINAPI ITextSelection_fnGetChar(ITextSelection *me, LONG *pch)
4269 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4270 ME_Cursor *start = NULL, *end = NULL;
4272 TRACE("(%p)->(%p)\n", This, pch);
4274 if (!This->reOle)
4275 return CO_E_RELEASED;
4277 if (!pch)
4278 return E_INVALIDARG;
4280 ME_GetSelection(This->reOle->editor, &start, &end);
4281 return range_GetChar(This->reOle->editor, start, pch);
4284 static HRESULT WINAPI ITextSelection_fnSetChar(ITextSelection *me, LONG ch)
4286 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4288 FIXME("(%p)->(%x): stub\n", This, ch);
4290 if (!This->reOle)
4291 return CO_E_RELEASED;
4293 return E_NOTIMPL;
4296 static HRESULT WINAPI ITextSelection_fnGetDuplicate(ITextSelection *me, ITextRange **range)
4298 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4299 LONG start, end;
4301 TRACE("(%p)->(%p)\n", This, range);
4303 if (!This->reOle)
4304 return CO_E_RELEASED;
4306 if (!range)
4307 return E_INVALIDARG;
4309 ITextSelection_GetStart(me, &start);
4310 ITextSelection_GetEnd(me, &end);
4311 return CreateITextRange(This->reOle, start, end, range);
4314 static HRESULT WINAPI ITextSelection_fnGetFormattedText(ITextSelection *me, ITextRange **range)
4316 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4318 FIXME("(%p)->(%p): stub\n", This, range);
4320 if (!This->reOle)
4321 return CO_E_RELEASED;
4323 return E_NOTIMPL;
4326 static HRESULT WINAPI ITextSelection_fnSetFormattedText(ITextSelection *me, ITextRange *range)
4328 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4330 FIXME("(%p)->(%p): stub\n", This, range);
4332 if (!This->reOle)
4333 return CO_E_RELEASED;
4335 FIXME("not implemented\n");
4336 return E_NOTIMPL;
4339 static HRESULT WINAPI ITextSelection_fnGetStart(ITextSelection *me, LONG *pcpFirst)
4341 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4342 LONG lim;
4344 TRACE("(%p)->(%p)\n", This, pcpFirst);
4346 if (!This->reOle)
4347 return CO_E_RELEASED;
4349 if (!pcpFirst)
4350 return E_INVALIDARG;
4351 ME_GetSelectionOfs(This->reOle->editor, pcpFirst, &lim);
4352 return S_OK;
4355 static HRESULT WINAPI ITextSelection_fnSetStart(ITextSelection *me, LONG value)
4357 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4358 LONG start, end;
4359 HRESULT hr;
4361 TRACE("(%p)->(%d)\n", This, value);
4363 if (!This->reOle)
4364 return CO_E_RELEASED;
4366 ME_GetSelectionOfs(This->reOle->editor, &start, &end);
4367 hr = textrange_setstart(This->reOle, value, &start, &end);
4368 if (hr == S_OK)
4369 ME_SetSelection(This->reOle->editor, start, end);
4371 return hr;
4374 static HRESULT WINAPI ITextSelection_fnGetEnd(ITextSelection *me, LONG *pcpLim)
4376 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4377 LONG first;
4379 TRACE("(%p)->(%p)\n", This, pcpLim);
4381 if (!This->reOle)
4382 return CO_E_RELEASED;
4384 if (!pcpLim)
4385 return E_INVALIDARG;
4386 ME_GetSelectionOfs(This->reOle->editor, &first, pcpLim);
4387 return S_OK;
4390 static HRESULT WINAPI ITextSelection_fnSetEnd(ITextSelection *me, LONG value)
4392 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4393 LONG start, end;
4394 HRESULT hr;
4396 TRACE("(%p)->(%d)\n", This, value);
4398 if (!This->reOle)
4399 return CO_E_RELEASED;
4401 ME_GetSelectionOfs(This->reOle->editor, &start, &end);
4402 hr = textrange_setend(This->reOle, value, &start, &end);
4403 if (hr == S_OK)
4404 ME_SetSelection(This->reOle->editor, start, end);
4406 return hr;
4409 static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **font)
4411 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4413 TRACE("(%p)->(%p)\n", This, font);
4415 if (!This->reOle)
4416 return CO_E_RELEASED;
4418 if (!font)
4419 return E_INVALIDARG;
4421 return create_textfont((ITextRange*)me, NULL, font);
4424 static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *font)
4426 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4428 TRACE("(%p)->(%p)\n", This, font);
4430 if (!font)
4431 return E_INVALIDARG;
4433 if (!This->reOle)
4434 return CO_E_RELEASED;
4436 textrange_set_font((ITextRange*)me, font);
4437 return S_OK;
4440 static HRESULT WINAPI ITextSelection_fnGetPara(ITextSelection *me, ITextPara **para)
4442 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4444 TRACE("(%p)->(%p)\n", This, para);
4446 if (!This->reOle)
4447 return CO_E_RELEASED;
4449 if (!para)
4450 return E_INVALIDARG;
4452 return create_textpara((ITextRange*)me, para);
4455 static HRESULT WINAPI ITextSelection_fnSetPara(ITextSelection *me, ITextPara *para)
4457 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4459 FIXME("(%p)->(%p): stub\n", This, para);
4461 if (!This->reOle)
4462 return CO_E_RELEASED;
4464 FIXME("not implemented\n");
4465 return E_NOTIMPL;
4468 static HRESULT WINAPI ITextSelection_fnGetStoryLength(ITextSelection *me, LONG *length)
4470 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4472 TRACE("(%p)->(%p)\n", This, length);
4474 if (!This->reOle)
4475 return CO_E_RELEASED;
4477 return textrange_get_storylength(This->reOle->editor, length);
4480 static HRESULT WINAPI ITextSelection_fnGetStoryType(ITextSelection *me, LONG *value)
4482 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4484 TRACE("(%p)->(%p)\n", This, value);
4486 if (!This->reOle)
4487 return CO_E_RELEASED;
4489 if (!value)
4490 return E_INVALIDARG;
4492 *value = tomUnknownStory;
4493 return S_OK;
4496 static HRESULT WINAPI ITextSelection_fnCollapse(ITextSelection *me, LONG bStart)
4498 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4499 LONG start, end;
4500 HRESULT hres;
4502 TRACE("(%p)->(%d)\n", This, bStart);
4504 if (!This->reOle)
4505 return CO_E_RELEASED;
4507 ME_GetSelectionOfs(This->reOle->editor, &start, &end);
4508 hres = range_Collapse(bStart, &start, &end);
4509 if (SUCCEEDED(hres))
4510 ME_SetSelection(This->reOle->editor, start, end);
4511 return hres;
4514 static HRESULT WINAPI ITextSelection_fnExpand(ITextSelection *me, LONG unit, LONG *delta)
4516 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4518 TRACE("(%p)->(%d %p)\n", This, unit, delta);
4520 if (!This->reOle)
4521 return CO_E_RELEASED;
4523 return textrange_expand((ITextRange*)me, unit, delta);
4526 static HRESULT WINAPI ITextSelection_fnGetIndex(ITextSelection *me, LONG unit, LONG *index)
4528 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4530 FIXME("(%p)->(%d %p): stub\n", This, unit, index);
4532 if (!This->reOle)
4533 return CO_E_RELEASED;
4535 return E_NOTIMPL;
4538 static HRESULT WINAPI ITextSelection_fnSetIndex(ITextSelection *me, LONG unit, LONG index,
4539 LONG extend)
4541 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4543 FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend);
4545 if (!This->reOle)
4546 return CO_E_RELEASED;
4548 return E_NOTIMPL;
4551 static HRESULT WINAPI ITextSelection_fnSetRange(ITextSelection *me, LONG anchor, LONG active)
4553 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4555 FIXME("(%p)->(%d %d): stub\n", This, anchor, active);
4557 if (!This->reOle)
4558 return CO_E_RELEASED;
4560 return E_NOTIMPL;
4563 static HRESULT WINAPI ITextSelection_fnInRange(ITextSelection *me, ITextRange *range, LONG *ret)
4565 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4566 ITextSelection *selection = NULL;
4567 LONG start, end;
4569 TRACE("(%p)->(%p %p)\n", This, range, ret);
4571 if (ret)
4572 *ret = tomFalse;
4574 if (!This->reOle)
4575 return CO_E_RELEASED;
4577 if (!range)
4578 return S_FALSE;
4580 ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection);
4581 if (!selection)
4582 return S_FALSE;
4583 ITextSelection_Release(selection);
4585 ITextSelection_GetStart(me, &start);
4586 ITextSelection_GetEnd(me, &end);
4587 return textrange_inrange(start, end, range, ret);
4590 static HRESULT WINAPI ITextSelection_fnInStory(ITextSelection *me, ITextRange *range, LONG *ret)
4592 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4594 FIXME("(%p)->(%p %p): stub\n", This, range, ret);
4596 if (!This->reOle)
4597 return CO_E_RELEASED;
4599 return E_NOTIMPL;
4602 static HRESULT WINAPI ITextSelection_fnIsEqual(ITextSelection *me, ITextRange *range, LONG *ret)
4604 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4605 ITextSelection *selection = NULL;
4606 LONG start, end;
4608 TRACE("(%p)->(%p %p)\n", This, range, ret);
4610 if (ret)
4611 *ret = tomFalse;
4613 if (!This->reOle)
4614 return CO_E_RELEASED;
4616 if (!range)
4617 return S_FALSE;
4619 ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection);
4620 if (!selection)
4621 return S_FALSE;
4622 ITextSelection_Release(selection);
4624 ITextSelection_GetStart(me, &start);
4625 ITextSelection_GetEnd(me, &end);
4626 return textrange_isequal(start, end, range, ret);
4629 static HRESULT WINAPI ITextSelection_fnSelect(ITextSelection *me)
4631 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4633 TRACE("(%p)\n", This);
4635 if (!This->reOle)
4636 return CO_E_RELEASED;
4638 /* nothing to do */
4639 return S_OK;
4642 static HRESULT WINAPI ITextSelection_fnStartOf(ITextSelection *me, LONG unit, LONG extend,
4643 LONG *delta)
4645 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4647 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
4649 if (!This->reOle)
4650 return CO_E_RELEASED;
4652 return E_NOTIMPL;
4655 static HRESULT WINAPI ITextSelection_fnEndOf(ITextSelection *me, LONG unit, LONG extend,
4656 LONG *delta)
4658 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4660 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
4662 if (!This->reOle)
4663 return CO_E_RELEASED;
4665 return E_NOTIMPL;
4668 static HRESULT WINAPI ITextSelection_fnMove(ITextSelection *me, LONG unit, LONG count, LONG *delta)
4670 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4672 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
4674 if (!This->reOle)
4675 return CO_E_RELEASED;
4677 return E_NOTIMPL;
4680 static HRESULT WINAPI ITextSelection_fnMoveStart(ITextSelection *me, LONG unit, LONG count,
4681 LONG *delta)
4683 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4685 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
4687 if (!This->reOle)
4688 return CO_E_RELEASED;
4690 return E_NOTIMPL;
4693 static HRESULT WINAPI ITextSelection_fnMoveEnd(ITextSelection *me, LONG unit, LONG count,
4694 LONG *delta)
4696 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4698 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
4700 if (!This->reOle)
4701 return CO_E_RELEASED;
4703 return E_NOTIMPL;
4706 static HRESULT WINAPI ITextSelection_fnMoveWhile(ITextSelection *me, VARIANT *charset, LONG count,
4707 LONG *delta)
4709 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4711 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4713 if (!This->reOle)
4714 return CO_E_RELEASED;
4716 return E_NOTIMPL;
4719 static HRESULT WINAPI ITextSelection_fnMoveStartWhile(ITextSelection *me, VARIANT *charset, LONG count,
4720 LONG *delta)
4722 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4724 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4726 if (!This->reOle)
4727 return CO_E_RELEASED;
4729 return E_NOTIMPL;
4732 static HRESULT WINAPI ITextSelection_fnMoveEndWhile(ITextSelection *me, VARIANT *charset, LONG count,
4733 LONG *delta)
4735 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4737 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4739 if (!This->reOle)
4740 return CO_E_RELEASED;
4742 return E_NOTIMPL;
4745 static HRESULT WINAPI ITextSelection_fnMoveUntil(ITextSelection *me, VARIANT *charset, LONG count,
4746 LONG *delta)
4748 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4750 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4752 if (!This->reOle)
4753 return CO_E_RELEASED;
4755 return E_NOTIMPL;
4758 static HRESULT WINAPI ITextSelection_fnMoveStartUntil(ITextSelection *me, VARIANT *charset, LONG count,
4759 LONG *delta)
4761 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4763 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4765 if (!This->reOle)
4766 return CO_E_RELEASED;
4768 return E_NOTIMPL;
4771 static HRESULT WINAPI ITextSelection_fnMoveEndUntil(ITextSelection *me, VARIANT *charset, LONG count,
4772 LONG *delta)
4774 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4776 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4778 if (!This->reOle)
4779 return CO_E_RELEASED;
4781 return E_NOTIMPL;
4784 static HRESULT WINAPI ITextSelection_fnFindText(ITextSelection *me, BSTR text, LONG count, LONG flags,
4785 LONG *length)
4787 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4789 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
4791 if (!This->reOle)
4792 return CO_E_RELEASED;
4794 FIXME("not implemented\n");
4795 return E_NOTIMPL;
4798 static HRESULT WINAPI ITextSelection_fnFindTextStart(ITextSelection *me, BSTR text, LONG count,
4799 LONG flags, LONG *length)
4801 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4803 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
4805 if (!This->reOle)
4806 return CO_E_RELEASED;
4808 return E_NOTIMPL;
4811 static HRESULT WINAPI ITextSelection_fnFindTextEnd(ITextSelection *me, BSTR text, LONG count,
4812 LONG flags, LONG *length)
4814 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4816 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
4818 if (!This->reOle)
4819 return CO_E_RELEASED;
4821 return E_NOTIMPL;
4824 static HRESULT WINAPI ITextSelection_fnDelete(ITextSelection *me, LONG unit, LONG count,
4825 LONG *delta)
4827 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4829 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
4831 if (!This->reOle)
4832 return CO_E_RELEASED;
4834 return E_NOTIMPL;
4837 static HRESULT WINAPI ITextSelection_fnCut(ITextSelection *me, VARIANT *v)
4839 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4841 FIXME("(%p)->(%p): stub\n", This, v);
4843 if (!This->reOle)
4844 return CO_E_RELEASED;
4846 return E_NOTIMPL;
4849 static HRESULT WINAPI ITextSelection_fnCopy(ITextSelection *me, VARIANT *v)
4851 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4853 FIXME("(%p)->(%p): stub\n", This, v);
4855 if (!This->reOle)
4856 return CO_E_RELEASED;
4858 return E_NOTIMPL;
4861 static HRESULT WINAPI ITextSelection_fnPaste(ITextSelection *me, VARIANT *v, LONG format)
4863 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4865 FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format);
4867 if (!This->reOle)
4868 return CO_E_RELEASED;
4870 return E_NOTIMPL;
4873 static HRESULT WINAPI ITextSelection_fnCanPaste(ITextSelection *me, VARIANT *v, LONG format,
4874 LONG *ret)
4876 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4878 FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret);
4880 if (!This->reOle)
4881 return CO_E_RELEASED;
4883 return E_NOTIMPL;
4886 static HRESULT WINAPI ITextSelection_fnCanEdit(ITextSelection *me, LONG *ret)
4888 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4890 FIXME("(%p)->(%p): stub\n", This, ret);
4892 if (!This->reOle)
4893 return CO_E_RELEASED;
4895 return E_NOTIMPL;
4898 static HRESULT WINAPI ITextSelection_fnChangeCase(ITextSelection *me, LONG type)
4900 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4902 FIXME("(%p)->(%d): stub\n", This, type);
4904 if (!This->reOle)
4905 return CO_E_RELEASED;
4907 return E_NOTIMPL;
4910 static HRESULT WINAPI ITextSelection_fnGetPoint(ITextSelection *me, LONG type, LONG *cx, LONG *cy)
4912 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4914 FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy);
4916 if (!This->reOle)
4917 return CO_E_RELEASED;
4919 return E_NOTIMPL;
4922 static HRESULT WINAPI ITextSelection_fnSetPoint(ITextSelection *me, LONG x, LONG y, LONG type,
4923 LONG extend)
4925 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4927 FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend);
4929 if (!This->reOle)
4930 return CO_E_RELEASED;
4932 return E_NOTIMPL;
4935 static HRESULT WINAPI ITextSelection_fnScrollIntoView(ITextSelection *me, LONG value)
4937 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4939 FIXME("(%p)->(%d): stub\n", This, value);
4941 if (!This->reOle)
4942 return CO_E_RELEASED;
4944 return E_NOTIMPL;
4947 static HRESULT WINAPI ITextSelection_fnGetEmbeddedObject(ITextSelection *me, IUnknown **ppv)
4949 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4951 FIXME("(%p)->(%p): stub\n", This, ppv);
4953 if (!This->reOle)
4954 return CO_E_RELEASED;
4956 return E_NOTIMPL;
4959 /*** ITextSelection methods ***/
4960 static HRESULT WINAPI ITextSelection_fnGetFlags(ITextSelection *me, LONG *flags)
4962 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4964 FIXME("(%p)->(%p): stub\n", This, flags);
4966 if (!This->reOle)
4967 return CO_E_RELEASED;
4969 return E_NOTIMPL;
4972 static HRESULT WINAPI ITextSelection_fnSetFlags(ITextSelection *me, LONG flags)
4974 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4976 FIXME("(%p)->(%x): stub\n", This, flags);
4978 if (!This->reOle)
4979 return CO_E_RELEASED;
4981 return E_NOTIMPL;
4984 static HRESULT WINAPI ITextSelection_fnGetType(ITextSelection *me, LONG *type)
4986 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4988 FIXME("(%p)->(%p): stub\n", This, type);
4990 if (!This->reOle)
4991 return CO_E_RELEASED;
4993 return E_NOTIMPL;
4996 static HRESULT WINAPI ITextSelection_fnMoveLeft(ITextSelection *me, LONG unit, LONG count,
4997 LONG extend, LONG *delta)
4999 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5001 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5003 if (!This->reOle)
5004 return CO_E_RELEASED;
5006 return E_NOTIMPL;
5009 static HRESULT WINAPI ITextSelection_fnMoveRight(ITextSelection *me, LONG unit, LONG count,
5010 LONG extend, LONG *delta)
5012 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5014 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5016 if (!This->reOle)
5017 return CO_E_RELEASED;
5019 return E_NOTIMPL;
5022 static HRESULT WINAPI ITextSelection_fnMoveUp(ITextSelection *me, LONG unit, LONG count,
5023 LONG extend, LONG *delta)
5025 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5027 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5029 if (!This->reOle)
5030 return CO_E_RELEASED;
5032 return E_NOTIMPL;
5035 static HRESULT WINAPI ITextSelection_fnMoveDown(ITextSelection *me, LONG unit, LONG count,
5036 LONG extend, LONG *delta)
5038 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5040 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5042 if (!This->reOle)
5043 return CO_E_RELEASED;
5045 return E_NOTIMPL;
5048 static HRESULT WINAPI ITextSelection_fnHomeKey(ITextSelection *me, LONG unit, LONG extend,
5049 LONG *delta)
5051 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5053 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
5055 if (!This->reOle)
5056 return CO_E_RELEASED;
5058 return E_NOTIMPL;
5061 static HRESULT WINAPI ITextSelection_fnEndKey(ITextSelection *me, LONG unit, LONG extend,
5062 LONG *delta)
5064 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5066 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
5068 if (!This->reOle)
5069 return CO_E_RELEASED;
5071 return E_NOTIMPL;
5074 static HRESULT WINAPI ITextSelection_fnTypeText(ITextSelection *me, BSTR text)
5076 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5078 FIXME("(%p)->(%s): stub\n", This, debugstr_w(text));
5080 if (!This->reOle)
5081 return CO_E_RELEASED;
5083 return E_NOTIMPL;
5086 static const ITextSelectionVtbl tsvt = {
5087 ITextSelection_fnQueryInterface,
5088 ITextSelection_fnAddRef,
5089 ITextSelection_fnRelease,
5090 ITextSelection_fnGetTypeInfoCount,
5091 ITextSelection_fnGetTypeInfo,
5092 ITextSelection_fnGetIDsOfNames,
5093 ITextSelection_fnInvoke,
5094 ITextSelection_fnGetText,
5095 ITextSelection_fnSetText,
5096 ITextSelection_fnGetChar,
5097 ITextSelection_fnSetChar,
5098 ITextSelection_fnGetDuplicate,
5099 ITextSelection_fnGetFormattedText,
5100 ITextSelection_fnSetFormattedText,
5101 ITextSelection_fnGetStart,
5102 ITextSelection_fnSetStart,
5103 ITextSelection_fnGetEnd,
5104 ITextSelection_fnSetEnd,
5105 ITextSelection_fnGetFont,
5106 ITextSelection_fnSetFont,
5107 ITextSelection_fnGetPara,
5108 ITextSelection_fnSetPara,
5109 ITextSelection_fnGetStoryLength,
5110 ITextSelection_fnGetStoryType,
5111 ITextSelection_fnCollapse,
5112 ITextSelection_fnExpand,
5113 ITextSelection_fnGetIndex,
5114 ITextSelection_fnSetIndex,
5115 ITextSelection_fnSetRange,
5116 ITextSelection_fnInRange,
5117 ITextSelection_fnInStory,
5118 ITextSelection_fnIsEqual,
5119 ITextSelection_fnSelect,
5120 ITextSelection_fnStartOf,
5121 ITextSelection_fnEndOf,
5122 ITextSelection_fnMove,
5123 ITextSelection_fnMoveStart,
5124 ITextSelection_fnMoveEnd,
5125 ITextSelection_fnMoveWhile,
5126 ITextSelection_fnMoveStartWhile,
5127 ITextSelection_fnMoveEndWhile,
5128 ITextSelection_fnMoveUntil,
5129 ITextSelection_fnMoveStartUntil,
5130 ITextSelection_fnMoveEndUntil,
5131 ITextSelection_fnFindText,
5132 ITextSelection_fnFindTextStart,
5133 ITextSelection_fnFindTextEnd,
5134 ITextSelection_fnDelete,
5135 ITextSelection_fnCut,
5136 ITextSelection_fnCopy,
5137 ITextSelection_fnPaste,
5138 ITextSelection_fnCanPaste,
5139 ITextSelection_fnCanEdit,
5140 ITextSelection_fnChangeCase,
5141 ITextSelection_fnGetPoint,
5142 ITextSelection_fnSetPoint,
5143 ITextSelection_fnScrollIntoView,
5144 ITextSelection_fnGetEmbeddedObject,
5145 ITextSelection_fnGetFlags,
5146 ITextSelection_fnSetFlags,
5147 ITextSelection_fnGetType,
5148 ITextSelection_fnMoveLeft,
5149 ITextSelection_fnMoveRight,
5150 ITextSelection_fnMoveUp,
5151 ITextSelection_fnMoveDown,
5152 ITextSelection_fnHomeKey,
5153 ITextSelection_fnEndKey,
5154 ITextSelection_fnTypeText
5157 static ITextSelectionImpl *
5158 CreateTextSelection(IRichEditOleImpl *reOle)
5160 ITextSelectionImpl *txtSel = heap_alloc(sizeof *txtSel);
5161 if (!txtSel)
5162 return NULL;
5164 txtSel->ITextSelection_iface.lpVtbl = &tsvt;
5165 txtSel->ref = 1;
5166 txtSel->reOle = reOle;
5167 return txtSel;
5170 LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *ppvObj)
5172 IRichEditOleImpl *reo;
5174 reo = heap_alloc(sizeof(IRichEditOleImpl));
5175 if (!reo)
5176 return 0;
5178 reo->IUnknown_inner.lpVtbl = &reo_unk_vtbl;
5179 reo->IRichEditOle_iface.lpVtbl = &revt;
5180 reo->ITextDocument_iface.lpVtbl = &tdvt;
5181 reo->ref = 1;
5182 reo->editor = editor;
5183 reo->txtSel = NULL;
5185 TRACE("Created %p\n",reo);
5186 list_init(&reo->rangelist);
5187 list_init(&reo->clientsites);
5188 if (outer_unk)
5189 reo->outer_unk = outer_unk;
5190 else
5191 reo->outer_unk = &reo->IUnknown_inner;
5192 *ppvObj = &reo->IRichEditOle_iface;
5194 return 1;
5197 static void convert_sizel(const ME_Context *c, const SIZEL* szl, SIZE* sz)
5199 /* sizel is in .01 millimeters, sz in pixels */
5200 sz->cx = MulDiv(szl->cx, c->dpi.cx, 2540);
5201 sz->cy = MulDiv(szl->cy, c->dpi.cy, 2540);
5204 /******************************************************************************
5205 * ME_GetOLEObjectSize
5207 * Sets run extent for OLE objects.
5209 void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize)
5211 IDataObject* ido;
5212 FORMATETC fmt;
5213 STGMEDIUM stgm;
5214 DIBSECTION dibsect;
5215 ENHMETAHEADER emh;
5217 assert(run->nFlags & MERF_GRAPHICS);
5218 assert(run->ole_obj);
5220 if (run->ole_obj->sizel.cx != 0 || run->ole_obj->sizel.cy != 0)
5222 convert_sizel(c, &run->ole_obj->sizel, pSize);
5223 if (c->editor->nZoomNumerator != 0)
5225 pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5226 pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5228 return;
5231 if (!run->ole_obj->poleobj)
5233 pSize->cx = pSize->cy = 0;
5234 return;
5237 if (IOleObject_QueryInterface(run->ole_obj->poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
5239 FIXME("Query Interface IID_IDataObject failed!\n");
5240 pSize->cx = pSize->cy = 0;
5241 return;
5243 fmt.cfFormat = CF_BITMAP;
5244 fmt.ptd = NULL;
5245 fmt.dwAspect = DVASPECT_CONTENT;
5246 fmt.lindex = -1;
5247 fmt.tymed = TYMED_GDI;
5248 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5250 fmt.cfFormat = CF_ENHMETAFILE;
5251 fmt.tymed = TYMED_ENHMF;
5252 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5254 FIXME("unsupported format\n");
5255 pSize->cx = pSize->cy = 0;
5256 IDataObject_Release(ido);
5257 return;
5260 IDataObject_Release(ido);
5262 switch (stgm.tymed)
5264 case TYMED_GDI:
5265 GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
5266 pSize->cx = dibsect.dsBm.bmWidth;
5267 pSize->cy = dibsect.dsBm.bmHeight;
5268 break;
5269 case TYMED_ENHMF:
5270 GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
5271 pSize->cx = emh.rclBounds.right - emh.rclBounds.left;
5272 pSize->cy = emh.rclBounds.bottom - emh.rclBounds.top;
5273 break;
5274 default:
5275 FIXME("Unsupported tymed %d\n", stgm.tymed);
5276 break;
5278 ReleaseStgMedium(&stgm);
5279 if (c->editor->nZoomNumerator != 0)
5281 pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5282 pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5286 void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run, BOOL selected)
5288 IDataObject* ido;
5289 FORMATETC fmt;
5290 STGMEDIUM stgm;
5291 DIBSECTION dibsect;
5292 ENHMETAHEADER emh;
5293 HDC hMemDC;
5294 SIZE sz;
5295 BOOL has_size;
5296 HBITMAP old_bm;
5297 RECT rc;
5299 assert(run->nFlags & MERF_GRAPHICS);
5300 assert(run->ole_obj);
5301 if (IOleObject_QueryInterface(run->ole_obj->poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
5303 FIXME("Couldn't get interface\n");
5304 return;
5306 has_size = run->ole_obj->sizel.cx != 0 || run->ole_obj->sizel.cy != 0;
5307 fmt.cfFormat = CF_BITMAP;
5308 fmt.ptd = NULL;
5309 fmt.dwAspect = DVASPECT_CONTENT;
5310 fmt.lindex = -1;
5311 fmt.tymed = TYMED_GDI;
5312 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5314 fmt.cfFormat = CF_ENHMETAFILE;
5315 fmt.tymed = TYMED_ENHMF;
5316 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5318 FIXME("Couldn't get storage medium\n");
5319 IDataObject_Release(ido);
5320 return;
5323 IDataObject_Release(ido);
5325 switch (stgm.tymed)
5327 case TYMED_GDI:
5328 GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
5329 hMemDC = CreateCompatibleDC(c->hDC);
5330 old_bm = SelectObject(hMemDC, stgm.u.hBitmap);
5331 if (has_size)
5333 convert_sizel(c, &run->ole_obj->sizel, &sz);
5334 } else {
5335 sz.cx = dibsect.dsBm.bmWidth;
5336 sz.cy = dibsect.dsBm.bmHeight;
5338 if (c->editor->nZoomNumerator != 0)
5340 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5341 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5343 StretchBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy,
5344 hMemDC, 0, 0, dibsect.dsBm.bmWidth, dibsect.dsBm.bmHeight, SRCCOPY);
5346 SelectObject(hMemDC, old_bm);
5347 DeleteDC(hMemDC);
5348 break;
5349 case TYMED_ENHMF:
5350 GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
5351 if (has_size)
5353 convert_sizel(c, &run->ole_obj->sizel, &sz);
5354 } else {
5355 sz.cx = emh.rclBounds.right - emh.rclBounds.left;
5356 sz.cy = emh.rclBounds.bottom - emh.rclBounds.top;
5358 if (c->editor->nZoomNumerator != 0)
5360 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5361 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5364 rc.left = x;
5365 rc.top = y - sz.cy;
5366 rc.right = x + sz.cx;
5367 rc.bottom = y;
5368 PlayEnhMetaFile(c->hDC, stgm.u.hEnhMetaFile, &rc);
5369 break;
5370 default:
5371 FIXME("Unsupported tymed %d\n", stgm.tymed);
5372 selected = FALSE;
5373 break;
5375 ReleaseStgMedium(&stgm);
5377 if (selected && !c->editor->bHideSelection)
5378 PatBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy, DSTINVERT);
5381 void ME_DeleteReObject(REOBJECT* reo)
5383 if (reo->poleobj) IOleObject_Release(reo->poleobj);
5384 if (reo->pstg) IStorage_Release(reo->pstg);
5385 if (reo->polesite) IOleClientSite_Release(reo->polesite);
5386 heap_free(reo);
5389 void ME_CopyReObject(REOBJECT* dst, const REOBJECT* src)
5391 *dst = *src;
5393 if (dst->poleobj) IOleObject_AddRef(dst->poleobj);
5394 if (dst->pstg) IStorage_AddRef(dst->pstg);
5395 if (dst->polesite) IOleClientSite_AddRef(dst->polesite);
5398 void ME_GetITextDocumentInterface(IRichEditOle *iface, LPVOID *ppvObj)
5400 IRichEditOleImpl *This = impl_from_IRichEditOle(iface);
5401 *ppvObj = &This->ITextDocument_iface;