ddraw: Set dwMaxVertexCount to 2048.
[wine.git] / dlls / riched20 / richole.c
blob51ae41d2fe71b32575b8a7f0ac17c898a51744c0
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 COBJMACROS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "winuser.h"
30 #include "ole2.h"
31 #include "richole.h"
32 #include "editor.h"
33 #include "richedit.h"
34 #include "tom.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(richedit);
39 /* there is no way to be consistent across different sets of headers - mingw, Wine, Win32 SDK*/
41 #include "initguid.h"
43 DEFINE_GUID(LIBID_tom, 0x8cc497c9, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
44 DEFINE_GUID(IID_ITextServices, 0x8d33f740, 0xcf58, 0x11ce, 0xa8, 0x9d, 0x00, 0xaa, 0x00, 0x6c, 0xad, 0xc5);
45 DEFINE_GUID(IID_ITextHost, 0x13e670f4,0x1a5a,0x11cf,0xab,0xeb,0x00,0xaa,0x00,0xb6,0x5e,0xa1);
46 DEFINE_GUID(IID_ITextHost2, 0x13e670f5,0x1a5a,0x11cf,0xab,0xeb,0x00,0xaa,0x00,0xb6,0x5e,0xa1);
47 DEFINE_GUID(IID_ITextDocument, 0x8cc497c0, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
48 DEFINE_GUID(IID_ITextDocument2Old, 0x01c25500, 0x4268, 0x11d1, 0x88, 0x3a, 0x3c, 0x8b, 0x00, 0xc1, 0x00, 0x00);
49 DEFINE_GUID(IID_ITextRange, 0x8cc497c2, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
50 DEFINE_GUID(IID_ITextSelection, 0x8cc497c1, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
51 DEFINE_GUID(IID_ITextFont, 0x8cc497c3, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
52 DEFINE_GUID(IID_ITextPara, 0x8cc497c4, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
54 static ITypeLib *typelib;
56 enum tid_t {
57 NULL_tid,
58 ITextDocument_tid,
59 ITextRange_tid,
60 ITextSelection_tid,
61 ITextFont_tid,
62 ITextPara_tid,
63 LAST_tid
66 static const IID * const tid_ids[] =
68 &IID_NULL,
69 &IID_ITextDocument,
70 &IID_ITextRange,
71 &IID_ITextSelection,
72 &IID_ITextFont,
73 &IID_ITextPara,
75 static ITypeInfo *typeinfos[LAST_tid];
77 static HRESULT load_typelib(void)
79 ITypeLib *tl;
80 HRESULT hr;
82 hr = LoadRegTypeLib(&LIBID_tom, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
83 if (FAILED(hr)) {
84 ERR("LoadRegTypeLib failed: %08lx\n", hr);
85 return hr;
88 if (InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
89 ITypeLib_Release(tl);
90 return hr;
93 void release_typelib(void)
95 unsigned i;
97 if (!typelib)
98 return;
100 for (i = 0; i < ARRAY_SIZE(typeinfos); i++)
101 if (typeinfos[i])
102 ITypeInfo_Release(typeinfos[i]);
104 ITypeLib_Release(typelib);
107 static HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo)
109 HRESULT hr;
111 if (!typelib)
112 hr = load_typelib();
113 if (!typelib)
114 return hr;
116 if (!typeinfos[tid])
118 ITypeInfo *ti;
120 hr = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
121 if (FAILED(hr))
123 ERR("GetTypeInfoOfGuid(%s) failed: %08lx\n", debugstr_guid(tid_ids[tid]), hr);
124 return hr;
127 if (InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
128 ITypeInfo_Release(ti);
131 *typeinfo = typeinfos[tid];
132 return S_OK;
135 /* private IID used to get back IRichEditOleImpl pointer */
136 DEFINE_GUID(IID_Igetrichole, 0xe3ce5c7a, 0x8247, 0x4622, 0x81, 0xad, 0x11, 0x81, 0x02, 0xaa, 0x01, 0x30);
138 typedef struct IOleClientSiteImpl IOleClientSiteImpl;
139 typedef struct ITextRangeImpl ITextRangeImpl;
141 enum textfont_prop_id {
142 FONT_ALLCAPS = 0,
143 FONT_ANIMATION,
144 FONT_BACKCOLOR,
145 FONT_BOLD,
146 FONT_EMBOSS,
147 FONT_FORECOLOR,
148 FONT_HIDDEN,
149 FONT_ENGRAVE,
150 FONT_ITALIC,
151 FONT_KERNING,
152 FONT_LANGID,
153 FONT_NAME,
154 FONT_OUTLINE,
155 FONT_POSITION,
156 FONT_PROTECTED,
157 FONT_SHADOW,
158 FONT_SIZE,
159 FONT_SMALLCAPS,
160 FONT_SPACING,
161 FONT_STRIKETHROUGH,
162 FONT_SUBSCRIPT,
163 FONT_SUPERSCRIPT,
164 FONT_UNDERLINE,
165 FONT_WEIGHT,
166 FONT_PROPID_LAST,
167 FONT_PROPID_FIRST = FONT_ALLCAPS
170 static const DWORD textfont_prop_masks[][2] = {
171 { CFM_ALLCAPS, CFE_ALLCAPS },
172 { CFM_ANIMATION },
173 { CFM_BACKCOLOR, CFE_AUTOBACKCOLOR },
174 { CFM_BOLD, CFE_BOLD },
175 { CFM_EMBOSS, CFE_EMBOSS },
176 { CFM_COLOR, CFE_AUTOCOLOR },
177 { CFM_HIDDEN, CFE_HIDDEN },
178 { CFM_IMPRINT, CFE_IMPRINT },
179 { CFM_ITALIC, CFE_ITALIC },
180 { CFM_KERNING },
181 { CFM_LCID },
182 { CFM_FACE },
183 { CFM_OUTLINE, CFE_OUTLINE },
184 { CFM_OFFSET },
185 { CFM_PROTECTED, CFE_PROTECTED },
186 { CFM_SHADOW, CFE_SHADOW },
187 { CFM_SIZE },
188 { CFM_SMALLCAPS, CFE_SMALLCAPS },
189 { CFM_SPACING },
190 { CFM_STRIKEOUT, CFE_STRIKEOUT },
191 { CFM_SUBSCRIPT, CFE_SUBSCRIPT },
192 { CFM_SUPERSCRIPT, CFE_SUPERSCRIPT },
193 { CFM_UNDERLINE, CFE_UNDERLINE },
194 { CFM_WEIGHT }
197 typedef union {
198 FLOAT f;
199 LONG l;
200 BSTR str;
201 } textfont_prop_val;
203 enum range_update_op {
204 RANGE_UPDATE_DELETE
207 struct reole_child {
208 struct list entry;
209 struct text_services *reole;
212 struct ITextRangeImpl {
213 struct reole_child child;
214 ITextRange ITextRange_iface;
215 LONG ref;
216 LONG start, end;
219 typedef struct ITextFontImpl {
220 ITextFont ITextFont_iface;
221 LONG ref;
223 ITextRange *range;
224 textfont_prop_val props[FONT_PROPID_LAST];
225 BOOL get_cache_enabled;
226 BOOL set_cache_enabled;
227 } ITextFontImpl;
229 typedef struct ITextParaImpl {
230 ITextPara ITextPara_iface;
231 LONG ref;
233 ITextRange *range;
234 } ITextParaImpl;
236 struct IOleClientSiteImpl {
237 struct reole_child child;
238 IOleClientSite IOleClientSite_iface;
239 IOleInPlaceSite IOleInPlaceSite_iface;
240 LONG ref;
243 static inline struct text_services *impl_from_IRichEditOle( IRichEditOle *iface )
245 return CONTAINING_RECORD( iface, struct text_services, IRichEditOle_iface );
248 static inline struct text_services *impl_from_ITextDocument2Old( ITextDocument2Old *iface )
250 return CONTAINING_RECORD( iface, struct text_services, ITextDocument2Old_iface );
253 static inline IOleClientSiteImpl *impl_from_IOleInPlaceSite(IOleInPlaceSite *iface)
255 return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleInPlaceSite_iface);
258 static inline ITextRangeImpl *impl_from_ITextRange(ITextRange *iface)
260 return CONTAINING_RECORD(iface, ITextRangeImpl, ITextRange_iface);
263 static inline struct text_selection *impl_from_ITextSelection(ITextSelection *iface)
265 return CONTAINING_RECORD(iface, struct text_selection, ITextSelection_iface);
268 static inline ITextFontImpl *impl_from_ITextFont(ITextFont *iface)
270 return CONTAINING_RECORD(iface, ITextFontImpl, ITextFont_iface);
273 static inline ITextParaImpl *impl_from_ITextPara(ITextPara *iface)
275 return CONTAINING_RECORD(iface, ITextParaImpl, ITextPara_iface);
278 static HRESULT create_textfont(ITextRange*, const ITextFontImpl*, ITextFont**);
279 static HRESULT create_textpara(ITextRange*, ITextPara**);
280 static struct text_selection *text_selection_create( struct text_services * );
282 static HRESULT textrange_get_storylength(ME_TextEditor *editor, LONG *length)
284 if (!length)
285 return E_INVALIDARG;
287 *length = ME_GetTextLength(editor) + 1;
288 return S_OK;
291 static void textranges_update_ranges(struct text_services *services, LONG start, LONG end, enum range_update_op op)
293 ITextRangeImpl *range;
295 LIST_FOR_EACH_ENTRY(range, &services->rangelist, ITextRangeImpl, child.entry) {
296 switch (op)
298 case RANGE_UPDATE_DELETE:
299 /* range fully covered by deleted range - collapse to insertion point */
300 if (range->start >= start && range->end <= end)
301 range->start = range->end = start;
302 /* deleted range cuts from the right */
303 else if (range->start < start && range->end <= end)
304 range->end = start;
305 /* deleted range cuts from the left */
306 else if (range->start >= start && range->end > end) {
307 range->start = start;
308 range->end -= end - start;
310 /* deleted range cuts within */
311 else
312 range->end -= end - start;
313 break;
314 default:
315 FIXME("unknown update op, %d\n", op);
320 static inline BOOL is_equal_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *left,
321 textfont_prop_val *right)
323 switch (propid)
325 case FONT_ALLCAPS:
326 case FONT_ANIMATION:
327 case FONT_BACKCOLOR:
328 case FONT_BOLD:
329 case FONT_EMBOSS:
330 case FONT_FORECOLOR:
331 case FONT_HIDDEN:
332 case FONT_ENGRAVE:
333 case FONT_ITALIC:
334 case FONT_KERNING:
335 case FONT_LANGID:
336 case FONT_OUTLINE:
337 case FONT_PROTECTED:
338 case FONT_SHADOW:
339 case FONT_SMALLCAPS:
340 case FONT_STRIKETHROUGH:
341 case FONT_SUBSCRIPT:
342 case FONT_SUPERSCRIPT:
343 case FONT_UNDERLINE:
344 case FONT_WEIGHT:
345 return left->l == right->l;
346 case FONT_NAME:
347 return !wcscmp(left->str, right->str);
348 case FONT_POSITION:
349 case FONT_SIZE:
350 case FONT_SPACING:
351 return left->f == right->f;
352 default:
353 FIXME("unhandled font property %d\n", propid);
354 return FALSE;
358 static inline void init_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *v)
360 switch (propid)
362 case FONT_ALLCAPS:
363 case FONT_ANIMATION:
364 case FONT_BACKCOLOR:
365 case FONT_BOLD:
366 case FONT_EMBOSS:
367 case FONT_FORECOLOR:
368 case FONT_HIDDEN:
369 case FONT_ENGRAVE:
370 case FONT_ITALIC:
371 case FONT_KERNING:
372 case FONT_LANGID:
373 case FONT_OUTLINE:
374 case FONT_PROTECTED:
375 case FONT_SHADOW:
376 case FONT_SMALLCAPS:
377 case FONT_STRIKETHROUGH:
378 case FONT_SUBSCRIPT:
379 case FONT_SUPERSCRIPT:
380 case FONT_UNDERLINE:
381 case FONT_WEIGHT:
382 v->l = tomUndefined;
383 return;
384 case FONT_NAME:
385 v->str = NULL;
386 return;
387 case FONT_POSITION:
388 case FONT_SIZE:
389 case FONT_SPACING:
390 v->f = tomUndefined;
391 return;
392 default:
393 FIXME("unhandled font property %d\n", propid);
394 v->l = tomUndefined;
395 return;
399 static inline FLOAT twips_to_points(LONG value)
401 return value * 72.0 / 1440;
404 static inline FLOAT points_to_twips(FLOAT value)
406 return value * 1440 / 72.0;
409 static HRESULT get_textfont_prop_for_pos(const struct text_services *services, int pos, enum textfont_prop_id propid,
410 textfont_prop_val *value)
412 ME_Cursor from, to;
413 CHARFORMAT2W fmt;
415 memset(&fmt, 0, sizeof(fmt));
416 fmt.cbSize = sizeof(fmt);
417 fmt.dwMask = textfont_prop_masks[propid][0];
419 cursor_from_char_ofs( services->editor, pos, &from );
420 to = from;
421 ME_MoveCursorChars( services->editor, &to, 1, FALSE );
422 ME_GetCharFormat( services->editor, &from, &to, &fmt );
424 switch (propid)
426 case FONT_ALLCAPS:
427 case FONT_BOLD:
428 case FONT_EMBOSS:
429 case FONT_HIDDEN:
430 case FONT_ENGRAVE:
431 case FONT_ITALIC:
432 case FONT_OUTLINE:
433 case FONT_PROTECTED:
434 case FONT_SHADOW:
435 case FONT_SMALLCAPS:
436 case FONT_STRIKETHROUGH:
437 case FONT_SUBSCRIPT:
438 case FONT_SUPERSCRIPT:
439 case FONT_UNDERLINE:
440 value->l = fmt.dwEffects & textfont_prop_masks[propid][1] ? tomTrue : tomFalse;
441 break;
442 case FONT_ANIMATION:
443 value->l = fmt.bAnimation;
444 break;
445 case FONT_BACKCOLOR:
446 value->l = fmt.dwEffects & CFE_AUTOBACKCOLOR ? GetSysColor(COLOR_WINDOW) : fmt.crBackColor;
447 break;
448 case FONT_FORECOLOR:
449 value->l = fmt.dwEffects & CFE_AUTOCOLOR ? GetSysColor(COLOR_WINDOWTEXT) : fmt.crTextColor;
450 break;
451 case FONT_KERNING:
452 value->f = twips_to_points(fmt.wKerning);
453 break;
454 case FONT_LANGID:
455 value->l = fmt.lcid;
456 break;
457 case FONT_NAME:
458 /* this case is used exclusively by GetName() */
459 value->str = SysAllocString(fmt.szFaceName);
460 if (!value->str)
461 return E_OUTOFMEMORY;
462 break;
463 case FONT_POSITION:
464 value->f = twips_to_points(fmt.yOffset);
465 break;
466 case FONT_SIZE:
467 value->f = twips_to_points(fmt.yHeight);
468 break;
469 case FONT_SPACING:
470 value->f = fmt.sSpacing;
471 break;
472 case FONT_WEIGHT:
473 value->l = fmt.wWeight;
474 break;
475 default:
476 FIXME("unhandled font property %d\n", propid);
477 return E_FAIL;
480 return S_OK;
483 static inline const struct text_services *get_range_reole(ITextRange *range)
485 struct text_services *services = NULL;
486 ITextRange_QueryInterface(range, &IID_Igetrichole, (void**)&services);
487 return services;
490 static void textrange_set_font(ITextRange *range, ITextFont *font)
492 CHARFORMAT2W fmt;
493 HRESULT hr;
494 LONG value;
495 BSTR str;
496 FLOAT f;
498 #define CHARFORMAT_SET_B_FIELD(mask, value) \
499 if (hr == S_OK && value != tomUndefined) { \
500 fmt.dwMask |= CFM_##mask; \
501 if (value == tomTrue) fmt.dwEffects |= CFE_##mask; \
504 /* fill format data from font */
505 memset(&fmt, 0, sizeof(fmt));
506 fmt.cbSize = sizeof(fmt);
508 value = tomUndefined;
509 hr = ITextFont_GetAllCaps(font, &value);
510 CHARFORMAT_SET_B_FIELD(ALLCAPS, value);
512 value = tomUndefined;
513 hr = ITextFont_GetBold(font, &value);
514 CHARFORMAT_SET_B_FIELD(BOLD, value);
516 value = tomUndefined;
517 hr = ITextFont_GetEmboss(font, &value);
518 CHARFORMAT_SET_B_FIELD(EMBOSS, value);
520 value = tomUndefined;
521 hr = ITextFont_GetHidden(font, &value);
522 CHARFORMAT_SET_B_FIELD(HIDDEN, value);
524 value = tomUndefined;
525 hr = ITextFont_GetEngrave(font, &value);
526 CHARFORMAT_SET_B_FIELD(IMPRINT, value);
528 value = tomUndefined;
529 hr = ITextFont_GetItalic(font, &value);
530 CHARFORMAT_SET_B_FIELD(ITALIC, value);
532 value = tomUndefined;
533 hr = ITextFont_GetOutline(font, &value);
534 CHARFORMAT_SET_B_FIELD(OUTLINE, value);
536 value = tomUndefined;
537 hr = ITextFont_GetProtected(font, &value);
538 CHARFORMAT_SET_B_FIELD(PROTECTED, value);
540 value = tomUndefined;
541 hr = ITextFont_GetShadow(font, &value);
542 CHARFORMAT_SET_B_FIELD(SHADOW, value);
544 value = tomUndefined;
545 hr = ITextFont_GetSmallCaps(font, &value);
546 CHARFORMAT_SET_B_FIELD(SMALLCAPS, value);
548 value = tomUndefined;
549 hr = ITextFont_GetStrikeThrough(font, &value);
550 CHARFORMAT_SET_B_FIELD(STRIKEOUT, value);
552 value = tomUndefined;
553 hr = ITextFont_GetSubscript(font, &value);
554 CHARFORMAT_SET_B_FIELD(SUBSCRIPT, value);
556 value = tomUndefined;
557 hr = ITextFont_GetSuperscript(font, &value);
558 CHARFORMAT_SET_B_FIELD(SUPERSCRIPT, value);
560 value = tomUndefined;
561 hr = ITextFont_GetUnderline(font, &value);
562 CHARFORMAT_SET_B_FIELD(UNDERLINE, value);
564 #undef CHARFORMAT_SET_B_FIELD
566 value = tomUndefined;
567 hr = ITextFont_GetAnimation(font, &value);
568 if (hr == S_OK && value != tomUndefined) {
569 fmt.dwMask |= CFM_ANIMATION;
570 fmt.bAnimation = value;
573 value = tomUndefined;
574 hr = ITextFont_GetBackColor(font, &value);
575 if (hr == S_OK && value != tomUndefined) {
576 fmt.dwMask |= CFM_BACKCOLOR;
577 if (value == tomAutoColor)
578 fmt.dwEffects |= CFE_AUTOBACKCOLOR;
579 else
580 fmt.crBackColor = value;
583 value = tomUndefined;
584 hr = ITextFont_GetForeColor(font, &value);
585 if (hr == S_OK && value != tomUndefined) {
586 fmt.dwMask |= CFM_COLOR;
587 if (value == tomAutoColor)
588 fmt.dwEffects |= CFE_AUTOCOLOR;
589 else
590 fmt.crTextColor = value;
593 value = tomUndefined;
594 hr = ITextFont_GetKerning(font, &f);
595 if (hr == S_OK && f != tomUndefined) {
596 fmt.dwMask |= CFM_KERNING;
597 fmt.wKerning = points_to_twips(f);
600 value = tomUndefined;
601 hr = ITextFont_GetLanguageID(font, &value);
602 if (hr == S_OK && value != tomUndefined) {
603 fmt.dwMask |= CFM_LCID;
604 fmt.lcid = value;
607 if (ITextFont_GetName(font, &str) == S_OK) {
608 fmt.dwMask |= CFM_FACE;
609 lstrcpynW(fmt.szFaceName, str, ARRAY_SIZE(fmt.szFaceName));
610 SysFreeString(str);
613 hr = ITextFont_GetPosition(font, &f);
614 if (hr == S_OK && f != tomUndefined) {
615 fmt.dwMask |= CFM_OFFSET;
616 fmt.yOffset = points_to_twips(f);
619 hr = ITextFont_GetSize(font, &f);
620 if (hr == S_OK && f != tomUndefined) {
621 fmt.dwMask |= CFM_SIZE;
622 fmt.yHeight = points_to_twips(f);
625 hr = ITextFont_GetSpacing(font, &f);
626 if (hr == S_OK && f != tomUndefined) {
627 fmt.dwMask |= CFM_SPACING;
628 fmt.sSpacing = f;
631 hr = ITextFont_GetWeight(font, &value);
632 if (hr == S_OK && value != tomUndefined) {
633 fmt.dwMask |= CFM_WEIGHT;
634 fmt.wWeight = value;
637 if (fmt.dwMask)
639 const struct text_services *services = get_range_reole(range);
640 ME_Cursor from, to;
641 LONG start, end;
643 ITextRange_GetStart(range, &start);
644 ITextRange_GetEnd(range, &end);
646 cursor_from_char_ofs( services->editor, start, &from );
647 cursor_from_char_ofs( services->editor, end, &to );
648 ME_SetCharFormat( services->editor, &from, &to, &fmt );
649 ME_CommitUndo( services->editor );
650 ME_WrapMarkedParagraphs( services->editor );
651 ME_UpdateScrollBar( services->editor );
655 static HRESULT get_textfont_prop(const ITextFontImpl *font, enum textfont_prop_id propid, textfont_prop_val *value)
657 const struct text_services *services;
658 textfont_prop_val v;
659 LONG start, end, i;
660 HRESULT hr;
662 /* when font is not attached to any range use cached values */
663 if (!font->range || font->get_cache_enabled) {
664 *value = font->props[propid];
665 return S_OK;
668 if (!(services = get_range_reole(font->range)))
669 return CO_E_RELEASED;
671 init_textfont_prop_value(propid, value);
673 ITextRange_GetStart(font->range, &start);
674 ITextRange_GetEnd(font->range, &end);
676 /* iterate trough a range to see if property value is consistent */
677 hr = get_textfont_prop_for_pos( services, start, propid, &v );
678 if (FAILED(hr))
679 return hr;
681 for (i = start + 1; i < end; i++) {
682 textfont_prop_val cur;
684 hr = get_textfont_prop_for_pos( services, i, propid, &cur );
685 if (FAILED(hr))
686 return hr;
688 if (!is_equal_textfont_prop_value(propid, &v, &cur))
689 return S_OK;
692 *value = v;
693 return S_OK;
696 static HRESULT get_textfont_propf(const ITextFontImpl *font, enum textfont_prop_id propid, FLOAT *value)
698 textfont_prop_val v;
699 HRESULT hr;
701 if (!value)
702 return E_INVALIDARG;
704 hr = get_textfont_prop(font, propid, &v);
705 *value = v.f;
706 return hr;
709 static HRESULT get_textfont_propl(const ITextFontImpl *font, enum textfont_prop_id propid, LONG *value)
711 textfont_prop_val v;
712 HRESULT hr;
714 if (!value)
715 return E_INVALIDARG;
717 hr = get_textfont_prop(font, propid, &v);
718 *value = v.l;
719 return hr;
722 /* Value should already have a terminal value, for boolean properties it means tomToggle is not handled */
723 static HRESULT set_textfont_prop(ITextFontImpl *font, enum textfont_prop_id propid, const textfont_prop_val *value)
725 const struct text_services *services;
726 ME_Cursor from, to;
727 CHARFORMAT2W fmt;
728 LONG start, end;
730 /* when font is not attached to any range use cache */
731 if (!font->range || font->set_cache_enabled) {
732 if (propid == FONT_NAME) {
733 SysFreeString(font->props[propid].str);
734 font->props[propid].str = SysAllocString(value->str);
736 else
737 font->props[propid] = *value;
738 return S_OK;
741 if (!(services = get_range_reole(font->range)))
742 return CO_E_RELEASED;
744 memset(&fmt, 0, sizeof(fmt));
745 fmt.cbSize = sizeof(fmt);
746 fmt.dwMask = textfont_prop_masks[propid][0];
748 switch (propid)
750 case FONT_ALLCAPS:
751 case FONT_BOLD:
752 case FONT_EMBOSS:
753 case FONT_HIDDEN:
754 case FONT_ENGRAVE:
755 case FONT_ITALIC:
756 case FONT_OUTLINE:
757 case FONT_PROTECTED:
758 case FONT_SHADOW:
759 case FONT_SMALLCAPS:
760 case FONT_STRIKETHROUGH:
761 case FONT_SUBSCRIPT:
762 case FONT_SUPERSCRIPT:
763 case FONT_UNDERLINE:
764 fmt.dwEffects = value->l == tomTrue ? textfont_prop_masks[propid][1] : 0;
765 break;
766 case FONT_ANIMATION:
767 fmt.bAnimation = value->l;
768 break;
769 case FONT_BACKCOLOR:
770 case FONT_FORECOLOR:
771 if (value->l == tomAutoColor)
772 fmt.dwEffects = textfont_prop_masks[propid][1];
773 else if (propid == FONT_BACKCOLOR)
774 fmt.crBackColor = value->l;
775 else
776 fmt.crTextColor = value->l;
777 break;
778 case FONT_KERNING:
779 fmt.wKerning = value->f;
780 break;
781 case FONT_LANGID:
782 fmt.lcid = value->l;
783 break;
784 case FONT_POSITION:
785 fmt.yOffset = value->f;
786 break;
787 case FONT_SIZE:
788 fmt.yHeight = value->f;
789 break;
790 case FONT_SPACING:
791 fmt.sSpacing = value->f;
792 break;
793 case FONT_WEIGHT:
794 fmt.wWeight = value->l;
795 break;
796 case FONT_NAME:
797 lstrcpynW(fmt.szFaceName, value->str, ARRAY_SIZE(fmt.szFaceName));
798 break;
799 default:
800 FIXME("unhandled font property %d\n", propid);
801 return E_FAIL;
804 ITextRange_GetStart(font->range, &start);
805 ITextRange_GetEnd(font->range, &end);
807 cursor_from_char_ofs( services->editor, start, &from );
808 cursor_from_char_ofs( services->editor, end, &to );
809 ME_SetCharFormat( services->editor, &from, &to, &fmt );
810 ME_CommitUndo( services->editor );
811 ME_WrapMarkedParagraphs( services->editor );
812 ME_UpdateScrollBar( services->editor );
814 return S_OK;
817 static inline HRESULT set_textfont_propl(ITextFontImpl *font, enum textfont_prop_id propid, LONG value)
819 textfont_prop_val v;
820 v.l = value;
821 return set_textfont_prop(font, propid, &v);
824 static inline HRESULT set_textfont_propf(ITextFontImpl *font, enum textfont_prop_id propid, FLOAT value)
826 textfont_prop_val v;
827 v.f = value;
828 return set_textfont_prop(font, propid, &v);
831 static HRESULT set_textfont_propd(ITextFontImpl *font, enum textfont_prop_id propid, LONG value)
833 textfont_prop_val v;
835 switch (value)
837 case tomUndefined:
838 return S_OK;
839 case tomToggle: {
840 LONG oldvalue;
841 get_textfont_propl(font, propid, &oldvalue);
842 if (oldvalue == tomFalse)
843 value = tomTrue;
844 else if (oldvalue == tomTrue)
845 value = tomFalse;
846 else
847 return E_INVALIDARG;
848 /* fallthrough */
850 case tomTrue:
851 case tomFalse:
852 v.l = value;
853 return set_textfont_prop(font, propid, &v);
854 default:
855 return E_INVALIDARG;
859 static HRESULT textfont_getname_from_range(ITextRange *range, BSTR *ret)
861 const struct text_services *services;
862 textfont_prop_val v;
863 HRESULT hr;
864 LONG start;
866 if (!(services = get_range_reole( range )))
867 return CO_E_RELEASED;
869 ITextRange_GetStart(range, &start);
870 hr = get_textfont_prop_for_pos( services, start, FONT_NAME, &v );
871 *ret = v.str;
872 return hr;
875 static void textfont_cache_range_props(ITextFontImpl *font)
877 enum textfont_prop_id propid;
878 for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++) {
879 if (propid == FONT_NAME)
880 textfont_getname_from_range(font->range, &font->props[propid].str);
881 else
882 get_textfont_prop(font, propid, &font->props[propid]);
886 static HRESULT textrange_expand(ITextRange *range, LONG unit, LONG *delta)
888 LONG expand_start, expand_end;
890 switch (unit)
892 case tomStory:
893 expand_start = 0;
894 ITextRange_GetStoryLength(range, &expand_end);
895 break;
896 default:
897 FIXME("unit %ld is not supported\n", unit);
898 return E_NOTIMPL;
901 if (delta) {
902 LONG start, end;
904 ITextRange_GetStart(range, &start);
905 ITextRange_GetEnd(range, &end);
906 *delta = expand_end - expand_start - (end - start);
909 ITextRange_SetStart(range, expand_start);
910 ITextRange_SetEnd(range, expand_end);
912 return S_OK;
915 static HRESULT WINAPI
916 IRichEditOle_fnQueryInterface(IRichEditOle *iface, REFIID riid, LPVOID *ppvObj)
918 struct text_services *services = impl_from_IRichEditOle( iface );
919 return IUnknown_QueryInterface( services->outer_unk, riid, ppvObj );
922 static ULONG WINAPI
923 IRichEditOle_fnAddRef(IRichEditOle *iface)
925 struct text_services *services = impl_from_IRichEditOle( iface );
926 return IUnknown_AddRef( services->outer_unk );
929 static ULONG WINAPI
930 IRichEditOle_fnRelease(IRichEditOle *iface)
932 struct text_services *services = impl_from_IRichEditOle( iface );
933 return IUnknown_Release( services->outer_unk );
936 static HRESULT WINAPI
937 IRichEditOle_fnActivateAs(IRichEditOle *iface, REFCLSID rclsid, REFCLSID rclsidAs)
939 struct text_services *services = impl_from_IRichEditOle( iface );
940 FIXME( "stub %p\n", services );
941 return E_NOTIMPL;
944 static HRESULT WINAPI
945 IRichEditOle_fnContextSensitiveHelp(IRichEditOle *iface, BOOL fEnterMode)
947 struct text_services *services = impl_from_IRichEditOle( iface );
948 FIXME( "stub %p\n", services );
949 return E_NOTIMPL;
952 static HRESULT WINAPI
953 IRichEditOle_fnConvertObject( IRichEditOle *iface, LONG iob, REFCLSID class, LPCSTR user_type )
955 struct text_services *services = impl_from_IRichEditOle( iface );
956 FIXME( "stub %p\n", services );
957 return E_NOTIMPL;
960 static inline IOleClientSiteImpl *impl_from_IOleClientSite(IOleClientSite *iface)
962 return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleClientSite_iface);
965 static HRESULT WINAPI
966 IOleClientSite_fnQueryInterface(IOleClientSite *me, REFIID riid, LPVOID *ppvObj)
968 IOleClientSiteImpl *This = impl_from_IOleClientSite(me);
969 TRACE("%p %s\n", me, debugstr_guid(riid) );
971 *ppvObj = NULL;
972 if (IsEqualGUID(riid, &IID_IUnknown) ||
973 IsEqualGUID(riid, &IID_IOleClientSite))
974 *ppvObj = me;
975 else if (IsEqualGUID(riid, &IID_IOleWindow) ||
976 IsEqualGUID(riid, &IID_IOleInPlaceSite))
977 *ppvObj = &This->IOleInPlaceSite_iface;
978 if (*ppvObj)
980 IOleClientSite_AddRef(me);
981 return S_OK;
983 FIXME("%p: unhandled interface %s\n", me, debugstr_guid(riid) );
985 return E_NOINTERFACE;
988 static ULONG WINAPI IOleClientSite_fnAddRef(IOleClientSite *iface)
990 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
991 ULONG ref = InterlockedIncrement(&This->ref);
992 TRACE("(%p)->(%lu)\n", This, ref);
993 return ref;
996 static ULONG WINAPI IOleClientSite_fnRelease(IOleClientSite *iface)
998 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
999 ULONG ref = InterlockedDecrement(&This->ref);
1001 TRACE("(%p)->(%lu)\n", This, ref);
1003 if (ref == 0) {
1004 if (This->child.reole) {
1005 list_remove(&This->child.entry);
1006 This->child.reole = NULL;
1008 free(This);
1010 return ref;
1013 static HRESULT WINAPI IOleClientSite_fnSaveObject(IOleClientSite *iface)
1015 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1016 if (!This->child.reole)
1017 return CO_E_RELEASED;
1019 FIXME("stub %p\n", iface);
1020 return E_NOTIMPL;
1023 static HRESULT WINAPI IOleClientSite_fnGetMoniker(IOleClientSite *iface, DWORD dwAssign,
1024 DWORD dwWhichMoniker, IMoniker **ppmk)
1026 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1027 if (!This->child.reole)
1028 return CO_E_RELEASED;
1030 FIXME("stub %p\n", iface);
1031 return E_NOTIMPL;
1034 static HRESULT WINAPI IOleClientSite_fnGetContainer(IOleClientSite *iface,
1035 IOleContainer **ppContainer)
1037 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1038 if (!This->child.reole)
1039 return CO_E_RELEASED;
1041 FIXME("stub %p\n", iface);
1042 return E_NOTIMPL;
1045 static HRESULT WINAPI IOleClientSite_fnShowObject(IOleClientSite *iface)
1047 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1048 if (!This->child.reole)
1049 return CO_E_RELEASED;
1051 FIXME("stub %p\n", iface);
1052 return E_NOTIMPL;
1055 static HRESULT WINAPI IOleClientSite_fnOnShowWindow(IOleClientSite *iface, BOOL fShow)
1057 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1058 if (!This->child.reole)
1059 return CO_E_RELEASED;
1061 FIXME("stub %p\n", iface);
1062 return E_NOTIMPL;
1065 static HRESULT WINAPI IOleClientSite_fnRequestNewObjectLayout(IOleClientSite *iface)
1067 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1068 if (!This->child.reole)
1069 return CO_E_RELEASED;
1071 FIXME("stub %p\n", iface);
1072 return E_NOTIMPL;
1075 static const IOleClientSiteVtbl ocst = {
1076 IOleClientSite_fnQueryInterface,
1077 IOleClientSite_fnAddRef,
1078 IOleClientSite_fnRelease,
1079 IOleClientSite_fnSaveObject,
1080 IOleClientSite_fnGetMoniker,
1081 IOleClientSite_fnGetContainer,
1082 IOleClientSite_fnShowObject,
1083 IOleClientSite_fnOnShowWindow,
1084 IOleClientSite_fnRequestNewObjectLayout
1087 /* IOleInPlaceSite interface */
1088 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnQueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppvObj)
1090 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1091 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppvObj);
1094 static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnAddRef(IOleInPlaceSite *iface)
1096 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1097 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1100 static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnRelease(IOleInPlaceSite *iface)
1102 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1103 return IOleClientSite_Release(&This->IOleClientSite_iface);
1106 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindow( IOleInPlaceSite *iface, HWND *window )
1108 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1110 TRACE( "(%p)->(%p)\n", This, window );
1112 if (!This->child.reole)
1113 return CO_E_RELEASED;
1115 if (!window) return E_INVALIDARG;
1117 if (!This->child.reole->editor->have_texthost2) return E_NOTIMPL;
1118 return ITextHost2_TxGetWindow( This->child.reole->editor->texthost, window );
1121 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode)
1123 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1124 FIXME("not implemented: (%p)->(%d)\n", This, fEnterMode);
1125 return E_NOTIMPL;
1128 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnCanInPlaceActivate(IOleInPlaceSite *iface)
1130 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1131 FIXME("not implemented: (%p)\n", This);
1132 return E_NOTIMPL;
1135 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceActivate(IOleInPlaceSite *iface)
1137 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1138 FIXME("not implemented: (%p)\n", This);
1139 return E_NOTIMPL;
1142 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIActivate(IOleInPlaceSite *iface)
1144 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1145 FIXME("not implemented: (%p)\n", This);
1146 return E_NOTIMPL;
1149 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindowContext(IOleInPlaceSite *iface, IOleInPlaceFrame **ppFrame,
1150 IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
1151 LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
1153 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1154 FIXME("not implemented: (%p)->(%p %p %p %p %p)\n", This, ppFrame, ppDoc, lprcPosRect, lprcClipRect, lpFrameInfo);
1155 return E_NOTIMPL;
1158 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnScroll(IOleInPlaceSite *iface, SIZE scrollExtent)
1160 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1161 FIXME("not implemented: (%p)\n", This);
1162 return E_NOTIMPL;
1165 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable)
1167 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1168 FIXME("not implemented: (%p)->(%d)\n", This, fUndoable);
1169 return E_NOTIMPL;
1172 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceDeactivate(IOleInPlaceSite *iface)
1174 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1175 FIXME("not implemented: (%p)\n", This);
1176 return E_NOTIMPL;
1179 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDiscardUndoState(IOleInPlaceSite *iface)
1181 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1182 FIXME("not implemented: (%p)\n", This);
1183 return E_NOTIMPL;
1186 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDeactivateAndUndo(IOleInPlaceSite *iface)
1188 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1189 FIXME("not implemented: (%p)\n", This);
1190 return E_NOTIMPL;
1193 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect)
1195 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1196 FIXME("not implemented: (%p)->(%p)\n", This, lprcPosRect);
1197 return E_NOTIMPL;
1200 static const IOleInPlaceSiteVtbl olestvt =
1202 IOleInPlaceSite_fnQueryInterface,
1203 IOleInPlaceSite_fnAddRef,
1204 IOleInPlaceSite_fnRelease,
1205 IOleInPlaceSite_fnGetWindow,
1206 IOleInPlaceSite_fnContextSensitiveHelp,
1207 IOleInPlaceSite_fnCanInPlaceActivate,
1208 IOleInPlaceSite_fnOnInPlaceActivate,
1209 IOleInPlaceSite_fnOnUIActivate,
1210 IOleInPlaceSite_fnGetWindowContext,
1211 IOleInPlaceSite_fnScroll,
1212 IOleInPlaceSite_fnOnUIDeactivate,
1213 IOleInPlaceSite_fnOnInPlaceDeactivate,
1214 IOleInPlaceSite_fnDiscardUndoState,
1215 IOleInPlaceSite_fnDeactivateAndUndo,
1216 IOleInPlaceSite_fnOnPosRectChange
1219 static HRESULT CreateOleClientSite( struct text_services *services, IOleClientSite **ret )
1221 IOleClientSiteImpl *clientSite = malloc(sizeof *clientSite);
1223 if (!clientSite)
1224 return E_OUTOFMEMORY;
1226 clientSite->IOleClientSite_iface.lpVtbl = &ocst;
1227 clientSite->IOleInPlaceSite_iface.lpVtbl = &olestvt;
1228 clientSite->ref = 1;
1229 clientSite->child.reole = services;
1230 list_add_head( &services->clientsites, &clientSite->child.entry );
1232 *ret = &clientSite->IOleClientSite_iface;
1233 return S_OK;
1236 static HRESULT WINAPI
1237 IRichEditOle_fnGetClientSite( IRichEditOle *iface, IOleClientSite **clientsite )
1239 struct text_services *services = impl_from_IRichEditOle( iface );
1241 TRACE("(%p)->(%p)\n", services, clientsite);
1243 if (!clientsite)
1244 return E_INVALIDARG;
1246 return CreateOleClientSite( services, clientsite );
1249 static HRESULT WINAPI
1250 IRichEditOle_fnGetClipboardData(IRichEditOle *iface, CHARRANGE *lpchrg,
1251 DWORD reco, LPDATAOBJECT *lplpdataobj)
1253 struct text_services *services = impl_from_IRichEditOle( iface );
1254 ME_Cursor start;
1255 int nChars;
1257 TRACE("(%p,%p,%ld)\n", services, lpchrg, reco);
1258 if(!lplpdataobj)
1259 return E_INVALIDARG;
1260 if(!lpchrg)
1262 LONG nFrom, nTo;
1263 int nStartCur = ME_GetSelectionOfs( services->editor, &nFrom, &nTo );
1264 start = services->editor->pCursors[nStartCur];
1265 nChars = nTo - nFrom;
1267 else
1269 cursor_from_char_ofs( services->editor, lpchrg->cpMin, &start );
1270 nChars = lpchrg->cpMax - lpchrg->cpMin;
1272 return ME_GetDataObject( services->editor, &start, nChars, lplpdataobj );
1275 static LONG WINAPI IRichEditOle_fnGetLinkCount(IRichEditOle *iface)
1277 struct text_services *services = impl_from_IRichEditOle( iface );
1278 FIXME("stub %p\n", services);
1279 return E_NOTIMPL;
1282 static HRESULT WINAPI
1283 IRichEditOle_fnGetObject(IRichEditOle *iface, LONG iob,
1284 REOBJECT *lpreobject, DWORD dwFlags)
1286 struct text_services *services = impl_from_IRichEditOle( iface );
1287 struct re_object *reobj = NULL;
1288 LONG count = 0;
1290 TRACE("(%p)->(%lx, %p, %lx)\n", services, iob, lpreobject, dwFlags);
1292 if (!lpreobject || !lpreobject->cbStruct)
1293 return E_INVALIDARG;
1295 if (iob == REO_IOB_USE_CP)
1297 ME_Cursor cursor;
1299 TRACE("character offset: %ld\n", lpreobject->cp);
1300 cursor_from_char_ofs( services->editor, lpreobject->cp, &cursor );
1301 if (!cursor.run->reobj)
1302 return E_INVALIDARG;
1303 else
1304 reobj = cursor.run->reobj;
1306 else if (iob == REO_IOB_SELECTION)
1308 ME_Cursor *from, *to;
1310 ME_GetSelection(services->editor, &from, &to);
1311 if (!from->run->reobj)
1312 return E_INVALIDARG;
1313 else
1314 reobj = from->run->reobj;
1316 else
1318 if (iob < 0 || iob >= IRichEditOle_GetObjectCount( iface ))
1319 return E_INVALIDARG;
1320 LIST_FOR_EACH_ENTRY(reobj, &services->editor->reobj_list, struct re_object, entry)
1322 if (count == iob)
1323 break;
1324 count++;
1327 ME_CopyReObject(lpreobject, &reobj->obj, dwFlags);
1328 lpreobject->cp = run_char_ofs( reobj->run, 0 );
1329 return S_OK;
1332 static LONG WINAPI
1333 IRichEditOle_fnGetObjectCount( IRichEditOle *iface )
1335 struct text_services *services = impl_from_IRichEditOle( iface );
1336 TRACE("(%p)\n", services);
1337 return list_count( &services->editor->reobj_list );
1340 static HRESULT WINAPI
1341 IRichEditOle_fnHandsOffStorage(IRichEditOle *iface, LONG iob)
1343 struct text_services *services = impl_from_IRichEditOle( iface );
1344 FIXME("stub %p\n", services);
1345 return E_NOTIMPL;
1348 static HRESULT WINAPI
1349 IRichEditOle_fnImportDataObject(IRichEditOle *iface, LPDATAOBJECT lpdataobj,
1350 CLIPFORMAT cf, HGLOBAL hMetaPict)
1352 struct text_services *services = impl_from_IRichEditOle( iface );
1353 FIXME("stub %p\n", services);
1354 return E_NOTIMPL;
1357 static HRESULT WINAPI
1358 IRichEditOle_fnInPlaceDeactivate(IRichEditOle *iface)
1360 struct text_services *services = impl_from_IRichEditOle( iface );
1361 FIXME("stub %p\n", services);
1362 return E_NOTIMPL;
1365 static HRESULT WINAPI
1366 IRichEditOle_fnInsertObject(IRichEditOle *iface, REOBJECT *reo)
1368 struct text_services *services = impl_from_IRichEditOle( iface );
1369 HRESULT hr;
1371 TRACE("(%p,%p)\n", services, reo);
1373 if (!reo)
1374 return E_INVALIDARG;
1376 if (reo->cbStruct < sizeof(*reo)) return STG_E_INVALIDPARAMETER;
1378 hr = editor_insert_oleobj(services->editor, reo);
1379 if (hr != S_OK)
1380 return hr;
1382 ME_CommitUndo(services->editor);
1383 ME_UpdateRepaint(services->editor, FALSE);
1384 return S_OK;
1387 static HRESULT WINAPI IRichEditOle_fnSaveCompleted(IRichEditOle *iface, LONG iob,
1388 LPSTORAGE lpstg)
1390 struct text_services *services = impl_from_IRichEditOle( iface );
1391 FIXME("stub %p\n", services);
1392 return E_NOTIMPL;
1395 static HRESULT WINAPI
1396 IRichEditOle_fnSetDvaspect(IRichEditOle *iface, LONG iob, DWORD dvaspect)
1398 struct text_services *services = impl_from_IRichEditOle( iface );
1399 FIXME("stub %p\n", services);
1400 return E_NOTIMPL;
1403 static HRESULT WINAPI IRichEditOle_fnSetHostNames(IRichEditOle *iface,
1404 LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj)
1406 struct text_services *services = impl_from_IRichEditOle( iface );
1407 FIXME("stub %p %s %s\n", services, lpstrContainerApp, lpstrContainerObj);
1408 return E_NOTIMPL;
1411 static HRESULT WINAPI
1412 IRichEditOle_fnSetLinkAvailable(IRichEditOle *iface, LONG iob, BOOL fAvailable)
1414 struct text_services *services = impl_from_IRichEditOle( iface );
1415 FIXME("stub %p\n", services);
1416 return E_NOTIMPL;
1419 const IRichEditOleVtbl re_ole_vtbl =
1421 IRichEditOle_fnQueryInterface,
1422 IRichEditOle_fnAddRef,
1423 IRichEditOle_fnRelease,
1424 IRichEditOle_fnGetClientSite,
1425 IRichEditOle_fnGetObjectCount,
1426 IRichEditOle_fnGetLinkCount,
1427 IRichEditOle_fnGetObject,
1428 IRichEditOle_fnInsertObject,
1429 IRichEditOle_fnConvertObject,
1430 IRichEditOle_fnActivateAs,
1431 IRichEditOle_fnSetHostNames,
1432 IRichEditOle_fnSetLinkAvailable,
1433 IRichEditOle_fnSetDvaspect,
1434 IRichEditOle_fnHandsOffStorage,
1435 IRichEditOle_fnSaveCompleted,
1436 IRichEditOle_fnInPlaceDeactivate,
1437 IRichEditOle_fnContextSensitiveHelp,
1438 IRichEditOle_fnGetClipboardData,
1439 IRichEditOle_fnImportDataObject
1442 /* ITextRange interface */
1443 static HRESULT WINAPI ITextRange_fnQueryInterface(ITextRange *me, REFIID riid, void **ppvObj)
1445 ITextRangeImpl *This = impl_from_ITextRange(me);
1447 *ppvObj = NULL;
1448 if (IsEqualGUID(riid, &IID_IUnknown)
1449 || IsEqualGUID(riid, &IID_IDispatch)
1450 || IsEqualGUID(riid, &IID_ITextRange))
1452 *ppvObj = me;
1453 ITextRange_AddRef(me);
1454 return S_OK;
1456 else if (IsEqualGUID(riid, &IID_Igetrichole))
1458 *ppvObj = This->child.reole;
1459 return S_OK;
1462 return E_NOINTERFACE;
1465 static ULONG WINAPI ITextRange_fnAddRef(ITextRange *me)
1467 ITextRangeImpl *This = impl_from_ITextRange(me);
1468 return InterlockedIncrement(&This->ref);
1471 static ULONG WINAPI ITextRange_fnRelease(ITextRange *me)
1473 ITextRangeImpl *This = impl_from_ITextRange(me);
1474 ULONG ref = InterlockedDecrement(&This->ref);
1476 TRACE ("%p ref=%lu\n", This, ref);
1477 if (ref == 0)
1479 if (This->child.reole)
1481 list_remove(&This->child.entry);
1482 This->child.reole = NULL;
1484 free(This);
1486 return ref;
1489 static HRESULT WINAPI ITextRange_fnGetTypeInfoCount(ITextRange *me, UINT *pctinfo)
1491 ITextRangeImpl *This = impl_from_ITextRange(me);
1492 TRACE("(%p)->(%p)\n", This, pctinfo);
1493 *pctinfo = 1;
1494 return S_OK;
1497 static HRESULT WINAPI ITextRange_fnGetTypeInfo(ITextRange *me, UINT iTInfo, LCID lcid,
1498 ITypeInfo **ppTInfo)
1500 ITextRangeImpl *This = impl_from_ITextRange(me);
1501 HRESULT hr;
1503 TRACE("(%p)->(%u,%ld,%p)\n", This, iTInfo, lcid, ppTInfo);
1505 hr = get_typeinfo(ITextRange_tid, ppTInfo);
1506 if (SUCCEEDED(hr))
1507 ITypeInfo_AddRef(*ppTInfo);
1508 return hr;
1511 static HRESULT WINAPI ITextRange_fnGetIDsOfNames(ITextRange *me, REFIID riid, LPOLESTR *rgszNames,
1512 UINT cNames, LCID lcid, DISPID *rgDispId)
1514 ITextRangeImpl *This = impl_from_ITextRange(me);
1515 ITypeInfo *ti;
1516 HRESULT hr;
1518 TRACE("(%p)->(%s, %p, %u, %ld, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
1519 rgDispId);
1521 hr = get_typeinfo(ITextRange_tid, &ti);
1522 if (SUCCEEDED(hr))
1523 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
1524 return hr;
1527 static HRESULT WINAPI ITextRange_fnInvoke(ITextRange *me, DISPID dispIdMember, REFIID riid,
1528 LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1529 VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
1530 UINT *puArgErr)
1532 ITextRangeImpl *This = impl_from_ITextRange(me);
1533 ITypeInfo *ti;
1534 HRESULT hr;
1536 TRACE("(%p)->(%ld, %s, %ld, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
1537 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1539 hr = get_typeinfo(ITextRange_tid, &ti);
1540 if (SUCCEEDED(hr))
1541 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1542 return hr;
1545 static HRESULT WINAPI ITextRange_fnGetText(ITextRange *me, BSTR *str)
1547 ITextRangeImpl *This = impl_from_ITextRange(me);
1548 ME_TextEditor *editor;
1549 ME_Cursor start, end;
1550 int length;
1551 BOOL bEOP;
1553 TRACE("(%p)->(%p)\n", This, str);
1555 if (!This->child.reole)
1556 return CO_E_RELEASED;
1558 if (!str)
1559 return E_INVALIDARG;
1561 /* return early for degenerate range */
1562 if (This->start == This->end) {
1563 *str = NULL;
1564 return S_OK;
1567 editor = This->child.reole->editor;
1568 cursor_from_char_ofs( editor, This->start, &start );
1569 cursor_from_char_ofs( editor, This->end, &end );
1571 length = This->end - This->start;
1572 *str = SysAllocStringLen(NULL, length);
1573 if (!*str)
1574 return E_OUTOFMEMORY;
1576 bEOP = (!para_next( para_next( end.para )) && This->end > ME_GetTextLength(editor));
1577 ME_GetTextW(editor, *str, length, &start, length, FALSE, bEOP);
1578 return S_OK;
1581 static HRESULT WINAPI ITextRange_fnSetText(ITextRange *me, BSTR str)
1583 ITextRangeImpl *This = impl_from_ITextRange(me);
1584 ME_TextEditor *editor;
1585 ME_Cursor cursor;
1586 ME_Style *style;
1587 int len;
1589 TRACE("(%p)->(%s)\n", This, debugstr_w(str));
1591 if (!This->child.reole)
1592 return CO_E_RELEASED;
1594 editor = This->child.reole->editor;
1596 /* delete only where's something to delete */
1597 if (This->start != This->end)
1599 cursor_from_char_ofs( editor, This->start, &cursor );
1600 ME_InternalDeleteText(editor, &cursor, This->end - This->start, FALSE);
1603 if (!str || !*str)
1605 /* will update this range as well */
1606 textranges_update_ranges(This->child.reole, This->start, This->end, RANGE_UPDATE_DELETE);
1607 return S_OK;
1610 /* it's safer not to rely on stored BSTR length */
1611 len = lstrlenW(str);
1612 cursor = editor->pCursors[0];
1613 cursor_from_char_ofs( editor, This->start, &editor->pCursors[0] );
1614 style = style_get_insert_style( editor, editor->pCursors );
1615 ME_InsertTextFromCursor(editor, 0, str, len, style);
1616 ME_ReleaseStyle(style);
1617 editor->pCursors[0] = cursor;
1619 if (len < This->end - This->start)
1620 textranges_update_ranges(This->child.reole, This->start + len, This->end, RANGE_UPDATE_DELETE);
1621 else
1622 This->end = len - This->start;
1624 return S_OK;
1627 static HRESULT range_GetChar(ME_TextEditor *editor, ME_Cursor *cursor, LONG *pch)
1629 WCHAR wch[2];
1631 ME_GetTextW(editor, wch, 1, cursor, 1, FALSE, !para_next( para_next( cursor->para ) ));
1632 *pch = wch[0];
1634 return S_OK;
1637 static HRESULT WINAPI ITextRange_fnGetChar(ITextRange *me, LONG *pch)
1639 ITextRangeImpl *This = impl_from_ITextRange(me);
1640 ME_TextEditor *editor;
1641 ME_Cursor cursor;
1643 TRACE("(%p)->(%p)\n", This, pch);
1645 if (!This->child.reole)
1646 return CO_E_RELEASED;
1648 if (!pch)
1649 return E_INVALIDARG;
1651 editor = This->child.reole->editor;
1652 cursor_from_char_ofs( editor, This->start, &cursor );
1653 return range_GetChar(editor, &cursor, pch);
1656 static HRESULT WINAPI ITextRange_fnSetChar(ITextRange *me, LONG ch)
1658 ITextRangeImpl *This = impl_from_ITextRange(me);
1660 FIXME("(%p)->(%lx): stub\n", This, ch);
1662 if (!This->child.reole)
1663 return CO_E_RELEASED;
1665 return E_NOTIMPL;
1668 static HRESULT CreateITextRange(struct text_services *services, LONG start, LONG end, ITextRange** ppRange);
1670 static HRESULT WINAPI ITextRange_fnGetDuplicate(ITextRange *me, ITextRange **ppRange)
1672 ITextRangeImpl *This = impl_from_ITextRange(me);
1674 TRACE("(%p)->(%p)\n", This, ppRange);
1676 if (!This->child.reole)
1677 return CO_E_RELEASED;
1679 if (!ppRange)
1680 return E_INVALIDARG;
1682 return CreateITextRange(This->child.reole, This->start, This->end, ppRange);
1685 static HRESULT WINAPI ITextRange_fnGetFormattedText(ITextRange *me, ITextRange **range)
1687 ITextRangeImpl *This = impl_from_ITextRange(me);
1689 FIXME("(%p)->(%p): stub\n", This, range);
1691 if (!This->child.reole)
1692 return CO_E_RELEASED;
1694 return E_NOTIMPL;
1697 static HRESULT WINAPI ITextRange_fnSetFormattedText(ITextRange *me, ITextRange *range)
1699 ITextRangeImpl *This = impl_from_ITextRange(me);
1701 FIXME("(%p)->(%p): stub\n", This, range);
1703 if (!This->child.reole)
1704 return CO_E_RELEASED;
1706 return E_NOTIMPL;
1709 static HRESULT WINAPI ITextRange_fnGetStart(ITextRange *me, LONG *start)
1711 ITextRangeImpl *This = impl_from_ITextRange(me);
1713 TRACE("(%p)->(%p)\n", This, start);
1715 if (!This->child.reole)
1716 return CO_E_RELEASED;
1718 if (!start)
1719 return E_INVALIDARG;
1721 *start = This->start;
1722 return S_OK;
1725 static HRESULT textrange_setstart(const struct text_services *services, LONG value, LONG *start, LONG *end)
1727 int len;
1729 if (value < 0)
1730 value = 0;
1732 if (value == *start)
1733 return S_FALSE;
1735 if (value <= *end) {
1736 *start = value;
1737 return S_OK;
1740 len = ME_GetTextLength(services->editor);
1741 *start = *end = value > len ? len : value;
1742 return S_OK;
1745 static HRESULT WINAPI ITextRange_fnSetStart(ITextRange *me, LONG value)
1747 ITextRangeImpl *This = impl_from_ITextRange(me);
1749 TRACE("(%p)->(%ld)\n", This, value);
1751 if (!This->child.reole)
1752 return CO_E_RELEASED;
1754 return textrange_setstart(This->child.reole, value, &This->start, &This->end);
1757 static HRESULT WINAPI ITextRange_fnGetEnd(ITextRange *me, LONG *end)
1759 ITextRangeImpl *This = impl_from_ITextRange(me);
1761 TRACE("(%p)->(%p)\n", This, end);
1763 if (!This->child.reole)
1764 return CO_E_RELEASED;
1766 if (!end)
1767 return E_INVALIDARG;
1769 *end = This->end;
1770 return S_OK;
1773 static HRESULT textrange_setend(const struct text_services *services, LONG value, LONG *start, LONG *end)
1775 int len;
1777 if (value == *end)
1778 return S_FALSE;
1780 if (value < *start) {
1781 *start = *end = max(0, value);
1782 return S_OK;
1785 len = ME_GetTextLength( services->editor );
1786 *end = value > len ? len + 1 : value;
1787 return S_OK;
1790 static HRESULT WINAPI ITextRange_fnSetEnd(ITextRange *me, LONG value)
1792 ITextRangeImpl *This = impl_from_ITextRange(me);
1794 TRACE("(%p)->(%ld)\n", This, value);
1796 if (!This->child.reole)
1797 return CO_E_RELEASED;
1799 return textrange_setend(This->child.reole, value, &This->start, &This->end);
1802 static HRESULT WINAPI ITextRange_fnGetFont(ITextRange *me, ITextFont **font)
1804 ITextRangeImpl *This = impl_from_ITextRange(me);
1806 TRACE("(%p)->(%p)\n", This, font);
1808 if (!This->child.reole)
1809 return CO_E_RELEASED;
1811 if (!font)
1812 return E_INVALIDARG;
1814 return create_textfont(me, NULL, font);
1817 static HRESULT WINAPI ITextRange_fnSetFont(ITextRange *me, ITextFont *font)
1819 ITextRangeImpl *This = impl_from_ITextRange(me);
1821 TRACE("(%p)->(%p)\n", This, font);
1823 if (!font)
1824 return E_INVALIDARG;
1826 if (!This->child.reole)
1827 return CO_E_RELEASED;
1829 textrange_set_font(me, font);
1830 return S_OK;
1833 static HRESULT WINAPI ITextRange_fnGetPara(ITextRange *me, ITextPara **para)
1835 ITextRangeImpl *This = impl_from_ITextRange(me);
1837 TRACE("(%p)->(%p)\n", This, para);
1839 if (!This->child.reole)
1840 return CO_E_RELEASED;
1842 if (!para)
1843 return E_INVALIDARG;
1845 return create_textpara(me, para);
1848 static HRESULT WINAPI ITextRange_fnSetPara(ITextRange *me, ITextPara *para)
1850 ITextRangeImpl *This = impl_from_ITextRange(me);
1852 FIXME("(%p)->(%p): stub\n", This, para);
1854 if (!This->child.reole)
1855 return CO_E_RELEASED;
1857 return E_NOTIMPL;
1860 static HRESULT WINAPI ITextRange_fnGetStoryLength(ITextRange *me, LONG *length)
1862 ITextRangeImpl *This = impl_from_ITextRange(me);
1864 TRACE("(%p)->(%p)\n", This, length);
1866 if (!This->child.reole)
1867 return CO_E_RELEASED;
1869 return textrange_get_storylength(This->child.reole->editor, length);
1872 static HRESULT WINAPI ITextRange_fnGetStoryType(ITextRange *me, LONG *value)
1874 ITextRangeImpl *This = impl_from_ITextRange(me);
1876 TRACE("(%p)->(%p)\n", This, value);
1878 if (!This->child.reole)
1879 return CO_E_RELEASED;
1881 if (!value)
1882 return E_INVALIDARG;
1884 *value = tomUnknownStory;
1885 return S_OK;
1888 static HRESULT range_Collapse(LONG bStart, LONG *start, LONG *end)
1890 if (*end == *start)
1891 return S_FALSE;
1893 if (bStart == tomEnd)
1894 *start = *end;
1895 else
1896 *end = *start;
1897 return S_OK;
1900 static HRESULT WINAPI ITextRange_fnCollapse(ITextRange *me, LONG bStart)
1902 ITextRangeImpl *This = impl_from_ITextRange(me);
1904 TRACE("(%p)->(%ld)\n", This, bStart);
1906 if (!This->child.reole)
1907 return CO_E_RELEASED;
1909 return range_Collapse(bStart, &This->start, &This->end);
1912 static HRESULT WINAPI ITextRange_fnExpand(ITextRange *me, LONG unit, LONG *delta)
1914 ITextRangeImpl *This = impl_from_ITextRange(me);
1916 TRACE("(%p)->(%ld %p)\n", This, unit, delta);
1918 if (!This->child.reole)
1919 return CO_E_RELEASED;
1921 return textrange_expand(me, unit, delta);
1924 static HRESULT WINAPI ITextRange_fnGetIndex(ITextRange *me, LONG unit, LONG *index)
1926 ITextRangeImpl *This = impl_from_ITextRange(me);
1928 FIXME("(%p)->(%ld %p): stub\n", This, unit, index);
1930 if (!This->child.reole)
1931 return CO_E_RELEASED;
1933 return E_NOTIMPL;
1936 static HRESULT WINAPI ITextRange_fnSetIndex(ITextRange *me, LONG unit, LONG index,
1937 LONG extend)
1939 ITextRangeImpl *This = impl_from_ITextRange(me);
1941 FIXME("(%p)->(%ld %ld %ld): stub\n", This, unit, index, extend);
1943 if (!This->child.reole)
1944 return CO_E_RELEASED;
1946 return E_NOTIMPL;
1949 static void cp2range(ME_TextEditor *editor, LONG *cp1, LONG *cp2)
1951 int len = ME_GetTextLength(editor) + 1;
1953 *cp1 = max(*cp1, 0);
1954 *cp2 = max(*cp2, 0);
1955 *cp1 = min(*cp1, len);
1956 *cp2 = min(*cp2, len);
1957 if (*cp1 > *cp2)
1959 int tmp = *cp1;
1960 *cp1 = *cp2;
1961 *cp2 = tmp;
1963 if (*cp1 == len)
1964 *cp1 = *cp2 = len - 1;
1967 static HRESULT WINAPI ITextRange_fnSetRange(ITextRange *me, LONG anchor, LONG active)
1969 ITextRangeImpl *This = impl_from_ITextRange(me);
1971 TRACE("(%p)->(%ld %ld)\n", This, anchor, active);
1973 if (!This->child.reole)
1974 return CO_E_RELEASED;
1976 cp2range(This->child.reole->editor, &anchor, &active);
1977 if (anchor == This->start && active == This->end)
1978 return S_FALSE;
1980 This->start = anchor;
1981 This->end = active;
1982 return S_OK;
1985 static HRESULT textrange_inrange(LONG start, LONG end, ITextRange *range, LONG *ret)
1987 LONG from, to, v;
1989 if (!ret)
1990 ret = &v;
1992 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
1993 *ret = tomFalse;
1995 else
1996 *ret = (start >= from && end <= to) ? tomTrue : tomFalse;
1997 return *ret == tomTrue ? S_OK : S_FALSE;
2000 static HRESULT WINAPI ITextRange_fnInRange(ITextRange *me, ITextRange *range, LONG *ret)
2002 ITextRangeImpl *This = impl_from_ITextRange(me);
2004 TRACE("(%p)->(%p %p)\n", This, range, ret);
2006 if (ret)
2007 *ret = tomFalse;
2009 if (!This->child.reole)
2010 return CO_E_RELEASED;
2012 if (!range)
2013 return S_FALSE;
2015 return textrange_inrange(This->start, This->end, range, ret);
2018 static HRESULT WINAPI ITextRange_fnInStory(ITextRange *me, ITextRange *pRange, LONG *ret)
2020 ITextRangeImpl *This = impl_from_ITextRange(me);
2022 FIXME("(%p)->(%p): stub\n", This, ret);
2024 if (!This->child.reole)
2025 return CO_E_RELEASED;
2027 return E_NOTIMPL;
2030 static HRESULT textrange_isequal(LONG start, LONG end, ITextRange *range, LONG *ret)
2032 LONG from, to, v;
2034 if (!ret)
2035 ret = &v;
2037 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
2038 *ret = tomFalse;
2040 else
2041 *ret = (start == from && end == to) ? tomTrue : tomFalse;
2042 return *ret == tomTrue ? S_OK : S_FALSE;
2045 static HRESULT WINAPI ITextRange_fnIsEqual(ITextRange *me, ITextRange *range, LONG *ret)
2047 ITextRangeImpl *This = impl_from_ITextRange(me);
2049 TRACE("(%p)->(%p %p)\n", This, range, ret);
2051 if (ret)
2052 *ret = tomFalse;
2054 if (!This->child.reole)
2055 return CO_E_RELEASED;
2057 if (!range)
2058 return S_FALSE;
2060 return textrange_isequal(This->start, This->end, range, ret);
2063 static HRESULT WINAPI ITextRange_fnSelect(ITextRange *me)
2065 ITextRangeImpl *This = impl_from_ITextRange(me);
2067 TRACE("(%p)\n", This);
2069 if (!This->child.reole)
2070 return CO_E_RELEASED;
2072 set_selection(This->child.reole->editor, This->start, This->end);
2073 return S_OK;
2076 static HRESULT textrange_startof(ITextRange *range, LONG unit, LONG extend, LONG *delta)
2078 HRESULT hr;
2079 LONG start, end;
2080 LONG moved;
2082 ITextRange_GetStart(range, &start);
2083 ITextRange_GetEnd(range, &end);
2085 switch (unit)
2087 case tomCharacter:
2089 moved = 0;
2090 if (extend == tomMove) {
2091 if (start != end) {
2092 ITextRange_SetEnd(range, start);
2093 moved = -1;
2096 if (delta)
2097 *delta = moved;
2098 hr = moved ? S_OK : S_FALSE;
2099 break;
2101 default:
2102 FIXME("unit %ld is not supported\n", unit);
2103 return E_NOTIMPL;
2105 return hr;
2108 static HRESULT WINAPI ITextRange_fnStartOf(ITextRange *me, LONG unit, LONG extend,
2109 LONG *delta)
2111 ITextRangeImpl *This = impl_from_ITextRange(me);
2113 TRACE("(%p)->(%ld %ld %p)\n", This, unit, extend, delta);
2115 if (!This->child.reole)
2116 return CO_E_RELEASED;
2118 return textrange_startof(me, unit, extend, delta);
2121 static HRESULT textrange_endof(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG extend, LONG *delta)
2123 HRESULT hr;
2124 LONG old_start, old_end, new_end;
2125 LONG moved;
2127 ITextRange_GetStart(range, &old_start);
2128 ITextRange_GetEnd(range, &old_end);
2130 switch (unit)
2132 case tomCharacter:
2134 moved = 0;
2135 new_end = old_end;
2136 if (old_end == 0)
2138 ME_Cursor cursor;
2139 cursor_from_char_ofs( editor, old_end, &cursor );
2140 moved = ME_MoveCursorChars(editor, &cursor, 1, TRUE);
2141 new_end = old_end + moved;
2143 else if (extend == tomMove && old_start != old_end)
2144 moved = 1;
2146 ITextRange_SetEnd(range, new_end);
2147 if (extend == tomMove)
2148 ITextRange_SetStart(range, new_end);
2149 if (delta)
2150 *delta = moved;
2151 hr = moved ? S_OK : S_FALSE;
2152 break;
2154 default:
2155 FIXME("unit %ld is not supported\n", unit);
2156 return E_NOTIMPL;
2158 return hr;
2161 static HRESULT WINAPI ITextRange_fnEndOf(ITextRange *me, LONG unit, LONG extend,
2162 LONG *delta)
2164 ITextRangeImpl *This = impl_from_ITextRange(me);
2166 TRACE("(%p)->(%ld %ld %p)\n", This, unit, extend, delta);
2168 if (!This->child.reole)
2169 return CO_E_RELEASED;
2171 return textrange_endof(me, This->child.reole->editor, unit, extend, delta);
2174 static HRESULT textrange_move(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG count, LONG *delta)
2176 LONG old_start, old_end, new_start, new_end;
2177 LONG move_by;
2178 LONG moved;
2179 HRESULT hr = S_OK;
2181 if (!count)
2183 if (delta)
2184 *delta = 0;
2185 return S_FALSE;
2188 ITextRange_GetStart(range, &old_start);
2189 ITextRange_GetEnd(range, &old_end);
2190 switch (unit)
2192 case tomCharacter:
2194 ME_Cursor cursor;
2196 if (count > 0)
2198 cursor_from_char_ofs( editor, old_end, &cursor );
2199 move_by = count;
2200 if (old_start != old_end)
2201 --move_by;
2203 else
2205 cursor_from_char_ofs( editor, old_start, &cursor );
2206 move_by = count;
2207 if (old_start != old_end)
2208 ++move_by;
2210 moved = ME_MoveCursorChars(editor, &cursor, move_by, FALSE);
2211 if (count > 0)
2213 new_end = old_end + moved;
2214 new_start = new_end;
2215 if (old_start != old_end)
2216 ++moved;
2218 else
2220 new_start = old_start + moved;
2221 new_end = new_start;
2222 if (old_start != old_end)
2223 --moved;
2225 if (delta) *delta = moved;
2226 break;
2228 default:
2229 FIXME("unit %ld is not supported\n", unit);
2230 return E_NOTIMPL;
2232 if (moved == 0)
2233 hr = S_FALSE;
2234 ITextRange_SetStart(range, new_start);
2235 ITextRange_SetEnd(range, new_end);
2237 return hr;
2240 static HRESULT WINAPI ITextRange_fnMove(ITextRange *me, LONG unit, LONG count, LONG *delta)
2242 ITextRangeImpl *This = impl_from_ITextRange(me);
2244 TRACE("(%p)->(%ld %ld %p)\n", This, unit, count, delta);
2246 if (!This->child.reole)
2247 return CO_E_RELEASED;
2249 return textrange_move(me, This->child.reole->editor, unit, count, delta);
2252 static HRESULT textrange_movestart(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG count, LONG *delta)
2254 LONG old_start, old_end, new_start, new_end;
2255 HRESULT hr = S_OK;
2257 if (!count)
2259 if (delta)
2260 *delta = 0;
2261 return S_FALSE;
2264 ITextRange_GetStart(range, &old_start);
2265 ITextRange_GetEnd(range, &old_end);
2266 switch (unit)
2268 case tomCharacter:
2270 ME_Cursor cursor;
2271 LONG moved;
2273 cursor_from_char_ofs( editor, old_start, &cursor );
2274 moved = ME_MoveCursorChars(editor, &cursor, count, FALSE);
2275 new_start = old_start + moved;
2276 new_end = old_end;
2277 if (new_end < new_start)
2278 new_end = new_start;
2279 if (delta)
2280 *delta = moved;
2281 break;
2283 default:
2284 FIXME("unit %ld is not supported\n", unit);
2285 return E_NOTIMPL;
2287 if (new_start == old_start)
2288 hr = S_FALSE;
2289 ITextRange_SetStart(range, new_start);
2290 ITextRange_SetEnd(range, new_end);
2292 return hr;
2295 static HRESULT WINAPI ITextRange_fnMoveStart(ITextRange *me, LONG unit, LONG count,
2296 LONG *delta)
2298 ITextRangeImpl *This = impl_from_ITextRange(me);
2300 TRACE("(%p)->(%ld %ld %p)\n", This, unit, count, delta);
2302 if (!This->child.reole)
2303 return CO_E_RELEASED;
2305 return textrange_movestart(me, This->child.reole->editor, unit, count, delta);
2308 static HRESULT textrange_moveend(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG count, LONG *delta)
2310 LONG old_start, old_end, new_start, new_end;
2311 HRESULT hr = S_OK;
2313 if (!count)
2315 if (delta)
2316 *delta = 0;
2317 return S_FALSE;
2320 ITextRange_GetStart(range, &old_start);
2321 ITextRange_GetEnd(range, &old_end);
2322 switch (unit)
2324 case tomCharacter:
2326 ME_Cursor cursor;
2327 LONG moved;
2329 cursor_from_char_ofs( editor, old_end, &cursor );
2330 moved = ME_MoveCursorChars(editor, &cursor, count, TRUE);
2331 new_start = old_start;
2332 new_end = old_end + moved;
2333 if (new_end < new_start)
2334 new_start = new_end;
2335 if (delta)
2336 *delta = moved;
2337 break;
2339 case tomStory:
2340 if (count < 0)
2341 new_start = new_end = 0;
2342 else
2344 new_start = old_start;
2345 ITextRange_GetStoryLength(range, &new_end);
2347 if (delta)
2349 if (new_end < old_end)
2350 *delta = -1;
2351 else if (new_end == old_end)
2352 *delta = 0;
2353 else
2354 *delta = 1;
2356 break;
2357 default:
2358 FIXME("unit %ld is not supported\n", unit);
2359 return E_NOTIMPL;
2361 if (new_end == old_end)
2362 hr = S_FALSE;
2363 ITextRange_SetStart(range, new_start);
2364 ITextRange_SetEnd(range, new_end);
2366 return hr;
2369 static HRESULT WINAPI ITextRange_fnMoveEnd(ITextRange *me, LONG unit, LONG count,
2370 LONG *delta)
2372 ITextRangeImpl *This = impl_from_ITextRange(me);
2374 TRACE("(%p)->(%ld %ld %p)\n", This, unit, count, delta);
2376 if (!This->child.reole)
2377 return CO_E_RELEASED;
2379 return textrange_moveend(me, This->child.reole->editor, unit, count, delta);
2382 static HRESULT WINAPI ITextRange_fnMoveWhile(ITextRange *me, VARIANT *charset, LONG count,
2383 LONG *delta)
2385 ITextRangeImpl *This = impl_from_ITextRange(me);
2387 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
2389 if (!This->child.reole)
2390 return CO_E_RELEASED;
2392 return E_NOTIMPL;
2395 static HRESULT WINAPI ITextRange_fnMoveStartWhile(ITextRange *me, VARIANT *charset, LONG count,
2396 LONG *delta)
2398 ITextRangeImpl *This = impl_from_ITextRange(me);
2400 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
2402 if (!This->child.reole)
2403 return CO_E_RELEASED;
2405 return E_NOTIMPL;
2408 static HRESULT WINAPI ITextRange_fnMoveEndWhile(ITextRange *me, VARIANT *charset, LONG count,
2409 LONG *delta)
2411 ITextRangeImpl *This = impl_from_ITextRange(me);
2413 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
2415 if (!This->child.reole)
2416 return CO_E_RELEASED;
2418 return E_NOTIMPL;
2421 static HRESULT WINAPI ITextRange_fnMoveUntil(ITextRange *me, VARIANT *charset, LONG count,
2422 LONG *delta)
2424 ITextRangeImpl *This = impl_from_ITextRange(me);
2426 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
2428 if (!This->child.reole)
2429 return CO_E_RELEASED;
2431 return E_NOTIMPL;
2434 static HRESULT WINAPI ITextRange_fnMoveStartUntil(ITextRange *me, VARIANT *charset, LONG count,
2435 LONG *delta)
2437 ITextRangeImpl *This = impl_from_ITextRange(me);
2439 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
2441 if (!This->child.reole)
2442 return CO_E_RELEASED;
2444 return E_NOTIMPL;
2447 static HRESULT WINAPI ITextRange_fnMoveEndUntil(ITextRange *me, VARIANT *charset, LONG count,
2448 LONG *delta)
2450 ITextRangeImpl *This = impl_from_ITextRange(me);
2452 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
2454 if (!This->child.reole)
2455 return CO_E_RELEASED;
2457 return E_NOTIMPL;
2460 static HRESULT WINAPI ITextRange_fnFindText(ITextRange *me, BSTR text, LONG count, LONG flags,
2461 LONG *length)
2463 ITextRangeImpl *This = impl_from_ITextRange(me);
2465 FIXME("(%p)->(%s %ld %lx %p): stub\n", This, debugstr_w(text), count, flags, length);
2467 if (!This->child.reole)
2468 return CO_E_RELEASED;
2470 return E_NOTIMPL;
2473 static HRESULT WINAPI ITextRange_fnFindTextStart(ITextRange *me, BSTR text, LONG count,
2474 LONG flags, LONG *length)
2476 ITextRangeImpl *This = impl_from_ITextRange(me);
2478 FIXME("(%p)->(%s %ld %lx %p): stub\n", This, debugstr_w(text), count, flags, length);
2480 if (!This->child.reole)
2481 return CO_E_RELEASED;
2483 return E_NOTIMPL;
2486 static HRESULT WINAPI ITextRange_fnFindTextEnd(ITextRange *me, BSTR text, LONG count,
2487 LONG flags, LONG *length)
2489 ITextRangeImpl *This = impl_from_ITextRange(me);
2491 FIXME("(%p)->(%s %ld %lx %p): stub\n", This, debugstr_w(text), count, flags, length);
2493 if (!This->child.reole)
2494 return CO_E_RELEASED;
2496 return E_NOTIMPL;
2499 static HRESULT WINAPI ITextRange_fnDelete(ITextRange *me, LONG unit, LONG count, LONG *delta)
2501 ITextRangeImpl *This = impl_from_ITextRange(me);
2503 FIXME("(%p)->(%ld %ld %p): stub\n", This, unit, count, delta);
2505 if (!This->child.reole)
2506 return CO_E_RELEASED;
2508 return E_NOTIMPL;
2511 static HRESULT textrange_copy_or_cut( ITextRange *range, ME_TextEditor *editor, BOOL cut, VARIANT *v )
2513 LONG start, end;
2514 ME_Cursor cursor;
2515 IDataObject **data_out = NULL;
2517 ITextRange_GetStart( range, &start );
2518 ITextRange_GetEnd( range, &end );
2519 if (start == end)
2521 /* If the range is empty, all text is copied */
2522 LONG prev_end = end;
2523 ITextRange_SetEnd( range, MAXLONG );
2524 start = 0;
2525 ITextRange_GetEnd( range, &end );
2526 ITextRange_SetEnd( range, prev_end );
2528 cursor_from_char_ofs( editor, start, &cursor );
2530 if (v && V_VT(v) == (VT_UNKNOWN | VT_BYREF) && V_UNKNOWNREF( v ))
2531 data_out = (IDataObject **)V_UNKNOWNREF( v );
2533 return editor_copy_or_cut( editor, cut, &cursor, end - start, data_out );
2536 static HRESULT WINAPI ITextRange_fnCut(ITextRange *me, VARIANT *v)
2538 ITextRangeImpl *This = impl_from_ITextRange(me);
2540 TRACE("(%p)->(%p)\n", This, v);
2542 if (!This->child.reole)
2543 return CO_E_RELEASED;
2545 return textrange_copy_or_cut(me, This->child.reole->editor, TRUE, v);
2548 static HRESULT WINAPI ITextRange_fnCopy(ITextRange *me, VARIANT *v)
2550 ITextRangeImpl *This = impl_from_ITextRange(me);
2552 TRACE("(%p)->(%p)\n", This, v);
2554 if (!This->child.reole)
2555 return CO_E_RELEASED;
2557 return textrange_copy_or_cut(me, This->child.reole->editor, FALSE, v);
2560 static HRESULT WINAPI ITextRange_fnPaste(ITextRange *me, VARIANT *v, LONG format)
2562 ITextRangeImpl *This = impl_from_ITextRange(me);
2564 FIXME("(%p)->(%s %lx): stub\n", This, debugstr_variant(v), format);
2566 if (!This->child.reole)
2567 return CO_E_RELEASED;
2569 return E_NOTIMPL;
2572 static HRESULT WINAPI ITextRange_fnCanPaste(ITextRange *me, VARIANT *v, LONG format, LONG *ret)
2574 ITextRangeImpl *This = impl_from_ITextRange(me);
2576 FIXME("(%p)->(%s %lx %p): stub\n", This, debugstr_variant(v), format, ret);
2578 if (!This->child.reole)
2579 return CO_E_RELEASED;
2581 return E_NOTIMPL;
2584 static HRESULT WINAPI ITextRange_fnCanEdit(ITextRange *me, LONG *ret)
2586 ITextRangeImpl *This = impl_from_ITextRange(me);
2588 FIXME("(%p)->(%p): stub\n", This, ret);
2590 if (!This->child.reole)
2591 return CO_E_RELEASED;
2593 return E_NOTIMPL;
2596 static HRESULT WINAPI ITextRange_fnChangeCase(ITextRange *me, LONG type)
2598 ITextRangeImpl *This = impl_from_ITextRange(me);
2600 FIXME("(%p)->(%ld): stub\n", This, type);
2602 if (!This->child.reole)
2603 return CO_E_RELEASED;
2605 return E_NOTIMPL;
2608 static HRESULT WINAPI ITextRange_fnGetPoint(ITextRange *me, LONG type, LONG *cx, LONG *cy)
2610 ITextRangeImpl *This = impl_from_ITextRange(me);
2612 FIXME("(%p)->(%ld %p %p): stub\n", This, type, cx, cy);
2614 if (!This->child.reole)
2615 return CO_E_RELEASED;
2617 return E_NOTIMPL;
2620 static HRESULT WINAPI ITextRange_fnSetPoint(ITextRange *me, LONG x, LONG y, LONG type,
2621 LONG extend)
2623 ITextRangeImpl *This = impl_from_ITextRange(me);
2625 FIXME("(%p)->(%ld %ld %ld %ld): stub\n", This, x, y, type, extend);
2627 if (!This->child.reole)
2628 return CO_E_RELEASED;
2630 return E_NOTIMPL;
2633 static HRESULT WINAPI ITextRange_fnScrollIntoView(ITextRange *me, LONG value)
2635 ITextRangeImpl *This = impl_from_ITextRange(me);
2636 ME_TextEditor *editor;
2637 ME_Cursor cursor;
2638 int x, y, height;
2640 TRACE("(%p)->(%ld)\n", This, value);
2642 if (!This->child.reole)
2643 return CO_E_RELEASED;
2645 editor = This->child.reole->editor;
2647 switch (value)
2649 case tomStart:
2650 cursor_from_char_ofs( editor, This->start, &cursor );
2651 cursor_coords( editor, &cursor, &x, &y, &height );
2652 break;
2653 case tomEnd:
2654 cursor_from_char_ofs( editor, This->end, &cursor );
2655 cursor_coords( editor, &cursor, &x, &y, &height );
2656 break;
2657 default:
2658 FIXME("bStart value %ld not handled\n", value);
2659 return E_NOTIMPL;
2661 scroll_abs( editor, x, y, TRUE );
2662 return S_OK;
2665 static HRESULT WINAPI ITextRange_fnGetEmbeddedObject(ITextRange *me, IUnknown **ppv)
2667 ITextRangeImpl *This = impl_from_ITextRange(me);
2669 FIXME("(%p)->(%p): stub\n", This, ppv);
2671 if (!This->child.reole)
2672 return CO_E_RELEASED;
2674 return E_NOTIMPL;
2677 static const ITextRangeVtbl trvt = {
2678 ITextRange_fnQueryInterface,
2679 ITextRange_fnAddRef,
2680 ITextRange_fnRelease,
2681 ITextRange_fnGetTypeInfoCount,
2682 ITextRange_fnGetTypeInfo,
2683 ITextRange_fnGetIDsOfNames,
2684 ITextRange_fnInvoke,
2685 ITextRange_fnGetText,
2686 ITextRange_fnSetText,
2687 ITextRange_fnGetChar,
2688 ITextRange_fnSetChar,
2689 ITextRange_fnGetDuplicate,
2690 ITextRange_fnGetFormattedText,
2691 ITextRange_fnSetFormattedText,
2692 ITextRange_fnGetStart,
2693 ITextRange_fnSetStart,
2694 ITextRange_fnGetEnd,
2695 ITextRange_fnSetEnd,
2696 ITextRange_fnGetFont,
2697 ITextRange_fnSetFont,
2698 ITextRange_fnGetPara,
2699 ITextRange_fnSetPara,
2700 ITextRange_fnGetStoryLength,
2701 ITextRange_fnGetStoryType,
2702 ITextRange_fnCollapse,
2703 ITextRange_fnExpand,
2704 ITextRange_fnGetIndex,
2705 ITextRange_fnSetIndex,
2706 ITextRange_fnSetRange,
2707 ITextRange_fnInRange,
2708 ITextRange_fnInStory,
2709 ITextRange_fnIsEqual,
2710 ITextRange_fnSelect,
2711 ITextRange_fnStartOf,
2712 ITextRange_fnEndOf,
2713 ITextRange_fnMove,
2714 ITextRange_fnMoveStart,
2715 ITextRange_fnMoveEnd,
2716 ITextRange_fnMoveWhile,
2717 ITextRange_fnMoveStartWhile,
2718 ITextRange_fnMoveEndWhile,
2719 ITextRange_fnMoveUntil,
2720 ITextRange_fnMoveStartUntil,
2721 ITextRange_fnMoveEndUntil,
2722 ITextRange_fnFindText,
2723 ITextRange_fnFindTextStart,
2724 ITextRange_fnFindTextEnd,
2725 ITextRange_fnDelete,
2726 ITextRange_fnCut,
2727 ITextRange_fnCopy,
2728 ITextRange_fnPaste,
2729 ITextRange_fnCanPaste,
2730 ITextRange_fnCanEdit,
2731 ITextRange_fnChangeCase,
2732 ITextRange_fnGetPoint,
2733 ITextRange_fnSetPoint,
2734 ITextRange_fnScrollIntoView,
2735 ITextRange_fnGetEmbeddedObject
2738 /* ITextFont */
2739 static HRESULT WINAPI TextFont_QueryInterface(ITextFont *iface, REFIID riid, void **ppv)
2741 ITextFontImpl *This = impl_from_ITextFont(iface);
2743 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
2745 if (IsEqualIID(riid, &IID_ITextFont) ||
2746 IsEqualIID(riid, &IID_IDispatch) ||
2747 IsEqualIID(riid, &IID_IUnknown))
2749 *ppv = iface;
2750 ITextFont_AddRef(iface);
2751 return S_OK;
2754 *ppv = NULL;
2755 return E_NOINTERFACE;
2758 static ULONG WINAPI TextFont_AddRef(ITextFont *iface)
2760 ITextFontImpl *This = impl_from_ITextFont(iface);
2761 ULONG ref = InterlockedIncrement(&This->ref);
2762 TRACE("(%p)->(%lu)\n", This, ref);
2763 return ref;
2766 static ULONG WINAPI TextFont_Release(ITextFont *iface)
2768 ITextFontImpl *This = impl_from_ITextFont(iface);
2769 ULONG ref = InterlockedDecrement(&This->ref);
2771 TRACE("(%p)->(%lu)\n", This, ref);
2773 if (!ref)
2775 if (This->range)
2776 ITextRange_Release(This->range);
2777 SysFreeString(This->props[FONT_NAME].str);
2778 free(This);
2781 return ref;
2784 static HRESULT WINAPI TextFont_GetTypeInfoCount(ITextFont *iface, UINT *pctinfo)
2786 ITextFontImpl *This = impl_from_ITextFont(iface);
2787 TRACE("(%p)->(%p)\n", This, pctinfo);
2788 *pctinfo = 1;
2789 return S_OK;
2792 static HRESULT WINAPI TextFont_GetTypeInfo(ITextFont *iface, UINT iTInfo, LCID lcid,
2793 ITypeInfo **ppTInfo)
2795 ITextFontImpl *This = impl_from_ITextFont(iface);
2796 HRESULT hr;
2798 TRACE("(%p)->(%u,%ld,%p)\n", This, iTInfo, lcid, ppTInfo);
2800 hr = get_typeinfo(ITextFont_tid, ppTInfo);
2801 if (SUCCEEDED(hr))
2802 ITypeInfo_AddRef(*ppTInfo);
2803 return hr;
2806 static HRESULT WINAPI TextFont_GetIDsOfNames(ITextFont *iface, REFIID riid,
2807 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
2809 ITextFontImpl *This = impl_from_ITextFont(iface);
2810 ITypeInfo *ti;
2811 HRESULT hr;
2813 TRACE("(%p)->(%s, %p, %u, %ld, %p)\n", This, debugstr_guid(riid),
2814 rgszNames, cNames, lcid, rgDispId);
2816 hr = get_typeinfo(ITextFont_tid, &ti);
2817 if (SUCCEEDED(hr))
2818 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
2819 return hr;
2822 static HRESULT WINAPI TextFont_Invoke(
2823 ITextFont *iface,
2824 DISPID dispIdMember,
2825 REFIID riid,
2826 LCID lcid,
2827 WORD wFlags,
2828 DISPPARAMS *pDispParams,
2829 VARIANT *pVarResult,
2830 EXCEPINFO *pExcepInfo,
2831 UINT *puArgErr)
2833 ITextFontImpl *This = impl_from_ITextFont(iface);
2834 ITypeInfo *ti;
2835 HRESULT hr;
2837 TRACE("(%p)->(%ld, %s, %ld, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
2838 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2840 hr = get_typeinfo(ITextFont_tid, &ti);
2841 if (SUCCEEDED(hr))
2842 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2843 return hr;
2846 static HRESULT WINAPI TextFont_GetDuplicate(ITextFont *iface, ITextFont **ret)
2848 ITextFontImpl *This = impl_from_ITextFont(iface);
2850 TRACE("(%p)->(%p)\n", This, ret);
2852 if (!ret)
2853 return E_INVALIDARG;
2855 *ret = NULL;
2856 if (This->range && !get_range_reole(This->range))
2857 return CO_E_RELEASED;
2859 return create_textfont(NULL, This, ret);
2862 static HRESULT WINAPI TextFont_SetDuplicate(ITextFont *iface, ITextFont *pFont)
2864 ITextFontImpl *This = impl_from_ITextFont(iface);
2865 FIXME("(%p)->(%p): stub\n", This, pFont);
2866 return E_NOTIMPL;
2869 static HRESULT WINAPI TextFont_CanChange(ITextFont *iface, LONG *ret)
2871 ITextFontImpl *This = impl_from_ITextFont(iface);
2872 FIXME("(%p)->(%p): stub\n", This, ret);
2873 return E_NOTIMPL;
2876 static HRESULT WINAPI TextFont_IsEqual(ITextFont *iface, ITextFont *font, LONG *ret)
2878 ITextFontImpl *This = impl_from_ITextFont(iface);
2879 FIXME("(%p)->(%p %p): stub\n", This, font, ret);
2880 return E_NOTIMPL;
2883 static void textfont_reset_to_default(ITextFontImpl *font)
2885 enum textfont_prop_id id;
2887 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2888 switch (id)
2890 case FONT_ALLCAPS:
2891 case FONT_ANIMATION:
2892 case FONT_BOLD:
2893 case FONT_EMBOSS:
2894 case FONT_HIDDEN:
2895 case FONT_ENGRAVE:
2896 case FONT_ITALIC:
2897 case FONT_OUTLINE:
2898 case FONT_PROTECTED:
2899 case FONT_SHADOW:
2900 case FONT_SMALLCAPS:
2901 case FONT_STRIKETHROUGH:
2902 case FONT_SUBSCRIPT:
2903 case FONT_SUPERSCRIPT:
2904 case FONT_UNDERLINE:
2905 font->props[id].l = tomFalse;
2906 break;
2907 case FONT_BACKCOLOR:
2908 case FONT_FORECOLOR:
2909 font->props[id].l = tomAutoColor;
2910 break;
2911 case FONT_KERNING:
2912 case FONT_POSITION:
2913 case FONT_SIZE:
2914 case FONT_SPACING:
2915 font->props[id].f = 0.0;
2916 break;
2917 case FONT_LANGID:
2918 font->props[id].l = GetSystemDefaultLCID();
2919 break;
2920 case FONT_NAME: {
2921 SysFreeString(font->props[id].str);
2922 font->props[id].str = SysAllocString(L"System");
2923 break;
2925 case FONT_WEIGHT:
2926 font->props[id].l = FW_NORMAL;
2927 break;
2928 default:
2929 FIXME("font property %d not handled\n", id);
2934 static void textfont_reset_to_undefined(ITextFontImpl *font)
2936 enum textfont_prop_id id;
2938 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2939 switch (id)
2941 case FONT_ALLCAPS:
2942 case FONT_ANIMATION:
2943 case FONT_BOLD:
2944 case FONT_EMBOSS:
2945 case FONT_HIDDEN:
2946 case FONT_ENGRAVE:
2947 case FONT_ITALIC:
2948 case FONT_OUTLINE:
2949 case FONT_PROTECTED:
2950 case FONT_SHADOW:
2951 case FONT_SMALLCAPS:
2952 case FONT_STRIKETHROUGH:
2953 case FONT_SUBSCRIPT:
2954 case FONT_SUPERSCRIPT:
2955 case FONT_UNDERLINE:
2956 case FONT_BACKCOLOR:
2957 case FONT_FORECOLOR:
2958 case FONT_LANGID:
2959 case FONT_WEIGHT:
2960 font->props[id].l = tomUndefined;
2961 break;
2962 case FONT_KERNING:
2963 case FONT_POSITION:
2964 case FONT_SIZE:
2965 case FONT_SPACING:
2966 font->props[id].f = tomUndefined;
2967 break;
2968 case FONT_NAME:
2969 break;
2970 default:
2971 FIXME("font property %d not handled\n", id);
2976 static void textfont_apply_range_props(ITextFontImpl *font)
2978 enum textfont_prop_id propid;
2979 for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++)
2980 set_textfont_prop(font, propid, &font->props[propid]);
2983 static HRESULT WINAPI TextFont_Reset(ITextFont *iface, LONG value)
2985 ITextFontImpl *This = impl_from_ITextFont(iface);
2987 TRACE("(%p)->(%ld)\n", This, value);
2989 /* If font is attached to a range, released or not, we can't
2990 reset to undefined */
2991 if (This->range) {
2992 if (!get_range_reole(This->range))
2993 return CO_E_RELEASED;
2995 switch (value)
2997 case tomUndefined:
2998 return E_INVALIDARG;
2999 case tomCacheParms:
3000 textfont_cache_range_props(This);
3001 This->get_cache_enabled = TRUE;
3002 break;
3003 case tomTrackParms:
3004 This->get_cache_enabled = FALSE;
3005 break;
3006 case tomApplyLater:
3007 This->set_cache_enabled = TRUE;
3008 break;
3009 case tomApplyNow:
3010 This->set_cache_enabled = FALSE;
3011 textfont_apply_range_props(This);
3012 break;
3013 case tomUsePoints:
3014 case tomUseTwips:
3015 return E_INVALIDARG;
3016 default:
3017 FIXME("reset mode %ld not supported\n", value);
3020 return S_OK;
3022 else {
3023 switch (value)
3025 /* reset to global defaults */
3026 case tomDefault:
3027 textfont_reset_to_default(This);
3028 return S_OK;
3029 /* all properties are set to tomUndefined, font name is retained */
3030 case tomUndefined:
3031 textfont_reset_to_undefined(This);
3032 return S_OK;
3033 case tomApplyNow:
3034 case tomApplyLater:
3035 case tomTrackParms:
3036 case tomCacheParms:
3037 return S_OK;
3038 case tomUsePoints:
3039 case tomUseTwips:
3040 return E_INVALIDARG;
3044 FIXME("reset mode %ld not supported\n", value);
3045 return E_NOTIMPL;
3048 static HRESULT WINAPI TextFont_GetStyle(ITextFont *iface, LONG *value)
3050 ITextFontImpl *This = impl_from_ITextFont(iface);
3051 FIXME("(%p)->(%p): stub\n", This, value);
3052 return E_NOTIMPL;
3055 static HRESULT WINAPI TextFont_SetStyle(ITextFont *iface, LONG value)
3057 ITextFontImpl *This = impl_from_ITextFont(iface);
3058 FIXME("(%p)->(%ld): stub\n", This, value);
3059 return E_NOTIMPL;
3062 static HRESULT WINAPI TextFont_GetAllCaps(ITextFont *iface, LONG *value)
3064 ITextFontImpl *This = impl_from_ITextFont(iface);
3065 TRACE("(%p)->(%p)\n", This, value);
3066 return get_textfont_propl(This, FONT_ALLCAPS, value);
3069 static HRESULT WINAPI TextFont_SetAllCaps(ITextFont *iface, LONG value)
3071 ITextFontImpl *This = impl_from_ITextFont(iface);
3072 TRACE("(%p)->(%ld)\n", This, value);
3073 return set_textfont_propd(This, FONT_ALLCAPS, value);
3076 static HRESULT WINAPI TextFont_GetAnimation(ITextFont *iface, LONG *value)
3078 ITextFontImpl *This = impl_from_ITextFont(iface);
3079 TRACE("(%p)->(%p)\n", This, value);
3080 return get_textfont_propl(This, FONT_ANIMATION, value);
3083 static HRESULT WINAPI TextFont_SetAnimation(ITextFont *iface, LONG value)
3085 ITextFontImpl *This = impl_from_ITextFont(iface);
3087 TRACE("(%p)->(%ld)\n", This, value);
3089 if (value < tomNoAnimation || value > tomAnimationMax)
3090 return E_INVALIDARG;
3092 return set_textfont_propl(This, FONT_ANIMATION, value);
3095 static HRESULT WINAPI TextFont_GetBackColor(ITextFont *iface, LONG *value)
3097 ITextFontImpl *This = impl_from_ITextFont(iface);
3098 TRACE("(%p)->(%p)\n", This, value);
3099 return get_textfont_propl(This, FONT_BACKCOLOR, value);
3102 static HRESULT WINAPI TextFont_SetBackColor(ITextFont *iface, LONG value)
3104 ITextFontImpl *This = impl_from_ITextFont(iface);
3105 TRACE("(%p)->(%ld)\n", This, value);
3106 return set_textfont_propl(This, FONT_BACKCOLOR, value);
3109 static HRESULT WINAPI TextFont_GetBold(ITextFont *iface, LONG *value)
3111 ITextFontImpl *This = impl_from_ITextFont(iface);
3112 TRACE("(%p)->(%p)\n", This, value);
3113 return get_textfont_propl(This, FONT_BOLD, value);
3116 static HRESULT WINAPI TextFont_SetBold(ITextFont *iface, LONG value)
3118 ITextFontImpl *This = impl_from_ITextFont(iface);
3119 TRACE("(%p)->(%ld)\n", This, value);
3120 return set_textfont_propd(This, FONT_BOLD, value);
3123 static HRESULT WINAPI TextFont_GetEmboss(ITextFont *iface, LONG *value)
3125 ITextFontImpl *This = impl_from_ITextFont(iface);
3126 TRACE("(%p)->(%p)\n", This, value);
3127 return get_textfont_propl(This, FONT_EMBOSS, value);
3130 static HRESULT WINAPI TextFont_SetEmboss(ITextFont *iface, LONG value)
3132 ITextFontImpl *This = impl_from_ITextFont(iface);
3133 TRACE("(%p)->(%ld)\n", This, value);
3134 return set_textfont_propd(This, FONT_EMBOSS, value);
3137 static HRESULT WINAPI TextFont_GetForeColor(ITextFont *iface, LONG *value)
3139 ITextFontImpl *This = impl_from_ITextFont(iface);
3140 TRACE("(%p)->(%p)\n", This, value);
3141 return get_textfont_propl(This, FONT_FORECOLOR, value);
3144 static HRESULT WINAPI TextFont_SetForeColor(ITextFont *iface, LONG value)
3146 ITextFontImpl *This = impl_from_ITextFont(iface);
3147 TRACE("(%p)->(%ld)\n", This, value);
3148 return set_textfont_propl(This, FONT_FORECOLOR, value);
3151 static HRESULT WINAPI TextFont_GetHidden(ITextFont *iface, LONG *value)
3153 ITextFontImpl *This = impl_from_ITextFont(iface);
3154 TRACE("(%p)->(%p)\n", This, value);
3155 return get_textfont_propl(This, FONT_HIDDEN, value);
3158 static HRESULT WINAPI TextFont_SetHidden(ITextFont *iface, LONG value)
3160 ITextFontImpl *This = impl_from_ITextFont(iface);
3161 TRACE("(%p)->(%ld)\n", This, value);
3162 return set_textfont_propd(This, FONT_HIDDEN, value);
3165 static HRESULT WINAPI TextFont_GetEngrave(ITextFont *iface, LONG *value)
3167 ITextFontImpl *This = impl_from_ITextFont(iface);
3168 TRACE("(%p)->(%p)\n", This, value);
3169 return get_textfont_propl(This, FONT_ENGRAVE, value);
3172 static HRESULT WINAPI TextFont_SetEngrave(ITextFont *iface, LONG value)
3174 ITextFontImpl *This = impl_from_ITextFont(iface);
3175 TRACE("(%p)->(%ld)\n", This, value);
3176 return set_textfont_propd(This, FONT_ENGRAVE, value);
3179 static HRESULT WINAPI TextFont_GetItalic(ITextFont *iface, LONG *value)
3181 ITextFontImpl *This = impl_from_ITextFont(iface);
3182 TRACE("(%p)->(%p)\n", This, value);
3183 return get_textfont_propl(This, FONT_ITALIC, value);
3186 static HRESULT WINAPI TextFont_SetItalic(ITextFont *iface, LONG value)
3188 ITextFontImpl *This = impl_from_ITextFont(iface);
3189 TRACE("(%p)->(%ld)\n", This, value);
3190 return set_textfont_propd(This, FONT_ITALIC, value);
3193 static HRESULT WINAPI TextFont_GetKerning(ITextFont *iface, FLOAT *value)
3195 ITextFontImpl *This = impl_from_ITextFont(iface);
3196 TRACE("(%p)->(%p)\n", This, value);
3197 return get_textfont_propf(This, FONT_KERNING, value);
3200 static HRESULT WINAPI TextFont_SetKerning(ITextFont *iface, FLOAT value)
3202 ITextFontImpl *This = impl_from_ITextFont(iface);
3203 TRACE("(%p)->(%.2f)\n", This, value);
3204 return set_textfont_propf(This, FONT_KERNING, value);
3207 static HRESULT WINAPI TextFont_GetLanguageID(ITextFont *iface, LONG *value)
3209 ITextFontImpl *This = impl_from_ITextFont(iface);
3210 TRACE("(%p)->(%p)\n", This, value);
3211 return get_textfont_propl(This, FONT_LANGID, value);
3214 static HRESULT WINAPI TextFont_SetLanguageID(ITextFont *iface, LONG value)
3216 ITextFontImpl *This = impl_from_ITextFont(iface);
3217 TRACE("(%p)->(%ld)\n", This, value);
3218 return set_textfont_propl(This, FONT_LANGID, value);
3221 static HRESULT WINAPI TextFont_GetName(ITextFont *iface, BSTR *value)
3223 ITextFontImpl *This = impl_from_ITextFont(iface);
3225 TRACE("(%p)->(%p)\n", This, value);
3227 if (!value)
3228 return E_INVALIDARG;
3230 *value = NULL;
3232 if (!This->range) {
3233 if (This->props[FONT_NAME].str)
3234 *value = SysAllocString(This->props[FONT_NAME].str);
3235 else
3236 *value = SysAllocStringLen(NULL, 0);
3237 return *value ? S_OK : E_OUTOFMEMORY;
3240 return textfont_getname_from_range(This->range, value);
3243 static HRESULT WINAPI TextFont_SetName(ITextFont *iface, BSTR value)
3245 ITextFontImpl *This = impl_from_ITextFont(iface);
3246 textfont_prop_val v;
3248 TRACE("(%p)->(%s)\n", This, debugstr_w(value));
3250 v.str = value;
3251 return set_textfont_prop(This, FONT_NAME, &v);
3254 static HRESULT WINAPI TextFont_GetOutline(ITextFont *iface, LONG *value)
3256 ITextFontImpl *This = impl_from_ITextFont(iface);
3257 TRACE("(%p)->(%p)\n", This, value);
3258 return get_textfont_propl(This, FONT_OUTLINE, value);
3261 static HRESULT WINAPI TextFont_SetOutline(ITextFont *iface, LONG value)
3263 ITextFontImpl *This = impl_from_ITextFont(iface);
3264 TRACE("(%p)->(%ld)\n", This, value);
3265 return set_textfont_propd(This, FONT_OUTLINE, value);
3268 static HRESULT WINAPI TextFont_GetPosition(ITextFont *iface, FLOAT *value)
3270 ITextFontImpl *This = impl_from_ITextFont(iface);
3271 TRACE("(%p)->(%p)\n", This, value);
3272 return get_textfont_propf(This, FONT_POSITION, value);
3275 static HRESULT WINAPI TextFont_SetPosition(ITextFont *iface, FLOAT value)
3277 ITextFontImpl *This = impl_from_ITextFont(iface);
3278 TRACE("(%p)->(%.2f)\n", This, value);
3279 return set_textfont_propf(This, FONT_POSITION, value);
3282 static HRESULT WINAPI TextFont_GetProtected(ITextFont *iface, LONG *value)
3284 ITextFontImpl *This = impl_from_ITextFont(iface);
3285 TRACE("(%p)->(%p)\n", This, value);
3286 return get_textfont_propl(This, FONT_PROTECTED, value);
3289 static HRESULT WINAPI TextFont_SetProtected(ITextFont *iface, LONG value)
3291 ITextFontImpl *This = impl_from_ITextFont(iface);
3292 TRACE("(%p)->(%ld)\n", This, value);
3293 return set_textfont_propd(This, FONT_PROTECTED, value);
3296 static HRESULT WINAPI TextFont_GetShadow(ITextFont *iface, LONG *value)
3298 ITextFontImpl *This = impl_from_ITextFont(iface);
3299 TRACE("(%p)->(%p)\n", This, value);
3300 return get_textfont_propl(This, FONT_SHADOW, value);
3303 static HRESULT WINAPI TextFont_SetShadow(ITextFont *iface, LONG value)
3305 ITextFontImpl *This = impl_from_ITextFont(iface);
3306 TRACE("(%p)->(%ld)\n", This, value);
3307 return set_textfont_propd(This, FONT_SHADOW, value);
3310 static HRESULT WINAPI TextFont_GetSize(ITextFont *iface, FLOAT *value)
3312 ITextFontImpl *This = impl_from_ITextFont(iface);
3313 TRACE("(%p)->(%p)\n", This, value);
3314 return get_textfont_propf(This, FONT_SIZE, value);
3317 static HRESULT WINAPI TextFont_SetSize(ITextFont *iface, FLOAT value)
3319 ITextFontImpl *This = impl_from_ITextFont(iface);
3320 TRACE("(%p)->(%.2f)\n", This, value);
3321 return set_textfont_propf(This, FONT_SIZE, value);
3324 static HRESULT WINAPI TextFont_GetSmallCaps(ITextFont *iface, LONG *value)
3326 ITextFontImpl *This = impl_from_ITextFont(iface);
3327 TRACE("(%p)->(%p)\n", This, value);
3328 return get_textfont_propl(This, FONT_SMALLCAPS, value);
3331 static HRESULT WINAPI TextFont_SetSmallCaps(ITextFont *iface, LONG value)
3333 ITextFontImpl *This = impl_from_ITextFont(iface);
3334 TRACE("(%p)->(%ld)\n", This, value);
3335 return set_textfont_propd(This, FONT_SMALLCAPS, value);
3338 static HRESULT WINAPI TextFont_GetSpacing(ITextFont *iface, FLOAT *value)
3340 ITextFontImpl *This = impl_from_ITextFont(iface);
3341 TRACE("(%p)->(%p)\n", This, value);
3342 return get_textfont_propf(This, FONT_SPACING, value);
3345 static HRESULT WINAPI TextFont_SetSpacing(ITextFont *iface, FLOAT value)
3347 ITextFontImpl *This = impl_from_ITextFont(iface);
3348 TRACE("(%p)->(%.2f)\n", This, value);
3349 return set_textfont_propf(This, FONT_SPACING, value);
3352 static HRESULT WINAPI TextFont_GetStrikeThrough(ITextFont *iface, LONG *value)
3354 ITextFontImpl *This = impl_from_ITextFont(iface);
3355 TRACE("(%p)->(%p)\n", This, value);
3356 return get_textfont_propl(This, FONT_STRIKETHROUGH, value);
3359 static HRESULT WINAPI TextFont_SetStrikeThrough(ITextFont *iface, LONG value)
3361 ITextFontImpl *This = impl_from_ITextFont(iface);
3362 TRACE("(%p)->(%ld)\n", This, value);
3363 return set_textfont_propd(This, FONT_STRIKETHROUGH, value);
3366 static HRESULT WINAPI TextFont_GetSubscript(ITextFont *iface, LONG *value)
3368 ITextFontImpl *This = impl_from_ITextFont(iface);
3369 TRACE("(%p)->(%p)\n", This, value);
3370 return get_textfont_propl(This, FONT_SUBSCRIPT, value);
3373 static HRESULT WINAPI TextFont_SetSubscript(ITextFont *iface, LONG value)
3375 ITextFontImpl *This = impl_from_ITextFont(iface);
3376 TRACE("(%p)->(%ld)\n", This, value);
3377 return set_textfont_propd(This, FONT_SUBSCRIPT, value);
3380 static HRESULT WINAPI TextFont_GetSuperscript(ITextFont *iface, LONG *value)
3382 ITextFontImpl *This = impl_from_ITextFont(iface);
3383 TRACE("(%p)->(%p)\n", This, value);
3384 return get_textfont_propl(This, FONT_SUPERSCRIPT, value);
3387 static HRESULT WINAPI TextFont_SetSuperscript(ITextFont *iface, LONG value)
3389 ITextFontImpl *This = impl_from_ITextFont(iface);
3390 TRACE("(%p)->(%ld)\n", This, value);
3391 return set_textfont_propd(This, FONT_SUPERSCRIPT, value);
3394 static HRESULT WINAPI TextFont_GetUnderline(ITextFont *iface, LONG *value)
3396 ITextFontImpl *This = impl_from_ITextFont(iface);
3397 TRACE("(%p)->(%p)\n", This, value);
3398 return get_textfont_propl(This, FONT_UNDERLINE, value);
3401 static HRESULT WINAPI TextFont_SetUnderline(ITextFont *iface, LONG value)
3403 ITextFontImpl *This = impl_from_ITextFont(iface);
3404 TRACE("(%p)->(%ld)\n", This, value);
3405 return set_textfont_propd(This, FONT_UNDERLINE, value);
3408 static HRESULT WINAPI TextFont_GetWeight(ITextFont *iface, LONG *value)
3410 ITextFontImpl *This = impl_from_ITextFont(iface);
3411 TRACE("(%p)->(%p)\n", This, value);
3412 return get_textfont_propl(This, FONT_WEIGHT, value);
3415 static HRESULT WINAPI TextFont_SetWeight(ITextFont *iface, LONG value)
3417 ITextFontImpl *This = impl_from_ITextFont(iface);
3418 TRACE("(%p)->(%ld)\n", This, value);
3419 return set_textfont_propl(This, FONT_WEIGHT, value);
3422 static ITextFontVtbl textfontvtbl = {
3423 TextFont_QueryInterface,
3424 TextFont_AddRef,
3425 TextFont_Release,
3426 TextFont_GetTypeInfoCount,
3427 TextFont_GetTypeInfo,
3428 TextFont_GetIDsOfNames,
3429 TextFont_Invoke,
3430 TextFont_GetDuplicate,
3431 TextFont_SetDuplicate,
3432 TextFont_CanChange,
3433 TextFont_IsEqual,
3434 TextFont_Reset,
3435 TextFont_GetStyle,
3436 TextFont_SetStyle,
3437 TextFont_GetAllCaps,
3438 TextFont_SetAllCaps,
3439 TextFont_GetAnimation,
3440 TextFont_SetAnimation,
3441 TextFont_GetBackColor,
3442 TextFont_SetBackColor,
3443 TextFont_GetBold,
3444 TextFont_SetBold,
3445 TextFont_GetEmboss,
3446 TextFont_SetEmboss,
3447 TextFont_GetForeColor,
3448 TextFont_SetForeColor,
3449 TextFont_GetHidden,
3450 TextFont_SetHidden,
3451 TextFont_GetEngrave,
3452 TextFont_SetEngrave,
3453 TextFont_GetItalic,
3454 TextFont_SetItalic,
3455 TextFont_GetKerning,
3456 TextFont_SetKerning,
3457 TextFont_GetLanguageID,
3458 TextFont_SetLanguageID,
3459 TextFont_GetName,
3460 TextFont_SetName,
3461 TextFont_GetOutline,
3462 TextFont_SetOutline,
3463 TextFont_GetPosition,
3464 TextFont_SetPosition,
3465 TextFont_GetProtected,
3466 TextFont_SetProtected,
3467 TextFont_GetShadow,
3468 TextFont_SetShadow,
3469 TextFont_GetSize,
3470 TextFont_SetSize,
3471 TextFont_GetSmallCaps,
3472 TextFont_SetSmallCaps,
3473 TextFont_GetSpacing,
3474 TextFont_SetSpacing,
3475 TextFont_GetStrikeThrough,
3476 TextFont_SetStrikeThrough,
3477 TextFont_GetSubscript,
3478 TextFont_SetSubscript,
3479 TextFont_GetSuperscript,
3480 TextFont_SetSuperscript,
3481 TextFont_GetUnderline,
3482 TextFont_SetUnderline,
3483 TextFont_GetWeight,
3484 TextFont_SetWeight
3487 static HRESULT create_textfont(ITextRange *range, const ITextFontImpl *src, ITextFont **ret)
3489 ITextFontImpl *font;
3491 *ret = NULL;
3492 font = malloc(sizeof(*font));
3493 if (!font)
3494 return E_OUTOFMEMORY;
3496 font->ITextFont_iface.lpVtbl = &textfontvtbl;
3497 font->ref = 1;
3499 if (src) {
3500 font->range = NULL;
3501 font->get_cache_enabled = TRUE;
3502 font->set_cache_enabled = TRUE;
3503 memcpy(&font->props, &src->props, sizeof(font->props));
3504 if (font->props[FONT_NAME].str)
3505 font->props[FONT_NAME].str = SysAllocString(font->props[FONT_NAME].str);
3507 else {
3508 font->range = range;
3509 ITextRange_AddRef(range);
3511 /* cache current properties */
3512 font->get_cache_enabled = FALSE;
3513 font->set_cache_enabled = FALSE;
3514 textfont_cache_range_props(font);
3517 *ret = &font->ITextFont_iface;
3518 return S_OK;
3521 /* ITextPara */
3522 static HRESULT WINAPI TextPara_QueryInterface(ITextPara *iface, REFIID riid, void **ppv)
3524 ITextParaImpl *This = impl_from_ITextPara(iface);
3526 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
3528 if (IsEqualIID(riid, &IID_ITextPara) ||
3529 IsEqualIID(riid, &IID_IDispatch) ||
3530 IsEqualIID(riid, &IID_IUnknown))
3532 *ppv = iface;
3533 ITextPara_AddRef(iface);
3534 return S_OK;
3537 *ppv = NULL;
3538 return E_NOINTERFACE;
3541 static ULONG WINAPI TextPara_AddRef(ITextPara *iface)
3543 ITextParaImpl *This = impl_from_ITextPara(iface);
3544 ULONG ref = InterlockedIncrement(&This->ref);
3545 TRACE("(%p)->(%lu)\n", This, ref);
3546 return ref;
3549 static ULONG WINAPI TextPara_Release(ITextPara *iface)
3551 ITextParaImpl *This = impl_from_ITextPara(iface);
3552 ULONG ref = InterlockedDecrement(&This->ref);
3554 TRACE("(%p)->(%lu)\n", This, ref);
3556 if (!ref)
3558 ITextRange_Release(This->range);
3559 free(This);
3562 return ref;
3565 static HRESULT WINAPI TextPara_GetTypeInfoCount(ITextPara *iface, UINT *pctinfo)
3567 ITextParaImpl *This = impl_from_ITextPara(iface);
3568 TRACE("(%p)->(%p)\n", This, pctinfo);
3569 *pctinfo = 1;
3570 return S_OK;
3573 static HRESULT WINAPI TextPara_GetTypeInfo(ITextPara *iface, UINT iTInfo, LCID lcid,
3574 ITypeInfo **ppTInfo)
3576 ITextParaImpl *This = impl_from_ITextPara(iface);
3577 HRESULT hr;
3579 TRACE("(%p)->(%u,%ld,%p)\n", This, iTInfo, lcid, ppTInfo);
3581 hr = get_typeinfo(ITextPara_tid, ppTInfo);
3582 if (SUCCEEDED(hr))
3583 ITypeInfo_AddRef(*ppTInfo);
3584 return hr;
3587 static HRESULT WINAPI TextPara_GetIDsOfNames(ITextPara *iface, REFIID riid,
3588 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
3590 ITextParaImpl *This = impl_from_ITextPara(iface);
3591 ITypeInfo *ti;
3592 HRESULT hr;
3594 TRACE("(%p)->(%s, %p, %u, %ld, %p)\n", This, debugstr_guid(riid), rgszNames,
3595 cNames, lcid, rgDispId);
3597 hr = get_typeinfo(ITextPara_tid, &ti);
3598 if (SUCCEEDED(hr))
3599 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
3600 return hr;
3603 static HRESULT WINAPI TextPara_Invoke(
3604 ITextPara *iface,
3605 DISPID dispIdMember,
3606 REFIID riid,
3607 LCID lcid,
3608 WORD wFlags,
3609 DISPPARAMS *pDispParams,
3610 VARIANT *pVarResult,
3611 EXCEPINFO *pExcepInfo,
3612 UINT *puArgErr)
3614 ITextParaImpl *This = impl_from_ITextPara(iface);
3615 ITypeInfo *ti;
3616 HRESULT hr;
3618 TRACE("(%p)->(%ld, %s, %ld, %u, %p, %p, %p, %p)\n", This, dispIdMember,
3619 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
3620 pExcepInfo, puArgErr);
3622 hr = get_typeinfo(ITextPara_tid, &ti);
3623 if (SUCCEEDED(hr))
3624 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3625 return hr;
3628 static HRESULT WINAPI TextPara_GetDuplicate(ITextPara *iface, ITextPara **ret)
3630 ITextParaImpl *This = impl_from_ITextPara(iface);
3631 FIXME("(%p)->(%p)\n", This, ret);
3632 return E_NOTIMPL;
3635 static HRESULT WINAPI TextPara_SetDuplicate(ITextPara *iface, ITextPara *para)
3637 ITextParaImpl *This = impl_from_ITextPara(iface);
3638 FIXME("(%p)->(%p)\n", This, para);
3639 return E_NOTIMPL;
3642 static HRESULT WINAPI TextPara_CanChange(ITextPara *iface, LONG *ret)
3644 ITextParaImpl *This = impl_from_ITextPara(iface);
3645 FIXME("(%p)->(%p)\n", This, ret);
3646 return E_NOTIMPL;
3649 static HRESULT WINAPI TextPara_IsEqual(ITextPara *iface, ITextPara *para, LONG *ret)
3651 ITextParaImpl *This = impl_from_ITextPara(iface);
3652 FIXME("(%p)->(%p %p)\n", This, para, ret);
3653 return E_NOTIMPL;
3656 static HRESULT WINAPI TextPara_Reset(ITextPara *iface, LONG value)
3658 ITextParaImpl *This = impl_from_ITextPara(iface);
3659 FIXME("(%p)->(%ld)\n", This, value);
3660 return E_NOTIMPL;
3663 static HRESULT WINAPI TextPara_GetStyle(ITextPara *iface, LONG *value)
3665 ITextParaImpl *This = impl_from_ITextPara(iface);
3666 FIXME("(%p)->(%p)\n", This, value);
3667 return E_NOTIMPL;
3670 static HRESULT WINAPI TextPara_SetStyle(ITextPara *iface, LONG value)
3672 ITextParaImpl *This = impl_from_ITextPara(iface);
3673 FIXME("(%p)->(%ld)\n", This, value);
3674 return E_NOTIMPL;
3677 static HRESULT WINAPI TextPara_GetAlignment(ITextPara *iface, LONG *value)
3679 ITextParaImpl *This = impl_from_ITextPara(iface);
3680 FIXME("(%p)->(%p)\n", This, value);
3681 return E_NOTIMPL;
3684 static HRESULT WINAPI TextPara_SetAlignment(ITextPara *iface, LONG value)
3686 ITextParaImpl *This = impl_from_ITextPara(iface);
3687 FIXME("(%p)->(%ld)\n", This, value);
3688 return E_NOTIMPL;
3691 static HRESULT WINAPI TextPara_GetHyphenation(ITextPara *iface, LONG *value)
3693 ITextParaImpl *This = impl_from_ITextPara(iface);
3694 FIXME("(%p)->(%p)\n", This, value);
3695 return E_NOTIMPL;
3698 static HRESULT WINAPI TextPara_SetHyphenation(ITextPara *iface, LONG value)
3700 ITextParaImpl *This = impl_from_ITextPara(iface);
3701 FIXME("(%p)->(%ld)\n", This, value);
3702 return E_NOTIMPL;
3705 static HRESULT WINAPI TextPara_GetFirstLineIndent(ITextPara *iface, FLOAT *value)
3707 ITextParaImpl *This = impl_from_ITextPara(iface);
3708 FIXME("(%p)->(%p)\n", This, value);
3709 return E_NOTIMPL;
3712 static HRESULT WINAPI TextPara_GetKeepTogether(ITextPara *iface, LONG *value)
3714 ITextParaImpl *This = impl_from_ITextPara(iface);
3715 FIXME("(%p)->(%p)\n", This, value);
3716 return E_NOTIMPL;
3719 static HRESULT WINAPI TextPara_SetKeepTogether(ITextPara *iface, LONG value)
3721 ITextParaImpl *This = impl_from_ITextPara(iface);
3722 FIXME("(%p)->(%ld)\n", This, value);
3723 return E_NOTIMPL;
3726 static HRESULT WINAPI TextPara_GetKeepWithNext(ITextPara *iface, LONG *value)
3728 ITextParaImpl *This = impl_from_ITextPara(iface);
3729 FIXME("(%p)->(%p)\n", This, value);
3730 return E_NOTIMPL;
3733 static HRESULT WINAPI TextPara_SetKeepWithNext(ITextPara *iface, LONG value)
3735 ITextParaImpl *This = impl_from_ITextPara(iface);
3736 FIXME("(%p)->(%ld)\n", This, value);
3737 return E_NOTIMPL;
3740 static HRESULT WINAPI TextPara_GetLeftIndent(ITextPara *iface, FLOAT *value)
3742 ITextParaImpl *This = impl_from_ITextPara(iface);
3743 FIXME("(%p)->(%p)\n", This, value);
3744 return E_NOTIMPL;
3747 static HRESULT WINAPI TextPara_GetLineSpacing(ITextPara *iface, FLOAT *value)
3749 ITextParaImpl *This = impl_from_ITextPara(iface);
3750 FIXME("(%p)->(%p)\n", This, value);
3751 return E_NOTIMPL;
3754 static HRESULT WINAPI TextPara_GetLineSpacingRule(ITextPara *iface, LONG *value)
3756 ITextParaImpl *This = impl_from_ITextPara(iface);
3757 FIXME("(%p)->(%p)\n", This, value);
3758 return E_NOTIMPL;
3761 static HRESULT WINAPI TextPara_GetListAlignment(ITextPara *iface, LONG *value)
3763 ITextParaImpl *This = impl_from_ITextPara(iface);
3764 FIXME("(%p)->(%p)\n", This, value);
3765 return E_NOTIMPL;
3768 static HRESULT WINAPI TextPara_SetListAlignment(ITextPara *iface, LONG value)
3770 ITextParaImpl *This = impl_from_ITextPara(iface);
3771 FIXME("(%p)->(%ld)\n", This, value);
3772 return E_NOTIMPL;
3775 static HRESULT WINAPI TextPara_GetListLevelIndex(ITextPara *iface, LONG *value)
3777 ITextParaImpl *This = impl_from_ITextPara(iface);
3778 FIXME("(%p)->(%p)\n", This, value);
3779 return E_NOTIMPL;
3782 static HRESULT WINAPI TextPara_SetListLevelIndex(ITextPara *iface, LONG value)
3784 ITextParaImpl *This = impl_from_ITextPara(iface);
3785 FIXME("(%p)->(%ld)\n", This, value);
3786 return E_NOTIMPL;
3789 static HRESULT WINAPI TextPara_GetListStart(ITextPara *iface, LONG *value)
3791 ITextParaImpl *This = impl_from_ITextPara(iface);
3792 FIXME("(%p)->(%p)\n", This, value);
3793 return E_NOTIMPL;
3796 static HRESULT WINAPI TextPara_SetListStart(ITextPara *iface, LONG value)
3798 ITextParaImpl *This = impl_from_ITextPara(iface);
3799 FIXME("(%p)->(%ld)\n", This, value);
3800 return E_NOTIMPL;
3803 static HRESULT WINAPI TextPara_GetListTab(ITextPara *iface, FLOAT *value)
3805 ITextParaImpl *This = impl_from_ITextPara(iface);
3806 FIXME("(%p)->(%p)\n", This, value);
3807 return E_NOTIMPL;
3810 static HRESULT WINAPI TextPara_SetListTab(ITextPara *iface, FLOAT value)
3812 ITextParaImpl *This = impl_from_ITextPara(iface);
3813 FIXME("(%p)->(%.2f)\n", This, value);
3814 return E_NOTIMPL;
3817 static HRESULT WINAPI TextPara_GetListType(ITextPara *iface, LONG *value)
3819 ITextParaImpl *This = impl_from_ITextPara(iface);
3820 FIXME("(%p)->(%p)\n", This, value);
3821 return E_NOTIMPL;
3824 static HRESULT WINAPI TextPara_SetListType(ITextPara *iface, LONG value)
3826 ITextParaImpl *This = impl_from_ITextPara(iface);
3827 FIXME("(%p)->(%ld)\n", This, value);
3828 return E_NOTIMPL;
3831 static HRESULT WINAPI TextPara_GetNoLineNumber(ITextPara *iface, LONG *value)
3833 ITextParaImpl *This = impl_from_ITextPara(iface);
3834 FIXME("(%p)->(%p)\n", This, value);
3835 return E_NOTIMPL;
3838 static HRESULT WINAPI TextPara_SetNoLineNumber(ITextPara *iface, LONG value)
3840 ITextParaImpl *This = impl_from_ITextPara(iface);
3841 FIXME("(%p)->(%ld)\n", This, value);
3842 return E_NOTIMPL;
3845 static HRESULT WINAPI TextPara_GetPageBreakBefore(ITextPara *iface, LONG *value)
3847 ITextParaImpl *This = impl_from_ITextPara(iface);
3848 FIXME("(%p)->(%p)\n", This, value);
3849 return E_NOTIMPL;
3852 static HRESULT WINAPI TextPara_SetPageBreakBefore(ITextPara *iface, LONG value)
3854 ITextParaImpl *This = impl_from_ITextPara(iface);
3855 FIXME("(%p)->(%ld)\n", This, value);
3856 return E_NOTIMPL;
3859 static HRESULT WINAPI TextPara_GetRightIndent(ITextPara *iface, FLOAT *value)
3861 ITextParaImpl *This = impl_from_ITextPara(iface);
3862 FIXME("(%p)->(%p)\n", This, value);
3863 return E_NOTIMPL;
3866 static HRESULT WINAPI TextPara_SetRightIndent(ITextPara *iface, FLOAT value)
3868 ITextParaImpl *This = impl_from_ITextPara(iface);
3869 FIXME("(%p)->(%.2f)\n", This, value);
3870 return E_NOTIMPL;
3873 static HRESULT WINAPI TextPara_SetIndents(ITextPara *iface, FLOAT StartIndent, FLOAT LeftIndent, FLOAT RightIndent)
3875 ITextParaImpl *This = impl_from_ITextPara(iface);
3876 FIXME("(%p)->(%.2f %.2f %.2f)\n", This, StartIndent, LeftIndent, RightIndent);
3877 return E_NOTIMPL;
3880 static HRESULT WINAPI TextPara_SetLineSpacing(ITextPara *iface, LONG LineSpacingRule, FLOAT LineSpacing)
3882 ITextParaImpl *This = impl_from_ITextPara(iface);
3883 FIXME("(%p)->(%ld %.2f)\n", This, LineSpacingRule, LineSpacing);
3884 return E_NOTIMPL;
3887 static HRESULT WINAPI TextPara_GetSpaceAfter(ITextPara *iface, FLOAT *value)
3889 ITextParaImpl *This = impl_from_ITextPara(iface);
3890 FIXME("(%p)->(%p)\n", This, value);
3891 return E_NOTIMPL;
3894 static HRESULT WINAPI TextPara_SetSpaceAfter(ITextPara *iface, FLOAT value)
3896 ITextParaImpl *This = impl_from_ITextPara(iface);
3897 FIXME("(%p)->(%.2f)\n", This, value);
3898 return E_NOTIMPL;
3901 static HRESULT WINAPI TextPara_GetSpaceBefore(ITextPara *iface, FLOAT *value)
3903 ITextParaImpl *This = impl_from_ITextPara(iface);
3904 FIXME("(%p)->(%p)\n", This, value);
3905 return E_NOTIMPL;
3908 static HRESULT WINAPI TextPara_SetSpaceBefore(ITextPara *iface, FLOAT value)
3910 ITextParaImpl *This = impl_from_ITextPara(iface);
3911 FIXME("(%p)->(%.2f)\n", This, value);
3912 return E_NOTIMPL;
3915 static HRESULT WINAPI TextPara_GetWidowControl(ITextPara *iface, LONG *value)
3917 ITextParaImpl *This = impl_from_ITextPara(iface);
3918 FIXME("(%p)->(%p)\n", This, value);
3919 return E_NOTIMPL;
3922 static HRESULT WINAPI TextPara_SetWidowControl(ITextPara *iface, LONG value)
3924 ITextParaImpl *This = impl_from_ITextPara(iface);
3925 FIXME("(%p)->(%ld)\n", This, value);
3926 return E_NOTIMPL;
3929 static HRESULT WINAPI TextPara_GetTabCount(ITextPara *iface, LONG *value)
3931 ITextParaImpl *This = impl_from_ITextPara(iface);
3932 FIXME("(%p)->(%p)\n", This, value);
3933 return E_NOTIMPL;
3936 static HRESULT WINAPI TextPara_AddTab(ITextPara *iface, FLOAT tbPos, LONG tbAlign, LONG tbLeader)
3938 ITextParaImpl *This = impl_from_ITextPara(iface);
3939 FIXME("(%p)->(%.2f %ld %ld)\n", This, tbPos, tbAlign, tbLeader);
3940 return E_NOTIMPL;
3943 static HRESULT WINAPI TextPara_ClearAllTabs(ITextPara *iface)
3945 ITextParaImpl *This = impl_from_ITextPara(iface);
3946 FIXME("(%p)\n", This);
3947 return E_NOTIMPL;
3950 static HRESULT WINAPI TextPara_DeleteTab(ITextPara *iface, FLOAT pos)
3952 ITextParaImpl *This = impl_from_ITextPara(iface);
3953 FIXME("(%p)->(%.2f)\n", This, pos);
3954 return E_NOTIMPL;
3957 static HRESULT WINAPI TextPara_GetTab(ITextPara *iface, LONG iTab, FLOAT *ptbPos, LONG *ptbAlign, LONG *ptbLeader)
3959 ITextParaImpl *This = impl_from_ITextPara(iface);
3960 FIXME("(%p)->(%ld %p %p %p)\n", This, iTab, ptbPos, ptbAlign, ptbLeader);
3961 return E_NOTIMPL;
3964 static ITextParaVtbl textparavtbl = {
3965 TextPara_QueryInterface,
3966 TextPara_AddRef,
3967 TextPara_Release,
3968 TextPara_GetTypeInfoCount,
3969 TextPara_GetTypeInfo,
3970 TextPara_GetIDsOfNames,
3971 TextPara_Invoke,
3972 TextPara_GetDuplicate,
3973 TextPara_SetDuplicate,
3974 TextPara_CanChange,
3975 TextPara_IsEqual,
3976 TextPara_Reset,
3977 TextPara_GetStyle,
3978 TextPara_SetStyle,
3979 TextPara_GetAlignment,
3980 TextPara_SetAlignment,
3981 TextPara_GetHyphenation,
3982 TextPara_SetHyphenation,
3983 TextPara_GetFirstLineIndent,
3984 TextPara_GetKeepTogether,
3985 TextPara_SetKeepTogether,
3986 TextPara_GetKeepWithNext,
3987 TextPara_SetKeepWithNext,
3988 TextPara_GetLeftIndent,
3989 TextPara_GetLineSpacing,
3990 TextPara_GetLineSpacingRule,
3991 TextPara_GetListAlignment,
3992 TextPara_SetListAlignment,
3993 TextPara_GetListLevelIndex,
3994 TextPara_SetListLevelIndex,
3995 TextPara_GetListStart,
3996 TextPara_SetListStart,
3997 TextPara_GetListTab,
3998 TextPara_SetListTab,
3999 TextPara_GetListType,
4000 TextPara_SetListType,
4001 TextPara_GetNoLineNumber,
4002 TextPara_SetNoLineNumber,
4003 TextPara_GetPageBreakBefore,
4004 TextPara_SetPageBreakBefore,
4005 TextPara_GetRightIndent,
4006 TextPara_SetRightIndent,
4007 TextPara_SetIndents,
4008 TextPara_SetLineSpacing,
4009 TextPara_GetSpaceAfter,
4010 TextPara_SetSpaceAfter,
4011 TextPara_GetSpaceBefore,
4012 TextPara_SetSpaceBefore,
4013 TextPara_GetWidowControl,
4014 TextPara_SetWidowControl,
4015 TextPara_GetTabCount,
4016 TextPara_AddTab,
4017 TextPara_ClearAllTabs,
4018 TextPara_DeleteTab,
4019 TextPara_GetTab
4022 static HRESULT create_textpara(ITextRange *range, ITextPara **ret)
4024 ITextParaImpl *para;
4026 *ret = NULL;
4027 para = malloc(sizeof(*para));
4028 if (!para)
4029 return E_OUTOFMEMORY;
4031 para->ITextPara_iface.lpVtbl = &textparavtbl;
4032 para->ref = 1;
4033 para->range = range;
4034 ITextRange_AddRef(range);
4036 *ret = &para->ITextPara_iface;
4037 return S_OK;
4040 /* ITextDocument */
4041 static HRESULT WINAPI ITextDocument2Old_fnQueryInterface(ITextDocument2Old* iface, REFIID riid,
4042 void **ppvObject)
4044 struct text_services *services = impl_from_ITextDocument2Old(iface);
4045 return IUnknown_QueryInterface( services->outer_unk, riid, ppvObject );
4048 static ULONG WINAPI ITextDocument2Old_fnAddRef(ITextDocument2Old *iface)
4050 struct text_services *services = impl_from_ITextDocument2Old(iface);
4051 return IUnknown_AddRef( services->outer_unk );
4054 static ULONG WINAPI ITextDocument2Old_fnRelease(ITextDocument2Old *iface)
4056 struct text_services *services = impl_from_ITextDocument2Old(iface);
4057 return IUnknown_Release( services->outer_unk );
4060 static HRESULT WINAPI ITextDocument2Old_fnGetTypeInfoCount(ITextDocument2Old *iface,
4061 UINT *pctinfo)
4063 struct text_services *services = impl_from_ITextDocument2Old(iface);
4064 TRACE("(%p)->(%p)\n", services, pctinfo);
4065 *pctinfo = 1;
4066 return S_OK;
4069 static HRESULT WINAPI ITextDocument2Old_fnGetTypeInfo(ITextDocument2Old *iface, UINT iTInfo, LCID lcid,
4070 ITypeInfo **ppTInfo)
4072 struct text_services *services = impl_from_ITextDocument2Old(iface);
4073 HRESULT hr;
4075 TRACE("(%p)->(%u,%ld,%p)\n", services, iTInfo, lcid, ppTInfo);
4077 hr = get_typeinfo(ITextDocument_tid, ppTInfo);
4078 if (SUCCEEDED(hr))
4079 ITypeInfo_AddRef(*ppTInfo);
4080 return hr;
4083 static HRESULT WINAPI ITextDocument2Old_fnGetIDsOfNames(ITextDocument2Old *iface, REFIID riid,
4084 LPOLESTR *rgszNames, UINT cNames,
4085 LCID lcid, DISPID *rgDispId)
4087 struct text_services *services = impl_from_ITextDocument2Old(iface);
4088 ITypeInfo *ti;
4089 HRESULT hr;
4091 TRACE("(%p)->(%s, %p, %u, %ld, %p)\n", services, debugstr_guid(riid),
4092 rgszNames, cNames, lcid, rgDispId);
4094 hr = get_typeinfo(ITextDocument_tid, &ti);
4095 if (SUCCEEDED(hr))
4096 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
4097 return hr;
4100 static HRESULT WINAPI ITextDocument2Old_fnInvoke(ITextDocument2Old *iface, DISPID dispIdMember,
4101 REFIID riid, LCID lcid, WORD wFlags,
4102 DISPPARAMS *pDispParams, VARIANT *pVarResult,
4103 EXCEPINFO *pExcepInfo, UINT *puArgErr)
4105 struct text_services *services = impl_from_ITextDocument2Old(iface);
4106 ITypeInfo *ti;
4107 HRESULT hr;
4109 TRACE("(%p)->(%ld, %s, %ld, %u, %p, %p, %p, %p)\n", services, dispIdMember,
4110 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
4111 pExcepInfo, puArgErr);
4113 hr = get_typeinfo(ITextDocument_tid, &ti);
4114 if (SUCCEEDED(hr))
4115 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4116 return hr;
4119 static HRESULT WINAPI ITextDocument2Old_fnGetName(ITextDocument2Old *iface, BSTR *pName)
4121 struct text_services *services = impl_from_ITextDocument2Old(iface);
4122 FIXME("stub %p\n", services);
4123 return E_NOTIMPL;
4126 static HRESULT WINAPI ITextDocument2Old_fnGetSelection(ITextDocument2Old *iface, ITextSelection **selection)
4128 struct text_services *services = impl_from_ITextDocument2Old(iface);
4130 TRACE("(%p)->(%p)\n", iface, selection);
4132 if (!selection)
4133 return E_INVALIDARG;
4135 if (!services->text_selection)
4137 services->text_selection = text_selection_create( services );
4138 if (!services->text_selection)
4140 *selection = NULL;
4141 return E_OUTOFMEMORY;
4145 *selection = &services->text_selection->ITextSelection_iface;
4146 ITextSelection_AddRef(*selection);
4147 return S_OK;
4150 static HRESULT WINAPI ITextDocument2Old_fnGetStoryCount(ITextDocument2Old *iface, LONG *pCount)
4152 struct text_services *services = impl_from_ITextDocument2Old(iface);
4153 FIXME("stub %p\n", services);
4154 return E_NOTIMPL;
4157 static HRESULT WINAPI ITextDocument2Old_fnGetStoryRanges(ITextDocument2Old *iface,
4158 ITextStoryRanges **ppStories)
4160 struct text_services *services = impl_from_ITextDocument2Old(iface);
4161 FIXME("stub %p\n", services);
4162 return E_NOTIMPL;
4165 static HRESULT WINAPI ITextDocument2Old_fnGetSaved(ITextDocument2Old *iface, LONG *pValue)
4167 struct text_services *services = impl_from_ITextDocument2Old(iface);
4168 FIXME("stub %p\n", services);
4169 return E_NOTIMPL;
4172 static HRESULT WINAPI ITextDocument2Old_fnSetSaved(ITextDocument2Old *iface, LONG Value)
4174 struct text_services *services = impl_from_ITextDocument2Old(iface);
4175 FIXME("stub %p\n", services);
4176 return E_NOTIMPL;
4179 static HRESULT WINAPI ITextDocument2Old_fnGetDefaultTabStop(ITextDocument2Old *iface, float *pValue)
4181 struct text_services *services = impl_from_ITextDocument2Old(iface);
4182 FIXME("stub %p\n", services);
4183 return E_NOTIMPL;
4186 static HRESULT WINAPI ITextDocument2Old_fnSetDefaultTabStop(ITextDocument2Old *iface, float Value)
4188 struct text_services *services = impl_from_ITextDocument2Old(iface);
4189 FIXME("stub %p\n", services);
4190 return E_NOTIMPL;
4193 static HRESULT WINAPI ITextDocument2Old_fnNew(ITextDocument2Old *iface)
4195 struct text_services *services = impl_from_ITextDocument2Old(iface);
4196 FIXME("stub %p\n", services);
4197 return E_NOTIMPL;
4200 static HRESULT WINAPI ITextDocument2Old_fnOpen(ITextDocument2Old *iface, VARIANT *pVar,
4201 LONG Flags, LONG CodePage)
4203 struct text_services *services = impl_from_ITextDocument2Old(iface);
4204 FIXME("stub %p\n", services);
4205 return E_NOTIMPL;
4208 static HRESULT WINAPI ITextDocument2Old_fnSave(ITextDocument2Old *iface, VARIANT *pVar,
4209 LONG Flags, LONG CodePage)
4211 struct text_services *services = impl_from_ITextDocument2Old(iface);
4212 FIXME("stub %p\n", services);
4213 return E_NOTIMPL;
4216 static HRESULT WINAPI ITextDocument2Old_fnFreeze(ITextDocument2Old *iface, LONG *pCount)
4218 struct text_services *services = impl_from_ITextDocument2Old(iface);
4220 if (services->editor->freeze_count < LONG_MAX) services->editor->freeze_count++;
4222 if (pCount) *pCount = services->editor->freeze_count;
4223 return services->editor->freeze_count != 0 ? S_OK : S_FALSE;
4226 static HRESULT WINAPI ITextDocument2Old_fnUnfreeze(ITextDocument2Old *iface, LONG *pCount)
4228 struct text_services *services = impl_from_ITextDocument2Old(iface);
4230 if (services->editor->freeze_count && !--services->editor->freeze_count)
4231 ME_RewrapRepaint(services->editor);
4233 if (pCount) *pCount = services->editor->freeze_count;
4234 return services->editor->freeze_count == 0 ? S_OK : S_FALSE;
4237 static HRESULT WINAPI ITextDocument2Old_fnBeginEditCollection(ITextDocument2Old *iface)
4239 struct text_services *services = impl_from_ITextDocument2Old(iface);
4240 FIXME("stub %p\n", services);
4241 return E_NOTIMPL;
4244 static HRESULT WINAPI ITextDocument2Old_fnEndEditCollection(ITextDocument2Old *iface)
4246 struct text_services *services = impl_from_ITextDocument2Old(iface);
4247 FIXME("stub %p\n", services);
4248 return E_NOTIMPL;
4251 static HRESULT WINAPI ITextDocument2Old_fnUndo(ITextDocument2Old *iface, LONG Count, LONG *prop)
4253 struct text_services *services = impl_from_ITextDocument2Old(iface);
4254 LONG actual_undo_count;
4256 if (prop) *prop = 0;
4258 switch (Count)
4260 case tomFalse:
4261 editor_disable_undo(services->editor);
4262 return S_OK;
4263 default:
4264 if (Count > 0) break;
4265 /* fallthrough */
4266 case tomTrue:
4267 editor_enable_undo(services->editor);
4268 return S_FALSE;
4269 case tomSuspend:
4270 if (services->editor->undo_ctl_state == undoActive)
4272 services->editor->undo_ctl_state = undoSuspended;
4274 return S_FALSE;
4275 case tomResume:
4276 services->editor->undo_ctl_state = undoActive;
4277 return S_FALSE;
4280 for (actual_undo_count = 0; actual_undo_count < Count; actual_undo_count++)
4282 if (!ME_Undo(services->editor)) break;
4285 if (prop) *prop = actual_undo_count;
4286 return actual_undo_count == Count ? S_OK : S_FALSE;
4289 static HRESULT WINAPI ITextDocument2Old_fnRedo(ITextDocument2Old *iface, LONG Count, LONG *prop)
4291 struct text_services *services = impl_from_ITextDocument2Old(iface);
4292 LONG actual_redo_count;
4294 if (prop) *prop = 0;
4296 for (actual_redo_count = 0; actual_redo_count < Count; actual_redo_count++)
4298 if (!ME_Redo(services->editor)) break;
4301 if (prop) *prop = actual_redo_count;
4302 return actual_redo_count == Count ? S_OK : S_FALSE;
4305 static HRESULT CreateITextRange(struct text_services *services, LONG start, LONG end, ITextRange** ppRange)
4307 ITextRangeImpl *txtRge = malloc(sizeof(ITextRangeImpl));
4309 if (!txtRge)
4310 return E_OUTOFMEMORY;
4311 txtRge->ITextRange_iface.lpVtbl = &trvt;
4312 txtRge->ref = 1;
4313 txtRge->child.reole = services;
4314 txtRge->start = start;
4315 txtRge->end = end;
4316 list_add_head( &services->rangelist, &txtRge->child.entry );
4317 *ppRange = &txtRge->ITextRange_iface;
4318 return S_OK;
4321 static HRESULT WINAPI ITextDocument2Old_fnRange(ITextDocument2Old *iface, LONG cp1, LONG cp2,
4322 ITextRange **ppRange)
4324 struct text_services *services = impl_from_ITextDocument2Old(iface);
4326 TRACE("%p %p %ld %ld\n", services, ppRange, cp1, cp2);
4327 if (!ppRange)
4328 return E_INVALIDARG;
4330 cp2range(services->editor, &cp1, &cp2);
4331 return CreateITextRange(services, cp1, cp2, ppRange);
4334 static HRESULT WINAPI ITextDocument2Old_fnRangeFromPoint(ITextDocument2Old *iface, LONG x, LONG y,
4335 ITextRange **ppRange)
4337 struct text_services *services = impl_from_ITextDocument2Old(iface);
4338 FIXME("stub %p\n", services);
4339 return E_NOTIMPL;
4342 /* ITextDocument2Old methods */
4343 static HRESULT WINAPI ITextDocument2Old_fnAttachMsgFilter(ITextDocument2Old *iface, IUnknown *filter)
4345 struct text_services *services = impl_from_ITextDocument2Old(iface);
4347 FIXME("(%p)->(%p): stub\n", services, filter);
4349 return E_NOTIMPL;
4352 static HRESULT WINAPI ITextDocument2Old_fnSetEffectColor(ITextDocument2Old *iface, LONG index, COLORREF cr)
4354 struct text_services *services = impl_from_ITextDocument2Old(iface);
4356 FIXME("(%p)->(%ld, 0x%lx): stub\n", services, index, cr);
4358 return E_NOTIMPL;
4361 static HRESULT WINAPI ITextDocument2Old_fnGetEffectColor(ITextDocument2Old *iface, LONG index, COLORREF *cr)
4363 struct text_services *services = impl_from_ITextDocument2Old(iface);
4365 FIXME("(%p)->(%ld, %p): stub\n", services, index, cr);
4367 return E_NOTIMPL;
4370 static HRESULT WINAPI ITextDocument2Old_fnGetCaretType(ITextDocument2Old *iface, LONG *type)
4372 struct text_services *services = impl_from_ITextDocument2Old(iface);
4374 FIXME("(%p)->(%p): stub\n", services, type);
4376 return E_NOTIMPL;
4379 static HRESULT WINAPI ITextDocument2Old_fnSetCaretType(ITextDocument2Old *iface, LONG type)
4381 struct text_services *services = impl_from_ITextDocument2Old(iface);
4383 FIXME("(%p)->(%ld): stub\n", services, type);
4385 return E_NOTIMPL;
4388 static HRESULT WINAPI ITextDocument2Old_fnGetImmContext(ITextDocument2Old *iface, LONG *context)
4390 struct text_services *services = impl_from_ITextDocument2Old(iface);
4392 FIXME("(%p)->(%p): stub\n", services, context);
4394 return E_NOTIMPL;
4397 static HRESULT WINAPI ITextDocument2Old_fnReleaseImmContext(ITextDocument2Old *iface, LONG context)
4399 struct text_services *services = impl_from_ITextDocument2Old(iface);
4401 FIXME("(%p)->(%ld): stub\n", services, context);
4403 return E_NOTIMPL;
4406 static HRESULT WINAPI ITextDocument2Old_fnGetPreferredFont(ITextDocument2Old *iface, LONG cp, LONG charrep,
4407 LONG options, LONG current_charrep, LONG current_fontsize,
4408 BSTR *bstr, LONG *pitch_family, LONG *new_fontsize)
4410 struct text_services *services = impl_from_ITextDocument2Old(iface);
4412 FIXME("(%p)->(%ld, %ld, %ld, %ld, %ld, %p, %p, %p): stub\n", services, cp, charrep, options, current_charrep,
4413 current_fontsize, bstr, pitch_family, new_fontsize);
4415 return E_NOTIMPL;
4418 static HRESULT WINAPI ITextDocument2Old_fnGetNotificationMode(ITextDocument2Old *iface, LONG *mode)
4420 struct text_services *services = impl_from_ITextDocument2Old(iface);
4422 FIXME("(%p)->(%p): stub\n", services, mode);
4424 return E_NOTIMPL;
4427 static HRESULT WINAPI ITextDocument2Old_fnSetNotificationMode(ITextDocument2Old *iface, LONG mode)
4429 struct text_services *services = impl_from_ITextDocument2Old(iface);
4431 FIXME("(%p)->(0x%lx): stub\n", services, mode);
4433 return E_NOTIMPL;
4436 static HRESULT WINAPI ITextDocument2Old_fnGetClientRect(ITextDocument2Old *iface, LONG type, LONG *left, LONG *top,
4437 LONG *right, LONG *bottom)
4439 struct text_services *services = impl_from_ITextDocument2Old(iface);
4441 FIXME("(%p)->(%ld, %p, %p, %p, %p): stub\n", services, type, left, top, right, bottom);
4443 return E_NOTIMPL;
4446 static HRESULT WINAPI ITextDocument2Old_fnGetSelectionEx(ITextDocument2Old *iface, ITextSelection **selection)
4448 struct text_services *services = impl_from_ITextDocument2Old(iface);
4450 FIXME("(%p)->(%p): stub\n", services, selection);
4452 return E_NOTIMPL;
4455 static HRESULT WINAPI ITextDocument2Old_fnGetWindow(ITextDocument2Old *iface, LONG *hwnd)
4457 struct text_services *services = impl_from_ITextDocument2Old(iface);
4459 FIXME("(%p)->(%p): stub\n", services, hwnd);
4461 return E_NOTIMPL;
4464 static HRESULT WINAPI ITextDocument2Old_fnGetFEFlags(ITextDocument2Old *iface, LONG *flags)
4466 struct text_services *services = impl_from_ITextDocument2Old(iface);
4468 FIXME("(%p)->(%p): stub\n", services, flags);
4470 return E_NOTIMPL;
4473 static HRESULT WINAPI ITextDocument2Old_fnUpdateWindow(ITextDocument2Old *iface)
4475 struct text_services *services = impl_from_ITextDocument2Old(iface);
4477 FIXME("(%p): stub\n", services);
4479 return E_NOTIMPL;
4482 static HRESULT WINAPI ITextDocument2Old_fnCheckTextLimit(ITextDocument2Old *iface, LONG cch, LONG *exceed)
4484 struct text_services *services = impl_from_ITextDocument2Old(iface);
4486 FIXME("(%p)->(%ld, %p): stub\n", services, cch, exceed);
4488 return E_NOTIMPL;
4491 static HRESULT WINAPI ITextDocument2Old_fnIMEInProgress(ITextDocument2Old *iface, LONG mode)
4493 struct text_services *services = impl_from_ITextDocument2Old(iface);
4495 FIXME("(%p)->(0x%lx): stub\n", services, mode);
4497 return E_NOTIMPL;
4500 static HRESULT WINAPI ITextDocument2Old_fnSysBeep(ITextDocument2Old *iface)
4502 struct text_services *services = impl_from_ITextDocument2Old(iface);
4504 FIXME("(%p): stub\n", services);
4506 return E_NOTIMPL;
4509 static HRESULT WINAPI ITextDocument2Old_fnUpdate(ITextDocument2Old *iface, LONG mode)
4511 struct text_services *services = impl_from_ITextDocument2Old(iface);
4513 FIXME("(%p)->(0x%lx): stub\n", services, mode);
4515 return E_NOTIMPL;
4518 static HRESULT WINAPI ITextDocument2Old_fnNotify(ITextDocument2Old *iface, LONG notify)
4520 struct text_services *services = impl_from_ITextDocument2Old(iface);
4522 FIXME("(%p)->(%ld): stub\n", services, notify);
4524 return E_NOTIMPL;
4527 const ITextDocument2OldVtbl text_doc2old_vtbl =
4529 ITextDocument2Old_fnQueryInterface,
4530 ITextDocument2Old_fnAddRef,
4531 ITextDocument2Old_fnRelease,
4532 ITextDocument2Old_fnGetTypeInfoCount,
4533 ITextDocument2Old_fnGetTypeInfo,
4534 ITextDocument2Old_fnGetIDsOfNames,
4535 ITextDocument2Old_fnInvoke,
4536 ITextDocument2Old_fnGetName,
4537 ITextDocument2Old_fnGetSelection,
4538 ITextDocument2Old_fnGetStoryCount,
4539 ITextDocument2Old_fnGetStoryRanges,
4540 ITextDocument2Old_fnGetSaved,
4541 ITextDocument2Old_fnSetSaved,
4542 ITextDocument2Old_fnGetDefaultTabStop,
4543 ITextDocument2Old_fnSetDefaultTabStop,
4544 ITextDocument2Old_fnNew,
4545 ITextDocument2Old_fnOpen,
4546 ITextDocument2Old_fnSave,
4547 ITextDocument2Old_fnFreeze,
4548 ITextDocument2Old_fnUnfreeze,
4549 ITextDocument2Old_fnBeginEditCollection,
4550 ITextDocument2Old_fnEndEditCollection,
4551 ITextDocument2Old_fnUndo,
4552 ITextDocument2Old_fnRedo,
4553 ITextDocument2Old_fnRange,
4554 ITextDocument2Old_fnRangeFromPoint,
4555 /* ITextDocument2Old methods */
4556 ITextDocument2Old_fnAttachMsgFilter,
4557 ITextDocument2Old_fnSetEffectColor,
4558 ITextDocument2Old_fnGetEffectColor,
4559 ITextDocument2Old_fnGetCaretType,
4560 ITextDocument2Old_fnSetCaretType,
4561 ITextDocument2Old_fnGetImmContext,
4562 ITextDocument2Old_fnReleaseImmContext,
4563 ITextDocument2Old_fnGetPreferredFont,
4564 ITextDocument2Old_fnGetNotificationMode,
4565 ITextDocument2Old_fnSetNotificationMode,
4566 ITextDocument2Old_fnGetClientRect,
4567 ITextDocument2Old_fnGetSelectionEx,
4568 ITextDocument2Old_fnGetWindow,
4569 ITextDocument2Old_fnGetFEFlags,
4570 ITextDocument2Old_fnUpdateWindow,
4571 ITextDocument2Old_fnCheckTextLimit,
4572 ITextDocument2Old_fnIMEInProgress,
4573 ITextDocument2Old_fnSysBeep,
4574 ITextDocument2Old_fnUpdate,
4575 ITextDocument2Old_fnNotify
4578 /* ITextSelection */
4579 static HRESULT WINAPI ITextSelection_fnQueryInterface(
4580 ITextSelection *me,
4581 REFIID riid,
4582 void **ppvObj)
4584 struct text_selection *This = impl_from_ITextSelection(me);
4586 *ppvObj = NULL;
4587 if (IsEqualGUID(riid, &IID_IUnknown)
4588 || IsEqualGUID(riid, &IID_IDispatch)
4589 || IsEqualGUID(riid, &IID_ITextRange)
4590 || IsEqualGUID(riid, &IID_ITextSelection))
4592 *ppvObj = me;
4593 ITextSelection_AddRef(me);
4594 return S_OK;
4596 else if (IsEqualGUID(riid, &IID_Igetrichole))
4598 *ppvObj = This->services;
4599 return S_OK;
4602 return E_NOINTERFACE;
4605 static ULONG WINAPI ITextSelection_fnAddRef(ITextSelection *me)
4607 struct text_selection *This = impl_from_ITextSelection(me);
4608 return InterlockedIncrement(&This->ref);
4611 static ULONG WINAPI ITextSelection_fnRelease(ITextSelection *me)
4613 struct text_selection *This = impl_from_ITextSelection(me);
4614 ULONG ref = InterlockedDecrement(&This->ref);
4615 if (ref == 0)
4616 free(This);
4617 return ref;
4620 static HRESULT WINAPI ITextSelection_fnGetTypeInfoCount(ITextSelection *me, UINT *pctinfo)
4622 struct text_selection *This = impl_from_ITextSelection(me);
4623 TRACE("(%p)->(%p)\n", This, pctinfo);
4624 *pctinfo = 1;
4625 return S_OK;
4628 static HRESULT WINAPI ITextSelection_fnGetTypeInfo(ITextSelection *me, UINT iTInfo, LCID lcid,
4629 ITypeInfo **ppTInfo)
4631 struct text_selection *This = impl_from_ITextSelection(me);
4632 HRESULT hr;
4634 TRACE("(%p)->(%u,%ld,%p)\n", This, iTInfo, lcid, ppTInfo);
4636 hr = get_typeinfo(ITextSelection_tid, ppTInfo);
4637 if (SUCCEEDED(hr))
4638 ITypeInfo_AddRef(*ppTInfo);
4639 return hr;
4642 static HRESULT WINAPI ITextSelection_fnGetIDsOfNames(ITextSelection *me, REFIID riid,
4643 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
4645 struct text_selection *This = impl_from_ITextSelection(me);
4646 ITypeInfo *ti;
4647 HRESULT hr;
4649 TRACE("(%p)->(%s, %p, %u, %ld, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
4650 rgDispId);
4652 hr = get_typeinfo(ITextSelection_tid, &ti);
4653 if (SUCCEEDED(hr))
4654 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
4655 return hr;
4658 static HRESULT WINAPI ITextSelection_fnInvoke(
4659 ITextSelection *me,
4660 DISPID dispIdMember,
4661 REFIID riid,
4662 LCID lcid,
4663 WORD wFlags,
4664 DISPPARAMS *pDispParams,
4665 VARIANT *pVarResult,
4666 EXCEPINFO *pExcepInfo,
4667 UINT *puArgErr)
4669 struct text_selection *This = impl_from_ITextSelection(me);
4670 ITypeInfo *ti;
4671 HRESULT hr;
4673 TRACE("(%p)->(%ld, %s, %ld, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid), lcid,
4674 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4676 hr = get_typeinfo(ITextSelection_tid, &ti);
4677 if (SUCCEEDED(hr))
4678 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4679 return hr;
4682 /*** ITextRange methods ***/
4683 static HRESULT WINAPI ITextSelection_fnGetText(ITextSelection *me, BSTR *pbstr)
4685 struct text_selection *This = impl_from_ITextSelection(me);
4686 ME_Cursor *start = NULL, *end = NULL;
4687 int nChars, endOfs;
4688 BOOL bEOP;
4690 TRACE("(%p)->(%p)\n", This, pbstr);
4692 if (!This->services)
4693 return CO_E_RELEASED;
4695 if (!pbstr)
4696 return E_INVALIDARG;
4698 ME_GetSelection(This->services->editor, &start, &end);
4699 endOfs = ME_GetCursorOfs(end);
4700 nChars = endOfs - ME_GetCursorOfs(start);
4701 if (!nChars)
4703 *pbstr = NULL;
4704 return S_OK;
4707 *pbstr = SysAllocStringLen(NULL, nChars);
4708 if (!*pbstr)
4709 return E_OUTOFMEMORY;
4711 bEOP = (!para_next( para_next( end->para ) ) && endOfs > ME_GetTextLength(This->services->editor));
4712 ME_GetTextW(This->services->editor, *pbstr, nChars, start, nChars, FALSE, bEOP);
4713 TRACE("%s\n", wine_dbgstr_w(*pbstr));
4715 return S_OK;
4718 static HRESULT WINAPI ITextSelection_fnSetText(ITextSelection *me, BSTR str)
4720 struct text_selection *This = impl_from_ITextSelection(me);
4721 ME_TextEditor *editor;
4722 int len;
4723 LONG to, from;
4725 TRACE("(%p)->(%s)\n", This, debugstr_w(str));
4727 if (!This->services)
4728 return CO_E_RELEASED;
4730 editor = This->services->editor;
4731 len = lstrlenW(str);
4732 ME_GetSelectionOfs(editor, &from, &to);
4733 ME_ReplaceSel(editor, FALSE, str, len);
4735 if (len < to - from)
4736 textranges_update_ranges(This->services, from, len, RANGE_UPDATE_DELETE);
4738 return S_OK;
4741 static HRESULT WINAPI ITextSelection_fnGetChar(ITextSelection *me, LONG *pch)
4743 struct text_selection *This = impl_from_ITextSelection(me);
4744 ME_Cursor *start = NULL, *end = NULL;
4746 TRACE("(%p)->(%p)\n", This, pch);
4748 if (!This->services)
4749 return CO_E_RELEASED;
4751 if (!pch)
4752 return E_INVALIDARG;
4754 ME_GetSelection(This->services->editor, &start, &end);
4755 return range_GetChar(This->services->editor, start, pch);
4758 static HRESULT WINAPI ITextSelection_fnSetChar(ITextSelection *me, LONG ch)
4760 struct text_selection *This = impl_from_ITextSelection(me);
4762 FIXME("(%p)->(%lx): stub\n", This, ch);
4764 if (!This->services)
4765 return CO_E_RELEASED;
4767 return E_NOTIMPL;
4770 static HRESULT WINAPI ITextSelection_fnGetDuplicate(ITextSelection *me, ITextRange **range)
4772 struct text_selection *This = impl_from_ITextSelection(me);
4773 LONG start, end;
4775 TRACE("(%p)->(%p)\n", This, range);
4777 if (!This->services)
4778 return CO_E_RELEASED;
4780 if (!range)
4781 return E_INVALIDARG;
4783 ITextSelection_GetStart(me, &start);
4784 ITextSelection_GetEnd(me, &end);
4785 return CreateITextRange(This->services, start, end, range);
4788 static HRESULT WINAPI ITextSelection_fnGetFormattedText(ITextSelection *me, ITextRange **range)
4790 struct text_selection *This = impl_from_ITextSelection(me);
4792 FIXME("(%p)->(%p): stub\n", This, range);
4794 if (!This->services)
4795 return CO_E_RELEASED;
4797 return E_NOTIMPL;
4800 static HRESULT WINAPI ITextSelection_fnSetFormattedText(ITextSelection *me, ITextRange *range)
4802 struct text_selection *This = impl_from_ITextSelection(me);
4804 FIXME("(%p)->(%p): stub\n", This, range);
4806 if (!This->services)
4807 return CO_E_RELEASED;
4809 FIXME("not implemented\n");
4810 return E_NOTIMPL;
4813 static HRESULT WINAPI ITextSelection_fnGetStart(ITextSelection *me, LONG *pcpFirst)
4815 struct text_selection *This = impl_from_ITextSelection(me);
4816 LONG lim;
4818 TRACE("(%p)->(%p)\n", This, pcpFirst);
4820 if (!This->services)
4821 return CO_E_RELEASED;
4823 if (!pcpFirst)
4824 return E_INVALIDARG;
4825 ME_GetSelectionOfs(This->services->editor, pcpFirst, &lim);
4826 return S_OK;
4829 static HRESULT WINAPI ITextSelection_fnSetStart(ITextSelection *me, LONG value)
4831 struct text_selection *This = impl_from_ITextSelection(me);
4832 LONG start, end;
4833 HRESULT hr;
4835 TRACE("(%p)->(%ld)\n", This, value);
4837 if (!This->services)
4838 return CO_E_RELEASED;
4840 ME_GetSelectionOfs(This->services->editor, &start, &end);
4841 hr = textrange_setstart(This->services, value, &start, &end);
4842 if (hr == S_OK)
4843 set_selection(This->services->editor, start, end);
4845 return hr;
4848 static HRESULT WINAPI ITextSelection_fnGetEnd(ITextSelection *me, LONG *pcpLim)
4850 struct text_selection *This = impl_from_ITextSelection(me);
4851 LONG first;
4853 TRACE("(%p)->(%p)\n", This, pcpLim);
4855 if (!This->services)
4856 return CO_E_RELEASED;
4858 if (!pcpLim)
4859 return E_INVALIDARG;
4860 ME_GetSelectionOfs(This->services->editor, &first, pcpLim);
4861 return S_OK;
4864 static HRESULT WINAPI ITextSelection_fnSetEnd(ITextSelection *me, LONG value)
4866 struct text_selection *This = impl_from_ITextSelection(me);
4867 LONG start, end;
4868 HRESULT hr;
4870 TRACE("(%p)->(%ld)\n", This, value);
4872 if (!This->services)
4873 return CO_E_RELEASED;
4875 ME_GetSelectionOfs(This->services->editor, &start, &end);
4876 hr = textrange_setend(This->services, value, &start, &end);
4877 if (hr == S_OK)
4878 set_selection(This->services->editor, start, end);
4880 return hr;
4883 static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **font)
4885 struct text_selection *This = impl_from_ITextSelection(me);
4886 ITextRange *range = NULL;
4887 HRESULT hr;
4889 TRACE("(%p)->(%p)\n", This, font);
4891 if (!This->services)
4892 return CO_E_RELEASED;
4894 if (!font)
4895 return E_INVALIDARG;
4897 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
4898 hr = create_textfont(range, NULL, font);
4899 ITextRange_Release(range);
4900 return hr;
4903 static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *font)
4905 struct text_selection *This = impl_from_ITextSelection(me);
4906 ITextRange *range = NULL;
4908 TRACE("(%p)->(%p)\n", This, font);
4910 if (!font)
4911 return E_INVALIDARG;
4913 if (!This->services)
4914 return CO_E_RELEASED;
4916 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
4917 textrange_set_font(range, font);
4918 ITextRange_Release(range);
4919 return S_OK;
4922 static HRESULT WINAPI ITextSelection_fnGetPara(ITextSelection *me, ITextPara **para)
4924 struct text_selection *This = impl_from_ITextSelection(me);
4925 ITextRange *range = NULL;
4926 HRESULT hr;
4928 TRACE("(%p)->(%p)\n", This, para);
4930 if (!This->services)
4931 return CO_E_RELEASED;
4933 if (!para)
4934 return E_INVALIDARG;
4936 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
4937 hr = create_textpara(range, para);
4938 ITextRange_Release(range);
4939 return hr;
4942 static HRESULT WINAPI ITextSelection_fnSetPara(ITextSelection *me, ITextPara *para)
4944 struct text_selection *This = impl_from_ITextSelection(me);
4946 FIXME("(%p)->(%p): stub\n", This, para);
4948 if (!This->services)
4949 return CO_E_RELEASED;
4951 FIXME("not implemented\n");
4952 return E_NOTIMPL;
4955 static HRESULT WINAPI ITextSelection_fnGetStoryLength(ITextSelection *me, LONG *length)
4957 struct text_selection *This = impl_from_ITextSelection(me);
4959 TRACE("(%p)->(%p)\n", This, length);
4961 if (!This->services)
4962 return CO_E_RELEASED;
4964 return textrange_get_storylength(This->services->editor, length);
4967 static HRESULT WINAPI ITextSelection_fnGetStoryType(ITextSelection *me, LONG *value)
4969 struct text_selection *This = impl_from_ITextSelection(me);
4971 TRACE("(%p)->(%p)\n", This, value);
4973 if (!This->services)
4974 return CO_E_RELEASED;
4976 if (!value)
4977 return E_INVALIDARG;
4979 *value = tomUnknownStory;
4980 return S_OK;
4983 static HRESULT WINAPI ITextSelection_fnCollapse(ITextSelection *me, LONG bStart)
4985 struct text_selection *This = impl_from_ITextSelection(me);
4986 LONG start, end;
4987 HRESULT hres;
4989 TRACE("(%p)->(%ld)\n", This, bStart);
4991 if (!This->services)
4992 return CO_E_RELEASED;
4994 ME_GetSelectionOfs(This->services->editor, &start, &end);
4995 hres = range_Collapse(bStart, &start, &end);
4996 if (SUCCEEDED(hres))
4997 set_selection(This->services->editor, start, end);
4998 return hres;
5001 static HRESULT WINAPI ITextSelection_fnExpand(ITextSelection *me, LONG unit, LONG *delta)
5003 struct text_selection *This = impl_from_ITextSelection(me);
5004 ITextRange *range = NULL;
5005 HRESULT hr;
5007 TRACE("(%p)->(%ld %p)\n", This, unit, delta);
5009 if (!This->services)
5010 return CO_E_RELEASED;
5012 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5013 hr = textrange_expand(range, unit, delta);
5014 ITextRange_Release(range);
5015 return hr;
5018 static HRESULT WINAPI ITextSelection_fnGetIndex(ITextSelection *me, LONG unit, LONG *index)
5020 struct text_selection *This = impl_from_ITextSelection(me);
5022 FIXME("(%p)->(%ld %p): stub\n", This, unit, index);
5024 if (!This->services)
5025 return CO_E_RELEASED;
5027 return E_NOTIMPL;
5030 static HRESULT WINAPI ITextSelection_fnSetIndex(ITextSelection *me, LONG unit, LONG index,
5031 LONG extend)
5033 struct text_selection *This = impl_from_ITextSelection(me);
5035 FIXME("(%p)->(%ld %ld %ld): stub\n", This, unit, index, extend);
5037 if (!This->services)
5038 return CO_E_RELEASED;
5040 return E_NOTIMPL;
5043 static HRESULT WINAPI ITextSelection_fnSetRange(ITextSelection *me, LONG anchor, LONG active)
5045 struct text_selection *This = impl_from_ITextSelection(me);
5047 FIXME("(%p)->(%ld %ld): stub\n", This, anchor, active);
5049 if (!This->services)
5050 return CO_E_RELEASED;
5052 return E_NOTIMPL;
5055 static HRESULT WINAPI ITextSelection_fnInRange(ITextSelection *me, ITextRange *range, LONG *ret)
5057 struct text_selection *This = impl_from_ITextSelection(me);
5058 ITextSelection *selection = NULL;
5059 LONG start, end;
5061 TRACE("(%p)->(%p %p)\n", This, range, ret);
5063 if (ret)
5064 *ret = tomFalse;
5066 if (!This->services)
5067 return CO_E_RELEASED;
5069 if (!range)
5070 return S_FALSE;
5072 ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection);
5073 if (!selection)
5074 return S_FALSE;
5075 ITextSelection_Release(selection);
5077 ITextSelection_GetStart(me, &start);
5078 ITextSelection_GetEnd(me, &end);
5079 return textrange_inrange(start, end, range, ret);
5082 static HRESULT WINAPI ITextSelection_fnInStory(ITextSelection *me, ITextRange *range, LONG *ret)
5084 struct text_selection *This = impl_from_ITextSelection(me);
5086 FIXME("(%p)->(%p %p): stub\n", This, range, ret);
5088 if (!This->services)
5089 return CO_E_RELEASED;
5091 return E_NOTIMPL;
5094 static HRESULT WINAPI ITextSelection_fnIsEqual(ITextSelection *me, ITextRange *range, LONG *ret)
5096 struct text_selection *This = impl_from_ITextSelection(me);
5097 ITextSelection *selection = NULL;
5098 LONG start, end;
5100 TRACE("(%p)->(%p %p)\n", This, range, ret);
5102 if (ret)
5103 *ret = tomFalse;
5105 if (!This->services)
5106 return CO_E_RELEASED;
5108 if (!range)
5109 return S_FALSE;
5111 ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection);
5112 if (!selection)
5113 return S_FALSE;
5114 ITextSelection_Release(selection);
5116 ITextSelection_GetStart(me, &start);
5117 ITextSelection_GetEnd(me, &end);
5118 return textrange_isequal(start, end, range, ret);
5121 static HRESULT WINAPI ITextSelection_fnSelect(ITextSelection *me)
5123 struct text_selection *This = impl_from_ITextSelection(me);
5125 TRACE("(%p)\n", This);
5127 if (!This->services)
5128 return CO_E_RELEASED;
5130 /* nothing to do */
5131 return S_OK;
5134 static HRESULT WINAPI ITextSelection_fnStartOf(ITextSelection *me, LONG unit, LONG extend,
5135 LONG *delta)
5137 struct text_selection *This = impl_from_ITextSelection(me);
5138 ITextRange *range = NULL;
5139 HRESULT hr;
5141 TRACE("(%p)->(%ld %ld %p)\n", This, unit, extend, delta);
5143 if (!This->services)
5144 return CO_E_RELEASED;
5146 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5147 hr = textrange_startof(range, unit, extend, delta);
5148 ITextRange_Release(range);
5149 return hr;
5152 static HRESULT WINAPI ITextSelection_fnEndOf(ITextSelection *me, LONG unit, LONG extend,
5153 LONG *delta)
5155 struct text_selection *This = impl_from_ITextSelection(me);
5156 ITextRange *range = NULL;
5157 HRESULT hr;
5159 TRACE("(%p)->(%ld %ld %p)\n", This, unit, extend, delta);
5161 if (!This->services)
5162 return CO_E_RELEASED;
5164 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5165 hr = textrange_endof(range, This->services->editor, unit, extend, delta);
5166 ITextRange_Release(range);
5167 return hr;
5170 static HRESULT WINAPI ITextSelection_fnMove(ITextSelection *me, LONG unit, LONG count, LONG *delta)
5172 struct text_selection *This = impl_from_ITextSelection(me);
5173 ITextRange *range = NULL;
5174 HRESULT hr;
5176 TRACE("(%p)->(%ld %ld %p)\n", This, unit, count, delta);
5178 if (!This->services)
5179 return CO_E_RELEASED;
5181 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5182 hr = textrange_movestart(range, This->services->editor, unit, count, delta);
5183 ITextRange_Release(range);
5184 return hr;
5187 static HRESULT WINAPI ITextSelection_fnMoveStart(ITextSelection *me, LONG unit, LONG count,
5188 LONG *delta)
5190 struct text_selection *This = impl_from_ITextSelection(me);
5191 ITextRange *range = NULL;
5192 HRESULT hr;
5194 TRACE("(%p)->(%ld %ld %p)\n", This, unit, count, delta);
5196 if (!This->services)
5197 return CO_E_RELEASED;
5199 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5200 hr = textrange_movestart(range, This->services->editor, unit, count, delta);
5201 ITextRange_Release(range);
5202 return hr;
5205 static HRESULT WINAPI ITextSelection_fnMoveEnd(ITextSelection *me, LONG unit, LONG count,
5206 LONG *delta)
5208 struct text_selection *This = impl_from_ITextSelection(me);
5209 ITextRange *range = NULL;
5210 HRESULT hr;
5212 TRACE("(%p)->(%ld %ld %p)\n", This, unit, count, delta);
5214 if (!This->services)
5215 return CO_E_RELEASED;
5217 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5218 hr = textrange_moveend(range, This->services->editor, unit, count, delta);
5219 ITextRange_Release(range);
5220 return hr;
5223 static HRESULT WINAPI ITextSelection_fnMoveWhile(ITextSelection *me, VARIANT *charset, LONG count,
5224 LONG *delta)
5226 struct text_selection *This = impl_from_ITextSelection(me);
5228 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
5230 if (!This->services)
5231 return CO_E_RELEASED;
5233 return E_NOTIMPL;
5236 static HRESULT WINAPI ITextSelection_fnMoveStartWhile(ITextSelection *me, VARIANT *charset, LONG count,
5237 LONG *delta)
5239 struct text_selection *This = impl_from_ITextSelection(me);
5241 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
5243 if (!This->services)
5244 return CO_E_RELEASED;
5246 return E_NOTIMPL;
5249 static HRESULT WINAPI ITextSelection_fnMoveEndWhile(ITextSelection *me, VARIANT *charset, LONG count,
5250 LONG *delta)
5252 struct text_selection *This = impl_from_ITextSelection(me);
5254 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
5256 if (!This->services)
5257 return CO_E_RELEASED;
5259 return E_NOTIMPL;
5262 static HRESULT WINAPI ITextSelection_fnMoveUntil(ITextSelection *me, VARIANT *charset, LONG count,
5263 LONG *delta)
5265 struct text_selection *This = impl_from_ITextSelection(me);
5267 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
5269 if (!This->services)
5270 return CO_E_RELEASED;
5272 return E_NOTIMPL;
5275 static HRESULT WINAPI ITextSelection_fnMoveStartUntil(ITextSelection *me, VARIANT *charset, LONG count,
5276 LONG *delta)
5278 struct text_selection *This = impl_from_ITextSelection(me);
5280 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
5282 if (!This->services)
5283 return CO_E_RELEASED;
5285 return E_NOTIMPL;
5288 static HRESULT WINAPI ITextSelection_fnMoveEndUntil(ITextSelection *me, VARIANT *charset, LONG count,
5289 LONG *delta)
5291 struct text_selection *This = impl_from_ITextSelection(me);
5293 FIXME("(%p)->(%s %ld %p): stub\n", This, debugstr_variant(charset), count, delta);
5295 if (!This->services)
5296 return CO_E_RELEASED;
5298 return E_NOTIMPL;
5301 static HRESULT WINAPI ITextSelection_fnFindText(ITextSelection *me, BSTR text, LONG count, LONG flags,
5302 LONG *length)
5304 struct text_selection *This = impl_from_ITextSelection(me);
5306 FIXME("(%p)->(%s %ld %lx %p): stub\n", This, debugstr_w(text), count, flags, length);
5308 if (!This->services)
5309 return CO_E_RELEASED;
5311 FIXME("not implemented\n");
5312 return E_NOTIMPL;
5315 static HRESULT WINAPI ITextSelection_fnFindTextStart(ITextSelection *me, BSTR text, LONG count,
5316 LONG flags, LONG *length)
5318 struct text_selection *This = impl_from_ITextSelection(me);
5320 FIXME("(%p)->(%s %ld %lx %p): stub\n", This, debugstr_w(text), count, flags, length);
5322 if (!This->services)
5323 return CO_E_RELEASED;
5325 return E_NOTIMPL;
5328 static HRESULT WINAPI ITextSelection_fnFindTextEnd(ITextSelection *me, BSTR text, LONG count,
5329 LONG flags, LONG *length)
5331 struct text_selection *This = impl_from_ITextSelection(me);
5333 FIXME("(%p)->(%s %ld %lx %p): stub\n", This, debugstr_w(text), count, flags, length);
5335 if (!This->services)
5336 return CO_E_RELEASED;
5338 return E_NOTIMPL;
5341 static HRESULT WINAPI ITextSelection_fnDelete(ITextSelection *me, LONG unit, LONG count,
5342 LONG *delta)
5344 struct text_selection *This = impl_from_ITextSelection(me);
5346 FIXME("(%p)->(%ld %ld %p): stub\n", This, unit, count, delta);
5348 if (!This->services)
5349 return CO_E_RELEASED;
5351 return E_NOTIMPL;
5354 static HRESULT WINAPI ITextSelection_fnCut(ITextSelection *me, VARIANT *v)
5356 struct text_selection *This = impl_from_ITextSelection(me);
5357 ITextRange *range = NULL;
5358 HRESULT hr;
5360 TRACE("(%p)->(%p): stub\n", This, v);
5362 if (!This->services)
5363 return CO_E_RELEASED;
5365 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5366 hr = textrange_copy_or_cut(range, This->services->editor, TRUE, v);
5367 ITextRange_Release(range);
5368 return hr;
5371 static HRESULT WINAPI ITextSelection_fnCopy(ITextSelection *me, VARIANT *v)
5373 struct text_selection *This = impl_from_ITextSelection(me);
5374 ITextRange *range = NULL;
5375 HRESULT hr;
5377 TRACE("(%p)->(%p)\n", This, v);
5379 if (!This->services)
5380 return CO_E_RELEASED;
5382 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
5383 hr = textrange_copy_or_cut(range, This->services->editor, FALSE, v);
5384 ITextRange_Release(range);
5385 return hr;
5388 static HRESULT WINAPI ITextSelection_fnPaste(ITextSelection *me, VARIANT *v, LONG format)
5390 struct text_selection *This = impl_from_ITextSelection(me);
5392 FIXME("(%p)->(%s %lx): stub\n", This, debugstr_variant(v), format);
5394 if (!This->services)
5395 return CO_E_RELEASED;
5397 return E_NOTIMPL;
5400 static HRESULT WINAPI ITextSelection_fnCanPaste(ITextSelection *me, VARIANT *v, LONG format,
5401 LONG *ret)
5403 struct text_selection *This = impl_from_ITextSelection(me);
5405 FIXME("(%p)->(%s %lx %p): stub\n", This, debugstr_variant(v), format, ret);
5407 if (!This->services)
5408 return CO_E_RELEASED;
5410 return E_NOTIMPL;
5413 static HRESULT WINAPI ITextSelection_fnCanEdit(ITextSelection *me, LONG *ret)
5415 struct text_selection *This = impl_from_ITextSelection(me);
5417 FIXME("(%p)->(%p): stub\n", This, ret);
5419 if (!This->services)
5420 return CO_E_RELEASED;
5422 return E_NOTIMPL;
5425 static HRESULT WINAPI ITextSelection_fnChangeCase(ITextSelection *me, LONG type)
5427 struct text_selection *This = impl_from_ITextSelection(me);
5429 FIXME("(%p)->(%ld): stub\n", This, type);
5431 if (!This->services)
5432 return CO_E_RELEASED;
5434 return E_NOTIMPL;
5437 static HRESULT WINAPI ITextSelection_fnGetPoint(ITextSelection *me, LONG type, LONG *cx, LONG *cy)
5439 struct text_selection *This = impl_from_ITextSelection(me);
5441 FIXME("(%p)->(%ld %p %p): stub\n", This, type, cx, cy);
5443 if (!This->services)
5444 return CO_E_RELEASED;
5446 return E_NOTIMPL;
5449 static HRESULT WINAPI ITextSelection_fnSetPoint(ITextSelection *me, LONG x, LONG y, LONG type,
5450 LONG extend)
5452 struct text_selection *This = impl_from_ITextSelection(me);
5454 FIXME("(%p)->(%ld %ld %ld %ld): stub\n", This, x, y, type, extend);
5456 if (!This->services)
5457 return CO_E_RELEASED;
5459 return E_NOTIMPL;
5462 static HRESULT WINAPI ITextSelection_fnScrollIntoView(ITextSelection *me, LONG value)
5464 struct text_selection *This = impl_from_ITextSelection(me);
5466 FIXME("(%p)->(%ld): stub\n", This, value);
5468 if (!This->services)
5469 return CO_E_RELEASED;
5471 return E_NOTIMPL;
5474 static HRESULT WINAPI ITextSelection_fnGetEmbeddedObject(ITextSelection *me, IUnknown **ppv)
5476 struct text_selection *This = impl_from_ITextSelection(me);
5478 FIXME("(%p)->(%p): stub\n", This, ppv);
5480 if (!This->services)
5481 return CO_E_RELEASED;
5483 return E_NOTIMPL;
5486 /*** ITextSelection methods ***/
5487 static HRESULT WINAPI ITextSelection_fnGetFlags(ITextSelection *me, LONG *flags)
5489 struct text_selection *This = impl_from_ITextSelection(me);
5491 FIXME("(%p)->(%p): stub\n", This, flags);
5493 if (!This->services)
5494 return CO_E_RELEASED;
5496 return E_NOTIMPL;
5499 static HRESULT WINAPI ITextSelection_fnSetFlags(ITextSelection *me, LONG flags)
5501 struct text_selection *This = impl_from_ITextSelection(me);
5503 FIXME("(%p)->(%lx): stub\n", This, flags);
5505 if (!This->services)
5506 return CO_E_RELEASED;
5508 return E_NOTIMPL;
5511 static HRESULT WINAPI ITextSelection_fnGetType(ITextSelection *me, LONG *type)
5513 struct text_selection *This = impl_from_ITextSelection(me);
5515 FIXME("(%p)->(%p): stub\n", This, type);
5517 if (!This->services)
5518 return CO_E_RELEASED;
5520 return E_NOTIMPL;
5523 static HRESULT WINAPI ITextSelection_fnMoveLeft(ITextSelection *me, LONG unit, LONG count,
5524 LONG extend, LONG *delta)
5526 struct text_selection *This = impl_from_ITextSelection(me);
5528 FIXME("(%p)->(%ld %ld %ld %p): stub\n", This, unit, count, extend, delta);
5530 if (!This->services)
5531 return CO_E_RELEASED;
5533 return E_NOTIMPL;
5536 static HRESULT WINAPI ITextSelection_fnMoveRight(ITextSelection *me, LONG unit, LONG count,
5537 LONG extend, LONG *delta)
5539 struct text_selection *This = impl_from_ITextSelection(me);
5541 FIXME("(%p)->(%ld %ld %ld %p): stub\n", This, unit, count, extend, delta);
5543 if (!This->services)
5544 return CO_E_RELEASED;
5546 return E_NOTIMPL;
5549 static HRESULT WINAPI ITextSelection_fnMoveUp(ITextSelection *me, LONG unit, LONG count,
5550 LONG extend, LONG *delta)
5552 struct text_selection *This = impl_from_ITextSelection(me);
5554 FIXME("(%p)->(%ld %ld %ld %p): stub\n", This, unit, count, extend, delta);
5556 if (!This->services)
5557 return CO_E_RELEASED;
5559 return E_NOTIMPL;
5562 static HRESULT WINAPI ITextSelection_fnMoveDown(ITextSelection *me, LONG unit, LONG count,
5563 LONG extend, LONG *delta)
5565 struct text_selection *This = impl_from_ITextSelection(me);
5567 FIXME("(%p)->(%ld %ld %ld %p): stub\n", This, unit, count, extend, delta);
5569 if (!This->services)
5570 return CO_E_RELEASED;
5572 return E_NOTIMPL;
5575 static HRESULT WINAPI ITextSelection_fnHomeKey(ITextSelection *me, LONG unit, LONG extend,
5576 LONG *delta)
5578 struct text_selection *This = impl_from_ITextSelection(me);
5580 FIXME("(%p)->(%ld %ld %p): stub\n", This, unit, extend, delta);
5582 if (!This->services)
5583 return CO_E_RELEASED;
5585 return E_NOTIMPL;
5588 static HRESULT WINAPI ITextSelection_fnEndKey(ITextSelection *me, LONG unit, LONG extend,
5589 LONG *delta)
5591 struct text_selection *This = impl_from_ITextSelection(me);
5593 FIXME("(%p)->(%ld %ld %p): stub\n", This, unit, extend, delta);
5595 if (!This->services)
5596 return CO_E_RELEASED;
5598 return E_NOTIMPL;
5601 static HRESULT WINAPI ITextSelection_fnTypeText(ITextSelection *me, BSTR text)
5603 struct text_selection *This = impl_from_ITextSelection(me);
5605 FIXME("(%p)->(%s): stub\n", This, debugstr_w(text));
5607 if (!This->services)
5608 return CO_E_RELEASED;
5610 return E_NOTIMPL;
5613 static const ITextSelectionVtbl tsvt = {
5614 ITextSelection_fnQueryInterface,
5615 ITextSelection_fnAddRef,
5616 ITextSelection_fnRelease,
5617 ITextSelection_fnGetTypeInfoCount,
5618 ITextSelection_fnGetTypeInfo,
5619 ITextSelection_fnGetIDsOfNames,
5620 ITextSelection_fnInvoke,
5621 ITextSelection_fnGetText,
5622 ITextSelection_fnSetText,
5623 ITextSelection_fnGetChar,
5624 ITextSelection_fnSetChar,
5625 ITextSelection_fnGetDuplicate,
5626 ITextSelection_fnGetFormattedText,
5627 ITextSelection_fnSetFormattedText,
5628 ITextSelection_fnGetStart,
5629 ITextSelection_fnSetStart,
5630 ITextSelection_fnGetEnd,
5631 ITextSelection_fnSetEnd,
5632 ITextSelection_fnGetFont,
5633 ITextSelection_fnSetFont,
5634 ITextSelection_fnGetPara,
5635 ITextSelection_fnSetPara,
5636 ITextSelection_fnGetStoryLength,
5637 ITextSelection_fnGetStoryType,
5638 ITextSelection_fnCollapse,
5639 ITextSelection_fnExpand,
5640 ITextSelection_fnGetIndex,
5641 ITextSelection_fnSetIndex,
5642 ITextSelection_fnSetRange,
5643 ITextSelection_fnInRange,
5644 ITextSelection_fnInStory,
5645 ITextSelection_fnIsEqual,
5646 ITextSelection_fnSelect,
5647 ITextSelection_fnStartOf,
5648 ITextSelection_fnEndOf,
5649 ITextSelection_fnMove,
5650 ITextSelection_fnMoveStart,
5651 ITextSelection_fnMoveEnd,
5652 ITextSelection_fnMoveWhile,
5653 ITextSelection_fnMoveStartWhile,
5654 ITextSelection_fnMoveEndWhile,
5655 ITextSelection_fnMoveUntil,
5656 ITextSelection_fnMoveStartUntil,
5657 ITextSelection_fnMoveEndUntil,
5658 ITextSelection_fnFindText,
5659 ITextSelection_fnFindTextStart,
5660 ITextSelection_fnFindTextEnd,
5661 ITextSelection_fnDelete,
5662 ITextSelection_fnCut,
5663 ITextSelection_fnCopy,
5664 ITextSelection_fnPaste,
5665 ITextSelection_fnCanPaste,
5666 ITextSelection_fnCanEdit,
5667 ITextSelection_fnChangeCase,
5668 ITextSelection_fnGetPoint,
5669 ITextSelection_fnSetPoint,
5670 ITextSelection_fnScrollIntoView,
5671 ITextSelection_fnGetEmbeddedObject,
5672 ITextSelection_fnGetFlags,
5673 ITextSelection_fnSetFlags,
5674 ITextSelection_fnGetType,
5675 ITextSelection_fnMoveLeft,
5676 ITextSelection_fnMoveRight,
5677 ITextSelection_fnMoveUp,
5678 ITextSelection_fnMoveDown,
5679 ITextSelection_fnHomeKey,
5680 ITextSelection_fnEndKey,
5681 ITextSelection_fnTypeText
5684 static struct text_selection *text_selection_create(struct text_services *services)
5686 struct text_selection *txtSel = malloc(sizeof *txtSel);
5687 if (!txtSel)
5688 return NULL;
5690 txtSel->ITextSelection_iface.lpVtbl = &tsvt;
5691 txtSel->ref = 1;
5692 txtSel->services = services;
5693 return txtSel;
5696 static void convert_sizel(const ME_Context *c, const SIZEL* szl, SIZE* sz)
5698 /* sizel is in .01 millimeters, sz in pixels */
5699 sz->cx = MulDiv(szl->cx, c->dpi.cx, 2540);
5700 sz->cy = MulDiv(szl->cy, c->dpi.cy, 2540);
5703 /******************************************************************************
5704 * ME_GetOLEObjectSize
5706 * Sets run extent for OLE objects.
5708 void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize)
5710 IDataObject* ido;
5711 FORMATETC fmt;
5712 STGMEDIUM stgm;
5713 DIBSECTION dibsect;
5714 ENHMETAHEADER emh;
5716 assert(run->nFlags & MERF_GRAPHICS);
5717 assert(run->reobj);
5719 if (run->reobj->obj.sizel.cx != 0 || run->reobj->obj.sizel.cy != 0)
5721 convert_sizel(c, &run->reobj->obj.sizel, pSize);
5722 if (c->editor->nZoomNumerator != 0)
5724 pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5725 pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5727 return;
5730 if (!run->reobj->obj.poleobj)
5732 pSize->cx = pSize->cy = 0;
5733 return;
5736 if (IOleObject_QueryInterface(run->reobj->obj.poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
5738 FIXME("Query Interface IID_IDataObject failed!\n");
5739 pSize->cx = pSize->cy = 0;
5740 return;
5742 fmt.cfFormat = CF_BITMAP;
5743 fmt.ptd = NULL;
5744 fmt.dwAspect = DVASPECT_CONTENT;
5745 fmt.lindex = -1;
5746 fmt.tymed = TYMED_GDI;
5747 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5749 fmt.cfFormat = CF_ENHMETAFILE;
5750 fmt.tymed = TYMED_ENHMF;
5751 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5753 FIXME("unsupported format\n");
5754 pSize->cx = pSize->cy = 0;
5755 IDataObject_Release(ido);
5756 return;
5759 IDataObject_Release(ido);
5761 switch (stgm.tymed)
5763 case TYMED_GDI:
5764 GetObjectW(stgm.hBitmap, sizeof(dibsect), &dibsect);
5765 pSize->cx = dibsect.dsBm.bmWidth;
5766 pSize->cy = dibsect.dsBm.bmHeight;
5767 break;
5768 case TYMED_ENHMF:
5769 GetEnhMetaFileHeader(stgm.hEnhMetaFile, sizeof(emh), &emh);
5770 pSize->cx = emh.rclBounds.right - emh.rclBounds.left;
5771 pSize->cy = emh.rclBounds.bottom - emh.rclBounds.top;
5772 break;
5773 default:
5774 FIXME("Unsupported tymed %ld\n", stgm.tymed);
5775 break;
5777 ReleaseStgMedium(&stgm);
5778 if (c->editor->nZoomNumerator != 0)
5780 pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5781 pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5785 void draw_ole( ME_Context *c, int x, int y, ME_Run *run, BOOL selected )
5787 IDataObject* ido;
5788 IViewObject* ivo;
5789 FORMATETC fmt;
5790 STGMEDIUM stgm;
5791 DIBSECTION dibsect;
5792 ENHMETAHEADER emh;
5793 HDC hMemDC;
5794 SIZE sz;
5795 BOOL has_size;
5796 HBITMAP old_bm;
5797 RECT rc;
5799 assert(run->nFlags & MERF_GRAPHICS);
5800 assert(run->reobj);
5802 if (!run->reobj->obj.poleobj) return;
5804 if (SUCCEEDED(IOleObject_QueryInterface(run->reobj->obj.poleobj, &IID_IViewObject, (void**)&ivo)))
5806 HRESULT hr;
5807 RECTL bounds;
5809 convert_sizel(c, &run->reobj->obj.sizel, &sz);
5810 if (c->editor->nZoomNumerator != 0)
5812 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5813 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5816 bounds.left = x;
5817 bounds.top = y - sz.cy;
5818 bounds.right = x + sz.cx;
5819 bounds.bottom = y;
5821 hr = IViewObject_Draw(ivo, DVASPECT_CONTENT, -1, 0, 0, 0, c->hDC, &bounds, NULL, NULL, 0);
5822 if (FAILED(hr))
5824 WARN("failed to draw object: %#08lx\n", hr);
5827 IViewObject_Release(ivo);
5828 return;
5831 if (IOleObject_QueryInterface(run->reobj->obj.poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
5833 FIXME("Couldn't get interface\n");
5834 return;
5836 has_size = run->reobj->obj.sizel.cx != 0 || run->reobj->obj.sizel.cy != 0;
5837 fmt.cfFormat = CF_BITMAP;
5838 fmt.ptd = NULL;
5839 fmt.dwAspect = DVASPECT_CONTENT;
5840 fmt.lindex = -1;
5841 fmt.tymed = TYMED_GDI;
5842 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5844 fmt.cfFormat = CF_ENHMETAFILE;
5845 fmt.tymed = TYMED_ENHMF;
5846 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5848 FIXME("Couldn't get storage medium\n");
5849 IDataObject_Release(ido);
5850 return;
5853 IDataObject_Release(ido);
5855 switch (stgm.tymed)
5857 case TYMED_GDI:
5858 GetObjectW(stgm.hBitmap, sizeof(dibsect), &dibsect);
5859 hMemDC = CreateCompatibleDC(c->hDC);
5860 old_bm = SelectObject(hMemDC, stgm.hBitmap);
5861 if (has_size)
5863 convert_sizel(c, &run->reobj->obj.sizel, &sz);
5864 } else {
5865 sz.cx = dibsect.dsBm.bmWidth;
5866 sz.cy = dibsect.dsBm.bmHeight;
5868 if (c->editor->nZoomNumerator != 0)
5870 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5871 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5873 StretchBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy,
5874 hMemDC, 0, 0, dibsect.dsBm.bmWidth, dibsect.dsBm.bmHeight, SRCCOPY);
5876 SelectObject(hMemDC, old_bm);
5877 DeleteDC(hMemDC);
5878 break;
5879 case TYMED_ENHMF:
5880 GetEnhMetaFileHeader(stgm.hEnhMetaFile, sizeof(emh), &emh);
5881 if (has_size)
5883 convert_sizel(c, &run->reobj->obj.sizel, &sz);
5884 } else {
5885 sz.cx = emh.rclBounds.right - emh.rclBounds.left;
5886 sz.cy = emh.rclBounds.bottom - emh.rclBounds.top;
5888 if (c->editor->nZoomNumerator != 0)
5890 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5891 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5894 rc.left = x;
5895 rc.top = y - sz.cy;
5896 rc.right = x + sz.cx;
5897 rc.bottom = y;
5898 PlayEnhMetaFile(c->hDC, stgm.hEnhMetaFile, &rc);
5899 break;
5900 default:
5901 FIXME("Unsupported tymed %ld\n", stgm.tymed);
5902 selected = FALSE;
5903 break;
5905 ReleaseStgMedium(&stgm);
5907 if (selected && !c->editor->bHideSelection)
5908 PatBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy, DSTINVERT);
5911 void ME_DeleteReObject(struct re_object *reobj)
5913 if (reobj->obj.poleobj) IOleObject_Release(reobj->obj.poleobj);
5914 if (reobj->obj.pstg) IStorage_Release(reobj->obj.pstg);
5915 if (reobj->obj.polesite) IOleClientSite_Release(reobj->obj.polesite);
5916 free(reobj);
5919 void ME_CopyReObject(REOBJECT *dst, const REOBJECT *src, DWORD flags)
5921 *dst = *src;
5922 dst->poleobj = NULL;
5923 dst->pstg = NULL;
5924 dst->polesite = NULL;
5926 if ((flags & REO_GETOBJ_POLEOBJ) && src->poleobj)
5928 dst->poleobj = src->poleobj;
5929 IOleObject_AddRef(dst->poleobj);
5931 if ((flags & REO_GETOBJ_PSTG) && src->pstg)
5933 dst->pstg = src->pstg;
5934 IStorage_AddRef(dst->pstg);
5936 if ((flags & REO_GETOBJ_POLESITE) && src->polesite)
5938 dst->polesite = src->polesite;
5939 IOleClientSite_AddRef(dst->polesite);
5943 void richole_release_children( struct text_services *services )
5945 ITextRangeImpl *range;
5946 IOleClientSiteImpl *site;
5948 if (services->text_selection)
5950 services->text_selection->services = NULL;
5951 ITextSelection_Release( &services->text_selection->ITextSelection_iface );
5954 LIST_FOR_EACH_ENTRY( range, &services->rangelist, ITextRangeImpl, child.entry )
5955 range->child.reole = NULL;
5957 LIST_FOR_EACH_ENTRY( site, &services->clientsites, IOleClientSiteImpl, child.entry )
5958 site->child.reole = NULL;