ReactOS 0.4.16-dev-106-g10b08aa
richole.c
Go to the documentation of this file.
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 <stdarg.h>
23
24#define NONAMELESSUNION
25#define COBJMACROS
26
27#include "windef.h"
28#include "winbase.h"
29#include "wingdi.h"
30#include "winuser.h"
31#include "ole2.h"
32#include "richole.h"
33#include "editor.h"
34#include "richedit.h"
35#include "tom.h"
36#include "wine/debug.h"
37
39
40/* there is no way to be consistent across different sets of headers - mingw, Wine, Win32 SDK*/
41
42#include "initguid.h"
43
44DEFINE_GUID(LIBID_tom, 0x8cc497c9, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
45DEFINE_GUID(IID_ITextServices, 0x8d33f740, 0xcf58, 0x11ce, 0xa8, 0x9d, 0x00, 0xaa, 0x00, 0x6c, 0xad, 0xc5);
46DEFINE_GUID(IID_ITextHost, 0x13e670f4,0x1a5a,0x11cf,0xab,0xeb,0x00,0xaa,0x00,0xb6,0x5e,0xa1);
47DEFINE_GUID(IID_ITextHost2, 0x13e670f5,0x1a5a,0x11cf,0xab,0xeb,0x00,0xaa,0x00,0xb6,0x5e,0xa1);
48DEFINE_GUID(IID_ITextDocument, 0x8cc497c0, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
49DEFINE_GUID(IID_ITextDocument2Old, 0x01c25500, 0x4268, 0x11d1, 0x88, 0x3a, 0x3c, 0x8b, 0x00, 0xc1, 0x00, 0x00);
50DEFINE_GUID(IID_ITextRange, 0x8cc497c2, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
51DEFINE_GUID(IID_ITextSelection, 0x8cc497c1, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
52DEFINE_GUID(IID_ITextFont, 0x8cc497c3, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
53DEFINE_GUID(IID_ITextPara, 0x8cc497c4, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
54
56
57enum tid_t {
65};
66
67static const IID * const tid_ids[] =
68{
69 &IID_NULL,
70 &IID_ITextDocument,
71 &IID_ITextRange,
72 &IID_ITextSelection,
73 &IID_ITextFont,
74 &IID_ITextPara,
75};
77
79{
80 ITypeLib *tl;
81 HRESULT hr;
82
83 hr = LoadRegTypeLib(&LIBID_tom, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
84 if (FAILED(hr)) {
85 ERR("LoadRegTypeLib failed: %08x\n", hr);
86 return hr;
87 }
88
90 ITypeLib_Release(tl);
91 return hr;
92}
93
95{
96 unsigned i;
97
98 if (!typelib)
99 return;
100
101 for (i = 0; i < ARRAY_SIZE(typeinfos); i++)
102 if (typeinfos[i])
103 ITypeInfo_Release(typeinfos[i]);
104
105 ITypeLib_Release(typelib);
106}
107
109{
110 HRESULT hr;
111
112 if (!typelib)
113 hr = load_typelib();
114 if (!typelib)
115 return hr;
116
117 if (!typeinfos[tid])
118 {
119 ITypeInfo *ti;
120
121 hr = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
122 if (FAILED(hr))
123 {
124 ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hr);
125 return hr;
126 }
127
129 ITypeInfo_Release(ti);
130 }
131
133 return S_OK;
134}
135
136/* private IID used to get back IRichEditOleImpl pointer */
137DEFINE_GUID(IID_Igetrichole, 0xe3ce5c7a, 0x8247, 0x4622, 0x81, 0xad, 0x11, 0x81, 0x02, 0xaa, 0x01, 0x30);
138
142
171
172static const DWORD textfont_prop_masks[][2] = {
174 { CFM_ANIMATION },
176 { CFM_BOLD, CFE_BOLD },
182 { CFM_KERNING },
183 { CFM_LCID },
184 { CFM_FACE },
186 { CFM_OFFSET },
189 { CFM_SIZE },
191 { CFM_SPACING },
196 { CFM_WEIGHT }
197};
198
199typedef union {
204
208
209typedef struct IRichEditOleImpl {
215
218
222
224 struct list entry;
226};
227
233};
234
238
240};
241
242typedef struct ITextFontImpl {
245
251
252typedef struct ITextParaImpl {
255
258
264};
265
267{
268 return CONTAINING_RECORD(iface, IRichEditOleImpl, IRichEditOle_iface);
269}
270
272{
273 return CONTAINING_RECORD(iface, IRichEditOleImpl, ITextDocument2Old_iface);
274}
275
277{
278 return CONTAINING_RECORD(iface, IRichEditOleImpl, IUnknown_inner);
279}
280
282{
283 return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleInPlaceSite_iface);
284}
285
287{
288 return CONTAINING_RECORD(iface, ITextRangeImpl, ITextRange_iface);
289}
290
292{
293 return CONTAINING_RECORD(iface, ITextSelectionImpl, ITextSelection_iface);
294}
295
297{
298 return CONTAINING_RECORD(iface, ITextFontImpl, ITextFont_iface);
299}
300
302{
303 return CONTAINING_RECORD(iface, ITextParaImpl, ITextPara_iface);
304}
305
309
311{
312 if (!length)
313 return E_INVALIDARG;
314
315 *length = ME_GetTextLength(editor) + 1;
316 return S_OK;
317}
318
320{
322
324 switch (op)
325 {
327 /* range fully covered by deleted range - collapse to insertion point */
328 if (range->start >= start && range->end <= end)
329 range->start = range->end = start;
330 /* deleted range cuts from the right */
331 else if (range->start < start && range->end <= end)
332 range->end = start;
333 /* deleted range cuts from the left */
334 else if (range->start >= start && range->end > end) {
335 range->start = start;
336 range->end -= end - start;
337 }
338 /* deleted range cuts within */
339 else
340 range->end -= end - start;
341 break;
342 default:
343 FIXME("unknown update op, %d\n", op);
344 }
345 }
346}
347
350{
351 switch (propid)
352 {
353 case FONT_ALLCAPS:
354 case FONT_ANIMATION:
355 case FONT_BACKCOLOR:
356 case FONT_BOLD:
357 case FONT_EMBOSS:
358 case FONT_FORECOLOR:
359 case FONT_HIDDEN:
360 case FONT_ENGRAVE:
361 case FONT_ITALIC:
362 case FONT_KERNING:
363 case FONT_LANGID:
364 case FONT_OUTLINE:
365 case FONT_PROTECTED:
366 case FONT_SHADOW:
367 case FONT_SMALLCAPS:
369 case FONT_SUBSCRIPT:
370 case FONT_SUPERSCRIPT:
371 case FONT_UNDERLINE:
372 case FONT_WEIGHT:
373 return left->l == right->l;
374 case FONT_NAME:
375 return !wcscmp(left->str, right->str);
376 case FONT_POSITION:
377 case FONT_SIZE:
378 case FONT_SPACING:
379 return left->f == right->f;
380 default:
381 FIXME("unhandled font property %d\n", propid);
382 return FALSE;
383 }
384}
385
387{
388 switch (propid)
389 {
390 case FONT_ALLCAPS:
391 case FONT_ANIMATION:
392 case FONT_BACKCOLOR:
393 case FONT_BOLD:
394 case FONT_EMBOSS:
395 case FONT_FORECOLOR:
396 case FONT_HIDDEN:
397 case FONT_ENGRAVE:
398 case FONT_ITALIC:
399 case FONT_KERNING:
400 case FONT_LANGID:
401 case FONT_OUTLINE:
402 case FONT_PROTECTED:
403 case FONT_SHADOW:
404 case FONT_SMALLCAPS:
406 case FONT_SUBSCRIPT:
407 case FONT_SUPERSCRIPT:
408 case FONT_UNDERLINE:
409 case FONT_WEIGHT:
410 v->l = tomUndefined;
411 return;
412 case FONT_NAME:
413 v->str = NULL;
414 return;
415 case FONT_POSITION:
416 case FONT_SIZE:
417 case FONT_SPACING:
418 v->f = tomUndefined;
419 return;
420 default:
421 FIXME("unhandled font property %d\n", propid);
422 v->l = tomUndefined;
423 return;
424 }
425}
426
428{
429 return value * 72.0 / 1440;
430}
431
433{
434 return value * 1440 / 72.0;
435}
436
439{
440 ME_Cursor from, to;
442
443 memset(&fmt, 0, sizeof(fmt));
444 fmt.cbSize = sizeof(fmt);
445 fmt.dwMask = textfont_prop_masks[propid][0];
446
448 to = from;
451
452 switch (propid)
453 {
454 case FONT_ALLCAPS:
455 case FONT_BOLD:
456 case FONT_EMBOSS:
457 case FONT_HIDDEN:
458 case FONT_ENGRAVE:
459 case FONT_ITALIC:
460 case FONT_OUTLINE:
461 case FONT_PROTECTED:
462 case FONT_SHADOW:
463 case FONT_SMALLCAPS:
465 case FONT_SUBSCRIPT:
466 case FONT_SUPERSCRIPT:
467 case FONT_UNDERLINE:
468 value->l = fmt.dwEffects & textfont_prop_masks[propid][1] ? tomTrue : tomFalse;
469 break;
470 case FONT_ANIMATION:
471 value->l = fmt.bAnimation;
472 break;
473 case FONT_BACKCOLOR:
474 value->l = fmt.dwEffects & CFE_AUTOBACKCOLOR ? GetSysColor(COLOR_WINDOW) : fmt.crBackColor;
475 break;
476 case FONT_FORECOLOR:
477 value->l = fmt.dwEffects & CFE_AUTOCOLOR ? GetSysColor(COLOR_WINDOWTEXT) : fmt.crTextColor;
478 break;
479 case FONT_KERNING:
480 value->f = twips_to_points(fmt.wKerning);
481 break;
482 case FONT_LANGID:
483 value->l = fmt.lcid;
484 break;
485 case FONT_NAME:
486 /* this case is used exclusively by GetName() */
487 value->str = SysAllocString(fmt.szFaceName);
488 if (!value->str)
489 return E_OUTOFMEMORY;
490 break;
491 case FONT_POSITION:
492 value->f = twips_to_points(fmt.yOffset);
493 break;
494 case FONT_SIZE:
495 value->f = twips_to_points(fmt.yHeight);
496 break;
497 case FONT_SPACING:
498 value->f = fmt.sSpacing;
499 break;
500 case FONT_WEIGHT:
501 value->l = fmt.wWeight;
502 break;
503 default:
504 FIXME("unhandled font property %d\n", propid);
505 return E_FAIL;
506 }
507
508 return S_OK;
509}
510
512{
514 ITextRange_QueryInterface(range, &IID_Igetrichole, (void**)&reole);
515 return reole;
516}
517
519{
521 HRESULT hr;
522 LONG value;
523 BSTR str;
524 FLOAT f;
525
526#define CHARFORMAT_SET_B_FIELD(mask, value) \
527 if (hr == S_OK && value != tomUndefined) { \
528 fmt.dwMask |= CFM_##mask; \
529 if (value == tomTrue) fmt.dwEffects |= CFE_##mask; \
530 } \
531
532 /* fill format data from font */
533 memset(&fmt, 0, sizeof(fmt));
534 fmt.cbSize = sizeof(fmt);
535
537 hr = ITextFont_GetAllCaps(font, &value);
539
541 hr = ITextFont_GetBold(font, &value);
543
545 hr = ITextFont_GetEmboss(font, &value);
547
549 hr = ITextFont_GetHidden(font, &value);
551
553 hr = ITextFont_GetEngrave(font, &value);
555
557 hr = ITextFont_GetItalic(font, &value);
559
561 hr = ITextFont_GetOutline(font, &value);
563
565 hr = ITextFont_GetProtected(font, &value);
566 CHARFORMAT_SET_B_FIELD(PROTECTED, value);
567
569 hr = ITextFont_GetShadow(font, &value);
571
573 hr = ITextFont_GetSmallCaps(font, &value);
574 CHARFORMAT_SET_B_FIELD(SMALLCAPS, value);
575
577 hr = ITextFont_GetStrikeThrough(font, &value);
578 CHARFORMAT_SET_B_FIELD(STRIKEOUT, value);
579
581 hr = ITextFont_GetSubscript(font, &value);
583
585 hr = ITextFont_GetSuperscript(font, &value);
586 CHARFORMAT_SET_B_FIELD(SUPERSCRIPT, value);
587
589 hr = ITextFont_GetUnderline(font, &value);
590 CHARFORMAT_SET_B_FIELD(UNDERLINE, value);
591
592#undef CHARFORMAT_SET_B_FIELD
593
595 hr = ITextFont_GetAnimation(font, &value);
596 if (hr == S_OK && value != tomUndefined) {
597 fmt.dwMask |= CFM_ANIMATION;
598 fmt.bAnimation = value;
599 }
600
602 hr = ITextFont_GetBackColor(font, &value);
603 if (hr == S_OK && value != tomUndefined) {
604 fmt.dwMask |= CFM_BACKCOLOR;
605 if (value == tomAutoColor)
606 fmt.dwEffects |= CFE_AUTOBACKCOLOR;
607 else
608 fmt.crBackColor = value;
609 }
610
612 hr = ITextFont_GetForeColor(font, &value);
613 if (hr == S_OK && value != tomUndefined) {
614 fmt.dwMask |= CFM_COLOR;
615 if (value == tomAutoColor)
616 fmt.dwEffects |= CFE_AUTOCOLOR;
617 else
618 fmt.crTextColor = value;
619 }
620
622 hr = ITextFont_GetKerning(font, &f);
623 if (hr == S_OK && f != tomUndefined) {
624 fmt.dwMask |= CFM_KERNING;
625 fmt.wKerning = points_to_twips(f);
626 }
627
629 hr = ITextFont_GetLanguageID(font, &value);
630 if (hr == S_OK && value != tomUndefined) {
631 fmt.dwMask |= CFM_LCID;
632 fmt.lcid = value;
633 }
634
635 if (ITextFont_GetName(font, &str) == S_OK) {
636 fmt.dwMask |= CFM_FACE;
637 lstrcpynW(fmt.szFaceName, str, ARRAY_SIZE(fmt.szFaceName));
639 }
640
641 hr = ITextFont_GetPosition(font, &f);
642 if (hr == S_OK && f != tomUndefined) {
643 fmt.dwMask |= CFM_OFFSET;
644 fmt.yOffset = points_to_twips(f);
645 }
646
647 hr = ITextFont_GetSize(font, &f);
648 if (hr == S_OK && f != tomUndefined) {
649 fmt.dwMask |= CFM_SIZE;
650 fmt.yHeight = points_to_twips(f);
651 }
652
653 hr = ITextFont_GetSpacing(font, &f);
654 if (hr == S_OK && f != tomUndefined) {
655 fmt.dwMask |= CFM_SPACING;
656 fmt.sSpacing = f;
657 }
658
659 hr = ITextFont_GetWeight(font, &value);
660 if (hr == S_OK && value != tomUndefined) {
661 fmt.dwMask |= CFM_WEIGHT;
662 fmt.wWeight = value;
663 }
664
665 if (fmt.dwMask) {
667 ME_Cursor from, to;
668 LONG start, end;
669
670 ITextRange_GetStart(range, &start);
671 ITextRange_GetEnd(range, &end);
672
676 }
677}
678
680{
681 const IRichEditOleImpl *reole;
683 LONG start, end, i;
684 HRESULT hr;
685
686 /* when font is not attached to any range use cached values */
687 if (!font->range || font->get_cache_enabled) {
688 *value = font->props[propid];
689 return S_OK;
690 }
691
692 if (!(reole = get_range_reole(font->range)))
693 return CO_E_RELEASED;
694
696
697 ITextRange_GetStart(font->range, &start);
698 ITextRange_GetEnd(font->range, &end);
699
700 /* iterate trough a range to see if property value is consistent */
702 if (FAILED(hr))
703 return hr;
704
705 for (i = start + 1; i < end; i++) {
707
708 hr = get_textfont_prop_for_pos(reole, i, propid, &cur);
709 if (FAILED(hr))
710 return hr;
711
712 if (!is_equal_textfont_prop_value(propid, &v, &cur))
713 return S_OK;
714 }
715
716 *value = v;
717 return S_OK;
718}
719
721{
723 HRESULT hr;
724
725 if (!value)
726 return E_INVALIDARG;
727
728 hr = get_textfont_prop(font, propid, &v);
729 *value = v.f;
730 return hr;
731}
732
734{
736 HRESULT hr;
737
738 if (!value)
739 return E_INVALIDARG;
740
741 hr = get_textfont_prop(font, propid, &v);
742 *value = v.l;
743 return hr;
744}
745
746/* Value should already have a terminal value, for boolean properties it means tomToggle is not handled */
748{
749 const IRichEditOleImpl *reole;
750 ME_Cursor from, to;
752 LONG start, end;
753
754 /* when font is not attached to any range use cache */
755 if (!font->range || font->set_cache_enabled) {
756 if (propid == FONT_NAME) {
757 SysFreeString(font->props[propid].str);
758 font->props[propid].str = SysAllocString(value->str);
759 }
760 else
761 font->props[propid] = *value;
762 return S_OK;
763 }
764
765 if (!(reole = get_range_reole(font->range)))
766 return CO_E_RELEASED;
767
768 memset(&fmt, 0, sizeof(fmt));
769 fmt.cbSize = sizeof(fmt);
770 fmt.dwMask = textfont_prop_masks[propid][0];
771
772 switch (propid)
773 {
774 case FONT_ALLCAPS:
775 case FONT_BOLD:
776 case FONT_EMBOSS:
777 case FONT_HIDDEN:
778 case FONT_ENGRAVE:
779 case FONT_ITALIC:
780 case FONT_OUTLINE:
781 case FONT_PROTECTED:
782 case FONT_SHADOW:
783 case FONT_SMALLCAPS:
785 case FONT_SUBSCRIPT:
786 case FONT_SUPERSCRIPT:
787 case FONT_UNDERLINE:
788 fmt.dwEffects = value->l == tomTrue ? textfont_prop_masks[propid][1] : 0;
789 break;
790 case FONT_ANIMATION:
791 fmt.bAnimation = value->l;
792 break;
793 case FONT_BACKCOLOR:
794 case FONT_FORECOLOR:
795 if (value->l == tomAutoColor)
796 fmt.dwEffects = textfont_prop_masks[propid][1];
797 else if (propid == FONT_BACKCOLOR)
798 fmt.crBackColor = value->l;
799 else
800 fmt.crTextColor = value->l;
801 break;
802 case FONT_KERNING:
803 fmt.wKerning = value->f;
804 break;
805 case FONT_LANGID:
806 fmt.lcid = value->l;
807 break;
808 case FONT_POSITION:
809 fmt.yOffset = value->f;
810 break;
811 case FONT_SIZE:
812 fmt.yHeight = value->f;
813 break;
814 case FONT_SPACING:
815 fmt.sSpacing = value->f;
816 break;
817 case FONT_WEIGHT:
818 fmt.wWeight = value->l;
819 break;
820 case FONT_NAME:
821 lstrcpynW(fmt.szFaceName, value->str, ARRAY_SIZE(fmt.szFaceName));
822 break;
823 default:
824 FIXME("unhandled font property %d\n", propid);
825 return E_FAIL;
826 }
827
828 ITextRange_GetStart(font->range, &start);
829 ITextRange_GetEnd(font->range, &end);
830
834
835 return S_OK;
836}
837
839{
841 v.l = value;
842 return set_textfont_prop(font, propid, &v);
843}
844
846{
848 v.f = value;
849 return set_textfont_prop(font, propid, &v);
850}
851
853{
855
856 switch (value)
857 {
858 case tomUndefined:
859 return S_OK;
860 case tomToggle: {
861 LONG oldvalue;
862 get_textfont_propl(font, propid, &oldvalue);
863 if (oldvalue == tomFalse)
864 value = tomTrue;
865 else if (oldvalue == tomTrue)
866 value = tomFalse;
867 else
868 return E_INVALIDARG;
869 /* fallthrough */
870 }
871 case tomTrue:
872 case tomFalse:
873 v.l = value;
874 return set_textfont_prop(font, propid, &v);
875 default:
876 return E_INVALIDARG;
877 }
878}
879
881{
882 const IRichEditOleImpl *reole;
884 HRESULT hr;
885 LONG start;
886
887 if (!(reole = get_range_reole(range)))
888 return CO_E_RELEASED;
889
890 ITextRange_GetStart(range, &start);
892 *ret = v.str;
893 return hr;
894}
895
897{
898 enum textfont_prop_id propid;
899 for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++) {
900 if (propid == FONT_NAME)
901 textfont_getname_from_range(font->range, &font->props[propid].str);
902 else
903 get_textfont_prop(font, propid, &font->props[propid]);
904 }
905}
906
908{
909 LONG expand_start, expand_end;
910
911 switch (unit)
912 {
913 case tomStory:
914 expand_start = 0;
915 ITextRange_GetStoryLength(range, &expand_end);
916 break;
917 default:
918 FIXME("unit %d is not supported\n", unit);
919 return E_NOTIMPL;
920 }
921
922 if (delta) {
923 LONG start, end;
924
925 ITextRange_GetStart(range, &start);
926 ITextRange_GetEnd(range, &end);
927 *delta = expand_end - expand_start - (end - start);
928 }
929
930 ITextRange_SetStart(range, expand_start);
931 ITextRange_SetEnd(range, expand_end);
932
933 return S_OK;
934}
935
937{
939
940 TRACE("%p %s\n", This, debugstr_guid(riid));
941
942 *ppvObj = NULL;
944 *ppvObj = &This->IUnknown_inner;
945 else if (IsEqualGUID(riid, &IID_IRichEditOle))
946 *ppvObj = &This->IRichEditOle_iface;
947 else if (IsEqualGUID(riid, &IID_ITextDocument) || IsEqualGUID(riid, &IID_ITextDocument2Old))
948 *ppvObj = &This->ITextDocument2Old_iface;
949 if (*ppvObj)
950 {
951 IUnknown_AddRef((IUnknown *)*ppvObj);
952 return S_OK;
953 }
954
955 if (IsEqualGUID(riid, &IID_ITextServices))
956 {
957 static int once;
958 if (!once++) FIXME("%p: unhandled interface IID_ITextServices\n", This);
959 return E_NOINTERFACE;
960 }
961
962 FIXME("%p: unhandled interface %s\n", This, debugstr_guid(riid));
963
964 return E_NOINTERFACE;
965}
966
968{
971
972 TRACE("%p ref = %u\n", This, ref);
973
974 return ref;
975}
976
978{
981
982 TRACE ("%p ref=%u\n", This, ref);
983
984 if (!ref)
985 {
986 IOleClientSiteImpl *clientsite;
987 ITextRangeImpl *txtRge;
988
989 This->editor->reOle = NULL;
990 if (This->txtSel) {
991 This->txtSel->reOle = NULL;
992 ITextSelection_Release(&This->txtSel->ITextSelection_iface);
993 }
994
995 LIST_FOR_EACH_ENTRY(txtRge, &This->rangelist, ITextRangeImpl, child.entry)
996 txtRge->child.reole = NULL;
997
998 LIST_FOR_EACH_ENTRY(clientsite, &This->clientsites, IOleClientSiteImpl, child.entry)
999 clientsite->child.reole = NULL;
1000
1001 heap_free(This);
1002 }
1003 return ref;
1004}
1005
1006static const IUnknownVtbl reo_unk_vtbl =
1007{
1011};
1012
1013static HRESULT WINAPI
1015{
1017 return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj);
1018}
1019
1020static ULONG WINAPI
1022{
1024 return IUnknown_AddRef(This->outer_unk);
1025}
1026
1027static ULONG WINAPI
1029{
1031 return IUnknown_Release(This->outer_unk);
1032}
1033
1034static HRESULT WINAPI
1036{
1038 FIXME("stub %p\n",This);
1039 return E_NOTIMPL;
1040}
1041
1042static HRESULT WINAPI
1044{
1046 FIXME("stub %p\n",This);
1047 return E_NOTIMPL;
1048}
1049
1050static HRESULT WINAPI
1052 REFCLSID rclsidNew, LPCSTR lpstrUserTypeNew)
1053{
1055 FIXME("stub %p\n",This);
1056 return E_NOTIMPL;
1057}
1058
1060{
1061 return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleClientSite_iface);
1062}
1063
1064static HRESULT WINAPI
1066{
1068 TRACE("%p %s\n", me, debugstr_guid(riid) );
1069
1070 *ppvObj = NULL;
1071 if (IsEqualGUID(riid, &IID_IUnknown) ||
1073 *ppvObj = me;
1074 else if (IsEqualGUID(riid, &IID_IOleWindow) ||
1076 *ppvObj = &This->IOleInPlaceSite_iface;
1077 if (*ppvObj)
1078 {
1079 IOleClientSite_AddRef(me);
1080 return S_OK;
1081 }
1082 FIXME("%p: unhandled interface %s\n", me, debugstr_guid(riid) );
1083
1084 return E_NOINTERFACE;
1085}
1086
1088{
1091 TRACE("(%p)->(%u)\n", This, ref);
1092 return ref;
1093}
1094
1096{
1099
1100 TRACE("(%p)->(%u)\n", This, ref);
1101
1102 if (ref == 0) {
1103 if (This->child.reole) {
1104 list_remove(&This->child.entry);
1105 This->child.reole = NULL;
1106 }
1107 heap_free(This);
1108 }
1109 return ref;
1110}
1111
1113{
1115 if (!This->child.reole)
1116 return CO_E_RELEASED;
1117
1118 FIXME("stub %p\n", iface);
1119 return E_NOTIMPL;
1120}
1121
1123 DWORD dwWhichMoniker, IMoniker **ppmk)
1124{
1126 if (!This->child.reole)
1127 return CO_E_RELEASED;
1128
1129 FIXME("stub %p\n", iface);
1130 return E_NOTIMPL;
1131}
1132
1134 IOleContainer **ppContainer)
1135{
1137 if (!This->child.reole)
1138 return CO_E_RELEASED;
1139
1140 FIXME("stub %p\n", iface);
1141 return E_NOTIMPL;
1142}
1143
1145{
1147 if (!This->child.reole)
1148 return CO_E_RELEASED;
1149
1150 FIXME("stub %p\n", iface);
1151 return E_NOTIMPL;
1152}
1153
1155{
1157 if (!This->child.reole)
1158 return CO_E_RELEASED;
1159
1160 FIXME("stub %p\n", iface);
1161 return E_NOTIMPL;
1162}
1163
1165{
1167 if (!This->child.reole)
1168 return CO_E_RELEASED;
1169
1170 FIXME("stub %p\n", iface);
1171 return E_NOTIMPL;
1172}
1173
1174static const IOleClientSiteVtbl ocst = {
1184};
1185
1186/* IOleInPlaceSite interface */
1188{
1190 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppvObj);
1191}
1192
1194{
1196 return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1197}
1198
1200{
1202 return IOleClientSite_Release(&This->IOleClientSite_iface);
1203}
1204
1206{
1208
1209 TRACE("(%p)->(%p)\n", This, phwnd);
1210
1211 if (!This->child.reole)
1212 return CO_E_RELEASED;
1213
1214 if (!phwnd)
1215 return E_INVALIDARG;
1216
1217 *phwnd = This->child.reole->editor->hWnd;
1218 return S_OK;
1219}
1220
1222{
1224 FIXME("not implemented: (%p)->(%d)\n", This, fEnterMode);
1225 return E_NOTIMPL;
1226}
1227
1229{
1231 FIXME("not implemented: (%p)\n", This);
1232 return E_NOTIMPL;
1233}
1234
1236{
1238 FIXME("not implemented: (%p)\n", This);
1239 return E_NOTIMPL;
1240}
1241
1243{
1245 FIXME("not implemented: (%p)\n", This);
1246 return E_NOTIMPL;
1247}
1248
1250 IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
1251 LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
1252{
1254 FIXME("not implemented: (%p)->(%p %p %p %p %p)\n", This, ppFrame, ppDoc, lprcPosRect, lprcClipRect, lpFrameInfo);
1255 return E_NOTIMPL;
1256}
1257
1259{
1261 FIXME("not implemented: (%p)\n", This);
1262 return E_NOTIMPL;
1263}
1264
1266{
1268 FIXME("not implemented: (%p)->(%d)\n", This, fUndoable);
1269 return E_NOTIMPL;
1270}
1271
1273{
1275 FIXME("not implemented: (%p)\n", This);
1276 return E_NOTIMPL;
1277}
1278
1280{
1282 FIXME("not implemented: (%p)\n", This);
1283 return E_NOTIMPL;
1284}
1285
1287{
1289 FIXME("not implemented: (%p)\n", This);
1290 return E_NOTIMPL;
1291}
1292
1294{
1296 FIXME("not implemented: (%p)->(%p)\n", This, lprcPosRect);
1297 return E_NOTIMPL;
1298}
1299
1300static const IOleInPlaceSiteVtbl olestvt =
1301{
1317};
1318
1320{
1321 IOleClientSiteImpl *clientSite = heap_alloc(sizeof *clientSite);
1322
1323 if (!clientSite)
1324 return E_OUTOFMEMORY;
1325
1326 clientSite->IOleClientSite_iface.lpVtbl = &ocst;
1327 clientSite->IOleInPlaceSite_iface.lpVtbl = &olestvt;
1328 clientSite->ref = 1;
1329 clientSite->child.reole = reOle;
1330 list_add_head(&reOle->clientsites, &clientSite->child.entry);
1331
1332 *ret = &clientSite->IOleClientSite_iface;
1333 return S_OK;
1334}
1335
1336static HRESULT WINAPI
1338{
1340
1341 TRACE("(%p)->(%p)\n", This, clientsite);
1342
1343 if (!clientsite)
1344 return E_INVALIDARG;
1345
1346 return CreateOleClientSite(This, clientsite);
1347}
1348
1349static HRESULT WINAPI
1351 DWORD reco, LPDATAOBJECT *lplpdataobj)
1352{
1355 int nChars;
1356
1357 TRACE("(%p,%p,%d)\n",This, lpchrg, reco);
1358 if(!lplpdataobj)
1359 return E_INVALIDARG;
1360 if(!lpchrg) {
1361 int nFrom, nTo, nStartCur = ME_GetSelectionOfs(This->editor, &nFrom, &nTo);
1362 start = This->editor->pCursors[nStartCur];
1363 nChars = nTo - nFrom;
1364 } else {
1365 ME_CursorFromCharOfs(This->editor, lpchrg->cpMin, &start);
1366 nChars = lpchrg->cpMax - lpchrg->cpMin;
1367 }
1368 return ME_GetDataObject(This->editor, &start, nChars, lplpdataobj);
1369}
1370
1372{
1374 FIXME("stub %p\n",This);
1375 return E_NOTIMPL;
1376}
1377
1378static HRESULT WINAPI
1380 REOBJECT *lpreobject, DWORD dwFlags)
1381{
1383 struct re_object *reobj = NULL;
1384 LONG count = 0;
1385
1386 TRACE("(%p)->(%x, %p, %x)\n", This, iob, lpreobject, dwFlags);
1387
1388 if (!lpreobject || !lpreobject->cbStruct)
1389 return E_INVALIDARG;
1390
1391 if (iob == REO_IOB_USE_CP)
1392 {
1394
1395 TRACE("character offset: %d\n", lpreobject->cp);
1396 ME_CursorFromCharOfs(This->editor, lpreobject->cp, &cursor);
1397 if (!cursor.pRun->member.run.reobj)
1398 return E_INVALIDARG;
1399 else
1400 reobj = cursor.pRun->member.run.reobj;
1401 }
1402 else if (iob == REO_IOB_SELECTION)
1403 {
1404 ME_Cursor *from, *to;
1405
1406 ME_GetSelection(This->editor, &from, &to);
1407 if (!from->pRun->member.run.reobj)
1408 return E_INVALIDARG;
1409 else
1410 reobj = from->pRun->member.run.reobj;
1411 }
1412 else
1413 {
1414 if (iob > IRichEditOle_GetObjectCount(me))
1415 return E_INVALIDARG;
1416 LIST_FOR_EACH_ENTRY(reobj, &This->editor->reobj_list, struct re_object, entry)
1417 {
1418 if (count == iob)
1419 break;
1420 count++;
1421 }
1422 }
1423 ME_CopyReObject(lpreobject, &reobj->obj, dwFlags);
1424 return S_OK;
1425}
1426
1427static LONG WINAPI
1429{
1431 TRACE("(%p)\n",This);
1432 return list_count(&This->editor->reobj_list);
1433}
1434
1435static HRESULT WINAPI
1437{
1439 FIXME("stub %p\n",This);
1440 return E_NOTIMPL;
1441}
1442
1443static HRESULT WINAPI
1445 CLIPFORMAT cf, HGLOBAL hMetaPict)
1446{
1448 FIXME("stub %p\n",This);
1449 return E_NOTIMPL;
1450}
1451
1452static HRESULT WINAPI
1454{
1456 FIXME("stub %p\n",This);
1457 return E_NOTIMPL;
1458}
1459
1460static HRESULT WINAPI
1462{
1464
1465 TRACE("(%p,%p)\n", This, reo);
1466
1467 if (!reo)
1468 return E_INVALIDARG;
1469
1470 if (reo->cbStruct < sizeof(*reo)) return STG_E_INVALIDPARAMETER;
1471
1472 ME_InsertOLEFromCursor(This->editor, reo, 0);
1473 ME_CommitUndo(This->editor);
1474 ME_UpdateRepaint(This->editor, FALSE);
1475 return S_OK;
1476}
1477
1479 LPSTORAGE lpstg)
1480{
1482 FIXME("stub %p\n",This);
1483 return E_NOTIMPL;
1484}
1485
1486static HRESULT WINAPI
1488{
1490 FIXME("stub %p\n",This);
1491 return E_NOTIMPL;
1492}
1493
1495 LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj)
1496{
1498 FIXME("stub %p %s %s\n",This, lpstrContainerApp, lpstrContainerObj);
1499 return E_NOTIMPL;
1500}
1501
1502static HRESULT WINAPI
1504{
1506 FIXME("stub %p\n",This);
1507 return E_NOTIMPL;
1508}
1509
1510static const IRichEditOleVtbl revt = {
1530};
1531
1532/* ITextRange interface */
1534{
1536
1537 *ppvObj = NULL;
1540 || IsEqualGUID(riid, &IID_ITextRange))
1541 {
1542 *ppvObj = me;
1543 ITextRange_AddRef(me);
1544 return S_OK;
1545 }
1546 else if (IsEqualGUID(riid, &IID_Igetrichole))
1547 {
1548 *ppvObj = This->child.reole;
1549 return S_OK;
1550 }
1551
1552 return E_NOINTERFACE;
1553}
1554
1556{
1558 return InterlockedIncrement(&This->ref);
1559}
1560
1562{
1565
1566 TRACE ("%p ref=%u\n", This, ref);
1567 if (ref == 0)
1568 {
1569 if (This->child.reole)
1570 {
1571 list_remove(&This->child.entry);
1572 This->child.reole = NULL;
1573 }
1574 heap_free(This);
1575 }
1576 return ref;
1577}
1578
1580{
1582 TRACE("(%p)->(%p)\n", This, pctinfo);
1583 *pctinfo = 1;
1584 return S_OK;
1585}
1586
1588 ITypeInfo **ppTInfo)
1589{
1591 HRESULT hr;
1592
1593 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
1594
1595 hr = get_typeinfo(ITextRange_tid, ppTInfo);
1596 if (SUCCEEDED(hr))
1597 ITypeInfo_AddRef(*ppTInfo);
1598 return hr;
1599}
1600
1602 UINT cNames, LCID lcid, DISPID *rgDispId)
1603{
1605 ITypeInfo *ti;
1606 HRESULT hr;
1607
1608 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
1609 rgDispId);
1610
1612 if (SUCCEEDED(hr))
1613 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
1614 return hr;
1615}
1616
1618 LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1619 VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
1620 UINT *puArgErr)
1621{
1623 ITypeInfo *ti;
1624 HRESULT hr;
1625
1626 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
1627 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1628
1630 if (SUCCEEDED(hr))
1631 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1632 return hr;
1633}
1634
1636{
1638 ME_TextEditor *editor;
1640 int length;
1641 BOOL bEOP;
1642
1643 TRACE("(%p)->(%p)\n", This, str);
1644
1645 if (!This->child.reole)
1646 return CO_E_RELEASED;
1647
1648 if (!str)
1649 return E_INVALIDARG;
1650
1651 /* return early for degenerate range */
1652 if (This->start == This->end) {
1653 *str = NULL;
1654 return S_OK;
1655 }
1656
1657 editor = This->child.reole->editor;
1658 ME_CursorFromCharOfs(editor, This->start, &start);
1659 ME_CursorFromCharOfs(editor, This->end, &end);
1660
1661 length = This->end - This->start;
1663 if (!*str)
1664 return E_OUTOFMEMORY;
1665
1666 bEOP = (end.pRun->next->type == diTextEnd && This->end > ME_GetTextLength(editor));
1667 ME_GetTextW(editor, *str, length, &start, length, FALSE, bEOP);
1668 return S_OK;
1669}
1670
1672{
1674 ME_TextEditor *editor;
1676 ME_Style *style;
1677 int len;
1678
1679 TRACE("(%p)->(%s)\n", This, debugstr_w(str));
1680
1681 if (!This->child.reole)
1682 return CO_E_RELEASED;
1683
1684 editor = This->child.reole->editor;
1685
1686 /* delete only where's something to delete */
1687 if (This->start != This->end) {
1688 ME_CursorFromCharOfs(editor, This->start, &cursor);
1689 ME_InternalDeleteText(editor, &cursor, This->end - This->start, FALSE);
1690 }
1691
1692 if (!str || !*str) {
1693 /* will update this range as well */
1694 textranges_update_ranges(This->child.reole, This->start, This->end, RANGE_UPDATE_DELETE);
1695 return S_OK;
1696 }
1697
1698 /* it's safer not to rely on stored BSTR length */
1699 len = lstrlenW(str);
1700 cursor = editor->pCursors[0];
1701 ME_CursorFromCharOfs(editor, This->start, &editor->pCursors[0]);
1702 style = ME_GetInsertStyle(editor, 0);
1703 ME_InsertTextFromCursor(editor, 0, str, len, style);
1705 editor->pCursors[0] = cursor;
1706
1707 if (len < This->end - This->start)
1708 textranges_update_ranges(This->child.reole, This->start + len, This->end, RANGE_UPDATE_DELETE);
1709 else
1710 This->end = len - This->start;
1711
1712 return S_OK;
1713}
1714
1716{
1717 WCHAR wch[2];
1718
1719 ME_GetTextW(editor, wch, 1, cursor, 1, FALSE, cursor->pRun->next->type == diTextEnd);
1720 *pch = wch[0];
1721
1722 return S_OK;
1723}
1724
1726{
1728 ME_TextEditor *editor;
1730
1731 TRACE("(%p)->(%p)\n", This, pch);
1732
1733 if (!This->child.reole)
1734 return CO_E_RELEASED;
1735
1736 if (!pch)
1737 return E_INVALIDARG;
1738
1739 editor = This->child.reole->editor;
1740 ME_CursorFromCharOfs(editor, This->start, &cursor);
1741 return range_GetChar(editor, &cursor, pch);
1742}
1743
1745{
1747
1748 FIXME("(%p)->(%x): stub\n", This, ch);
1749
1750 if (!This->child.reole)
1751 return CO_E_RELEASED;
1752
1753 return E_NOTIMPL;
1754}
1755
1757
1759{
1761
1762 TRACE("(%p)->(%p)\n", This, ppRange);
1763
1764 if (!This->child.reole)
1765 return CO_E_RELEASED;
1766
1767 if (!ppRange)
1768 return E_INVALIDARG;
1769
1770 return CreateITextRange(This->child.reole, This->start, This->end, ppRange);
1771}
1772
1774{
1776
1777 FIXME("(%p)->(%p): stub\n", This, range);
1778
1779 if (!This->child.reole)
1780 return CO_E_RELEASED;
1781
1782 return E_NOTIMPL;
1783}
1784
1786{
1788
1789 FIXME("(%p)->(%p): stub\n", This, range);
1790
1791 if (!This->child.reole)
1792 return CO_E_RELEASED;
1793
1794 return E_NOTIMPL;
1795}
1796
1798{
1800
1801 TRACE("(%p)->(%p)\n", This, start);
1802
1803 if (!This->child.reole)
1804 return CO_E_RELEASED;
1805
1806 if (!start)
1807 return E_INVALIDARG;
1808
1809 *start = This->start;
1810 return S_OK;
1811}
1812
1814{
1815 int len;
1816
1817 if (value < 0)
1818 value = 0;
1819
1820 if (value == *start)
1821 return S_FALSE;
1822
1823 if (value <= *end) {
1824 *start = value;
1825 return S_OK;
1826 }
1827
1828 len = ME_GetTextLength(reole->editor);
1829 *start = *end = value > len ? len : value;
1830 return S_OK;
1831}
1832
1834{
1836
1837 TRACE("(%p)->(%d)\n", This, value);
1838
1839 if (!This->child.reole)
1840 return CO_E_RELEASED;
1841
1842 return textrange_setstart(This->child.reole, value, &This->start, &This->end);
1843}
1844
1846{
1848
1849 TRACE("(%p)->(%p)\n", This, end);
1850
1851 if (!This->child.reole)
1852 return CO_E_RELEASED;
1853
1854 if (!end)
1855 return E_INVALIDARG;
1856
1857 *end = This->end;
1858 return S_OK;
1859}
1860
1862{
1863 int len;
1864
1865 if (value == *end)
1866 return S_FALSE;
1867
1868 if (value < *start) {
1869 *start = *end = max(0, value);
1870 return S_OK;
1871 }
1872
1873 len = ME_GetTextLength(reole->editor);
1874 *end = value > len ? len + 1 : value;
1875 return S_OK;
1876}
1877
1879{
1881
1882 TRACE("(%p)->(%d)\n", This, value);
1883
1884 if (!This->child.reole)
1885 return CO_E_RELEASED;
1886
1887 return textrange_setend(This->child.reole, value, &This->start, &This->end);
1888}
1889
1891{
1893
1894 TRACE("(%p)->(%p)\n", This, font);
1895
1896 if (!This->child.reole)
1897 return CO_E_RELEASED;
1898
1899 if (!font)
1900 return E_INVALIDARG;
1901
1902 return create_textfont(me, NULL, font);
1903}
1904
1906{
1908
1909 TRACE("(%p)->(%p)\n", This, font);
1910
1911 if (!font)
1912 return E_INVALIDARG;
1913
1914 if (!This->child.reole)
1915 return CO_E_RELEASED;
1916
1918 return S_OK;
1919}
1920
1922{
1924
1925 TRACE("(%p)->(%p)\n", This, para);
1926
1927 if (!This->child.reole)
1928 return CO_E_RELEASED;
1929
1930 if (!para)
1931 return E_INVALIDARG;
1932
1933 return create_textpara(me, para);
1934}
1935
1937{
1939
1940 FIXME("(%p)->(%p): stub\n", This, para);
1941
1942 if (!This->child.reole)
1943 return CO_E_RELEASED;
1944
1945 return E_NOTIMPL;
1946}
1947
1949{
1951
1952 TRACE("(%p)->(%p)\n", This, length);
1953
1954 if (!This->child.reole)
1955 return CO_E_RELEASED;
1956
1957 return textrange_get_storylength(This->child.reole->editor, length);
1958}
1959
1961{
1963
1964 TRACE("(%p)->(%p)\n", This, value);
1965
1966 if (!This->child.reole)
1967 return CO_E_RELEASED;
1968
1969 if (!value)
1970 return E_INVALIDARG;
1971
1973 return S_OK;
1974}
1975
1977{
1978 if (*end == *start)
1979 return S_FALSE;
1980
1981 if (bStart == tomEnd)
1982 *start = *end;
1983 else
1984 *end = *start;
1985 return S_OK;
1986}
1987
1989{
1991
1992 TRACE("(%p)->(%d)\n", This, bStart);
1993
1994 if (!This->child.reole)
1995 return CO_E_RELEASED;
1996
1997 return range_Collapse(bStart, &This->start, &This->end);
1998}
1999
2001{
2003
2004 TRACE("(%p)->(%d %p)\n", This, unit, delta);
2005
2006 if (!This->child.reole)
2007 return CO_E_RELEASED;
2008
2009 return textrange_expand(me, unit, delta);
2010}
2011
2013{
2015
2016 FIXME("(%p)->(%d %p): stub\n", This, unit, index);
2017
2018 if (!This->child.reole)
2019 return CO_E_RELEASED;
2020
2021 return E_NOTIMPL;
2022}
2023
2025 LONG extend)
2026{
2028
2029 FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend);
2030
2031 if (!This->child.reole)
2032 return CO_E_RELEASED;
2033
2034 return E_NOTIMPL;
2035}
2036
2037static void cp2range(ME_TextEditor *editor, LONG *cp1, LONG *cp2)
2038{
2039 int len = ME_GetTextLength(editor) + 1;
2040
2041 *cp1 = max(*cp1, 0);
2042 *cp2 = max(*cp2, 0);
2043 *cp1 = min(*cp1, len);
2044 *cp2 = min(*cp2, len);
2045 if (*cp1 > *cp2)
2046 {
2047 int tmp = *cp1;
2048 *cp1 = *cp2;
2049 *cp2 = tmp;
2050 }
2051 if (*cp1 == len)
2052 *cp1 = *cp2 = len - 1;
2053}
2054
2056{
2058
2059 FIXME("(%p)->(%d %d): stub\n", This, anchor, active);
2060
2061 if (!This->child.reole)
2062 return CO_E_RELEASED;
2063
2064 cp2range(This->child.reole->editor, &anchor, &active);
2065 if (anchor == This->start && active == This->end)
2066 return S_FALSE;
2067
2068 This->start = anchor;
2069 This->end = active;
2070 return S_OK;
2071}
2072
2074{
2075 LONG from, to, v;
2076
2077 if (!ret)
2078 ret = &v;
2079
2080 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
2081 *ret = tomFalse;
2082 }
2083 else
2084 *ret = (start >= from && end <= to) ? tomTrue : tomFalse;
2085 return *ret == tomTrue ? S_OK : S_FALSE;
2086}
2087
2089{
2091
2092 TRACE("(%p)->(%p %p)\n", This, range, ret);
2093
2094 if (ret)
2095 *ret = tomFalse;
2096
2097 if (!This->child.reole)
2098 return CO_E_RELEASED;
2099
2100 if (!range)
2101 return S_FALSE;
2102
2103 return textrange_inrange(This->start, This->end, range, ret);
2104}
2105
2107{
2109
2110 FIXME("(%p)->(%p): stub\n", This, ret);
2111
2112 if (!This->child.reole)
2113 return CO_E_RELEASED;
2114
2115 return E_NOTIMPL;
2116}
2117
2119{
2120 LONG from, to, v;
2121
2122 if (!ret)
2123 ret = &v;
2124
2125 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
2126 *ret = tomFalse;
2127 }
2128 else
2129 *ret = (start == from && end == to) ? tomTrue : tomFalse;
2130 return *ret == tomTrue ? S_OK : S_FALSE;
2131}
2132
2134{
2136
2137 TRACE("(%p)->(%p %p)\n", This, range, ret);
2138
2139 if (ret)
2140 *ret = tomFalse;
2141
2142 if (!This->child.reole)
2143 return CO_E_RELEASED;
2144
2145 if (!range)
2146 return S_FALSE;
2147
2148 return textrange_isequal(This->start, This->end, range, ret);
2149}
2150
2152{
2154
2155 TRACE("(%p)\n", This);
2156
2157 if (!This->child.reole)
2158 return CO_E_RELEASED;
2159
2160 set_selection(This->child.reole->editor, This->start, This->end);
2161 return S_OK;
2162}
2163
2165 LONG *delta)
2166{
2168
2169 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
2170
2171 if (!This->child.reole)
2172 return CO_E_RELEASED;
2173
2174 return E_NOTIMPL;
2175}
2176
2178 LONG *delta)
2179{
2181
2182 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
2183
2184 if (!This->child.reole)
2185 return CO_E_RELEASED;
2186
2187 return E_NOTIMPL;
2188}
2189
2191{
2193
2194 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2195
2196 if (!This->child.reole)
2197 return CO_E_RELEASED;
2198
2199 return E_NOTIMPL;
2200}
2201
2203 LONG *delta)
2204{
2206
2207 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2208
2209 if (!This->child.reole)
2210 return CO_E_RELEASED;
2211
2212 return E_NOTIMPL;
2213}
2214
2216{
2217 LONG old_start, old_end, new_start, new_end;
2218 HRESULT hr = S_OK;
2219
2220 if (!count)
2221 {
2222 if (delta)
2223 *delta = 0;
2224 return S_FALSE;
2225 }
2226
2227 ITextRange_GetStart(range, &old_start);
2228 ITextRange_GetEnd(range, &old_end);
2229 switch (unit)
2230 {
2231 case tomStory:
2232 if (count < 0)
2233 new_start = new_end = 0;
2234 else
2235 {
2236 new_start = old_start;
2237 ITextRange_GetStoryLength(range, &new_end);
2238 }
2239 if (delta)
2240 {
2241 if (new_end < old_end)
2242 *delta = -1;
2243 else if (new_end == old_end)
2244 *delta = 0;
2245 else
2246 *delta = 1;
2247 }
2248 break;
2249 default:
2250 FIXME("unit %d is not supported\n", unit);
2251 return E_NOTIMPL;
2252 }
2253 if (new_end == old_end)
2254 hr = S_FALSE;
2255 ITextRange_SetStart(range, new_start);
2256 ITextRange_SetEnd(range, new_end);
2257
2258 return hr;
2259}
2260
2262 LONG *delta)
2263{
2265
2266 TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta);
2267
2268 if (!This->child.reole)
2269 return CO_E_RELEASED;
2270
2271 return textrange_moveend(me, unit, count, delta);
2272}
2273
2275 LONG *delta)
2276{
2278
2279 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2280
2281 if (!This->child.reole)
2282 return CO_E_RELEASED;
2283
2284 return E_NOTIMPL;
2285}
2286
2288 LONG *delta)
2289{
2291
2292 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2293
2294 if (!This->child.reole)
2295 return CO_E_RELEASED;
2296
2297 return E_NOTIMPL;
2298}
2299
2301 LONG *delta)
2302{
2304
2305 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2306
2307 if (!This->child.reole)
2308 return CO_E_RELEASED;
2309
2310 return E_NOTIMPL;
2311}
2312
2314 LONG *delta)
2315{
2317
2318 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2319
2320 if (!This->child.reole)
2321 return CO_E_RELEASED;
2322
2323 return E_NOTIMPL;
2324}
2325
2327 LONG *delta)
2328{
2330
2331 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2332
2333 if (!This->child.reole)
2334 return CO_E_RELEASED;
2335
2336 return E_NOTIMPL;
2337}
2338
2340 LONG *delta)
2341{
2343
2344 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2345
2346 if (!This->child.reole)
2347 return CO_E_RELEASED;
2348
2349 return E_NOTIMPL;
2350}
2351
2353 LONG *length)
2354{
2356
2357 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2358
2359 if (!This->child.reole)
2360 return CO_E_RELEASED;
2361
2362 return E_NOTIMPL;
2363}
2364
2367{
2369
2370 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2371
2372 if (!This->child.reole)
2373 return CO_E_RELEASED;
2374
2375 return E_NOTIMPL;
2376}
2377
2380{
2382
2383 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2384
2385 if (!This->child.reole)
2386 return CO_E_RELEASED;
2387
2388 return E_NOTIMPL;
2389}
2390
2392{
2394
2395 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2396
2397 if (!This->child.reole)
2398 return CO_E_RELEASED;
2399
2400 return E_NOTIMPL;
2401}
2402
2404{
2406
2407 FIXME("(%p)->(%p): stub\n", This, v);
2408
2409 if (!This->child.reole)
2410 return CO_E_RELEASED;
2411
2412 return E_NOTIMPL;
2413}
2414
2416{
2418
2419 FIXME("(%p)->(%p): stub\n", This, v);
2420
2421 if (!This->child.reole)
2422 return CO_E_RELEASED;
2423
2424 return E_NOTIMPL;
2425}
2426
2428{
2430
2431 FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format);
2432
2433 if (!This->child.reole)
2434 return CO_E_RELEASED;
2435
2436 return E_NOTIMPL;
2437}
2438
2440{
2442
2443 FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret);
2444
2445 if (!This->child.reole)
2446 return CO_E_RELEASED;
2447
2448 return E_NOTIMPL;
2449}
2450
2452{
2454
2455 FIXME("(%p)->(%p): stub\n", This, ret);
2456
2457 if (!This->child.reole)
2458 return CO_E_RELEASED;
2459
2460 return E_NOTIMPL;
2461}
2462
2464{
2466
2467 FIXME("(%p)->(%d): stub\n", This, type);
2468
2469 if (!This->child.reole)
2470 return CO_E_RELEASED;
2471
2472 return E_NOTIMPL;
2473}
2474
2476{
2478
2479 FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy);
2480
2481 if (!This->child.reole)
2482 return CO_E_RELEASED;
2483
2484 return E_NOTIMPL;
2485}
2486
2488 LONG extend)
2489{
2491
2492 FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend);
2493
2494 if (!This->child.reole)
2495 return CO_E_RELEASED;
2496
2497 return E_NOTIMPL;
2498}
2499
2501{
2503 ME_TextEditor *editor;
2505 int x, y, height;
2506
2507 TRACE("(%p)->(%d)\n", This, value);
2508
2509 if (!This->child.reole)
2510 return CO_E_RELEASED;
2511
2512 editor = This->child.reole->editor;
2513
2514 switch (value)
2515 {
2516 case tomStart:
2517 ME_CursorFromCharOfs(editor, This->start, &cursor);
2518 ME_GetCursorCoordinates(editor, &cursor, &x, &y, &height);
2519 break;
2520 case tomEnd:
2521 ME_CursorFromCharOfs(editor, This->end, &cursor);
2522 ME_GetCursorCoordinates(editor, &cursor, &x, &y, &height);
2523 break;
2524 default:
2525 FIXME("bStart value %d not handled\n", value);
2526 return E_NOTIMPL;
2527 }
2528 ME_ScrollAbs(editor, x, y);
2529 return S_OK;
2530}
2531
2533{
2535
2536 FIXME("(%p)->(%p): stub\n", This, ppv);
2537
2538 if (!This->child.reole)
2539 return CO_E_RELEASED;
2540
2541 return E_NOTIMPL;
2542}
2543
2544static const ITextRangeVtbl trvt = {
2603};
2604
2605/* ITextFont */
2607{
2609
2610 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
2611
2612 if (IsEqualIID(riid, &IID_ITextFont) ||
2615 {
2616 *ppv = iface;
2617 ITextFont_AddRef(iface);
2618 return S_OK;
2619 }
2620
2621 *ppv = NULL;
2622 return E_NOINTERFACE;
2623}
2624
2626{
2629 TRACE("(%p)->(%u)\n", This, ref);
2630 return ref;
2631}
2632
2634{
2637
2638 TRACE("(%p)->(%u)\n", This, ref);
2639
2640 if (!ref)
2641 {
2642 if (This->range)
2643 ITextRange_Release(This->range);
2644 SysFreeString(This->props[FONT_NAME].str);
2645 heap_free(This);
2646 }
2647
2648 return ref;
2649}
2650
2652{
2654 TRACE("(%p)->(%p)\n", This, pctinfo);
2655 *pctinfo = 1;
2656 return S_OK;
2657}
2658
2660 ITypeInfo **ppTInfo)
2661{
2663 HRESULT hr;
2664
2665 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
2666
2667 hr = get_typeinfo(ITextFont_tid, ppTInfo);
2668 if (SUCCEEDED(hr))
2669 ITypeInfo_AddRef(*ppTInfo);
2670 return hr;
2671}
2672
2674 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
2675{
2677 ITypeInfo *ti;
2678 HRESULT hr;
2679
2680 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid),
2681 rgszNames, cNames, lcid, rgDispId);
2682
2684 if (SUCCEEDED(hr))
2685 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
2686 return hr;
2687}
2688
2690 ITextFont *iface,
2691 DISPID dispIdMember,
2692 REFIID riid,
2693 LCID lcid,
2694 WORD wFlags,
2695 DISPPARAMS *pDispParams,
2696 VARIANT *pVarResult,
2697 EXCEPINFO *pExcepInfo,
2698 UINT *puArgErr)
2699{
2701 ITypeInfo *ti;
2702 HRESULT hr;
2703
2704 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
2705 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2706
2708 if (SUCCEEDED(hr))
2709 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2710 return hr;
2711}
2712
2714{
2716
2717 TRACE("(%p)->(%p)\n", This, ret);
2718
2719 if (!ret)
2720 return E_INVALIDARG;
2721
2722 *ret = NULL;
2723 if (This->range && !get_range_reole(This->range))
2724 return CO_E_RELEASED;
2725
2726 return create_textfont(NULL, This, ret);
2727}
2728
2730{
2732 FIXME("(%p)->(%p): stub\n", This, pFont);
2733 return E_NOTIMPL;
2734}
2735
2737{
2739 FIXME("(%p)->(%p): stub\n", This, ret);
2740 return E_NOTIMPL;
2741}
2742
2744{
2746 FIXME("(%p)->(%p %p): stub\n", This, font, ret);
2747 return E_NOTIMPL;
2748}
2749
2751{
2752 enum textfont_prop_id id;
2753
2754 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2755 switch (id)
2756 {
2757 case FONT_ALLCAPS:
2758 case FONT_ANIMATION:
2759 case FONT_BOLD:
2760 case FONT_EMBOSS:
2761 case FONT_HIDDEN:
2762 case FONT_ENGRAVE:
2763 case FONT_ITALIC:
2764 case FONT_OUTLINE:
2765 case FONT_PROTECTED:
2766 case FONT_SHADOW:
2767 case FONT_SMALLCAPS:
2768 case FONT_STRIKETHROUGH:
2769 case FONT_SUBSCRIPT:
2770 case FONT_SUPERSCRIPT:
2771 case FONT_UNDERLINE:
2772 font->props[id].l = tomFalse;
2773 break;
2774 case FONT_BACKCOLOR:
2775 case FONT_FORECOLOR:
2776 font->props[id].l = tomAutoColor;
2777 break;
2778 case FONT_KERNING:
2779 case FONT_POSITION:
2780 case FONT_SIZE:
2781 case FONT_SPACING:
2782 font->props[id].f = 0.0;
2783 break;
2784 case FONT_LANGID:
2785 font->props[id].l = GetSystemDefaultLCID();
2786 break;
2787 case FONT_NAME: {
2788 static const WCHAR sysW[] = {'S','y','s','t','e','m',0};
2789 SysFreeString(font->props[id].str);
2790 font->props[id].str = SysAllocString(sysW);
2791 break;
2792 }
2793 case FONT_WEIGHT:
2794 font->props[id].l = FW_NORMAL;
2795 break;
2796 default:
2797 FIXME("font property %d not handled\n", id);
2798 }
2799 }
2800}
2801
2803{
2804 enum textfont_prop_id id;
2805
2806 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2807 switch (id)
2808 {
2809 case FONT_ALLCAPS:
2810 case FONT_ANIMATION:
2811 case FONT_BOLD:
2812 case FONT_EMBOSS:
2813 case FONT_HIDDEN:
2814 case FONT_ENGRAVE:
2815 case FONT_ITALIC:
2816 case FONT_OUTLINE:
2817 case FONT_PROTECTED:
2818 case FONT_SHADOW:
2819 case FONT_SMALLCAPS:
2820 case FONT_STRIKETHROUGH:
2821 case FONT_SUBSCRIPT:
2822 case FONT_SUPERSCRIPT:
2823 case FONT_UNDERLINE:
2824 case FONT_BACKCOLOR:
2825 case FONT_FORECOLOR:
2826 case FONT_LANGID:
2827 case FONT_WEIGHT:
2828 font->props[id].l = tomUndefined;
2829 break;
2830 case FONT_KERNING:
2831 case FONT_POSITION:
2832 case FONT_SIZE:
2833 case FONT_SPACING:
2834 font->props[id].f = tomUndefined;
2835 break;
2836 case FONT_NAME:
2837 break;
2838 default:
2839 FIXME("font property %d not handled\n", id);
2840 }
2841 }
2842}
2843
2845{
2846 enum textfont_prop_id propid;
2847 for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++)
2848 set_textfont_prop(font, propid, &font->props[propid]);
2849}
2850
2852{
2854
2855 TRACE("(%p)->(%d)\n", This, value);
2856
2857 /* If font is attached to a range, released or not, we can't
2858 reset to undefined */
2859 if (This->range) {
2860 if (!get_range_reole(This->range))
2861 return CO_E_RELEASED;
2862
2863 switch (value)
2864 {
2865 case tomUndefined:
2866 return E_INVALIDARG;
2867 case tomCacheParms:
2869 This->get_cache_enabled = TRUE;
2870 break;
2871 case tomTrackParms:
2872 This->get_cache_enabled = FALSE;
2873 break;
2874 case tomApplyLater:
2875 This->set_cache_enabled = TRUE;
2876 break;
2877 case tomApplyNow:
2878 This->set_cache_enabled = FALSE;
2880 break;
2881 case tomUsePoints:
2882 case tomUseTwips:
2883 return E_INVALIDARG;
2884 default:
2885 FIXME("reset mode %d not supported\n", value);
2886 }
2887
2888 return S_OK;
2889 }
2890 else {
2891 switch (value)
2892 {
2893 /* reset to global defaults */
2894 case tomDefault:
2896 return S_OK;
2897 /* all properties are set to tomUndefined, font name is retained */
2898 case tomUndefined:
2900 return S_OK;
2901 case tomApplyNow:
2902 case tomApplyLater:
2903 case tomTrackParms:
2904 case tomCacheParms:
2905 return S_OK;
2906 case tomUsePoints:
2907 case tomUseTwips:
2908 return E_INVALIDARG;
2909 }
2910 }
2911
2912 FIXME("reset mode %d not supported\n", value);
2913 return E_NOTIMPL;
2914}
2915
2917{
2919 FIXME("(%p)->(%p): stub\n", This, value);
2920 return E_NOTIMPL;
2921}
2922
2924{
2926 FIXME("(%p)->(%d): stub\n", This, value);
2927 return E_NOTIMPL;
2928}
2929
2931{
2933 TRACE("(%p)->(%p)\n", This, value);
2935}
2936
2938{
2940 TRACE("(%p)->(%d)\n", This, value);
2942}
2943
2945{
2947 TRACE("(%p)->(%p)\n", This, value);
2949}
2950
2952{
2954
2955 TRACE("(%p)->(%d)\n", This, value);
2956
2957 if (value < tomNoAnimation || value > tomAnimationMax)
2958 return E_INVALIDARG;
2959
2961}
2962
2964{
2966 TRACE("(%p)->(%p)\n", This, value);
2968}
2969
2971{
2973 TRACE("(%p)->(%d)\n", This, value);
2975}
2976
2978{
2980 TRACE("(%p)->(%p)\n", This, value);
2982}
2983
2985{
2987 TRACE("(%p)->(%d)\n", This, value);
2989}
2990
2992{
2994 TRACE("(%p)->(%p)\n", This, value);
2996}
2997
2999{
3001 TRACE("(%p)->(%d)\n", This, value);
3003}
3004
3006{
3008 TRACE("(%p)->(%p)\n", This, value);
3010}
3011
3013{
3015 TRACE("(%p)->(%d)\n", This, value);
3017}
3018
3020{
3022 TRACE("(%p)->(%p)\n", This, value);
3024}
3025
3027{
3029 TRACE("(%p)->(%d)\n", This, value);
3031}
3032
3034{
3036 TRACE("(%p)->(%p)\n", This, value);
3038}
3039
3041{
3043 TRACE("(%p)->(%d)\n", This, value);
3045}
3046
3048{
3050 TRACE("(%p)->(%p)\n", This, value);
3052}
3053
3055{
3057 TRACE("(%p)->(%d)\n", This, value);
3059}
3060
3062{
3064 TRACE("(%p)->(%p)\n", This, value);
3066}
3067
3069{
3071 TRACE("(%p)->(%.2f)\n", This, value);
3073}
3074
3076{
3078 TRACE("(%p)->(%p)\n", This, value);
3080}
3081
3083{
3085 TRACE("(%p)->(%d)\n", This, value);
3087}
3088
3090{
3092
3093 TRACE("(%p)->(%p)\n", This, value);
3094
3095 if (!value)
3096 return E_INVALIDARG;
3097
3098 *value = NULL;
3099
3100 if (!This->range) {
3101 if (This->props[FONT_NAME].str)
3102 *value = SysAllocString(This->props[FONT_NAME].str);
3103 else
3105 return *value ? S_OK : E_OUTOFMEMORY;
3106 }
3107
3108 return textfont_getname_from_range(This->range, value);
3109}
3110
3112{
3115
3116 TRACE("(%p)->(%s)\n", This, debugstr_w(value));
3117
3118 v.str = value;
3119 return set_textfont_prop(This, FONT_NAME, &v);
3120}
3121
3123{
3125 TRACE("(%p)->(%p)\n", This, value);
3127}
3128
3130{
3132 TRACE("(%p)->(%d)\n", This, value);
3134}
3135
3137{
3139 TRACE("(%p)->(%p)\n", This, value);
3141}
3142
3144{
3146 TRACE("(%p)->(%.2f)\n", This, value);
3148}
3149
3151{
3153 TRACE("(%p)->(%p)\n", This, value);
3155}
3156
3158{
3160 TRACE("(%p)->(%d)\n", This, value);
3162}
3163
3165{
3167 TRACE("(%p)->(%p)\n", This, value);
3169}
3170
3172{
3174 TRACE("(%p)->(%d)\n", This, value);
3176}
3177
3179{
3181 TRACE("(%p)->(%p)\n", This, value);
3183}
3184
3186{
3188 TRACE("(%p)->(%.2f)\n", This, value);
3190}
3191
3193{
3195 TRACE("(%p)->(%p)\n", This, value);
3197}
3198
3200{
3202 TRACE("(%p)->(%d)\n", This, value);
3204}
3205
3207{
3209 TRACE("(%p)->(%p)\n", This, value);
3211}
3212
3214{
3216 TRACE("(%p)->(%.2f)\n", This, value);
3218}
3219
3221{
3223 TRACE("(%p)->(%p)\n", This, value);
3225}
3226
3228{
3230 TRACE("(%p)->(%d)\n", This, value);
3232}
3233
3235{
3237 TRACE("(%p)->(%p)\n", This, value);
3239}
3240
3242{
3244 TRACE("(%p)->(%d)\n", This, value);
3246}
3247
3249{
3251 TRACE("(%p)->(%p)\n", This, value);
3253}
3254
3256{
3258 TRACE("(%p)->(%d)\n", This, value);
3260}
3261
3263{
3265 TRACE("(%p)->(%p)\n", This, value);
3267}
3268
3270{
3272 TRACE("(%p)->(%d)\n", This, value);
3274}
3275
3277{
3279 TRACE("(%p)->(%p)\n", This, value);
3281}
3282
3284{
3286 TRACE("(%p)->(%d)\n", This, value);
3288}
3289
3290static ITextFontVtbl textfontvtbl = {
3353};
3354
3356{
3358
3359 *ret = NULL;
3360 font = heap_alloc(sizeof(*font));
3361 if (!font)
3362 return E_OUTOFMEMORY;
3363
3364 font->ITextFont_iface.lpVtbl = &textfontvtbl;
3365 font->ref = 1;
3366
3367 if (src) {
3368 font->range = NULL;
3369 font->get_cache_enabled = TRUE;
3370 font->set_cache_enabled = TRUE;
3371 memcpy(&font->props, &src->props, sizeof(font->props));
3372 if (font->props[FONT_NAME].str)
3373 font->props[FONT_NAME].str = SysAllocString(font->props[FONT_NAME].str);
3374 }
3375 else {
3376 font->range = range;
3377 ITextRange_AddRef(range);
3378
3379 /* cache current properties */
3380 font->get_cache_enabled = FALSE;
3381 font->set_cache_enabled = FALSE;
3383 }
3384
3385 *ret = &font->ITextFont_iface;
3386 return S_OK;
3387}
3388
3389/* ITextPara */
3391{
3393
3394 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
3395
3396 if (IsEqualIID(riid, &IID_ITextPara) ||
3399 {
3400 *ppv = iface;
3401 ITextPara_AddRef(iface);
3402 return S_OK;
3403 }
3404
3405 *ppv = NULL;
3406 return E_NOINTERFACE;
3407}
3408
3410{
3413 TRACE("(%p)->(%u)\n", This, ref);
3414 return ref;
3415}
3416
3418{
3421
3422 TRACE("(%p)->(%u)\n", This, ref);
3423
3424 if (!ref)
3425 {
3426 ITextRange_Release(This->range);
3427 heap_free(This);
3428 }
3429
3430 return ref;
3431}
3432
3434{
3435 if (This->range)
3436 {
3438 return rng->child.reole;
3439 }
3440 return NULL;
3441}
3442
3444{
3446 TRACE("(%p)->(%p)\n", This, pctinfo);
3447 *pctinfo = 1;
3448 return S_OK;
3449}
3450
3452 ITypeInfo **ppTInfo)
3453{
3455 HRESULT hr;
3456
3457 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
3458
3459 hr = get_typeinfo(ITextPara_tid, ppTInfo);
3460 if (SUCCEEDED(hr))
3461 ITypeInfo_AddRef(*ppTInfo);
3462 return hr;
3463}
3464
3466 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
3467{
3469 ITypeInfo *ti;
3470 HRESULT hr;
3471
3472 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames,
3473 cNames, lcid, rgDispId);
3474
3476 if (SUCCEEDED(hr))
3477 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
3478 return hr;
3479}
3480
3482 ITextPara *iface,
3483 DISPID dispIdMember,
3484 REFIID riid,
3485 LCID lcid,
3486 WORD wFlags,
3487 DISPPARAMS *pDispParams,
3488 VARIANT *pVarResult,
3489 EXCEPINFO *pExcepInfo,
3490 UINT *puArgErr)
3491{
3493 ITypeInfo *ti;
3494 HRESULT hr;
3495
3496 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember,
3497 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
3498 pExcepInfo, puArgErr);
3499
3501 if (SUCCEEDED(hr))
3502 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3503 return hr;
3504}
3505
3507{
3509 FIXME("(%p)->(%p)\n", This, ret);
3510
3511 if (!para_get_reole(This))
3512 return CO_E_RELEASED;
3513
3514 return E_NOTIMPL;
3515}
3516
3518{
3520 FIXME("(%p)->(%p)\n", This, para);
3521
3522 if (!para_get_reole(This))
3523 return CO_E_RELEASED;
3524
3525 return E_NOTIMPL;
3526}
3527
3529{
3531 FIXME("(%p)->(%p)\n", This, ret);
3532
3533 if (!para_get_reole(This))
3534 return CO_E_RELEASED;
3535
3536 return E_NOTIMPL;
3537}
3538
3540{
3542 FIXME("(%p)->(%p %p)\n", This, para, ret);
3543
3544 if (!para_get_reole(This))
3545 return CO_E_RELEASED;
3546
3547 return E_NOTIMPL;
3548}
3549
3551{
3553 FIXME("(%p)->(%d)\n", This, value);
3554
3555 if (!para_get_reole(This))
3556 return CO_E_RELEASED;
3557
3558 return E_NOTIMPL;
3559}
3560
3562{
3564 FIXME("(%p)->(%p)\n", This, value);
3565
3566 if (!para_get_reole(This))
3567 return CO_E_RELEASED;
3568
3569 return E_NOTIMPL;
3570}
3571
3573{
3575 FIXME("(%p)->(%d)\n", This, value);
3576
3577 if (!para_get_reole(This))
3578 return CO_E_RELEASED;
3579
3580 return E_NOTIMPL;
3581}
3582
3584{
3586 static int once;
3587
3588 if (!once++) FIXME("(%p)->(%p)\n", This, value);
3589
3590 if (!para_get_reole(This))
3591 return CO_E_RELEASED;
3592
3593 return E_NOTIMPL;
3594}
3595
3597{
3599 FIXME("(%p)->(%d)\n", This, value);
3600
3601 if (!para_get_reole(This))
3602 return CO_E_RELEASED;
3603
3604 return E_NOTIMPL;
3605}
3606
3608{
3610 FIXME("(%p)->(%p)\n", This, value);
3611
3612 if (!para_get_reole(This))
3613 return CO_E_RELEASED;
3614
3615 return E_NOTIMPL;
3616}
3617
3619{
3621 FIXME("(%p)->(%d)\n", This, value);
3622
3623 if (!para_get_reole(This))
3624 return CO_E_RELEASED;
3625
3626 return E_NOTIMPL;
3627}
3628
3630{
3632 FIXME("(%p)->(%p)\n", This, value);
3633
3634 if (!para_get_reole(This))
3635 return CO_E_RELEASED;
3636
3637 return E_NOTIMPL;
3638}
3639
3641{
3643 FIXME("(%p)->(%p)\n", This, value);
3644
3645 if (!para_get_reole(This))
3646 return CO_E_RELEASED;
3647
3648 return E_NOTIMPL;
3649}
3650
3652{
3654 FIXME("(%p)->(%d)\n", This, value);
3655
3656 if (!para_get_reole(This))
3657 return CO_E_RELEASED;
3658
3659 return E_NOTIMPL;
3660}
3661
3663{
3665 FIXME("(%p)->(%p)\n", This, value);
3666
3667 if (!para_get_reole(This))
3668 return CO_E_RELEASED;
3669
3670 return E_NOTIMPL;
3671}
3672
3674{
3676 FIXME("(%p)->(%d)\n", This, value);
3677
3678 if (!para_get_reole(This))
3679 return CO_E_RELEASED;
3680
3681 return E_NOTIMPL;
3682}
3683
3685{
3687 FIXME("(%p)->(%p)\n", This, value);
3688
3689 if (!para_get_reole(This))
3690 return CO_E_RELEASED;
3691
3692 return E_NOTIMPL;
3693}
3694
3696{
3698 FIXME("(%p)->(%p)\n", This, value);
3699
3700 if (!para_get_reole(This))
3701 return CO_E_RELEASED;
3702
3703 return E_NOTIMPL;
3704}
3705
3707{
3709 FIXME("(%p)->(%p)\n", This, value);
3710
3711 if (!para_get_reole(This))
3712 return CO_E_RELEASED;
3713
3714 return E_NOTIMPL;
3715}
3716
3718{
3720 FIXME("(%p)->(%p)\n", This, value);
3721
3722 if (!para_get_reole(This))
3723 return