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 #include "oledlg_private.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
27 OLEUIPASTESPECIALW
*ps
;
30 WCHAR
*link_source_name
;
32 WCHAR
*link_type_name
;
36 static const struct ps_flag
41 #define PS_FLAG_ENTRY(p) {p, #p}
42 PS_FLAG_ENTRY(PSF_SHOWHELP
),
43 PS_FLAG_ENTRY(PSF_SELECTPASTE
),
44 PS_FLAG_ENTRY(PSF_SELECTPASTELINK
),
45 PS_FLAG_ENTRY(PSF_CHECKDISPLAYASICON
),
46 PS_FLAG_ENTRY(PSF_DISABLEDISPLAYASICON
),
47 PS_FLAG_ENTRY(PSF_HIDECHANGEICON
),
48 PS_FLAG_ENTRY(PSF_STAYONCLIPBOARDCHANGE
),
49 PS_FLAG_ENTRY(PSF_NOREFRESHDATAOBJECT
),
54 static void dump_ps_flags(DWORD flags
)
56 char flagstr
[1000] = "";
58 const struct ps_flag
*flag
= ps_flags
;
59 for( ; flag
->name
; flag
++) {
60 if(flags
& flag
->flag
) {
61 strcat(flagstr
, flag
->name
);
65 TRACE("flags %08x %s\n", flags
, flagstr
);
68 static void dump_pastespecial(const OLEUIPASTESPECIALW
*ps
)
73 dump_ps_flags(ps
->dwFlags
);
74 TRACE("hwnd %p caption %s hook %p custdata %lx\n",
75 ps
->hWndOwner
, debugstr_w(ps
->lpszCaption
), ps
->lpfnHook
, ps
->lCustData
);
76 if(IS_INTRESOURCE(ps
->lpszTemplate
))
77 TRACE("hinst %p template %04x hresource %p\n", ps
->hInstance
, (WORD
)(ULONG_PTR
)ps
->lpszTemplate
, ps
->hResource
);
79 TRACE("hinst %p template %s hresource %p\n", ps
->hInstance
, debugstr_w(ps
->lpszTemplate
), ps
->hResource
);
80 TRACE("dataobj %p arrpasteent %p cpasteent %d arrlinktype %p clinktype %d\n",
81 ps
->lpSrcDataObj
, ps
->arrPasteEntries
, ps
->cPasteEntries
,
82 ps
->arrLinkTypes
, ps
->cLinkTypes
);
83 TRACE("cclsidex %d lpclsidex %p nselect %d flink %d hmetapict %p size(%d,%d)\n",
84 ps
->cClsidExclude
, ps
->lpClsidExclude
, ps
->nSelectedIndex
, ps
->fLink
,
85 ps
->hMetaPict
, ps
->sizel
.cx
, ps
->sizel
.cy
);
86 for(i
= 0; i
< ps
->cPasteEntries
; i
++)
88 TRACE("arrPasteEntries[%d]: cFormat %08x pTargetDevice %p dwAspect %d lindex %d tymed %d\n",
89 i
, ps
->arrPasteEntries
[i
].fmtetc
.cfFormat
, ps
->arrPasteEntries
[i
].fmtetc
.ptd
,
90 ps
->arrPasteEntries
[i
].fmtetc
.dwAspect
, ps
->arrPasteEntries
[i
].fmtetc
.lindex
,
91 ps
->arrPasteEntries
[i
].fmtetc
.tymed
);
92 TRACE("\tformat name %s result text %s flags %04x\n", debugstr_w(ps
->arrPasteEntries
[i
].lpstrFormatName
),
93 debugstr_w(ps
->arrPasteEntries
[i
].lpstrResultText
), ps
->arrPasteEntries
[i
].dwFlags
);
95 for(i
= 0; i
< ps
->cLinkTypes
; i
++)
96 TRACE("arrLinkTypes[%d] %08x\n", i
, ps
->arrLinkTypes
[i
]);
97 for(j
= 0; j
< ps
->cClsidExclude
; j
++)
98 TRACE("lpClsidExclude[%u] %s\n", j
, debugstr_guid(&ps
->lpClsidExclude
[j
]));
102 static inline WCHAR
*strdupAtoW(const char *str
)
106 if(!str
) return NULL
;
107 len
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
108 ret
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
109 MultiByteToWideChar(CP_ACP
, 0, str
, -1, ret
, len
);
113 static inline WCHAR
*strdupW(const WCHAR
*str
)
117 if(!str
) return NULL
;
118 len
= lstrlenW(str
) + 1;
119 ret
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
120 memcpy(ret
, str
, len
* sizeof(WCHAR
));
124 static void get_descriptors(HWND hdlg
, ps_struct_t
*ps_struct
)
129 fmtetc
.tymed
= TYMED_HGLOBAL
;
130 fmtetc
.dwAspect
= DVASPECT_CONTENT
;
134 fmtetc
.cfFormat
= cf_object_descriptor
;
135 if(IDataObject_GetData(ps_struct
->ps
->lpSrcDataObj
, &fmtetc
, &stg
) == S_OK
)
137 OBJECTDESCRIPTOR
*obj_desc
= GlobalLock(stg
.u
.hGlobal
);
138 if(obj_desc
->dwSrcOfCopy
)
139 ps_struct
->source_name
= strdupW((WCHAR
*)((char*)obj_desc
+ obj_desc
->dwSrcOfCopy
));
140 if(obj_desc
->dwFullUserTypeName
)
141 ps_struct
->type_name
= strdupW((WCHAR
*)((char*)obj_desc
+ obj_desc
->dwFullUserTypeName
));
142 OleRegGetUserType(&obj_desc
->clsid
, USERCLASSTYPE_APPNAME
, &ps_struct
->app_name
);
143 /* Get the icon here. If dwDrawAspect & DVASCPECT_ICON call GetData(CF_METAFILEPICT), otherwise
144 native calls OleGetIconFromClass(obj_desc->clsid) */
145 GlobalUnlock(stg
.u
.hGlobal
);
146 GlobalFree(stg
.u
.hGlobal
);
150 /* Try to get some data using some of the other clipboard formats */
153 fmtetc
.cfFormat
= cf_link_src_descriptor
;
154 if(IDataObject_GetData(ps_struct
->ps
->lpSrcDataObj
, &fmtetc
, &stg
) == S_OK
)
156 OBJECTDESCRIPTOR
*obj_desc
= GlobalLock(stg
.u
.hGlobal
);
157 if(obj_desc
->dwSrcOfCopy
)
158 ps_struct
->link_source_name
= strdupW((WCHAR
*)((char*)obj_desc
+ obj_desc
->dwSrcOfCopy
));
159 if(obj_desc
->dwFullUserTypeName
)
160 ps_struct
->link_type_name
= strdupW((WCHAR
*)((char*)obj_desc
+ obj_desc
->dwFullUserTypeName
));
161 GlobalUnlock(stg
.u
.hGlobal
);
162 GlobalFree(stg
.u
.hGlobal
);
165 if(ps_struct
->source_name
== NULL
&& ps_struct
->link_source_name
== NULL
)
168 LoadStringW(OLEDLG_hInstance
, IDS_PS_UNKNOWN_SRC
, buf
, sizeof(buf
)/sizeof(WCHAR
));
169 ps_struct
->source_name
= strdupW(buf
);
172 if(ps_struct
->type_name
== NULL
&& ps_struct
->link_type_name
== NULL
)
175 LoadStringW(OLEDLG_hInstance
, IDS_PS_UNKNOWN_TYPE
, buf
, sizeof(buf
)/sizeof(WCHAR
));
176 ps_struct
->type_name
= strdupW(buf
);
180 static BOOL
add_entry_to_lb(HWND hdlg
, UINT id
, OLEUIPASTEENTRYW
*pe
)
182 HWND hwnd
= GetDlgItem(hdlg
, id
);
185 /* FIXME %s handling */
187 /* Note that this suffers from the same bug as native, in that if a new string
188 is a substring of an already added string, then the FINDSTRING will succeed
189 this is probably not what we want */
190 if(SendMessageW(hwnd
, LB_FINDSTRING
, 0, (LPARAM
)pe
->lpstrFormatName
) == -1)
192 LRESULT pos
= SendMessageW(hwnd
, LB_ADDSTRING
, 0, (LPARAM
)pe
->lpstrFormatName
);
193 SendMessageW(hwnd
, LB_SETITEMDATA
, pos
, (LPARAM
)pe
);
199 static DWORD
init_pastelist(HWND hdlg
, OLEUIPASTESPECIALW
*ps
)
201 IEnumFORMATETC
*penum
;
204 DWORD fetched
, items_added
= 0;
206 hr
= IDataObject_EnumFormatEtc(ps
->lpSrcDataObj
, DATADIR_GET
, &penum
);
209 WARN("Unable to create IEnumFORMATETC\n");
213 /* The native version grabs only the first 20 fmts and we do the same */
214 hr
= IEnumFORMATETC_Next(penum
, sizeof(fmts
)/sizeof(fmts
[0]), fmts
, &fetched
);
215 TRACE("got %d formats hr %08x\n", fetched
, hr
);
219 DWORD src_fmt
, req_fmt
;
220 for(req_fmt
= 0; req_fmt
< ps
->cPasteEntries
; req_fmt
++)
222 /* This is used by update_structure() to set nSelectedIndex on exit */
223 ps
->arrPasteEntries
[req_fmt
].dwScratchSpace
= req_fmt
;
224 TRACE("req_fmt %x\n", ps
->arrPasteEntries
[req_fmt
].fmtetc
.cfFormat
);
225 for(src_fmt
= 0; src_fmt
< fetched
; src_fmt
++)
227 TRACE("\tenum'ed fmt %x\n", fmts
[src_fmt
].cfFormat
);
228 if(ps
->arrPasteEntries
[req_fmt
].fmtetc
.cfFormat
== fmts
[src_fmt
].cfFormat
)
230 add_entry_to_lb(hdlg
, IDC_PS_PASTELIST
, ps
->arrPasteEntries
+ req_fmt
);
238 IEnumFORMATETC_Release(penum
);
239 EnableWindow(GetDlgItem(hdlg
, IDC_PS_PASTE
), items_added
!= 0);
243 static DWORD
init_linklist(HWND hdlg
, OLEUIPASTESPECIALW
*ps
)
246 DWORD supported_mask
= 0;
247 DWORD items_added
= 0;
249 FORMATETC fmt
= {0, NULL
, DVASPECT_CONTENT
, -1, -1};
251 for(link
= 0; link
< ps
->cLinkTypes
&& link
< PS_MAXLINKTYPES
; link
++)
253 fmt
.cfFormat
= ps
->arrLinkTypes
[link
];
254 hr
= IDataObject_QueryGetData(ps
->lpSrcDataObj
, &fmt
);
256 supported_mask
|= 1 << link
;
258 TRACE("supported_mask %02x\n", supported_mask
);
259 for(req_fmt
= 0; req_fmt
< ps
->cPasteEntries
; req_fmt
++)
262 if(ps
->arrPasteEntries
[req_fmt
].dwFlags
& OLEUIPASTE_LINKANYTYPE
)
265 linktypes
= ps
->arrPasteEntries
[req_fmt
].dwFlags
& 0xff;
267 if(linktypes
& supported_mask
)
269 add_entry_to_lb(hdlg
, IDC_PS_PASTELINKLIST
, ps
->arrPasteEntries
+ req_fmt
);
274 EnableWindow(GetDlgItem(hdlg
, IDC_PS_PASTELINK
), items_added
!= 0);
278 /* copies src_list_id into the display list */
279 static void update_display_list(HWND hdlg
, UINT src_list_id
)
281 LONG count
, i
, old_pos
;
284 HWND display_list
= GetDlgItem(hdlg
, IDC_PS_DISPLAYLIST
);
285 HWND list
= GetDlgItem(hdlg
, src_list_id
);
287 old_pos
= SendMessageW(display_list
, LB_GETCURSEL
, 0, 0);
288 if(old_pos
== -1) old_pos
= 0;
290 SendMessageW(display_list
, WM_SETREDRAW
, 0, 0);
291 SendMessageW(display_list
, LB_RESETCONTENT
, 0, 0);
292 count
= SendMessageW(list
, LB_GETCOUNT
, 0, 0);
293 for(i
= 0; i
< count
; i
++)
295 SendMessageW(list
, LB_GETTEXT
, i
, (LPARAM
)txt
);
296 item_data
= SendMessageW(list
, LB_GETITEMDATA
, i
, 0);
297 SendMessageW(display_list
, LB_INSERTSTRING
, i
, (LPARAM
)txt
);
298 SendMessageW(display_list
, LB_SETITEMDATA
, i
, item_data
);
300 SendMessageW(display_list
, LB_SETCURSEL
, 0, 0);
301 SendMessageW(display_list
, WM_SETREDRAW
, 1, 0);
302 if(GetForegroundWindow() == hdlg
)
303 SetFocus(display_list
);
306 static void init_lists(HWND hdlg
, ps_struct_t
*ps_struct
)
308 DWORD pastes_added
= init_pastelist(hdlg
, ps_struct
->ps
);
309 DWORD links_added
= init_linklist(hdlg
, ps_struct
->ps
);
310 UINT check_id
, list_id
;
312 if((ps_struct
->flags
& (PSF_SELECTPASTE
| PSF_SELECTPASTELINK
)) == 0)
313 ps_struct
->flags
|= PSF_SELECTPASTE
;
315 if(!pastes_added
&& !links_added
)
316 ps_struct
->flags
&= ~(PSF_SELECTPASTE
| PSF_SELECTPASTELINK
);
317 else if(!pastes_added
&& (ps_struct
->flags
& PSF_SELECTPASTE
))
319 ps_struct
->flags
&= ~PSF_SELECTPASTE
;
320 ps_struct
->flags
|= PSF_SELECTPASTELINK
;
322 else if(!links_added
&& (ps_struct
->flags
& PSF_SELECTPASTELINK
))
324 ps_struct
->flags
&= ~PSF_SELECTPASTELINK
;
325 ps_struct
->flags
|= PSF_SELECTPASTE
;
330 if(ps_struct
->flags
& PSF_SELECTPASTE
)
332 check_id
= IDC_PS_PASTE
;
333 list_id
= IDC_PS_PASTELIST
;
335 else if(ps_struct
->flags
& PSF_SELECTPASTELINK
)
337 check_id
= IDC_PS_PASTELINK
;
338 list_id
= IDC_PS_PASTELINKLIST
;
341 CheckRadioButton(hdlg
, IDC_PS_PASTE
, IDC_PS_PASTELINK
, check_id
);
344 update_display_list(hdlg
, list_id
);
346 EnableWindow(GetDlgItem(hdlg
, IDOK
), 0);
349 static void update_src_text(HWND hdlg
, const ps_struct_t
*ps_struct
)
353 if(ps_struct
->flags
& PSF_SELECTPASTE
)
355 if(ps_struct
->source_name
)
356 str
= ps_struct
->source_name
;
358 str
= ps_struct
->link_source_name
;
363 if(ps_struct
->link_source_name
)
364 str
= ps_struct
->link_source_name
;
366 str
= ps_struct
->source_name
;
369 SetDlgItemTextW(hdlg
, IDC_PS_SOURCETEXT
, str
);
372 static void update_as_icon(HWND hdlg
, ps_struct_t
*ps_struct
)
374 HWND icon_display
= GetDlgItem(hdlg
, IDC_PS_ICONDISPLAY
);
375 HWND display_as_icon
= GetDlgItem(hdlg
, IDC_PS_DISPLAYASICON
);
376 HWND change_icon
= GetDlgItem(hdlg
, IDC_PS_CHANGEICON
);
378 /* FIXME. No as icon handling */
379 ps_struct
->flags
&= ~PSF_CHECKDISPLAYASICON
;
381 CheckDlgButton(hdlg
, IDC_PS_DISPLAYASICON
, ps_struct
->flags
& PSF_CHECKDISPLAYASICON
);
382 EnableWindow(display_as_icon
, 0);
383 ShowWindow(icon_display
, SW_HIDE
);
384 EnableWindow(icon_display
, 0);
385 ShowWindow(change_icon
, SW_HIDE
);
386 EnableWindow(change_icon
, 0);
389 static void update_result_text(HWND hdlg
, const ps_struct_t
*ps_struct
)
391 WCHAR resource_txt
[200];
393 OLEUIPASTEENTRYW
*pent
;
395 static const WCHAR percent_s
[] = {'%','s',0};
396 WCHAR
*result_txt
, *ptr
;
398 cur_sel
= SendMessageW(GetDlgItem(hdlg
, IDC_PS_DISPLAYLIST
), LB_GETCURSEL
, 0, 0);
399 if(cur_sel
== -1) return;
400 pent
= (OLEUIPASTEENTRYW
*)SendMessageW(GetDlgItem(hdlg
, IDC_PS_DISPLAYLIST
), LB_GETITEMDATA
, cur_sel
, 0);
402 if(ps_struct
->flags
& PSF_SELECTPASTE
)
404 if(ps_struct
->flags
& PSF_CHECKDISPLAYASICON
)
405 res_id
= IDS_PS_PASTE_OBJECT_AS_ICON
;
407 res_id
= IDS_PS_PASTE_DATA
;
411 if(ps_struct
->flags
& PSF_CHECKDISPLAYASICON
)
412 res_id
= IDS_PS_PASTE_LINK_OBJECT_AS_ICON
;
414 res_id
= IDS_PS_PASTE_LINK_DATA
;
417 LoadStringW(OLEDLG_hInstance
, res_id
, resource_txt
, sizeof(resource_txt
)/sizeof(WCHAR
));
418 if((ptr
= strstrW(resource_txt
, percent_s
)))
420 /* FIXME handle %s in ResultText. Sub appname if IDS_PS_PASTE_OBJECT{_AS_ICON}. Else sub appropriate type name */
421 size_t result_txt_len
= strlenW(pent
->lpstrResultText
);
422 ptrdiff_t offs
= (char*)ptr
- (char*)resource_txt
;
423 result_txt
= HeapAlloc(GetProcessHeap(), 0, (strlenW(resource_txt
) + result_txt_len
- 1) * sizeof(WCHAR
));
424 memcpy(result_txt
, resource_txt
, offs
);
425 memcpy((char*)result_txt
+ offs
, pent
->lpstrResultText
, result_txt_len
* sizeof(WCHAR
));
426 memcpy((char*)result_txt
+ offs
+ result_txt_len
* sizeof(WCHAR
), ptr
+ 2, (strlenW(ptr
+ 2) + 1) * sizeof(WCHAR
));
429 result_txt
= resource_txt
;
431 SetDlgItemTextW(hdlg
, IDC_PS_RESULTTEXT
, result_txt
);
433 if(result_txt
!= resource_txt
)
434 HeapFree(GetProcessHeap(), 0, result_txt
);
438 static void selection_change(HWND hdlg
, ps_struct_t
*ps_struct
)
440 update_as_icon(hdlg
, ps_struct
);
441 update_result_text(hdlg
, ps_struct
);
444 static void mode_change(HWND hdlg
, ps_struct_t
*ps_struct
, UINT id
)
446 if(id
== IDC_PS_PASTE
)
448 ps_struct
->flags
&= ~PSF_SELECTPASTELINK
;
449 ps_struct
->flags
|= PSF_SELECTPASTE
;
453 ps_struct
->flags
&= ~PSF_SELECTPASTE
;
454 ps_struct
->flags
|= PSF_SELECTPASTELINK
;
457 update_src_text(hdlg
, ps_struct
);
458 update_display_list(hdlg
, id
== IDC_PS_PASTE
? IDC_PS_PASTELIST
: IDC_PS_PASTELINKLIST
);
459 selection_change(hdlg
, ps_struct
);
462 static void post_help_msg(HWND hdlg
, ps_struct_t
*ps_struct
)
464 PostMessageW(ps_struct
->ps
->hWndOwner
, oleui_msg_help
, (WPARAM
)hdlg
, IDD_PASTESPECIAL
);
467 static void send_end_dialog_msg(HWND hdlg
, ps_struct_t
*ps_struct
, UINT id
)
469 SendMessageW(hdlg
, oleui_msg_enddialog
, id
, 0);
472 static void update_structure(HWND hdlg
, ps_struct_t
*ps_struct
)
474 LONG cur_sel
= SendMessageW(GetDlgItem(hdlg
, IDC_PS_DISPLAYLIST
), LB_GETCURSEL
, 0, 0);
477 OLEUIPASTEENTRYW
*pent
;
478 pent
= (OLEUIPASTEENTRYW
*)SendMessageW(GetDlgItem(hdlg
, IDC_PS_DISPLAYLIST
), LB_GETITEMDATA
, cur_sel
, 0);
479 ps_struct
->ps
->nSelectedIndex
= pent
->dwScratchSpace
;
481 ps_struct
->ps
->dwFlags
= ps_struct
->flags
;
482 ps_struct
->ps
->fLink
= (ps_struct
->flags
& PSF_SELECTPASTELINK
) != 0;
485 static void free_structure(ps_struct_t
*ps_struct
)
487 HeapFree(GetProcessHeap(), 0, ps_struct
->type_name
);
488 HeapFree(GetProcessHeap(), 0, ps_struct
->source_name
);
489 HeapFree(GetProcessHeap(), 0, ps_struct
->link_type_name
);
490 HeapFree(GetProcessHeap(), 0, ps_struct
->link_source_name
);
491 CoTaskMemFree(ps_struct
->app_name
);
492 HeapFree(GetProcessHeap(), 0, ps_struct
);
495 static INT_PTR CALLBACK
ps_dlg_proc(HWND hdlg
, UINT msg
, WPARAM wp
, LPARAM lp
)
497 /* native uses prop name "Structure", but we're not compatible
498 with that so we'll prepend "Wine_". */
499 static const WCHAR prop_name
[] = {'W','i','n','e','_','S','t','r','u','c','t','u','r','e',0};
500 ps_struct_t
*ps_struct
;
502 TRACE("(%p, %04x, %08lx, %08lx)\n", hdlg
, msg
, wp
, lp
);
504 ps_struct
= GetPropW(hdlg
, prop_name
);
506 if(msg
!= WM_INITDIALOG
)
511 if(ps_struct
->ps
->lpfnHook
)
513 INT_PTR ret
= ps_struct
->ps
->lpfnHook(hdlg
, msg
, wp
, lp
);
522 ps_struct
= HeapAlloc(GetProcessHeap(), 0, sizeof(*ps_struct
));
523 ps_struct
->ps
= (OLEUIPASTESPECIALW
*)lp
;
524 ps_struct
->type_name
= NULL
;
525 ps_struct
->source_name
= NULL
;
526 ps_struct
->link_type_name
= NULL
;
527 ps_struct
->link_source_name
= NULL
;
528 ps_struct
->app_name
= NULL
;
529 ps_struct
->flags
= ps_struct
->ps
->dwFlags
;
531 SetPropW(hdlg
, prop_name
, ps_struct
);
533 if(!(ps_struct
->ps
->dwFlags
& PSF_SHOWHELP
))
535 ShowWindow(GetDlgItem(hdlg
, IDC_OLEUIHELP
), SW_HIDE
);
536 EnableWindow(GetDlgItem(hdlg
, IDC_OLEUIHELP
), 0);
539 if(ps_struct
->ps
->lpszCaption
)
540 SetWindowTextW(hdlg
, ps_struct
->ps
->lpszCaption
);
542 get_descriptors(hdlg
, ps_struct
);
544 init_lists(hdlg
, ps_struct
);
546 update_src_text(hdlg
, ps_struct
);
548 selection_change(hdlg
, ps_struct
);
550 SetFocus(GetDlgItem(hdlg
, IDC_PS_DISPLAYLIST
));
552 if(ps_struct
->ps
->lpfnHook
)
553 ps_struct
->ps
->lpfnHook(hdlg
, msg
, 0, 0);
554 return FALSE
; /* use new focus */
559 case IDC_PS_DISPLAYLIST
:
563 selection_change(hdlg
, ps_struct
);
569 case IDC_PS_PASTELINK
:
573 mode_change(hdlg
, ps_struct
, LOWORD(wp
));
583 post_help_msg(hdlg
, ps_struct
);
593 send_end_dialog_msg(hdlg
, ps_struct
, LOWORD(wp
));
601 if(msg
== oleui_msg_enddialog
)
604 update_structure(hdlg
, ps_struct
);
606 /* native does its cleanup in WM_DESTROY */
607 RemovePropW(hdlg
, prop_name
);
608 free_structure(ps_struct
);
616 /***********************************************************************
617 * OleUIPasteSpecialA (OLEDLG.4)
619 UINT WINAPI
OleUIPasteSpecialA(LPOLEUIPASTESPECIALA psA
)
621 OLEUIPASTESPECIALW ps
;
623 TRACE("(%p)\n", psA
);
625 memcpy(&ps
, psA
, psA
->cbStruct
);
627 ps
.lpszCaption
= strdupAtoW(psA
->lpszCaption
);
628 if(!IS_INTRESOURCE(ps
.lpszTemplate
))
629 ps
.lpszTemplate
= strdupAtoW(psA
->lpszTemplate
);
631 if(psA
->cPasteEntries
> 0)
633 DWORD size
= psA
->cPasteEntries
* sizeof(ps
.arrPasteEntries
[0]);
636 ps
.arrPasteEntries
= HeapAlloc(GetProcessHeap(), 0, size
);
637 memcpy(ps
.arrPasteEntries
, psA
->arrPasteEntries
, size
);
638 for(i
= 0; i
< psA
->cPasteEntries
; i
++)
640 ps
.arrPasteEntries
[i
].lpstrFormatName
=
641 strdupAtoW(psA
->arrPasteEntries
[i
].lpstrFormatName
);
642 ps
.arrPasteEntries
[i
].lpstrResultText
=
643 strdupAtoW(psA
->arrPasteEntries
[i
].lpstrResultText
);
647 ret
= OleUIPasteSpecialW(&ps
);
649 if(psA
->cPasteEntries
> 0)
652 for(i
= 0; i
< psA
->cPasteEntries
; i
++)
654 HeapFree(GetProcessHeap(), 0, (WCHAR
*)ps
.arrPasteEntries
[i
].lpstrFormatName
);
655 HeapFree(GetProcessHeap(), 0, (WCHAR
*)ps
.arrPasteEntries
[i
].lpstrResultText
);
657 HeapFree(GetProcessHeap(), 0, ps
.arrPasteEntries
);
659 if(!IS_INTRESOURCE(ps
.lpszTemplate
))
660 HeapFree(GetProcessHeap(), 0, (WCHAR
*)ps
.lpszTemplate
);
661 HeapFree(GetProcessHeap(), 0, (WCHAR
*)ps
.lpszCaption
);
663 /* Copy back the output fields */
664 psA
->dwFlags
= ps
.dwFlags
;
665 psA
->lpSrcDataObj
= ps
.lpSrcDataObj
;
666 psA
->nSelectedIndex
= ps
.nSelectedIndex
;
667 psA
->fLink
= ps
.fLink
;
668 psA
->hMetaPict
= ps
.hMetaPict
;
669 psA
->sizel
= ps
.sizel
;
674 /***********************************************************************
675 * OleUIPasteSpecialW (OLEDLG.22)
677 UINT WINAPI
OleUIPasteSpecialW(LPOLEUIPASTESPECIALW ps
)
679 LPCDLGTEMPLATEW dlg_templ
= (LPCDLGTEMPLATEW
)ps
->hResource
;
684 if(TRACE_ON(ole
)) dump_pastespecial(ps
);
686 if(!ps
->lpSrcDataObj
)
687 OleGetClipboard(&ps
->lpSrcDataObj
);
689 if(ps
->hInstance
|| !ps
->hResource
)
691 HINSTANCE hInst
= ps
->hInstance
? ps
->hInstance
: OLEDLG_hInstance
;
692 const WCHAR
*name
= ps
->hInstance
? ps
->lpszTemplate
: MAKEINTRESOURCEW(IDD_PASTESPECIAL4
);
695 if(name
== NULL
) return OLEUI_ERR_LPSZTEMPLATEINVALID
;
696 hrsrc
= FindResourceW(hInst
, name
, MAKEINTRESOURCEW(RT_DIALOG
));
697 if(!hrsrc
) return OLEUI_ERR_FINDTEMPLATEFAILURE
;
698 dlg_templ
= LoadResource(hInst
, hrsrc
);
699 if(!dlg_templ
) return OLEUI_ERR_LOADTEMPLATEFAILURE
;
702 ret
= DialogBoxIndirectParamW(OLEDLG_hInstance
, dlg_templ
, ps
->hWndOwner
, ps_dlg_proc
, (LPARAM
)ps
);