1 /*
2  * Wordpad implementation - Richedit OLE callback implementation
3  *
4  * Copyright 2010 by Dylan Smith <dylan.ah.smith@gmail.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #define COBJMACROS
22 
23 #define WIN32_NO_STATUS
24 #define WIN32_LEAN_AND_MEAN
25 #include <windows.h>
26 #include <richedit.h>
27 #include <richole.h>
28 #include <wine/debug.h>
29 
30 #include "wordpad.h"
31 
32 WINE_DEFAULT_DEBUG_CHANNEL(wordpad);
33 
34 struct IRichEditOleCallbackImpl {
35     const IRichEditOleCallbackVtbl *vtbl;
36     IStorage *stg;
37     int item_num;
38 };
39 
40 struct IRichEditOleCallbackImpl olecallback;
41 
RichEditOleCallback_QueryInterface(IRichEditOleCallback * This,REFIID riid,void ** ppvObject)42 static HRESULT STDMETHODCALLTYPE RichEditOleCallback_QueryInterface(
43     IRichEditOleCallback* This,
44     REFIID riid,
45     void **ppvObject)
46 {
47     WINE_TRACE("(%p, %s, %p)\n", This, wine_dbgstr_guid(riid), ppvObject);
48     if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IRichEditOleCallback))
49     {
50         *ppvObject = This;
51         return S_OK;
52     }
53     WINE_FIXME("Unknown interface: %s\n", wine_dbgstr_guid(riid));
54     return E_NOINTERFACE;
55 }
56 
RichEditOleCallback_AddRef(IRichEditOleCallback * This)57 static ULONG STDMETHODCALLTYPE RichEditOleCallback_AddRef(
58     IRichEditOleCallback* This)
59 {
60     WINE_TRACE("(%p)\n", This);
61     /* singleton */
62     return 1;
63 }
64 
RichEditOleCallback_Release(IRichEditOleCallback * This)65 static ULONG STDMETHODCALLTYPE RichEditOleCallback_Release(
66     IRichEditOleCallback* This)
67 {
68     WINE_TRACE("(%p)\n", This);
69     return 1;
70 }
71 
72 /*** IRichEditOleCallback methods ***/
RichEditOleCallback_GetNewStorage(IRichEditOleCallback * This,LPSTORAGE * lplpstg)73 static HRESULT STDMETHODCALLTYPE RichEditOleCallback_GetNewStorage(
74     IRichEditOleCallback* This,
75     LPSTORAGE *lplpstg)
76 {
77     WCHAR name[32];
78     static const WCHAR template[] = {'R','E','O','L','E','_','%','u','\0'};
79 
80     WINE_TRACE("(%p, %p)\n", This, lplpstg);
81     wsprintfW(name, template, olecallback.item_num++);
82     return IStorage_CreateStorage(olecallback.stg, name,
83                       STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE,
84                       0, 0, lplpstg);
85 }
86 
RichEditOleCallback_GetInPlaceContext(IRichEditOleCallback * This,LPOLEINPLACEFRAME * lplpFrame,LPOLEINPLACEUIWINDOW * lplpDoc,LPOLEINPLACEFRAMEINFO lpFrameInfo)87 static HRESULT STDMETHODCALLTYPE RichEditOleCallback_GetInPlaceContext(
88     IRichEditOleCallback* This,
89     LPOLEINPLACEFRAME *lplpFrame,
90     LPOLEINPLACEUIWINDOW *lplpDoc,
91     LPOLEINPLACEFRAMEINFO lpFrameInfo)
92 {
93     WINE_FIXME("(%p, %p, %p, %p) stub\n", This, lplpFrame, lplpDoc, lpFrameInfo);
94     return E_INVALIDARG;
95 }
96 
RichEditOleCallback_ShowContainerUI(IRichEditOleCallback * This,BOOL fShow)97 static HRESULT STDMETHODCALLTYPE RichEditOleCallback_ShowContainerUI(
98     IRichEditOleCallback* This,
99     BOOL fShow)
100 {
101     WINE_TRACE("(%p, %d)\n", This, fShow);
102     return S_OK;
103 }
104 
RichEditOleCallback_QueryInsertObject(IRichEditOleCallback * This,LPCLSID lpclsid,LPSTORAGE lpstg,LONG cp)105 static HRESULT STDMETHODCALLTYPE RichEditOleCallback_QueryInsertObject(
106     IRichEditOleCallback* This,
107     LPCLSID lpclsid,
108     LPSTORAGE lpstg,
109     LONG cp)
110 {
111     WINE_TRACE("(%p, %p, %p, %d)\n", This, lpclsid, lpstg, cp);
112     return S_OK;
113 }
114 
RichEditOleCallback_DeleteObject(IRichEditOleCallback * This,LPOLEOBJECT lpoleobj)115 static HRESULT STDMETHODCALLTYPE RichEditOleCallback_DeleteObject(
116     IRichEditOleCallback* This,
117     LPOLEOBJECT lpoleobj)
118 {
119     WINE_TRACE("(%p, %p)\n", This, lpoleobj);
120     return S_OK;
121 }
122 
RichEditOleCallback_QueryAcceptData(IRichEditOleCallback * This,LPDATAOBJECT lpdataobj,CLIPFORMAT * lpcfFormat,DWORD reco,BOOL fReally,HGLOBAL hMetaPict)123 static HRESULT STDMETHODCALLTYPE RichEditOleCallback_QueryAcceptData(
124     IRichEditOleCallback* This,
125     LPDATAOBJECT lpdataobj,
126     CLIPFORMAT *lpcfFormat,
127     DWORD reco,
128     BOOL fReally,
129     HGLOBAL hMetaPict)
130 {
131     WINE_TRACE("(%p, %p, %p, %x, %d, %p)\n",
132                This, lpdataobj, lpcfFormat, reco, fReally, hMetaPict);
133     return S_OK;
134 }
135 
RichEditOleCallback_ContextSensitiveHelp(IRichEditOleCallback * This,BOOL fEnterMode)136 static HRESULT STDMETHODCALLTYPE RichEditOleCallback_ContextSensitiveHelp(
137     IRichEditOleCallback* This,
138     BOOL fEnterMode)
139 {
140     WINE_TRACE("(%p, %d)\n", This, fEnterMode);
141     return S_OK;
142 }
143 
RichEditOleCallback_GetClipboardData(IRichEditOleCallback * This,CHARRANGE * lpchrg,DWORD reco,LPDATAOBJECT * lplpdataobj)144 static HRESULT STDMETHODCALLTYPE RichEditOleCallback_GetClipboardData(
145     IRichEditOleCallback* This,
146     CHARRANGE *lpchrg,
147     DWORD reco,
148     LPDATAOBJECT *lplpdataobj)
149 {
150     WINE_TRACE("(%p, %p, %x, %p)\n", This, lpchrg, reco, lplpdataobj);
151     return E_NOTIMPL;
152 }
153 
RichEditOleCallback_GetDragDropEffect(IRichEditOleCallback * This,BOOL fDrag,DWORD grfKeyState,LPDWORD pdwEffect)154 static HRESULT STDMETHODCALLTYPE RichEditOleCallback_GetDragDropEffect(
155     IRichEditOleCallback* This,
156     BOOL fDrag,
157     DWORD grfKeyState,
158     LPDWORD pdwEffect)
159 {
160     WINE_TRACE("(%p, %d, %x, %p)\n", This, fDrag, grfKeyState, pdwEffect);
161     if (pdwEffect)
162           *pdwEffect = DROPEFFECT_COPY;
163     return S_OK;
164 }
165 
RichEditOleCallback_GetContextMenu(IRichEditOleCallback * This,WORD seltype,LPOLEOBJECT lpoleobj,CHARRANGE * lpchrg,HMENU * lphmenu)166 static HRESULT STDMETHODCALLTYPE RichEditOleCallback_GetContextMenu(
167     IRichEditOleCallback* This,
168     WORD seltype,
169     LPOLEOBJECT lpoleobj,
170     CHARRANGE *lpchrg,
171     HMENU *lphmenu)
172 {
173     HINSTANCE hInstance = GetModuleHandleW(0);
174     HMENU hPopupMenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDM_POPUP));
175 
176     WINE_TRACE("(%p, %x, %p, %p, %p)\n",
177                This, seltype, lpoleobj, lpchrg, lphmenu);
178 
179     *lphmenu = GetSubMenu(hPopupMenu, 0);
180     return S_OK;
181 }
182 
183 struct IRichEditOleCallbackVtbl olecallbackVtbl = {
184     RichEditOleCallback_QueryInterface,
185     RichEditOleCallback_AddRef,
186     RichEditOleCallback_Release,
187     RichEditOleCallback_GetNewStorage,
188     RichEditOleCallback_GetInPlaceContext,
189     RichEditOleCallback_ShowContainerUI,
190     RichEditOleCallback_QueryInsertObject,
191     RichEditOleCallback_DeleteObject,
192     RichEditOleCallback_QueryAcceptData,
193     RichEditOleCallback_ContextSensitiveHelp,
194     RichEditOleCallback_GetClipboardData,
195     RichEditOleCallback_GetDragDropEffect,
196     RichEditOleCallback_GetContextMenu
197 };
198 
199 struct IRichEditOleCallbackImpl olecallback = {
200     &olecallbackVtbl, NULL, 0
201 };
202 
setup_richedit_olecallback(HWND hEditorWnd)203 HRESULT setup_richedit_olecallback(HWND hEditorWnd)
204 {
205     HRESULT hr = StgCreateDocfile(NULL,
206           STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE,
207           0, &olecallback.stg);
208 
209     SendMessageW(hEditorWnd, EM_SETOLECALLBACK, 0, (LPARAM)&olecallback);
210     return hr;
211 }
212