user32: Load uxtheme when theming is active.
[wine.git] / dlls / riched20 / richole.c
blob03572511ff77b579927bce9f42c8c5ac6a70fc08
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 IOleClientSiteImpl IOleClientSiteImpl;
140 typedef struct ITextRangeImpl ITextRangeImpl;
142 enum textfont_prop_id {
143 FONT_ALLCAPS = 0,
144 FONT_ANIMATION,
145 FONT_BACKCOLOR,
146 FONT_BOLD,
147 FONT_EMBOSS,
148 FONT_FORECOLOR,
149 FONT_HIDDEN,
150 FONT_ENGRAVE,
151 FONT_ITALIC,
152 FONT_KERNING,
153 FONT_LANGID,
154 FONT_NAME,
155 FONT_OUTLINE,
156 FONT_POSITION,
157 FONT_PROTECTED,
158 FONT_SHADOW,
159 FONT_SIZE,
160 FONT_SMALLCAPS,
161 FONT_SPACING,
162 FONT_STRIKETHROUGH,
163 FONT_SUBSCRIPT,
164 FONT_SUPERSCRIPT,
165 FONT_UNDERLINE,
166 FONT_WEIGHT,
167 FONT_PROPID_LAST,
168 FONT_PROPID_FIRST = FONT_ALLCAPS
171 static const DWORD textfont_prop_masks[][2] = {
172 { CFM_ALLCAPS, CFE_ALLCAPS },
173 { CFM_ANIMATION },
174 { CFM_BACKCOLOR, CFE_AUTOBACKCOLOR },
175 { CFM_BOLD, CFE_BOLD },
176 { CFM_EMBOSS, CFE_EMBOSS },
177 { CFM_COLOR, CFE_AUTOCOLOR },
178 { CFM_HIDDEN, CFE_HIDDEN },
179 { CFM_IMPRINT, CFE_IMPRINT },
180 { CFM_ITALIC, CFE_ITALIC },
181 { CFM_KERNING },
182 { CFM_LCID },
183 { CFM_FACE },
184 { CFM_OUTLINE, CFE_OUTLINE },
185 { CFM_OFFSET },
186 { CFM_PROTECTED, CFE_PROTECTED },
187 { CFM_SHADOW, CFE_SHADOW },
188 { CFM_SIZE },
189 { CFM_SMALLCAPS, CFE_SMALLCAPS },
190 { CFM_SPACING },
191 { CFM_STRIKEOUT, CFE_STRIKEOUT },
192 { CFM_SUBSCRIPT, CFE_SUBSCRIPT },
193 { CFM_SUPERSCRIPT, CFE_SUPERSCRIPT },
194 { CFM_UNDERLINE, CFE_UNDERLINE },
195 { CFM_WEIGHT }
198 typedef union {
199 FLOAT f;
200 LONG l;
201 BSTR str;
202 } textfont_prop_val;
204 enum range_update_op {
205 RANGE_UPDATE_DELETE
208 struct reole_child {
209 struct list entry;
210 struct text_services *reole;
213 struct ITextRangeImpl {
214 struct reole_child child;
215 ITextRange ITextRange_iface;
216 LONG ref;
217 LONG start, end;
220 typedef struct ITextFontImpl {
221 ITextFont ITextFont_iface;
222 LONG ref;
224 ITextRange *range;
225 textfont_prop_val props[FONT_PROPID_LAST];
226 BOOL get_cache_enabled;
227 BOOL set_cache_enabled;
228 } ITextFontImpl;
230 typedef struct ITextParaImpl {
231 ITextPara ITextPara_iface;
232 LONG ref;
234 ITextRange *range;
235 } ITextParaImpl;
237 struct IOleClientSiteImpl {
238 struct reole_child child;
239 IOleClientSite IOleClientSite_iface;
240 IOleInPlaceSite IOleInPlaceSite_iface;
241 LONG ref;
244 static inline struct text_services *impl_from_IRichEditOle( IRichEditOle *iface )
246 return CONTAINING_RECORD( iface, struct text_services, IRichEditOle_iface );
249 static inline struct text_services *impl_from_ITextDocument2Old( ITextDocument2Old *iface )
251 return CONTAINING_RECORD( iface, struct text_services, ITextDocument2Old_iface );
254 static inline IOleClientSiteImpl *impl_from_IOleInPlaceSite(IOleInPlaceSite *iface)
256 return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleInPlaceSite_iface);
259 static inline ITextRangeImpl *impl_from_ITextRange(ITextRange *iface)
261 return CONTAINING_RECORD(iface, ITextRangeImpl, ITextRange_iface);
264 static inline struct text_selection *impl_from_ITextSelection(ITextSelection *iface)
266 return CONTAINING_RECORD(iface, struct text_selection, ITextSelection_iface);
269 static inline ITextFontImpl *impl_from_ITextFont(ITextFont *iface)
271 return CONTAINING_RECORD(iface, ITextFontImpl, ITextFont_iface);
274 static inline ITextParaImpl *impl_from_ITextPara(ITextPara *iface)
276 return CONTAINING_RECORD(iface, ITextParaImpl, ITextPara_iface);
279 static HRESULT create_textfont(ITextRange*, const ITextFontImpl*, ITextFont**);
280 static HRESULT create_textpara(ITextRange*, ITextPara**);
281 static struct text_selection *text_selection_create( struct text_services * );
283 static HRESULT textrange_get_storylength(ME_TextEditor *editor, LONG *length)
285 if (!length)
286 return E_INVALIDARG;
288 *length = ME_GetTextLength(editor) + 1;
289 return S_OK;
292 static void textranges_update_ranges(struct text_services *services, LONG start, LONG end, enum range_update_op op)
294 ITextRangeImpl *range;
296 LIST_FOR_EACH_ENTRY(range, &services->rangelist, ITextRangeImpl, child.entry) {
297 switch (op)
299 case RANGE_UPDATE_DELETE:
300 /* range fully covered by deleted range - collapse to insertion point */
301 if (range->start >= start && range->end <= end)
302 range->start = range->end = start;
303 /* deleted range cuts from the right */
304 else if (range->start < start && range->end <= end)
305 range->end = start;
306 /* deleted range cuts from the left */
307 else if (range->start >= start && range->end > end) {
308 range->start = start;
309 range->end -= end - start;
311 /* deleted range cuts within */
312 else
313 range->end -= end - start;
314 break;
315 default:
316 FIXME("unknown update op, %d\n", op);
321 static inline BOOL is_equal_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *left,
322 textfont_prop_val *right)
324 switch (propid)
326 case FONT_ALLCAPS:
327 case FONT_ANIMATION:
328 case FONT_BACKCOLOR:
329 case FONT_BOLD:
330 case FONT_EMBOSS:
331 case FONT_FORECOLOR:
332 case FONT_HIDDEN:
333 case FONT_ENGRAVE:
334 case FONT_ITALIC:
335 case FONT_KERNING:
336 case FONT_LANGID:
337 case FONT_OUTLINE:
338 case FONT_PROTECTED:
339 case FONT_SHADOW:
340 case FONT_SMALLCAPS:
341 case FONT_STRIKETHROUGH:
342 case FONT_SUBSCRIPT:
343 case FONT_SUPERSCRIPT:
344 case FONT_UNDERLINE:
345 case FONT_WEIGHT:
346 return left->l == right->l;
347 case FONT_NAME:
348 return !wcscmp(left->str, right->str);
349 case FONT_POSITION:
350 case FONT_SIZE:
351 case FONT_SPACING:
352 return left->f == right->f;
353 default:
354 FIXME("unhandled font property %d\n", propid);
355 return FALSE;
359 static inline void init_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *v)
361 switch (propid)
363 case FONT_ALLCAPS:
364 case FONT_ANIMATION:
365 case FONT_BACKCOLOR:
366 case FONT_BOLD:
367 case FONT_EMBOSS:
368 case FONT_FORECOLOR:
369 case FONT_HIDDEN:
370 case FONT_ENGRAVE:
371 case FONT_ITALIC:
372 case FONT_KERNING:
373 case FONT_LANGID:
374 case FONT_OUTLINE:
375 case FONT_PROTECTED:
376 case FONT_SHADOW:
377 case FONT_SMALLCAPS:
378 case FONT_STRIKETHROUGH:
379 case FONT_SUBSCRIPT:
380 case FONT_SUPERSCRIPT:
381 case FONT_UNDERLINE:
382 case FONT_WEIGHT:
383 v->l = tomUndefined;
384 return;
385 case FONT_NAME:
386 v->str = NULL;
387 return;
388 case FONT_POSITION:
389 case FONT_SIZE:
390 case FONT_SPACING:
391 v->f = tomUndefined;
392 return;
393 default:
394 FIXME("unhandled font property %d\n", propid);
395 v->l = tomUndefined;
396 return;
400 static inline FLOAT twips_to_points(LONG value)
402 return value * 72.0 / 1440;
405 static inline FLOAT points_to_twips(FLOAT value)
407 return value * 1440 / 72.0;
410 static HRESULT get_textfont_prop_for_pos(const struct text_services *services, int pos, enum textfont_prop_id propid,
411 textfont_prop_val *value)
413 ME_Cursor from, to;
414 CHARFORMAT2W fmt;
416 memset(&fmt, 0, sizeof(fmt));
417 fmt.cbSize = sizeof(fmt);
418 fmt.dwMask = textfont_prop_masks[propid][0];
420 cursor_from_char_ofs( services->editor, pos, &from );
421 to = from;
422 ME_MoveCursorChars( services->editor, &to, 1, FALSE );
423 ME_GetCharFormat( services->editor, &from, &to, &fmt );
425 switch (propid)
427 case FONT_ALLCAPS:
428 case FONT_BOLD:
429 case FONT_EMBOSS:
430 case FONT_HIDDEN:
431 case FONT_ENGRAVE:
432 case FONT_ITALIC:
433 case FONT_OUTLINE:
434 case FONT_PROTECTED:
435 case FONT_SHADOW:
436 case FONT_SMALLCAPS:
437 case FONT_STRIKETHROUGH:
438 case FONT_SUBSCRIPT:
439 case FONT_SUPERSCRIPT:
440 case FONT_UNDERLINE:
441 value->l = fmt.dwEffects & textfont_prop_masks[propid][1] ? tomTrue : tomFalse;
442 break;
443 case FONT_ANIMATION:
444 value->l = fmt.bAnimation;
445 break;
446 case FONT_BACKCOLOR:
447 value->l = fmt.dwEffects & CFE_AUTOBACKCOLOR ? GetSysColor(COLOR_WINDOW) : fmt.crBackColor;
448 break;
449 case FONT_FORECOLOR:
450 value->l = fmt.dwEffects & CFE_AUTOCOLOR ? GetSysColor(COLOR_WINDOWTEXT) : fmt.crTextColor;
451 break;
452 case FONT_KERNING:
453 value->f = twips_to_points(fmt.wKerning);
454 break;
455 case FONT_LANGID:
456 value->l = fmt.lcid;
457 break;
458 case FONT_NAME:
459 /* this case is used exclusively by GetName() */
460 value->str = SysAllocString(fmt.szFaceName);
461 if (!value->str)
462 return E_OUTOFMEMORY;
463 break;
464 case FONT_POSITION:
465 value->f = twips_to_points(fmt.yOffset);
466 break;
467 case FONT_SIZE:
468 value->f = twips_to_points(fmt.yHeight);
469 break;
470 case FONT_SPACING:
471 value->f = fmt.sSpacing;
472 break;
473 case FONT_WEIGHT:
474 value->l = fmt.wWeight;
475 break;
476 default:
477 FIXME("unhandled font property %d\n", propid);
478 return E_FAIL;
481 return S_OK;
484 static inline const struct text_services *get_range_reole(ITextRange *range)
486 struct text_services *services = NULL;
487 ITextRange_QueryInterface(range, &IID_Igetrichole, (void**)&services);
488 return services;
491 static void textrange_set_font(ITextRange *range, ITextFont *font)
493 CHARFORMAT2W fmt;
494 HRESULT hr;
495 LONG value;
496 BSTR str;
497 FLOAT f;
499 #define CHARFORMAT_SET_B_FIELD(mask, value) \
500 if (hr == S_OK && value != tomUndefined) { \
501 fmt.dwMask |= CFM_##mask; \
502 if (value == tomTrue) fmt.dwEffects |= CFE_##mask; \
505 /* fill format data from font */
506 memset(&fmt, 0, sizeof(fmt));
507 fmt.cbSize = sizeof(fmt);
509 value = tomUndefined;
510 hr = ITextFont_GetAllCaps(font, &value);
511 CHARFORMAT_SET_B_FIELD(ALLCAPS, value);
513 value = tomUndefined;
514 hr = ITextFont_GetBold(font, &value);
515 CHARFORMAT_SET_B_FIELD(BOLD, value);
517 value = tomUndefined;
518 hr = ITextFont_GetEmboss(font, &value);
519 CHARFORMAT_SET_B_FIELD(EMBOSS, value);
521 value = tomUndefined;
522 hr = ITextFont_GetHidden(font, &value);
523 CHARFORMAT_SET_B_FIELD(HIDDEN, value);
525 value = tomUndefined;
526 hr = ITextFont_GetEngrave(font, &value);
527 CHARFORMAT_SET_B_FIELD(IMPRINT, value);
529 value = tomUndefined;
530 hr = ITextFont_GetItalic(font, &value);
531 CHARFORMAT_SET_B_FIELD(ITALIC, value);
533 value = tomUndefined;
534 hr = ITextFont_GetOutline(font, &value);
535 CHARFORMAT_SET_B_FIELD(OUTLINE, value);
537 value = tomUndefined;
538 hr = ITextFont_GetProtected(font, &value);
539 CHARFORMAT_SET_B_FIELD(PROTECTED, value);
541 value = tomUndefined;
542 hr = ITextFont_GetShadow(font, &value);
543 CHARFORMAT_SET_B_FIELD(SHADOW, value);
545 value = tomUndefined;
546 hr = ITextFont_GetSmallCaps(font, &value);
547 CHARFORMAT_SET_B_FIELD(SMALLCAPS, value);
549 value = tomUndefined;
550 hr = ITextFont_GetStrikeThrough(font, &value);
551 CHARFORMAT_SET_B_FIELD(STRIKEOUT, value);
553 value = tomUndefined;
554 hr = ITextFont_GetSubscript(font, &value);
555 CHARFORMAT_SET_B_FIELD(SUBSCRIPT, value);
557 value = tomUndefined;
558 hr = ITextFont_GetSuperscript(font, &value);
559 CHARFORMAT_SET_B_FIELD(SUPERSCRIPT, value);
561 value = tomUndefined;
562 hr = ITextFont_GetUnderline(font, &value);
563 CHARFORMAT_SET_B_FIELD(UNDERLINE, value);
565 #undef CHARFORMAT_SET_B_FIELD
567 value = tomUndefined;
568 hr = ITextFont_GetAnimation(font, &value);
569 if (hr == S_OK && value != tomUndefined) {
570 fmt.dwMask |= CFM_ANIMATION;
571 fmt.bAnimation = value;
574 value = tomUndefined;
575 hr = ITextFont_GetBackColor(font, &value);
576 if (hr == S_OK && value != tomUndefined) {
577 fmt.dwMask |= CFM_BACKCOLOR;
578 if (value == tomAutoColor)
579 fmt.dwEffects |= CFE_AUTOBACKCOLOR;
580 else
581 fmt.crBackColor = value;
584 value = tomUndefined;
585 hr = ITextFont_GetForeColor(font, &value);
586 if (hr == S_OK && value != tomUndefined) {
587 fmt.dwMask |= CFM_COLOR;
588 if (value == tomAutoColor)
589 fmt.dwEffects |= CFE_AUTOCOLOR;
590 else
591 fmt.crTextColor = value;
594 value = tomUndefined;
595 hr = ITextFont_GetKerning(font, &f);
596 if (hr == S_OK && f != tomUndefined) {
597 fmt.dwMask |= CFM_KERNING;
598 fmt.wKerning = points_to_twips(f);
601 value = tomUndefined;
602 hr = ITextFont_GetLanguageID(font, &value);
603 if (hr == S_OK && value != tomUndefined) {
604 fmt.dwMask |= CFM_LCID;
605 fmt.lcid = value;
608 if (ITextFont_GetName(font, &str) == S_OK) {
609 fmt.dwMask |= CFM_FACE;
610 lstrcpynW(fmt.szFaceName, str, ARRAY_SIZE(fmt.szFaceName));
611 SysFreeString(str);
614 hr = ITextFont_GetPosition(font, &f);
615 if (hr == S_OK && f != tomUndefined) {
616 fmt.dwMask |= CFM_OFFSET;
617 fmt.yOffset = points_to_twips(f);
620 hr = ITextFont_GetSize(font, &f);
621 if (hr == S_OK && f != tomUndefined) {
622 fmt.dwMask |= CFM_SIZE;
623 fmt.yHeight = points_to_twips(f);
626 hr = ITextFont_GetSpacing(font, &f);
627 if (hr == S_OK && f != tomUndefined) {
628 fmt.dwMask |= CFM_SPACING;
629 fmt.sSpacing = f;
632 hr = ITextFont_GetWeight(font, &value);
633 if (hr == S_OK && value != tomUndefined) {
634 fmt.dwMask |= CFM_WEIGHT;
635 fmt.wWeight = value;
638 if (fmt.dwMask)
640 const struct text_services *services = get_range_reole(range);
641 ME_Cursor from, to;
642 LONG start, end;
644 ITextRange_GetStart(range, &start);
645 ITextRange_GetEnd(range, &end);
647 cursor_from_char_ofs( services->editor, start, &from );
648 cursor_from_char_ofs( services->editor, end, &to );
649 ME_SetCharFormat( services->editor, &from, &to, &fmt );
653 static HRESULT get_textfont_prop(const ITextFontImpl *font, enum textfont_prop_id propid, textfont_prop_val *value)
655 const struct text_services *services;
656 textfont_prop_val v;
657 LONG start, end, i;
658 HRESULT hr;
660 /* when font is not attached to any range use cached values */
661 if (!font->range || font->get_cache_enabled) {
662 *value = font->props[propid];
663 return S_OK;
666 if (!(services = get_range_reole(font->range)))
667 return CO_E_RELEASED;
669 init_textfont_prop_value(propid, value);
671 ITextRange_GetStart(font->range, &start);
672 ITextRange_GetEnd(font->range, &end);
674 /* iterate trough a range to see if property value is consistent */
675 hr = get_textfont_prop_for_pos( services, start, propid, &v );
676 if (FAILED(hr))
677 return hr;
679 for (i = start + 1; i < end; i++) {
680 textfont_prop_val cur;
682 hr = get_textfont_prop_for_pos( services, i, propid, &cur );
683 if (FAILED(hr))
684 return hr;
686 if (!is_equal_textfont_prop_value(propid, &v, &cur))
687 return S_OK;
690 *value = v;
691 return S_OK;
694 static HRESULT get_textfont_propf(const ITextFontImpl *font, enum textfont_prop_id propid, FLOAT *value)
696 textfont_prop_val v;
697 HRESULT hr;
699 if (!value)
700 return E_INVALIDARG;
702 hr = get_textfont_prop(font, propid, &v);
703 *value = v.f;
704 return hr;
707 static HRESULT get_textfont_propl(const ITextFontImpl *font, enum textfont_prop_id propid, LONG *value)
709 textfont_prop_val v;
710 HRESULT hr;
712 if (!value)
713 return E_INVALIDARG;
715 hr = get_textfont_prop(font, propid, &v);
716 *value = v.l;
717 return hr;
720 /* Value should already have a terminal value, for boolean properties it means tomToggle is not handled */
721 static HRESULT set_textfont_prop(ITextFontImpl *font, enum textfont_prop_id propid, const textfont_prop_val *value)
723 const struct text_services *services;
724 ME_Cursor from, to;
725 CHARFORMAT2W fmt;
726 LONG start, end;
728 /* when font is not attached to any range use cache */
729 if (!font->range || font->set_cache_enabled) {
730 if (propid == FONT_NAME) {
731 SysFreeString(font->props[propid].str);
732 font->props[propid].str = SysAllocString(value->str);
734 else
735 font->props[propid] = *value;
736 return S_OK;
739 if (!(services = get_range_reole(font->range)))
740 return CO_E_RELEASED;
742 memset(&fmt, 0, sizeof(fmt));
743 fmt.cbSize = sizeof(fmt);
744 fmt.dwMask = textfont_prop_masks[propid][0];
746 switch (propid)
748 case FONT_ALLCAPS:
749 case FONT_BOLD:
750 case FONT_EMBOSS:
751 case FONT_HIDDEN:
752 case FONT_ENGRAVE:
753 case FONT_ITALIC:
754 case FONT_OUTLINE:
755 case FONT_PROTECTED:
756 case FONT_SHADOW:
757 case FONT_SMALLCAPS:
758 case FONT_STRIKETHROUGH:
759 case FONT_SUBSCRIPT:
760 case FONT_SUPERSCRIPT:
761 case FONT_UNDERLINE:
762 fmt.dwEffects = value->l == tomTrue ? textfont_prop_masks[propid][1] : 0;
763 break;
764 case FONT_ANIMATION:
765 fmt.bAnimation = value->l;
766 break;
767 case FONT_BACKCOLOR:
768 case FONT_FORECOLOR:
769 if (value->l == tomAutoColor)
770 fmt.dwEffects = textfont_prop_masks[propid][1];
771 else if (propid == FONT_BACKCOLOR)
772 fmt.crBackColor = value->l;
773 else
774 fmt.crTextColor = value->l;
775 break;
776 case FONT_KERNING:
777 fmt.wKerning = value->f;
778 break;
779 case FONT_LANGID:
780 fmt.lcid = value->l;
781 break;
782 case FONT_POSITION:
783 fmt.yOffset = value->f;
784 break;
785 case FONT_SIZE:
786 fmt.yHeight = value->f;
787 break;
788 case FONT_SPACING:
789 fmt.sSpacing = value->f;
790 break;
791 case FONT_WEIGHT:
792 fmt.wWeight = value->l;
793 break;
794 case FONT_NAME:
795 lstrcpynW(fmt.szFaceName, value->str, ARRAY_SIZE(fmt.szFaceName));
796 break;
797 default:
798 FIXME("unhandled font property %d\n", propid);
799 return E_FAIL;
802 ITextRange_GetStart(font->range, &start);
803 ITextRange_GetEnd(font->range, &end);
805 cursor_from_char_ofs( services->editor, start, &from );
806 cursor_from_char_ofs( services->editor, end, &to );
807 ME_SetCharFormat( services->editor, &from, &to, &fmt );
809 return S_OK;
812 static inline HRESULT set_textfont_propl(ITextFontImpl *font, enum textfont_prop_id propid, LONG value)
814 textfont_prop_val v;
815 v.l = value;
816 return set_textfont_prop(font, propid, &v);
819 static inline HRESULT set_textfont_propf(ITextFontImpl *font, enum textfont_prop_id propid, FLOAT value)
821 textfont_prop_val v;
822 v.f = value;
823 return set_textfont_prop(font, propid, &v);
826 static HRESULT set_textfont_propd(ITextFontImpl *font, enum textfont_prop_id propid, LONG value)
828 textfont_prop_val v;
830 switch (value)
832 case tomUndefined:
833 return S_OK;
834 case tomToggle: {
835 LONG oldvalue;
836 get_textfont_propl(font, propid, &oldvalue);
837 if (oldvalue == tomFalse)
838 value = tomTrue;
839 else if (oldvalue == tomTrue)
840 value = tomFalse;
841 else
842 return E_INVALIDARG;
843 /* fallthrough */
845 case tomTrue:
846 case tomFalse:
847 v.l = value;
848 return set_textfont_prop(font, propid, &v);
849 default:
850 return E_INVALIDARG;
854 static HRESULT textfont_getname_from_range(ITextRange *range, BSTR *ret)
856 const struct text_services *services;
857 textfont_prop_val v;
858 HRESULT hr;
859 LONG start;
861 if (!(services = get_range_reole( range )))
862 return CO_E_RELEASED;
864 ITextRange_GetStart(range, &start);
865 hr = get_textfont_prop_for_pos( services, start, FONT_NAME, &v );
866 *ret = v.str;
867 return hr;
870 static void textfont_cache_range_props(ITextFontImpl *font)
872 enum textfont_prop_id propid;
873 for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++) {
874 if (propid == FONT_NAME)
875 textfont_getname_from_range(font->range, &font->props[propid].str);
876 else
877 get_textfont_prop(font, propid, &font->props[propid]);
881 static HRESULT textrange_expand(ITextRange *range, LONG unit, LONG *delta)
883 LONG expand_start, expand_end;
885 switch (unit)
887 case tomStory:
888 expand_start = 0;
889 ITextRange_GetStoryLength(range, &expand_end);
890 break;
891 default:
892 FIXME("unit %d is not supported\n", unit);
893 return E_NOTIMPL;
896 if (delta) {
897 LONG start, end;
899 ITextRange_GetStart(range, &start);
900 ITextRange_GetEnd(range, &end);
901 *delta = expand_end - expand_start - (end - start);
904 ITextRange_SetStart(range, expand_start);
905 ITextRange_SetEnd(range, expand_end);
907 return S_OK;
910 static HRESULT WINAPI
911 IRichEditOle_fnQueryInterface(IRichEditOle *iface, REFIID riid, LPVOID *ppvObj)
913 struct text_services *services = impl_from_IRichEditOle( iface );
914 return IUnknown_QueryInterface( services->outer_unk, riid, ppvObj );
917 static ULONG WINAPI
918 IRichEditOle_fnAddRef(IRichEditOle *iface)
920 struct text_services *services = impl_from_IRichEditOle( iface );
921 return IUnknown_AddRef( services->outer_unk );
924 static ULONG WINAPI
925 IRichEditOle_fnRelease(IRichEditOle *iface)
927 struct text_services *services = impl_from_IRichEditOle( iface );
928 return IUnknown_Release( services->outer_unk );
931 static HRESULT WINAPI
932 IRichEditOle_fnActivateAs(IRichEditOle *iface, REFCLSID rclsid, REFCLSID rclsidAs)
934 struct text_services *services = impl_from_IRichEditOle( iface );
935 FIXME( "stub %p\n", services );
936 return E_NOTIMPL;
939 static HRESULT WINAPI
940 IRichEditOle_fnContextSensitiveHelp(IRichEditOle *iface, BOOL fEnterMode)
942 struct text_services *services = impl_from_IRichEditOle( iface );
943 FIXME( "stub %p\n", services );
944 return E_NOTIMPL;
947 static HRESULT WINAPI
948 IRichEditOle_fnConvertObject( IRichEditOle *iface, LONG iob, REFCLSID class, LPCSTR user_type )
950 struct text_services *services = impl_from_IRichEditOle( iface );
951 FIXME( "stub %p\n", services );
952 return E_NOTIMPL;
955 static inline IOleClientSiteImpl *impl_from_IOleClientSite(IOleClientSite *iface)
957 return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleClientSite_iface);
960 static HRESULT WINAPI
961 IOleClientSite_fnQueryInterface(IOleClientSite *me, REFIID riid, LPVOID *ppvObj)
963 IOleClientSiteImpl *This = impl_from_IOleClientSite(me);
964 TRACE("%p %s\n", me, debugstr_guid(riid) );
966 *ppvObj = NULL;
967 if (IsEqualGUID(riid, &IID_IUnknown) ||
968 IsEqualGUID(riid, &IID_IOleClientSite))
969 *ppvObj = me;
970 else if (IsEqualGUID(riid, &IID_IOleWindow) ||
971 IsEqualGUID(riid, &IID_IOleInPlaceSite))
972 *ppvObj = &This->IOleInPlaceSite_iface;
973 if (*ppvObj)
975 IOleClientSite_AddRef(me);
976 return S_OK;
978 FIXME("%p: unhandled interface %s\n", me, debugstr_guid(riid) );
980 return E_NOINTERFACE;
983 static ULONG WINAPI IOleClientSite_fnAddRef(IOleClientSite *iface)
985 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
986 ULONG ref = InterlockedIncrement(&This->ref);
987 TRACE("(%p)->(%u)\n", This, ref);
988 return ref;
991 static ULONG WINAPI IOleClientSite_fnRelease(IOleClientSite *iface)
993 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
994 ULONG ref = InterlockedDecrement(&This->ref);
996 TRACE("(%p)->(%u)\n", This, ref);
998 if (ref == 0) {
999 if (This->child.reole) {
1000 list_remove(&This->child.entry);
1001 This->child.reole = NULL;
1003 heap_free(This);
1005 return ref;
1008 static HRESULT WINAPI IOleClientSite_fnSaveObject(IOleClientSite *iface)
1010 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1011 if (!This->child.reole)
1012 return CO_E_RELEASED;
1014 FIXME("stub %p\n", iface);
1015 return E_NOTIMPL;
1018 static HRESULT WINAPI IOleClientSite_fnGetMoniker(IOleClientSite *iface, DWORD dwAssign,
1019 DWORD dwWhichMoniker, IMoniker **ppmk)
1021 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1022 if (!This->child.reole)
1023 return CO_E_RELEASED;
1025 FIXME("stub %p\n", iface);
1026 return E_NOTIMPL;
1029 static HRESULT WINAPI IOleClientSite_fnGetContainer(IOleClientSite *iface,
1030 IOleContainer **ppContainer)
1032 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1033 if (!This->child.reole)
1034 return CO_E_RELEASED;
1036 FIXME("stub %p\n", iface);
1037 return E_NOTIMPL;
1040 static HRESULT WINAPI IOleClientSite_fnShowObject(IOleClientSite *iface)
1042 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1043 if (!This->child.reole)
1044 return CO_E_RELEASED;
1046 FIXME("stub %p\n", iface);
1047 return E_NOTIMPL;
1050 static HRESULT WINAPI IOleClientSite_fnOnShowWindow(IOleClientSite *iface, BOOL fShow)
1052 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1053 if (!This->child.reole)
1054 return CO_E_RELEASED;
1056 FIXME("stub %p\n", iface);
1057 return E_NOTIMPL;
1060 static HRESULT WINAPI IOleClientSite_fnRequestNewObjectLayout(IOleClientSite *iface)
1062 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1063 if (!This->child.reole)
1064 return CO_E_RELEASED;
1066 FIXME("stub %p\n", iface);
1067 return E_NOTIMPL;
1070 static const IOleClientSiteVtbl ocst = {
1071 IOleClientSite_fnQueryInterface,
1072 IOleClientSite_fnAddRef,
1073 IOleClientSite_fnRelease,
1074 IOleClientSite_fnSaveObject,
1075 IOleClientSite_fnGetMoniker,
1076 IOleClientSite_fnGetContainer,
1077 IOleClientSite_fnShowObject,
1078 IOleClientSite_fnOnShowWindow,
1079 IOleClientSite_fnRequestNewObjectLayout
1082 /* IOleInPlaceSite interface */
1083 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnQueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppvObj)
1085 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1086 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppvObj);
1089 static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnAddRef(IOleInPlaceSite *iface)
1091 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1092 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1095 static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnRelease(IOleInPlaceSite *iface)
1097 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1098 return IOleClientSite_Release(&This->IOleClientSite_iface);
1101 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindow( IOleInPlaceSite *iface, HWND *window )
1103 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1105 TRACE( "(%p)->(%p)\n", This, window );
1107 if (!This->child.reole)
1108 return CO_E_RELEASED;
1110 if (!window) return E_INVALIDARG;
1112 if (!This->child.reole->editor->have_texthost2) return E_NOTIMPL;
1113 return ITextHost2_TxGetWindow( This->child.reole->editor->texthost, window );
1116 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode)
1118 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1119 FIXME("not implemented: (%p)->(%d)\n", This, fEnterMode);
1120 return E_NOTIMPL;
1123 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnCanInPlaceActivate(IOleInPlaceSite *iface)
1125 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1126 FIXME("not implemented: (%p)\n", This);
1127 return E_NOTIMPL;
1130 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceActivate(IOleInPlaceSite *iface)
1132 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1133 FIXME("not implemented: (%p)\n", This);
1134 return E_NOTIMPL;
1137 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIActivate(IOleInPlaceSite *iface)
1139 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1140 FIXME("not implemented: (%p)\n", This);
1141 return E_NOTIMPL;
1144 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindowContext(IOleInPlaceSite *iface, IOleInPlaceFrame **ppFrame,
1145 IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
1146 LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
1148 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1149 FIXME("not implemented: (%p)->(%p %p %p %p %p)\n", This, ppFrame, ppDoc, lprcPosRect, lprcClipRect, lpFrameInfo);
1150 return E_NOTIMPL;
1153 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnScroll(IOleInPlaceSite *iface, SIZE scrollExtent)
1155 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1156 FIXME("not implemented: (%p)\n", This);
1157 return E_NOTIMPL;
1160 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable)
1162 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1163 FIXME("not implemented: (%p)->(%d)\n", This, fUndoable);
1164 return E_NOTIMPL;
1167 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceDeactivate(IOleInPlaceSite *iface)
1169 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1170 FIXME("not implemented: (%p)\n", This);
1171 return E_NOTIMPL;
1174 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDiscardUndoState(IOleInPlaceSite *iface)
1176 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1177 FIXME("not implemented: (%p)\n", This);
1178 return E_NOTIMPL;
1181 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDeactivateAndUndo(IOleInPlaceSite *iface)
1183 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1184 FIXME("not implemented: (%p)\n", This);
1185 return E_NOTIMPL;
1188 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect)
1190 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1191 FIXME("not implemented: (%p)->(%p)\n", This, lprcPosRect);
1192 return E_NOTIMPL;
1195 static const IOleInPlaceSiteVtbl olestvt =
1197 IOleInPlaceSite_fnQueryInterface,
1198 IOleInPlaceSite_fnAddRef,
1199 IOleInPlaceSite_fnRelease,
1200 IOleInPlaceSite_fnGetWindow,
1201 IOleInPlaceSite_fnContextSensitiveHelp,
1202 IOleInPlaceSite_fnCanInPlaceActivate,
1203 IOleInPlaceSite_fnOnInPlaceActivate,
1204 IOleInPlaceSite_fnOnUIActivate,
1205 IOleInPlaceSite_fnGetWindowContext,
1206 IOleInPlaceSite_fnScroll,
1207 IOleInPlaceSite_fnOnUIDeactivate,
1208 IOleInPlaceSite_fnOnInPlaceDeactivate,
1209 IOleInPlaceSite_fnDiscardUndoState,
1210 IOleInPlaceSite_fnDeactivateAndUndo,
1211 IOleInPlaceSite_fnOnPosRectChange
1214 static HRESULT CreateOleClientSite( struct text_services *services, IOleClientSite **ret )
1216 IOleClientSiteImpl *clientSite = heap_alloc(sizeof *clientSite);
1218 if (!clientSite)
1219 return E_OUTOFMEMORY;
1221 clientSite->IOleClientSite_iface.lpVtbl = &ocst;
1222 clientSite->IOleInPlaceSite_iface.lpVtbl = &olestvt;
1223 clientSite->ref = 1;
1224 clientSite->child.reole = services;
1225 list_add_head( &services->clientsites, &clientSite->child.entry );
1227 *ret = &clientSite->IOleClientSite_iface;
1228 return S_OK;
1231 static HRESULT WINAPI
1232 IRichEditOle_fnGetClientSite( IRichEditOle *iface, IOleClientSite **clientsite )
1234 struct text_services *services = impl_from_IRichEditOle( iface );
1236 TRACE("(%p)->(%p)\n", services, clientsite);
1238 if (!clientsite)
1239 return E_INVALIDARG;
1241 return CreateOleClientSite( services, clientsite );
1244 static HRESULT WINAPI
1245 IRichEditOle_fnGetClipboardData(IRichEditOle *iface, CHARRANGE *lpchrg,
1246 DWORD reco, LPDATAOBJECT *lplpdataobj)
1248 struct text_services *services = impl_from_IRichEditOle( iface );
1249 ME_Cursor start;
1250 int nChars;
1252 TRACE("(%p,%p,%d)\n", services, lpchrg, reco);
1253 if(!lplpdataobj)
1254 return E_INVALIDARG;
1255 if(!lpchrg)
1257 int nFrom, nTo, nStartCur = ME_GetSelectionOfs( services->editor, &nFrom, &nTo );
1258 start = services->editor->pCursors[nStartCur];
1259 nChars = nTo - nFrom;
1261 else
1263 cursor_from_char_ofs( services->editor, lpchrg->cpMin, &start );
1264 nChars = lpchrg->cpMax - lpchrg->cpMin;
1266 return ME_GetDataObject( services->editor, &start, nChars, lplpdataobj );
1269 static LONG WINAPI IRichEditOle_fnGetLinkCount(IRichEditOle *iface)
1271 struct text_services *services = impl_from_IRichEditOle( iface );
1272 FIXME("stub %p\n", services);
1273 return E_NOTIMPL;
1276 static HRESULT WINAPI
1277 IRichEditOle_fnGetObject(IRichEditOle *iface, LONG iob,
1278 REOBJECT *lpreobject, DWORD dwFlags)
1280 struct text_services *services = impl_from_IRichEditOle( iface );
1281 struct re_object *reobj = NULL;
1282 LONG count = 0;
1284 TRACE("(%p)->(%x, %p, %x)\n", services, iob, lpreobject, dwFlags);
1286 if (!lpreobject || !lpreobject->cbStruct)
1287 return E_INVALIDARG;
1289 if (iob == REO_IOB_USE_CP)
1291 ME_Cursor cursor;
1293 TRACE("character offset: %d\n", lpreobject->cp);
1294 cursor_from_char_ofs( services->editor, lpreobject->cp, &cursor );
1295 if (!cursor.run->reobj)
1296 return E_INVALIDARG;
1297 else
1298 reobj = cursor.run->reobj;
1300 else if (iob == REO_IOB_SELECTION)
1302 ME_Cursor *from, *to;
1304 ME_GetSelection(services->editor, &from, &to);
1305 if (!from->run->reobj)
1306 return E_INVALIDARG;
1307 else
1308 reobj = from->run->reobj;
1310 else
1312 if (iob < 0 || iob >= IRichEditOle_GetObjectCount( iface ))
1313 return E_INVALIDARG;
1314 LIST_FOR_EACH_ENTRY(reobj, &services->editor->reobj_list, struct re_object, entry)
1316 if (count == iob)
1317 break;
1318 count++;
1321 ME_CopyReObject(lpreobject, &reobj->obj, dwFlags);
1322 return S_OK;
1325 static LONG WINAPI
1326 IRichEditOle_fnGetObjectCount( IRichEditOle *iface )
1328 struct text_services *services = impl_from_IRichEditOle( iface );
1329 TRACE("(%p)\n", services);
1330 return list_count( &services->editor->reobj_list );
1333 static HRESULT WINAPI
1334 IRichEditOle_fnHandsOffStorage(IRichEditOle *iface, LONG iob)
1336 struct text_services *services = impl_from_IRichEditOle( iface );
1337 FIXME("stub %p\n", services);
1338 return E_NOTIMPL;
1341 static HRESULT WINAPI
1342 IRichEditOle_fnImportDataObject(IRichEditOle *iface, LPDATAOBJECT lpdataobj,
1343 CLIPFORMAT cf, HGLOBAL hMetaPict)
1345 struct text_services *services = impl_from_IRichEditOle( iface );
1346 FIXME("stub %p\n", services);
1347 return E_NOTIMPL;
1350 static HRESULT WINAPI
1351 IRichEditOle_fnInPlaceDeactivate(IRichEditOle *iface)
1353 struct text_services *services = impl_from_IRichEditOle( iface );
1354 FIXME("stub %p\n", services);
1355 return E_NOTIMPL;
1358 static HRESULT WINAPI
1359 IRichEditOle_fnInsertObject(IRichEditOle *iface, REOBJECT *reo)
1361 struct text_services *services = impl_from_IRichEditOle( iface );
1363 TRACE("(%p,%p)\n", services, reo);
1365 if (!reo)
1366 return E_INVALIDARG;
1368 if (reo->cbStruct < sizeof(*reo)) return STG_E_INVALIDPARAMETER;
1370 editor_insert_oleobj(services->editor, reo);
1371 ME_CommitUndo(services->editor);
1372 ME_UpdateRepaint(services->editor, FALSE);
1373 return S_OK;
1376 static HRESULT WINAPI IRichEditOle_fnSaveCompleted(IRichEditOle *iface, LONG iob,
1377 LPSTORAGE lpstg)
1379 struct text_services *services = impl_from_IRichEditOle( iface );
1380 FIXME("stub %p\n", services);
1381 return E_NOTIMPL;
1384 static HRESULT WINAPI
1385 IRichEditOle_fnSetDvaspect(IRichEditOle *iface, LONG iob, DWORD dvaspect)
1387 struct text_services *services = impl_from_IRichEditOle( iface );
1388 FIXME("stub %p\n", services);
1389 return E_NOTIMPL;
1392 static HRESULT WINAPI IRichEditOle_fnSetHostNames(IRichEditOle *iface,
1393 LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj)
1395 struct text_services *services = impl_from_IRichEditOle( iface );
1396 FIXME("stub %p %s %s\n", services, lpstrContainerApp, lpstrContainerObj);
1397 return E_NOTIMPL;
1400 static HRESULT WINAPI
1401 IRichEditOle_fnSetLinkAvailable(IRichEditOle *iface, LONG iob, BOOL fAvailable)
1403 struct text_services *services = impl_from_IRichEditOle( iface );
1404 FIXME("stub %p\n", services);
1405 return E_NOTIMPL;
1408 const IRichEditOleVtbl re_ole_vtbl =
1410 IRichEditOle_fnQueryInterface,
1411 IRichEditOle_fnAddRef,
1412 IRichEditOle_fnRelease,
1413 IRichEditOle_fnGetClientSite,
1414 IRichEditOle_fnGetObjectCount,
1415 IRichEditOle_fnGetLinkCount,
1416 IRichEditOle_fnGetObject,
1417 IRichEditOle_fnInsertObject,
1418 IRichEditOle_fnConvertObject,
1419 IRichEditOle_fnActivateAs,
1420 IRichEditOle_fnSetHostNames,
1421 IRichEditOle_fnSetLinkAvailable,
1422 IRichEditOle_fnSetDvaspect,
1423 IRichEditOle_fnHandsOffStorage,
1424 IRichEditOle_fnSaveCompleted,
1425 IRichEditOle_fnInPlaceDeactivate,
1426 IRichEditOle_fnContextSensitiveHelp,
1427 IRichEditOle_fnGetClipboardData,
1428 IRichEditOle_fnImportDataObject
1431 /* ITextRange interface */
1432 static HRESULT WINAPI ITextRange_fnQueryInterface(ITextRange *me, REFIID riid, void **ppvObj)
1434 ITextRangeImpl *This = impl_from_ITextRange(me);
1436 *ppvObj = NULL;
1437 if (IsEqualGUID(riid, &IID_IUnknown)
1438 || IsEqualGUID(riid, &IID_IDispatch)
1439 || IsEqualGUID(riid, &IID_ITextRange))
1441 *ppvObj = me;
1442 ITextRange_AddRef(me);
1443 return S_OK;
1445 else if (IsEqualGUID(riid, &IID_Igetrichole))
1447 *ppvObj = This->child.reole;
1448 return S_OK;
1451 return E_NOINTERFACE;
1454 static ULONG WINAPI ITextRange_fnAddRef(ITextRange *me)
1456 ITextRangeImpl *This = impl_from_ITextRange(me);
1457 return InterlockedIncrement(&This->ref);
1460 static ULONG WINAPI ITextRange_fnRelease(ITextRange *me)
1462 ITextRangeImpl *This = impl_from_ITextRange(me);
1463 ULONG ref = InterlockedDecrement(&This->ref);
1465 TRACE ("%p ref=%u\n", This, ref);
1466 if (ref == 0)
1468 if (This->child.reole)
1470 list_remove(&This->child.entry);
1471 This->child.reole = NULL;
1473 heap_free(This);
1475 return ref;
1478 static HRESULT WINAPI ITextRange_fnGetTypeInfoCount(ITextRange *me, UINT *pctinfo)
1480 ITextRangeImpl *This = impl_from_ITextRange(me);
1481 TRACE("(%p)->(%p)\n", This, pctinfo);
1482 *pctinfo = 1;
1483 return S_OK;
1486 static HRESULT WINAPI ITextRange_fnGetTypeInfo(ITextRange *me, UINT iTInfo, LCID lcid,
1487 ITypeInfo **ppTInfo)
1489 ITextRangeImpl *This = impl_from_ITextRange(me);
1490 HRESULT hr;
1492 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
1494 hr = get_typeinfo(ITextRange_tid, ppTInfo);
1495 if (SUCCEEDED(hr))
1496 ITypeInfo_AddRef(*ppTInfo);
1497 return hr;
1500 static HRESULT WINAPI ITextRange_fnGetIDsOfNames(ITextRange *me, REFIID riid, LPOLESTR *rgszNames,
1501 UINT cNames, LCID lcid, DISPID *rgDispId)
1503 ITextRangeImpl *This = impl_from_ITextRange(me);
1504 ITypeInfo *ti;
1505 HRESULT hr;
1507 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
1508 rgDispId);
1510 hr = get_typeinfo(ITextRange_tid, &ti);
1511 if (SUCCEEDED(hr))
1512 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
1513 return hr;
1516 static HRESULT WINAPI ITextRange_fnInvoke(ITextRange *me, DISPID dispIdMember, REFIID riid,
1517 LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1518 VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
1519 UINT *puArgErr)
1521 ITextRangeImpl *This = impl_from_ITextRange(me);
1522 ITypeInfo *ti;
1523 HRESULT hr;
1525 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
1526 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1528 hr = get_typeinfo(ITextRange_tid, &ti);
1529 if (SUCCEEDED(hr))
1530 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1531 return hr;
1534 static HRESULT WINAPI ITextRange_fnGetText(ITextRange *me, BSTR *str)
1536 ITextRangeImpl *This = impl_from_ITextRange(me);
1537 ME_TextEditor *editor;
1538 ME_Cursor start, end;
1539 int length;
1540 BOOL bEOP;
1542 TRACE("(%p)->(%p)\n", This, str);
1544 if (!This->child.reole)
1545 return CO_E_RELEASED;
1547 if (!str)
1548 return E_INVALIDARG;
1550 /* return early for degenerate range */
1551 if (This->start == This->end) {
1552 *str = NULL;
1553 return S_OK;
1556 editor = This->child.reole->editor;
1557 cursor_from_char_ofs( editor, This->start, &start );
1558 cursor_from_char_ofs( editor, This->end, &end );
1560 length = This->end - This->start;
1561 *str = SysAllocStringLen(NULL, length);
1562 if (!*str)
1563 return E_OUTOFMEMORY;
1565 bEOP = (!para_next( para_next( end.para )) && This->end > ME_GetTextLength(editor));
1566 ME_GetTextW(editor, *str, length, &start, length, FALSE, bEOP);
1567 return S_OK;
1570 static HRESULT WINAPI ITextRange_fnSetText(ITextRange *me, BSTR str)
1572 ITextRangeImpl *This = impl_from_ITextRange(me);
1573 ME_TextEditor *editor;
1574 ME_Cursor cursor;
1575 ME_Style *style;
1576 int len;
1578 TRACE("(%p)->(%s)\n", This, debugstr_w(str));
1580 if (!This->child.reole)
1581 return CO_E_RELEASED;
1583 editor = This->child.reole->editor;
1585 /* delete only where's something to delete */
1586 if (This->start != This->end)
1588 cursor_from_char_ofs( editor, This->start, &cursor );
1589 ME_InternalDeleteText(editor, &cursor, This->end - This->start, FALSE);
1592 if (!str || !*str)
1594 /* will update this range as well */
1595 textranges_update_ranges(This->child.reole, This->start, This->end, RANGE_UPDATE_DELETE);
1596 return S_OK;
1599 /* it's safer not to rely on stored BSTR length */
1600 len = lstrlenW(str);
1601 cursor = editor->pCursors[0];
1602 cursor_from_char_ofs( editor, This->start, &editor->pCursors[0] );
1603 style = style_get_insert_style( editor, editor->pCursors );
1604 ME_InsertTextFromCursor(editor, 0, str, len, style);
1605 ME_ReleaseStyle(style);
1606 editor->pCursors[0] = cursor;
1608 if (len < This->end - This->start)
1609 textranges_update_ranges(This->child.reole, This->start + len, This->end, RANGE_UPDATE_DELETE);
1610 else
1611 This->end = len - This->start;
1613 return S_OK;
1616 static HRESULT range_GetChar(ME_TextEditor *editor, ME_Cursor *cursor, LONG *pch)
1618 WCHAR wch[2];
1620 ME_GetTextW(editor, wch, 1, cursor, 1, FALSE, !para_next( para_next( cursor->para ) ));
1621 *pch = wch[0];
1623 return S_OK;
1626 static HRESULT WINAPI ITextRange_fnGetChar(ITextRange *me, LONG *pch)
1628 ITextRangeImpl *This = impl_from_ITextRange(me);
1629 ME_TextEditor *editor;
1630 ME_Cursor cursor;
1632 TRACE("(%p)->(%p)\n", This, pch);
1634 if (!This->child.reole)
1635 return CO_E_RELEASED;
1637 if (!pch)
1638 return E_INVALIDARG;
1640 editor = This->child.reole->editor;
1641 cursor_from_char_ofs( editor, This->start, &cursor );
1642 return range_GetChar(editor, &cursor, pch);
1645 static HRESULT WINAPI ITextRange_fnSetChar(ITextRange *me, LONG ch)
1647 ITextRangeImpl *This = impl_from_ITextRange(me);
1649 FIXME("(%p)->(%x): stub\n", This, ch);
1651 if (!This->child.reole)
1652 return CO_E_RELEASED;
1654 return E_NOTIMPL;
1657 static HRESULT CreateITextRange(struct text_services *services, LONG start, LONG end, ITextRange** ppRange);
1659 static HRESULT WINAPI ITextRange_fnGetDuplicate(ITextRange *me, ITextRange **ppRange)
1661 ITextRangeImpl *This = impl_from_ITextRange(me);
1663 TRACE("(%p)->(%p)\n", This, ppRange);
1665 if (!This->child.reole)
1666 return CO_E_RELEASED;
1668 if (!ppRange)
1669 return E_INVALIDARG;
1671 return CreateITextRange(This->child.reole, This->start, This->end, ppRange);
1674 static HRESULT WINAPI ITextRange_fnGetFormattedText(ITextRange *me, ITextRange **range)
1676 ITextRangeImpl *This = impl_from_ITextRange(me);
1678 FIXME("(%p)->(%p): stub\n", This, range);
1680 if (!This->child.reole)
1681 return CO_E_RELEASED;
1683 return E_NOTIMPL;
1686 static HRESULT WINAPI ITextRange_fnSetFormattedText(ITextRange *me, ITextRange *range)
1688 ITextRangeImpl *This = impl_from_ITextRange(me);
1690 FIXME("(%p)->(%p): stub\n", This, range);
1692 if (!This->child.reole)
1693 return CO_E_RELEASED;
1695 return E_NOTIMPL;
1698 static HRESULT WINAPI ITextRange_fnGetStart(ITextRange *me, LONG *start)
1700 ITextRangeImpl *This = impl_from_ITextRange(me);
1702 TRACE("(%p)->(%p)\n", This, start);
1704 if (!This->child.reole)
1705 return CO_E_RELEASED;
1707 if (!start)
1708 return E_INVALIDARG;
1710 *start = This->start;
1711 return S_OK;
1714 static HRESULT textrange_setstart(const struct text_services *services, LONG value, LONG *start, LONG *end)
1716 int len;
1718 if (value < 0)
1719 value = 0;
1721 if (value == *start)
1722 return S_FALSE;
1724 if (value <= *end) {
1725 *start = value;
1726 return S_OK;
1729 len = ME_GetTextLength(services->editor);
1730 *start = *end = value > len ? len : value;
1731 return S_OK;
1734 static HRESULT WINAPI ITextRange_fnSetStart(ITextRange *me, LONG value)
1736 ITextRangeImpl *This = impl_from_ITextRange(me);
1738 TRACE("(%p)->(%d)\n", This, value);
1740 if (!This->child.reole)
1741 return CO_E_RELEASED;
1743 return textrange_setstart(This->child.reole, value, &This->start, &This->end);
1746 static HRESULT WINAPI ITextRange_fnGetEnd(ITextRange *me, LONG *end)
1748 ITextRangeImpl *This = impl_from_ITextRange(me);
1750 TRACE("(%p)->(%p)\n", This, end);
1752 if (!This->child.reole)
1753 return CO_E_RELEASED;
1755 if (!end)
1756 return E_INVALIDARG;
1758 *end = This->end;
1759 return S_OK;
1762 static HRESULT textrange_setend(const struct text_services *services, LONG value, LONG *start, LONG *end)
1764 int len;
1766 if (value == *end)
1767 return S_FALSE;
1769 if (value < *start) {
1770 *start = *end = max(0, value);
1771 return S_OK;
1774 len = ME_GetTextLength( services->editor );
1775 *end = value > len ? len + 1 : value;
1776 return S_OK;
1779 static HRESULT WINAPI ITextRange_fnSetEnd(ITextRange *me, LONG value)
1781 ITextRangeImpl *This = impl_from_ITextRange(me);
1783 TRACE("(%p)->(%d)\n", This, value);
1785 if (!This->child.reole)
1786 return CO_E_RELEASED;
1788 return textrange_setend(This->child.reole, value, &This->start, &This->end);
1791 static HRESULT WINAPI ITextRange_fnGetFont(ITextRange *me, ITextFont **font)
1793 ITextRangeImpl *This = impl_from_ITextRange(me);
1795 TRACE("(%p)->(%p)\n", This, font);
1797 if (!This->child.reole)
1798 return CO_E_RELEASED;
1800 if (!font)
1801 return E_INVALIDARG;
1803 return create_textfont(me, NULL, font);
1806 static HRESULT WINAPI ITextRange_fnSetFont(ITextRange *me, ITextFont *font)
1808 ITextRangeImpl *This = impl_from_ITextRange(me);
1810 TRACE("(%p)->(%p)\n", This, font);
1812 if (!font)
1813 return E_INVALIDARG;
1815 if (!This->child.reole)
1816 return CO_E_RELEASED;
1818 textrange_set_font(me, font);
1819 return S_OK;
1822 static HRESULT WINAPI ITextRange_fnGetPara(ITextRange *me, ITextPara **para)
1824 ITextRangeImpl *This = impl_from_ITextRange(me);
1826 TRACE("(%p)->(%p)\n", This, para);
1828 if (!This->child.reole)
1829 return CO_E_RELEASED;
1831 if (!para)
1832 return E_INVALIDARG;
1834 return create_textpara(me, para);
1837 static HRESULT WINAPI ITextRange_fnSetPara(ITextRange *me, ITextPara *para)
1839 ITextRangeImpl *This = impl_from_ITextRange(me);
1841 FIXME("(%p)->(%p): stub\n", This, para);
1843 if (!This->child.reole)
1844 return CO_E_RELEASED;
1846 return E_NOTIMPL;
1849 static HRESULT WINAPI ITextRange_fnGetStoryLength(ITextRange *me, LONG *length)
1851 ITextRangeImpl *This = impl_from_ITextRange(me);
1853 TRACE("(%p)->(%p)\n", This, length);
1855 if (!This->child.reole)
1856 return CO_E_RELEASED;
1858 return textrange_get_storylength(This->child.reole->editor, length);
1861 static HRESULT WINAPI ITextRange_fnGetStoryType(ITextRange *me, LONG *value)
1863 ITextRangeImpl *This = impl_from_ITextRange(me);
1865 TRACE("(%p)->(%p)\n", This, value);
1867 if (!This->child.reole)
1868 return CO_E_RELEASED;
1870 if (!value)
1871 return E_INVALIDARG;
1873 *value = tomUnknownStory;
1874 return S_OK;
1877 static HRESULT range_Collapse(LONG bStart, LONG *start, LONG *end)
1879 if (*end == *start)
1880 return S_FALSE;
1882 if (bStart == tomEnd)
1883 *start = *end;
1884 else
1885 *end = *start;
1886 return S_OK;
1889 static HRESULT WINAPI ITextRange_fnCollapse(ITextRange *me, LONG bStart)
1891 ITextRangeImpl *This = impl_from_ITextRange(me);
1893 TRACE("(%p)->(%d)\n", This, bStart);
1895 if (!This->child.reole)
1896 return CO_E_RELEASED;
1898 return range_Collapse(bStart, &This->start, &This->end);
1901 static HRESULT WINAPI ITextRange_fnExpand(ITextRange *me, LONG unit, LONG *delta)
1903 ITextRangeImpl *This = impl_from_ITextRange(me);
1905 TRACE("(%p)->(%d %p)\n", This, unit, delta);
1907 if (!This->child.reole)
1908 return CO_E_RELEASED;
1910 return textrange_expand(me, unit, delta);
1913 static HRESULT WINAPI ITextRange_fnGetIndex(ITextRange *me, LONG unit, LONG *index)
1915 ITextRangeImpl *This = impl_from_ITextRange(me);
1917 FIXME("(%p)->(%d %p): stub\n", This, unit, index);
1919 if (!This->child.reole)
1920 return CO_E_RELEASED;
1922 return E_NOTIMPL;
1925 static HRESULT WINAPI ITextRange_fnSetIndex(ITextRange *me, LONG unit, LONG index,
1926 LONG extend)
1928 ITextRangeImpl *This = impl_from_ITextRange(me);
1930 FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend);
1932 if (!This->child.reole)
1933 return CO_E_RELEASED;
1935 return E_NOTIMPL;
1938 static void cp2range(ME_TextEditor *editor, LONG *cp1, LONG *cp2)
1940 int len = ME_GetTextLength(editor) + 1;
1942 *cp1 = max(*cp1, 0);
1943 *cp2 = max(*cp2, 0);
1944 *cp1 = min(*cp1, len);
1945 *cp2 = min(*cp2, len);
1946 if (*cp1 > *cp2)
1948 int tmp = *cp1;
1949 *cp1 = *cp2;
1950 *cp2 = tmp;
1952 if (*cp1 == len)
1953 *cp1 = *cp2 = len - 1;
1956 static HRESULT WINAPI ITextRange_fnSetRange(ITextRange *me, LONG anchor, LONG active)
1958 ITextRangeImpl *This = impl_from_ITextRange(me);
1960 TRACE("(%p)->(%d %d)\n", This, anchor, active);
1962 if (!This->child.reole)
1963 return CO_E_RELEASED;
1965 cp2range(This->child.reole->editor, &anchor, &active);
1966 if (anchor == This->start && active == This->end)
1967 return S_FALSE;
1969 This->start = anchor;
1970 This->end = active;
1971 return S_OK;
1974 static HRESULT textrange_inrange(LONG start, LONG end, ITextRange *range, LONG *ret)
1976 LONG from, to, v;
1978 if (!ret)
1979 ret = &v;
1981 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
1982 *ret = tomFalse;
1984 else
1985 *ret = (start >= from && end <= to) ? tomTrue : tomFalse;
1986 return *ret == tomTrue ? S_OK : S_FALSE;
1989 static HRESULT WINAPI ITextRange_fnInRange(ITextRange *me, ITextRange *range, LONG *ret)
1991 ITextRangeImpl *This = impl_from_ITextRange(me);
1993 TRACE("(%p)->(%p %p)\n", This, range, ret);
1995 if (ret)
1996 *ret = tomFalse;
1998 if (!This->child.reole)
1999 return CO_E_RELEASED;
2001 if (!range)
2002 return S_FALSE;
2004 return textrange_inrange(This->start, This->end, range, ret);
2007 static HRESULT WINAPI ITextRange_fnInStory(ITextRange *me, ITextRange *pRange, LONG *ret)
2009 ITextRangeImpl *This = impl_from_ITextRange(me);
2011 FIXME("(%p)->(%p): stub\n", This, ret);
2013 if (!This->child.reole)
2014 return CO_E_RELEASED;
2016 return E_NOTIMPL;
2019 static HRESULT textrange_isequal(LONG start, LONG end, ITextRange *range, LONG *ret)
2021 LONG from, to, v;
2023 if (!ret)
2024 ret = &v;
2026 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
2027 *ret = tomFalse;
2029 else
2030 *ret = (start == from && end == to) ? tomTrue : tomFalse;
2031 return *ret == tomTrue ? S_OK : S_FALSE;
2034 static HRESULT WINAPI ITextRange_fnIsEqual(ITextRange *me, ITextRange *range, LONG *ret)
2036 ITextRangeImpl *This = impl_from_ITextRange(me);
2038 TRACE("(%p)->(%p %p)\n", This, range, ret);
2040 if (ret)
2041 *ret = tomFalse;
2043 if (!This->child.reole)
2044 return CO_E_RELEASED;
2046 if (!range)
2047 return S_FALSE;
2049 return textrange_isequal(This->start, This->end, range, ret);
2052 static HRESULT WINAPI ITextRange_fnSelect(ITextRange *me)
2054 ITextRangeImpl *This = impl_from_ITextRange(me);
2056 TRACE("(%p)\n", This);
2058 if (!This->child.reole)
2059 return CO_E_RELEASED;
2061 set_selection(This->child.reole->editor, This->start, This->end);
2062 return S_OK;
2065 static HRESULT textrange_startof(ITextRange *range, LONG unit, LONG extend, LONG *delta)
2067 HRESULT hr;
2068 LONG start, end;
2069 LONG moved;
2071 ITextRange_GetStart(range, &start);
2072 ITextRange_GetEnd(range, &end);
2074 switch (unit)
2076 case tomCharacter:
2078 moved = 0;
2079 if (extend == tomMove) {
2080 if (start != end) {
2081 ITextRange_SetEnd(range, start);
2082 moved = -1;
2085 if (delta)
2086 *delta = moved;
2087 hr = moved ? S_OK : S_FALSE;
2088 break;
2090 default:
2091 FIXME("unit %d is not supported\n", unit);
2092 return E_NOTIMPL;
2094 return hr;
2097 static HRESULT WINAPI ITextRange_fnStartOf(ITextRange *me, LONG unit, LONG extend,
2098 LONG *delta)
2100 ITextRangeImpl *This = impl_from_ITextRange(me);
2102 TRACE("(%p)->(%d %d %p)\n", This, unit, extend, delta);
2104 if (!This->child.reole)
2105 return CO_E_RELEASED;
2107 return textrange_startof(me, unit, extend, delta);
2110 static HRESULT textrange_endof(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG extend, LONG *delta)
2112 HRESULT hr;
2113 LONG old_start, old_end, new_end;
2114 LONG moved;
2116 ITextRange_GetStart(range, &old_start);
2117 ITextRange_GetEnd(range, &old_end);
2119 switch (unit)
2121 case tomCharacter:
2123 moved = 0;
2124 new_end = old_end;
2125 if (old_end == 0)
2127 ME_Cursor cursor;
2128 cursor_from_char_ofs( editor, old_end, &cursor );
2129 moved = ME_MoveCursorChars(editor, &cursor, 1, TRUE);
2130 new_end = old_end + moved;
2132 else if (extend == tomMove && old_start != old_end)
2133 moved = 1;
2135 ITextRange_SetEnd(range, new_end);
2136 if (extend == tomMove)
2137 ITextRange_SetStart(range, new_end);
2138 if (delta)
2139 *delta = moved;
2140 hr = moved ? S_OK : S_FALSE;
2141 break;
2143 default:
2144 FIXME("unit %d is not supported\n", unit);
2145 return E_NOTIMPL;
2147 return hr;
2150 static HRESULT WINAPI ITextRange_fnEndOf(ITextRange *me, LONG unit, LONG extend,
2151 LONG *delta)
2153 ITextRangeImpl *This = impl_from_ITextRange(me);
2155 TRACE("(%p)->(%d %d %p)\n", This, unit, extend, delta);
2157 if (!This->child.reole)
2158 return CO_E_RELEASED;
2160 return textrange_endof(me, This->child.reole->editor, unit, extend, delta);
2163 static HRESULT textrange_move(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG count, LONG *delta)
2165 LONG old_start, old_end, new_start, new_end;
2166 LONG move_by;
2167 LONG moved;
2168 HRESULT hr = S_OK;
2170 if (!count)
2172 if (delta)
2173 *delta = 0;
2174 return S_FALSE;
2177 ITextRange_GetStart(range, &old_start);
2178 ITextRange_GetEnd(range, &old_end);
2179 switch (unit)
2181 case tomCharacter:
2183 ME_Cursor cursor;
2185 if (count > 0)
2187 cursor_from_char_ofs( editor, old_end, &cursor );
2188 move_by = count;
2189 if (old_start != old_end)
2190 --move_by;
2192 else
2194 cursor_from_char_ofs( editor, old_start, &cursor );
2195 move_by = count;
2196 if (old_start != old_end)
2197 ++move_by;
2199 moved = ME_MoveCursorChars(editor, &cursor, move_by, FALSE);
2200 if (count > 0)
2202 new_end = old_end + moved;
2203 new_start = new_end;
2204 if (old_start != old_end)
2205 ++moved;
2207 else
2209 new_start = old_start + moved;
2210 new_end = new_start;
2211 if (old_start != old_end)
2212 --moved;
2214 if (delta) *delta = moved;
2215 break;
2217 default:
2218 FIXME("unit %d is not supported\n", unit);
2219 return E_NOTIMPL;
2221 if (moved == 0)
2222 hr = S_FALSE;
2223 ITextRange_SetStart(range, new_start);
2224 ITextRange_SetEnd(range, new_end);
2226 return hr;
2229 static HRESULT WINAPI ITextRange_fnMove(ITextRange *me, LONG unit, LONG count, LONG *delta)
2231 ITextRangeImpl *This = impl_from_ITextRange(me);
2233 TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta);
2235 if (!This->child.reole)
2236 return CO_E_RELEASED;
2238 return textrange_move(me, This->child.reole->editor, unit, count, delta);
2241 static HRESULT textrange_movestart(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG count, LONG *delta)
2243 LONG old_start, old_end, new_start, new_end;
2244 HRESULT hr = S_OK;
2246 if (!count)
2248 if (delta)
2249 *delta = 0;
2250 return S_FALSE;
2253 ITextRange_GetStart(range, &old_start);
2254 ITextRange_GetEnd(range, &old_end);
2255 switch (unit)
2257 case tomCharacter:
2259 ME_Cursor cursor;
2260 LONG moved;
2262 cursor_from_char_ofs( editor, old_start, &cursor );
2263 moved = ME_MoveCursorChars(editor, &cursor, count, FALSE);
2264 new_start = old_start + moved;
2265 new_end = old_end;
2266 if (new_end < new_start)
2267 new_end = new_start;
2268 if (delta)
2269 *delta = moved;
2270 break;
2272 default:
2273 FIXME("unit %d is not supported\n", unit);
2274 return E_NOTIMPL;
2276 if (new_start == old_start)
2277 hr = S_FALSE;
2278 ITextRange_SetStart(range, new_start);
2279 ITextRange_SetEnd(range, new_end);
2281 return hr;
2284 static HRESULT WINAPI ITextRange_fnMoveStart(ITextRange *me, LONG unit, LONG count,
2285 LONG *delta)
2287 ITextRangeImpl *This = impl_from_ITextRange(me);
2289 TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta);
2291 if (!This->child.reole)
2292 return CO_E_RELEASED;
2294 return textrange_movestart(me, This->child.reole->editor, unit, count, delta);
2297 static HRESULT textrange_moveend(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG count, LONG *delta)
2299 LONG old_start, old_end, new_start, new_end;
2300 HRESULT hr = S_OK;
2302 if (!count)
2304 if (delta)
2305 *delta = 0;
2306 return S_FALSE;
2309 ITextRange_GetStart(range, &old_start);
2310 ITextRange_GetEnd(range, &old_end);
2311 switch (unit)
2313 case tomCharacter:
2315 ME_Cursor cursor;
2316 LONG moved;
2318 cursor_from_char_ofs( editor, old_end, &cursor );
2319 moved = ME_MoveCursorChars(editor, &cursor, count, TRUE);
2320 new_start = old_start;
2321 new_end = old_end + moved;
2322 if (new_end < new_start)
2323 new_start = new_end;
2324 if (delta)
2325 *delta = moved;
2326 break;
2328 case tomStory:
2329 if (count < 0)
2330 new_start = new_end = 0;
2331 else
2333 new_start = old_start;
2334 ITextRange_GetStoryLength(range, &new_end);
2336 if (delta)
2338 if (new_end < old_end)
2339 *delta = -1;
2340 else if (new_end == old_end)
2341 *delta = 0;
2342 else
2343 *delta = 1;
2345 break;
2346 default:
2347 FIXME("unit %d is not supported\n", unit);
2348 return E_NOTIMPL;
2350 if (new_end == old_end)
2351 hr = S_FALSE;
2352 ITextRange_SetStart(range, new_start);
2353 ITextRange_SetEnd(range, new_end);
2355 return hr;
2358 static HRESULT WINAPI ITextRange_fnMoveEnd(ITextRange *me, LONG unit, LONG count,
2359 LONG *delta)
2361 ITextRangeImpl *This = impl_from_ITextRange(me);
2363 TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta);
2365 if (!This->child.reole)
2366 return CO_E_RELEASED;
2368 return textrange_moveend(me, This->child.reole->editor, unit, count, delta);
2371 static HRESULT WINAPI ITextRange_fnMoveWhile(ITextRange *me, VARIANT *charset, LONG count,
2372 LONG *delta)
2374 ITextRangeImpl *This = impl_from_ITextRange(me);
2376 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2378 if (!This->child.reole)
2379 return CO_E_RELEASED;
2381 return E_NOTIMPL;
2384 static HRESULT WINAPI ITextRange_fnMoveStartWhile(ITextRange *me, VARIANT *charset, LONG count,
2385 LONG *delta)
2387 ITextRangeImpl *This = impl_from_ITextRange(me);
2389 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2391 if (!This->child.reole)
2392 return CO_E_RELEASED;
2394 return E_NOTIMPL;
2397 static HRESULT WINAPI ITextRange_fnMoveEndWhile(ITextRange *me, VARIANT *charset, LONG count,
2398 LONG *delta)
2400 ITextRangeImpl *This = impl_from_ITextRange(me);
2402 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2404 if (!This->child.reole)
2405 return CO_E_RELEASED;
2407 return E_NOTIMPL;
2410 static HRESULT WINAPI ITextRange_fnMoveUntil(ITextRange *me, VARIANT *charset, LONG count,
2411 LONG *delta)
2413 ITextRangeImpl *This = impl_from_ITextRange(me);
2415 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2417 if (!This->child.reole)
2418 return CO_E_RELEASED;
2420 return E_NOTIMPL;
2423 static HRESULT WINAPI ITextRange_fnMoveStartUntil(ITextRange *me, VARIANT *charset, LONG count,
2424 LONG *delta)
2426 ITextRangeImpl *This = impl_from_ITextRange(me);
2428 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2430 if (!This->child.reole)
2431 return CO_E_RELEASED;
2433 return E_NOTIMPL;
2436 static HRESULT WINAPI ITextRange_fnMoveEndUntil(ITextRange *me, VARIANT *charset, LONG count,
2437 LONG *delta)
2439 ITextRangeImpl *This = impl_from_ITextRange(me);
2441 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2443 if (!This->child.reole)
2444 return CO_E_RELEASED;
2446 return E_NOTIMPL;
2449 static HRESULT WINAPI ITextRange_fnFindText(ITextRange *me, BSTR text, LONG count, LONG flags,
2450 LONG *length)
2452 ITextRangeImpl *This = impl_from_ITextRange(me);
2454 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2456 if (!This->child.reole)
2457 return CO_E_RELEASED;
2459 return E_NOTIMPL;
2462 static HRESULT WINAPI ITextRange_fnFindTextStart(ITextRange *me, BSTR text, LONG count,
2463 LONG flags, LONG *length)
2465 ITextRangeImpl *This = impl_from_ITextRange(me);
2467 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2469 if (!This->child.reole)
2470 return CO_E_RELEASED;
2472 return E_NOTIMPL;
2475 static HRESULT WINAPI ITextRange_fnFindTextEnd(ITextRange *me, BSTR text, LONG count,
2476 LONG flags, LONG *length)
2478 ITextRangeImpl *This = impl_from_ITextRange(me);
2480 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2482 if (!This->child.reole)
2483 return CO_E_RELEASED;
2485 return E_NOTIMPL;
2488 static HRESULT WINAPI ITextRange_fnDelete(ITextRange *me, LONG unit, LONG count, LONG *delta)
2490 ITextRangeImpl *This = impl_from_ITextRange(me);
2492 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2494 if (!This->child.reole)
2495 return CO_E_RELEASED;
2497 return E_NOTIMPL;
2500 static HRESULT textrange_copy_or_cut( ITextRange *range, ME_TextEditor *editor, BOOL cut, VARIANT *v )
2502 LONG start, end;
2503 ME_Cursor cursor;
2504 IDataObject **data_out = NULL;
2506 ITextRange_GetStart( range, &start );
2507 ITextRange_GetEnd( range, &end );
2508 if (start == end)
2510 /* If the range is empty, all text is copied */
2511 LONG prev_end = end;
2512 ITextRange_SetEnd( range, MAXLONG );
2513 start = 0;
2514 ITextRange_GetEnd( range, &end );
2515 ITextRange_SetEnd( range, prev_end );
2517 cursor_from_char_ofs( editor, start, &cursor );
2519 if (v && V_VT(v) == (VT_UNKNOWN | VT_BYREF) && V_UNKNOWNREF( v ))
2520 data_out = (IDataObject **)V_UNKNOWNREF( v );
2522 return editor_copy_or_cut( editor, cut, &cursor, end - start, data_out );
2525 static HRESULT WINAPI ITextRange_fnCut(ITextRange *me, VARIANT *v)
2527 ITextRangeImpl *This = impl_from_ITextRange(me);
2529 TRACE("(%p)->(%p)\n", This, v);
2531 if (!This->child.reole)
2532 return CO_E_RELEASED;
2534 return textrange_copy_or_cut(me, This->child.reole->editor, TRUE, v);
2537 static HRESULT WINAPI ITextRange_fnCopy(ITextRange *me, VARIANT *v)
2539 ITextRangeImpl *This = impl_from_ITextRange(me);
2541 TRACE("(%p)->(%p)\n", This, v);
2543 if (!This->child.reole)
2544 return CO_E_RELEASED;
2546 return textrange_copy_or_cut(me, This->child.reole->editor, FALSE, v);
2549 static HRESULT WINAPI ITextRange_fnPaste(ITextRange *me, VARIANT *v, LONG format)
2551 ITextRangeImpl *This = impl_from_ITextRange(me);
2553 FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format);
2555 if (!This->child.reole)
2556 return CO_E_RELEASED;
2558 return E_NOTIMPL;
2561 static HRESULT WINAPI ITextRange_fnCanPaste(ITextRange *me, VARIANT *v, LONG format, LONG *ret)
2563 ITextRangeImpl *This = impl_from_ITextRange(me);
2565 FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret);
2567 if (!This->child.reole)
2568 return CO_E_RELEASED;
2570 return E_NOTIMPL;
2573 static HRESULT WINAPI ITextRange_fnCanEdit(ITextRange *me, LONG *ret)
2575 ITextRangeImpl *This = impl_from_ITextRange(me);
2577 FIXME("(%p)->(%p): stub\n", This, ret);
2579 if (!This->child.reole)
2580 return CO_E_RELEASED;
2582 return E_NOTIMPL;
2585 static HRESULT WINAPI ITextRange_fnChangeCase(ITextRange *me, LONG type)
2587 ITextRangeImpl *This = impl_from_ITextRange(me);
2589 FIXME("(%p)->(%d): stub\n", This, type);
2591 if (!This->child.reole)
2592 return CO_E_RELEASED;
2594 return E_NOTIMPL;
2597 static HRESULT WINAPI ITextRange_fnGetPoint(ITextRange *me, LONG type, LONG *cx, LONG *cy)
2599 ITextRangeImpl *This = impl_from_ITextRange(me);
2601 FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy);
2603 if (!This->child.reole)
2604 return CO_E_RELEASED;
2606 return E_NOTIMPL;
2609 static HRESULT WINAPI ITextRange_fnSetPoint(ITextRange *me, LONG x, LONG y, LONG type,
2610 LONG extend)
2612 ITextRangeImpl *This = impl_from_ITextRange(me);
2614 FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend);
2616 if (!This->child.reole)
2617 return CO_E_RELEASED;
2619 return E_NOTIMPL;
2622 static HRESULT WINAPI ITextRange_fnScrollIntoView(ITextRange *me, LONG value)
2624 ITextRangeImpl *This = impl_from_ITextRange(me);
2625 ME_TextEditor *editor;
2626 ME_Cursor cursor;
2627 int x, y, height;
2629 TRACE("(%p)->(%d)\n", This, value);
2631 if (!This->child.reole)
2632 return CO_E_RELEASED;
2634 editor = This->child.reole->editor;
2636 switch (value)
2638 case tomStart:
2639 cursor_from_char_ofs( editor, This->start, &cursor );
2640 cursor_coords( editor, &cursor, &x, &y, &height );
2641 break;
2642 case tomEnd:
2643 cursor_from_char_ofs( editor, This->end, &cursor );
2644 cursor_coords( editor, &cursor, &x, &y, &height );
2645 break;
2646 default:
2647 FIXME("bStart value %d not handled\n", value);
2648 return E_NOTIMPL;
2650 scroll_abs( editor, x, y, TRUE );
2651 return S_OK;
2654 static HRESULT WINAPI ITextRange_fnGetEmbeddedObject(ITextRange *me, IUnknown **ppv)
2656 ITextRangeImpl *This = impl_from_ITextRange(me);
2658 FIXME("(%p)->(%p): stub\n", This, ppv);
2660 if (!This->child.reole)
2661 return CO_E_RELEASED;
2663 return E_NOTIMPL;
2666 static const ITextRangeVtbl trvt = {
2667 ITextRange_fnQueryInterface,
2668 ITextRange_fnAddRef,
2669 ITextRange_fnRelease,
2670 ITextRange_fnGetTypeInfoCount,
2671 ITextRange_fnGetTypeInfo,
2672 ITextRange_fnGetIDsOfNames,
2673 ITextRange_fnInvoke,
2674 ITextRange_fnGetText,
2675 ITextRange_fnSetText,
2676 ITextRange_fnGetChar,
2677 ITextRange_fnSetChar,
2678 ITextRange_fnGetDuplicate,
2679 ITextRange_fnGetFormattedText,
2680 ITextRange_fnSetFormattedText,
2681 ITextRange_fnGetStart,
2682 ITextRange_fnSetStart,
2683 ITextRange_fnGetEnd,
2684 ITextRange_fnSetEnd,
2685 ITextRange_fnGetFont,
2686 ITextRange_fnSetFont,
2687 ITextRange_fnGetPara,
2688 ITextRange_fnSetPara,
2689 ITextRange_fnGetStoryLength,
2690 ITextRange_fnGetStoryType,
2691 ITextRange_fnCollapse,
2692 ITextRange_fnExpand,
2693 ITextRange_fnGetIndex,
2694 ITextRange_fnSetIndex,
2695 ITextRange_fnSetRange,
2696 ITextRange_fnInRange,
2697 ITextRange_fnInStory,
2698 ITextRange_fnIsEqual,
2699 ITextRange_fnSelect,
2700 ITextRange_fnStartOf,
2701 ITextRange_fnEndOf,
2702 ITextRange_fnMove,
2703 ITextRange_fnMoveStart,
2704 ITextRange_fnMoveEnd,
2705 ITextRange_fnMoveWhile,
2706 ITextRange_fnMoveStartWhile,
2707 ITextRange_fnMoveEndWhile,
2708 ITextRange_fnMoveUntil,
2709 ITextRange_fnMoveStartUntil,
2710 ITextRange_fnMoveEndUntil,
2711 ITextRange_fnFindText,
2712 ITextRange_fnFindTextStart,
2713 ITextRange_fnFindTextEnd,
2714 ITextRange_fnDelete,
2715 ITextRange_fnCut,
2716 ITextRange_fnCopy,
2717 ITextRange_fnPaste,
2718 ITextRange_fnCanPaste,
2719 ITextRange_fnCanEdit,
2720 ITextRange_fnChangeCase,
2721 ITextRange_fnGetPoint,
2722 ITextRange_fnSetPoint,
2723 ITextRange_fnScrollIntoView,
2724 ITextRange_fnGetEmbeddedObject
2727 /* ITextFont */
2728 static HRESULT WINAPI TextFont_QueryInterface(ITextFont *iface, REFIID riid, void **ppv)
2730 ITextFontImpl *This = impl_from_ITextFont(iface);
2732 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
2734 if (IsEqualIID(riid, &IID_ITextFont) ||
2735 IsEqualIID(riid, &IID_IDispatch) ||
2736 IsEqualIID(riid, &IID_IUnknown))
2738 *ppv = iface;
2739 ITextFont_AddRef(iface);
2740 return S_OK;
2743 *ppv = NULL;
2744 return E_NOINTERFACE;
2747 static ULONG WINAPI TextFont_AddRef(ITextFont *iface)
2749 ITextFontImpl *This = impl_from_ITextFont(iface);
2750 ULONG ref = InterlockedIncrement(&This->ref);
2751 TRACE("(%p)->(%u)\n", This, ref);
2752 return ref;
2755 static ULONG WINAPI TextFont_Release(ITextFont *iface)
2757 ITextFontImpl *This = impl_from_ITextFont(iface);
2758 ULONG ref = InterlockedDecrement(&This->ref);
2760 TRACE("(%p)->(%u)\n", This, ref);
2762 if (!ref)
2764 if (This->range)
2765 ITextRange_Release(This->range);
2766 SysFreeString(This->props[FONT_NAME].str);
2767 heap_free(This);
2770 return ref;
2773 static HRESULT WINAPI TextFont_GetTypeInfoCount(ITextFont *iface, UINT *pctinfo)
2775 ITextFontImpl *This = impl_from_ITextFont(iface);
2776 TRACE("(%p)->(%p)\n", This, pctinfo);
2777 *pctinfo = 1;
2778 return S_OK;
2781 static HRESULT WINAPI TextFont_GetTypeInfo(ITextFont *iface, UINT iTInfo, LCID lcid,
2782 ITypeInfo **ppTInfo)
2784 ITextFontImpl *This = impl_from_ITextFont(iface);
2785 HRESULT hr;
2787 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
2789 hr = get_typeinfo(ITextFont_tid, ppTInfo);
2790 if (SUCCEEDED(hr))
2791 ITypeInfo_AddRef(*ppTInfo);
2792 return hr;
2795 static HRESULT WINAPI TextFont_GetIDsOfNames(ITextFont *iface, REFIID riid,
2796 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
2798 ITextFontImpl *This = impl_from_ITextFont(iface);
2799 ITypeInfo *ti;
2800 HRESULT hr;
2802 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid),
2803 rgszNames, cNames, lcid, rgDispId);
2805 hr = get_typeinfo(ITextFont_tid, &ti);
2806 if (SUCCEEDED(hr))
2807 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
2808 return hr;
2811 static HRESULT WINAPI TextFont_Invoke(
2812 ITextFont *iface,
2813 DISPID dispIdMember,
2814 REFIID riid,
2815 LCID lcid,
2816 WORD wFlags,
2817 DISPPARAMS *pDispParams,
2818 VARIANT *pVarResult,
2819 EXCEPINFO *pExcepInfo,
2820 UINT *puArgErr)
2822 ITextFontImpl *This = impl_from_ITextFont(iface);
2823 ITypeInfo *ti;
2824 HRESULT hr;
2826 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
2827 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2829 hr = get_typeinfo(ITextFont_tid, &ti);
2830 if (SUCCEEDED(hr))
2831 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2832 return hr;
2835 static HRESULT WINAPI TextFont_GetDuplicate(ITextFont *iface, ITextFont **ret)
2837 ITextFontImpl *This = impl_from_ITextFont(iface);
2839 TRACE("(%p)->(%p)\n", This, ret);
2841 if (!ret)
2842 return E_INVALIDARG;
2844 *ret = NULL;
2845 if (This->range && !get_range_reole(This->range))
2846 return CO_E_RELEASED;
2848 return create_textfont(NULL, This, ret);
2851 static HRESULT WINAPI TextFont_SetDuplicate(ITextFont *iface, ITextFont *pFont)
2853 ITextFontImpl *This = impl_from_ITextFont(iface);
2854 FIXME("(%p)->(%p): stub\n", This, pFont);
2855 return E_NOTIMPL;
2858 static HRESULT WINAPI TextFont_CanChange(ITextFont *iface, LONG *ret)
2860 ITextFontImpl *This = impl_from_ITextFont(iface);
2861 FIXME("(%p)->(%p): stub\n", This, ret);
2862 return E_NOTIMPL;
2865 static HRESULT WINAPI TextFont_IsEqual(ITextFont *iface, ITextFont *font, LONG *ret)
2867 ITextFontImpl *This = impl_from_ITextFont(iface);
2868 FIXME("(%p)->(%p %p): stub\n", This, font, ret);
2869 return E_NOTIMPL;
2872 static void textfont_reset_to_default(ITextFontImpl *font)
2874 enum textfont_prop_id id;
2876 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2877 switch (id)
2879 case FONT_ALLCAPS:
2880 case FONT_ANIMATION:
2881 case FONT_BOLD:
2882 case FONT_EMBOSS:
2883 case FONT_HIDDEN:
2884 case FONT_ENGRAVE:
2885 case FONT_ITALIC:
2886 case FONT_OUTLINE:
2887 case FONT_PROTECTED:
2888 case FONT_SHADOW:
2889 case FONT_SMALLCAPS:
2890 case FONT_STRIKETHROUGH:
2891 case FONT_SUBSCRIPT:
2892 case FONT_SUPERSCRIPT:
2893 case FONT_UNDERLINE:
2894 font->props[id].l = tomFalse;
2895 break;
2896 case FONT_BACKCOLOR:
2897 case FONT_FORECOLOR:
2898 font->props[id].l = tomAutoColor;
2899 break;
2900 case FONT_KERNING:
2901 case FONT_POSITION:
2902 case FONT_SIZE:
2903 case FONT_SPACING:
2904 font->props[id].f = 0.0;
2905 break;
2906 case FONT_LANGID:
2907 font->props[id].l = GetSystemDefaultLCID();
2908 break;
2909 case FONT_NAME: {
2910 SysFreeString(font->props[id].str);
2911 font->props[id].str = SysAllocString(L"System");
2912 break;
2914 case FONT_WEIGHT:
2915 font->props[id].l = FW_NORMAL;
2916 break;
2917 default:
2918 FIXME("font property %d not handled\n", id);
2923 static void textfont_reset_to_undefined(ITextFontImpl *font)
2925 enum textfont_prop_id id;
2927 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2928 switch (id)
2930 case FONT_ALLCAPS:
2931 case FONT_ANIMATION:
2932 case FONT_BOLD:
2933 case FONT_EMBOSS:
2934 case FONT_HIDDEN:
2935 case FONT_ENGRAVE:
2936 case FONT_ITALIC:
2937 case FONT_OUTLINE:
2938 case FONT_PROTECTED:
2939 case FONT_SHADOW:
2940 case FONT_SMALLCAPS:
2941 case FONT_STRIKETHROUGH:
2942 case FONT_SUBSCRIPT:
2943 case FONT_SUPERSCRIPT:
2944 case FONT_UNDERLINE:
2945 case FONT_BACKCOLOR:
2946 case FONT_FORECOLOR:
2947 case FONT_LANGID:
2948 case FONT_WEIGHT:
2949 font->props[id].l = tomUndefined;
2950 break;
2951 case FONT_KERNING:
2952 case FONT_POSITION:
2953 case FONT_SIZE:
2954 case FONT_SPACING:
2955 font->props[id].f = tomUndefined;
2956 break;
2957 case FONT_NAME:
2958 break;
2959 default:
2960 FIXME("font property %d not handled\n", id);
2965 static void textfont_apply_range_props(ITextFontImpl *font)
2967 enum textfont_prop_id propid;
2968 for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++)
2969 set_textfont_prop(font, propid, &font->props[propid]);
2972 static HRESULT WINAPI TextFont_Reset(ITextFont *iface, LONG value)
2974 ITextFontImpl *This = impl_from_ITextFont(iface);
2976 TRACE("(%p)->(%d)\n", This, value);
2978 /* If font is attached to a range, released or not, we can't
2979 reset to undefined */
2980 if (This->range) {
2981 if (!get_range_reole(This->range))
2982 return CO_E_RELEASED;
2984 switch (value)
2986 case tomUndefined:
2987 return E_INVALIDARG;
2988 case tomCacheParms:
2989 textfont_cache_range_props(This);
2990 This->get_cache_enabled = TRUE;
2991 break;
2992 case tomTrackParms:
2993 This->get_cache_enabled = FALSE;
2994 break;
2995 case tomApplyLater:
2996 This->set_cache_enabled = TRUE;
2997 break;
2998 case tomApplyNow:
2999 This->set_cache_enabled = FALSE;
3000 textfont_apply_range_props(This);
3001 break;
3002 case tomUsePoints:
3003 case tomUseTwips:
3004 return E_INVALIDARG;
3005 default:
3006 FIXME("reset mode %d not supported\n", value);
3009 return S_OK;
3011 else {
3012 switch (value)
3014 /* reset to global defaults */
3015 case tomDefault:
3016 textfont_reset_to_default(This);
3017 return S_OK;
3018 /* all properties are set to tomUndefined, font name is retained */
3019 case tomUndefined:
3020 textfont_reset_to_undefined(This);
3021 return S_OK;
3022 case tomApplyNow:
3023 case tomApplyLater:
3024 case tomTrackParms:
3025 case tomCacheParms:
3026 return S_OK;
3027 case tomUsePoints:
3028 case tomUseTwips:
3029 return E_INVALIDARG;
3033 FIXME("reset mode %d not supported\n", value);
3034 return E_NOTIMPL;
3037 static HRESULT WINAPI TextFont_GetStyle(ITextFont *iface, LONG *value)
3039 ITextFontImpl *This = impl_from_ITextFont(iface);
3040 FIXME("(%p)->(%p): stub\n", This, value);
3041 return E_NOTIMPL;
3044 static HRESULT WINAPI TextFont_SetStyle(ITextFont *iface, LONG value)
3046 ITextFontImpl *This = impl_from_ITextFont(iface);
3047 FIXME("(%p)->(%d): stub\n", This, value);
3048 return E_NOTIMPL;
3051 static HRESULT WINAPI TextFont_GetAllCaps(ITextFont *iface, LONG *value)
3053 ITextFontImpl *This = impl_from_ITextFont(iface);
3054 TRACE("(%p)->(%p)\n", This, value);
3055 return get_textfont_propl(This, FONT_ALLCAPS, value);
3058 static HRESULT WINAPI TextFont_SetAllCaps(ITextFont *iface, LONG value)
3060 ITextFontImpl *This = impl_from_ITextFont(iface);
3061 TRACE("(%p)->(%d)\n", This, value);
3062 return set_textfont_propd(This, FONT_ALLCAPS, value);
3065 static HRESULT WINAPI TextFont_GetAnimation(ITextFont *iface, LONG *value)
3067 ITextFontImpl *This = impl_from_ITextFont(iface);
3068 TRACE("(%p)->(%p)\n", This, value);
3069 return get_textfont_propl(This, FONT_ANIMATION, value);
3072 static HRESULT WINAPI TextFont_SetAnimation(ITextFont *iface, LONG value)
3074 ITextFontImpl *This = impl_from_ITextFont(iface);
3076 TRACE("(%p)->(%d)\n", This, value);
3078 if (value < tomNoAnimation || value > tomAnimationMax)
3079 return E_INVALIDARG;
3081 return set_textfont_propl(This, FONT_ANIMATION, value);
3084 static HRESULT WINAPI TextFont_GetBackColor(ITextFont *iface, LONG *value)
3086 ITextFontImpl *This = impl_from_ITextFont(iface);
3087 TRACE("(%p)->(%p)\n", This, value);
3088 return get_textfont_propl(This, FONT_BACKCOLOR, value);
3091 static HRESULT WINAPI TextFont_SetBackColor(ITextFont *iface, LONG value)
3093 ITextFontImpl *This = impl_from_ITextFont(iface);
3094 TRACE("(%p)->(%d)\n", This, value);
3095 return set_textfont_propl(This, FONT_BACKCOLOR, value);
3098 static HRESULT WINAPI TextFont_GetBold(ITextFont *iface, LONG *value)
3100 ITextFontImpl *This = impl_from_ITextFont(iface);
3101 TRACE("(%p)->(%p)\n", This, value);
3102 return get_textfont_propl(This, FONT_BOLD, value);
3105 static HRESULT WINAPI TextFont_SetBold(ITextFont *iface, LONG value)
3107 ITextFontImpl *This = impl_from_ITextFont(iface);
3108 TRACE("(%p)->(%d)\n", This, value);
3109 return set_textfont_propd(This, FONT_BOLD, value);
3112 static HRESULT WINAPI TextFont_GetEmboss(ITextFont *iface, LONG *value)
3114 ITextFontImpl *This = impl_from_ITextFont(iface);
3115 TRACE("(%p)->(%p)\n", This, value);
3116 return get_textfont_propl(This, FONT_EMBOSS, value);
3119 static HRESULT WINAPI TextFont_SetEmboss(ITextFont *iface, LONG value)
3121 ITextFontImpl *This = impl_from_ITextFont(iface);
3122 TRACE("(%p)->(%d)\n", This, value);
3123 return set_textfont_propd(This, FONT_EMBOSS, value);
3126 static HRESULT WINAPI TextFont_GetForeColor(ITextFont *iface, LONG *value)
3128 ITextFontImpl *This = impl_from_ITextFont(iface);
3129 TRACE("(%p)->(%p)\n", This, value);
3130 return get_textfont_propl(This, FONT_FORECOLOR, value);
3133 static HRESULT WINAPI TextFont_SetForeColor(ITextFont *iface, LONG value)
3135 ITextFontImpl *This = impl_from_ITextFont(iface);
3136 TRACE("(%p)->(%d)\n", This, value);
3137 return set_textfont_propl(This, FONT_FORECOLOR, value);
3140 static HRESULT WINAPI TextFont_GetHidden(ITextFont *iface, LONG *value)
3142 ITextFontImpl *This = impl_from_ITextFont(iface);
3143 TRACE("(%p)->(%p)\n", This, value);
3144 return get_textfont_propl(This, FONT_HIDDEN, value);
3147 static HRESULT WINAPI TextFont_SetHidden(ITextFont *iface, LONG value)
3149 ITextFontImpl *This = impl_from_ITextFont(iface);
3150 TRACE("(%p)->(%d)\n", This, value);
3151 return set_textfont_propd(This, FONT_HIDDEN, value);
3154 static HRESULT WINAPI TextFont_GetEngrave(ITextFont *iface, LONG *value)
3156 ITextFontImpl *This = impl_from_ITextFont(iface);
3157 TRACE("(%p)->(%p)\n", This, value);
3158 return get_textfont_propl(This, FONT_ENGRAVE, value);
3161 static HRESULT WINAPI TextFont_SetEngrave(ITextFont *iface, LONG value)
3163 ITextFontImpl *This = impl_from_ITextFont(iface);
3164 TRACE("(%p)->(%d)\n", This, value);
3165 return set_textfont_propd(This, FONT_ENGRAVE, value);
3168 static HRESULT WINAPI TextFont_GetItalic(ITextFont *iface, LONG *value)
3170 ITextFontImpl *This = impl_from_ITextFont(iface);
3171 TRACE("(%p)->(%p)\n", This, value);
3172 return get_textfont_propl(This, FONT_ITALIC, value);
3175 static HRESULT WINAPI TextFont_SetItalic(ITextFont *iface, LONG value)
3177 ITextFontImpl *This = impl_from_ITextFont(iface);
3178 TRACE("(%p)->(%d)\n", This, value);
3179 return set_textfont_propd(This, FONT_ITALIC, value);
3182 static HRESULT WINAPI TextFont_GetKerning(ITextFont *iface, FLOAT *value)
3184 ITextFontImpl *This = impl_from_ITextFont(iface);
3185 TRACE("(%p)->(%p)\n", This, value);
3186 return get_textfont_propf(This, FONT_KERNING, value);
3189 static HRESULT WINAPI TextFont_SetKerning(ITextFont *iface, FLOAT value)
3191 ITextFontImpl *This = impl_from_ITextFont(iface);
3192 TRACE("(%p)->(%.2f)\n", This, value);
3193 return set_textfont_propf(This, FONT_KERNING, value);
3196 static HRESULT WINAPI TextFont_GetLanguageID(ITextFont *iface, LONG *value)
3198 ITextFontImpl *This = impl_from_ITextFont(iface);
3199 TRACE("(%p)->(%p)\n", This, value);
3200 return get_textfont_propl(This, FONT_LANGID, value);
3203 static HRESULT WINAPI TextFont_SetLanguageID(ITextFont *iface, LONG value)
3205 ITextFontImpl *This = impl_from_ITextFont(iface);
3206 TRACE("(%p)->(%d)\n", This, value);
3207 return set_textfont_propl(This, FONT_LANGID, value);
3210 static HRESULT WINAPI TextFont_GetName(ITextFont *iface, BSTR *value)
3212 ITextFontImpl *This = impl_from_ITextFont(iface);
3214 TRACE("(%p)->(%p)\n", This, value);
3216 if (!value)
3217 return E_INVALIDARG;
3219 *value = NULL;
3221 if (!This->range) {
3222 if (This->props[FONT_NAME].str)
3223 *value = SysAllocString(This->props[FONT_NAME].str);
3224 else
3225 *value = SysAllocStringLen(NULL, 0);
3226 return *value ? S_OK : E_OUTOFMEMORY;
3229 return textfont_getname_from_range(This->range, value);
3232 static HRESULT WINAPI TextFont_SetName(ITextFont *iface, BSTR value)
3234 ITextFontImpl *This = impl_from_ITextFont(iface);
3235 textfont_prop_val v;
3237 TRACE("(%p)->(%s)\n", This, debugstr_w(value));
3239 v.str = value;
3240 return set_textfont_prop(This, FONT_NAME, &v);
3243 static HRESULT WINAPI TextFont_GetOutline(ITextFont *iface, LONG *value)
3245 ITextFontImpl *This = impl_from_ITextFont(iface);
3246 TRACE("(%p)->(%p)\n", This, value);
3247 return get_textfont_propl(This, FONT_OUTLINE, value);
3250 static HRESULT WINAPI TextFont_SetOutline(ITextFont *iface, LONG value)
3252 ITextFontImpl *This = impl_from_ITextFont(iface);
3253 TRACE("(%p)->(%d)\n", This, value);
3254 return set_textfont_propd(This, FONT_OUTLINE, value);
3257 static HRESULT WINAPI TextFont_GetPosition(ITextFont *iface, FLOAT *value)
3259 ITextFontImpl *This = impl_from_ITextFont(iface);
3260 TRACE("(%p)->(%p)\n", This, value);
3261 return get_textfont_propf(This, FONT_POSITION, value);
3264 static HRESULT WINAPI TextFont_SetPosition(ITextFont *iface, FLOAT value)
3266 ITextFontImpl *This = impl_from_ITextFont(iface);
3267 TRACE("(%p)->(%.2f)\n", This, value);
3268 return set_textfont_propf(This, FONT_POSITION, value);
3271 static HRESULT WINAPI TextFont_GetProtected(ITextFont *iface, LONG *value)
3273 ITextFontImpl *This = impl_from_ITextFont(iface);
3274 TRACE("(%p)->(%p)\n", This, value);
3275 return get_textfont_propl(This, FONT_PROTECTED, value);
3278 static HRESULT WINAPI TextFont_SetProtected(ITextFont *iface, LONG value)
3280 ITextFontImpl *This = impl_from_ITextFont(iface);
3281 TRACE("(%p)->(%d)\n", This, value);
3282 return set_textfont_propd(This, FONT_PROTECTED, value);
3285 static HRESULT WINAPI TextFont_GetShadow(ITextFont *iface, LONG *value)
3287 ITextFontImpl *This = impl_from_ITextFont(iface);
3288 TRACE("(%p)->(%p)\n", This, value);
3289 return get_textfont_propl(This, FONT_SHADOW, value);
3292 static HRESULT WINAPI TextFont_SetShadow(ITextFont *iface, LONG value)
3294 ITextFontImpl *This = impl_from_ITextFont(iface);
3295 TRACE("(%p)->(%d)\n", This, value);
3296 return set_textfont_propd(This, FONT_SHADOW, value);
3299 static HRESULT WINAPI TextFont_GetSize(ITextFont *iface, FLOAT *value)
3301 ITextFontImpl *This = impl_from_ITextFont(iface);
3302 TRACE("(%p)->(%p)\n", This, value);
3303 return get_textfont_propf(This, FONT_SIZE, value);
3306 static HRESULT WINAPI TextFont_SetSize(ITextFont *iface, FLOAT value)
3308 ITextFontImpl *This = impl_from_ITextFont(iface);
3309 TRACE("(%p)->(%.2f)\n", This, value);
3310 return set_textfont_propf(This, FONT_SIZE, value);
3313 static HRESULT WINAPI TextFont_GetSmallCaps(ITextFont *iface, LONG *value)
3315 ITextFontImpl *This = impl_from_ITextFont(iface);
3316 TRACE("(%p)->(%p)\n", This, value);
3317 return get_textfont_propl(This, FONT_SMALLCAPS, value);
3320 static HRESULT WINAPI TextFont_SetSmallCaps(ITextFont *iface, LONG value)
3322 ITextFontImpl *This = impl_from_ITextFont(iface);
3323 TRACE("(%p)->(%d)\n", This, value);
3324 return set_textfont_propd(This, FONT_SMALLCAPS, value);
3327 static HRESULT WINAPI TextFont_GetSpacing(ITextFont *iface, FLOAT *value)
3329 ITextFontImpl *This = impl_from_ITextFont(iface);
3330 TRACE("(%p)->(%p)\n", This, value);
3331 return get_textfont_propf(This, FONT_SPACING, value);
3334 static HRESULT WINAPI TextFont_SetSpacing(ITextFont *iface, FLOAT value)
3336 ITextFontImpl *This = impl_from_ITextFont(iface);
3337 TRACE("(%p)->(%.2f)\n", This, value);
3338 return set_textfont_propf(This, FONT_SPACING, value);
3341 static HRESULT WINAPI TextFont_GetStrikeThrough(ITextFont *iface, LONG *value)
3343 ITextFontImpl *This = impl_from_ITextFont(iface);
3344 TRACE("(%p)->(%p)\n", This, value);
3345 return get_textfont_propl(This, FONT_STRIKETHROUGH, value);
3348 static HRESULT WINAPI TextFont_SetStrikeThrough(ITextFont *iface, LONG value)
3350 ITextFontImpl *This = impl_from_ITextFont(iface);
3351 TRACE("(%p)->(%d)\n", This, value);
3352 return set_textfont_propd(This, FONT_STRIKETHROUGH, value);
3355 static HRESULT WINAPI TextFont_GetSubscript(ITextFont *iface, LONG *value)
3357 ITextFontImpl *This = impl_from_ITextFont(iface);
3358 TRACE("(%p)->(%p)\n", This, value);
3359 return get_textfont_propl(This, FONT_SUBSCRIPT, value);
3362 static HRESULT WINAPI TextFont_SetSubscript(ITextFont *iface, LONG value)
3364 ITextFontImpl *This = impl_from_ITextFont(iface);
3365 TRACE("(%p)->(%d)\n", This, value);
3366 return set_textfont_propd(This, FONT_SUBSCRIPT, value);
3369 static HRESULT WINAPI TextFont_GetSuperscript(ITextFont *iface, LONG *value)
3371 ITextFontImpl *This = impl_from_ITextFont(iface);
3372 TRACE("(%p)->(%p)\n", This, value);
3373 return get_textfont_propl(This, FONT_SUPERSCRIPT, value);
3376 static HRESULT WINAPI TextFont_SetSuperscript(ITextFont *iface, LONG value)
3378 ITextFontImpl *This = impl_from_ITextFont(iface);
3379 TRACE("(%p)->(%d)\n", This, value);
3380 return set_textfont_propd(This, FONT_SUPERSCRIPT, value);
3383 static HRESULT WINAPI TextFont_GetUnderline(ITextFont *iface, LONG *value)
3385 ITextFontImpl *This = impl_from_ITextFont(iface);
3386 TRACE("(%p)->(%p)\n", This, value);
3387 return get_textfont_propl(This, FONT_UNDERLINE, value);
3390 static HRESULT WINAPI TextFont_SetUnderline(ITextFont *iface, LONG value)
3392 ITextFontImpl *This = impl_from_ITextFont(iface);
3393 TRACE("(%p)->(%d)\n", This, value);
3394 return set_textfont_propd(This, FONT_UNDERLINE, value);
3397 static HRESULT WINAPI TextFont_GetWeight(ITextFont *iface, LONG *value)
3399 ITextFontImpl *This = impl_from_ITextFont(iface);
3400 TRACE("(%p)->(%p)\n", This, value);
3401 return get_textfont_propl(This, FONT_WEIGHT, value);
3404 static HRESULT WINAPI TextFont_SetWeight(ITextFont *iface, LONG value)
3406 ITextFontImpl *This = impl_from_ITextFont(iface);
3407 TRACE("(%p)->(%d)\n", This, value);
3408 return set_textfont_propl(This, FONT_WEIGHT, value);
3411 static ITextFontVtbl textfontvtbl = {
3412 TextFont_QueryInterface,
3413 TextFont_AddRef,
3414 TextFont_Release,
3415 TextFont_GetTypeInfoCount,
3416 TextFont_GetTypeInfo,
3417 TextFont_GetIDsOfNames,
3418 TextFont_Invoke,
3419 TextFont_GetDuplicate,
3420 TextFont_SetDuplicate,
3421 TextFont_CanChange,
3422 TextFont_IsEqual,
3423 TextFont_Reset,
3424 TextFont_GetStyle,
3425 TextFont_SetStyle,
3426 TextFont_GetAllCaps,
3427 TextFont_SetAllCaps,
3428 TextFont_GetAnimation,
3429 TextFont_SetAnimation,
3430 TextFont_GetBackColor,
3431 TextFont_SetBackColor,
3432 TextFont_GetBold,
3433 TextFont_SetBold,
3434 TextFont_GetEmboss,
3435 TextFont_SetEmboss,
3436 TextFont_GetForeColor,
3437 TextFont_SetForeColor,
3438 TextFont_GetHidden,
3439 TextFont_SetHidden,
3440 TextFont_GetEngrave,
3441 TextFont_SetEngrave,
3442 TextFont_GetItalic,
3443 TextFont_SetItalic,
3444 TextFont_GetKerning,
3445 TextFont_SetKerning,
3446 TextFont_GetLanguageID,
3447 TextFont_SetLanguageID,
3448 TextFont_GetName,
3449 TextFont_SetName,
3450 TextFont_GetOutline,
3451 TextFont_SetOutline,
3452 TextFont_GetPosition,
3453 TextFont_SetPosition,
3454 TextFont_GetProtected,
3455 TextFont_SetProtected,
3456 TextFont_GetShadow,
3457 TextFont_SetShadow,
3458 TextFont_GetSize,
3459 TextFont_SetSize,
3460 TextFont_GetSmallCaps,
3461 TextFont_SetSmallCaps,
3462 TextFont_GetSpacing,
3463 TextFont_SetSpacing,
3464 TextFont_GetStrikeThrough,
3465 TextFont_SetStrikeThrough,
3466 TextFont_GetSubscript,
3467 TextFont_SetSubscript,
3468 TextFont_GetSuperscript,
3469 TextFont_SetSuperscript,
3470 TextFont_GetUnderline,
3471 TextFont_SetUnderline,
3472 TextFont_GetWeight,
3473 TextFont_SetWeight
3476 static HRESULT create_textfont(ITextRange *range, const ITextFontImpl *src, ITextFont **ret)
3478 ITextFontImpl *font;
3480 *ret = NULL;
3481 font = heap_alloc(sizeof(*font));
3482 if (!font)
3483 return E_OUTOFMEMORY;
3485 font->ITextFont_iface.lpVtbl = &textfontvtbl;
3486 font->ref = 1;
3488 if (src) {
3489 font->range = NULL;
3490 font->get_cache_enabled = TRUE;
3491 font->set_cache_enabled = TRUE;
3492 memcpy(&font->props, &src->props, sizeof(font->props));
3493 if (font->props[FONT_NAME].str)
3494 font->props[FONT_NAME].str = SysAllocString(font->props[FONT_NAME].str);
3496 else {
3497 font->range = range;
3498 ITextRange_AddRef(range);
3500 /* cache current properties */
3501 font->get_cache_enabled = FALSE;
3502 font->set_cache_enabled = FALSE;
3503 textfont_cache_range_props(font);
3506 *ret = &font->ITextFont_iface;
3507 return S_OK;
3510 /* ITextPara */
3511 static HRESULT WINAPI TextPara_QueryInterface(ITextPara *iface, REFIID riid, void **ppv)
3513 ITextParaImpl *This = impl_from_ITextPara(iface);
3515 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
3517 if (IsEqualIID(riid, &IID_ITextPara) ||
3518 IsEqualIID(riid, &IID_IDispatch) ||
3519 IsEqualIID(riid, &IID_IUnknown))
3521 *ppv = iface;
3522 ITextPara_AddRef(iface);
3523 return S_OK;
3526 *ppv = NULL;
3527 return E_NOINTERFACE;
3530 static ULONG WINAPI TextPara_AddRef(ITextPara *iface)
3532 ITextParaImpl *This = impl_from_ITextPara(iface);
3533 ULONG ref = InterlockedIncrement(&This->ref);
3534 TRACE("(%p)->(%u)\n", This, ref);
3535 return ref;
3538 static ULONG WINAPI TextPara_Release(ITextPara *iface)
3540 ITextParaImpl *This = impl_from_ITextPara(iface);
3541 ULONG ref = InterlockedDecrement(&This->ref);
3543 TRACE("(%p)->(%u)\n", This, ref);
3545 if (!ref)
3547 ITextRange_Release(This->range);
3548 heap_free(This);
3551 return ref;
3554 static HRESULT WINAPI TextPara_GetTypeInfoCount(ITextPara *iface, UINT *pctinfo)
3556 ITextParaImpl *This = impl_from_ITextPara(iface);
3557 TRACE("(%p)->(%p)\n", This, pctinfo);
3558 *pctinfo = 1;
3559 return S_OK;
3562 static HRESULT WINAPI TextPara_GetTypeInfo(ITextPara *iface, UINT iTInfo, LCID lcid,
3563 ITypeInfo **ppTInfo)
3565 ITextParaImpl *This = impl_from_ITextPara(iface);
3566 HRESULT hr;
3568 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
3570 hr = get_typeinfo(ITextPara_tid, ppTInfo);
3571 if (SUCCEEDED(hr))
3572 ITypeInfo_AddRef(*ppTInfo);
3573 return hr;
3576 static HRESULT WINAPI TextPara_GetIDsOfNames(ITextPara *iface, REFIID riid,
3577 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
3579 ITextParaImpl *This = impl_from_ITextPara(iface);
3580 ITypeInfo *ti;
3581 HRESULT hr;
3583 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames,
3584 cNames, lcid, rgDispId);
3586 hr = get_typeinfo(ITextPara_tid, &ti);
3587 if (SUCCEEDED(hr))
3588 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
3589 return hr;
3592 static HRESULT WINAPI TextPara_Invoke(
3593 ITextPara *iface,
3594 DISPID dispIdMember,
3595 REFIID riid,
3596 LCID lcid,
3597 WORD wFlags,
3598 DISPPARAMS *pDispParams,
3599 VARIANT *pVarResult,
3600 EXCEPINFO *pExcepInfo,
3601 UINT *puArgErr)
3603 ITextParaImpl *This = impl_from_ITextPara(iface);
3604 ITypeInfo *ti;
3605 HRESULT hr;
3607 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember,
3608 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
3609 pExcepInfo, puArgErr);
3611 hr = get_typeinfo(ITextPara_tid, &ti);
3612 if (SUCCEEDED(hr))
3613 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3614 return hr;
3617 static HRESULT WINAPI TextPara_GetDuplicate(ITextPara *iface, ITextPara **ret)
3619 ITextParaImpl *This = impl_from_ITextPara(iface);
3620 FIXME("(%p)->(%p)\n", This, ret);
3621 return E_NOTIMPL;
3624 static HRESULT WINAPI TextPara_SetDuplicate(ITextPara *iface, ITextPara *para)
3626 ITextParaImpl *This = impl_from_ITextPara(iface);
3627 FIXME("(%p)->(%p)\n", This, para);
3628 return E_NOTIMPL;
3631 static HRESULT WINAPI TextPara_CanChange(ITextPara *iface, LONG *ret)
3633 ITextParaImpl *This = impl_from_ITextPara(iface);
3634 FIXME("(%p)->(%p)\n", This, ret);
3635 return E_NOTIMPL;
3638 static HRESULT WINAPI TextPara_IsEqual(ITextPara *iface, ITextPara *para, LONG *ret)
3640 ITextParaImpl *This = impl_from_ITextPara(iface);
3641 FIXME("(%p)->(%p %p)\n", This, para, ret);
3642 return E_NOTIMPL;
3645 static HRESULT WINAPI TextPara_Reset(ITextPara *iface, LONG value)
3647 ITextParaImpl *This = impl_from_ITextPara(iface);
3648 FIXME("(%p)->(%d)\n", This, value);
3649 return E_NOTIMPL;
3652 static HRESULT WINAPI TextPara_GetStyle(ITextPara *iface, LONG *value)
3654 ITextParaImpl *This = impl_from_ITextPara(iface);
3655 FIXME("(%p)->(%p)\n", This, value);
3656 return E_NOTIMPL;
3659 static HRESULT WINAPI TextPara_SetStyle(ITextPara *iface, LONG value)
3661 ITextParaImpl *This = impl_from_ITextPara(iface);
3662 FIXME("(%p)->(%d)\n", This, value);
3663 return E_NOTIMPL;
3666 static HRESULT WINAPI TextPara_GetAlignment(ITextPara *iface, LONG *value)
3668 ITextParaImpl *This = impl_from_ITextPara(iface);
3669 FIXME("(%p)->(%p)\n", This, value);
3670 return E_NOTIMPL;
3673 static HRESULT WINAPI TextPara_SetAlignment(ITextPara *iface, LONG value)
3675 ITextParaImpl *This = impl_from_ITextPara(iface);
3676 FIXME("(%p)->(%d)\n", This, value);
3677 return E_NOTIMPL;
3680 static HRESULT WINAPI TextPara_GetHyphenation(ITextPara *iface, LONG *value)
3682 ITextParaImpl *This = impl_from_ITextPara(iface);
3683 FIXME("(%p)->(%p)\n", This, value);
3684 return E_NOTIMPL;
3687 static HRESULT WINAPI TextPara_SetHyphenation(ITextPara *iface, LONG value)
3689 ITextParaImpl *This = impl_from_ITextPara(iface);
3690 FIXME("(%p)->(%d)\n", This, value);
3691 return E_NOTIMPL;
3694 static HRESULT WINAPI TextPara_GetFirstLineIndent(ITextPara *iface, FLOAT *value)
3696 ITextParaImpl *This = impl_from_ITextPara(iface);
3697 FIXME("(%p)->(%p)\n", This, value);
3698 return E_NOTIMPL;
3701 static HRESULT WINAPI TextPara_GetKeepTogether(ITextPara *iface, LONG *value)
3703 ITextParaImpl *This = impl_from_ITextPara(iface);
3704 FIXME("(%p)->(%p)\n", This, value);
3705 return E_NOTIMPL;
3708 static HRESULT WINAPI TextPara_SetKeepTogether(ITextPara *iface, LONG value)
3710 ITextParaImpl *This = impl_from_ITextPara(iface);
3711 FIXME("(%p)->(%d)\n", This, value);
3712 return E_NOTIMPL;
3715 static HRESULT WINAPI TextPara_GetKeepWithNext(ITextPara *iface, LONG *value)
3717 ITextParaImpl *This = impl_from_ITextPara(iface);
3718 FIXME("(%p)->(%p)\n", This, value);
3719 return E_NOTIMPL;
3722 static HRESULT WINAPI TextPara_SetKeepWithNext(ITextPara *iface, LONG value)
3724 ITextParaImpl *This = impl_from_ITextPara(iface);
3725 FIXME("(%p)->(%d)\n", This, value);
3726 return E_NOTIMPL;
3729 static HRESULT WINAPI TextPara_GetLeftIndent(ITextPara *iface, FLOAT *value)
3731 ITextParaImpl *This = impl_from_ITextPara(iface);
3732 FIXME("(%p)->(%p)\n", This, value);
3733 return E_NOTIMPL;
3736 static HRESULT WINAPI TextPara_GetLineSpacing(ITextPara *iface, FLOAT *value)
3738 ITextParaImpl *This = impl_from_ITextPara(iface);
3739 FIXME("(%p)->(%p)\n", This, value);
3740 return E_NOTIMPL;
3743 static HRESULT WINAPI TextPara_GetLineSpacingRule(ITextPara *iface, LONG *value)
3745 ITextParaImpl *This = impl_from_ITextPara(iface);
3746 FIXME("(%p)->(%p)\n", This, value);
3747 return E_NOTIMPL;
3750 static HRESULT WINAPI TextPara_GetListAlignment(ITextPara *iface, LONG *value)
3752 ITextParaImpl *This = impl_from_ITextPara(iface);
3753 FIXME("(%p)->(%p)\n", This, value);
3754 return E_NOTIMPL;
3757 static HRESULT WINAPI TextPara_SetListAlignment(ITextPara *iface, LONG value)
3759 ITextParaImpl *This = impl_from_ITextPara(iface);
3760 FIXME("(%p)->(%d)\n", This, value);
3761 return E_NOTIMPL;
3764 static HRESULT WINAPI TextPara_GetListLevelIndex(ITextPara *iface, LONG *value)
3766 ITextParaImpl *This = impl_from_ITextPara(iface);
3767 FIXME("(%p)->(%p)\n", This, value);
3768 return E_NOTIMPL;
3771 static HRESULT WINAPI TextPara_SetListLevelIndex(ITextPara *iface, LONG value)
3773 ITextParaImpl *This = impl_from_ITextPara(iface);
3774 FIXME("(%p)->(%d)\n", This, value);
3775 return E_NOTIMPL;
3778 static HRESULT WINAPI TextPara_GetListStart(ITextPara *iface, LONG *value)
3780 ITextParaImpl *This = impl_from_ITextPara(iface);
3781 FIXME("(%p)->(%p)\n", This, value);
3782 return E_NOTIMPL;
3785 static HRESULT WINAPI TextPara_SetListStart(ITextPara *iface, LONG value)
3787 ITextParaImpl *This = impl_from_ITextPara(iface);
3788 FIXME("(%p)->(%d)\n", This, value);
3789 return E_NOTIMPL;
3792 static HRESULT WINAPI TextPara_GetListTab(ITextPara *iface, FLOAT *value)
3794 ITextParaImpl *This = impl_from_ITextPara(iface);
3795 FIXME("(%p)->(%p)\n", This, value);
3796 return E_NOTIMPL;
3799 static HRESULT WINAPI TextPara_SetListTab(ITextPara *iface, FLOAT value)
3801 ITextParaImpl *This = impl_from_ITextPara(iface);
3802 FIXME("(%p)->(%.2f)\n", This, value);
3803 return E_NOTIMPL;
3806 static HRESULT WINAPI TextPara_GetListType(ITextPara *iface, LONG *value)
3808 ITextParaImpl *This = impl_from_ITextPara(iface);
3809 FIXME("(%p)->(%p)\n", This, value);
3810 return E_NOTIMPL;
3813 static HRESULT WINAPI TextPara_SetListType(ITextPara *iface, LONG value)
3815 ITextParaImpl *This = impl_from_ITextPara(iface);
3816 FIXME("(%p)->(%d)\n", This, value);
3817 return E_NOTIMPL;
3820 static HRESULT WINAPI TextPara_GetNoLineNumber(ITextPara *iface, LONG *value)
3822 ITextParaImpl *This = impl_from_ITextPara(iface);
3823 FIXME("(%p)->(%p)\n", This, value);
3824 return E_NOTIMPL;
3827 static HRESULT WINAPI TextPara_SetNoLineNumber(ITextPara *iface, LONG value)
3829 ITextParaImpl *This = impl_from_ITextPara(iface);
3830 FIXME("(%p)->(%d)\n", This, value);
3831 return E_NOTIMPL;
3834 static HRESULT WINAPI TextPara_GetPageBreakBefore(ITextPara *iface, LONG *value)
3836 ITextParaImpl *This = impl_from_ITextPara(iface);
3837 FIXME("(%p)->(%p)\n", This, value);
3838 return E_NOTIMPL;
3841 static HRESULT WINAPI TextPara_SetPageBreakBefore(ITextPara *iface, LONG value)
3843 ITextParaImpl *This = impl_from_ITextPara(iface);
3844 FIXME("(%p)->(%d)\n", This, value);
3845 return E_NOTIMPL;
3848 static HRESULT WINAPI TextPara_GetRightIndent(ITextPara *iface, FLOAT *value)
3850 ITextParaImpl *This = impl_from_ITextPara(iface);
3851 FIXME("(%p)->(%p)\n", This, value);
3852 return E_NOTIMPL;
3855 static HRESULT WINAPI TextPara_SetRightIndent(ITextPara *iface, FLOAT value)
3857 ITextParaImpl *This = impl_from_ITextPara(iface);
3858 FIXME("(%p)->(%.2f)\n", This, value);
3859 return E_NOTIMPL;
3862 static HRESULT WINAPI TextPara_SetIndents(ITextPara *iface, FLOAT StartIndent, FLOAT LeftIndent, FLOAT RightIndent)
3864 ITextParaImpl *This = impl_from_ITextPara(iface);
3865 FIXME("(%p)->(%.2f %.2f %.2f)\n", This, StartIndent, LeftIndent, RightIndent);
3866 return E_NOTIMPL;
3869 static HRESULT WINAPI TextPara_SetLineSpacing(ITextPara *iface, LONG LineSpacingRule, FLOAT LineSpacing)
3871 ITextParaImpl *This = impl_from_ITextPara(iface);
3872 FIXME("(%p)->(%d %.2f)\n", This, LineSpacingRule, LineSpacing);
3873 return E_NOTIMPL;
3876 static HRESULT WINAPI TextPara_GetSpaceAfter(ITextPara *iface, FLOAT *value)
3878 ITextParaImpl *This = impl_from_ITextPara(iface);
3879 FIXME("(%p)->(%p)\n", This, value);
3880 return E_NOTIMPL;
3883 static HRESULT WINAPI TextPara_SetSpaceAfter(ITextPara *iface, FLOAT value)
3885 ITextParaImpl *This = impl_from_ITextPara(iface);
3886 FIXME("(%p)->(%.2f)\n", This, value);
3887 return E_NOTIMPL;
3890 static HRESULT WINAPI TextPara_GetSpaceBefore(ITextPara *iface, FLOAT *value)
3892 ITextParaImpl *This = impl_from_ITextPara(iface);
3893 FIXME("(%p)->(%p)\n", This, value);
3894 return E_NOTIMPL;
3897 static HRESULT WINAPI TextPara_SetSpaceBefore(ITextPara *iface, FLOAT value)
3899 ITextParaImpl *This = impl_from_ITextPara(iface);
3900 FIXME("(%p)->(%.2f)\n", This, value);
3901 return E_NOTIMPL;
3904 static HRESULT WINAPI TextPara_GetWidowControl(ITextPara *iface, LONG *value)
3906 ITextParaImpl *This = impl_from_ITextPara(iface);
3907 FIXME("(%p)->(%p)\n", This, value);
3908 return E_NOTIMPL;
3911 static HRESULT WINAPI TextPara_SetWidowControl(ITextPara *iface, LONG value)
3913 ITextParaImpl *This = impl_from_ITextPara(iface);
3914 FIXME("(%p)->(%d)\n", This, value);
3915 return E_NOTIMPL;
3918 static HRESULT WINAPI TextPara_GetTabCount(ITextPara *iface, LONG *value)
3920 ITextParaImpl *This = impl_from_ITextPara(iface);
3921 FIXME("(%p)->(%p)\n", This, value);
3922 return E_NOTIMPL;
3925 static HRESULT WINAPI TextPara_AddTab(ITextPara *iface, FLOAT tbPos, LONG tbAlign, LONG tbLeader)
3927 ITextParaImpl *This = impl_from_ITextPara(iface);
3928 FIXME("(%p)->(%.2f %d %d)\n", This, tbPos, tbAlign, tbLeader);
3929 return E_NOTIMPL;
3932 static HRESULT WINAPI TextPara_ClearAllTabs(ITextPara *iface)
3934 ITextParaImpl *This = impl_from_ITextPara(iface);
3935 FIXME("(%p)\n", This);
3936 return E_NOTIMPL;
3939 static HRESULT WINAPI TextPara_DeleteTab(ITextPara *iface, FLOAT pos)
3941 ITextParaImpl *This = impl_from_ITextPara(iface);
3942 FIXME("(%p)->(%.2f)\n", This, pos);
3943 return E_NOTIMPL;
3946 static HRESULT WINAPI TextPara_GetTab(ITextPara *iface, LONG iTab, FLOAT *ptbPos, LONG *ptbAlign, LONG *ptbLeader)
3948 ITextParaImpl *This = impl_from_ITextPara(iface);
3949 FIXME("(%p)->(%d %p %p %p)\n", This, iTab, ptbPos, ptbAlign, ptbLeader);
3950 return E_NOTIMPL;
3953 static ITextParaVtbl textparavtbl = {
3954 TextPara_QueryInterface,
3955 TextPara_AddRef,
3956 TextPara_Release,
3957 TextPara_GetTypeInfoCount,
3958 TextPara_GetTypeInfo,
3959 TextPara_GetIDsOfNames,
3960 TextPara_Invoke,
3961 TextPara_GetDuplicate,
3962 TextPara_SetDuplicate,
3963 TextPara_CanChange,
3964 TextPara_IsEqual,
3965 TextPara_Reset,
3966 TextPara_GetStyle,
3967 TextPara_SetStyle,
3968 TextPara_GetAlignment,
3969 TextPara_SetAlignment,
3970 TextPara_GetHyphenation,
3971 TextPara_SetHyphenation,
3972 TextPara_GetFirstLineIndent,
3973 TextPara_GetKeepTogether,
3974 TextPara_SetKeepTogether,
3975 TextPara_GetKeepWithNext,
3976 TextPara_SetKeepWithNext,
3977 TextPara_GetLeftIndent,
3978 TextPara_GetLineSpacing,
3979 TextPara_GetLineSpacingRule,
3980 TextPara_GetListAlignment,
3981 TextPara_SetListAlignment,
3982 TextPara_GetListLevelIndex,
3983 TextPara_SetListLevelIndex,
3984 TextPara_GetListStart,
3985 TextPara_SetListStart,
3986 TextPara_GetListTab,
3987 TextPara_SetListTab,
3988 TextPara_GetListType,
3989 TextPara_SetListType,
3990 TextPara_GetNoLineNumber,
3991 TextPara_SetNoLineNumber,
3992 TextPara_GetPageBreakBefore,
3993 TextPara_SetPageBreakBefore,
3994 TextPara_GetRightIndent,
3995 TextPara_SetRightIndent,
3996 TextPara_SetIndents,
3997 TextPara_SetLineSpacing,
3998 TextPara_GetSpaceAfter,
3999 TextPara_SetSpaceAfter,
4000 TextPara_GetSpaceBefore,
4001 TextPara_SetSpaceBefore,
4002 TextPara_GetWidowControl,
4003 TextPara_SetWidowControl,
4004 TextPara_GetTabCount,
4005 TextPara_AddTab,
4006 TextPara_ClearAllTabs,
4007 TextPara_DeleteTab,
4008 TextPara_GetTab
4011 static HRESULT create_textpara(ITextRange *range, ITextPara **ret)
4013 ITextParaImpl *para;
4015 *ret = NULL;
4016 para = heap_alloc(sizeof(*para));
4017 if (!para)
4018 return E_OUTOFMEMORY;
4020 para->ITextPara_iface.lpVtbl = &textparavtbl;
4021 para->ref = 1;
4022 para->range = range;
4023 ITextRange_AddRef(range);
4025 *ret = &para->ITextPara_iface;
4026 return S_OK;
4029 /* ITextDocument */
4030 static HRESULT WINAPI ITextDocument2Old_fnQueryInterface(ITextDocument2Old* iface, REFIID riid,
4031 void **ppvObject)
4033 struct text_services *services = impl_from_ITextDocument2Old(iface);
4034 return IUnknown_QueryInterface( services->outer_unk, riid, ppvObject );
4037 static ULONG WINAPI ITextDocument2Old_fnAddRef(ITextDocument2Old *iface)
4039 struct text_services *services = impl_from_ITextDocument2Old(iface);
4040 return IUnknown_AddRef( services->outer_unk );
4043 static ULONG WINAPI ITextDocument2Old_fnRelease(ITextDocument2Old *iface)
4045 struct text_services *services = impl_from_ITextDocument2Old(iface);
4046 return IUnknown_Release( services->outer_unk );
4049 static HRESULT WINAPI ITextDocument2Old_fnGetTypeInfoCount(ITextDocument2Old *iface,
4050 UINT *pctinfo)
4052 struct text_services *services = impl_from_ITextDocument2Old(iface);
4053 TRACE("(%p)->(%p)\n", services, pctinfo);
4054 *pctinfo = 1;
4055 return S_OK;
4058 static HRESULT WINAPI ITextDocument2Old_fnGetTypeInfo(ITextDocument2Old *iface, UINT iTInfo, LCID lcid,
4059 ITypeInfo **ppTInfo)
4061 struct text_services *services = impl_from_ITextDocument2Old(iface);
4062 HRESULT hr;
4064 TRACE("(%p)->(%u,%d,%p)\n", services, iTInfo, lcid, ppTInfo);
4066 hr = get_typeinfo(ITextDocument_tid, ppTInfo);
4067 if (SUCCEEDED(hr))
4068 ITypeInfo_AddRef(*ppTInfo);
4069 return hr;
4072 static HRESULT WINAPI ITextDocument2Old_fnGetIDsOfNames(ITextDocument2Old *iface, REFIID riid,
4073 LPOLESTR *rgszNames, UINT cNames,
4074 LCID lcid, DISPID *rgDispId)
4076 struct text_services *services = impl_from_ITextDocument2Old(iface);
4077 ITypeInfo *ti;
4078 HRESULT hr;
4080 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", services, debugstr_guid(riid),
4081 rgszNames, cNames, lcid, rgDispId);
4083 hr = get_typeinfo(ITextDocument_tid, &ti);
4084 if (SUCCEEDED(hr))
4085 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
4086 return hr;
4089 static HRESULT WINAPI ITextDocument2Old_fnInvoke(ITextDocument2Old *iface, DISPID dispIdMember,
4090 REFIID riid, LCID lcid, WORD wFlags,
4091 DISPPARAMS *pDispParams, VARIANT *pVarResult,
4092 EXCEPINFO *pExcepInfo, UINT *puArgErr)
4094 struct text_services *services = impl_from_ITextDocument2Old(iface);
4095 ITypeInfo *ti;
4096 HRESULT hr;
4098 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", services, dispIdMember,
4099 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
4100 pExcepInfo, puArgErr);
4102 hr = get_typeinfo(ITextDocument_tid, &ti);
4103 if (SUCCEEDED(hr))
4104 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4105 return hr;
4108 static HRESULT WINAPI ITextDocument2Old_fnGetName(ITextDocument2Old *iface, BSTR *pName)
4110 struct text_services *services = impl_from_ITextDocument2Old(iface);
4111 FIXME("stub %p\n", services);
4112 return E_NOTIMPL;
4115 static HRESULT WINAPI ITextDocument2Old_fnGetSelection(ITextDocument2Old *iface, ITextSelection **selection)
4117 struct text_services *services = impl_from_ITextDocument2Old(iface);
4119 TRACE("(%p)->(%p)\n", iface, selection);
4121 if (!selection)
4122 return E_INVALIDARG;
4124 if (!services->text_selection)
4126 services->text_selection = text_selection_create( services );
4127 if (!services->text_selection)
4129 *selection = NULL;
4130 return E_OUTOFMEMORY;
4134 *selection = &services->text_selection->ITextSelection_iface;
4135 ITextSelection_AddRef(*selection);
4136 return S_OK;
4139 static HRESULT WINAPI ITextDocument2Old_fnGetStoryCount(ITextDocument2Old *iface, LONG *pCount)
4141 struct text_services *services = impl_from_ITextDocument2Old(iface);
4142 FIXME("stub %p\n", services);
4143 return E_NOTIMPL;
4146 static HRESULT WINAPI ITextDocument2Old_fnGetStoryRanges(ITextDocument2Old *iface,
4147 ITextStoryRanges **ppStories)
4149 struct text_services *services = impl_from_ITextDocument2Old(iface);
4150 FIXME("stub %p\n", services);
4151 return E_NOTIMPL;
4154 static HRESULT WINAPI ITextDocument2Old_fnGetSaved(ITextDocument2Old *iface, LONG *pValue)
4156 struct text_services *services = impl_from_ITextDocument2Old(iface);
4157 FIXME("stub %p\n", services);
4158 return E_NOTIMPL;
4161 static HRESULT WINAPI ITextDocument2Old_fnSetSaved(ITextDocument2Old *iface, LONG Value)
4163 struct text_services *services = impl_from_ITextDocument2Old(iface);
4164 FIXME("stub %p\n", services);
4165 return E_NOTIMPL;
4168 static HRESULT WINAPI ITextDocument2Old_fnGetDefaultTabStop(ITextDocument2Old *iface, float *pValue)
4170 struct text_services *services = impl_from_ITextDocument2Old(iface);
4171 FIXME("stub %p\n", services);
4172 return E_NOTIMPL;
4175 static HRESULT WINAPI ITextDocument2Old_fnSetDefaultTabStop(ITextDocument2Old *iface, float Value)
4177 struct text_services *services = impl_from_ITextDocument2Old(iface);
4178 FIXME("stub %p\n", services);
4179 return E_NOTIMPL;
4182 static HRESULT WINAPI ITextDocument2Old_fnNew(ITextDocument2Old *iface)
4184 struct text_services *services = impl_from_ITextDocument2Old(iface);
4185 FIXME("stub %p\n", services);
4186 return E_NOTIMPL;
4189 static HRESULT WINAPI ITextDocument2Old_fnOpen(ITextDocument2Old *iface, VARIANT *pVar,
4190 LONG Flags, LONG CodePage)
4192 struct text_services *services = impl_from_ITextDocument2Old(iface);
4193 FIXME("stub %p\n", services);
4194 return E_NOTIMPL;
4197 static HRESULT WINAPI ITextDocument2Old_fnSave(ITextDocument2Old *iface, VARIANT *pVar,
4198 LONG Flags, LONG CodePage)
4200 struct text_services *services = impl_from_ITextDocument2Old(iface);
4201 FIXME("stub %p\n", services);
4202 return E_NOTIMPL;
4205 static HRESULT WINAPI ITextDocument2Old_fnFreeze(ITextDocument2Old *iface, LONG *pCount)
4207 struct text_services *services = impl_from_ITextDocument2Old(iface);
4208 FIXME("stub %p\n", services);
4209 return E_NOTIMPL;
4212 static HRESULT WINAPI ITextDocument2Old_fnUnfreeze(ITextDocument2Old *iface, LONG *pCount)
4214 struct text_services *services = impl_from_ITextDocument2Old(iface);
4215 FIXME("stub %p\n", services);
4216 return E_NOTIMPL;
4219 static HRESULT WINAPI ITextDocument2Old_fnBeginEditCollection(ITextDocument2Old *iface)
4221 struct text_services *services = impl_from_ITextDocument2Old(iface);
4222 FIXME("stub %p\n", services);
4223 return E_NOTIMPL;
4226 static HRESULT WINAPI ITextDocument2Old_fnEndEditCollection(ITextDocument2Old *iface)
4228 struct text_services *services = impl_from_ITextDocument2Old(iface);
4229 FIXME("stub %p\n", services);
4230 return E_NOTIMPL;
4233 static HRESULT WINAPI ITextDocument2Old_fnUndo(ITextDocument2Old *iface, LONG Count, LONG *prop)
4235 struct text_services *services = impl_from_ITextDocument2Old(iface);
4236 FIXME("stub %p\n", services);
4237 return E_NOTIMPL;
4240 static HRESULT WINAPI ITextDocument2Old_fnRedo(ITextDocument2Old *iface, LONG Count, LONG *prop)
4242 struct text_services *services = impl_from_ITextDocument2Old(iface);
4243 FIXME("stub %p\n", services);
4244 return E_NOTIMPL;
4247 static HRESULT CreateITextRange(struct text_services *services, LONG start, LONG end, ITextRange** ppRange)
4249 ITextRangeImpl *txtRge = heap_alloc(sizeof(ITextRangeImpl));
4251 if (!txtRge)
4252 return E_OUTOFMEMORY;
4253 txtRge->ITextRange_iface.lpVtbl = &trvt;
4254 txtRge->ref = 1;
4255 txtRge->child.reole = services;
4256 txtRge->start = start;
4257 txtRge->end = end;
4258 list_add_head( &services->rangelist, &txtRge->child.entry );
4259 *ppRange = &txtRge->ITextRange_iface;
4260 return S_OK;
4263 static HRESULT WINAPI ITextDocument2Old_fnRange(ITextDocument2Old *iface, LONG cp1, LONG cp2,
4264 ITextRange **ppRange)
4266 struct text_services *services = impl_from_ITextDocument2Old(iface);
4268 TRACE("%p %p %d %d\n", services, ppRange, cp1, cp2);
4269 if (!ppRange)
4270 return E_INVALIDARG;
4272 cp2range(services->editor, &cp1, &cp2);
4273 return CreateITextRange(services, cp1, cp2, ppRange);
4276 static HRESULT WINAPI ITextDocument2Old_fnRangeFromPoint(ITextDocument2Old *iface, LONG x, LONG y,
4277 ITextRange **ppRange)
4279 struct text_services *services = impl_from_ITextDocument2Old(iface);
4280 FIXME("stub %p\n", services);
4281 return E_NOTIMPL;
4284 /* ITextDocument2Old methods */
4285 static HRESULT WINAPI ITextDocument2Old_fnAttachMsgFilter(ITextDocument2Old *iface, IUnknown *filter)
4287 struct text_services *services = impl_from_ITextDocument2Old(iface);
4289 FIXME("(%p)->(%p): stub\n", services, filter);
4291 return E_NOTIMPL;
4294 static HRESULT WINAPI ITextDocument2Old_fnSetEffectColor(ITextDocument2Old *iface, LONG index, COLORREF cr)
4296 struct text_services *services = impl_from_ITextDocument2Old(iface);
4298 FIXME("(%p)->(%d, 0x%x): stub\n", services, index, cr);
4300 return E_NOTIMPL;
4303 static HRESULT WINAPI ITextDocument2Old_fnGetEffectColor(ITextDocument2Old *iface, LONG index, COLORREF *cr)
4305 struct text_services *services = impl_from_ITextDocument2Old(iface);
4307 FIXME("(%p)->(%d, %p): stub\n", services, index, cr);
4309 return E_NOTIMPL;
4312 static HRESULT WINAPI ITextDocument2Old_fnGetCaretType(ITextDocument2Old *iface, LONG *type)
4314 struct text_services *services = impl_from_ITextDocument2Old(iface);
4316 FIXME("(%p)->(%p): stub\n", services, type);
4318 return E_NOTIMPL;
4321 static HRESULT WINAPI ITextDocument2Old_fnSetCaretType(ITextDocument2Old *iface, LONG type)
4323 struct text_services *services = impl_from_ITextDocument2Old(iface);
4325 FIXME("(%p)->(%d): stub\n", services, type);
4327 return E_NOTIMPL;
4330 static HRESULT WINAPI ITextDocument2Old_fnGetImmContext(ITextDocument2Old *iface, LONG *context)
4332 struct text_services *services = impl_from_ITextDocument2Old(iface);
4334 FIXME("(%p)->(%p): stub\n", services, context);
4336 return E_NOTIMPL;
4339 static HRESULT WINAPI ITextDocument2Old_fnReleaseImmContext(ITextDocument2Old *iface, LONG context)
4341 struct text_services *services = impl_from_ITextDocument2Old(iface);
4343 FIXME("(%p)->(%d): stub\n", services, context);
4345 return E_NOTIMPL;
4348 static HRESULT WINAPI ITextDocument2Old_fnGetPreferredFont(ITextDocument2Old *iface, LONG cp, LONG charrep,
4349 LONG options, LONG current_charrep, LONG current_fontsize,
4350 BSTR *bstr, LONG *pitch_family, LONG *new_fontsize)
4352 struct text_services *services = impl_from_ITextDocument2Old(iface);
4354 FIXME("(%p)->(%d, %d, %d, %d, %d, %p, %p, %p): stub\n", services, cp, charrep, options, current_charrep,
4355 current_fontsize, bstr, pitch_family, new_fontsize);
4357 return E_NOTIMPL;
4360 static HRESULT WINAPI ITextDocument2Old_fnGetNotificationMode(ITextDocument2Old *iface, LONG *mode)
4362 struct text_services *services = impl_from_ITextDocument2Old(iface);
4364 FIXME("(%p)->(%p): stub\n", services, mode);
4366 return E_NOTIMPL;
4369 static HRESULT WINAPI ITextDocument2Old_fnSetNotificationMode(ITextDocument2Old *iface, LONG mode)
4371 struct text_services *services = impl_from_ITextDocument2Old(iface);
4373 FIXME("(%p)->(0x%x): stub\n", services, mode);
4375 return E_NOTIMPL;
4378 static HRESULT WINAPI ITextDocument2Old_fnGetClientRect(ITextDocument2Old *iface, LONG type, LONG *left, LONG *top,
4379 LONG *right, LONG *bottom)
4381 struct text_services *services = impl_from_ITextDocument2Old(iface);
4383 FIXME("(%p)->(%d, %p, %p, %p, %p): stub\n", services, type, left, top, right, bottom);
4385 return E_NOTIMPL;
4388 static HRESULT WINAPI ITextDocument2Old_fnGetSelectionEx(ITextDocument2Old *iface, ITextSelection **selection)
4390 struct text_services *services = impl_from_ITextDocument2Old(iface);
4392 FIXME("(%p)->(%p): stub\n", services, selection);
4394 return E_NOTIMPL;
4397 static HRESULT WINAPI ITextDocument2Old_fnGetWindow(ITextDocument2Old *iface, LONG *hwnd)
4399 struct text_services *services = impl_from_ITextDocument2Old(iface);
4401 FIXME("(%p)->(%p): stub\n", services, hwnd);
4403 return E_NOTIMPL;
4406 static HRESULT WINAPI ITextDocument2Old_fnGetFEFlags(ITextDocument2Old *iface, LONG *flags)
4408 struct text_services *services = impl_from_ITextDocument2Old(iface);
4410 FIXME("(%p)->(%p): stub\n", services, flags);
4412 return E_NOTIMPL;
4415 static HRESULT WINAPI ITextDocument2Old_fnUpdateWindow(ITextDocument2Old *iface)
4417 struct text_services *services = impl_from_ITextDocument2Old(iface);
4419 FIXME("(%p): stub\n", services);
4421 return E_NOTIMPL;
4424 static HRESULT WINAPI ITextDocument2Old_fnCheckTextLimit(ITextDocument2Old *iface, LONG cch, LONG *exceed)
4426 struct text_services *services = impl_from_ITextDocument2Old(iface);
4428 FIXME("(%p)->(%d, %p): stub\n", services, cch, exceed);
4430 return E_NOTIMPL;
4433 static HRESULT WINAPI ITextDocument2Old_fnIMEInProgress(ITextDocument2Old *iface, LONG mode)
4435 struct text_services *services = impl_from_ITextDocument2Old(iface);
4437 FIXME("(%p)->(0x%x): stub\n", services, mode);
4439 return E_NOTIMPL;
4442 static HRESULT WINAPI ITextDocument2Old_fnSysBeep(ITextDocument2Old *iface)
4444 struct text_services *services = impl_from_ITextDocument2Old(iface);
4446 FIXME("(%p): stub\n", services);
4448 return E_NOTIMPL;
4451 static HRESULT WINAPI ITextDocument2Old_fnUpdate(ITextDocument2Old *iface, LONG mode)
4453 struct text_services *services = impl_from_ITextDocument2Old(iface);
4455 FIXME("(%p)->(0x%x): stub\n", services, mode);
4457 return E_NOTIMPL;
4460 static HRESULT WINAPI ITextDocument2Old_fnNotify(ITextDocument2Old *iface, LONG notify)
4462 struct text_services *services = impl_from_ITextDocument2Old(iface);
4464 FIXME("(%p)->(%d): stub\n", services, notify);
4466 return E_NOTIMPL;
4469 const ITextDocument2OldVtbl text_doc2old_vtbl =
4471 ITextDocument2Old_fnQueryInterface,
4472 ITextDocument2Old_fnAddRef,
4473 ITextDocument2Old_fnRelease,
4474 ITextDocument2Old_fnGetTypeInfoCount,
4475 ITextDocument2Old_fnGetTypeInfo,
4476 ITextDocument2Old_fnGetIDsOfNames,
4477 ITextDocument2Old_fnInvoke,
4478 ITextDocument2Old_fnGetName,
4479 ITextDocument2Old_fnGetSelection,
4480 ITextDocument2Old_fnGetStoryCount,
4481 ITextDocument2Old_fnGetStoryRanges,
4482 ITextDocument2Old_fnGetSaved,
4483 ITextDocument2Old_fnSetSaved,
4484 ITextDocument2Old_fnGetDefaultTabStop,
4485 ITextDocument2Old_fnSetDefaultTabStop,
4486 ITextDocument2Old_fnNew,
4487 ITextDocument2Old_fnOpen,
4488 ITextDocument2Old_fnSave,
4489 ITextDocument2Old_fnFreeze,
4490 ITextDocument2Old_fnUnfreeze,
4491 ITextDocument2Old_fnBeginEditCollection,
4492 ITextDocument2Old_fnEndEditCollection,
4493 ITextDocument2Old_fnUndo,
4494 ITextDocument2Old_fnRedo,
4495 ITextDocument2Old_fnRange,
4496 ITextDocument2Old_fnRangeFromPoint,
4497 /* ITextDocument2Old methods */
4498 ITextDocument2Old_fnAttachMsgFilter,
4499 ITextDocument2Old_fnSetEffectColor,
4500 ITextDocument2Old_fnGetEffectColor,
4501 ITextDocument2Old_fnGetCaretType,
4502 ITextDocument2Old_fnSetCaretType,
4503 ITextDocument2Old_fnGetImmContext,
4504 ITextDocument2Old_fnReleaseImmContext,
4505 ITextDocument2Old_fnGetPreferredFont,
4506 ITextDocument2Old_fnGetNotificationMode,
4507 ITextDocument2Old_fnSetNotificationMode,
4508 ITextDocument2Old_fnGetClientRect,
4509 ITextDocument2Old_fnGetSelectionEx,
4510 ITextDocument2Old_fnGetWindow,
4511 ITextDocument2Old_fnGetFEFlags,
4512 ITextDocument2Old_fnUpdateWindow,
4513 ITextDocument2Old_fnCheckTextLimit,
4514 ITextDocument2Old_fnIMEInProgress,
4515 ITextDocument2Old_fnSysBeep,
4516 ITextDocument2Old_fnUpdate,
4517 ITextDocument2Old_fnNotify
4520 /* ITextSelection */
4521 static HRESULT WINAPI ITextSelection_fnQueryInterface(
4522 ITextSelection *me,
4523 REFIID riid,
4524 void **ppvObj)
4526 struct text_selection *This = impl_from_ITextSelection(me);
4528 *ppvObj = NULL;
4529 if (IsEqualGUID(riid, &IID_IUnknown)
4530 || IsEqualGUID(riid, &IID_IDispatch)
4531 || IsEqualGUID(riid, &IID_ITextRange)
4532 || IsEqualGUID(riid, &IID_ITextSelection))
4534 *ppvObj = me;
4535 ITextSelection_AddRef(me);
4536 return S_OK;
4538 else if (IsEqualGUID(riid, &IID_Igetrichole))
4540 *ppvObj = This->services;
4541 return S_OK;
4544 return E_NOINTERFACE;
4547 static ULONG WINAPI ITextSelection_fnAddRef(ITextSelection *me)
4549 struct text_selection *This = impl_from_ITextSelection(me);
4550 return InterlockedIncrement(&This->ref);
4553 static ULONG WINAPI ITextSelection_fnRelease(ITextSelection *me)
4555 struct text_selection *This = impl_from_ITextSelection(me);
4556 ULONG ref = InterlockedDecrement(&This->ref);
4557 if (ref == 0)
4558 heap_free(This);
4559 return ref;
4562 static HRESULT WINAPI ITextSelection_fnGetTypeInfoCount(ITextSelection *me, UINT *pctinfo)
4564 struct text_selection *This = impl_from_ITextSelection(me);
4565 TRACE("(%p)->(%p)\n", This, pctinfo);
4566 *pctinfo = 1;
4567 return S_OK;
4570 static HRESULT WINAPI ITextSelection_fnGetTypeInfo(ITextSelection *me, UINT iTInfo, LCID lcid,
4571 ITypeInfo **ppTInfo)
4573 struct text_selection *This = impl_from_ITextSelection(me);
4574 HRESULT hr;
4576 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
4578 hr = get_typeinfo(ITextSelection_tid, ppTInfo);
4579 if (SUCCEEDED(hr))
4580 ITypeInfo_AddRef(*ppTInfo);
4581 return hr;
4584 static HRESULT WINAPI ITextSelection_fnGetIDsOfNames(ITextSelection *me, REFIID riid,
4585 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
4587 struct text_selection *This = impl_from_ITextSelection(me);
4588 ITypeInfo *ti;
4589 HRESULT hr;
4591 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
4592 rgDispId);
4594 hr = get_typeinfo(ITextSelection_tid, &ti);
4595 if (SUCCEEDED(hr))
4596 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
4597 return hr;
4600 static HRESULT WINAPI ITextSelection_fnInvoke(
4601 ITextSelection *me,
4602 DISPID dispIdMember,
4603 REFIID riid,
4604 LCID lcid,
4605 WORD wFlags,
4606 DISPPARAMS *pDispParams,
4607 VARIANT *pVarResult,
4608 EXCEPINFO *pExcepInfo,
4609 UINT *puArgErr)
4611 struct text_selection *This = impl_from_ITextSelection(me);
4612 ITypeInfo *ti;
4613 HRESULT hr;
4615 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid), lcid,
4616 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4618 hr = get_typeinfo(ITextSelection_tid, &ti);
4619 if (SUCCEEDED(hr))
4620 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4621 return hr;
4624 /*** ITextRange methods ***/
4625 static HRESULT WINAPI ITextSelection_fnGetText(ITextSelection *me, BSTR *pbstr)
4627 struct text_selection *This = impl_from_ITextSelection(me);
4628 ME_Cursor *start = NULL, *end = NULL;
4629 int nChars, endOfs;
4630 BOOL bEOP;
4632 TRACE("(%p)->(%p)\n", This, pbstr);
4634 if (!This->services)
4635 return CO_E_RELEASED;
4637 if (!pbstr)
4638 return E_INVALIDARG;
4640 ME_GetSelection(This->services->editor, &start, &end);
4641 endOfs = ME_GetCursorOfs(end);
4642 nChars = endOfs - ME_GetCursorOfs(start);
4643 if (!nChars)
4645 *pbstr = NULL;
4646 return S_OK;
4649 *pbstr = SysAllocStringLen(NULL, nChars);
4650 if (!*pbstr)
4651 return E_OUTOFMEMORY;
4653 bEOP = (!para_next( para_next( end->para ) ) && endOfs > ME_GetTextLength(This->services->editor));
4654 ME_GetTextW(This->services->editor, *pbstr, nChars, start, nChars, FALSE, bEOP);
4655 TRACE("%s\n", wine_dbgstr_w(*pbstr));
4657 return S_OK;
4660 static HRESULT WINAPI ITextSelection_fnSetText(ITextSelection *me, BSTR str)
4662 struct text_selection *This = impl_from_ITextSelection(me);
4663 ME_TextEditor *editor;
4664 int len, to, from;
4666 TRACE("(%p)->(%s)\n", This, debugstr_w(str));
4668 if (!This->services)
4669 return CO_E_RELEASED;
4671 editor = This->services->editor;
4672 len = lstrlenW(str);
4673 ME_GetSelectionOfs(editor, &from, &to);
4674 ME_ReplaceSel(editor, FALSE, str, len);
4676 if (len < to - from)
4677 textranges_update_ranges(This->services, from, len, RANGE_UPDATE_DELETE);
4679 return S_OK;
4682 static HRESULT WINAPI ITextSelection_fnGetChar(ITextSelection *me, LONG *pch)
4684 struct text_selection *This = impl_from_ITextSelection(me);
4685 ME_Cursor *start = NULL, *end = NULL;
4687 TRACE("(%p)->(%p)\n", This, pch);
4689 if (!This->services)
4690 return CO_E_RELEASED;
4692 if (!pch)
4693 return E_INVALIDARG;
4695 ME_GetSelection(This->services->editor, &start, &end);
4696 return range_GetChar(This->services->editor, start, pch);
4699 static HRESULT WINAPI ITextSelection_fnSetChar(ITextSelection *me, LONG ch)
4701 struct text_selection *This = impl_from_ITextSelection(me);
4703 FIXME("(%p)->(%x): stub\n", This, ch);
4705 if (!This->services)
4706 return CO_E_RELEASED;
4708 return E_NOTIMPL;
4711 static HRESULT WINAPI ITextSelection_fnGetDuplicate(ITextSelection *me, ITextRange **range)
4713 struct text_selection *This = impl_from_ITextSelection(me);
4714 LONG start, end;
4716 TRACE("(%p)->(%p)\n", This, range);
4718 if (!This->services)
4719 return CO_E_RELEASED;
4721 if (!range)
4722 return E_INVALIDARG;
4724 ITextSelection_GetStart(me, &start);
4725 ITextSelection_GetEnd(me, &end);
4726 return CreateITextRange(This->services, start, end, range);
4729 static HRESULT WINAPI ITextSelection_fnGetFormattedText(ITextSelection *me, ITextRange **range)
4731 struct text_selection *This = impl_from_ITextSelection(me);
4733 FIXME("(%p)->(%p): stub\n", This, range);
4735 if (!This->services)
4736 return CO_E_RELEASED;
4738 return E_NOTIMPL;
4741 static HRESULT WINAPI ITextSelection_fnSetFormattedText(ITextSelection *me, ITextRange *range)
4743 struct text_selection *This = impl_from_ITextSelection(me);
4745 FIXME("(%p)->(%p): stub\n", This, range);
4747 if (!This->services)
4748 return CO_E_RELEASED;
4750 FIXME("not implemented\n");
4751 return E_NOTIMPL;
4754 static HRESULT WINAPI ITextSelection_fnGetStart(ITextSelection *me, LONG *pcpFirst)
4756 struct text_selection *This = impl_from_ITextSelection(me);
4757 LONG lim;
4759 TRACE("(%p)->(%p)\n", This, pcpFirst);
4761 if (!This->services)
4762 return CO_E_RELEASED;
4764 if (!pcpFirst)
4765 return E_INVALIDARG;
4766 ME_GetSelectionOfs(This->services->editor, pcpFirst, &lim);
4767 return S_OK;
4770 static HRESULT WINAPI ITextSelection_fnSetStart(ITextSelection *me, LONG value)
4772 struct text_selection *This = impl_from_ITextSelection(me);
4773 LONG start, end;
4774 HRESULT hr;
4776 TRACE("(%p)->(%d)\n", This, value);
4778 if (!This->services)
4779 return CO_E_RELEASED;
4781 ME_GetSelectionOfs(This->services->editor, &start, &end);
4782 hr = textrange_setstart(This->services, value, &start, &end);
4783 if (hr == S_OK)
4784 set_selection(This->services->editor, start, end);
4786 return hr;
4789 static HRESULT WINAPI ITextSelection_fnGetEnd(ITextSelection *me, LONG *pcpLim)
4791 struct text_selection *This = impl_from_ITextSelection(me);
4792 LONG first;
4794 TRACE("(%p)->(%p)\n", This, pcpLim);
4796 if (!This->services)
4797 return CO_E_RELEASED;
4799 if (!pcpLim)
4800 return E_INVALIDARG;
4801 ME_GetSelectionOfs(This->services->editor, &first, pcpLim);
4802 return S_OK;
4805 static HRESULT WINAPI ITextSelection_fnSetEnd(ITextSelection *me, LONG value)
4807 struct text_selection *This = impl_from_ITextSelection(me);
4808 LONG start, end;
4809 HRESULT hr;
4811 TRACE("(%p)->(%d)\n", This, value);
4813 if (!This->services)
4814 return CO_E_RELEASED;
4816 ME_GetSelectionOfs(This->services->editor, &start, &end);
4817 hr = textrange_setend(This->services, value, &start, &end);
4818 if (hr == S_OK)
4819 set_selection(This->services->editor, start, end);
4821 return hr;
4824 static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **font)
4826 struct text_selection *This = impl_from_ITextSelection(me);
4827 ITextRange *range = NULL;
4828 HRESULT hr;
4830 TRACE("(%p)->(%p)\n", This, font);
4832 if (!This->services)
4833 return CO_E_RELEASED;
4835 if (!font)
4836 return E_INVALIDARG;
4838 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
4839 hr = create_textfont(range, NULL, font);
4840 ITextRange_Release(range);
4841 return hr;
4844 static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *font)
4846 struct text_selection *This = impl_from_ITextSelection(me);
4847 ITextRange *range = NULL;
4849 TRACE("(%p)->(%p)\n", This, font);
4851 if (!font)
4852 return E_INVALIDARG;
4854 if (!This->services)
4855 return CO_E_RELEASED;
4857 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
4858 textrange_set_font(range, font);
4859 ITextRange_Release(range);
4860 return S_OK;
4863 static HRESULT WINAPI ITextSelection_fnGetPara(ITextSelection *me, ITextPara **para)
4865 struct text_selection *This = impl_from_ITextSelection(me);
4866 ITextRange *range = NULL;
4867 HRESULT hr;
4869 TRACE("(%p)->(%p)\n", This, para);
4871 if (!This->services)
4872 return CO_E_RELEASED;
4874 if (!para)
4875 return E_INVALIDARG;
4877 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
4878 hr = create_textpara(range, para);
4879 ITextRange_Release(range);
4880 return hr;
4883 static HRESULT WINAPI ITextSelection_fnSetPara(ITextSelection *me, ITextPara *para)
4885 struct text_selection *This = impl_from_ITextSelection(me);
4887 FIXME("(%p)->(%p): stub\n", This, para);
4889 if (!This->services)
4890 return CO_E_RELEASED;
4892 FIXME("not implemented\n");
4893 return E_NOTIMPL;
4896 static HRESULT WINAPI ITextSelection_fnGetStoryLength(ITextSelection *me, LONG *length)
4898 struct text_selection *This = impl_from_ITextSelection(me);
4900 TRACE("(%p)->(%p)\n", This, length);
4902 if (!This->services)
4903 return CO_E_RELEASED;
4905 return textrange_get_storylength(This->services->editor, length);
4908 static HRESULT WINAPI ITextSelection_fnGetStoryType(ITextSelection *me, LONG *value)
4910 struct text_selection *This = impl_from_ITextSelection(me);
4912 TRACE("(%p)->(%p)\n", This, value);
4914 if (!This->services)
4915 return CO_E_RELEASED;
4917 if (!value)
4918 return E_INVALIDARG;
4920 *value = tomUnknownStory;
4921 return S_OK;
4924 static HRESULT WINAPI ITextSelection_fnCollapse(ITextSelection *me, LONG bStart)
4926 struct text_selection *This = impl_from_ITextSelection(me);
4927 LONG start, end;
4928 HRESULT hres;
4930 TRACE("(%p)->(%d)\n", This, bStart);
4932 if (!This->services)
4933 return CO_E_RELEASED;
4935 ME_GetSelectionOfs(This->services->editor, &start, &end);
4936 hres = range_Collapse(bStart, &start, &end);
4937 if (SUCCEEDED(hres))
4938 set_selection(This->services->editor, start, end);
4939 return hres;
4942 static HRESULT WINAPI ITextSelection_fnExpand(ITextSelection *me, LONG unit, LONG *delta)
4944 struct text_selection *This = impl_from_ITextSelection(me);
4945 ITextRange *range = NULL;
4946 HRESULT hr;
4948 TRACE("(%p)->(%d %p)\n", This, unit, delta);
4950 if (!This->services)
4951 return CO_E_RELEASED;
4953 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
4954 hr = textrange_expand(range, unit, delta);
4955 ITextRange_Release(range);
4956 return hr;
4959 static HRESULT WINAPI ITextSelection_fnGetIndex(ITextSelection *me, LONG unit, LONG *index)
4961 struct text_selection *This = impl_from_ITextSelection(me);
4963 FIXME("(%p)->(%d %p): stub\n", This, unit, index);
4965 if (!This->services)
4966 return CO_E_RELEASED;
4968 return E_NOTIMPL;
4971 static HRESULT WINAPI ITextSelection_fnSetIndex(ITextSelection *me, LONG unit, LONG index,
4972 LONG extend)
4974 struct text_selection *This = impl_from_ITextSelection(me);
4976 FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend);
4978 if (!This->services)
4979 return CO_E_RELEASED;
4981 return E_NOTIMPL;
4984 static HRESULT WINAPI ITextSelection_fnSetRange(ITextSelection *me, LONG anchor, LONG active)
4986 struct text_selection *This = impl_from_ITextSelection(me);
4988 FIXME("(%p)->(%d %d): stub\n", This, anchor, active);
4990 if (!This->services)
4991 return CO_E_RELEASED;
4993 return E_NOTIMPL;
4996 static HRESULT WINAPI ITextSelection_fnInRange(ITextSelection *me, ITextRange *range, LONG *ret)
4998 struct text_selection *This = impl_from_ITextSelection(me);
4999 ITextSelection *selection = NULL;
5000 LONG start, end;
5002 TRACE("(%p)->(%p %p)\n", This, range, ret);
5004 if (ret)
5005 *ret = tomFalse;
5007 if (!This->services)
5008 return CO_E_RELEASED;
5010 if (!range)
5011 return S_FALSE;
5013 ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection);
5014 if (!selection)
5015 return S_FALSE;
5016 ITextSelection_Release(selection);
5018 ITextSelection_GetStart(me, &start);
5019 ITextSelection_GetEnd(me, &end);
5020 return textrange_inrange(start, end, range, ret);
5023 static HRESULT WINAPI ITextSelection_fnInStory(ITextSelection *me, ITextRange *range, LONG *ret)
5025 struct text_selection *This = impl_from_ITextSelection(me);
5027 FIXME("(%p)->(%p %p): stub\n", This, range, ret);
5029 if (!This->services)
5030 return CO_E_RELEASED;
5032 return E_NOTIMPL;
5035 static HRESULT WINAPI ITextSelection_fnIsEqual(ITextSelection *me, ITextRange *range, LONG *ret)
5037 struct text_selection *This = impl_from_ITextSelection(me);
5038 ITextSelection *selection = NULL;
5039 LONG start, end;
5041 TRACE("(%p)->(%p %p)\n", This, range, ret);
5043 if (ret)
5044 *ret = tomFalse;
5046 if (!This->services)
5047 return CO_E_RELEASED;
5049 if (!range)
5050 return S_FALSE;
5052 ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection);
5053 if (!selection)
5054 return S_FALSE;
5055 ITextSelection_Release(selection);
5057 ITextSelection_GetStart(me, &start);
5058 ITextSelection_GetEnd(me, &end);
5059 return textrange_isequal(start, end, range, ret);
5062 static HRESULT WINAPI ITextSelection_fnSelect(ITextSelection *me)
5064 struct text_selection *This = impl_from_ITextSelection(me);
5066 TRACE("(%p)\n", This);
5068 if (!This->services)
5069 return CO_E_RELEASED;
5071 /* nothing to do */
5072 return S_OK;
5075 static HRESULT WINAPI ITextSelection_fnStartOf(ITextSelection *me, LONG unit, LONG extend,
5076 LONG *delta)
5078 struct text_selection *This = impl_from_ITextSelection(me);
5079 ITextRange *range = NULL;
5080 HRESULT hr;
5082 TRACE("(%p)->(%d %d %p)\n", This, unit, extend, delta);
5084 if (!This->services)
5085 return CO_E_RELEASED;
5087 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5088 hr = textrange_startof(range, unit, extend, delta);
5089 ITextRange_Release(range);
5090 return hr;
5093 static HRESULT WINAPI ITextSelection_fnEndOf(ITextSelection *me, LONG unit, LONG extend,
5094 LONG *delta)
5096 struct text_selection *This = impl_from_ITextSelection(me);
5097 ITextRange *range = NULL;
5098 HRESULT hr;
5100 TRACE("(%p)->(%d %d %p)\n", This, unit, extend, delta);
5102 if (!This->services)
5103 return CO_E_RELEASED;
5105 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5106 hr = textrange_endof(range, This->services->editor, unit, extend, delta);
5107 ITextRange_Release(range);
5108 return hr;
5111 static HRESULT WINAPI ITextSelection_fnMove(ITextSelection *me, LONG unit, LONG count, LONG *delta)
5113 struct text_selection *This = impl_from_ITextSelection(me);
5114 ITextRange *range = NULL;
5115 HRESULT hr;
5117 TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta);
5119 if (!This->services)
5120 return CO_E_RELEASED;
5122 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5123 hr = textrange_movestart(range, This->services->editor, unit, count, delta);
5124 ITextRange_Release(range);
5125 return hr;
5128 static HRESULT WINAPI ITextSelection_fnMoveStart(ITextSelection *me, LONG unit, LONG count,
5129 LONG *delta)
5131 struct text_selection *This = impl_from_ITextSelection(me);
5132 ITextRange *range = NULL;
5133 HRESULT hr;
5135 TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta);
5137 if (!This->services)
5138 return CO_E_RELEASED;
5140 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5141 hr = textrange_movestart(range, This->services->editor, unit, count, delta);
5142 ITextRange_Release(range);
5143 return hr;
5146 static HRESULT WINAPI ITextSelection_fnMoveEnd(ITextSelection *me, LONG unit, LONG count,
5147 LONG *delta)
5149 struct text_selection *This = impl_from_ITextSelection(me);
5150 ITextRange *range = NULL;
5151 HRESULT hr;
5153 TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta);
5155 if (!This->services)
5156 return CO_E_RELEASED;
5158 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5159 hr = textrange_moveend(range, This->services->editor, unit, count, delta);
5160 ITextRange_Release(range);
5161 return hr;
5164 static HRESULT WINAPI ITextSelection_fnMoveWhile(ITextSelection *me, VARIANT *charset, LONG count,
5165 LONG *delta)
5167 struct text_selection *This = impl_from_ITextSelection(me);
5169 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
5171 if (!This->services)
5172 return CO_E_RELEASED;
5174 return E_NOTIMPL;
5177 static HRESULT WINAPI ITextSelection_fnMoveStartWhile(ITextSelection *me, VARIANT *charset, LONG count,
5178 LONG *delta)
5180 struct text_selection *This = impl_from_ITextSelection(me);
5182 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
5184 if (!This->services)
5185 return CO_E_RELEASED;
5187 return E_NOTIMPL;
5190 static HRESULT WINAPI ITextSelection_fnMoveEndWhile(ITextSelection *me, VARIANT *charset, LONG count,
5191 LONG *delta)
5193 struct text_selection *This = impl_from_ITextSelection(me);
5195 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
5197 if (!This->services)
5198 return CO_E_RELEASED;
5200 return E_NOTIMPL;
5203 static HRESULT WINAPI ITextSelection_fnMoveUntil(ITextSelection *me, VARIANT *charset, LONG count,
5204 LONG *delta)
5206 struct text_selection *This = impl_from_ITextSelection(me);
5208 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
5210 if (!This->services)
5211 return CO_E_RELEASED;
5213 return E_NOTIMPL;
5216 static HRESULT WINAPI ITextSelection_fnMoveStartUntil(ITextSelection *me, VARIANT *charset, LONG count,
5217 LONG *delta)
5219 struct text_selection *This = impl_from_ITextSelection(me);
5221 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
5223 if (!This->services)
5224 return CO_E_RELEASED;
5226 return E_NOTIMPL;
5229 static HRESULT WINAPI ITextSelection_fnMoveEndUntil(ITextSelection *me, VARIANT *charset, LONG count,
5230 LONG *delta)
5232 struct text_selection *This = impl_from_ITextSelection(me);
5234 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
5236 if (!This->services)
5237 return CO_E_RELEASED;
5239 return E_NOTIMPL;
5242 static HRESULT WINAPI ITextSelection_fnFindText(ITextSelection *me, BSTR text, LONG count, LONG flags,
5243 LONG *length)
5245 struct text_selection *This = impl_from_ITextSelection(me);
5247 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
5249 if (!This->services)
5250 return CO_E_RELEASED;
5252 FIXME("not implemented\n");
5253 return E_NOTIMPL;
5256 static HRESULT WINAPI ITextSelection_fnFindTextStart(ITextSelection *me, BSTR text, LONG count,
5257 LONG flags, LONG *length)
5259 struct text_selection *This = impl_from_ITextSelection(me);
5261 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
5263 if (!This->services)
5264 return CO_E_RELEASED;
5266 return E_NOTIMPL;
5269 static HRESULT WINAPI ITextSelection_fnFindTextEnd(ITextSelection *me, BSTR text, LONG count,
5270 LONG flags, LONG *length)
5272 struct text_selection *This = impl_from_ITextSelection(me);
5274 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
5276 if (!This->services)
5277 return CO_E_RELEASED;
5279 return E_NOTIMPL;
5282 static HRESULT WINAPI ITextSelection_fnDelete(ITextSelection *me, LONG unit, LONG count,
5283 LONG *delta)
5285 struct text_selection *This = impl_from_ITextSelection(me);
5287 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
5289 if (!This->services)
5290 return CO_E_RELEASED;
5292 return E_NOTIMPL;
5295 static HRESULT WINAPI ITextSelection_fnCut(ITextSelection *me, VARIANT *v)
5297 struct text_selection *This = impl_from_ITextSelection(me);
5298 ITextRange *range = NULL;
5299 HRESULT hr;
5301 TRACE("(%p)->(%p): stub\n", This, v);
5303 if (!This->services)
5304 return CO_E_RELEASED;
5306 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5307 hr = textrange_copy_or_cut(range, This->services->editor, TRUE, v);
5308 ITextRange_Release(range);
5309 return hr;
5312 static HRESULT WINAPI ITextSelection_fnCopy(ITextSelection *me, VARIANT *v)
5314 struct text_selection *This = impl_from_ITextSelection(me);
5315 ITextRange *range = NULL;
5316 HRESULT hr;
5318 TRACE("(%p)->(%p)\n", This, v);
5320 if (!This->services)
5321 return CO_E_RELEASED;
5323 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5324 hr = textrange_copy_or_cut(range, This->services->editor, FALSE, v);
5325 ITextRange_Release(range);
5326 return hr;
5329 static HRESULT WINAPI ITextSelection_fnPaste(ITextSelection *me, VARIANT *v, LONG format)
5331 struct text_selection *This = impl_from_ITextSelection(me);
5333 FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format);
5335 if (!This->services)
5336 return CO_E_RELEASED;
5338 return E_NOTIMPL;
5341 static HRESULT WINAPI ITextSelection_fnCanPaste(ITextSelection *me, VARIANT *v, LONG format,
5342 LONG *ret)
5344 struct text_selection *This = impl_from_ITextSelection(me);
5346 FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret);
5348 if (!This->services)
5349 return CO_E_RELEASED;
5351 return E_NOTIMPL;
5354 static HRESULT WINAPI ITextSelection_fnCanEdit(ITextSelection *me, LONG *ret)
5356 struct text_selection *This = impl_from_ITextSelection(me);
5358 FIXME("(%p)->(%p): stub\n", This, ret);
5360 if (!This->services)
5361 return CO_E_RELEASED;
5363 return E_NOTIMPL;
5366 static HRESULT WINAPI ITextSelection_fnChangeCase(ITextSelection *me, LONG type)
5368 struct text_selection *This = impl_from_ITextSelection(me);
5370 FIXME("(%p)->(%d): stub\n", This, type);
5372 if (!This->services)
5373 return CO_E_RELEASED;
5375 return E_NOTIMPL;
5378 static HRESULT WINAPI ITextSelection_fnGetPoint(ITextSelection *me, LONG type, LONG *cx, LONG *cy)
5380 struct text_selection *This = impl_from_ITextSelection(me);
5382 FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy);
5384 if (!This->services)
5385 return CO_E_RELEASED;
5387 return E_NOTIMPL;
5390 static HRESULT WINAPI ITextSelection_fnSetPoint(ITextSelection *me, LONG x, LONG y, LONG type,
5391 LONG extend)
5393 struct text_selection *This = impl_from_ITextSelection(me);
5395 FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend);
5397 if (!This->services)
5398 return CO_E_RELEASED;
5400 return E_NOTIMPL;
5403 static HRESULT WINAPI ITextSelection_fnScrollIntoView(ITextSelection *me, LONG value)
5405 struct text_selection *This = impl_from_ITextSelection(me);
5407 FIXME("(%p)->(%d): stub\n", This, value);
5409 if (!This->services)
5410 return CO_E_RELEASED;
5412 return E_NOTIMPL;
5415 static HRESULT WINAPI ITextSelection_fnGetEmbeddedObject(ITextSelection *me, IUnknown **ppv)
5417 struct text_selection *This = impl_from_ITextSelection(me);
5419 FIXME("(%p)->(%p): stub\n", This, ppv);
5421 if (!This->services)
5422 return CO_E_RELEASED;
5424 return E_NOTIMPL;
5427 /*** ITextSelection methods ***/
5428 static HRESULT WINAPI ITextSelection_fnGetFlags(ITextSelection *me, LONG *flags)
5430 struct text_selection *This = impl_from_ITextSelection(me);
5432 FIXME("(%p)->(%p): stub\n", This, flags);
5434 if (!This->services)
5435 return CO_E_RELEASED;
5437 return E_NOTIMPL;
5440 static HRESULT WINAPI ITextSelection_fnSetFlags(ITextSelection *me, LONG flags)
5442 struct text_selection *This = impl_from_ITextSelection(me);
5444 FIXME("(%p)->(%x): stub\n", This, flags);
5446 if (!This->services)
5447 return CO_E_RELEASED;
5449 return E_NOTIMPL;
5452 static HRESULT WINAPI ITextSelection_fnGetType(ITextSelection *me, LONG *type)
5454 struct text_selection *This = impl_from_ITextSelection(me);
5456 FIXME("(%p)->(%p): stub\n", This, type);
5458 if (!This->services)
5459 return CO_E_RELEASED;
5461 return E_NOTIMPL;
5464 static HRESULT WINAPI ITextSelection_fnMoveLeft(ITextSelection *me, LONG unit, LONG count,
5465 LONG extend, LONG *delta)
5467 struct text_selection *This = impl_from_ITextSelection(me);
5469 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5471 if (!This->services)
5472 return CO_E_RELEASED;
5474 return E_NOTIMPL;
5477 static HRESULT WINAPI ITextSelection_fnMoveRight(ITextSelection *me, LONG unit, LONG count,
5478 LONG extend, LONG *delta)
5480 struct text_selection *This = impl_from_ITextSelection(me);
5482 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5484 if (!This->services)
5485 return CO_E_RELEASED;
5487 return E_NOTIMPL;
5490 static HRESULT WINAPI ITextSelection_fnMoveUp(ITextSelection *me, LONG unit, LONG count,
5491 LONG extend, LONG *delta)
5493 struct text_selection *This = impl_from_ITextSelection(me);
5495 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5497 if (!This->services)
5498 return CO_E_RELEASED;
5500 return E_NOTIMPL;
5503 static HRESULT WINAPI ITextSelection_fnMoveDown(ITextSelection *me, LONG unit, LONG count,
5504 LONG extend, LONG *delta)
5506 struct text_selection *This = impl_from_ITextSelection(me);
5508 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5510 if (!This->services)
5511 return CO_E_RELEASED;
5513 return E_NOTIMPL;
5516 static HRESULT WINAPI ITextSelection_fnHomeKey(ITextSelection *me, LONG unit, LONG extend,
5517 LONG *delta)
5519 struct text_selection *This = impl_from_ITextSelection(me);
5521 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
5523 if (!This->services)
5524 return CO_E_RELEASED;
5526 return E_NOTIMPL;
5529 static HRESULT WINAPI ITextSelection_fnEndKey(ITextSelection *me, LONG unit, LONG extend,
5530 LONG *delta)
5532 struct text_selection *This = impl_from_ITextSelection(me);
5534 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
5536 if (!This->services)
5537 return CO_E_RELEASED;
5539 return E_NOTIMPL;
5542 static HRESULT WINAPI ITextSelection_fnTypeText(ITextSelection *me, BSTR text)
5544 struct text_selection *This = impl_from_ITextSelection(me);
5546 FIXME("(%p)->(%s): stub\n", This, debugstr_w(text));
5548 if (!This->services)
5549 return CO_E_RELEASED;
5551 return E_NOTIMPL;
5554 static const ITextSelectionVtbl tsvt = {
5555 ITextSelection_fnQueryInterface,
5556 ITextSelection_fnAddRef,
5557 ITextSelection_fnRelease,
5558 ITextSelection_fnGetTypeInfoCount,
5559 ITextSelection_fnGetTypeInfo,
5560 ITextSelection_fnGetIDsOfNames,
5561 ITextSelection_fnInvoke,
5562 ITextSelection_fnGetText,
5563 ITextSelection_fnSetText,
5564 ITextSelection_fnGetChar,
5565 ITextSelection_fnSetChar,
5566 ITextSelection_fnGetDuplicate,
5567 ITextSelection_fnGetFormattedText,
5568 ITextSelection_fnSetFormattedText,
5569 ITextSelection_fnGetStart,
5570 ITextSelection_fnSetStart,
5571 ITextSelection_fnGetEnd,
5572 ITextSelection_fnSetEnd,
5573 ITextSelection_fnGetFont,
5574 ITextSelection_fnSetFont,
5575 ITextSelection_fnGetPara,
5576 ITextSelection_fnSetPara,
5577 ITextSelection_fnGetStoryLength,
5578 ITextSelection_fnGetStoryType,
5579 ITextSelection_fnCollapse,
5580 ITextSelection_fnExpand,
5581 ITextSelection_fnGetIndex,
5582 ITextSelection_fnSetIndex,
5583 ITextSelection_fnSetRange,
5584 ITextSelection_fnInRange,
5585 ITextSelection_fnInStory,
5586 ITextSelection_fnIsEqual,
5587 ITextSelection_fnSelect,
5588 ITextSelection_fnStartOf,
5589 ITextSelection_fnEndOf,
5590 ITextSelection_fnMove,
5591 ITextSelection_fnMoveStart,
5592 ITextSelection_fnMoveEnd,
5593 ITextSelection_fnMoveWhile,
5594 ITextSelection_fnMoveStartWhile,
5595 ITextSelection_fnMoveEndWhile,
5596 ITextSelection_fnMoveUntil,
5597 ITextSelection_fnMoveStartUntil,
5598 ITextSelection_fnMoveEndUntil,
5599 ITextSelection_fnFindText,
5600 ITextSelection_fnFindTextStart,
5601 ITextSelection_fnFindTextEnd,
5602 ITextSelection_fnDelete,
5603 ITextSelection_fnCut,
5604 ITextSelection_fnCopy,
5605 ITextSelection_fnPaste,
5606 ITextSelection_fnCanPaste,
5607 ITextSelection_fnCanEdit,
5608 ITextSelection_fnChangeCase,
5609 ITextSelection_fnGetPoint,
5610 ITextSelection_fnSetPoint,
5611 ITextSelection_fnScrollIntoView,
5612 ITextSelection_fnGetEmbeddedObject,
5613 ITextSelection_fnGetFlags,
5614 ITextSelection_fnSetFlags,
5615 ITextSelection_fnGetType,
5616 ITextSelection_fnMoveLeft,
5617 ITextSelection_fnMoveRight,
5618 ITextSelection_fnMoveUp,
5619 ITextSelection_fnMoveDown,
5620 ITextSelection_fnHomeKey,
5621 ITextSelection_fnEndKey,
5622 ITextSelection_fnTypeText
5625 static struct text_selection *text_selection_create(struct text_services *services)
5627 struct text_selection *txtSel = heap_alloc(sizeof *txtSel);
5628 if (!txtSel)
5629 return NULL;
5631 txtSel->ITextSelection_iface.lpVtbl = &tsvt;
5632 txtSel->ref = 1;
5633 txtSel->services = services;
5634 return txtSel;
5637 static void convert_sizel(const ME_Context *c, const SIZEL* szl, SIZE* sz)
5639 /* sizel is in .01 millimeters, sz in pixels */
5640 sz->cx = MulDiv(szl->cx, c->dpi.cx, 2540);
5641 sz->cy = MulDiv(szl->cy, c->dpi.cy, 2540);
5644 /******************************************************************************
5645 * ME_GetOLEObjectSize
5647 * Sets run extent for OLE objects.
5649 void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize)
5651 IDataObject* ido;
5652 FORMATETC fmt;
5653 STGMEDIUM stgm;
5654 DIBSECTION dibsect;
5655 ENHMETAHEADER emh;
5657 assert(run->nFlags & MERF_GRAPHICS);
5658 assert(run->reobj);
5660 if (run->reobj->obj.sizel.cx != 0 || run->reobj->obj.sizel.cy != 0)
5662 convert_sizel(c, &run->reobj->obj.sizel, pSize);
5663 if (c->editor->nZoomNumerator != 0)
5665 pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5666 pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5668 return;
5671 if (!run->reobj->obj.poleobj)
5673 pSize->cx = pSize->cy = 0;
5674 return;
5677 if (IOleObject_QueryInterface(run->reobj->obj.poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
5679 FIXME("Query Interface IID_IDataObject failed!\n");
5680 pSize->cx = pSize->cy = 0;
5681 return;
5683 fmt.cfFormat = CF_BITMAP;
5684 fmt.ptd = NULL;
5685 fmt.dwAspect = DVASPECT_CONTENT;
5686 fmt.lindex = -1;
5687 fmt.tymed = TYMED_GDI;
5688 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5690 fmt.cfFormat = CF_ENHMETAFILE;
5691 fmt.tymed = TYMED_ENHMF;
5692 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5694 FIXME("unsupported format\n");
5695 pSize->cx = pSize->cy = 0;
5696 IDataObject_Release(ido);
5697 return;
5700 IDataObject_Release(ido);
5702 switch (stgm.tymed)
5704 case TYMED_GDI:
5705 GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
5706 pSize->cx = dibsect.dsBm.bmWidth;
5707 pSize->cy = dibsect.dsBm.bmHeight;
5708 break;
5709 case TYMED_ENHMF:
5710 GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
5711 pSize->cx = emh.rclBounds.right - emh.rclBounds.left;
5712 pSize->cy = emh.rclBounds.bottom - emh.rclBounds.top;
5713 break;
5714 default:
5715 FIXME("Unsupported tymed %d\n", stgm.tymed);
5716 break;
5718 ReleaseStgMedium(&stgm);
5719 if (c->editor->nZoomNumerator != 0)
5721 pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5722 pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5726 void draw_ole( ME_Context *c, int x, int y, ME_Run *run, BOOL selected )
5728 IDataObject* ido;
5729 FORMATETC fmt;
5730 STGMEDIUM stgm;
5731 DIBSECTION dibsect;
5732 ENHMETAHEADER emh;
5733 HDC hMemDC;
5734 SIZE sz;
5735 BOOL has_size;
5736 HBITMAP old_bm;
5737 RECT rc;
5739 assert(run->nFlags & MERF_GRAPHICS);
5740 assert(run->reobj);
5741 if (IOleObject_QueryInterface(run->reobj->obj.poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
5743 FIXME("Couldn't get interface\n");
5744 return;
5746 has_size = run->reobj->obj.sizel.cx != 0 || run->reobj->obj.sizel.cy != 0;
5747 fmt.cfFormat = CF_BITMAP;
5748 fmt.ptd = NULL;
5749 fmt.dwAspect = DVASPECT_CONTENT;
5750 fmt.lindex = -1;
5751 fmt.tymed = TYMED_GDI;
5752 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5754 fmt.cfFormat = CF_ENHMETAFILE;
5755 fmt.tymed = TYMED_ENHMF;
5756 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5758 FIXME("Couldn't get storage medium\n");
5759 IDataObject_Release(ido);
5760 return;
5763 IDataObject_Release(ido);
5765 switch (stgm.tymed)
5767 case TYMED_GDI:
5768 GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
5769 hMemDC = CreateCompatibleDC(c->hDC);
5770 old_bm = SelectObject(hMemDC, stgm.u.hBitmap);
5771 if (has_size)
5773 convert_sizel(c, &run->reobj->obj.sizel, &sz);
5774 } else {
5775 sz.cx = dibsect.dsBm.bmWidth;
5776 sz.cy = dibsect.dsBm.bmHeight;
5778 if (c->editor->nZoomNumerator != 0)
5780 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5781 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5783 StretchBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy,
5784 hMemDC, 0, 0, dibsect.dsBm.bmWidth, dibsect.dsBm.bmHeight, SRCCOPY);
5786 SelectObject(hMemDC, old_bm);
5787 DeleteDC(hMemDC);
5788 break;
5789 case TYMED_ENHMF:
5790 GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
5791 if (has_size)
5793 convert_sizel(c, &run->reobj->obj.sizel, &sz);
5794 } else {
5795 sz.cx = emh.rclBounds.right - emh.rclBounds.left;
5796 sz.cy = emh.rclBounds.bottom - emh.rclBounds.top;
5798 if (c->editor->nZoomNumerator != 0)
5800 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5801 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5804 rc.left = x;
5805 rc.top = y - sz.cy;
5806 rc.right = x + sz.cx;
5807 rc.bottom = y;
5808 PlayEnhMetaFile(c->hDC, stgm.u.hEnhMetaFile, &rc);
5809 break;
5810 default:
5811 FIXME("Unsupported tymed %d\n", stgm.tymed);
5812 selected = FALSE;
5813 break;
5815 ReleaseStgMedium(&stgm);
5817 if (selected && !c->editor->bHideSelection)
5818 PatBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy, DSTINVERT);
5821 void ME_DeleteReObject(struct re_object *reobj)
5823 if (reobj->obj.poleobj) IOleObject_Release(reobj->obj.poleobj);
5824 if (reobj->obj.pstg) IStorage_Release(reobj->obj.pstg);
5825 if (reobj->obj.polesite) IOleClientSite_Release(reobj->obj.polesite);
5826 heap_free(reobj);
5829 void ME_CopyReObject(REOBJECT *dst, const REOBJECT *src, DWORD flags)
5831 *dst = *src;
5832 dst->poleobj = NULL;
5833 dst->pstg = NULL;
5834 dst->polesite = NULL;
5836 if ((flags & REO_GETOBJ_POLEOBJ) && src->poleobj)
5838 dst->poleobj = src->poleobj;
5839 IOleObject_AddRef(dst->poleobj);
5841 if ((flags & REO_GETOBJ_PSTG) && src->pstg)
5843 dst->pstg = src->pstg;
5844 IStorage_AddRef(dst->pstg);
5846 if ((flags & REO_GETOBJ_POLESITE) && src->polesite)
5848 dst->polesite = src->polesite;
5849 IOleClientSite_AddRef(dst->polesite);
5853 void richole_release_children( struct text_services *services )
5855 ITextRangeImpl *range;
5856 IOleClientSiteImpl *site;
5858 if (services->text_selection)
5860 services->text_selection->services = NULL;
5861 ITextSelection_Release( &services->text_selection->ITextSelection_iface );
5864 LIST_FOR_EACH_ENTRY( range, &services->rangelist, ITextRangeImpl, child.entry )
5865 range->child.reole = NULL;
5867 LIST_FOR_EACH_ENTRY( site, &services->clientsites, IOleClientSiteImpl, child.entry )
5868 site->child.reole = NULL;