ntdll: Implement NtCreateDebugObject().
[wine.git] / dlls / riched20 / richole.c
blobb8b081fc916d4a10ce6599ce8fa18cad572bf696
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_ITextDocument2Old, 0x01c25500, 0x4268, 0x11d1, 0x88, 0x3a, 0x3c, 0x8b, 0x00, 0xc1, 0x00, 0x00);
50 DEFINE_GUID(IID_ITextRange, 0x8cc497c2, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
51 DEFINE_GUID(IID_ITextSelection, 0x8cc497c1, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
52 DEFINE_GUID(IID_ITextFont, 0x8cc497c3, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
53 DEFINE_GUID(IID_ITextPara, 0x8cc497c4, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
55 static ITypeLib *typelib;
57 enum tid_t {
58 NULL_tid,
59 ITextDocument_tid,
60 ITextRange_tid,
61 ITextSelection_tid,
62 ITextFont_tid,
63 ITextPara_tid,
64 LAST_tid
67 static const IID * const tid_ids[] =
69 &IID_NULL,
70 &IID_ITextDocument,
71 &IID_ITextRange,
72 &IID_ITextSelection,
73 &IID_ITextFont,
74 &IID_ITextPara,
76 static ITypeInfo *typeinfos[LAST_tid];
78 static HRESULT load_typelib(void)
80 ITypeLib *tl;
81 HRESULT hr;
83 hr = LoadRegTypeLib(&LIBID_tom, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
84 if (FAILED(hr)) {
85 ERR("LoadRegTypeLib failed: %08x\n", hr);
86 return hr;
89 if (InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
90 ITypeLib_Release(tl);
91 return hr;
94 void release_typelib(void)
96 unsigned i;
98 if (!typelib)
99 return;
101 for (i = 0; i < ARRAY_SIZE(typeinfos); i++)
102 if (typeinfos[i])
103 ITypeInfo_Release(typeinfos[i]);
105 ITypeLib_Release(typelib);
108 static HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo)
110 HRESULT hr;
112 if (!typelib)
113 hr = load_typelib();
114 if (!typelib)
115 return hr;
117 if (!typeinfos[tid])
119 ITypeInfo *ti;
121 hr = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
122 if (FAILED(hr))
124 ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hr);
125 return hr;
128 if (InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
129 ITypeInfo_Release(ti);
132 *typeinfo = typeinfos[tid];
133 return S_OK;
136 /* private IID used to get back IRichEditOleImpl pointer */
137 DEFINE_GUID(IID_Igetrichole, 0xe3ce5c7a, 0x8247, 0x4622, 0x81, 0xad, 0x11, 0x81, 0x02, 0xaa, 0x01, 0x30);
139 typedef struct ITextSelectionImpl ITextSelectionImpl;
140 typedef struct IOleClientSiteImpl IOleClientSiteImpl;
141 typedef struct ITextRangeImpl ITextRangeImpl;
143 enum textfont_prop_id {
144 FONT_ALLCAPS = 0,
145 FONT_ANIMATION,
146 FONT_BACKCOLOR,
147 FONT_BOLD,
148 FONT_EMBOSS,
149 FONT_FORECOLOR,
150 FONT_HIDDEN,
151 FONT_ENGRAVE,
152 FONT_ITALIC,
153 FONT_KERNING,
154 FONT_LANGID,
155 FONT_NAME,
156 FONT_OUTLINE,
157 FONT_POSITION,
158 FONT_PROTECTED,
159 FONT_SHADOW,
160 FONT_SIZE,
161 FONT_SMALLCAPS,
162 FONT_SPACING,
163 FONT_STRIKETHROUGH,
164 FONT_SUBSCRIPT,
165 FONT_SUPERSCRIPT,
166 FONT_UNDERLINE,
167 FONT_WEIGHT,
168 FONT_PROPID_LAST,
169 FONT_PROPID_FIRST = FONT_ALLCAPS
172 static const DWORD textfont_prop_masks[][2] = {
173 { CFM_ALLCAPS, CFE_ALLCAPS },
174 { CFM_ANIMATION },
175 { CFM_BACKCOLOR, CFE_AUTOBACKCOLOR },
176 { CFM_BOLD, CFE_BOLD },
177 { CFM_EMBOSS, CFE_EMBOSS },
178 { CFM_COLOR, CFE_AUTOCOLOR },
179 { CFM_HIDDEN, CFE_HIDDEN },
180 { CFM_IMPRINT, CFE_IMPRINT },
181 { CFM_ITALIC, CFE_ITALIC },
182 { CFM_KERNING },
183 { CFM_LCID },
184 { CFM_FACE },
185 { CFM_OUTLINE, CFE_OUTLINE },
186 { CFM_OFFSET },
187 { CFM_PROTECTED, CFE_PROTECTED },
188 { CFM_SHADOW, CFE_SHADOW },
189 { CFM_SIZE },
190 { CFM_SMALLCAPS, CFE_SMALLCAPS },
191 { CFM_SPACING },
192 { CFM_STRIKEOUT, CFE_STRIKEOUT },
193 { CFM_SUBSCRIPT, CFE_SUBSCRIPT },
194 { CFM_SUPERSCRIPT, CFE_SUPERSCRIPT },
195 { CFM_UNDERLINE, CFE_UNDERLINE },
196 { CFM_WEIGHT }
199 typedef union {
200 FLOAT f;
201 LONG l;
202 BSTR str;
203 } textfont_prop_val;
205 enum range_update_op {
206 RANGE_UPDATE_DELETE
209 typedef struct IRichEditOleImpl {
210 IUnknown IUnknown_inner;
211 IRichEditOle IRichEditOle_iface;
212 ITextDocument2Old ITextDocument2Old_iface;
213 IUnknown *outer_unk;
214 LONG ref;
216 ME_TextEditor *editor;
217 ITextSelectionImpl *txtSel;
219 struct list rangelist;
220 struct list clientsites;
221 } IRichEditOleImpl;
223 struct reole_child {
224 struct list entry;
225 IRichEditOleImpl *reole;
228 struct ITextRangeImpl {
229 struct reole_child child;
230 ITextRange ITextRange_iface;
231 LONG ref;
232 LONG start, end;
235 struct ITextSelectionImpl {
236 ITextSelection ITextSelection_iface;
237 LONG ref;
239 IRichEditOleImpl *reOle;
242 typedef struct ITextFontImpl {
243 ITextFont ITextFont_iface;
244 LONG ref;
246 ITextRange *range;
247 textfont_prop_val props[FONT_PROPID_LAST];
248 BOOL get_cache_enabled;
249 BOOL set_cache_enabled;
250 } ITextFontImpl;
252 typedef struct ITextParaImpl {
253 ITextPara ITextPara_iface;
254 LONG ref;
256 ITextRange *range;
257 } ITextParaImpl;
259 struct IOleClientSiteImpl {
260 struct reole_child child;
261 IOleClientSite IOleClientSite_iface;
262 IOleInPlaceSite IOleInPlaceSite_iface;
263 LONG ref;
266 static inline IRichEditOleImpl *impl_from_IRichEditOle(IRichEditOle *iface)
268 return CONTAINING_RECORD(iface, IRichEditOleImpl, IRichEditOle_iface);
271 static inline IRichEditOleImpl *impl_from_ITextDocument2Old(ITextDocument2Old *iface)
273 return CONTAINING_RECORD(iface, IRichEditOleImpl, ITextDocument2Old_iface);
276 static inline IRichEditOleImpl *impl_from_IUnknown(IUnknown *iface)
278 return CONTAINING_RECORD(iface, IRichEditOleImpl, IUnknown_inner);
281 static inline IOleClientSiteImpl *impl_from_IOleInPlaceSite(IOleInPlaceSite *iface)
283 return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleInPlaceSite_iface);
286 static inline ITextRangeImpl *impl_from_ITextRange(ITextRange *iface)
288 return CONTAINING_RECORD(iface, ITextRangeImpl, ITextRange_iface);
291 static inline ITextSelectionImpl *impl_from_ITextSelection(ITextSelection *iface)
293 return CONTAINING_RECORD(iface, ITextSelectionImpl, ITextSelection_iface);
296 static inline ITextFontImpl *impl_from_ITextFont(ITextFont *iface)
298 return CONTAINING_RECORD(iface, ITextFontImpl, ITextFont_iface);
301 static inline ITextParaImpl *impl_from_ITextPara(ITextPara *iface)
303 return CONTAINING_RECORD(iface, ITextParaImpl, ITextPara_iface);
306 static HRESULT create_textfont(ITextRange*, const ITextFontImpl*, ITextFont**);
307 static HRESULT create_textpara(ITextRange*, ITextPara**);
308 static ITextSelectionImpl *CreateTextSelection(IRichEditOleImpl*);
310 static HRESULT textrange_get_storylength(ME_TextEditor *editor, LONG *length)
312 if (!length)
313 return E_INVALIDARG;
315 *length = ME_GetTextLength(editor) + 1;
316 return S_OK;
319 static void textranges_update_ranges(IRichEditOleImpl *reole, LONG start, LONG end, enum range_update_op op)
321 ITextRangeImpl *range;
323 LIST_FOR_EACH_ENTRY(range, &reole->rangelist, ITextRangeImpl, child.entry) {
324 switch (op)
326 case RANGE_UPDATE_DELETE:
327 /* range fully covered by deleted range - collapse to insertion point */
328 if (range->start >= start && range->end <= end)
329 range->start = range->end = start;
330 /* deleted range cuts from the right */
331 else if (range->start < start && range->end <= end)
332 range->end = start;
333 /* deleted range cuts from the left */
334 else if (range->start >= start && range->end > end) {
335 range->start = start;
336 range->end -= end - start;
338 /* deleted range cuts within */
339 else
340 range->end -= end - start;
341 break;
342 default:
343 FIXME("unknown update op, %d\n", op);
348 static inline BOOL is_equal_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *left,
349 textfont_prop_val *right)
351 switch (propid)
353 case FONT_ALLCAPS:
354 case FONT_ANIMATION:
355 case FONT_BACKCOLOR:
356 case FONT_BOLD:
357 case FONT_EMBOSS:
358 case FONT_FORECOLOR:
359 case FONT_HIDDEN:
360 case FONT_ENGRAVE:
361 case FONT_ITALIC:
362 case FONT_KERNING:
363 case FONT_LANGID:
364 case FONT_OUTLINE:
365 case FONT_PROTECTED:
366 case FONT_SHADOW:
367 case FONT_SMALLCAPS:
368 case FONT_STRIKETHROUGH:
369 case FONT_SUBSCRIPT:
370 case FONT_SUPERSCRIPT:
371 case FONT_UNDERLINE:
372 case FONT_WEIGHT:
373 return left->l == right->l;
374 case FONT_NAME:
375 return !wcscmp(left->str, right->str);
376 case FONT_POSITION:
377 case FONT_SIZE:
378 case FONT_SPACING:
379 return left->f == right->f;
380 default:
381 FIXME("unhandled font property %d\n", propid);
382 return FALSE;
386 static inline void init_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *v)
388 switch (propid)
390 case FONT_ALLCAPS:
391 case FONT_ANIMATION:
392 case FONT_BACKCOLOR:
393 case FONT_BOLD:
394 case FONT_EMBOSS:
395 case FONT_FORECOLOR:
396 case FONT_HIDDEN:
397 case FONT_ENGRAVE:
398 case FONT_ITALIC:
399 case FONT_KERNING:
400 case FONT_LANGID:
401 case FONT_OUTLINE:
402 case FONT_PROTECTED:
403 case FONT_SHADOW:
404 case FONT_SMALLCAPS:
405 case FONT_STRIKETHROUGH:
406 case FONT_SUBSCRIPT:
407 case FONT_SUPERSCRIPT:
408 case FONT_UNDERLINE:
409 case FONT_WEIGHT:
410 v->l = tomUndefined;
411 return;
412 case FONT_NAME:
413 v->str = NULL;
414 return;
415 case FONT_POSITION:
416 case FONT_SIZE:
417 case FONT_SPACING:
418 v->f = tomUndefined;
419 return;
420 default:
421 FIXME("unhandled font property %d\n", propid);
422 v->l = tomUndefined;
423 return;
427 static inline FLOAT twips_to_points(LONG value)
429 return value * 72.0 / 1440;
432 static inline FLOAT points_to_twips(FLOAT value)
434 return value * 1440 / 72.0;
437 static HRESULT get_textfont_prop_for_pos(const IRichEditOleImpl *reole, int pos, enum textfont_prop_id propid,
438 textfont_prop_val *value)
440 ME_Cursor from, to;
441 CHARFORMAT2W fmt;
443 memset(&fmt, 0, sizeof(fmt));
444 fmt.cbSize = sizeof(fmt);
445 fmt.dwMask = textfont_prop_masks[propid][0];
447 cursor_from_char_ofs( reole->editor, pos, &from );
448 to = from;
449 ME_MoveCursorChars(reole->editor, &to, 1, FALSE);
450 ME_GetCharFormat(reole->editor, &from, &to, &fmt);
452 switch (propid)
454 case FONT_ALLCAPS:
455 case FONT_BOLD:
456 case FONT_EMBOSS:
457 case FONT_HIDDEN:
458 case FONT_ENGRAVE:
459 case FONT_ITALIC:
460 case FONT_OUTLINE:
461 case FONT_PROTECTED:
462 case FONT_SHADOW:
463 case FONT_SMALLCAPS:
464 case FONT_STRIKETHROUGH:
465 case FONT_SUBSCRIPT:
466 case FONT_SUPERSCRIPT:
467 case FONT_UNDERLINE:
468 value->l = fmt.dwEffects & textfont_prop_masks[propid][1] ? tomTrue : tomFalse;
469 break;
470 case FONT_ANIMATION:
471 value->l = fmt.bAnimation;
472 break;
473 case FONT_BACKCOLOR:
474 value->l = fmt.dwEffects & CFE_AUTOBACKCOLOR ? GetSysColor(COLOR_WINDOW) : fmt.crBackColor;
475 break;
476 case FONT_FORECOLOR:
477 value->l = fmt.dwEffects & CFE_AUTOCOLOR ? GetSysColor(COLOR_WINDOWTEXT) : fmt.crTextColor;
478 break;
479 case FONT_KERNING:
480 value->f = twips_to_points(fmt.wKerning);
481 break;
482 case FONT_LANGID:
483 value->l = fmt.lcid;
484 break;
485 case FONT_NAME:
486 /* this case is used exclusively by GetName() */
487 value->str = SysAllocString(fmt.szFaceName);
488 if (!value->str)
489 return E_OUTOFMEMORY;
490 break;
491 case FONT_POSITION:
492 value->f = twips_to_points(fmt.yOffset);
493 break;
494 case FONT_SIZE:
495 value->f = twips_to_points(fmt.yHeight);
496 break;
497 case FONT_SPACING:
498 value->f = fmt.sSpacing;
499 break;
500 case FONT_WEIGHT:
501 value->l = fmt.wWeight;
502 break;
503 default:
504 FIXME("unhandled font property %d\n", propid);
505 return E_FAIL;
508 return S_OK;
511 static inline const IRichEditOleImpl *get_range_reole(ITextRange *range)
513 IRichEditOleImpl *reole = NULL;
514 ITextRange_QueryInterface(range, &IID_Igetrichole, (void**)&reole);
515 return reole;
518 static void textrange_set_font(ITextRange *range, ITextFont *font)
520 CHARFORMAT2W fmt;
521 HRESULT hr;
522 LONG value;
523 BSTR str;
524 FLOAT f;
526 #define CHARFORMAT_SET_B_FIELD(mask, value) \
527 if (hr == S_OK && value != tomUndefined) { \
528 fmt.dwMask |= CFM_##mask; \
529 if (value == tomTrue) fmt.dwEffects |= CFE_##mask; \
532 /* fill format data from font */
533 memset(&fmt, 0, sizeof(fmt));
534 fmt.cbSize = sizeof(fmt);
536 value = tomUndefined;
537 hr = ITextFont_GetAllCaps(font, &value);
538 CHARFORMAT_SET_B_FIELD(ALLCAPS, value);
540 value = tomUndefined;
541 hr = ITextFont_GetBold(font, &value);
542 CHARFORMAT_SET_B_FIELD(BOLD, value);
544 value = tomUndefined;
545 hr = ITextFont_GetEmboss(font, &value);
546 CHARFORMAT_SET_B_FIELD(EMBOSS, value);
548 value = tomUndefined;
549 hr = ITextFont_GetHidden(font, &value);
550 CHARFORMAT_SET_B_FIELD(HIDDEN, value);
552 value = tomUndefined;
553 hr = ITextFont_GetEngrave(font, &value);
554 CHARFORMAT_SET_B_FIELD(IMPRINT, value);
556 value = tomUndefined;
557 hr = ITextFont_GetItalic(font, &value);
558 CHARFORMAT_SET_B_FIELD(ITALIC, value);
560 value = tomUndefined;
561 hr = ITextFont_GetOutline(font, &value);
562 CHARFORMAT_SET_B_FIELD(OUTLINE, value);
564 value = tomUndefined;
565 hr = ITextFont_GetProtected(font, &value);
566 CHARFORMAT_SET_B_FIELD(PROTECTED, value);
568 value = tomUndefined;
569 hr = ITextFont_GetShadow(font, &value);
570 CHARFORMAT_SET_B_FIELD(SHADOW, value);
572 value = tomUndefined;
573 hr = ITextFont_GetSmallCaps(font, &value);
574 CHARFORMAT_SET_B_FIELD(SMALLCAPS, value);
576 value = tomUndefined;
577 hr = ITextFont_GetStrikeThrough(font, &value);
578 CHARFORMAT_SET_B_FIELD(STRIKEOUT, value);
580 value = tomUndefined;
581 hr = ITextFont_GetSubscript(font, &value);
582 CHARFORMAT_SET_B_FIELD(SUBSCRIPT, value);
584 value = tomUndefined;
585 hr = ITextFont_GetSuperscript(font, &value);
586 CHARFORMAT_SET_B_FIELD(SUPERSCRIPT, value);
588 value = tomUndefined;
589 hr = ITextFont_GetUnderline(font, &value);
590 CHARFORMAT_SET_B_FIELD(UNDERLINE, value);
592 #undef CHARFORMAT_SET_B_FIELD
594 value = tomUndefined;
595 hr = ITextFont_GetAnimation(font, &value);
596 if (hr == S_OK && value != tomUndefined) {
597 fmt.dwMask |= CFM_ANIMATION;
598 fmt.bAnimation = value;
601 value = tomUndefined;
602 hr = ITextFont_GetBackColor(font, &value);
603 if (hr == S_OK && value != tomUndefined) {
604 fmt.dwMask |= CFM_BACKCOLOR;
605 if (value == tomAutoColor)
606 fmt.dwEffects |= CFE_AUTOBACKCOLOR;
607 else
608 fmt.crBackColor = value;
611 value = tomUndefined;
612 hr = ITextFont_GetForeColor(font, &value);
613 if (hr == S_OK && value != tomUndefined) {
614 fmt.dwMask |= CFM_COLOR;
615 if (value == tomAutoColor)
616 fmt.dwEffects |= CFE_AUTOCOLOR;
617 else
618 fmt.crTextColor = value;
621 value = tomUndefined;
622 hr = ITextFont_GetKerning(font, &f);
623 if (hr == S_OK && f != tomUndefined) {
624 fmt.dwMask |= CFM_KERNING;
625 fmt.wKerning = points_to_twips(f);
628 value = tomUndefined;
629 hr = ITextFont_GetLanguageID(font, &value);
630 if (hr == S_OK && value != tomUndefined) {
631 fmt.dwMask |= CFM_LCID;
632 fmt.lcid = value;
635 if (ITextFont_GetName(font, &str) == S_OK) {
636 fmt.dwMask |= CFM_FACE;
637 lstrcpynW(fmt.szFaceName, str, ARRAY_SIZE(fmt.szFaceName));
638 SysFreeString(str);
641 hr = ITextFont_GetPosition(font, &f);
642 if (hr == S_OK && f != tomUndefined) {
643 fmt.dwMask |= CFM_OFFSET;
644 fmt.yOffset = points_to_twips(f);
647 hr = ITextFont_GetSize(font, &f);
648 if (hr == S_OK && f != tomUndefined) {
649 fmt.dwMask |= CFM_SIZE;
650 fmt.yHeight = points_to_twips(f);
653 hr = ITextFont_GetSpacing(font, &f);
654 if (hr == S_OK && f != tomUndefined) {
655 fmt.dwMask |= CFM_SPACING;
656 fmt.sSpacing = f;
659 hr = ITextFont_GetWeight(font, &value);
660 if (hr == S_OK && value != tomUndefined) {
661 fmt.dwMask |= CFM_WEIGHT;
662 fmt.wWeight = value;
665 if (fmt.dwMask)
667 const IRichEditOleImpl *reole = get_range_reole(range);
668 ME_Cursor from, to;
669 LONG start, end;
671 ITextRange_GetStart(range, &start);
672 ITextRange_GetEnd(range, &end);
674 cursor_from_char_ofs( reole->editor, start, &from );
675 cursor_from_char_ofs( reole->editor, end, &to );
676 ME_SetCharFormat(reole->editor, &from, &to, &fmt);
680 static HRESULT get_textfont_prop(const ITextFontImpl *font, enum textfont_prop_id propid, textfont_prop_val *value)
682 const IRichEditOleImpl *reole;
683 textfont_prop_val v;
684 LONG start, end, i;
685 HRESULT hr;
687 /* when font is not attached to any range use cached values */
688 if (!font->range || font->get_cache_enabled) {
689 *value = font->props[propid];
690 return S_OK;
693 if (!(reole = get_range_reole(font->range)))
694 return CO_E_RELEASED;
696 init_textfont_prop_value(propid, value);
698 ITextRange_GetStart(font->range, &start);
699 ITextRange_GetEnd(font->range, &end);
701 /* iterate trough a range to see if property value is consistent */
702 hr = get_textfont_prop_for_pos(reole, start, propid, &v);
703 if (FAILED(hr))
704 return hr;
706 for (i = start + 1; i < end; i++) {
707 textfont_prop_val cur;
709 hr = get_textfont_prop_for_pos(reole, i, propid, &cur);
710 if (FAILED(hr))
711 return hr;
713 if (!is_equal_textfont_prop_value(propid, &v, &cur))
714 return S_OK;
717 *value = v;
718 return S_OK;
721 static HRESULT get_textfont_propf(const ITextFontImpl *font, enum textfont_prop_id propid, FLOAT *value)
723 textfont_prop_val v;
724 HRESULT hr;
726 if (!value)
727 return E_INVALIDARG;
729 hr = get_textfont_prop(font, propid, &v);
730 *value = v.f;
731 return hr;
734 static HRESULT get_textfont_propl(const ITextFontImpl *font, enum textfont_prop_id propid, LONG *value)
736 textfont_prop_val v;
737 HRESULT hr;
739 if (!value)
740 return E_INVALIDARG;
742 hr = get_textfont_prop(font, propid, &v);
743 *value = v.l;
744 return hr;
747 /* Value should already have a terminal value, for boolean properties it means tomToggle is not handled */
748 static HRESULT set_textfont_prop(ITextFontImpl *font, enum textfont_prop_id propid, const textfont_prop_val *value)
750 const IRichEditOleImpl *reole;
751 ME_Cursor from, to;
752 CHARFORMAT2W fmt;
753 LONG start, end;
755 /* when font is not attached to any range use cache */
756 if (!font->range || font->set_cache_enabled) {
757 if (propid == FONT_NAME) {
758 SysFreeString(font->props[propid].str);
759 font->props[propid].str = SysAllocString(value->str);
761 else
762 font->props[propid] = *value;
763 return S_OK;
766 if (!(reole = get_range_reole(font->range)))
767 return CO_E_RELEASED;
769 memset(&fmt, 0, sizeof(fmt));
770 fmt.cbSize = sizeof(fmt);
771 fmt.dwMask = textfont_prop_masks[propid][0];
773 switch (propid)
775 case FONT_ALLCAPS:
776 case FONT_BOLD:
777 case FONT_EMBOSS:
778 case FONT_HIDDEN:
779 case FONT_ENGRAVE:
780 case FONT_ITALIC:
781 case FONT_OUTLINE:
782 case FONT_PROTECTED:
783 case FONT_SHADOW:
784 case FONT_SMALLCAPS:
785 case FONT_STRIKETHROUGH:
786 case FONT_SUBSCRIPT:
787 case FONT_SUPERSCRIPT:
788 case FONT_UNDERLINE:
789 fmt.dwEffects = value->l == tomTrue ? textfont_prop_masks[propid][1] : 0;
790 break;
791 case FONT_ANIMATION:
792 fmt.bAnimation = value->l;
793 break;
794 case FONT_BACKCOLOR:
795 case FONT_FORECOLOR:
796 if (value->l == tomAutoColor)
797 fmt.dwEffects = textfont_prop_masks[propid][1];
798 else if (propid == FONT_BACKCOLOR)
799 fmt.crBackColor = value->l;
800 else
801 fmt.crTextColor = value->l;
802 break;
803 case FONT_KERNING:
804 fmt.wKerning = value->f;
805 break;
806 case FONT_LANGID:
807 fmt.lcid = value->l;
808 break;
809 case FONT_POSITION:
810 fmt.yOffset = value->f;
811 break;
812 case FONT_SIZE:
813 fmt.yHeight = value->f;
814 break;
815 case FONT_SPACING:
816 fmt.sSpacing = value->f;
817 break;
818 case FONT_WEIGHT:
819 fmt.wWeight = value->l;
820 break;
821 case FONT_NAME:
822 lstrcpynW(fmt.szFaceName, value->str, ARRAY_SIZE(fmt.szFaceName));
823 break;
824 default:
825 FIXME("unhandled font property %d\n", propid);
826 return E_FAIL;
829 ITextRange_GetStart(font->range, &start);
830 ITextRange_GetEnd(font->range, &end);
832 cursor_from_char_ofs( reole->editor, start, &from );
833 cursor_from_char_ofs( reole->editor, end, &to );
834 ME_SetCharFormat(reole->editor, &from, &to, &fmt);
836 return S_OK;
839 static inline HRESULT set_textfont_propl(ITextFontImpl *font, enum textfont_prop_id propid, LONG value)
841 textfont_prop_val v;
842 v.l = value;
843 return set_textfont_prop(font, propid, &v);
846 static inline HRESULT set_textfont_propf(ITextFontImpl *font, enum textfont_prop_id propid, FLOAT value)
848 textfont_prop_val v;
849 v.f = value;
850 return set_textfont_prop(font, propid, &v);
853 static HRESULT set_textfont_propd(ITextFontImpl *font, enum textfont_prop_id propid, LONG value)
855 textfont_prop_val v;
857 switch (value)
859 case tomUndefined:
860 return S_OK;
861 case tomToggle: {
862 LONG oldvalue;
863 get_textfont_propl(font, propid, &oldvalue);
864 if (oldvalue == tomFalse)
865 value = tomTrue;
866 else if (oldvalue == tomTrue)
867 value = tomFalse;
868 else
869 return E_INVALIDARG;
870 /* fallthrough */
872 case tomTrue:
873 case tomFalse:
874 v.l = value;
875 return set_textfont_prop(font, propid, &v);
876 default:
877 return E_INVALIDARG;
881 static HRESULT textfont_getname_from_range(ITextRange *range, BSTR *ret)
883 const IRichEditOleImpl *reole;
884 textfont_prop_val v;
885 HRESULT hr;
886 LONG start;
888 if (!(reole = get_range_reole(range)))
889 return CO_E_RELEASED;
891 ITextRange_GetStart(range, &start);
892 hr = get_textfont_prop_for_pos(reole, start, FONT_NAME, &v);
893 *ret = v.str;
894 return hr;
897 static void textfont_cache_range_props(ITextFontImpl *font)
899 enum textfont_prop_id propid;
900 for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++) {
901 if (propid == FONT_NAME)
902 textfont_getname_from_range(font->range, &font->props[propid].str);
903 else
904 get_textfont_prop(font, propid, &font->props[propid]);
908 static HRESULT textrange_expand(ITextRange *range, LONG unit, LONG *delta)
910 LONG expand_start, expand_end;
912 switch (unit)
914 case tomStory:
915 expand_start = 0;
916 ITextRange_GetStoryLength(range, &expand_end);
917 break;
918 default:
919 FIXME("unit %d is not supported\n", unit);
920 return E_NOTIMPL;
923 if (delta) {
924 LONG start, end;
926 ITextRange_GetStart(range, &start);
927 ITextRange_GetEnd(range, &end);
928 *delta = expand_end - expand_start - (end - start);
931 ITextRange_SetStart(range, expand_start);
932 ITextRange_SetEnd(range, expand_end);
934 return S_OK;
937 static HRESULT WINAPI IRichEditOleImpl_inner_fnQueryInterface(IUnknown *iface, REFIID riid, LPVOID *ppvObj)
939 IRichEditOleImpl *This = impl_from_IUnknown(iface);
941 TRACE("%p %s\n", This, debugstr_guid(riid));
943 *ppvObj = NULL;
944 if (IsEqualGUID(riid, &IID_IUnknown))
945 *ppvObj = &This->IUnknown_inner;
946 else if (IsEqualGUID(riid, &IID_IRichEditOle))
947 *ppvObj = &This->IRichEditOle_iface;
948 else if (IsEqualGUID(riid, &IID_ITextDocument) || IsEqualGUID(riid, &IID_ITextDocument2Old))
949 *ppvObj = &This->ITextDocument2Old_iface;
950 if (*ppvObj)
952 IUnknown_AddRef((IUnknown *)*ppvObj);
953 return S_OK;
955 FIXME("%p: unhandled interface %s\n", This, debugstr_guid(riid));
957 return E_NOINTERFACE;
960 static ULONG WINAPI IRichEditOleImpl_inner_fnAddRef(IUnknown *iface)
962 IRichEditOleImpl *This = impl_from_IUnknown(iface);
963 ULONG ref = InterlockedIncrement(&This->ref);
965 TRACE("%p ref = %u\n", This, ref);
967 return ref;
970 static ULONG WINAPI IRichEditOleImpl_inner_fnRelease(IUnknown *iface)
972 IRichEditOleImpl *This = impl_from_IUnknown(iface);
973 ULONG ref = InterlockedDecrement(&This->ref);
975 TRACE ("%p ref=%u\n", This, ref);
977 if (!ref)
979 IOleClientSiteImpl *clientsite;
980 ITextRangeImpl *txtRge;
982 This->editor->reOle = NULL;
983 if (This->txtSel) {
984 This->txtSel->reOle = NULL;
985 ITextSelection_Release(&This->txtSel->ITextSelection_iface);
988 LIST_FOR_EACH_ENTRY(txtRge, &This->rangelist, ITextRangeImpl, child.entry)
989 txtRge->child.reole = NULL;
991 LIST_FOR_EACH_ENTRY(clientsite, &This->clientsites, IOleClientSiteImpl, child.entry)
992 clientsite->child.reole = NULL;
994 heap_free(This);
996 return ref;
999 static const IUnknownVtbl reo_unk_vtbl =
1001 IRichEditOleImpl_inner_fnQueryInterface,
1002 IRichEditOleImpl_inner_fnAddRef,
1003 IRichEditOleImpl_inner_fnRelease
1006 static HRESULT WINAPI
1007 IRichEditOle_fnQueryInterface(IRichEditOle *me, REFIID riid, LPVOID *ppvObj)
1009 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1010 return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj);
1013 static ULONG WINAPI
1014 IRichEditOle_fnAddRef(IRichEditOle *me)
1016 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1017 return IUnknown_AddRef(This->outer_unk);
1020 static ULONG WINAPI
1021 IRichEditOle_fnRelease(IRichEditOle *me)
1023 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1024 return IUnknown_Release(This->outer_unk);
1027 static HRESULT WINAPI
1028 IRichEditOle_fnActivateAs(IRichEditOle *me, REFCLSID rclsid, REFCLSID rclsidAs)
1030 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1031 FIXME("stub %p\n",This);
1032 return E_NOTIMPL;
1035 static HRESULT WINAPI
1036 IRichEditOle_fnContextSensitiveHelp(IRichEditOle *me, BOOL fEnterMode)
1038 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1039 FIXME("stub %p\n",This);
1040 return E_NOTIMPL;
1043 static HRESULT WINAPI
1044 IRichEditOle_fnConvertObject(IRichEditOle *me, LONG iob,
1045 REFCLSID rclsidNew, LPCSTR lpstrUserTypeNew)
1047 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1048 FIXME("stub %p\n",This);
1049 return E_NOTIMPL;
1052 static inline IOleClientSiteImpl *impl_from_IOleClientSite(IOleClientSite *iface)
1054 return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleClientSite_iface);
1057 static HRESULT WINAPI
1058 IOleClientSite_fnQueryInterface(IOleClientSite *me, REFIID riid, LPVOID *ppvObj)
1060 IOleClientSiteImpl *This = impl_from_IOleClientSite(me);
1061 TRACE("%p %s\n", me, debugstr_guid(riid) );
1063 *ppvObj = NULL;
1064 if (IsEqualGUID(riid, &IID_IUnknown) ||
1065 IsEqualGUID(riid, &IID_IOleClientSite))
1066 *ppvObj = me;
1067 else if (IsEqualGUID(riid, &IID_IOleWindow) ||
1068 IsEqualGUID(riid, &IID_IOleInPlaceSite))
1069 *ppvObj = &This->IOleInPlaceSite_iface;
1070 if (*ppvObj)
1072 IOleClientSite_AddRef(me);
1073 return S_OK;
1075 FIXME("%p: unhandled interface %s\n", me, debugstr_guid(riid) );
1077 return E_NOINTERFACE;
1080 static ULONG WINAPI IOleClientSite_fnAddRef(IOleClientSite *iface)
1082 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1083 ULONG ref = InterlockedIncrement(&This->ref);
1084 TRACE("(%p)->(%u)\n", This, ref);
1085 return ref;
1088 static ULONG WINAPI IOleClientSite_fnRelease(IOleClientSite *iface)
1090 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1091 ULONG ref = InterlockedDecrement(&This->ref);
1093 TRACE("(%p)->(%u)\n", This, ref);
1095 if (ref == 0) {
1096 if (This->child.reole) {
1097 list_remove(&This->child.entry);
1098 This->child.reole = NULL;
1100 heap_free(This);
1102 return ref;
1105 static HRESULT WINAPI IOleClientSite_fnSaveObject(IOleClientSite *iface)
1107 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1108 if (!This->child.reole)
1109 return CO_E_RELEASED;
1111 FIXME("stub %p\n", iface);
1112 return E_NOTIMPL;
1115 static HRESULT WINAPI IOleClientSite_fnGetMoniker(IOleClientSite *iface, DWORD dwAssign,
1116 DWORD dwWhichMoniker, IMoniker **ppmk)
1118 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1119 if (!This->child.reole)
1120 return CO_E_RELEASED;
1122 FIXME("stub %p\n", iface);
1123 return E_NOTIMPL;
1126 static HRESULT WINAPI IOleClientSite_fnGetContainer(IOleClientSite *iface,
1127 IOleContainer **ppContainer)
1129 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1130 if (!This->child.reole)
1131 return CO_E_RELEASED;
1133 FIXME("stub %p\n", iface);
1134 return E_NOTIMPL;
1137 static HRESULT WINAPI IOleClientSite_fnShowObject(IOleClientSite *iface)
1139 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1140 if (!This->child.reole)
1141 return CO_E_RELEASED;
1143 FIXME("stub %p\n", iface);
1144 return E_NOTIMPL;
1147 static HRESULT WINAPI IOleClientSite_fnOnShowWindow(IOleClientSite *iface, BOOL fShow)
1149 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1150 if (!This->child.reole)
1151 return CO_E_RELEASED;
1153 FIXME("stub %p\n", iface);
1154 return E_NOTIMPL;
1157 static HRESULT WINAPI IOleClientSite_fnRequestNewObjectLayout(IOleClientSite *iface)
1159 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1160 if (!This->child.reole)
1161 return CO_E_RELEASED;
1163 FIXME("stub %p\n", iface);
1164 return E_NOTIMPL;
1167 static const IOleClientSiteVtbl ocst = {
1168 IOleClientSite_fnQueryInterface,
1169 IOleClientSite_fnAddRef,
1170 IOleClientSite_fnRelease,
1171 IOleClientSite_fnSaveObject,
1172 IOleClientSite_fnGetMoniker,
1173 IOleClientSite_fnGetContainer,
1174 IOleClientSite_fnShowObject,
1175 IOleClientSite_fnOnShowWindow,
1176 IOleClientSite_fnRequestNewObjectLayout
1179 /* IOleInPlaceSite interface */
1180 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnQueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppvObj)
1182 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1183 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppvObj);
1186 static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnAddRef(IOleInPlaceSite *iface)
1188 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1189 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1192 static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnRelease(IOleInPlaceSite *iface)
1194 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1195 return IOleClientSite_Release(&This->IOleClientSite_iface);
1198 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindow(IOleInPlaceSite *iface, HWND *phwnd)
1200 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1202 TRACE("(%p)->(%p)\n", This, phwnd);
1204 if (!This->child.reole)
1205 return CO_E_RELEASED;
1207 if (!phwnd)
1208 return E_INVALIDARG;
1210 *phwnd = This->child.reole->editor->hWnd;
1211 return S_OK;
1214 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode)
1216 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1217 FIXME("not implemented: (%p)->(%d)\n", This, fEnterMode);
1218 return E_NOTIMPL;
1221 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnCanInPlaceActivate(IOleInPlaceSite *iface)
1223 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1224 FIXME("not implemented: (%p)\n", This);
1225 return E_NOTIMPL;
1228 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceActivate(IOleInPlaceSite *iface)
1230 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1231 FIXME("not implemented: (%p)\n", This);
1232 return E_NOTIMPL;
1235 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIActivate(IOleInPlaceSite *iface)
1237 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1238 FIXME("not implemented: (%p)\n", This);
1239 return E_NOTIMPL;
1242 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindowContext(IOleInPlaceSite *iface, IOleInPlaceFrame **ppFrame,
1243 IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
1244 LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
1246 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1247 FIXME("not implemented: (%p)->(%p %p %p %p %p)\n", This, ppFrame, ppDoc, lprcPosRect, lprcClipRect, lpFrameInfo);
1248 return E_NOTIMPL;
1251 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnScroll(IOleInPlaceSite *iface, SIZE scrollExtent)
1253 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1254 FIXME("not implemented: (%p)\n", This);
1255 return E_NOTIMPL;
1258 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable)
1260 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1261 FIXME("not implemented: (%p)->(%d)\n", This, fUndoable);
1262 return E_NOTIMPL;
1265 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceDeactivate(IOleInPlaceSite *iface)
1267 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1268 FIXME("not implemented: (%p)\n", This);
1269 return E_NOTIMPL;
1272 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDiscardUndoState(IOleInPlaceSite *iface)
1274 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1275 FIXME("not implemented: (%p)\n", This);
1276 return E_NOTIMPL;
1279 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDeactivateAndUndo(IOleInPlaceSite *iface)
1281 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1282 FIXME("not implemented: (%p)\n", This);
1283 return E_NOTIMPL;
1286 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect)
1288 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1289 FIXME("not implemented: (%p)->(%p)\n", This, lprcPosRect);
1290 return E_NOTIMPL;
1293 static const IOleInPlaceSiteVtbl olestvt =
1295 IOleInPlaceSite_fnQueryInterface,
1296 IOleInPlaceSite_fnAddRef,
1297 IOleInPlaceSite_fnRelease,
1298 IOleInPlaceSite_fnGetWindow,
1299 IOleInPlaceSite_fnContextSensitiveHelp,
1300 IOleInPlaceSite_fnCanInPlaceActivate,
1301 IOleInPlaceSite_fnOnInPlaceActivate,
1302 IOleInPlaceSite_fnOnUIActivate,
1303 IOleInPlaceSite_fnGetWindowContext,
1304 IOleInPlaceSite_fnScroll,
1305 IOleInPlaceSite_fnOnUIDeactivate,
1306 IOleInPlaceSite_fnOnInPlaceDeactivate,
1307 IOleInPlaceSite_fnDiscardUndoState,
1308 IOleInPlaceSite_fnDeactivateAndUndo,
1309 IOleInPlaceSite_fnOnPosRectChange
1312 static HRESULT CreateOleClientSite(IRichEditOleImpl *reOle, IOleClientSite **ret)
1314 IOleClientSiteImpl *clientSite = heap_alloc(sizeof *clientSite);
1316 if (!clientSite)
1317 return E_OUTOFMEMORY;
1319 clientSite->IOleClientSite_iface.lpVtbl = &ocst;
1320 clientSite->IOleInPlaceSite_iface.lpVtbl = &olestvt;
1321 clientSite->ref = 1;
1322 clientSite->child.reole = reOle;
1323 list_add_head(&reOle->clientsites, &clientSite->child.entry);
1325 *ret = &clientSite->IOleClientSite_iface;
1326 return S_OK;
1329 static HRESULT WINAPI
1330 IRichEditOle_fnGetClientSite(IRichEditOle *me, IOleClientSite **clientsite)
1332 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1334 TRACE("(%p)->(%p)\n", This, clientsite);
1336 if (!clientsite)
1337 return E_INVALIDARG;
1339 return CreateOleClientSite(This, clientsite);
1342 static HRESULT WINAPI
1343 IRichEditOle_fnGetClipboardData(IRichEditOle *me, CHARRANGE *lpchrg,
1344 DWORD reco, LPDATAOBJECT *lplpdataobj)
1346 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1347 ME_Cursor start;
1348 int nChars;
1350 TRACE("(%p,%p,%d)\n",This, lpchrg, reco);
1351 if(!lplpdataobj)
1352 return E_INVALIDARG;
1353 if(!lpchrg)
1355 int nFrom, nTo, nStartCur = ME_GetSelectionOfs(This->editor, &nFrom, &nTo);
1356 start = This->editor->pCursors[nStartCur];
1357 nChars = nTo - nFrom;
1359 else
1361 cursor_from_char_ofs( This->editor, lpchrg->cpMin, &start );
1362 nChars = lpchrg->cpMax - lpchrg->cpMin;
1364 return ME_GetDataObject(This->editor, &start, nChars, lplpdataobj);
1367 static LONG WINAPI IRichEditOle_fnGetLinkCount(IRichEditOle *me)
1369 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1370 FIXME("stub %p\n",This);
1371 return E_NOTIMPL;
1374 static HRESULT WINAPI
1375 IRichEditOle_fnGetObject(IRichEditOle *me, LONG iob,
1376 REOBJECT *lpreobject, DWORD dwFlags)
1378 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1379 struct re_object *reobj = NULL;
1380 LONG count = 0;
1382 TRACE("(%p)->(%x, %p, %x)\n", This, iob, lpreobject, dwFlags);
1384 if (!lpreobject || !lpreobject->cbStruct)
1385 return E_INVALIDARG;
1387 if (iob == REO_IOB_USE_CP)
1389 ME_Cursor cursor;
1391 TRACE("character offset: %d\n", lpreobject->cp);
1392 cursor_from_char_ofs( This->editor, lpreobject->cp, &cursor );
1393 if (!cursor.run->reobj)
1394 return E_INVALIDARG;
1395 else
1396 reobj = cursor.run->reobj;
1398 else if (iob == REO_IOB_SELECTION)
1400 ME_Cursor *from, *to;
1402 ME_GetSelection(This->editor, &from, &to);
1403 if (!from->run->reobj)
1404 return E_INVALIDARG;
1405 else
1406 reobj = from->run->reobj;
1408 else
1410 if (iob < 0 || iob >= IRichEditOle_GetObjectCount(me))
1411 return E_INVALIDARG;
1412 LIST_FOR_EACH_ENTRY(reobj, &This->editor->reobj_list, struct re_object, entry)
1414 if (count == iob)
1415 break;
1416 count++;
1419 ME_CopyReObject(lpreobject, &reobj->obj, dwFlags);
1420 return S_OK;
1423 static LONG WINAPI
1424 IRichEditOle_fnGetObjectCount(IRichEditOle *me)
1426 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1427 TRACE("(%p)\n",This);
1428 return list_count(&This->editor->reobj_list);
1431 static HRESULT WINAPI
1432 IRichEditOle_fnHandsOffStorage(IRichEditOle *me, LONG iob)
1434 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1435 FIXME("stub %p\n",This);
1436 return E_NOTIMPL;
1439 static HRESULT WINAPI
1440 IRichEditOle_fnImportDataObject(IRichEditOle *me, LPDATAOBJECT lpdataobj,
1441 CLIPFORMAT cf, HGLOBAL hMetaPict)
1443 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1444 FIXME("stub %p\n",This);
1445 return E_NOTIMPL;
1448 static HRESULT WINAPI
1449 IRichEditOle_fnInPlaceDeactivate(IRichEditOle *me)
1451 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1452 FIXME("stub %p\n",This);
1453 return E_NOTIMPL;
1456 static HRESULT WINAPI
1457 IRichEditOle_fnInsertObject(IRichEditOle *me, REOBJECT *reo)
1459 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1461 TRACE("(%p,%p)\n", This, reo);
1463 if (!reo)
1464 return E_INVALIDARG;
1466 if (reo->cbStruct < sizeof(*reo)) return STG_E_INVALIDPARAMETER;
1468 ME_InsertOLEFromCursor(This->editor, reo, 0);
1469 ME_CommitUndo(This->editor);
1470 ME_UpdateRepaint(This->editor, FALSE);
1471 return S_OK;
1474 static HRESULT WINAPI IRichEditOle_fnSaveCompleted(IRichEditOle *me, LONG iob,
1475 LPSTORAGE lpstg)
1477 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1478 FIXME("stub %p\n",This);
1479 return E_NOTIMPL;
1482 static HRESULT WINAPI
1483 IRichEditOle_fnSetDvaspect(IRichEditOle *me, LONG iob, DWORD dvaspect)
1485 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1486 FIXME("stub %p\n",This);
1487 return E_NOTIMPL;
1490 static HRESULT WINAPI IRichEditOle_fnSetHostNames(IRichEditOle *me,
1491 LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj)
1493 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1494 FIXME("stub %p %s %s\n",This, lpstrContainerApp, lpstrContainerObj);
1495 return E_NOTIMPL;
1498 static HRESULT WINAPI
1499 IRichEditOle_fnSetLinkAvailable(IRichEditOle *me, LONG iob, BOOL fAvailable)
1501 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1502 FIXME("stub %p\n",This);
1503 return E_NOTIMPL;
1506 static const IRichEditOleVtbl revt = {
1507 IRichEditOle_fnQueryInterface,
1508 IRichEditOle_fnAddRef,
1509 IRichEditOle_fnRelease,
1510 IRichEditOle_fnGetClientSite,
1511 IRichEditOle_fnGetObjectCount,
1512 IRichEditOle_fnGetLinkCount,
1513 IRichEditOle_fnGetObject,
1514 IRichEditOle_fnInsertObject,
1515 IRichEditOle_fnConvertObject,
1516 IRichEditOle_fnActivateAs,
1517 IRichEditOle_fnSetHostNames,
1518 IRichEditOle_fnSetLinkAvailable,
1519 IRichEditOle_fnSetDvaspect,
1520 IRichEditOle_fnHandsOffStorage,
1521 IRichEditOle_fnSaveCompleted,
1522 IRichEditOle_fnInPlaceDeactivate,
1523 IRichEditOle_fnContextSensitiveHelp,
1524 IRichEditOle_fnGetClipboardData,
1525 IRichEditOle_fnImportDataObject
1528 /* ITextRange interface */
1529 static HRESULT WINAPI ITextRange_fnQueryInterface(ITextRange *me, REFIID riid, void **ppvObj)
1531 ITextRangeImpl *This = impl_from_ITextRange(me);
1533 *ppvObj = NULL;
1534 if (IsEqualGUID(riid, &IID_IUnknown)
1535 || IsEqualGUID(riid, &IID_IDispatch)
1536 || IsEqualGUID(riid, &IID_ITextRange))
1538 *ppvObj = me;
1539 ITextRange_AddRef(me);
1540 return S_OK;
1542 else if (IsEqualGUID(riid, &IID_Igetrichole))
1544 *ppvObj = This->child.reole;
1545 return S_OK;
1548 return E_NOINTERFACE;
1551 static ULONG WINAPI ITextRange_fnAddRef(ITextRange *me)
1553 ITextRangeImpl *This = impl_from_ITextRange(me);
1554 return InterlockedIncrement(&This->ref);
1557 static ULONG WINAPI ITextRange_fnRelease(ITextRange *me)
1559 ITextRangeImpl *This = impl_from_ITextRange(me);
1560 ULONG ref = InterlockedDecrement(&This->ref);
1562 TRACE ("%p ref=%u\n", This, ref);
1563 if (ref == 0)
1565 if (This->child.reole)
1567 list_remove(&This->child.entry);
1568 This->child.reole = NULL;
1570 heap_free(This);
1572 return ref;
1575 static HRESULT WINAPI ITextRange_fnGetTypeInfoCount(ITextRange *me, UINT *pctinfo)
1577 ITextRangeImpl *This = impl_from_ITextRange(me);
1578 TRACE("(%p)->(%p)\n", This, pctinfo);
1579 *pctinfo = 1;
1580 return S_OK;
1583 static HRESULT WINAPI ITextRange_fnGetTypeInfo(ITextRange *me, UINT iTInfo, LCID lcid,
1584 ITypeInfo **ppTInfo)
1586 ITextRangeImpl *This = impl_from_ITextRange(me);
1587 HRESULT hr;
1589 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
1591 hr = get_typeinfo(ITextRange_tid, ppTInfo);
1592 if (SUCCEEDED(hr))
1593 ITypeInfo_AddRef(*ppTInfo);
1594 return hr;
1597 static HRESULT WINAPI ITextRange_fnGetIDsOfNames(ITextRange *me, REFIID riid, LPOLESTR *rgszNames,
1598 UINT cNames, LCID lcid, DISPID *rgDispId)
1600 ITextRangeImpl *This = impl_from_ITextRange(me);
1601 ITypeInfo *ti;
1602 HRESULT hr;
1604 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
1605 rgDispId);
1607 hr = get_typeinfo(ITextRange_tid, &ti);
1608 if (SUCCEEDED(hr))
1609 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
1610 return hr;
1613 static HRESULT WINAPI ITextRange_fnInvoke(ITextRange *me, DISPID dispIdMember, REFIID riid,
1614 LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1615 VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
1616 UINT *puArgErr)
1618 ITextRangeImpl *This = impl_from_ITextRange(me);
1619 ITypeInfo *ti;
1620 HRESULT hr;
1622 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
1623 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1625 hr = get_typeinfo(ITextRange_tid, &ti);
1626 if (SUCCEEDED(hr))
1627 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1628 return hr;
1631 static HRESULT WINAPI ITextRange_fnGetText(ITextRange *me, BSTR *str)
1633 ITextRangeImpl *This = impl_from_ITextRange(me);
1634 ME_TextEditor *editor;
1635 ME_Cursor start, end;
1636 int length;
1637 BOOL bEOP;
1639 TRACE("(%p)->(%p)\n", This, str);
1641 if (!This->child.reole)
1642 return CO_E_RELEASED;
1644 if (!str)
1645 return E_INVALIDARG;
1647 /* return early for degenerate range */
1648 if (This->start == This->end) {
1649 *str = NULL;
1650 return S_OK;
1653 editor = This->child.reole->editor;
1654 cursor_from_char_ofs( editor, This->start, &start );
1655 cursor_from_char_ofs( editor, This->end, &end );
1657 length = This->end - This->start;
1658 *str = SysAllocStringLen(NULL, length);
1659 if (!*str)
1660 return E_OUTOFMEMORY;
1662 bEOP = (!para_next( para_next( end.para )) && This->end > ME_GetTextLength(editor));
1663 ME_GetTextW(editor, *str, length, &start, length, FALSE, bEOP);
1664 return S_OK;
1667 static HRESULT WINAPI ITextRange_fnSetText(ITextRange *me, BSTR str)
1669 ITextRangeImpl *This = impl_from_ITextRange(me);
1670 ME_TextEditor *editor;
1671 ME_Cursor cursor;
1672 ME_Style *style;
1673 int len;
1675 TRACE("(%p)->(%s)\n", This, debugstr_w(str));
1677 if (!This->child.reole)
1678 return CO_E_RELEASED;
1680 editor = This->child.reole->editor;
1682 /* delete only where's something to delete */
1683 if (This->start != This->end)
1685 cursor_from_char_ofs( editor, This->start, &cursor );
1686 ME_InternalDeleteText(editor, &cursor, This->end - This->start, FALSE);
1689 if (!str || !*str)
1691 /* will update this range as well */
1692 textranges_update_ranges(This->child.reole, This->start, This->end, RANGE_UPDATE_DELETE);
1693 return S_OK;
1696 /* it's safer not to rely on stored BSTR length */
1697 len = lstrlenW(str);
1698 cursor = editor->pCursors[0];
1699 cursor_from_char_ofs( editor, This->start, &editor->pCursors[0] );
1700 style = style_get_insert_style( editor, editor->pCursors );
1701 ME_InsertTextFromCursor(editor, 0, str, len, style);
1702 ME_ReleaseStyle(style);
1703 editor->pCursors[0] = cursor;
1705 if (len < This->end - This->start)
1706 textranges_update_ranges(This->child.reole, This->start + len, This->end, RANGE_UPDATE_DELETE);
1707 else
1708 This->end = len - This->start;
1710 return S_OK;
1713 static HRESULT range_GetChar(ME_TextEditor *editor, ME_Cursor *cursor, LONG *pch)
1715 WCHAR wch[2];
1717 ME_GetTextW(editor, wch, 1, cursor, 1, FALSE, !para_next( para_next( cursor->para ) ));
1718 *pch = wch[0];
1720 return S_OK;
1723 static HRESULT WINAPI ITextRange_fnGetChar(ITextRange *me, LONG *pch)
1725 ITextRangeImpl *This = impl_from_ITextRange(me);
1726 ME_TextEditor *editor;
1727 ME_Cursor cursor;
1729 TRACE("(%p)->(%p)\n", This, pch);
1731 if (!This->child.reole)
1732 return CO_E_RELEASED;
1734 if (!pch)
1735 return E_INVALIDARG;
1737 editor = This->child.reole->editor;
1738 cursor_from_char_ofs( editor, This->start, &cursor );
1739 return range_GetChar(editor, &cursor, pch);
1742 static HRESULT WINAPI ITextRange_fnSetChar(ITextRange *me, LONG ch)
1744 ITextRangeImpl *This = impl_from_ITextRange(me);
1746 FIXME("(%p)->(%x): stub\n", This, ch);
1748 if (!This->child.reole)
1749 return CO_E_RELEASED;
1751 return E_NOTIMPL;
1754 static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, ITextRange** ppRange);
1756 static HRESULT WINAPI ITextRange_fnGetDuplicate(ITextRange *me, ITextRange **ppRange)
1758 ITextRangeImpl *This = impl_from_ITextRange(me);
1760 TRACE("(%p)->(%p)\n", This, ppRange);
1762 if (!This->child.reole)
1763 return CO_E_RELEASED;
1765 if (!ppRange)
1766 return E_INVALIDARG;
1768 return CreateITextRange(This->child.reole, This->start, This->end, ppRange);
1771 static HRESULT WINAPI ITextRange_fnGetFormattedText(ITextRange *me, ITextRange **range)
1773 ITextRangeImpl *This = impl_from_ITextRange(me);
1775 FIXME("(%p)->(%p): stub\n", This, range);
1777 if (!This->child.reole)
1778 return CO_E_RELEASED;
1780 return E_NOTIMPL;
1783 static HRESULT WINAPI ITextRange_fnSetFormattedText(ITextRange *me, ITextRange *range)
1785 ITextRangeImpl *This = impl_from_ITextRange(me);
1787 FIXME("(%p)->(%p): stub\n", This, range);
1789 if (!This->child.reole)
1790 return CO_E_RELEASED;
1792 return E_NOTIMPL;
1795 static HRESULT WINAPI ITextRange_fnGetStart(ITextRange *me, LONG *start)
1797 ITextRangeImpl *This = impl_from_ITextRange(me);
1799 TRACE("(%p)->(%p)\n", This, start);
1801 if (!This->child.reole)
1802 return CO_E_RELEASED;
1804 if (!start)
1805 return E_INVALIDARG;
1807 *start = This->start;
1808 return S_OK;
1811 static HRESULT textrange_setstart(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end)
1813 int len;
1815 if (value < 0)
1816 value = 0;
1818 if (value == *start)
1819 return S_FALSE;
1821 if (value <= *end) {
1822 *start = value;
1823 return S_OK;
1826 len = ME_GetTextLength(reole->editor);
1827 *start = *end = value > len ? len : value;
1828 return S_OK;
1831 static HRESULT WINAPI ITextRange_fnSetStart(ITextRange *me, LONG value)
1833 ITextRangeImpl *This = impl_from_ITextRange(me);
1835 TRACE("(%p)->(%d)\n", This, value);
1837 if (!This->child.reole)
1838 return CO_E_RELEASED;
1840 return textrange_setstart(This->child.reole, value, &This->start, &This->end);
1843 static HRESULT WINAPI ITextRange_fnGetEnd(ITextRange *me, LONG *end)
1845 ITextRangeImpl *This = impl_from_ITextRange(me);
1847 TRACE("(%p)->(%p)\n", This, end);
1849 if (!This->child.reole)
1850 return CO_E_RELEASED;
1852 if (!end)
1853 return E_INVALIDARG;
1855 *end = This->end;
1856 return S_OK;
1859 static HRESULT textrange_setend(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end)
1861 int len;
1863 if (value == *end)
1864 return S_FALSE;
1866 if (value < *start) {
1867 *start = *end = max(0, value);
1868 return S_OK;
1871 len = ME_GetTextLength(reole->editor);
1872 *end = value > len ? len + 1 : value;
1873 return S_OK;
1876 static HRESULT WINAPI ITextRange_fnSetEnd(ITextRange *me, LONG value)
1878 ITextRangeImpl *This = impl_from_ITextRange(me);
1880 TRACE("(%p)->(%d)\n", This, value);
1882 if (!This->child.reole)
1883 return CO_E_RELEASED;
1885 return textrange_setend(This->child.reole, value, &This->start, &This->end);
1888 static HRESULT WINAPI ITextRange_fnGetFont(ITextRange *me, ITextFont **font)
1890 ITextRangeImpl *This = impl_from_ITextRange(me);
1892 TRACE("(%p)->(%p)\n", This, font);
1894 if (!This->child.reole)
1895 return CO_E_RELEASED;
1897 if (!font)
1898 return E_INVALIDARG;
1900 return create_textfont(me, NULL, font);
1903 static HRESULT WINAPI ITextRange_fnSetFont(ITextRange *me, ITextFont *font)
1905 ITextRangeImpl *This = impl_from_ITextRange(me);
1907 TRACE("(%p)->(%p)\n", This, font);
1909 if (!font)
1910 return E_INVALIDARG;
1912 if (!This->child.reole)
1913 return CO_E_RELEASED;
1915 textrange_set_font(me, font);
1916 return S_OK;
1919 static HRESULT WINAPI ITextRange_fnGetPara(ITextRange *me, ITextPara **para)
1921 ITextRangeImpl *This = impl_from_ITextRange(me);
1923 TRACE("(%p)->(%p)\n", This, para);
1925 if (!This->child.reole)
1926 return CO_E_RELEASED;
1928 if (!para)
1929 return E_INVALIDARG;
1931 return create_textpara(me, para);
1934 static HRESULT WINAPI ITextRange_fnSetPara(ITextRange *me, ITextPara *para)
1936 ITextRangeImpl *This = impl_from_ITextRange(me);
1938 FIXME("(%p)->(%p): stub\n", This, para);
1940 if (!This->child.reole)
1941 return CO_E_RELEASED;
1943 return E_NOTIMPL;
1946 static HRESULT WINAPI ITextRange_fnGetStoryLength(ITextRange *me, LONG *length)
1948 ITextRangeImpl *This = impl_from_ITextRange(me);
1950 TRACE("(%p)->(%p)\n", This, length);
1952 if (!This->child.reole)
1953 return CO_E_RELEASED;
1955 return textrange_get_storylength(This->child.reole->editor, length);
1958 static HRESULT WINAPI ITextRange_fnGetStoryType(ITextRange *me, LONG *value)
1960 ITextRangeImpl *This = impl_from_ITextRange(me);
1962 TRACE("(%p)->(%p)\n", This, value);
1964 if (!This->child.reole)
1965 return CO_E_RELEASED;
1967 if (!value)
1968 return E_INVALIDARG;
1970 *value = tomUnknownStory;
1971 return S_OK;
1974 static HRESULT range_Collapse(LONG bStart, LONG *start, LONG *end)
1976 if (*end == *start)
1977 return S_FALSE;
1979 if (bStart == tomEnd)
1980 *start = *end;
1981 else
1982 *end = *start;
1983 return S_OK;
1986 static HRESULT WINAPI ITextRange_fnCollapse(ITextRange *me, LONG bStart)
1988 ITextRangeImpl *This = impl_from_ITextRange(me);
1990 TRACE("(%p)->(%d)\n", This, bStart);
1992 if (!This->child.reole)
1993 return CO_E_RELEASED;
1995 return range_Collapse(bStart, &This->start, &This->end);
1998 static HRESULT WINAPI ITextRange_fnExpand(ITextRange *me, LONG unit, LONG *delta)
2000 ITextRangeImpl *This = impl_from_ITextRange(me);
2002 TRACE("(%p)->(%d %p)\n", This, unit, delta);
2004 if (!This->child.reole)
2005 return CO_E_RELEASED;
2007 return textrange_expand(me, unit, delta);
2010 static HRESULT WINAPI ITextRange_fnGetIndex(ITextRange *me, LONG unit, LONG *index)
2012 ITextRangeImpl *This = impl_from_ITextRange(me);
2014 FIXME("(%p)->(%d %p): stub\n", This, unit, index);
2016 if (!This->child.reole)
2017 return CO_E_RELEASED;
2019 return E_NOTIMPL;
2022 static HRESULT WINAPI ITextRange_fnSetIndex(ITextRange *me, LONG unit, LONG index,
2023 LONG extend)
2025 ITextRangeImpl *This = impl_from_ITextRange(me);
2027 FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend);
2029 if (!This->child.reole)
2030 return CO_E_RELEASED;
2032 return E_NOTIMPL;
2035 static void cp2range(ME_TextEditor *editor, LONG *cp1, LONG *cp2)
2037 int len = ME_GetTextLength(editor) + 1;
2039 *cp1 = max(*cp1, 0);
2040 *cp2 = max(*cp2, 0);
2041 *cp1 = min(*cp1, len);
2042 *cp2 = min(*cp2, len);
2043 if (*cp1 > *cp2)
2045 int tmp = *cp1;
2046 *cp1 = *cp2;
2047 *cp2 = tmp;
2049 if (*cp1 == len)
2050 *cp1 = *cp2 = len - 1;
2053 static HRESULT WINAPI ITextRange_fnSetRange(ITextRange *me, LONG anchor, LONG active)
2055 ITextRangeImpl *This = impl_from_ITextRange(me);
2057 TRACE("(%p)->(%d %d)\n", This, anchor, active);
2059 if (!This->child.reole)
2060 return CO_E_RELEASED;
2062 cp2range(This->child.reole->editor, &anchor, &active);
2063 if (anchor == This->start && active == This->end)
2064 return S_FALSE;
2066 This->start = anchor;
2067 This->end = active;
2068 return S_OK;
2071 static HRESULT textrange_inrange(LONG start, LONG end, ITextRange *range, LONG *ret)
2073 LONG from, to, v;
2075 if (!ret)
2076 ret = &v;
2078 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
2079 *ret = tomFalse;
2081 else
2082 *ret = (start >= from && end <= to) ? tomTrue : tomFalse;
2083 return *ret == tomTrue ? S_OK : S_FALSE;
2086 static HRESULT WINAPI ITextRange_fnInRange(ITextRange *me, ITextRange *range, LONG *ret)
2088 ITextRangeImpl *This = impl_from_ITextRange(me);
2090 TRACE("(%p)->(%p %p)\n", This, range, ret);
2092 if (ret)
2093 *ret = tomFalse;
2095 if (!This->child.reole)
2096 return CO_E_RELEASED;
2098 if (!range)
2099 return S_FALSE;
2101 return textrange_inrange(This->start, This->end, range, ret);
2104 static HRESULT WINAPI ITextRange_fnInStory(ITextRange *me, ITextRange *pRange, LONG *ret)
2106 ITextRangeImpl *This = impl_from_ITextRange(me);
2108 FIXME("(%p)->(%p): stub\n", This, ret);
2110 if (!This->child.reole)
2111 return CO_E_RELEASED;
2113 return E_NOTIMPL;
2116 static HRESULT textrange_isequal(LONG start, LONG end, ITextRange *range, LONG *ret)
2118 LONG from, to, v;
2120 if (!ret)
2121 ret = &v;
2123 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
2124 *ret = tomFalse;
2126 else
2127 *ret = (start == from && end == to) ? tomTrue : tomFalse;
2128 return *ret == tomTrue ? S_OK : S_FALSE;
2131 static HRESULT WINAPI ITextRange_fnIsEqual(ITextRange *me, ITextRange *range, LONG *ret)
2133 ITextRangeImpl *This = impl_from_ITextRange(me);
2135 TRACE("(%p)->(%p %p)\n", This, range, ret);
2137 if (ret)
2138 *ret = tomFalse;
2140 if (!This->child.reole)
2141 return CO_E_RELEASED;
2143 if (!range)
2144 return S_FALSE;
2146 return textrange_isequal(This->start, This->end, range, ret);
2149 static HRESULT WINAPI ITextRange_fnSelect(ITextRange *me)
2151 ITextRangeImpl *This = impl_from_ITextRange(me);
2153 TRACE("(%p)\n", This);
2155 if (!This->child.reole)
2156 return CO_E_RELEASED;
2158 set_selection(This->child.reole->editor, This->start, This->end);
2159 return S_OK;
2162 static HRESULT textrange_startof(ITextRange *range, LONG unit, LONG extend, LONG *delta)
2164 HRESULT hr;
2165 LONG start, end;
2166 LONG moved;
2168 ITextRange_GetStart(range, &start);
2169 ITextRange_GetEnd(range, &end);
2171 switch (unit)
2173 case tomCharacter:
2175 moved = 0;
2176 if (extend == tomMove) {
2177 if (start != end) {
2178 ITextRange_SetEnd(range, start);
2179 moved = -1;
2182 if (delta)
2183 *delta = moved;
2184 hr = moved ? S_OK : S_FALSE;
2185 break;
2187 default:
2188 FIXME("unit %d is not supported\n", unit);
2189 return E_NOTIMPL;
2191 return hr;
2194 static HRESULT WINAPI ITextRange_fnStartOf(ITextRange *me, LONG unit, LONG extend,
2195 LONG *delta)
2197 ITextRangeImpl *This = impl_from_ITextRange(me);
2199 TRACE("(%p)->(%d %d %p)\n", This, unit, extend, delta);
2201 if (!This->child.reole)
2202 return CO_E_RELEASED;
2204 return textrange_startof(me, unit, extend, delta);
2207 static HRESULT textrange_endof(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG extend, LONG *delta)
2209 HRESULT hr;
2210 LONG old_start, old_end, new_end;
2211 LONG moved;
2213 ITextRange_GetStart(range, &old_start);
2214 ITextRange_GetEnd(range, &old_end);
2216 switch (unit)
2218 case tomCharacter:
2220 moved = 0;
2221 new_end = old_end;
2222 if (old_end == 0)
2224 ME_Cursor cursor;
2225 cursor_from_char_ofs( editor, old_end, &cursor );
2226 moved = ME_MoveCursorChars(editor, &cursor, 1, TRUE);
2227 new_end = old_end + moved;
2229 else if (extend == tomMove && old_start != old_end)
2230 moved = 1;
2232 ITextRange_SetEnd(range, new_end);
2233 if (extend == tomMove)
2234 ITextRange_SetStart(range, new_end);
2235 if (delta)
2236 *delta = moved;
2237 hr = moved ? S_OK : S_FALSE;
2238 break;
2240 default:
2241 FIXME("unit %d is not supported\n", unit);
2242 return E_NOTIMPL;
2244 return hr;
2247 static HRESULT WINAPI ITextRange_fnEndOf(ITextRange *me, LONG unit, LONG extend,
2248 LONG *delta)
2250 ITextRangeImpl *This = impl_from_ITextRange(me);
2252 TRACE("(%p)->(%d %d %p)\n", This, unit, extend, delta);
2254 if (!This->child.reole)
2255 return CO_E_RELEASED;
2257 return textrange_endof(me, This->child.reole->editor, unit, extend, delta);
2260 static HRESULT textrange_move(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG count, LONG *delta)
2262 LONG old_start, old_end, new_start, new_end;
2263 LONG move_by;
2264 LONG moved;
2265 HRESULT hr = S_OK;
2267 if (!count)
2269 if (delta)
2270 *delta = 0;
2271 return S_FALSE;
2274 ITextRange_GetStart(range, &old_start);
2275 ITextRange_GetEnd(range, &old_end);
2276 switch (unit)
2278 case tomCharacter:
2280 ME_Cursor cursor;
2282 if (count > 0)
2284 cursor_from_char_ofs( editor, old_end, &cursor );
2285 move_by = count;
2286 if (old_start != old_end)
2287 --move_by;
2289 else
2291 cursor_from_char_ofs( editor, old_start, &cursor );
2292 move_by = count;
2293 if (old_start != old_end)
2294 ++move_by;
2296 moved = ME_MoveCursorChars(editor, &cursor, move_by, FALSE);
2297 if (count > 0)
2299 new_end = old_end + moved;
2300 new_start = new_end;
2301 if (old_start != old_end)
2302 ++moved;
2304 else
2306 new_start = old_start + moved;
2307 new_end = new_start;
2308 if (old_start != old_end)
2309 --moved;
2311 if (delta) *delta = moved;
2312 break;
2314 default:
2315 FIXME("unit %d is not supported\n", unit);
2316 return E_NOTIMPL;
2318 if (moved == 0)
2319 hr = S_FALSE;
2320 ITextRange_SetStart(range, new_start);
2321 ITextRange_SetEnd(range, new_end);
2323 return hr;
2326 static HRESULT WINAPI ITextRange_fnMove(ITextRange *me, LONG unit, LONG count, LONG *delta)
2328 ITextRangeImpl *This = impl_from_ITextRange(me);
2330 TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta);
2332 if (!This->child.reole)
2333 return CO_E_RELEASED;
2335 return textrange_move(me, This->child.reole->editor, unit, count, delta);
2338 static HRESULT textrange_movestart(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG count, LONG *delta)
2340 LONG old_start, old_end, new_start, new_end;
2341 HRESULT hr = S_OK;
2343 if (!count)
2345 if (delta)
2346 *delta = 0;
2347 return S_FALSE;
2350 ITextRange_GetStart(range, &old_start);
2351 ITextRange_GetEnd(range, &old_end);
2352 switch (unit)
2354 case tomCharacter:
2356 ME_Cursor cursor;
2357 LONG moved;
2359 cursor_from_char_ofs( editor, old_start, &cursor );
2360 moved = ME_MoveCursorChars(editor, &cursor, count, FALSE);
2361 new_start = old_start + moved;
2362 new_end = old_end;
2363 if (new_end < new_start)
2364 new_end = new_start;
2365 if (delta)
2366 *delta = moved;
2367 break;
2369 default:
2370 FIXME("unit %d is not supported\n", unit);
2371 return E_NOTIMPL;
2373 if (new_start == old_start)
2374 hr = S_FALSE;
2375 ITextRange_SetStart(range, new_start);
2376 ITextRange_SetEnd(range, new_end);
2378 return hr;
2381 static HRESULT WINAPI ITextRange_fnMoveStart(ITextRange *me, LONG unit, LONG count,
2382 LONG *delta)
2384 ITextRangeImpl *This = impl_from_ITextRange(me);
2386 TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta);
2388 if (!This->child.reole)
2389 return CO_E_RELEASED;
2391 return textrange_movestart(me, This->child.reole->editor, unit, count, delta);
2394 static HRESULT textrange_moveend(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG count, LONG *delta)
2396 LONG old_start, old_end, new_start, new_end;
2397 HRESULT hr = S_OK;
2399 if (!count)
2401 if (delta)
2402 *delta = 0;
2403 return S_FALSE;
2406 ITextRange_GetStart(range, &old_start);
2407 ITextRange_GetEnd(range, &old_end);
2408 switch (unit)
2410 case tomCharacter:
2412 ME_Cursor cursor;
2413 LONG moved;
2415 cursor_from_char_ofs( editor, old_end, &cursor );
2416 moved = ME_MoveCursorChars(editor, &cursor, count, TRUE);
2417 new_start = old_start;
2418 new_end = old_end + moved;
2419 if (new_end < new_start)
2420 new_start = new_end;
2421 if (delta)
2422 *delta = moved;
2423 break;
2425 case tomStory:
2426 if (count < 0)
2427 new_start = new_end = 0;
2428 else
2430 new_start = old_start;
2431 ITextRange_GetStoryLength(range, &new_end);
2433 if (delta)
2435 if (new_end < old_end)
2436 *delta = -1;
2437 else if (new_end == old_end)
2438 *delta = 0;
2439 else
2440 *delta = 1;
2442 break;
2443 default:
2444 FIXME("unit %d is not supported\n", unit);
2445 return E_NOTIMPL;
2447 if (new_end == old_end)
2448 hr = S_FALSE;
2449 ITextRange_SetStart(range, new_start);
2450 ITextRange_SetEnd(range, new_end);
2452 return hr;
2455 static HRESULT WINAPI ITextRange_fnMoveEnd(ITextRange *me, LONG unit, LONG count,
2456 LONG *delta)
2458 ITextRangeImpl *This = impl_from_ITextRange(me);
2460 TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta);
2462 if (!This->child.reole)
2463 return CO_E_RELEASED;
2465 return textrange_moveend(me, This->child.reole->editor, unit, count, delta);
2468 static HRESULT WINAPI ITextRange_fnMoveWhile(ITextRange *me, VARIANT *charset, LONG count,
2469 LONG *delta)
2471 ITextRangeImpl *This = impl_from_ITextRange(me);
2473 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2475 if (!This->child.reole)
2476 return CO_E_RELEASED;
2478 return E_NOTIMPL;
2481 static HRESULT WINAPI ITextRange_fnMoveStartWhile(ITextRange *me, VARIANT *charset, LONG count,
2482 LONG *delta)
2484 ITextRangeImpl *This = impl_from_ITextRange(me);
2486 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2488 if (!This->child.reole)
2489 return CO_E_RELEASED;
2491 return E_NOTIMPL;
2494 static HRESULT WINAPI ITextRange_fnMoveEndWhile(ITextRange *me, VARIANT *charset, LONG count,
2495 LONG *delta)
2497 ITextRangeImpl *This = impl_from_ITextRange(me);
2499 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2501 if (!This->child.reole)
2502 return CO_E_RELEASED;
2504 return E_NOTIMPL;
2507 static HRESULT WINAPI ITextRange_fnMoveUntil(ITextRange *me, VARIANT *charset, LONG count,
2508 LONG *delta)
2510 ITextRangeImpl *This = impl_from_ITextRange(me);
2512 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2514 if (!This->child.reole)
2515 return CO_E_RELEASED;
2517 return E_NOTIMPL;
2520 static HRESULT WINAPI ITextRange_fnMoveStartUntil(ITextRange *me, VARIANT *charset, LONG count,
2521 LONG *delta)
2523 ITextRangeImpl *This = impl_from_ITextRange(me);
2525 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2527 if (!This->child.reole)
2528 return CO_E_RELEASED;
2530 return E_NOTIMPL;
2533 static HRESULT WINAPI ITextRange_fnMoveEndUntil(ITextRange *me, VARIANT *charset, LONG count,
2534 LONG *delta)
2536 ITextRangeImpl *This = impl_from_ITextRange(me);
2538 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2540 if (!This->child.reole)
2541 return CO_E_RELEASED;
2543 return E_NOTIMPL;
2546 static HRESULT WINAPI ITextRange_fnFindText(ITextRange *me, BSTR text, LONG count, LONG flags,
2547 LONG *length)
2549 ITextRangeImpl *This = impl_from_ITextRange(me);
2551 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2553 if (!This->child.reole)
2554 return CO_E_RELEASED;
2556 return E_NOTIMPL;
2559 static HRESULT WINAPI ITextRange_fnFindTextStart(ITextRange *me, BSTR text, LONG count,
2560 LONG flags, LONG *length)
2562 ITextRangeImpl *This = impl_from_ITextRange(me);
2564 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2566 if (!This->child.reole)
2567 return CO_E_RELEASED;
2569 return E_NOTIMPL;
2572 static HRESULT WINAPI ITextRange_fnFindTextEnd(ITextRange *me, BSTR text, LONG count,
2573 LONG flags, LONG *length)
2575 ITextRangeImpl *This = impl_from_ITextRange(me);
2577 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2579 if (!This->child.reole)
2580 return CO_E_RELEASED;
2582 return E_NOTIMPL;
2585 static HRESULT WINAPI ITextRange_fnDelete(ITextRange *me, LONG unit, LONG count, LONG *delta)
2587 ITextRangeImpl *This = impl_from_ITextRange(me);
2589 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2591 if (!This->child.reole)
2592 return CO_E_RELEASED;
2594 return E_NOTIMPL;
2597 static HRESULT textrange_copy_or_cut( ITextRange *range, ME_TextEditor *editor, BOOL cut, VARIANT *v )
2599 LONG start, end;
2600 ME_Cursor cursor;
2601 IDataObject **data_out = NULL;
2603 ITextRange_GetStart( range, &start );
2604 ITextRange_GetEnd( range, &end );
2605 if (start == end)
2607 /* If the range is empty, all text is copied */
2608 LONG prev_end = end;
2609 ITextRange_SetEnd( range, MAXLONG );
2610 start = 0;
2611 ITextRange_GetEnd( range, &end );
2612 ITextRange_SetEnd( range, prev_end );
2614 cursor_from_char_ofs( editor, start, &cursor );
2616 if (v && V_VT(v) == (VT_UNKNOWN | VT_BYREF) && V_UNKNOWNREF( v ))
2617 data_out = (IDataObject **)V_UNKNOWNREF( v );
2619 return editor_copy_or_cut( editor, cut, &cursor, end - start, data_out );
2622 static HRESULT WINAPI ITextRange_fnCut(ITextRange *me, VARIANT *v)
2624 ITextRangeImpl *This = impl_from_ITextRange(me);
2626 TRACE("(%p)->(%p)\n", This, v);
2628 if (!This->child.reole)
2629 return CO_E_RELEASED;
2631 return textrange_copy_or_cut(me, This->child.reole->editor, TRUE, v);
2634 static HRESULT WINAPI ITextRange_fnCopy(ITextRange *me, VARIANT *v)
2636 ITextRangeImpl *This = impl_from_ITextRange(me);
2638 TRACE("(%p)->(%p)\n", This, v);
2640 if (!This->child.reole)
2641 return CO_E_RELEASED;
2643 return textrange_copy_or_cut(me, This->child.reole->editor, FALSE, v);
2646 static HRESULT WINAPI ITextRange_fnPaste(ITextRange *me, VARIANT *v, LONG format)
2648 ITextRangeImpl *This = impl_from_ITextRange(me);
2650 FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format);
2652 if (!This->child.reole)
2653 return CO_E_RELEASED;
2655 return E_NOTIMPL;
2658 static HRESULT WINAPI ITextRange_fnCanPaste(ITextRange *me, VARIANT *v, LONG format, LONG *ret)
2660 ITextRangeImpl *This = impl_from_ITextRange(me);
2662 FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret);
2664 if (!This->child.reole)
2665 return CO_E_RELEASED;
2667 return E_NOTIMPL;
2670 static HRESULT WINAPI ITextRange_fnCanEdit(ITextRange *me, LONG *ret)
2672 ITextRangeImpl *This = impl_from_ITextRange(me);
2674 FIXME("(%p)->(%p): stub\n", This, ret);
2676 if (!This->child.reole)
2677 return CO_E_RELEASED;
2679 return E_NOTIMPL;
2682 static HRESULT WINAPI ITextRange_fnChangeCase(ITextRange *me, LONG type)
2684 ITextRangeImpl *This = impl_from_ITextRange(me);
2686 FIXME("(%p)->(%d): stub\n", This, type);
2688 if (!This->child.reole)
2689 return CO_E_RELEASED;
2691 return E_NOTIMPL;
2694 static HRESULT WINAPI ITextRange_fnGetPoint(ITextRange *me, LONG type, LONG *cx, LONG *cy)
2696 ITextRangeImpl *This = impl_from_ITextRange(me);
2698 FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy);
2700 if (!This->child.reole)
2701 return CO_E_RELEASED;
2703 return E_NOTIMPL;
2706 static HRESULT WINAPI ITextRange_fnSetPoint(ITextRange *me, LONG x, LONG y, LONG type,
2707 LONG extend)
2709 ITextRangeImpl *This = impl_from_ITextRange(me);
2711 FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend);
2713 if (!This->child.reole)
2714 return CO_E_RELEASED;
2716 return E_NOTIMPL;
2719 static HRESULT WINAPI ITextRange_fnScrollIntoView(ITextRange *me, LONG value)
2721 ITextRangeImpl *This = impl_from_ITextRange(me);
2722 ME_TextEditor *editor;
2723 ME_Cursor cursor;
2724 int x, y, height;
2726 TRACE("(%p)->(%d)\n", This, value);
2728 if (!This->child.reole)
2729 return CO_E_RELEASED;
2731 editor = This->child.reole->editor;
2733 switch (value)
2735 case tomStart:
2736 cursor_from_char_ofs( editor, This->start, &cursor );
2737 cursor_coords( editor, &cursor, &x, &y, &height );
2738 break;
2739 case tomEnd:
2740 cursor_from_char_ofs( editor, This->end, &cursor );
2741 cursor_coords( editor, &cursor, &x, &y, &height );
2742 break;
2743 default:
2744 FIXME("bStart value %d not handled\n", value);
2745 return E_NOTIMPL;
2747 ME_ScrollAbs(editor, x, y);
2748 return S_OK;
2751 static HRESULT WINAPI ITextRange_fnGetEmbeddedObject(ITextRange *me, IUnknown **ppv)
2753 ITextRangeImpl *This = impl_from_ITextRange(me);
2755 FIXME("(%p)->(%p): stub\n", This, ppv);
2757 if (!This->child.reole)
2758 return CO_E_RELEASED;
2760 return E_NOTIMPL;
2763 static const ITextRangeVtbl trvt = {
2764 ITextRange_fnQueryInterface,
2765 ITextRange_fnAddRef,
2766 ITextRange_fnRelease,
2767 ITextRange_fnGetTypeInfoCount,
2768 ITextRange_fnGetTypeInfo,
2769 ITextRange_fnGetIDsOfNames,
2770 ITextRange_fnInvoke,
2771 ITextRange_fnGetText,
2772 ITextRange_fnSetText,
2773 ITextRange_fnGetChar,
2774 ITextRange_fnSetChar,
2775 ITextRange_fnGetDuplicate,
2776 ITextRange_fnGetFormattedText,
2777 ITextRange_fnSetFormattedText,
2778 ITextRange_fnGetStart,
2779 ITextRange_fnSetStart,
2780 ITextRange_fnGetEnd,
2781 ITextRange_fnSetEnd,
2782 ITextRange_fnGetFont,
2783 ITextRange_fnSetFont,
2784 ITextRange_fnGetPara,
2785 ITextRange_fnSetPara,
2786 ITextRange_fnGetStoryLength,
2787 ITextRange_fnGetStoryType,
2788 ITextRange_fnCollapse,
2789 ITextRange_fnExpand,
2790 ITextRange_fnGetIndex,
2791 ITextRange_fnSetIndex,
2792 ITextRange_fnSetRange,
2793 ITextRange_fnInRange,
2794 ITextRange_fnInStory,
2795 ITextRange_fnIsEqual,
2796 ITextRange_fnSelect,
2797 ITextRange_fnStartOf,
2798 ITextRange_fnEndOf,
2799 ITextRange_fnMove,
2800 ITextRange_fnMoveStart,
2801 ITextRange_fnMoveEnd,
2802 ITextRange_fnMoveWhile,
2803 ITextRange_fnMoveStartWhile,
2804 ITextRange_fnMoveEndWhile,
2805 ITextRange_fnMoveUntil,
2806 ITextRange_fnMoveStartUntil,
2807 ITextRange_fnMoveEndUntil,
2808 ITextRange_fnFindText,
2809 ITextRange_fnFindTextStart,
2810 ITextRange_fnFindTextEnd,
2811 ITextRange_fnDelete,
2812 ITextRange_fnCut,
2813 ITextRange_fnCopy,
2814 ITextRange_fnPaste,
2815 ITextRange_fnCanPaste,
2816 ITextRange_fnCanEdit,
2817 ITextRange_fnChangeCase,
2818 ITextRange_fnGetPoint,
2819 ITextRange_fnSetPoint,
2820 ITextRange_fnScrollIntoView,
2821 ITextRange_fnGetEmbeddedObject
2824 /* ITextFont */
2825 static HRESULT WINAPI TextFont_QueryInterface(ITextFont *iface, REFIID riid, void **ppv)
2827 ITextFontImpl *This = impl_from_ITextFont(iface);
2829 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
2831 if (IsEqualIID(riid, &IID_ITextFont) ||
2832 IsEqualIID(riid, &IID_IDispatch) ||
2833 IsEqualIID(riid, &IID_IUnknown))
2835 *ppv = iface;
2836 ITextFont_AddRef(iface);
2837 return S_OK;
2840 *ppv = NULL;
2841 return E_NOINTERFACE;
2844 static ULONG WINAPI TextFont_AddRef(ITextFont *iface)
2846 ITextFontImpl *This = impl_from_ITextFont(iface);
2847 ULONG ref = InterlockedIncrement(&This->ref);
2848 TRACE("(%p)->(%u)\n", This, ref);
2849 return ref;
2852 static ULONG WINAPI TextFont_Release(ITextFont *iface)
2854 ITextFontImpl *This = impl_from_ITextFont(iface);
2855 ULONG ref = InterlockedDecrement(&This->ref);
2857 TRACE("(%p)->(%u)\n", This, ref);
2859 if (!ref)
2861 if (This->range)
2862 ITextRange_Release(This->range);
2863 SysFreeString(This->props[FONT_NAME].str);
2864 heap_free(This);
2867 return ref;
2870 static HRESULT WINAPI TextFont_GetTypeInfoCount(ITextFont *iface, UINT *pctinfo)
2872 ITextFontImpl *This = impl_from_ITextFont(iface);
2873 TRACE("(%p)->(%p)\n", This, pctinfo);
2874 *pctinfo = 1;
2875 return S_OK;
2878 static HRESULT WINAPI TextFont_GetTypeInfo(ITextFont *iface, UINT iTInfo, LCID lcid,
2879 ITypeInfo **ppTInfo)
2881 ITextFontImpl *This = impl_from_ITextFont(iface);
2882 HRESULT hr;
2884 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
2886 hr = get_typeinfo(ITextFont_tid, ppTInfo);
2887 if (SUCCEEDED(hr))
2888 ITypeInfo_AddRef(*ppTInfo);
2889 return hr;
2892 static HRESULT WINAPI TextFont_GetIDsOfNames(ITextFont *iface, REFIID riid,
2893 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
2895 ITextFontImpl *This = impl_from_ITextFont(iface);
2896 ITypeInfo *ti;
2897 HRESULT hr;
2899 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid),
2900 rgszNames, cNames, lcid, rgDispId);
2902 hr = get_typeinfo(ITextFont_tid, &ti);
2903 if (SUCCEEDED(hr))
2904 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
2905 return hr;
2908 static HRESULT WINAPI TextFont_Invoke(
2909 ITextFont *iface,
2910 DISPID dispIdMember,
2911 REFIID riid,
2912 LCID lcid,
2913 WORD wFlags,
2914 DISPPARAMS *pDispParams,
2915 VARIANT *pVarResult,
2916 EXCEPINFO *pExcepInfo,
2917 UINT *puArgErr)
2919 ITextFontImpl *This = impl_from_ITextFont(iface);
2920 ITypeInfo *ti;
2921 HRESULT hr;
2923 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
2924 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2926 hr = get_typeinfo(ITextFont_tid, &ti);
2927 if (SUCCEEDED(hr))
2928 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2929 return hr;
2932 static HRESULT WINAPI TextFont_GetDuplicate(ITextFont *iface, ITextFont **ret)
2934 ITextFontImpl *This = impl_from_ITextFont(iface);
2936 TRACE("(%p)->(%p)\n", This, ret);
2938 if (!ret)
2939 return E_INVALIDARG;
2941 *ret = NULL;
2942 if (This->range && !get_range_reole(This->range))
2943 return CO_E_RELEASED;
2945 return create_textfont(NULL, This, ret);
2948 static HRESULT WINAPI TextFont_SetDuplicate(ITextFont *iface, ITextFont *pFont)
2950 ITextFontImpl *This = impl_from_ITextFont(iface);
2951 FIXME("(%p)->(%p): stub\n", This, pFont);
2952 return E_NOTIMPL;
2955 static HRESULT WINAPI TextFont_CanChange(ITextFont *iface, LONG *ret)
2957 ITextFontImpl *This = impl_from_ITextFont(iface);
2958 FIXME("(%p)->(%p): stub\n", This, ret);
2959 return E_NOTIMPL;
2962 static HRESULT WINAPI TextFont_IsEqual(ITextFont *iface, ITextFont *font, LONG *ret)
2964 ITextFontImpl *This = impl_from_ITextFont(iface);
2965 FIXME("(%p)->(%p %p): stub\n", This, font, ret);
2966 return E_NOTIMPL;
2969 static void textfont_reset_to_default(ITextFontImpl *font)
2971 enum textfont_prop_id id;
2973 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2974 switch (id)
2976 case FONT_ALLCAPS:
2977 case FONT_ANIMATION:
2978 case FONT_BOLD:
2979 case FONT_EMBOSS:
2980 case FONT_HIDDEN:
2981 case FONT_ENGRAVE:
2982 case FONT_ITALIC:
2983 case FONT_OUTLINE:
2984 case FONT_PROTECTED:
2985 case FONT_SHADOW:
2986 case FONT_SMALLCAPS:
2987 case FONT_STRIKETHROUGH:
2988 case FONT_SUBSCRIPT:
2989 case FONT_SUPERSCRIPT:
2990 case FONT_UNDERLINE:
2991 font->props[id].l = tomFalse;
2992 break;
2993 case FONT_BACKCOLOR:
2994 case FONT_FORECOLOR:
2995 font->props[id].l = tomAutoColor;
2996 break;
2997 case FONT_KERNING:
2998 case FONT_POSITION:
2999 case FONT_SIZE:
3000 case FONT_SPACING:
3001 font->props[id].f = 0.0;
3002 break;
3003 case FONT_LANGID:
3004 font->props[id].l = GetSystemDefaultLCID();
3005 break;
3006 case FONT_NAME: {
3007 SysFreeString(font->props[id].str);
3008 font->props[id].str = SysAllocString(L"System");
3009 break;
3011 case FONT_WEIGHT:
3012 font->props[id].l = FW_NORMAL;
3013 break;
3014 default:
3015 FIXME("font property %d not handled\n", id);
3020 static void textfont_reset_to_undefined(ITextFontImpl *font)
3022 enum textfont_prop_id id;
3024 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
3025 switch (id)
3027 case FONT_ALLCAPS:
3028 case FONT_ANIMATION:
3029 case FONT_BOLD:
3030 case FONT_EMBOSS:
3031 case FONT_HIDDEN:
3032 case FONT_ENGRAVE:
3033 case FONT_ITALIC:
3034 case FONT_OUTLINE:
3035 case FONT_PROTECTED:
3036 case FONT_SHADOW:
3037 case FONT_SMALLCAPS:
3038 case FONT_STRIKETHROUGH:
3039 case FONT_SUBSCRIPT:
3040 case FONT_SUPERSCRIPT:
3041 case FONT_UNDERLINE:
3042 case FONT_BACKCOLOR:
3043 case FONT_FORECOLOR:
3044 case FONT_LANGID:
3045 case FONT_WEIGHT:
3046 font->props[id].l = tomUndefined;
3047 break;
3048 case FONT_KERNING:
3049 case FONT_POSITION:
3050 case FONT_SIZE:
3051 case FONT_SPACING:
3052 font->props[id].f = tomUndefined;
3053 break;
3054 case FONT_NAME:
3055 break;
3056 default:
3057 FIXME("font property %d not handled\n", id);
3062 static void textfont_apply_range_props(ITextFontImpl *font)
3064 enum textfont_prop_id propid;
3065 for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++)
3066 set_textfont_prop(font, propid, &font->props[propid]);
3069 static HRESULT WINAPI TextFont_Reset(ITextFont *iface, LONG value)
3071 ITextFontImpl *This = impl_from_ITextFont(iface);
3073 TRACE("(%p)->(%d)\n", This, value);
3075 /* If font is attached to a range, released or not, we can't
3076 reset to undefined */
3077 if (This->range) {
3078 if (!get_range_reole(This->range))
3079 return CO_E_RELEASED;
3081 switch (value)
3083 case tomUndefined:
3084 return E_INVALIDARG;
3085 case tomCacheParms:
3086 textfont_cache_range_props(This);
3087 This->get_cache_enabled = TRUE;
3088 break;
3089 case tomTrackParms:
3090 This->get_cache_enabled = FALSE;
3091 break;
3092 case tomApplyLater:
3093 This->set_cache_enabled = TRUE;
3094 break;
3095 case tomApplyNow:
3096 This->set_cache_enabled = FALSE;
3097 textfont_apply_range_props(This);
3098 break;
3099 case tomUsePoints:
3100 case tomUseTwips:
3101 return E_INVALIDARG;
3102 default:
3103 FIXME("reset mode %d not supported\n", value);
3106 return S_OK;
3108 else {
3109 switch (value)
3111 /* reset to global defaults */
3112 case tomDefault:
3113 textfont_reset_to_default(This);
3114 return S_OK;
3115 /* all properties are set to tomUndefined, font name is retained */
3116 case tomUndefined:
3117 textfont_reset_to_undefined(This);
3118 return S_OK;
3119 case tomApplyNow:
3120 case tomApplyLater:
3121 case tomTrackParms:
3122 case tomCacheParms:
3123 return S_OK;
3124 case tomUsePoints:
3125 case tomUseTwips:
3126 return E_INVALIDARG;
3130 FIXME("reset mode %d not supported\n", value);
3131 return E_NOTIMPL;
3134 static HRESULT WINAPI TextFont_GetStyle(ITextFont *iface, LONG *value)
3136 ITextFontImpl *This = impl_from_ITextFont(iface);
3137 FIXME("(%p)->(%p): stub\n", This, value);
3138 return E_NOTIMPL;
3141 static HRESULT WINAPI TextFont_SetStyle(ITextFont *iface, LONG value)
3143 ITextFontImpl *This = impl_from_ITextFont(iface);
3144 FIXME("(%p)->(%d): stub\n", This, value);
3145 return E_NOTIMPL;
3148 static HRESULT WINAPI TextFont_GetAllCaps(ITextFont *iface, LONG *value)
3150 ITextFontImpl *This = impl_from_ITextFont(iface);
3151 TRACE("(%p)->(%p)\n", This, value);
3152 return get_textfont_propl(This, FONT_ALLCAPS, value);
3155 static HRESULT WINAPI TextFont_SetAllCaps(ITextFont *iface, LONG value)
3157 ITextFontImpl *This = impl_from_ITextFont(iface);
3158 TRACE("(%p)->(%d)\n", This, value);
3159 return set_textfont_propd(This, FONT_ALLCAPS, value);
3162 static HRESULT WINAPI TextFont_GetAnimation(ITextFont *iface, LONG *value)
3164 ITextFontImpl *This = impl_from_ITextFont(iface);
3165 TRACE("(%p)->(%p)\n", This, value);
3166 return get_textfont_propl(This, FONT_ANIMATION, value);
3169 static HRESULT WINAPI TextFont_SetAnimation(ITextFont *iface, LONG value)
3171 ITextFontImpl *This = impl_from_ITextFont(iface);
3173 TRACE("(%p)->(%d)\n", This, value);
3175 if (value < tomNoAnimation || value > tomAnimationMax)
3176 return E_INVALIDARG;
3178 return set_textfont_propl(This, FONT_ANIMATION, value);
3181 static HRESULT WINAPI TextFont_GetBackColor(ITextFont *iface, LONG *value)
3183 ITextFontImpl *This = impl_from_ITextFont(iface);
3184 TRACE("(%p)->(%p)\n", This, value);
3185 return get_textfont_propl(This, FONT_BACKCOLOR, value);
3188 static HRESULT WINAPI TextFont_SetBackColor(ITextFont *iface, LONG value)
3190 ITextFontImpl *This = impl_from_ITextFont(iface);
3191 TRACE("(%p)->(%d)\n", This, value);
3192 return set_textfont_propl(This, FONT_BACKCOLOR, value);
3195 static HRESULT WINAPI TextFont_GetBold(ITextFont *iface, LONG *value)
3197 ITextFontImpl *This = impl_from_ITextFont(iface);
3198 TRACE("(%p)->(%p)\n", This, value);
3199 return get_textfont_propl(This, FONT_BOLD, value);
3202 static HRESULT WINAPI TextFont_SetBold(ITextFont *iface, LONG value)
3204 ITextFontImpl *This = impl_from_ITextFont(iface);
3205 TRACE("(%p)->(%d)\n", This, value);
3206 return set_textfont_propd(This, FONT_BOLD, value);
3209 static HRESULT WINAPI TextFont_GetEmboss(ITextFont *iface, LONG *value)
3211 ITextFontImpl *This = impl_from_ITextFont(iface);
3212 TRACE("(%p)->(%p)\n", This, value);
3213 return get_textfont_propl(This, FONT_EMBOSS, value);
3216 static HRESULT WINAPI TextFont_SetEmboss(ITextFont *iface, LONG value)
3218 ITextFontImpl *This = impl_from_ITextFont(iface);
3219 TRACE("(%p)->(%d)\n", This, value);
3220 return set_textfont_propd(This, FONT_EMBOSS, value);
3223 static HRESULT WINAPI TextFont_GetForeColor(ITextFont *iface, LONG *value)
3225 ITextFontImpl *This = impl_from_ITextFont(iface);
3226 TRACE("(%p)->(%p)\n", This, value);
3227 return get_textfont_propl(This, FONT_FORECOLOR, value);
3230 static HRESULT WINAPI TextFont_SetForeColor(ITextFont *iface, LONG value)
3232 ITextFontImpl *This = impl_from_ITextFont(iface);
3233 TRACE("(%p)->(%d)\n", This, value);
3234 return set_textfont_propl(This, FONT_FORECOLOR, value);
3237 static HRESULT WINAPI TextFont_GetHidden(ITextFont *iface, LONG *value)
3239 ITextFontImpl *This = impl_from_ITextFont(iface);
3240 TRACE("(%p)->(%p)\n", This, value);
3241 return get_textfont_propl(This, FONT_HIDDEN, value);
3244 static HRESULT WINAPI TextFont_SetHidden(ITextFont *iface, LONG value)
3246 ITextFontImpl *This = impl_from_ITextFont(iface);
3247 TRACE("(%p)->(%d)\n", This, value);
3248 return set_textfont_propd(This, FONT_HIDDEN, value);
3251 static HRESULT WINAPI TextFont_GetEngrave(ITextFont *iface, LONG *value)
3253 ITextFontImpl *This = impl_from_ITextFont(iface);
3254 TRACE("(%p)->(%p)\n", This, value);
3255 return get_textfont_propl(This, FONT_ENGRAVE, value);
3258 static HRESULT WINAPI TextFont_SetEngrave(ITextFont *iface, LONG value)
3260 ITextFontImpl *This = impl_from_ITextFont(iface);
3261 TRACE("(%p)->(%d)\n", This, value);
3262 return set_textfont_propd(This, FONT_ENGRAVE, value);
3265 static HRESULT WINAPI TextFont_GetItalic(ITextFont *iface, LONG *value)
3267 ITextFontImpl *This = impl_from_ITextFont(iface);
3268 TRACE("(%p)->(%p)\n", This, value);
3269 return get_textfont_propl(This, FONT_ITALIC, value);
3272 static HRESULT WINAPI TextFont_SetItalic(ITextFont *iface, LONG value)
3274 ITextFontImpl *This = impl_from_ITextFont(iface);
3275 TRACE("(%p)->(%d)\n", This, value);
3276 return set_textfont_propd(This, FONT_ITALIC, value);
3279 static HRESULT WINAPI TextFont_GetKerning(ITextFont *iface, FLOAT *value)
3281 ITextFontImpl *This = impl_from_ITextFont(iface);
3282 TRACE("(%p)->(%p)\n", This, value);
3283 return get_textfont_propf(This, FONT_KERNING, value);
3286 static HRESULT WINAPI TextFont_SetKerning(ITextFont *iface, FLOAT value)
3288 ITextFontImpl *This = impl_from_ITextFont(iface);
3289 TRACE("(%p)->(%.2f)\n", This, value);
3290 return set_textfont_propf(This, FONT_KERNING, value);
3293 static HRESULT WINAPI TextFont_GetLanguageID(ITextFont *iface, LONG *value)
3295 ITextFontImpl *This = impl_from_ITextFont(iface);
3296 TRACE("(%p)->(%p)\n", This, value);
3297 return get_textfont_propl(This, FONT_LANGID, value);
3300 static HRESULT WINAPI TextFont_SetLanguageID(ITextFont *iface, LONG value)
3302 ITextFontImpl *This = impl_from_ITextFont(iface);
3303 TRACE("(%p)->(%d)\n", This, value);
3304 return set_textfont_propl(This, FONT_LANGID, value);
3307 static HRESULT WINAPI TextFont_GetName(ITextFont *iface, BSTR *value)
3309 ITextFontImpl *This = impl_from_ITextFont(iface);
3311 TRACE("(%p)->(%p)\n", This, value);
3313 if (!value)
3314 return E_INVALIDARG;
3316 *value = NULL;
3318 if (!This->range) {
3319 if (This->props[FONT_NAME].str)
3320 *value = SysAllocString(This->props[FONT_NAME].str);
3321 else
3322 *value = SysAllocStringLen(NULL, 0);
3323 return *value ? S_OK : E_OUTOFMEMORY;
3326 return textfont_getname_from_range(This->range, value);
3329 static HRESULT WINAPI TextFont_SetName(ITextFont *iface, BSTR value)
3331 ITextFontImpl *This = impl_from_ITextFont(iface);
3332 textfont_prop_val v;
3334 TRACE("(%p)->(%s)\n", This, debugstr_w(value));
3336 v.str = value;
3337 return set_textfont_prop(This, FONT_NAME, &v);
3340 static HRESULT WINAPI TextFont_GetOutline(ITextFont *iface, LONG *value)
3342 ITextFontImpl *This = impl_from_ITextFont(iface);
3343 TRACE("(%p)->(%p)\n", This, value);
3344 return get_textfont_propl(This, FONT_OUTLINE, value);
3347 static HRESULT WINAPI TextFont_SetOutline(ITextFont *iface, LONG value)
3349 ITextFontImpl *This = impl_from_ITextFont(iface);
3350 TRACE("(%p)->(%d)\n", This, value);
3351 return set_textfont_propd(This, FONT_OUTLINE, value);
3354 static HRESULT WINAPI TextFont_GetPosition(ITextFont *iface, FLOAT *value)
3356 ITextFontImpl *This = impl_from_ITextFont(iface);
3357 TRACE("(%p)->(%p)\n", This, value);
3358 return get_textfont_propf(This, FONT_POSITION, value);
3361 static HRESULT WINAPI TextFont_SetPosition(ITextFont *iface, FLOAT value)
3363 ITextFontImpl *This = impl_from_ITextFont(iface);
3364 TRACE("(%p)->(%.2f)\n", This, value);
3365 return set_textfont_propf(This, FONT_POSITION, value);
3368 static HRESULT WINAPI TextFont_GetProtected(ITextFont *iface, LONG *value)
3370 ITextFontImpl *This = impl_from_ITextFont(iface);
3371 TRACE("(%p)->(%p)\n", This, value);
3372 return get_textfont_propl(This, FONT_PROTECTED, value);
3375 static HRESULT WINAPI TextFont_SetProtected(ITextFont *iface, LONG value)
3377 ITextFontImpl *This = impl_from_ITextFont(iface);
3378 TRACE("(%p)->(%d)\n", This, value);
3379 return set_textfont_propd(This, FONT_PROTECTED, value);
3382 static HRESULT WINAPI TextFont_GetShadow(ITextFont *iface, LONG *value)
3384 ITextFontImpl *This = impl_from_ITextFont(iface);
3385 TRACE("(%p)->(%p)\n", This, value);
3386 return get_textfont_propl(This, FONT_SHADOW, value);
3389 static HRESULT WINAPI TextFont_SetShadow(ITextFont *iface, LONG value)
3391 ITextFontImpl *This = impl_from_ITextFont(iface);
3392 TRACE("(%p)->(%d)\n", This, value);
3393 return set_textfont_propd(This, FONT_SHADOW, value);
3396 static HRESULT WINAPI TextFont_GetSize(ITextFont *iface, FLOAT *value)
3398 ITextFontImpl *This = impl_from_ITextFont(iface);
3399 TRACE("(%p)->(%p)\n", This, value);
3400 return get_textfont_propf(This, FONT_SIZE, value);
3403 static HRESULT WINAPI TextFont_SetSize(ITextFont *iface, FLOAT value)
3405 ITextFontImpl *This = impl_from_ITextFont(iface);
3406 TRACE("(%p)->(%.2f)\n", This, value);
3407 return set_textfont_propf(This, FONT_SIZE, value);
3410 static HRESULT WINAPI TextFont_GetSmallCaps(ITextFont *iface, LONG *value)
3412 ITextFontImpl *This = impl_from_ITextFont(iface);
3413 TRACE("(%p)->(%p)\n", This, value);
3414 return get_textfont_propl(This, FONT_SMALLCAPS, value);
3417 static HRESULT WINAPI TextFont_SetSmallCaps(ITextFont *iface, LONG value)
3419 ITextFontImpl *This = impl_from_ITextFont(iface);
3420 TRACE("(%p)->(%d)\n", This, value);
3421 return set_textfont_propd(This, FONT_SMALLCAPS, value);
3424 static HRESULT WINAPI TextFont_GetSpacing(ITextFont *iface, FLOAT *value)
3426 ITextFontImpl *This = impl_from_ITextFont(iface);
3427 TRACE("(%p)->(%p)\n", This, value);
3428 return get_textfont_propf(This, FONT_SPACING, value);
3431 static HRESULT WINAPI TextFont_SetSpacing(ITextFont *iface, FLOAT value)
3433 ITextFontImpl *This = impl_from_ITextFont(iface);
3434 TRACE("(%p)->(%.2f)\n", This, value);
3435 return set_textfont_propf(This, FONT_SPACING, value);
3438 static HRESULT WINAPI TextFont_GetStrikeThrough(ITextFont *iface, LONG *value)
3440 ITextFontImpl *This = impl_from_ITextFont(iface);
3441 TRACE("(%p)->(%p)\n", This, value);
3442 return get_textfont_propl(This, FONT_STRIKETHROUGH, value);
3445 static HRESULT WINAPI TextFont_SetStrikeThrough(ITextFont *iface, LONG value)
3447 ITextFontImpl *This = impl_from_ITextFont(iface);
3448 TRACE("(%p)->(%d)\n", This, value);
3449 return set_textfont_propd(This, FONT_STRIKETHROUGH, value);
3452 static HRESULT WINAPI TextFont_GetSubscript(ITextFont *iface, LONG *value)
3454 ITextFontImpl *This = impl_from_ITextFont(iface);
3455 TRACE("(%p)->(%p)\n", This, value);
3456 return get_textfont_propl(This, FONT_SUBSCRIPT, value);
3459 static HRESULT WINAPI TextFont_SetSubscript(ITextFont *iface, LONG value)
3461 ITextFontImpl *This = impl_from_ITextFont(iface);
3462 TRACE("(%p)->(%d)\n", This, value);
3463 return set_textfont_propd(This, FONT_SUBSCRIPT, value);
3466 static HRESULT WINAPI TextFont_GetSuperscript(ITextFont *iface, LONG *value)
3468 ITextFontImpl *This = impl_from_ITextFont(iface);
3469 TRACE("(%p)->(%p)\n", This, value);
3470 return get_textfont_propl(This, FONT_SUPERSCRIPT, value);
3473 static HRESULT WINAPI TextFont_SetSuperscript(ITextFont *iface, LONG value)
3475 ITextFontImpl *This = impl_from_ITextFont(iface);
3476 TRACE("(%p)->(%d)\n", This, value);
3477 return set_textfont_propd(This, FONT_SUPERSCRIPT, value);
3480 static HRESULT WINAPI TextFont_GetUnderline(ITextFont *iface, LONG *value)
3482 ITextFontImpl *This = impl_from_ITextFont(iface);
3483 TRACE("(%p)->(%p)\n", This, value);
3484 return get_textfont_propl(This, FONT_UNDERLINE, value);
3487 static HRESULT WINAPI TextFont_SetUnderline(ITextFont *iface, LONG value)
3489 ITextFontImpl *This = impl_from_ITextFont(iface);
3490 TRACE("(%p)->(%d)\n", This, value);
3491 return set_textfont_propd(This, FONT_UNDERLINE, value);
3494 static HRESULT WINAPI TextFont_GetWeight(ITextFont *iface, LONG *value)
3496 ITextFontImpl *This = impl_from_ITextFont(iface);
3497 TRACE("(%p)->(%p)\n", This, value);
3498 return get_textfont_propl(This, FONT_WEIGHT, value);
3501 static HRESULT WINAPI TextFont_SetWeight(ITextFont *iface, LONG value)
3503 ITextFontImpl *This = impl_from_ITextFont(iface);
3504 TRACE("(%p)->(%d)\n", This, value);
3505 return set_textfont_propl(This, FONT_WEIGHT, value);
3508 static ITextFontVtbl textfontvtbl = {
3509 TextFont_QueryInterface,
3510 TextFont_AddRef,
3511 TextFont_Release,
3512 TextFont_GetTypeInfoCount,
3513 TextFont_GetTypeInfo,
3514 TextFont_GetIDsOfNames,
3515 TextFont_Invoke,
3516 TextFont_GetDuplicate,
3517 TextFont_SetDuplicate,
3518 TextFont_CanChange,
3519 TextFont_IsEqual,
3520 TextFont_Reset,
3521 TextFont_GetStyle,
3522 TextFont_SetStyle,
3523 TextFont_GetAllCaps,
3524 TextFont_SetAllCaps,
3525 TextFont_GetAnimation,
3526 TextFont_SetAnimation,
3527 TextFont_GetBackColor,
3528 TextFont_SetBackColor,
3529 TextFont_GetBold,
3530 TextFont_SetBold,
3531 TextFont_GetEmboss,
3532 TextFont_SetEmboss,
3533 TextFont_GetForeColor,
3534 TextFont_SetForeColor,
3535 TextFont_GetHidden,
3536 TextFont_SetHidden,
3537 TextFont_GetEngrave,
3538 TextFont_SetEngrave,
3539 TextFont_GetItalic,
3540 TextFont_SetItalic,
3541 TextFont_GetKerning,
3542 TextFont_SetKerning,
3543 TextFont_GetLanguageID,
3544 TextFont_SetLanguageID,
3545 TextFont_GetName,
3546 TextFont_SetName,
3547 TextFont_GetOutline,
3548 TextFont_SetOutline,
3549 TextFont_GetPosition,
3550 TextFont_SetPosition,
3551 TextFont_GetProtected,
3552 TextFont_SetProtected,
3553 TextFont_GetShadow,
3554 TextFont_SetShadow,
3555 TextFont_GetSize,
3556 TextFont_SetSize,
3557 TextFont_GetSmallCaps,
3558 TextFont_SetSmallCaps,
3559 TextFont_GetSpacing,
3560 TextFont_SetSpacing,
3561 TextFont_GetStrikeThrough,
3562 TextFont_SetStrikeThrough,
3563 TextFont_GetSubscript,
3564 TextFont_SetSubscript,
3565 TextFont_GetSuperscript,
3566 TextFont_SetSuperscript,
3567 TextFont_GetUnderline,
3568 TextFont_SetUnderline,
3569 TextFont_GetWeight,
3570 TextFont_SetWeight
3573 static HRESULT create_textfont(ITextRange *range, const ITextFontImpl *src, ITextFont **ret)
3575 ITextFontImpl *font;
3577 *ret = NULL;
3578 font = heap_alloc(sizeof(*font));
3579 if (!font)
3580 return E_OUTOFMEMORY;
3582 font->ITextFont_iface.lpVtbl = &textfontvtbl;
3583 font->ref = 1;
3585 if (src) {
3586 font->range = NULL;
3587 font->get_cache_enabled = TRUE;
3588 font->set_cache_enabled = TRUE;
3589 memcpy(&font->props, &src->props, sizeof(font->props));
3590 if (font->props[FONT_NAME].str)
3591 font->props[FONT_NAME].str = SysAllocString(font->props[FONT_NAME].str);
3593 else {
3594 font->range = range;
3595 ITextRange_AddRef(range);
3597 /* cache current properties */
3598 font->get_cache_enabled = FALSE;
3599 font->set_cache_enabled = FALSE;
3600 textfont_cache_range_props(font);
3603 *ret = &font->ITextFont_iface;
3604 return S_OK;
3607 /* ITextPara */
3608 static HRESULT WINAPI TextPara_QueryInterface(ITextPara *iface, REFIID riid, void **ppv)
3610 ITextParaImpl *This = impl_from_ITextPara(iface);
3612 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
3614 if (IsEqualIID(riid, &IID_ITextPara) ||
3615 IsEqualIID(riid, &IID_IDispatch) ||
3616 IsEqualIID(riid, &IID_IUnknown))
3618 *ppv = iface;
3619 ITextPara_AddRef(iface);
3620 return S_OK;
3623 *ppv = NULL;
3624 return E_NOINTERFACE;
3627 static ULONG WINAPI TextPara_AddRef(ITextPara *iface)
3629 ITextParaImpl *This = impl_from_ITextPara(iface);
3630 ULONG ref = InterlockedIncrement(&This->ref);
3631 TRACE("(%p)->(%u)\n", This, ref);
3632 return ref;
3635 static ULONG WINAPI TextPara_Release(ITextPara *iface)
3637 ITextParaImpl *This = impl_from_ITextPara(iface);
3638 ULONG ref = InterlockedDecrement(&This->ref);
3640 TRACE("(%p)->(%u)\n", This, ref);
3642 if (!ref)
3644 ITextRange_Release(This->range);
3645 heap_free(This);
3648 return ref;
3651 static HRESULT WINAPI TextPara_GetTypeInfoCount(ITextPara *iface, UINT *pctinfo)
3653 ITextParaImpl *This = impl_from_ITextPara(iface);
3654 TRACE("(%p)->(%p)\n", This, pctinfo);
3655 *pctinfo = 1;
3656 return S_OK;
3659 static HRESULT WINAPI TextPara_GetTypeInfo(ITextPara *iface, UINT iTInfo, LCID lcid,
3660 ITypeInfo **ppTInfo)
3662 ITextParaImpl *This = impl_from_ITextPara(iface);
3663 HRESULT hr;
3665 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
3667 hr = get_typeinfo(ITextPara_tid, ppTInfo);
3668 if (SUCCEEDED(hr))
3669 ITypeInfo_AddRef(*ppTInfo);
3670 return hr;
3673 static HRESULT WINAPI TextPara_GetIDsOfNames(ITextPara *iface, REFIID riid,
3674 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
3676 ITextParaImpl *This = impl_from_ITextPara(iface);
3677 ITypeInfo *ti;
3678 HRESULT hr;
3680 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames,
3681 cNames, lcid, rgDispId);
3683 hr = get_typeinfo(ITextPara_tid, &ti);
3684 if (SUCCEEDED(hr))
3685 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
3686 return hr;
3689 static HRESULT WINAPI TextPara_Invoke(
3690 ITextPara *iface,
3691 DISPID dispIdMember,
3692 REFIID riid,
3693 LCID lcid,
3694 WORD wFlags,
3695 DISPPARAMS *pDispParams,
3696 VARIANT *pVarResult,
3697 EXCEPINFO *pExcepInfo,
3698 UINT *puArgErr)
3700 ITextParaImpl *This = impl_from_ITextPara(iface);
3701 ITypeInfo *ti;
3702 HRESULT hr;
3704 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember,
3705 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
3706 pExcepInfo, puArgErr);
3708 hr = get_typeinfo(ITextPara_tid, &ti);
3709 if (SUCCEEDED(hr))
3710 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3711 return hr;
3714 static HRESULT WINAPI TextPara_GetDuplicate(ITextPara *iface, ITextPara **ret)
3716 ITextParaImpl *This = impl_from_ITextPara(iface);
3717 FIXME("(%p)->(%p)\n", This, ret);
3718 return E_NOTIMPL;
3721 static HRESULT WINAPI TextPara_SetDuplicate(ITextPara *iface, ITextPara *para)
3723 ITextParaImpl *This = impl_from_ITextPara(iface);
3724 FIXME("(%p)->(%p)\n", This, para);
3725 return E_NOTIMPL;
3728 static HRESULT WINAPI TextPara_CanChange(ITextPara *iface, LONG *ret)
3730 ITextParaImpl *This = impl_from_ITextPara(iface);
3731 FIXME("(%p)->(%p)\n", This, ret);
3732 return E_NOTIMPL;
3735 static HRESULT WINAPI TextPara_IsEqual(ITextPara *iface, ITextPara *para, LONG *ret)
3737 ITextParaImpl *This = impl_from_ITextPara(iface);
3738 FIXME("(%p)->(%p %p)\n", This, para, ret);
3739 return E_NOTIMPL;
3742 static HRESULT WINAPI TextPara_Reset(ITextPara *iface, LONG value)
3744 ITextParaImpl *This = impl_from_ITextPara(iface);
3745 FIXME("(%p)->(%d)\n", This, value);
3746 return E_NOTIMPL;
3749 static HRESULT WINAPI TextPara_GetStyle(ITextPara *iface, LONG *value)
3751 ITextParaImpl *This = impl_from_ITextPara(iface);
3752 FIXME("(%p)->(%p)\n", This, value);
3753 return E_NOTIMPL;
3756 static HRESULT WINAPI TextPara_SetStyle(ITextPara *iface, LONG value)
3758 ITextParaImpl *This = impl_from_ITextPara(iface);
3759 FIXME("(%p)->(%d)\n", This, value);
3760 return E_NOTIMPL;
3763 static HRESULT WINAPI TextPara_GetAlignment(ITextPara *iface, LONG *value)
3765 ITextParaImpl *This = impl_from_ITextPara(iface);
3766 FIXME("(%p)->(%p)\n", This, value);
3767 return E_NOTIMPL;
3770 static HRESULT WINAPI TextPara_SetAlignment(ITextPara *iface, LONG value)
3772 ITextParaImpl *This = impl_from_ITextPara(iface);
3773 FIXME("(%p)->(%d)\n", This, value);
3774 return E_NOTIMPL;
3777 static HRESULT WINAPI TextPara_GetHyphenation(ITextPara *iface, LONG *value)
3779 ITextParaImpl *This = impl_from_ITextPara(iface);
3780 FIXME("(%p)->(%p)\n", This, value);
3781 return E_NOTIMPL;
3784 static HRESULT WINAPI TextPara_SetHyphenation(ITextPara *iface, LONG value)
3786 ITextParaImpl *This = impl_from_ITextPara(iface);
3787 FIXME("(%p)->(%d)\n", This, value);
3788 return E_NOTIMPL;
3791 static HRESULT WINAPI TextPara_GetFirstLineIndent(ITextPara *iface, FLOAT *value)
3793 ITextParaImpl *This = impl_from_ITextPara(iface);
3794 FIXME("(%p)->(%p)\n", This, value);
3795 return E_NOTIMPL;
3798 static HRESULT WINAPI TextPara_GetKeepTogether(ITextPara *iface, LONG *value)
3800 ITextParaImpl *This = impl_from_ITextPara(iface);
3801 FIXME("(%p)->(%p)\n", This, value);
3802 return E_NOTIMPL;
3805 static HRESULT WINAPI TextPara_SetKeepTogether(ITextPara *iface, LONG value)
3807 ITextParaImpl *This = impl_from_ITextPara(iface);
3808 FIXME("(%p)->(%d)\n", This, value);
3809 return E_NOTIMPL;
3812 static HRESULT WINAPI TextPara_GetKeepWithNext(ITextPara *iface, LONG *value)
3814 ITextParaImpl *This = impl_from_ITextPara(iface);
3815 FIXME("(%p)->(%p)\n", This, value);
3816 return E_NOTIMPL;
3819 static HRESULT WINAPI TextPara_SetKeepWithNext(ITextPara *iface, LONG value)
3821 ITextParaImpl *This = impl_from_ITextPara(iface);
3822 FIXME("(%p)->(%d)\n", This, value);
3823 return E_NOTIMPL;
3826 static HRESULT WINAPI TextPara_GetLeftIndent(ITextPara *iface, FLOAT *value)
3828 ITextParaImpl *This = impl_from_ITextPara(iface);
3829 FIXME("(%p)->(%p)\n", This, value);
3830 return E_NOTIMPL;
3833 static HRESULT WINAPI TextPara_GetLineSpacing(ITextPara *iface, FLOAT *value)
3835 ITextParaImpl *This = impl_from_ITextPara(iface);
3836 FIXME("(%p)->(%p)\n", This, value);
3837 return E_NOTIMPL;
3840 static HRESULT WINAPI TextPara_GetLineSpacingRule(ITextPara *iface, LONG *value)
3842 ITextParaImpl *This = impl_from_ITextPara(iface);
3843 FIXME("(%p)->(%p)\n", This, value);
3844 return E_NOTIMPL;
3847 static HRESULT WINAPI TextPara_GetListAlignment(ITextPara *iface, LONG *value)
3849 ITextParaImpl *This = impl_from_ITextPara(iface);
3850 FIXME("(%p)->(%p)\n", This, value);
3851 return E_NOTIMPL;
3854 static HRESULT WINAPI TextPara_SetListAlignment(ITextPara *iface, LONG value)
3856 ITextParaImpl *This = impl_from_ITextPara(iface);
3857 FIXME("(%p)->(%d)\n", This, value);
3858 return E_NOTIMPL;
3861 static HRESULT WINAPI TextPara_GetListLevelIndex(ITextPara *iface, LONG *value)
3863 ITextParaImpl *This = impl_from_ITextPara(iface);
3864 FIXME("(%p)->(%p)\n", This, value);
3865 return E_NOTIMPL;
3868 static HRESULT WINAPI TextPara_SetListLevelIndex(ITextPara *iface, LONG value)
3870 ITextParaImpl *This = impl_from_ITextPara(iface);
3871 FIXME("(%p)->(%d)\n", This, value);
3872 return E_NOTIMPL;
3875 static HRESULT WINAPI TextPara_GetListStart(ITextPara *iface, LONG *value)
3877 ITextParaImpl *This = impl_from_ITextPara(iface);
3878 FIXME("(%p)->(%p)\n", This, value);
3879 return E_NOTIMPL;
3882 static HRESULT WINAPI TextPara_SetListStart(ITextPara *iface, LONG value)
3884 ITextParaImpl *This = impl_from_ITextPara(iface);
3885 FIXME("(%p)->(%d)\n", This, value);
3886 return E_NOTIMPL;
3889 static HRESULT WINAPI TextPara_GetListTab(ITextPara *iface, FLOAT *value)
3891 ITextParaImpl *This = impl_from_ITextPara(iface);
3892 FIXME("(%p)->(%p)\n", This, value);
3893 return E_NOTIMPL;
3896 static HRESULT WINAPI TextPara_SetListTab(ITextPara *iface, FLOAT value)
3898 ITextParaImpl *This = impl_from_ITextPara(iface);
3899 FIXME("(%p)->(%.2f)\n", This, value);
3900 return E_NOTIMPL;
3903 static HRESULT WINAPI TextPara_GetListType(ITextPara *iface, LONG *value)
3905 ITextParaImpl *This = impl_from_ITextPara(iface);
3906 FIXME("(%p)->(%p)\n", This, value);
3907 return E_NOTIMPL;
3910 static HRESULT WINAPI TextPara_SetListType(ITextPara *iface, LONG value)
3912 ITextParaImpl *This = impl_from_ITextPara(iface);
3913 FIXME("(%p)->(%d)\n", This, value);
3914 return E_NOTIMPL;
3917 static HRESULT WINAPI TextPara_GetNoLineNumber(ITextPara *iface, LONG *value)
3919 ITextParaImpl *This = impl_from_ITextPara(iface);
3920 FIXME("(%p)->(%p)\n", This, value);
3921 return E_NOTIMPL;
3924 static HRESULT WINAPI TextPara_SetNoLineNumber(ITextPara *iface, LONG value)
3926 ITextParaImpl *This = impl_from_ITextPara(iface);
3927 FIXME("(%p)->(%d)\n", This, value);
3928 return E_NOTIMPL;
3931 static HRESULT WINAPI TextPara_GetPageBreakBefore(ITextPara *iface, LONG *value)
3933 ITextParaImpl *This = impl_from_ITextPara(iface);
3934 FIXME("(%p)->(%p)\n", This, value);
3935 return E_NOTIMPL;
3938 static HRESULT WINAPI TextPara_SetPageBreakBefore(ITextPara *iface, LONG value)
3940 ITextParaImpl *This = impl_from_ITextPara(iface);
3941 FIXME("(%p)->(%d)\n", This, value);
3942 return E_NOTIMPL;
3945 static HRESULT WINAPI TextPara_GetRightIndent(ITextPara *iface, FLOAT *value)
3947 ITextParaImpl *This = impl_from_ITextPara(iface);
3948 FIXME("(%p)->(%p)\n", This, value);
3949 return E_NOTIMPL;
3952 static HRESULT WINAPI TextPara_SetRightIndent(ITextPara *iface, FLOAT value)
3954 ITextParaImpl *This = impl_from_ITextPara(iface);
3955 FIXME("(%p)->(%.2f)\n", This, value);
3956 return E_NOTIMPL;
3959 static HRESULT WINAPI TextPara_SetIndents(ITextPara *iface, FLOAT StartIndent, FLOAT LeftIndent, FLOAT RightIndent)
3961 ITextParaImpl *This = impl_from_ITextPara(iface);
3962 FIXME("(%p)->(%.2f %.2f %.2f)\n", This, StartIndent, LeftIndent, RightIndent);
3963 return E_NOTIMPL;
3966 static HRESULT WINAPI TextPara_SetLineSpacing(ITextPara *iface, LONG LineSpacingRule, FLOAT LineSpacing)
3968 ITextParaImpl *This = impl_from_ITextPara(iface);
3969 FIXME("(%p)->(%d %.2f)\n", This, LineSpacingRule, LineSpacing);
3970 return E_NOTIMPL;
3973 static HRESULT WINAPI TextPara_GetSpaceAfter(ITextPara *iface, FLOAT *value)
3975 ITextParaImpl *This = impl_from_ITextPara(iface);
3976 FIXME("(%p)->(%p)\n", This, value);
3977 return E_NOTIMPL;
3980 static HRESULT WINAPI TextPara_SetSpaceAfter(ITextPara *iface, FLOAT value)
3982 ITextParaImpl *This = impl_from_ITextPara(iface);
3983 FIXME("(%p)->(%.2f)\n", This, value);
3984 return E_NOTIMPL;
3987 static HRESULT WINAPI TextPara_GetSpaceBefore(ITextPara *iface, FLOAT *value)
3989 ITextParaImpl *This = impl_from_ITextPara(iface);
3990 FIXME("(%p)->(%p)\n", This, value);
3991 return E_NOTIMPL;
3994 static HRESULT WINAPI TextPara_SetSpaceBefore(ITextPara *iface, FLOAT value)
3996 ITextParaImpl *This = impl_from_ITextPara(iface);
3997 FIXME("(%p)->(%.2f)\n", This, value);
3998 return E_NOTIMPL;
4001 static HRESULT WINAPI TextPara_GetWidowControl(ITextPara *iface, LONG *value)
4003 ITextParaImpl *This = impl_from_ITextPara(iface);
4004 FIXME("(%p)->(%p)\n", This, value);
4005 return E_NOTIMPL;
4008 static HRESULT WINAPI TextPara_SetWidowControl(ITextPara *iface, LONG value)
4010 ITextParaImpl *This = impl_from_ITextPara(iface);
4011 FIXME("(%p)->(%d)\n", This, value);
4012 return E_NOTIMPL;
4015 static HRESULT WINAPI TextPara_GetTabCount(ITextPara *iface, LONG *value)
4017 ITextParaImpl *This = impl_from_ITextPara(iface);
4018 FIXME("(%p)->(%p)\n", This, value);
4019 return E_NOTIMPL;
4022 static HRESULT WINAPI TextPara_AddTab(ITextPara *iface, FLOAT tbPos, LONG tbAlign, LONG tbLeader)
4024 ITextParaImpl *This = impl_from_ITextPara(iface);
4025 FIXME("(%p)->(%.2f %d %d)\n", This, tbPos, tbAlign, tbLeader);
4026 return E_NOTIMPL;
4029 static HRESULT WINAPI TextPara_ClearAllTabs(ITextPara *iface)
4031 ITextParaImpl *This = impl_from_ITextPara(iface);
4032 FIXME("(%p)\n", This);
4033 return E_NOTIMPL;
4036 static HRESULT WINAPI TextPara_DeleteTab(ITextPara *iface, FLOAT pos)
4038 ITextParaImpl *This = impl_from_ITextPara(iface);
4039 FIXME("(%p)->(%.2f)\n", This, pos);
4040 return E_NOTIMPL;
4043 static HRESULT WINAPI TextPara_GetTab(ITextPara *iface, LONG iTab, FLOAT *ptbPos, LONG *ptbAlign, LONG *ptbLeader)
4045 ITextParaImpl *This = impl_from_ITextPara(iface);
4046 FIXME("(%p)->(%d %p %p %p)\n", This, iTab, ptbPos, ptbAlign, ptbLeader);
4047 return E_NOTIMPL;
4050 static ITextParaVtbl textparavtbl = {
4051 TextPara_QueryInterface,
4052 TextPara_AddRef,
4053 TextPara_Release,
4054 TextPara_GetTypeInfoCount,
4055 TextPara_GetTypeInfo,
4056 TextPara_GetIDsOfNames,
4057 TextPara_Invoke,
4058 TextPara_GetDuplicate,
4059 TextPara_SetDuplicate,
4060 TextPara_CanChange,
4061 TextPara_IsEqual,
4062 TextPara_Reset,
4063 TextPara_GetStyle,
4064 TextPara_SetStyle,
4065 TextPara_GetAlignment,
4066 TextPara_SetAlignment,
4067 TextPara_GetHyphenation,
4068 TextPara_SetHyphenation,
4069 TextPara_GetFirstLineIndent,
4070 TextPara_GetKeepTogether,
4071 TextPara_SetKeepTogether,
4072 TextPara_GetKeepWithNext,
4073 TextPara_SetKeepWithNext,
4074 TextPara_GetLeftIndent,
4075 TextPara_GetLineSpacing,
4076 TextPara_GetLineSpacingRule,
4077 TextPara_GetListAlignment,
4078 TextPara_SetListAlignment,
4079 TextPara_GetListLevelIndex,
4080 TextPara_SetListLevelIndex,
4081 TextPara_GetListStart,
4082 TextPara_SetListStart,
4083 TextPara_GetListTab,
4084 TextPara_SetListTab,
4085 TextPara_GetListType,
4086 TextPara_SetListType,
4087 TextPara_GetNoLineNumber,
4088 TextPara_SetNoLineNumber,
4089 TextPara_GetPageBreakBefore,
4090 TextPara_SetPageBreakBefore,
4091 TextPara_GetRightIndent,
4092 TextPara_SetRightIndent,
4093 TextPara_SetIndents,
4094 TextPara_SetLineSpacing,
4095 TextPara_GetSpaceAfter,
4096 TextPara_SetSpaceAfter,
4097 TextPara_GetSpaceBefore,
4098 TextPara_SetSpaceBefore,
4099 TextPara_GetWidowControl,
4100 TextPara_SetWidowControl,
4101 TextPara_GetTabCount,
4102 TextPara_AddTab,
4103 TextPara_ClearAllTabs,
4104 TextPara_DeleteTab,
4105 TextPara_GetTab
4108 static HRESULT create_textpara(ITextRange *range, ITextPara **ret)
4110 ITextParaImpl *para;
4112 *ret = NULL;
4113 para = heap_alloc(sizeof(*para));
4114 if (!para)
4115 return E_OUTOFMEMORY;
4117 para->ITextPara_iface.lpVtbl = &textparavtbl;
4118 para->ref = 1;
4119 para->range = range;
4120 ITextRange_AddRef(range);
4122 *ret = &para->ITextPara_iface;
4123 return S_OK;
4126 /* ITextDocument */
4127 static HRESULT WINAPI ITextDocument2Old_fnQueryInterface(ITextDocument2Old* iface, REFIID riid,
4128 void **ppvObject)
4130 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4131 return IRichEditOle_QueryInterface(&This->IRichEditOle_iface, riid, ppvObject);
4134 static ULONG WINAPI ITextDocument2Old_fnAddRef(ITextDocument2Old *iface)
4136 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4137 return IRichEditOle_AddRef(&This->IRichEditOle_iface);
4140 static ULONG WINAPI ITextDocument2Old_fnRelease(ITextDocument2Old *iface)
4142 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4143 return IRichEditOle_Release(&This->IRichEditOle_iface);
4146 static HRESULT WINAPI ITextDocument2Old_fnGetTypeInfoCount(ITextDocument2Old *iface,
4147 UINT *pctinfo)
4149 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4150 TRACE("(%p)->(%p)\n", This, pctinfo);
4151 *pctinfo = 1;
4152 return S_OK;
4155 static HRESULT WINAPI ITextDocument2Old_fnGetTypeInfo(ITextDocument2Old *iface, UINT iTInfo, LCID lcid,
4156 ITypeInfo **ppTInfo)
4158 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4159 HRESULT hr;
4161 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
4163 hr = get_typeinfo(ITextDocument_tid, ppTInfo);
4164 if (SUCCEEDED(hr))
4165 ITypeInfo_AddRef(*ppTInfo);
4166 return hr;
4169 static HRESULT WINAPI ITextDocument2Old_fnGetIDsOfNames(ITextDocument2Old *iface, REFIID riid,
4170 LPOLESTR *rgszNames, UINT cNames,
4171 LCID lcid, DISPID *rgDispId)
4173 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4174 ITypeInfo *ti;
4175 HRESULT hr;
4177 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid),
4178 rgszNames, cNames, lcid, rgDispId);
4180 hr = get_typeinfo(ITextDocument_tid, &ti);
4181 if (SUCCEEDED(hr))
4182 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
4183 return hr;
4186 static HRESULT WINAPI ITextDocument2Old_fnInvoke(ITextDocument2Old *iface, DISPID dispIdMember,
4187 REFIID riid, LCID lcid, WORD wFlags,
4188 DISPPARAMS *pDispParams, VARIANT *pVarResult,
4189 EXCEPINFO *pExcepInfo, UINT *puArgErr)
4191 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4192 ITypeInfo *ti;
4193 HRESULT hr;
4195 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember,
4196 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
4197 pExcepInfo, puArgErr);
4199 hr = get_typeinfo(ITextDocument_tid, &ti);
4200 if (SUCCEEDED(hr))
4201 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4202 return hr;
4205 static HRESULT WINAPI ITextDocument2Old_fnGetName(ITextDocument2Old *iface, BSTR *pName)
4207 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4208 FIXME("stub %p\n",This);
4209 return E_NOTIMPL;
4212 static HRESULT WINAPI ITextDocument2Old_fnGetSelection(ITextDocument2Old *iface, ITextSelection **selection)
4214 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4216 TRACE("(%p)->(%p)\n", iface, selection);
4218 if (!selection)
4219 return E_INVALIDARG;
4221 if (!This->txtSel) {
4222 This->txtSel = CreateTextSelection(This);
4223 if (!This->txtSel) {
4224 *selection = NULL;
4225 return E_OUTOFMEMORY;
4229 *selection = &This->txtSel->ITextSelection_iface;
4230 ITextSelection_AddRef(*selection);
4231 return S_OK;
4234 static HRESULT WINAPI ITextDocument2Old_fnGetStoryCount(ITextDocument2Old *iface, LONG *pCount)
4236 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4237 FIXME("stub %p\n",This);
4238 return E_NOTIMPL;
4241 static HRESULT WINAPI ITextDocument2Old_fnGetStoryRanges(ITextDocument2Old *iface,
4242 ITextStoryRanges **ppStories)
4244 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4245 FIXME("stub %p\n",This);
4246 return E_NOTIMPL;
4249 static HRESULT WINAPI ITextDocument2Old_fnGetSaved(ITextDocument2Old *iface, LONG *pValue)
4251 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4252 FIXME("stub %p\n",This);
4253 return E_NOTIMPL;
4256 static HRESULT WINAPI ITextDocument2Old_fnSetSaved(ITextDocument2Old *iface, LONG Value)
4258 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4259 FIXME("stub %p\n",This);
4260 return E_NOTIMPL;
4263 static HRESULT WINAPI ITextDocument2Old_fnGetDefaultTabStop(ITextDocument2Old *iface, float *pValue)
4265 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4266 FIXME("stub %p\n",This);
4267 return E_NOTIMPL;
4270 static HRESULT WINAPI ITextDocument2Old_fnSetDefaultTabStop(ITextDocument2Old *iface, float Value)
4272 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4273 FIXME("stub %p\n",This);
4274 return E_NOTIMPL;
4277 static HRESULT WINAPI ITextDocument2Old_fnNew(ITextDocument2Old *iface)
4279 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4280 FIXME("stub %p\n",This);
4281 return E_NOTIMPL;
4284 static HRESULT WINAPI ITextDocument2Old_fnOpen(ITextDocument2Old *iface, VARIANT *pVar,
4285 LONG Flags, LONG CodePage)
4287 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4288 FIXME("stub %p\n",This);
4289 return E_NOTIMPL;
4292 static HRESULT WINAPI ITextDocument2Old_fnSave(ITextDocument2Old *iface, VARIANT *pVar,
4293 LONG Flags, LONG CodePage)
4295 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4296 FIXME("stub %p\n",This);
4297 return E_NOTIMPL;
4300 static HRESULT WINAPI ITextDocument2Old_fnFreeze(ITextDocument2Old *iface, LONG *pCount)
4302 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4303 FIXME("stub %p\n",This);
4304 return E_NOTIMPL;
4307 static HRESULT WINAPI ITextDocument2Old_fnUnfreeze(ITextDocument2Old *iface, LONG *pCount)
4309 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4310 FIXME("stub %p\n",This);
4311 return E_NOTIMPL;
4314 static HRESULT WINAPI ITextDocument2Old_fnBeginEditCollection(ITextDocument2Old *iface)
4316 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4317 FIXME("stub %p\n",This);
4318 return E_NOTIMPL;
4321 static HRESULT WINAPI ITextDocument2Old_fnEndEditCollection(ITextDocument2Old *iface)
4323 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4324 FIXME("stub %p\n",This);
4325 return E_NOTIMPL;
4328 static HRESULT WINAPI ITextDocument2Old_fnUndo(ITextDocument2Old *iface, LONG Count, LONG *prop)
4330 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4331 FIXME("stub %p\n",This);
4332 return E_NOTIMPL;
4335 static HRESULT WINAPI ITextDocument2Old_fnRedo(ITextDocument2Old *iface, LONG Count, LONG *prop)
4337 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4338 FIXME("stub %p\n",This);
4339 return E_NOTIMPL;
4342 static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, ITextRange** ppRange)
4344 ITextRangeImpl *txtRge = heap_alloc(sizeof(ITextRangeImpl));
4346 if (!txtRge)
4347 return E_OUTOFMEMORY;
4348 txtRge->ITextRange_iface.lpVtbl = &trvt;
4349 txtRge->ref = 1;
4350 txtRge->child.reole = reOle;
4351 txtRge->start = start;
4352 txtRge->end = end;
4353 list_add_head(&reOle->rangelist, &txtRge->child.entry);
4354 *ppRange = &txtRge->ITextRange_iface;
4355 return S_OK;
4358 static HRESULT WINAPI ITextDocument2Old_fnRange(ITextDocument2Old *iface, LONG cp1, LONG cp2,
4359 ITextRange **ppRange)
4361 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4363 TRACE("%p %p %d %d\n", This, ppRange, cp1, cp2);
4364 if (!ppRange)
4365 return E_INVALIDARG;
4367 cp2range(This->editor, &cp1, &cp2);
4368 return CreateITextRange(This, cp1, cp2, ppRange);
4371 static HRESULT WINAPI ITextDocument2Old_fnRangeFromPoint(ITextDocument2Old *iface, LONG x, LONG y,
4372 ITextRange **ppRange)
4374 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4375 FIXME("stub %p\n",This);
4376 return E_NOTIMPL;
4379 /* ITextDocument2Old methods */
4380 static HRESULT WINAPI ITextDocument2Old_fnAttachMsgFilter(ITextDocument2Old *iface, IUnknown *filter)
4382 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4384 FIXME("(%p)->(%p): stub\n", This, filter);
4386 return E_NOTIMPL;
4389 static HRESULT WINAPI ITextDocument2Old_fnSetEffectColor(ITextDocument2Old *iface, LONG index, COLORREF cr)
4391 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4393 FIXME("(%p)->(%d, 0x%x): stub\n", This, index, cr);
4395 return E_NOTIMPL;
4398 static HRESULT WINAPI ITextDocument2Old_fnGetEffectColor(ITextDocument2Old *iface, LONG index, COLORREF *cr)
4400 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4402 FIXME("(%p)->(%d, %p): stub\n", This, index, cr);
4404 return E_NOTIMPL;
4407 static HRESULT WINAPI ITextDocument2Old_fnGetCaretType(ITextDocument2Old *iface, LONG *type)
4409 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4411 FIXME("(%p)->(%p): stub\n", This, type);
4413 return E_NOTIMPL;
4416 static HRESULT WINAPI ITextDocument2Old_fnSetCaretType(ITextDocument2Old *iface, LONG type)
4418 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4420 FIXME("(%p)->(%d): stub\n", This, type);
4422 return E_NOTIMPL;
4425 static HRESULT WINAPI ITextDocument2Old_fnGetImmContext(ITextDocument2Old *iface, LONG *context)
4427 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4429 FIXME("(%p)->(%p): stub\n", This, context);
4431 return E_NOTIMPL;
4434 static HRESULT WINAPI ITextDocument2Old_fnReleaseImmContext(ITextDocument2Old *iface, LONG context)
4436 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4438 FIXME("(%p)->(%d): stub\n", This, context);
4440 return E_NOTIMPL;
4443 static HRESULT WINAPI ITextDocument2Old_fnGetPreferredFont(ITextDocument2Old *iface, LONG cp, LONG charrep,
4444 LONG options, LONG current_charrep, LONG current_fontsize,
4445 BSTR *bstr, LONG *pitch_family, LONG *new_fontsize)
4447 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4449 FIXME("(%p)->(%d, %d, %d, %d, %d, %p, %p, %p): stub\n", This, cp, charrep, options, current_charrep,
4450 current_fontsize, bstr, pitch_family, new_fontsize);
4452 return E_NOTIMPL;
4455 static HRESULT WINAPI ITextDocument2Old_fnGetNotificationMode(ITextDocument2Old *iface, LONG *mode)
4457 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4459 FIXME("(%p)->(%p): stub\n", This, mode);
4461 return E_NOTIMPL;
4464 static HRESULT WINAPI ITextDocument2Old_fnSetNotificationMode(ITextDocument2Old *iface, LONG mode)
4466 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4468 FIXME("(%p)->(0x%x): stub\n", This, mode);
4470 return E_NOTIMPL;
4473 static HRESULT WINAPI ITextDocument2Old_fnGetClientRect(ITextDocument2Old *iface, LONG type, LONG *left, LONG *top,
4474 LONG *right, LONG *bottom)
4476 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4478 FIXME("(%p)->(%d, %p, %p, %p, %p): stub\n", This, type, left, top, right, bottom);
4480 return E_NOTIMPL;
4483 static HRESULT WINAPI ITextDocument2Old_fnGetSelectionEx(ITextDocument2Old *iface, ITextSelection **selection)
4485 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4487 FIXME("(%p)->(%p): stub\n", This, selection);
4489 return E_NOTIMPL;
4492 static HRESULT WINAPI ITextDocument2Old_fnGetWindow(ITextDocument2Old *iface, LONG *hwnd)
4494 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4496 FIXME("(%p)->(%p): stub\n", This, hwnd);
4498 return E_NOTIMPL;
4501 static HRESULT WINAPI ITextDocument2Old_fnGetFEFlags(ITextDocument2Old *iface, LONG *flags)
4503 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4505 FIXME("(%p)->(%p): stub\n", This, flags);
4507 return E_NOTIMPL;
4510 static HRESULT WINAPI ITextDocument2Old_fnUpdateWindow(ITextDocument2Old *iface)
4512 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4514 FIXME("(%p): stub\n", This);
4516 return E_NOTIMPL;
4519 static HRESULT WINAPI ITextDocument2Old_fnCheckTextLimit(ITextDocument2Old *iface, LONG cch, LONG *exceed)
4521 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4523 FIXME("(%p)->(%d, %p): stub\n", This, cch, exceed);
4525 return E_NOTIMPL;
4528 static HRESULT WINAPI ITextDocument2Old_fnIMEInProgress(ITextDocument2Old *iface, LONG mode)
4530 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4532 FIXME("(%p)->(0x%x): stub\n", This, mode);
4534 return E_NOTIMPL;
4537 static HRESULT WINAPI ITextDocument2Old_fnSysBeep(ITextDocument2Old *iface)
4539 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4541 FIXME("(%p): stub\n", This);
4543 return E_NOTIMPL;
4546 static HRESULT WINAPI ITextDocument2Old_fnUpdate(ITextDocument2Old *iface, LONG mode)
4548 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4550 FIXME("(%p)->(0x%x): stub\n", This, mode);
4552 return E_NOTIMPL;
4555 static HRESULT WINAPI ITextDocument2Old_fnNotify(ITextDocument2Old *iface, LONG notify)
4557 IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface);
4559 FIXME("(%p)->(%d): stub\n", This, notify);
4561 return E_NOTIMPL;
4564 static const ITextDocument2OldVtbl tdvt = {
4565 ITextDocument2Old_fnQueryInterface,
4566 ITextDocument2Old_fnAddRef,
4567 ITextDocument2Old_fnRelease,
4568 ITextDocument2Old_fnGetTypeInfoCount,
4569 ITextDocument2Old_fnGetTypeInfo,
4570 ITextDocument2Old_fnGetIDsOfNames,
4571 ITextDocument2Old_fnInvoke,
4572 ITextDocument2Old_fnGetName,
4573 ITextDocument2Old_fnGetSelection,
4574 ITextDocument2Old_fnGetStoryCount,
4575 ITextDocument2Old_fnGetStoryRanges,
4576 ITextDocument2Old_fnGetSaved,
4577 ITextDocument2Old_fnSetSaved,
4578 ITextDocument2Old_fnGetDefaultTabStop,
4579 ITextDocument2Old_fnSetDefaultTabStop,
4580 ITextDocument2Old_fnNew,
4581 ITextDocument2Old_fnOpen,
4582 ITextDocument2Old_fnSave,
4583 ITextDocument2Old_fnFreeze,
4584 ITextDocument2Old_fnUnfreeze,
4585 ITextDocument2Old_fnBeginEditCollection,
4586 ITextDocument2Old_fnEndEditCollection,
4587 ITextDocument2Old_fnUndo,
4588 ITextDocument2Old_fnRedo,
4589 ITextDocument2Old_fnRange,
4590 ITextDocument2Old_fnRangeFromPoint,
4591 /* ITextDocument2Old methods */
4592 ITextDocument2Old_fnAttachMsgFilter,
4593 ITextDocument2Old_fnSetEffectColor,
4594 ITextDocument2Old_fnGetEffectColor,
4595 ITextDocument2Old_fnGetCaretType,
4596 ITextDocument2Old_fnSetCaretType,
4597 ITextDocument2Old_fnGetImmContext,
4598 ITextDocument2Old_fnReleaseImmContext,
4599 ITextDocument2Old_fnGetPreferredFont,
4600 ITextDocument2Old_fnGetNotificationMode,
4601 ITextDocument2Old_fnSetNotificationMode,
4602 ITextDocument2Old_fnGetClientRect,
4603 ITextDocument2Old_fnGetSelectionEx,
4604 ITextDocument2Old_fnGetWindow,
4605 ITextDocument2Old_fnGetFEFlags,
4606 ITextDocument2Old_fnUpdateWindow,
4607 ITextDocument2Old_fnCheckTextLimit,
4608 ITextDocument2Old_fnIMEInProgress,
4609 ITextDocument2Old_fnSysBeep,
4610 ITextDocument2Old_fnUpdate,
4611 ITextDocument2Old_fnNotify
4614 /* ITextSelection */
4615 static HRESULT WINAPI ITextSelection_fnQueryInterface(
4616 ITextSelection *me,
4617 REFIID riid,
4618 void **ppvObj)
4620 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4622 *ppvObj = NULL;
4623 if (IsEqualGUID(riid, &IID_IUnknown)
4624 || IsEqualGUID(riid, &IID_IDispatch)
4625 || IsEqualGUID(riid, &IID_ITextRange)
4626 || IsEqualGUID(riid, &IID_ITextSelection))
4628 *ppvObj = me;
4629 ITextSelection_AddRef(me);
4630 return S_OK;
4632 else if (IsEqualGUID(riid, &IID_Igetrichole))
4634 *ppvObj = This->reOle;
4635 return S_OK;
4638 return E_NOINTERFACE;
4641 static ULONG WINAPI ITextSelection_fnAddRef(ITextSelection *me)
4643 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4644 return InterlockedIncrement(&This->ref);
4647 static ULONG WINAPI ITextSelection_fnRelease(ITextSelection *me)
4649 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4650 ULONG ref = InterlockedDecrement(&This->ref);
4651 if (ref == 0)
4652 heap_free(This);
4653 return ref;
4656 static HRESULT WINAPI ITextSelection_fnGetTypeInfoCount(ITextSelection *me, UINT *pctinfo)
4658 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4659 TRACE("(%p)->(%p)\n", This, pctinfo);
4660 *pctinfo = 1;
4661 return S_OK;
4664 static HRESULT WINAPI ITextSelection_fnGetTypeInfo(ITextSelection *me, UINT iTInfo, LCID lcid,
4665 ITypeInfo **ppTInfo)
4667 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4668 HRESULT hr;
4670 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
4672 hr = get_typeinfo(ITextSelection_tid, ppTInfo);
4673 if (SUCCEEDED(hr))
4674 ITypeInfo_AddRef(*ppTInfo);
4675 return hr;
4678 static HRESULT WINAPI ITextSelection_fnGetIDsOfNames(ITextSelection *me, REFIID riid,
4679 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
4681 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4682 ITypeInfo *ti;
4683 HRESULT hr;
4685 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
4686 rgDispId);
4688 hr = get_typeinfo(ITextSelection_tid, &ti);
4689 if (SUCCEEDED(hr))
4690 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
4691 return hr;
4694 static HRESULT WINAPI ITextSelection_fnInvoke(
4695 ITextSelection *me,
4696 DISPID dispIdMember,
4697 REFIID riid,
4698 LCID lcid,
4699 WORD wFlags,
4700 DISPPARAMS *pDispParams,
4701 VARIANT *pVarResult,
4702 EXCEPINFO *pExcepInfo,
4703 UINT *puArgErr)
4705 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4706 ITypeInfo *ti;
4707 HRESULT hr;
4709 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid), lcid,
4710 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4712 hr = get_typeinfo(ITextSelection_tid, &ti);
4713 if (SUCCEEDED(hr))
4714 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4715 return hr;
4718 /*** ITextRange methods ***/
4719 static HRESULT WINAPI ITextSelection_fnGetText(ITextSelection *me, BSTR *pbstr)
4721 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4722 ME_Cursor *start = NULL, *end = NULL;
4723 int nChars, endOfs;
4724 BOOL bEOP;
4726 TRACE("(%p)->(%p)\n", This, pbstr);
4728 if (!This->reOle)
4729 return CO_E_RELEASED;
4731 if (!pbstr)
4732 return E_INVALIDARG;
4734 ME_GetSelection(This->reOle->editor, &start, &end);
4735 endOfs = ME_GetCursorOfs(end);
4736 nChars = endOfs - ME_GetCursorOfs(start);
4737 if (!nChars)
4739 *pbstr = NULL;
4740 return S_OK;
4743 *pbstr = SysAllocStringLen(NULL, nChars);
4744 if (!*pbstr)
4745 return E_OUTOFMEMORY;
4747 bEOP = (!para_next( para_next( end->para ) ) && endOfs > ME_GetTextLength(This->reOle->editor));
4748 ME_GetTextW(This->reOle->editor, *pbstr, nChars, start, nChars, FALSE, bEOP);
4749 TRACE("%s\n", wine_dbgstr_w(*pbstr));
4751 return S_OK;
4754 static HRESULT WINAPI ITextSelection_fnSetText(ITextSelection *me, BSTR str)
4756 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4757 ME_TextEditor *editor;
4758 int len, to, from;
4760 TRACE("(%p)->(%s)\n", This, debugstr_w(str));
4762 if (!This->reOle)
4763 return CO_E_RELEASED;
4765 editor = This->reOle->editor;
4766 len = lstrlenW(str);
4767 ME_GetSelectionOfs(editor, &from, &to);
4768 ME_ReplaceSel(editor, FALSE, str, len);
4770 if (len < to - from)
4771 textranges_update_ranges(This->reOle, from, len, RANGE_UPDATE_DELETE);
4773 return S_OK;
4776 static HRESULT WINAPI ITextSelection_fnGetChar(ITextSelection *me, LONG *pch)
4778 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4779 ME_Cursor *start = NULL, *end = NULL;
4781 TRACE("(%p)->(%p)\n", This, pch);
4783 if (!This->reOle)
4784 return CO_E_RELEASED;
4786 if (!pch)
4787 return E_INVALIDARG;
4789 ME_GetSelection(This->reOle->editor, &start, &end);
4790 return range_GetChar(This->reOle->editor, start, pch);
4793 static HRESULT WINAPI ITextSelection_fnSetChar(ITextSelection *me, LONG ch)
4795 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4797 FIXME("(%p)->(%x): stub\n", This, ch);
4799 if (!This->reOle)
4800 return CO_E_RELEASED;
4802 return E_NOTIMPL;
4805 static HRESULT WINAPI ITextSelection_fnGetDuplicate(ITextSelection *me, ITextRange **range)
4807 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4808 LONG start, end;
4810 TRACE("(%p)->(%p)\n", This, range);
4812 if (!This->reOle)
4813 return CO_E_RELEASED;
4815 if (!range)
4816 return E_INVALIDARG;
4818 ITextSelection_GetStart(me, &start);
4819 ITextSelection_GetEnd(me, &end);
4820 return CreateITextRange(This->reOle, start, end, range);
4823 static HRESULT WINAPI ITextSelection_fnGetFormattedText(ITextSelection *me, ITextRange **range)
4825 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4827 FIXME("(%p)->(%p): stub\n", This, range);
4829 if (!This->reOle)
4830 return CO_E_RELEASED;
4832 return E_NOTIMPL;
4835 static HRESULT WINAPI ITextSelection_fnSetFormattedText(ITextSelection *me, ITextRange *range)
4837 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4839 FIXME("(%p)->(%p): stub\n", This, range);
4841 if (!This->reOle)
4842 return CO_E_RELEASED;
4844 FIXME("not implemented\n");
4845 return E_NOTIMPL;
4848 static HRESULT WINAPI ITextSelection_fnGetStart(ITextSelection *me, LONG *pcpFirst)
4850 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4851 LONG lim;
4853 TRACE("(%p)->(%p)\n", This, pcpFirst);
4855 if (!This->reOle)
4856 return CO_E_RELEASED;
4858 if (!pcpFirst)
4859 return E_INVALIDARG;
4860 ME_GetSelectionOfs(This->reOle->editor, pcpFirst, &lim);
4861 return S_OK;
4864 static HRESULT WINAPI ITextSelection_fnSetStart(ITextSelection *me, LONG value)
4866 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4867 LONG start, end;
4868 HRESULT hr;
4870 TRACE("(%p)->(%d)\n", This, value);
4872 if (!This->reOle)
4873 return CO_E_RELEASED;
4875 ME_GetSelectionOfs(This->reOle->editor, &start, &end);
4876 hr = textrange_setstart(This->reOle, value, &start, &end);
4877 if (hr == S_OK)
4878 set_selection(This->reOle->editor, start, end);
4880 return hr;
4883 static HRESULT WINAPI ITextSelection_fnGetEnd(ITextSelection *me, LONG *pcpLim)
4885 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4886 LONG first;
4888 TRACE("(%p)->(%p)\n", This, pcpLim);
4890 if (!This->reOle)
4891 return CO_E_RELEASED;
4893 if (!pcpLim)
4894 return E_INVALIDARG;
4895 ME_GetSelectionOfs(This->reOle->editor, &first, pcpLim);
4896 return S_OK;
4899 static HRESULT WINAPI ITextSelection_fnSetEnd(ITextSelection *me, LONG value)
4901 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4902 LONG start, end;
4903 HRESULT hr;
4905 TRACE("(%p)->(%d)\n", This, value);
4907 if (!This->reOle)
4908 return CO_E_RELEASED;
4910 ME_GetSelectionOfs(This->reOle->editor, &start, &end);
4911 hr = textrange_setend(This->reOle, value, &start, &end);
4912 if (hr == S_OK)
4913 set_selection(This->reOle->editor, start, end);
4915 return hr;
4918 static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **font)
4920 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4921 ITextRange *range = NULL;
4922 HRESULT hr;
4924 TRACE("(%p)->(%p)\n", This, font);
4926 if (!This->reOle)
4927 return CO_E_RELEASED;
4929 if (!font)
4930 return E_INVALIDARG;
4932 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
4933 hr = create_textfont(range, NULL, font);
4934 ITextRange_Release(range);
4935 return hr;
4938 static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *font)
4940 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4941 ITextRange *range = NULL;
4943 TRACE("(%p)->(%p)\n", This, font);
4945 if (!font)
4946 return E_INVALIDARG;
4948 if (!This->reOle)
4949 return CO_E_RELEASED;
4951 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
4952 textrange_set_font(range, font);
4953 ITextRange_Release(range);
4954 return S_OK;
4957 static HRESULT WINAPI ITextSelection_fnGetPara(ITextSelection *me, ITextPara **para)
4959 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4960 ITextRange *range = NULL;
4961 HRESULT hr;
4963 TRACE("(%p)->(%p)\n", This, para);
4965 if (!This->reOle)
4966 return CO_E_RELEASED;
4968 if (!para)
4969 return E_INVALIDARG;
4971 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
4972 hr = create_textpara(range, para);
4973 ITextRange_Release(range);
4974 return hr;
4977 static HRESULT WINAPI ITextSelection_fnSetPara(ITextSelection *me, ITextPara *para)
4979 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4981 FIXME("(%p)->(%p): stub\n", This, para);
4983 if (!This->reOle)
4984 return CO_E_RELEASED;
4986 FIXME("not implemented\n");
4987 return E_NOTIMPL;
4990 static HRESULT WINAPI ITextSelection_fnGetStoryLength(ITextSelection *me, LONG *length)
4992 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4994 TRACE("(%p)->(%p)\n", This, length);
4996 if (!This->reOle)
4997 return CO_E_RELEASED;
4999 return textrange_get_storylength(This->reOle->editor, length);
5002 static HRESULT WINAPI ITextSelection_fnGetStoryType(ITextSelection *me, LONG *value)
5004 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5006 TRACE("(%p)->(%p)\n", This, value);
5008 if (!This->reOle)
5009 return CO_E_RELEASED;
5011 if (!value)
5012 return E_INVALIDARG;
5014 *value = tomUnknownStory;
5015 return S_OK;
5018 static HRESULT WINAPI ITextSelection_fnCollapse(ITextSelection *me, LONG bStart)
5020 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5021 LONG start, end;
5022 HRESULT hres;
5024 TRACE("(%p)->(%d)\n", This, bStart);
5026 if (!This->reOle)
5027 return CO_E_RELEASED;
5029 ME_GetSelectionOfs(This->reOle->editor, &start, &end);
5030 hres = range_Collapse(bStart, &start, &end);
5031 if (SUCCEEDED(hres))
5032 set_selection(This->reOle->editor, start, end);
5033 return hres;
5036 static HRESULT WINAPI ITextSelection_fnExpand(ITextSelection *me, LONG unit, LONG *delta)
5038 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5039 ITextRange *range = NULL;
5040 HRESULT hr;
5042 TRACE("(%p)->(%d %p)\n", This, unit, delta);
5044 if (!This->reOle)
5045 return CO_E_RELEASED;
5047 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5048 hr = textrange_expand(range, unit, delta);
5049 ITextRange_Release(range);
5050 return hr;
5053 static HRESULT WINAPI ITextSelection_fnGetIndex(ITextSelection *me, LONG unit, LONG *index)
5055 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5057 FIXME("(%p)->(%d %p): stub\n", This, unit, index);
5059 if (!This->reOle)
5060 return CO_E_RELEASED;
5062 return E_NOTIMPL;
5065 static HRESULT WINAPI ITextSelection_fnSetIndex(ITextSelection *me, LONG unit, LONG index,
5066 LONG extend)
5068 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5070 FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend);
5072 if (!This->reOle)
5073 return CO_E_RELEASED;
5075 return E_NOTIMPL;
5078 static HRESULT WINAPI ITextSelection_fnSetRange(ITextSelection *me, LONG anchor, LONG active)
5080 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5082 FIXME("(%p)->(%d %d): stub\n", This, anchor, active);
5084 if (!This->reOle)
5085 return CO_E_RELEASED;
5087 return E_NOTIMPL;
5090 static HRESULT WINAPI ITextSelection_fnInRange(ITextSelection *me, ITextRange *range, LONG *ret)
5092 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5093 ITextSelection *selection = NULL;
5094 LONG start, end;
5096 TRACE("(%p)->(%p %p)\n", This, range, ret);
5098 if (ret)
5099 *ret = tomFalse;
5101 if (!This->reOle)
5102 return CO_E_RELEASED;
5104 if (!range)
5105 return S_FALSE;
5107 ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection);
5108 if (!selection)
5109 return S_FALSE;
5110 ITextSelection_Release(selection);
5112 ITextSelection_GetStart(me, &start);
5113 ITextSelection_GetEnd(me, &end);
5114 return textrange_inrange(start, end, range, ret);
5117 static HRESULT WINAPI ITextSelection_fnInStory(ITextSelection *me, ITextRange *range, LONG *ret)
5119 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5121 FIXME("(%p)->(%p %p): stub\n", This, range, ret);
5123 if (!This->reOle)
5124 return CO_E_RELEASED;
5126 return E_NOTIMPL;
5129 static HRESULT WINAPI ITextSelection_fnIsEqual(ITextSelection *me, ITextRange *range, LONG *ret)
5131 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5132 ITextSelection *selection = NULL;
5133 LONG start, end;
5135 TRACE("(%p)->(%p %p)\n", This, range, ret);
5137 if (ret)
5138 *ret = tomFalse;
5140 if (!This->reOle)
5141 return CO_E_RELEASED;
5143 if (!range)
5144 return S_FALSE;
5146 ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection);
5147 if (!selection)
5148 return S_FALSE;
5149 ITextSelection_Release(selection);
5151 ITextSelection_GetStart(me, &start);
5152 ITextSelection_GetEnd(me, &end);
5153 return textrange_isequal(start, end, range, ret);
5156 static HRESULT WINAPI ITextSelection_fnSelect(ITextSelection *me)
5158 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5160 TRACE("(%p)\n", This);
5162 if (!This->reOle)
5163 return CO_E_RELEASED;
5165 /* nothing to do */
5166 return S_OK;
5169 static HRESULT WINAPI ITextSelection_fnStartOf(ITextSelection *me, LONG unit, LONG extend,
5170 LONG *delta)
5172 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5173 ITextRange *range = NULL;
5174 HRESULT hr;
5176 TRACE("(%p)->(%d %d %p)\n", This, unit, extend, delta);
5178 if (!This->reOle)
5179 return CO_E_RELEASED;
5181 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5182 hr = textrange_startof(range, unit, extend, delta);
5183 ITextRange_Release(range);
5184 return hr;
5187 static HRESULT WINAPI ITextSelection_fnEndOf(ITextSelection *me, LONG unit, LONG extend,
5188 LONG *delta)
5190 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5191 ITextRange *range = NULL;
5192 HRESULT hr;
5194 TRACE("(%p)->(%d %d %p)\n", This, unit, extend, delta);
5196 if (!This->reOle)
5197 return CO_E_RELEASED;
5199 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5200 hr = textrange_endof(range, This->reOle->editor, unit, extend, delta);
5201 ITextRange_Release(range);
5202 return hr;
5205 static HRESULT WINAPI ITextSelection_fnMove(ITextSelection *me, LONG unit, LONG count, LONG *delta)
5207 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5208 ITextRange *range = NULL;
5209 HRESULT hr;
5211 TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta);
5213 if (!This->reOle)
5214 return CO_E_RELEASED;
5216 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5217 hr = textrange_movestart(range, This->reOle->editor, unit, count, delta);
5218 ITextRange_Release(range);
5219 return hr;
5222 static HRESULT WINAPI ITextSelection_fnMoveStart(ITextSelection *me, LONG unit, LONG count,
5223 LONG *delta)
5225 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5226 ITextRange *range = NULL;
5227 HRESULT hr;
5229 TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta);
5231 if (!This->reOle)
5232 return CO_E_RELEASED;
5234 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5235 hr = textrange_movestart(range, This->reOle->editor, unit, count, delta);
5236 ITextRange_Release(range);
5237 return hr;
5240 static HRESULT WINAPI ITextSelection_fnMoveEnd(ITextSelection *me, LONG unit, LONG count,
5241 LONG *delta)
5243 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5244 ITextRange *range = NULL;
5245 HRESULT hr;
5247 TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta);
5249 if (!This->reOle)
5250 return CO_E_RELEASED;
5252 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5253 hr = textrange_moveend(range, This->reOle->editor, unit, count, delta);
5254 ITextRange_Release(range);
5255 return hr;
5258 static HRESULT WINAPI ITextSelection_fnMoveWhile(ITextSelection *me, VARIANT *charset, LONG count,
5259 LONG *delta)
5261 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5263 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
5265 if (!This->reOle)
5266 return CO_E_RELEASED;
5268 return E_NOTIMPL;
5271 static HRESULT WINAPI ITextSelection_fnMoveStartWhile(ITextSelection *me, VARIANT *charset, LONG count,
5272 LONG *delta)
5274 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5276 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
5278 if (!This->reOle)
5279 return CO_E_RELEASED;
5281 return E_NOTIMPL;
5284 static HRESULT WINAPI ITextSelection_fnMoveEndWhile(ITextSelection *me, VARIANT *charset, LONG count,
5285 LONG *delta)
5287 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5289 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
5291 if (!This->reOle)
5292 return CO_E_RELEASED;
5294 return E_NOTIMPL;
5297 static HRESULT WINAPI ITextSelection_fnMoveUntil(ITextSelection *me, VARIANT *charset, LONG count,
5298 LONG *delta)
5300 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5302 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
5304 if (!This->reOle)
5305 return CO_E_RELEASED;
5307 return E_NOTIMPL;
5310 static HRESULT WINAPI ITextSelection_fnMoveStartUntil(ITextSelection *me, VARIANT *charset, LONG count,
5311 LONG *delta)
5313 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5315 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
5317 if (!This->reOle)
5318 return CO_E_RELEASED;
5320 return E_NOTIMPL;
5323 static HRESULT WINAPI ITextSelection_fnMoveEndUntil(ITextSelection *me, VARIANT *charset, LONG count,
5324 LONG *delta)
5326 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5328 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
5330 if (!This->reOle)
5331 return CO_E_RELEASED;
5333 return E_NOTIMPL;
5336 static HRESULT WINAPI ITextSelection_fnFindText(ITextSelection *me, BSTR text, LONG count, LONG flags,
5337 LONG *length)
5339 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5341 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
5343 if (!This->reOle)
5344 return CO_E_RELEASED;
5346 FIXME("not implemented\n");
5347 return E_NOTIMPL;
5350 static HRESULT WINAPI ITextSelection_fnFindTextStart(ITextSelection *me, BSTR text, LONG count,
5351 LONG flags, LONG *length)
5353 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5355 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
5357 if (!This->reOle)
5358 return CO_E_RELEASED;
5360 return E_NOTIMPL;
5363 static HRESULT WINAPI ITextSelection_fnFindTextEnd(ITextSelection *me, BSTR text, LONG count,
5364 LONG flags, LONG *length)
5366 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5368 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
5370 if (!This->reOle)
5371 return CO_E_RELEASED;
5373 return E_NOTIMPL;
5376 static HRESULT WINAPI ITextSelection_fnDelete(ITextSelection *me, LONG unit, LONG count,
5377 LONG *delta)
5379 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5381 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
5383 if (!This->reOle)
5384 return CO_E_RELEASED;
5386 return E_NOTIMPL;
5389 static HRESULT WINAPI ITextSelection_fnCut(ITextSelection *me, VARIANT *v)
5391 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5392 ITextRange *range = NULL;
5393 HRESULT hr;
5395 TRACE("(%p)->(%p): stub\n", This, v);
5397 if (!This->reOle)
5398 return CO_E_RELEASED;
5400 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5401 hr = textrange_copy_or_cut(range, This->reOle->editor, TRUE, v);
5402 ITextRange_Release(range);
5403 return hr;
5406 static HRESULT WINAPI ITextSelection_fnCopy(ITextSelection *me, VARIANT *v)
5408 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5409 ITextRange *range = NULL;
5410 HRESULT hr;
5412 TRACE("(%p)->(%p)\n", This, v);
5414 if (!This->reOle)
5415 return CO_E_RELEASED;
5417 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5418 hr = textrange_copy_or_cut(range, This->reOle->editor, FALSE, v);
5419 ITextRange_Release(range);
5420 return hr;
5423 static HRESULT WINAPI ITextSelection_fnPaste(ITextSelection *me, VARIANT *v, LONG format)
5425 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5427 FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format);
5429 if (!This->reOle)
5430 return CO_E_RELEASED;
5432 return E_NOTIMPL;
5435 static HRESULT WINAPI ITextSelection_fnCanPaste(ITextSelection *me, VARIANT *v, LONG format,
5436 LONG *ret)
5438 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5440 FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret);
5442 if (!This->reOle)
5443 return CO_E_RELEASED;
5445 return E_NOTIMPL;
5448 static HRESULT WINAPI ITextSelection_fnCanEdit(ITextSelection *me, LONG *ret)
5450 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5452 FIXME("(%p)->(%p): stub\n", This, ret);
5454 if (!This->reOle)
5455 return CO_E_RELEASED;
5457 return E_NOTIMPL;
5460 static HRESULT WINAPI ITextSelection_fnChangeCase(ITextSelection *me, LONG type)
5462 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5464 FIXME("(%p)->(%d): stub\n", This, type);
5466 if (!This->reOle)
5467 return CO_E_RELEASED;
5469 return E_NOTIMPL;
5472 static HRESULT WINAPI ITextSelection_fnGetPoint(ITextSelection *me, LONG type, LONG *cx, LONG *cy)
5474 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5476 FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy);
5478 if (!This->reOle)
5479 return CO_E_RELEASED;
5481 return E_NOTIMPL;
5484 static HRESULT WINAPI ITextSelection_fnSetPoint(ITextSelection *me, LONG x, LONG y, LONG type,
5485 LONG extend)
5487 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5489 FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend);
5491 if (!This->reOle)
5492 return CO_E_RELEASED;
5494 return E_NOTIMPL;
5497 static HRESULT WINAPI ITextSelection_fnScrollIntoView(ITextSelection *me, LONG value)
5499 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5501 FIXME("(%p)->(%d): stub\n", This, value);
5503 if (!This->reOle)
5504 return CO_E_RELEASED;
5506 return E_NOTIMPL;
5509 static HRESULT WINAPI ITextSelection_fnGetEmbeddedObject(ITextSelection *me, IUnknown **ppv)
5511 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5513 FIXME("(%p)->(%p): stub\n", This, ppv);
5515 if (!This->reOle)
5516 return CO_E_RELEASED;
5518 return E_NOTIMPL;
5521 /*** ITextSelection methods ***/
5522 static HRESULT WINAPI ITextSelection_fnGetFlags(ITextSelection *me, LONG *flags)
5524 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5526 FIXME("(%p)->(%p): stub\n", This, flags);
5528 if (!This->reOle)
5529 return CO_E_RELEASED;
5531 return E_NOTIMPL;
5534 static HRESULT WINAPI ITextSelection_fnSetFlags(ITextSelection *me, LONG flags)
5536 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5538 FIXME("(%p)->(%x): stub\n", This, flags);
5540 if (!This->reOle)
5541 return CO_E_RELEASED;
5543 return E_NOTIMPL;
5546 static HRESULT WINAPI ITextSelection_fnGetType(ITextSelection *me, LONG *type)
5548 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5550 FIXME("(%p)->(%p): stub\n", This, type);
5552 if (!This->reOle)
5553 return CO_E_RELEASED;
5555 return E_NOTIMPL;
5558 static HRESULT WINAPI ITextSelection_fnMoveLeft(ITextSelection *me, LONG unit, LONG count,
5559 LONG extend, LONG *delta)
5561 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5563 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5565 if (!This->reOle)
5566 return CO_E_RELEASED;
5568 return E_NOTIMPL;
5571 static HRESULT WINAPI ITextSelection_fnMoveRight(ITextSelection *me, LONG unit, LONG count,
5572 LONG extend, LONG *delta)
5574 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5576 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5578 if (!This->reOle)
5579 return CO_E_RELEASED;
5581 return E_NOTIMPL;
5584 static HRESULT WINAPI ITextSelection_fnMoveUp(ITextSelection *me, LONG unit, LONG count,
5585 LONG extend, LONG *delta)
5587 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5589 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5591 if (!This->reOle)
5592 return CO_E_RELEASED;
5594 return E_NOTIMPL;
5597 static HRESULT WINAPI ITextSelection_fnMoveDown(ITextSelection *me, LONG unit, LONG count,
5598 LONG extend, LONG *delta)
5600 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5602 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5604 if (!This->reOle)
5605 return CO_E_RELEASED;
5607 return E_NOTIMPL;
5610 static HRESULT WINAPI ITextSelection_fnHomeKey(ITextSelection *me, LONG unit, LONG extend,
5611 LONG *delta)
5613 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5615 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
5617 if (!This->reOle)
5618 return CO_E_RELEASED;
5620 return E_NOTIMPL;
5623 static HRESULT WINAPI ITextSelection_fnEndKey(ITextSelection *me, LONG unit, LONG extend,
5624 LONG *delta)
5626 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5628 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
5630 if (!This->reOle)
5631 return CO_E_RELEASED;
5633 return E_NOTIMPL;
5636 static HRESULT WINAPI ITextSelection_fnTypeText(ITextSelection *me, BSTR text)
5638 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5640 FIXME("(%p)->(%s): stub\n", This, debugstr_w(text));
5642 if (!This->reOle)
5643 return CO_E_RELEASED;
5645 return E_NOTIMPL;
5648 static const ITextSelectionVtbl tsvt = {
5649 ITextSelection_fnQueryInterface,
5650 ITextSelection_fnAddRef,
5651 ITextSelection_fnRelease,
5652 ITextSelection_fnGetTypeInfoCount,
5653 ITextSelection_fnGetTypeInfo,
5654 ITextSelection_fnGetIDsOfNames,
5655 ITextSelection_fnInvoke,
5656 ITextSelection_fnGetText,
5657 ITextSelection_fnSetText,
5658 ITextSelection_fnGetChar,
5659 ITextSelection_fnSetChar,
5660 ITextSelection_fnGetDuplicate,
5661 ITextSelection_fnGetFormattedText,
5662 ITextSelection_fnSetFormattedText,
5663 ITextSelection_fnGetStart,
5664 ITextSelection_fnSetStart,
5665 ITextSelection_fnGetEnd,
5666 ITextSelection_fnSetEnd,
5667 ITextSelection_fnGetFont,
5668 ITextSelection_fnSetFont,
5669 ITextSelection_fnGetPara,
5670 ITextSelection_fnSetPara,
5671 ITextSelection_fnGetStoryLength,
5672 ITextSelection_fnGetStoryType,
5673 ITextSelection_fnCollapse,
5674 ITextSelection_fnExpand,
5675 ITextSelection_fnGetIndex,
5676 ITextSelection_fnSetIndex,
5677 ITextSelection_fnSetRange,
5678 ITextSelection_fnInRange,
5679 ITextSelection_fnInStory,
5680 ITextSelection_fnIsEqual,
5681 ITextSelection_fnSelect,
5682 ITextSelection_fnStartOf,
5683 ITextSelection_fnEndOf,
5684 ITextSelection_fnMove,
5685 ITextSelection_fnMoveStart,
5686 ITextSelection_fnMoveEnd,
5687 ITextSelection_fnMoveWhile,
5688 ITextSelection_fnMoveStartWhile,
5689 ITextSelection_fnMoveEndWhile,
5690 ITextSelection_fnMoveUntil,
5691 ITextSelection_fnMoveStartUntil,
5692 ITextSelection_fnMoveEndUntil,
5693 ITextSelection_fnFindText,
5694 ITextSelection_fnFindTextStart,
5695 ITextSelection_fnFindTextEnd,
5696 ITextSelection_fnDelete,
5697 ITextSelection_fnCut,
5698 ITextSelection_fnCopy,
5699 ITextSelection_fnPaste,
5700 ITextSelection_fnCanPaste,
5701 ITextSelection_fnCanEdit,
5702 ITextSelection_fnChangeCase,
5703 ITextSelection_fnGetPoint,
5704 ITextSelection_fnSetPoint,
5705 ITextSelection_fnScrollIntoView,
5706 ITextSelection_fnGetEmbeddedObject,
5707 ITextSelection_fnGetFlags,
5708 ITextSelection_fnSetFlags,
5709 ITextSelection_fnGetType,
5710 ITextSelection_fnMoveLeft,
5711 ITextSelection_fnMoveRight,
5712 ITextSelection_fnMoveUp,
5713 ITextSelection_fnMoveDown,
5714 ITextSelection_fnHomeKey,
5715 ITextSelection_fnEndKey,
5716 ITextSelection_fnTypeText
5719 static ITextSelectionImpl *
5720 CreateTextSelection(IRichEditOleImpl *reOle)
5722 ITextSelectionImpl *txtSel = heap_alloc(sizeof *txtSel);
5723 if (!txtSel)
5724 return NULL;
5726 txtSel->ITextSelection_iface.lpVtbl = &tsvt;
5727 txtSel->ref = 1;
5728 txtSel->reOle = reOle;
5729 return txtSel;
5732 LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *ppvObj)
5734 IRichEditOleImpl *reo;
5736 reo = heap_alloc(sizeof(IRichEditOleImpl));
5737 if (!reo)
5738 return 0;
5740 reo->IUnknown_inner.lpVtbl = &reo_unk_vtbl;
5741 reo->IRichEditOle_iface.lpVtbl = &revt;
5742 reo->ITextDocument2Old_iface.lpVtbl = &tdvt;
5743 reo->ref = 1;
5744 reo->editor = editor;
5745 reo->txtSel = NULL;
5747 TRACE("Created %p\n",reo);
5748 list_init(&reo->rangelist);
5749 list_init(&reo->clientsites);
5750 if (outer_unk)
5751 reo->outer_unk = outer_unk;
5752 else
5753 reo->outer_unk = &reo->IUnknown_inner;
5754 *ppvObj = &reo->IUnknown_inner;
5756 return 1;
5759 static void convert_sizel(const ME_Context *c, const SIZEL* szl, SIZE* sz)
5761 /* sizel is in .01 millimeters, sz in pixels */
5762 sz->cx = MulDiv(szl->cx, c->dpi.cx, 2540);
5763 sz->cy = MulDiv(szl->cy, c->dpi.cy, 2540);
5766 /******************************************************************************
5767 * ME_GetOLEObjectSize
5769 * Sets run extent for OLE objects.
5771 void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize)
5773 IDataObject* ido;
5774 FORMATETC fmt;
5775 STGMEDIUM stgm;
5776 DIBSECTION dibsect;
5777 ENHMETAHEADER emh;
5779 assert(run->nFlags & MERF_GRAPHICS);
5780 assert(run->reobj);
5782 if (run->reobj->obj.sizel.cx != 0 || run->reobj->obj.sizel.cy != 0)
5784 convert_sizel(c, &run->reobj->obj.sizel, pSize);
5785 if (c->editor->nZoomNumerator != 0)
5787 pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5788 pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5790 return;
5793 if (!run->reobj->obj.poleobj)
5795 pSize->cx = pSize->cy = 0;
5796 return;
5799 if (IOleObject_QueryInterface(run->reobj->obj.poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
5801 FIXME("Query Interface IID_IDataObject failed!\n");
5802 pSize->cx = pSize->cy = 0;
5803 return;
5805 fmt.cfFormat = CF_BITMAP;
5806 fmt.ptd = NULL;
5807 fmt.dwAspect = DVASPECT_CONTENT;
5808 fmt.lindex = -1;
5809 fmt.tymed = TYMED_GDI;
5810 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5812 fmt.cfFormat = CF_ENHMETAFILE;
5813 fmt.tymed = TYMED_ENHMF;
5814 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5816 FIXME("unsupported format\n");
5817 pSize->cx = pSize->cy = 0;
5818 IDataObject_Release(ido);
5819 return;
5822 IDataObject_Release(ido);
5824 switch (stgm.tymed)
5826 case TYMED_GDI:
5827 GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
5828 pSize->cx = dibsect.dsBm.bmWidth;
5829 pSize->cy = dibsect.dsBm.bmHeight;
5830 break;
5831 case TYMED_ENHMF:
5832 GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
5833 pSize->cx = emh.rclBounds.right - emh.rclBounds.left;
5834 pSize->cy = emh.rclBounds.bottom - emh.rclBounds.top;
5835 break;
5836 default:
5837 FIXME("Unsupported tymed %d\n", stgm.tymed);
5838 break;
5840 ReleaseStgMedium(&stgm);
5841 if (c->editor->nZoomNumerator != 0)
5843 pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5844 pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5848 void draw_ole( ME_Context *c, int x, int y, ME_Run *run, BOOL selected )
5850 IDataObject* ido;
5851 FORMATETC fmt;
5852 STGMEDIUM stgm;
5853 DIBSECTION dibsect;
5854 ENHMETAHEADER emh;
5855 HDC hMemDC;
5856 SIZE sz;
5857 BOOL has_size;
5858 HBITMAP old_bm;
5859 RECT rc;
5861 assert(run->nFlags & MERF_GRAPHICS);
5862 assert(run->reobj);
5863 if (IOleObject_QueryInterface(run->reobj->obj.poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
5865 FIXME("Couldn't get interface\n");
5866 return;
5868 has_size = run->reobj->obj.sizel.cx != 0 || run->reobj->obj.sizel.cy != 0;
5869 fmt.cfFormat = CF_BITMAP;
5870 fmt.ptd = NULL;
5871 fmt.dwAspect = DVASPECT_CONTENT;
5872 fmt.lindex = -1;
5873 fmt.tymed = TYMED_GDI;
5874 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5876 fmt.cfFormat = CF_ENHMETAFILE;
5877 fmt.tymed = TYMED_ENHMF;
5878 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5880 FIXME("Couldn't get storage medium\n");
5881 IDataObject_Release(ido);
5882 return;
5885 IDataObject_Release(ido);
5887 switch (stgm.tymed)
5889 case TYMED_GDI:
5890 GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
5891 hMemDC = CreateCompatibleDC(c->hDC);
5892 old_bm = SelectObject(hMemDC, stgm.u.hBitmap);
5893 if (has_size)
5895 convert_sizel(c, &run->reobj->obj.sizel, &sz);
5896 } else {
5897 sz.cx = dibsect.dsBm.bmWidth;
5898 sz.cy = dibsect.dsBm.bmHeight;
5900 if (c->editor->nZoomNumerator != 0)
5902 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5903 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5905 StretchBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy,
5906 hMemDC, 0, 0, dibsect.dsBm.bmWidth, dibsect.dsBm.bmHeight, SRCCOPY);
5908 SelectObject(hMemDC, old_bm);
5909 DeleteDC(hMemDC);
5910 break;
5911 case TYMED_ENHMF:
5912 GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
5913 if (has_size)
5915 convert_sizel(c, &run->reobj->obj.sizel, &sz);
5916 } else {
5917 sz.cx = emh.rclBounds.right - emh.rclBounds.left;
5918 sz.cy = emh.rclBounds.bottom - emh.rclBounds.top;
5920 if (c->editor->nZoomNumerator != 0)
5922 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5923 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5926 rc.left = x;
5927 rc.top = y - sz.cy;
5928 rc.right = x + sz.cx;
5929 rc.bottom = y;
5930 PlayEnhMetaFile(c->hDC, stgm.u.hEnhMetaFile, &rc);
5931 break;
5932 default:
5933 FIXME("Unsupported tymed %d\n", stgm.tymed);
5934 selected = FALSE;
5935 break;
5937 ReleaseStgMedium(&stgm);
5939 if (selected && !c->editor->bHideSelection)
5940 PatBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy, DSTINVERT);
5943 void ME_DeleteReObject(struct re_object *reobj)
5945 if (reobj->obj.poleobj) IOleObject_Release(reobj->obj.poleobj);
5946 if (reobj->obj.pstg) IStorage_Release(reobj->obj.pstg);
5947 if (reobj->obj.polesite) IOleClientSite_Release(reobj->obj.polesite);
5948 heap_free(reobj);
5951 void ME_CopyReObject(REOBJECT *dst, const REOBJECT *src, DWORD flags)
5953 *dst = *src;
5954 dst->poleobj = NULL;
5955 dst->pstg = NULL;
5956 dst->polesite = NULL;
5958 if ((flags & REO_GETOBJ_POLEOBJ) && src->poleobj)
5960 dst->poleobj = src->poleobj;
5961 IOleObject_AddRef(dst->poleobj);
5963 if ((flags & REO_GETOBJ_PSTG) && src->pstg)
5965 dst->pstg = src->pstg;
5966 IStorage_AddRef(dst->pstg);
5968 if ((flags & REO_GETOBJ_POLESITE) && src->polesite)
5970 dst->polesite = src->polesite;
5971 IOleClientSite_AddRef(dst->polesite);