riched20: ITextDocument stubs for ITextServices

Tiger Soldier tigersoldi at gmail.com
Sat Jul 13 20:50:54 CDT 2013


This patch implements a standalone stub of ITextDocument. The stub is
currently used in txtsrv.c and will replace the stub in richole.c

---
 dlls/riched20/Makefile.in    |   1 +
 dlls/riched20/tests/txtsrv.c |  16 ++-
 dlls/riched20/txtdoc.c       | 282 +++++++++++++++++++++++++++++++++++++++++++
 dlls/riched20/txtdoc.h       |  46 +++++++
 dlls/riched20/txtsrv.c       |   6 +
 5 files changed, 350 insertions(+), 1 deletion(-)
 create mode 100644 dlls/riched20/txtdoc.c
 create mode 100644 dlls/riched20/txtdoc.h
-------------- next part --------------
From 2ec18f9b8baf11ecaedbc113c0023a8bbe225452 Mon Sep 17 00:00:00 2001
From: Caibin Chen <tigersoldi at gmail.com>
Date: Sun, 30 Jun 2013 17:14:41 -0700
Subject: riched20: ITextDocument stubs for ITextServices

---
 dlls/riched20/Makefile.in    |   1 +
 dlls/riched20/tests/txtsrv.c |  16 ++-
 dlls/riched20/txtdoc.c       | 282 +++++++++++++++++++++++++++++++++++++++++++
 dlls/riched20/txtdoc.h       |  46 +++++++
 dlls/riched20/txtsrv.c       |   6 +
 5 files changed, 350 insertions(+), 1 deletion(-)
 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..2ad1246 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,13 +859,15 @@ 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;
 
-    /* COM aggregation */
+    /* COM aggregation on ITextServices */
     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,16 @@ 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);
+
+    /* COM aggregation on ITextDocument */
+    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_AddRef(textdoc);
+    ok(refcount == unk_obj.ref, "CreateTextServices just pretends to support COM aggregation\n");
+    refcount = ITextDocument_Release(textdoc);
+    ok(refcount == unk_obj.ref, "CreateTextServices just pretends to support COM aggregation\n");
+    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..781f510
--- /dev/null
+++ b/dlls/riched20/txtdoc.c
@@ -0,0 +1,282 @@
+/*
+ * 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);
+
+struct tagReTxtDoc {
+  IUnknown *outerObj;
+  ME_TextEditor *editor;
+  ITextDocument iTextDocumentIface;
+};
+
+static inline ReTxtDoc *impl_from_interface(ITextDocument *iface)
+{
+  return CONTAINING_RECORD(iface, ReTxtDoc, iTextDocumentIface);
+}
+
+/* Implementation of IUnknown */
+static ULONG WINAPI ITextDocument_fnAddRef(ITextDocument *iface)
+{
+  ReTxtDoc *This = impl_from_interface(iface);
+  TRACE("(%p)\n", iface);
+  /* COM aggregation - delegate to outer IUnknown object. */
+  return IUnknown_AddRef(This->outerObj);
+}
+
+static ULONG WINAPI ITextDocument_fnRelease(ITextDocument *iface)
+{
+  ReTxtDoc *This = impl_from_interface(iface);;
+  TRACE("(%p)\n", iface);
+  /* COM aggregation - delegate to outer IUnknown object. */
+  return IUnknown_Release(This->outerObj);
+}
+
+static HRESULT WINAPI ITextDocument_fnQueryInterface(ITextDocument *iface, REFIID riid, void **ppv)
+{
+  ReTxtDoc *This = impl_from_interface(iface);;
+  TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv);
+
+  /* COM aggregation - delegate to outer IUnknown object. */
+  return IUnknown_QueryInterface(This->outerObj, 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 *outerObj, ME_TextEditor *editor)
+{
+  ReTxtDoc *This = heap_alloc(sizeof *This);
+  TRACE("(%p,%p)\n", outerObj, editor);
+  if (!This)
+    return NULL;
+
+  This->outerObj = outerObj;
+  This->editor = editor;
+  This->iTextDocumentIface.lpVtbl = &vtbl;
+  return This;
+}
+
+ITextDocument *ReTxtDoc_get_ITextDocument(ReTxtDoc *document)
+{
+  TRACE("(%p)\n", document);
+  return &document->iTextDocumentIface;
+}
+
+void ReTxtDoc_destroy(ReTxtDoc *document)
+{
+  TRACE("(%p)\n", document);
+  document->outerObj = 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..02579b2
--- /dev/null
+++ b/dlls/riched20/txtdoc.h
@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+/**
+ * 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 outerObj}.
+ *
+ * @param outerObj 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 *outerObj, ME_TextEditor *editor);
+ITextDocument *ReTxtDoc_get_ITextDocument(ReTxtDoc *document);
+void ReTxtDoc_destroy(ReTxtDoc *document);
+
+#endif /* __TXTDOC_H */
diff --git a/dlls/riched20/txtsrv.c b/dlls/riched20/txtsrv.c
index 0e78c53..5319f76 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 = ReTxtDoc_get_ITextDocument(This->txtDoc);
    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.2


More information about the wine-patches mailing list