Index: src/chext/MenuExt.cpp =================================================================== diff -u -N -rd5c3edd0d167db9b5d47d04248820fda49499a5e -r0373359eff650e8cf04a5992711ef9f20347536f --- src/chext/MenuExt.cpp (.../MenuExt.cpp) (revision d5c3edd0d167db9b5d47d04248820fda49499a5e) +++ src/chext/MenuExt.cpp (.../MenuExt.cpp) (revision 0373359eff650e8cf04a5992711ef9f20347536f) @@ -62,126 +62,198 @@ } } -HRESULT CMenuExt::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam) +STDMETHODIMP CMenuExt::Initialize(LPCITEMIDLIST pidlFolder, LPDATAOBJECT lpdobj, HKEY /*hkeyProgID*/) { -// OTF("CMenuExt::HandleMenuMsg\r\n"); - return HandleMenuMsg2(uMsg, wParam, lParam, NULL); -} + ATLTRACE(_T("CMenuExt::Initialize()\n")); + // check options + HRESULT hResult = IsShellExtEnabled(m_piShellExtControl); + if(FAILED(hResult) || hResult == S_FALSE) + return hResult; -HRESULT CMenuExt::HandleMenuMsg2(UINT uMsg, WPARAM /*wParam*/, LPARAM lParam, LRESULT* /*plResult*/) -{ - switch(uMsg) - { - case WM_INITMENUPOPUP: - { -// OTF("CMenuExt::HandleMenuMsg2 / Init menu popup\r\n"); - break; - } - - case WM_DRAWITEM: - { -// OTF("CMenuExt::HandleMenuMsg2 / Drawitem\r\n"); - LPDRAWITEMSTRUCT lpdis=(LPDRAWITEMSTRUCT) lParam; - DrawMenuItem(lpdis); - break; - } - - case WM_MEASUREITEM: - { -// OTF("CMenuExt::HandleMenuMsg2 / MeasureItem\r\n"); - LPMEASUREITEMSTRUCT lpmis=(LPMEASUREITEMSTRUCT)lParam; + // find ch window + HWND hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); + if (hWnd == NULL) + return E_FAIL; - // establish display text - int iShortcutIndex=(lpmis->itemID-m_uiFirstID-5)%g_pscsShared->iShortcutsCount; - _SHORTCUT* pShortcuts = g_pscsShared->GetShortcutsPtr(); + // get cfg from ch + ::SendMessage(hWnd, WM_GETCONFIG, GC_EXPLORER, 0); - // measure the text - HWND hDesktop=GetDesktopWindow(); - HDC hDC=GetDC(hDesktop); + // read dest folder + m_szDstPath[0]=_T('\0'); - // get menu logfont - NONCLIENTMETRICS ncm; - ncm.cbSize=sizeof(NONCLIENTMETRICS); - SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0); + // get data from IDataObject - files to copy/move + bool bPathFound=false; + m_bGroupFiles=false; + if (lpdobj) + { + STGMEDIUM medium; + FORMATETC fe = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; - HFONT hFont=CreateFontIndirect(&ncm.lfMenuFont); - HFONT hOldFont=(HFONT)SelectObject(hDC, hFont); + HRESULT hr = lpdobj->GetData(&fe, &medium); + if (FAILED(hr)) + return E_FAIL; - // calc text size - SIZE size; - GetTextExtentPoint32(hDC, pShortcuts[iShortcutIndex].szName, (int)_tcslen(pShortcuts[iShortcutIndex].szName), &size); + // copy all filenames to a table + GetDataFromClipboard(static_cast(medium.hGlobal), NULL, &m_bBuffer.m_pszFiles, &m_bBuffer.m_iDataSize); - // restore old settings - SelectObject(hDC, hOldFont); - ReleaseDC(hDesktop, hDC); + // find the first non-empty entry + UINT fileCount = DragQueryFile((HDROP)medium.hGlobal, 0xFFFFFFFF, NULL, 0); + TCHAR szPath[_MAX_PATH]; + UINT uiRes; + for (UINT i=0;iitemWidth=size.cx+GetSystemMetrics(SM_CXMENUCHECK)+2*GetSystemMetrics(SM_CXSMICON); - lpmis->itemHeight = __max(size.cy+3, GetSystemMetrics(SM_CYMENU)+3); + // check if there are files + if (!(GetFileAttributes(szPath) & FILE_ATTRIBUTE_DIRECTORY)) + m_bGroupFiles=true; - break; + if (bPathFound && m_bGroupFiles) + break; } + + ReleaseStgMedium(&medium); } + // if all paths are empty - check pidlfolder + if (!bPathFound) + { + if (!SHGetPathFromIDList(pidlFolder, m_szDstPath)) + return E_FAIL; + + // empty path - error + if (_tcslen(m_szDstPath) == 0) + return E_FAIL; + } + + // background or folder ? + m_bBackground=(lpdobj == NULL) && (pidlFolder != NULL); + return S_OK; } -void CMenuExt::DrawMenuItem(LPDRAWITEMSTRUCT lpdis) +STDMETHODIMP CMenuExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpici) { - // check if menu - if (lpdis->CtlType != ODT_MENU) - return; + ATLTRACE(_T("CMenuExt::InvokeCommand()\n")); + // check options + HRESULT hResult = IsShellExtEnabled(m_piShellExtControl); + if(FAILED(hResult) || hResult == S_FALSE) + return E_FAIL; // required to process other InvokeCommand handlers. - // margins and other stuff - const int iSmallIconWidth=GetSystemMetrics(SM_CXSMICON); - const int iSmallIconHeight=GetSystemMetrics(SM_CYSMICON); - const int iLeftMargin=GetSystemMetrics(SM_CXMENUCHECK)/2; - const int iRightMargin=GetSystemMetrics(SM_CXMENUCHECK)-iLeftMargin; - - int iShortcutIndex=(lpdis->itemID-m_uiFirstID-5)%g_pscsShared->iShortcutsCount; - _SHORTCUT* pShortcuts=g_pscsShared->GetShortcutsPtr(); + // find window + HWND hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); + if (hWnd == NULL) + return E_FAIL; - // text color - HBRUSH hbr; - if (lpdis->itemState & ODS_SELECTED) + // commands + _COMMAND* pCommand = g_pscsShared->GetCommandsPtr(); + + // OTF("Invoke Command\r\n"); + // command type + switch (LOWORD(lpici->lpVerb)) { - SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); - SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT)); - hbr=CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT)); - } - else - { - SetTextColor(lpdis->hDC, GetSysColor(COLOR_MENUTEXT)); - SetBkColor(lpdis->hDC, GetSysColor(COLOR_MENU)); - hbr=CreateSolidBrush(GetSysColor(COLOR_MENU)); - } + // paste & paste special + case 0: + case 1: + { + // search for data in a clipboard + if (IsClipboardFormatAvailable(CF_HDROP)) + { + bool bMove=false; // 0-copy, 1-move - // draw background - RECT rcSelect=lpdis->rcItem; - rcSelect.top++; - rcSelect.bottom--; + // get data + OpenClipboard(lpici->hwnd); + HANDLE handle=GetClipboardData(CF_HDROP); + TCHAR *pchBuffer=NULL; + UINT uiSize; - FillRect(lpdis->hDC, &rcSelect, hbr); - DeleteObject(hbr); + GetDataFromClipboard(static_cast(handle), m_szDstPath, &pchBuffer, &uiSize); - // get img list - SHFILEINFO sfi; - HIMAGELIST himl=(HIMAGELIST)SHGetFileInfo(pShortcuts[iShortcutIndex].szPath, FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(SHFILEINFO), SHGFI_SMALLICON | SHGFI_ICON | SHGFI_SYSICONINDEX); - ImageList_Draw(himl, sfi.iIcon, lpdis->hDC, lpdis->rcItem.left+iLeftMargin, - lpdis->rcItem.top+(lpdis->rcItem.bottom-lpdis->rcItem.top+1-iSmallIconHeight)/2, ILD_TRANSPARENT); + // register clipboard format nad if exists in it + UINT nFormat=RegisterClipboardFormat(_T("Preferred DropEffect")); + if (IsClipboardFormatAvailable(nFormat)) + { + handle=GetClipboardData(nFormat); + LPVOID addr=GlobalLock(handle); + if(!addr) + return E_FAIL; + DWORD dwData=((DWORD*)addr)[0]; + if (dwData & DROPEFFECT_MOVE) + bMove=true; - RECT rcText; - rcText.left=iLeftMargin+iSmallIconWidth+iRightMargin; - rcText.top=lpdis->rcItem.top; - rcText.right=lpdis->rcItem.right; - rcText.bottom=lpdis->rcItem.bottom; + GlobalUnlock(handle); + } -// OTF("Drawing text: %s\r\n", pShortcuts[iShortcutIndex].szName); - DrawText(lpdis->hDC, pShortcuts[iShortcutIndex].szName, -1, &rcText, DT_LEFT | DT_SINGLELINE | DT_VCENTER); + CloseClipboard(); + + // fill struct + COPYDATASTRUCT cds; + cds.dwData=(((DWORD)bMove) << 31) | pCommand[LOWORD(lpici->lpVerb)].uiCommandID; + cds.lpData=pchBuffer; + cds.cbData=uiSize * sizeof(TCHAR); + + // send a message + ::SendMessage(hWnd, WM_COPYDATA, reinterpret_cast(lpici->hwnd), reinterpret_cast(&cds)); + + // delete buffer + delete [] pchBuffer; + } + } + break; + + // case 2: + // case 3: + // case 4: + default: + { + // out of range - may be a shortcut + if (LOWORD(lpici->lpVerb) < g_pscsShared->iCommandCount+(m_bBackground ? 0 : 3*g_pscsShared->iShortcutsCount)) + { + // addr of a table with shortcuts + _SHORTCUT* stShortcuts = g_pscsShared->GetShortcutsPtr(); + + // find command for which this command is generated + int iCommandIndex=(int)(((LOWORD(lpici->lpVerb)-5) / g_pscsShared->iShortcutsCount))+2; // command index + int iShortcutIndex=((LOWORD(lpici->lpVerb)-5) % g_pscsShared->iShortcutsCount); // shortcut index + + // buffer for data + UINT uiSize=_tcslen(stShortcuts[iShortcutIndex].szPath)+1+m_bBuffer.m_iDataSize; + TCHAR *pszBuffer=new TCHAR[uiSize]; + _tcscpy(pszBuffer, stShortcuts[iShortcutIndex].szPath); // �cie�ka docelowa + + // buffer with files + memcpy(pszBuffer+_tcslen(stShortcuts[iShortcutIndex].szPath)+1, m_bBuffer.m_pszFiles, m_bBuffer.m_iDataSize*sizeof(TCHAR)); + + // fill struct + COPYDATASTRUCT cds; + cds.dwData=pCommand[iCommandIndex].uiCommandID; + cds.lpData=pszBuffer; + cds.cbData=uiSize * sizeof(TCHAR); + + // send message + ::SendMessage(hWnd, WM_COPYDATA, reinterpret_cast(lpici->hwnd), reinterpret_cast(&cds)); + + // delete buffer + delete [] pszBuffer; + m_bBuffer.Destroy(); + } + else + return E_FAIL; + } + break; + } + + return S_OK; } STDMETHODIMP CMenuExt::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT /*idCmdLast*/, UINT /*uFlags*/) { + ATLTRACE(_T("CMenuExt::QueryContextMenu()\n")); // check options HRESULT hResult = IsShellExtEnabled(m_piShellExtControl); if(FAILED(hResult) || hResult == S_FALSE) @@ -193,27 +265,6 @@ if(!hWnd) return S_OK; -/* OTF("CMenuExt::QueryContextMenu - idCmdFirst=%lu, uFlags=%lu (", idCmdFirst, uFlags); - if (uFlags & CMF_CANRENAME) - OTF("CMF_CANRENAME "); - if (uFlags & CMF_DEFAULTONLY) - OTF("CMF_DEFAULTONLY "); - if (uFlags & CMF_EXPLORE) - OTF("CMF_EXPLORE "); - if (uFlags & CMF_EXTENDEDVERBS) - OTF("CMF_EXTENDEDVERBS "); - if (uFlags & CMF_INCLUDESTATIC) - OTF("CMF_INCLUDESTATIC "); - if (uFlags & CMF_NODEFAULT) - OTF("CMF_NODEFAULT "); - if (uFlags & CMF_NORMAL) - OTF("CMF_NORMAL "); - if (uFlags & CMF_NOVERBS) - OTF("CMF_NOVERBS "); - if (uFlags & CMF_VERBSONLY) - OTF("CMF_VERBSONLY "); - OTF(")\r\n"); -*/ // remember ID of the first command m_uiFirstID=idCmdFirst; @@ -231,7 +282,7 @@ for (int i=0;iGetCommandsPtr(); // data about commands int iCommandCount=0; - + if (!m_bGroupFiles) { // paste - if (g_pscsShared->uiFlags & EC_PASTE_FLAG) + if (g_pscsShared->uiFlags & CSharedConfigStruct::EC_PASTE_FLAG) { ::InsertMenu(hmenu, indexMenu++, MF_BYPOSITION | MF_STRING | (IsClipboardFormatAvailable(CF_HDROP) ? MF_ENABLED : MF_GRAYED), idCmdFirst+0, pCommand[0].szCommand); iCommandCount++; } - - if (g_pscsShared->uiFlags & EC_PASTESPECIAL_FLAG) + + if (g_pscsShared->uiFlags & CSharedConfigStruct::EC_PASTESPECIAL_FLAG) { ::InsertMenu(hmenu, indexMenu++, MF_BYPOSITION | MF_STRING | (IsClipboardFormatAvailable(CF_HDROP) ? MF_ENABLED : MF_GRAYED), idCmdFirst+1, pCommand[1].szCommand); iCommandCount++; } } -// OTF("After group files\r\n"); - if (!m_bBackground) { CreateShortcutsMenu(idCmdFirst+5, g_pscsShared->bShowShortcutIcons); -// OTF("after creating shortcuts menu\r\n"); - + // copy to > - if (g_pscsShared->uiFlags & EC_COPYTO_FLAG) + if (g_pscsShared->uiFlags & CSharedConfigStruct::EC_COPYTO_FLAG) { mii.cbSize=sizeof(MENUITEMINFO); mii.fMask=MIIM_ID | MIIM_STATE | MIIM_SUBMENU | MIIM_TYPE; @@ -303,14 +349,13 @@ mii.cch=_tcslen(pCommand[2].szCommand); ::InsertMenuItem(hmenu, indexMenu++, TRUE, &mii); -// ::InsertMenu(hmenu, indexMenu++, MF_BYPOSITION | MF_POPUP | MF_STRING | ((g_pscsShared->iShortcutsCount > 0) ? MF_ENABLED : MF_GRAYED), -// (UINT)m_mMenus.hShortcuts[0], pCommand[2].szCommand); + // ::InsertMenu(hmenu, indexMenu++, MF_BYPOSITION | MF_POPUP | MF_STRING | ((g_pscsShared->iShortcutsCount > 0) ? MF_ENABLED : MF_GRAYED), + // (UINT)m_mMenus.hShortcuts[0], pCommand[2].szCommand); iCommandCount++; -// OTF("added menu item\r\n"); } - + // move to > - if (g_pscsShared->uiFlags & EC_MOVETO_FLAG) + if (g_pscsShared->uiFlags & CSharedConfigStruct::EC_MOVETO_FLAG) { mii.cbSize=sizeof(MENUITEMINFO); mii.fMask=MIIM_ID | MIIM_STATE | MIIM_SUBMENU | MIIM_TYPE; @@ -322,13 +367,13 @@ mii.cch=_tcslen(pCommand[3].szCommand); ::InsertMenuItem(hmenu, indexMenu++, TRUE, &mii); -// ::InsertMenu(hmenu, indexMenu++, MF_BYPOSITION | MF_POPUP | MF_STRING | ((g_pscsShared->iShortcutsCount > 0) ? MF_ENABLED : MF_GRAYED), -// (UINT)m_mMenus.hShortcuts[1], pCommand[3].szCommand); + // ::InsertMenu(hmenu, indexMenu++, MF_BYPOSITION | MF_POPUP | MF_STRING | ((g_pscsShared->iShortcutsCount > 0) ? MF_ENABLED : MF_GRAYED), + // (UINT)m_mMenus.hShortcuts[1], pCommand[3].szCommand); iCommandCount++; } - + // copy/move to special... > - if (g_pscsShared->uiFlags & EC_COPYMOVETOSPECIAL_FLAG) + if (g_pscsShared->uiFlags & CSharedConfigStruct::EC_COPYMOVETOSPECIAL_FLAG) { mii.cbSize=sizeof(MENUITEMINFO); mii.fMask=MIIM_ID | MIIM_STATE | MIIM_SUBMENU | MIIM_TYPE; @@ -340,21 +385,131 @@ mii.cch=_tcslen(pCommand[4].szCommand); ::InsertMenuItem(hmenu, indexMenu++, TRUE, &mii); -// ::InsertMenu(hmenu, indexMenu++, MF_BYPOSITION | MF_POPUP | MF_STRING | ((g_pscsShared->iShortcutsCount > 0) ? MF_ENABLED : MF_GRAYED), -// (UINT)m_mMenus.hShortcuts[2], pCommand[4].szCommand); + // ::InsertMenu(hmenu, indexMenu++, MF_BYPOSITION | MF_POPUP | MF_STRING | ((g_pscsShared->iShortcutsCount > 0) ? MF_ENABLED : MF_GRAYED), + // (UINT)m_mMenus.hShortcuts[2], pCommand[4].szCommand); iCommandCount++; } } -// OTF("before return\r\n"); return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, g_pscsShared->iCommandCount+(m_bBackground ? 0 : 3*g_pscsShared->iShortcutsCount)); } -void CMenuExt::CreateShortcutsMenu(UINT uiIDBase, bool bOwnerDrawn) +HRESULT CMenuExt::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam) { -// OTF("CreateShortcutsMenu\r\n"); + return HandleMenuMsg2(uMsg, wParam, lParam, NULL); +} - // tw�rz puste menu +HRESULT CMenuExt::HandleMenuMsg2(UINT uMsg, WPARAM /*wParam*/, LPARAM lParam, LRESULT* /*plResult*/) +{ + ATLTRACE(_T("CMenuExt::HandleMenuMsg2()\n")); + + switch(uMsg) + { + case WM_INITMENUPOPUP: + break; + + case WM_DRAWITEM: + { + LPDRAWITEMSTRUCT lpdis=(LPDRAWITEMSTRUCT) lParam; + DrawMenuItem(lpdis); + break; + } + + case WM_MEASUREITEM: + { + LPMEASUREITEMSTRUCT lpmis=(LPMEASUREITEMSTRUCT)lParam; + + // establish display text + int iShortcutIndex=(lpmis->itemID-m_uiFirstID-5)%g_pscsShared->iShortcutsCount; + _SHORTCUT* pShortcuts = g_pscsShared->GetShortcutsPtr(); + + // measure the text + HWND hDesktop=GetDesktopWindow(); + HDC hDC=GetDC(hDesktop); + + // get menu logfont + NONCLIENTMETRICS ncm; + ncm.cbSize=sizeof(NONCLIENTMETRICS); + SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0); + + HFONT hFont=CreateFontIndirect(&ncm.lfMenuFont); + HFONT hOldFont=(HFONT)SelectObject(hDC, hFont); + + // calc text size + SIZE size; + GetTextExtentPoint32(hDC, pShortcuts[iShortcutIndex].szName, (int)_tcslen(pShortcuts[iShortcutIndex].szName), &size); + + // restore old settings + SelectObject(hDC, hOldFont); + ReleaseDC(hDesktop, hDC); + + // set + lpmis->itemWidth=size.cx+GetSystemMetrics(SM_CXMENUCHECK)+2*GetSystemMetrics(SM_CXSMICON); + lpmis->itemHeight = __max(size.cy+3, GetSystemMetrics(SM_CYMENU)+3); + + break; + } + } + + return S_OK; +} + +void CMenuExt::DrawMenuItem(LPDRAWITEMSTRUCT lpdis) +{ + // check if menu + if (lpdis->CtlType != ODT_MENU) + return; + + // margins and other stuff + const int iSmallIconWidth=GetSystemMetrics(SM_CXSMICON); + const int iSmallIconHeight=GetSystemMetrics(SM_CYSMICON); + const int iLeftMargin=GetSystemMetrics(SM_CXMENUCHECK)/2; + const int iRightMargin=GetSystemMetrics(SM_CXMENUCHECK)-iLeftMargin; + + int iShortcutIndex=(lpdis->itemID-m_uiFirstID-5)%g_pscsShared->iShortcutsCount; + _SHORTCUT* pShortcuts=g_pscsShared->GetShortcutsPtr(); + + // text color + HBRUSH hbr; + if (lpdis->itemState & ODS_SELECTED) + { + SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); + SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT)); + hbr=CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT)); + } + else + { + SetTextColor(lpdis->hDC, GetSysColor(COLOR_MENUTEXT)); + SetBkColor(lpdis->hDC, GetSysColor(COLOR_MENU)); + hbr=CreateSolidBrush(GetSysColor(COLOR_MENU)); + } + + // draw background + RECT rcSelect=lpdis->rcItem; + rcSelect.top++; + rcSelect.bottom--; + + FillRect(lpdis->hDC, &rcSelect, hbr); + DeleteObject(hbr); + + // get img list + SHFILEINFO sfi; + HIMAGELIST himl=(HIMAGELIST)SHGetFileInfo(pShortcuts[iShortcutIndex].szPath, FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(SHFILEINFO), SHGFI_SMALLICON | SHGFI_ICON | SHGFI_SYSICONINDEX); + ImageList_Draw(himl, sfi.iIcon, lpdis->hDC, lpdis->rcItem.left+iLeftMargin, + lpdis->rcItem.top+(lpdis->rcItem.bottom-lpdis->rcItem.top+1-iSmallIconHeight)/2, ILD_TRANSPARENT); + + RECT rcText; + rcText.left=iLeftMargin+iSmallIconWidth+iRightMargin; + rcText.top=lpdis->rcItem.top; + rcText.right=lpdis->rcItem.right; + rcText.bottom=lpdis->rcItem.bottom; + + DrawText(lpdis->hDC, pShortcuts[iShortcutIndex].szName, -1, &rcText, DT_LEFT | DT_SINGLELINE | DT_VCENTER); +} + +void CMenuExt::CreateShortcutsMenu(UINT uiIDBase, bool bOwnerDrawn) +{ + // create empty menus m_mMenus.hShortcuts[0]=CreatePopupMenu(); m_mMenus.hShortcuts[1]=CreatePopupMenu(); m_mMenus.hShortcuts[2]=CreatePopupMenu(); @@ -372,7 +527,6 @@ _sntprintf(szText, 256 - 1, _T("%s (%s)"), pShortcuts[i].szName, GetSizeString(ullFree, szSize, 32)); szText[256 - 1] = _T('\0'); _tcsncpy(pShortcuts[i].szName, szText, 127); -// OTF("Text to display=%s\r\n", pShortcuts[i].szName); pShortcuts[i].szName[127]=_T('\0'); } @@ -476,195 +630,3 @@ return S_OK; } - - -STDMETHODIMP CMenuExt::Initialize(LPCITEMIDLIST pidlFolder, LPDATAOBJECT lpdobj, HKEY /*hkeyProgID*/) -{ - // check options - HRESULT hResult = IsShellExtEnabled(m_piShellExtControl); - if(FAILED(hResult) || hResult == S_FALSE) - return hResult; - - // find ch window - HWND hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); - if (hWnd == NULL) - return E_FAIL; - - // get cfg from ch - ::SendMessage(hWnd, WM_GETCONFIG, GC_EXPLORER, 0); - - // read dest folder - m_szDstPath[0]=_T('\0'); - - // TEMP -// OTF("****************************************************************\r\n"); -// OTF("CMenuExt::Initialize: pidlFolder=%lu, lpdobj=%lu\r\n", pidlFolder, lpdobj); - - // get data from IDataObject - files to copy/move - bool bPathFound=false; - m_bGroupFiles=false; - if (lpdobj) - { - STGMEDIUM medium; - FORMATETC fe = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; - - HRESULT hr = lpdobj->GetData(&fe, &medium); - if (FAILED(hr)) - return E_FAIL; - - // copy all filenames to a table - GetDataFromClipboard(static_cast(medium.hGlobal), NULL, &m_bBuffer.m_pszFiles, &m_bBuffer.m_iDataSize); - - // find the first non-empty entry - UINT fileCount = DragQueryFile((HDROP)medium.hGlobal, 0xFFFFFFFF, NULL, 0); - TCHAR szPath[_MAX_PATH]; - UINT uiRes; - for (UINT i=0;iGetCommandsPtr(); - -// OTF("Invoke Command\r\n"); - // command type - switch (LOWORD(lpici->lpVerb)) - { - // paste & paste special - case 0: - case 1: - { - // search for data in a clipboard - if (IsClipboardFormatAvailable(CF_HDROP)) - { - bool bMove=false; // 0-copy, 1-move - - // get data - OpenClipboard(lpici->hwnd); - HANDLE handle=GetClipboardData(CF_HDROP); - TCHAR *pchBuffer=NULL; - UINT uiSize; - - GetDataFromClipboard(static_cast(handle), m_szDstPath, &pchBuffer, &uiSize); - - // register clipboard format nad if exists in it - UINT nFormat=RegisterClipboardFormat(_T("Preferred DropEffect")); - if (IsClipboardFormatAvailable(nFormat)) - { - handle=GetClipboardData(nFormat); - LPVOID addr=GlobalLock(handle); - if(!addr) - return E_FAIL; - DWORD dwData=((DWORD*)addr)[0]; - if (dwData & DROPEFFECT_MOVE) - bMove=true; - - GlobalUnlock(handle); - } - - CloseClipboard(); - - // fill struct - COPYDATASTRUCT cds; - cds.dwData=(((DWORD)bMove) << 31) | pCommand[LOWORD(lpici->lpVerb)].uiCommandID; - cds.lpData=pchBuffer; - cds.cbData=uiSize * sizeof(TCHAR); - - // send a message - ::SendMessage(hWnd, WM_COPYDATA, reinterpret_cast(lpici->hwnd), reinterpret_cast(&cds)); - - // delete buffer - delete [] pchBuffer; - } - } - break; - -// case 2: -// case 3: -// case 4: - default: - { - // out of range - may be a shortcut - if (LOWORD(lpici->lpVerb) < g_pscsShared->iCommandCount+(m_bBackground ? 0 : 3*g_pscsShared->iShortcutsCount)) - { - // addr of a table with shortcuts - _SHORTCUT* stShortcuts = g_pscsShared->GetShortcutsPtr(); - - // find command for which this command is generated - int iCommandIndex=(int)(((LOWORD(lpici->lpVerb)-5) / g_pscsShared->iShortcutsCount))+2; // command index - int iShortcutIndex=((LOWORD(lpici->lpVerb)-5) % g_pscsShared->iShortcutsCount); // shortcut index - - // buffer for data - UINT uiSize=_tcslen(stShortcuts[iShortcutIndex].szPath)+1+m_bBuffer.m_iDataSize; - TCHAR *pszBuffer=new TCHAR[uiSize]; - _tcscpy(pszBuffer, stShortcuts[iShortcutIndex].szPath); // �cie�ka docelowa - - // buffer with files - memcpy(pszBuffer+_tcslen(stShortcuts[iShortcutIndex].szPath)+1, m_bBuffer.m_pszFiles, m_bBuffer.m_iDataSize*sizeof(TCHAR)); - - // fill struct - COPYDATASTRUCT cds; - cds.dwData=pCommand[iCommandIndex].uiCommandID; - cds.lpData=pszBuffer; - cds.cbData=uiSize * sizeof(TCHAR); - - // send message - ::SendMessage(hWnd, WM_COPYDATA, reinterpret_cast(lpici->hwnd), reinterpret_cast(&cds)); - - // delete buffer - delete [] pszBuffer; - m_bBuffer.Destroy(); - } - else - return E_FAIL; - } - break; - } - - return S_OK; -}