Index: src/chext/DropMenuExt.cpp =================================================================== diff -u -N -r9227280f45190af35bc63d25b0be65681f76de3b -rd5c3edd0d167db9b5d47d04248820fda49499a5e --- src/chext/DropMenuExt.cpp (.../DropMenuExt.cpp) (revision 9227280f45190af35bc63d25b0be65681f76de3b) +++ src/chext/DropMenuExt.cpp (.../DropMenuExt.cpp) (revision d5c3edd0d167db9b5d47d04248820fda49499a5e) @@ -1,367 +1,367 @@ -/*************************************************************************** -* Copyright (C) 2001-2008 by J�zef Starosczyk * -* ixen@copyhandler.com * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU Library General Public License * -* (version 2) as published by the Free Software Foundation; * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License for more details. * -* * -* You should have received a copy of the GNU Library General Public * -* License along with this program; if not, write to the * -* Free Software Foundation, Inc., * -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * -***************************************************************************/ -#include "stdafx.h" -#include "chext.h" -#include "DropMenuExt.h" -#include "clipboard.h" -#include "chext-utils.h" - -///////////////////////////////////////////////////////////////////////////// -// CDropMenuExt - -extern CSharedConfigStruct* g_pscsShared; - -#define DE_COPY 0 -#define DE_MOVE 1 -#define DE_SPECIAL 2 -#define DE_AUTO 3 - -CDropMenuExt::CDropMenuExt() : - m_piShellExtControl(NULL) -{ - CoCreateInstance(CLSID_CShellExtControl, NULL, CLSCTX_ALL, IID_IShellExtControl, (void**)&m_piShellExtControl); -} - -CDropMenuExt::~CDropMenuExt() -{ - if(m_piShellExtControl) - { - m_piShellExtControl->Release(); - m_piShellExtControl = NULL; - } -} - -STDMETHODIMP CDropMenuExt::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT /*idCmdLast*/, UINT /*uFlags*/) -{ - // check options - HRESULT hResult = IsShellExtEnabled(m_piShellExtControl); - if(FAILED(hResult) || hResult == S_FALSE) - return hResult; - - // find CH's window - HWND hWnd; - hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); - if (hWnd) - { - // get state of keys - bool bShift=(GetKeyState(VK_SHIFT) & 0x80) != 0; - bool bCtrl=(GetKeyState(VK_CONTROL) & 0x80) != 0; - bool bAlt=(GetKeyState(VK_MENU) & 0x80) != 0; - -/* OTF2("CDropMenuExt::QueryContextMenu - uFlags=%lu (", uFlags); - if (uFlags & CMF_CANRENAME) - OTF2("CMF_CANRENAME "); - if (uFlags & CMF_DEFAULTONLY) - OTF2("CMF_DEFAULTONLY "); - if (uFlags & CMF_EXPLORE) - OTF2("CMF_EXPLORE "); - if (uFlags & CMF_EXTENDEDVERBS) - OTF2("CMF_EXTENDEDVERBS "); - if (uFlags & CMF_INCLUDESTATIC) - OTF2("CMF_INCLUDESTATIC "); - if (uFlags & CMF_NODEFAULT) - OTF2("CMF_NODEFAULT "); - if (uFlags & CMF_NORMAL) - OTF2("CMF_NORMAL "); - if (uFlags & CMF_NOVERBS) - OTF2("CMF_NOVERBS "); - if (uFlags & CMF_VERBSONLY) - OTF2("CMF_VERBSONLY "); - OTF2(")\r\n"); - OTF2("Keys State: Shift:%u, ctrl:%u, alt:%u\r\n", bShift, bCtrl, bAlt); -*/ - // got a config - _COMMAND* pCommand = g_pscsShared->GetCommandsPtr(); - int iCommandCount=0; - - if (g_pscsShared->uiFlags & DD_COPY_FLAG) - { - ::InsertMenu(hmenu, indexMenu+iCommandCount, MF_BYPOSITION | MF_STRING, idCmdFirst+0, pCommand[0].szCommand); - if (g_pscsShared->bOverrideDefault) - ::SetMenuDefaultItem(hmenu, idCmdFirst+0, FALSE); - iCommandCount++; - } - - if (g_pscsShared->uiFlags & DD_MOVE_FLAG) - { - ::InsertMenu(hmenu, indexMenu+iCommandCount, MF_BYPOSITION | MF_STRING, idCmdFirst+1, pCommand[1].szCommand); - if (g_pscsShared->bOverrideDefault && (bShift || (m_uiDropEffect == DE_MOVE && (m_bExplorer || !bCtrl))) ) - ::SetMenuDefaultItem(hmenu, idCmdFirst+1, FALSE); - iCommandCount++; - } - - if (g_pscsShared->uiFlags & DD_COPYMOVESPECIAL_FLAG) - { - ::InsertMenu(hmenu, indexMenu+iCommandCount, MF_BYPOSITION | MF_STRING, idCmdFirst+2, pCommand[2].szCommand); - if (g_pscsShared->bOverrideDefault && (bAlt || (bCtrl && bShift) || m_uiDropEffect == DE_SPECIAL) && !(m_uiDropEffect == DE_MOVE)) - ::SetMenuDefaultItem(hmenu, idCmdFirst+2, FALSE); - iCommandCount++; - } - - if (iCommandCount) - { - ::InsertMenu(hmenu, indexMenu+iCommandCount, MF_BYPOSITION | MF_SEPARATOR, idCmdFirst+3, NULL); - iCommandCount++; - } - - return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 4); - } - else - return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0); -} - -STDMETHODIMP CDropMenuExt::GetCommandString(UINT_PTR idCmd, UINT uFlags, UINT* /*pwReserved*/, LPSTR pszName, UINT cchMax) -{ - // check options - HRESULT hResult = IsShellExtEnabled(m_piShellExtControl); - if(FAILED(hResult) || hResult == S_FALSE) - { - pszName[0] = _T('\0'); - return hResult; - } - - if (uFlags == GCS_HELPTEXTW) - { - USES_CONVERSION; - - // find CH's window - HWND hWnd; - hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); - if (hWnd) - { - _COMMAND* pCommand = g_pscsShared->GetCommandsPtr(); - - switch (idCmd) - { - case 0: - case 1: - case 2: - { - CT2W ct2w(pCommand[idCmd].szDesc); - wcsncpy(reinterpret_cast(pszName), ct2w, cchMax); - break; - } - default: - wcsncpy(reinterpret_cast(pszName), L"", cchMax); - break; - } - } - else - wcsncpy(reinterpret_cast(pszName), L"", cchMax); - } - if (uFlags == GCS_HELPTEXTA) - { - // find CH's window - HWND hWnd; - hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); - - if (hWnd) - { - _COMMAND* pCommand = g_pscsShared->GetCommandsPtr(); - - switch (idCmd) - { - case 0: - case 1: - case 2: - { - CT2A ct2a(pCommand[idCmd].szDesc); - strncpy(pszName, ct2a, cchMax); - break; - } - default: - strncpy(pszName, "", cchMax); - break; - } - } - else - strncpy(pszName, "", cchMax); - } - - return S_OK; -} - -STDMETHODIMP CDropMenuExt::Initialize(LPCITEMIDLIST pidlFolder, LPDATAOBJECT lpdobj, HKEY /*hkeyProgID*/) -{ -// OTF2("Initialize cdropmenuext\r\n"); - HRESULT hResult = IsShellExtEnabled(m_piShellExtControl); - if(FAILED(hResult) || hResult == S_FALSE) - return hResult; - - // find window - HWND hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); - if (hWnd == NULL) - return E_FAIL; - - // gets the config from CH - ::SendMessage(hWnd, WM_GETCONFIG, GC_DRAGDROP, 0); - -// OTF2("========================================================\r\n"); -// OTF2("Initialize drag&drop context menu handler pidlFolder=%lu, lpdobj=%lu\r\n", pidlFolder, lpdobj); - - // get dest folder - m_szDstPath[0]=_T('\0'); - if (!SHGetPathFromIDList(pidlFolder, m_szDstPath)) - return E_FAIL; - - // get data from IDataObject - files to copy/move - if (lpdobj) - { -// ReportAvailableFormats(lpdobj); - // file list - STGMEDIUM medium; - FORMATETC fe = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; - - HRESULT hr = lpdobj->GetData(&fe, &medium); - if (FAILED(hr)) - return E_FAIL; - - GetDataFromClipboard(static_cast(medium.hGlobal), m_szDstPath, &m_bBuffer.m_pszFiles, &m_bBuffer.m_iDataSize); - - // set std text - switch (g_pscsShared->uiDefaultAction) - { - case 1: - // move action - m_uiDropEffect=DE_MOVE; - break; - case 2: - // special operation - m_uiDropEffect=DE_SPECIAL; - break; - case 3: - { - // autodetecting - copy or move - check the last path - UINT uiCount=DragQueryFile((HDROP)medium.hGlobal, 0xffffffff, NULL, 0); - TCHAR szPath[_MAX_PATH]; - if (DragQueryFile((HDROP)medium.hGlobal, uiCount-1, szPath, _MAX_PATH)) - { - if (_tcsncmp(szPath, _T("\\\\"), 2) == 0) - { - TCHAR* pFnd=_tcsstr(szPath+2, _T("\\")); - - if (pFnd) - { - int iCount; - // find another - TCHAR *pSecond=_tcsstr(pFnd+1, _T("\\")); - if (pSecond) - { - iCount=pSecond-szPath; -// OTF2("Counted: %lu\r\n", iCount); - } - else - iCount=_tcslen(szPath); - - // found - compare -// OTF2("Compare %s and %s\r\n", szPath, m_szDstPath); - if (_tcsnicmp(szPath, m_szDstPath, iCount) == 0) - { -// OTF2("OP: MOVE\r\n"); - m_uiDropEffect=DE_MOVE; - } - else - { -// OTF2("OP: COPY\r\n"); - m_uiDropEffect=DE_COPY; - } - } - else - m_uiDropEffect=DE_COPY; - - } - else - { - // local path - check drive letter - if (m_szDstPath[0] == szPath[0]) - m_uiDropEffect=DE_MOVE; - else - m_uiDropEffect=DE_COPY; - } - } - else - m_uiDropEffect=DE_COPY; - } - break; - - default: - m_uiDropEffect=DE_COPY; // std copying - break; - } - - ReleaseStgMedium(&medium); - - // get operation type - UINT cf=RegisterClipboardFormat(CFSTR_PREFERREDDROPEFFECT); - fe.cfFormat=(unsigned short)cf; - - // if explorer knows better - change effect - m_bExplorer=false; - hr=lpdobj->GetData(&fe, &medium); - if (SUCCEEDED(hr)) - { - // specify operation - LPVOID lpv=GlobalLock(medium.hGlobal); - if (lpv) - { - UINT uiDrop=*((DWORD*)lpv); - if (uiDrop & DROPEFFECT_MOVE) - m_uiDropEffect=DE_MOVE; - else - m_uiDropEffect=DE_COPY; - m_bExplorer=true; - -// OTF2("Detected operation %lu\r\n", m_uiDropEffect); - GlobalUnlock(medium.hGlobal); - } - - ReleaseStgMedium(&medium); - } - } - - return S_OK; -} - -STDMETHODIMP CDropMenuExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpici) -{ - 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; +/*************************************************************************** +* Copyright (C) 2001-2008 by J�zef Starosczyk * +* ixen@copyhandler.com * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU Library General Public License * +* (version 2) as published by the Free Software Foundation; * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License for more details. * +* * +* You should have received a copy of the GNU Library General Public * +* License along with this program; if not, write to the * +* Free Software Foundation, Inc., * +* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * +***************************************************************************/ +#include "stdafx.h" +#include "chext.h" +#include "DropMenuExt.h" +#include "clipboard.h" +#include "chext-utils.h" + +///////////////////////////////////////////////////////////////////////////// +// CDropMenuExt + +extern CSharedConfigStruct* g_pscsShared; + +#define DE_COPY 0 +#define DE_MOVE 1 +#define DE_SPECIAL 2 +#define DE_AUTO 3 + +CDropMenuExt::CDropMenuExt() : + m_piShellExtControl(NULL) +{ + CoCreateInstance(CLSID_CShellExtControl, NULL, CLSCTX_ALL, IID_IShellExtControl, (void**)&m_piShellExtControl); +} + +CDropMenuExt::~CDropMenuExt() +{ + if(m_piShellExtControl) + { + m_piShellExtControl->Release(); + m_piShellExtControl = NULL; + } +} + +STDMETHODIMP CDropMenuExt::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT /*idCmdLast*/, UINT /*uFlags*/) +{ + // check options + HRESULT hResult = IsShellExtEnabled(m_piShellExtControl); + if(FAILED(hResult) || hResult == S_FALSE) + return hResult; + + // find CH's window + HWND hWnd; + hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); + if (hWnd) + { + // get state of keys + bool bShift=(GetKeyState(VK_SHIFT) & 0x80) != 0; + bool bCtrl=(GetKeyState(VK_CONTROL) & 0x80) != 0; + bool bAlt=(GetKeyState(VK_MENU) & 0x80) != 0; + +/* OTF2("CDropMenuExt::QueryContextMenu - uFlags=%lu (", uFlags); + if (uFlags & CMF_CANRENAME) + OTF2("CMF_CANRENAME "); + if (uFlags & CMF_DEFAULTONLY) + OTF2("CMF_DEFAULTONLY "); + if (uFlags & CMF_EXPLORE) + OTF2("CMF_EXPLORE "); + if (uFlags & CMF_EXTENDEDVERBS) + OTF2("CMF_EXTENDEDVERBS "); + if (uFlags & CMF_INCLUDESTATIC) + OTF2("CMF_INCLUDESTATIC "); + if (uFlags & CMF_NODEFAULT) + OTF2("CMF_NODEFAULT "); + if (uFlags & CMF_NORMAL) + OTF2("CMF_NORMAL "); + if (uFlags & CMF_NOVERBS) + OTF2("CMF_NOVERBS "); + if (uFlags & CMF_VERBSONLY) + OTF2("CMF_VERBSONLY "); + OTF2(")\r\n"); + OTF2("Keys State: Shift:%u, ctrl:%u, alt:%u\r\n", bShift, bCtrl, bAlt); +*/ + // got a config + _COMMAND* pCommand = g_pscsShared->GetCommandsPtr(); + int iCommandCount=0; + + if (g_pscsShared->uiFlags & DD_COPY_FLAG) + { + ::InsertMenu(hmenu, indexMenu+iCommandCount, MF_BYPOSITION | MF_STRING, idCmdFirst+0, pCommand[0].szCommand); + if (g_pscsShared->bOverrideDefault) + ::SetMenuDefaultItem(hmenu, idCmdFirst+0, FALSE); + iCommandCount++; + } + + if (g_pscsShared->uiFlags & DD_MOVE_FLAG) + { + ::InsertMenu(hmenu, indexMenu+iCommandCount, MF_BYPOSITION | MF_STRING, idCmdFirst+1, pCommand[1].szCommand); + if (g_pscsShared->bOverrideDefault && (bShift || (m_uiDropEffect == DE_MOVE && (m_bExplorer || !bCtrl))) ) + ::SetMenuDefaultItem(hmenu, idCmdFirst+1, FALSE); + iCommandCount++; + } + + if (g_pscsShared->uiFlags & DD_COPYMOVESPECIAL_FLAG) + { + ::InsertMenu(hmenu, indexMenu+iCommandCount, MF_BYPOSITION | MF_STRING, idCmdFirst+2, pCommand[2].szCommand); + if (g_pscsShared->bOverrideDefault && (bAlt || (bCtrl && bShift) || m_uiDropEffect == DE_SPECIAL) && !(m_uiDropEffect == DE_MOVE)) + ::SetMenuDefaultItem(hmenu, idCmdFirst+2, FALSE); + iCommandCount++; + } + + if (iCommandCount) + { + ::InsertMenu(hmenu, indexMenu+iCommandCount, MF_BYPOSITION | MF_SEPARATOR, idCmdFirst+3, NULL); + iCommandCount++; + } + + return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 4); + } + else + return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0); +} + +STDMETHODIMP CDropMenuExt::GetCommandString(UINT_PTR idCmd, UINT uFlags, UINT* /*pwReserved*/, LPSTR pszName, UINT cchMax) +{ + // check options + HRESULT hResult = IsShellExtEnabled(m_piShellExtControl); + if(FAILED(hResult) || hResult == S_FALSE) + { + pszName[0] = _T('\0'); + return hResult; + } + + if (uFlags == GCS_HELPTEXTW) + { + USES_CONVERSION; + + // find CH's window + HWND hWnd; + hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); + if (hWnd) + { + _COMMAND* pCommand = g_pscsShared->GetCommandsPtr(); + + switch (idCmd) + { + case 0: + case 1: + case 2: + { + CT2W ct2w(pCommand[idCmd].szDesc); + wcsncpy(reinterpret_cast(pszName), ct2w, cchMax); + break; + } + default: + wcsncpy(reinterpret_cast(pszName), L"", cchMax); + break; + } + } + else + wcsncpy(reinterpret_cast(pszName), L"", cchMax); + } + if (uFlags == GCS_HELPTEXTA) + { + // find CH's window + HWND hWnd; + hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); + + if (hWnd) + { + _COMMAND* pCommand = g_pscsShared->GetCommandsPtr(); + + switch (idCmd) + { + case 0: + case 1: + case 2: + { + CT2A ct2a(pCommand[idCmd].szDesc); + strncpy(pszName, ct2a, cchMax); + break; + } + default: + strncpy(pszName, "", cchMax); + break; + } + } + else + strncpy(pszName, "", cchMax); + } + + return S_OK; +} + +STDMETHODIMP CDropMenuExt::Initialize(LPCITEMIDLIST pidlFolder, LPDATAOBJECT lpdobj, HKEY /*hkeyProgID*/) +{ +// OTF2("Initialize cdropmenuext\r\n"); + HRESULT hResult = IsShellExtEnabled(m_piShellExtControl); + if(FAILED(hResult) || hResult == S_FALSE) + return hResult; + + // find window + HWND hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); + if (hWnd == NULL) + return E_FAIL; + + // gets the config from CH + ::SendMessage(hWnd, WM_GETCONFIG, GC_DRAGDROP, 0); + +// OTF2("========================================================\r\n"); +// OTF2("Initialize drag&drop context menu handler pidlFolder=%lu, lpdobj=%lu\r\n", pidlFolder, lpdobj); + + // get dest folder + m_szDstPath[0]=_T('\0'); + if (!SHGetPathFromIDList(pidlFolder, m_szDstPath)) + return E_FAIL; + + // get data from IDataObject - files to copy/move + if (lpdobj) + { +// ReportAvailableFormats(lpdobj); + // file list + STGMEDIUM medium; + FORMATETC fe = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + + HRESULT hr = lpdobj->GetData(&fe, &medium); + if (FAILED(hr)) + return E_FAIL; + + GetDataFromClipboard(static_cast(medium.hGlobal), m_szDstPath, &m_bBuffer.m_pszFiles, &m_bBuffer.m_iDataSize); + + // set std text + switch (g_pscsShared->uiDefaultAction) + { + case 1: + // move action + m_uiDropEffect=DE_MOVE; + break; + case 2: + // special operation + m_uiDropEffect=DE_SPECIAL; + break; + case 3: + { + // autodetecting - copy or move - check the last path + UINT uiCount=DragQueryFile((HDROP)medium.hGlobal, 0xffffffff, NULL, 0); + TCHAR szPath[_MAX_PATH]; + if (DragQueryFile((HDROP)medium.hGlobal, uiCount-1, szPath, _MAX_PATH)) + { + if (_tcsncmp(szPath, _T("\\\\"), 2) == 0) + { + TCHAR* pFnd=_tcsstr(szPath+2, _T("\\")); + + if (pFnd) + { + int iCount; + // find another + TCHAR *pSecond=_tcsstr(pFnd+1, _T("\\")); + if (pSecond) + { + iCount=pSecond-szPath; +// OTF2("Counted: %lu\r\n", iCount); + } + else + iCount=_tcslen(szPath); + + // found - compare +// OTF2("Compare %s and %s\r\n", szPath, m_szDstPath); + if (_tcsnicmp(szPath, m_szDstPath, iCount) == 0) + { +// OTF2("OP: MOVE\r\n"); + m_uiDropEffect=DE_MOVE; + } + else + { +// OTF2("OP: COPY\r\n"); + m_uiDropEffect=DE_COPY; + } + } + else + m_uiDropEffect=DE_COPY; + + } + else + { + // local path - check drive letter + if (m_szDstPath[0] == szPath[0]) + m_uiDropEffect=DE_MOVE; + else + m_uiDropEffect=DE_COPY; + } + } + else + m_uiDropEffect=DE_COPY; + } + break; + + default: + m_uiDropEffect=DE_COPY; // std copying + break; + } + + ReleaseStgMedium(&medium); + + // get operation type + UINT cf=RegisterClipboardFormat(CFSTR_PREFERREDDROPEFFECT); + fe.cfFormat=(unsigned short)cf; + + // if explorer knows better - change effect + m_bExplorer=false; + hr=lpdobj->GetData(&fe, &medium); + if (SUCCEEDED(hr)) + { + // specify operation + LPVOID lpv=GlobalLock(medium.hGlobal); + if (lpv) + { + UINT uiDrop=*((DWORD*)lpv); + if (uiDrop & DROPEFFECT_MOVE) + m_uiDropEffect=DE_MOVE; + else + m_uiDropEffect=DE_COPY; + m_bExplorer=true; + +// OTF2("Detected operation %lu\r\n", m_uiDropEffect); + GlobalUnlock(medium.hGlobal); + } + + ReleaseStgMedium(&medium); + } + } + + return S_OK; +} + +STDMETHODIMP CDropMenuExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpici) +{ + 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; } \ No newline at end of file