From d8a05c37d992d8b51d26fc100bd86d35bf0ef203 Mon Sep 17 00:00:00 2001 From: Dylan Smith Date: Thu, 22 Jul 2010 08:30:19 -0400 Subject: [PATCH] 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). --- 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 9cc678541b9..a7e484f7c29 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 00000000000..8b279ada89d --- /dev/null +++ b/programs/wordpad/olecallback.c @@ -0,0 +1,210 @@ +/* + * Wordpad implementation - Richedit OLE callback implementation + * + * Copyright 2010 by Dylan Smith + * + * 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 +#include +#include +#include + +#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 abd7cd21db4..187aef09842 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); + setup_richedit_olecallback(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 f50881abe07..0cde557117c 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 setup_richedit_olecallback(HWND hEditorWnd);