[PATCH 1/4] riched20: Basic ITextDocument implementation for ITextServices (try 3)
Caibin Chen
tigersoldi at gmail.com
Wed Jul 31 01:57:47 CDT 2013
Thanks Jacek for reviewing. This time I send all the changes I have in
4 patches to make it clear that ReTxtDoc is reused between txtsrv.c
and richole.c
- Suppressed Patch 97331
- Change log from try 2:
- follow COM naming convention
- move ReTxtDoc definition to header, removed
ReTxtDoc_get_ITextDocument() function
- remove COM aggregation test for ITextDocument, only test
ITextService supports querying for the interface.
---
dlls/riched20/Makefile.in | 1 +
dlls/riched20/tests/txtsrv.c | 10 ++
dlls/riched20/txtdoc.c | 270 +++++++++++++++++++++++++++++++++++++++++++
dlls/riched20/txtdoc.h | 51 ++++++++
dlls/riched20/txtsrv.c | 6 +
-------------- next part --------------
From ccd409befdc02e3cb989c1c07713b66e90a44a36 Mon Sep 17 00:00:00 2001
From: Caibin Chen <tigersoldi at gmail.com>
Date: Sun, 30 Jun 2013 17:14:41 -0700
Subject: [PATCH 1/4] riched20: Basic ITextDocument implementation for
ITextServices
---
dlls/riched20/Makefile.in | 1 +
dlls/riched20/tests/txtsrv.c | 10 ++
dlls/riched20/txtdoc.c | 270 +++++++++++++++++++++++++++++++++++++++++++
dlls/riched20/txtdoc.h | 51 ++++++++
dlls/riched20/txtsrv.c | 6 +
5 files changed, 338 insertions(+)
create mode 100644 dlls/riched20/txtdoc.c
create mode 100644 dlls/riched20/txtdoc.h
diff --git a/dlls/riched20/Makefile.in b/dlls/riched20/Makefile.in
index 49ba7a1..be4fdce 100644
--- a/dlls/riched20/Makefile.in
+++ b/dlls/riched20/Makefile.in
@@ -18,6 +18,7 @@ C_SRCS = \
string.c \
style.c \
table.c \
+ txtdoc.c \
txthost.c \
txtsrv.c \
undo.c \
diff --git a/dlls/riched20/tests/txtsrv.c b/dlls/riched20/tests/txtsrv.c
index e517e03..5f7d7de 100644
--- a/dlls/riched20/tests/txtsrv.c
+++ b/dlls/riched20/tests/txtsrv.c
@@ -29,6 +29,8 @@
#include <winbase.h>
#include <objbase.h>
#include <richedit.h>
+/* should be included before initguid.h to avoid multiple difenition with richole.c */
+#include <tom.h>
#include <initguid.h>
#include <textserv.h>
#include <wine/test.h>
@@ -857,6 +859,7 @@ static void test_COM(void)
struct unk_impl unk_obj = {{&unk_vtbl}, 19, NULL};
struct ITextHostTestImpl texthost = {{&itextHostVtbl}, 1};
ITextServices *textsrv;
+ ITextDocument *textdoc;
ULONG refcount;
HRESULT hr;
@@ -864,6 +867,7 @@ static void test_COM(void)
hr = pCreateTextServices(&unk_obj.IUnknown_iface, &texthost.ITextHost_iface,
&unk_obj.inner_unk);
ok(hr == S_OK, "CreateTextServices failed: %08x\n", hr);
+
hr = IUnknown_QueryInterface(unk_obj.inner_unk, pIID_ITextServices, (void**)&textsrv);
ok(hr == S_OK, "QueryInterface for IID_ITextServices failed: %08x\n", hr);
refcount = ITextServices_AddRef(textsrv);
@@ -871,6 +875,12 @@ static void test_COM(void)
refcount = ITextServices_Release(textsrv);
ok(refcount == unk_obj.ref, "CreateTextServices just pretends to support COM aggregation\n");
refcount = ITextServices_Release(textsrv);
+
+ /* Test that ITextDocument is supported */
+ hr = IUnknown_QueryInterface(unk_obj.inner_unk, &IID_ITextDocument, (void**)&textdoc);
+ ok(hr == S_OK, "QueryInterface for IID_ITextDocument failed: %08x\n", hr);
+ refcount = ITextDocument_Release(textdoc);
+
ok(refcount == 19, "Refcount should be back at 19 but is %u\n", refcount);
IUnknown_Release(unk_obj.inner_unk);
diff --git a/dlls/riched20/txtdoc.c b/dlls/riched20/txtdoc.c
new file mode 100644
index 0000000..697e1f9
--- /dev/null
+++ b/dlls/riched20/txtdoc.c
@@ -0,0 +1,270 @@
+/*
+ * RichEdit - ITextDocument implementation
+ *
+ * Copyright 2013 by Caibin Chen
+ *
+ * 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
+ */
+#define COBJMACROS /* For COM objects interfaces definition */
+
+#include "txtdoc.h"
+
+#include "editor.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(richedit);
+
+static inline ReTxtDoc *impl_from_ITextDocument(ITextDocument *iface)
+{
+ return CONTAINING_RECORD(iface, ReTxtDoc, ITextDocument_iface);
+}
+
+/* Implementation of IUnknown */
+static ULONG WINAPI ITextDocument_fnAddRef(ITextDocument *iface)
+{
+ ReTxtDoc *This = impl_from_ITextDocument(iface);
+ TRACE("(%p)\n", iface);
+ /* COM aggregation - delegate to outer IUnknown object. */
+ return IUnknown_AddRef(This->outer_unk);
+}
+
+static ULONG WINAPI ITextDocument_fnRelease(ITextDocument *iface)
+{
+ ReTxtDoc *This = impl_from_ITextDocument(iface);
+ TRACE("(%p)\n", iface);
+ /* COM aggregation - delegate to outer IUnknown object. */
+ return IUnknown_Release(This->outer_unk);
+}
+
+static HRESULT WINAPI ITextDocument_fnQueryInterface(ITextDocument *iface, REFIID riid, void **ppv)
+{
+ ReTxtDoc *This = impl_from_ITextDocument(iface);
+ TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv);
+
+ /* COM aggregation - delegate to outer IUnknown object. */
+ return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
+}
+
+/* Implementation of IDispatch */
+
+static HRESULT WINAPI ITextDocument_fnGetTypeInfoCount(ITextDocument *iface, UINT *pctinfo)
+{
+ TRACE("(%p)->(%p)\n", iface, pctinfo);
+ /* Ruturn 0 since type info is not implemented */
+ *pctinfo = 0;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI ITextDocument_fnGetTypeInfo(ITextDocument *iface, UINT iTInfo, LCID lcid,
+ ITypeInfo **ppTInfo)
+{
+ FIXME("not implemented\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextDocument_fnGetIDsOfNames(ITextDocument *iface, REFIID riid,
+ LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
+{
+ FIXME("not implemented\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextDocument_fnInvoke(
+ ITextDocument *me,
+ DISPID dispIdMember,
+ REFIID riid,
+ LCID lcid,
+ WORD wFlags,
+ DISPPARAMS *pDispParams,
+ VARIANT *pVarResult,
+ EXCEPINFO *pExcepInfo,
+ UINT *puArgErr)
+{
+ FIXME("not implemented\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextDocument_fnGetName(ITextDocument *iface, BSTR *pName)
+{
+ FIXME("not implemented\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextDocument_fnGetSelection(ITextDocument *me, ITextSelection **ppSel)
+{
+ FIXME("not implemented\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextDocument_fnGetStoryCount(ITextDocument *iface, LONG *pCount)
+{
+ TRACE("(%p)->(%p)\n", iface, pCount);
+ *pCount = 1; /* GetStory is not implemented. */
+ return S_OK;
+}
+
+static HRESULT WINAPI ITextDocument_fnGetStoryRanges(ITextDocument *iface,
+ ITextStoryRanges **ppStories)
+{
+ FIXME("not implemented\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextDocument_fnGetSaved(ITextDocument *iface, LONG *pValue)
+{
+ FIXME("not implemented\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextDocument_fnSetSaved(ITextDocument *iface, LONG Value)
+{
+ FIXME("not implemented\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextDocument_fnGetDefaultTabStop(ITextDocument *iface, float *pValue)
+{
+ FIXME("not implemented\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextDocument_fnSetDefaultTabStop(ITextDocument *iface, float Value)
+{
+ FIXME("not implemented\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextDocument_fnNew(ITextDocument *iface)
+{
+ FIXME("not implemented\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextDocument_fnOpen(ITextDocument *iface, VARIANT *pVar, LONG Flags,
+ LONG CodePage)
+{
+ FIXME("not implemented\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextDocument_fnSave(ITextDocument *iface, VARIANT *pVar, LONG Flags,
+ LONG CodePage)
+{
+ FIXME("not implement\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextDocument_fnFreeze(ITextDocument *iface, LONG *pCount)
+{
+ FIXME("not implemented\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextDocument_fnUnfreeze(ITextDocument *iface, LONG *pCount)
+{
+ FIXME("not implemented\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextDocument_fnBeginEditCollection(ITextDocument *iface)
+{
+ FIXME("not implemented\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextDocument_fnEndEditCollection(ITextDocument *iface)
+{
+ FIXME("not implemented\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextDocument_fnUndo(ITextDocument *iface, LONG Count, LONG *prop)
+{
+ FIXME("not implemented\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextDocument_fnRedo(ITextDocument *iface, LONG Count, LONG *prop)
+{
+ FIXME("not implemented\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextDocument_fnRange(ITextDocument *iface, LONG cp1, LONG cp2,
+ ITextRange **ppRange)
+{
+ FIXME("not implemented\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextDocument_fnRangeFromPoint(ITextDocument *me, LONG x, LONG y,
+ ITextRange **ppRange)
+{
+ FIXME("not implemented\n");
+ return E_NOTIMPL;
+}
+
+static const ITextDocumentVtbl vtbl = {
+ /* IUnknown */
+ ITextDocument_fnQueryInterface,
+ ITextDocument_fnAddRef,
+ ITextDocument_fnRelease,
+ /* IDispatch */
+ ITextDocument_fnGetTypeInfoCount,
+ ITextDocument_fnGetTypeInfo,
+ ITextDocument_fnGetIDsOfNames,
+ ITextDocument_fnInvoke,
+ /* ITextDocument */
+ 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
+};
+
+ReTxtDoc *ReTxtDoc_create(IUnknown *outer_unk, ME_TextEditor *editor)
+{
+ ReTxtDoc *This = heap_alloc(sizeof *This);
+ TRACE("(%p,%p)\n", outer_unk, editor);
+ if (!This)
+ return NULL;
+
+ This->outer_unk = outer_unk;
+ This->editor = editor;
+ This->ITextDocument_iface.lpVtbl = &vtbl;
+ return This;
+}
+
+void ReTxtDoc_destroy(ReTxtDoc *document)
+{
+ TRACE("(%p)\n", document);
+ document->outer_unk = NULL;
+ document->editor = NULL;
+ heap_free(document);
+}
diff --git a/dlls/riched20/txtdoc.h b/dlls/riched20/txtdoc.h
new file mode 100644
index 0000000..a8a86bc
--- /dev/null
+++ b/dlls/riched20/txtdoc.h
@@ -0,0 +1,51 @@
+/*
+ * RichEdit - ITextDocument implementation
+ *
+ * Copyright 2013 by Caibin Chen
+ *
+ * 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
+ */
+
+#ifndef __TXTDOC_H
+#define __TXTDOC_H
+
+#include <tom.h>
+
+#include "editstr.h"
+
+typedef struct tagReTxtDoc ReTxtDoc;
+struct tagReTxtDoc {
+ IUnknown *outer_unk;
+ ME_TextEditor *editor;
+ ITextDocument ITextDocument_iface;
+};
+
+/**
+ * Create an ReTxtDoc object, which acts as an inner object of COM aggression.
+ *
+ * The ReTxtDoc object will delegate all of its IUnknown calls to the specified
+ * {@code outer_unk}.
+ *
+ * @param outer_unk The outer objects that creates and delegates ITextDocument
+ * method calls to the created ReTxtDoc.
+ * @param editor The editor implementation.
+ *
+ * @return An ReTxtDoc object that should be destroyed with {@code ReTxtDoc_destroy}
+ */
+ReTxtDoc *ReTxtDoc_create(IUnknown *outer_unk, ME_TextEditor *editor);
+
+void ReTxtDoc_destroy(ReTxtDoc *document);
+
+#endif /* __TXTDOC_H */
diff --git a/dlls/riched20/txtsrv.c b/dlls/riched20/txtsrv.c
index 0e78c53..f72ce3a 100644
--- a/dlls/riched20/txtsrv.c
+++ b/dlls/riched20/txtsrv.c
@@ -31,6 +31,7 @@
#include "richole.h"
#include "imm.h"
#include "textserv.h"
+#include "txtdoc.h"
#include "wine/debug.h"
#include "editstr.h"
@@ -61,6 +62,7 @@ typedef struct ITextServicesImpl {
ITextHost *pMyHost;
CRITICAL_SECTION csTxtSrv;
ME_TextEditor *editor;
+ ReTxtDoc *txtDoc;
char spare[256];
} ITextServicesImpl;
@@ -79,6 +81,8 @@ static HRESULT WINAPI ITextServicesImpl_QueryInterface(IUnknown *iface, REFIID r
*ppv = &This->IUnknown_inner;
else if (IsEqualIID(riid, &IID_ITextServices))
*ppv = &This->ITextServices_iface;
+ else if (IsEqualIID(riid, &IID_ITextDocument))
+ *ppv = &This->txtDoc->ITextDocument_iface;
else {
*ppv = NULL;
FIXME("Unknown interface: %s\n", debugstr_guid(riid));
@@ -111,6 +115,7 @@ static ULONG WINAPI ITextServicesImpl_Release(IUnknown *iface)
ITextHost_Release(This->pMyHost);
This->csTxtSrv.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->csTxtSrv);
+ ReTxtDoc_destroy(This->txtDoc);
CoTaskMemFree(This);
}
return ref;
@@ -420,6 +425,7 @@ HRESULT WINAPI CreateTextServices(IUnknown *pUnkOuter, ITextHost *pITextHost, I
ITextImpl->outer_unk = pUnkOuter;
else
ITextImpl->outer_unk = &ITextImpl->IUnknown_inner;
+ ITextImpl->txtDoc = ReTxtDoc_create(ITextImpl->outer_unk, ITextImpl->editor);
*ppUnk = &ITextImpl->IUnknown_inner;
return S_OK;
--
1.8.3.4
More information about the wine-patches
mailing list