2 * OleUIPasteSpecial implementation
4 * Copyright 2006 Huw Davies
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.
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.
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
21 #define COM_NO_WINDOWS_H
32 #include "oledlg_private.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(ole);
40 OLEUIPASTESPECIALW *ps;
44 static const struct ps_flag
49 #define PS_FLAG_ENTRY(p) {p, #p}
50 PS_FLAG_ENTRY(PSF_SHOWHELP),
51 PS_FLAG_ENTRY(PSF_SELECTPASTE),
52 PS_FLAG_ENTRY(PSF_SELECTPASTELINK),
53 PS_FLAG_ENTRY(PSF_CHECKDISPLAYASICON),
54 PS_FLAG_ENTRY(PSF_DISABLEDISPLAYASICON),
55 PS_FLAG_ENTRY(PSF_HIDECHANGEICON),
56 PS_FLAG_ENTRY(PSF_STAYONCLIPBOARDCHANGE),
57 PS_FLAG_ENTRY(PSF_NOREFRESHDATAOBJECT),
62 static void dump_ps_flags(DWORD flags)
64 char flagstr[1000] = "";
66 const struct ps_flag *flag = ps_flags;
67 for( ; flag->name; flag++) {
68 if(flags & flag->flag) {
69 strcat(flagstr, flag->name);
73 TRACE("flags %08x %s\n", flags, flagstr);
76 static void dump_pastespecial(LPOLEUIPASTESPECIALW ps)
79 dump_ps_flags(ps->dwFlags);
80 TRACE("hwnd %p caption %s hook %p custdata %lx\n",
81 ps->hWndOwner, debugstr_w(ps->lpszCaption), ps->lpfnHook, ps->lCustData);
82 if(IS_INTRESOURCE(ps->lpszTemplate))
83 TRACE("hinst %p template %04x hresource %p\n", ps->hInstance, (WORD)(ULONG_PTR)ps->lpszTemplate, ps->hResource);
85 TRACE("hinst %p template %s hresource %p\n", ps->hInstance, debugstr_w(ps->lpszTemplate), ps->hResource);
86 TRACE("dataobj %p arrpasteent %p cpasteent %d arrlinktype %p clinktype %d\n",
87 ps->lpSrcDataObj, ps->arrPasteEntries, ps->cPasteEntries,
88 ps->arrLinkTypes, ps->cLinkTypes);
89 TRACE("cclsidex %d lpclsidex %p nselect %d flink %d hmetapict %p size(%d,%d)\n",
90 ps->cClsidExclude, ps->lpClsidExclude, ps->nSelectedIndex, ps->fLink,
91 ps->hMetaPict, ps->sizel.cx, ps->sizel.cy);
92 for(i = 0; i < ps->cPasteEntries; i++)
94 TRACE("arrPasteEntries[%d]: cFormat %08x pTargetDevice %p dwAspect %d lindex %d tymed %d\n",
95 i, ps->arrPasteEntries[i].fmtetc.cfFormat, ps->arrPasteEntries[i].fmtetc.ptd,
96 ps->arrPasteEntries[i].fmtetc.dwAspect, ps->arrPasteEntries[i].fmtetc.lindex,
97 ps->arrPasteEntries[i].fmtetc.tymed);
98 TRACE("\tformat name %s result text %s flags %04x\n", debugstr_w(ps->arrPasteEntries[i].lpstrFormatName),
99 debugstr_w(ps->arrPasteEntries[i].lpstrResultText), ps->arrPasteEntries[i].dwFlags);
101 for(i = 0; i < ps->cLinkTypes; i++)
102 TRACE("arrLinkTypes[%d] %08x\n", i, ps->arrLinkTypes[i]);
103 for(i = 0; i < ps->cClsidExclude; i++)
104 TRACE("lpClsidExclude[%d] %s\n", i, debugstr_guid(&ps->lpClsidExclude[i]));
108 static inline WCHAR *strdupAtoW(const char *str)
112 if(!str) return NULL;
113 len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
114 ret = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
115 MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
119 static void update_structure(HWND hdlg, ps_struct_t *ps_struct)
121 ps_struct->ps->dwFlags = ps_struct->flags;
122 ps_struct->ps->fLink = (ps_struct->flags & PSF_SELECTPASTELINK) ? TRUE : FALSE;
125 static void free_structure(ps_struct_t *ps_struct)
127 HeapFree(GetProcessHeap(), 0, ps_struct);
130 static INT_PTR CALLBACK ps_dlg_proc(HWND hdlg, UINT msg, WPARAM wp, LPARAM lp)
132 /* native uses prop name "Structure", but we're not compatible
133 with that so we'll prepend "Wine_". */
134 static const WCHAR prop_name[] = {'W','i','n','e','_','S','t','r','u','c','t','u','r','e',0};
135 ps_struct_t *ps_struct;
137 TRACE("(%p, %04x, %08x, %08lx)\n", hdlg, msg, wp, lp);
139 ps_struct = GetPropW(hdlg, prop_name);
141 if(msg != WM_INITDIALOG)
151 ps_struct = HeapAlloc(GetProcessHeap(), 0, sizeof(*ps_struct));
152 ps_struct->ps = (OLEUIPASTESPECIALW*)lp;
153 ps_struct->flags = ps_struct->ps->dwFlags;
155 SetPropW(hdlg, prop_name, ps_struct);
157 if(ps_struct->ps->lpszCaption)
158 SetWindowTextW(hdlg, ps_struct->ps->lpszCaption);
160 return TRUE; /* use default focus */
168 update_structure(hdlg, ps_struct);
170 free_structure(ps_struct);
180 /***********************************************************************
181 * OleUIPasteSpecialA (OLEDLG.4)
183 UINT WINAPI OleUIPasteSpecialA(LPOLEUIPASTESPECIALA psA)
185 OLEUIPASTESPECIALW ps;
187 TRACE("(%p)\n", psA);
189 memcpy(&ps, psA, psA->cbStruct);
191 ps.lpszCaption = strdupAtoW(psA->lpszCaption);
192 if(!IS_INTRESOURCE(ps.lpszTemplate))
193 ps.lpszTemplate = strdupAtoW(psA->lpszTemplate);
195 if(psA->cPasteEntries > 0)
197 DWORD size = psA->cPasteEntries * sizeof(ps.arrPasteEntries[0]);
200 ps.arrPasteEntries = HeapAlloc(GetProcessHeap(), 0, size);
201 memcpy(ps.arrPasteEntries, psA->arrPasteEntries, size);
202 for(i = 0; i < psA->cPasteEntries; i++)
204 ps.arrPasteEntries[i].lpstrFormatName =
205 strdupAtoW(psA->arrPasteEntries[i].lpstrFormatName);
206 ps.arrPasteEntries[i].lpstrResultText =
207 strdupAtoW(psA->arrPasteEntries[i].lpstrResultText);
211 ret = OleUIPasteSpecialW(&ps);
213 if(psA->cPasteEntries > 0)
216 for(i = 0; i < psA->cPasteEntries; i++)
218 HeapFree(GetProcessHeap(), 0, (WCHAR*)ps.arrPasteEntries[i].lpstrFormatName);
219 HeapFree(GetProcessHeap(), 0, (WCHAR*)ps.arrPasteEntries[i].lpstrResultText);
221 HeapFree(GetProcessHeap(), 0, ps.arrPasteEntries);
223 if(!IS_INTRESOURCE(ps.lpszTemplate))
224 HeapFree(GetProcessHeap(), 0, (WCHAR*)ps.lpszTemplate);
225 HeapFree(GetProcessHeap(), 0, (WCHAR*)ps.lpszCaption);
227 /* Copy back the output fields */
228 psA->dwFlags = ps.dwFlags;
229 psA->lpSrcDataObj = ps.lpSrcDataObj;
230 psA->nSelectedIndex = ps.nSelectedIndex;
231 psA->fLink = ps.fLink;
232 psA->hMetaPict = ps.hMetaPict;
233 psA->sizel = ps.sizel;
238 /***********************************************************************
239 * OleUIPasteSpecialW (OLEDLG.22)
241 UINT WINAPI OleUIPasteSpecialW(LPOLEUIPASTESPECIALW ps)
243 LPCDLGTEMPLATEW dlg_templ = (LPCDLGTEMPLATEW)ps->hResource;
247 if(TRACE_ON(ole)) dump_pastespecial(ps);
249 if(!ps->lpSrcDataObj)
250 OleGetClipboard(&ps->lpSrcDataObj);
252 if(ps->hInstance || !ps->hResource)
254 HINSTANCE hInst = ps->hInstance ? ps->hInstance : OLEDLG_hInstance;
255 const WCHAR *name = ps->hInstance ? ps->lpszTemplate : MAKEINTRESOURCEW(IDD_PASTESPECIAL4);
258 if(name == NULL) return OLEUI_ERR_LPSZTEMPLATEINVALID;
259 hrsrc = FindResourceW(hInst, name, MAKEINTRESOURCEW(RT_DIALOG));
260 if(!hrsrc) return OLEUI_ERR_FINDTEMPLATEFAILURE;
261 dlg_templ = LoadResource(hInst, hrsrc);
262 if(!dlg_templ) return OLEUI_ERR_LOADTEMPLATEFAILURE;
265 DialogBoxIndirectParamW(OLEDLG_hInstance, dlg_templ, ps->hWndOwner, ps_dlg_proc, (LPARAM)ps);
267 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);