wordpad: Allow objects & images to be added with native riched20.
Native riched20.dll seems to need an IRichEditOleCallback object in
order to get a buffer to store the image (using the GetNewStorage
method).
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 @@
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..8b279ad
--- /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@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 setup_richedit_olecallback(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..187aef0 100644
--- a/programs/wordpad/wordpad.c
+++ b/programs/wordpad/wordpad.c
@@ -62,7 +62,6 @@
static HWND hMainWnd;
static HWND hEditorWnd;
static HWND hFindWnd;
-static HMENU hPopupMenu;
static HMENU hColorPopupMenu;
static UINT ID_FINDMSGSTRING;
@@ -1795,29 +1794,6 @@
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 @@
}
assert(hEditorWnd);
+ setup_richedit_olecallback(hEditorWnd);
SetFocus(hEditorWnd);
SendMessageW(hEditorWnd, EM_SETEVENTMASK, 0, ENM_SELCHANGE);
@@ -2656,10 +2633,7 @@
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 @@
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..0cde557 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 @@
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_set_filelist(LPCWSTR, HWND);
void registry_set_formatopts_all(DWORD[], DWORD[]);
void registry_set_options(HWND);
+
+/* olecallback.c */
+HRESULT setup_richedit_olecallback(HWND hEditorWnd);