Index: src/chext/DropMenuExt.cpp =================================================================== diff -u -N -rc435ab507c8b8280264188b49e9ada56d46c0261 -r2d7bee54f998ae8f5d4145a2cf3f4a589253016f --- src/chext/DropMenuExt.cpp (.../DropMenuExt.cpp) (revision c435ab507c8b8280264188b49e9ada56d46c0261) +++ src/chext/DropMenuExt.cpp (.../DropMenuExt.cpp) (revision 2d7bee54f998ae8f5d4145a2cf3f4a589253016f) @@ -19,9 +19,12 @@ #include "stdafx.h" #include "chext.h" #include "DropMenuExt.h" -#include "clipboard.h" #include "chext-utils.h" -#include "..\Common\ipcstructs.h" +#include "../Common/ipcstructs.h" +#include "../libchcore/TTaskDefinition.h" +#include +#include "ShellPathsHelpers.h" +#include "../libchcore/TWStringData.h" ///////////////////////////////////////////////////////////////////////////// // CDropMenuExt @@ -31,7 +34,6 @@ CDropMenuExt::CDropMenuExt() : m_piShellExtControl(NULL) { - m_szDstPath[0] = _T('\0'); CoCreateInstance(CLSID_CShellExtControl, NULL, CLSCTX_ALL, IID_IShellExtControl, (void**)&m_piShellExtControl); } @@ -44,32 +46,19 @@ } } -HRESULT CDropMenuExt::ReadFileData(IDataObject* piDataObject) +STDMETHODIMP CDropMenuExt::Initialize(LPCITEMIDLIST pidlFolder, IDataObject* piDataObject, HKEY /*hkeyProgID*/) { - _ASSERTE(piDataObject); - if(!piDataObject) - return E_INVALIDARG; + if(!pidlFolder && !piDataObject) + return E_FAIL; - // retrieve some informations from the data object - STGMEDIUM medium; - FORMATETC fe = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + if(!pidlFolder || !piDataObject) + _ASSERTE(!_T("Missing at least one parameter - it's unexpected.")); - // retrieve the CF_HDROP-type data from data object - HRESULT hResult = piDataObject->QueryGetData(&fe); - if(hResult != S_OK) - return hResult; - hResult = piDataObject->GetData(&fe, &medium); - if(SUCCEEDED(hResult)) - GetDataFromClipboard(static_cast(medium.hGlobal), m_szDstPath, &m_bBuffer.m_pszFiles, &m_bBuffer.m_iDataSize); - - ReleaseStgMedium(&medium); - - return hResult; -} - -STDMETHODIMP CDropMenuExt::Initialize(LPCITEMIDLIST pidlFolder, IDataObject* piDataObject, HKEY /*hkeyProgID*/) -{ - ATLTRACE(_T("CDropMenuExt::Initialize()\n")); + // When called: + // 1. R-click on a directory + // 2. R-click on a directory background + // 3. Pressed Ctrl+C, Ctrl+X on a specified file/directory + ATLTRACE(_T("[CDropMenuExt::Initialize] CDropMenuExt::Initialize()\n")); if(!piDataObject) return E_FAIL; @@ -90,19 +79,65 @@ // retrieve config from CH ::SendMessage(hWnd, WM_GETCONFIG, GC_DRAGDROP, 0); - // get dest folder - m_szDstPath[0]=_T('\0'); - if(!SHGetPathFromIDList(pidlFolder, m_szDstPath)) - return E_FAIL; + m_vPaths.Clear(); + m_pathPidl.Clear(); + // get dest folder + if(pidlFolder) + hResult = ShellPathsHelpers::GetPathFromITEMIDLIST(pidlFolder, m_pathPidl); // now retrieve the preferred drop effect from IDataObject - hResult = m_asSelector.ReadStateFromDataObject(piDataObject, m_szDstPath); if(SUCCEEDED(hResult)) - hResult = ReadFileData(piDataObject); + hResult = m_asSelector.ReadStateFromDataObject(piDataObject, m_pathPidl.ToString()); + if(SUCCEEDED(hResult)) + hResult = ShellPathsHelpers::GetPathsFromIDataObject(piDataObject, m_vPaths); + + ATLTRACE(_T("[CDropMenuExt::Initialize] Exit hResult == 0x%lx\n"), hResult); + return hResult; } +STDMETHODIMP CDropMenuExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpici) +{ + ATLTRACE(_T("CDropMenuExt::InvokeCommand()\n")); + HRESULT hResult = IsShellExtEnabled(m_piShellExtControl); + if(FAILED(hResult) || hResult == S_FALSE) + return E_FAIL; // required to process other InvokeCommand handlers. + + // find window + HWND hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); + if(hWnd == NULL) + return E_FAIL; + + // commands + _COMMAND* pCommand = g_pscsShared->GetCommandsPtr(); + if(!pCommand) + return E_FAIL; + + // set the operation type + chcore::TTaskDefinition tTaskDefinition; + tTaskDefinition.SetSourcePaths(m_vPaths); + tTaskDefinition.SetDestinationPath(m_pathPidl); + tTaskDefinition.SetOperationType(pCommand[LOWORD(lpici->lpVerb)].eOperationType); + + // get the gathered data as XML + chcore::TWStringData wstrXML; + tTaskDefinition.StoreInString(wstrXML); + +// ::MessageBox(NULL, wstrXML.GetData(), _T("DropMenuExt.cpp / Copy/Move to [special]"), MB_OK); // TEMP - to be removed before commit + + // IPC struct + COPYDATASTRUCT cds; + cds.dwData = pCommand[LOWORD(lpici->lpVerb)].uiCommandID; // based on command's number (0-copy, 1-move, 2-special (copy), 3-special (move)) + cds.cbData = (DWORD)wstrXML.GetBytesCount(); + cds.lpData = (void*)wstrXML.GetData(); + + // send a message to ch + ::SendMessage(hWnd, WM_COPYDATA, reinterpret_cast(lpici->hwnd), reinterpret_cast(&cds)); + + return S_OK; +} + STDMETHODIMP CDropMenuExt::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT /*idCmdLast*/, UINT /*uFlags*/) { ATLTRACE(_T("CDropMenuExt::QueryContextMenu()\n")); @@ -240,35 +275,6 @@ return S_OK; } -STDMETHODIMP CDropMenuExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpici) -{ - ATLTRACE(_T("CDropMenuExt::InvokeCommand()\n")); - HRESULT hResult = IsShellExtEnabled(m_piShellExtControl); - if(FAILED(hResult) || hResult == S_FALSE) - return E_FAIL; // required to process other InvokeCommand handlers. - - // find window - HWND hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); - if(hWnd == NULL) - return E_FAIL; - - // commands - _COMMAND* pCommand = g_pscsShared->GetCommandsPtr(); - - // IPC struct - COPYDATASTRUCT cds; - cds.dwData=pCommand[LOWORD(lpici->lpVerb)].uiCommandID; // based on command's number (0-copy, 1-move, 2-special (copy), 3-special (move)) - cds.cbData=m_bBuffer.m_iDataSize * sizeof(TCHAR); - cds.lpData=m_bBuffer.m_pszFiles; - - // send a message to ch - ::SendMessage(hWnd, WM_COPYDATA, reinterpret_cast(lpici->hwnd), reinterpret_cast(&cds)); - - m_bBuffer.Destroy(); - - return S_OK; -} - STDMETHODIMP CDropMenuExt::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam) { return HandleMenuMsg2(uMsg, wParam, lParam, NULL);