mf/tests: Test AAC decoder MFT presence and media types.
[wine.git] / dlls / riched20 / richole.c
blob8190a4e27533a7bad0e3d92687b92c33baf7044d
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: %08lx\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: %08lx\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 );
650 ME_CommitUndo( services->editor );
651 ME_WrapMarkedParagraphs( services->editor );
652 ME_UpdateScrollBar( services->editor );
656 static HRESULT get_textfont_prop(const ITextFontImpl *font, enum textfont_prop_id propid, textfont_prop_val *value)
658 const struct text_services *services;
659 textfont_prop_val v;
660 LONG start, end, i;
661 HRESULT hr;
663 /* when font is not attached to any range use cached values */
664 if (!font->range || font->get_cache_enabled) {
665 *value = font->props[propid];
666 return S_OK;
669 if (!(services = get_range_reole(font->range)))
670 return CO_E_RELEASED;
672 init_textfont_prop_value(propid, value);
674 ITextRange_GetStart(font->range, &start);
675 ITextRange_GetEnd(font->range, &end);
677 /* iterate trough a range to see if property value is consistent */
678 hr = get_textfont_prop_for_pos( services, start, propid, &v );
679 if (FAILED(hr))
680 return hr;
682 for (i = start + 1; i < end; i++) {
683 textfont_prop_val cur;
685 hr = get_textfont_prop_for_pos( services, i, propid, &cur );
686 if (FAILED(hr))
687 return hr;
689 if (!is_equal_textfont_prop_value(propid, &v, &cur))
690 return S_OK;
693 *value = v;
694 return S_OK;
697 static HRESULT get_textfont_propf(const ITextFontImpl *font, enum textfont_prop_id propid, FLOAT *value)
699 textfont_prop_val v;
700 HRESULT hr;
702 if (!value)
703 return E_INVALIDARG;
705 hr = get_textfont_prop(font, propid, &v);
706 *value = v.f;
707 return hr;
710 static HRESULT get_textfont_propl(const ITextFontImpl *font, enum textfont_prop_id propid, LONG *value)
712 textfont_prop_val v;
713 HRESULT hr;
715 if (!value)
716 return E_INVALIDARG;
718 hr = get_textfont_prop(font, propid, &v);
719 *value = v.l;
720 return hr;
723 /* Value should already have a terminal value, for boolean properties it means tomToggle is not handled */
724 static HRESULT set_textfont_prop(ITextFontImpl *font, enum textfont_prop_id propid, const textfont_prop_val *value)
726 const struct text_services *services;
727 ME_Cursor from, to;
728 CHARFORMAT2W fmt;
729 LONG start, end;
731 /* when font is not attached to any range use cache */
732 if (!font->range || font->set_cache_enabled) {
733 if (propid == FONT_NAME) {
734 SysFreeString(font->props[propid].str);
735 font->props[propid].str = SysAllocString(value->str);
737 else
738 font->props[propid] = *value;
739 return S_OK;
742 if (!(services = get_range_reole(font->range)))
743 return CO_E_RELEASED;
745 memset(&fmt, 0, sizeof(fmt));
746 fmt.cbSize = sizeof(fmt);
747 fmt.dwMask = textfont_prop_masks[propid][0];
749 switch (propid)
751 case FONT_ALLCAPS:
752 case FONT_BOLD:
753 case FONT_EMBOSS:
754 case FONT_HIDDEN:
755 case FONT_ENGRAVE:
756 case FONT_ITALIC:
757 case FONT_OUTLINE:
758 case FONT_PROTECTED:
759 case FONT_SHADOW:
760 case FONT_SMALLCAPS:
761 case FONT_STRIKETHROUGH:
762 case FONT_SUBSCRIPT:
763 case FONT_SUPERSCRIPT:
764 case FONT_UNDERLINE:
765 fmt.dwEffects = value->l == tomTrue ? textfont_prop_masks[propid][1] : 0;
766 break;
767 case FONT_ANIMATION:
768 fmt.bAnimation = value->l;
769 break;
770 case FONT_BACKCOLOR:
771 case FONT_FORECOLOR:
772 if (value->l == tomAutoColor)
773 fmt.dwEffects = textfont_prop_masks[propid][1];
774 else if (propid == FONT_BACKCOLOR)
775 fmt.crBackColor = value->l;
776 else
777 fmt.crTextColor = value->l;
778 break;
779 case FONT_KERNING:
780 fmt.wKerning = value->f;
781 break;
782 case FONT_LANGID:
783 fmt.lcid = value->l;
784 break;
785 case FONT_POSITION:
786 fmt.yOffset = value->f;
787 break;
788 case FONT_SIZE:
789 fmt.yHeight = value->f;
790 break;
791 case FONT_SPACING:
792 fmt.sSpacing = value->f;
793 break;
794 case FONT_WEIGHT:
795 fmt.wWeight = value->l;
796 break;
797 case FONT_NAME:
798 lstrcpynW(fmt.szFaceName, value->str, ARRAY_SIZE(fmt.szFaceName));
799 break;
800 default:
801 FIXME("unhandled font property %d\n", propid);
802 return E_FAIL;
805 ITextRange_GetStart(font->range, &start);
806 ITextRange_GetEnd(font->range, &end);
808 cursor_from_char_ofs( services->editor, start, &from );
809 cursor_from_char_ofs( services->editor, end, &to );
810 ME_SetCharFormat( services->editor, &from, &to, &fmt );
811 ME_CommitUndo( services->editor );
812 ME_WrapMarkedParagraphs( services->editor );
813 ME_UpdateScrollBar( services->editor );
815 return S_OK;
818 static inline HRESULT set_textfont_propl(ITextFontImpl *font, enum textfont_prop_id propid, LONG value)
820 textfont_prop_val v;
821 v.l = value;
822 return set_textfont_prop(font, propid, &v);
825 static inline HRESULT set_textfont_propf(ITextFontImpl *font, enum textfont_prop_id propid, FLOAT value)
827 textfont_prop_val v;
828 v.f = value;
829 return set_textfont_prop(font, propid, &v);
832 static HRESULT set_textfont_propd(ITextFontImpl *font, enum textfont_prop_id propid, LONG value)
834 textfont_prop_val v;
836 switch (value)
838 case tomUndefined:
839 return S_OK;
840 case tomToggle: {
841 LONG oldvalue;
842 get_textfont_propl(font, propid, &oldvalue);
843 if (oldvalue == tomFalse)
844 value = tomTrue;
845 else if (oldvalue == tomTrue)
846 value = tomFalse;
847 else
848 return E_INVALIDARG;
849 /* fallthrough */
851 case tomTrue:
852 case tomFalse:
853 v.l = value;
854 return set_textfont_prop(font, propid, &v);
855 default:
856 return E_INVALIDARG;
860 static HRESULT textfont_getname_from_range(ITextRange *range, BSTR *ret)
862 const struct text_services *services;
863 textfont_prop_val v;
864 HRESULT hr;
865 LONG start;
867 if (!(services = get_range_reole( range )))
868 return CO_E_RELEASED;
870 ITextRange_GetStart(range, &start);
871 hr = get_textfont_prop_for_pos( services, start, FONT_NAME, &v );
872 *ret = v.str;
873 return hr;
876 static void textfont_cache_range_props(ITextFontImpl *font)
878 enum textfont_prop_id propid;
879 for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++) {
880 if (propid == FONT_NAME)
881 textfont_getname_from_range(font->range, &font->props[propid].str);
882 else
883 get_textfont_prop(font, propid, &font->props[propid]);
887 static HRESULT textrange_expand(ITextRange *range, LONG unit, LONG *delta)
889 LONG expand_start, expand_end;
891 switch (unit)
893 case tomStory:
894 expand_start = 0;
895 ITextRange_GetStoryLength(range, &expand_end);
896 break;
897 default:
898 FIXME("unit %ld is not supported\n", unit);
899 return E_NOTIMPL;
902 if (delta) {
903 LONG start, end;
905 ITextRange_GetStart(range, &start);
906 ITextRange_GetEnd(range, &end);
907 *delta = expand_end - expand_start - (end - start);
910 ITextRange_SetStart(range, expand_start);
911 ITextRange_SetEnd(range, expand_end);
913 return S_OK;
916 static HRESULT WINAPI
917 IRichEditOle_fnQueryInterface(IRichEditOle *iface, REFIID riid, LPVOID *ppvObj)
919 struct text_services *services = impl_from_IRichEditOle( iface );
920 return IUnknown_QueryInterface( services->outer_unk, riid, ppvObj );
923 static ULONG WINAPI
924 IRichEditOle_fnAddRef(IRichEditOle *iface)
926 struct text_services *services = impl_from_IRichEditOle( iface );
927 return IUnknown_AddRef( services->outer_unk );
930 static ULONG WINAPI
931 IRichEditOle_fnRelease(IRichEditOle *iface)
933 struct text_services *services = impl_from_IRichEditOle( iface );
934 return IUnknown_Release( services->outer_unk );
937 static HRESULT WINAPI
938 IRichEditOle_fnActivateAs(IRichEditOle *iface, REFCLSID rclsid, REFCLSID rclsidAs)
940 struct text_services *services = impl_from_IRichEditOle( iface );
941 FIXME( "stub %p\n", services );
942 return E_NOTIMPL;
945 static HRESULT WINAPI
946 IRichEditOle_fnContextSensitiveHelp(IRichEditOle *iface, BOOL fEnterMode)
948 struct text_services *services = impl_from_IRichEditOle( iface );
949 FIXME( "stub %p\n", services );
950 return E_NOTIMPL;
953 static HRESULT WINAPI
954 IRichEditOle_fnConvertObject( IRichEditOle *iface, LONG iob, REFCLSID class, LPCSTR user_type )
956 struct text_services *services = impl_from_IRichEditOle( iface );
957 FIXME( "stub %p\n", services );
958 return E_NOTIMPL;
961 static inline IOleClientSiteImpl *impl_from_IOleClientSite(IOleClientSite *iface)
963 return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleClientSite_iface);
966 static HRESULT WINAPI
967 IOleClientSite_fnQueryInterface(IOleClientSite *me, REFIID riid, LPVOID *ppvObj)
969 IOleClientSiteImpl *This = impl_from_IOleClientSite(me);
970 TRACE("%p %s\n", me, debugstr_guid(riid) );
972 *ppvObj = NULL;
973 if (IsEqualGUID(riid, &IID_IUnknown) ||
974 IsEqualGUID(riid, &IID_IOleClientSite))
975 *ppvObj = me;
976 else if (IsEqualGUID(riid, &IID_IOleWindow) ||
977 IsEqualGUID(riid, &IID_IOleInPlaceSite))
978 *ppvObj = &This->IOleInPlaceSite_iface;
979 if (*ppvObj)
981 IOleClientSite_AddRef(me);
982 return S_OK;
984 FIXME("%p: unhandled interface %s\n", me, debugstr_guid(riid) );
986 return E_NOINTERFACE;
989 static ULONG WINAPI IOleClientSite_fnAddRef(IOleClientSite *iface)
991 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
992 ULONG ref = InterlockedIncrement(&This->ref);
993 TRACE("(%p)->(%lu)\n", This, ref);
994 return ref;
997 static ULONG WINAPI IOleClientSite_fnRelease(IOleClientSite *iface)
999 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1000 ULONG ref = InterlockedDecrement(&This->ref);
1002 TRACE("(%p)->(%lu)\n", This, ref);
1004 if (ref == 0) {
1005 if (This->child.reole) {
1006 list_remove(&This->child.entry);
1007 This->child.reole = NULL;
1009 heap_free(This);
1011 return ref;
1014 static HRESULT WINAPI IOleClientSite_fnSaveObject(IOleClientSite *iface)
1016 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1017 if (!This->child.reole)
1018 return CO_E_RELEASED;
1020 FIXME("stub %p\n", iface);
1021 return E_NOTIMPL;
1024 static HRESULT WINAPI IOleClientSite_fnGetMoniker(IOleClientSite *iface, DWORD dwAssign,
1025 DWORD dwWhichMoniker, IMoniker **ppmk)
1027 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1028 if (!This->child.reole)
1029 return CO_E_RELEASED;
1031 FIXME("stub %p\n", iface);
1032 return E_NOTIMPL;
1035 static HRESULT WINAPI IOleClientSite_fnGetContainer(IOleClientSite *iface,
1036 IOleContainer **ppContainer)
1038 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1039 if (!This->child.reole)
1040 return CO_E_RELEASED;
1042 FIXME("stub %p\n", iface);
1043 return E_NOTIMPL;
1046 static HRESULT WINAPI IOleClientSite_fnShowObject(IOleClientSite *iface)
1048 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1049 if (!This->child.reole)
1050 return CO_E_RELEASED;
1052 FIXME("stub %p\n", iface);
1053 return E_NOTIMPL;
1056 static HRESULT WINAPI IOleClientSite_fnOnShowWindow(IOleClientSite *iface, BOOL fShow)
1058 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1059 if (!This->child.reole)
1060 return CO_E_RELEASED;
1062 FIXME("stub %p\n", iface);
1063 return E_NOTIMPL;
1066 static HRESULT WINAPI IOleClientSite_fnRequestNewObjectLayout(IOleClientSite *iface)
1068 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1069 if (!This->child.reole)
1070 return CO_E_RELEASED;
1072 FIXME("stub %p\n", iface);
1073 return E_NOTIMPL;
1076 static const IOleClientSiteVtbl ocst = {
1077 IOleClientSite_fnQueryInterface,
1078 IOleClientSite_fnAddRef,
1079 IOleClientSite_fnRelease,
1080 IOleClientSite_fnSaveObject,
1081 IOleClientSite_fnGetMoniker,
1082 IOleClientSite_fnGetContainer,
1083 IOleClientSite_fnShowObject,
1084 IOleClientSite_fnOnShowWindow,
1085 IOleClientSite_fnRequestNewObjectLayout
1088 /* IOleInPlaceSite interface */
1089 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnQueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppvObj)
1091 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1092 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppvObj);
1095 static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnAddRef(IOleInPlaceSite *iface)
1097 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1098 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1101 static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnRelease(IOleInPlaceSite *iface)
1103 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1104 return IOleClientSite_Release(&This->IOleClientSite_iface);
1107 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindow( IOleInPlaceSite *iface, HWND *window )
1109 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1111 TRACE( "(%p)->(%p)\n", This, window );
1113 if (!This->child.reole)
1114 return CO_E_RELEASED;
1116 if (!window) return E_INVALIDARG;
1118 if (!This->child.reole->editor->have_texthost2) return E_NOTIMPL;
1119 return ITextHost2_TxGetWindow( This->child.reole->editor->texthost, window );
1122 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode)
1124 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1125 FIXME("not implemented: (%p)->(%d)\n", This, fEnterMode);
1126 return E_NOTIMPL;
1129 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnCanInPlaceActivate(IOleInPlaceSite *iface)
1131 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1132 FIXME("not implemented: (%p)\n", This);
1133 return E_NOTIMPL;
1136 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceActivate(IOleInPlaceSite *iface)
1138 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1139 FIXME("not implemented: (%p)\n", This);
1140 return E_NOTIMPL;
1143 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIActivate(IOleInPlaceSite *iface)
1145 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1146 FIXME("not implemented: (%p)\n", This);
1147 return E_NOTIMPL;
1150 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindowContext(IOleInPlaceSite *iface, IOleInPlaceFrame **ppFrame,
1151 IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
1152 LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
1154 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1155 FIXME("not implemented: (%p)->(%p %p %p %p %p)\n", This, ppFrame, ppDoc, lprcPosRect, lprcClipRect, lpFrameInfo);
1156 return E_NOTIMPL;
1159 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnScroll(IOleInPlaceSite *iface, SIZE scrollExtent)
1161 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1162 FIXME("not implemented: (%p)\n", This);
1163 return E_NOTIMPL;
1166 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable)
1168 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1169 FIXME("not implemented: (%p)->(%d)\n", This, fUndoable);
1170 return E_NOTIMPL;
1173 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceDeactivate(IOleInPlaceSite *iface)
1175 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1176 FIXME("not implemented: (%p)\n", This);
1177 return E_NOTIMPL;
1180 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDiscardUndoState(IOleInPlaceSite *iface)
1182 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1183 FIXME("not implemented: (%p)\n", This);
1184 return E_NOTIMPL;
1187 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDeactivateAndUndo(IOleInPlaceSite *iface)
1189 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1190 FIXME("not implemented: (%p)\n", This);
1191 return E_NOTIMPL;
1194 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect)
1196 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1197 FIXME("not implemented: (%p)->(%p)\n", This, lprcPosRect);
1198 return E_NOTIMPL;
1201 static const IOleInPlaceSiteVtbl olestvt =
1203 IOleInPlaceSite_fnQueryInterface,
1204 IOleInPlaceSite_fnAddRef,
1205 IOleInPlaceSite_fnRelease,
1206 IOleInPlaceSite_fnGetWindow,
1207 IOleInPlaceSite_fnContextSensitiveHelp,
1208 IOleInPlaceSite_fnCanInPlaceActivate,
1209 IOleInPlaceSite_fnOnInPlaceActivate,
1210 IOleInPlaceSite_fnOnUIActivate,
1211 IOleInPlaceSite_fnGetWindowContext,
1212 IOleInPlaceSite_fnScroll,
1213 IOleInPlaceSite_fnOnUIDeactivate,
1214 IOleInPlaceSite_fnOnInPlaceDeactivate,
1215 IOleInPlaceSite_fnDiscardUndoState,
1216 IOleInPlaceSite_fnDeactivateAndUndo,
1217 IOleInPlaceSite_fnOnPosRectChange
1220 static HRESULT CreateOleClientSite( struct text_services *services, IOleClientSite **ret )
1222 IOleClientSiteImpl *clientSite = heap_alloc(sizeof *clientSite);
1224 if (!clientSite)
1225 return E_OUTOFMEMORY;
1227 clientSite->IOleClientSite_iface.lpVtbl = &ocst;
1228 clientSite->IOleInPlaceSite_iface.lpVtbl = &olestvt;
1229 clientSite->ref = 1;
1230 clientSite->child.reole = services;
1231 list_add_head( &services->clientsites, &clientSite->child.entry );
1233 *ret = &clientSite->IOleClientSite_iface;
1234 return S_OK;
1237 static HRESULT WINAPI
1238 IRichEditOle_fnGetClientSite( IRichEditOle *iface, IOleClientSite **clientsite )
1240 struct text_services *services = impl_from_IRichEditOle( iface );
1242 TRACE("(%p)->(%p)\n", services, clientsite);
1244 if (!clientsite)
1245 return E_INVALIDARG;
1247 return CreateOleClientSite( services, clientsite );
1250 static HRESULT WINAPI
1251 IRichEditOle_fnGetClipboardData(IRichEditOle *iface, CHARRANGE *lpchrg,
1252 DWORD reco, LPDATAOBJECT *lplpdataobj)
1254 struct text_services *services = impl_from_IRichEditOle( iface );
1255 ME_Cursor start;
1256 int nChars;
1258 TRACE("(%p,%p,%ld)\n", services, lpchrg, reco);
1259 if(!lplpdataobj)
1260 return E_INVALIDARG;
1261 if(!lpchrg)
1263 LONG nFrom, nTo;
1264 int nStartCur = ME_GetSelectionOfs( services->editor, &nFrom, &nTo );
1265 start = services->editor->pCursors[nStartCur];
1266 nChars = nTo - nFrom;
1268 else
1270 cursor_from_char_ofs( services->editor, lpchrg->cpMin, &start );
1271 nChars = lpchrg->cpMax - lpchrg->cpMin;
1273 return ME_GetDataObject( services->editor, &start, nChars, lplpdataobj );
1276 static LONG WINAPI IRichEditOle_fnGetLinkCount(IRichEditOle *iface)
1278 struct text_services *services = impl_from_IRichEditOle( iface );
1279 FIXME("stub %p\n", services);
1280 return E_NOTIMPL;
1283 static HRESULT WINAPI
1284 IRichEditOle_fnGetObject(IRichEditOle *iface, LONG iob,
1285 REOBJECT *lpreobject, DWORD dwFlags)
1287 struct text_services *services = impl_from_IRichEditOle( iface );
1288 struct re_object *reobj = NULL;
1289 LONG count = 0;
1291 TRACE("(%p)->(%lx, %p, %lx)\n", services, iob, lpreobject, dwFlags);
1293 if (!lpreobject || !lpreobject->cbStruct)
1294 return E_INVALIDARG;
1296 if (iob == REO_IOB_USE_CP)
1298 ME_Cursor cursor;
1300 TRACE("character offset: %ld\n", lpreobject->cp);
1301 cursor_from_char_ofs( services->editor, lpreobject->cp, &cursor );
1302 if (!cursor.run->reobj)
1303 return E_INVALIDARG;
1304 else
1305 reobj = cursor.run->reobj;
1307 else if (iob == REO_IOB_SELECTION)
1309 ME_Cursor *from, *to;
1311 ME_GetSelection(services->editor, &from, &to);
1312 if (!from->run->reobj)
1313 return E_INVALIDARG;
1314 else
1315 reobj = from->run->reobj;
1317 else
1319 if (iob < 0 || iob >= IRichEditOle_GetObjectCount( iface ))
1320 return E_INVALIDARG;
1321 LIST_FOR_EACH_ENTRY(reobj, &services->editor->reobj_list, struct re_object, entry)
1323 if (count == iob)
1324 break;
1325 count++;
1328 ME_CopyReObject(lpreobject, &reobj->obj, dwFlags);
1329 lpreobject->cp = run_char_ofs( reobj->run, 0 );
1330 return S_OK;
1333 static LONG WINAPI
1334 IRichEditOle_fnGetObjectCount( IRichEditOle *iface )
1336 struct text_services *services = impl_from_IRichEditOle( iface );
1337 TRACE("(%p)\n", services);
1338 return list_count( &services->editor->reobj_list );
1341 static HRESULT WINAPI
1342 IRichEditOle_fnHandsOffStorage(IRichEditOle *iface, LONG iob)
1344 struct text_services *services = impl_from_IRichEditOle( iface );
1345 FIXME("stub %p\n", services);
1346 return E_NOTIMPL;
1349 static HRESULT WINAPI
1350 IRichEditOle_fnImportDataObject(IRichEditOle *iface, LPDATAOBJECT lpdataobj,
1351 CLIPFORMAT cf, HGLOBAL hMetaPict)
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_fnInPlaceDeactivate(IRichEditOle *iface)
1361 struct text_services *services = impl_from_IRichEditOle( iface );
1362 FIXME("stub %p\n", services);
1363 return E_NOTIMPL;
1366 static HRESULT WINAPI
1367 IRichEditOle_fnInsertObject(IRichEditOle *iface, REOBJECT *reo)
1369 struct text_services *services = impl_from_IRichEditOle( iface );
1370 HRESULT hr;
1372 TRACE("(%p,%p)\n", services, reo);
1374 if (!reo)
1375 return E_INVALIDARG;
1377 if (reo->cbStruct < sizeof(*reo)) return STG_E_INVALIDPARAMETER;
1379 hr = editor_insert_oleobj(services->editor, reo);
1380 if (hr != S_OK)
1381 return hr;
1383 ME_CommitUndo(services->editor);
1384 ME_UpdateRepaint(services->editor, FALSE);
1385 return S_OK;
1388 static HRESULT WINAPI IRichEditOle_fnSaveCompleted(IRichEditOle *iface, LONG iob,
1389 LPSTORAGE lpstg)
1391 struct text_services *services = impl_from_IRichEditOle( iface );
1392 FIXME("stub %p\n", services);
1393 return E_NOTIMPL;
1396 static HRESULT WINAPI
1397 IRichEditOle_fnSetDvaspect(IRichEditOle *iface, LONG iob, DWORD dvaspect)
1399 struct text_services *services = impl_from_IRichEditOle( iface );
1400 FIXME("stub %p\n", services);
1401 return E_NOTIMPL;
1404 static HRESULT WINAPI IRichEditOle_fnSetHostNames(IRichEditOle *iface,
1405 LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj)
1407 struct text_services *services = impl_from_IRichEditOle( iface );
1408 FIXME("stub %p %s %s\n", services, lpstrContainerApp, lpstrContainerObj);
1409 return E_NOTIMPL;
1412 static HRESULT WINAPI
1413 IRichEditOle_fnSetLinkAvailable(IRichEditOle *iface, LONG iob, BOOL fAvailable)
1415 struct text_services *services = impl_from_IRichEditOle( iface );
1416 FIXME("stub %p\n", services);
1417 return E_NOTIMPL;
1420 const IRichEditOleVtbl re_ole_vtbl =
1422 IRichEditOle_fnQueryInterface,
1423 IRichEditOle_fnAddRef,
1424 IRichEditOle_fnRelease,
1425 IRichEditOle_fnGetClientSite,
1426 IRichEditOle_fnGetObjectCount,
1427 IRichEditOle_fnGetLinkCount,
1428 IRichEditOle_fnGetObject,
1429 IRichEditOle_fnInsertObject,
1430 IRichEditOle_fnConvertObject,
1431 IRichEditOle_fnActivateAs,
1432 IRichEditOle_fnSetHostNames,
1433 IRichEditOle_fnSetLinkAvailable,
1434 IRichEditOle_fnSetDvaspect,
1435 IRichEditOle_fnHandsOffStorage,
1436 IRichEditOle_fnSaveCompleted,
1437 IRichEditOle_fnInPlaceDeactivate,
1438 IRichEditOle_fnContextSensitiveHelp,
1439 IRichEditOle_fnGetClipboardData,
1440 IRichEditOle_fnImportDataObject
1443 /* ITextRange interface */
1444 static HRESULT WINAPI ITextRange_fnQueryInterface(ITextRange *me, REFIID riid, void **ppvObj)
1446 ITextRangeImpl *This = impl_from_ITextRange(me);
1448 *ppvObj = NULL;
1449 if (IsEqualGUID(riid, &IID_IUnknown)
1450 || IsEqualGUID(riid, &IID_IDispatch)
1451 || IsEqualGUID(riid, &IID_ITextRange))
1453 *ppvObj = me;
1454 ITextRange_AddRef(me);
1455 return S_OK;
1457 else if (IsEqualGUID(riid, &IID_Igetrichole))
1459 *ppvObj = This->child.reole;
1460 return S_OK;
1463 return E_NOINTERFACE;
1466 static ULONG WINAPI ITextRange_fnAddRef(ITextRange *me)
1468 ITextRangeImpl *This = impl_from_ITextRange(me);
1469 return InterlockedIncrement(&This->ref);
1472 static ULONG WINAPI ITextRange_fnRelease(ITextRange *me)
1474 ITextRangeImpl *This = impl_from_ITextRange(me);
1475 ULONG ref = InterlockedDecrement(&This->ref);
1477 TRACE ("%p ref=%lu\n", This, ref);
1478 if (ref == 0)
1480 if (This->child.reole)
1482 list_remove(&This->child.entry);
1483 This->child.reole = NULL;
1485 heap_free(This);
1487 return ref;
1490 static HRESULT WINAPI ITextRange_fnGetTypeInfoCount(ITextRange *me, UINT *pctinfo)
1492 ITextRangeImpl *This = impl_from_ITextRange(me);
1493 TRACE("(%p)->(%p)\n", This, pctinfo);
1494 *pctinfo = 1;
1495 return S_OK;
1498 static HRESULT WINAPI ITextRange_fnGetTypeInfo(ITextRange *me, UINT iTInfo, LCID lcid,
1499 ITypeInfo **ppTInfo)
1501 ITextRangeImpl *This = impl_from_ITextRange(me);
1502 HRESULT hr;
1504 TRACE("(%p)->(%u,%ld,%p)\n", This, iTInfo, lcid, ppTInfo);
1506 hr = get_typeinfo(ITextRange_tid, ppTInfo);
1507 if (SUCCEEDED(hr))
1508 ITypeInfo_AddRef(*ppTInfo);
1509 return hr;
1512 static HRESULT WINAPI ITextRange_fnGetIDsOfNames(ITextRange *me, REFIID riid, LPOLESTR *rgszNames,
1513 UINT cNames, LCID lcid, DISPID *rgDispId)
1515 ITextRangeImpl *This = impl_from_ITextRange(me);
1516 ITypeInfo *ti;
1517 HRESULT hr;
1519 TRACE("(%p)->(%s, %p, %u, %ld, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
1520 rgDispId);
1522 hr = get_typeinfo(ITextRange_tid, &ti);
1523 if (SUCCEEDED(hr))
1524 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
1525 return hr;
1528 static HRESULT WINAPI ITextRange_fnInvoke(ITextRange *me, DISPID dispIdMember, REFIID riid,
1529 LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1530 VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
1531 UINT *puArgErr)
1533 ITextRangeImpl *This = impl_from_ITextRange(me);
1534 ITypeInfo *ti;
1535 HRESULT hr;
1537 TRACE("(%p)->(%ld, %s, %ld, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
1538 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1540 hr = get_typeinfo(ITextRange_tid, &ti);
1541 if (SUCCEEDED(hr))
1542 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1543 return hr;
1546 static HRESULT WINAPI ITextRange_fnGetText(ITextRange *me, BSTR *str)
1548 ITextRangeImpl *This = impl_from_ITextRange(me);
1549 ME_TextEditor *editor;
1550 ME_Cursor start, end;
1551 int length;
1552 BOOL bEOP;
1554 TRACE("(%p)->(%p)\n", This, str);
1556 if (!This->child.reole)
1557 return CO_E_RELEASED;
1559 if (!str)
1560 return E_INVALIDARG;
1562 /* return early for degenerate range */
1563 if (This->start == This->end) {
1564 *str = NULL;
1565 return S_OK;
1568 editor = This->child.reole->editor;
1569 cursor_from_char_ofs( editor, This->start, &start );
1570 cursor_from_char_ofs( editor, This->end, &end );
1572 length = This->end - This->start;
1573 *str = SysAllocStringLen(NULL, length);
1574 if (!*str)
1575 return E_OUTOFMEMORY;
1577 bEOP = (!para_next( para_next( end.para )) && This->end > ME_GetTextLength(editor));
1578 ME_GetTextW(editor, *str, length, &start, length, FALSE, bEOP);
1579 return S_OK;
1582 static HRESULT WINAPI ITextRange_fnSetText(ITextRange *me, BSTR str)
1584 ITextRangeImpl *This = impl_from_ITextRange(me);
1585 ME_TextEditor *editor;
1586 ME_Cursor cursor;
1587 ME_Style *style;
1588 int len;
1590 TRACE("(%p)->(%s)\n", This, debugstr_w(str));
1592 if (!This->child.reole)
1593 return CO_E_RELEASED;
1595 editor = This->child.reole->editor;
1597 /* delete only where's something to delete */
1598 if (This->start != This->end)
1600 cursor_from_char_ofs( editor, This->start, &cursor );
1601 ME_InternalDeleteText(editor, &cursor, This->end - This->start, FALSE);
1604 if (!str || !*str)
1606 /* will update this range as well */
1607 textranges_update_ranges(This->child.reole, This->start, This->end, RANGE_UPDATE_DELETE);
1608 return S_OK;
1611 /* it's safer not to rely on stored BSTR length */
1612 len = lstrlenW(str);
1613 cursor = editor->pCursors[0];
1614 cursor_from_char_ofs( editor, This->start, &editor->pCursors[0] );
1615 style = style_get_insert_style( editor, editor->pCursors );
1616 ME_InsertTextFromCursor(editor, 0, str, len, style);
1617 ME_ReleaseStyle(style);
1618 editor->pCursors[0] = cursor;
1620 if (len < This->end - This->start)
1621 textranges_update_ranges(This->child.reole, This->start + len, This->end, RANGE_UPDATE_DELETE);
1622 else
1623 This->end = len - This->start;
1625 return S_OK;
1628 static HRESULT range_GetChar(ME_TextEditor *editor, ME_Cursor *cursor, LONG *pch)
1630 WCHAR wch[2];
1632 ME_GetTextW(editor, wch, 1, cursor, 1, FALSE, !para_next( para_next( cursor->para ) ));
1633 *pch = wch[0];
1635 return S_OK;
1638 static HRESULT WINAPI ITextRange_fnGetChar(ITextRange *me, LONG *pch)
1640 ITextRangeImpl *This = impl_from_ITextRange(me);
1641 ME_TextEditor *editor;
1642 ME_Cursor cursor;
1644 TRACE("(%p)->(%p)\n", This, pch);
1646 if (!This->child.reole)
1647 return CO_E_RELEASED;
1649 if (!pch)
1650 return E_INVALIDARG;
1652 editor = This->child.reole->editor;
1653 cursor_from_char_ofs( editor, This->start, &cursor );
1654 return range_GetChar(editor, &cursor, pch);
1657 static HRESULT WINAPI ITextRange_fnSetChar(ITextRange *me, LONG ch)
1659 ITextRangeImpl *This = impl_from_ITextRange(me);
1661 FIXME("(%p)->(%lx): stub\n", This, ch);
1663 if (!This->child.reole)
1664 return CO_E_RELEASED;
1666 return E_NOTIMPL;
1669 static HRESULT CreateITextRange(struct text_services *services, LONG start, LONG end, ITextRange** ppRange);
1671 static HRESULT WINAPI ITextRange_fnGetDuplicate(ITextRange *me, ITextRange **ppRange)
1673 ITextRangeImpl *This = impl_from_ITextRange(me);
1675 TRACE("(%p)->(%p)\n", This, ppRange);
1677 if (!This->child.reole)
1678 return CO_E_RELEASED;
1680 if (!ppRange)
1681 return E_INVALIDARG;
1683 return CreateITextRange(This->child.reole, This->start, This->end, ppRange);
1686 static HRESULT WINAPI ITextRange_fnGetFormattedText(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_fnSetFormattedText(ITextRange *me, ITextRange *range)
1700 ITextRangeImpl *This = impl_from_ITextRange(me);
1702 FIXME("(%p)->(%p): stub\n", This, range);
1704 if (!This->child.reole)
1705 return CO_E_RELEASED;
1707 return E_NOTIMPL;
1710 static HRESULT WINAPI ITextRange_fnGetStart(ITextRange *me, LONG *start)
1712 ITextRangeImpl *This = impl_from_ITextRange(me);
1714 TRACE("(%p)->(%p)\n", This, start);
1716 if (!This->child.reole)
1717 return CO_E_RELEASED;
1719 if (!start)
1720 return E_INVALIDARG;
1722 *start = This->start;
1723 return S_OK;
1726 static HRESULT textrange_setstart(const struct text_services *services, LONG value, LONG *start, LONG *end)
1728 int len;
1730 if (value < 0)
1731 value = 0;
1733 if (value == *start)
1734 return S_FALSE;
1736 if (value <= *end) {
1737 *start = value;
1738 return S_OK;
1741 len = ME_GetTextLength(services->editor);
1742 *start = *end = value > len ? len : value;
1743 return S_OK;
1746 static HRESULT WINAPI ITextRange_fnSetStart(ITextRange *me, LONG value)
1748 ITextRangeImpl *This = impl_from_ITextRange(me);
1750 TRACE("(%p)->(%ld)\n", This, value);
1752 if (!This->child.reole)
1753 return CO_E_RELEASED;
1755 return textrange_setstart(This->child.reole, value, &This->start, &This->end);
1758 static HRESULT WINAPI ITextRange_fnGetEnd(ITextRange *me, LONG *end)
1760 ITextRangeImpl *This = impl_from_ITextRange(me);
1762 TRACE("(%p)->(%p)\n", This, end);
1764 if (!This->child.reole)
1765 return CO_E_RELEASED;
1767 if (!end)
1768 return E_INVALIDARG;
1770 *end = This->end;
1771 return S_OK;
1774 static HRESULT textrange_setend(const struct text_services *services, LONG value, LONG *start, LONG *end)
1776 int len;
1778 if (value == *end)
1779 return S_FALSE;
1781 if (value < *start) {
1782 *start = *end = max(0, value);
1783 return S_OK;
1786 len = ME_GetTextLength( services->editor );
1787 *end = value > len ? len + 1 : value;
1788 return S_OK;
1791 static HRESULT WINAPI ITextRange_fnSetEnd(ITextRange *me, LONG value)
1793 ITextRangeImpl *This = impl_from_ITextRange(me);
1795 TRACE("(%p)->(%ld)\n", This, value);
1797 if (!This->child.reole)
1798 return CO_E_RELEASED;
1800 return textrange_setend(This->child.reole, value, &This->start, &This->end);
1803 static HRESULT WINAPI ITextRange_fnGetFont(ITextRange *me, ITextFont **font)
1805 ITextRangeImpl *This = impl_from_ITextRange(me);
1807 TRACE("(%p)->(%p)\n", This, font);
1809 if (!This->child.reole)
1810 return CO_E_RELEASED;
1812 if (!font)
1813 return E_INVALIDARG;
1815 return create_textfont(me, NULL, font);
1818 static HRESULT WINAPI ITextRange_fnSetFont(ITextRange *me, ITextFont *font)
1820 ITextRangeImpl *This = impl_from_ITextRange(me);
1822 TRACE("(%p)->(%p)\n", This, font);
1824 if (!font)
1825 return E_INVALIDARG;
1827 if (!This->child.reole)
1828 return CO_E_RELEASED;
1830 textrange_set_font(me, font);
1831 return S_OK;
1834 static HRESULT WINAPI ITextRange_fnGetPara(ITextRange *me, ITextPara **para)
1836 ITextRangeImpl *This = impl_from_ITextRange(me);
1838 TRACE("(%p)->(%p)\n", This, para);
1840 if (!This->child.reole)
1841 return CO_E_RELEASED;
1843 if (!para)
1844 return E_INVALIDARG;
1846 return create_textpara(me, para);
1849 static HRESULT WINAPI ITextRange_fnSetPara(ITextRange *me, ITextPara *para)
1851 ITextRangeImpl *This = impl_from_ITextRange(me);
1853 FIXME("(%p)->(%p): stub\n", This, para);
1855 if (!This->child.reole)
1856 return CO_E_RELEASED;
1858 return E_NOTIMPL;
1861 static HRESULT WINAPI ITextRange_fnGetStoryLength(ITextRange *me, LONG *length)
1863 ITextRangeImpl *This = impl_from_ITextRange(me);
1865 TRACE("(%p)->(%p)\n", This, length);
1867 if (!This->child.reole)
1868 return CO_E_RELEASED;
1870 return textrange_get_storylength(This->child.reole->editor, length);
1873 static HRESULT WINAPI ITextRange_fnGetStoryType(ITextRange *me, LONG *value)
1875 ITextRangeImpl *This = impl_from_ITextRange(me);
1877 TRACE("(%p)->(%p)\n", This, value);
1879 if (!This->child.reole)
1880 return CO_E_RELEASED;
1882 if (!value)
1883 return E_INVALIDARG;
1885 *value = tomUnknownStory;
1886 return S_OK;
1889 static HRESULT range_Collapse(LONG bStart, LONG *start, LONG *end)
1891 if (*end == *start)
1892 return S_FALSE;
1894 if (bStart == tomEnd)
1895 *start = *end;
1896 else
1897 *end = *start;
1898 return S_OK;
1901 static HRESULT WINAPI ITextRange_fnCollapse(ITextRange *me, LONG bStart)
1903 ITextRangeImpl *This = impl_from_ITextRange(me);
1905 TRACE("(%p)->(%ld)\n", This, bStart);
1907 if (!This->child.reole)
1908 return CO_E_RELEASED;
1910 return range_Collapse(bStart, &This->start, &This->end);
1913 static HRESULT WINAPI ITextRange_fnExpand(ITextRange *me, LONG unit, LONG *delta)
1915 ITextRangeImpl *This = impl_from_ITextRange(me);
1917 TRACE("(%p)->(%ld %p)\n", This, unit, delta);
1919 if (!This->child.reole)
1920 return CO_E_RELEASED;
1922 return textrange_expand(me, unit, delta);
1925 static HRESULT WINAPI ITextRange_fnGetIndex(ITextRange *me, LONG unit, LONG *index)
1927 ITextRangeImpl *This = impl_from_ITextRange(me);
1929 FIXME("(%p)->(%ld %p): stub\n", This, unit, index);
1931 if (!This->child.reole)
1932 return CO_E_RELEASED;
1934 return E_NOTIMPL;
1937 static HRESULT WINAPI ITextRange_fnSetIndex(ITextRange *me, LONG unit, LONG index,
1938 LONG extend)
1940 ITextRangeImpl *This = impl_from_ITextRange(me);
1942 FIXME("(%p)->(%ld %ld %ld): stub\n", This, unit, index, extend);
1944 if (!This->child.reole)
1945 return CO_E_RELEASED;
1947 return E_NOTIMPL;
1950 static void cp2range(ME_TextEditor *editor, LONG *cp1, LONG *cp2)
1952 int len = ME_GetTextLength(editor) + 1;
1954 *cp1 = max(*cp1, 0);
1955 *cp2 = max(*cp2, 0);
1956 *cp1 = min(*cp1, len);
1957 *cp2 = min(*cp2, len);
1958 if (*cp1 > *cp2)
1960 int tmp = *cp1;
1961 *cp1 = *cp2;
1962 *cp2 = tmp;
1964 if (*cp1 == len)
1965 *cp1 = *cp2 = len - 1;
1968 static HRESULT WINAPI ITextRange_fnSetRange(ITextRange *me, LONG anchor, LONG active)
1970 ITextRangeImpl *This = impl_from_ITextRange(me);
1972 TRACE("(%p)->(%ld %ld)\n", This, anchor, active);
1974 if (!This->child.reole)
1975 return CO_E_RELEASED;
1977 cp2range(This->child.reole->editor, &anchor, &active);
1978 if (anchor == This->start && active == This->end)
1979 return S_FALSE;
1981 This->start = anchor;
1982 This->end = active;
1983 return S_OK;
1986 static HRESULT textrange_inrange(LONG start, LONG end, ITextRange *range, LONG *ret)
1988 LONG from, to, v;
1990 if (!ret)
1991 ret = &v;
1993 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
1994 *ret = tomFalse;
1996 else
1997 *ret = (start >= from && end <= to) ? tomTrue : tomFalse;
1998 return *ret == tomTrue ? S_OK : S_FALSE;
2001 static HRESULT WINAPI ITextRange_fnInRange(ITextRange *me, ITextRange *range, LONG *ret)
2003 ITextRangeImpl *This = impl_from_ITextRange(me);
2005 TRACE("(%p)->(%p %p)\n", This, range, ret);
2007 if (ret)
2008 *ret = tomFalse;
2010 if (!This->child.reole)
2011 return CO_E_RELEASED;
2013 if (!range)
2014 return S_FALSE;
2016 return textrange_inrange(This->start, This->end, range, ret);
2019 static HRESULT WINAPI ITextRange_fnInStory(ITextRange *me, ITextRange *pRange, LONG *ret)
2021 ITextRangeImpl *This = impl_from_ITextRange(me);
2023 FIXME("(%p)->(%p): stub\n", This, ret);
2025 if (!This->child.reole)
2026 return CO_E_RELEASED;
2028 return E_NOTIMPL;
2031 static HRESULT textrange_isequal(LONG start, LONG end, ITextRange *range, LONG *ret)
2033 LONG from, to, v;
2035 if (!ret)
2036 ret = &v;
2038 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
2039 *ret = tomFalse;
2041 else
2042 *ret = (start == from && end == to) ? tomTrue : tomFalse;
2043 return *ret == tomTrue ? S_OK : S_FALSE;
2046 static HRESULT WINAPI ITextRange_fnIsEqual(ITextRange *me, ITextRange *range, LONG *ret)
2048 ITextRangeImpl *This = impl_from_ITextRange(me);
2050 TRACE("(%p)->(%p %p)\n", This, range, ret);
2052 if (ret)
2053 *ret = tomFalse;
2055 if (!This->child.reole)
2056 return CO_E_RELEASED;
2058 if (!range)
2059 return S_FALSE;
2061 return textrange_isequal(This->start, This->end, range, ret);
2064 static HRESULT WINAPI ITextRange_fnSelect(ITextRange *me)
2066 ITextRangeImpl *This = impl_from_ITextRange(me);
2068 TRACE("(%p)\n", This);
2070 if (!This->child.reole)
2071 return CO_E_RELEASED;
2073 set_selection(This->child.reole->editor, This->start, This->end);
2074 return S_OK;
2077 static HRESULT textrange_startof(ITextRange *range, LONG unit, LONG extend, LONG *delta)
2079 HRESULT hr;
2080 LONG start, end;
2081 LONG moved;
2083 ITextRange_GetStart(range, &start);
2084 ITextRange_GetEnd(range, &end);
2086 switch (unit)
2088 case tomCharacter:
2090 moved = 0;
2091 if (extend == tomMove) {
2092 if (start != end) {
2093 ITextRange_SetEnd(range, start);
2094 moved = -1;
2097 if (delta)
2098 *delta = moved;
2099 hr = moved ? S_OK : S_FALSE;
2100 break;
2102 default:
2103 FIXME("unit %ld is not supported\n", unit);
2104 return E_NOTIMPL;
2106 return hr;
2109 static HRESULT WINAPI ITextRange_fnStartOf(ITextRange *me, LONG unit, LONG extend,
2110 LONG *delta)
2112 ITextRangeImpl *This = impl_from_ITextRange(me);
2114 TRACE("(%p)->(%ld %ld %p)\n", This, unit, extend, delta);
2116 if (!This->child.reole)
2117 return CO_E_RELEASED;
2119 return textrange_startof(me, unit, extend, delta);
2122 static HRESULT textrange_endof(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG extend, LONG *delta)
2124 HRESULT hr;
2125 LONG old_start, old_end, new_end;
2126 LONG moved;
2128 ITextRange_GetStart(range, &old_start);
2129 ITextRange_GetEnd(range, &old_end);
2131 switch (unit)
2133 case tomCharacter:
2135 moved = 0;
2136 new_end = old_end;
2137 if (old_end == 0)
2139 ME_Cursor cursor;
2140 cursor_from_char_ofs( editor, old_end, &cursor );
2141 moved = ME_MoveCursorChars(editor, &cursor, 1, TRUE);
2142 new_end = old_end + moved;
2144 else if (extend == tomMove && old_start != old_end)
2145 moved = 1;
2147 ITextRange_SetEnd(range, new_end);
2148 if (extend == tomMove)
2149 ITextRange_SetStart(range, new_end);
2150 if (delta)
2151 *delta = moved;
2152 hr = moved ? S_OK : S_FALSE;
2153 break;
2155 default:
2156 FIXME("unit %ld is not supported\n", unit);
2157 return E_NOTIMPL;
2159 return hr;
2162 static HRESULT WINAPI ITextRange_fnEndOf(ITextRange *me, LONG unit, LONG extend,
2163 LONG *delta)
2165 ITextRangeImpl *This = impl_from_ITextRange(me);
2167 TRACE("(%p)->(%ld %ld %p)\n", This, unit, extend, delta);
2169 if (!This->child.reole)
2170 return CO_E_RELEASED;
2172 return textrange_endof(me, This->child.reole->editor, unit, extend, delta);
2175 static HRESULT textrange_move(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG count, LONG *delta)
2177 LONG old_start, old_end, new_start, new_end;
2178 LONG move_by;
2179 LONG moved;
2180 HRESULT hr = S_OK;
2182 if (!count)
2184 if (delta)
2185 *delta = 0;
2186 return S_FALSE;
2189 ITextRange_GetStart(range, &old_start);
2190 ITextRange_GetEnd(range, &old_end);
2191 switch (unit)
2193 case tomCharacter:
2195 ME_Cursor cursor;
2197 if (count > 0)
2199 cursor_from_char_ofs( editor, old_end, &cursor );
2200 move_by = count;
2201 if (old_start != old_end)
2202 --move_by;
2204 else
2206 cursor_from_char_ofs( editor, old_start, &cursor );
2207 move_by = count;
2208 if (old_start != old_end)
2209 ++move_by;
2211 moved = ME_MoveCursorChars(editor, &cursor, move_by, FALSE);
2212 if (count > 0)
2214 new_end = old_end + moved;
2215 new_start = new_end;
2216 if (old_start != old_end)
2217 ++moved;
2219 else
2221 new_start = old_start + moved;
2222 new_end = new_start;
2223 if (old_start != old_end)
2224 --moved;
2226 if (delta) *delta = moved;
2227 break;
2229 default:
2230 FIXME("unit %ld is not supported\n", unit);
2231 return E_NOTIMPL;
2233 if (moved == 0)
2234 hr = S_FALSE;
2235 ITextRange_SetStart(range, new_start);
2236 ITextRange_SetEnd(range, new_end);
2238 return hr;
2241 static HRESULT WINAPI ITextRange_fnMove(ITextRange *me, LONG unit, LONG count, LONG *delta)
2243 ITextRangeImpl *This = impl_from_ITextRange(me);
2245 TRACE("(%p)->(%ld %ld %p)\n", This, unit, count, delta);
2247 if (!This->child.reole)
2248 return CO_E_RELEASED;
2250 return textrange_move(me, This->child.reole->editor, unit, count, delta);
2253 static HRESULT textrange_movestart(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG count, LONG *delta)
2255 LONG old_start, old_end, new_start, new_end;
2256 HRESULT hr = S_OK;
2258 if (!count)
2260 if (delta)
2261 *delta = 0;
2262 return S_FALSE;
2265 ITextRange_GetStart(range, &old_start);
2266 ITextRange_GetEnd(range, &old_end);
2267 switch (unit)
2269 case tomCharacter:
2271 ME_Cursor cursor;
2272 LONG moved;
2274 cursor_from_char_ofs( editor, old_start, &cursor );
2275 moved = ME_MoveCursorChars(editor, &cursor, count, FALSE);
2276 new_start = old_start + moved;
2277 new_end = old_end;
2278 if (new_end < new_start)
2279 new_end = new_start;
2280 if (delta)
2281 *delta = moved;
2282 break;
2284 default:
2285 FIXME("unit %ld is not supported\n", unit);
2286 return E_NOTIMPL;
2288 if (new_start == old_start)
2289 hr = S_FALSE;
2290 ITextRange_SetStart(range, new_start);
2291 ITextRange_SetEnd(range, new_end);
2293 return hr;
2296 static HRESULT WINAPI ITextRange_fnMoveStart(ITextRange *me, LONG unit, LONG count,
2297 LONG *delta)
2299 ITextRangeImpl *This = impl_from_ITextRange(me);
2301 TRACE("(%p)->(%ld %ld %p)\n", This, unit, count, delta);
2303 if (!This->child.reole)
2304 return CO_E_RELEASED;
2306 return textrange_movestart(me, This->child.reole->editor, unit, count, delta);
2309 static HRESULT textrange_moveend(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG count, LONG *delta)
2311 LONG old_start, old_end, new_start, new_end;
2312 HRESULT hr = S_OK;
2314 if (!count)
2316 if (delta)
2317 *delta = 0;
2318 return S_FALSE;
2321 ITextRange_GetStart(range, &old_start);
2322 ITextRange_GetEnd(range, &old_end);
2323 switch (unit)
2325 case tomCharacter:
2327 ME_Cursor cursor;
2328 LONG moved;
2330 cursor_from_char_ofs( editor, old_end, &cursor );
2331 moved = ME_MoveCursorChars(editor, &cursor, count, TRUE);
2332 new_start = old_start;
2333 new_end = old_end + moved;
2334 if (new_end < new_start)
2335 new_start = new_end;
2336 if (delta)
2337 *delta = moved;
2338 break;
2340 case tomStory:
2341 if (count < 0)
2342 new_start = new_end = 0;
2343 else
2345 new_start = old_start;
2346 ITextRange_GetStoryLength(range, &new_end);
2348 if (delta)
2350 if (new_end < old_end)
2351 *delta = -1;
2352 else if (new_end == old_end)
2353 *delta = 0;
2354 else
2355 *delta = 1;
2357 break;
2358 default:
2359 FIXME("unit %ld is not supported\n", unit);
2360 return E_NOTIMPL;
2362 if (new_end == old_end)
2363 hr = S_FALSE;
2364 ITextRange_SetStart(range, new_start);
2365 ITextRange_SetEnd(range, new_end);
2367 return hr;
2370 static HRESULT WINAPI ITextRange_fnMoveEnd(ITextRange *me, LONG unit, LONG count,
2371 LONG *delta)
2373 ITextRangeImpl *This = impl_from_ITextRange(me);
2375 TRACE("(%p)->(%ld %ld %p)\n", This, unit, count, delta);
2377 if (!This->child.reole)
2378 return CO_E_RELEASED;
2380 return textrange_moveend(me, This->child.reole->editor, unit, count, delta);
2383 static HRESULT WINAPI ITextRange_fnMoveWhile(ITextRange *me, VARIANT *charset, LONG count,
2384 LONG *delta)
2386 ITextRangeImpl *This = impl_from_ITextRange(me);
2388 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
2390 if (!This->child.reole)
2391 return CO_E_RELEASED;
2393 return E_NOTIMPL;
2396 static HRESULT WINAPI ITextRange_fnMoveStartWhile(ITextRange *me, VARIANT *charset, LONG count,
2397 LONG *delta)
2399 ITextRangeImpl *This = impl_from_ITextRange(me);
2401 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
2403 if (!This->child.reole)
2404 return CO_E_RELEASED;
2406 return E_NOTIMPL;
2409 static HRESULT WINAPI ITextRange_fnMoveEndWhile(ITextRange *me, VARIANT *charset, LONG count,
2410 LONG *delta)
2412 ITextRangeImpl *This = impl_from_ITextRange(me);
2414 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
2416 if (!This->child.reole)
2417 return CO_E_RELEASED;
2419 return E_NOTIMPL;
2422 static HRESULT WINAPI ITextRange_fnMoveUntil(ITextRange *me, VARIANT *charset, LONG count,
2423 LONG *delta)
2425 ITextRangeImpl *This = impl_from_ITextRange(me);
2427 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
2429 if (!This->child.reole)
2430 return CO_E_RELEASED;
2432 return E_NOTIMPL;
2435 static HRESULT WINAPI ITextRange_fnMoveStartUntil(ITextRange *me, VARIANT *charset, LONG count,
2436 LONG *delta)
2438 ITextRangeImpl *This = impl_from_ITextRange(me);
2440 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
2442 if (!This->child.reole)
2443 return CO_E_RELEASED;
2445 return E_NOTIMPL;
2448 static HRESULT WINAPI ITextRange_fnMoveEndUntil(ITextRange *me, VARIANT *charset, LONG count,
2449 LONG *delta)
2451 ITextRangeImpl *This = impl_from_ITextRange(me);
2453 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
2455 if (!This->child.reole)
2456 return CO_E_RELEASED;
2458 return E_NOTIMPL;
2461 static HRESULT WINAPI ITextRange_fnFindText(ITextRange *me, BSTR text, LONG count, LONG flags,
2462 LONG *length)
2464 ITextRangeImpl *This = impl_from_ITextRange(me);
2466 FIXME("(%p)->(%s %ld %lx %p): stub\n", This, debugstr_w(text), count, flags, length);
2468 if (!This->child.reole)
2469 return CO_E_RELEASED;
2471 return E_NOTIMPL;
2474 static HRESULT WINAPI ITextRange_fnFindTextStart(ITextRange *me, BSTR text, LONG count,
2475 LONG flags, LONG *length)
2477 ITextRangeImpl *This = impl_from_ITextRange(me);
2479 FIXME("(%p)->(%s %ld %lx %p): stub\n", This, debugstr_w(text), count, flags, length);
2481 if (!This->child.reole)
2482 return CO_E_RELEASED;
2484 return E_NOTIMPL;
2487 static HRESULT WINAPI ITextRange_fnFindTextEnd(ITextRange *me, BSTR text, LONG count,
2488 LONG flags, LONG *length)
2490 ITextRangeImpl *This = impl_from_ITextRange(me);
2492 FIXME("(%p)->(%s %ld %lx %p): stub\n", This, debugstr_w(text), count, flags, length);
2494 if (!This->child.reole)
2495 return CO_E_RELEASED;
2497 return E_NOTIMPL;
2500 static HRESULT WINAPI ITextRange_fnDelete(ITextRange *me, LONG unit, LONG count, LONG *delta)
2502 ITextRangeImpl *This = impl_from_ITextRange(me);
2504 FIXME("(%p)->(%ld %ld %p): stub\n", This, unit, count, delta);
2506 if (!This->child.reole)
2507 return CO_E_RELEASED;
2509 return E_NOTIMPL;
2512 static HRESULT textrange_copy_or_cut( ITextRange *range, ME_TextEditor *editor, BOOL cut, VARIANT *v )
2514 LONG start, end;
2515 ME_Cursor cursor;
2516 IDataObject **data_out = NULL;
2518 ITextRange_GetStart( range, &start );
2519 ITextRange_GetEnd( range, &end );
2520 if (start == end)
2522 /* If the range is empty, all text is copied */
2523 LONG prev_end = end;
2524 ITextRange_SetEnd( range, MAXLONG );
2525 start = 0;
2526 ITextRange_GetEnd( range, &end );
2527 ITextRange_SetEnd( range, prev_end );
2529 cursor_from_char_ofs( editor, start, &cursor );
2531 if (v && V_VT(v) == (VT_UNKNOWN | VT_BYREF) && V_UNKNOWNREF( v ))
2532 data_out = (IDataObject **)V_UNKNOWNREF( v );
2534 return editor_copy_or_cut( editor, cut, &cursor, end - start, data_out );
2537 static HRESULT WINAPI ITextRange_fnCut(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, TRUE, v);
2549 static HRESULT WINAPI ITextRange_fnCopy(ITextRange *me, VARIANT *v)
2551 ITextRangeImpl *This = impl_from_ITextRange(me);
2553 TRACE("(%p)->(%p)\n", This, v);
2555 if (!This->child.reole)
2556 return CO_E_RELEASED;
2558 return textrange_copy_or_cut(me, This->child.reole->editor, FALSE, v);
2561 static HRESULT WINAPI ITextRange_fnPaste(ITextRange *me, VARIANT *v, LONG format)
2563 ITextRangeImpl *This = impl_from_ITextRange(me);
2565 FIXME("(%p)->(%s %lx): stub\n", This, debugstr_variant(v), format);
2567 if (!This->child.reole)
2568 return CO_E_RELEASED;
2570 return E_NOTIMPL;
2573 static HRESULT WINAPI ITextRange_fnCanPaste(ITextRange *me, VARIANT *v, LONG format, LONG *ret)
2575 ITextRangeImpl *This = impl_from_ITextRange(me);
2577 FIXME("(%p)->(%s %lx %p): stub\n", This, debugstr_variant(v), format, ret);
2579 if (!This->child.reole)
2580 return CO_E_RELEASED;
2582 return E_NOTIMPL;
2585 static HRESULT WINAPI ITextRange_fnCanEdit(ITextRange *me, LONG *ret)
2587 ITextRangeImpl *This = impl_from_ITextRange(me);
2589 FIXME("(%p)->(%p): stub\n", This, ret);
2591 if (!This->child.reole)
2592 return CO_E_RELEASED;
2594 return E_NOTIMPL;
2597 static HRESULT WINAPI ITextRange_fnChangeCase(ITextRange *me, LONG type)
2599 ITextRangeImpl *This = impl_from_ITextRange(me);
2601 FIXME("(%p)->(%ld): stub\n", This, type);
2603 if (!This->child.reole)
2604 return CO_E_RELEASED;
2606 return E_NOTIMPL;
2609 static HRESULT WINAPI ITextRange_fnGetPoint(ITextRange *me, LONG type, LONG *cx, LONG *cy)
2611 ITextRangeImpl *This = impl_from_ITextRange(me);
2613 FIXME("(%p)->(%ld %p %p): stub\n", This, type, cx, cy);
2615 if (!This->child.reole)
2616 return CO_E_RELEASED;
2618 return E_NOTIMPL;
2621 static HRESULT WINAPI ITextRange_fnSetPoint(ITextRange *me, LONG x, LONG y, LONG type,
2622 LONG extend)
2624 ITextRangeImpl *This = impl_from_ITextRange(me);
2626 FIXME("(%p)->(%ld %ld %ld %ld): stub\n", This, x, y, type, extend);
2628 if (!This->child.reole)
2629 return CO_E_RELEASED;
2631 return E_NOTIMPL;
2634 static HRESULT WINAPI ITextRange_fnScrollIntoView(ITextRange *me, LONG value)
2636 ITextRangeImpl *This = impl_from_ITextRange(me);
2637 ME_TextEditor *editor;
2638 ME_Cursor cursor;
2639 int x, y, height;
2641 TRACE("(%p)->(%ld)\n", This, value);
2643 if (!This->child.reole)
2644 return CO_E_RELEASED;
2646 editor = This->child.reole->editor;
2648 switch (value)
2650 case tomStart:
2651 cursor_from_char_ofs( editor, This->start, &cursor );
2652 cursor_coords( editor, &cursor, &x, &y, &height );
2653 break;
2654 case tomEnd:
2655 cursor_from_char_ofs( editor, This->end, &cursor );
2656 cursor_coords( editor, &cursor, &x, &y, &height );
2657 break;
2658 default:
2659 FIXME("bStart value %ld not handled\n", value);
2660 return E_NOTIMPL;
2662 scroll_abs( editor, x, y, TRUE );
2663 return S_OK;
2666 static HRESULT WINAPI ITextRange_fnGetEmbeddedObject(ITextRange *me, IUnknown **ppv)
2668 ITextRangeImpl *This = impl_from_ITextRange(me);
2670 FIXME("(%p)->(%p): stub\n", This, ppv);
2672 if (!This->child.reole)
2673 return CO_E_RELEASED;
2675 return E_NOTIMPL;
2678 static const ITextRangeVtbl trvt = {
2679 ITextRange_fnQueryInterface,
2680 ITextRange_fnAddRef,
2681 ITextRange_fnRelease,
2682 ITextRange_fnGetTypeInfoCount,
2683 ITextRange_fnGetTypeInfo,
2684 ITextRange_fnGetIDsOfNames,
2685 ITextRange_fnInvoke,
2686 ITextRange_fnGetText,
2687 ITextRange_fnSetText,
2688 ITextRange_fnGetChar,
2689 ITextRange_fnSetChar,
2690 ITextRange_fnGetDuplicate,
2691 ITextRange_fnGetFormattedText,
2692 ITextRange_fnSetFormattedText,
2693 ITextRange_fnGetStart,
2694 ITextRange_fnSetStart,
2695 ITextRange_fnGetEnd,
2696 ITextRange_fnSetEnd,
2697 ITextRange_fnGetFont,
2698 ITextRange_fnSetFont,
2699 ITextRange_fnGetPara,
2700 ITextRange_fnSetPara,
2701 ITextRange_fnGetStoryLength,
2702 ITextRange_fnGetStoryType,
2703 ITextRange_fnCollapse,
2704 ITextRange_fnExpand,
2705 ITextRange_fnGetIndex,
2706 ITextRange_fnSetIndex,
2707 ITextRange_fnSetRange,
2708 ITextRange_fnInRange,
2709 ITextRange_fnInStory,
2710 ITextRange_fnIsEqual,
2711 ITextRange_fnSelect,
2712 ITextRange_fnStartOf,
2713 ITextRange_fnEndOf,
2714 ITextRange_fnMove,
2715 ITextRange_fnMoveStart,
2716 ITextRange_fnMoveEnd,
2717 ITextRange_fnMoveWhile,
2718 ITextRange_fnMoveStartWhile,
2719 ITextRange_fnMoveEndWhile,
2720 ITextRange_fnMoveUntil,
2721 ITextRange_fnMoveStartUntil,
2722 ITextRange_fnMoveEndUntil,
2723 ITextRange_fnFindText,
2724 ITextRange_fnFindTextStart,
2725 ITextRange_fnFindTextEnd,
2726 ITextRange_fnDelete,
2727 ITextRange_fnCut,
2728 ITextRange_fnCopy,
2729 ITextRange_fnPaste,
2730 ITextRange_fnCanPaste,
2731 ITextRange_fnCanEdit,
2732 ITextRange_fnChangeCase,
2733 ITextRange_fnGetPoint,
2734 ITextRange_fnSetPoint,
2735 ITextRange_fnScrollIntoView,
2736 ITextRange_fnGetEmbeddedObject
2739 /* ITextFont */
2740 static HRESULT WINAPI TextFont_QueryInterface(ITextFont *iface, REFIID riid, void **ppv)
2742 ITextFontImpl *This = impl_from_ITextFont(iface);
2744 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
2746 if (IsEqualIID(riid, &IID_ITextFont) ||
2747 IsEqualIID(riid, &IID_IDispatch) ||
2748 IsEqualIID(riid, &IID_IUnknown))
2750 *ppv = iface;
2751 ITextFont_AddRef(iface);
2752 return S_OK;
2755 *ppv = NULL;
2756 return E_NOINTERFACE;
2759 static ULONG WINAPI TextFont_AddRef(ITextFont *iface)
2761 ITextFontImpl *This = impl_from_ITextFont(iface);
2762 ULONG ref = InterlockedIncrement(&This->ref);
2763 TRACE("(%p)->(%lu)\n", This, ref);
2764 return ref;
2767 static ULONG WINAPI TextFont_Release(ITextFont *iface)
2769 ITextFontImpl *This = impl_from_ITextFont(iface);
2770 ULONG ref = InterlockedDecrement(&This->ref);
2772 TRACE("(%p)->(%lu)\n", This, ref);
2774 if (!ref)
2776 if (This->range)
2777 ITextRange_Release(This->range);
2778 SysFreeString(This->props[FONT_NAME].str);
2779 heap_free(This);
2782 return ref;
2785 static HRESULT WINAPI TextFont_GetTypeInfoCount(ITextFont *iface, UINT *pctinfo)
2787 ITextFontImpl *This = impl_from_ITextFont(iface);
2788 TRACE("(%p)->(%p)\n", This, pctinfo);
2789 *pctinfo = 1;
2790 return S_OK;
2793 static HRESULT WINAPI TextFont_GetTypeInfo(ITextFont *iface, UINT iTInfo, LCID lcid,
2794 ITypeInfo **ppTInfo)
2796 ITextFontImpl *This = impl_from_ITextFont(iface);
2797 HRESULT hr;
2799 TRACE("(%p)->(%u,%ld,%p)\n", This, iTInfo, lcid, ppTInfo);
2801 hr = get_typeinfo(ITextFont_tid, ppTInfo);
2802 if (SUCCEEDED(hr))
2803 ITypeInfo_AddRef(*ppTInfo);
2804 return hr;
2807 static HRESULT WINAPI TextFont_GetIDsOfNames(ITextFont *iface, REFIID riid,
2808 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
2810 ITextFontImpl *This = impl_from_ITextFont(iface);
2811 ITypeInfo *ti;
2812 HRESULT hr;
2814 TRACE("(%p)->(%s, %p, %u, %ld, %p)\n", This, debugstr_guid(riid),
2815 rgszNames, cNames, lcid, rgDispId);
2817 hr = get_typeinfo(ITextFont_tid, &ti);
2818 if (SUCCEEDED(hr))
2819 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
2820 return hr;
2823 static HRESULT WINAPI TextFont_Invoke(
2824 ITextFont *iface,
2825 DISPID dispIdMember,
2826 REFIID riid,
2827 LCID lcid,
2828 WORD wFlags,
2829 DISPPARAMS *pDispParams,
2830 VARIANT *pVarResult,
2831 EXCEPINFO *pExcepInfo,
2832 UINT *puArgErr)
2834 ITextFontImpl *This = impl_from_ITextFont(iface);
2835 ITypeInfo *ti;
2836 HRESULT hr;
2838 TRACE("(%p)->(%ld, %s, %ld, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
2839 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2841 hr = get_typeinfo(ITextFont_tid, &ti);
2842 if (SUCCEEDED(hr))
2843 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2844 return hr;
2847 static HRESULT WINAPI TextFont_GetDuplicate(ITextFont *iface, ITextFont **ret)
2849 ITextFontImpl *This = impl_from_ITextFont(iface);
2851 TRACE("(%p)->(%p)\n", This, ret);
2853 if (!ret)
2854 return E_INVALIDARG;
2856 *ret = NULL;
2857 if (This->range && !get_range_reole(This->range))
2858 return CO_E_RELEASED;
2860 return create_textfont(NULL, This, ret);
2863 static HRESULT WINAPI TextFont_SetDuplicate(ITextFont *iface, ITextFont *pFont)
2865 ITextFontImpl *This = impl_from_ITextFont(iface);
2866 FIXME("(%p)->(%p): stub\n", This, pFont);
2867 return E_NOTIMPL;
2870 static HRESULT WINAPI TextFont_CanChange(ITextFont *iface, LONG *ret)
2872 ITextFontImpl *This = impl_from_ITextFont(iface);
2873 FIXME("(%p)->(%p): stub\n", This, ret);
2874 return E_NOTIMPL;
2877 static HRESULT WINAPI TextFont_IsEqual(ITextFont *iface, ITextFont *font, LONG *ret)
2879 ITextFontImpl *This = impl_from_ITextFont(iface);
2880 FIXME("(%p)->(%p %p): stub\n", This, font, ret);
2881 return E_NOTIMPL;
2884 static void textfont_reset_to_default(ITextFontImpl *font)
2886 enum textfont_prop_id id;
2888 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2889 switch (id)
2891 case FONT_ALLCAPS:
2892 case FONT_ANIMATION:
2893 case FONT_BOLD:
2894 case FONT_EMBOSS:
2895 case FONT_HIDDEN:
2896 case FONT_ENGRAVE:
2897 case FONT_ITALIC:
2898 case FONT_OUTLINE:
2899 case FONT_PROTECTED:
2900 case FONT_SHADOW:
2901 case FONT_SMALLCAPS:
2902 case FONT_STRIKETHROUGH:
2903 case FONT_SUBSCRIPT:
2904 case FONT_SUPERSCRIPT:
2905 case FONT_UNDERLINE:
2906 font->props[id].l = tomFalse;
2907 break;
2908 case FONT_BACKCOLOR:
2909 case FONT_FORECOLOR:
2910 font->props[id].l = tomAutoColor;
2911 break;
2912 case FONT_KERNING:
2913 case FONT_POSITION:
2914 case FONT_SIZE:
2915 case FONT_SPACING:
2916 font->props[id].f = 0.0;
2917 break;
2918 case FONT_LANGID:
2919 font->props[id].l = GetSystemDefaultLCID();
2920 break;
2921 case FONT_NAME: {
2922 SysFreeString(font->props[id].str);
2923 font->props[id].str = SysAllocString(L"System");
2924 break;
2926 case FONT_WEIGHT:
2927 font->props[id].l = FW_NORMAL;
2928 break;
2929 default:
2930 FIXME("font property %d not handled\n", id);
2935 static void textfont_reset_to_undefined(ITextFontImpl *font)
2937 enum textfont_prop_id id;
2939 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2940 switch (id)
2942 case FONT_ALLCAPS:
2943 case FONT_ANIMATION:
2944 case FONT_BOLD:
2945 case FONT_EMBOSS:
2946 case FONT_HIDDEN:
2947 case FONT_ENGRAVE:
2948 case FONT_ITALIC:
2949 case FONT_OUTLINE:
2950 case FONT_PROTECTED:
2951 case FONT_SHADOW:
2952 case FONT_SMALLCAPS:
2953 case FONT_STRIKETHROUGH:
2954 case FONT_SUBSCRIPT:
2955 case FONT_SUPERSCRIPT:
2956 case FONT_UNDERLINE:
2957 case FONT_BACKCOLOR:
2958 case FONT_FORECOLOR:
2959 case FONT_LANGID:
2960 case FONT_WEIGHT:
2961 font->props[id].l = tomUndefined;
2962 break;
2963 case FONT_KERNING:
2964 case FONT_POSITION:
2965 case FONT_SIZE:
2966 case FONT_SPACING:
2967 font->props[id].f = tomUndefined;
2968 break;
2969 case FONT_NAME:
2970 break;
2971 default:
2972 FIXME("font property %d not handled\n", id);
2977 static void textfont_apply_range_props(ITextFontImpl *font)
2979 enum textfont_prop_id propid;
2980 for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++)
2981 set_textfont_prop(font, propid, &font->props[propid]);
2984 static HRESULT WINAPI TextFont_Reset(ITextFont *iface, LONG value)
2986 ITextFontImpl *This = impl_from_ITextFont(iface);
2988 TRACE("(%p)->(%ld)\n", This, value);
2990 /* If font is attached to a range, released or not, we can't
2991 reset to undefined */
2992 if (This->range) {
2993 if (!get_range_reole(This->range))
2994 return CO_E_RELEASED;
2996 switch (value)
2998 case tomUndefined:
2999 return E_INVALIDARG;
3000 case tomCacheParms:
3001 textfont_cache_range_props(This);
3002 This->get_cache_enabled = TRUE;
3003 break;
3004 case tomTrackParms:
3005 This->get_cache_enabled = FALSE;
3006 break;
3007 case tomApplyLater:
3008 This->set_cache_enabled = TRUE;
3009 break;
3010 case tomApplyNow:
3011 This->set_cache_enabled = FALSE;
3012 textfont_apply_range_props(This);
3013 break;
3014 case tomUsePoints:
3015 case tomUseTwips:
3016 return E_INVALIDARG;
3017 default:
3018 FIXME("reset mode %ld not supported\n", value);
3021 return S_OK;
3023 else {
3024 switch (value)
3026 /* reset to global defaults */
3027 case tomDefault:
3028 textfont_reset_to_default(This);
3029 return S_OK;
3030 /* all properties are set to tomUndefined, font name is retained */
3031 case tomUndefined:
3032 textfont_reset_to_undefined(This);
3033 return S_OK;
3034 case tomApplyNow:
3035 case tomApplyLater:
3036 case tomTrackParms:
3037 case tomCacheParms:
3038 return S_OK;
3039 case tomUsePoints:
3040 case tomUseTwips:
3041 return E_INVALIDARG;
3045 FIXME("reset mode %ld not supported\n", value);
3046 return E_NOTIMPL;
3049 static HRESULT WINAPI TextFont_GetStyle(ITextFont *iface, LONG *value)
3051 ITextFontImpl *This = impl_from_ITextFont(iface);
3052 FIXME("(%p)->(%p): stub\n", This, value);
3053 return E_NOTIMPL;
3056 static HRESULT WINAPI TextFont_SetStyle(ITextFont *iface, LONG value)
3058 ITextFontImpl *This = impl_from_ITextFont(iface);
3059 FIXME("(%p)->(%ld): stub\n", This, value);
3060 return E_NOTIMPL;
3063 static HRESULT WINAPI TextFont_GetAllCaps(ITextFont *iface, LONG *value)
3065 ITextFontImpl *This = impl_from_ITextFont(iface);
3066 TRACE("(%p)->(%p)\n", This, value);
3067 return get_textfont_propl(This, FONT_ALLCAPS, value);
3070 static HRESULT WINAPI TextFont_SetAllCaps(ITextFont *iface, LONG value)
3072 ITextFontImpl *This = impl_from_ITextFont(iface);
3073 TRACE("(%p)->(%ld)\n", This, value);
3074 return set_textfont_propd(This, FONT_ALLCAPS, value);
3077 static HRESULT WINAPI TextFont_GetAnimation(ITextFont *iface, LONG *value)
3079 ITextFontImpl *This = impl_from_ITextFont(iface);
3080 TRACE("(%p)->(%p)\n", This, value);
3081 return get_textfont_propl(This, FONT_ANIMATION, value);
3084 static HRESULT WINAPI TextFont_SetAnimation(ITextFont *iface, LONG value)
3086 ITextFontImpl *This = impl_from_ITextFont(iface);
3088 TRACE("(%p)->(%ld)\n", This, value);
3090 if (value < tomNoAnimation || value > tomAnimationMax)
3091 return E_INVALIDARG;
3093 return set_textfont_propl(This, FONT_ANIMATION, value);
3096 static HRESULT WINAPI TextFont_GetBackColor(ITextFont *iface, LONG *value)
3098 ITextFontImpl *This = impl_from_ITextFont(iface);
3099 TRACE("(%p)->(%p)\n", This, value);
3100 return get_textfont_propl(This, FONT_BACKCOLOR, value);
3103 static HRESULT WINAPI TextFont_SetBackColor(ITextFont *iface, LONG value)
3105 ITextFontImpl *This = impl_from_ITextFont(iface);
3106 TRACE("(%p)->(%ld)\n", This, value);
3107 return set_textfont_propl(This, FONT_BACKCOLOR, value);
3110 static HRESULT WINAPI TextFont_GetBold(ITextFont *iface, LONG *value)
3112 ITextFontImpl *This = impl_from_ITextFont(iface);
3113 TRACE("(%p)->(%p)\n", This, value);
3114 return get_textfont_propl(This, FONT_BOLD, value);
3117 static HRESULT WINAPI TextFont_SetBold(ITextFont *iface, LONG value)
3119 ITextFontImpl *This = impl_from_ITextFont(iface);
3120 TRACE("(%p)->(%ld)\n", This, value);
3121 return set_textfont_propd(This, FONT_BOLD, value);
3124 static HRESULT WINAPI TextFont_GetEmboss(ITextFont *iface, LONG *value)
3126 ITextFontImpl *This = impl_from_ITextFont(iface);
3127 TRACE("(%p)->(%p)\n", This, value);
3128 return get_textfont_propl(This, FONT_EMBOSS, value);
3131 static HRESULT WINAPI TextFont_SetEmboss(ITextFont *iface, LONG value)
3133 ITextFontImpl *This = impl_from_ITextFont(iface);
3134 TRACE("(%p)->(%ld)\n", This, value);
3135 return set_textfont_propd(This, FONT_EMBOSS, value);
3138 static HRESULT WINAPI TextFont_GetForeColor(ITextFont *iface, LONG *value)
3140 ITextFontImpl *This = impl_from_ITextFont(iface);
3141 TRACE("(%p)->(%p)\n", This, value);
3142 return get_textfont_propl(This, FONT_FORECOLOR, value);
3145 static HRESULT WINAPI TextFont_SetForeColor(ITextFont *iface, LONG value)
3147 ITextFontImpl *This = impl_from_ITextFont(iface);
3148 TRACE("(%p)->(%ld)\n", This, value);
3149 return set_textfont_propl(This, FONT_FORECOLOR, value);
3152 static HRESULT WINAPI TextFont_GetHidden(ITextFont *iface, LONG *value)
3154 ITextFontImpl *This = impl_from_ITextFont(iface);
3155 TRACE("(%p)->(%p)\n", This, value);
3156 return get_textfont_propl(This, FONT_HIDDEN, value);
3159 static HRESULT WINAPI TextFont_SetHidden(ITextFont *iface, LONG value)
3161 ITextFontImpl *This = impl_from_ITextFont(iface);
3162 TRACE("(%p)->(%ld)\n", This, value);
3163 return set_textfont_propd(This, FONT_HIDDEN, value);
3166 static HRESULT WINAPI TextFont_GetEngrave(ITextFont *iface, LONG *value)
3168 ITextFontImpl *This = impl_from_ITextFont(iface);
3169 TRACE("(%p)->(%p)\n", This, value);
3170 return get_textfont_propl(This, FONT_ENGRAVE, value);
3173 static HRESULT WINAPI TextFont_SetEngrave(ITextFont *iface, LONG value)
3175 ITextFontImpl *This = impl_from_ITextFont(iface);
3176 TRACE("(%p)->(%ld)\n", This, value);
3177 return set_textfont_propd(This, FONT_ENGRAVE, value);
3180 static HRESULT WINAPI TextFont_GetItalic(ITextFont *iface, LONG *value)
3182 ITextFontImpl *This = impl_from_ITextFont(iface);
3183 TRACE("(%p)->(%p)\n", This, value);
3184 return get_textfont_propl(This, FONT_ITALIC, value);
3187 static HRESULT WINAPI TextFont_SetItalic(ITextFont *iface, LONG value)
3189 ITextFontImpl *This = impl_from_ITextFont(iface);
3190 TRACE("(%p)->(%ld)\n", This, value);
3191 return set_textfont_propd(This, FONT_ITALIC, value);
3194 static HRESULT WINAPI TextFont_GetKerning(ITextFont *iface, FLOAT *value)
3196 ITextFontImpl *This = impl_from_ITextFont(iface);
3197 TRACE("(%p)->(%p)\n", This, value);
3198 return get_textfont_propf(This, FONT_KERNING, value);
3201 static HRESULT WINAPI TextFont_SetKerning(ITextFont *iface, FLOAT value)
3203 ITextFontImpl *This = impl_from_ITextFont(iface);
3204 TRACE("(%p)->(%.2f)\n", This, value);
3205 return set_textfont_propf(This, FONT_KERNING, value);
3208 static HRESULT WINAPI TextFont_GetLanguageID(ITextFont *iface, LONG *value)
3210 ITextFontImpl *This = impl_from_ITextFont(iface);
3211 TRACE("(%p)->(%p)\n", This, value);
3212 return get_textfont_propl(This, FONT_LANGID, value);
3215 static HRESULT WINAPI TextFont_SetLanguageID(ITextFont *iface, LONG value)
3217 ITextFontImpl *This = impl_from_ITextFont(iface);
3218 TRACE("(%p)->(%ld)\n", This, value);
3219 return set_textfont_propl(This, FONT_LANGID, value);
3222 static HRESULT WINAPI TextFont_GetName(ITextFont *iface, BSTR *value)
3224 ITextFontImpl *This = impl_from_ITextFont(iface);
3226 TRACE("(%p)->(%p)\n", This, value);
3228 if (!value)
3229 return E_INVALIDARG;
3231 *value = NULL;
3233 if (!This->range) {
3234 if (This->props[FONT_NAME].str)
3235 *value = SysAllocString(This->props[FONT_NAME].str);
3236 else
3237 *value = SysAllocStringLen(NULL, 0);
3238 return *value ? S_OK : E_OUTOFMEMORY;
3241 return textfont_getname_from_range(This->range, value);
3244 static HRESULT WINAPI TextFont_SetName(ITextFont *iface, BSTR value)
3246 ITextFontImpl *This = impl_from_ITextFont(iface);
3247 textfont_prop_val v;
3249 TRACE("(%p)->(%s)\n", This, debugstr_w(value));
3251 v.str = value;
3252 return set_textfont_prop(This, FONT_NAME, &v);
3255 static HRESULT WINAPI TextFont_GetOutline(ITextFont *iface, LONG *value)
3257 ITextFontImpl *This = impl_from_ITextFont(iface);
3258 TRACE("(%p)->(%p)\n", This, value);
3259 return get_textfont_propl(This, FONT_OUTLINE, value);
3262 static HRESULT WINAPI TextFont_SetOutline(ITextFont *iface, LONG value)
3264 ITextFontImpl *This = impl_from_ITextFont(iface);
3265 TRACE("(%p)->(%ld)\n", This, value);
3266 return set_textfont_propd(This, FONT_OUTLINE, value);
3269 static HRESULT WINAPI TextFont_GetPosition(ITextFont *iface, FLOAT *value)
3271 ITextFontImpl *This = impl_from_ITextFont(iface);
3272 TRACE("(%p)->(%p)\n", This, value);
3273 return get_textfont_propf(This, FONT_POSITION, value);
3276 static HRESULT WINAPI TextFont_SetPosition(ITextFont *iface, FLOAT value)
3278 ITextFontImpl *This = impl_from_ITextFont(iface);
3279 TRACE("(%p)->(%.2f)\n", This, value);
3280 return set_textfont_propf(This, FONT_POSITION, value);
3283 static HRESULT WINAPI TextFont_GetProtected(ITextFont *iface, LONG *value)
3285 ITextFontImpl *This = impl_from_ITextFont(iface);
3286 TRACE("(%p)->(%p)\n", This, value);
3287 return get_textfont_propl(This, FONT_PROTECTED, value);
3290 static HRESULT WINAPI TextFont_SetProtected(ITextFont *iface, LONG value)
3292 ITextFontImpl *This = impl_from_ITextFont(iface);
3293 TRACE("(%p)->(%ld)\n", This, value);
3294 return set_textfont_propd(This, FONT_PROTECTED, value);
3297 static HRESULT WINAPI TextFont_GetShadow(ITextFont *iface, LONG *value)
3299 ITextFontImpl *This = impl_from_ITextFont(iface);
3300 TRACE("(%p)->(%p)\n", This, value);
3301 return get_textfont_propl(This, FONT_SHADOW, value);
3304 static HRESULT WINAPI TextFont_SetShadow(ITextFont *iface, LONG value)
3306 ITextFontImpl *This = impl_from_ITextFont(iface);
3307 TRACE("(%p)->(%ld)\n", This, value);
3308 return set_textfont_propd(This, FONT_SHADOW, value);
3311 static HRESULT WINAPI TextFont_GetSize(ITextFont *iface, FLOAT *value)
3313 ITextFontImpl *This = impl_from_ITextFont(iface);
3314 TRACE("(%p)->(%p)\n", This, value);
3315 return get_textfont_propf(This, FONT_SIZE, value);
3318 static HRESULT WINAPI TextFont_SetSize(ITextFont *iface, FLOAT value)
3320 ITextFontImpl *This = impl_from_ITextFont(iface);
3321 TRACE("(%p)->(%.2f)\n", This, value);
3322 return set_textfont_propf(This, FONT_SIZE, value);
3325 static HRESULT WINAPI TextFont_GetSmallCaps(ITextFont *iface, LONG *value)
3327 ITextFontImpl *This = impl_from_ITextFont(iface);
3328 TRACE("(%p)->(%p)\n", This, value);
3329 return get_textfont_propl(This, FONT_SMALLCAPS, value);
3332 static HRESULT WINAPI TextFont_SetSmallCaps(ITextFont *iface, LONG value)
3334 ITextFontImpl *This = impl_from_ITextFont(iface);
3335 TRACE("(%p)->(%ld)\n", This, value);
3336 return set_textfont_propd(This, FONT_SMALLCAPS, value);
3339 static HRESULT WINAPI TextFont_GetSpacing(ITextFont *iface, FLOAT *value)
3341 ITextFontImpl *This = impl_from_ITextFont(iface);
3342 TRACE("(%p)->(%p)\n", This, value);
3343 return get_textfont_propf(This, FONT_SPACING, value);
3346 static HRESULT WINAPI TextFont_SetSpacing(ITextFont *iface, FLOAT value)
3348 ITextFontImpl *This = impl_from_ITextFont(iface);
3349 TRACE("(%p)->(%.2f)\n", This, value);
3350 return set_textfont_propf(This, FONT_SPACING, value);
3353 static HRESULT WINAPI TextFont_GetStrikeThrough(ITextFont *iface, LONG *value)
3355 ITextFontImpl *This = impl_from_ITextFont(iface);
3356 TRACE("(%p)->(%p)\n", This, value);
3357 return get_textfont_propl(This, FONT_STRIKETHROUGH, value);
3360 static HRESULT WINAPI TextFont_SetStrikeThrough(ITextFont *iface, LONG value)
3362 ITextFontImpl *This = impl_from_ITextFont(iface);
3363 TRACE("(%p)->(%ld)\n", This, value);
3364 return set_textfont_propd(This, FONT_STRIKETHROUGH, value);
3367 static HRESULT WINAPI TextFont_GetSubscript(ITextFont *iface, LONG *value)
3369 ITextFontImpl *This = impl_from_ITextFont(iface);
3370 TRACE("(%p)->(%p)\n", This, value);
3371 return get_textfont_propl(This, FONT_SUBSCRIPT, value);
3374 static HRESULT WINAPI TextFont_SetSubscript(ITextFont *iface, LONG value)
3376 ITextFontImpl *This = impl_from_ITextFont(iface);
3377 TRACE("(%p)->(%ld)\n", This, value);
3378 return set_textfont_propd(This, FONT_SUBSCRIPT, value);
3381 static HRESULT WINAPI TextFont_GetSuperscript(ITextFont *iface, LONG *value)
3383 ITextFontImpl *This = impl_from_ITextFont(iface);
3384 TRACE("(%p)->(%p)\n", This, value);
3385 return get_textfont_propl(This, FONT_SUPERSCRIPT, value);
3388 static HRESULT WINAPI TextFont_SetSuperscript(ITextFont *iface, LONG value)
3390 ITextFontImpl *This = impl_from_ITextFont(iface);
3391 TRACE("(%p)->(%ld)\n", This, value);
3392 return set_textfont_propd(This, FONT_SUPERSCRIPT, value);
3395 static HRESULT WINAPI TextFont_GetUnderline(ITextFont *iface, LONG *value)
3397 ITextFontImpl *This = impl_from_ITextFont(iface);
3398 TRACE("(%p)->(%p)\n", This, value);
3399 return get_textfont_propl(This, FONT_UNDERLINE, value);
3402 static HRESULT WINAPI TextFont_SetUnderline(ITextFont *iface, LONG value)
3404 ITextFontImpl *This = impl_from_ITextFont(iface);
3405 TRACE("(%p)->(%ld)\n", This, value);
3406 return set_textfont_propd(This, FONT_UNDERLINE, value);
3409 static HRESULT WINAPI TextFont_GetWeight(ITextFont *iface, LONG *value)
3411 ITextFontImpl *This = impl_from_ITextFont(iface);
3412 TRACE("(%p)->(%p)\n", This, value);
3413 return get_textfont_propl(This, FONT_WEIGHT, value);
3416 static HRESULT WINAPI TextFont_SetWeight(ITextFont *iface, LONG value)
3418 ITextFontImpl *This = impl_from_ITextFont(iface);
3419 TRACE("(%p)->(%ld)\n", This, value);
3420 return set_textfont_propl(This, FONT_WEIGHT, value);
3423 static ITextFontVtbl textfontvtbl = {
3424 TextFont_QueryInterface,
3425 TextFont_AddRef,
3426 TextFont_Release,
3427 TextFont_GetTypeInfoCount,
3428 TextFont_GetTypeInfo,
3429 TextFont_GetIDsOfNames,
3430 TextFont_Invoke,
3431 TextFont_GetDuplicate,
3432 TextFont_SetDuplicate,
3433 TextFont_CanChange,
3434 TextFont_IsEqual,
3435 TextFont_Reset,
3436 TextFont_GetStyle,
3437 TextFont_SetStyle,
3438 TextFont_GetAllCaps,
3439 TextFont_SetAllCaps,
3440 TextFont_GetAnimation,
3441 TextFont_SetAnimation,
3442 TextFont_GetBackColor,
3443 TextFont_SetBackColor,
3444 TextFont_GetBold,
3445 TextFont_SetBold,
3446 TextFont_GetEmboss,
3447 TextFont_SetEmboss,
3448 TextFont_GetForeColor,
3449 TextFont_SetForeColor,
3450 TextFont_GetHidden,
3451 TextFont_SetHidden,
3452 TextFont_GetEngrave,
3453 TextFont_SetEngrave,
3454 TextFont_GetItalic,
3455 TextFont_SetItalic,
3456 TextFont_GetKerning,
3457 TextFont_SetKerning,
3458 TextFont_GetLanguageID,
3459 TextFont_SetLanguageID,
3460 TextFont_GetName,
3461 TextFont_SetName,
3462 TextFont_GetOutline,
3463 TextFont_SetOutline,
3464 TextFont_GetPosition,
3465 TextFont_SetPosition,
3466 TextFont_GetProtected,
3467 TextFont_SetProtected,
3468 TextFont_GetShadow,
3469 TextFont_SetShadow,
3470 TextFont_GetSize,
3471 TextFont_SetSize,
3472 TextFont_GetSmallCaps,
3473 TextFont_SetSmallCaps,
3474 TextFont_GetSpacing,
3475 TextFont_SetSpacing,
3476 TextFont_GetStrikeThrough,
3477 TextFont_SetStrikeThrough,
3478 TextFont_GetSubscript,
3479 TextFont_SetSubscript,
3480 TextFont_GetSuperscript,
3481 TextFont_SetSuperscript,
3482 TextFont_GetUnderline,
3483 TextFont_SetUnderline,
3484 TextFont_GetWeight,
3485 TextFont_SetWeight
3488 static HRESULT create_textfont(ITextRange *range, const ITextFontImpl *src, ITextFont **ret)
3490 ITextFontImpl *font;
3492 *ret = NULL;
3493 font = heap_alloc(sizeof(*font));
3494 if (!font)
3495 return E_OUTOFMEMORY;
3497 font->ITextFont_iface.lpVtbl = &textfontvtbl;
3498 font->ref = 1;
3500 if (src) {
3501 font->range = NULL;
3502 font->get_cache_enabled = TRUE;
3503 font->set_cache_enabled = TRUE;
3504 memcpy(&font->props, &src->props, sizeof(font->props));
3505 if (font->props[FONT_NAME].str)
3506 font->props[FONT_NAME].str = SysAllocString(font->props[FONT_NAME].str);
3508 else {
3509 font->range = range;
3510 ITextRange_AddRef(range);
3512 /* cache current properties */
3513 font->get_cache_enabled = FALSE;
3514 font->set_cache_enabled = FALSE;
3515 textfont_cache_range_props(font);
3518 *ret = &font->ITextFont_iface;
3519 return S_OK;
3522 /* ITextPara */
3523 static HRESULT WINAPI TextPara_QueryInterface(ITextPara *iface, REFIID riid, void **ppv)
3525 ITextParaImpl *This = impl_from_ITextPara(iface);
3527 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
3529 if (IsEqualIID(riid, &IID_ITextPara) ||
3530 IsEqualIID(riid, &IID_IDispatch) ||
3531 IsEqualIID(riid, &IID_IUnknown))
3533 *ppv = iface;
3534 ITextPara_AddRef(iface);
3535 return S_OK;
3538 *ppv = NULL;
3539 return E_NOINTERFACE;
3542 static ULONG WINAPI TextPara_AddRef(ITextPara *iface)
3544 ITextParaImpl *This = impl_from_ITextPara(iface);
3545 ULONG ref = InterlockedIncrement(&This->ref);
3546 TRACE("(%p)->(%lu)\n", This, ref);
3547 return ref;
3550 static ULONG WINAPI TextPara_Release(ITextPara *iface)
3552 ITextParaImpl *This = impl_from_ITextPara(iface);
3553 ULONG ref = InterlockedDecrement(&This->ref);
3555 TRACE("(%p)->(%lu)\n", This, ref);
3557 if (!ref)
3559 ITextRange_Release(This->range);
3560 heap_free(This);
3563 return ref;
3566 static HRESULT WINAPI TextPara_GetTypeInfoCount(ITextPara *iface, UINT *pctinfo)
3568 ITextParaImpl *This = impl_from_ITextPara(iface);
3569 TRACE("(%p)->(%p)\n", This, pctinfo);
3570 *pctinfo = 1;
3571 return S_OK;
3574 static HRESULT WINAPI TextPara_GetTypeInfo(ITextPara *iface, UINT iTInfo, LCID lcid,
3575 ITypeInfo **ppTInfo)
3577 ITextParaImpl *This = impl_from_ITextPara(iface);
3578 HRESULT hr;
3580 TRACE("(%p)->(%u,%ld,%p)\n", This, iTInfo, lcid, ppTInfo);
3582 hr = get_typeinfo(ITextPara_tid, ppTInfo);
3583 if (SUCCEEDED(hr))
3584 ITypeInfo_AddRef(*ppTInfo);
3585 return hr;
3588 static HRESULT WINAPI TextPara_GetIDsOfNames(ITextPara *iface, REFIID riid,
3589 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
3591 ITextParaImpl *This = impl_from_ITextPara(iface);
3592 ITypeInfo *ti;
3593 HRESULT hr;
3595 TRACE("(%p)->(%s, %p, %u, %ld, %p)\n", This, debugstr_guid(riid), rgszNames,
3596 cNames, lcid, rgDispId);
3598 hr = get_typeinfo(ITextPara_tid, &ti);
3599 if (SUCCEEDED(hr))
3600 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
3601 return hr;
3604 static HRESULT WINAPI TextPara_Invoke(
3605 ITextPara *iface,
3606 DISPID dispIdMember,
3607 REFIID riid,
3608 LCID lcid,
3609 WORD wFlags,
3610 DISPPARAMS *pDispParams,
3611 VARIANT *pVarResult,
3612 EXCEPINFO *pExcepInfo,
3613 UINT *puArgErr)
3615 ITextParaImpl *This = impl_from_ITextPara(iface);
3616 ITypeInfo *ti;
3617 HRESULT hr;
3619 TRACE("(%p)->(%ld, %s, %ld, %u, %p, %p, %p, %p)\n", This, dispIdMember,
3620 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
3621 pExcepInfo, puArgErr);
3623 hr = get_typeinfo(ITextPara_tid, &ti);
3624 if (SUCCEEDED(hr))
3625 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3626 return hr;
3629 static HRESULT WINAPI TextPara_GetDuplicate(ITextPara *iface, ITextPara **ret)
3631 ITextParaImpl *This = impl_from_ITextPara(iface);
3632 FIXME("(%p)->(%p)\n", This, ret);
3633 return E_NOTIMPL;
3636 static HRESULT WINAPI TextPara_SetDuplicate(ITextPara *iface, ITextPara *para)
3638 ITextParaImpl *This = impl_from_ITextPara(iface);
3639 FIXME("(%p)->(%p)\n", This, para);
3640 return E_NOTIMPL;
3643 static HRESULT WINAPI TextPara_CanChange(ITextPara *iface, LONG *ret)
3645 ITextParaImpl *This = impl_from_ITextPara(iface);
3646 FIXME("(%p)->(%p)\n", This, ret);
3647 return E_NOTIMPL;
3650 static HRESULT WINAPI TextPara_IsEqual(ITextPara *iface, ITextPara *para, LONG *ret)
3652 ITextParaImpl *This = impl_from_ITextPara(iface);
3653 FIXME("(%p)->(%p %p)\n", This, para, ret);
3654 return E_NOTIMPL;
3657 static HRESULT WINAPI TextPara_Reset(ITextPara *iface, LONG value)
3659 ITextParaImpl *This = impl_from_ITextPara(iface);
3660 FIXME("(%p)->(%ld)\n", This, value);
3661 return E_NOTIMPL;
3664 static HRESULT WINAPI TextPara_GetStyle(ITextPara *iface, LONG *value)
3666 ITextParaImpl *This = impl_from_ITextPara(iface);
3667 FIXME("(%p)->(%p)\n", This, value);
3668 return E_NOTIMPL;
3671 static HRESULT WINAPI TextPara_SetStyle(ITextPara *iface, LONG value)
3673 ITextParaImpl *This = impl_from_ITextPara(iface);
3674 FIXME("(%p)->(%ld)\n", This, value);
3675 return E_NOTIMPL;
3678 static HRESULT WINAPI TextPara_GetAlignment(ITextPara *iface, LONG *value)
3680 ITextParaImpl *This = impl_from_ITextPara(iface);
3681 FIXME("(%p)->(%p)\n", This, value);
3682 return E_NOTIMPL;
3685 static HRESULT WINAPI TextPara_SetAlignment(ITextPara *iface, LONG value)
3687 ITextParaImpl *This = impl_from_ITextPara(iface);
3688 FIXME("(%p)->(%ld)\n", This, value);
3689 return E_NOTIMPL;
3692 static HRESULT WINAPI TextPara_GetHyphenation(ITextPara *iface, LONG *value)
3694 ITextParaImpl *This = impl_from_ITextPara(iface);
3695 FIXME("(%p)->(%p)\n", This, value);
3696 return E_NOTIMPL;
3699 static HRESULT WINAPI TextPara_SetHyphenation(ITextPara *iface, LONG value)
3701 ITextParaImpl *This = impl_from_ITextPara(iface);
3702 FIXME("(%p)->(%ld)\n", This, value);
3703 return E_NOTIMPL;
3706 static HRESULT WINAPI TextPara_GetFirstLineIndent(ITextPara *iface, FLOAT *value)
3708 ITextParaImpl *This = impl_from_ITextPara(iface);
3709 FIXME("(%p)->(%p)\n", This, value);
3710 return E_NOTIMPL;
3713 static HRESULT WINAPI TextPara_GetKeepTogether(ITextPara *iface, LONG *value)
3715 ITextParaImpl *This = impl_from_ITextPara(iface);
3716 FIXME("(%p)->(%p)\n", This, value);
3717 return E_NOTIMPL;
3720 static HRESULT WINAPI TextPara_SetKeepTogether(ITextPara *iface, LONG value)
3722 ITextParaImpl *This = impl_from_ITextPara(iface);
3723 FIXME("(%p)->(%ld)\n", This, value);
3724 return E_NOTIMPL;
3727 static HRESULT WINAPI TextPara_GetKeepWithNext(ITextPara *iface, LONG *value)
3729 ITextParaImpl *This = impl_from_ITextPara(iface);
3730 FIXME("(%p)->(%p)\n", This, value);
3731 return E_NOTIMPL;
3734 static HRESULT WINAPI TextPara_SetKeepWithNext(ITextPara *iface, LONG value)
3736 ITextParaImpl *This = impl_from_ITextPara(iface);
3737 FIXME("(%p)->(%ld)\n", This, value);
3738 return E_NOTIMPL;
3741 static HRESULT WINAPI TextPara_GetLeftIndent(ITextPara *iface, FLOAT *value)
3743 ITextParaImpl *This = impl_from_ITextPara(iface);
3744 FIXME("(%p)->(%p)\n", This, value);
3745 return E_NOTIMPL;
3748 static HRESULT WINAPI TextPara_GetLineSpacing(ITextPara *iface, FLOAT *value)
3750 ITextParaImpl *This = impl_from_ITextPara(iface);
3751 FIXME("(%p)->(%p)\n", This, value);
3752 return E_NOTIMPL;
3755 static HRESULT WINAPI TextPara_GetLineSpacingRule(ITextPara *iface, LONG *value)
3757 ITextParaImpl *This = impl_from_ITextPara(iface);
3758 FIXME("(%p)->(%p)\n", This, value);
3759 return E_NOTIMPL;
3762 static HRESULT WINAPI TextPara_GetListAlignment(ITextPara *iface, LONG *value)
3764 ITextParaImpl *This = impl_from_ITextPara(iface);
3765 FIXME("(%p)->(%p)\n", This, value);
3766 return E_NOTIMPL;
3769 static HRESULT WINAPI TextPara_SetListAlignment(ITextPara *iface, LONG value)
3771 ITextParaImpl *This = impl_from_ITextPara(iface);
3772 FIXME("(%p)->(%ld)\n", This, value);
3773 return E_NOTIMPL;
3776 static HRESULT WINAPI TextPara_GetListLevelIndex(ITextPara *iface, LONG *value)
3778 ITextParaImpl *This = impl_from_ITextPara(iface);
3779 FIXME("(%p)->(%p)\n", This, value);
3780 return E_NOTIMPL;
3783 static HRESULT WINAPI TextPara_SetListLevelIndex(ITextPara *iface, LONG value)
3785 ITextParaImpl *This = impl_from_ITextPara(iface);
3786 FIXME("(%p)->(%ld)\n", This, value);
3787 return E_NOTIMPL;
3790 static HRESULT WINAPI TextPara_GetListStart(ITextPara *iface, LONG *value)
3792 ITextParaImpl *This = impl_from_ITextPara(iface);
3793 FIXME("(%p)->(%p)\n", This, value);
3794 return E_NOTIMPL;
3797 static HRESULT WINAPI TextPara_SetListStart(ITextPara *iface, LONG value)
3799 ITextParaImpl *This = impl_from_ITextPara(iface);
3800 FIXME("(%p)->(%ld)\n", This, value);
3801 return E_NOTIMPL;
3804 static HRESULT WINAPI TextPara_GetListTab(ITextPara *iface, FLOAT *value)
3806 ITextParaImpl *This = impl_from_ITextPara(iface);
3807 FIXME("(%p)->(%p)\n", This, value);
3808 return E_NOTIMPL;
3811 static HRESULT WINAPI TextPara_SetListTab(ITextPara *iface, FLOAT value)
3813 ITextParaImpl *This = impl_from_ITextPara(iface);
3814 FIXME("(%p)->(%.2f)\n", This, value);
3815 return E_NOTIMPL;
3818 static HRESULT WINAPI TextPara_GetListType(ITextPara *iface, LONG *value)
3820 ITextParaImpl *This = impl_from_ITextPara(iface);
3821 FIXME("(%p)->(%p)\n", This, value);
3822 return E_NOTIMPL;
3825 static HRESULT WINAPI TextPara_SetListType(ITextPara *iface, LONG value)
3827 ITextParaImpl *This = impl_from_ITextPara(iface);
3828 FIXME("(%p)->(%ld)\n", This, value);
3829 return E_NOTIMPL;
3832 static HRESULT WINAPI TextPara_GetNoLineNumber(ITextPara *iface, LONG *value)
3834 ITextParaImpl *This = impl_from_ITextPara(iface);
3835 FIXME("(%p)->(%p)\n", This, value);
3836 return E_NOTIMPL;
3839 static HRESULT WINAPI TextPara_SetNoLineNumber(ITextPara *iface, LONG value)
3841 ITextParaImpl *This = impl_from_ITextPara(iface);
3842 FIXME("(%p)->(%ld)\n", This, value);
3843 return E_NOTIMPL;
3846 static HRESULT WINAPI TextPara_GetPageBreakBefore(ITextPara *iface, LONG *value)
3848 ITextParaImpl *This = impl_from_ITextPara(iface);
3849 FIXME("(%p)->(%p)\n", This, value);
3850 return E_NOTIMPL;
3853 static HRESULT WINAPI TextPara_SetPageBreakBefore(ITextPara *iface, LONG value)
3855 ITextParaImpl *This = impl_from_ITextPara(iface);
3856 FIXME("(%p)->(%ld)\n", This, value);
3857 return E_NOTIMPL;
3860 static HRESULT WINAPI TextPara_GetRightIndent(ITextPara *iface, FLOAT *value)
3862 ITextParaImpl *This = impl_from_ITextPara(iface);
3863 FIXME("(%p)->(%p)\n", This, value);
3864 return E_NOTIMPL;
3867 static HRESULT WINAPI TextPara_SetRightIndent(ITextPara *iface, FLOAT value)
3869 ITextParaImpl *This = impl_from_ITextPara(iface);
3870 FIXME("(%p)->(%.2f)\n", This, value);
3871 return E_NOTIMPL;
3874 static HRESULT WINAPI TextPara_SetIndents(ITextPara *iface, FLOAT StartIndent, FLOAT LeftIndent, FLOAT RightIndent)
3876 ITextParaImpl *This = impl_from_ITextPara(iface);
3877 FIXME("(%p)->(%.2f %.2f %.2f)\n", This, StartIndent, LeftIndent, RightIndent);
3878 return E_NOTIMPL;
3881 static HRESULT WINAPI TextPara_SetLineSpacing(ITextPara *iface, LONG LineSpacingRule, FLOAT LineSpacing)
3883 ITextParaImpl *This = impl_from_ITextPara(iface);
3884 FIXME("(%p)->(%ld %.2f)\n", This, LineSpacingRule, LineSpacing);
3885 return E_NOTIMPL;
3888 static HRESULT WINAPI TextPara_GetSpaceAfter(ITextPara *iface, FLOAT *value)
3890 ITextParaImpl *This = impl_from_ITextPara(iface);
3891 FIXME("(%p)->(%p)\n", This, value);
3892 return E_NOTIMPL;
3895 static HRESULT WINAPI TextPara_SetSpaceAfter(ITextPara *iface, FLOAT value)
3897 ITextParaImpl *This = impl_from_ITextPara(iface);
3898 FIXME("(%p)->(%.2f)\n", This, value);
3899 return E_NOTIMPL;
3902 static HRESULT WINAPI TextPara_GetSpaceBefore(ITextPara *iface, FLOAT *value)
3904 ITextParaImpl *This = impl_from_ITextPara(iface);
3905 FIXME("(%p)->(%p)\n", This, value);
3906 return E_NOTIMPL;
3909 static HRESULT WINAPI TextPara_SetSpaceBefore(ITextPara *iface, FLOAT value)
3911 ITextParaImpl *This = impl_from_ITextPara(iface);
3912 FIXME("(%p)->(%.2f)\n", This, value);
3913 return E_NOTIMPL;
3916 static HRESULT WINAPI TextPara_GetWidowControl(ITextPara *iface, LONG *value)
3918 ITextParaImpl *This = impl_from_ITextPara(iface);
3919 FIXME("(%p)->(%p)\n", This, value);
3920 return E_NOTIMPL;
3923 static HRESULT WINAPI TextPara_SetWidowControl(ITextPara *iface, LONG value)
3925 ITextParaImpl *This = impl_from_ITextPara(iface);
3926 FIXME("(%p)->(%ld)\n", This, value);
3927 return E_NOTIMPL;
3930 static HRESULT WINAPI TextPara_GetTabCount(ITextPara *iface, LONG *value)
3932 ITextParaImpl *This = impl_from_ITextPara(iface);
3933 FIXME("(%p)->(%p)\n", This, value);
3934 return E_NOTIMPL;
3937 static HRESULT WINAPI TextPara_AddTab(ITextPara *iface, FLOAT tbPos, LONG tbAlign, LONG tbLeader)
3939 ITextParaImpl *This = impl_from_ITextPara(iface);
3940 FIXME("(%p)->(%.2f %ld %ld)\n", This, tbPos, tbAlign, tbLeader);
3941 return E_NOTIMPL;
3944 static HRESULT WINAPI TextPara_ClearAllTabs(ITextPara *iface)
3946 ITextParaImpl *This = impl_from_ITextPara(iface);
3947 FIXME("(%p)\n", This);
3948 return E_NOTIMPL;
3951 static HRESULT WINAPI TextPara_DeleteTab(ITextPara *iface, FLOAT pos)
3953 ITextParaImpl *This = impl_from_ITextPara(iface);
3954 FIXME("(%p)->(%.2f)\n", This, pos);
3955 return E_NOTIMPL;
3958 static HRESULT WINAPI TextPara_GetTab(ITextPara *iface, LONG iTab, FLOAT *ptbPos, LONG *ptbAlign, LONG *ptbLeader)
3960 ITextParaImpl *This = impl_from_ITextPara(iface);
3961 FIXME("(%p)->(%ld %p %p %p)\n", This, iTab, ptbPos, ptbAlign, ptbLeader);
3962 return E_NOTIMPL;
3965 static ITextParaVtbl textparavtbl = {
3966 TextPara_QueryInterface,
3967 TextPara_AddRef,
3968 TextPara_Release,
3969 TextPara_GetTypeInfoCount,
3970 TextPara_GetTypeInfo,
3971 TextPara_GetIDsOfNames,
3972 TextPara_Invoke,
3973 TextPara_GetDuplicate,
3974 TextPara_SetDuplicate,
3975 TextPara_CanChange,
3976 TextPara_IsEqual,
3977 TextPara_Reset,
3978 TextPara_GetStyle,
3979 TextPara_SetStyle,
3980 TextPara_GetAlignment,
3981 TextPara_SetAlignment,
3982 TextPara_GetHyphenation,
3983 TextPara_SetHyphenation,
3984 TextPara_GetFirstLineIndent,
3985 TextPara_GetKeepTogether,
3986 TextPara_SetKeepTogether,
3987 TextPara_GetKeepWithNext,
3988 TextPara_SetKeepWithNext,
3989 TextPara_GetLeftIndent,
3990 TextPara_GetLineSpacing,
3991 TextPara_GetLineSpacingRule,
3992 TextPara_GetListAlignment,
3993 TextPara_SetListAlignment,
3994 TextPara_GetListLevelIndex,
3995 TextPara_SetListLevelIndex,
3996 TextPara_GetListStart,
3997 TextPara_SetListStart,
3998 TextPara_GetListTab,
3999 TextPara_SetListTab,
4000 TextPara_GetListType,
4001 TextPara_SetListType,
4002 TextPara_GetNoLineNumber,
4003 TextPara_SetNoLineNumber,
4004 TextPara_GetPageBreakBefore,
4005 TextPara_SetPageBreakBefore,
4006 TextPara_GetRightIndent,
4007 TextPara_SetRightIndent,
4008 TextPara_SetIndents,
4009 TextPara_SetLineSpacing,
4010 TextPara_GetSpaceAfter,
4011 TextPara_SetSpaceAfter,
4012 TextPara_GetSpaceBefore,
4013 TextPara_SetSpaceBefore,
4014 TextPara_GetWidowControl,
4015 TextPara_SetWidowControl,
4016 TextPara_GetTabCount,
4017 TextPara_AddTab,
4018 TextPara_ClearAllTabs,
4019 TextPara_DeleteTab,
4020 TextPara_GetTab
4023 static HRESULT create_textpara(ITextRange *range, ITextPara **ret)
4025 ITextParaImpl *para;
4027 *ret = NULL;
4028 para = heap_alloc(sizeof(*para));
4029 if (!para)
4030 return E_OUTOFMEMORY;
4032 para->ITextPara_iface.lpVtbl = &textparavtbl;
4033 para->ref = 1;
4034 para->range = range;
4035 ITextRange_AddRef(range);
4037 *ret = &para->ITextPara_iface;
4038 return S_OK;
4041 /* ITextDocument */
4042 static HRESULT WINAPI ITextDocument2Old_fnQueryInterface(ITextDocument2Old* iface, REFIID riid,
4043 void **ppvObject)
4045 struct text_services *services = impl_from_ITextDocument2Old(iface);
4046 return IUnknown_QueryInterface( services->outer_unk, riid, ppvObject );
4049 static ULONG WINAPI ITextDocument2Old_fnAddRef(ITextDocument2Old *iface)
4051 struct text_services *services = impl_from_ITextDocument2Old(iface);
4052 return IUnknown_AddRef( services->outer_unk );
4055 static ULONG WINAPI ITextDocument2Old_fnRelease(ITextDocument2Old *iface)
4057 struct text_services *services = impl_from_ITextDocument2Old(iface);
4058 return IUnknown_Release( services->outer_unk );
4061 static HRESULT WINAPI ITextDocument2Old_fnGetTypeInfoCount(ITextDocument2Old *iface,
4062 UINT *pctinfo)
4064 struct text_services *services = impl_from_ITextDocument2Old(iface);
4065 TRACE("(%p)->(%p)\n", services, pctinfo);
4066 *pctinfo = 1;
4067 return S_OK;
4070 static HRESULT WINAPI ITextDocument2Old_fnGetTypeInfo(ITextDocument2Old *iface, UINT iTInfo, LCID lcid,
4071 ITypeInfo **ppTInfo)
4073 struct text_services *services = impl_from_ITextDocument2Old(iface);
4074 HRESULT hr;
4076 TRACE("(%p)->(%u,%ld,%p)\n", services, iTInfo, lcid, ppTInfo);
4078 hr = get_typeinfo(ITextDocument_tid, ppTInfo);
4079 if (SUCCEEDED(hr))
4080 ITypeInfo_AddRef(*ppTInfo);
4081 return hr;
4084 static HRESULT WINAPI ITextDocument2Old_fnGetIDsOfNames(ITextDocument2Old *iface, REFIID riid,
4085 LPOLESTR *rgszNames, UINT cNames,
4086 LCID lcid, DISPID *rgDispId)
4088 struct text_services *services = impl_from_ITextDocument2Old(iface);
4089 ITypeInfo *ti;
4090 HRESULT hr;
4092 TRACE("(%p)->(%s, %p, %u, %ld, %p)\n", services, debugstr_guid(riid),
4093 rgszNames, cNames, lcid, rgDispId);
4095 hr = get_typeinfo(ITextDocument_tid, &ti);
4096 if (SUCCEEDED(hr))
4097 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
4098 return hr;
4101 static HRESULT WINAPI ITextDocument2Old_fnInvoke(ITextDocument2Old *iface, DISPID dispIdMember,
4102 REFIID riid, LCID lcid, WORD wFlags,
4103 DISPPARAMS *pDispParams, VARIANT *pVarResult,
4104 EXCEPINFO *pExcepInfo, UINT *puArgErr)
4106 struct text_services *services = impl_from_ITextDocument2Old(iface);
4107 ITypeInfo *ti;
4108 HRESULT hr;
4110 TRACE("(%p)->(%ld, %s, %ld, %u, %p, %p, %p, %p)\n", services, dispIdMember,
4111 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
4112 pExcepInfo, puArgErr);
4114 hr = get_typeinfo(ITextDocument_tid, &ti);
4115 if (SUCCEEDED(hr))
4116 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4117 return hr;
4120 static HRESULT WINAPI ITextDocument2Old_fnGetName(ITextDocument2Old *iface, BSTR *pName)
4122 struct text_services *services = impl_from_ITextDocument2Old(iface);
4123 FIXME("stub %p\n", services);
4124 return E_NOTIMPL;
4127 static HRESULT WINAPI ITextDocument2Old_fnGetSelection(ITextDocument2Old *iface, ITextSelection **selection)
4129 struct text_services *services = impl_from_ITextDocument2Old(iface);
4131 TRACE("(%p)->(%p)\n", iface, selection);
4133 if (!selection)
4134 return E_INVALIDARG;
4136 if (!services->text_selection)
4138 services->text_selection = text_selection_create( services );
4139 if (!services->text_selection)
4141 *selection = NULL;
4142 return E_OUTOFMEMORY;
4146 *selection = &services->text_selection->ITextSelection_iface;
4147 ITextSelection_AddRef(*selection);
4148 return S_OK;
4151 static HRESULT WINAPI ITextDocument2Old_fnGetStoryCount(ITextDocument2Old *iface, LONG *pCount)
4153 struct text_services *services = impl_from_ITextDocument2Old(iface);
4154 FIXME("stub %p\n", services);
4155 return E_NOTIMPL;
4158 static HRESULT WINAPI ITextDocument2Old_fnGetStoryRanges(ITextDocument2Old *iface,
4159 ITextStoryRanges **ppStories)
4161 struct text_services *services = impl_from_ITextDocument2Old(iface);
4162 FIXME("stub %p\n", services);
4163 return E_NOTIMPL;
4166 static HRESULT WINAPI ITextDocument2Old_fnGetSaved(ITextDocument2Old *iface, LONG *pValue)
4168 struct text_services *services = impl_from_ITextDocument2Old(iface);
4169 FIXME("stub %p\n", services);
4170 return E_NOTIMPL;
4173 static HRESULT WINAPI ITextDocument2Old_fnSetSaved(ITextDocument2Old *iface, LONG Value)
4175 struct text_services *services = impl_from_ITextDocument2Old(iface);
4176 FIXME("stub %p\n", services);
4177 return E_NOTIMPL;
4180 static HRESULT WINAPI ITextDocument2Old_fnGetDefaultTabStop(ITextDocument2Old *iface, float *pValue)
4182 struct text_services *services = impl_from_ITextDocument2Old(iface);
4183 FIXME("stub %p\n", services);
4184 return E_NOTIMPL;
4187 static HRESULT WINAPI ITextDocument2Old_fnSetDefaultTabStop(ITextDocument2Old *iface, float Value)
4189 struct text_services *services = impl_from_ITextDocument2Old(iface);
4190 FIXME("stub %p\n", services);
4191 return E_NOTIMPL;
4194 static HRESULT WINAPI ITextDocument2Old_fnNew(ITextDocument2Old *iface)
4196 struct text_services *services = impl_from_ITextDocument2Old(iface);
4197 FIXME("stub %p\n", services);
4198 return E_NOTIMPL;
4201 static HRESULT WINAPI ITextDocument2Old_fnOpen(ITextDocument2Old *iface, VARIANT *pVar,
4202 LONG Flags, LONG CodePage)
4204 struct text_services *services = impl_from_ITextDocument2Old(iface);
4205 FIXME("stub %p\n", services);
4206 return E_NOTIMPL;
4209 static HRESULT WINAPI ITextDocument2Old_fnSave(ITextDocument2Old *iface, VARIANT *pVar,
4210 LONG Flags, LONG CodePage)
4212 struct text_services *services = impl_from_ITextDocument2Old(iface);
4213 FIXME("stub %p\n", services);
4214 return E_NOTIMPL;
4217 static HRESULT WINAPI ITextDocument2Old_fnFreeze(ITextDocument2Old *iface, LONG *pCount)
4219 struct text_services *services = impl_from_ITextDocument2Old(iface);
4220 FIXME("stub %p\n", services);
4221 return E_NOTIMPL;
4224 static HRESULT WINAPI ITextDocument2Old_fnUnfreeze(ITextDocument2Old *iface, LONG *pCount)
4226 struct text_services *services = impl_from_ITextDocument2Old(iface);
4227 FIXME("stub %p\n", services);
4228 return E_NOTIMPL;
4231 static HRESULT WINAPI ITextDocument2Old_fnBeginEditCollection(ITextDocument2Old *iface)
4233 struct text_services *services = impl_from_ITextDocument2Old(iface);
4234 FIXME("stub %p\n", services);
4235 return E_NOTIMPL;
4238 static HRESULT WINAPI ITextDocument2Old_fnEndEditCollection(ITextDocument2Old *iface)
4240 struct text_services *services = impl_from_ITextDocument2Old(iface);
4241 FIXME("stub %p\n", services);
4242 return E_NOTIMPL;
4245 static HRESULT WINAPI ITextDocument2Old_fnUndo(ITextDocument2Old *iface, LONG Count, LONG *prop)
4247 struct text_services *services = impl_from_ITextDocument2Old(iface);
4248 LONG actual_undo_count;
4250 if (prop) *prop = 0;
4252 switch (Count)
4254 case tomFalse:
4255 editor_disable_undo(services->editor);
4256 return S_OK;
4257 default:
4258 if (Count > 0) break;
4259 /* fallthrough */
4260 case tomTrue:
4261 editor_enable_undo(services->editor);
4262 return S_FALSE;
4263 case tomSuspend:
4264 if (services->editor->undo_ctl_state == undoActive)
4266 services->editor->undo_ctl_state = undoSuspended;
4268 return S_FALSE;
4269 case tomResume:
4270 services->editor->undo_ctl_state = undoActive;
4271 return S_FALSE;
4274 for (actual_undo_count = 0; actual_undo_count < Count; actual_undo_count++)
4276 if (!ME_Undo(services->editor)) break;
4279 if (prop) *prop = actual_undo_count;
4280 return actual_undo_count == Count ? S_OK : S_FALSE;
4283 static HRESULT WINAPI ITextDocument2Old_fnRedo(ITextDocument2Old *iface, LONG Count, LONG *prop)
4285 struct text_services *services = impl_from_ITextDocument2Old(iface);
4286 LONG actual_redo_count;
4288 if (prop) *prop = 0;
4290 for (actual_redo_count = 0; actual_redo_count < Count; actual_redo_count++)
4292 if (!ME_Redo(services->editor)) break;
4295 if (prop) *prop = actual_redo_count;
4296 return actual_redo_count == Count ? S_OK : S_FALSE;
4299 static HRESULT CreateITextRange(struct text_services *services, LONG start, LONG end, ITextRange** ppRange)
4301 ITextRangeImpl *txtRge = heap_alloc(sizeof(ITextRangeImpl));
4303 if (!txtRge)
4304 return E_OUTOFMEMORY;
4305 txtRge->ITextRange_iface.lpVtbl = &trvt;
4306 txtRge->ref = 1;
4307 txtRge->child.reole = services;
4308 txtRge->start = start;
4309 txtRge->end = end;
4310 list_add_head( &services->rangelist, &txtRge->child.entry );
4311 *ppRange = &txtRge->ITextRange_iface;
4312 return S_OK;
4315 static HRESULT WINAPI ITextDocument2Old_fnRange(ITextDocument2Old *iface, LONG cp1, LONG cp2,
4316 ITextRange **ppRange)
4318 struct text_services *services = impl_from_ITextDocument2Old(iface);
4320 TRACE("%p %p %ld %ld\n", services, ppRange, cp1, cp2);
4321 if (!ppRange)
4322 return E_INVALIDARG;
4324 cp2range(services->editor, &cp1, &cp2);
4325 return CreateITextRange(services, cp1, cp2, ppRange);
4328 static HRESULT WINAPI ITextDocument2Old_fnRangeFromPoint(ITextDocument2Old *iface, LONG x, LONG y,
4329 ITextRange **ppRange)
4331 struct text_services *services = impl_from_ITextDocument2Old(iface);
4332 FIXME("stub %p\n", services);
4333 return E_NOTIMPL;
4336 /* ITextDocument2Old methods */
4337 static HRESULT WINAPI ITextDocument2Old_fnAttachMsgFilter(ITextDocument2Old *iface, IUnknown *filter)
4339 struct text_services *services = impl_from_ITextDocument2Old(iface);
4341 FIXME("(%p)->(%p): stub\n", services, filter);
4343 return E_NOTIMPL;
4346 static HRESULT WINAPI ITextDocument2Old_fnSetEffectColor(ITextDocument2Old *iface, LONG index, COLORREF cr)
4348 struct text_services *services = impl_from_ITextDocument2Old(iface);
4350 FIXME("(%p)->(%ld, 0x%lx): stub\n", services, index, cr);
4352 return E_NOTIMPL;
4355 static HRESULT WINAPI ITextDocument2Old_fnGetEffectColor(ITextDocument2Old *iface, LONG index, COLORREF *cr)
4357 struct text_services *services = impl_from_ITextDocument2Old(iface);
4359 FIXME("(%p)->(%ld, %p): stub\n", services, index, cr);
4361 return E_NOTIMPL;
4364 static HRESULT WINAPI ITextDocument2Old_fnGetCaretType(ITextDocument2Old *iface, LONG *type)
4366 struct text_services *services = impl_from_ITextDocument2Old(iface);
4368 FIXME("(%p)->(%p): stub\n", services, type);
4370 return E_NOTIMPL;
4373 static HRESULT WINAPI ITextDocument2Old_fnSetCaretType(ITextDocument2Old *iface, LONG type)
4375 struct text_services *services = impl_from_ITextDocument2Old(iface);
4377 FIXME("(%p)->(%ld): stub\n", services, type);
4379 return E_NOTIMPL;
4382 static HRESULT WINAPI ITextDocument2Old_fnGetImmContext(ITextDocument2Old *iface, LONG *context)
4384 struct text_services *services = impl_from_ITextDocument2Old(iface);
4386 FIXME("(%p)->(%p): stub\n", services, context);
4388 return E_NOTIMPL;
4391 static HRESULT WINAPI ITextDocument2Old_fnReleaseImmContext(ITextDocument2Old *iface, LONG context)
4393 struct text_services *services = impl_from_ITextDocument2Old(iface);
4395 FIXME("(%p)->(%ld): stub\n", services, context);
4397 return E_NOTIMPL;
4400 static HRESULT WINAPI ITextDocument2Old_fnGetPreferredFont(ITextDocument2Old *iface, LONG cp, LONG charrep,
4401 LONG options, LONG current_charrep, LONG current_fontsize,
4402 BSTR *bstr, LONG *pitch_family, LONG *new_fontsize)
4404 struct text_services *services = impl_from_ITextDocument2Old(iface);
4406 FIXME("(%p)->(%ld, %ld, %ld, %ld, %ld, %p, %p, %p): stub\n", services, cp, charrep, options, current_charrep,
4407 current_fontsize, bstr, pitch_family, new_fontsize);
4409 return E_NOTIMPL;
4412 static HRESULT WINAPI ITextDocument2Old_fnGetNotificationMode(ITextDocument2Old *iface, LONG *mode)
4414 struct text_services *services = impl_from_ITextDocument2Old(iface);
4416 FIXME("(%p)->(%p): stub\n", services, mode);
4418 return E_NOTIMPL;
4421 static HRESULT WINAPI ITextDocument2Old_fnSetNotificationMode(ITextDocument2Old *iface, LONG mode)
4423 struct text_services *services = impl_from_ITextDocument2Old(iface);
4425 FIXME("(%p)->(0x%lx): stub\n", services, mode);
4427 return E_NOTIMPL;
4430 static HRESULT WINAPI ITextDocument2Old_fnGetClientRect(ITextDocument2Old *iface, LONG type, LONG *left, LONG *top,
4431 LONG *right, LONG *bottom)
4433 struct text_services *services = impl_from_ITextDocument2Old(iface);
4435 FIXME("(%p)->(%ld, %p, %p, %p, %p): stub\n", services, type, left, top, right, bottom);
4437 return E_NOTIMPL;
4440 static HRESULT WINAPI ITextDocument2Old_fnGetSelectionEx(ITextDocument2Old *iface, ITextSelection **selection)
4442 struct text_services *services = impl_from_ITextDocument2Old(iface);
4444 FIXME("(%p)->(%p): stub\n", services, selection);
4446 return E_NOTIMPL;
4449 static HRESULT WINAPI ITextDocument2Old_fnGetWindow(ITextDocument2Old *iface, LONG *hwnd)
4451 struct text_services *services = impl_from_ITextDocument2Old(iface);
4453 FIXME("(%p)->(%p): stub\n", services, hwnd);
4455 return E_NOTIMPL;
4458 static HRESULT WINAPI ITextDocument2Old_fnGetFEFlags(ITextDocument2Old *iface, LONG *flags)
4460 struct text_services *services = impl_from_ITextDocument2Old(iface);
4462 FIXME("(%p)->(%p): stub\n", services, flags);
4464 return E_NOTIMPL;
4467 static HRESULT WINAPI ITextDocument2Old_fnUpdateWindow(ITextDocument2Old *iface)
4469 struct text_services *services = impl_from_ITextDocument2Old(iface);
4471 FIXME("(%p): stub\n", services);
4473 return E_NOTIMPL;
4476 static HRESULT WINAPI ITextDocument2Old_fnCheckTextLimit(ITextDocument2Old *iface, LONG cch, LONG *exceed)
4478 struct text_services *services = impl_from_ITextDocument2Old(iface);
4480 FIXME("(%p)->(%ld, %p): stub\n", services, cch, exceed);
4482 return E_NOTIMPL;
4485 static HRESULT WINAPI ITextDocument2Old_fnIMEInProgress(ITextDocument2Old *iface, LONG mode)
4487 struct text_services *services = impl_from_ITextDocument2Old(iface);
4489 FIXME("(%p)->(0x%lx): stub\n", services, mode);
4491 return E_NOTIMPL;
4494 static HRESULT WINAPI ITextDocument2Old_fnSysBeep(ITextDocument2Old *iface)
4496 struct text_services *services = impl_from_ITextDocument2Old(iface);
4498 FIXME("(%p): stub\n", services);
4500 return E_NOTIMPL;
4503 static HRESULT WINAPI ITextDocument2Old_fnUpdate(ITextDocument2Old *iface, LONG mode)
4505 struct text_services *services = impl_from_ITextDocument2Old(iface);
4507 FIXME("(%p)->(0x%lx): stub\n", services, mode);
4509 return E_NOTIMPL;
4512 static HRESULT WINAPI ITextDocument2Old_fnNotify(ITextDocument2Old *iface, LONG notify)
4514 struct text_services *services = impl_from_ITextDocument2Old(iface);
4516 FIXME("(%p)->(%ld): stub\n", services, notify);
4518 return E_NOTIMPL;
4521 const ITextDocument2OldVtbl text_doc2old_vtbl =
4523 ITextDocument2Old_fnQueryInterface,
4524 ITextDocument2Old_fnAddRef,
4525 ITextDocument2Old_fnRelease,
4526 ITextDocument2Old_fnGetTypeInfoCount,
4527 ITextDocument2Old_fnGetTypeInfo,
4528 ITextDocument2Old_fnGetIDsOfNames,
4529 ITextDocument2Old_fnInvoke,
4530 ITextDocument2Old_fnGetName,
4531 ITextDocument2Old_fnGetSelection,
4532 ITextDocument2Old_fnGetStoryCount,
4533 ITextDocument2Old_fnGetStoryRanges,
4534 ITextDocument2Old_fnGetSaved,
4535 ITextDocument2Old_fnSetSaved,
4536 ITextDocument2Old_fnGetDefaultTabStop,
4537 ITextDocument2Old_fnSetDefaultTabStop,
4538 ITextDocument2Old_fnNew,
4539 ITextDocument2Old_fnOpen,
4540 ITextDocument2Old_fnSave,
4541 ITextDocument2Old_fnFreeze,
4542 ITextDocument2Old_fnUnfreeze,
4543 ITextDocument2Old_fnBeginEditCollection,
4544 ITextDocument2Old_fnEndEditCollection,
4545 ITextDocument2Old_fnUndo,
4546 ITextDocument2Old_fnRedo,
4547 ITextDocument2Old_fnRange,
4548 ITextDocument2Old_fnRangeFromPoint,
4549 /* ITextDocument2Old methods */
4550 ITextDocument2Old_fnAttachMsgFilter,
4551 ITextDocument2Old_fnSetEffectColor,
4552 ITextDocument2Old_fnGetEffectColor,
4553 ITextDocument2Old_fnGetCaretType,
4554 ITextDocument2Old_fnSetCaretType,
4555 ITextDocument2Old_fnGetImmContext,
4556 ITextDocument2Old_fnReleaseImmContext,
4557 ITextDocument2Old_fnGetPreferredFont,
4558 ITextDocument2Old_fnGetNotificationMode,
4559 ITextDocument2Old_fnSetNotificationMode,
4560 ITextDocument2Old_fnGetClientRect,
4561 ITextDocument2Old_fnGetSelectionEx,
4562 ITextDocument2Old_fnGetWindow,
4563 ITextDocument2Old_fnGetFEFlags,
4564 ITextDocument2Old_fnUpdateWindow,
4565 ITextDocument2Old_fnCheckTextLimit,
4566 ITextDocument2Old_fnIMEInProgress,
4567 ITextDocument2Old_fnSysBeep,
4568 ITextDocument2Old_fnUpdate,
4569 ITextDocument2Old_fnNotify
4572 /* ITextSelection */
4573 static HRESULT WINAPI ITextSelection_fnQueryInterface(
4574 ITextSelection *me,
4575 REFIID riid,
4576 void **ppvObj)
4578 struct text_selection *This = impl_from_ITextSelection(me);
4580 *ppvObj = NULL;
4581 if (IsEqualGUID(riid, &IID_IUnknown)
4582 || IsEqualGUID(riid, &IID_IDispatch)
4583 || IsEqualGUID(riid, &IID_ITextRange)
4584 || IsEqualGUID(riid, &IID_ITextSelection))
4586 *ppvObj = me;
4587 ITextSelection_AddRef(me);
4588 return S_OK;
4590 else if (IsEqualGUID(riid, &IID_Igetrichole))
4592 *ppvObj = This->services;
4593 return S_OK;
4596 return E_NOINTERFACE;
4599 static ULONG WINAPI ITextSelection_fnAddRef(ITextSelection *me)
4601 struct text_selection *This = impl_from_ITextSelection(me);
4602 return InterlockedIncrement(&This->ref);
4605 static ULONG WINAPI ITextSelection_fnRelease(ITextSelection *me)
4607 struct text_selection *This = impl_from_ITextSelection(me);
4608 ULONG ref = InterlockedDecrement(&This->ref);
4609 if (ref == 0)
4610 heap_free(This);
4611 return ref;
4614 static HRESULT WINAPI ITextSelection_fnGetTypeInfoCount(ITextSelection *me, UINT *pctinfo)
4616 struct text_selection *This = impl_from_ITextSelection(me);
4617 TRACE("(%p)->(%p)\n", This, pctinfo);
4618 *pctinfo = 1;
4619 return S_OK;
4622 static HRESULT WINAPI ITextSelection_fnGetTypeInfo(ITextSelection *me, UINT iTInfo, LCID lcid,
4623 ITypeInfo **ppTInfo)
4625 struct text_selection *This = impl_from_ITextSelection(me);
4626 HRESULT hr;
4628 TRACE("(%p)->(%u,%ld,%p)\n", This, iTInfo, lcid, ppTInfo);
4630 hr = get_typeinfo(ITextSelection_tid, ppTInfo);
4631 if (SUCCEEDED(hr))
4632 ITypeInfo_AddRef(*ppTInfo);
4633 return hr;
4636 static HRESULT WINAPI ITextSelection_fnGetIDsOfNames(ITextSelection *me, REFIID riid,
4637 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
4639 struct text_selection *This = impl_from_ITextSelection(me);
4640 ITypeInfo *ti;
4641 HRESULT hr;
4643 TRACE("(%p)->(%s, %p, %u, %ld, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
4644 rgDispId);
4646 hr = get_typeinfo(ITextSelection_tid, &ti);
4647 if (SUCCEEDED(hr))
4648 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
4649 return hr;
4652 static HRESULT WINAPI ITextSelection_fnInvoke(
4653 ITextSelection *me,
4654 DISPID dispIdMember,
4655 REFIID riid,
4656 LCID lcid,
4657 WORD wFlags,
4658 DISPPARAMS *pDispParams,
4659 VARIANT *pVarResult,
4660 EXCEPINFO *pExcepInfo,
4661 UINT *puArgErr)
4663 struct text_selection *This = impl_from_ITextSelection(me);
4664 ITypeInfo *ti;
4665 HRESULT hr;
4667 TRACE("(%p)->(%ld, %s, %ld, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid), lcid,
4668 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4670 hr = get_typeinfo(ITextSelection_tid, &ti);
4671 if (SUCCEEDED(hr))
4672 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4673 return hr;
4676 /*** ITextRange methods ***/
4677 static HRESULT WINAPI ITextSelection_fnGetText(ITextSelection *me, BSTR *pbstr)
4679 struct text_selection *This = impl_from_ITextSelection(me);
4680 ME_Cursor *start = NULL, *end = NULL;
4681 int nChars, endOfs;
4682 BOOL bEOP;
4684 TRACE("(%p)->(%p)\n", This, pbstr);
4686 if (!This->services)
4687 return CO_E_RELEASED;
4689 if (!pbstr)
4690 return E_INVALIDARG;
4692 ME_GetSelection(This->services->editor, &start, &end);
4693 endOfs = ME_GetCursorOfs(end);
4694 nChars = endOfs - ME_GetCursorOfs(start);
4695 if (!nChars)
4697 *pbstr = NULL;
4698 return S_OK;
4701 *pbstr = SysAllocStringLen(NULL, nChars);
4702 if (!*pbstr)
4703 return E_OUTOFMEMORY;
4705 bEOP = (!para_next( para_next( end->para ) ) && endOfs > ME_GetTextLength(This->services->editor));
4706 ME_GetTextW(This->services->editor, *pbstr, nChars, start, nChars, FALSE, bEOP);
4707 TRACE("%s\n", wine_dbgstr_w(*pbstr));
4709 return S_OK;
4712 static HRESULT WINAPI ITextSelection_fnSetText(ITextSelection *me, BSTR str)
4714 struct text_selection *This = impl_from_ITextSelection(me);
4715 ME_TextEditor *editor;
4716 int len;
4717 LONG to, from;
4719 TRACE("(%p)->(%s)\n", This, debugstr_w(str));
4721 if (!This->services)
4722 return CO_E_RELEASED;
4724 editor = This->services->editor;
4725 len = lstrlenW(str);
4726 ME_GetSelectionOfs(editor, &from, &to);
4727 ME_ReplaceSel(editor, FALSE, str, len);
4729 if (len < to - from)
4730 textranges_update_ranges(This->services, from, len, RANGE_UPDATE_DELETE);
4732 return S_OK;
4735 static HRESULT WINAPI ITextSelection_fnGetChar(ITextSelection *me, LONG *pch)
4737 struct text_selection *This = impl_from_ITextSelection(me);
4738 ME_Cursor *start = NULL, *end = NULL;
4740 TRACE("(%p)->(%p)\n", This, pch);
4742 if (!This->services)
4743 return CO_E_RELEASED;
4745 if (!pch)
4746 return E_INVALIDARG;
4748 ME_GetSelection(This->services->editor, &start, &end);
4749 return range_GetChar(This->services->editor, start, pch);
4752 static HRESULT WINAPI ITextSelection_fnSetChar(ITextSelection *me, LONG ch)
4754 struct text_selection *This = impl_from_ITextSelection(me);
4756 FIXME("(%p)->(%lx): stub\n", This, ch);
4758 if (!This->services)
4759 return CO_E_RELEASED;
4761 return E_NOTIMPL;
4764 static HRESULT WINAPI ITextSelection_fnGetDuplicate(ITextSelection *me, ITextRange **range)
4766 struct text_selection *This = impl_from_ITextSelection(me);
4767 LONG start, end;
4769 TRACE("(%p)->(%p)\n", This, range);
4771 if (!This->services)
4772 return CO_E_RELEASED;
4774 if (!range)
4775 return E_INVALIDARG;
4777 ITextSelection_GetStart(me, &start);
4778 ITextSelection_GetEnd(me, &end);
4779 return CreateITextRange(This->services, start, end, range);
4782 static HRESULT WINAPI ITextSelection_fnGetFormattedText(ITextSelection *me, ITextRange **range)
4784 struct text_selection *This = impl_from_ITextSelection(me);
4786 FIXME("(%p)->(%p): stub\n", This, range);
4788 if (!This->services)
4789 return CO_E_RELEASED;
4791 return E_NOTIMPL;
4794 static HRESULT WINAPI ITextSelection_fnSetFormattedText(ITextSelection *me, ITextRange *range)
4796 struct text_selection *This = impl_from_ITextSelection(me);
4798 FIXME("(%p)->(%p): stub\n", This, range);
4800 if (!This->services)
4801 return CO_E_RELEASED;
4803 FIXME("not implemented\n");
4804 return E_NOTIMPL;
4807 static HRESULT WINAPI ITextSelection_fnGetStart(ITextSelection *me, LONG *pcpFirst)
4809 struct text_selection *This = impl_from_ITextSelection(me);
4810 LONG lim;
4812 TRACE("(%p)->(%p)\n", This, pcpFirst);
4814 if (!This->services)
4815 return CO_E_RELEASED;
4817 if (!pcpFirst)
4818 return E_INVALIDARG;
4819 ME_GetSelectionOfs(This->services->editor, pcpFirst, &lim);
4820 return S_OK;
4823 static HRESULT WINAPI ITextSelection_fnSetStart(ITextSelection *me, LONG value)
4825 struct text_selection *This = impl_from_ITextSelection(me);
4826 LONG start, end;
4827 HRESULT hr;
4829 TRACE("(%p)->(%ld)\n", This, value);
4831 if (!This->services)
4832 return CO_E_RELEASED;
4834 ME_GetSelectionOfs(This->services->editor, &start, &end);
4835 hr = textrange_setstart(This->services, value, &start, &end);
4836 if (hr == S_OK)
4837 set_selection(This->services->editor, start, end);
4839 return hr;
4842 static HRESULT WINAPI ITextSelection_fnGetEnd(ITextSelection *me, LONG *pcpLim)
4844 struct text_selection *This = impl_from_ITextSelection(me);
4845 LONG first;
4847 TRACE("(%p)->(%p)\n", This, pcpLim);
4849 if (!This->services)
4850 return CO_E_RELEASED;
4852 if (!pcpLim)
4853 return E_INVALIDARG;
4854 ME_GetSelectionOfs(This->services->editor, &first, pcpLim);
4855 return S_OK;
4858 static HRESULT WINAPI ITextSelection_fnSetEnd(ITextSelection *me, LONG value)
4860 struct text_selection *This = impl_from_ITextSelection(me);
4861 LONG start, end;
4862 HRESULT hr;
4864 TRACE("(%p)->(%ld)\n", This, value);
4866 if (!This->services)
4867 return CO_E_RELEASED;
4869 ME_GetSelectionOfs(This->services->editor, &start, &end);
4870 hr = textrange_setend(This->services, value, &start, &end);
4871 if (hr == S_OK)
4872 set_selection(This->services->editor, start, end);
4874 return hr;
4877 static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **font)
4879 struct text_selection *This = impl_from_ITextSelection(me);
4880 ITextRange *range = NULL;
4881 HRESULT hr;
4883 TRACE("(%p)->(%p)\n", This, font);
4885 if (!This->services)
4886 return CO_E_RELEASED;
4888 if (!font)
4889 return E_INVALIDARG;
4891 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
4892 hr = create_textfont(range, NULL, font);
4893 ITextRange_Release(range);
4894 return hr;
4897 static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *font)
4899 struct text_selection *This = impl_from_ITextSelection(me);
4900 ITextRange *range = NULL;
4902 TRACE("(%p)->(%p)\n", This, font);
4904 if (!font)
4905 return E_INVALIDARG;
4907 if (!This->services)
4908 return CO_E_RELEASED;
4910 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
4911 textrange_set_font(range, font);
4912 ITextRange_Release(range);
4913 return S_OK;
4916 static HRESULT WINAPI ITextSelection_fnGetPara(ITextSelection *me, ITextPara **para)
4918 struct text_selection *This = impl_from_ITextSelection(me);
4919 ITextRange *range = NULL;
4920 HRESULT hr;
4922 TRACE("(%p)->(%p)\n", This, para);
4924 if (!This->services)
4925 return CO_E_RELEASED;
4927 if (!para)
4928 return E_INVALIDARG;
4930 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
4931 hr = create_textpara(range, para);
4932 ITextRange_Release(range);
4933 return hr;
4936 static HRESULT WINAPI ITextSelection_fnSetPara(ITextSelection *me, ITextPara *para)
4938 struct text_selection *This = impl_from_ITextSelection(me);
4940 FIXME("(%p)->(%p): stub\n", This, para);
4942 if (!This->services)
4943 return CO_E_RELEASED;
4945 FIXME("not implemented\n");
4946 return E_NOTIMPL;
4949 static HRESULT WINAPI ITextSelection_fnGetStoryLength(ITextSelection *me, LONG *length)
4951 struct text_selection *This = impl_from_ITextSelection(me);
4953 TRACE("(%p)->(%p)\n", This, length);
4955 if (!This->services)
4956 return CO_E_RELEASED;
4958 return textrange_get_storylength(This->services->editor, length);
4961 static HRESULT WINAPI ITextSelection_fnGetStoryType(ITextSelection *me, LONG *value)
4963 struct text_selection *This = impl_from_ITextSelection(me);
4965 TRACE("(%p)->(%p)\n", This, value);
4967 if (!This->services)
4968 return CO_E_RELEASED;
4970 if (!value)
4971 return E_INVALIDARG;
4973 *value = tomUnknownStory;
4974 return S_OK;
4977 static HRESULT WINAPI ITextSelection_fnCollapse(ITextSelection *me, LONG bStart)
4979 struct text_selection *This = impl_from_ITextSelection(me);
4980 LONG start, end;
4981 HRESULT hres;
4983 TRACE("(%p)->(%ld)\n", This, bStart);
4985 if (!This->services)
4986 return CO_E_RELEASED;
4988 ME_GetSelectionOfs(This->services->editor, &start, &end);
4989 hres = range_Collapse(bStart, &start, &end);
4990 if (SUCCEEDED(hres))
4991 set_selection(This->services->editor, start, end);
4992 return hres;
4995 static HRESULT WINAPI ITextSelection_fnExpand(ITextSelection *me, LONG unit, LONG *delta)
4997 struct text_selection *This = impl_from_ITextSelection(me);
4998 ITextRange *range = NULL;
4999 HRESULT hr;
5001 TRACE("(%p)->(%ld %p)\n", This, unit, delta);
5003 if (!This->services)
5004 return CO_E_RELEASED;
5006 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5007 hr = textrange_expand(range, unit, delta);
5008 ITextRange_Release(range);
5009 return hr;
5012 static HRESULT WINAPI ITextSelection_fnGetIndex(ITextSelection *me, LONG unit, LONG *index)
5014 struct text_selection *This = impl_from_ITextSelection(me);
5016 FIXME("(%p)->(%ld %p): stub\n", This, unit, index);
5018 if (!This->services)
5019 return CO_E_RELEASED;
5021 return E_NOTIMPL;
5024 static HRESULT WINAPI ITextSelection_fnSetIndex(ITextSelection *me, LONG unit, LONG index,
5025 LONG extend)
5027 struct text_selection *This = impl_from_ITextSelection(me);
5029 FIXME("(%p)->(%ld %ld %ld): stub\n", This, unit, index, extend);
5031 if (!This->services)
5032 return CO_E_RELEASED;
5034 return E_NOTIMPL;
5037 static HRESULT WINAPI ITextSelection_fnSetRange(ITextSelection *me, LONG anchor, LONG active)
5039 struct text_selection *This = impl_from_ITextSelection(me);
5041 FIXME("(%p)->(%ld %ld): stub\n", This, anchor, active);
5043 if (!This->services)
5044 return CO_E_RELEASED;
5046 return E_NOTIMPL;
5049 static HRESULT WINAPI ITextSelection_fnInRange(ITextSelection *me, ITextRange *range, LONG *ret)
5051 struct text_selection *This = impl_from_ITextSelection(me);
5052 ITextSelection *selection = NULL;
5053 LONG start, end;
5055 TRACE("(%p)->(%p %p)\n", This, range, ret);
5057 if (ret)
5058 *ret = tomFalse;
5060 if (!This->services)
5061 return CO_E_RELEASED;
5063 if (!range)
5064 return S_FALSE;
5066 ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection);
5067 if (!selection)
5068 return S_FALSE;
5069 ITextSelection_Release(selection);
5071 ITextSelection_GetStart(me, &start);
5072 ITextSelection_GetEnd(me, &end);
5073 return textrange_inrange(start, end, range, ret);
5076 static HRESULT WINAPI ITextSelection_fnInStory(ITextSelection *me, ITextRange *range, LONG *ret)
5078 struct text_selection *This = impl_from_ITextSelection(me);
5080 FIXME("(%p)->(%p %p): stub\n", This, range, ret);
5082 if (!This->services)
5083 return CO_E_RELEASED;
5085 return E_NOTIMPL;
5088 static HRESULT WINAPI ITextSelection_fnIsEqual(ITextSelection *me, ITextRange *range, LONG *ret)
5090 struct text_selection *This = impl_from_ITextSelection(me);
5091 ITextSelection *selection = NULL;
5092 LONG start, end;
5094 TRACE("(%p)->(%p %p)\n", This, range, ret);
5096 if (ret)
5097 *ret = tomFalse;
5099 if (!This->services)
5100 return CO_E_RELEASED;
5102 if (!range)
5103 return S_FALSE;
5105 ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection);
5106 if (!selection)
5107 return S_FALSE;
5108 ITextSelection_Release(selection);
5110 ITextSelection_GetStart(me, &start);
5111 ITextSelection_GetEnd(me, &end);
5112 return textrange_isequal(start, end, range, ret);
5115 static HRESULT WINAPI ITextSelection_fnSelect(ITextSelection *me)
5117 struct text_selection *This = impl_from_ITextSelection(me);
5119 TRACE("(%p)\n", This);
5121 if (!This->services)
5122 return CO_E_RELEASED;
5124 /* nothing to do */
5125 return S_OK;
5128 static HRESULT WINAPI ITextSelection_fnStartOf(ITextSelection *me, LONG unit, LONG extend,
5129 LONG *delta)
5131 struct text_selection *This = impl_from_ITextSelection(me);
5132 ITextRange *range = NULL;
5133 HRESULT hr;
5135 TRACE("(%p)->(%ld %ld %p)\n", This, unit, extend, delta);
5137 if (!This->services)
5138 return CO_E_RELEASED;
5140 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5141 hr = textrange_startof(range, unit, extend, delta);
5142 ITextRange_Release(range);
5143 return hr;
5146 static HRESULT WINAPI ITextSelection_fnEndOf(ITextSelection *me, LONG unit, LONG extend,
5147 LONG *delta)
5149 struct text_selection *This = impl_from_ITextSelection(me);
5150 ITextRange *range = NULL;
5151 HRESULT hr;
5153 TRACE("(%p)->(%ld %ld %p)\n", This, unit, extend, delta);
5155 if (!This->services)
5156 return CO_E_RELEASED;
5158 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5159 hr = textrange_endof(range, This->services->editor, unit, extend, delta);
5160 ITextRange_Release(range);
5161 return hr;
5164 static HRESULT WINAPI ITextSelection_fnMove(ITextSelection *me, LONG unit, LONG count, LONG *delta)
5166 struct text_selection *This = impl_from_ITextSelection(me);
5167 ITextRange *range = NULL;
5168 HRESULT hr;
5170 TRACE("(%p)->(%ld %ld %p)\n", This, unit, count, delta);
5172 if (!This->services)
5173 return CO_E_RELEASED;
5175 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5176 hr = textrange_movestart(range, This->services->editor, unit, count, delta);
5177 ITextRange_Release(range);
5178 return hr;
5181 static HRESULT WINAPI ITextSelection_fnMoveStart(ITextSelection *me, LONG unit, LONG count,
5182 LONG *delta)
5184 struct text_selection *This = impl_from_ITextSelection(me);
5185 ITextRange *range = NULL;
5186 HRESULT hr;
5188 TRACE("(%p)->(%ld %ld %p)\n", This, unit, count, delta);
5190 if (!This->services)
5191 return CO_E_RELEASED;
5193 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5194 hr = textrange_movestart(range, This->services->editor, unit, count, delta);
5195 ITextRange_Release(range);
5196 return hr;
5199 static HRESULT WINAPI ITextSelection_fnMoveEnd(ITextSelection *me, LONG unit, LONG count,
5200 LONG *delta)
5202 struct text_selection *This = impl_from_ITextSelection(me);
5203 ITextRange *range = NULL;
5204 HRESULT hr;
5206 TRACE("(%p)->(%ld %ld %p)\n", This, unit, count, delta);
5208 if (!This->services)
5209 return CO_E_RELEASED;
5211 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5212 hr = textrange_moveend(range, This->services->editor, unit, count, delta);
5213 ITextRange_Release(range);
5214 return hr;
5217 static HRESULT WINAPI ITextSelection_fnMoveWhile(ITextSelection *me, VARIANT *charset, LONG count,
5218 LONG *delta)
5220 struct text_selection *This = impl_from_ITextSelection(me);
5222 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
5224 if (!This->services)
5225 return CO_E_RELEASED;
5227 return E_NOTIMPL;
5230 static HRESULT WINAPI ITextSelection_fnMoveStartWhile(ITextSelection *me, VARIANT *charset, LONG count,
5231 LONG *delta)
5233 struct text_selection *This = impl_from_ITextSelection(me);
5235 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
5237 if (!This->services)
5238 return CO_E_RELEASED;
5240 return E_NOTIMPL;
5243 static HRESULT WINAPI ITextSelection_fnMoveEndWhile(ITextSelection *me, VARIANT *charset, LONG count,
5244 LONG *delta)
5246 struct text_selection *This = impl_from_ITextSelection(me);
5248 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
5250 if (!This->services)
5251 return CO_E_RELEASED;
5253 return E_NOTIMPL;
5256 static HRESULT WINAPI ITextSelection_fnMoveUntil(ITextSelection *me, VARIANT *charset, LONG count,
5257 LONG *delta)
5259 struct text_selection *This = impl_from_ITextSelection(me);
5261 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
5263 if (!This->services)
5264 return CO_E_RELEASED;
5266 return E_NOTIMPL;
5269 static HRESULT WINAPI ITextSelection_fnMoveStartUntil(ITextSelection *me, VARIANT *charset, LONG count,
5270 LONG *delta)
5272 struct text_selection *This = impl_from_ITextSelection(me);
5274 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
5276 if (!This->services)
5277 return CO_E_RELEASED;
5279 return E_NOTIMPL;
5282 static HRESULT WINAPI ITextSelection_fnMoveEndUntil(ITextSelection *me, VARIANT *charset, LONG count,
5283 LONG *delta)
5285 struct text_selection *This = impl_from_ITextSelection(me);
5287 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
5289 if (!This->services)
5290 return CO_E_RELEASED;
5292 return E_NOTIMPL;
5295 static HRESULT WINAPI ITextSelection_fnFindText(ITextSelection *me, BSTR text, LONG count, LONG flags,
5296 LONG *length)
5298 struct text_selection *This = impl_from_ITextSelection(me);
5300 FIXME("(%p)->(%s %ld %lx %p): stub\n", This, debugstr_w(text), count, flags, length);
5302 if (!This->services)
5303 return CO_E_RELEASED;
5305 FIXME("not implemented\n");
5306 return E_NOTIMPL;
5309 static HRESULT WINAPI ITextSelection_fnFindTextStart(ITextSelection *me, BSTR text, LONG count,
5310 LONG flags, LONG *length)
5312 struct text_selection *This = impl_from_ITextSelection(me);
5314 FIXME("(%p)->(%s %ld %lx %p): stub\n", This, debugstr_w(text), count, flags, length);
5316 if (!This->services)
5317 return CO_E_RELEASED;
5319 return E_NOTIMPL;
5322 static HRESULT WINAPI ITextSelection_fnFindTextEnd(ITextSelection *me, BSTR text, LONG count,
5323 LONG flags, LONG *length)
5325 struct text_selection *This = impl_from_ITextSelection(me);
5327 FIXME("(%p)->(%s %ld %lx %p): stub\n", This, debugstr_w(text), count, flags, length);
5329 if (!This->services)
5330 return CO_E_RELEASED;
5332 return E_NOTIMPL;
5335 static HRESULT WINAPI ITextSelection_fnDelete(ITextSelection *me, LONG unit, LONG count,
5336 LONG *delta)
5338 struct text_selection *This = impl_from_ITextSelection(me);
5340 FIXME("(%p)->(%ld %ld %p): stub\n", This, unit, count, delta);
5342 if (!This->services)
5343 return CO_E_RELEASED;
5345 return E_NOTIMPL;
5348 static HRESULT WINAPI ITextSelection_fnCut(ITextSelection *me, VARIANT *v)
5350 struct text_selection *This = impl_from_ITextSelection(me);
5351 ITextRange *range = NULL;
5352 HRESULT hr;
5354 TRACE("(%p)->(%p): stub\n", This, v);
5356 if (!This->services)
5357 return CO_E_RELEASED;
5359 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5360 hr = textrange_copy_or_cut(range, This->services->editor, TRUE, v);
5361 ITextRange_Release(range);
5362 return hr;
5365 static HRESULT WINAPI ITextSelection_fnCopy(ITextSelection *me, VARIANT *v)
5367 struct text_selection *This = impl_from_ITextSelection(me);
5368 ITextRange *range = NULL;
5369 HRESULT hr;
5371 TRACE("(%p)->(%p)\n", This, v);
5373 if (!This->services)
5374 return CO_E_RELEASED;
5376 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5377 hr = textrange_copy_or_cut(range, This->services->editor, FALSE, v);
5378 ITextRange_Release(range);
5379 return hr;
5382 static HRESULT WINAPI ITextSelection_fnPaste(ITextSelection *me, VARIANT *v, LONG format)
5384 struct text_selection *This = impl_from_ITextSelection(me);
5386 FIXME("(%p)->(%s %lx): stub\n", This, debugstr_variant(v), format);
5388 if (!This->services)
5389 return CO_E_RELEASED;
5391 return E_NOTIMPL;
5394 static HRESULT WINAPI ITextSelection_fnCanPaste(ITextSelection *me, VARIANT *v, LONG format,
5395 LONG *ret)
5397 struct text_selection *This = impl_from_ITextSelection(me);
5399 FIXME("(%p)->(%s %lx %p): stub\n", This, debugstr_variant(v), format, ret);
5401 if (!This->services)
5402 return CO_E_RELEASED;
5404 return E_NOTIMPL;
5407 static HRESULT WINAPI ITextSelection_fnCanEdit(ITextSelection *me, LONG *ret)
5409 struct text_selection *This = impl_from_ITextSelection(me);
5411 FIXME("(%p)->(%p): stub\n", This, ret);
5413 if (!This->services)
5414 return CO_E_RELEASED;
5416 return E_NOTIMPL;
5419 static HRESULT WINAPI ITextSelection_fnChangeCase(ITextSelection *me, LONG type)
5421 struct text_selection *This = impl_from_ITextSelection(me);
5423 FIXME("(%p)->(%ld): stub\n", This, type);
5425 if (!This->services)
5426 return CO_E_RELEASED;
5428 return E_NOTIMPL;
5431 static HRESULT WINAPI ITextSelection_fnGetPoint(ITextSelection *me, LONG type, LONG *cx, LONG *cy)
5433 struct text_selection *This = impl_from_ITextSelection(me);
5435 FIXME("(%p)->(%ld %p %p): stub\n", This, type, cx, cy);
5437 if (!This->services)
5438 return CO_E_RELEASED;
5440 return E_NOTIMPL;
5443 static HRESULT WINAPI ITextSelection_fnSetPoint(ITextSelection *me, LONG x, LONG y, LONG type,
5444 LONG extend)
5446 struct text_selection *This = impl_from_ITextSelection(me);
5448 FIXME("(%p)->(%ld %ld %ld %ld): stub\n", This, x, y, type, extend);
5450 if (!This->services)
5451 return CO_E_RELEASED;
5453 return E_NOTIMPL;
5456 static HRESULT WINAPI ITextSelection_fnScrollIntoView(ITextSelection *me, LONG value)
5458 struct text_selection *This = impl_from_ITextSelection(me);
5460 FIXME("(%p)->(%ld): stub\n", This, value);
5462 if (!This->services)
5463 return CO_E_RELEASED;
5465 return E_NOTIMPL;
5468 static HRESULT WINAPI ITextSelection_fnGetEmbeddedObject(ITextSelection *me, IUnknown **ppv)
5470 struct text_selection *This = impl_from_ITextSelection(me);
5472 FIXME("(%p)->(%p): stub\n", This, ppv);
5474 if (!This->services)
5475 return CO_E_RELEASED;
5477 return E_NOTIMPL;
5480 /*** ITextSelection methods ***/
5481 static HRESULT WINAPI ITextSelection_fnGetFlags(ITextSelection *me, LONG *flags)
5483 struct text_selection *This = impl_from_ITextSelection(me);
5485 FIXME("(%p)->(%p): stub\n", This, flags);
5487 if (!This->services)
5488 return CO_E_RELEASED;
5490 return E_NOTIMPL;
5493 static HRESULT WINAPI ITextSelection_fnSetFlags(ITextSelection *me, LONG flags)
5495 struct text_selection *This = impl_from_ITextSelection(me);
5497 FIXME("(%p)->(%lx): stub\n", This, flags);
5499 if (!This->services)
5500 return CO_E_RELEASED;
5502 return E_NOTIMPL;
5505 static HRESULT WINAPI ITextSelection_fnGetType(ITextSelection *me, LONG *type)
5507 struct text_selection *This = impl_from_ITextSelection(me);
5509 FIXME("(%p)->(%p): stub\n", This, type);
5511 if (!This->services)
5512 return CO_E_RELEASED;
5514 return E_NOTIMPL;
5517 static HRESULT WINAPI ITextSelection_fnMoveLeft(ITextSelection *me, LONG unit, LONG count,
5518 LONG extend, LONG *delta)
5520 struct text_selection *This = impl_from_ITextSelection(me);
5522 FIXME("(%p)->(%ld %ld %ld %p): stub\n", This, unit, count, extend, delta);
5524 if (!This->services)
5525 return CO_E_RELEASED;
5527 return E_NOTIMPL;
5530 static HRESULT WINAPI ITextSelection_fnMoveRight(ITextSelection *me, LONG unit, LONG count,
5531 LONG extend, LONG *delta)
5533 struct text_selection *This = impl_from_ITextSelection(me);
5535 FIXME("(%p)->(%ld %ld %ld %p): stub\n", This, unit, count, extend, delta);
5537 if (!This->services)
5538 return CO_E_RELEASED;
5540 return E_NOTIMPL;
5543 static HRESULT WINAPI ITextSelection_fnMoveUp(ITextSelection *me, LONG unit, LONG count,
5544 LONG extend, LONG *delta)
5546 struct text_selection *This = impl_from_ITextSelection(me);
5548 FIXME("(%p)->(%ld %ld %ld %p): stub\n", This, unit, count, extend, delta);
5550 if (!This->services)
5551 return CO_E_RELEASED;
5553 return E_NOTIMPL;
5556 static HRESULT WINAPI ITextSelection_fnMoveDown(ITextSelection *me, LONG unit, LONG count,
5557 LONG extend, LONG *delta)
5559 struct text_selection *This = impl_from_ITextSelection(me);
5561 FIXME("(%p)->(%ld %ld %ld %p): stub\n", This, unit, count, extend, delta);
5563 if (!This->services)
5564 return CO_E_RELEASED;
5566 return E_NOTIMPL;
5569 static HRESULT WINAPI ITextSelection_fnHomeKey(ITextSelection *me, LONG unit, LONG extend,
5570 LONG *delta)
5572 struct text_selection *This = impl_from_ITextSelection(me);
5574 FIXME("(%p)->(%ld %ld %p): stub\n", This, unit, extend, delta);
5576 if (!This->services)
5577 return CO_E_RELEASED;
5579 return E_NOTIMPL;
5582 static HRESULT WINAPI ITextSelection_fnEndKey(ITextSelection *me, LONG unit, LONG extend,
5583 LONG *delta)
5585 struct text_selection *This = impl_from_ITextSelection(me);
5587 FIXME("(%p)->(%ld %ld %p): stub\n", This, unit, extend, delta);
5589 if (!This->services)
5590 return CO_E_RELEASED;
5592 return E_NOTIMPL;
5595 static HRESULT WINAPI ITextSelection_fnTypeText(ITextSelection *me, BSTR text)
5597 struct text_selection *This = impl_from_ITextSelection(me);
5599 FIXME("(%p)->(%s): stub\n", This, debugstr_w(text));
5601 if (!This->services)
5602 return CO_E_RELEASED;
5604 return E_NOTIMPL;
5607 static const ITextSelectionVtbl tsvt = {
5608 ITextSelection_fnQueryInterface,
5609 ITextSelection_fnAddRef,
5610 ITextSelection_fnRelease,
5611 ITextSelection_fnGetTypeInfoCount,
5612 ITextSelection_fnGetTypeInfo,
5613 ITextSelection_fnGetIDsOfNames,
5614 ITextSelection_fnInvoke,
5615 ITextSelection_fnGetText,
5616 ITextSelection_fnSetText,
5617 ITextSelection_fnGetChar,
5618 ITextSelection_fnSetChar,
5619 ITextSelection_fnGetDuplicate,
5620 ITextSelection_fnGetFormattedText,
5621 ITextSelection_fnSetFormattedText,
5622 ITextSelection_fnGetStart,
5623 ITextSelection_fnSetStart,
5624 ITextSelection_fnGetEnd,
5625 ITextSelection_fnSetEnd,
5626 ITextSelection_fnGetFont,
5627 ITextSelection_fnSetFont,
5628 ITextSelection_fnGetPara,
5629 ITextSelection_fnSetPara,
5630 ITextSelection_fnGetStoryLength,
5631 ITextSelection_fnGetStoryType,
5632 ITextSelection_fnCollapse,
5633 ITextSelection_fnExpand,
5634 ITextSelection_fnGetIndex,
5635 ITextSelection_fnSetIndex,
5636 ITextSelection_fnSetRange,
5637 ITextSelection_fnInRange,
5638 ITextSelection_fnInStory,
5639 ITextSelection_fnIsEqual,
5640 ITextSelection_fnSelect,
5641 ITextSelection_fnStartOf,
5642 ITextSelection_fnEndOf,
5643 ITextSelection_fnMove,
5644 ITextSelection_fnMoveStart,
5645 ITextSelection_fnMoveEnd,
5646 ITextSelection_fnMoveWhile,
5647 ITextSelection_fnMoveStartWhile,
5648 ITextSelection_fnMoveEndWhile,
5649 ITextSelection_fnMoveUntil,
5650 ITextSelection_fnMoveStartUntil,
5651 ITextSelection_fnMoveEndUntil,
5652 ITextSelection_fnFindText,
5653 ITextSelection_fnFindTextStart,
5654 ITextSelection_fnFindTextEnd,
5655 ITextSelection_fnDelete,
5656 ITextSelection_fnCut,
5657 ITextSelection_fnCopy,
5658 ITextSelection_fnPaste,
5659 ITextSelection_fnCanPaste,
5660 ITextSelection_fnCanEdit,
5661 ITextSelection_fnChangeCase,
5662 ITextSelection_fnGetPoint,
5663 ITextSelection_fnSetPoint,
5664 ITextSelection_fnScrollIntoView,
5665 ITextSelection_fnGetEmbeddedObject,
5666 ITextSelection_fnGetFlags,
5667 ITextSelection_fnSetFlags,
5668 ITextSelection_fnGetType,
5669 ITextSelection_fnMoveLeft,
5670 ITextSelection_fnMoveRight,
5671 ITextSelection_fnMoveUp,
5672 ITextSelection_fnMoveDown,
5673 ITextSelection_fnHomeKey,
5674 ITextSelection_fnEndKey,
5675 ITextSelection_fnTypeText
5678 static struct text_selection *text_selection_create(struct text_services *services)
5680 struct text_selection *txtSel = heap_alloc(sizeof *txtSel);
5681 if (!txtSel)
5682 return NULL;
5684 txtSel->ITextSelection_iface.lpVtbl = &tsvt;
5685 txtSel->ref = 1;
5686 txtSel->services = services;
5687 return txtSel;
5690 static void convert_sizel(const ME_Context *c, const SIZEL* szl, SIZE* sz)
5692 /* sizel is in .01 millimeters, sz in pixels */
5693 sz->cx = MulDiv(szl->cx, c->dpi.cx, 2540);
5694 sz->cy = MulDiv(szl->cy, c->dpi.cy, 2540);
5697 /******************************************************************************
5698 * ME_GetOLEObjectSize
5700 * Sets run extent for OLE objects.
5702 void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize)
5704 IDataObject* ido;
5705 FORMATETC fmt;
5706 STGMEDIUM stgm;
5707 DIBSECTION dibsect;
5708 ENHMETAHEADER emh;
5710 assert(run->nFlags & MERF_GRAPHICS);
5711 assert(run->reobj);
5713 if (run->reobj->obj.sizel.cx != 0 || run->reobj->obj.sizel.cy != 0)
5715 convert_sizel(c, &run->reobj->obj.sizel, pSize);
5716 if (c->editor->nZoomNumerator != 0)
5718 pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5719 pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5721 return;
5724 if (!run->reobj->obj.poleobj)
5726 pSize->cx = pSize->cy = 0;
5727 return;
5730 if (IOleObject_QueryInterface(run->reobj->obj.poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
5732 FIXME("Query Interface IID_IDataObject failed!\n");
5733 pSize->cx = pSize->cy = 0;
5734 return;
5736 fmt.cfFormat = CF_BITMAP;
5737 fmt.ptd = NULL;
5738 fmt.dwAspect = DVASPECT_CONTENT;
5739 fmt.lindex = -1;
5740 fmt.tymed = TYMED_GDI;
5741 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5743 fmt.cfFormat = CF_ENHMETAFILE;
5744 fmt.tymed = TYMED_ENHMF;
5745 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5747 FIXME("unsupported format\n");
5748 pSize->cx = pSize->cy = 0;
5749 IDataObject_Release(ido);
5750 return;
5753 IDataObject_Release(ido);
5755 switch (stgm.tymed)
5757 case TYMED_GDI:
5758 GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
5759 pSize->cx = dibsect.dsBm.bmWidth;
5760 pSize->cy = dibsect.dsBm.bmHeight;
5761 break;
5762 case TYMED_ENHMF:
5763 GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
5764 pSize->cx = emh.rclBounds.right - emh.rclBounds.left;
5765 pSize->cy = emh.rclBounds.bottom - emh.rclBounds.top;
5766 break;
5767 default:
5768 FIXME("Unsupported tymed %ld\n", stgm.tymed);
5769 break;
5771 ReleaseStgMedium(&stgm);
5772 if (c->editor->nZoomNumerator != 0)
5774 pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5775 pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5779 void draw_ole( ME_Context *c, int x, int y, ME_Run *run, BOOL selected )
5781 IDataObject* ido;
5782 IViewObject* ivo;
5783 FORMATETC fmt;
5784 STGMEDIUM stgm;
5785 DIBSECTION dibsect;
5786 ENHMETAHEADER emh;
5787 HDC hMemDC;
5788 SIZE sz;
5789 BOOL has_size;
5790 HBITMAP old_bm;
5791 RECT rc;
5793 assert(run->nFlags & MERF_GRAPHICS);
5794 assert(run->reobj);
5796 if (SUCCEEDED(IOleObject_QueryInterface(run->reobj->obj.poleobj, &IID_IViewObject, (void**)&ivo)))
5798 HRESULT hr;
5799 RECTL bounds;
5801 convert_sizel(c, &run->reobj->obj.sizel, &sz);
5802 if (c->editor->nZoomNumerator != 0)
5804 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5805 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5808 bounds.left = x;
5809 bounds.top = y - sz.cy;
5810 bounds.right = x + sz.cx;
5811 bounds.bottom = y;
5813 hr = IViewObject_Draw(ivo, DVASPECT_CONTENT, -1, 0, 0, 0, c->hDC, &bounds, NULL, NULL, 0);
5814 if (FAILED(hr))
5816 WARN("failed to draw object: %#08lx\n", hr);
5819 IViewObject_Release(ivo);
5820 return;
5823 if (IOleObject_QueryInterface(run->reobj->obj.poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
5825 FIXME("Couldn't get interface\n");
5826 return;
5828 has_size = run->reobj->obj.sizel.cx != 0 || run->reobj->obj.sizel.cy != 0;
5829 fmt.cfFormat = CF_BITMAP;
5830 fmt.ptd = NULL;
5831 fmt.dwAspect = DVASPECT_CONTENT;
5832 fmt.lindex = -1;
5833 fmt.tymed = TYMED_GDI;
5834 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5836 fmt.cfFormat = CF_ENHMETAFILE;
5837 fmt.tymed = TYMED_ENHMF;
5838 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5840 FIXME("Couldn't get storage medium\n");
5841 IDataObject_Release(ido);
5842 return;
5845 IDataObject_Release(ido);
5847 switch (stgm.tymed)
5849 case TYMED_GDI:
5850 GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
5851 hMemDC = CreateCompatibleDC(c->hDC);
5852 old_bm = SelectObject(hMemDC, stgm.u.hBitmap);
5853 if (has_size)
5855 convert_sizel(c, &run->reobj->obj.sizel, &sz);
5856 } else {
5857 sz.cx = dibsect.dsBm.bmWidth;
5858 sz.cy = dibsect.dsBm.bmHeight;
5860 if (c->editor->nZoomNumerator != 0)
5862 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5863 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5865 StretchBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy,
5866 hMemDC, 0, 0, dibsect.dsBm.bmWidth, dibsect.dsBm.bmHeight, SRCCOPY);
5868 SelectObject(hMemDC, old_bm);
5869 DeleteDC(hMemDC);
5870 break;
5871 case TYMED_ENHMF:
5872 GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
5873 if (has_size)
5875 convert_sizel(c, &run->reobj->obj.sizel, &sz);
5876 } else {
5877 sz.cx = emh.rclBounds.right - emh.rclBounds.left;
5878 sz.cy = emh.rclBounds.bottom - emh.rclBounds.top;
5880 if (c->editor->nZoomNumerator != 0)
5882 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5883 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5886 rc.left = x;
5887 rc.top = y - sz.cy;
5888 rc.right = x + sz.cx;
5889 rc.bottom = y;
5890 PlayEnhMetaFile(c->hDC, stgm.u.hEnhMetaFile, &rc);
5891 break;
5892 default:
5893 FIXME("Unsupported tymed %ld\n", stgm.tymed);
5894 selected = FALSE;
5895 break;
5897 ReleaseStgMedium(&stgm);
5899 if (selected && !c->editor->bHideSelection)
5900 PatBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy, DSTINVERT);
5903 void ME_DeleteReObject(struct re_object *reobj)
5905 if (reobj->obj.poleobj) IOleObject_Release(reobj->obj.poleobj);
5906 if (reobj->obj.pstg) IStorage_Release(reobj->obj.pstg);
5907 if (reobj->obj.polesite) IOleClientSite_Release(reobj->obj.polesite);
5908 heap_free(reobj);
5911 void ME_CopyReObject(REOBJECT *dst, const REOBJECT *src, DWORD flags)
5913 *dst = *src;
5914 dst->poleobj = NULL;
5915 dst->pstg = NULL;
5916 dst->polesite = NULL;
5918 if ((flags & REO_GETOBJ_POLEOBJ) && src->poleobj)
5920 dst->poleobj = src->poleobj;
5921 IOleObject_AddRef(dst->poleobj);
5923 if ((flags & REO_GETOBJ_PSTG) && src->pstg)
5925 dst->pstg = src->pstg;
5926 IStorage_AddRef(dst->pstg);
5928 if ((flags & REO_GETOBJ_POLESITE) && src->polesite)
5930 dst->polesite = src->polesite;
5931 IOleClientSite_AddRef(dst->polesite);
5935 void richole_release_children( struct text_services *services )
5937 ITextRangeImpl *range;
5938 IOleClientSiteImpl *site;
5940 if (services->text_selection)
5942 services->text_selection->services = NULL;
5943 ITextSelection_Release( &services->text_selection->ITextSelection_iface );
5946 LIST_FOR_EACH_ENTRY( range, &services->rangelist, ITextRangeImpl, child.entry )
5947 range->child.reole = NULL;
5949 LIST_FOR_EACH_ENTRY( site, &services->clientsites, IOleClientSiteImpl, child.entry )
5950 site->child.reole = NULL;