b04b6b10a30bcb24cc07d27181632b9414ed3220
[reactos.git] / dll / win32 / riched20 / richole.c
1 /*
2 * RichEdit GUIDs and OLE interface
3 *
4 * Copyright 2004 by Krzysztof Foltman
5 * Copyright 2004 Aric Stewart
6 *
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.
11 *
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.
16 *
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
20 */
21
22 #include "editor.h"
23
24 WINE_DEFAULT_DEBUG_CHANNEL(richedit);
25
26 /* there is no way to be consistent across different sets of headers - mingw, Wine, Win32 SDK*/
27
28 #include <initguid.h>
29
30 DEFINE_GUID(LIBID_tom, 0x8cc497c9, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
31 DEFINE_GUID(IID_ITextServices, 0x8d33f740, 0xcf58, 0x11ce, 0xa8, 0x9d, 0x00, 0xaa, 0x00, 0x6c, 0xad, 0xc5);
32 DEFINE_GUID(IID_ITextHost, 0x13e670f4,0x1a5a,0x11cf,0xab,0xeb,0x00,0xaa,0x00,0xb6,0x5e,0xa1);
33 DEFINE_GUID(IID_ITextHost2, 0x13e670f5,0x1a5a,0x11cf,0xab,0xeb,0x00,0xaa,0x00,0xb6,0x5e,0xa1);
34 DEFINE_GUID(IID_ITextDocument, 0x8cc497c0, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
35 DEFINE_GUID(IID_ITextRange, 0x8cc497c2, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
36 DEFINE_GUID(IID_ITextSelection, 0x8cc497c1, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
37 DEFINE_GUID(IID_ITextFont, 0x8cc497c3, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
38 DEFINE_GUID(IID_ITextPara, 0x8cc497c4, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
39
40 static ITypeLib *typelib;
41
42 enum tid_t {
43 NULL_tid,
44 ITextDocument_tid,
45 ITextRange_tid,
46 ITextSelection_tid,
47 ITextFont_tid,
48 ITextPara_tid,
49 LAST_tid
50 };
51
52 static const IID * const tid_ids[] =
53 {
54 &IID_NULL,
55 &IID_ITextDocument,
56 &IID_ITextRange,
57 &IID_ITextSelection,
58 &IID_ITextFont,
59 &IID_ITextPara,
60 };
61 static ITypeInfo *typeinfos[LAST_tid];
62
63 static HRESULT load_typelib(void)
64 {
65 ITypeLib *tl;
66 HRESULT hr;
67
68 hr = LoadRegTypeLib(&LIBID_tom, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
69 if (FAILED(hr)) {
70 ERR("LoadRegTypeLib failed: %08x\n", hr);
71 return hr;
72 }
73
74 if (InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
75 ITypeLib_Release(tl);
76 return hr;
77 }
78
79 void release_typelib(void)
80 {
81 unsigned i;
82
83 if (!typelib)
84 return;
85
86 for (i = 0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++)
87 if (typeinfos[i])
88 ITypeInfo_Release(typeinfos[i]);
89
90 ITypeLib_Release(typelib);
91 }
92
93 static HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo)
94 {
95 HRESULT hr;
96
97 if (!typelib)
98 hr = load_typelib();
99 if (!typelib)
100 return hr;
101
102 if (!typeinfos[tid])
103 {
104 ITypeInfo *ti;
105
106 hr = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
107 if (FAILED(hr))
108 {
109 ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hr);
110 return hr;
111 }
112
113 if (InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
114 ITypeInfo_Release(ti);
115 }
116
117 *typeinfo = typeinfos[tid];
118 return S_OK;
119 }
120
121 /* private IID used to get back IRichEditOleImpl pointer */
122 DEFINE_GUID(IID_Igetrichole, 0xe3ce5c7a, 0x8247, 0x4622, 0x81, 0xad, 0x11, 0x81, 0x02, 0xaa, 0x01, 0x30);
123
124 typedef struct ITextSelectionImpl ITextSelectionImpl;
125 typedef struct IOleClientSiteImpl IOleClientSiteImpl;
126 typedef struct ITextRangeImpl ITextRangeImpl;
127
128 enum textfont_prop_id {
129 FONT_ALLCAPS = 0,
130 FONT_ANIMATION,
131 FONT_BACKCOLOR,
132 FONT_BOLD,
133 FONT_EMBOSS,
134 FONT_FORECOLOR,
135 FONT_HIDDEN,
136 FONT_ENGRAVE,
137 FONT_ITALIC,
138 FONT_KERNING,
139 FONT_LANGID,
140 FONT_NAME,
141 FONT_OUTLINE,
142 FONT_POSITION,
143 FONT_PROTECTED,
144 FONT_SHADOW,
145 FONT_SIZE,
146 FONT_SMALLCAPS,
147 FONT_SPACING,
148 FONT_STRIKETHROUGH,
149 FONT_SUBSCRIPT,
150 FONT_SUPERSCRIPT,
151 FONT_UNDERLINE,
152 FONT_WEIGHT,
153 FONT_PROPID_LAST,
154 FONT_PROPID_FIRST = FONT_ALLCAPS
155 };
156
157 static const DWORD textfont_prop_masks[][2] = {
158 { CFM_ALLCAPS, CFE_ALLCAPS },
159 { CFM_ANIMATION },
160 { CFM_BACKCOLOR, CFE_AUTOBACKCOLOR },
161 { CFM_BOLD, CFE_BOLD },
162 { CFM_EMBOSS, CFE_EMBOSS },
163 { CFM_COLOR, CFE_AUTOCOLOR },
164 { CFM_HIDDEN, CFE_HIDDEN },
165 { CFM_IMPRINT, CFE_IMPRINT },
166 { CFM_ITALIC, CFE_ITALIC },
167 { CFM_KERNING },
168 { CFM_LCID },
169 { CFM_FACE },
170 { CFM_OUTLINE, CFE_OUTLINE },
171 { CFM_OFFSET },
172 { CFM_PROTECTED, CFE_PROTECTED },
173 { CFM_SHADOW, CFE_SHADOW },
174 { CFM_SIZE },
175 { CFM_SMALLCAPS, CFE_SMALLCAPS },
176 { CFM_SPACING },
177 { CFM_STRIKEOUT, CFE_STRIKEOUT },
178 { CFM_SUBSCRIPT, CFE_SUBSCRIPT },
179 { CFM_SUPERSCRIPT, CFE_SUPERSCRIPT },
180 { CFM_UNDERLINE, CFE_UNDERLINE },
181 { CFM_WEIGHT }
182 };
183
184 typedef union {
185 FLOAT f;
186 LONG l;
187 BSTR str;
188 } textfont_prop_val;
189
190 enum range_update_op {
191 RANGE_UPDATE_DELETE
192 };
193
194 typedef struct IRichEditOleImpl {
195 IUnknown IUnknown_inner;
196 IRichEditOle IRichEditOle_iface;
197 ITextDocument ITextDocument_iface;
198 IUnknown *outer_unk;
199 LONG ref;
200
201 ME_TextEditor *editor;
202 ITextSelectionImpl *txtSel;
203
204 struct list rangelist;
205 struct list clientsites;
206 } IRichEditOleImpl;
207
208 struct reole_child {
209 struct list entry;
210 IRichEditOleImpl *reole;
211 };
212
213 struct ITextRangeImpl {
214 struct reole_child child;
215 ITextRange ITextRange_iface;
216 LONG ref;
217 LONG start, end;
218 };
219
220 struct ITextSelectionImpl {
221 ITextSelection ITextSelection_iface;
222 LONG ref;
223
224 IRichEditOleImpl *reOle;
225 };
226
227 typedef struct ITextFontImpl {
228 ITextFont ITextFont_iface;
229 LONG ref;
230
231 ITextRange *range;
232 textfont_prop_val props[FONT_PROPID_LAST];
233 BOOL get_cache_enabled;
234 BOOL set_cache_enabled;
235 } ITextFontImpl;
236
237 typedef struct ITextParaImpl {
238 ITextPara ITextPara_iface;
239 LONG ref;
240
241 ITextRange *range;
242 } ITextParaImpl;
243
244 struct IOleClientSiteImpl {
245 struct reole_child child;
246 IOleClientSite IOleClientSite_iface;
247 IOleInPlaceSite IOleInPlaceSite_iface;
248 LONG ref;
249 };
250
251 static inline IRichEditOleImpl *impl_from_IRichEditOle(IRichEditOle *iface)
252 {
253 return CONTAINING_RECORD(iface, IRichEditOleImpl, IRichEditOle_iface);
254 }
255
256 static inline IRichEditOleImpl *impl_from_ITextDocument(ITextDocument *iface)
257 {
258 return CONTAINING_RECORD(iface, IRichEditOleImpl, ITextDocument_iface);
259 }
260
261 static inline IRichEditOleImpl *impl_from_IUnknown(IUnknown *iface)
262 {
263 return CONTAINING_RECORD(iface, IRichEditOleImpl, IUnknown_inner);
264 }
265
266 static inline IOleClientSiteImpl *impl_from_IOleInPlaceSite(IOleInPlaceSite *iface)
267 {
268 return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleInPlaceSite_iface);
269 }
270
271 static inline ITextRangeImpl *impl_from_ITextRange(ITextRange *iface)
272 {
273 return CONTAINING_RECORD(iface, ITextRangeImpl, ITextRange_iface);
274 }
275
276 static inline ITextSelectionImpl *impl_from_ITextSelection(ITextSelection *iface)
277 {
278 return CONTAINING_RECORD(iface, ITextSelectionImpl, ITextSelection_iface);
279 }
280
281 static inline ITextFontImpl *impl_from_ITextFont(ITextFont *iface)
282 {
283 return CONTAINING_RECORD(iface, ITextFontImpl, ITextFont_iface);
284 }
285
286 static inline ITextParaImpl *impl_from_ITextPara(ITextPara *iface)
287 {
288 return CONTAINING_RECORD(iface, ITextParaImpl, ITextPara_iface);
289 }
290
291 static HRESULT create_textfont(ITextRange*, const ITextFontImpl*, ITextFont**);
292 static HRESULT create_textpara(ITextRange*, ITextPara**);
293 static ITextSelectionImpl *CreateTextSelection(IRichEditOleImpl*);
294
295 static HRESULT textrange_get_storylength(ME_TextEditor *editor, LONG *length)
296 {
297 if (!length)
298 return E_INVALIDARG;
299
300 *length = ME_GetTextLength(editor) + 1;
301 return S_OK;
302 }
303
304 static void textranges_update_ranges(IRichEditOleImpl *reole, LONG start, LONG end, enum range_update_op op)
305 {
306 ITextRangeImpl *range;
307
308 LIST_FOR_EACH_ENTRY(range, &reole->rangelist, ITextRangeImpl, child.entry) {
309 switch (op)
310 {
311 case RANGE_UPDATE_DELETE:
312 /* range fully covered by deleted range - collapse to insertion point */
313 if (range->start >= start && range->end <= end)
314 range->start = range->end = start;
315 /* deleted range cuts from the right */
316 else if (range->start < start && range->end <= end)
317 range->end = start;
318 /* deleted range cuts from the left */
319 else if (range->start >= start && range->end > end) {
320 range->start = start;
321 range->end -= end - start;
322 }
323 /* deleted range cuts within */
324 else
325 range->end -= end - start;
326 break;
327 default:
328 FIXME("unknown update op, %d\n", op);
329 }
330 }
331 }
332
333 static inline BOOL is_equal_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *left,
334 textfont_prop_val *right)
335 {
336 switch (propid)
337 {
338 case FONT_ALLCAPS:
339 case FONT_ANIMATION:
340 case FONT_BACKCOLOR:
341 case FONT_BOLD:
342 case FONT_EMBOSS:
343 case FONT_FORECOLOR:
344 case FONT_HIDDEN:
345 case FONT_ENGRAVE:
346 case FONT_ITALIC:
347 case FONT_KERNING:
348 case FONT_LANGID:
349 case FONT_OUTLINE:
350 case FONT_PROTECTED:
351 case FONT_SHADOW:
352 case FONT_SMALLCAPS:
353 case FONT_STRIKETHROUGH:
354 case FONT_SUBSCRIPT:
355 case FONT_SUPERSCRIPT:
356 case FONT_UNDERLINE:
357 case FONT_WEIGHT:
358 return left->l == right->l;
359 case FONT_NAME:
360 return !strcmpW(left->str, right->str);
361 case FONT_POSITION:
362 case FONT_SIZE:
363 case FONT_SPACING:
364 return left->f == right->f;
365 default:
366 FIXME("unhandled font property %d\n", propid);
367 return FALSE;
368 }
369 }
370
371 static inline void init_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *v)
372 {
373 switch (propid)
374 {
375 case FONT_ALLCAPS:
376 case FONT_ANIMATION:
377 case FONT_BACKCOLOR:
378 case FONT_BOLD:
379 case FONT_EMBOSS:
380 case FONT_FORECOLOR:
381 case FONT_HIDDEN:
382 case FONT_ENGRAVE:
383 case FONT_ITALIC:
384 case FONT_KERNING:
385 case FONT_LANGID:
386 case FONT_OUTLINE:
387 case FONT_PROTECTED:
388 case FONT_SHADOW:
389 case FONT_SMALLCAPS:
390 case FONT_STRIKETHROUGH:
391 case FONT_SUBSCRIPT:
392 case FONT_SUPERSCRIPT:
393 case FONT_UNDERLINE:
394 case FONT_WEIGHT:
395 v->l = tomUndefined;
396 return;
397 case FONT_NAME:
398 v->str = NULL;
399 return;
400 case FONT_POSITION:
401 case FONT_SIZE:
402 case FONT_SPACING:
403 v->f = tomUndefined;
404 return;
405 default:
406 FIXME("unhandled font property %d\n", propid);
407 v->l = tomUndefined;
408 return;
409 }
410 }
411
412 static inline FLOAT twips_to_points(LONG value)
413 {
414 return value * 72.0 / 1440;
415 }
416
417 static inline FLOAT points_to_twips(FLOAT value)
418 {
419 return value * 1440 / 72.0;
420 }
421
422 static HRESULT get_textfont_prop_for_pos(const IRichEditOleImpl *reole, int pos, enum textfont_prop_id propid,
423 textfont_prop_val *value)
424 {
425 ME_Cursor from, to;
426 CHARFORMAT2W fmt;
427
428 memset(&fmt, 0, sizeof(fmt));
429 fmt.cbSize = sizeof(fmt);
430 fmt.dwMask = textfont_prop_masks[propid][0];
431
432 ME_CursorFromCharOfs(reole->editor, pos, &from);
433 to = from;
434 ME_MoveCursorChars(reole->editor, &to, 1, FALSE);
435 ME_GetCharFormat(reole->editor, &from, &to, &fmt);
436
437 switch (propid)
438 {
439 case FONT_ALLCAPS:
440 case FONT_BOLD:
441 case FONT_EMBOSS:
442 case FONT_HIDDEN:
443 case FONT_ENGRAVE:
444 case FONT_ITALIC:
445 case FONT_OUTLINE:
446 case FONT_PROTECTED:
447 case FONT_SHADOW:
448 case FONT_SMALLCAPS:
449 case FONT_STRIKETHROUGH:
450 case FONT_SUBSCRIPT:
451 case FONT_SUPERSCRIPT:
452 case FONT_UNDERLINE:
453 value->l = fmt.dwEffects & textfont_prop_masks[propid][1] ? tomTrue : tomFalse;
454 break;
455 case FONT_ANIMATION:
456 value->l = fmt.bAnimation;
457 break;
458 case FONT_BACKCOLOR:
459 value->l = fmt.dwEffects & CFE_AUTOBACKCOLOR ? GetSysColor(COLOR_WINDOW) : fmt.crBackColor;
460 break;
461 case FONT_FORECOLOR:
462 value->l = fmt.dwEffects & CFE_AUTOCOLOR ? GetSysColor(COLOR_WINDOWTEXT) : fmt.crTextColor;
463 break;
464 case FONT_KERNING:
465 value->f = twips_to_points(fmt.wKerning);
466 break;
467 case FONT_LANGID:
468 value->l = fmt.lcid;
469 break;
470 case FONT_NAME:
471 /* this case is used exclusively by GetName() */
472 value->str = SysAllocString(fmt.szFaceName);
473 if (!value->str)
474 return E_OUTOFMEMORY;
475 break;
476 case FONT_POSITION:
477 value->f = twips_to_points(fmt.yOffset);
478 break;
479 case FONT_SIZE:
480 value->f = twips_to_points(fmt.yHeight);
481 break;
482 case FONT_SPACING:
483 value->f = fmt.sSpacing;
484 break;
485 case FONT_WEIGHT:
486 value->l = fmt.wWeight;
487 break;
488 default:
489 FIXME("unhandled font property %d\n", propid);
490 return E_FAIL;
491 }
492
493 return S_OK;
494 }
495
496 static inline const IRichEditOleImpl *get_range_reole(ITextRange *range)
497 {
498 IRichEditOleImpl *reole = NULL;
499 ITextRange_QueryInterface(range, &IID_Igetrichole, (void**)&reole);
500 return reole;
501 }
502
503 static void textrange_set_font(ITextRange *range, ITextFont *font)
504 {
505 CHARFORMAT2W fmt;
506 HRESULT hr;
507 LONG value;
508 BSTR str;
509 FLOAT f;
510
511 #define CHARFORMAT_SET_B_FIELD(mask, value) \
512 if (hr == S_OK && value != tomUndefined) { \
513 fmt.dwMask |= CFM_##mask; \
514 if (value == tomTrue) fmt.dwEffects |= CFE_##mask; \
515 } \
516
517 /* fill format data from font */
518 memset(&fmt, 0, sizeof(fmt));
519 fmt.cbSize = sizeof(fmt);
520
521 value = tomUndefined;
522 hr = ITextFont_GetAllCaps(font, &value);
523 CHARFORMAT_SET_B_FIELD(ALLCAPS, value);
524
525 value = tomUndefined;
526 hr = ITextFont_GetBold(font, &value);
527 CHARFORMAT_SET_B_FIELD(BOLD, value);
528
529 value = tomUndefined;
530 hr = ITextFont_GetEmboss(font, &value);
531 CHARFORMAT_SET_B_FIELD(EMBOSS, value);
532
533 value = tomUndefined;
534 hr = ITextFont_GetHidden(font, &value);
535 CHARFORMAT_SET_B_FIELD(HIDDEN, value);
536
537 value = tomUndefined;
538 hr = ITextFont_GetEngrave(font, &value);
539 CHARFORMAT_SET_B_FIELD(IMPRINT, value);
540
541 value = tomUndefined;
542 hr = ITextFont_GetItalic(font, &value);
543 CHARFORMAT_SET_B_FIELD(ITALIC, value);
544
545 value = tomUndefined;
546 hr = ITextFont_GetOutline(font, &value);
547 CHARFORMAT_SET_B_FIELD(OUTLINE, value);
548
549 value = tomUndefined;
550 hr = ITextFont_GetProtected(font, &value);
551 CHARFORMAT_SET_B_FIELD(PROTECTED, value);
552
553 value = tomUndefined;
554 hr = ITextFont_GetShadow(font, &value);
555 CHARFORMAT_SET_B_FIELD(SHADOW, value);
556
557 value = tomUndefined;
558 hr = ITextFont_GetSmallCaps(font, &value);
559 CHARFORMAT_SET_B_FIELD(SMALLCAPS, value);
560
561 value = tomUndefined;
562 hr = ITextFont_GetStrikeThrough(font, &value);
563 CHARFORMAT_SET_B_FIELD(STRIKEOUT, value);
564
565 value = tomUndefined;
566 hr = ITextFont_GetSubscript(font, &value);
567 CHARFORMAT_SET_B_FIELD(SUBSCRIPT, value);
568
569 value = tomUndefined;
570 hr = ITextFont_GetSuperscript(font, &value);
571 CHARFORMAT_SET_B_FIELD(SUPERSCRIPT, value);
572
573 value = tomUndefined;
574 hr = ITextFont_GetUnderline(font, &value);
575 CHARFORMAT_SET_B_FIELD(UNDERLINE, value);
576
577 #undef CHARFORMAT_SET_B_FIELD
578
579 value = tomUndefined;
580 hr = ITextFont_GetAnimation(font, &value);
581 if (hr == S_OK && value != tomUndefined) {
582 fmt.dwMask |= CFM_ANIMATION;
583 fmt.bAnimation = value;
584 }
585
586 value = tomUndefined;
587 hr = ITextFont_GetBackColor(font, &value);
588 if (hr == S_OK && value != tomUndefined) {
589 fmt.dwMask |= CFM_BACKCOLOR;
590 if (value == tomAutoColor)
591 fmt.dwEffects |= CFE_AUTOBACKCOLOR;
592 else
593 fmt.crBackColor = value;
594 }
595
596 value = tomUndefined;
597 hr = ITextFont_GetForeColor(font, &value);
598 if (hr == S_OK && value != tomUndefined) {
599 fmt.dwMask |= CFM_COLOR;
600 if (value == tomAutoColor)
601 fmt.dwEffects |= CFE_AUTOCOLOR;
602 else
603 fmt.crTextColor = value;
604 }
605
606 value = tomUndefined;
607 hr = ITextFont_GetKerning(font, &f);
608 if (hr == S_OK && f != tomUndefined) {
609 fmt.dwMask |= CFM_KERNING;
610 fmt.wKerning = points_to_twips(f);
611 }
612
613 value = tomUndefined;
614 hr = ITextFont_GetLanguageID(font, &value);
615 if (hr == S_OK && value != tomUndefined) {
616 fmt.dwMask |= CFM_LCID;
617 fmt.lcid = value;
618 }
619
620 if (ITextFont_GetName(font, &str) == S_OK) {
621 fmt.dwMask |= CFM_FACE;
622 lstrcpynW(fmt.szFaceName, str, sizeof(fmt.szFaceName)/sizeof(WCHAR));
623 SysFreeString(str);
624 }
625
626 hr = ITextFont_GetPosition(font, &f);
627 if (hr == S_OK && f != tomUndefined) {
628 fmt.dwMask |= CFM_OFFSET;
629 fmt.yOffset = points_to_twips(f);
630 }
631
632 hr = ITextFont_GetSize(font, &f);
633 if (hr == S_OK && f != tomUndefined) {
634 fmt.dwMask |= CFM_SIZE;
635 fmt.yHeight = points_to_twips(f);
636 }
637
638 hr = ITextFont_GetSpacing(font, &f);
639 if (hr == S_OK && f != tomUndefined) {
640 fmt.dwMask |= CFM_SPACING;
641 fmt.sSpacing = f;
642 }
643
644 hr = ITextFont_GetWeight(font, &value);
645 if (hr == S_OK && value != tomUndefined) {
646 fmt.dwMask |= CFM_WEIGHT;
647 fmt.wWeight = value;
648 }
649
650 if (fmt.dwMask) {
651 const IRichEditOleImpl *reole = get_range_reole(range);
652 ME_Cursor from, to;
653 LONG start, end;
654
655 ITextRange_GetStart(range, &start);
656 ITextRange_GetEnd(range, &end);
657
658 ME_CursorFromCharOfs(reole->editor, start, &from);
659 ME_CursorFromCharOfs(reole->editor, end, &to);
660 ME_SetCharFormat(reole->editor, &from, &to, &fmt);
661 }
662 }
663
664 static HRESULT get_textfont_prop(const ITextFontImpl *font, enum textfont_prop_id propid, textfont_prop_val *value)
665 {
666 const IRichEditOleImpl *reole;
667 textfont_prop_val v;
668 LONG start, end, i;
669 HRESULT hr;
670
671 /* when font is not attached to any range use cached values */
672 if (!font->range || font->get_cache_enabled) {
673 *value = font->props[propid];
674 return S_OK;
675 }
676
677 if (!(reole = get_range_reole(font->range)))
678 return CO_E_RELEASED;
679
680 init_textfont_prop_value(propid, value);
681
682 ITextRange_GetStart(font->range, &start);
683 ITextRange_GetEnd(font->range, &end);
684
685 /* iterate trough a range to see if property value is consistent */
686 hr = get_textfont_prop_for_pos(reole, start, propid, &v);
687 if (FAILED(hr))
688 return hr;
689
690 for (i = start + 1; i < end; i++) {
691 textfont_prop_val cur;
692
693 hr = get_textfont_prop_for_pos(reole, i, propid, &cur);
694 if (FAILED(hr))
695 return hr;
696
697 if (!is_equal_textfont_prop_value(propid, &v, &cur))
698 return S_OK;
699 }
700
701 *value = v;
702 return S_OK;
703 }
704
705 static HRESULT get_textfont_propf(const ITextFontImpl *font, enum textfont_prop_id propid, FLOAT *value)
706 {
707 textfont_prop_val v;
708 HRESULT hr;
709
710 if (!value)
711 return E_INVALIDARG;
712
713 hr = get_textfont_prop(font, propid, &v);
714 *value = v.f;
715 return hr;
716 }
717
718 static HRESULT get_textfont_propl(const ITextFontImpl *font, enum textfont_prop_id propid, LONG *value)
719 {
720 textfont_prop_val v;
721 HRESULT hr;
722
723 if (!value)
724 return E_INVALIDARG;
725
726 hr = get_textfont_prop(font, propid, &v);
727 *value = v.l;
728 return hr;
729 }
730
731 /* Value should already have a terminal value, for boolean properties it means tomToggle is not handled */
732 static HRESULT set_textfont_prop(ITextFontImpl *font, enum textfont_prop_id propid, const textfont_prop_val *value)
733 {
734 const IRichEditOleImpl *reole;
735 ME_Cursor from, to;
736 CHARFORMAT2W fmt;
737 LONG start, end;
738
739 /* when font is not attached to any range use cache */
740 if (!font->range || font->set_cache_enabled) {
741 if (propid == FONT_NAME) {
742 SysFreeString(font->props[propid].str);
743 font->props[propid].str = SysAllocString(value->str);
744 }
745 else
746 font->props[propid] = *value;
747 return S_OK;
748 }
749
750 if (!(reole = get_range_reole(font->range)))
751 return CO_E_RELEASED;
752
753 memset(&fmt, 0, sizeof(fmt));
754 fmt.cbSize = sizeof(fmt);
755 fmt.dwMask = textfont_prop_masks[propid][0];
756
757 switch (propid)
758 {
759 case FONT_ALLCAPS:
760 case FONT_BOLD:
761 case FONT_EMBOSS:
762 case FONT_HIDDEN:
763 case FONT_ENGRAVE:
764 case FONT_ITALIC:
765 case FONT_OUTLINE:
766 case FONT_PROTECTED:
767 case FONT_SHADOW:
768 case FONT_SMALLCAPS:
769 case FONT_STRIKETHROUGH:
770 case FONT_SUBSCRIPT:
771 case FONT_SUPERSCRIPT:
772 case FONT_UNDERLINE:
773 fmt.dwEffects = value->l == tomTrue ? textfont_prop_masks[propid][1] : 0;
774 break;
775 case FONT_ANIMATION:
776 fmt.bAnimation = value->l;
777 break;
778 case FONT_BACKCOLOR:
779 case FONT_FORECOLOR:
780 if (value->l == tomAutoColor)
781 fmt.dwEffects = textfont_prop_masks[propid][1];
782 else if (propid == FONT_BACKCOLOR)
783 fmt.crBackColor = value->l;
784 else
785 fmt.crTextColor = value->l;
786 break;
787 case FONT_KERNING:
788 fmt.wKerning = value->f;
789 break;
790 case FONT_LANGID:
791 fmt.lcid = value->l;
792 break;
793 case FONT_POSITION:
794 fmt.yOffset = value->f;
795 break;
796 case FONT_SIZE:
797 fmt.yHeight = value->f;
798 break;
799 case FONT_SPACING:
800 fmt.sSpacing = value->f;
801 break;
802 case FONT_WEIGHT:
803 fmt.wWeight = value->l;
804 break;
805 case FONT_NAME:
806 lstrcpynW(fmt.szFaceName, value->str, sizeof(fmt.szFaceName)/sizeof(WCHAR));
807 break;
808 default:
809 FIXME("unhandled font property %d\n", propid);
810 return E_FAIL;
811 }
812
813 ITextRange_GetStart(font->range, &start);
814 ITextRange_GetEnd(font->range, &end);
815
816 ME_CursorFromCharOfs(reole->editor, start, &from);
817 ME_CursorFromCharOfs(reole->editor, end, &to);
818 ME_SetCharFormat(reole->editor, &from, &to, &fmt);
819
820 return S_OK;
821 }
822
823 static inline HRESULT set_textfont_propl(ITextFontImpl *font, enum textfont_prop_id propid, LONG value)
824 {
825 textfont_prop_val v;
826 v.l = value;
827 return set_textfont_prop(font, propid, &v);
828 }
829
830 static inline HRESULT set_textfont_propf(ITextFontImpl *font, enum textfont_prop_id propid, FLOAT value)
831 {
832 textfont_prop_val v;
833 v.f = value;
834 return set_textfont_prop(font, propid, &v);
835 }
836
837 static HRESULT set_textfont_propd(ITextFontImpl *font, enum textfont_prop_id propid, LONG value)
838 {
839 textfont_prop_val v;
840
841 switch (value)
842 {
843 case tomUndefined:
844 return S_OK;
845 case tomToggle: {
846 LONG oldvalue;
847 get_textfont_propl(font, propid, &oldvalue);
848 if (oldvalue == tomFalse)
849 value = tomTrue;
850 else if (oldvalue == tomTrue)
851 value = tomFalse;
852 else
853 return E_INVALIDARG;
854 /* fallthrough */
855 }
856 case tomTrue:
857 case tomFalse:
858 v.l = value;
859 return set_textfont_prop(font, propid, &v);
860 default:
861 return E_INVALIDARG;
862 }
863 }
864
865 static HRESULT textfont_getname_from_range(ITextRange *range, BSTR *ret)
866 {
867 const IRichEditOleImpl *reole;
868 textfont_prop_val v;
869 HRESULT hr;
870 LONG start;
871
872 if (!(reole = get_range_reole(range)))
873 return CO_E_RELEASED;
874
875 ITextRange_GetStart(range, &start);
876 hr = get_textfont_prop_for_pos(reole, start, FONT_NAME, &v);
877 *ret = v.str;
878 return hr;
879 }
880
881 static void textfont_cache_range_props(ITextFontImpl *font)
882 {
883 enum textfont_prop_id propid;
884 for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++) {
885 if (propid == FONT_NAME)
886 textfont_getname_from_range(font->range, &font->props[propid].str);
887 else
888 get_textfont_prop(font, propid, &font->props[propid]);
889 }
890 }
891
892 static HRESULT textrange_expand(ITextRange *range, LONG unit, LONG *delta)
893 {
894 LONG expand_start, expand_end;
895
896 switch (unit)
897 {
898 case tomStory:
899 expand_start = 0;
900 ITextRange_GetStoryLength(range, &expand_end);
901 break;
902 default:
903 FIXME("unit %d is not supported\n", unit);
904 return E_NOTIMPL;
905 }
906
907 if (delta) {
908 LONG start, end;
909
910 ITextRange_GetStart(range, &start);
911 ITextRange_GetEnd(range, &end);
912 *delta = expand_end - expand_start - (end - start);
913 }
914
915 ITextRange_SetStart(range, expand_start);
916 ITextRange_SetEnd(range, expand_end);
917
918 return S_OK;
919 }
920
921 static HRESULT WINAPI IRichEditOleImpl_inner_fnQueryInterface(IUnknown *iface, REFIID riid, LPVOID *ppvObj)
922 {
923 IRichEditOleImpl *This = impl_from_IUnknown(iface);
924
925 TRACE("%p %s\n", This, debugstr_guid(riid));
926
927 *ppvObj = NULL;
928 if (IsEqualGUID(riid, &IID_IUnknown))
929 *ppvObj = &This->IUnknown_inner;
930 else if (IsEqualGUID(riid, &IID_IRichEditOle))
931 *ppvObj = &This->IRichEditOle_iface;
932 else if (IsEqualGUID(riid, &IID_ITextDocument))
933 *ppvObj = &This->ITextDocument_iface;
934 if (*ppvObj)
935 {
936 IUnknown_AddRef((IUnknown *)*ppvObj);
937 return S_OK;
938 }
939 FIXME("%p: unhandled interface %s\n", This, debugstr_guid(riid));
940
941 return E_NOINTERFACE;
942 }
943
944 static ULONG WINAPI IRichEditOleImpl_inner_fnAddRef(IUnknown *iface)
945 {
946 IRichEditOleImpl *This = impl_from_IUnknown(iface);
947 ULONG ref = InterlockedIncrement(&This->ref);
948
949 TRACE("%p ref = %u\n", This, ref);
950
951 return ref;
952 }
953
954 static ULONG WINAPI IRichEditOleImpl_inner_fnRelease(IUnknown *iface)
955 {
956 IRichEditOleImpl *This = impl_from_IUnknown(iface);
957 ULONG ref = InterlockedDecrement(&This->ref);
958
959 TRACE ("%p ref=%u\n", This, ref);
960
961 if (!ref)
962 {
963 IOleClientSiteImpl *clientsite;
964 ITextRangeImpl *txtRge;
965
966 This->editor->reOle = NULL;
967 if (This->txtSel) {
968 This->txtSel->reOle = NULL;
969 ITextSelection_Release(&This->txtSel->ITextSelection_iface);
970 }
971
972 LIST_FOR_EACH_ENTRY(txtRge, &This->rangelist, ITextRangeImpl, child.entry)
973 txtRge->child.reole = NULL;
974
975 LIST_FOR_EACH_ENTRY(clientsite, &This->clientsites, IOleClientSiteImpl, child.entry)
976 clientsite->child.reole = NULL;
977
978 heap_free(This);
979 }
980 return ref;
981 }
982
983 static const IUnknownVtbl reo_unk_vtbl =
984 {
985 IRichEditOleImpl_inner_fnQueryInterface,
986 IRichEditOleImpl_inner_fnAddRef,
987 IRichEditOleImpl_inner_fnRelease
988 };
989
990 static HRESULT WINAPI
991 IRichEditOle_fnQueryInterface(IRichEditOle *me, REFIID riid, LPVOID *ppvObj)
992 {
993 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
994 return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj);
995 }
996
997 static ULONG WINAPI
998 IRichEditOle_fnAddRef(IRichEditOle *me)
999 {
1000 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1001 return IUnknown_AddRef(This->outer_unk);
1002 }
1003
1004 static ULONG WINAPI
1005 IRichEditOle_fnRelease(IRichEditOle *me)
1006 {
1007 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1008 return IUnknown_Release(This->outer_unk);
1009 }
1010
1011 static HRESULT WINAPI
1012 IRichEditOle_fnActivateAs(IRichEditOle *me, REFCLSID rclsid, REFCLSID rclsidAs)
1013 {
1014 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1015 FIXME("stub %p\n",This);
1016 return E_NOTIMPL;
1017 }
1018
1019 static HRESULT WINAPI
1020 IRichEditOle_fnContextSensitiveHelp(IRichEditOle *me, BOOL fEnterMode)
1021 {
1022 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1023 FIXME("stub %p\n",This);
1024 return E_NOTIMPL;
1025 }
1026
1027 static HRESULT WINAPI
1028 IRichEditOle_fnConvertObject(IRichEditOle *me, LONG iob,
1029 REFCLSID rclsidNew, LPCSTR lpstrUserTypeNew)
1030 {
1031 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1032 FIXME("stub %p\n",This);
1033 return E_NOTIMPL;
1034 }
1035
1036 static inline IOleClientSiteImpl *impl_from_IOleClientSite(IOleClientSite *iface)
1037 {
1038 return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleClientSite_iface);
1039 }
1040
1041 static HRESULT WINAPI
1042 IOleClientSite_fnQueryInterface(IOleClientSite *me, REFIID riid, LPVOID *ppvObj)
1043 {
1044 IOleClientSiteImpl *This = impl_from_IOleClientSite(me);
1045 TRACE("%p %s\n", me, debugstr_guid(riid) );
1046
1047 *ppvObj = NULL;
1048 if (IsEqualGUID(riid, &IID_IUnknown) ||
1049 IsEqualGUID(riid, &IID_IOleClientSite))
1050 *ppvObj = me;
1051 else if (IsEqualGUID(riid, &IID_IOleWindow) ||
1052 IsEqualGUID(riid, &IID_IOleInPlaceSite))
1053 *ppvObj = &This->IOleInPlaceSite_iface;
1054 if (*ppvObj)
1055 {
1056 IOleClientSite_AddRef(me);
1057 return S_OK;
1058 }
1059 FIXME("%p: unhandled interface %s\n", me, debugstr_guid(riid) );
1060
1061 return E_NOINTERFACE;
1062 }
1063
1064 static ULONG WINAPI IOleClientSite_fnAddRef(IOleClientSite *iface)
1065 {
1066 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1067 ULONG ref = InterlockedIncrement(&This->ref);
1068 TRACE("(%p)->(%u)\n", This, ref);
1069 return ref;
1070 }
1071
1072 static ULONG WINAPI IOleClientSite_fnRelease(IOleClientSite *iface)
1073 {
1074 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1075 ULONG ref = InterlockedDecrement(&This->ref);
1076
1077 TRACE("(%p)->(%u)\n", This, ref);
1078
1079 if (ref == 0) {
1080 if (This->child.reole) {
1081 list_remove(&This->child.entry);
1082 This->child.reole = NULL;
1083 }
1084 heap_free(This);
1085 }
1086 return ref;
1087 }
1088
1089 static HRESULT WINAPI IOleClientSite_fnSaveObject(IOleClientSite *iface)
1090 {
1091 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1092 if (!This->child.reole)
1093 return CO_E_RELEASED;
1094
1095 FIXME("stub %p\n", iface);
1096 return E_NOTIMPL;
1097 }
1098
1099 static HRESULT WINAPI IOleClientSite_fnGetMoniker(IOleClientSite *iface, DWORD dwAssign,
1100 DWORD dwWhichMoniker, IMoniker **ppmk)
1101 {
1102 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1103 if (!This->child.reole)
1104 return CO_E_RELEASED;
1105
1106 FIXME("stub %p\n", iface);
1107 return E_NOTIMPL;
1108 }
1109
1110 static HRESULT WINAPI IOleClientSite_fnGetContainer(IOleClientSite *iface,
1111 IOleContainer **ppContainer)
1112 {
1113 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1114 if (!This->child.reole)
1115 return CO_E_RELEASED;
1116
1117 FIXME("stub %p\n", iface);
1118 return E_NOTIMPL;
1119 }
1120
1121 static HRESULT WINAPI IOleClientSite_fnShowObject(IOleClientSite *iface)
1122 {
1123 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1124 if (!This->child.reole)
1125 return CO_E_RELEASED;
1126
1127 FIXME("stub %p\n", iface);
1128 return E_NOTIMPL;
1129 }
1130
1131 static HRESULT WINAPI IOleClientSite_fnOnShowWindow(IOleClientSite *iface, BOOL fShow)
1132 {
1133 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1134 if (!This->child.reole)
1135 return CO_E_RELEASED;
1136
1137 FIXME("stub %p\n", iface);
1138 return E_NOTIMPL;
1139 }
1140
1141 static HRESULT WINAPI IOleClientSite_fnRequestNewObjectLayout(IOleClientSite *iface)
1142 {
1143 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
1144 if (!This->child.reole)
1145 return CO_E_RELEASED;
1146
1147 FIXME("stub %p\n", iface);
1148 return E_NOTIMPL;
1149 }
1150
1151 static const IOleClientSiteVtbl ocst = {
1152 IOleClientSite_fnQueryInterface,
1153 IOleClientSite_fnAddRef,
1154 IOleClientSite_fnRelease,
1155 IOleClientSite_fnSaveObject,
1156 IOleClientSite_fnGetMoniker,
1157 IOleClientSite_fnGetContainer,
1158 IOleClientSite_fnShowObject,
1159 IOleClientSite_fnOnShowWindow,
1160 IOleClientSite_fnRequestNewObjectLayout
1161 };
1162
1163 /* IOleInPlaceSite interface */
1164 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnQueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppvObj)
1165 {
1166 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1167 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppvObj);
1168 }
1169
1170 static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnAddRef(IOleInPlaceSite *iface)
1171 {
1172 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1173 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1174 }
1175
1176 static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnRelease(IOleInPlaceSite *iface)
1177 {
1178 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1179 return IOleClientSite_Release(&This->IOleClientSite_iface);
1180 }
1181
1182 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindow(IOleInPlaceSite *iface, HWND *phwnd)
1183 {
1184 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1185
1186 TRACE("(%p)->(%p)\n", This, phwnd);
1187
1188 if (!This->child.reole)
1189 return CO_E_RELEASED;
1190
1191 if (!phwnd)
1192 return E_INVALIDARG;
1193
1194 *phwnd = This->child.reole->editor->hWnd;
1195 return S_OK;
1196 }
1197
1198 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode)
1199 {
1200 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1201 FIXME("not implemented: (%p)->(%d)\n", This, fEnterMode);
1202 return E_NOTIMPL;
1203 }
1204
1205 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnCanInPlaceActivate(IOleInPlaceSite *iface)
1206 {
1207 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1208 FIXME("not implemented: (%p)\n", This);
1209 return E_NOTIMPL;
1210 }
1211
1212 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceActivate(IOleInPlaceSite *iface)
1213 {
1214 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1215 FIXME("not implemented: (%p)\n", This);
1216 return E_NOTIMPL;
1217 }
1218
1219 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIActivate(IOleInPlaceSite *iface)
1220 {
1221 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1222 FIXME("not implemented: (%p)\n", This);
1223 return E_NOTIMPL;
1224 }
1225
1226 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindowContext(IOleInPlaceSite *iface, IOleInPlaceFrame **ppFrame,
1227 IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
1228 LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
1229 {
1230 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1231 FIXME("not implemented: (%p)->(%p %p %p %p %p)\n", This, ppFrame, ppDoc, lprcPosRect, lprcClipRect, lpFrameInfo);
1232 return E_NOTIMPL;
1233 }
1234
1235 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnScroll(IOleInPlaceSite *iface, SIZE scrollExtent)
1236 {
1237 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1238 FIXME("not implemented: (%p)\n", This);
1239 return E_NOTIMPL;
1240 }
1241
1242 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable)
1243 {
1244 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1245 FIXME("not implemented: (%p)->(%d)\n", This, fUndoable);
1246 return E_NOTIMPL;
1247 }
1248
1249 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceDeactivate(IOleInPlaceSite *iface)
1250 {
1251 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1252 FIXME("not implemented: (%p)\n", This);
1253 return E_NOTIMPL;
1254 }
1255
1256 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDiscardUndoState(IOleInPlaceSite *iface)
1257 {
1258 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1259 FIXME("not implemented: (%p)\n", This);
1260 return E_NOTIMPL;
1261 }
1262
1263 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDeactivateAndUndo(IOleInPlaceSite *iface)
1264 {
1265 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1266 FIXME("not implemented: (%p)\n", This);
1267 return E_NOTIMPL;
1268 }
1269
1270 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect)
1271 {
1272 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface);
1273 FIXME("not implemented: (%p)->(%p)\n", This, lprcPosRect);
1274 return E_NOTIMPL;
1275 }
1276
1277 static const IOleInPlaceSiteVtbl olestvt =
1278 {
1279 IOleInPlaceSite_fnQueryInterface,
1280 IOleInPlaceSite_fnAddRef,
1281 IOleInPlaceSite_fnRelease,
1282 IOleInPlaceSite_fnGetWindow,
1283 IOleInPlaceSite_fnContextSensitiveHelp,
1284 IOleInPlaceSite_fnCanInPlaceActivate,
1285 IOleInPlaceSite_fnOnInPlaceActivate,
1286 IOleInPlaceSite_fnOnUIActivate,
1287 IOleInPlaceSite_fnGetWindowContext,
1288 IOleInPlaceSite_fnScroll,
1289 IOleInPlaceSite_fnOnUIDeactivate,
1290 IOleInPlaceSite_fnOnInPlaceDeactivate,
1291 IOleInPlaceSite_fnDiscardUndoState,
1292 IOleInPlaceSite_fnDeactivateAndUndo,
1293 IOleInPlaceSite_fnOnPosRectChange
1294 };
1295
1296 static HRESULT CreateOleClientSite(IRichEditOleImpl *reOle, IOleClientSite **ret)
1297 {
1298 IOleClientSiteImpl *clientSite = heap_alloc(sizeof *clientSite);
1299
1300 if (!clientSite)
1301 return E_OUTOFMEMORY;
1302
1303 clientSite->IOleClientSite_iface.lpVtbl = &ocst;
1304 clientSite->IOleInPlaceSite_iface.lpVtbl = &olestvt;
1305 clientSite->ref = 1;
1306 clientSite->child.reole = reOle;
1307 list_add_head(&reOle->clientsites, &clientSite->child.entry);
1308
1309 *ret = &clientSite->IOleClientSite_iface;
1310 return S_OK;
1311 }
1312
1313 static HRESULT WINAPI
1314 IRichEditOle_fnGetClientSite(IRichEditOle *me, IOleClientSite **clientsite)
1315 {
1316 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1317
1318 TRACE("(%p)->(%p)\n", This, clientsite);
1319
1320 if (!clientsite)
1321 return E_INVALIDARG;
1322
1323 return CreateOleClientSite(This, clientsite);
1324 }
1325
1326 static HRESULT WINAPI
1327 IRichEditOle_fnGetClipboardData(IRichEditOle *me, CHARRANGE *lpchrg,
1328 DWORD reco, LPDATAOBJECT *lplpdataobj)
1329 {
1330 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1331 ME_Cursor start;
1332 int nChars;
1333
1334 TRACE("(%p,%p,%d)\n",This, lpchrg, reco);
1335 if(!lplpdataobj)
1336 return E_INVALIDARG;
1337 if(!lpchrg) {
1338 int nFrom, nTo, nStartCur = ME_GetSelectionOfs(This->editor, &nFrom, &nTo);
1339 start = This->editor->pCursors[nStartCur];
1340 nChars = nTo - nFrom;
1341 } else {
1342 ME_CursorFromCharOfs(This->editor, lpchrg->cpMin, &start);
1343 nChars = lpchrg->cpMax - lpchrg->cpMin;
1344 }
1345 return ME_GetDataObject(This->editor, &start, nChars, lplpdataobj);
1346 }
1347
1348 static LONG WINAPI IRichEditOle_fnGetLinkCount(IRichEditOle *me)
1349 {
1350 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1351 FIXME("stub %p\n",This);
1352 return E_NOTIMPL;
1353 }
1354
1355 static HRESULT WINAPI
1356 IRichEditOle_fnGetObject(IRichEditOle *me, LONG iob,
1357 REOBJECT *lpreobject, DWORD dwFlags)
1358 {
1359 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1360 FIXME("stub %p\n",This);
1361 return E_NOTIMPL;
1362 }
1363
1364 static LONG WINAPI
1365 IRichEditOle_fnGetObjectCount(IRichEditOle *me)
1366 {
1367 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1368 FIXME("stub %p\n",This);
1369 return 0;
1370 }
1371
1372 static HRESULT WINAPI
1373 IRichEditOle_fnHandsOffStorage(IRichEditOle *me, LONG iob)
1374 {
1375 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1376 FIXME("stub %p\n",This);
1377 return E_NOTIMPL;
1378 }
1379
1380 static HRESULT WINAPI
1381 IRichEditOle_fnImportDataObject(IRichEditOle *me, LPDATAOBJECT lpdataobj,
1382 CLIPFORMAT cf, HGLOBAL hMetaPict)
1383 {
1384 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1385 FIXME("stub %p\n",This);
1386 return E_NOTIMPL;
1387 }
1388
1389 static HRESULT WINAPI
1390 IRichEditOle_fnInPlaceDeactivate(IRichEditOle *me)
1391 {
1392 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1393 FIXME("stub %p\n",This);
1394 return E_NOTIMPL;
1395 }
1396
1397 static HRESULT WINAPI
1398 IRichEditOle_fnInsertObject(IRichEditOle *me, REOBJECT *reo)
1399 {
1400 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1401
1402 TRACE("(%p,%p)\n", This, reo);
1403
1404 if (!reo)
1405 return E_INVALIDARG;
1406
1407 if (reo->cbStruct < sizeof(*reo)) return STG_E_INVALIDPARAMETER;
1408
1409 ME_InsertOLEFromCursor(This->editor, reo, 0);
1410 ME_CommitUndo(This->editor);
1411 ME_UpdateRepaint(This->editor, FALSE);
1412 return S_OK;
1413 }
1414
1415 static HRESULT WINAPI IRichEditOle_fnSaveCompleted(IRichEditOle *me, LONG iob,
1416 LPSTORAGE lpstg)
1417 {
1418 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1419 FIXME("stub %p\n",This);
1420 return E_NOTIMPL;
1421 }
1422
1423 static HRESULT WINAPI
1424 IRichEditOle_fnSetDvaspect(IRichEditOle *me, LONG iob, DWORD dvaspect)
1425 {
1426 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1427 FIXME("stub %p\n",This);
1428 return E_NOTIMPL;
1429 }
1430
1431 static HRESULT WINAPI IRichEditOle_fnSetHostNames(IRichEditOle *me,
1432 LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj)
1433 {
1434 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1435 FIXME("stub %p %s %s\n",This, lpstrContainerApp, lpstrContainerObj);
1436 return E_NOTIMPL;
1437 }
1438
1439 static HRESULT WINAPI
1440 IRichEditOle_fnSetLinkAvailable(IRichEditOle *me, LONG iob, BOOL fAvailable)
1441 {
1442 IRichEditOleImpl *This = impl_from_IRichEditOle(me);
1443 FIXME("stub %p\n",This);
1444 return E_NOTIMPL;
1445 }
1446
1447 static const IRichEditOleVtbl revt = {
1448 IRichEditOle_fnQueryInterface,
1449 IRichEditOle_fnAddRef,
1450 IRichEditOle_fnRelease,
1451 IRichEditOle_fnGetClientSite,
1452 IRichEditOle_fnGetObjectCount,
1453 IRichEditOle_fnGetLinkCount,
1454 IRichEditOle_fnGetObject,
1455 IRichEditOle_fnInsertObject,
1456 IRichEditOle_fnConvertObject,
1457 IRichEditOle_fnActivateAs,
1458 IRichEditOle_fnSetHostNames,
1459 IRichEditOle_fnSetLinkAvailable,
1460 IRichEditOle_fnSetDvaspect,
1461 IRichEditOle_fnHandsOffStorage,
1462 IRichEditOle_fnSaveCompleted,
1463 IRichEditOle_fnInPlaceDeactivate,
1464 IRichEditOle_fnContextSensitiveHelp,
1465 IRichEditOle_fnGetClipboardData,
1466 IRichEditOle_fnImportDataObject
1467 };
1468
1469 /* ITextRange interface */
1470 static HRESULT WINAPI ITextRange_fnQueryInterface(ITextRange *me, REFIID riid, void **ppvObj)
1471 {
1472 ITextRangeImpl *This = impl_from_ITextRange(me);
1473
1474 *ppvObj = NULL;
1475 if (IsEqualGUID(riid, &IID_IUnknown)
1476 || IsEqualGUID(riid, &IID_IDispatch)
1477 || IsEqualGUID(riid, &IID_ITextRange))
1478 {
1479 *ppvObj = me;
1480 ITextRange_AddRef(me);
1481 return S_OK;
1482 }
1483 else if (IsEqualGUID(riid, &IID_Igetrichole))
1484 {
1485 *ppvObj = This->child.reole;
1486 return S_OK;
1487 }
1488
1489 return E_NOINTERFACE;
1490 }
1491
1492 static ULONG WINAPI ITextRange_fnAddRef(ITextRange *me)
1493 {
1494 ITextRangeImpl *This = impl_from_ITextRange(me);
1495 return InterlockedIncrement(&This->ref);
1496 }
1497
1498 static ULONG WINAPI ITextRange_fnRelease(ITextRange *me)
1499 {
1500 ITextRangeImpl *This = impl_from_ITextRange(me);
1501 ULONG ref = InterlockedDecrement(&This->ref);
1502
1503 TRACE ("%p ref=%u\n", This, ref);
1504 if (ref == 0)
1505 {
1506 if (This->child.reole)
1507 {
1508 list_remove(&This->child.entry);
1509 This->child.reole = NULL;
1510 }
1511 heap_free(This);
1512 }
1513 return ref;
1514 }
1515
1516 static HRESULT WINAPI ITextRange_fnGetTypeInfoCount(ITextRange *me, UINT *pctinfo)
1517 {
1518 ITextRangeImpl *This = impl_from_ITextRange(me);
1519 TRACE("(%p)->(%p)\n", This, pctinfo);
1520 *pctinfo = 1;
1521 return S_OK;
1522 }
1523
1524 static HRESULT WINAPI ITextRange_fnGetTypeInfo(ITextRange *me, UINT iTInfo, LCID lcid,
1525 ITypeInfo **ppTInfo)
1526 {
1527 ITextRangeImpl *This = impl_from_ITextRange(me);
1528 HRESULT hr;
1529
1530 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
1531
1532 hr = get_typeinfo(ITextRange_tid, ppTInfo);
1533 if (SUCCEEDED(hr))
1534 ITypeInfo_AddRef(*ppTInfo);
1535 return hr;
1536 }
1537
1538 static HRESULT WINAPI ITextRange_fnGetIDsOfNames(ITextRange *me, REFIID riid, LPOLESTR *rgszNames,
1539 UINT cNames, LCID lcid, DISPID *rgDispId)
1540 {
1541 ITextRangeImpl *This = impl_from_ITextRange(me);
1542 ITypeInfo *ti;
1543 HRESULT hr;
1544
1545 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
1546 rgDispId);
1547
1548 hr = get_typeinfo(ITextRange_tid, &ti);
1549 if (SUCCEEDED(hr))
1550 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
1551 return hr;
1552 }
1553
1554 static HRESULT WINAPI ITextRange_fnInvoke(ITextRange *me, DISPID dispIdMember, REFIID riid,
1555 LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1556 VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
1557 UINT *puArgErr)
1558 {
1559 ITextRangeImpl *This = impl_from_ITextRange(me);
1560 ITypeInfo *ti;
1561 HRESULT hr;
1562
1563 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
1564 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1565
1566 hr = get_typeinfo(ITextRange_tid, &ti);
1567 if (SUCCEEDED(hr))
1568 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1569 return hr;
1570 }
1571
1572 static HRESULT WINAPI ITextRange_fnGetText(ITextRange *me, BSTR *str)
1573 {
1574 ITextRangeImpl *This = impl_from_ITextRange(me);
1575 ME_TextEditor *editor;
1576 ME_Cursor start, end;
1577 int length;
1578 BOOL bEOP;
1579
1580 TRACE("(%p)->(%p)\n", This, str);
1581
1582 if (!This->child.reole)
1583 return CO_E_RELEASED;
1584
1585 if (!str)
1586 return E_INVALIDARG;
1587
1588 /* return early for degenerate range */
1589 if (This->start == This->end) {
1590 *str = NULL;
1591 return S_OK;
1592 }
1593
1594 editor = This->child.reole->editor;
1595 ME_CursorFromCharOfs(editor, This->start, &start);
1596 ME_CursorFromCharOfs(editor, This->end, &end);
1597
1598 length = This->end - This->start;
1599 *str = SysAllocStringLen(NULL, length);
1600 if (!*str)
1601 return E_OUTOFMEMORY;
1602
1603 bEOP = (end.pRun->next->type == diTextEnd && This->end > ME_GetTextLength(editor));
1604 ME_GetTextW(editor, *str, length, &start, length, FALSE, bEOP);
1605 return S_OK;
1606 }
1607
1608 static HRESULT WINAPI ITextRange_fnSetText(ITextRange *me, BSTR str)
1609 {
1610 ITextRangeImpl *This = impl_from_ITextRange(me);
1611 ME_TextEditor *editor;
1612 ME_Cursor cursor;
1613 ME_Style *style;
1614 int len;
1615
1616 TRACE("(%p)->(%s)\n", This, debugstr_w(str));
1617
1618 if (!This->child.reole)
1619 return CO_E_RELEASED;
1620
1621 editor = This->child.reole->editor;
1622
1623 /* delete only where's something to delete */
1624 if (This->start != This->end) {
1625 ME_CursorFromCharOfs(editor, This->start, &cursor);
1626 ME_InternalDeleteText(editor, &cursor, This->end - This->start, FALSE);
1627 }
1628
1629 if (!str || !*str) {
1630 /* will update this range as well */
1631 textranges_update_ranges(This->child.reole, This->start, This->end, RANGE_UPDATE_DELETE);
1632 return S_OK;
1633 }
1634
1635 /* it's safer not to rely on stored BSTR length */
1636 len = strlenW(str);
1637 cursor = editor->pCursors[0];
1638 ME_CursorFromCharOfs(editor, This->start, &editor->pCursors[0]);
1639 style = ME_GetInsertStyle(editor, 0);
1640 ME_InsertTextFromCursor(editor, 0, str, len, style);
1641 ME_ReleaseStyle(style);
1642 editor->pCursors[0] = cursor;
1643
1644 if (len < This->end - This->start)
1645 textranges_update_ranges(This->child.reole, This->start + len, This->end, RANGE_UPDATE_DELETE);
1646 else
1647 This->end = len - This->start;
1648
1649 return S_OK;
1650 }
1651
1652 static HRESULT range_GetChar(ME_TextEditor *editor, ME_Cursor *cursor, LONG *pch)
1653 {
1654 WCHAR wch[2];
1655
1656 ME_GetTextW(editor, wch, 1, cursor, 1, FALSE, cursor->pRun->next->type == diTextEnd);
1657 *pch = wch[0];
1658
1659 return S_OK;
1660 }
1661
1662 static HRESULT WINAPI ITextRange_fnGetChar(ITextRange *me, LONG *pch)
1663 {
1664 ITextRangeImpl *This = impl_from_ITextRange(me);
1665 ME_TextEditor *editor;
1666 ME_Cursor cursor;
1667
1668 TRACE("(%p)->(%p)\n", This, pch);
1669
1670 if (!This->child.reole)
1671 return CO_E_RELEASED;
1672
1673 if (!pch)
1674 return E_INVALIDARG;
1675
1676 editor = This->child.reole->editor;
1677 ME_CursorFromCharOfs(editor, This->start, &cursor);
1678 return range_GetChar(editor, &cursor, pch);
1679 }
1680
1681 static HRESULT WINAPI ITextRange_fnSetChar(ITextRange *me, LONG ch)
1682 {
1683 ITextRangeImpl *This = impl_from_ITextRange(me);
1684
1685 FIXME("(%p)->(%x): stub\n", This, ch);
1686
1687 if (!This->child.reole)
1688 return CO_E_RELEASED;
1689
1690 return E_NOTIMPL;
1691 }
1692
1693 static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, ITextRange** ppRange);
1694
1695 static HRESULT WINAPI ITextRange_fnGetDuplicate(ITextRange *me, ITextRange **ppRange)
1696 {
1697 ITextRangeImpl *This = impl_from_ITextRange(me);
1698
1699 TRACE("(%p)->(%p)\n", This, ppRange);
1700
1701 if (!This->child.reole)
1702 return CO_E_RELEASED;
1703
1704 if (!ppRange)
1705 return E_INVALIDARG;
1706
1707 return CreateITextRange(This->child.reole, This->start, This->end, ppRange);
1708 }
1709
1710 static HRESULT WINAPI ITextRange_fnGetFormattedText(ITextRange *me, ITextRange **range)
1711 {
1712 ITextRangeImpl *This = impl_from_ITextRange(me);
1713
1714 FIXME("(%p)->(%p): stub\n", This, range);
1715
1716 if (!This->child.reole)
1717 return CO_E_RELEASED;
1718
1719 return E_NOTIMPL;
1720 }
1721
1722 static HRESULT WINAPI ITextRange_fnSetFormattedText(ITextRange *me, ITextRange *range)
1723 {
1724 ITextRangeImpl *This = impl_from_ITextRange(me);
1725
1726 FIXME("(%p)->(%p): stub\n", This, range);
1727
1728 if (!This->child.reole)
1729 return CO_E_RELEASED;
1730
1731 return E_NOTIMPL;
1732 }
1733
1734 static HRESULT WINAPI ITextRange_fnGetStart(ITextRange *me, LONG *start)
1735 {
1736 ITextRangeImpl *This = impl_from_ITextRange(me);
1737
1738 TRACE("(%p)->(%p)\n", This, start);
1739
1740 if (!This->child.reole)
1741 return CO_E_RELEASED;
1742
1743 if (!start)
1744 return E_INVALIDARG;
1745
1746 *start = This->start;
1747 return S_OK;
1748 }
1749
1750 static HRESULT textrange_setstart(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end)
1751 {
1752 int len;
1753
1754 if (value < 0)
1755 value = 0;
1756
1757 if (value == *start)
1758 return S_FALSE;
1759
1760 if (value <= *end) {
1761 *start = value;
1762 return S_OK;
1763 }
1764
1765 len = ME_GetTextLength(reole->editor);
1766 *start = *end = value > len ? len : value;
1767 return S_OK;
1768 }
1769
1770 static HRESULT WINAPI ITextRange_fnSetStart(ITextRange *me, LONG value)
1771 {
1772 ITextRangeImpl *This = impl_from_ITextRange(me);
1773
1774 TRACE("(%p)->(%d)\n", This, value);
1775
1776 if (!This->child.reole)
1777 return CO_E_RELEASED;
1778
1779 return textrange_setstart(This->child.reole, value, &This->start, &This->end);
1780 }
1781
1782 static HRESULT WINAPI ITextRange_fnGetEnd(ITextRange *me, LONG *end)
1783 {
1784 ITextRangeImpl *This = impl_from_ITextRange(me);
1785
1786 TRACE("(%p)->(%p)\n", This, end);
1787
1788 if (!This->child.reole)
1789 return CO_E_RELEASED;
1790
1791 if (!end)
1792 return E_INVALIDARG;
1793
1794 *end = This->end;
1795 return S_OK;
1796 }
1797
1798 static HRESULT textrange_setend(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end)
1799 {
1800 int len;
1801
1802 if (value == *end)
1803 return S_FALSE;
1804
1805 if (value < *start) {
1806 *start = *end = max(0, value);
1807 return S_OK;
1808 }
1809
1810 len = ME_GetTextLength(reole->editor);
1811 *end = value > len ? len + 1 : value;
1812 return S_OK;
1813 }
1814
1815 static HRESULT WINAPI ITextRange_fnSetEnd(ITextRange *me, LONG value)
1816 {
1817 ITextRangeImpl *This = impl_from_ITextRange(me);
1818
1819 TRACE("(%p)->(%d)\n", This, value);
1820
1821 if (!This->child.reole)
1822 return CO_E_RELEASED;
1823
1824 return textrange_setend(This->child.reole, value, &This->start, &This->end);
1825 }
1826
1827 static HRESULT WINAPI ITextRange_fnGetFont(ITextRange *me, ITextFont **font)
1828 {
1829 ITextRangeImpl *This = impl_from_ITextRange(me);
1830
1831 TRACE("(%p)->(%p)\n", This, font);
1832
1833 if (!This->child.reole)
1834 return CO_E_RELEASED;
1835
1836 if (!font)
1837 return E_INVALIDARG;
1838
1839 return create_textfont(me, NULL, font);
1840 }
1841
1842 static HRESULT WINAPI ITextRange_fnSetFont(ITextRange *me, ITextFont *font)
1843 {
1844 ITextRangeImpl *This = impl_from_ITextRange(me);
1845
1846 TRACE("(%p)->(%p)\n", This, font);
1847
1848 if (!font)
1849 return E_INVALIDARG;
1850
1851 if (!This->child.reole)
1852 return CO_E_RELEASED;
1853
1854 textrange_set_font(me, font);
1855 return S_OK;
1856 }
1857
1858 static HRESULT WINAPI ITextRange_fnGetPara(ITextRange *me, ITextPara **para)
1859 {
1860 ITextRangeImpl *This = impl_from_ITextRange(me);
1861
1862 TRACE("(%p)->(%p)\n", This, para);
1863
1864 if (!This->child.reole)
1865 return CO_E_RELEASED;
1866
1867 if (!para)
1868 return E_INVALIDARG;
1869
1870 return create_textpara(me, para);
1871 }
1872
1873 static HRESULT WINAPI ITextRange_fnSetPara(ITextRange *me, ITextPara *para)
1874 {
1875 ITextRangeImpl *This = impl_from_ITextRange(me);
1876
1877 FIXME("(%p)->(%p): stub\n", This, para);
1878
1879 if (!This->child.reole)
1880 return CO_E_RELEASED;
1881
1882 return E_NOTIMPL;
1883 }
1884
1885 static HRESULT WINAPI ITextRange_fnGetStoryLength(ITextRange *me, LONG *length)
1886 {
1887 ITextRangeImpl *This = impl_from_ITextRange(me);
1888
1889 TRACE("(%p)->(%p)\n", This, length);
1890
1891 if (!This->child.reole)
1892 return CO_E_RELEASED;
1893
1894 return textrange_get_storylength(This->child.reole->editor, length);
1895 }
1896
1897 static HRESULT WINAPI ITextRange_fnGetStoryType(ITextRange *me, LONG *value)
1898 {
1899 ITextRangeImpl *This = impl_from_ITextRange(me);
1900
1901 TRACE("(%p)->(%p)\n", This, value);
1902
1903 if (!This->child.reole)
1904 return CO_E_RELEASED;
1905
1906 if (!value)
1907 return E_INVALIDARG;
1908
1909 *value = tomUnknownStory;
1910 return S_OK;
1911 }
1912
1913 static HRESULT range_Collapse(LONG bStart, LONG *start, LONG *end)
1914 {
1915 if (*end == *start)
1916 return S_FALSE;
1917
1918 if (bStart == tomEnd)
1919 *start = *end;
1920 else
1921 *end = *start;
1922 return S_OK;
1923 }
1924
1925 static HRESULT WINAPI ITextRange_fnCollapse(ITextRange *me, LONG bStart)
1926 {
1927 ITextRangeImpl *This = impl_from_ITextRange(me);
1928
1929 TRACE("(%p)->(%d)\n", This, bStart);
1930
1931 if (!This->child.reole)
1932 return CO_E_RELEASED;
1933
1934 return range_Collapse(bStart, &This->start, &This->end);
1935 }
1936
1937 static HRESULT WINAPI ITextRange_fnExpand(ITextRange *me, LONG unit, LONG *delta)
1938 {
1939 ITextRangeImpl *This = impl_from_ITextRange(me);
1940
1941 TRACE("(%p)->(%d %p)\n", This, unit, delta);
1942
1943 if (!This->child.reole)
1944 return CO_E_RELEASED;
1945
1946 return textrange_expand(me, unit, delta);
1947 }
1948
1949 static HRESULT WINAPI ITextRange_fnGetIndex(ITextRange *me, LONG unit, LONG *index)
1950 {
1951 ITextRangeImpl *This = impl_from_ITextRange(me);
1952
1953 FIXME("(%p)->(%d %p): stub\n", This, unit, index);
1954
1955 if (!This->child.reole)
1956 return CO_E_RELEASED;
1957
1958 return E_NOTIMPL;
1959 }
1960
1961 static HRESULT WINAPI ITextRange_fnSetIndex(ITextRange *me, LONG unit, LONG index,
1962 LONG extend)
1963 {
1964 ITextRangeImpl *This = impl_from_ITextRange(me);
1965
1966 FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend);
1967
1968 if (!This->child.reole)
1969 return CO_E_RELEASED;
1970
1971 return E_NOTIMPL;
1972 }
1973
1974 static HRESULT WINAPI ITextRange_fnSetRange(ITextRange *me, LONG anchor, LONG active)
1975 {
1976 ITextRangeImpl *This = impl_from_ITextRange(me);
1977
1978 FIXME("(%p)->(%d %d): stub\n", This, anchor, active);
1979
1980 if (!This->child.reole)
1981 return CO_E_RELEASED;
1982
1983 return E_NOTIMPL;
1984 }
1985
1986 static HRESULT textrange_inrange(LONG start, LONG end, ITextRange *range, LONG *ret)
1987 {
1988 LONG from, to, v;
1989
1990 if (!ret)
1991 ret = &v;
1992
1993 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
1994 *ret = tomFalse;
1995 }
1996 else
1997 *ret = (start >= from && end <= to) ? tomTrue : tomFalse;
1998 return *ret == tomTrue ? S_OK : S_FALSE;
1999 }
2000
2001 static HRESULT WINAPI ITextRange_fnInRange(ITextRange *me, ITextRange *range, LONG *ret)
2002 {
2003 ITextRangeImpl *This = impl_from_ITextRange(me);
2004
2005 TRACE("(%p)->(%p %p)\n", This, range, ret);
2006
2007 if (ret)
2008 *ret = tomFalse;
2009
2010 if (!This->child.reole)
2011 return CO_E_RELEASED;
2012
2013 if (!range)
2014 return S_FALSE;
2015
2016 return textrange_inrange(This->start, This->end, range, ret);
2017 }
2018
2019 static HRESULT WINAPI ITextRange_fnInStory(ITextRange *me, ITextRange *pRange, LONG *ret)
2020 {
2021 ITextRangeImpl *This = impl_from_ITextRange(me);
2022
2023 FIXME("(%p)->(%p): stub\n", This, ret);
2024
2025 if (!This->child.reole)
2026 return CO_E_RELEASED;
2027
2028 return E_NOTIMPL;
2029 }
2030
2031 static HRESULT textrange_isequal(LONG start, LONG end, ITextRange *range, LONG *ret)
2032 {
2033 LONG from, to, v;
2034
2035 if (!ret)
2036 ret = &v;
2037
2038 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
2039 *ret = tomFalse;
2040 }
2041 else
2042 *ret = (start == from && end == to) ? tomTrue : tomFalse;
2043 return *ret == tomTrue ? S_OK : S_FALSE;
2044 }
2045
2046 static HRESULT WINAPI ITextRange_fnIsEqual(ITextRange *me, ITextRange *range, LONG *ret)
2047 {
2048 ITextRangeImpl *This = impl_from_ITextRange(me);
2049
2050 TRACE("(%p)->(%p %p)\n", This, range, ret);
2051
2052 if (ret)
2053 *ret = tomFalse;
2054
2055 if (!This->child.reole)
2056 return CO_E_RELEASED;
2057
2058 if (!range)
2059 return S_FALSE;
2060
2061 return textrange_isequal(This->start, This->end, range, ret);
2062 }
2063
2064 static HRESULT WINAPI ITextRange_fnSelect(ITextRange *me)
2065 {
2066 ITextRangeImpl *This = impl_from_ITextRange(me);
2067
2068 TRACE("(%p)\n", This);
2069
2070 if (!This->child.reole)
2071 return CO_E_RELEASED;
2072
2073 ME_SetSelection(This->child.reole->editor, This->start, This->end);
2074 return S_OK;
2075 }
2076
2077 static HRESULT WINAPI ITextRange_fnStartOf(ITextRange *me, LONG unit, LONG extend,
2078 LONG *delta)
2079 {
2080 ITextRangeImpl *This = impl_from_ITextRange(me);
2081
2082 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
2083
2084 if (!This->child.reole)
2085 return CO_E_RELEASED;
2086
2087 return E_NOTIMPL;
2088 }
2089
2090 static HRESULT WINAPI ITextRange_fnEndOf(ITextRange *me, LONG unit, LONG extend,
2091 LONG *delta)
2092 {
2093 ITextRangeImpl *This = impl_from_ITextRange(me);
2094
2095 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
2096
2097 if (!This->child.reole)
2098 return CO_E_RELEASED;
2099
2100 return E_NOTIMPL;
2101 }
2102
2103 static HRESULT WINAPI ITextRange_fnMove(ITextRange *me, LONG unit, LONG count, LONG *delta)
2104 {
2105 ITextRangeImpl *This = impl_from_ITextRange(me);
2106
2107 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2108
2109 if (!This->child.reole)
2110 return CO_E_RELEASED;
2111
2112 return E_NOTIMPL;
2113 }
2114
2115 static HRESULT WINAPI ITextRange_fnMoveStart(ITextRange *me, LONG unit, LONG count,
2116 LONG *delta)
2117 {
2118 ITextRangeImpl *This = impl_from_ITextRange(me);
2119
2120 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2121
2122 if (!This->child.reole)
2123 return CO_E_RELEASED;
2124
2125 return E_NOTIMPL;
2126 }
2127
2128 static HRESULT WINAPI ITextRange_fnMoveEnd(ITextRange *me, LONG unit, LONG count,
2129 LONG *delta)
2130 {
2131 ITextRangeImpl *This = impl_from_ITextRange(me);
2132
2133 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2134
2135 if (!This->child.reole)
2136 return CO_E_RELEASED;
2137
2138 return E_NOTIMPL;
2139 }
2140
2141 static HRESULT WINAPI ITextRange_fnMoveWhile(ITextRange *me, VARIANT *charset, LONG count,
2142 LONG *delta)
2143 {
2144 ITextRangeImpl *This = impl_from_ITextRange(me);
2145
2146 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2147
2148 if (!This->child.reole)
2149 return CO_E_RELEASED;
2150
2151 return E_NOTIMPL;
2152 }
2153
2154 static HRESULT WINAPI ITextRange_fnMoveStartWhile(ITextRange *me, VARIANT *charset, LONG count,
2155 LONG *delta)
2156 {
2157 ITextRangeImpl *This = impl_from_ITextRange(me);
2158
2159 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2160
2161 if (!This->child.reole)
2162 return CO_E_RELEASED;
2163
2164 return E_NOTIMPL;
2165 }
2166
2167 static HRESULT WINAPI ITextRange_fnMoveEndWhile(ITextRange *me, VARIANT *charset, LONG count,
2168 LONG *delta)
2169 {
2170 ITextRangeImpl *This = impl_from_ITextRange(me);
2171
2172 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2173
2174 if (!This->child.reole)
2175 return CO_E_RELEASED;
2176
2177 return E_NOTIMPL;
2178 }
2179
2180 static HRESULT WINAPI ITextRange_fnMoveUntil(ITextRange *me, VARIANT *charset, LONG count,
2181 LONG *delta)
2182 {
2183 ITextRangeImpl *This = impl_from_ITextRange(me);
2184
2185 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2186
2187 if (!This->child.reole)
2188 return CO_E_RELEASED;
2189
2190 return E_NOTIMPL;
2191 }
2192
2193 static HRESULT WINAPI ITextRange_fnMoveStartUntil(ITextRange *me, VARIANT *charset, LONG count,
2194 LONG *delta)
2195 {
2196 ITextRangeImpl *This = impl_from_ITextRange(me);
2197
2198 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2199
2200 if (!This->child.reole)
2201 return CO_E_RELEASED;
2202
2203 return E_NOTIMPL;
2204 }
2205
2206 static HRESULT WINAPI ITextRange_fnMoveEndUntil(ITextRange *me, VARIANT *charset, LONG count,
2207 LONG *delta)
2208 {
2209 ITextRangeImpl *This = impl_from_ITextRange(me);
2210
2211 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2212
2213 if (!This->child.reole)
2214 return CO_E_RELEASED;
2215
2216 return E_NOTIMPL;
2217 }
2218
2219 static HRESULT WINAPI ITextRange_fnFindText(ITextRange *me, BSTR text, LONG count, LONG flags,
2220 LONG *length)
2221 {
2222 ITextRangeImpl *This = impl_from_ITextRange(me);
2223
2224 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2225
2226 if (!This->child.reole)
2227 return CO_E_RELEASED;
2228
2229 return E_NOTIMPL;
2230 }
2231
2232 static HRESULT WINAPI ITextRange_fnFindTextStart(ITextRange *me, BSTR text, LONG count,
2233 LONG flags, LONG *length)
2234 {
2235 ITextRangeImpl *This = impl_from_ITextRange(me);
2236
2237 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2238
2239 if (!This->child.reole)
2240 return CO_E_RELEASED;
2241
2242 return E_NOTIMPL;
2243 }
2244
2245 static HRESULT WINAPI ITextRange_fnFindTextEnd(ITextRange *me, BSTR text, LONG count,
2246 LONG flags, LONG *length)
2247 {
2248 ITextRangeImpl *This = impl_from_ITextRange(me);
2249
2250 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2251
2252 if (!This->child.reole)
2253 return CO_E_RELEASED;
2254
2255 return E_NOTIMPL;
2256 }
2257
2258 static HRESULT WINAPI ITextRange_fnDelete(ITextRange *me, LONG unit, LONG count, LONG *delta)
2259 {
2260 ITextRangeImpl *This = impl_from_ITextRange(me);
2261
2262 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2263
2264 if (!This->child.reole)
2265 return CO_E_RELEASED;
2266
2267 return E_NOTIMPL;
2268 }
2269
2270 static HRESULT WINAPI ITextRange_fnCut(ITextRange *me, VARIANT *v)
2271 {
2272 ITextRangeImpl *This = impl_from_ITextRange(me);
2273
2274 FIXME("(%p)->(%p): stub\n", This, v);
2275
2276 if (!This->child.reole)
2277 return CO_E_RELEASED;
2278
2279 return E_NOTIMPL;
2280 }
2281
2282 static HRESULT WINAPI ITextRange_fnCopy(ITextRange *me, VARIANT *v)
2283 {
2284 ITextRangeImpl *This = impl_from_ITextRange(me);
2285
2286 FIXME("(%p)->(%p): stub\n", This, v);
2287
2288 if (!This->child.reole)
2289 return CO_E_RELEASED;
2290
2291 return E_NOTIMPL;
2292 }
2293
2294 static HRESULT WINAPI ITextRange_fnPaste(ITextRange *me, VARIANT *v, LONG format)
2295 {
2296 ITextRangeImpl *This = impl_from_ITextRange(me);
2297
2298 FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format);
2299
2300 if (!This->child.reole)
2301 return CO_E_RELEASED;
2302
2303 return E_NOTIMPL;
2304 }
2305
2306 static HRESULT WINAPI ITextRange_fnCanPaste(ITextRange *me, VARIANT *v, LONG format, LONG *ret)
2307 {
2308 ITextRangeImpl *This = impl_from_ITextRange(me);
2309
2310 FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret);
2311
2312 if (!This->child.reole)
2313 return CO_E_RELEASED;
2314
2315 return E_NOTIMPL;
2316 }
2317
2318 static HRESULT WINAPI ITextRange_fnCanEdit(ITextRange *me, LONG *ret)
2319 {
2320 ITextRangeImpl *This = impl_from_ITextRange(me);
2321
2322 FIXME("(%p)->(%p): stub\n", This, ret);
2323
2324 if (!This->child.reole)
2325 return CO_E_RELEASED;
2326
2327 return E_NOTIMPL;
2328 }
2329
2330 static HRESULT WINAPI ITextRange_fnChangeCase(ITextRange *me, LONG type)
2331 {
2332 ITextRangeImpl *This = impl_from_ITextRange(me);
2333
2334 FIXME("(%p)->(%d): stub\n", This, type);
2335
2336 if (!This->child.reole)
2337 return CO_E_RELEASED;
2338
2339 return E_NOTIMPL;
2340 }
2341
2342 static HRESULT WINAPI ITextRange_fnGetPoint(ITextRange *me, LONG type, LONG *cx, LONG *cy)
2343 {
2344 ITextRangeImpl *This = impl_from_ITextRange(me);
2345
2346 FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy);
2347
2348 if (!This->child.reole)
2349 return CO_E_RELEASED;
2350
2351 return E_NOTIMPL;
2352 }
2353
2354 static HRESULT WINAPI ITextRange_fnSetPoint(ITextRange *me, LONG x, LONG y, LONG type,
2355 LONG extend)
2356 {
2357 ITextRangeImpl *This = impl_from_ITextRange(me);
2358
2359 FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend);
2360
2361 if (!This->child.reole)
2362 return CO_E_RELEASED;
2363
2364 return E_NOTIMPL;
2365 }
2366
2367 static HRESULT WINAPI ITextRange_fnScrollIntoView(ITextRange *me, LONG value)
2368 {
2369 ITextRangeImpl *This = impl_from_ITextRange(me);
2370 ME_TextEditor *editor;
2371 ME_Cursor cursor;
2372 int x, y, height;
2373
2374 TRACE("(%p)->(%d)\n", This, value);
2375
2376 if (!This->child.reole)
2377 return CO_E_RELEASED;
2378
2379 editor = This->child.reole->editor;
2380
2381 switch (value)
2382 {
2383 case tomStart:
2384 ME_CursorFromCharOfs(editor, This->start, &cursor);
2385 ME_GetCursorCoordinates(editor, &cursor, &x, &y, &height);
2386 break;
2387 default:
2388 FIXME("bStart value %d not handled\n", value);
2389 return E_NOTIMPL;
2390 }
2391 ME_ScrollAbs(editor, x, y);
2392 return S_OK;
2393 }
2394
2395 static HRESULT WINAPI ITextRange_fnGetEmbeddedObject(ITextRange *me, IUnknown **ppv)
2396 {
2397 ITextRangeImpl *This = impl_from_ITextRange(me);
2398
2399 FIXME("(%p)->(%p): stub\n", This, ppv);
2400
2401 if (!This->child.reole)
2402 return CO_E_RELEASED;
2403
2404 return E_NOTIMPL;
2405 }
2406
2407 static const ITextRangeVtbl trvt = {
2408 ITextRange_fnQueryInterface,
2409 ITextRange_fnAddRef,
2410 ITextRange_fnRelease,
2411 ITextRange_fnGetTypeInfoCount,
2412 ITextRange_fnGetTypeInfo,
2413 ITextRange_fnGetIDsOfNames,
2414 ITextRange_fnInvoke,
2415 ITextRange_fnGetText,
2416 ITextRange_fnSetText,
2417 ITextRange_fnGetChar,
2418 ITextRange_fnSetChar,
2419 ITextRange_fnGetDuplicate,
2420 ITextRange_fnGetFormattedText,
2421 ITextRange_fnSetFormattedText,
2422 ITextRange_fnGetStart,
2423 ITextRange_fnSetStart,
2424 ITextRange_fnGetEnd,
2425 ITextRange_fnSetEnd,
2426 ITextRange_fnGetFont,
2427 ITextRange_fnSetFont,
2428 ITextRange_fnGetPara,
2429 ITextRange_fnSetPara,
2430 ITextRange_fnGetStoryLength,
2431 ITextRange_fnGetStoryType,
2432 ITextRange_fnCollapse,
2433 ITextRange_fnExpand,
2434 ITextRange_fnGetIndex,
2435 ITextRange_fnSetIndex,
2436 ITextRange_fnSetRange,
2437 ITextRange_fnInRange,
2438 ITextRange_fnInStory,
2439 ITextRange_fnIsEqual,
2440 ITextRange_fnSelect,
2441 ITextRange_fnStartOf,
2442 ITextRange_fnEndOf,
2443 ITextRange_fnMove,
2444 ITextRange_fnMoveStart,
2445 ITextRange_fnMoveEnd,
2446 ITextRange_fnMoveWhile,
2447 ITextRange_fnMoveStartWhile,
2448 ITextRange_fnMoveEndWhile,
2449 ITextRange_fnMoveUntil,
2450 ITextRange_fnMoveStartUntil,
2451 ITextRange_fnMoveEndUntil,
2452 ITextRange_fnFindText,
2453 ITextRange_fnFindTextStart,
2454 ITextRange_fnFindTextEnd,
2455 ITextRange_fnDelete,
2456 ITextRange_fnCut,
2457 ITextRange_fnCopy,
2458 ITextRange_fnPaste,
2459 ITextRange_fnCanPaste,
2460 ITextRange_fnCanEdit,
2461 ITextRange_fnChangeCase,
2462 ITextRange_fnGetPoint,
2463 ITextRange_fnSetPoint,
2464 ITextRange_fnScrollIntoView,
2465 ITextRange_fnGetEmbeddedObject
2466 };
2467
2468 /* ITextFont */
2469 static HRESULT WINAPI TextFont_QueryInterface(ITextFont *iface, REFIID riid, void **ppv)
2470 {
2471 ITextFontImpl *This = impl_from_ITextFont(iface);
2472
2473 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
2474
2475 if (IsEqualIID(riid, &IID_ITextFont) ||
2476 IsEqualIID(riid, &IID_IDispatch) ||
2477 IsEqualIID(riid, &IID_IUnknown))
2478 {
2479 *ppv = iface;
2480 ITextFont_AddRef(iface);
2481 return S_OK;
2482 }
2483
2484 *ppv = NULL;
2485 return E_NOINTERFACE;
2486 }
2487
2488 static ULONG WINAPI TextFont_AddRef(ITextFont *iface)
2489 {
2490 ITextFontImpl *This = impl_from_ITextFont(iface);
2491 ULONG ref = InterlockedIncrement(&This->ref);
2492 TRACE("(%p)->(%u)\n", This, ref);
2493 return ref;
2494 }
2495
2496 static ULONG WINAPI TextFont_Release(ITextFont *iface)
2497 {
2498 ITextFontImpl *This = impl_from_ITextFont(iface);
2499 ULONG ref = InterlockedDecrement(&This->ref);
2500
2501 TRACE("(%p)->(%u)\n", This, ref);
2502
2503 if (!ref)
2504 {
2505 if (This->range)
2506 ITextRange_Release(This->range);
2507 SysFreeString(This->props[FONT_NAME].str);
2508 heap_free(This);
2509 }
2510
2511 return ref;
2512 }
2513
2514 static HRESULT WINAPI TextFont_GetTypeInfoCount(ITextFont *iface, UINT *pctinfo)
2515 {
2516 ITextFontImpl *This = impl_from_ITextFont(iface);
2517 TRACE("(%p)->(%p)\n", This, pctinfo);
2518 *pctinfo = 1;
2519 return S_OK;
2520 }
2521
2522 static HRESULT WINAPI TextFont_GetTypeInfo(ITextFont *iface, UINT iTInfo, LCID lcid,
2523 ITypeInfo **ppTInfo)
2524 {
2525 ITextFontImpl *This = impl_from_ITextFont(iface);
2526 HRESULT hr;
2527
2528 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
2529
2530 hr = get_typeinfo(ITextFont_tid, ppTInfo);
2531 if (SUCCEEDED(hr))
2532 ITypeInfo_AddRef(*ppTInfo);
2533 return hr;
2534 }
2535
2536 static HRESULT WINAPI TextFont_GetIDsOfNames(ITextFont *iface, REFIID riid,
2537 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
2538 {
2539 ITextFontImpl *This = impl_from_ITextFont(iface);
2540 ITypeInfo *ti;
2541 HRESULT hr;
2542
2543 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid),
2544 rgszNames, cNames, lcid, rgDispId);
2545
2546 hr = get_typeinfo(ITextFont_tid, &ti);
2547 if (SUCCEEDED(hr))
2548 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
2549 return hr;
2550 }
2551
2552 static HRESULT WINAPI TextFont_Invoke(
2553 ITextFont *iface,
2554 DISPID dispIdMember,
2555 REFIID riid,
2556 LCID lcid,
2557 WORD wFlags,
2558 DISPPARAMS *pDispParams,
2559 VARIANT *pVarResult,
2560 EXCEPINFO *pExcepInfo,
2561 UINT *puArgErr)
2562 {
2563 ITextFontImpl *This = impl_from_ITextFont(iface);
2564 ITypeInfo *ti;
2565 HRESULT hr;
2566
2567 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
2568 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2569
2570 hr = get_typeinfo(ITextFont_tid, &ti);
2571 if (SUCCEEDED(hr))
2572 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2573 return hr;
2574 }
2575
2576 static HRESULT WINAPI TextFont_GetDuplicate(ITextFont *iface, ITextFont **ret)
2577 {
2578 ITextFontImpl *This = impl_from_ITextFont(iface);
2579
2580 TRACE("(%p)->(%p)\n", This, ret);
2581
2582 if (!ret)
2583 return E_INVALIDARG;
2584
2585 *ret = NULL;
2586 if (This->range && !get_range_reole(This->range))
2587 return CO_E_RELEASED;
2588
2589 return create_textfont(NULL, This, ret);
2590 }
2591
2592 static HRESULT WINAPI TextFont_SetDuplicate(ITextFont *iface, ITextFont *pFont)
2593 {
2594 ITextFontImpl *This = impl_from_ITextFont(iface);
2595 FIXME("(%p)->(%p): stub\n", This, pFont);
2596 return E_NOTIMPL;
2597 }
2598
2599 static HRESULT WINAPI TextFont_CanChange(ITextFont *iface, LONG *ret)
2600 {
2601 ITextFontImpl *This = impl_from_ITextFont(iface);
2602 FIXME("(%p)->(%p): stub\n", This, ret);
2603 return E_NOTIMPL;
2604 }
2605
2606 static HRESULT WINAPI TextFont_IsEqual(ITextFont *iface, ITextFont *font, LONG *ret)
2607 {
2608 ITextFontImpl *This = impl_from_ITextFont(iface);
2609 FIXME("(%p)->(%p %p): stub\n", This, font, ret);
2610 return E_NOTIMPL;
2611 }
2612
2613 static void textfont_reset_to_default(ITextFontImpl *font)
2614 {
2615 enum textfont_prop_id id;
2616
2617 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2618 switch (id)
2619 {
2620 case FONT_ALLCAPS:
2621 case FONT_ANIMATION:
2622 case FONT_BOLD:
2623 case FONT_EMBOSS:
2624 case FONT_HIDDEN:
2625 case FONT_ENGRAVE:
2626 case FONT_ITALIC:
2627 case FONT_OUTLINE:
2628 case FONT_PROTECTED:
2629 case FONT_SHADOW:
2630 case FONT_SMALLCAPS:
2631 case FONT_STRIKETHROUGH:
2632 case FONT_SUBSCRIPT:
2633 case FONT_SUPERSCRIPT:
2634 case FONT_UNDERLINE:
2635 font->props[id].l = tomFalse;
2636 break;
2637 case FONT_BACKCOLOR:
2638 case FONT_FORECOLOR:
2639 font->props[id].l = tomAutoColor;
2640 break;
2641 case FONT_KERNING:
2642 case FONT_POSITION:
2643 case FONT_SIZE:
2644 case FONT_SPACING:
2645 font->props[id].f = 0.0;
2646 break;
2647 case FONT_LANGID:
2648 font->props[id].l = GetSystemDefaultLCID();
2649 break;
2650 case FONT_NAME: {
2651 static const WCHAR sysW[] = {'S','y','s','t','e','m',0};
2652 SysFreeString(font->props[id].str);
2653 font->props[id].str = SysAllocString(sysW);
2654 break;
2655 }
2656 case FONT_WEIGHT:
2657 font->props[id].l = FW_NORMAL;
2658 break;
2659 default:
2660 FIXME("font property %d not handled\n", id);
2661 }
2662 }
2663 }
2664
2665 static void textfont_reset_to_undefined(ITextFontImpl *font)
2666 {
2667 enum textfont_prop_id id;
2668
2669 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2670 switch (id)
2671 {
2672 case FONT_ALLCAPS:
2673 case FONT_ANIMATION:
2674 case FONT_BOLD:
2675 case FONT_EMBOSS:
2676 case FONT_HIDDEN:
2677 case FONT_ENGRAVE:
2678 case FONT_ITALIC:
2679 case FONT_OUTLINE:
2680 case FONT_PROTECTED:
2681 case FONT_SHADOW:
2682 case FONT_SMALLCAPS:
2683 case FONT_STRIKETHROUGH:
2684 case FONT_SUBSCRIPT:
2685 case FONT_SUPERSCRIPT:
2686 case FONT_UNDERLINE:
2687 case FONT_BACKCOLOR:
2688 case FONT_FORECOLOR:
2689 case FONT_LANGID:
2690 case FONT_WEIGHT:
2691 font->props[id].l = tomUndefined;
2692 break;
2693 case FONT_KERNING:
2694 case FONT_POSITION:
2695 case FONT_SIZE:
2696 case FONT_SPACING:
2697 font->props[id].f = tomUndefined;
2698 break;
2699 case FONT_NAME:
2700 break;
2701 default:
2702 FIXME("font property %d not handled\n", id);
2703 }
2704 }
2705 }
2706
2707 static void textfont_apply_range_props(ITextFontImpl *font)
2708 {
2709 enum textfont_prop_id propid;
2710 for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++)
2711 set_textfont_prop(font, propid, &font->props[propid]);
2712 }
2713
2714 static HRESULT WINAPI TextFont_Reset(ITextFont *iface, LONG value)
2715 {
2716 ITextFontImpl *This = impl_from_ITextFont(iface);
2717
2718 TRACE("(%p)->(%d)\n", This, value);
2719
2720 /* If font is attached to a range, released or not, we can't
2721 reset to undefined */
2722 if (This->range) {
2723 if (!get_range_reole(This->range))
2724 return CO_E_RELEASED;
2725
2726 switch (value)
2727 {
2728 case tomUndefined:
2729 return E_INVALIDARG;
2730 case tomCacheParms:
2731 textfont_cache_range_props(This);
2732 This->get_cache_enabled = TRUE;
2733 break;
2734 case tomTrackParms:
2735 This->get_cache_enabled = FALSE;
2736 break;
2737 case tomApplyLater:
2738 This->set_cache_enabled = TRUE;
2739 break;
2740 case tomApplyNow:
2741 This->set_cache_enabled = FALSE;
2742 textfont_apply_range_props(This);
2743 break;
2744 case tomUsePoints:
2745 case tomUseTwips:
2746 return E_INVALIDARG;
2747 default:
2748 FIXME("reset mode %d not supported\n", value);
2749 }
2750
2751 return S_OK;
2752 }
2753 else {
2754 switch (value)
2755 {
2756 /* reset to global defaults */
2757 case tomDefault:
2758 textfont_reset_to_default(This);
2759 return S_OK;
2760 /* all properties are set to tomUndefined, font name is retained */
2761 case tomUndefined:
2762 textfont_reset_to_undefined(This);
2763 return S_OK;
2764 case tomApplyNow:
2765 case tomApplyLater:
2766 case tomTrackParms:
2767 case tomCacheParms:
2768 return S_OK;
2769 case tomUsePoints:
2770 case tomUseTwips:
2771 return E_INVALIDARG;
2772 }
2773 }
2774
2775 FIXME("reset mode %d not supported\n", value);
2776 return E_NOTIMPL;
2777 }
2778
2779 static HRESULT WINAPI TextFont_GetStyle(ITextFont *iface, LONG *value)
2780 {
2781 ITextFontImpl *This = impl_from_ITextFont(iface);
2782 FIXME("(%p)->(%p): stub\n", This, value);
2783 return E_NOTIMPL;
2784 }
2785
2786 static HRESULT WINAPI TextFont_SetStyle(ITextFont *iface, LONG value)
2787 {
2788 ITextFontImpl *This = impl_from_ITextFont(iface);
2789 FIXME("(%p)->(%d): stub\n", This, value);
2790 return E_NOTIMPL;
2791 }
2792
2793 static HRESULT WINAPI TextFont_GetAllCaps(ITextFont *iface, LONG *value)
2794 {
2795 ITextFontImpl *This = impl_from_ITextFont(iface);
2796 TRACE("(%p)->(%p)\n", This, value);
2797 return get_textfont_propl(This, FONT_ALLCAPS, value);
2798 }
2799
2800 static HRESULT WINAPI TextFont_SetAllCaps(ITextFont *iface, LONG value)
2801 {
2802 ITextFontImpl *This = impl_from_ITextFont(iface);
2803 TRACE("(%p)->(%d)\n", This, value);
2804 return set_textfont_propd(This, FONT_ALLCAPS, value);
2805 }
2806
2807 static HRESULT WINAPI TextFont_GetAnimation(ITextFont *iface, LONG *value)
2808 {
2809 ITextFontImpl *This = impl_from_ITextFont(iface);
2810 TRACE("(%p)->(%p)\n", This, value);
2811 return get_textfont_propl(This, FONT_ANIMATION, value);
2812 }
2813
2814 static HRESULT WINAPI TextFont_SetAnimation(ITextFont *iface, LONG value)
2815 {
2816 ITextFontImpl *This = impl_from_ITextFont(iface);
2817
2818 TRACE("(%p)->(%d)\n", This, value);
2819
2820 if (value < tomNoAnimation || value > tomAnimationMax)
2821 return E_INVALIDARG;
2822
2823 return set_textfont_propl(This, FONT_ANIMATION, value);
2824 }
2825
2826 static HRESULT WINAPI TextFont_GetBackColor(ITextFont *iface, LONG *value)
2827 {
2828 ITextFontImpl *This = impl_from_ITextFont(iface);
2829 TRACE("(%p)->(%p)\n", This, value);
2830 return get_textfont_propl(This, FONT_BACKCOLOR, value);
2831 }
2832
2833 static HRESULT WINAPI TextFont_SetBackColor(ITextFont *iface, LONG value)
2834 {
2835 ITextFontImpl *This = impl_from_ITextFont(iface);
2836 TRACE("(%p)->(%d)\n", This, value);
2837 return set_textfont_propl(This, FONT_BACKCOLOR, value);
2838 }
2839
2840 static HRESULT WINAPI TextFont_GetBold(ITextFont *iface, LONG *value)
2841 {
2842 ITextFontImpl *This = impl_from_ITextFont(iface);
2843 TRACE("(%p)->(%p)\n", This, value);
2844 return get_textfont_propl(This, FONT_BOLD, value);
2845 }
2846
2847 static HRESULT WINAPI TextFont_SetBold(ITextFont *iface, LONG value)
2848 {
2849 ITextFontImpl *This = impl_from_ITextFont(iface);
2850 TRACE("(%p)->(%d)\n", This, value);
2851 return set_textfont_propd(This, FONT_BOLD, value);
2852 }
2853
2854 static HRESULT WINAPI TextFont_GetEmboss(ITextFont *iface, LONG *value)
2855 {
2856 ITextFontImpl *This = impl_from_ITextFont(iface);
2857 TRACE("(%p)->(%p)\n", This, value);
2858 return get_textfont_propl(This, FONT_EMBOSS, value);
2859 }
2860
2861 static HRESULT WINAPI TextFont_SetEmboss(ITextFont *iface, LONG value)
2862 {
2863 ITextFontImpl *This = impl_from_ITextFont(iface);
2864 TRACE("(%p)->(%d)\n", This, value);
2865 return set_textfont_propd(This, FONT_EMBOSS, value);
2866 }
2867
2868 static HRESULT WINAPI TextFont_GetForeColor(ITextFont *iface, LONG *value)
2869 {
2870 ITextFontImpl *This = impl_from_ITextFont(iface);
2871 TRACE("(%p)->(%p)\n", This, value);
2872 return get_textfont_propl(This, FONT_FORECOLOR, value);
2873 }
2874
2875 static HRESULT WINAPI TextFont_SetForeColor(ITextFont *iface, LONG value)
2876 {
2877 ITextFontImpl *This = impl_from_ITextFont(iface);
2878 TRACE("(%p)->(%d)\n", This, value);
2879 return set_textfont_propl(This, FONT_FORECOLOR, value);
2880 }
2881
2882 static HRESULT WINAPI TextFont_GetHidden(ITextFont *iface, LONG *value)
2883 {
2884 ITextFontImpl *This = impl_from_ITextFont(iface);
2885 TRACE("(%p)->(%p)\n", This, value);
2886 return get_textfont_propl(This, FONT_HIDDEN, value);
2887 }
2888
2889 static HRESULT WINAPI TextFont_SetHidden(ITextFont *iface, LONG value)
2890 {
2891 ITextFontImpl *This = impl_from_ITextFont(iface);
2892 TRACE("(%p)->(%d)\n", This, value);
2893 return set_textfont_propd(This, FONT_HIDDEN, value);
2894 }
2895
2896 static HRESULT WINAPI TextFont_GetEngrave(ITextFont *iface, LONG *value)
2897 {
2898 ITextFontImpl *This = impl_from_ITextFont(iface);
2899 TRACE("(%p)->(%p)\n", This, value);
2900 return get_textfont_propl(This, FONT_ENGRAVE, value);
2901 }
2902
2903 static HRESULT WINAPI TextFont_SetEngrave(ITextFont *iface, LONG value)
2904 {
2905 ITextFontImpl *This = impl_from_ITextFont(iface);
2906 TRACE("(%p)->(%d)\n", This, value);
2907 return set_textfont_propd(This, FONT_ENGRAVE, value);
2908 }
2909
2910 static HRESULT WINAPI TextFont_GetItalic(ITextFont *iface, LONG *value)
2911 {
2912 ITextFontImpl *This = impl_from_ITextFont(iface);
2913 TRACE("(%p)->(%p)\n", This, value);
2914 return get_textfont_propl(This, FONT_ITALIC, value);
2915 }
2916
2917 static HRESULT WINAPI TextFont_SetItalic(ITextFont *iface, LONG value)
2918 {
2919 ITextFontImpl *This = impl_from_ITextFont(iface);
2920 TRACE("(%p)->(%d)\n", This, value);
2921 return set_textfont_propd(This, FONT_ITALIC, value);
2922 }
2923
2924 static HRESULT WINAPI TextFont_GetKerning(ITextFont *iface, FLOAT *value)
2925 {
2926 ITextFontImpl *This = impl_from_ITextFont(iface);
2927 TRACE("(%p)->(%p)\n", This, value);
2928 return get_textfont_propf(This, FONT_KERNING, value);
2929 }
2930
2931 static HRESULT WINAPI TextFont_SetKerning(ITextFont *iface, FLOAT value)
2932 {
2933 ITextFontImpl *This = impl_from_ITextFont(iface);
2934 TRACE("(%p)->(%.2f)\n", This, value);
2935 return set_textfont_propf(This, FONT_KERNING, value);
2936 }
2937
2938 static HRESULT WINAPI TextFont_GetLanguageID(ITextFont *iface, LONG *value)
2939 {
2940 ITextFontImpl *This = impl_from_ITextFont(iface);
2941 TRACE("(%p)->(%p)\n", This, value);
2942 return get_textfont_propl(This, FONT_LANGID, value);
2943 }
2944
2945 static HRESULT WINAPI TextFont_SetLanguageID(ITextFont *iface, LONG value)
2946 {
2947 ITextFontImpl *This = impl_from_ITextFont(iface);
2948 TRACE("(%p)->(%d)\n", This, value);
2949 return set_textfont_propl(This, FONT_LANGID, value);
2950 }
2951
2952 static HRESULT WINAPI TextFont_GetName(ITextFont *iface, BSTR *value)
2953 {
2954 ITextFontImpl *This = impl_from_ITextFont(iface);
2955
2956 TRACE("(%p)->(%p)\n", This, value);
2957
2958 if (!value)
2959 return E_INVALIDARG;
2960
2961 *value = NULL;
2962
2963 if (!This->range) {
2964 if (This->props[FONT_NAME].str)
2965 *value = SysAllocString(This->props[FONT_NAME].str);
2966 else
2967 *value = SysAllocStringLen(NULL, 0);
2968 return *value ? S_OK : E_OUTOFMEMORY;
2969 }
2970
2971 return textfont_getname_from_range(This->range, value);
2972 }
2973
2974 static HRESULT WINAPI TextFont_SetName(ITextFont *iface, BSTR value)
2975 {
2976 ITextFontImpl *This = impl_from_ITextFont(iface);
2977 textfont_prop_val v;
2978
2979 TRACE("(%p)->(%s)\n", This, debugstr_w(value));
2980
2981 v.str = value;
2982 return set_textfont_prop(This, FONT_NAME, &v);
2983 }
2984
2985 static HRESULT WINAPI TextFont_GetOutline(ITextFont *iface, LONG *value)
2986 {
2987 ITextFontImpl *This = impl_from_ITextFont(iface);
2988 TRACE("(%p)->(%p)\n", This, value);
2989 return get_textfont_propl(This, FONT_OUTLINE, value);
2990 }
2991
2992 static HRESULT WINAPI TextFont_SetOutline(ITextFont *iface, LONG value)
2993 {
2994 ITextFontImpl *This = impl_from_ITextFont(iface);
2995 TRACE("(%p)->(%d)\n", This, value);
2996 return set_textfont_propd(This, FONT_OUTLINE, value);
2997 }
2998
2999 static HRESULT WINAPI TextFont_GetPosition(ITextFont *iface, FLOAT *value)
3000 {
3001 ITextFontImpl *This = impl_from_ITextFont(iface);
3002 TRACE("(%p)->(%p)\n", This, value);
3003 return get_textfont_propf(This, FONT_POSITION, value);
3004 }
3005
3006 static HRESULT WINAPI TextFont_SetPosition(ITextFont *iface, FLOAT value)
3007 {
3008 ITextFontImpl *This = impl_from_ITextFont(iface);
3009 TRACE("(%p)->(%.2f)\n", This, value);
3010 return set_textfont_propf(This, FONT_POSITION, value);
3011 }
3012
3013 static HRESULT WINAPI TextFont_GetProtected(ITextFont *iface, LONG *value)
3014 {
3015 ITextFontImpl *This = impl_from_ITextFont(iface);
3016 TRACE("(%p)->(%p)\n", This, value);
3017 return get_textfont_propl(This, FONT_PROTECTED, value);
3018 }
3019
3020 static HRESULT WINAPI TextFont_SetProtected(ITextFont *iface, LONG value)
3021 {
3022 ITextFontImpl *This = impl_from_ITextFont(iface);
3023 TRACE("(%p)->(%d)\n", This, value);
3024 return set_textfont_propd(This, FONT_PROTECTED, value);
3025 }
3026
3027 static HRESULT WINAPI TextFont_GetShadow(ITextFont *iface, LONG *value)
3028 {
3029 ITextFontImpl *This = impl_from_ITextFont(iface);
3030 TRACE("(%p)->(%p)\n", This, value);
3031 return get_textfont_propl(This, FONT_SHADOW, value);
3032 }
3033
3034 static HRESULT WINAPI TextFont_SetShadow(ITextFont *iface, LONG value)
3035 {
3036 ITextFontImpl *This = impl_from_ITextFont(iface);
3037 TRACE("(%p)->(%d)\n", This, value);
3038 return set_textfont_propd(This, FONT_SHADOW, value);
3039 }
3040
3041 static HRESULT WINAPI TextFont_GetSize(ITextFont *iface, FLOAT *value)
3042 {
3043 ITextFontImpl *This = impl_from_ITextFont(iface);
3044 TRACE("(%p)->(%p)\n", This, value);
3045 return get_textfont_propf(This, FONT_SIZE, value);
3046 }
3047
3048 static HRESULT WINAPI TextFont_SetSize(ITextFont *iface, FLOAT value)
3049 {
3050 ITextFontImpl *This = impl_from_ITextFont(iface);
3051 TRACE("(%p)->(%.2f)\n", This, value);
3052 return set_textfont_propf(This, FONT_SIZE, value);
3053 }
3054
3055 static HRESULT WINAPI TextFont_GetSmallCaps(ITextFont *iface, LONG *value)
3056 {
3057 ITextFontImpl *This = impl_from_ITextFont(iface);
3058 TRACE("(%p)->(%p)\n", This, value);
3059 return get_textfont_propl(This, FONT_SMALLCAPS, value);
3060 }
3061
3062 static HRESULT WINAPI TextFont_SetSmallCaps(ITextFont *iface, LONG value)
3063 {
3064 ITextFontImpl *This = impl_from_ITextFont(iface);
3065 TRACE("(%p)->(%d)\n", This, value);
3066 return set_textfont_propd(This, FONT_SMALLCAPS, value);
3067 }
3068
3069 static HRESULT WINAPI TextFont_GetSpacing(ITextFont *iface, FLOAT *value)
3070 {
3071 ITextFontImpl *This = impl_from_ITextFont(iface);
3072 TRACE("(%p)->(%p)\n", This, value);
3073 return get_textfont_propf(This, FONT_SPACING, value);
3074 }
3075
3076 static HRESULT WINAPI TextFont_SetSpacing(ITextFont *iface, FLOAT value)
3077 {
3078 ITextFontImpl *This = impl_from_ITextFont(iface);
3079 TRACE("(%p)->(%.2f)\n", This, value);
3080 return set_textfont_propf(This, FONT_SPACING, value);
3081 }
3082
3083 static HRESULT WINAPI TextFont_GetStrikeThrough(ITextFont *iface, LONG *value)
3084 {
3085 ITextFontImpl *This = impl_from_ITextFont(iface);
3086 TRACE("(%p)->(%p)\n", This, value);
3087 return get_textfont_propl(This, FONT_STRIKETHROUGH, value);
3088 }
3089
3090 static HRESULT WINAPI TextFont_SetStrikeThrough(ITextFont *iface, LONG value)
3091 {
3092 ITextFontImpl *This = impl_from_ITextFont(iface);
3093 TRACE("(%p)->(%d)\n", This, value);
3094 return set_textfont_propd(This, FONT_STRIKETHROUGH, value);
3095 }
3096
3097 static HRESULT WINAPI TextFont_GetSubscript(ITextFont *iface, LONG *value)
3098 {
3099 ITextFontImpl *This = impl_from_ITextFont(iface);
3100 TRACE("(%p)->(%p)\n", This, value);
3101 return get_textfont_propl(This, FONT_SUBSCRIPT, value);
3102 }
3103
3104 static HRESULT WINAPI TextFont_SetSubscript(ITextFont *iface, LONG value)
3105 {
3106 ITextFontImpl *This = impl_from_ITextFont(iface);
3107 TRACE("(%p)->(%d)\n", This, value);
3108 return set_textfont_propd(This, FONT_SUBSCRIPT, value);
3109 }
3110
3111 static HRESULT WINAPI TextFont_GetSuperscript(ITextFont *iface, LONG *value)
3112 {
3113 ITextFontImpl *This = impl_from_ITextFont(iface);
3114 TRACE("(%p)->(%p)\n", This, value);
3115 return get_textfont_propl(This, FONT_SUPERSCRIPT, value);
3116 }
3117
3118 static HRESULT WINAPI TextFont_SetSuperscript(ITextFont *iface, LONG value)
3119 {
3120 ITextFontImpl *This = impl_from_ITextFont(iface);
3121 TRACE("(%p)->(%d)\n", This, value);
3122 return set_textfont_propd(This, FONT_SUPERSCRIPT, value);
3123 }
3124
3125 static HRESULT WINAPI TextFont_GetUnderline(ITextFont *iface, LONG *value)
3126 {
3127 ITextFontImpl *This = impl_from_ITextFont(iface);
3128 TRACE("(%p)->(%p)\n", This, value);
3129 return get_textfont_propl(This, FONT_UNDERLINE, value);
3130 }
3131
3132 static HRESULT WINAPI TextFont_SetUnderline(ITextFont *iface, LONG value)
3133 {
3134 ITextFontImpl *This = impl_from_ITextFont(iface);
3135 TRACE("(%p)->(%d)\n", This, value);
3136 return set_textfont_propd(This, FONT_UNDERLINE, value);
3137 }
3138
3139 static HRESULT WINAPI TextFont_GetWeight(ITextFont *iface, LONG *value)
3140 {
3141 ITextFontImpl *This = impl_from_ITextFont(iface);
3142 TRACE("(%p)->(%p)\n", This, value);
3143 return get_textfont_propl(This, FONT_WEIGHT, value);
3144 }
3145
3146 static HRESULT WINAPI TextFont_SetWeight(ITextFont *iface, LONG value)
3147 {
3148 ITextFontImpl *This = impl_from_ITextFont(iface);
3149 TRACE("(%p)->(%d)\n", This, value);
3150 return set_textfont_propl(This, FONT_WEIGHT, value);
3151 }
3152
3153 static ITextFontVtbl textfontvtbl = {
3154 TextFont_QueryInterface,
3155 TextFont_AddRef,
3156 TextFont_Release,
3157 TextFont_GetTypeInfoCount,
3158 TextFont_GetTypeInfo,
3159 TextFont_GetIDsOfNames,
3160 TextFont_Invoke,
3161 TextFont_GetDuplicate,
3162 TextFont_SetDuplicate,
3163 TextFont_CanChange,
3164 TextFont_IsEqual,
3165 TextFont_Reset,
3166 TextFont_GetStyle,
3167 TextFont_SetStyle,
3168 TextFont_GetAllCaps,
3169 TextFont_SetAllCaps,
3170 TextFont_GetAnimation,
3171 TextFont_SetAnimation,
3172 TextFont_GetBackColor,
3173 TextFont_SetBackColor,
3174 TextFont_GetBold,
3175 TextFont_SetBold,
3176 TextFont_GetEmboss,
3177 TextFont_SetEmboss,
3178 TextFont_GetForeColor,
3179 TextFont_SetForeColor,
3180 TextFont_GetHidden,
3181 TextFont_SetHidden,
3182 TextFont_GetEngrave,
3183 TextFont_SetEngrave,
3184 TextFont_GetItalic,
3185 TextFont_SetItalic,
3186 TextFont_GetKerning,
3187 TextFont_SetKerning,
3188 TextFont_GetLanguageID,
3189 TextFont_SetLanguageID,
3190 TextFont_GetName,
3191 TextFont_SetName,
3192 TextFont_GetOutline,
3193 TextFont_SetOutline,
3194 TextFont_GetPosition,
3195 TextFont_SetPosition,
3196 TextFont_GetProtected,
3197 TextFont_SetProtected,
3198 TextFont_GetShadow,
3199 TextFont_SetShadow,
3200 TextFont_GetSize,
3201 TextFont_SetSize,
3202 TextFont_GetSmallCaps,
3203 TextFont_SetSmallCaps,
3204 TextFont_GetSpacing,
3205 TextFont_SetSpacing,
3206 TextFont_GetStrikeThrough,
3207 TextFont_SetStrikeThrough,
3208 TextFont_GetSubscript,
3209 TextFont_SetSubscript,
3210 TextFont_GetSuperscript,
3211 TextFont_SetSuperscript,
3212 TextFont_GetUnderline,
3213 TextFont_SetUnderline,
3214 TextFont_GetWeight,
3215 TextFont_SetWeight
3216 };
3217
3218 static HRESULT create_textfont(ITextRange *range, const ITextFontImpl *src, ITextFont **ret)
3219 {
3220 ITextFontImpl *font;
3221
3222 *ret = NULL;
3223 font = heap_alloc(sizeof(*font));
3224 if (!font)
3225 return E_OUTOFMEMORY;
3226
3227 font->ITextFont_iface.lpVtbl = &textfontvtbl;
3228 font->ref = 1;
3229
3230 if (src) {
3231 font->range = NULL;
3232 font->get_cache_enabled = TRUE;
3233 font->set_cache_enabled = TRUE;
3234 memcpy(&font->props, &src->props, sizeof(font->props));
3235 if (font->props[FONT_NAME].str)
3236 font->props[FONT_NAME].str = SysAllocString(font->props[FONT_NAME].str);
3237 }
3238 else {
3239 font->range = range;
3240 ITextRange_AddRef(range);
3241
3242 /* cache current properties */
3243 font->get_cache_enabled = FALSE;
3244 font->set_cache_enabled = FALSE;
3245 textfont_cache_range_props(font);
3246 }
3247
3248 *ret = &font->ITextFont_iface;
3249 return S_OK;
3250 }
3251
3252 /* ITextPara */
3253 static HRESULT WINAPI TextPara_QueryInterface(ITextPara *iface, REFIID riid, void **ppv)
3254 {
3255 ITextParaImpl *This = impl_from_ITextPara(iface);
3256
3257 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
3258
3259 if (IsEqualIID(riid, &IID_ITextPara) ||
3260 IsEqualIID(riid, &IID_IDispatch) ||
3261 IsEqualIID(riid, &IID_IUnknown))
3262 {
3263 *ppv = iface;
3264 ITextPara_AddRef(iface);
3265 return S_OK;
3266 }
3267
3268 *ppv = NULL;
3269 return E_NOINTERFACE;
3270 }
3271
3272 static ULONG WINAPI TextPara_AddRef(ITextPara *iface)
3273 {
3274 ITextParaImpl *This = impl_from_ITextPara(iface);
3275 ULONG ref = InterlockedIncrement(&This->ref);
3276 TRACE("(%p)->(%u)\n", This, ref);
3277 return ref;
3278 }
3279
3280 static ULONG WINAPI TextPara_Release(ITextPara *iface)
3281 {
3282 ITextParaImpl *This = impl_from_ITextPara(iface);
3283 ULONG ref = InterlockedDecrement(&This->ref);
3284
3285 TRACE("(%p)->(%u)\n", This, ref);
3286
3287 if (!ref)
3288 {
3289 ITextRange_Release(This->range);
3290 heap_free(This);
3291 }
3292
3293 return ref;
3294 }
3295
3296 static HRESULT WINAPI TextPara_GetTypeInfoCount(ITextPara *iface, UINT *pctinfo)
3297 {
3298 ITextParaImpl *This = impl_from_ITextPara(iface);
3299 TRACE("(%p)->(%p)\n", This, pctinfo);
3300 *pctinfo = 1;
3301 return S_OK;
3302 }
3303
3304 static HRESULT WINAPI TextPara_GetTypeInfo(ITextPara *iface, UINT iTInfo, LCID lcid,
3305 ITypeInfo **ppTInfo)
3306 {
3307 ITextParaImpl *This = impl_from_ITextPara(iface);
3308 HRESULT hr;
3309
3310 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
3311
3312 hr = get_typeinfo(ITextPara_tid, ppTInfo);
3313 if (SUCCEEDED(hr))
3314 ITypeInfo_AddRef(*ppTInfo);
3315 return hr;
3316 }
3317
3318 static HRESULT WINAPI TextPara_GetIDsOfNames(ITextPara *iface, REFIID riid,
3319 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
3320 {
3321 ITextParaImpl *This = impl_from_ITextPara(iface);
3322 ITypeInfo *ti;
3323 HRESULT hr;
3324
3325 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames,
3326 cNames, lcid, rgDispId);
3327
3328 hr = get_typeinfo(ITextPara_tid, &ti);
3329 if (SUCCEEDED(hr))
3330 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
3331 return hr;
3332 }
3333
3334 static HRESULT WINAPI TextPara_Invoke(
3335 ITextPara *iface,
3336 DISPID dispIdMember,
3337 REFIID riid,
3338 LCID lcid,
3339 WORD wFlags,
3340 DISPPARAMS *pDispParams,
3341 VARIANT *pVarResult,
3342 EXCEPINFO *pExcepInfo,
3343 UINT *puArgErr)
3344 {
3345 ITextParaImpl *This = impl_from_ITextPara(iface);
3346 ITypeInfo *ti;
3347 HRESULT hr;
3348
3349 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember,
3350 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
3351 pExcepInfo, puArgErr);
3352
3353 hr = get_typeinfo(ITextPara_tid, &ti);
3354 if (SUCCEEDED(hr))
3355 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3356 return hr;
3357 }
3358
3359 static HRESULT WINAPI TextPara_GetDuplicate(ITextPara *iface, ITextPara **ret)
3360 {
3361 ITextParaImpl *This = impl_from_ITextPara(iface);
3362 FIXME("(%p)->(%p)\n", This, ret);
3363 return E_NOTIMPL;
3364 }
3365
3366 static HRESULT WINAPI TextPara_SetDuplicate(ITextPara *iface, ITextPara *para)
3367 {
3368 ITextParaImpl *This = impl_from_ITextPara(iface);
3369 FIXME("(%p)->(%p)\n", This, para);
3370 return E_NOTIMPL;
3371 }
3372
3373 static HRESULT WINAPI TextPara_CanChange(ITextPara *iface, LONG *ret)
3374 {
3375 ITextParaImpl *This = impl_from_ITextPara(iface);
3376 FIXME("(%p)->(%p)\n", This, ret);
3377 return E_NOTIMPL;
3378 }
3379
3380 static HRESULT WINAPI TextPara_IsEqual(ITextPara *iface, ITextPara *para, LONG *ret)
3381 {
3382 ITextParaImpl *This = impl_from_ITextPara(iface);
3383 FIXME("(%p)->(%p %p)\n", This, para, ret);
3384 return E_NOTIMPL;
3385 }
3386
3387 static HRESULT WINAPI TextPara_Reset(ITextPara *iface, LONG value)
3388 {
3389 ITextParaImpl *This = impl_from_ITextPara(iface);
3390 FIXME("(%p)->(%d)\n", This, value);
3391 return E_NOTIMPL;
3392 }
3393
3394 static HRESULT WINAPI TextPara_GetStyle(ITextPara *iface, LONG *value)
3395 {
3396 ITextParaImpl *This = impl_from_ITextPara(iface);
3397 FIXME("(%p)->(%p)\n", This, value);
3398 return E_NOTIMPL;
3399 }
3400
3401 static HRESULT WINAPI TextPara_SetStyle(ITextPara *iface, LONG value)
3402 {
3403 ITextParaImpl *This = impl_from_ITextPara(iface);
3404 FIXME("(%p)->(%d)\n", This, value);
3405 return E_NOTIMPL;
3406 }
3407
3408 static HRESULT WINAPI TextPara_GetAlignment(ITextPara *iface, LONG *value)
3409 {
3410 ITextParaImpl *This = impl_from_ITextPara(iface);
3411 FIXME("(%p)->(%p)\n", This, value);
3412 return E_NOTIMPL;
3413 }
3414
3415 static HRESULT WINAPI TextPara_SetAlignment(ITextPara *iface, LONG value)
3416 {
3417 ITextParaImpl *This = impl_from_ITextPara(iface);
3418 FIXME("(%p)->(%d)\n", This, value);
3419 return E_NOTIMPL;
3420 }
3421
3422 static HRESULT WINAPI TextPara_GetHyphenation(ITextPara *iface, LONG *value)
3423 {
3424 ITextParaImpl *This = impl_from_ITextPara(iface);
3425 FIXME("(%p)->(%p)\n", This, value);
3426 return E_NOTIMPL;
3427 }
3428
3429 static HRESULT WINAPI TextPara_SetHyphenation(ITextPara *iface, LONG value)
3430 {
3431 ITextParaImpl *This = impl_from_ITextPara(iface);
3432 FIXME("(%p)->(%d)\n", This, value);
3433 return E_NOTIMPL;
3434 }
3435
3436 static HRESULT WINAPI TextPara_GetFirstLineIndent(ITextPara *iface, FLOAT *value)
3437 {
3438 ITextParaImpl *This = impl_from_ITextPara(iface);
3439 FIXME("(%p)->(%p)\n", This, value);
3440 return E_NOTIMPL;
3441 }
3442
3443 static HRESULT WINAPI TextPara_GetKeepTogether(ITextPara *iface, LONG *value)
3444 {
3445 ITextParaImpl *This = impl_from_ITextPara(iface);
3446 FIXME("(%p)->(%p)\n", This, value);
3447 return E_NOTIMPL;
3448 }
3449
3450 static HRESULT WINAPI TextPara_SetKeepTogether(ITextPara *iface, LONG value)
3451 {
3452 ITextParaImpl *This = impl_from_ITextPara(iface);
3453 FIXME("(%p)->(%d)\n", This, value);
3454 return E_NOTIMPL;
3455 }
3456
3457 static HRESULT WINAPI TextPara_GetKeepWithNext(ITextPara *iface, LONG *value)
3458 {
3459 ITextParaImpl *This = impl_from_ITextPara(iface);
3460 FIXME("(%p)->(%p)\n", This, value);
3461 return E_NOTIMPL;
3462 }
3463
3464 static HRESULT WINAPI TextPara_SetKeepWithNext(ITextPara *iface, LONG value)
3465 {
3466 ITextParaImpl *This = impl_from_ITextPara(iface);
3467 FIXME("(%p)->(%d)\n", This, value);
3468 return E_NOTIMPL;
3469 }
3470
3471 static HRESULT WINAPI TextPara_GetLeftIndent(ITextPara *iface, FLOAT *value)
3472 {
3473 ITextParaImpl *This = impl_from_ITextPara(iface);
3474 FIXME("(%p)->(%p)\n", This, value);
3475 return E_NOTIMPL;
3476 }
3477
3478 static HRESULT WINAPI TextPara_GetLineSpacing(ITextPara *iface, FLOAT *value)
3479 {
3480 ITextParaImpl *This = impl_from_ITextPara(iface);
3481 FIXME("(%p)->(%p)\n", This, value);
3482 return E_NOTIMPL;
3483 }
3484
3485 static HRESULT WINAPI TextPara_GetLineSpacingRule(ITextPara *iface, LONG *value)
3486 {
3487 ITextParaImpl *This = impl_from_ITextPara(iface);
3488 FIXME("(%p)->(%p)\n", This, value);
3489 return E_NOTIMPL;
3490 }
3491
3492 static HRESULT WINAPI TextPara_GetListAlignment(ITextPara *iface, LONG *value)
3493 {
3494 ITextParaImpl *This = impl_from_ITextPara(iface);
3495 FIXME("(%p)->(%p)\n", This, value);
3496 return E_NOTIMPL;
3497 }
3498
3499 static HRESULT WINAPI TextPara_SetListAlignment(ITextPara *iface, LONG value)
3500 {
3501 ITextParaImpl *This = impl_from_ITextPara(iface);
3502 FIXME("(%p)->(%d)\n", This, value);
3503 return E_NOTIMPL;
3504 }
3505
3506 static HRESULT WINAPI TextPara_GetListLevelIndex(ITextPara *iface, LONG *value)
3507 {
3508 ITextParaImpl *This = impl_from_ITextPara(iface);
3509 FIXME("(%p)->(%p)\n", This, value);
3510 return E_NOTIMPL;
3511 }
3512
3513 static HRESULT WINAPI TextPara_SetListLevelIndex(ITextPara *iface, LONG value)
3514 {
3515 ITextParaImpl *This = impl_from_ITextPara(iface);
3516 FIXME("(%p)->(%d)\n", This, value);
3517 return E_NOTIMPL;
3518 }
3519
3520 static HRESULT WINAPI TextPara_GetListStart(ITextPara *iface, LONG *value)
3521 {
3522 ITextParaImpl *This = impl_from_ITextPara(iface);
3523 FIXME("(%p)->(%p)\n", This, value);
3524 return E_NOTIMPL;
3525 }
3526
3527 static HRESULT WINAPI TextPara_SetListStart(ITextPara *iface, LONG value)
3528 {
3529 ITextParaImpl *This = impl_from_ITextPara(iface);
3530 FIXME("(%p)->(%d)\n", This, value);
3531 return E_NOTIMPL;
3532 }
3533
3534 static HRESULT WINAPI TextPara_GetListTab(ITextPara *iface, FLOAT *value)
3535 {
3536 ITextParaImpl *This = impl_from_ITextPara(iface);
3537 FIXME("(%p)->(%p)\n", This, value);
3538 return E_NOTIMPL;
3539 }
3540
3541 static HRESULT WINAPI TextPara_SetListTab(ITextPara *iface, FLOAT value)
3542 {
3543 ITextParaImpl *This = impl_from_ITextPara(iface);
3544 FIXME("(%p)->(%.2f)\n", This, value);
3545 return E_NOTIMPL;
3546 }
3547
3548 static HRESULT WINAPI TextPara_GetListType(ITextPara *iface, LONG *value)
3549 {
3550 ITextParaImpl *This = impl_from_ITextPara(iface);
3551 FIXME("(%p)->(%p)\n", This, value);
3552 return E_NOTIMPL;
3553 }
3554
3555 static HRESULT WINAPI TextPara_SetListType(ITextPara *iface, LONG value)
3556 {
3557 ITextParaImpl *This = impl_from_ITextPara(iface);
3558 FIXME("(%p)->(%d)\n", This, value);
3559 return E_NOTIMPL;
3560 }
3561
3562 static HRESULT WINAPI TextPara_GetNoLineNumber(ITextPara *iface, LONG *value)
3563 {
3564 ITextParaImpl *This = impl_from_ITextPara(iface);
3565 FIXME("(%p)->(%p)\n", This, value);
3566 return E_NOTIMPL;
3567 }
3568
3569 static HRESULT WINAPI TextPara_SetNoLineNumber(ITextPara *iface, LONG value)
3570 {
3571 ITextParaImpl *This = impl_from_ITextPara(iface);
3572 FIXME("(%p)->(%d)\n", This, value);
3573 return E_NOTIMPL;
3574 }
3575
3576 static HRESULT WINAPI TextPara_GetPageBreakBefore(ITextPara *iface, LONG *value)
3577 {
3578 ITextParaImpl *This = impl_from_ITextPara(iface);
3579 FIXME("(%p)->(%p)\n", This, value);
3580 return E_NOTIMPL;
3581 }
3582
3583 static HRESULT WINAPI TextPara_SetPageBreakBefore(ITextPara *iface, LONG value)
3584 {
3585 ITextParaImpl *This = impl_from_ITextPara(iface);
3586 FIXME("(%p)->(%d)\n", This, value);
3587 return E_NOTIMPL;
3588 }
3589
3590 static HRESULT WINAPI TextPara_GetRightIndent(ITextPara *iface, FLOAT *value)
3591 {
3592 ITextParaImpl *This = impl_from_ITextPara(iface);
3593 FIXME("(%p)->(%p)\n", This, value);
3594 return E_NOTIMPL;
3595 }
3596
3597 static HRESULT WINAPI TextPara_SetRightIndent(ITextPara *iface, FLOAT value)
3598 {
3599 ITextParaImpl *This = impl_from_ITextPara(iface);
3600 FIXME("(%p)->(%.2f)\n", This, value);
3601 return E_NOTIMPL;
3602 }
3603
3604 static HRESULT WINAPI TextPara_SetIndents(ITextPara *iface, FLOAT StartIndent, FLOAT LeftIndent, FLOAT RightIndent)
3605 {
3606 ITextParaImpl *This = impl_from_ITextPara(iface);
3607 FIXME("(%p)->(%.2f %.2f %.2f)\n", This, StartIndent, LeftIndent, RightIndent);
3608 return E_NOTIMPL;
3609 }
3610
3611 static HRESULT WINAPI TextPara_SetLineSpacing(ITextPara *iface, LONG LineSpacingRule, FLOAT LineSpacing)
3612 {
3613 ITextParaImpl *This = impl_from_ITextPara(iface);
3614 FIXME("(%p)->(%d %.2f)\n", This, LineSpacingRule, LineSpacing);
3615 return E_NOTIMPL;
3616 }
3617
3618 static HRESULT WINAPI TextPara_GetSpaceAfter(ITextPara *iface, FLOAT *value)
3619 {
3620 ITextParaImpl *This = impl_from_ITextPara(iface);
3621 FIXME("(%p)->(%p)\n", This, value);
3622 return E_NOTIMPL;
3623 }
3624
3625 static HRESULT WINAPI TextPara_SetSpaceAfter(ITextPara *iface, FLOAT value)
3626 {
3627 ITextParaImpl *This = impl_from_ITextPara(iface);
3628 FIXME("(%p)->(%.2f)\n", This, value);
3629 return E_NOTIMPL;
3630 }
3631
3632 static HRESULT WINAPI TextPara_GetSpaceBefore(ITextPara *iface, FLOAT *value)
3633 {
3634 ITextParaImpl *This = impl_from_ITextPara(iface);
3635 FIXME("(%p)->(%p)\n", This, value);
3636 return E_NOTIMPL;
3637 }
3638
3639 static HRESULT WINAPI TextPara_SetSpaceBefore(ITextPara *iface, FLOAT value)
3640 {
3641 ITextParaImpl *This = impl_from_ITextPara(iface);
3642 FIXME("(%p)->(%.2f)\n", This, value);
3643 return E_NOTIMPL;
3644 }
3645
3646 static HRESULT WINAPI TextPara_GetWidowControl(ITextPara *iface, LONG *value)
3647 {
3648 ITextParaImpl *This = impl_from_ITextPara(iface);
3649 FIXME("(%p)->(%p)\n", This, value);
3650 return E_NOTIMPL;
3651 }
3652
3653 static HRESULT WINAPI TextPara_SetWidowControl(ITextPara *iface, LONG value)
3654 {
3655 ITextParaImpl *This = impl_from_ITextPara(iface);
3656 FIXME("(%p)->(%d)\n", This, value);
3657 return E_NOTIMPL;
3658 }
3659
3660 static HRESULT WINAPI TextPara_GetTabCount(ITextPara *iface, LONG *value)
3661 {
3662 ITextParaImpl *This = impl_from_ITextPara(iface);
3663 FIXME("(%p)->(%p)\n", This, value);
3664 return E_NOTIMPL;
3665 }
3666
3667 static HRESULT WINAPI TextPara_AddTab(ITextPara *iface, FLOAT tbPos, LONG tbAlign, LONG tbLeader)
3668 {
3669 ITextParaImpl *This = impl_from_ITextPara(iface);
3670 FIXME("(%p)->(%.2f %d %d)\n", This, tbPos, tbAlign, tbLeader);
3671 return E_NOTIMPL;
3672 }
3673
3674 static HRESULT WINAPI TextPara_ClearAllTabs(ITextPara *iface)
3675 {
3676 ITextParaImpl *This = impl_from_ITextPara(iface);
3677 FIXME("(%p)\n", This);
3678 return E_NOTIMPL;
3679 }
3680
3681 static HRESULT WINAPI TextPara_DeleteTab(ITextPara *iface, FLOAT pos)
3682 {
3683 ITextParaImpl *This = impl_from_ITextPara(iface);
3684 FIXME("(%p)->(%.2f)\n", This, pos);
3685 return E_NOTIMPL;
3686 }
3687
3688 static HRESULT WINAPI TextPara_GetTab(ITextPara *iface, LONG iTab, FLOAT *ptbPos, LONG *ptbAlign, LONG *ptbLeader)
3689 {
3690 ITextParaImpl *This = impl_from_ITextPara(iface);
3691 FIXME("(%p)->(%d %p %p %p)\n", This, iTab, ptbPos, ptbAlign, ptbLeader);
3692 return E_NOTIMPL;
3693 }
3694
3695 static ITextParaVtbl textparavtbl = {
3696 TextPara_QueryInterface,
3697 TextPara_AddRef,
3698 TextPara_Release,
3699 TextPara_GetTypeInfoCount,
3700 TextPara_GetTypeInfo,
3701 TextPara_GetIDsOfNames,
3702 TextPara_Invoke,
3703 TextPara_GetDuplicate,
3704 TextPara_SetDuplicate,
3705 TextPara_CanChange,
3706 TextPara_IsEqual,
3707 TextPara_Reset,
3708 TextPara_GetStyle,
3709 TextPara_SetStyle,
3710 TextPara_GetAlignment,
3711 TextPara_SetAlignment,
3712 TextPara_GetHyphenation,
3713 TextPara_SetHyphenation,
3714 TextPara_GetFirstLineIndent,
3715 TextPara_GetKeepTogether,
3716 TextPara_SetKeepTogether,
3717 TextPara_GetKeepWithNext,
3718 TextPara_SetKeepWithNext,
3719 TextPara_GetLeftIndent,
3720 TextPara_GetLineSpacing,
3721 TextPara_GetLineSpacingRule,
3722 TextPara_GetListAlignment,
3723 TextPara_SetListAlignment,
3724 TextPara_GetListLevelIndex,
3725 TextPara_SetListLevelIndex,
3726 TextPara_GetListStart,
3727 TextPara_SetListStart,
3728 TextPara_GetListTab,
3729 TextPara_SetListTab,
3730 TextPara_GetListType,
3731 TextPara_SetListType,
3732 TextPara_GetNoLineNumber,
3733 TextPara_SetNoLineNumber,
3734 TextPara_GetPageBreakBefore,
3735 TextPara_SetPageBreakBefore,
3736 TextPara_GetRightIndent,
3737 TextPara_SetRightIndent,
3738 TextPara_SetIndents,
3739 TextPara_SetLineSpacing,
3740 TextPara_GetSpaceAfter,
3741 TextPara_SetSpaceAfter,
3742 TextPara_GetSpaceBefore,
3743 TextPara_SetSpaceBefore,
3744 TextPara_GetWidowControl,
3745 TextPara_SetWidowControl,
3746 TextPara_GetTabCount,
3747 TextPara_AddTab,
3748 TextPara_ClearAllTabs,
3749 TextPara_DeleteTab,
3750 TextPara_GetTab
3751 };
3752
3753 static HRESULT create_textpara(ITextRange *range, ITextPara **ret)
3754 {
3755 ITextParaImpl *para;
3756
3757 *ret = NULL;
3758 para = heap_alloc(sizeof(*para));
3759 if (!para)
3760 return E_OUTOFMEMORY;
3761
3762 para->ITextPara_iface.lpVtbl = &textparavtbl;
3763 para->ref = 1;
3764 para->range = range;
3765 ITextRange_AddRef(range);
3766
3767 *ret = &para->ITextPara_iface;
3768 return S_OK;
3769 }
3770
3771 /* ITextDocument */
3772 static HRESULT WINAPI
3773 ITextDocument_fnQueryInterface(ITextDocument* me, REFIID riid,
3774 void** ppvObject)
3775 {
3776 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3777 return IRichEditOle_QueryInterface(&This->IRichEditOle_iface, riid, ppvObject);
3778 }
3779
3780 static ULONG WINAPI
3781 ITextDocument_fnAddRef(ITextDocument* me)
3782 {
3783 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3784 return IRichEditOle_AddRef(&This->IRichEditOle_iface);
3785 }
3786
3787 static ULONG WINAPI
3788 ITextDocument_fnRelease(ITextDocument* me)
3789 {
3790 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3791 return IRichEditOle_Release(&This->IRichEditOle_iface);
3792 }
3793
3794 static HRESULT WINAPI
3795 ITextDocument_fnGetTypeInfoCount(ITextDocument* me,
3796 UINT* pctinfo)
3797 {
3798 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3799 TRACE("(%p)->(%p)\n", This, pctinfo);
3800 *pctinfo = 1;
3801 return S_OK;
3802 }
3803
3804 static HRESULT WINAPI
3805 ITextDocument_fnGetTypeInfo(ITextDocument* me, UINT iTInfo, LCID lcid,
3806 ITypeInfo** ppTInfo)
3807 {
3808 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3809 HRESULT hr;
3810
3811 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
3812
3813 hr = get_typeinfo(ITextDocument_tid, ppTInfo);
3814 if (SUCCEEDED(hr))
3815 ITypeInfo_AddRef(*ppTInfo);
3816 return hr;
3817 }
3818
3819 static HRESULT WINAPI
3820 ITextDocument_fnGetIDsOfNames(ITextDocument* me, REFIID riid,
3821 LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId)
3822 {
3823 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3824 ITypeInfo *ti;
3825 HRESULT hr;
3826
3827 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid),
3828 rgszNames, cNames, lcid, rgDispId);
3829
3830 hr = get_typeinfo(ITextDocument_tid, &ti);
3831 if (SUCCEEDED(hr))
3832 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
3833 return hr;
3834 }
3835
3836 static HRESULT WINAPI
3837 ITextDocument_fnInvoke(ITextDocument* me, DISPID dispIdMember,
3838 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
3839 VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
3840 {
3841 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3842 ITypeInfo *ti;
3843 HRESULT hr;
3844
3845 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember,
3846 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
3847 pExcepInfo, puArgErr);
3848
3849 hr = get_typeinfo(ITextDocument_tid, &ti);
3850 if (SUCCEEDED(hr))
3851 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3852 return hr;
3853 }
3854
3855 static HRESULT WINAPI
3856 ITextDocument_fnGetName(ITextDocument* me, BSTR* pName)
3857 {
3858 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3859 FIXME("stub %p\n",This);
3860 return E_NOTIMPL;
3861 }
3862
3863 static HRESULT WINAPI
3864 ITextDocument_fnGetSelection(ITextDocument *me, ITextSelection **selection)
3865 {
3866 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3867
3868 TRACE("(%p)->(%p)\n", me, selection);
3869
3870 if (!selection)
3871 return E_INVALIDARG;
3872
3873 if (!This->txtSel) {
3874 This->txtSel = CreateTextSelection(This);
3875 if (!This->txtSel) {
3876 *selection = NULL;
3877 return E_OUTOFMEMORY;
3878 }
3879 }
3880
3881 *selection = &This->txtSel->ITextSelection_iface;
3882 ITextSelection_AddRef(*selection);
3883 return S_OK;
3884 }
3885
3886 static HRESULT WINAPI
3887 ITextDocument_fnGetStoryCount(ITextDocument* me, LONG* pCount)
3888 {
3889 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3890 FIXME("stub %p\n",This);
3891 return E_NOTIMPL;
3892 }
3893
3894 static HRESULT WINAPI
3895 ITextDocument_fnGetStoryRanges(ITextDocument* me,
3896 ITextStoryRanges** ppStories)
3897 {
3898 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3899 FIXME("stub %p\n",This);
3900 return E_NOTIMPL;
3901 }
3902
3903 static HRESULT WINAPI
3904 ITextDocument_fnGetSaved(ITextDocument* me, LONG* pValue)
3905 {
3906 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3907 FIXME("stub %p\n",This);
3908 return E_NOTIMPL;
3909 }
3910
3911 static HRESULT WINAPI
3912 ITextDocument_fnSetSaved(ITextDocument* me, LONG Value)
3913 {
3914 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3915 FIXME("stub %p\n",This);
3916 return E_NOTIMPL;
3917 }
3918
3919 static HRESULT WINAPI
3920 ITextDocument_fnGetDefaultTabStop(ITextDocument* me, float* pValue)
3921 {
3922 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3923 FIXME("stub %p\n",This);
3924 return E_NOTIMPL;
3925 }
3926
3927 static HRESULT WINAPI
3928 ITextDocument_fnSetDefaultTabStop(ITextDocument* me, float Value)
3929 {
3930 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3931 FIXME("stub %p\n",This);
3932 return E_NOTIMPL;
3933 }
3934
3935 static HRESULT WINAPI
3936 ITextDocument_fnNew(ITextDocument* me)
3937 {
3938 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3939 FIXME("stub %p\n",This);
3940 return E_NOTIMPL;
3941 }
3942
3943 static HRESULT WINAPI
3944 ITextDocument_fnOpen(ITextDocument* me, VARIANT* pVar, LONG Flags,
3945 LONG CodePage)
3946 {
3947 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3948 FIXME("stub %p\n",This);
3949 return E_NOTIMPL;
3950 }
3951
3952 static HRESULT WINAPI
3953 ITextDocument_fnSave(ITextDocument* me, VARIANT* pVar, LONG Flags,
3954 LONG CodePage)
3955 {
3956 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3957 FIXME("stub %p\n",This);
3958 return E_NOTIMPL;
3959 }
3960
3961 static HRESULT WINAPI
3962 ITextDocument_fnFreeze(ITextDocument* me, LONG* pCount)
3963 {
3964 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3965 FIXME("stub %p\n",This);
3966 return E_NOTIMPL;
3967 }
3968
3969 static HRESULT WINAPI
3970 ITextDocument_fnUnfreeze(ITextDocument* me, LONG* pCount)
3971 {
3972 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3973 FIXME("stub %p\n",This);
3974 return E_NOTIMPL;
3975 }
3976
3977 static HRESULT WINAPI
3978 ITextDocument_fnBeginEditCollection(ITextDocument* me)
3979 {
3980 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3981 FIXME("stub %p\n",This);
3982 return E_NOTIMPL;
3983 }
3984
3985 static HRESULT WINAPI
3986 ITextDocument_fnEndEditCollection(ITextDocument* me)
3987 {
3988 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3989 FIXME("stub %p\n",This);
3990 return E_NOTIMPL;
3991 }
3992
3993 static HRESULT WINAPI
3994 ITextDocument_fnUndo(ITextDocument* me, LONG Count, LONG* prop)
3995 {
3996 IRichEditOleImpl *This = impl_from_ITextDocument(me);
3997 FIXME("stub %p\n",This);
3998 return E_NOTIMPL;
3999 }
4000
4001 static HRESULT WINAPI
4002 ITextDocument_fnRedo(ITextDocument* me, LONG Count, LONG* prop)
4003 {
4004 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4005 FIXME("stub %p\n",This);
4006 return E_NOTIMPL;
4007 }
4008
4009 static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, ITextRange** ppRange)
4010 {
4011 ITextRangeImpl *txtRge = heap_alloc(sizeof(ITextRangeImpl));
4012
4013 if (!txtRge)
4014 return E_OUTOFMEMORY;
4015 txtRge->ITextRange_iface.lpVtbl = &trvt;
4016 txtRge->ref = 1;
4017 txtRge->child.reole = reOle;
4018 txtRge->start = start;
4019 txtRge->end = end;
4020 list_add_head(&reOle->rangelist, &txtRge->child.entry);
4021 *ppRange = &txtRge->ITextRange_iface;
4022 return S_OK;
4023 }
4024
4025 static HRESULT WINAPI
4026 ITextDocument_fnRange(ITextDocument* me, LONG cp1, LONG cp2,
4027 ITextRange** ppRange)
4028 {
4029 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4030 const int len = ME_GetTextLength(This->editor) + 1;
4031
4032 TRACE("%p %p %d %d\n", This, ppRange, cp1, cp2);
4033 if (!ppRange)
4034 return E_INVALIDARG;
4035
4036 cp1 = max(cp1, 0);
4037 cp2 = max(cp2, 0);
4038 cp1 = min(cp1, len);
4039 cp2 = min(cp2, len);
4040 if (cp1 > cp2)
4041 {
4042 LONG tmp;
4043 tmp = cp1;
4044 cp1 = cp2;
4045 cp2 = tmp;
4046 }
4047 if (cp1 == len)
4048 cp1 = cp2 = len - 1;
4049
4050 return CreateITextRange(This, cp1, cp2, ppRange);
4051 }
4052
4053 static HRESULT WINAPI
4054 ITextDocument_fnRangeFromPoint(ITextDocument* me, LONG x, LONG y,
4055 ITextRange** ppRange)
4056 {
4057 IRichEditOleImpl *This = impl_from_ITextDocument(me);
4058 FIXME("stub %p\n",This);
4059 return E_NOTIMPL;
4060 }
4061
4062 static const ITextDocumentVtbl tdvt = {
4063 ITextDocument_fnQueryInterface,
4064 ITextDocument_fnAddRef,
4065 ITextDocument_fnRelease,
4066 ITextDocument_fnGetTypeInfoCount,
4067 ITextDocument_fnGetTypeInfo,
4068 ITextDocument_fnGetIDsOfNames,
4069 ITextDocument_fnInvoke,
4070 ITextDocument_fnGetName,
4071 ITextDocument_fnGetSelection,
4072 ITextDocument_fnGetStoryCount,
4073 ITextDocument_fnGetStoryRanges,
4074 ITextDocument_fnGetSaved,
4075 ITextDocument_fnSetSaved,
4076 ITextDocument_fnGetDefaultTabStop,
4077 ITextDocument_fnSetDefaultTabStop,
4078 ITextDocument_fnNew,
4079 ITextDocument_fnOpen,
4080 ITextDocument_fnSave,
4081 ITextDocument_fnFreeze,
4082 ITextDocument_fnUnfreeze,
4083 ITextDocument_fnBeginEditCollection,
4084 ITextDocument_fnEndEditCollection,
4085 ITextDocument_fnUndo,
4086 ITextDocument_fnRedo,
4087 ITextDocument_fnRange,
4088 ITextDocument_fnRangeFromPoint
4089 };
4090
4091 /* ITextSelection */
4092 static HRESULT WINAPI ITextSelection_fnQueryInterface(
4093 ITextSelection *me,
4094 REFIID riid,
4095 void **ppvObj)
4096 {
4097 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4098
4099 *ppvObj = NULL;
4100 if (IsEqualGUID(riid, &IID_IUnknown)
4101 || IsEqualGUID(riid, &IID_IDispatch)
4102 || IsEqualGUID(riid, &IID_ITextRange)
4103 || IsEqualGUID(riid, &IID_ITextSelection))
4104 {
4105 *ppvObj = me;
4106 ITextSelection_AddRef(me);
4107 return S_OK;
4108 }
4109 else if (IsEqualGUID(riid, &IID_Igetrichole))
4110 {
4111 *ppvObj = This->reOle;
4112 return S_OK;
4113 }
4114
4115 return E_NOINTERFACE;
4116 }
4117
4118 static ULONG WINAPI ITextSelection_fnAddRef(ITextSelection *me)
4119 {
4120 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4121 return InterlockedIncrement(&This->ref);
4122 }
4123
4124 static ULONG WINAPI ITextSelection_fnRelease(ITextSelection *me)
4125 {
4126 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4127 ULONG ref = InterlockedDecrement(&This->ref);
4128 if (ref == 0)
4129 heap_free(This);
4130 return ref;
4131 }
4132
4133 static HRESULT WINAPI ITextSelection_fnGetTypeInfoCount(ITextSelection *me, UINT *pctinfo)
4134 {
4135 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4136 TRACE("(%p)->(%p)\n", This, pctinfo);
4137 *pctinfo = 1;
4138 return S_OK;
4139 }
4140
4141 static HRESULT WINAPI ITextSelection_fnGetTypeInfo(ITextSelection *me, UINT iTInfo, LCID lcid,
4142 ITypeInfo **ppTInfo)
4143 {
4144 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4145 HRESULT hr;
4146
4147 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
4148
4149 hr = get_typeinfo(ITextSelection_tid, ppTInfo);
4150 if (SUCCEEDED(hr))
4151 ITypeInfo_AddRef(*ppTInfo);
4152 return hr;
4153 }
4154
4155 static HRESULT WINAPI ITextSelection_fnGetIDsOfNames(ITextSelection *me, REFIID riid,
4156 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
4157 {
4158 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4159 ITypeInfo *ti;
4160 HRESULT hr;
4161
4162 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
4163 rgDispId);
4164
4165 hr = get_typeinfo(ITextSelection_tid, &ti);
4166 if (SUCCEEDED(hr))
4167 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
4168 return hr;
4169 }
4170
4171 static HRESULT WINAPI ITextSelection_fnInvoke(
4172 ITextSelection *me,
4173 DISPID dispIdMember,
4174 REFIID riid,
4175 LCID lcid,
4176 WORD wFlags,
4177 DISPPARAMS *pDispParams,
4178 VARIANT *pVarResult,
4179 EXCEPINFO *pExcepInfo,
4180 UINT *puArgErr)
4181 {
4182 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4183 ITypeInfo *ti;
4184 HRESULT hr;
4185
4186 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid), lcid,
4187 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4188
4189 hr = get_typeinfo(ITextSelection_tid, &ti);
4190 if (SUCCEEDED(hr))
4191 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
4192 return hr;
4193 }
4194
4195 /*** ITextRange methods ***/
4196 static HRESULT WINAPI ITextSelection_fnGetText(ITextSelection *me, BSTR *pbstr)
4197 {
4198 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4199 ME_Cursor *start = NULL, *end = NULL;
4200 int nChars, endOfs;
4201 BOOL bEOP;
4202
4203 TRACE("(%p)->(%p)\n", This, pbstr);
4204
4205 if (!This->reOle)
4206 return CO_E_RELEASED;
4207
4208 if (!pbstr)
4209 return E_INVALIDARG;
4210
4211 ME_GetSelection(This->reOle->editor, &start, &end);
4212 endOfs = ME_GetCursorOfs(end);
4213 nChars = endOfs - ME_GetCursorOfs(start);
4214 if (!nChars)
4215 {
4216 *pbstr = NULL;
4217 return S_OK;
4218 }
4219
4220 *pbstr = SysAllocStringLen(NULL, nChars);
4221 if (!*pbstr)
4222 return E_OUTOFMEMORY;
4223
4224 bEOP = (end->pRun->next->type == diTextEnd && endOfs > ME_GetTextLength(This->reOle->editor));
4225 ME_GetTextW(This->reOle->editor, *pbstr, nChars, start, nChars, FALSE, bEOP);
4226 TRACE("%s\n", wine_dbgstr_w(*pbstr));
4227
4228 return S_OK;
4229 }
4230
4231 static HRESULT WINAPI ITextSelection_fnSetText(ITextSelection *me, BSTR str)
4232 {
4233 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4234 ME_TextEditor *editor;
4235 int len, to, from;
4236
4237 TRACE("(%p)->(%s)\n", This, debugstr_w(str));
4238
4239 if (!This->reOle)
4240 return CO_E_RELEASED;
4241
4242 editor = This->reOle->editor;
4243 len = strlenW(str);
4244 ME_GetSelectionOfs(editor, &from, &to);
4245 ME_ReplaceSel(editor, FALSE, str, len);
4246
4247 if (len < to - from)
4248 textranges_update_ranges(This->reOle, from, len, RANGE_UPDATE_DELETE);
4249
4250 return S_OK;
4251 }
4252
4253 static HRESULT WINAPI ITextSelection_fnGetChar(ITextSelection *me, LONG *pch)
4254 {
4255 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4256 ME_Cursor *start = NULL, *end = NULL;
4257
4258 TRACE("(%p)->(%p)\n", This, pch);
4259
4260 if (!This->reOle)
4261 return CO_E_RELEASED;
4262
4263 if (!pch)
4264 return E_INVALIDARG;
4265
4266 ME_GetSelection(This->reOle->editor, &start, &end);
4267 return range_GetChar(This->reOle->editor, start, pch);
4268 }
4269
4270 static HRESULT WINAPI ITextSelection_fnSetChar(ITextSelection *me, LONG ch)
4271 {
4272 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4273
4274 FIXME("(%p)->(%x): stub\n", This, ch);
4275
4276 if (!This->reOle)
4277 return CO_E_RELEASED;
4278
4279 return E_NOTIMPL;
4280 }
4281
4282 static HRESULT WINAPI ITextSelection_fnGetDuplicate(ITextSelection *me, ITextRange **range)
4283 {
4284 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4285 LONG start, end;
4286
4287 TRACE("(%p)->(%p)\n", This, range);
4288
4289 if (!This->reOle)
4290 return CO_E_RELEASED;
4291
4292 if (!range)
4293 return E_INVALIDARG;
4294
4295 ITextSelection_GetStart(me, &start);
4296 ITextSelection_GetEnd(me, &end);
4297 return CreateITextRange(This->reOle, start, end, range);
4298 }
4299
4300 static HRESULT WINAPI ITextSelection_fnGetFormattedText(ITextSelection *me, ITextRange **range)
4301 {
4302 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4303
4304 FIXME("(%p)->(%p): stub\n", This, range);
4305
4306 if (!This->reOle)
4307 return CO_E_RELEASED;
4308
4309 return E_NOTIMPL;
4310 }
4311
4312 static HRESULT WINAPI ITextSelection_fnSetFormattedText(ITextSelection *me, ITextRange *range)
4313 {
4314 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4315
4316 FIXME("(%p)->(%p): stub\n", This, range);
4317
4318 if (!This->reOle)
4319 return CO_E_RELEASED;
4320
4321 FIXME("not implemented\n");
4322 return E_NOTIMPL;
4323 }
4324
4325 static HRESULT WINAPI ITextSelection_fnGetStart(ITextSelection *me, LONG *pcpFirst)
4326 {
4327 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4328 LONG lim;
4329
4330 TRACE("(%p)->(%p)\n", This, pcpFirst);
4331
4332 if (!This->reOle)
4333 return CO_E_RELEASED;
4334
4335 if (!pcpFirst)
4336 return E_INVALIDARG;
4337 ME_GetSelectionOfs(This->reOle->editor, pcpFirst, &lim);
4338 return S_OK;
4339 }
4340
4341 static HRESULT WINAPI ITextSelection_fnSetStart(ITextSelection *me, LONG value)
4342 {
4343 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4344 LONG start, end;
4345 HRESULT hr;
4346
4347 TRACE("(%p)->(%d)\n", This, value);
4348
4349 if (!This->reOle)
4350 return CO_E_RELEASED;
4351
4352 ME_GetSelectionOfs(This->reOle->editor, &start, &end);
4353 hr = textrange_setstart(This->reOle, value, &start, &end);
4354 if (hr == S_OK)
4355 ME_SetSelection(This->reOle->editor, start, end);
4356
4357 return hr;
4358 }
4359
4360 static HRESULT WINAPI ITextSelection_fnGetEnd(ITextSelection *me, LONG *pcpLim)
4361 {
4362 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4363 LONG first;
4364
4365 TRACE("(%p)->(%p)\n", This, pcpLim);
4366
4367 if (!This->reOle)
4368 return CO_E_RELEASED;
4369
4370 if (!pcpLim)
4371 return E_INVALIDARG;
4372 ME_GetSelectionOfs(This->reOle->editor, &first, pcpLim);
4373 return S_OK;
4374 }
4375
4376 static HRESULT WINAPI ITextSelection_fnSetEnd(ITextSelection *me, LONG value)
4377 {
4378 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4379 LONG start, end;
4380 HRESULT hr;
4381
4382 TRACE("(%p)->(%d)\n", This, value);
4383
4384 if (!This->reOle)
4385 return CO_E_RELEASED;
4386
4387 ME_GetSelectionOfs(This->reOle->editor, &start, &end);
4388 hr = textrange_setend(This->reOle, value, &start, &end);
4389 if (hr == S_OK)
4390 ME_SetSelection(This->reOle->editor, start, end);
4391
4392 return hr;
4393 }
4394
4395 static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **font)
4396 {
4397 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4398
4399 TRACE("(%p)->(%p)\n", This, font);
4400
4401 if (!This->reOle)
4402 return CO_E_RELEASED;
4403
4404 if (!font)
4405 return E_INVALIDARG;
4406
4407 return create_textfont((ITextRange*)me, NULL, font);
4408 }
4409
4410 static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *font)
4411 {
4412 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4413
4414 TRACE("(%p)->(%p)\n", This, font);
4415
4416 if (!font)
4417 return E_INVALIDARG;
4418
4419 if (!This->reOle)
4420 return CO_E_RELEASED;
4421
4422 textrange_set_font((ITextRange*)me, font);
4423 return S_OK;
4424 }
4425
4426 static HRESULT WINAPI ITextSelection_fnGetPara(ITextSelection *me, ITextPara **para)
4427 {
4428 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4429
4430 TRACE("(%p)->(%p)\n", This, para);
4431
4432 if (!This->reOle)
4433 return CO_E_RELEASED;
4434
4435 if (!para)
4436 return E_INVALIDARG;
4437
4438 return create_textpara((ITextRange*)me, para);
4439 }
4440
4441 static HRESULT WINAPI ITextSelection_fnSetPara(ITextSelection *me, ITextPara *para)
4442 {
4443 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4444
4445 FIXME("(%p)->(%p): stub\n", This, para);
4446
4447 if (!This->reOle)
4448 return CO_E_RELEASED;
4449
4450 FIXME("not implemented\n");
4451 return E_NOTIMPL;
4452 }
4453
4454 static HRESULT WINAPI ITextSelection_fnGetStoryLength(ITextSelection *me, LONG *length)
4455 {
4456 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4457
4458 TRACE("(%p)->(%p)\n", This, length);
4459
4460 if (!This->reOle)
4461 return CO_E_RELEASED;
4462
4463 return textrange_get_storylength(This->reOle->editor, length);
4464 }
4465
4466 static HRESULT WINAPI ITextSelection_fnGetStoryType(ITextSelection *me, LONG *value)
4467 {
4468 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4469
4470 TRACE("(%p)->(%p)\n", This, value);
4471
4472 if (!This->reOle)
4473 return CO_E_RELEASED;
4474
4475 if (!value)
4476 return E_INVALIDARG;
4477
4478 *value = tomUnknownStory;
4479 return S_OK;
4480 }
4481
4482 static HRESULT WINAPI ITextSelection_fnCollapse(ITextSelection *me, LONG bStart)
4483 {
4484 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4485 LONG start, end;
4486 HRESULT hres;
4487
4488 TRACE("(%p)->(%d)\n", This, bStart);
4489
4490 if (!This->reOle)
4491 return CO_E_RELEASED;
4492
4493 ME_GetSelectionOfs(This->reOle->editor, &start, &end);
4494 hres = range_Collapse(bStart, &start, &end);
4495 if (SUCCEEDED(hres))
4496 ME_SetSelection(This->reOle->editor, start, end);
4497 return hres;
4498 }
4499
4500 static HRESULT WINAPI ITextSelection_fnExpand(ITextSelection *me, LONG unit, LONG *delta)
4501 {
4502 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4503
4504 TRACE("(%p)->(%d %p)\n", This, unit, delta);
4505
4506 if (!This->reOle)
4507 return CO_E_RELEASED;
4508
4509 return textrange_expand((ITextRange*)me, unit, delta);
4510 }
4511
4512 static HRESULT WINAPI ITextSelection_fnGetIndex(ITextSelection *me, LONG unit, LONG *index)
4513 {
4514 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4515
4516 FIXME("(%p)->(%d %p): stub\n", This, unit, index);
4517
4518 if (!This->reOle)
4519 return CO_E_RELEASED;
4520
4521 return E_NOTIMPL;
4522 }
4523
4524 static HRESULT WINAPI ITextSelection_fnSetIndex(ITextSelection *me, LONG unit, LONG index,
4525 LONG extend)
4526 {
4527 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4528
4529 FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend);
4530
4531 if (!This->reOle)
4532 return CO_E_RELEASED;
4533
4534 return E_NOTIMPL;
4535 }
4536
4537 static HRESULT WINAPI ITextSelection_fnSetRange(ITextSelection *me, LONG anchor, LONG active)
4538 {
4539 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4540
4541 FIXME("(%p)->(%d %d): stub\n", This, anchor, active);
4542
4543 if (!This->reOle)
4544 return CO_E_RELEASED;
4545
4546 return E_NOTIMPL;
4547 }
4548
4549 static HRESULT WINAPI ITextSelection_fnInRange(ITextSelection *me, ITextRange *range, LONG *ret)
4550 {
4551 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4552 ITextSelection *selection = NULL;
4553 LONG start, end;
4554
4555 TRACE("(%p)->(%p %p)\n", This, range, ret);
4556
4557 if (ret)
4558 *ret = tomFalse;
4559
4560 if (!This->reOle)
4561 return CO_E_RELEASED;
4562
4563 if (!range)
4564 return S_FALSE;
4565
4566 ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection);
4567 if (!selection)
4568 return S_FALSE;
4569 ITextSelection_Release(selection);
4570
4571 ITextSelection_GetStart(me, &start);
4572 ITextSelection_GetEnd(me, &end);
4573 return textrange_inrange(start, end, range, ret);
4574 }
4575
4576 static HRESULT WINAPI ITextSelection_fnInStory(ITextSelection *me, ITextRange *range, LONG *ret)
4577 {
4578 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4579
4580 FIXME("(%p)->(%p %p): stub\n", This, range, ret);
4581
4582 if (!This->reOle)
4583 return CO_E_RELEASED;
4584
4585 return E_NOTIMPL;
4586 }
4587
4588 static HRESULT WINAPI ITextSelection_fnIsEqual(ITextSelection *me, ITextRange *range, LONG *ret)
4589 {
4590 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4591 ITextSelection *selection = NULL;
4592 LONG start, end;
4593
4594 TRACE("(%p)->(%p %p)\n", This, range, ret);
4595
4596 if (ret)
4597 *ret = tomFalse;
4598
4599 if (!This->reOle)
4600 return CO_E_RELEASED;
4601
4602 if (!range)
4603 return S_FALSE;
4604
4605 ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection);
4606 if (!selection)
4607 return S_FALSE;
4608 ITextSelection_Release(selection);
4609
4610 ITextSelection_GetStart(me, &start);
4611 ITextSelection_GetEnd(me, &end);
4612 return textrange_isequal(start, end, range, ret);
4613 }
4614
4615 static HRESULT WINAPI ITextSelection_fnSelect(ITextSelection *me)
4616 {
4617 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4618
4619 TRACE("(%p)\n", This);
4620
4621 if (!This->reOle)
4622 return CO_E_RELEASED;
4623
4624 /* nothing to do */
4625 return S_OK;
4626 }
4627
4628 static HRESULT WINAPI ITextSelection_fnStartOf(ITextSelection *me, LONG unit, LONG extend,
4629 LONG *delta)
4630 {
4631 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4632
4633 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
4634
4635 if (!This->reOle)
4636 return CO_E_RELEASED;
4637
4638 return E_NOTIMPL;
4639 }
4640
4641 static HRESULT WINAPI ITextSelection_fnEndOf(ITextSelection *me, LONG unit, LONG extend,
4642 LONG *delta)
4643 {
4644 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4645
4646 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
4647
4648 if (!This->reOle)
4649 return CO_E_RELEASED;
4650
4651 return E_NOTIMPL;
4652 }
4653
4654 static HRESULT WINAPI ITextSelection_fnMove(ITextSelection *me, LONG unit, LONG count, LONG *delta)
4655 {
4656 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4657
4658 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
4659
4660 if (!This->reOle)
4661 return CO_E_RELEASED;
4662
4663 return E_NOTIMPL;
4664 }
4665
4666 static HRESULT WINAPI ITextSelection_fnMoveStart(ITextSelection *me, LONG unit, LONG count,
4667 LONG *delta)
4668 {
4669 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4670
4671 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
4672
4673 if (!This->reOle)
4674 return CO_E_RELEASED;
4675
4676 return E_NOTIMPL;
4677 }
4678
4679 static HRESULT WINAPI ITextSelection_fnMoveEnd(ITextSelection *me, LONG unit, LONG count,
4680 LONG *delta)
4681 {
4682 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4683
4684 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
4685
4686 if (!This->reOle)
4687 return CO_E_RELEASED;
4688
4689 return E_NOTIMPL;
4690 }
4691
4692 static HRESULT WINAPI ITextSelection_fnMoveWhile(ITextSelection *me, VARIANT *charset, LONG count,
4693 LONG *delta)
4694 {
4695 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4696
4697 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4698
4699 if (!This->reOle)
4700 return CO_E_RELEASED;
4701
4702 return E_NOTIMPL;
4703 }
4704
4705 static HRESULT WINAPI ITextSelection_fnMoveStartWhile(ITextSelection *me, VARIANT *charset, LONG count,
4706 LONG *delta)
4707 {
4708 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4709
4710 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4711
4712 if (!This->reOle)
4713 return CO_E_RELEASED;
4714
4715 return E_NOTIMPL;
4716 }
4717
4718 static HRESULT WINAPI ITextSelection_fnMoveEndWhile(ITextSelection *me, VARIANT *charset, LONG count,
4719 LONG *delta)
4720 {
4721 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4722
4723 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4724
4725 if (!This->reOle)
4726 return CO_E_RELEASED;
4727
4728 return E_NOTIMPL;
4729 }
4730
4731 static HRESULT WINAPI ITextSelection_fnMoveUntil(ITextSelection *me, VARIANT *charset, LONG count,
4732 LONG *delta)
4733 {
4734 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4735
4736 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4737
4738 if (!This->reOle)
4739 return CO_E_RELEASED;
4740
4741 return E_NOTIMPL;
4742 }
4743
4744 static HRESULT WINAPI ITextSelection_fnMoveStartUntil(ITextSelection *me, VARIANT *charset, LONG count,
4745 LONG *delta)
4746 {
4747 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4748
4749 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4750
4751 if (!This->reOle)
4752 return CO_E_RELEASED;
4753
4754 return E_NOTIMPL;
4755 }
4756
4757 static HRESULT WINAPI ITextSelection_fnMoveEndUntil(ITextSelection *me, VARIANT *charset, LONG count,
4758 LONG *delta)
4759 {
4760 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4761
4762 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
4763
4764 if (!This->reOle)
4765 return CO_E_RELEASED;
4766
4767 return E_NOTIMPL;
4768 }
4769
4770 static HRESULT WINAPI ITextSelection_fnFindText(ITextSelection *me, BSTR text, LONG count, LONG flags,
4771 LONG *length)
4772 {
4773 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4774
4775 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
4776
4777 if (!This->reOle)
4778 return CO_E_RELEASED;
4779
4780 FIXME("not implemented\n");
4781 return E_NOTIMPL;
4782 }
4783
4784 static HRESULT WINAPI ITextSelection_fnFindTextStart(ITextSelection *me, BSTR text, LONG count,
4785 LONG flags, LONG *length)
4786 {
4787 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4788
4789 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
4790
4791 if (!This->reOle)
4792 return CO_E_RELEASED;
4793
4794 return E_NOTIMPL;
4795 }
4796
4797 static HRESULT WINAPI ITextSelection_fnFindTextEnd(ITextSelection *me, BSTR text, LONG count,
4798 LONG flags, LONG *length)
4799 {
4800 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4801
4802 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
4803
4804 if (!This->reOle)
4805 return CO_E_RELEASED;
4806
4807 return E_NOTIMPL;
4808 }
4809
4810 static HRESULT WINAPI ITextSelection_fnDelete(ITextSelection *me, LONG unit, LONG count,
4811 LONG *delta)
4812 {
4813 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4814
4815 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
4816
4817 if (!This->reOle)
4818 return CO_E_RELEASED;
4819
4820 return E_NOTIMPL;
4821 }
4822
4823 static HRESULT WINAPI ITextSelection_fnCut(ITextSelection *me, VARIANT *v)
4824 {
4825 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4826
4827 FIXME("(%p)->(%p): stub\n", This, v);
4828
4829 if (!This->reOle)
4830 return CO_E_RELEASED;
4831
4832 return E_NOTIMPL;
4833 }
4834
4835 static HRESULT WINAPI ITextSelection_fnCopy(ITextSelection *me, VARIANT *v)
4836 {
4837 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4838
4839 FIXME("(%p)->(%p): stub\n", This, v);
4840
4841 if (!This->reOle)
4842 return CO_E_RELEASED;
4843
4844 return E_NOTIMPL;
4845 }
4846
4847 static HRESULT WINAPI ITextSelection_fnPaste(ITextSelection *me, VARIANT *v, LONG format)
4848 {
4849 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4850
4851 FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format);
4852
4853 if (!This->reOle)
4854 return CO_E_RELEASED;
4855
4856 return E_NOTIMPL;
4857 }
4858
4859 static HRESULT WINAPI ITextSelection_fnCanPaste(ITextSelection *me, VARIANT *v, LONG format,
4860 LONG *ret)
4861 {
4862 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4863
4864 FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret);
4865
4866 if (!This->reOle)
4867 return CO_E_RELEASED;
4868
4869 return E_NOTIMPL;
4870 }
4871
4872 static HRESULT WINAPI ITextSelection_fnCanEdit(ITextSelection *me, LONG *ret)
4873 {
4874 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4875
4876 FIXME("(%p)->(%p): stub\n", This, ret);
4877
4878 if (!This->reOle)
4879 return CO_E_RELEASED;
4880
4881 return E_NOTIMPL;
4882 }
4883
4884 static HRESULT WINAPI ITextSelection_fnChangeCase(ITextSelection *me, LONG type)
4885 {
4886 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4887
4888 FIXME("(%p)->(%d): stub\n", This, type);
4889
4890 if (!This->reOle)
4891 return CO_E_RELEASED;
4892
4893 return E_NOTIMPL;
4894 }
4895
4896 static HRESULT WINAPI ITextSelection_fnGetPoint(ITextSelection *me, LONG type, LONG *cx, LONG *cy)
4897 {
4898 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4899
4900 FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy);
4901
4902 if (!This->reOle)
4903 return CO_E_RELEASED;
4904
4905 return E_NOTIMPL;
4906 }
4907
4908 static HRESULT WINAPI ITextSelection_fnSetPoint(ITextSelection *me, LONG x, LONG y, LONG type,
4909 LONG extend)
4910 {
4911 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4912
4913 FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend);
4914
4915 if (!This->reOle)
4916 return CO_E_RELEASED;
4917
4918 return E_NOTIMPL;
4919 }
4920
4921 static HRESULT WINAPI ITextSelection_fnScrollIntoView(ITextSelection *me, LONG value)
4922 {
4923 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4924
4925 FIXME("(%p)->(%d): stub\n", This, value);
4926
4927 if (!This->reOle)
4928 return CO_E_RELEASED;
4929
4930 return E_NOTIMPL;
4931 }
4932
4933 static HRESULT WINAPI ITextSelection_fnGetEmbeddedObject(ITextSelection *me, IUnknown **ppv)
4934 {
4935 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4936
4937 FIXME("(%p)->(%p): stub\n", This, ppv);
4938
4939 if (!This->reOle)
4940 return CO_E_RELEASED;
4941
4942 return E_NOTIMPL;
4943 }
4944
4945 /*** ITextSelection methods ***/
4946 static HRESULT WINAPI ITextSelection_fnGetFlags(ITextSelection *me, LONG *flags)
4947 {
4948 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4949
4950 FIXME("(%p)->(%p): stub\n", This, flags);
4951
4952 if (!This->reOle)
4953 return CO_E_RELEASED;
4954
4955 return E_NOTIMPL;
4956 }
4957
4958 static HRESULT WINAPI ITextSelection_fnSetFlags(ITextSelection *me, LONG flags)
4959 {
4960 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4961
4962 FIXME("(%p)->(%x): stub\n", This, flags);
4963
4964 if (!This->reOle)
4965 return CO_E_RELEASED;
4966
4967 return E_NOTIMPL;
4968 }
4969
4970 static HRESULT WINAPI ITextSelection_fnGetType(ITextSelection *me, LONG *type)
4971 {
4972 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4973
4974 FIXME("(%p)->(%p): stub\n", This, type);
4975
4976 if (!This->reOle)
4977 return CO_E_RELEASED;
4978
4979 return E_NOTIMPL;
4980 }
4981
4982 static HRESULT WINAPI ITextSelection_fnMoveLeft(ITextSelection *me, LONG unit, LONG count,
4983 LONG extend, LONG *delta)
4984 {
4985 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4986
4987 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
4988
4989 if (!This->reOle)
4990 return CO_E_RELEASED;
4991
4992 return E_NOTIMPL;
4993 }
4994
4995 static HRESULT WINAPI ITextSelection_fnMoveRight(ITextSelection *me, LONG unit, LONG count,
4996 LONG extend, LONG *delta)
4997 {
4998 ITextSelectionImpl *This = impl_from_ITextSelection(me);
4999
5000 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5001
5002 if (!This->reOle)
5003 return CO_E_RELEASED;
5004
5005 return E_NOTIMPL;
5006 }
5007
5008 static HRESULT WINAPI ITextSelection_fnMoveUp(ITextSelection *me, LONG unit, LONG count,
5009 LONG extend, LONG *delta)
5010 {
5011 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5012
5013 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5014
5015 if (!This->reOle)
5016 return CO_E_RELEASED;
5017
5018 return E_NOTIMPL;
5019 }
5020
5021 static HRESULT WINAPI ITextSelection_fnMoveDown(ITextSelection *me, LONG unit, LONG count,
5022 LONG extend, LONG *delta)
5023 {
5024 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5025
5026 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta);
5027
5028 if (!This->reOle)
5029 return CO_E_RELEASED;
5030
5031 return E_NOTIMPL;
5032 }
5033
5034 static HRESULT WINAPI ITextSelection_fnHomeKey(ITextSelection *me, LONG unit, LONG extend,
5035 LONG *delta)
5036 {
5037 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5038
5039 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
5040
5041 if (!This->reOle)
5042 return CO_E_RELEASED;
5043
5044 return E_NOTIMPL;
5045 }
5046
5047 static HRESULT WINAPI ITextSelection_fnEndKey(ITextSelection *me, LONG unit, LONG extend,
5048 LONG *delta)
5049 {
5050 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5051
5052 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
5053
5054 if (!This->reOle)
5055 return CO_E_RELEASED;
5056
5057 return E_NOTIMPL;
5058 }
5059
5060 static HRESULT WINAPI ITextSelection_fnTypeText(ITextSelection *me, BSTR text)
5061 {
5062 ITextSelectionImpl *This = impl_from_ITextSelection(me);
5063
5064 FIXME("(%p)->(%s): stub\n", This, debugstr_w(text));
5065
5066 if (!This->reOle)
5067 return CO_E_RELEASED;
5068
5069 return E_NOTIMPL;
5070 }
5071
5072 static const ITextSelectionVtbl tsvt = {
5073 ITextSelection_fnQueryInterface,
5074 ITextSelection_fnAddRef,
5075 ITextSelection_fnRelease,
5076 ITextSelection_fnGetTypeInfoCount,
5077 ITextSelection_fnGetTypeInfo,
5078 ITextSelection_fnGetIDsOfNames,
5079 ITextSelection_fnInvoke,
5080 ITextSelection_fnGetText,
5081 ITextSelection_fnSetText,
5082 ITextSelection_fnGetChar,
5083 ITextSelection_fnSetChar,
5084 ITextSelection_fnGetDuplicate,
5085 ITextSelection_fnGetFormattedText,
5086 ITextSelection_fnSetFormattedText,
5087 ITextSelection_fnGetStart,
5088 ITextSelection_fnSetStart,
5089 ITextSelection_fnGetEnd,
5090 ITextSelection_fnSetEnd,
5091 ITextSelection_fnGetFont,
5092 ITextSelection_fnSetFont,
5093 ITextSelection_fnGetPara,
5094 ITextSelection_fnSetPara,
5095 ITextSelection_fnGetStoryLength,
5096 ITextSelection_fnGetStoryType,
5097 ITextSelection_fnCollapse,
5098 ITextSelection_fnExpand,
5099 ITextSelection_fnGetIndex,
5100 ITextSelection_fnSetIndex,
5101 ITextSelection_fnSetRange,
5102 ITextSelection_fnInRange,
5103 ITextSelection_fnInStory,
5104 ITextSelection_fnIsEqual,
5105 ITextSelection_fnSelect,
5106 ITextSelection_fnStartOf,
5107 ITextSelection_fnEndOf,
5108 ITextSelection_fnMove,
5109 ITextSelection_fnMoveStart,
5110 ITextSelection_fnMoveEnd,
5111 ITextSelection_fnMoveWhile,
5112 ITextSelection_fnMoveStartWhile,
5113 ITextSelection_fnMoveEndWhile,
5114 ITextSelection_fnMoveUntil,
5115 ITextSelection_fnMoveStartUntil,
5116 ITextSelection_fnMoveEndUntil,
5117 ITextSelection_fnFindText,
5118 ITextSelection_fnFindTextStart,
5119 ITextSelection_fnFindTextEnd,
5120 ITextSelection_fnDelete,
5121 ITextSelection_fnCut,
5122 ITextSelection_fnCopy,
5123 ITextSelection_fnPaste,
5124 ITextSelection_fnCanPaste,
5125 ITextSelection_fnCanEdit,
5126 ITextSelection_fnChangeCase,
5127 ITextSelection_fnGetPoint,
5128 ITextSelection_fnSetPoint,
5129 ITextSelection_fnScrollIntoView,
5130 ITextSelection_fnGetEmbeddedObject,
5131 ITextSelection_fnGetFlags,
5132 ITextSelection_fnSetFlags,
5133 ITextSelection_fnGetType,
5134 ITextSelection_fnMoveLeft,
5135 ITextSelection_fnMoveRight,
5136 ITextSelection_fnMoveUp,
5137 ITextSelection_fnMoveDown,
5138 ITextSelection_fnHomeKey,
5139 ITextSelection_fnEndKey,
5140 ITextSelection_fnTypeText
5141 };
5142
5143 static ITextSelectionImpl *
5144 CreateTextSelection(IRichEditOleImpl *reOle)
5145 {
5146 ITextSelectionImpl *txtSel = heap_alloc(sizeof *txtSel);
5147 if (!txtSel)
5148 return NULL;
5149
5150 txtSel->ITextSelection_iface.lpVtbl = &tsvt;
5151 txtSel->ref = 1;
5152 txtSel->reOle = reOle;
5153 return txtSel;
5154 }
5155
5156 LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *ppvObj)
5157 {
5158 IRichEditOleImpl *reo;
5159
5160 reo = heap_alloc(sizeof(IRichEditOleImpl));
5161 if (!reo)
5162 return 0;
5163
5164 reo->IUnknown_inner.lpVtbl = &reo_unk_vtbl;
5165 reo->IRichEditOle_iface.lpVtbl = &revt;
5166 reo->ITextDocument_iface.lpVtbl = &tdvt;
5167 reo->ref = 1;
5168 reo->editor = editor;
5169 reo->txtSel = NULL;
5170
5171 TRACE("Created %p\n",reo);
5172 list_init(&reo->rangelist);
5173 list_init(&reo->clientsites);
5174 if (outer_unk)
5175 reo->outer_unk = outer_unk;
5176 else
5177 reo->outer_unk = &reo->IUnknown_inner;
5178 *ppvObj = &reo->IRichEditOle_iface;
5179
5180 return 1;
5181 }
5182
5183 static void convert_sizel(const ME_Context *c, const SIZEL* szl, SIZE* sz)
5184 {
5185 /* sizel is in .01 millimeters, sz in pixels */
5186 sz->cx = MulDiv(szl->cx, c->dpi.cx, 2540);
5187 sz->cy = MulDiv(szl->cy, c->dpi.cy, 2540);
5188 }
5189
5190 /******************************************************************************
5191 * ME_GetOLEObjectSize
5192 *
5193 * Sets run extent for OLE objects.
5194 */
5195 void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize)
5196 {
5197 IDataObject* ido;
5198 FORMATETC fmt;
5199 STGMEDIUM stgm;
5200 DIBSECTION dibsect;
5201 ENHMETAHEADER emh;
5202
5203 assert(run->nFlags & MERF_GRAPHICS);
5204 assert(run->ole_obj);
5205
5206 if (run->ole_obj->sizel.cx != 0 || run->ole_obj->sizel.cy != 0)
5207 {
5208 convert_sizel(c, &run->ole_obj->sizel, pSize);
5209 if (c->editor->nZoomNumerator != 0)
5210 {
5211 pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5212 pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5213 }
5214 return;
5215 }
5216
5217 if (!run->ole_obj->poleobj)
5218 {
5219 pSize->cx = pSize->cy = 0;
5220 return;
5221 }
5222
5223 if (IOleObject_QueryInterface(run->ole_obj->poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
5224 {
5225 FIXME("Query Interface IID_IDataObject failed!\n");
5226 pSize->cx = pSize->cy = 0;
5227 return;
5228 }
5229 fmt.cfFormat = CF_BITMAP;
5230 fmt.ptd = NULL;
5231 fmt.dwAspect = DVASPECT_CONTENT;
5232 fmt.lindex = -1;
5233 fmt.tymed = TYMED_GDI;
5234 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5235 {
5236 fmt.cfFormat = CF_ENHMETAFILE;
5237 fmt.tymed = TYMED_ENHMF;
5238 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5239 {
5240 FIXME("unsupported format\n");
5241 pSize->cx = pSize->cy = 0;
5242 IDataObject_Release(ido);
5243 return;
5244 }
5245 }
5246 IDataObject_Release(ido);
5247
5248 switch (stgm.tymed)
5249 {
5250 case TYMED_GDI:
5251 GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
5252 pSize->cx = dibsect.dsBm.bmWidth;
5253 pSize->cy = dibsect.dsBm.bmHeight;
5254 break;
5255 case TYMED_ENHMF:
5256 GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
5257 pSize->cx = emh.rclBounds.right - emh.rclBounds.left;
5258 pSize->cy = emh.rclBounds.bottom - emh.rclBounds.top;
5259 break;
5260 default:
5261 FIXME("Unsupported tymed %d\n", stgm.tymed);
5262 break;
5263 }
5264 ReleaseStgMedium(&stgm);
5265 if (c->editor->nZoomNumerator != 0)
5266 {
5267 pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5268 pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5269 }
5270 }
5271
5272 void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run, BOOL selected)
5273 {
5274 IDataObject* ido;
5275 FORMATETC fmt;
5276 STGMEDIUM stgm;
5277 DIBSECTION dibsect;
5278 ENHMETAHEADER emh;
5279 HDC hMemDC;
5280 SIZE sz;
5281 BOOL has_size;
5282 HBITMAP old_bm;
5283 RECT rc;
5284
5285 assert(run->nFlags & MERF_GRAPHICS);
5286 assert(run->ole_obj);
5287 if (IOleObject_QueryInterface(run->ole_obj->poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
5288 {
5289 FIXME("Couldn't get interface\n");
5290 return;
5291 }
5292 has_size = run->ole_obj->sizel.cx != 0 || run->ole_obj->sizel.cy != 0;
5293 fmt.cfFormat = CF_BITMAP;
5294 fmt.ptd = NULL;
5295 fmt.dwAspect = DVASPECT_CONTENT;
5296 fmt.lindex = -1;
5297 fmt.tymed = TYMED_GDI;
5298 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5299 {
5300 fmt.cfFormat = CF_ENHMETAFILE;
5301 fmt.tymed = TYMED_ENHMF;
5302 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
5303 {
5304 FIXME("Couldn't get storage medium\n");
5305 IDataObject_Release(ido);
5306 return;
5307 }
5308 }
5309 IDataObject_Release(ido);
5310
5311 switch (stgm.tymed)
5312 {
5313 case TYMED_GDI:
5314 GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
5315 hMemDC = CreateCompatibleDC(c->hDC);
5316 old_bm = SelectObject(hMemDC, stgm.u.hBitmap);
5317 if (has_size)
5318 {
5319 convert_sizel(c, &run->ole_obj->sizel, &sz);
5320 } else {
5321 sz.cx = dibsect.dsBm.bmWidth;
5322 sz.cy = dibsect.dsBm.bmHeight;
5323 }
5324 if (c->editor->nZoomNumerator != 0)
5325 {
5326 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5327 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5328 }
5329 StretchBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy,
5330 hMemDC, 0, 0, dibsect.dsBm.bmWidth, dibsect.dsBm.bmHeight, SRCCOPY);
5331
5332 SelectObject(hMemDC, old_bm);
5333 DeleteDC(hMemDC);
5334 break;
5335 case TYMED_ENHMF:
5336 GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
5337 if (has_size)
5338 {
5339 convert_sizel(c, &run->ole_obj->sizel, &sz);
5340 } else {
5341 sz.cx = emh.rclBounds.right - emh.rclBounds.left;
5342 sz.cy = emh.rclBounds.bottom - emh.rclBounds.top;
5343 }
5344 if (c->editor->nZoomNumerator != 0)
5345 {
5346 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5347 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
5348 }
5349
5350 rc.left = x;
5351 rc.top = y - sz.cy;
5352 rc.right = x + sz.cx;
5353 rc.bottom = y;
5354 PlayEnhMetaFile(c->hDC, stgm.u.hEnhMetaFile, &rc);
5355 break;
5356 default:
5357 FIXME("Unsupported tymed %d\n", stgm.tymed);
5358 selected = FALSE;
5359 break;
5360 }
5361 ReleaseStgMedium(&stgm);
5362
5363 if (selected && !c->editor->bHideSelection)
5364 PatBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy, DSTINVERT);
5365 }
5366
5367 void ME_DeleteReObject(REOBJECT* reo)
5368 {
5369 if (reo->poleobj) IOleObject_Release(reo->poleobj);
5370 if (reo->pstg) IStorage_Release(reo->pstg);
5371 if (reo->polesite) IOleClientSite_Release(reo->polesite);
5372 FREE_OBJ(reo);
5373 }
5374
5375 void ME_CopyReObject(REOBJECT* dst, const REOBJECT* src)
5376 {
5377 *dst = *src;
5378
5379 if (dst->poleobj) IOleObject_AddRef(dst->poleobj);
5380 if (dst->pstg) IStorage_AddRef(dst->pstg);
5381 if (dst->polesite) IOleClientSite_AddRef(dst->polesite);
5382 }
5383
5384 void ME_GetITextDocumentInterface(IRichEditOle *iface, LPVOID *ppvObj)
5385 {
5386 IRichEditOleImpl *This = impl_from_IRichEditOle(iface);
5387 *ppvObj = &This->ITextDocument_iface;
5388 }