wordpad: Allow objects & images to be added with native riched20. (resend)

Dylan Smith dylan.ah.smith at gmail.com
Wed Jul 21 11:23:11 CDT 2010


Native riched20.dll seems to need an IRichEditOleCallback object in
order to get a buffer to store the image (using the GetNewStorage
method).
---
(resend: Resolved a conflict on rebase from kernel32 import being removed)

 programs/wordpad/Makefile.in   |    3 +-
 programs/wordpad/olecallback.c |  210 ++++++++++++++++++++++++++++++++++++++++
 programs/wordpad/wordpad.c     |   31 +------
 programs/wordpad/wordpad.h     |    6 +
 4 files changed, 220 insertions(+), 30 deletions(-)
 create mode 100644 programs/wordpad/olecallback.c

diff --git a/programs/wordpad/Makefile.in b/programs/wordpad/Makefile.in
index 9cc6785..a7e484f 100644
--- a/programs/wordpad/Makefile.in
+++ b/programs/wordpad/Makefile.in
@@ -4,12 +4,13 @@ SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = wordpad.exe
 APPMODE   = -mwindows -mno-cygwin
-IMPORTS   = comdlg32 shell32 user32 gdi32 advapi32 comctl32
+IMPORTS   = comdlg32 uuid ole32 shell32 user32 gdi32 advapi32 comctl32
 EXTRAINCL = -I$(TOPSRCDIR)/include/msvcrt
 EXTRADEFS = -DNO_LIBWINE_PORT
 MODCFLAGS = @BUILTINFLAG@
 
 C_SRCS = \
+	olecallback.c \
 	print.c \
 	registry.c \
 	wordpad.c
diff --git a/programs/wordpad/olecallback.c b/programs/wordpad/olecallback.c
new file mode 100644
index 0000000..9f9c258
--- /dev/null
+++ b/programs/wordpad/olecallback.c
@@ -0,0 +1,210 @@
+/*
+ * Wordpad implementation - Richedit OLE callback implementation
+ *
+ * Copyright 2010 by Dylan Smith <dylan.ah.smith at gmail.com>
+ *
+ * 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
+
+#include <windows.h>
+#include <richedit.h>
+#include <ole2.h>
+#include <richole.h>
+
+#include "wine/debug.h"
+#include "wordpad.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(wordpad);
+
+struct IRichEditOleCallbackImpl {
+    const IRichEditOleCallbackVtbl *vtbl;
+    IStorage *stg;
+    int item_num;
+};
+
+struct IRichEditOleCallbackImpl olecallback;
+
+static HRESULT STDMETHODCALLTYPE RichEditOleCallback_QueryInterface(
+    IRichEditOleCallback* This,
+    REFIID riid,
+    void **ppvObject)
+{
+    WINE_TRACE("(%p, %s, %p)\n", This, wine_dbgstr_guid(riid), ppvObject);
+    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IRichEditOleCallback))
+    {
+        *ppvObject = This;
+        return S_OK;
+    }
+    WINE_FIXME("Unknown interface: %s\n", wine_dbgstr_guid(riid));
+    return E_NOINTERFACE;
+}
+
+static ULONG STDMETHODCALLTYPE RichEditOleCallback_AddRef(
+    IRichEditOleCallback* This)
+{
+    WINE_TRACE("(%p)\n", This);
+    /* singleton */
+    return 1;
+}
+
+static ULONG STDMETHODCALLTYPE RichEditOleCallback_Release(
+    IRichEditOleCallback* This)
+{
+    WINE_TRACE("(%p)\n", This);
+    return 1;
+}
+
+/*** IRichEditOleCallback methods ***/
+static HRESULT STDMETHODCALLTYPE RichEditOleCallback_GetNewStorage(
+    IRichEditOleCallback* This,
+    LPSTORAGE *lplpstg)
+{
+    WCHAR name[32];
+    static const WCHAR template[] = {'R','E','O','L','E','_','%','u','\0'};
+
+    WINE_TRACE("(%p, %p)\n", This, lplpstg);
+    wsprintfW(name, template, olecallback.item_num++);
+    return IStorage_CreateStorage(olecallback.stg, name,
+                      STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE,
+                      0, 0, lplpstg);
+}
+
+static HRESULT STDMETHODCALLTYPE RichEditOleCallback_GetInPlaceContext(
+    IRichEditOleCallback* This,
+    LPOLEINPLACEFRAME *lplpFrame,
+    LPOLEINPLACEUIWINDOW *lplpDoc,
+    LPOLEINPLACEFRAMEINFO lpFrameInfo)
+{
+    WINE_FIXME("(%p, %p, %p, %p) stub\n", This, lplpFrame, lplpDoc, lpFrameInfo);
+    return E_INVALIDARG;
+}
+
+static HRESULT STDMETHODCALLTYPE RichEditOleCallback_ShowContainerUI(
+    IRichEditOleCallback* This,
+    BOOL fShow)
+{
+    WINE_TRACE("(%p, %d)\n", This, fShow);
+    return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE RichEditOleCallback_QueryInsertObject(
+    IRichEditOleCallback* This,
+    LPCLSID lpclsid,
+    LPSTORAGE lpstg,
+    LONG cp)
+{
+    WINE_TRACE("(%p, %p, %p, %d)\n", This, lpclsid, lpstg, cp);
+    return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE RichEditOleCallback_DeleteObject(
+    IRichEditOleCallback* This,
+    LPOLEOBJECT lpoleobj)
+{
+    WINE_TRACE("(%p, %p)\n", This, lpoleobj);
+    return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE RichEditOleCallback_QueryAcceptData(
+    IRichEditOleCallback* This,
+    LPDATAOBJECT lpdataobj,
+    CLIPFORMAT *lpcfFormat,
+    DWORD reco,
+    BOOL fReally,
+    HGLOBAL hMetaPict)
+{
+    WINE_TRACE("(%p, %p, %p, %x, %d, %p)\n",
+               This, lpdataobj, lpcfFormat, reco, fReally, hMetaPict);
+    return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE RichEditOleCallback_ContextSensitiveHelp(
+    IRichEditOleCallback* This,
+    BOOL fEnterMode)
+{
+    WINE_TRACE("(%p, %d)\n", This, fEnterMode);
+    return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE RichEditOleCallback_GetClipboardData(
+    IRichEditOleCallback* This,
+    CHARRANGE *lpchrg,
+    DWORD reco,
+    LPDATAOBJECT *lplpdataobj)
+{
+    WINE_TRACE("(%p, %p, %x, %p)\n", This, lpchrg, reco, lplpdataobj);
+    return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE RichEditOleCallback_GetDragDropEffect(
+    IRichEditOleCallback* This,
+    BOOL fDrag,
+    DWORD grfKeyState,
+    LPDWORD pdwEffect)
+{
+    WINE_TRACE("(%p, %d, %x, %p)\n", This, fDrag, grfKeyState, pdwEffect);
+    if (pdwEffect)
+          *pdwEffect = DROPEFFECT_COPY;
+    return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE RichEditOleCallback_GetContextMenu(
+    IRichEditOleCallback* This,
+    WORD seltype,
+    LPOLEOBJECT lpoleobj,
+    CHARRANGE *lpchrg,
+    HMENU *lphmenu)
+{
+    HINSTANCE hInstance = GetModuleHandleW(0);
+    HMENU hPopupMenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDM_POPUP));
+
+    WINE_TRACE("(%p, %x, %p, %p, %p)\n",
+               This, seltype, lpoleobj, lpchrg, lphmenu);
+
+    *lphmenu = GetSubMenu(hPopupMenu, 0);
+    return S_OK;
+}
+
+struct IRichEditOleCallbackVtbl olecallbackVtbl = {
+    RichEditOleCallback_QueryInterface,
+    RichEditOleCallback_AddRef,
+    RichEditOleCallback_Release,
+    RichEditOleCallback_GetNewStorage,
+    RichEditOleCallback_GetInPlaceContext,
+    RichEditOleCallback_ShowContainerUI,
+    RichEditOleCallback_QueryInsertObject,
+    RichEditOleCallback_DeleteObject,
+    RichEditOleCallback_QueryAcceptData,
+    RichEditOleCallback_ContextSensitiveHelp,
+    RichEditOleCallback_GetClipboardData,
+    RichEditOleCallback_GetDragDropEffect,
+    RichEditOleCallback_GetContextMenu
+};
+
+struct IRichEditOleCallbackImpl olecallback = {
+    &olecallbackVtbl, NULL, 0
+};
+
+HRESULT SetupRichEditOleCallback(HWND hEditorWnd)
+{
+    HRESULT hr = StgCreateDocfile(NULL,
+          STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE,
+          0, &olecallback.stg);
+
+    SendMessageW(hEditorWnd, EM_SETOLECALLBACK, 0, (LPARAM)&olecallback);
+    return hr;
+}
diff --git a/programs/wordpad/wordpad.c b/programs/wordpad/wordpad.c
index abd7cd2..6fc2242 100644
--- a/programs/wordpad/wordpad.c
+++ b/programs/wordpad/wordpad.c
@@ -62,7 +62,6 @@ LRESULT CALLBACK preview_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 static HWND hMainWnd;
 static HWND hEditorWnd;
 static HWND hFindWnd;
-static HMENU hPopupMenu;
 static HMENU hColorPopupMenu;
 
 static UINT ID_FINDMSGSTRING;
@@ -1795,29 +1794,6 @@ static INT_PTR CALLBACK tabstops_proc(HWND hWnd, UINT message, WPARAM wParam, LP
     return FALSE;
 }
 
-static int context_menu(LPARAM lParam)
-{
-    int x = (int)(short)LOWORD(lParam);
-    int y = (int)(short)HIWORD(lParam);
-    HMENU hPop = GetSubMenu(hPopupMenu, 0);
-
-    if(x == -1)
-    {
-        int from = 0, to = 0;
-        POINTL pt;
-        SendMessageW(hEditorWnd, EM_GETSEL, (WPARAM)&from, (LPARAM)&to);
-        SendMessageW(hEditorWnd, EM_POSFROMCHAR, (WPARAM)&pt, to);
-        ClientToScreen(hEditorWnd, (POINT*)&pt);
-        x = pt.x;
-        y = pt.y;
-    }
-
-    TrackPopupMenu(hPop, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON,
-                   x, y, 0, hMainWnd, 0);
-
-    return 0;
-}
-
 static LRESULT OnCreate( HWND hWnd )
 {
     HWND hToolBarWnd, hFormatBarWnd,  hReBarWnd, hFontListWnd, hSizeListWnd, hRulerWnd;
@@ -1955,6 +1931,7 @@ static LRESULT OnCreate( HWND hWnd )
     }
     assert(hEditorWnd);
 
+    SetupRichEditOleCallback(hEditorWnd);
     SetFocus(hEditorWnd);
     SendMessageW(hEditorWnd, EM_SETEVENTMASK, 0, ENM_SELCHANGE);
 
@@ -2656,10 +2633,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPara
         return OnSize( hWnd, wParam, lParam );
 
     case WM_CONTEXTMENU:
-        if((HWND)wParam == hEditorWnd)
-            return context_menu(lParam);
-        else
-            return DefWindowProcW(hWnd, msg, wParam, lParam);
+        return DefWindowProcW(hWnd, msg, wParam, lParam);
 
     case WM_DROPFILES:
         {
@@ -2740,7 +2714,6 @@ int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hOldInstance, LPSTR szCmdPar
     set_caption(NULL);
     set_bar_states();
     set_fileformat(SF_RTF);
-    hPopupMenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDM_POPUP));
     hColorPopupMenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDM_COLOR_POPUP));
     get_default_printer_opts();
     target_device(hMainWnd, wordWrap[reg_formatindex(fileFormat)]);
diff --git a/programs/wordpad/wordpad.h b/programs/wordpad/wordpad.h
index f50881a..6b9ff24 100644
--- a/programs/wordpad/wordpad.h
+++ b/programs/wordpad/wordpad.h
@@ -237,8 +237,10 @@
 #define STRING_PRINTING_NOT_IMPLEMENTED 1711
 #define STRING_MAX_TAB_STOPS 1712
 
+/* wordpad.c */
 LPWSTR file_basename(LPWSTR);
 
+/* print.c */
 void dialog_printsetup(HWND);
 void dialog_print(HWND, LPWSTR);
 void target_device(HWND, DWORD);
@@ -255,6 +257,7 @@ void registry_read_previewpages(HKEY hKey);
 LRESULT CALLBACK ruler_proc(HWND, UINT, WPARAM, LPARAM);
 void redraw_ruler(HWND);
 
+/* registry.c */
 int reg_formatindex(WPARAM);
 void registry_read_filelist(HWND);
 void registry_read_options(void);
@@ -264,3 +267,6 @@ void registry_read_maximized(DWORD*);
 void registry_set_filelist(LPCWSTR, HWND);
 void registry_set_formatopts_all(DWORD[], DWORD[]);
 void registry_set_options(HWND);
+
+/* olecallback.c */
+HRESULT SetupRichEditOleCallback(HWND hEditorWnd);
-- 
1.7.0.4



More information about the wine-patches mailing list