| /* | |
| * RichEdit GUIDs and OLE interface | |
| * | |
| * Copyright 2004 by Krzysztof Foltman | |
| * Copyright 2004 Aric Stewart | |
| * | |
| * This library is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU Lesser General Public | |
| * License as published by the Free Software Foundation; either | |
| * version 2.1 of the License, or (at your option) any later version. | |
| * | |
| * This library is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| * Lesser General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU Lesser General Public | |
| * License along with this library; if not, write to the Free Software | |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | |
| */ | |
| #include <stdarg.h> | |
| #define NONAMELESSUNION | |
| #define COBJMACROS | |
| #include "windef.h" | |
| #include "winbase.h" | |
| #include "wingdi.h" | |
| #include "winuser.h" | |
| #include "ole2.h" | |
| #include "richole.h" | |
| #include "editor.h" | |
| #include "richedit.h" | |
| #include "tom.h" | |
| #include "wine/debug.h" | |
| WINE_DEFAULT_DEBUG_CHANNEL(richedit); | |
| /* there is no way to be consistent across different sets of headers - mingw, Wine, Win32 SDK*/ | |
| #include "initguid.h" | |
| DEFINE_GUID(LIBID_tom, 0x8cc497c9, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d); | |
| DEFINE_GUID(IID_ITextServices, 0x8d33f740, 0xcf58, 0x11ce, 0xa8, 0x9d, 0x00, 0xaa, 0x00, 0x6c, 0xad, 0xc5); | |
| DEFINE_GUID(IID_ITextHost, 0x13e670f4,0x1a5a,0x11cf,0xab,0xeb,0x00,0xaa,0x00,0xb6,0x5e,0xa1); | |
| DEFINE_GUID(IID_ITextHost2, 0x13e670f5,0x1a5a,0x11cf,0xab,0xeb,0x00,0xaa,0x00,0xb6,0x5e,0xa1); | |
| DEFINE_GUID(IID_ITextDocument, 0x8cc497c0, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d); | |
| DEFINE_GUID(IID_ITextRange, 0x8cc497c2, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d); | |
| DEFINE_GUID(IID_ITextSelection, 0x8cc497c1, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d); | |
| DEFINE_GUID(IID_ITextFont, 0x8cc497c3, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d); | |
| DEFINE_GUID(IID_ITextPara, 0x8cc497c4, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d); | |
| static ITypeLib *typelib; | |
| enum tid_t { | |
| NULL_tid, | |
| ITextDocument_tid, | |
| ITextRange_tid, | |
| ITextSelection_tid, | |
| ITextFont_tid, | |
| ITextPara_tid, | |
| LAST_tid | |
| }; | |
| static const IID * const tid_ids[] = | |
| { | |
| &IID_NULL, | |
| &IID_ITextDocument, | |
| &IID_ITextRange, | |
| &IID_ITextSelection, | |
| &IID_ITextFont, | |
| &IID_ITextPara, | |
| }; | |
| static ITypeInfo *typeinfos[LAST_tid]; | |
| static HRESULT load_typelib(void) | |
| { | |
| ITypeLib *tl; | |
| HRESULT hr; | |
| hr = LoadRegTypeLib(&LIBID_tom, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl); | |
| if (FAILED(hr)) { | |
| ERR("LoadRegTypeLib failed: %08x\n", hr); | |
| return hr; | |
| } | |
| if (InterlockedCompareExchangePointer((void**)&typelib, tl, NULL)) | |
| ITypeLib_Release(tl); | |
| return hr; | |
| } | |
| void release_typelib(void) | |
| { | |
| unsigned i; | |
| if (!typelib) | |
| return; | |
| for (i = 0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++) | |
| if (typeinfos[i]) | |
| ITypeInfo_Release(typeinfos[i]); | |
| ITypeLib_Release(typelib); | |
| } | |
| static HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo) | |
| { | |
| HRESULT hr; | |
| if (!typelib) | |
| hr = load_typelib(); | |
| if (!typelib) | |
| return hr; | |
| if (!typeinfos[tid]) | |
| { | |
| ITypeInfo *ti; | |
| hr = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti); | |
| if (FAILED(hr)) | |
| { | |
| ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hr); | |
| return hr; | |
| } | |
| if (InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL)) | |
| ITypeInfo_Release(ti); | |
| } | |
| *typeinfo = typeinfos[tid]; | |
| return S_OK; | |
| } | |
| /* private IID used to get back IRichEditOleImpl pointer */ | |
| DEFINE_GUID(IID_Igetrichole, 0xe3ce5c7a, 0x8247, 0x4622, 0x81, 0xad, 0x11, 0x81, 0x02, 0xaa, 0x01, 0x30); | |
| typedef struct ITextSelectionImpl ITextSelectionImpl; | |
| typedef struct IOleClientSiteImpl IOleClientSiteImpl; | |
| typedef struct ITextRangeImpl ITextRangeImpl; | |
| enum textfont_prop_id { | |
| FONT_ALLCAPS = 0, | |
| FONT_ANIMATION, | |
| FONT_BACKCOLOR, | |
| FONT_BOLD, | |
| FONT_EMBOSS, | |
| FONT_FORECOLOR, | |
| FONT_HIDDEN, | |
| FONT_ENGRAVE, | |
| FONT_ITALIC, | |
| FONT_KERNING, | |
| FONT_LANGID, | |
| FONT_NAME, | |
| FONT_OUTLINE, | |
| FONT_POSITION, | |
| FONT_PROTECTED, | |
| FONT_SHADOW, | |
| FONT_SIZE, | |
| FONT_SMALLCAPS, | |
| FONT_SPACING, | |
| FONT_STRIKETHROUGH, | |
| FONT_SUBSCRIPT, | |
| FONT_SUPERSCRIPT, | |
| FONT_UNDERLINE, | |
| FONT_WEIGHT, | |
| FONT_PROPID_LAST, | |
| FONT_PROPID_FIRST = FONT_ALLCAPS | |
| }; | |
| static const DWORD textfont_prop_masks[][2] = { | |
| { CFM_ALLCAPS, CFE_ALLCAPS }, | |
| { CFM_ANIMATION }, | |
| { CFM_BACKCOLOR, CFE_AUTOBACKCOLOR }, | |
| { CFM_BOLD, CFE_BOLD }, | |
| { CFM_EMBOSS, CFE_EMBOSS }, | |
| { CFM_COLOR, CFE_AUTOCOLOR }, | |
| { CFM_HIDDEN, CFE_HIDDEN }, | |
| { CFM_IMPRINT, CFE_IMPRINT }, | |
| { CFM_ITALIC, CFE_ITALIC }, | |
| { CFM_KERNING }, | |
| { CFM_LCID }, | |
| { CFM_FACE }, | |
| { CFM_OUTLINE, CFE_OUTLINE }, | |
| { CFM_OFFSET }, | |
| { CFM_PROTECTED, CFE_PROTECTED }, | |
| { CFM_SHADOW, CFE_SHADOW }, | |
| { CFM_SIZE }, | |
| { CFM_SMALLCAPS, CFE_SMALLCAPS }, | |
| { CFM_SPACING }, | |
| { CFM_STRIKEOUT, CFE_STRIKEOUT }, | |
| { CFM_SUBSCRIPT, CFE_SUBSCRIPT }, | |
| { CFM_SUPERSCRIPT, CFE_SUPERSCRIPT }, | |
| { CFM_UNDERLINE, CFE_UNDERLINE }, | |
| { CFM_WEIGHT } | |
| }; | |
| typedef union { | |
| FLOAT f; | |
| LONG l; | |
| BSTR str; | |
| } textfont_prop_val; | |
| enum range_update_op { | |
| RANGE_UPDATE_DELETE | |
| }; | |
| typedef struct IRichEditOleImpl { | |
| IUnknown IUnknown_inner; | |
| IRichEditOle IRichEditOle_iface; | |
| ITextDocument ITextDocument_iface; | |
| IUnknown *outer_unk; | |
| LONG ref; | |
| ME_TextEditor *editor; | |
| ITextSelectionImpl *txtSel; | |
| struct list rangelist; | |
| struct list clientsites; | |
| } IRichEditOleImpl; | |
| struct reole_child { | |
| struct list entry; | |
| IRichEditOleImpl *reole; | |
| }; | |
| struct ITextRangeImpl { | |
| struct reole_child child; | |
| ITextRange ITextRange_iface; | |
| LONG ref; | |
| LONG start, end; | |
| }; | |
| struct ITextSelectionImpl { | |
| ITextSelection ITextSelection_iface; | |
| LONG ref; | |
| IRichEditOleImpl *reOle; | |
| }; | |
| typedef struct ITextFontImpl { | |
| ITextFont ITextFont_iface; | |
| LONG ref; | |
| ITextRange *range; | |
| textfont_prop_val props[FONT_PROPID_LAST]; | |
| BOOL get_cache_enabled; | |
| BOOL set_cache_enabled; | |
| } ITextFontImpl; | |
| typedef struct ITextParaImpl { | |
| ITextPara ITextPara_iface; | |
| LONG ref; | |
| ITextRange *range; | |
| } ITextParaImpl; | |
| struct IOleClientSiteImpl { | |
| struct reole_child child; | |
| IOleClientSite IOleClientSite_iface; | |
| IOleInPlaceSite IOleInPlaceSite_iface; | |
| LONG ref; | |
| }; | |
| static inline IRichEditOleImpl *impl_from_IRichEditOle(IRichEditOle *iface) | |
| { | |
| return CONTAINING_RECORD(iface, IRichEditOleImpl, IRichEditOle_iface); | |
| } | |
| static inline IRichEditOleImpl *impl_from_ITextDocument(ITextDocument *iface) | |
| { | |
| return CONTAINING_RECORD(iface, IRichEditOleImpl, ITextDocument_iface); | |
| } | |
| static inline IRichEditOleImpl *impl_from_IUnknown(IUnknown *iface) | |
| { | |
| return CONTAINING_RECORD(iface, IRichEditOleImpl, IUnknown_inner); | |
| } | |
| static inline IOleClientSiteImpl *impl_from_IOleInPlaceSite(IOleInPlaceSite *iface) | |
| { | |
| return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleInPlaceSite_iface); | |
| } | |
| static inline ITextRangeImpl *impl_from_ITextRange(ITextRange *iface) | |
| { | |
| return CONTAINING_RECORD(iface, ITextRangeImpl, ITextRange_iface); | |
| } | |
| static inline ITextSelectionImpl *impl_from_ITextSelection(ITextSelection *iface) | |
| { | |
| return CONTAINING_RECORD(iface, ITextSelectionImpl, ITextSelection_iface); | |
| } | |
| static inline ITextFontImpl *impl_from_ITextFont(ITextFont *iface) | |
| { | |
| return CONTAINING_RECORD(iface, ITextFontImpl, ITextFont_iface); | |
| } | |
| static inline ITextParaImpl *impl_from_ITextPara(ITextPara *iface) | |
| { | |
| return CONTAINING_RECORD(iface, ITextParaImpl, ITextPara_iface); | |
| } | |
| static HRESULT create_textfont(ITextRange*, const ITextFontImpl*, ITextFont**); | |
| static HRESULT create_textpara(ITextRange*, ITextPara**); | |
| static ITextSelectionImpl *CreateTextSelection(IRichEditOleImpl*); | |
| static HRESULT textrange_get_storylength(ME_TextEditor *editor, LONG *length) | |
| { | |
| if (!length) | |
| return E_INVALIDARG; | |
| *length = ME_GetTextLength(editor) + 1; | |
| return S_OK; | |
| } | |
| static void textranges_update_ranges(IRichEditOleImpl *reole, LONG start, LONG end, enum range_update_op op) | |
| { | |
| ITextRangeImpl *range; | |
| LIST_FOR_EACH_ENTRY(range, &reole->rangelist, ITextRangeImpl, child.entry) { | |
| switch (op) | |
| { | |
| case RANGE_UPDATE_DELETE: | |
| /* range fully covered by deleted range - collapse to insertion point */ | |
| if (range->start >= start && range->end <= end) | |
| range->start = range->end = start; | |
| /* deleted range cuts from the right */ | |
| else if (range->start < start && range->end <= end) | |
| range->end = start; | |
| /* deleted range cuts from the left */ | |
| else if (range->start >= start && range->end > end) { | |
| range->start = start; | |
| range->end -= end - start; | |
| } | |
| /* deleted range cuts within */ | |
| else | |
| range->end -= end - start; | |
| break; | |
| default: | |
| FIXME("unknown update op, %d\n", op); | |
| } | |
| } | |
| } | |
| static inline BOOL is_equal_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *left, | |
| textfont_prop_val *right) | |
| { | |
| switch (propid) | |
| { | |
| case FONT_ALLCAPS: | |
| case FONT_ANIMATION: | |
| case FONT_BACKCOLOR: | |
| case FONT_BOLD: | |
| case FONT_EMBOSS: | |
| case FONT_FORECOLOR: | |
| case FONT_HIDDEN: | |
| case FONT_ENGRAVE: | |
| case FONT_ITALIC: | |
| case FONT_KERNING: | |
| case FONT_LANGID: | |
| case FONT_OUTLINE: | |
| case FONT_PROTECTED: | |
| case FONT_SHADOW: | |
| case FONT_SMALLCAPS: | |
| case FONT_STRIKETHROUGH: | |
| case FONT_SUBSCRIPT: | |
| case FONT_SUPERSCRIPT: | |
| case FONT_UNDERLINE: | |
| case FONT_WEIGHT: | |
| return left->l == right->l; | |
| case FONT_NAME: | |
| return !strcmpW(left->str, right->str); | |
| case FONT_POSITION: | |
| case FONT_SIZE: | |
| case FONT_SPACING: | |
| return left->f == right->f; | |
| default: | |
| FIXME("unhandled font property %d\n", propid); | |
| return FALSE; | |
| } | |
| } | |
| static inline void init_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *v) | |
| { | |
| switch (propid) | |
| { | |
| case FONT_ALLCAPS: | |
| case FONT_ANIMATION: | |
| case FONT_BACKCOLOR: | |
| case FONT_BOLD: | |
| case FONT_EMBOSS: | |
| case FONT_FORECOLOR: | |
| case FONT_HIDDEN: | |
| case FONT_ENGRAVE: | |
| case FONT_ITALIC: | |
| case FONT_KERNING: | |
| case FONT_LANGID: | |
| case FONT_OUTLINE: | |
| case FONT_PROTECTED: | |
| case FONT_SHADOW: | |
| case FONT_SMALLCAPS: | |
| case FONT_STRIKETHROUGH: | |
| case FONT_SUBSCRIPT: | |
| case FONT_SUPERSCRIPT: | |
| case FONT_UNDERLINE: | |
| case FONT_WEIGHT: | |
| v->l = tomUndefined; | |
| return; | |
| case FONT_NAME: | |
| v->str = NULL; | |
| return; | |
| case FONT_POSITION: | |
| case FONT_SIZE: | |
| case FONT_SPACING: | |
| v->f = tomUndefined; | |
| return; | |
| default: | |
| FIXME("unhandled font property %d\n", propid); | |
| v->l = tomUndefined; | |
| return; | |
| } | |
| } | |
| static inline FLOAT twips_to_points(LONG value) | |
| { | |
| return value * 72.0 / 1440; | |
| } | |
| static inline FLOAT points_to_twips(FLOAT value) | |
| { | |
| return value * 1440 / 72.0; | |
| } | |
| static HRESULT get_textfont_prop_for_pos(const IRichEditOleImpl *reole, int pos, enum textfont_prop_id propid, | |
| textfont_prop_val *value) | |
| { | |
| ME_Cursor from, to; | |
| CHARFORMAT2W fmt; | |
| memset(&fmt, 0, sizeof(fmt)); | |
| fmt.cbSize = sizeof(fmt); | |
| fmt.dwMask = textfont_prop_masks[propid][0]; | |
| ME_CursorFromCharOfs(reole->editor, pos, &from); | |
| to = from; | |
| ME_MoveCursorChars(reole->editor, &to, 1, FALSE); | |
| ME_GetCharFormat(reole->editor, &from, &to, &fmt); | |
| switch (propid) | |
| { | |
| case FONT_ALLCAPS: | |
| case FONT_BOLD: | |
| case FONT_EMBOSS: | |
| case FONT_HIDDEN: | |
| case FONT_ENGRAVE: | |
| case FONT_ITALIC: | |
| case FONT_OUTLINE: | |
| case FONT_PROTECTED: | |
| case FONT_SHADOW: | |
| case FONT_SMALLCAPS: | |
| case FONT_STRIKETHROUGH: | |
| case FONT_SUBSCRIPT: | |
| case FONT_SUPERSCRIPT: | |
| case FONT_UNDERLINE: | |
| value->l = fmt.dwEffects & textfont_prop_masks[propid][1] ? tomTrue : tomFalse; | |
| break; | |
| case FONT_ANIMATION: | |
| value->l = fmt.bAnimation; | |
| break; | |
| case FONT_BACKCOLOR: | |
| value->l = fmt.dwEffects & CFE_AUTOBACKCOLOR ? GetSysColor(COLOR_WINDOW) : fmt.crBackColor; | |
| break; | |
| case FONT_FORECOLOR: | |
| value->l = fmt.dwEffects & CFE_AUTOCOLOR ? GetSysColor(COLOR_WINDOWTEXT) : fmt.crTextColor; | |
| break; | |
| case FONT_KERNING: | |
| value->f = twips_to_points(fmt.wKerning); | |
| break; | |
| case FONT_LANGID: | |
| value->l = fmt.lcid; | |
| break; | |
| case FONT_NAME: | |
| /* this case is used exclusively by GetName() */ | |
| value->str = SysAllocString(fmt.szFaceName); | |
| if (!value->str) | |
| return E_OUTOFMEMORY; | |
| break; | |
| case FONT_POSITION: | |
| value->f = twips_to_points(fmt.yOffset); | |
| break; | |
| case FONT_SIZE: | |
| value->f = twips_to_points(fmt.yHeight); | |
| break; | |
| case FONT_SPACING: | |
| value->f = fmt.sSpacing; | |
| break; | |
| case FONT_WEIGHT: | |
| value->l = fmt.wWeight; | |
| break; | |
| default: | |
| FIXME("unhandled font property %d\n", propid); | |
| return E_FAIL; | |
| } | |
| return S_OK; | |
| } | |
| static inline const IRichEditOleImpl *get_range_reole(ITextRange *range) | |
| { | |
| IRichEditOleImpl *reole = NULL; | |
| ITextRange_QueryInterface(range, &IID_Igetrichole, (void**)&reole); | |
| return reole; | |
| } | |
| static void textrange_set_font(ITextRange *range, ITextFont *font) | |
| { | |
| CHARFORMAT2W fmt; | |
| HRESULT hr; | |
| LONG value; | |
| BSTR str; | |
| FLOAT f; | |
| #define CHARFORMAT_SET_B_FIELD(mask, value) \ | |
| if (hr == S_OK && value != tomUndefined) { \ | |
| fmt.dwMask |= CFM_##mask; \ | |
| if (value == tomTrue) fmt.dwEffects |= CFE_##mask; \ | |
| } \ | |
| /* fill format data from font */ | |
| memset(&fmt, 0, sizeof(fmt)); | |
| fmt.cbSize = sizeof(fmt); | |
| value = tomUndefined; | |
| hr = ITextFont_GetAllCaps(font, &value); | |
| CHARFORMAT_SET_B_FIELD(ALLCAPS, value); | |
| value = tomUndefined; | |
| hr = ITextFont_GetBold(font, &value); | |
| CHARFORMAT_SET_B_FIELD(BOLD, value); | |
| value = tomUndefined; | |
| hr = ITextFont_GetEmboss(font, &value); | |
| CHARFORMAT_SET_B_FIELD(EMBOSS, value); | |
| value = tomUndefined; | |
| hr = ITextFont_GetHidden(font, &value); | |
| CHARFORMAT_SET_B_FIELD(HIDDEN, value); | |
| value = tomUndefined; | |
| hr = ITextFont_GetEngrave(font, &value); | |
| CHARFORMAT_SET_B_FIELD(IMPRINT, value); | |
| value = tomUndefined; | |
| hr = ITextFont_GetItalic(font, &value); | |
| CHARFORMAT_SET_B_FIELD(ITALIC, value); | |
| value = tomUndefined; | |
| hr = ITextFont_GetOutline(font, &value); | |
| CHARFORMAT_SET_B_FIELD(OUTLINE, value); | |
| value = tomUndefined; | |
| hr = ITextFont_GetProtected(font, &value); | |
| CHARFORMAT_SET_B_FIELD(PROTECTED, value); | |
| value = tomUndefined; | |
| hr = ITextFont_GetShadow(font, &value); | |
| CHARFORMAT_SET_B_FIELD(SHADOW, value); | |
| value = tomUndefined; | |
| hr = ITextFont_GetSmallCaps(font, &value); | |
| CHARFORMAT_SET_B_FIELD(SMALLCAPS, value); | |
| value = tomUndefined; | |
| hr = ITextFont_GetStrikeThrough(font, &value); | |
| CHARFORMAT_SET_B_FIELD(STRIKEOUT, value); | |
| value = tomUndefined; | |
| hr = ITextFont_GetSubscript(font, &value); | |
| CHARFORMAT_SET_B_FIELD(SUBSCRIPT, value); | |
| value = tomUndefined; | |
| hr = ITextFont_GetSuperscript(font, &value); | |
| CHARFORMAT_SET_B_FIELD(SUPERSCRIPT, value); | |
| value = tomUndefined; | |
| hr = ITextFont_GetUnderline(font, &value); | |
| CHARFORMAT_SET_B_FIELD(UNDERLINE, value); | |
| #undef CHARFORMAT_SET_B_FIELD | |
| value = tomUndefined; | |
| hr = ITextFont_GetAnimation(font, &value); | |
| if (hr == S_OK && value != tomUndefined) { | |
| fmt.dwMask |= CFM_ANIMATION; | |
| fmt.bAnimation = value; | |
| } | |
| value = tomUndefined; | |
| hr = ITextFont_GetBackColor(font, &value); | |
| if (hr == S_OK && value != tomUndefined) { | |
| fmt.dwMask |= CFM_BACKCOLOR; | |
| if (value == tomAutoColor) | |
| fmt.dwEffects |= CFE_AUTOBACKCOLOR; | |
| else | |
| fmt.crBackColor = value; | |
| } | |
| value = tomUndefined; | |
| hr = ITextFont_GetForeColor(font, &value); | |
| if (hr == S_OK && value != tomUndefined) { | |
| fmt.dwMask |= CFM_COLOR; | |
| if (value == tomAutoColor) | |
| fmt.dwEffects |= CFE_AUTOCOLOR; | |
| else | |
| fmt.crTextColor = value; | |
| } | |
| value = tomUndefined; | |
| hr = ITextFont_GetKerning(font, &f); | |
| if (hr == S_OK && f != tomUndefined) { | |
| fmt.dwMask |= CFM_KERNING; | |
| fmt.wKerning = points_to_twips(f); | |
| } | |
| value = tomUndefined; | |
| hr = ITextFont_GetLanguageID(font, &value); | |
| if (hr == S_OK && value != tomUndefined) { | |
| fmt.dwMask |= CFM_LCID; | |
| fmt.lcid = value; | |
| } | |
| if (ITextFont_GetName(font, &str) == S_OK) { | |
| fmt.dwMask |= CFM_FACE; | |
| lstrcpynW(fmt.szFaceName, str, sizeof(fmt.szFaceName)/sizeof(WCHAR)); | |
| SysFreeString(str); | |
| } | |
| hr = ITextFont_GetPosition(font, &f); | |
| if (hr == S_OK && f != tomUndefined) { | |
| fmt.dwMask |= CFM_OFFSET; | |
| fmt.yOffset = points_to_twips(f); | |
| } | |
| hr = ITextFont_GetSize(font, &f); | |
| if (hr == S_OK && f != tomUndefined) { | |
| fmt.dwMask |= CFM_SIZE; | |
| fmt.yHeight = points_to_twips(f); | |
| } | |
| hr = ITextFont_GetSpacing(font, &f); | |
| if (hr == S_OK && f != tomUndefined) { | |
| fmt.dwMask |= CFM_SPACING; | |
| fmt.sSpacing = f; | |
| } | |
| hr = ITextFont_GetWeight(font, &value); | |
| if (hr == S_OK && value != tomUndefined) { | |
| fmt.dwMask |= CFM_WEIGHT; | |
| fmt.wWeight = value; | |
| } | |
| if (fmt.dwMask) { | |
| const IRichEditOleImpl *reole = get_range_reole(range); | |
| ME_Cursor from, to; | |
| LONG start, end; | |
| ITextRange_GetStart(range, &start); | |
| ITextRange_GetEnd(range, &end); | |
| ME_CursorFromCharOfs(reole->editor, start, &from); | |
| ME_CursorFromCharOfs(reole->editor, end, &to); | |
| ME_SetCharFormat(reole->editor, &from, &to, &fmt); | |
| } | |
| } | |
| static HRESULT get_textfont_prop(const ITextFontImpl *font, enum textfont_prop_id propid, textfont_prop_val *value) | |
| { | |
| const IRichEditOleImpl *reole; | |
| textfont_prop_val v; | |
| LONG start, end, i; | |
| HRESULT hr; | |
| /* when font is not attached to any range use cached values */ | |
| if (!font->range || font->get_cache_enabled) { | |
| *value = font->props[propid]; | |
| return S_OK; | |
| } | |
| if (!(reole = get_range_reole(font->range))) | |
| return CO_E_RELEASED; | |
| init_textfont_prop_value(propid, value); | |
| ITextRange_GetStart(font->range, &start); | |
| ITextRange_GetEnd(font->range, &end); | |
| /* iterate trough a range to see if property value is consistent */ | |
| hr = get_textfont_prop_for_pos(reole, start, propid, &v); | |
| if (FAILED(hr)) | |
| return hr; | |
| for (i = start + 1; i < end; i++) { | |
| textfont_prop_val cur; | |
| hr = get_textfont_prop_for_pos(reole, i, propid, &cur); | |
| if (FAILED(hr)) | |
| return hr; | |
| if (!is_equal_textfont_prop_value(propid, &v, &cur)) | |
| return S_OK; | |
| } | |
| *value = v; | |
| return S_OK; | |
| } | |
| static HRESULT get_textfont_propf(const ITextFontImpl *font, enum textfont_prop_id propid, FLOAT *value) | |
| { | |
| textfont_prop_val v; | |
| HRESULT hr; | |
| if (!value) | |
| return E_INVALIDARG; | |
| hr = get_textfont_prop(font, propid, &v); | |
| *value = v.f; | |
| return hr; | |
| } | |
| static HRESULT get_textfont_propl(const ITextFontImpl *font, enum textfont_prop_id propid, LONG *value) | |
| { | |
| textfont_prop_val v; | |
| HRESULT hr; | |
| if (!value) | |
| return E_INVALIDARG; | |
| hr = get_textfont_prop(font, propid, &v); | |
| *value = v.l; | |
| return hr; | |
| } | |
| /* Value should already have a terminal value, for boolean properties it means tomToggle is not handled */ | |
| static HRESULT set_textfont_prop(ITextFontImpl *font, enum textfont_prop_id propid, const textfont_prop_val *value) | |
| { | |
| const IRichEditOleImpl *reole; | |
| ME_Cursor from, to; | |
| CHARFORMAT2W fmt; | |
| LONG start, end; | |
| /* when font is not attached to any range use cache */ | |
| if (!font->range || font->set_cache_enabled) { | |
| if (propid == FONT_NAME) { | |
| SysFreeString(font->props[propid].str); | |
| font->props[propid].str = SysAllocString(value->str); | |
| } | |
| else | |
| font->props[propid] = *value; | |
| return S_OK; | |
| } | |
| if (!(reole = get_range_reole(font->range))) | |
| return CO_E_RELEASED; | |
| memset(&fmt, 0, sizeof(fmt)); | |
| fmt.cbSize = sizeof(fmt); | |
| fmt.dwMask = textfont_prop_masks[propid][0]; | |
| switch (propid) | |
| { | |
| case FONT_ALLCAPS: | |
| case FONT_BOLD: | |
| case FONT_EMBOSS: | |
| case FONT_HIDDEN: | |
| case FONT_ENGRAVE: | |
| case FONT_ITALIC: | |
| case FONT_OUTLINE: | |
| case FONT_PROTECTED: | |
| case FONT_SHADOW: | |
| case FONT_SMALLCAPS: | |
| case FONT_STRIKETHROUGH: | |
| case FONT_SUBSCRIPT: | |
| case FONT_SUPERSCRIPT: | |
| case FONT_UNDERLINE: | |
| fmt.dwEffects = value->l == tomTrue ? textfont_prop_masks[propid][1] : 0; | |
| break; | |
| case FONT_ANIMATION: | |
| fmt.bAnimation = value->l; | |
| break; | |
| case FONT_BACKCOLOR: | |
| case FONT_FORECOLOR: | |
| if (value->l == tomAutoColor) | |
| fmt.dwEffects = textfont_prop_masks[propid][1]; | |
| else if (propid == FONT_BACKCOLOR) | |
| fmt.crBackColor = value->l; | |
| else | |
| fmt.crTextColor = value->l; | |
| break; | |
| case FONT_KERNING: | |
| fmt.wKerning = value->f; | |
| break; | |
| case FONT_LANGID: | |
| fmt.lcid = value->l; | |
| break; | |
| case FONT_POSITION: | |
| fmt.yOffset = value->f; | |
| break; | |
| case FONT_SIZE: | |
| fmt.yHeight = value->f; | |
| break; | |
| case FONT_SPACING: | |
| fmt.sSpacing = value->f; | |
| break; | |
| case FONT_WEIGHT: | |
| fmt.wWeight = value->l; | |
| break; | |
| case FONT_NAME: | |
| lstrcpynW(fmt.szFaceName, value->str, sizeof(fmt.szFaceName)/sizeof(WCHAR)); | |
| break; | |
| default: | |
| FIXME("unhandled font property %d\n", propid); | |
| return E_FAIL; | |
| } | |
| ITextRange_GetStart(font->range, &start); | |
| ITextRange_GetEnd(font->range, &end); | |
| ME_CursorFromCharOfs(reole->editor, start, &from); | |
| ME_CursorFromCharOfs(reole->editor, end, &to); | |
| ME_SetCharFormat(reole->editor, &from, &to, &fmt); | |
| return S_OK; | |
| } | |
| static inline HRESULT set_textfont_propl(ITextFontImpl *font, enum textfont_prop_id propid, LONG value) | |
| { | |
| textfont_prop_val v; | |
| v.l = value; | |
| return set_textfont_prop(font, propid, &v); | |
| } | |
| static inline HRESULT set_textfont_propf(ITextFontImpl *font, enum textfont_prop_id propid, FLOAT value) | |
| { | |
| textfont_prop_val v; | |
| v.f = value; | |
| return set_textfont_prop(font, propid, &v); | |
| } | |
| static HRESULT set_textfont_propd(ITextFontImpl *font, enum textfont_prop_id propid, LONG value) | |
| { | |
| textfont_prop_val v; | |
| switch (value) | |
| { | |
| case tomUndefined: | |
| return S_OK; | |
| case tomToggle: { | |
| LONG oldvalue; | |
| get_textfont_propl(font, propid, &oldvalue); | |
| if (oldvalue == tomFalse) | |
| value = tomTrue; | |
| else if (oldvalue == tomTrue) | |
| value = tomFalse; | |
| else | |
| return E_INVALIDARG; | |
| /* fallthrough */ | |
| } | |
| case tomTrue: | |
| case tomFalse: | |
| v.l = value; | |
| return set_textfont_prop(font, propid, &v); | |
| default: | |
| return E_INVALIDARG; | |
| } | |
| } | |
| static HRESULT textfont_getname_from_range(ITextRange *range, BSTR *ret) | |
| { | |
| const IRichEditOleImpl *reole; | |
| textfont_prop_val v; | |
| HRESULT hr; | |
| LONG start; | |
| if (!(reole = get_range_reole(range))) | |
| return CO_E_RELEASED; | |
| ITextRange_GetStart(range, &start); | |
| hr = get_textfont_prop_for_pos(reole, start, FONT_NAME, &v); | |
| *ret = v.str; | |
| return hr; | |
| } | |
| static void textfont_cache_range_props(ITextFontImpl *font) | |
| { | |
| enum textfont_prop_id propid; | |
| for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++) { | |
| if (propid == FONT_NAME) | |
| textfont_getname_from_range(font->range, &font->props[propid].str); | |
| else | |
| get_textfont_prop(font, propid, &font->props[propid]); | |
| } | |
| } | |
| static HRESULT textrange_expand(ITextRange *range, LONG unit, LONG *delta) | |
| { | |
| LONG expand_start, expand_end; | |
| switch (unit) | |
| { | |
| case tomStory: | |
| expand_start = 0; | |
| ITextRange_GetStoryLength(range, &expand_end); | |
| break; | |
| default: | |
| FIXME("unit %d is not supported\n", unit); | |
| return E_NOTIMPL; | |
| } | |
| if (delta) { | |
| LONG start, end; | |
| ITextRange_GetStart(range, &start); | |
| ITextRange_GetEnd(range, &end); | |
| *delta = expand_end - expand_start - (end - start); | |
| } | |
| ITextRange_SetStart(range, expand_start); | |
| ITextRange_SetEnd(range, expand_end); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI IRichEditOleImpl_inner_fnQueryInterface(IUnknown *iface, REFIID riid, LPVOID *ppvObj) | |
| { | |
| IRichEditOleImpl *This = impl_from_IUnknown(iface); | |
| TRACE("%p %s\n", This, debugstr_guid(riid)); | |
| *ppvObj = NULL; | |
| if (IsEqualGUID(riid, &IID_IUnknown)) | |
| *ppvObj = &This->IUnknown_inner; | |
| else if (IsEqualGUID(riid, &IID_IRichEditOle)) | |
| *ppvObj = &This->IRichEditOle_iface; | |
| else if (IsEqualGUID(riid, &IID_ITextDocument)) | |
| *ppvObj = &This->ITextDocument_iface; | |
| if (*ppvObj) | |
| { | |
| IUnknown_AddRef((IUnknown *)*ppvObj); | |
| return S_OK; | |
| } | |
| FIXME("%p: unhandled interface %s\n", This, debugstr_guid(riid)); | |
| return E_NOINTERFACE; | |
| } | |
| static ULONG WINAPI IRichEditOleImpl_inner_fnAddRef(IUnknown *iface) | |
| { | |
| IRichEditOleImpl *This = impl_from_IUnknown(iface); | |
| ULONG ref = InterlockedIncrement(&This->ref); | |
| TRACE("%p ref = %u\n", This, ref); | |
| return ref; | |
| } | |
| static ULONG WINAPI IRichEditOleImpl_inner_fnRelease(IUnknown *iface) | |
| { | |
| IRichEditOleImpl *This = impl_from_IUnknown(iface); | |
| ULONG ref = InterlockedDecrement(&This->ref); | |
| TRACE ("%p ref=%u\n", This, ref); | |
| if (!ref) | |
| { | |
| IOleClientSiteImpl *clientsite; | |
| ITextRangeImpl *txtRge; | |
| This->editor->reOle = NULL; | |
| if (This->txtSel) { | |
| This->txtSel->reOle = NULL; | |
| ITextSelection_Release(&This->txtSel->ITextSelection_iface); | |
| } | |
| LIST_FOR_EACH_ENTRY(txtRge, &This->rangelist, ITextRangeImpl, child.entry) | |
| txtRge->child.reole = NULL; | |
| LIST_FOR_EACH_ENTRY(clientsite, &This->clientsites, IOleClientSiteImpl, child.entry) | |
| clientsite->child.reole = NULL; | |
| heap_free(This); | |
| } | |
| return ref; | |
| } | |
| static const IUnknownVtbl reo_unk_vtbl = | |
| { | |
| IRichEditOleImpl_inner_fnQueryInterface, | |
| IRichEditOleImpl_inner_fnAddRef, | |
| IRichEditOleImpl_inner_fnRelease | |
| }; | |
| static HRESULT WINAPI | |
| IRichEditOle_fnQueryInterface(IRichEditOle *me, REFIID riid, LPVOID *ppvObj) | |
| { | |
| IRichEditOleImpl *This = impl_from_IRichEditOle(me); | |
| return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj); | |
| } | |
| static ULONG WINAPI | |
| IRichEditOle_fnAddRef(IRichEditOle *me) | |
| { | |
| IRichEditOleImpl *This = impl_from_IRichEditOle(me); | |
| return IUnknown_AddRef(This->outer_unk); | |
| } | |
| static ULONG WINAPI | |
| IRichEditOle_fnRelease(IRichEditOle *me) | |
| { | |
| IRichEditOleImpl *This = impl_from_IRichEditOle(me); | |
| return IUnknown_Release(This->outer_unk); | |
| } | |
| static HRESULT WINAPI | |
| IRichEditOle_fnActivateAs(IRichEditOle *me, REFCLSID rclsid, REFCLSID rclsidAs) | |
| { | |
| IRichEditOleImpl *This = impl_from_IRichEditOle(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI | |
| IRichEditOle_fnContextSensitiveHelp(IRichEditOle *me, BOOL fEnterMode) | |
| { | |
| IRichEditOleImpl *This = impl_from_IRichEditOle(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI | |
| IRichEditOle_fnConvertObject(IRichEditOle *me, LONG iob, | |
| REFCLSID rclsidNew, LPCSTR lpstrUserTypeNew) | |
| { | |
| IRichEditOleImpl *This = impl_from_IRichEditOle(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static inline IOleClientSiteImpl *impl_from_IOleClientSite(IOleClientSite *iface) | |
| { | |
| return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleClientSite_iface); | |
| } | |
| static HRESULT WINAPI | |
| IOleClientSite_fnQueryInterface(IOleClientSite *me, REFIID riid, LPVOID *ppvObj) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleClientSite(me); | |
| TRACE("%p %s\n", me, debugstr_guid(riid) ); | |
| *ppvObj = NULL; | |
| if (IsEqualGUID(riid, &IID_IUnknown) || | |
| IsEqualGUID(riid, &IID_IOleClientSite)) | |
| *ppvObj = me; | |
| else if (IsEqualGUID(riid, &IID_IOleWindow) || | |
| IsEqualGUID(riid, &IID_IOleInPlaceSite)) | |
| *ppvObj = &This->IOleInPlaceSite_iface; | |
| if (*ppvObj) | |
| { | |
| IOleClientSite_AddRef(me); | |
| return S_OK; | |
| } | |
| FIXME("%p: unhandled interface %s\n", me, debugstr_guid(riid) ); | |
| return E_NOINTERFACE; | |
| } | |
| static ULONG WINAPI IOleClientSite_fnAddRef(IOleClientSite *iface) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleClientSite(iface); | |
| ULONG ref = InterlockedIncrement(&This->ref); | |
| TRACE("(%p)->(%u)\n", This, ref); | |
| return ref; | |
| } | |
| static ULONG WINAPI IOleClientSite_fnRelease(IOleClientSite *iface) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleClientSite(iface); | |
| ULONG ref = InterlockedDecrement(&This->ref); | |
| TRACE("(%p)->(%u)\n", This, ref); | |
| if (ref == 0) { | |
| if (This->child.reole) { | |
| list_remove(&This->child.entry); | |
| This->child.reole = NULL; | |
| } | |
| heap_free(This); | |
| } | |
| return ref; | |
| } | |
| static HRESULT WINAPI IOleClientSite_fnSaveObject(IOleClientSite *iface) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleClientSite(iface); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| FIXME("stub %p\n", iface); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IOleClientSite_fnGetMoniker(IOleClientSite *iface, DWORD dwAssign, | |
| DWORD dwWhichMoniker, IMoniker **ppmk) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleClientSite(iface); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| FIXME("stub %p\n", iface); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IOleClientSite_fnGetContainer(IOleClientSite *iface, | |
| IOleContainer **ppContainer) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleClientSite(iface); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| FIXME("stub %p\n", iface); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IOleClientSite_fnShowObject(IOleClientSite *iface) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleClientSite(iface); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| FIXME("stub %p\n", iface); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IOleClientSite_fnOnShowWindow(IOleClientSite *iface, BOOL fShow) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleClientSite(iface); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| FIXME("stub %p\n", iface); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IOleClientSite_fnRequestNewObjectLayout(IOleClientSite *iface) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleClientSite(iface); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| FIXME("stub %p\n", iface); | |
| return E_NOTIMPL; | |
| } | |
| static const IOleClientSiteVtbl ocst = { | |
| IOleClientSite_fnQueryInterface, | |
| IOleClientSite_fnAddRef, | |
| IOleClientSite_fnRelease, | |
| IOleClientSite_fnSaveObject, | |
| IOleClientSite_fnGetMoniker, | |
| IOleClientSite_fnGetContainer, | |
| IOleClientSite_fnShowObject, | |
| IOleClientSite_fnOnShowWindow, | |
| IOleClientSite_fnRequestNewObjectLayout | |
| }; | |
| /* IOleInPlaceSite interface */ | |
| static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnQueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppvObj) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); | |
| return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppvObj); | |
| } | |
| static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnAddRef(IOleInPlaceSite *iface) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); | |
| return IOleClientSite_AddRef(&This->IOleClientSite_iface); | |
| } | |
| static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnRelease(IOleInPlaceSite *iface) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); | |
| return IOleClientSite_Release(&This->IOleClientSite_iface); | |
| } | |
| static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindow(IOleInPlaceSite *iface, HWND *phwnd) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); | |
| TRACE("(%p)->(%p)\n", This, phwnd); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| if (!phwnd) | |
| return E_INVALIDARG; | |
| *phwnd = This->child.reole->editor->hWnd; | |
| return S_OK; | |
| } | |
| static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); | |
| FIXME("not implemented: (%p)->(%d)\n", This, fEnterMode); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnCanInPlaceActivate(IOleInPlaceSite *iface) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); | |
| FIXME("not implemented: (%p)\n", This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceActivate(IOleInPlaceSite *iface) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); | |
| FIXME("not implemented: (%p)\n", This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIActivate(IOleInPlaceSite *iface) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); | |
| FIXME("not implemented: (%p)\n", This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindowContext(IOleInPlaceSite *iface, IOleInPlaceFrame **ppFrame, | |
| IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect, | |
| LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); | |
| FIXME("not implemented: (%p)->(%p %p %p %p %p)\n", This, ppFrame, ppDoc, lprcPosRect, lprcClipRect, lpFrameInfo); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnScroll(IOleInPlaceSite *iface, SIZE scrollExtent) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); | |
| FIXME("not implemented: (%p)\n", This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); | |
| FIXME("not implemented: (%p)->(%d)\n", This, fUndoable); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceDeactivate(IOleInPlaceSite *iface) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); | |
| FIXME("not implemented: (%p)\n", This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDiscardUndoState(IOleInPlaceSite *iface) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); | |
| FIXME("not implemented: (%p)\n", This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDeactivateAndUndo(IOleInPlaceSite *iface) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); | |
| FIXME("not implemented: (%p)\n", This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect) | |
| { | |
| IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); | |
| FIXME("not implemented: (%p)->(%p)\n", This, lprcPosRect); | |
| return E_NOTIMPL; | |
| } | |
| static const IOleInPlaceSiteVtbl olestvt = | |
| { | |
| IOleInPlaceSite_fnQueryInterface, | |
| IOleInPlaceSite_fnAddRef, | |
| IOleInPlaceSite_fnRelease, | |
| IOleInPlaceSite_fnGetWindow, | |
| IOleInPlaceSite_fnContextSensitiveHelp, | |
| IOleInPlaceSite_fnCanInPlaceActivate, | |
| IOleInPlaceSite_fnOnInPlaceActivate, | |
| IOleInPlaceSite_fnOnUIActivate, | |
| IOleInPlaceSite_fnGetWindowContext, | |
| IOleInPlaceSite_fnScroll, | |
| IOleInPlaceSite_fnOnUIDeactivate, | |
| IOleInPlaceSite_fnOnInPlaceDeactivate, | |
| IOleInPlaceSite_fnDiscardUndoState, | |
| IOleInPlaceSite_fnDeactivateAndUndo, | |
| IOleInPlaceSite_fnOnPosRectChange | |
| }; | |
| static HRESULT CreateOleClientSite(IRichEditOleImpl *reOle, IOleClientSite **ret) | |
| { | |
| IOleClientSiteImpl *clientSite = heap_alloc(sizeof *clientSite); | |
| if (!clientSite) | |
| return E_OUTOFMEMORY; | |
| clientSite->IOleClientSite_iface.lpVtbl = &ocst; | |
| clientSite->IOleInPlaceSite_iface.lpVtbl = &olestvt; | |
| clientSite->ref = 1; | |
| clientSite->child.reole = reOle; | |
| list_add_head(&reOle->clientsites, &clientSite->child.entry); | |
| *ret = &clientSite->IOleClientSite_iface; | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI | |
| IRichEditOle_fnGetClientSite(IRichEditOle *me, IOleClientSite **clientsite) | |
| { | |
| IRichEditOleImpl *This = impl_from_IRichEditOle(me); | |
| TRACE("(%p)->(%p)\n", This, clientsite); | |
| if (!clientsite) | |
| return E_INVALIDARG; | |
| return CreateOleClientSite(This, clientsite); | |
| } | |
| static HRESULT WINAPI | |
| IRichEditOle_fnGetClipboardData(IRichEditOle *me, CHARRANGE *lpchrg, | |
| DWORD reco, LPDATAOBJECT *lplpdataobj) | |
| { | |
| IRichEditOleImpl *This = impl_from_IRichEditOle(me); | |
| ME_Cursor start; | |
| int nChars; | |
| TRACE("(%p,%p,%d)\n",This, lpchrg, reco); | |
| if(!lplpdataobj) | |
| return E_INVALIDARG; | |
| if(!lpchrg) { | |
| int nFrom, nTo, nStartCur = ME_GetSelectionOfs(This->editor, &nFrom, &nTo); | |
| start = This->editor->pCursors[nStartCur]; | |
| nChars = nTo - nFrom; | |
| } else { | |
| ME_CursorFromCharOfs(This->editor, lpchrg->cpMin, &start); | |
| nChars = lpchrg->cpMax - lpchrg->cpMin; | |
| } | |
| return ME_GetDataObject(This->editor, &start, nChars, lplpdataobj); | |
| } | |
| static LONG WINAPI IRichEditOle_fnGetLinkCount(IRichEditOle *me) | |
| { | |
| IRichEditOleImpl *This = impl_from_IRichEditOle(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI | |
| IRichEditOle_fnGetObject(IRichEditOle *me, LONG iob, | |
| REOBJECT *lpreobject, DWORD dwFlags) | |
| { | |
| IRichEditOleImpl *This = impl_from_IRichEditOle(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static LONG WINAPI | |
| IRichEditOle_fnGetObjectCount(IRichEditOle *me) | |
| { | |
| IRichEditOleImpl *This = impl_from_IRichEditOle(me); | |
| FIXME("stub %p\n",This); | |
| return 0; | |
| } | |
| static HRESULT WINAPI | |
| IRichEditOle_fnHandsOffStorage(IRichEditOle *me, LONG iob) | |
| { | |
| IRichEditOleImpl *This = impl_from_IRichEditOle(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI | |
| IRichEditOle_fnImportDataObject(IRichEditOle *me, LPDATAOBJECT lpdataobj, | |
| CLIPFORMAT cf, HGLOBAL hMetaPict) | |
| { | |
| IRichEditOleImpl *This = impl_from_IRichEditOle(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI | |
| IRichEditOle_fnInPlaceDeactivate(IRichEditOle *me) | |
| { | |
| IRichEditOleImpl *This = impl_from_IRichEditOle(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI | |
| IRichEditOle_fnInsertObject(IRichEditOle *me, REOBJECT *reo) | |
| { | |
| IRichEditOleImpl *This = impl_from_IRichEditOle(me); | |
| TRACE("(%p,%p)\n", This, reo); | |
| if (!reo) | |
| return E_INVALIDARG; | |
| if (reo->cbStruct < sizeof(*reo)) return STG_E_INVALIDPARAMETER; | |
| ME_InsertOLEFromCursor(This->editor, reo, 0); | |
| ME_CommitUndo(This->editor); | |
| ME_UpdateRepaint(This->editor, FALSE); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI IRichEditOle_fnSaveCompleted(IRichEditOle *me, LONG iob, | |
| LPSTORAGE lpstg) | |
| { | |
| IRichEditOleImpl *This = impl_from_IRichEditOle(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI | |
| IRichEditOle_fnSetDvaspect(IRichEditOle *me, LONG iob, DWORD dvaspect) | |
| { | |
| IRichEditOleImpl *This = impl_from_IRichEditOle(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IRichEditOle_fnSetHostNames(IRichEditOle *me, | |
| LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj) | |
| { | |
| IRichEditOleImpl *This = impl_from_IRichEditOle(me); | |
| FIXME("stub %p %s %s\n",This, lpstrContainerApp, lpstrContainerObj); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI | |
| IRichEditOle_fnSetLinkAvailable(IRichEditOle *me, LONG iob, BOOL fAvailable) | |
| { | |
| IRichEditOleImpl *This = impl_from_IRichEditOle(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static const IRichEditOleVtbl revt = { | |
| IRichEditOle_fnQueryInterface, | |
| IRichEditOle_fnAddRef, | |
| IRichEditOle_fnRelease, | |
| IRichEditOle_fnGetClientSite, | |
| IRichEditOle_fnGetObjectCount, | |
| IRichEditOle_fnGetLinkCount, | |
| IRichEditOle_fnGetObject, | |
| IRichEditOle_fnInsertObject, | |
| IRichEditOle_fnConvertObject, | |
| IRichEditOle_fnActivateAs, | |
| IRichEditOle_fnSetHostNames, | |
| IRichEditOle_fnSetLinkAvailable, | |
| IRichEditOle_fnSetDvaspect, | |
| IRichEditOle_fnHandsOffStorage, | |
| IRichEditOle_fnSaveCompleted, | |
| IRichEditOle_fnInPlaceDeactivate, | |
| IRichEditOle_fnContextSensitiveHelp, | |
| IRichEditOle_fnGetClipboardData, | |
| IRichEditOle_fnImportDataObject | |
| }; | |
| /* ITextRange interface */ | |
| static HRESULT WINAPI ITextRange_fnQueryInterface(ITextRange *me, REFIID riid, void **ppvObj) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| *ppvObj = NULL; | |
| if (IsEqualGUID(riid, &IID_IUnknown) | |
| || IsEqualGUID(riid, &IID_IDispatch) | |
| || IsEqualGUID(riid, &IID_ITextRange)) | |
| { | |
| *ppvObj = me; | |
| ITextRange_AddRef(me); | |
| return S_OK; | |
| } | |
| else if (IsEqualGUID(riid, &IID_Igetrichole)) | |
| { | |
| *ppvObj = This->child.reole; | |
| return S_OK; | |
| } | |
| return E_NOINTERFACE; | |
| } | |
| static ULONG WINAPI ITextRange_fnAddRef(ITextRange *me) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| return InterlockedIncrement(&This->ref); | |
| } | |
| static ULONG WINAPI ITextRange_fnRelease(ITextRange *me) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| ULONG ref = InterlockedDecrement(&This->ref); | |
| TRACE ("%p ref=%u\n", This, ref); | |
| if (ref == 0) | |
| { | |
| if (This->child.reole) | |
| { | |
| list_remove(&This->child.entry); | |
| This->child.reole = NULL; | |
| } | |
| heap_free(This); | |
| } | |
| return ref; | |
| } | |
| static HRESULT WINAPI ITextRange_fnGetTypeInfoCount(ITextRange *me, UINT *pctinfo) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| TRACE("(%p)->(%p)\n", This, pctinfo); | |
| *pctinfo = 1; | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI ITextRange_fnGetTypeInfo(ITextRange *me, UINT iTInfo, LCID lcid, | |
| ITypeInfo **ppTInfo) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| HRESULT hr; | |
| TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo); | |
| hr = get_typeinfo(ITextRange_tid, ppTInfo); | |
| if (SUCCEEDED(hr)) | |
| ITypeInfo_AddRef(*ppTInfo); | |
| return hr; | |
| } | |
| static HRESULT WINAPI ITextRange_fnGetIDsOfNames(ITextRange *me, REFIID riid, LPOLESTR *rgszNames, | |
| UINT cNames, LCID lcid, DISPID *rgDispId) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| ITypeInfo *ti; | |
| HRESULT hr; | |
| TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, | |
| rgDispId); | |
| hr = get_typeinfo(ITextRange_tid, &ti); | |
| if (SUCCEEDED(hr)) | |
| hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId); | |
| return hr; | |
| } | |
| static HRESULT WINAPI ITextRange_fnInvoke(ITextRange *me, DISPID dispIdMember, REFIID riid, | |
| LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, | |
| VARIANT *pVarResult, EXCEPINFO *pExcepInfo, | |
| UINT *puArgErr) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| ITypeInfo *ti; | |
| HRESULT hr; | |
| TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid), | |
| lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); | |
| hr = get_typeinfo(ITextRange_tid, &ti); | |
| if (SUCCEEDED(hr)) | |
| hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); | |
| return hr; | |
| } | |
| static HRESULT WINAPI ITextRange_fnGetText(ITextRange *me, BSTR *str) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| ME_TextEditor *editor; | |
| ME_Cursor start, end; | |
| int length; | |
| BOOL bEOP; | |
| TRACE("(%p)->(%p)\n", This, str); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| if (!str) | |
| return E_INVALIDARG; | |
| /* return early for degenerate range */ | |
| if (This->start == This->end) { | |
| *str = NULL; | |
| return S_OK; | |
| } | |
| editor = This->child.reole->editor; | |
| ME_CursorFromCharOfs(editor, This->start, &start); | |
| ME_CursorFromCharOfs(editor, This->end, &end); | |
| length = This->end - This->start; | |
| *str = SysAllocStringLen(NULL, length); | |
| if (!*str) | |
| return E_OUTOFMEMORY; | |
| bEOP = (end.pRun->next->type == diTextEnd && This->end > ME_GetTextLength(editor)); | |
| ME_GetTextW(editor, *str, length, &start, length, FALSE, bEOP); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI ITextRange_fnSetText(ITextRange *me, BSTR str) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| ME_TextEditor *editor; | |
| ME_Cursor cursor; | |
| ME_Style *style; | |
| int len; | |
| TRACE("(%p)->(%s)\n", This, debugstr_w(str)); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| editor = This->child.reole->editor; | |
| /* delete only where's something to delete */ | |
| if (This->start != This->end) { | |
| ME_CursorFromCharOfs(editor, This->start, &cursor); | |
| ME_InternalDeleteText(editor, &cursor, This->end - This->start, FALSE); | |
| } | |
| if (!str || !*str) { | |
| /* will update this range as well */ | |
| textranges_update_ranges(This->child.reole, This->start, This->end, RANGE_UPDATE_DELETE); | |
| return S_OK; | |
| } | |
| /* it's safer not to rely on stored BSTR length */ | |
| len = strlenW(str); | |
| cursor = editor->pCursors[0]; | |
| ME_CursorFromCharOfs(editor, This->start, &editor->pCursors[0]); | |
| style = ME_GetInsertStyle(editor, 0); | |
| ME_InsertTextFromCursor(editor, 0, str, len, style); | |
| ME_ReleaseStyle(style); | |
| editor->pCursors[0] = cursor; | |
| if (len < This->end - This->start) | |
| textranges_update_ranges(This->child.reole, This->start + len, This->end, RANGE_UPDATE_DELETE); | |
| else | |
| This->end = len - This->start; | |
| return S_OK; | |
| } | |
| static HRESULT range_GetChar(ME_TextEditor *editor, ME_Cursor *cursor, LONG *pch) | |
| { | |
| WCHAR wch[2]; | |
| ME_GetTextW(editor, wch, 1, cursor, 1, FALSE, cursor->pRun->next->type == diTextEnd); | |
| *pch = wch[0]; | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI ITextRange_fnGetChar(ITextRange *me, LONG *pch) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| ME_TextEditor *editor; | |
| ME_Cursor cursor; | |
| TRACE("(%p)->(%p)\n", This, pch); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| if (!pch) | |
| return E_INVALIDARG; | |
| editor = This->child.reole->editor; | |
| ME_CursorFromCharOfs(editor, This->start, &cursor); | |
| return range_GetChar(editor, &cursor, pch); | |
| } | |
| static HRESULT WINAPI ITextRange_fnSetChar(ITextRange *me, LONG ch) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%x): stub\n", This, ch); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, ITextRange** ppRange); | |
| static HRESULT WINAPI ITextRange_fnGetDuplicate(ITextRange *me, ITextRange **ppRange) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| TRACE("(%p)->(%p)\n", This, ppRange); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| if (!ppRange) | |
| return E_INVALIDARG; | |
| return CreateITextRange(This->child.reole, This->start, This->end, ppRange); | |
| } | |
| static HRESULT WINAPI ITextRange_fnGetFormattedText(ITextRange *me, ITextRange **range) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%p): stub\n", This, range); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnSetFormattedText(ITextRange *me, ITextRange *range) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%p): stub\n", This, range); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnGetStart(ITextRange *me, LONG *start) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| TRACE("(%p)->(%p)\n", This, start); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| if (!start) | |
| return E_INVALIDARG; | |
| *start = This->start; | |
| return S_OK; | |
| } | |
| static HRESULT textrange_setstart(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end) | |
| { | |
| int len; | |
| if (value < 0) | |
| value = 0; | |
| if (value == *start) | |
| return S_FALSE; | |
| if (value <= *end) { | |
| *start = value; | |
| return S_OK; | |
| } | |
| len = ME_GetTextLength(reole->editor); | |
| *start = *end = value > len ? len : value; | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI ITextRange_fnSetStart(ITextRange *me, LONG value) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| TRACE("(%p)->(%d)\n", This, value); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return textrange_setstart(This->child.reole, value, &This->start, &This->end); | |
| } | |
| static HRESULT WINAPI ITextRange_fnGetEnd(ITextRange *me, LONG *end) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| TRACE("(%p)->(%p)\n", This, end); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| if (!end) | |
| return E_INVALIDARG; | |
| *end = This->end; | |
| return S_OK; | |
| } | |
| static HRESULT textrange_setend(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end) | |
| { | |
| int len; | |
| if (value == *end) | |
| return S_FALSE; | |
| if (value < *start) { | |
| *start = *end = max(0, value); | |
| return S_OK; | |
| } | |
| len = ME_GetTextLength(reole->editor); | |
| *end = value > len ? len + 1 : value; | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI ITextRange_fnSetEnd(ITextRange *me, LONG value) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| TRACE("(%p)->(%d)\n", This, value); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return textrange_setend(This->child.reole, value, &This->start, &This->end); | |
| } | |
| static HRESULT WINAPI ITextRange_fnGetFont(ITextRange *me, ITextFont **font) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| TRACE("(%p)->(%p)\n", This, font); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| if (!font) | |
| return E_INVALIDARG; | |
| return create_textfont(me, NULL, font); | |
| } | |
| static HRESULT WINAPI ITextRange_fnSetFont(ITextRange *me, ITextFont *font) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| TRACE("(%p)->(%p)\n", This, font); | |
| if (!font) | |
| return E_INVALIDARG; | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| textrange_set_font(me, font); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI ITextRange_fnGetPara(ITextRange *me, ITextPara **para) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| TRACE("(%p)->(%p)\n", This, para); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| if (!para) | |
| return E_INVALIDARG; | |
| return create_textpara(me, para); | |
| } | |
| static HRESULT WINAPI ITextRange_fnSetPara(ITextRange *me, ITextPara *para) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%p): stub\n", This, para); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnGetStoryLength(ITextRange *me, LONG *length) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| TRACE("(%p)->(%p)\n", This, length); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return textrange_get_storylength(This->child.reole->editor, length); | |
| } | |
| static HRESULT WINAPI ITextRange_fnGetStoryType(ITextRange *me, LONG *value) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| if (!value) | |
| return E_INVALIDARG; | |
| *value = tomUnknownStory; | |
| return S_OK; | |
| } | |
| static HRESULT range_Collapse(LONG bStart, LONG *start, LONG *end) | |
| { | |
| if (*end == *start) | |
| return S_FALSE; | |
| if (bStart == tomEnd) | |
| *start = *end; | |
| else | |
| *end = *start; | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI ITextRange_fnCollapse(ITextRange *me, LONG bStart) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| TRACE("(%p)->(%d)\n", This, bStart); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return range_Collapse(bStart, &This->start, &This->end); | |
| } | |
| static HRESULT WINAPI ITextRange_fnExpand(ITextRange *me, LONG unit, LONG *delta) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| TRACE("(%p)->(%d %p)\n", This, unit, delta); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return textrange_expand(me, unit, delta); | |
| } | |
| static HRESULT WINAPI ITextRange_fnGetIndex(ITextRange *me, LONG unit, LONG *index) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%d %p): stub\n", This, unit, index); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnSetIndex(ITextRange *me, LONG unit, LONG index, | |
| LONG extend) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnSetRange(ITextRange *me, LONG anchor, LONG active) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%d %d): stub\n", This, anchor, active); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT textrange_inrange(LONG start, LONG end, ITextRange *range, LONG *ret) | |
| { | |
| LONG from, to, v; | |
| if (!ret) | |
| ret = &v; | |
| if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) { | |
| *ret = tomFalse; | |
| } | |
| else | |
| *ret = (start >= from && end <= to) ? tomTrue : tomFalse; | |
| return *ret == tomTrue ? S_OK : S_FALSE; | |
| } | |
| static HRESULT WINAPI ITextRange_fnInRange(ITextRange *me, ITextRange *range, LONG *ret) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| TRACE("(%p)->(%p %p)\n", This, range, ret); | |
| if (ret) | |
| *ret = tomFalse; | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| if (!range) | |
| return S_FALSE; | |
| return textrange_inrange(This->start, This->end, range, ret); | |
| } | |
| static HRESULT WINAPI ITextRange_fnInStory(ITextRange *me, ITextRange *pRange, LONG *ret) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%p): stub\n", This, ret); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT textrange_isequal(LONG start, LONG end, ITextRange *range, LONG *ret) | |
| { | |
| LONG from, to, v; | |
| if (!ret) | |
| ret = &v; | |
| if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) { | |
| *ret = tomFalse; | |
| } | |
| else | |
| *ret = (start == from && end == to) ? tomTrue : tomFalse; | |
| return *ret == tomTrue ? S_OK : S_FALSE; | |
| } | |
| static HRESULT WINAPI ITextRange_fnIsEqual(ITextRange *me, ITextRange *range, LONG *ret) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| TRACE("(%p)->(%p %p)\n", This, range, ret); | |
| if (ret) | |
| *ret = tomFalse; | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| if (!range) | |
| return S_FALSE; | |
| return textrange_isequal(This->start, This->end, range, ret); | |
| } | |
| static HRESULT WINAPI ITextRange_fnSelect(ITextRange *me) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| TRACE("(%p)\n", This); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| ME_SetSelection(This->child.reole->editor, This->start, This->end); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI ITextRange_fnStartOf(ITextRange *me, LONG unit, LONG extend, | |
| LONG *delta) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnEndOf(ITextRange *me, LONG unit, LONG extend, | |
| LONG *delta) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnMove(ITextRange *me, LONG unit, LONG count, LONG *delta) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnMoveStart(ITextRange *me, LONG unit, LONG count, | |
| LONG *delta) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnMoveEnd(ITextRange *me, LONG unit, LONG count, | |
| LONG *delta) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnMoveWhile(ITextRange *me, VARIANT *charset, LONG count, | |
| LONG *delta) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnMoveStartWhile(ITextRange *me, VARIANT *charset, LONG count, | |
| LONG *delta) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnMoveEndWhile(ITextRange *me, VARIANT *charset, LONG count, | |
| LONG *delta) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnMoveUntil(ITextRange *me, VARIANT *charset, LONG count, | |
| LONG *delta) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnMoveStartUntil(ITextRange *me, VARIANT *charset, LONG count, | |
| LONG *delta) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnMoveEndUntil(ITextRange *me, VARIANT *charset, LONG count, | |
| LONG *delta) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnFindText(ITextRange *me, BSTR text, LONG count, LONG flags, | |
| LONG *length) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnFindTextStart(ITextRange *me, BSTR text, LONG count, | |
| LONG flags, LONG *length) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnFindTextEnd(ITextRange *me, BSTR text, LONG count, | |
| LONG flags, LONG *length) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnDelete(ITextRange *me, LONG unit, LONG count, LONG *delta) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnCut(ITextRange *me, VARIANT *v) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%p): stub\n", This, v); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnCopy(ITextRange *me, VARIANT *v) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%p): stub\n", This, v); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnPaste(ITextRange *me, VARIANT *v, LONG format) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnCanPaste(ITextRange *me, VARIANT *v, LONG format, LONG *ret) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnCanEdit(ITextRange *me, LONG *ret) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%p): stub\n", This, ret); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnChangeCase(ITextRange *me, LONG type) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%d): stub\n", This, type); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnGetPoint(ITextRange *me, LONG type, LONG *cx, LONG *cy) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnSetPoint(ITextRange *me, LONG x, LONG y, LONG type, | |
| LONG extend) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextRange_fnScrollIntoView(ITextRange *me, LONG value) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| ME_TextEditor *editor; | |
| ME_Cursor cursor; | |
| int x, y, height; | |
| TRACE("(%p)->(%d)\n", This, value); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| editor = This->child.reole->editor; | |
| switch (value) | |
| { | |
| case tomStart: | |
| ME_CursorFromCharOfs(editor, This->start, &cursor); | |
| ME_GetCursorCoordinates(editor, &cursor, &x, &y, &height); | |
| break; | |
| default: | |
| FIXME("bStart value %d not handled\n", value); | |
| return E_NOTIMPL; | |
| } | |
| ME_ScrollAbs(editor, x, y); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI ITextRange_fnGetEmbeddedObject(ITextRange *me, IUnknown **ppv) | |
| { | |
| ITextRangeImpl *This = impl_from_ITextRange(me); | |
| FIXME("(%p)->(%p): stub\n", This, ppv); | |
| if (!This->child.reole) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static const ITextRangeVtbl trvt = { | |
| ITextRange_fnQueryInterface, | |
| ITextRange_fnAddRef, | |
| ITextRange_fnRelease, | |
| ITextRange_fnGetTypeInfoCount, | |
| ITextRange_fnGetTypeInfo, | |
| ITextRange_fnGetIDsOfNames, | |
| ITextRange_fnInvoke, | |
| ITextRange_fnGetText, | |
| ITextRange_fnSetText, | |
| ITextRange_fnGetChar, | |
| ITextRange_fnSetChar, | |
| ITextRange_fnGetDuplicate, | |
| ITextRange_fnGetFormattedText, | |
| ITextRange_fnSetFormattedText, | |
| ITextRange_fnGetStart, | |
| ITextRange_fnSetStart, | |
| ITextRange_fnGetEnd, | |
| ITextRange_fnSetEnd, | |
| ITextRange_fnGetFont, | |
| ITextRange_fnSetFont, | |
| ITextRange_fnGetPara, | |
| ITextRange_fnSetPara, | |
| ITextRange_fnGetStoryLength, | |
| ITextRange_fnGetStoryType, | |
| ITextRange_fnCollapse, | |
| ITextRange_fnExpand, | |
| ITextRange_fnGetIndex, | |
| ITextRange_fnSetIndex, | |
| ITextRange_fnSetRange, | |
| ITextRange_fnInRange, | |
| ITextRange_fnInStory, | |
| ITextRange_fnIsEqual, | |
| ITextRange_fnSelect, | |
| ITextRange_fnStartOf, | |
| ITextRange_fnEndOf, | |
| ITextRange_fnMove, | |
| ITextRange_fnMoveStart, | |
| ITextRange_fnMoveEnd, | |
| ITextRange_fnMoveWhile, | |
| ITextRange_fnMoveStartWhile, | |
| ITextRange_fnMoveEndWhile, | |
| ITextRange_fnMoveUntil, | |
| ITextRange_fnMoveStartUntil, | |
| ITextRange_fnMoveEndUntil, | |
| ITextRange_fnFindText, | |
| ITextRange_fnFindTextStart, | |
| ITextRange_fnFindTextEnd, | |
| ITextRange_fnDelete, | |
| ITextRange_fnCut, | |
| ITextRange_fnCopy, | |
| ITextRange_fnPaste, | |
| ITextRange_fnCanPaste, | |
| ITextRange_fnCanEdit, | |
| ITextRange_fnChangeCase, | |
| ITextRange_fnGetPoint, | |
| ITextRange_fnSetPoint, | |
| ITextRange_fnScrollIntoView, | |
| ITextRange_fnGetEmbeddedObject | |
| }; | |
| /* ITextFont */ | |
| static HRESULT WINAPI TextFont_QueryInterface(ITextFont *iface, REFIID riid, void **ppv) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); | |
| if (IsEqualIID(riid, &IID_ITextFont) || | |
| IsEqualIID(riid, &IID_IDispatch) || | |
| IsEqualIID(riid, &IID_IUnknown)) | |
| { | |
| *ppv = iface; | |
| ITextFont_AddRef(iface); | |
| return S_OK; | |
| } | |
| *ppv = NULL; | |
| return E_NOINTERFACE; | |
| } | |
| static ULONG WINAPI TextFont_AddRef(ITextFont *iface) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| ULONG ref = InterlockedIncrement(&This->ref); | |
| TRACE("(%p)->(%u)\n", This, ref); | |
| return ref; | |
| } | |
| static ULONG WINAPI TextFont_Release(ITextFont *iface) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| ULONG ref = InterlockedDecrement(&This->ref); | |
| TRACE("(%p)->(%u)\n", This, ref); | |
| if (!ref) | |
| { | |
| if (This->range) | |
| ITextRange_Release(This->range); | |
| SysFreeString(This->props[FONT_NAME].str); | |
| heap_free(This); | |
| } | |
| return ref; | |
| } | |
| static HRESULT WINAPI TextFont_GetTypeInfoCount(ITextFont *iface, UINT *pctinfo) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, pctinfo); | |
| *pctinfo = 1; | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI TextFont_GetTypeInfo(ITextFont *iface, UINT iTInfo, LCID lcid, | |
| ITypeInfo **ppTInfo) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| HRESULT hr; | |
| TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo); | |
| hr = get_typeinfo(ITextFont_tid, ppTInfo); | |
| if (SUCCEEDED(hr)) | |
| ITypeInfo_AddRef(*ppTInfo); | |
| return hr; | |
| } | |
| static HRESULT WINAPI TextFont_GetIDsOfNames(ITextFont *iface, REFIID riid, | |
| LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| ITypeInfo *ti; | |
| HRESULT hr; | |
| TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), | |
| rgszNames, cNames, lcid, rgDispId); | |
| hr = get_typeinfo(ITextFont_tid, &ti); | |
| if (SUCCEEDED(hr)) | |
| hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId); | |
| return hr; | |
| } | |
| static HRESULT WINAPI TextFont_Invoke( | |
| ITextFont *iface, | |
| DISPID dispIdMember, | |
| REFIID riid, | |
| LCID lcid, | |
| WORD wFlags, | |
| DISPPARAMS *pDispParams, | |
| VARIANT *pVarResult, | |
| EXCEPINFO *pExcepInfo, | |
| UINT *puArgErr) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| ITypeInfo *ti; | |
| HRESULT hr; | |
| TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid), | |
| lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); | |
| hr = get_typeinfo(ITextFont_tid, &ti); | |
| if (SUCCEEDED(hr)) | |
| hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); | |
| return hr; | |
| } | |
| static HRESULT WINAPI TextFont_GetDuplicate(ITextFont *iface, ITextFont **ret) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, ret); | |
| if (!ret) | |
| return E_INVALIDARG; | |
| *ret = NULL; | |
| if (This->range && !get_range_reole(This->range)) | |
| return CO_E_RELEASED; | |
| return create_textfont(NULL, This, ret); | |
| } | |
| static HRESULT WINAPI TextFont_SetDuplicate(ITextFont *iface, ITextFont *pFont) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| FIXME("(%p)->(%p): stub\n", This, pFont); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextFont_CanChange(ITextFont *iface, LONG *ret) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| FIXME("(%p)->(%p): stub\n", This, ret); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextFont_IsEqual(ITextFont *iface, ITextFont *font, LONG *ret) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| FIXME("(%p)->(%p %p): stub\n", This, font, ret); | |
| return E_NOTIMPL; | |
| } | |
| static void textfont_reset_to_default(ITextFontImpl *font) | |
| { | |
| enum textfont_prop_id id; | |
| for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) { | |
| switch (id) | |
| { | |
| case FONT_ALLCAPS: | |
| case FONT_ANIMATION: | |
| case FONT_BOLD: | |
| case FONT_EMBOSS: | |
| case FONT_HIDDEN: | |
| case FONT_ENGRAVE: | |
| case FONT_ITALIC: | |
| case FONT_OUTLINE: | |
| case FONT_PROTECTED: | |
| case FONT_SHADOW: | |
| case FONT_SMALLCAPS: | |
| case FONT_STRIKETHROUGH: | |
| case FONT_SUBSCRIPT: | |
| case FONT_SUPERSCRIPT: | |
| case FONT_UNDERLINE: | |
| font->props[id].l = tomFalse; | |
| break; | |
| case FONT_BACKCOLOR: | |
| case FONT_FORECOLOR: | |
| font->props[id].l = tomAutoColor; | |
| break; | |
| case FONT_KERNING: | |
| case FONT_POSITION: | |
| case FONT_SIZE: | |
| case FONT_SPACING: | |
| font->props[id].f = 0.0; | |
| break; | |
| case FONT_LANGID: | |
| font->props[id].l = GetSystemDefaultLCID(); | |
| break; | |
| case FONT_NAME: { | |
| static const WCHAR sysW[] = {'S','y','s','t','e','m',0}; | |
| SysFreeString(font->props[id].str); | |
| font->props[id].str = SysAllocString(sysW); | |
| break; | |
| } | |
| case FONT_WEIGHT: | |
| font->props[id].l = FW_NORMAL; | |
| break; | |
| default: | |
| FIXME("font property %d not handled\n", id); | |
| } | |
| } | |
| } | |
| static void textfont_reset_to_undefined(ITextFontImpl *font) | |
| { | |
| enum textfont_prop_id id; | |
| for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) { | |
| switch (id) | |
| { | |
| case FONT_ALLCAPS: | |
| case FONT_ANIMATION: | |
| case FONT_BOLD: | |
| case FONT_EMBOSS: | |
| case FONT_HIDDEN: | |
| case FONT_ENGRAVE: | |
| case FONT_ITALIC: | |
| case FONT_OUTLINE: | |
| case FONT_PROTECTED: | |
| case FONT_SHADOW: | |
| case FONT_SMALLCAPS: | |
| case FONT_STRIKETHROUGH: | |
| case FONT_SUBSCRIPT: | |
| case FONT_SUPERSCRIPT: | |
| case FONT_UNDERLINE: | |
| case FONT_BACKCOLOR: | |
| case FONT_FORECOLOR: | |
| case FONT_LANGID: | |
| case FONT_WEIGHT: | |
| font->props[id].l = tomUndefined; | |
| break; | |
| case FONT_KERNING: | |
| case FONT_POSITION: | |
| case FONT_SIZE: | |
| case FONT_SPACING: | |
| font->props[id].f = tomUndefined; | |
| break; | |
| case FONT_NAME: | |
| break; | |
| default: | |
| FIXME("font property %d not handled\n", id); | |
| } | |
| } | |
| } | |
| static void textfont_apply_range_props(ITextFontImpl *font) | |
| { | |
| enum textfont_prop_id propid; | |
| for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++) | |
| set_textfont_prop(font, propid, &font->props[propid]); | |
| } | |
| static HRESULT WINAPI TextFont_Reset(ITextFont *iface, LONG value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%d)\n", This, value); | |
| /* If font is attached to a range, released or not, we can't | |
| reset to undefined */ | |
| if (This->range) { | |
| if (!get_range_reole(This->range)) | |
| return CO_E_RELEASED; | |
| switch (value) | |
| { | |
| case tomUndefined: | |
| return E_INVALIDARG; | |
| case tomCacheParms: | |
| textfont_cache_range_props(This); | |
| This->get_cache_enabled = TRUE; | |
| break; | |
| case tomTrackParms: | |
| This->get_cache_enabled = FALSE; | |
| break; | |
| case tomApplyLater: | |
| This->set_cache_enabled = TRUE; | |
| break; | |
| case tomApplyNow: | |
| This->set_cache_enabled = FALSE; | |
| textfont_apply_range_props(This); | |
| break; | |
| case tomUsePoints: | |
| case tomUseTwips: | |
| return E_INVALIDARG; | |
| default: | |
| FIXME("reset mode %d not supported\n", value); | |
| } | |
| return S_OK; | |
| } | |
| else { | |
| switch (value) | |
| { | |
| /* reset to global defaults */ | |
| case tomDefault: | |
| textfont_reset_to_default(This); | |
| return S_OK; | |
| /* all properties are set to tomUndefined, font name is retained */ | |
| case tomUndefined: | |
| textfont_reset_to_undefined(This); | |
| return S_OK; | |
| case tomApplyNow: | |
| case tomApplyLater: | |
| case tomTrackParms: | |
| case tomCacheParms: | |
| return S_OK; | |
| case tomUsePoints: | |
| case tomUseTwips: | |
| return E_INVALIDARG; | |
| } | |
| } | |
| FIXME("reset mode %d not supported\n", value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextFont_GetStyle(ITextFont *iface, LONG *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| FIXME("(%p)->(%p): stub\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextFont_SetStyle(ITextFont *iface, LONG value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| FIXME("(%p)->(%d): stub\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextFont_GetAllCaps(ITextFont *iface, LONG *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| return get_textfont_propl(This, FONT_ALLCAPS, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetAllCaps(ITextFont *iface, LONG value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%d)\n", This, value); | |
| return set_textfont_propd(This, FONT_ALLCAPS, value); | |
| } | |
| static HRESULT WINAPI TextFont_GetAnimation(ITextFont *iface, LONG *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| return get_textfont_propl(This, FONT_ANIMATION, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetAnimation(ITextFont *iface, LONG value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%d)\n", This, value); | |
| if (value < tomNoAnimation || value > tomAnimationMax) | |
| return E_INVALIDARG; | |
| return set_textfont_propl(This, FONT_ANIMATION, value); | |
| } | |
| static HRESULT WINAPI TextFont_GetBackColor(ITextFont *iface, LONG *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| return get_textfont_propl(This, FONT_BACKCOLOR, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetBackColor(ITextFont *iface, LONG value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%d)\n", This, value); | |
| return set_textfont_propl(This, FONT_BACKCOLOR, value); | |
| } | |
| static HRESULT WINAPI TextFont_GetBold(ITextFont *iface, LONG *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| return get_textfont_propl(This, FONT_BOLD, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetBold(ITextFont *iface, LONG value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%d)\n", This, value); | |
| return set_textfont_propd(This, FONT_BOLD, value); | |
| } | |
| static HRESULT WINAPI TextFont_GetEmboss(ITextFont *iface, LONG *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| return get_textfont_propl(This, FONT_EMBOSS, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetEmboss(ITextFont *iface, LONG value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%d)\n", This, value); | |
| return set_textfont_propd(This, FONT_EMBOSS, value); | |
| } | |
| static HRESULT WINAPI TextFont_GetForeColor(ITextFont *iface, LONG *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| return get_textfont_propl(This, FONT_FORECOLOR, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetForeColor(ITextFont *iface, LONG value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%d)\n", This, value); | |
| return set_textfont_propl(This, FONT_FORECOLOR, value); | |
| } | |
| static HRESULT WINAPI TextFont_GetHidden(ITextFont *iface, LONG *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| return get_textfont_propl(This, FONT_HIDDEN, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetHidden(ITextFont *iface, LONG value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%d)\n", This, value); | |
| return set_textfont_propd(This, FONT_HIDDEN, value); | |
| } | |
| static HRESULT WINAPI TextFont_GetEngrave(ITextFont *iface, LONG *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| return get_textfont_propl(This, FONT_ENGRAVE, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetEngrave(ITextFont *iface, LONG value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%d)\n", This, value); | |
| return set_textfont_propd(This, FONT_ENGRAVE, value); | |
| } | |
| static HRESULT WINAPI TextFont_GetItalic(ITextFont *iface, LONG *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| return get_textfont_propl(This, FONT_ITALIC, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetItalic(ITextFont *iface, LONG value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%d)\n", This, value); | |
| return set_textfont_propd(This, FONT_ITALIC, value); | |
| } | |
| static HRESULT WINAPI TextFont_GetKerning(ITextFont *iface, FLOAT *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| return get_textfont_propf(This, FONT_KERNING, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetKerning(ITextFont *iface, FLOAT value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%.2f)\n", This, value); | |
| return set_textfont_propf(This, FONT_KERNING, value); | |
| } | |
| static HRESULT WINAPI TextFont_GetLanguageID(ITextFont *iface, LONG *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| return get_textfont_propl(This, FONT_LANGID, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetLanguageID(ITextFont *iface, LONG value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%d)\n", This, value); | |
| return set_textfont_propl(This, FONT_LANGID, value); | |
| } | |
| static HRESULT WINAPI TextFont_GetName(ITextFont *iface, BSTR *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| if (!value) | |
| return E_INVALIDARG; | |
| *value = NULL; | |
| if (!This->range) { | |
| if (This->props[FONT_NAME].str) | |
| *value = SysAllocString(This->props[FONT_NAME].str); | |
| else | |
| *value = SysAllocStringLen(NULL, 0); | |
| return *value ? S_OK : E_OUTOFMEMORY; | |
| } | |
| return textfont_getname_from_range(This->range, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetName(ITextFont *iface, BSTR value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| textfont_prop_val v; | |
| TRACE("(%p)->(%s)\n", This, debugstr_w(value)); | |
| v.str = value; | |
| return set_textfont_prop(This, FONT_NAME, &v); | |
| } | |
| static HRESULT WINAPI TextFont_GetOutline(ITextFont *iface, LONG *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| return get_textfont_propl(This, FONT_OUTLINE, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetOutline(ITextFont *iface, LONG value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%d)\n", This, value); | |
| return set_textfont_propd(This, FONT_OUTLINE, value); | |
| } | |
| static HRESULT WINAPI TextFont_GetPosition(ITextFont *iface, FLOAT *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| return get_textfont_propf(This, FONT_POSITION, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetPosition(ITextFont *iface, FLOAT value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%.2f)\n", This, value); | |
| return set_textfont_propf(This, FONT_POSITION, value); | |
| } | |
| static HRESULT WINAPI TextFont_GetProtected(ITextFont *iface, LONG *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| return get_textfont_propl(This, FONT_PROTECTED, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetProtected(ITextFont *iface, LONG value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%d)\n", This, value); | |
| return set_textfont_propd(This, FONT_PROTECTED, value); | |
| } | |
| static HRESULT WINAPI TextFont_GetShadow(ITextFont *iface, LONG *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| return get_textfont_propl(This, FONT_SHADOW, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetShadow(ITextFont *iface, LONG value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%d)\n", This, value); | |
| return set_textfont_propd(This, FONT_SHADOW, value); | |
| } | |
| static HRESULT WINAPI TextFont_GetSize(ITextFont *iface, FLOAT *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| return get_textfont_propf(This, FONT_SIZE, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetSize(ITextFont *iface, FLOAT value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%.2f)\n", This, value); | |
| return set_textfont_propf(This, FONT_SIZE, value); | |
| } | |
| static HRESULT WINAPI TextFont_GetSmallCaps(ITextFont *iface, LONG *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| return get_textfont_propl(This, FONT_SMALLCAPS, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetSmallCaps(ITextFont *iface, LONG value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%d)\n", This, value); | |
| return set_textfont_propd(This, FONT_SMALLCAPS, value); | |
| } | |
| static HRESULT WINAPI TextFont_GetSpacing(ITextFont *iface, FLOAT *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| return get_textfont_propf(This, FONT_SPACING, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetSpacing(ITextFont *iface, FLOAT value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%.2f)\n", This, value); | |
| return set_textfont_propf(This, FONT_SPACING, value); | |
| } | |
| static HRESULT WINAPI TextFont_GetStrikeThrough(ITextFont *iface, LONG *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| return get_textfont_propl(This, FONT_STRIKETHROUGH, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetStrikeThrough(ITextFont *iface, LONG value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%d)\n", This, value); | |
| return set_textfont_propd(This, FONT_STRIKETHROUGH, value); | |
| } | |
| static HRESULT WINAPI TextFont_GetSubscript(ITextFont *iface, LONG *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| return get_textfont_propl(This, FONT_SUBSCRIPT, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetSubscript(ITextFont *iface, LONG value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%d)\n", This, value); | |
| return set_textfont_propd(This, FONT_SUBSCRIPT, value); | |
| } | |
| static HRESULT WINAPI TextFont_GetSuperscript(ITextFont *iface, LONG *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| return get_textfont_propl(This, FONT_SUPERSCRIPT, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetSuperscript(ITextFont *iface, LONG value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%d)\n", This, value); | |
| return set_textfont_propd(This, FONT_SUPERSCRIPT, value); | |
| } | |
| static HRESULT WINAPI TextFont_GetUnderline(ITextFont *iface, LONG *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| return get_textfont_propl(This, FONT_UNDERLINE, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetUnderline(ITextFont *iface, LONG value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%d)\n", This, value); | |
| return set_textfont_propd(This, FONT_UNDERLINE, value); | |
| } | |
| static HRESULT WINAPI TextFont_GetWeight(ITextFont *iface, LONG *value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| return get_textfont_propl(This, FONT_WEIGHT, value); | |
| } | |
| static HRESULT WINAPI TextFont_SetWeight(ITextFont *iface, LONG value) | |
| { | |
| ITextFontImpl *This = impl_from_ITextFont(iface); | |
| TRACE("(%p)->(%d)\n", This, value); | |
| return set_textfont_propl(This, FONT_WEIGHT, value); | |
| } | |
| static ITextFontVtbl textfontvtbl = { | |
| TextFont_QueryInterface, | |
| TextFont_AddRef, | |
| TextFont_Release, | |
| TextFont_GetTypeInfoCount, | |
| TextFont_GetTypeInfo, | |
| TextFont_GetIDsOfNames, | |
| TextFont_Invoke, | |
| TextFont_GetDuplicate, | |
| TextFont_SetDuplicate, | |
| TextFont_CanChange, | |
| TextFont_IsEqual, | |
| TextFont_Reset, | |
| TextFont_GetStyle, | |
| TextFont_SetStyle, | |
| TextFont_GetAllCaps, | |
| TextFont_SetAllCaps, | |
| TextFont_GetAnimation, | |
| TextFont_SetAnimation, | |
| TextFont_GetBackColor, | |
| TextFont_SetBackColor, | |
| TextFont_GetBold, | |
| TextFont_SetBold, | |
| TextFont_GetEmboss, | |
| TextFont_SetEmboss, | |
| TextFont_GetForeColor, | |
| TextFont_SetForeColor, | |
| TextFont_GetHidden, | |
| TextFont_SetHidden, | |
| TextFont_GetEngrave, | |
| TextFont_SetEngrave, | |
| TextFont_GetItalic, | |
| TextFont_SetItalic, | |
| TextFont_GetKerning, | |
| TextFont_SetKerning, | |
| TextFont_GetLanguageID, | |
| TextFont_SetLanguageID, | |
| TextFont_GetName, | |
| TextFont_SetName, | |
| TextFont_GetOutline, | |
| TextFont_SetOutline, | |
| TextFont_GetPosition, | |
| TextFont_SetPosition, | |
| TextFont_GetProtected, | |
| TextFont_SetProtected, | |
| TextFont_GetShadow, | |
| TextFont_SetShadow, | |
| TextFont_GetSize, | |
| TextFont_SetSize, | |
| TextFont_GetSmallCaps, | |
| TextFont_SetSmallCaps, | |
| TextFont_GetSpacing, | |
| TextFont_SetSpacing, | |
| TextFont_GetStrikeThrough, | |
| TextFont_SetStrikeThrough, | |
| TextFont_GetSubscript, | |
| TextFont_SetSubscript, | |
| TextFont_GetSuperscript, | |
| TextFont_SetSuperscript, | |
| TextFont_GetUnderline, | |
| TextFont_SetUnderline, | |
| TextFont_GetWeight, | |
| TextFont_SetWeight | |
| }; | |
| static HRESULT create_textfont(ITextRange *range, const ITextFontImpl *src, ITextFont **ret) | |
| { | |
| ITextFontImpl *font; | |
| *ret = NULL; | |
| font = heap_alloc(sizeof(*font)); | |
| if (!font) | |
| return E_OUTOFMEMORY; | |
| font->ITextFont_iface.lpVtbl = &textfontvtbl; | |
| font->ref = 1; | |
| if (src) { | |
| font->range = NULL; | |
| font->get_cache_enabled = TRUE; | |
| font->set_cache_enabled = TRUE; | |
| memcpy(&font->props, &src->props, sizeof(font->props)); | |
| if (font->props[FONT_NAME].str) | |
| font->props[FONT_NAME].str = SysAllocString(font->props[FONT_NAME].str); | |
| } | |
| else { | |
| font->range = range; | |
| ITextRange_AddRef(range); | |
| /* cache current properties */ | |
| font->get_cache_enabled = FALSE; | |
| font->set_cache_enabled = FALSE; | |
| textfont_cache_range_props(font); | |
| } | |
| *ret = &font->ITextFont_iface; | |
| return S_OK; | |
| } | |
| /* ITextPara */ | |
| static HRESULT WINAPI TextPara_QueryInterface(ITextPara *iface, REFIID riid, void **ppv) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); | |
| if (IsEqualIID(riid, &IID_ITextPara) || | |
| IsEqualIID(riid, &IID_IDispatch) || | |
| IsEqualIID(riid, &IID_IUnknown)) | |
| { | |
| *ppv = iface; | |
| ITextPara_AddRef(iface); | |
| return S_OK; | |
| } | |
| *ppv = NULL; | |
| return E_NOINTERFACE; | |
| } | |
| static ULONG WINAPI TextPara_AddRef(ITextPara *iface) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| ULONG ref = InterlockedIncrement(&This->ref); | |
| TRACE("(%p)->(%u)\n", This, ref); | |
| return ref; | |
| } | |
| static ULONG WINAPI TextPara_Release(ITextPara *iface) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| ULONG ref = InterlockedDecrement(&This->ref); | |
| TRACE("(%p)->(%u)\n", This, ref); | |
| if (!ref) | |
| { | |
| ITextRange_Release(This->range); | |
| heap_free(This); | |
| } | |
| return ref; | |
| } | |
| static HRESULT WINAPI TextPara_GetTypeInfoCount(ITextPara *iface, UINT *pctinfo) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| TRACE("(%p)->(%p)\n", This, pctinfo); | |
| *pctinfo = 1; | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI TextPara_GetTypeInfo(ITextPara *iface, UINT iTInfo, LCID lcid, | |
| ITypeInfo **ppTInfo) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| HRESULT hr; | |
| TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo); | |
| hr = get_typeinfo(ITextPara_tid, ppTInfo); | |
| if (SUCCEEDED(hr)) | |
| ITypeInfo_AddRef(*ppTInfo); | |
| return hr; | |
| } | |
| static HRESULT WINAPI TextPara_GetIDsOfNames(ITextPara *iface, REFIID riid, | |
| LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| ITypeInfo *ti; | |
| HRESULT hr; | |
| TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, | |
| cNames, lcid, rgDispId); | |
| hr = get_typeinfo(ITextPara_tid, &ti); | |
| if (SUCCEEDED(hr)) | |
| hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId); | |
| return hr; | |
| } | |
| static HRESULT WINAPI TextPara_Invoke( | |
| ITextPara *iface, | |
| DISPID dispIdMember, | |
| REFIID riid, | |
| LCID lcid, | |
| WORD wFlags, | |
| DISPPARAMS *pDispParams, | |
| VARIANT *pVarResult, | |
| EXCEPINFO *pExcepInfo, | |
| UINT *puArgErr) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| ITypeInfo *ti; | |
| HRESULT hr; | |
| TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, | |
| debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, | |
| pExcepInfo, puArgErr); | |
| hr = get_typeinfo(ITextPara_tid, &ti); | |
| if (SUCCEEDED(hr)) | |
| hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); | |
| return hr; | |
| } | |
| static HRESULT WINAPI TextPara_GetDuplicate(ITextPara *iface, ITextPara **ret) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, ret); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_SetDuplicate(ITextPara *iface, ITextPara *para) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, para); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_CanChange(ITextPara *iface, LONG *ret) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, ret); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_IsEqual(ITextPara *iface, ITextPara *para, LONG *ret) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p %p)\n", This, para, ret); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_Reset(ITextPara *iface, LONG value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%d)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_GetStyle(ITextPara *iface, LONG *value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_SetStyle(ITextPara *iface, LONG value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%d)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_GetAlignment(ITextPara *iface, LONG *value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_SetAlignment(ITextPara *iface, LONG value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%d)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_GetHyphenation(ITextPara *iface, LONG *value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_SetHyphenation(ITextPara *iface, LONG value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%d)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_GetFirstLineIndent(ITextPara *iface, FLOAT *value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_GetKeepTogether(ITextPara *iface, LONG *value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_SetKeepTogether(ITextPara *iface, LONG value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%d)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_GetKeepWithNext(ITextPara *iface, LONG *value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_SetKeepWithNext(ITextPara *iface, LONG value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%d)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_GetLeftIndent(ITextPara *iface, FLOAT *value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_GetLineSpacing(ITextPara *iface, FLOAT *value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_GetLineSpacingRule(ITextPara *iface, LONG *value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_GetListAlignment(ITextPara *iface, LONG *value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_SetListAlignment(ITextPara *iface, LONG value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%d)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_GetListLevelIndex(ITextPara *iface, LONG *value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_SetListLevelIndex(ITextPara *iface, LONG value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%d)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_GetListStart(ITextPara *iface, LONG *value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_SetListStart(ITextPara *iface, LONG value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%d)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_GetListTab(ITextPara *iface, FLOAT *value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_SetListTab(ITextPara *iface, FLOAT value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%.2f)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_GetListType(ITextPara *iface, LONG *value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_SetListType(ITextPara *iface, LONG value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%d)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_GetNoLineNumber(ITextPara *iface, LONG *value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_SetNoLineNumber(ITextPara *iface, LONG value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%d)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_GetPageBreakBefore(ITextPara *iface, LONG *value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_SetPageBreakBefore(ITextPara *iface, LONG value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%d)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_GetRightIndent(ITextPara *iface, FLOAT *value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_SetRightIndent(ITextPara *iface, FLOAT value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%.2f)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_SetIndents(ITextPara *iface, FLOAT StartIndent, FLOAT LeftIndent, FLOAT RightIndent) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%.2f %.2f %.2f)\n", This, StartIndent, LeftIndent, RightIndent); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_SetLineSpacing(ITextPara *iface, LONG LineSpacingRule, FLOAT LineSpacing) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%d %.2f)\n", This, LineSpacingRule, LineSpacing); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_GetSpaceAfter(ITextPara *iface, FLOAT *value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_SetSpaceAfter(ITextPara *iface, FLOAT value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%.2f)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_GetSpaceBefore(ITextPara *iface, FLOAT *value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_SetSpaceBefore(ITextPara *iface, FLOAT value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%.2f)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_GetWidowControl(ITextPara *iface, LONG *value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_SetWidowControl(ITextPara *iface, LONG value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%d)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_GetTabCount(ITextPara *iface, LONG *value) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%p)\n", This, value); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_AddTab(ITextPara *iface, FLOAT tbPos, LONG tbAlign, LONG tbLeader) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%.2f %d %d)\n", This, tbPos, tbAlign, tbLeader); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_ClearAllTabs(ITextPara *iface) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)\n", This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_DeleteTab(ITextPara *iface, FLOAT pos) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%.2f)\n", This, pos); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI TextPara_GetTab(ITextPara *iface, LONG iTab, FLOAT *ptbPos, LONG *ptbAlign, LONG *ptbLeader) | |
| { | |
| ITextParaImpl *This = impl_from_ITextPara(iface); | |
| FIXME("(%p)->(%d %p %p %p)\n", This, iTab, ptbPos, ptbAlign, ptbLeader); | |
| return E_NOTIMPL; | |
| } | |
| static ITextParaVtbl textparavtbl = { | |
| TextPara_QueryInterface, | |
| TextPara_AddRef, | |
| TextPara_Release, | |
| TextPara_GetTypeInfoCount, | |
| TextPara_GetTypeInfo, | |
| TextPara_GetIDsOfNames, | |
| TextPara_Invoke, | |
| TextPara_GetDuplicate, | |
| TextPara_SetDuplicate, | |
| TextPara_CanChange, | |
| TextPara_IsEqual, | |
| TextPara_Reset, | |
| TextPara_GetStyle, | |
| TextPara_SetStyle, | |
| TextPara_GetAlignment, | |
| TextPara_SetAlignment, | |
| TextPara_GetHyphenation, | |
| TextPara_SetHyphenation, | |
| TextPara_GetFirstLineIndent, | |
| TextPara_GetKeepTogether, | |
| TextPara_SetKeepTogether, | |
| TextPara_GetKeepWithNext, | |
| TextPara_SetKeepWithNext, | |
| TextPara_GetLeftIndent, | |
| TextPara_GetLineSpacing, | |
| TextPara_GetLineSpacingRule, | |
| TextPara_GetListAlignment, | |
| TextPara_SetListAlignment, | |
| TextPara_GetListLevelIndex, | |
| TextPara_SetListLevelIndex, | |
| TextPara_GetListStart, | |
| TextPara_SetListStart, | |
| TextPara_GetListTab, | |
| TextPara_SetListTab, | |
| TextPara_GetListType, | |
| TextPara_SetListType, | |
| TextPara_GetNoLineNumber, | |
| TextPara_SetNoLineNumber, | |
| TextPara_GetPageBreakBefore, | |
| TextPara_SetPageBreakBefore, | |
| TextPara_GetRightIndent, | |
| TextPara_SetRightIndent, | |
| TextPara_SetIndents, | |
| TextPara_SetLineSpacing, | |
| TextPara_GetSpaceAfter, | |
| TextPara_SetSpaceAfter, | |
| TextPara_GetSpaceBefore, | |
| TextPara_SetSpaceBefore, | |
| TextPara_GetWidowControl, | |
| TextPara_SetWidowControl, | |
| TextPara_GetTabCount, | |
| TextPara_AddTab, | |
| TextPara_ClearAllTabs, | |
| TextPara_DeleteTab, | |
| TextPara_GetTab | |
| }; | |
| static HRESULT create_textpara(ITextRange *range, ITextPara **ret) | |
| { | |
| ITextParaImpl *para; | |
| *ret = NULL; | |
| para = heap_alloc(sizeof(*para)); | |
| if (!para) | |
| return E_OUTOFMEMORY; | |
| para->ITextPara_iface.lpVtbl = &textparavtbl; | |
| para->ref = 1; | |
| para->range = range; | |
| ITextRange_AddRef(range); | |
| *ret = ¶->ITextPara_iface; | |
| return S_OK; | |
| } | |
| /* ITextDocument */ | |
| static HRESULT WINAPI | |
| ITextDocument_fnQueryInterface(ITextDocument* me, REFIID riid, | |
| void** ppvObject) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| return IRichEditOle_QueryInterface(&This->IRichEditOle_iface, riid, ppvObject); | |
| } | |
| static ULONG WINAPI | |
| ITextDocument_fnAddRef(ITextDocument* me) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| return IRichEditOle_AddRef(&This->IRichEditOle_iface); | |
| } | |
| static ULONG WINAPI | |
| ITextDocument_fnRelease(ITextDocument* me) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| return IRichEditOle_Release(&This->IRichEditOle_iface); | |
| } | |
| static HRESULT WINAPI | |
| ITextDocument_fnGetTypeInfoCount(ITextDocument* me, | |
| UINT* pctinfo) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| TRACE("(%p)->(%p)\n", This, pctinfo); | |
| *pctinfo = 1; | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI | |
| ITextDocument_fnGetTypeInfo(ITextDocument* me, UINT iTInfo, LCID lcid, | |
| ITypeInfo** ppTInfo) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| HRESULT hr; | |
| TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo); | |
| hr = get_typeinfo(ITextDocument_tid, ppTInfo); | |
| if (SUCCEEDED(hr)) | |
| ITypeInfo_AddRef(*ppTInfo); | |
| return hr; | |
| } | |
| static HRESULT WINAPI | |
| ITextDocument_fnGetIDsOfNames(ITextDocument* me, REFIID riid, | |
| LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| ITypeInfo *ti; | |
| HRESULT hr; | |
| TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), | |
| rgszNames, cNames, lcid, rgDispId); | |
| hr = get_typeinfo(ITextDocument_tid, &ti); | |
| if (SUCCEEDED(hr)) | |
| hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId); | |
| return hr; | |
| } | |
| static HRESULT WINAPI | |
| ITextDocument_fnInvoke(ITextDocument* me, DISPID dispIdMember, | |
| REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, | |
| VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| ITypeInfo *ti; | |
| HRESULT hr; | |
| TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, | |
| debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, | |
| pExcepInfo, puArgErr); | |
| hr = get_typeinfo(ITextDocument_tid, &ti); | |
| if (SUCCEEDED(hr)) | |
| hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); | |
| return hr; | |
| } | |
| static HRESULT WINAPI | |
| ITextDocument_fnGetName(ITextDocument* me, BSTR* pName) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI | |
| ITextDocument_fnGetSelection(ITextDocument *me, ITextSelection **selection) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| TRACE("(%p)->(%p)\n", me, selection); | |
| if (!selection) | |
| return E_INVALIDARG; | |
| if (!This->txtSel) { | |
| This->txtSel = CreateTextSelection(This); | |
| if (!This->txtSel) { | |
| *selection = NULL; | |
| return E_OUTOFMEMORY; | |
| } | |
| } | |
| *selection = &This->txtSel->ITextSelection_iface; | |
| ITextSelection_AddRef(*selection); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI | |
| ITextDocument_fnGetStoryCount(ITextDocument* me, LONG* pCount) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI | |
| ITextDocument_fnGetStoryRanges(ITextDocument* me, | |
| ITextStoryRanges** ppStories) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI | |
| ITextDocument_fnGetSaved(ITextDocument* me, LONG* pValue) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI | |
| ITextDocument_fnSetSaved(ITextDocument* me, LONG Value) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI | |
| ITextDocument_fnGetDefaultTabStop(ITextDocument* me, float* pValue) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI | |
| ITextDocument_fnSetDefaultTabStop(ITextDocument* me, float Value) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI | |
| ITextDocument_fnNew(ITextDocument* me) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI | |
| ITextDocument_fnOpen(ITextDocument* me, VARIANT* pVar, LONG Flags, | |
| LONG CodePage) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI | |
| ITextDocument_fnSave(ITextDocument* me, VARIANT* pVar, LONG Flags, | |
| LONG CodePage) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI | |
| ITextDocument_fnFreeze(ITextDocument* me, LONG* pCount) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI | |
| ITextDocument_fnUnfreeze(ITextDocument* me, LONG* pCount) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI | |
| ITextDocument_fnBeginEditCollection(ITextDocument* me) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI | |
| ITextDocument_fnEndEditCollection(ITextDocument* me) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI | |
| ITextDocument_fnUndo(ITextDocument* me, LONG Count, LONG* prop) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI | |
| ITextDocument_fnRedo(ITextDocument* me, LONG Count, LONG* prop) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, ITextRange** ppRange) | |
| { | |
| ITextRangeImpl *txtRge = heap_alloc(sizeof(ITextRangeImpl)); | |
| if (!txtRge) | |
| return E_OUTOFMEMORY; | |
| txtRge->ITextRange_iface.lpVtbl = &trvt; | |
| txtRge->ref = 1; | |
| txtRge->child.reole = reOle; | |
| txtRge->start = start; | |
| txtRge->end = end; | |
| list_add_head(&reOle->rangelist, &txtRge->child.entry); | |
| *ppRange = &txtRge->ITextRange_iface; | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI | |
| ITextDocument_fnRange(ITextDocument* me, LONG cp1, LONG cp2, | |
| ITextRange** ppRange) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| const int len = ME_GetTextLength(This->editor) + 1; | |
| TRACE("%p %p %d %d\n", This, ppRange, cp1, cp2); | |
| if (!ppRange) | |
| return E_INVALIDARG; | |
| cp1 = max(cp1, 0); | |
| cp2 = max(cp2, 0); | |
| cp1 = min(cp1, len); | |
| cp2 = min(cp2, len); | |
| if (cp1 > cp2) | |
| { | |
| LONG tmp; | |
| tmp = cp1; | |
| cp1 = cp2; | |
| cp2 = tmp; | |
| } | |
| if (cp1 == len) | |
| cp1 = cp2 = len - 1; | |
| return CreateITextRange(This, cp1, cp2, ppRange); | |
| } | |
| static HRESULT WINAPI | |
| ITextDocument_fnRangeFromPoint(ITextDocument* me, LONG x, LONG y, | |
| ITextRange** ppRange) | |
| { | |
| IRichEditOleImpl *This = impl_from_ITextDocument(me); | |
| FIXME("stub %p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static const ITextDocumentVtbl tdvt = { | |
| ITextDocument_fnQueryInterface, | |
| ITextDocument_fnAddRef, | |
| ITextDocument_fnRelease, | |
| ITextDocument_fnGetTypeInfoCount, | |
| ITextDocument_fnGetTypeInfo, | |
| ITextDocument_fnGetIDsOfNames, | |
| ITextDocument_fnInvoke, | |
| ITextDocument_fnGetName, | |
| ITextDocument_fnGetSelection, | |
| ITextDocument_fnGetStoryCount, | |
| ITextDocument_fnGetStoryRanges, | |
| ITextDocument_fnGetSaved, | |
| ITextDocument_fnSetSaved, | |
| ITextDocument_fnGetDefaultTabStop, | |
| ITextDocument_fnSetDefaultTabStop, | |
| ITextDocument_fnNew, | |
| ITextDocument_fnOpen, | |
| ITextDocument_fnSave, | |
| ITextDocument_fnFreeze, | |
| ITextDocument_fnUnfreeze, | |
| ITextDocument_fnBeginEditCollection, | |
| ITextDocument_fnEndEditCollection, | |
| ITextDocument_fnUndo, | |
| ITextDocument_fnRedo, | |
| ITextDocument_fnRange, | |
| ITextDocument_fnRangeFromPoint | |
| }; | |
| /* ITextSelection */ | |
| static HRESULT WINAPI ITextSelection_fnQueryInterface( | |
| ITextSelection *me, | |
| REFIID riid, | |
| void **ppvObj) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| *ppvObj = NULL; | |
| if (IsEqualGUID(riid, &IID_IUnknown) | |
| || IsEqualGUID(riid, &IID_IDispatch) | |
| || IsEqualGUID(riid, &IID_ITextRange) | |
| || IsEqualGUID(riid, &IID_ITextSelection)) | |
| { | |
| *ppvObj = me; | |
| ITextSelection_AddRef(me); | |
| return S_OK; | |
| } | |
| else if (IsEqualGUID(riid, &IID_Igetrichole)) | |
| { | |
| *ppvObj = This->reOle; | |
| return S_OK; | |
| } | |
| return E_NOINTERFACE; | |
| } | |
| static ULONG WINAPI ITextSelection_fnAddRef(ITextSelection *me) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| return InterlockedIncrement(&This->ref); | |
| } | |
| static ULONG WINAPI ITextSelection_fnRelease(ITextSelection *me) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| ULONG ref = InterlockedDecrement(&This->ref); | |
| if (ref == 0) | |
| heap_free(This); | |
| return ref; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnGetTypeInfoCount(ITextSelection *me, UINT *pctinfo) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| TRACE("(%p)->(%p)\n", This, pctinfo); | |
| *pctinfo = 1; | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnGetTypeInfo(ITextSelection *me, UINT iTInfo, LCID lcid, | |
| ITypeInfo **ppTInfo) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| HRESULT hr; | |
| TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo); | |
| hr = get_typeinfo(ITextSelection_tid, ppTInfo); | |
| if (SUCCEEDED(hr)) | |
| ITypeInfo_AddRef(*ppTInfo); | |
| return hr; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnGetIDsOfNames(ITextSelection *me, REFIID riid, | |
| LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| ITypeInfo *ti; | |
| HRESULT hr; | |
| TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, | |
| rgDispId); | |
| hr = get_typeinfo(ITextSelection_tid, &ti); | |
| if (SUCCEEDED(hr)) | |
| hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId); | |
| return hr; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnInvoke( | |
| ITextSelection *me, | |
| DISPID dispIdMember, | |
| REFIID riid, | |
| LCID lcid, | |
| WORD wFlags, | |
| DISPPARAMS *pDispParams, | |
| VARIANT *pVarResult, | |
| EXCEPINFO *pExcepInfo, | |
| UINT *puArgErr) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| ITypeInfo *ti; | |
| HRESULT hr; | |
| TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid), lcid, | |
| wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); | |
| hr = get_typeinfo(ITextSelection_tid, &ti); | |
| if (SUCCEEDED(hr)) | |
| hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); | |
| return hr; | |
| } | |
| /*** ITextRange methods ***/ | |
| static HRESULT WINAPI ITextSelection_fnGetText(ITextSelection *me, BSTR *pbstr) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| ME_Cursor *start = NULL, *end = NULL; | |
| int nChars, endOfs; | |
| BOOL bEOP; | |
| TRACE("(%p)->(%p)\n", This, pbstr); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| if (!pbstr) | |
| return E_INVALIDARG; | |
| ME_GetSelection(This->reOle->editor, &start, &end); | |
| endOfs = ME_GetCursorOfs(end); | |
| nChars = endOfs - ME_GetCursorOfs(start); | |
| if (!nChars) | |
| { | |
| *pbstr = NULL; | |
| return S_OK; | |
| } | |
| *pbstr = SysAllocStringLen(NULL, nChars); | |
| if (!*pbstr) | |
| return E_OUTOFMEMORY; | |
| bEOP = (end->pRun->next->type == diTextEnd && endOfs > ME_GetTextLength(This->reOle->editor)); | |
| ME_GetTextW(This->reOle->editor, *pbstr, nChars, start, nChars, FALSE, bEOP); | |
| TRACE("%s\n", wine_dbgstr_w(*pbstr)); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnSetText(ITextSelection *me, BSTR str) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| ME_TextEditor *editor; | |
| int len, to, from; | |
| TRACE("(%p)->(%s)\n", This, debugstr_w(str)); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| editor = This->reOle->editor; | |
| len = strlenW(str); | |
| ME_GetSelectionOfs(editor, &from, &to); | |
| ME_ReplaceSel(editor, FALSE, str, len); | |
| if (len < to - from) | |
| textranges_update_ranges(This->reOle, from, len, RANGE_UPDATE_DELETE); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnGetChar(ITextSelection *me, LONG *pch) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| ME_Cursor *start = NULL, *end = NULL; | |
| TRACE("(%p)->(%p)\n", This, pch); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| if (!pch) | |
| return E_INVALIDARG; | |
| ME_GetSelection(This->reOle->editor, &start, &end); | |
| return range_GetChar(This->reOle->editor, start, pch); | |
| } | |
| static HRESULT WINAPI ITextSelection_fnSetChar(ITextSelection *me, LONG ch) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%x): stub\n", This, ch); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnGetDuplicate(ITextSelection *me, ITextRange **range) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| LONG start, end; | |
| TRACE("(%p)->(%p)\n", This, range); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| if (!range) | |
| return E_INVALIDARG; | |
| ITextSelection_GetStart(me, &start); | |
| ITextSelection_GetEnd(me, &end); | |
| return CreateITextRange(This->reOle, start, end, range); | |
| } | |
| static HRESULT WINAPI ITextSelection_fnGetFormattedText(ITextSelection *me, ITextRange **range) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%p): stub\n", This, range); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnSetFormattedText(ITextSelection *me, ITextRange *range) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%p): stub\n", This, range); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| FIXME("not implemented\n"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnGetStart(ITextSelection *me, LONG *pcpFirst) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| LONG lim; | |
| TRACE("(%p)->(%p)\n", This, pcpFirst); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| if (!pcpFirst) | |
| return E_INVALIDARG; | |
| ME_GetSelectionOfs(This->reOle->editor, pcpFirst, &lim); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnSetStart(ITextSelection *me, LONG value) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| LONG start, end; | |
| HRESULT hr; | |
| TRACE("(%p)->(%d)\n", This, value); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| ME_GetSelectionOfs(This->reOle->editor, &start, &end); | |
| hr = textrange_setstart(This->reOle, value, &start, &end); | |
| if (hr == S_OK) | |
| ME_SetSelection(This->reOle->editor, start, end); | |
| return hr; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnGetEnd(ITextSelection *me, LONG *pcpLim) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| LONG first; | |
| TRACE("(%p)->(%p)\n", This, pcpLim); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| if (!pcpLim) | |
| return E_INVALIDARG; | |
| ME_GetSelectionOfs(This->reOle->editor, &first, pcpLim); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnSetEnd(ITextSelection *me, LONG value) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| LONG start, end; | |
| HRESULT hr; | |
| TRACE("(%p)->(%d)\n", This, value); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| ME_GetSelectionOfs(This->reOle->editor, &start, &end); | |
| hr = textrange_setend(This->reOle, value, &start, &end); | |
| if (hr == S_OK) | |
| ME_SetSelection(This->reOle->editor, start, end); | |
| return hr; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **font) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| TRACE("(%p)->(%p)\n", This, font); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| if (!font) | |
| return E_INVALIDARG; | |
| return create_textfont((ITextRange*)me, NULL, font); | |
| } | |
| static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *font) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| TRACE("(%p)->(%p)\n", This, font); | |
| if (!font) | |
| return E_INVALIDARG; | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| textrange_set_font((ITextRange*)me, font); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnGetPara(ITextSelection *me, ITextPara **para) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| TRACE("(%p)->(%p)\n", This, para); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| if (!para) | |
| return E_INVALIDARG; | |
| return create_textpara((ITextRange*)me, para); | |
| } | |
| static HRESULT WINAPI ITextSelection_fnSetPara(ITextSelection *me, ITextPara *para) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%p): stub\n", This, para); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| FIXME("not implemented\n"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnGetStoryLength(ITextSelection *me, LONG *length) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| TRACE("(%p)->(%p)\n", This, length); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return textrange_get_storylength(This->reOle->editor, length); | |
| } | |
| static HRESULT WINAPI ITextSelection_fnGetStoryType(ITextSelection *me, LONG *value) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| TRACE("(%p)->(%p)\n", This, value); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| if (!value) | |
| return E_INVALIDARG; | |
| *value = tomUnknownStory; | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnCollapse(ITextSelection *me, LONG bStart) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| LONG start, end; | |
| HRESULT hres; | |
| TRACE("(%p)->(%d)\n", This, bStart); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| ME_GetSelectionOfs(This->reOle->editor, &start, &end); | |
| hres = range_Collapse(bStart, &start, &end); | |
| if (SUCCEEDED(hres)) | |
| ME_SetSelection(This->reOle->editor, start, end); | |
| return hres; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnExpand(ITextSelection *me, LONG unit, LONG *delta) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| TRACE("(%p)->(%d %p)\n", This, unit, delta); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return textrange_expand((ITextRange*)me, unit, delta); | |
| } | |
| static HRESULT WINAPI ITextSelection_fnGetIndex(ITextSelection *me, LONG unit, LONG *index) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%d %p): stub\n", This, unit, index); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnSetIndex(ITextSelection *me, LONG unit, LONG index, | |
| LONG extend) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnSetRange(ITextSelection *me, LONG anchor, LONG active) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%d %d): stub\n", This, anchor, active); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnInRange(ITextSelection *me, ITextRange *range, LONG *ret) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| ITextSelection *selection = NULL; | |
| LONG start, end; | |
| TRACE("(%p)->(%p %p)\n", This, range, ret); | |
| if (ret) | |
| *ret = tomFalse; | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| if (!range) | |
| return S_FALSE; | |
| ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection); | |
| if (!selection) | |
| return S_FALSE; | |
| ITextSelection_Release(selection); | |
| ITextSelection_GetStart(me, &start); | |
| ITextSelection_GetEnd(me, &end); | |
| return textrange_inrange(start, end, range, ret); | |
| } | |
| static HRESULT WINAPI ITextSelection_fnInStory(ITextSelection *me, ITextRange *range, LONG *ret) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%p %p): stub\n", This, range, ret); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnIsEqual(ITextSelection *me, ITextRange *range, LONG *ret) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| ITextSelection *selection = NULL; | |
| LONG start, end; | |
| TRACE("(%p)->(%p %p)\n", This, range, ret); | |
| if (ret) | |
| *ret = tomFalse; | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| if (!range) | |
| return S_FALSE; | |
| ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection); | |
| if (!selection) | |
| return S_FALSE; | |
| ITextSelection_Release(selection); | |
| ITextSelection_GetStart(me, &start); | |
| ITextSelection_GetEnd(me, &end); | |
| return textrange_isequal(start, end, range, ret); | |
| } | |
| static HRESULT WINAPI ITextSelection_fnSelect(ITextSelection *me) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| TRACE("(%p)\n", This); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| /* nothing to do */ | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnStartOf(ITextSelection *me, LONG unit, LONG extend, | |
| LONG *delta) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnEndOf(ITextSelection *me, LONG unit, LONG extend, | |
| LONG *delta) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnMove(ITextSelection *me, LONG unit, LONG count, LONG *delta) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnMoveStart(ITextSelection *me, LONG unit, LONG count, | |
| LONG *delta) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnMoveEnd(ITextSelection *me, LONG unit, LONG count, | |
| LONG *delta) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnMoveWhile(ITextSelection *me, VARIANT *charset, LONG count, | |
| LONG *delta) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnMoveStartWhile(ITextSelection *me, VARIANT *charset, LONG count, | |
| LONG *delta) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnMoveEndWhile(ITextSelection *me, VARIANT *charset, LONG count, | |
| LONG *delta) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnMoveUntil(ITextSelection *me, VARIANT *charset, LONG count, | |
| LONG *delta) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnMoveStartUntil(ITextSelection *me, VARIANT *charset, LONG count, | |
| LONG *delta) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnMoveEndUntil(ITextSelection *me, VARIANT *charset, LONG count, | |
| LONG *delta) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnFindText(ITextSelection *me, BSTR text, LONG count, LONG flags, | |
| LONG *length) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| FIXME("not implemented\n"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnFindTextStart(ITextSelection *me, BSTR text, LONG count, | |
| LONG flags, LONG *length) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnFindTextEnd(ITextSelection *me, BSTR text, LONG count, | |
| LONG flags, LONG *length) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnDelete(ITextSelection *me, LONG unit, LONG count, | |
| LONG *delta) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnCut(ITextSelection *me, VARIANT *v) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%p): stub\n", This, v); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnCopy(ITextSelection *me, VARIANT *v) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%p): stub\n", This, v); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnPaste(ITextSelection *me, VARIANT *v, LONG format) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnCanPaste(ITextSelection *me, VARIANT *v, LONG format, | |
| LONG *ret) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnCanEdit(ITextSelection *me, LONG *ret) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%p): stub\n", This, ret); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnChangeCase(ITextSelection *me, LONG type) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%d): stub\n", This, type); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnGetPoint(ITextSelection *me, LONG type, LONG *cx, LONG *cy) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnSetPoint(ITextSelection *me, LONG x, LONG y, LONG type, | |
| LONG extend) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnScrollIntoView(ITextSelection *me, LONG value) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%d): stub\n", This, value); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnGetEmbeddedObject(ITextSelection *me, IUnknown **ppv) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%p): stub\n", This, ppv); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| /*** ITextSelection methods ***/ | |
| static HRESULT WINAPI ITextSelection_fnGetFlags(ITextSelection *me, LONG *flags) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%p): stub\n", This, flags); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnSetFlags(ITextSelection *me, LONG flags) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%x): stub\n", This, flags); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnGetType(ITextSelection *me, LONG *type) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%p): stub\n", This, type); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnMoveLeft(ITextSelection *me, LONG unit, LONG count, | |
| LONG extend, LONG *delta) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnMoveRight(ITextSelection *me, LONG unit, LONG count, | |
| LONG extend, LONG *delta) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnMoveUp(ITextSelection *me, LONG unit, LONG count, | |
| LONG extend, LONG *delta) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnMoveDown(ITextSelection *me, LONG unit, LONG count, | |
| LONG extend, LONG *delta) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnHomeKey(ITextSelection *me, LONG unit, LONG extend, | |
| LONG *delta) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnEndKey(ITextSelection *me, LONG unit, LONG extend, | |
| LONG *delta) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ITextSelection_fnTypeText(ITextSelection *me, BSTR text) | |
| { | |
| ITextSelectionImpl *This = impl_from_ITextSelection(me); | |
| FIXME("(%p)->(%s): stub\n", This, debugstr_w(text)); | |
| if (!This->reOle) | |
| return CO_E_RELEASED; | |
| return E_NOTIMPL; | |
| } | |
| static const ITextSelectionVtbl tsvt = { | |
| ITextSelection_fnQueryInterface, | |
| ITextSelection_fnAddRef, | |
| ITextSelection_fnRelease, | |
| ITextSelection_fnGetTypeInfoCount, | |
| ITextSelection_fnGetTypeInfo, | |
| ITextSelection_fnGetIDsOfNames, | |
| ITextSelection_fnInvoke, | |
| ITextSelection_fnGetText, | |
| ITextSelection_fnSetText, | |
| ITextSelection_fnGetChar, | |
| ITextSelection_fnSetChar, | |
| ITextSelection_fnGetDuplicate, | |
| ITextSelection_fnGetFormattedText, | |
| ITextSelection_fnSetFormattedText, | |
| ITextSelection_fnGetStart, | |
| ITextSelection_fnSetStart, | |
| ITextSelection_fnGetEnd, | |
| ITextSelection_fnSetEnd, | |
| ITextSelection_fnGetFont, | |
| ITextSelection_fnSetFont, | |
| ITextSelection_fnGetPara, | |
| ITextSelection_fnSetPara, | |
| ITextSelection_fnGetStoryLength, | |
| ITextSelection_fnGetStoryType, | |
| ITextSelection_fnCollapse, | |
| ITextSelection_fnExpand, | |
| ITextSelection_fnGetIndex, | |
| ITextSelection_fnSetIndex, | |
| ITextSelection_fnSetRange, | |
| ITextSelection_fnInRange, | |
| ITextSelection_fnInStory, | |
| ITextSelection_fnIsEqual, | |
| ITextSelection_fnSelect, | |
| ITextSelection_fnStartOf, | |
| ITextSelection_fnEndOf, | |
| ITextSelection_fnMove, | |
| ITextSelection_fnMoveStart, | |
| ITextSelection_fnMoveEnd, | |
| ITextSelection_fnMoveWhile, | |
| ITextSelection_fnMoveStartWhile, | |
| ITextSelection_fnMoveEndWhile, | |
| ITextSelection_fnMoveUntil, | |
| ITextSelection_fnMoveStartUntil, | |
| ITextSelection_fnMoveEndUntil, | |
| ITextSelection_fnFindText, | |
| ITextSelection_fnFindTextStart, | |
| ITextSelection_fnFindTextEnd, | |
| ITextSelection_fnDelete, | |
| ITextSelection_fnCut, | |
| ITextSelection_fnCopy, | |
| ITextSelection_fnPaste, | |
| ITextSelection_fnCanPaste, | |
| ITextSelection_fnCanEdit, | |
| ITextSelection_fnChangeCase, | |
| ITextSelection_fnGetPoint, | |
| ITextSelection_fnSetPoint, | |
| ITextSelection_fnScrollIntoView, | |
| ITextSelection_fnGetEmbeddedObject, | |
| ITextSelection_fnGetFlags, | |
| ITextSelection_fnSetFlags, | |
| ITextSelection_fnGetType, | |
| ITextSelection_fnMoveLeft, | |
| ITextSelection_fnMoveRight, | |
| ITextSelection_fnMoveUp, | |
| ITextSelection_fnMoveDown, | |
| ITextSelection_fnHomeKey, | |
| ITextSelection_fnEndKey, | |
| ITextSelection_fnTypeText | |
| }; | |
| static ITextSelectionImpl * | |
| CreateTextSelection(IRichEditOleImpl *reOle) | |
| { | |
| ITextSelectionImpl *txtSel = heap_alloc(sizeof *txtSel); | |
| if (!txtSel) | |
| return NULL; | |
| txtSel->ITextSelection_iface.lpVtbl = &tsvt; | |
| txtSel->ref = 1; | |
| txtSel->reOle = reOle; | |
| return txtSel; | |
| } | |
| LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *ppvObj) | |
| { | |
| IRichEditOleImpl *reo; | |
| reo = heap_alloc(sizeof(IRichEditOleImpl)); | |
| if (!reo) | |
| return 0; | |
| reo->IUnknown_inner.lpVtbl = &reo_unk_vtbl; | |
| reo->IRichEditOle_iface.lpVtbl = &revt; | |
| reo->ITextDocument_iface.lpVtbl = &tdvt; | |
| reo->ref = 1; | |
| reo->editor = editor; | |
| reo->txtSel = NULL; | |
| TRACE("Created %p\n",reo); | |
| list_init(&reo->rangelist); | |
| list_init(&reo->clientsites); | |
| if (outer_unk) | |
| reo->outer_unk = outer_unk; | |
| else | |
| reo->outer_unk = &reo->IUnknown_inner; | |
| *ppvObj = &reo->IRichEditOle_iface; | |
| return 1; | |
| } | |
| static void convert_sizel(const ME_Context *c, const SIZEL* szl, SIZE* sz) | |
| { | |
| /* sizel is in .01 millimeters, sz in pixels */ | |
| sz->cx = MulDiv(szl->cx, c->dpi.cx, 2540); | |
| sz->cy = MulDiv(szl->cy, c->dpi.cy, 2540); | |
| } | |
| /****************************************************************************** | |
| * ME_GetOLEObjectSize | |
| * | |
| * Sets run extent for OLE objects. | |
| */ | |
| void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize) | |
| { | |
| IDataObject* ido; | |
| FORMATETC fmt; | |
| STGMEDIUM stgm; | |
| DIBSECTION dibsect; | |
| ENHMETAHEADER emh; | |
| assert(run->nFlags & MERF_GRAPHICS); | |
| assert(run->ole_obj); | |
| if (run->ole_obj->sizel.cx != 0 || run->ole_obj->sizel.cy != 0) | |
| { | |
| convert_sizel(c, &run->ole_obj->sizel, pSize); | |
| if (c->editor->nZoomNumerator != 0) | |
| { | |
| pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator); | |
| pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator); | |
| } | |
| return; | |
| } | |
| if (!run->ole_obj->poleobj) | |
| { | |
| pSize->cx = pSize->cy = 0; | |
| return; | |
| } | |
| if (IOleObject_QueryInterface(run->ole_obj->poleobj, &IID_IDataObject, (void**)&ido) != S_OK) | |
| { | |
| FIXME("Query Interface IID_IDataObject failed!\n"); | |
| pSize->cx = pSize->cy = 0; | |
| return; | |
| } | |
| fmt.cfFormat = CF_BITMAP; | |
| fmt.ptd = NULL; | |
| fmt.dwAspect = DVASPECT_CONTENT; | |
| fmt.lindex = -1; | |
| fmt.tymed = TYMED_GDI; | |
| if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK) | |
| { | |
| fmt.cfFormat = CF_ENHMETAFILE; | |
| fmt.tymed = TYMED_ENHMF; | |
| if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK) | |
| { | |
| FIXME("unsupported format\n"); | |
| pSize->cx = pSize->cy = 0; | |
| IDataObject_Release(ido); | |
| return; | |
| } | |
| } | |
| IDataObject_Release(ido); | |
| switch (stgm.tymed) | |
| { | |
| case TYMED_GDI: | |
| GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect); | |
| pSize->cx = dibsect.dsBm.bmWidth; | |
| pSize->cy = dibsect.dsBm.bmHeight; | |
| break; | |
| case TYMED_ENHMF: | |
| GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh); | |
| pSize->cx = emh.rclBounds.right - emh.rclBounds.left; | |
| pSize->cy = emh.rclBounds.bottom - emh.rclBounds.top; | |
| break; | |
| default: | |
| FIXME("Unsupported tymed %d\n", stgm.tymed); | |
| break; | |
| } | |
| ReleaseStgMedium(&stgm); | |
| if (c->editor->nZoomNumerator != 0) | |
| { | |
| pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator); | |
| pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator); | |
| } | |
| } | |
| void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run, BOOL selected) | |
| { | |
| IDataObject* ido; | |
| FORMATETC fmt; | |
| STGMEDIUM stgm; | |
| DIBSECTION dibsect; | |
| ENHMETAHEADER emh; | |
| HDC hMemDC; | |
| SIZE sz; | |
| BOOL has_size; | |
| HBITMAP old_bm; | |
| RECT rc; | |
| assert(run->nFlags & MERF_GRAPHICS); | |
| assert(run->ole_obj); | |
| if (IOleObject_QueryInterface(run->ole_obj->poleobj, &IID_IDataObject, (void**)&ido) != S_OK) | |
| { | |
| FIXME("Couldn't get interface\n"); | |
| return; | |
| } | |
| has_size = run->ole_obj->sizel.cx != 0 || run->ole_obj->sizel.cy != 0; | |
| fmt.cfFormat = CF_BITMAP; | |
| fmt.ptd = NULL; | |
| fmt.dwAspect = DVASPECT_CONTENT; | |
| fmt.lindex = -1; | |
| fmt.tymed = TYMED_GDI; | |
| if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK) | |
| { | |
| fmt.cfFormat = CF_ENHMETAFILE; | |
| fmt.tymed = TYMED_ENHMF; | |
| if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK) | |
| { | |
| FIXME("Couldn't get storage medium\n"); | |
| IDataObject_Release(ido); | |
| return; | |
| } | |
| } | |
| IDataObject_Release(ido); | |
| switch (stgm.tymed) | |
| { | |
| case TYMED_GDI: | |
| GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect); | |
| hMemDC = CreateCompatibleDC(c->hDC); | |
| old_bm = SelectObject(hMemDC, stgm.u.hBitmap); | |
| if (has_size) | |
| { | |
| convert_sizel(c, &run->ole_obj->sizel, &sz); | |
| } else { | |
| sz.cx = dibsect.dsBm.bmWidth; | |
| sz.cy = dibsect.dsBm.bmHeight; | |
| } | |
| if (c->editor->nZoomNumerator != 0) | |
| { | |
| sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator); | |
| sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator); | |
| } | |
| StretchBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy, | |
| hMemDC, 0, 0, dibsect.dsBm.bmWidth, dibsect.dsBm.bmHeight, SRCCOPY); | |
| SelectObject(hMemDC, old_bm); | |
| DeleteDC(hMemDC); | |
| break; | |
| case TYMED_ENHMF: | |
| GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh); | |
| if (has_size) | |
| { | |
| convert_sizel(c, &run->ole_obj->sizel, &sz); | |
| } else { | |
| sz.cx = emh.rclBounds.right - emh.rclBounds.left; | |
| sz.cy = emh.rclBounds.bottom - emh.rclBounds.top; | |
| } | |
| if (c->editor->nZoomNumerator != 0) | |
| { | |
| sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator); | |
| sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator); | |
| } | |
| rc.left = x; | |
| rc.top = y - sz.cy; | |
| rc.right = x + sz.cx; | |
| rc.bottom = y; | |
| PlayEnhMetaFile(c->hDC, stgm.u.hEnhMetaFile, &rc); | |
| break; | |
| default: | |
| FIXME("Unsupported tymed %d\n", stgm.tymed); | |
| selected = FALSE; | |
| break; | |
| } | |
| ReleaseStgMedium(&stgm); | |
| if (selected && !c->editor->bHideSelection) | |
| PatBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy, DSTINVERT); | |
| } | |
| void ME_DeleteReObject(REOBJECT* reo) | |
| { | |
| if (reo->poleobj) IOleObject_Release(reo->poleobj); | |
| if (reo->pstg) IStorage_Release(reo->pstg); | |
| if (reo->polesite) IOleClientSite_Release(reo->polesite); | |
| FREE_OBJ(reo); | |
| } | |
| void ME_CopyReObject(REOBJECT* dst, const REOBJECT* src) | |
| { | |
| *dst = *src; | |
| if (dst->poleobj) IOleObject_AddRef(dst->poleobj); | |
| if (dst->pstg) IStorage_AddRef(dst->pstg); | |
| if (dst->polesite) IOleClientSite_AddRef(dst->polesite); | |
| } | |
| void ME_GetITextDocumentInterface(IRichEditOle *iface, LPVOID *ppvObj) | |
| { | |
| IRichEditOleImpl *This = impl_from_IRichEditOle(iface); | |
| *ppvObj = &This->ITextDocument_iface; | |
| } |