* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#define COM_NO_WINDOWS_H
#define COBJMACROS
+#define NONAMELESSSTRUCT
+#define NONAMELESSUNION
#include <stdarg.h>
#include "oledlg.h"
#include "oledlg_private.h"
+#include "resource.h"
#include "wine/debug.h"
+#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
{
OLEUIPASTESPECIALW *ps;
DWORD flags;
+ WCHAR *source_name;
+ WCHAR *link_source_name;
+ WCHAR *type_name;
+ WCHAR *link_type_name;
+ LPOLESTR app_name;
} ps_struct_t;
static const struct ps_flag
TRACE("flags %08x %s\n", flags, flagstr);
}
-static void dump_pastespecial(LPOLEUIPASTESPECIALW ps)
+static void dump_pastespecial(const OLEUIPASTESPECIALW *ps)
{
UINT i;
dump_ps_flags(ps->dwFlags);
return ret;
}
+static inline WCHAR *strdupW(const WCHAR *str)
+{
+ DWORD len;
+ WCHAR *ret;
+ if(!str) return NULL;
+ len = lstrlenW(str) + 1;
+ ret = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ memcpy(ret, str, len * sizeof(WCHAR));
+ return ret;
+}
+
+static void get_descriptors(HWND hdlg, ps_struct_t *ps_struct)
+{
+ FORMATETC fmtetc;
+ STGMEDIUM stg;
+
+ fmtetc.tymed = TYMED_HGLOBAL;
+ fmtetc.dwAspect = DVASPECT_CONTENT;
+ fmtetc.ptd = NULL;
+ fmtetc.lindex = -1;
+
+ fmtetc.cfFormat = cf_object_descriptor;
+ if(IDataObject_GetData(ps_struct->ps->lpSrcDataObj, &fmtetc, &stg) == S_OK)
+ {
+ OBJECTDESCRIPTOR *obj_desc = GlobalLock(stg.u.hGlobal);
+ if(obj_desc->dwSrcOfCopy)
+ ps_struct->source_name = strdupW((WCHAR*)((char*)obj_desc + obj_desc->dwSrcOfCopy));
+ if(obj_desc->dwFullUserTypeName)
+ ps_struct->type_name = strdupW((WCHAR*)((char*)obj_desc + obj_desc->dwFullUserTypeName));
+ OleRegGetUserType(&obj_desc->clsid, USERCLASSTYPE_APPNAME, &ps_struct->app_name);
+ /* Get the icon here. If dwDrawAspect & DVASCPECT_ICON call GetData(CF_METAFILEPICT), otherwise
+ native calls OleGetIconFromClass(obj_desc->clsid) */
+ GlobalUnlock(stg.u.hGlobal);
+ GlobalFree(stg.u.hGlobal);
+ }
+ else
+ {
+ /* Try to get some data using some of the other clipboard formats */
+ }
+
+ fmtetc.cfFormat = cf_link_src_descriptor;
+ if(IDataObject_GetData(ps_struct->ps->lpSrcDataObj, &fmtetc, &stg) == S_OK)
+ {
+ OBJECTDESCRIPTOR *obj_desc = GlobalLock(stg.u.hGlobal);
+ if(obj_desc->dwSrcOfCopy)
+ ps_struct->link_source_name = strdupW((WCHAR*)((char*)obj_desc + obj_desc->dwSrcOfCopy));
+ if(obj_desc->dwFullUserTypeName)
+ ps_struct->link_type_name = strdupW((WCHAR*)((char*)obj_desc + obj_desc->dwFullUserTypeName));
+ GlobalUnlock(stg.u.hGlobal);
+ GlobalFree(stg.u.hGlobal);
+ }
+
+ if(ps_struct->source_name == NULL && ps_struct->link_source_name == NULL)
+ {
+ WCHAR buf[200];
+ LoadStringW(OLEDLG_hInstance, IDS_PS_UNKNOWN_SRC, buf, sizeof(buf)/sizeof(WCHAR));
+ ps_struct->source_name = strdupW(buf);
+ }
+
+ if(ps_struct->type_name == NULL && ps_struct->link_type_name == NULL)
+ {
+ WCHAR buf[200];
+ LoadStringW(OLEDLG_hInstance, IDS_PS_UNKNOWN_TYPE, buf, sizeof(buf)/sizeof(WCHAR));
+ ps_struct->type_name = strdupW(buf);
+ }
+}
+
static BOOL add_entry_to_lb(HWND hdlg, UINT id, OLEUIPASTEENTRYW *pe)
{
HWND hwnd = GetDlgItem(hdlg, id);
DWORD src_fmt, req_fmt;
for(req_fmt = 0; req_fmt < ps->cPasteEntries; req_fmt++)
{
- /* This is used by update_struct() to set nSelectedIndex on exit */
+ /* This is used by update_structure() to set nSelectedIndex on exit */
ps->arrPasteEntries[req_fmt].dwScratchSpace = req_fmt;
TRACE("req_fmt %x\n", ps->arrPasteEntries[req_fmt].fmtetc.cfFormat);
for(src_fmt = 0; src_fmt < fetched; src_fmt++)
EnableWindow(GetDlgItem(hdlg, IDOK), 0);
}
+static void update_src_text(HWND hdlg, const ps_struct_t *ps_struct)
+{
+ WCHAR *str;
+
+ if(ps_struct->flags & PSF_SELECTPASTE)
+ {
+ if(ps_struct->source_name)
+ str = ps_struct->source_name;
+ else
+ str = ps_struct->link_source_name;
+
+ }
+ else
+ {
+ if(ps_struct->link_source_name)
+ str = ps_struct->link_source_name;
+ else
+ str = ps_struct->source_name;
+
+ }
+ SetDlgItemTextW(hdlg, IDC_PS_SOURCETEXT, str);
+}
+
+static void update_as_icon(HWND hdlg, ps_struct_t *ps_struct)
+{
+ HWND icon_display = GetDlgItem(hdlg, IDC_PS_ICONDISPLAY);
+ HWND display_as_icon = GetDlgItem(hdlg, IDC_PS_DISPLAYASICON);
+ HWND change_icon = GetDlgItem(hdlg, IDC_PS_CHANGEICON);
+
+ /* FIXME. No as icon handling */
+ ps_struct->flags &= ~PSF_CHECKDISPLAYASICON;
+
+ CheckDlgButton(hdlg, IDC_PS_DISPLAYASICON, ps_struct->flags & PSF_CHECKDISPLAYASICON);
+ EnableWindow(display_as_icon, 0);
+ ShowWindow(icon_display, SW_HIDE);
+ EnableWindow(icon_display, 0);
+ ShowWindow(change_icon, SW_HIDE);
+ EnableWindow(change_icon, 0);
+}
+
+static void update_result_text(HWND hdlg, const ps_struct_t *ps_struct)
+{
+ WCHAR resource_txt[200];
+ UINT res_id;
+ OLEUIPASTEENTRYW *pent;
+ LONG cur_sel;
+ static const WCHAR percent_s[] = {'%','s',0};
+ WCHAR *result_txt, *ptr;
+
+ cur_sel = SendMessageW(GetDlgItem(hdlg, IDC_PS_DISPLAYLIST), LB_GETCURSEL, 0, 0);
+ if(cur_sel == -1) return;
+ pent = (OLEUIPASTEENTRYW*)SendMessageW(GetDlgItem(hdlg, IDC_PS_DISPLAYLIST), LB_GETITEMDATA, cur_sel, 0);
+
+ if(ps_struct->flags & PSF_SELECTPASTE)
+ {
+ if(ps_struct->flags & PSF_CHECKDISPLAYASICON)
+ res_id = IDS_PS_PASTE_OBJECT_AS_ICON;
+ else
+ res_id = IDS_PS_PASTE_DATA;
+ }
+ else
+ {
+ if(ps_struct->flags & PSF_CHECKDISPLAYASICON)
+ res_id = IDS_PS_PASTE_LINK_OBJECT_AS_ICON;
+ else
+ res_id = IDS_PS_PASTE_LINK_DATA;
+ }
+
+ LoadStringW(OLEDLG_hInstance, res_id, resource_txt, sizeof(resource_txt)/sizeof(WCHAR));
+ if((ptr = strstrW(resource_txt, percent_s)))
+ {
+ /* FIXME handle %s in ResultText. Sub appname if IDS_PS_PASTE_OBJECT{_AS_ICON}. Else sub appropriate type name */
+ size_t result_txt_len = strlenW(pent->lpstrResultText);
+ ptrdiff_t offs = (char*)ptr - (char*)resource_txt;
+ result_txt = HeapAlloc(GetProcessHeap(), 0, (strlenW(resource_txt) + result_txt_len - 1) * sizeof(WCHAR));
+ memcpy(result_txt, resource_txt, offs);
+ memcpy((char*)result_txt + offs, pent->lpstrResultText, result_txt_len * sizeof(WCHAR));
+ memcpy((char*)result_txt + offs + result_txt_len * sizeof(WCHAR), ptr + 2, (strlenW(ptr + 2) + 1) * sizeof(WCHAR));
+ }
+ else
+ result_txt = resource_txt;
+
+ SetDlgItemTextW(hdlg, IDC_PS_RESULTTEXT, result_txt);
+
+ if(result_txt != resource_txt)
+ HeapFree(GetProcessHeap(), 0, result_txt);
+
+}
+
+static void selection_change(HWND hdlg, ps_struct_t *ps_struct)
+{
+ update_as_icon(hdlg, ps_struct);
+ update_result_text(hdlg, ps_struct);
+}
+
+static void mode_change(HWND hdlg, ps_struct_t *ps_struct, UINT id)
+{
+ if(id == IDC_PS_PASTE)
+ {
+ ps_struct->flags &= ~PSF_SELECTPASTELINK;
+ ps_struct->flags |= PSF_SELECTPASTE;
+ }
+ else
+ {
+ ps_struct->flags &= ~PSF_SELECTPASTE;
+ ps_struct->flags |= PSF_SELECTPASTELINK;
+ }
+
+ update_src_text(hdlg, ps_struct);
+ update_display_list(hdlg, id == IDC_PS_PASTE ? IDC_PS_PASTELIST : IDC_PS_PASTELINKLIST);
+ selection_change(hdlg, ps_struct);
+}
+
static void post_help_msg(HWND hdlg, ps_struct_t *ps_struct)
{
PostMessageW(ps_struct->ps->hWndOwner, oleui_msg_help, (WPARAM)hdlg, IDD_PASTESPECIAL);
static void update_structure(HWND hdlg, ps_struct_t *ps_struct)
{
+ LONG cur_sel = SendMessageW(GetDlgItem(hdlg, IDC_PS_DISPLAYLIST), LB_GETCURSEL, 0, 0);
+ if(cur_sel != -1)
+ {
+ OLEUIPASTEENTRYW *pent;
+ pent = (OLEUIPASTEENTRYW *)SendMessageW(GetDlgItem(hdlg, IDC_PS_DISPLAYLIST), LB_GETITEMDATA, cur_sel, 0);
+ ps_struct->ps->nSelectedIndex = pent->dwScratchSpace;
+ }
ps_struct->ps->dwFlags = ps_struct->flags;
ps_struct->ps->fLink = (ps_struct->flags & PSF_SELECTPASTELINK) ? TRUE : FALSE;
}
static void free_structure(ps_struct_t *ps_struct)
{
+ HeapFree(GetProcessHeap(), 0, ps_struct->type_name);
+ HeapFree(GetProcessHeap(), 0, ps_struct->source_name);
+ HeapFree(GetProcessHeap(), 0, ps_struct->link_type_name);
+ HeapFree(GetProcessHeap(), 0, ps_struct->link_source_name);
+ CoTaskMemFree(ps_struct->app_name);
HeapFree(GetProcessHeap(), 0, ps_struct);
}
static const WCHAR prop_name[] = {'W','i','n','e','_','S','t','r','u','c','t','u','r','e',0};
ps_struct_t *ps_struct;
- TRACE("(%p, %04x, %08x, %08lx)\n", hdlg, msg, wp, lp);
+ TRACE("(%p, %04x, %08lx, %08lx)\n", hdlg, msg, wp, lp);
ps_struct = GetPropW(hdlg, prop_name);
{
if(!ps_struct)
return 0;
+
+ if(ps_struct->ps->lpfnHook)
+ {
+ INT_PTR ret = ps_struct->ps->lpfnHook(hdlg, msg, wp, lp);
+ if(ret) return ret;
+ }
}
switch(msg)
{
ps_struct = HeapAlloc(GetProcessHeap(), 0, sizeof(*ps_struct));
ps_struct->ps = (OLEUIPASTESPECIALW*)lp;
+ ps_struct->type_name = NULL;
+ ps_struct->source_name = NULL;
+ ps_struct->link_type_name = NULL;
+ ps_struct->link_source_name = NULL;
+ ps_struct->app_name = NULL;
ps_struct->flags = ps_struct->ps->dwFlags;
SetPropW(hdlg, prop_name, ps_struct);
EnableWindow(GetDlgItem(hdlg, IDC_OLEUIHELP), 0);
}
- if(ps_struct->ps->lpszCaption)
+ if(ps_struct->ps->lpszCaption)
SetWindowTextW(hdlg, ps_struct->ps->lpszCaption);
+ get_descriptors(hdlg, ps_struct);
+
init_lists(hdlg, ps_struct);
- return TRUE; /* use default focus */
+ update_src_text(hdlg, ps_struct);
+
+ selection_change(hdlg, ps_struct);
+
+ SetFocus(GetDlgItem(hdlg, IDC_PS_DISPLAYLIST));
+
+ if(ps_struct->ps->lpfnHook)
+ ps_struct->ps->lpfnHook(hdlg, msg, 0, 0);
+ return FALSE; /* use new focus */
}
case WM_COMMAND:
switch(LOWORD(wp))
{
+ case IDC_PS_DISPLAYLIST:
+ switch(HIWORD(wp))
+ {
+ case LBN_SELCHANGE:
+ selection_change(hdlg, ps_struct);
+ return FALSE;
+ default:
+ return FALSE;
+ }
+ case IDC_PS_PASTE:
+ case IDC_PS_PASTELINK:
+ switch(HIWORD(wp))
+ {
+ case BN_CLICKED:
+ mode_change(hdlg, ps_struct, LOWORD(wp));
+ return FALSE;
+
+ default:
+ return FALSE;
+ }
case IDC_OLEUIHELP:
switch(HIWORD(wp))
{
}
case IDOK:
case IDCANCEL:
- send_end_dialog_msg(hdlg, ps_struct, LOWORD(wp));
- return FALSE;
+ switch(HIWORD(wp))
+ {
+ case BN_CLICKED:
+ send_end_dialog_msg(hdlg, ps_struct, LOWORD(wp));
+ return FALSE;
+ default:
+ return FALSE;
+ }
}
return FALSE;
default:
if(wp == IDOK)
update_structure(hdlg, ps_struct);
EndDialog(hdlg, wp);
+ /* native does its cleanup in WM_DESTROY */
+ RemovePropW(hdlg, prop_name);
free_structure(ps_struct);
return TRUE;
}
if(psA->cPasteEntries > 0)
{
DWORD size = psA->cPasteEntries * sizeof(ps.arrPasteEntries[0]);
- UINT i;
+ INT i;
ps.arrPasteEntries = HeapAlloc(GetProcessHeap(), 0, size);
memcpy(ps.arrPasteEntries, psA->arrPasteEntries, size);
if(psA->cPasteEntries > 0)
{
- UINT i;
+ INT i;
for(i = 0; i < psA->cPasteEntries; i++)
{
HeapFree(GetProcessHeap(), 0, (WCHAR*)ps.arrPasteEntries[i].lpstrFormatName);
UINT WINAPI OleUIPasteSpecialW(LPOLEUIPASTESPECIALW ps)
{
LPCDLGTEMPLATEW dlg_templ = (LPCDLGTEMPLATEW)ps->hResource;
+ UINT ret;
TRACE("(%p)\n", ps);
if(!dlg_templ) return OLEUI_ERR_LOADTEMPLATEFAILURE;
}
- DialogBoxIndirectParamW(OLEDLG_hInstance, dlg_templ, ps->hWndOwner, ps_dlg_proc, (LPARAM)ps);
+ ret = DialogBoxIndirectParamW(OLEDLG_hInstance, dlg_templ, ps->hWndOwner, ps_dlg_proc, (LPARAM)ps);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return OLEUI_FALSE;
+ return ret;
}