Index: CopyHandlerShellExt/MenuExt.cpp =================================================================== diff -u -N --- CopyHandlerShellExt/MenuExt.cpp (revision 3e1186252ab31f63d86d86c4b0ff593cfffbefde) +++ CopyHandlerShellExt/MenuExt.cpp (revision 0) @@ -1,608 +0,0 @@ -/************************************************************************ - Copy Handler 1.x - program for copying data in Microsoft Windows - systems. - Copyright (C) 2001-2004 Ixen Gerthannes (copyhandler@o2.pl) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - 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 General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*************************************************************************/ -#include "stdafx.h" -#include "CopyHandlerShellExt.h" -#include "MenuExt.h" -#include "clipboard.h" -#include "..\Common\ipcstructs.h" -#include "..\Common\FileSupport.h" -#include "stdio.h" -#include "memory.h" -#include "StringHelpers.h" - -extern CSharedConfigStruct* g_pscsShared; - -// globals -void CutAmpersands(LPTSTR lpszString) -{ - int iOffset=0; - int iLength=_tcslen(lpszString); - for (int j=0;jitemID-m_uiFirstID-5)%g_pscsShared->iShortcutsCount; - _SHORTCUT* pShortcuts=(_SHORTCUT*)(g_pscsShared->szData+g_pscsShared->iCommandCount*sizeof(_COMMAND)); - - // 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, _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=(_SHORTCUT*)(g_pscsShared->szData+g_pscsShared->iCommandCount*sizeof(_COMMAND)); - - // 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; - -// OTF("Drawing text: %s\r\n", pShortcuts[iShortcutIndex].szName); - DrawText(lpdis->hDC, pShortcuts[iShortcutIndex].szName, -1, &rcText, DT_LEFT | DT_SINGLELINE | DT_VCENTER); -} - -STDMETHODIMP CMenuExt::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT /*idCmdLast*/, UINT /*uFlags*/) -{ - // find ch window - HWND hWnd; - hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); - if (!hWnd) - return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0); - -/* 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; - - // current commands count in menu - TCHAR szText[_MAX_PATH]; - int iCount=::GetMenuItemCount(hmenu); - - MENUITEMINFO mii; - mii.cbSize=sizeof(mii); - mii.fMask=MIIM_TYPE; - mii.dwTypeData=szText; - mii.cch=_MAX_PATH; - - // find a place where the commands should be inserted - for (int i=0;iszData; - - // data about commands - int iCommandCount=0; - - if (!m_bGroupFiles) - { - // paste - if (g_pscsShared->uiFlags & 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) - { - ::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) - { - MENUITEMINFO mii; - mii.cbSize=sizeof(MENUITEMINFO); - mii.fMask=MIIM_ID | MIIM_STATE | MIIM_SUBMENU | MIIM_TYPE; - mii.fType=MFT_STRING; - mii.fState=(g_pscsShared->iShortcutsCount > 0) ? MFS_ENABLED : MFS_GRAYED; - mii.wID=idCmdFirst+2; - mii.hSubMenu=m_mMenus.hShortcuts[0]; - mii.dwTypeData=pCommand[2].szCommand; - 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); - iCommandCount++; -// OTF("added menu item\r\n"); - } - - // move to > - if (g_pscsShared->uiFlags & EC_MOVETO_FLAG) - { - MENUITEMINFO mii; - mii.cbSize=sizeof(MENUITEMINFO); - mii.fMask=MIIM_ID | MIIM_STATE | MIIM_SUBMENU | MIIM_TYPE; - mii.fType=MFT_STRING; - mii.fState=(g_pscsShared->iShortcutsCount > 0) ? MFS_ENABLED : MFS_GRAYED; - mii.wID=idCmdFirst+3; - mii.hSubMenu=m_mMenus.hShortcuts[1]; - mii.dwTypeData=pCommand[3].szCommand; - 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); - iCommandCount++; - } - - // copy/move to special... > - if (g_pscsShared->uiFlags & EC_COPYMOVETOSPECIAL_FLAG) - { - MENUITEMINFO mii; - mii.cbSize=sizeof(MENUITEMINFO); - mii.fMask=MIIM_ID | MIIM_STATE | MIIM_SUBMENU | MIIM_TYPE; - mii.fType=MFT_STRING; - mii.fState=(g_pscsShared->iShortcutsCount > 0) ? MFS_ENABLED : MFS_GRAYED; - mii.wID=idCmdFirst+4; - mii.hSubMenu=m_mMenus.hShortcuts[2]; - mii.dwTypeData=pCommand[4].szCommand; - 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); - 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) -{ -// OTF("CreateShortcutsMenu\r\n"); - - // tw�rz puste menu - m_mMenus.hShortcuts[0]=CreatePopupMenu(); - m_mMenus.hShortcuts[1]=CreatePopupMenu(); - m_mMenus.hShortcuts[2]=CreatePopupMenu(); - - // fill with shortcuts - _SHORTCUT* pShortcuts=(_SHORTCUT*)(g_pscsShared->szData+g_pscsShared->iCommandCount*sizeof(_COMMAND)); - TCHAR szText[256], szSize[32]; - __int64 iiFree; - - for (int i=0;iiShortcutsCount;i++) - { - // modify text - if (g_pscsShared->bShowFreeSpace && GetDynamicFreeSpace(pShortcuts[i].szPath, &iiFree, NULL)) - { - _stprintf(szText, _T("%s (%s)"), pShortcuts[i].szName, GetSizeString(iiFree, szSize)); - _tcsncpy(pShortcuts[i].szName, szText, 127); -// OTF("Text to display=%s\r\n", pShortcuts[i].szName); - pShortcuts[i].szName[127]=_T('\0'); - } - - // add to all menus - for (int j=0;j<3;j++) - ::InsertMenu(m_mMenus.hShortcuts[j], i, MF_BYPOSITION | MF_ENABLED | (bOwnerDrawn ? MF_OWNERDRAW : 0), uiIDBase+i+j*g_pscsShared->iShortcutsCount, (bOwnerDrawn ? NULL : pShortcuts[i].szName)); - } -} - -STDMETHODIMP CMenuExt::GetCommandString(UINT idCmd, UINT uFlags, UINT* /*pwReserved*/, LPSTR pszName, UINT cchMax) -{ - if (uFlags == GCS_HELPTEXTW) - { - USES_CONVERSION; - // find window - HWND hWnd; - hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); - if (!hWnd) - wcscpy(reinterpret_cast(pszName), L""); - - _COMMAND* pCommand=(_COMMAND*)g_pscsShared->szData; - - switch (idCmd) - { - case 0: - case 1: - case 2: - case 3: - case 4: - wcsncpy(reinterpret_cast(pszName), A2W(pCommand[idCmd].szDesc), cchMax); - break; - default: - _SHORTCUT* pShortcuts=(_SHORTCUT*)(g_pscsShared->szData+g_pscsShared->iCommandCount*sizeof(_COMMAND)); - if ((int)(idCmd-5) < g_pscsShared->iShortcutsCount*3) - wcsncpy(reinterpret_cast(pszName), A2W(pShortcuts[(idCmd-5)%g_pscsShared->iShortcutsCount].szPath), cchMax); - else - wcsncpy(reinterpret_cast(pszName), L"", cchMax); - } - } - if (uFlags == GCS_HELPTEXTA) - { - // find window - HWND hWnd; - hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); - - if (!hWnd) - strcpy(pszName, ""); - - _COMMAND* pCommand=(_COMMAND*)g_pscsShared->szData; - - switch (idCmd) - { - case 0: - case 1: - case 2: - case 3: - case 4: - strncpy(pszName, pCommand[idCmd].szDesc, cchMax); - break; - default: // rest of commands - _SHORTCUT* pShortcuts=(_SHORTCUT*)(g_pscsShared->szData+g_pscsShared->iCommandCount*sizeof(_COMMAND)); - if ((int)(idCmd-5) < g_pscsShared->iShortcutsCount*3) - strncpy(pszName, pShortcuts[(idCmd-5)%g_pscsShared->iShortcutsCount].szPath, cchMax); - else - strncpy(pszName, "", cchMax); - } - } - - return S_OK; -} - - -STDMETHODIMP CMenuExt::Initialize(LPCITEMIDLIST pidlFolder, LPDATAOBJECT lpdobj, HKEY /*hkeyProgID*/) -{ - // 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;iszData; - -// 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); - char *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 handle=GetClipboardData(nFormat); - LPVOID addr=GlobalLock(handle); - - 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; - - // 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=(_SHORTCUT*)(g_pscsShared->szData+g_pscsShared->iCommandCount*sizeof(_COMMAND)); - - // 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; - - // send message - ::SendMessage(hWnd, WM_COPYDATA, reinterpret_cast(lpici->hwnd), reinterpret_cast(&cds)); - - // delete bufor - delete [] pszBuffer; - m_bBuffer.Destroy(); - } - else - return E_FAIL; - } - break; - } - - return S_OK; -}