Index: src/chext/MenuExt.cpp =================================================================== diff -u -N -r3d1951f52696fe21e01618e1bbfb9e14745a3827 -r633a533cb6e741d44fe28aa56339e1d2709b1b27 --- src/chext/MenuExt.cpp (.../MenuExt.cpp) (revision 3d1951f52696fe21e01618e1bbfb9e14745a3827) +++ src/chext/MenuExt.cpp (.../MenuExt.cpp) (revision 633a533cb6e741d44fe28aa56339e1d2709b1b27) @@ -20,19 +20,19 @@ #include "chext.h" #include "MenuExt.h" #include "..\common\ipcstructs.h" -#include "..\common\FileSupport.h" #include "stdio.h" #include "memory.h" -#include "StringHelpers.h" #include "chext-utils.h" #include #include "ShellPathsHelpers.h" #include "../libchcore/TWStringData.h" +#include "../common/TShellExtMenuConfig.h" +#include "../libchcore/TSharedMemory.h" +#include "../libchcore/TTaskDefinition.h" +#include -extern CSharedConfigStruct* g_pscsShared; - // globals -void CutAmpersands(LPTSTR lpszString) +static void CutAmpersands(LPTSTR lpszString) { int iOffset=0; size_t iLength=_tcslen(lpszString); @@ -77,209 +77,35 @@ return hResult; // find ch window + // find ch window HWND hWnd = ::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); - if(hWnd == NULL) - return E_FAIL; + if(!hWnd) + return S_OK; - // get cfg from ch - ::SendMessage(hWnd, WM_GETCONFIG, GC_EXPLORER, 0); + hResult = ReadShellConfig(); + if(SUCCEEDED(hResult)) + hResult = m_tShellExtData.GatherDataFromInitialize(pidlFolder, piDataObject); - // background or folder ? - m_bBackground = (piDataObject == NULL) && (pidlFolder != NULL); - - // get data from IDataObject - files to copy/move - m_bShowPasteOption = true; - - m_vPaths.Clear(); - - if(piDataObject) - { - hResult = ShellPathsHelpers::GetPathsFromIDataObject(piDataObject, m_vPaths); - if(hResult != S_OK) - return E_FAIL; - } - else if(pidlFolder) - { - chcore::TSmartPath pathFromPIDL; - hResult = ShellPathsHelpers::GetPathFromITEMIDLIST(pidlFolder, pathFromPIDL); - if(SUCCEEDED(hResult) && !pathFromPIDL.IsEmpty()) - m_vPaths.Add(pathFromPIDL); - } - else - _ASSERTE(!_T("Both pidlFolder and piDataObject specified. Report this unsupported situation.")); - - // find the first non-empty entry - m_bShowPasteOption = (m_vPaths.GetCount() == 1) && (::GetFileAttributes(m_vPaths.GetAt(0).ToString()) & FILE_ATTRIBUTE_DIRECTORY); - - return S_OK; + return hResult; } -STDMETHODIMP CMenuExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpici) +STDMETHODIMP CMenuExt::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT /*idCmdLast*/, UINT /*uFlags*/) { - ATLTRACE(_T("CMenuExt::InvokeCommand()\n")); + ATLTRACE(_T("CMenuExt::QueryContextMenu()\n")); // check options 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(); - - // command type - switch(LOWORD(lpici->lpVerb)) - { - // paste & paste special - case 0: - case 1: - { - // paste and paste special requires a single directory path inside m_vPaths - if((m_vPaths.GetCount() != 1) || !(::GetFileAttributes(m_vPaths.GetAt(0).ToString()) & FILE_ATTRIBUTE_DIRECTORY)) - return E_FAIL; - - // search for source paths in the clipboard - if(IsClipboardFormatAvailable(CF_HDROP)) - { - bool bMove = false; // 0-copy, 1-move - - // read paths from clipboard - OpenClipboard(lpici->hwnd); - HANDLE hClipboardData = GetClipboardData(CF_HDROP); - - chcore::TPathContainer vPaths; - ShellPathsHelpers::GetPathsFromHDROP(static_cast(hClipboardData), vPaths); - - // check if there is also a hint about operation type - UINT nFormat = RegisterClipboardFormat(_T("Preferred DropEffect")); - if(IsClipboardFormatAvailable(nFormat)) - { - hClipboardData = GetClipboardData(nFormat); - if(!hClipboardData) - return E_FAIL; - - LPVOID pClipboardData = GlobalLock(hClipboardData); - if(!pClipboardData) - return E_FAIL; - - DWORD dwData = ((DWORD*)pClipboardData)[0]; - if(dwData & DROPEFFECT_MOVE) - bMove = true; - - GlobalUnlock(hClipboardData); - } - - CloseClipboard(); - - chcore::TTaskDefinition tTaskDefinition; - tTaskDefinition.SetSourcePaths(vPaths); - tTaskDefinition.SetDestinationPath(m_vPaths.GetAt(0)); - tTaskDefinition.SetOperationType(bMove ? chcore::eOperation_Move : chcore::eOperation_Copy); - - // get task data as xml - chcore::TWStringData wstrData; - tTaskDefinition.StoreInString(wstrData); - - //::MessageBox(NULL, wstrData.GetData(), _T("MenuExt.cpp / Paste [special]"), MB_OK); // TEMP - to be removed before commit - - // fill struct - COPYDATASTRUCT cds; - - switch(pCommand[LOWORD(lpici->lpVerb)].uiCommandID) - { - case CSharedConfigStruct::EC_PASTESPECIAL_FLAG: - cds.dwData = eCDType_TaskDefinitionContentSpecial; - break; - default: - cds.dwData = eCDType_TaskDefinitionContent; - } - cds.lpData = (void*)wstrData.GetData(); - cds.cbData = (DWORD)wstrData.GetBytesCount(); - - // send a message - ::SendMessage(hWnd, WM_COPYDATA, reinterpret_cast(lpici->hwnd), reinterpret_cast(&cds)); - } - } - 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)) - { - // pClipboardData 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 - - chcore::TTaskDefinition tTaskDefinition; - - tTaskDefinition.SetSourcePaths(m_vPaths); - tTaskDefinition.SetDestinationPath(chcore::PathFromString(stShortcuts[iShortcutIndex].szPath)); - tTaskDefinition.SetOperationType(pCommand[iCommandIndex].eOperationType); - - // get task data as xml - chcore::TWStringData wstrData; - tTaskDefinition.StoreInString(wstrData); - -// ::MessageBox(NULL, wstrData.GetData(), _T("MenuExt.cpp / Copy/Move to [special]"), MB_OK); // TEMP - to be removed before commit - - // fill struct - COPYDATASTRUCT cds; - switch(pCommand[iCommandIndex].uiCommandID) - { - case CSharedConfigStruct::EC_COPYMOVETOSPECIAL_FLAG: - cds.dwData = eCDType_TaskDefinitionContentSpecial; - break; - default: - cds.dwData = eCDType_TaskDefinitionContent; - } - - cds.dwData = pCommand[iCommandIndex].uiCommandID; - cds.lpData = (void*)wstrData.GetData(); - cds.cbData = (DWORD)wstrData.GetBytesCount(); - - // send message - ::SendMessage(hWnd, WM_COPYDATA, reinterpret_cast(lpici->hwnd), reinterpret_cast(&cds)); - } - 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) return hResult; // find ch window - HWND hWnd; - hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); + HWND hWnd = ::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); if(!hWnd) return S_OK; - // remember ID of the first command - m_uiFirstID=idCmdFirst; - // current commands count in menu TCHAR szText[_MAX_PATH]; - int iCount=::GetMenuItemCount(hmenu); + int iCount = ::GetMenuItemCount(hMenu); MENUITEMINFO mii; mii.cbSize=sizeof(mii); @@ -290,7 +116,7 @@ // find a place where the commands should be inserted for (int i=0;iGetCommandsPtr(); + TShellMenuItemPtr spRootMenuItem = m_tShellExtMenuConfig.GetCommandRoot(); + m_tContextMenuHandler.Init(spRootMenuItem, hMenu, idCmdFirst, indexMenu, m_tShellExtData, m_tShellExtMenuConfig.GetShowShortcutIcons(), false); - // data about commands - int iCommandCount=0; + return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, m_tContextMenuHandler.GetLastCommandID() - idCmdFirst + 1); +} - if(m_bShowPasteOption) - { - // paste - 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++; - } +STDMETHODIMP CMenuExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpici) +{ + ATLTRACE(_T("CMenuExt::InvokeCommand()\n")); - 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++; - } - } + // textual verbs are not supported by this extension + if(HIWORD(lpici->lpVerb) != 0) + return E_FAIL; - if (!m_bBackground) - { - CreateShortcutsMenu(idCmdFirst+5, g_pscsShared->bShowShortcutIcons); + // check options + HRESULT hResult = IsShellExtEnabled(m_piShellExtControl); + if(FAILED(hResult) || hResult == S_FALSE) + return E_FAIL; // required to process other InvokeCommand handlers. - // copy to > - if (g_pscsShared->uiFlags & CSharedConfigStruct::EC_COPYTO_FLAG) - { - 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=(UINT)_tcslen(pCommand[2].szCommand); + // find window + HWND hWnd = ::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); + if(hWnd == NULL) + return E_FAIL; - ::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++; - } + // find command to be executed, if not found - fail + TShellMenuItemPtr spSelectedItem = m_tContextMenuHandler.GetCommandByMenuItemOffset(LOWORD(lpici->lpVerb)); + if(!spSelectedItem) + return E_FAIL; - // move to > - if (g_pscsShared->uiFlags & CSharedConfigStruct::EC_MOVETO_FLAG) - { - 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=(UINT)_tcslen(pCommand[3].szCommand); + // data retrieval and validation + if(!m_tShellExtData.VerifyItemCanBeExecuted(spSelectedItem)) + return E_FAIL; - ::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++; - } + chcore::TPathContainer vSourcePaths; + chcore::TSmartPath spDestinationPath; + chcore::EOperationType eOperationType = chcore::eOperation_None; - // copy/move to special... > - if (g_pscsShared->uiFlags & CSharedConfigStruct::EC_COPYMOVETOSPECIAL_FLAG) - { - 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=(UINT)_tcslen(pCommand[4].szCommand); + if(!m_tShellExtData.GetSourcePathsByItem(spSelectedItem, vSourcePaths)) + return E_FAIL; + if(!m_tShellExtData.GetDestinationPathByItem(spSelectedItem, spDestinationPath)) + return E_FAIL; + if(!m_tShellExtData.GetOperationTypeByItem(spSelectedItem, eOperationType)) + return E_FAIL; - ::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++; - } - } + chcore::TTaskDefinition tTaskDefinition; + tTaskDefinition.SetSourcePaths(vSourcePaths); + tTaskDefinition.SetDestinationPath(spDestinationPath); + tTaskDefinition.SetOperationType(eOperationType); - return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, g_pscsShared->iCommandCount+(m_bBackground ? 0 : 3*g_pscsShared->iShortcutsCount)); + // get task data as xml + chcore::TWStringData wstrData; + tTaskDefinition.StoreInString(wstrData); + + // fill struct + COPYDATASTRUCT cds; + cds.dwData = spSelectedItem->IsSpecialOperation() ? eCDType_TaskDefinitionContentSpecial : eCDType_TaskDefinitionContent; + cds.lpData = (void*)wstrData.GetData(); + cds.cbData = (DWORD)wstrData.GetBytesCount(); + + // send a message + ::SendMessage(hWnd, WM_COPYDATA, reinterpret_cast(lpici->hwnd), reinterpret_cast(&cds)); + + return S_OK; } HRESULT CMenuExt::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam) @@ -418,43 +224,46 @@ break; case WM_DRAWITEM: - { - LPDRAWITEMSTRUCT lpdis=(LPDRAWITEMSTRUCT) lParam; - DrawMenuItem(lpdis); - break; - } + return DrawMenuItem((LPDRAWITEMSTRUCT)lParam); case WM_MEASUREITEM: { - LPMEASUREITEMSTRUCT lpmis=(LPMEASUREITEMSTRUCT)lParam; + LPMEASUREITEMSTRUCT lpmis = (LPMEASUREITEMSTRUCT)lParam; + if(!lpmis) + return E_FAIL; - // establish display text - int iShortcutIndex=(lpmis->itemID-m_uiFirstID-5)%g_pscsShared->iShortcutsCount; - _SHORTCUT* pShortcuts = g_pscsShared->GetShortcutsPtr(); + // find command to be executed, if not found - fail + TShellMenuItemPtr spSelectedItem = m_tContextMenuHandler.GetCommandByMenuItemOffset(LOWORD(lpmis->itemID)); + if(!spSelectedItem || !spSelectedItem->SpecifiesDestinationPath()) + return E_FAIL; - // measure the text - HWND hDesktop=GetDesktopWindow(); - HDC hDC=GetDC(hDesktop); - // get menu logfont NONCLIENTMETRICS ncm; - ncm.cbSize=sizeof(NONCLIENTMETRICS); + ncm.cbSize = sizeof(NONCLIENTMETRICS); SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0); - HFONT hFont=CreateFontIndirect(&ncm.lfMenuFont); - HFONT hOldFont=(HFONT)SelectObject(hDC, hFont); + HFONT hFont = CreateFontIndirect(&ncm.lfMenuFont); + if(!hFont) + return E_FAIL; + // measure the text + HWND hDesktop = GetDesktopWindow(); + HDC hDC = GetDC(hDesktop); + + HFONT hOldFont = (HFONT)SelectObject(hDC, hFont); + // calc text size SIZE size; - GetTextExtentPoint32(hDC, pShortcuts[iShortcutIndex].szName, (int)_tcslen(pShortcuts[iShortcutIndex].szName), &size); + GetTextExtentPoint32(hDC, spSelectedItem->GetName(), boost::numeric_cast(spSelectedItem->GetName().GetLength()), &size); // restore old settings SelectObject(hDC, hOldFont); ReleaseDC(hDesktop, hDC); + DeleteObject(hFont); // set - lpmis->itemWidth=size.cx+GetSystemMetrics(SM_CXMENUCHECK)+2*GetSystemMetrics(SM_CXSMICON); - lpmis->itemHeight = __max(size.cy+3, GetSystemMetrics(SM_CYMENU)+3); + lpmis->itemWidth = size.cx + GetSystemMetrics(SM_CXMENUCHECK) + 2 * GetSystemMetrics(SM_CXSMICON); + lpmis->itemHeight = __max(size.cy + 3, GetSystemMetrics(SM_CYMENU) + 3); break; } @@ -463,179 +272,133 @@ return S_OK; } -void CMenuExt::DrawMenuItem(LPDRAWITEMSTRUCT lpdis) +HRESULT CMenuExt::DrawMenuItem(LPDRAWITEMSTRUCT lpdis) { + if(!lpdis) + return E_FAIL; + // check if menu - if (lpdis->CtlType != ODT_MENU) - return; + if(lpdis->CtlType != ODT_MENU) + return S_OK; + // find command to be executed, if not found - fail + TShellMenuItemPtr spSelectedItem = m_tContextMenuHandler.GetCommandByMenuItemOffset(LOWORD(lpdis->itemID)); + if(!spSelectedItem || !spSelectedItem->SpecifiesDestinationPath()) + return E_FAIL; + // 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; + 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) + HBRUSH hBrush = NULL; + if(lpdis->itemState & ODS_SELECTED) { SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT)); - hbr=CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT)); + hBrush = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT)); } else { SetTextColor(lpdis->hDC, GetSysColor(COLOR_MENUTEXT)); SetBkColor(lpdis->hDC, GetSysColor(COLOR_MENU)); - hbr=CreateSolidBrush(GetSysColor(COLOR_MENU)); + hBrush = CreateSolidBrush(GetSysColor(COLOR_MENU)); } // draw background - RECT rcSelect=lpdis->rcItem; + RECT rcSelect = lpdis->rcItem; rcSelect.top++; rcSelect.bottom--; - FillRect(lpdis->hDC, &rcSelect, hbr); - DeleteObject(hbr); + FillRect(lpdis->hDC, &rcSelect, hBrush); + DeleteObject(hBrush); // 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); + HIMAGELIST hImageList = (HIMAGELIST)SHGetFileInfo(spSelectedItem->GetDestinationPathInfo().GetDefaultDestinationPath().ToString(), FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(SHFILEINFO), SHGFI_SMALLICON | SHGFI_ICON | SHGFI_SYSICONINDEX); + ImageList_Draw(hImageList, 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; + 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); -} + DrawText(lpdis->hDC, spSelectedItem->GetName(), -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(); - - // fill with shortcuts - _SHORTCUT* pShortcuts=g_pscsShared->GetShortcutsPtr(); - TCHAR szText[256], szSize[32]; - ull_t ullFree; - - for (int i=0;iiShortcutsCount;i++) - { - // modify text - if (g_pscsShared->bShowFreeSpace && GetDynamicFreeSpace(pShortcuts[i].szPath, &ullFree, NULL)) - { - _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); - 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)); - } + return S_OK; } STDMETHODIMP CMenuExt::GetCommandString(UINT_PTR idCmd, UINT uFlags, UINT* /*pwReserved*/, LPSTR pszName, UINT cchMax) { + memset(pszName, 0, cchMax); + + if(uFlags != GCS_HELPTEXTW && uFlags != GCS_HELPTEXTA) + return S_OK; + // check options HRESULT hResult = IsShellExtEnabled(m_piShellExtControl); - if(FAILED(hResult) || hResult == S_FALSE) - { - pszName[0] = _T('\0'); - return hResult; - } - - LONG lFlags = eShellExt_None; - hResult = m_piShellExtControl->GetFlags(&lFlags); if(FAILED(hResult)) - { - pszName[0] = _T('\0'); return hResult; - } - if(!(lFlags & eShellExt_Enabled)) - { - pszName[0] = _T('\0'); + else if(hResult == S_FALSE) return S_OK; - } - if (uFlags == GCS_HELPTEXTW) + TShellMenuItemPtr spSelectedItem = m_tContextMenuHandler.GetCommandByMenuItemOffset(LOWORD(idCmd)); + if(!spSelectedItem || !spSelectedItem->SpecifiesDestinationPath()) + return E_FAIL; + + switch(uFlags) { - 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=g_pscsShared->GetCommandsPtr(); - - switch (idCmd) + case GCS_HELPTEXTW: { - case 0: - case 1: - case 2: - case 3: - case 4: - { - CT2W ct2w(pCommand[idCmd].szDesc); - wcsncpy(reinterpret_cast(pszName), ct2w, cchMax); - break; - } - default: - _SHORTCUT* pShortcuts = g_pscsShared->GetShortcutsPtr(); - if ((int)(idCmd-5) < g_pscsShared->iShortcutsCount*3) - { - CT2W ct2w(pShortcuts[(idCmd-5)%g_pscsShared->iShortcutsCount].szPath); - wcsncpy(reinterpret_cast(pszName), ct2w, cchMax); - } - else - wcsncpy(reinterpret_cast(pszName), L"", cchMax); + wcsncpy(reinterpret_cast(pszName), spSelectedItem->GetItemTip(), spSelectedItem->GetItemTip().GetLength() + 1); + break; } - } - if (uFlags == GCS_HELPTEXTA) - { - // find window - HWND hWnd; - hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); - - if (!hWnd) - strcpy(pszName, ""); - - _COMMAND* pCommand=g_pscsShared->GetCommandsPtr(); - - switch (idCmd) + case GCS_HELPTEXTA: { - case 0: - case 1: - case 2: - case 3: - case 4: - { - CT2A ct2a(pCommand[idCmd].szDesc); - strncpy(reinterpret_cast(pszName), ct2a, cchMax); - break; - } - default: // rest of commands - _SHORTCUT* pShortcuts = g_pscsShared->GetShortcutsPtr(); - if ((int)(idCmd-5) < g_pscsShared->iShortcutsCount*3) - { - CT2A ct2a(pShortcuts[(idCmd-5)%g_pscsShared->iShortcutsCount].szPath); - strncpy(pszName, ct2a, cchMax); - } - else - strncpy(pszName, "", cchMax); + USES_CONVERSION; + CT2A ct2a(spSelectedItem->GetItemTip()); + strncpy(reinterpret_cast(pszName), ct2a, strlen(ct2a) + 1); + break; } } return S_OK; } + +HRESULT CMenuExt::ReadShellConfig() +{ + try + { + HWND hWnd = ::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); + if(hWnd == NULL) + return E_FAIL; + + // get cfg from ch + unsigned long ulSHMID = GetTickCount(); + ::SendMessage(hWnd, WM_GETCONFIG, eLocation_ContextMenu, ulSHMID); + + std::wstring strSHMName = IPCSupport::GenerateSHMName(ulSHMID); + + chcore::TSharedMemory tSharedMemory; + chcore::TWStringData wstrData; + chcore::TConfig cfgShellExtData; + + tSharedMemory.Open(strSHMName.c_str()); + tSharedMemory.Read(wstrData); + + //::MessageBox(NULL, wstrData.GetData(), _T("CMenuExt::ReadShellConfig"), MB_OK); + + cfgShellExtData.ReadFromString(wstrData); + + m_tShellExtMenuConfig.ReadFromConfig(cfgShellExtData, _T("ShellExtCfg")); + + return S_OK; + } + catch(...) + { + return E_FAIL; + } +}