diff --git a/dlls/shell32/clipboard.c b/dlls/shell32/clipboard.c index 07a0447a722..4ab2e99d4ad 100644 --- a/dlls/shell32/clipboard.c +++ b/dlls/shell32/clipboard.c @@ -43,6 +43,7 @@ #include "shell32_main.h" #include "shlwapi.h" +#include "wine/unicode.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(shell); @@ -202,7 +203,7 @@ HGLOBAL RenderFILEDESCRIPTOR (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT return 0; } -HGLOBAL RenderFILENAME (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) +HGLOBAL RenderFILENAMEA (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) { int len, size = 0; char szTemp[MAX_PATH], *szFileName; @@ -220,7 +221,32 @@ HGLOBAL RenderFILENAME (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) /* fill the structure */ hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size); if(!hGlobal) return hGlobal; - szFileName = (char *)GlobalLock(hGlobal); + szFileName = (char *)GlobalLock(hGlobal); + memcpy(szFileName, szTemp, size); + GlobalUnlock(hGlobal); + return hGlobal; +} + +HGLOBAL RenderFILENAMEW (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) +{ + int len, size = 0; + WCHAR szTemp[MAX_PATH], *szFileName; + HGLOBAL hGlobal; + + TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl); + + /* build name of first file */ + SHGetPathFromIDListW(pidlRoot, szTemp); + PathAddBackslashW(szTemp); + len = strlenW(szTemp); + _ILSimpleGetTextW(apidl[0], szTemp+len, MAX_PATH - len); + size = sizeof(WCHAR) * (strlenW(szTemp)+1); + + /* fill the structure */ + hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size); + if(!hGlobal) return hGlobal; + szFileName = (WCHAR *)GlobalLock(hGlobal); + memcpy(szFileName, szTemp, size); GlobalUnlock(hGlobal); return hGlobal; } diff --git a/dlls/shell32/dataobject.c b/dlls/shell32/dataobject.c index e91eac0905a..f482b288bb7 100644 --- a/dlls/shell32/dataobject.c +++ b/dlls/shell32/dataobject.c @@ -201,7 +201,7 @@ static HRESULT WINAPI IEnumFORMATETC_fnClone(LPENUMFORMATETC iface, LPENUMFORMAT */ /* number of supported formats */ -#define MAX_FORMATS 3 +#define MAX_FORMATS 4 typedef struct { @@ -216,7 +216,8 @@ typedef struct FORMATETC pFormatEtc[MAX_FORMATS]; UINT cfShellIDList; - UINT cfFileName; + UINT cfFileNameA; + UINT cfFileNameW; } IDataObjectImpl; @@ -240,10 +241,12 @@ LPDATAOBJECT IDataObject_Constructor(HWND hwndOwner, LPITEMIDLIST pMyPidl, LPITE dto->cidl = cidl; dto->cfShellIDList = RegisterClipboardFormatA(CFSTR_SHELLIDLIST); - dto->cfFileName = RegisterClipboardFormatA(CFSTR_FILENAMEA); + dto->cfFileNameA = RegisterClipboardFormatA(CFSTR_FILENAMEA); + dto->cfFileNameW = RegisterClipboardFormatA(CFSTR_FILENAMEW); InitFormatEtc(dto->pFormatEtc[0], dto->cfShellIDList, TYMED_HGLOBAL); InitFormatEtc(dto->pFormatEtc[1], CF_HDROP, TYMED_HGLOBAL); - InitFormatEtc(dto->pFormatEtc[2], dto->cfFileName, TYMED_HGLOBAL); + InitFormatEtc(dto->pFormatEtc[2], dto->cfFileNameA, TYMED_HGLOBAL); + InitFormatEtc(dto->pFormatEtc[3], dto->cfFileNameW, TYMED_HGLOBAL); } TRACE("(%p)->(apidl=%p cidl=%u)\n",dto, apidl, cidl); @@ -331,10 +334,15 @@ static HRESULT WINAPI IDataObject_fnGetData(LPDATAOBJECT iface, LPFORMATETC pfor if (This->cidl < 1) return(E_UNEXPECTED); pmedium->u.hGlobal = RenderHDROP(This->pidl, This->apidl, This->cidl); } - else if (pformatetcIn->cfFormat == This->cfFileName) + else if (pformatetcIn->cfFormat == This->cfFileNameA) { if (This->cidl < 1) return(E_UNEXPECTED); - pmedium->u.hGlobal = RenderFILENAME(This->pidl, This->apidl, This->cidl); + pmedium->u.hGlobal = RenderFILENAMEA(This->pidl, This->apidl, This->cidl); + } + else if (pformatetcIn->cfFormat == This->cfFileNameW) + { + if (This->cidl < 1) return(E_UNEXPECTED); + pmedium->u.hGlobal = RenderFILENAMEW(This->pidl, This->apidl, This->cidl); } else { diff --git a/dlls/shell32/pidl.c b/dlls/shell32/pidl.c index 6d85e46656e..4419f6c5d6e 100644 --- a/dlls/shell32/pidl.c +++ b/dlls/shell32/pidl.c @@ -1558,6 +1558,29 @@ DWORD _ILSimpleGetText (LPCITEMIDLIST pidl, LPSTR szOut, UINT uOutSize) return dwReturn; } + /************************************************************************** + * _ILSimpleGetTextW + * + * gets the text for the first item in the pidl (eg. simple pidl) + * + * returns the length of the string + */ +DWORD _ILSimpleGetTextW (LPCITEMIDLIST pidl, LPWSTR szOut, UINT uOutSize) +{ + DWORD dwReturn; + char szTemp[MAX_PATH]; + + TRACE("(%p %p %x)\n",pidl,szOut,uOutSize); + + dwReturn = _ILSimpleGetText(pidl, szTemp, uOutSize); + + if (!MultiByteToWideChar(CP_ACP, 0, szTemp, -1, szOut, MAX_PATH)) + *szOut = 0; + + TRACE("-- (%p=%s 0x%08lx)\n",szOut,debugstr_w(szOut),dwReturn); + return dwReturn; +} + /************************************************************************** * * ### 4. getting pointers to parts of pidls ### diff --git a/dlls/shell32/pidl.h b/dlls/shell32/pidl.h index c43dc4e7bea..65605d4f521 100644 --- a/dlls/shell32/pidl.h +++ b/dlls/shell32/pidl.h @@ -141,6 +141,7 @@ typedef struct tagPIDLDATA * getting special values from simple pidls */ DWORD _ILSimpleGetText (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize); +DWORD _ILSimpleGetTextW (LPCITEMIDLIST pidl, LPWSTR pOut, UINT uOutSize); BOOL _ILGetFileDate (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize); DWORD _ILGetFileSize (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize); BOOL _ILGetExtension (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize); diff --git a/dlls/shell32/shell32_main.h b/dlls/shell32/shell32_main.h index 0f64d97836e..50cd7eca0d4 100644 --- a/dlls/shell32/shell32_main.h +++ b/dlls/shell32/shell32_main.h @@ -151,7 +151,8 @@ HGLOBAL RenderSHELLIDLIST (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cid HGLOBAL RenderSHELLIDLISTOFFSET (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl); HGLOBAL RenderFILECONTENTS (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl); HGLOBAL RenderFILEDESCRIPTOR (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl); -HGLOBAL RenderFILENAME (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl); +HGLOBAL RenderFILENAMEA (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl); +HGLOBAL RenderFILENAMEW (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl); HGLOBAL RenderPREFEREDDROPEFFECT (DWORD dwFlags); /* Change Notification */ diff --git a/include/shlobj.h b/include/shlobj.h index ab166168b42..d7bc5a06ec5 100644 --- a/include/shlobj.h +++ b/include/shlobj.h @@ -111,6 +111,8 @@ extern UINT cfFileContents; #define CFSTR_PASTESUCCEEDED "Paste Succeeded" #define CFSTR_INDRAGLOOP "InShellDragLoop" +#define CFSTR_FILENAME WINELIB_NAME_AW(CFSTR_FILENAME) + /************************************************************************ * IShellView interface