Author: pborobia Date: Wed Aug 30 23:35:54 2006 New Revision: 23811
URL: http://svn.reactos.org/svn/reactos?rev=23811&view=rev Log: 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
Modified: trunk/reactos/dll/win32/shell32/shell32_main.h trunk/reactos/dll/win32/shell32/shfldr_fs.c trunk/reactos/dll/win32/shell32/shlfileop.c trunk/reactos/dll/win32/shell32/shv_bg_cmenu.c trunk/reactos/dll/win32/shell32/shv_item_cmenu.c
Modified: trunk/reactos/dll/win32/shell32/shell32_main.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shell32_m... ============================================================================== --- trunk/reactos/dll/win32/shell32/shell32_main.h (original) +++ trunk/reactos/dll/win32/shell32/shell32_main.h Wed Aug 30 23:35:54 2006 @@ -148,6 +148,8 @@ 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);
Modified: trunk/reactos/dll/win32/shell32/shfldr_fs.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shfldr_fs... ============================================================================== --- trunk/reactos/dll/win32/shell32/shfldr_fs.c (original) +++ trunk/reactos/dll/win32/shell32/shfldr_fs.c Wed Aug 30 23:35:54 2006 @@ -1154,6 +1154,8 @@ return hres; }
+extern BOOL fileMoving; + /**************************************************************************** * ISFHelper_fnDeleteItems * @@ -1168,7 +1170,7 @@ BOOL bConfirm = TRUE;
TRACE ("(%p)(%u %p)\n", This, cidl, apidl); - + /* deleting multiple items so give a slightly different warning */ if (cidl != 1) { char tmp[8]; @@ -1178,7 +1180,7 @@ return E_FAIL; bConfirm = FALSE; } - + for (i = 0; i < cidl; i++) { strcpy (szPath, This->sPathTarget); PathAddBackslashA (szPath); @@ -1236,7 +1238,8 @@ 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 @@
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 @@ 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; }
Modified: trunk/reactos/dll/win32/shell32/shlfileop.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shlfileop... ============================================================================== --- trunk/reactos/dll/win32/shell32/shlfileop.c (original) +++ trunk/reactos/dll/win32/shell32/shlfileop.c Wed Aug 30 23:35:54 2006 @@ -478,6 +478,65 @@ 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 @@ } 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
Modified: trunk/reactos/dll/win32/shell32/shv_bg_cmenu.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shv_bg_cm... ============================================================================== --- trunk/reactos/dll/win32/shell32/shv_bg_cmenu.c (original) +++ trunk/reactos/dll/win32/shell32/shv_bg_cmenu.c Wed Aug 30 23:35:54 2006 @@ -38,6 +38,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(shell);
+extern BOOL fileMoving; + /************************************************************************** * IContextMenu Implementation */ @@ -215,6 +217,198 @@ } }
+/***************************************************************************/ +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 */ @@ -226,19 +420,19 @@ 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))) + if(SUCCEEDED(IDataObject_GetData(pda, &formatetc, &medium))) { LPITEMIDLIST * apidl; LPITEMIDLIST pidl; @@ -248,7 +442,7 @@ TRACE("cida=%p\n", lpcida);
apidl = _ILCopyCidaToaPidl(&pidl, lpcida); - + /* bind to the source shellfolder */ SHGetDesktopFolder(&psfDesktop); if(psfDesktop) @@ -261,17 +455,28 @@ { /* get source and destination shellfolder */ ISFHelper *psfhlpdst, *psfhlpsrc; - IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper, (LPVOID*)&psfhlpdst); + 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 @@ } 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 @@ IShellView_GetWindow(lpSV, &hWndSV); } } - if(HIWORD(lpcmi->lpVerb)) { TRACE("%s\n",lpcmi->lpVerb); @@ -371,6 +552,10 @@
case FCIDM_SHVIEW_INSERT: DoPaste(iface); + break; + + case FCIDM_SHVIEW_INSERTLINK: + MakeLink(iface); break;
case FCIDM_SHVIEW_PROPERTIES:
Modified: trunk/reactos/dll/win32/shell32/shv_item_cmenu.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shv_item_... ============================================================================== --- trunk/reactos/dll/win32/shell32/shv_item_cmenu.c (original) +++ trunk/reactos/dll/win32/shell32/shv_item_cmenu.c Wed Aug 30 23:35:54 2006 @@ -39,6 +39,10 @@
WINE_DEFAULT_DEBUG_CHANNEL(shell);
+/* ugly hack for cut&psate files */ +BOOL fileMoving = FALSE; + + /************************************************************************** * IContextMenu Implementation */ @@ -98,7 +102,7 @@ { cm->bAllValues &= (_ILIsValue(apidl[u]) ? 1 : 0); } - + TRACE("(%p)->()\n",cm);
return (IContextMenu2*)cm; @@ -374,9 +378,10 @@ 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))) {