riched20: Add COM aggregation support for IRichEditOle.

This commit is contained in:
Jactry Zeng 2014-10-28 20:10:33 +08:00 committed by Alexandre Julliard
parent ffb706ceb0
commit 234310e752
3 changed files with 58 additions and 20 deletions

View File

@ -1194,7 +1194,7 @@ static BOOL ME_RTFInsertOleObject(RTF_Info *info, HENHMETAFILE hemf, HBITMAP hbm
if (!info->lpRichEditOle) if (!info->lpRichEditOle)
{ {
CreateIRichEditOle(info->editor, (VOID**)&info->lpRichEditOle); CreateIRichEditOle(NULL, info->editor, (VOID**)&info->lpRichEditOle);
} }
if (OleCreateDefaultHandler(&CLSID_NULL, NULL, &IID_IOleObject, (void**)&lpObject) == S_OK && if (OleCreateDefaultHandler(&CLSID_NULL, NULL, &IID_IOleObject, (void**)&lpObject) == S_OK &&
@ -4474,7 +4474,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
case EM_GETOLEINTERFACE: case EM_GETOLEINTERFACE:
{ {
if (!editor->reOle) if (!editor->reOle)
if (!CreateIRichEditOle(editor, (LPVOID *)&editor->reOle)) if (!CreateIRichEditOle(NULL, editor, (LPVOID *)&editor->reOle))
return 0; return 0;
*(LPVOID *)lParam = editor->reOle; *(LPVOID *)lParam = editor->reOle;
IRichEditOle_AddRef(editor->reOle); IRichEditOle_AddRef(editor->reOle);

View File

@ -240,7 +240,7 @@ void ME_UpdateScrollBar(ME_TextEditor *editor) DECLSPEC_HIDDEN;
int ME_GetParaBorderWidth(const ME_Context *c, int flags) DECLSPEC_HIDDEN; int ME_GetParaBorderWidth(const ME_Context *c, int flags) DECLSPEC_HIDDEN;
/* richole.c */ /* richole.c */
LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *) DECLSPEC_HIDDEN; LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *ppvObj) DECLSPEC_HIDDEN;
void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run* run, ME_Paragraph *para, BOOL selected) DECLSPEC_HIDDEN; void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run* run, ME_Paragraph *para, BOOL selected) DECLSPEC_HIDDEN;
void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize) DECLSPEC_HIDDEN; void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize) DECLSPEC_HIDDEN;
void ME_CopyReObject(REOBJECT* dst, const REOBJECT* src) DECLSPEC_HIDDEN; void ME_CopyReObject(REOBJECT* dst, const REOBJECT* src) DECLSPEC_HIDDEN;

View File

@ -52,8 +52,10 @@ typedef struct IOleClientSiteImpl IOleClientSiteImpl;
typedef struct ITextRangeImpl ITextRangeImpl; typedef struct ITextRangeImpl ITextRangeImpl;
typedef struct IRichEditOleImpl { typedef struct IRichEditOleImpl {
IUnknown IUnknown_inner;
IRichEditOle IRichEditOle_iface; IRichEditOle IRichEditOle_iface;
ITextDocument ITextDocument_iface; ITextDocument ITextDocument_iface;
IUnknown *outer_unk;
LONG ref; LONG ref;
ME_TextEditor *editor; ME_TextEditor *editor;
@ -95,44 +97,47 @@ static inline IRichEditOleImpl *impl_from_ITextDocument(ITextDocument *iface)
return CONTAINING_RECORD(iface, IRichEditOleImpl, ITextDocument_iface); return CONTAINING_RECORD(iface, IRichEditOleImpl, ITextDocument_iface);
} }
static HRESULT WINAPI static inline IRichEditOleImpl *impl_from_IUnknown(IUnknown *iface)
IRichEditOle_fnQueryInterface(IRichEditOle *me, REFIID riid, LPVOID *ppvObj)
{ {
IRichEditOleImpl *This = impl_from_IRichEditOle(me); return CONTAINING_RECORD(iface, IRichEditOleImpl, IUnknown_inner);
}
TRACE("%p %s\n", This, debugstr_guid(riid) ); 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; *ppvObj = NULL;
if (IsEqualGUID(riid, &IID_IUnknown) || if (IsEqualGUID(riid, &IID_IUnknown))
IsEqualGUID(riid, &IID_IRichEditOle)) *ppvObj = &This->IUnknown_inner;
else if (IsEqualGUID(riid, &IID_IRichEditOle))
*ppvObj = &This->IRichEditOle_iface; *ppvObj = &This->IRichEditOle_iface;
else if (IsEqualGUID(riid, &IID_ITextDocument)) else if (IsEqualGUID(riid, &IID_ITextDocument))
*ppvObj = &This->ITextDocument_iface; *ppvObj = &This->ITextDocument_iface;
if (*ppvObj) if (*ppvObj)
{ {
IRichEditOle_AddRef(me); IUnknown_AddRef((IUnknown *)*ppvObj);
return S_OK; return S_OK;
} }
FIXME("%p: unhandled interface %s\n", This, debugstr_guid(riid) ); FIXME("%p: unhandled interface %s\n", This, debugstr_guid(riid));
return E_NOINTERFACE; return E_NOINTERFACE;
} }
static ULONG WINAPI static ULONG WINAPI IRichEditOleImpl_inner_fnAddRef(IUnknown *iface)
IRichEditOle_fnAddRef(IRichEditOle *me)
{ {
IRichEditOleImpl *This = impl_from_IRichEditOle(me); IRichEditOleImpl *This = impl_from_IUnknown(iface);
ULONG ref = InterlockedIncrement( &This->ref ); ULONG ref = InterlockedIncrement(&This->ref);
TRACE("%p ref = %u\n", This, ref); TRACE("%p ref = %u\n", This, ref);
return ref; return ref;
} }
static ULONG WINAPI static ULONG WINAPI IRichEditOleImpl_inner_fnRelease(IUnknown *iface)
IRichEditOle_fnRelease(IRichEditOle *me)
{ {
IRichEditOleImpl *This = impl_from_IRichEditOle(me); IRichEditOleImpl *This = impl_from_IUnknown(iface);
ULONG ref = InterlockedDecrement(&This->ref); ULONG ref = InterlockedDecrement(&This->ref);
TRACE ("%p ref=%u\n", This, ref); TRACE ("%p ref=%u\n", This, ref);
@ -152,6 +157,34 @@ IRichEditOle_fnRelease(IRichEditOle *me)
return ref; 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 static HRESULT WINAPI
IRichEditOle_fnActivateAs(IRichEditOle *me, REFCLSID rclsid, REFCLSID rclsidAs) IRichEditOle_fnActivateAs(IRichEditOle *me, REFCLSID rclsid, REFCLSID rclsidAs)
{ {
@ -2305,7 +2338,7 @@ CreateTextSelection(IRichEditOleImpl *reOle)
return txtSel; return txtSel;
} }
LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *ppObj) LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *ppvObj)
{ {
IRichEditOleImpl *reo; IRichEditOleImpl *reo;
@ -2313,6 +2346,7 @@ LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *ppObj)
if (!reo) if (!reo)
return 0; return 0;
reo->IUnknown_inner.lpVtbl = &reo_unk_vtbl;
reo->IRichEditOle_iface.lpVtbl = &revt; reo->IRichEditOle_iface.lpVtbl = &revt;
reo->ITextDocument_iface.lpVtbl = &tdvt; reo->ITextDocument_iface.lpVtbl = &tdvt;
reo->ref = 1; reo->ref = 1;
@ -2331,8 +2365,12 @@ LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *ppObj)
return 0; return 0;
} }
TRACE("Created %p\n",reo); TRACE("Created %p\n",reo);
*ppObj = reo;
list_init(&reo->rangelist); list_init(&reo->rangelist);
if (outer_unk)
reo->outer_unk = outer_unk;
else
reo->outer_unk = &reo->IUnknown_inner;
*ppvObj = &reo->IRichEditOle_iface;
return 1; return 1;
} }