shel32.dll part:

* Clipboard implemtation in win32k and user32
* Added a clipboard system for each Window Station
* GetLastInputInfo implementation
* GetLayout in win32k Stubs
* Shell32 changes to cut/copy & paste link/paste
* Implemented ALT+PrintScreen to clipboard

svn path=/trunk/; revision=23811
This commit is contained in:
Pablo Borobia 2006-08-30 19:35:54 +00:00
parent 5a624910f1
commit 38bee199b7
5 changed files with 355 additions and 43 deletions

View file

@ -148,6 +148,8 @@ void FreeChangeNotifications(void);
BOOL SHELL_DeleteDirectoryA(LPCSTR pszDir, BOOL bShowUI);
BOOL SHELL_DeleteFileA(LPCSTR pszFile, BOOL bShowUI);
BOOL SHELL_ConfirmDialog(int nKindOfDialog, LPCSTR szDir);
DWORD SHNotifyMoveFileA(LPCSTR src, LPCSTR dest);
DWORD SHNotifyCopyFileA(LPCSTR src, LPCSTR dest, BOOL bFailIfExists);
/* 16-bit functions */
void WINAPI DragAcceptFiles16(HWND16 hWnd, BOOL16 b);

View file

@ -1154,6 +1154,8 @@ ISFHelper_fnAddFolder (ISFHelper * iface, HWND hwnd, LPCSTR lpName,
return hres;
}
extern BOOL fileMoving;
/****************************************************************************
* ISFHelper_fnDeleteItems
*
@ -1236,7 +1238,8 @@ ISFHelper_fnCopyItems (ISFHelper * iface, IShellFolder * pSFFrom, UINT cidl,
LPITEMIDLIST pidl;
if (SUCCEEDED (IPersistFolder2_GetCurFolder (ppf2, &pidl))) {
for (i = 0; i < cidl; i++) {
for (i = 0; i < cidl; i++)
{
SHGetPathFromIDListA (pidl, szSrcPath);
PathAddBackslashA (szSrcPath);
_ILSimpleGetText (apidl[i], szSrcPath + strlen (szSrcPath),
@ -1244,9 +1247,43 @@ ISFHelper_fnCopyItems (ISFHelper * iface, IShellFolder * pSFFrom, UINT cidl,
strcpy (szDstPath, This->sPathTarget);
PathAddBackslashA (szDstPath);
_ILSimpleGetText (apidl[i], szDstPath + strlen (szDstPath),
MAX_PATH);
MESSAGE ("would copy %s to %s\n", szSrcPath, szDstPath);
_ILSimpleGetText (apidl[i], szDstPath + strlen (szDstPath), MAX_PATH);
DPRINT1 ("copy %s to %s\n", szSrcPath, szDstPath);
if (fileMoving)
{
fileMoving = FALSE;
SHNotifyMoveFileA(szSrcPath, szDstPath);
}
else
{
SHNotifyCopyFileA(szSrcPath, szDstPath, TRUE);
}
/*
SHFILEOPSTRUCTA op;
if (fileMoving)
{
op.wFunc = FO_MOVE;
fileMoving = FALSE;
}
else
{
op.wFunc = FO_COPY;
}
op.pTo = szDstPath;
op.pFrom = szSrcPath;
op.fFlags = FOF_SIMPLEPROGRESS;
op.hwnd = NULL;
op.hNameMappings = NULL;
op.lpszProgressTitle = NULL;
UINT bRes = SHFileOperationA(&op);
DbgPrint("CopyItems SHFileOperationA 0x%08x\n", bRes);
*/
}
SHFree (pidl);
}
@ -1558,9 +1595,11 @@ static HRESULT WINAPI
ISFDropTarget_Drop (IDropTarget * iface, IDataObject * pDataObject,
DWORD dwKeyState, POINTL pt, DWORD * pdwEffect)
{
DWORD dwEffect = *pdwEffect;
IGenericSFImpl *This = impl_from_IDropTarget(iface);
FIXME ("(%p) object dropped\n", This);
FIXME ("(%p) object dropped(%d)\n", This, dwKeyState);
return E_NOTIMPL;
}

View file

@ -478,6 +478,65 @@ static DWORD SHNotifyCopyFileW(LPCWSTR src, LPCWSTR dest, BOOL bFailIfExists)
return GetLastError();
}
DWORD SHNotifyMoveFileA(LPCSTR src, LPCSTR dest)
{
BOOL ret;
LPWSTR destW;
ret = MoveFileA(src, dest);
if (!ret)
{
DWORD dwAttr;
SHELL32_AnsiToUnicodeBuf(dest, &destW, 0);
dwAttr = SHFindAttrW(destW, FALSE);
SHELL32_FreeUnicodeBuf(destW);
if (INVALID_FILE_ATTRIBUTES == dwAttr)
{
/* Source file may be write protected or a system file */
dwAttr = GetFileAttributesA(src);
if (IsAttrib(dwAttr, FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM))
if (SetFileAttributesA(src, dwAttr & ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)))
ret = MoveFileA(src, dest);
}
}
if (ret)
{
//SHChangeNotify(SHCNE_RENAMEITEM, SHCNF_PATHA, src, dest);
SHChangeNotify(SHCNE_CREATE, SHCNF_PATHA, dest, NULL);
SHChangeNotify(SHCNE_DELETE, SHCNF_PATHA, src, NULL);
return ERROR_SUCCESS;
}
return GetLastError();
}
/************************************************************************
* SHNotifyCopyFile [internal]
*
* Copies a file. Also triggers a change notify if one exists.
*
* PARAMS
* src [I] path to source file to move
* dest [I] path to target file to move to
* bFailIfExists [I] if TRUE, the target file will not be overwritten if
* a file with this name already exists
*
* RETURNS
* ERROR_SUCCESS if successful
*/
DWORD SHNotifyCopyFileA(LPCSTR src, LPCSTR dest, BOOL bFailIfExists)
{
BOOL ret;
ret = CopyFileA(src, dest, bFailIfExists);
if (ret)
{
SHChangeNotify(SHCNE_CREATE, SHCNF_PATHA, dest, NULL);
return ERROR_SUCCESS;
}
return GetLastError();
}
/*************************************************************************
* SHCreateDirectory [SHELL32.165]
*
@ -649,7 +708,29 @@ static DWORD SHFindAttrW(LPCWSTR pName, BOOL fileOnly)
}
return dwAttr;
}
/*
DWORD SHFindAttrA(LPSTR pName, BOOL fileOnly)
{
WIN32_FIND_DATAA wfd;
BOOL b_FileMask = fileOnly && (NULL != StrPBrkA(pName, wWildcardChars));
DWORD dwAttr = INVALID_FILE_ATTRIBUTES;
HANDLE hFind = FindFirstFileA(pName, &wfd);
if (INVALID_HANDLE_VALUE != hFind)
{
do
{
if (b_FileMask && IsAttribDir(wfd.dwFileAttributes))
continue;
dwAttr = wfd.dwFileAttributes;
break;
}
while (FindNextFileA(hFind, &wfd));
FindClose(hFind);
}
return dwAttr;
}
*/
/*************************************************************************
*
* SHFileStrICmp HelperFunction for SHFileOperationW

View file

@ -38,6 +38,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(shell);
extern BOOL fileMoving;
/**************************************************************************
* IContextMenu Implementation
*/
@ -215,6 +217,198 @@ static void DoNewFolder(
}
}
/***************************************************************************/
static BOOL DoLink(LPCSTR pSrcFile, LPCSTR pDstFile)
{
IShellLinkA *psl = NULL;
IPersistFile *pPf = NULL;
HRESULT hres;
WCHAR widelink[MAX_PATH];
BOOL ret = FALSE;
CoInitialize(0);
hres = CoCreateInstance( &CLSID_ShellLink,
NULL,
CLSCTX_INPROC_SERVER,
&IID_IShellLinkA,
(LPVOID )&psl);
if(SUCCEEDED(hres)) {
hres = IShellLinkA_QueryInterface(psl, &IID_IPersistFile,
(LPVOID *)&pPf);
if(FAILED(hres))
{
ERR("failed QueryInterface for IPersistFile %08lx\n", hres);
goto fail;
}
DPRINT1("shortcut point to %s\n", pSrcFile);
hres = IShellLinkA_SetPath(psl, pSrcFile);
if(FAILED(hres))
{
ERR("failed Set{IDList|Path} %08lx\n", hres);
goto fail;
}
MultiByteToWideChar(CP_ACP, 0, pDstFile, -1,
widelink, MAX_PATH);
/* create the short cut */
hres = IPersistFile_Save(pPf, widelink, TRUE);
if(FAILED(hres))
{
ERR("failed IPersistFile::Save %08lx\n", hres);
IPersistFile_Release(pPf);
IShellLinkA_Release(psl);
goto fail;
}
hres = IPersistFile_SaveCompleted(pPf, widelink);
IPersistFile_Release(pPf);
IShellLinkA_Release(psl);
DPRINT1("shortcut %s has been created, result=%08lx\n",
pDstFile, hres);
ret = TRUE;
}
else {
DPRINT1("CoCreateInstance failed, hres=%08lx\n", hres);
}
fail:
CoUninitialize();
return ret;
}
static BOOL MakeLink(
IContextMenu2 *iface)
{
BgCmImpl *This = (BgCmImpl *)iface;
BOOL bSuccess = FALSE;
IDataObject * pda;
TRACE("\n");
if(SUCCEEDED(OleGetClipboard(&pda)))
{
STGMEDIUM medium;
FORMATETC formatetc;
TRACE("pda=%p\n", pda);
/* Set the FORMATETC structure*/
InitFormatEtc(formatetc, RegisterClipboardFormatA(CFSTR_SHELLIDLIST), TYMED_HGLOBAL);
/* Get the pidls from IDataObject */
if(SUCCEEDED(IDataObject_GetData(pda, &formatetc, &medium)))
{
LPITEMIDLIST * apidl;
LPITEMIDLIST pidl;
IShellFolder *psfFrom = NULL, *psfDesktop;
LPIDA lpcida = GlobalLock(medium.u.hGlobal);
TRACE("cida=%p\n", lpcida);
apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
/* bind to the source shellfolder */
SHGetDesktopFolder(&psfDesktop);
if(psfDesktop)
{
IShellFolder_BindToObject(psfDesktop, pidl, NULL, &IID_IShellFolder, (LPVOID*)&psfFrom);
IShellFolder_Release(psfDesktop);
}
if (psfFrom)
{
/* get source and destination shellfolder */
IPersistFolder2 *ppfdst = NULL;
IPersistFolder2 *ppfsrc = NULL;
IShellFolder_QueryInterface(This->pSFParent, &IID_IPersistFolder2, (LPVOID*)&ppfdst);
IShellFolder_QueryInterface(psfFrom, &IID_IPersistFolder2, (LPVOID*)&ppfsrc);
DPRINT1("[%p,%p]\n",ppfdst,ppfsrc);
/* do the link/s */
/* hack to get desktop path */
if ( (ppfdst && ppfsrc) || (This->bDesktop && ppfsrc) )
{
int i;
char szSrcPath[MAX_PATH];
char szDstPath[MAX_PATH];
BOOL ret = FALSE;
LPITEMIDLIST pidl2;
char filename[MAX_PATH];
char linkFilename[MAX_PATH];
char srcFilename[MAX_PATH];
DbgPrint("&&&");
IPersistFolder2_GetCurFolder(ppfsrc, &pidl2);
SHGetPathFromIDListA (pidl2, szSrcPath);
if (This->bDesktop)
{
SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, &pidl2);
SHGetPathFromIDListA (pidl2, szDstPath);
}
else
{
IPersistFolder2_GetCurFolder(ppfdst, &pidl2);
SHGetPathFromIDListA (pidl2, szDstPath);
}
for (i = 0; i < lpcida->cidl; i++)
{
_ILSimpleGetText (apidl[i], filename, MAX_PATH);
DbgPrint("filename %s\n", filename);
lstrcpyA(linkFilename, szDstPath);
PathAddBackslashA(linkFilename);
//lstrcatA(linkFilename, "Shortcut to ");
lstrcatA(linkFilename, filename);
lstrcatA(linkFilename, ".lnk");
DbgPrint("linkFilename %s\n", linkFilename);
lstrcpyA(srcFilename, szSrcPath);
PathAddBackslashA(srcFilename);
lstrcatA(srcFilename, filename);
DbgPrint("srcFilename %s\n", srcFilename);
ret = DoLink(srcFilename, linkFilename);
if (ret)
{
SHChangeNotify(SHCNE_CREATE, SHCNF_PATHA, linkFilename, NULL);
}
}
}
if(ppfdst) IPersistFolder2_Release(ppfdst);
if(ppfsrc) IPersistFolder2_Release(ppfsrc);
IShellFolder_Release(psfFrom);
}
_ILFreeaPidl(apidl, lpcida->cidl);
SHFree(pidl);
/* release the medium*/
ReleaseStgMedium(&medium);
}
IDataObject_Release(pda);
}
return bSuccess;
}
/**************************************************************************
* DoPaste
*/
@ -238,7 +432,7 @@ static BOOL DoPaste(
InitFormatEtc(formatetc, RegisterClipboardFormatA(CFSTR_SHELLIDLIST), TYMED_HGLOBAL);
/* Get the pidls from IDataObject */
if(SUCCEEDED(IDataObject_GetData(pda,&formatetc,&medium)))
if(SUCCEEDED(IDataObject_GetData(pda, &formatetc, &medium)))
{
LPITEMIDLIST * apidl;
LPITEMIDLIST pidl;
@ -261,17 +455,28 @@ static BOOL DoPaste(
{
/* get source and destination shellfolder */
ISFHelper *psfhlpdst, *psfhlpsrc;
if (This->bDesktop)
{
/* unimplemented*/
SHGetDesktopFolder(&psfDesktop);
IFSFolder_Constructor(psfDesktop, &IID_ISFHelper, (LPVOID*)&psfhlpdst);
IShellFolder_QueryInterface(psfhlpdst, &IID_ISFHelper, (LPVOID*)&psfhlpdst);
}
else
{
IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper, (LPVOID*)&psfhlpdst);
}
IShellFolder_QueryInterface(psfFrom, &IID_ISFHelper, (LPVOID*)&psfhlpsrc);
DPRINT1("[%p,%p]\n",psfhlpdst,psfhlpsrc);
/* do the copy/move */
if (psfhlpdst && psfhlpsrc)
{
ISFHelper_CopyItems(psfhlpdst, psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl);
/* FIXME handle move
ISFHelper_DeleteItems(psfhlpsrc, lpcida->cidl, apidl);
*/
}
if(psfhlpdst) ISFHelper_Release(psfhlpdst);
if(psfhlpsrc) ISFHelper_Release(psfhlpsrc);
IShellFolder_Release(psfFrom);
@ -285,30 +490,7 @@ static BOOL DoPaste(
}
IDataObject_Release(pda);
}
#if 0
HGLOBAL hMem;
OpenClipboard(NULL);
hMem = GetClipboardData(CF_HDROP);
if(hMem)
{
char * pDropFiles = (char *)GlobalLock(hMem);
if(pDropFiles)
{
int len, offset = sizeof(DROPFILESTRUCT);
while( pDropFiles[offset] != 0)
{
len = strlen(pDropFiles + offset);
TRACE("%s\n", pDropFiles + offset);
offset += len+1;
}
}
GlobalUnlock(hMem);
}
CloseClipboard();
#endif
return bSuccess;
}
@ -335,7 +517,6 @@ static HRESULT WINAPI ISVBgCm_fnInvokeCommand(
IShellView_GetWindow(lpSV, &hWndSV);
}
}
if(HIWORD(lpcmi->lpVerb))
{
TRACE("%s\n",lpcmi->lpVerb);
@ -373,6 +554,10 @@ static HRESULT WINAPI ISVBgCm_fnInvokeCommand(
DoPaste(iface);
break;
case FCIDM_SHVIEW_INSERTLINK:
MakeLink(iface);
break;
case FCIDM_SHVIEW_PROPERTIES:
if (This->bDesktop) {
ShellExecuteA(lpcmi->hwnd, "open", "rundll32.exe shell32.dll,Control_RunDLL desk.cpl", NULL, NULL, SW_SHOWNORMAL);

View file

@ -39,6 +39,10 @@
WINE_DEFAULT_DEBUG_CHANNEL(shell);
/* ugly hack for cut&psate files */
BOOL fileMoving = FALSE;
/**************************************************************************
* IContextMenu Implementation
*/
@ -374,9 +378,10 @@ static BOOL DoCopyOrCut(
LPDATAOBJECT lpDo;
TRACE("(%p)->(wnd=%p,bCut=0x%08x)\n",This, hwnd, bCut);
fileMoving = bCut;
/* get the active IShellView */
if ((lpSB = (LPSHELLBROWSER)SendMessageA(hwnd, CWM_GETISHELLBROWSER,0,0)))
if ((lpSB = (LPSHELLBROWSER)SendMessageA(hwnd, CWM_GETISHELLBROWSER, 0, 0)))
{
if (SUCCEEDED(IShellBrowser_QueryActiveShellView(lpSB, &lpSV)))
{