⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftpcm.cpp

📁 很好用的ftp源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
{
    ASSERT(ILIsSimple(pidl));

    if (GetAsyncKeyState(VK_ESCAPE) >= 0)
    {
        if (EVAL(SUCCEEDED(peii->hres)))
            peii->hres = peii->pfn(peii->pfcm, peii->pici, peii->ptszCmd, pidl);
    }
    else
        peii->hres = HRESULT_FROM_WIN32(ERROR_CANCELLED);

    return SUCCEEDED(peii->hres);
}





/*****************************************************************************\
 *
 *    _EnumInvoke
 *
 * Invoke the command on each object in the list, assuming that
 * permissions are properly set.  (We need to check the permissions
 * in case somebody randomly threw the verb at us.)
 *
\*****************************************************************************/

STDMETHODIMP CFtpMenu::_EnumInvoke(LPCMINVOKECOMMANDINFO pici, INVOKEPROC pfn, LPCTSTR pszCmd)
{
    EII eii;
    eii.pfcm = this;
    eii.pici = pici;
    eii.pfn = pfn;
    eii.ptszCmd = pszCmd;
    eii.hres = S_OK;

    if (m_pflHfpl->GetCount())
        m_pflHfpl->Enum(_InvokeOneCB, (LPVOID) &eii);
    else
        _InvokeOne(c_pidlNil, &eii);

    return eii.hres;
}





/*****************************************************************************\
 *
 * _InvokeRename
 *
 * Rename the object to the indicated name.
 *
 *  The rename verb should have been enabled only if the pidl list
 *  is singleton.  Of course, that doesn't prevent some random bozo
 *  from throwing the word "rename" at us from out of the blue, so
 *  we need to remain on guard.
 *
 * _UNOBVIOUS_:  If the user does an in-place rename, we don't get
 *  a "rename" command invoked against our context menu.  Instead,
 *  the shell goes straight for the SetNameOf method in the ShellFolder.
 *  Which means that we cannot put UI in the context menu (which is the
 *  obvious place for it, because it has a CMIC_MASK_FLAG_NO_UI bit);
 *  we must put it into SetNameOf, which is annoying because it means
 *  there is no way to programmatically perform a SetNameOf without UI.
 *
 *  _SOMEDAY_
 *  We fix this unobvious-ness by passing the CMIC_MASK_FLAG_NO_UI bit
 *  through to our SetNameOf backdoor, so you can programmatically
 *  rename a file without UI by going through the IContextMenu.
 *
\*****************************************************************************/

HRESULT CFtpMenu::_InvokeRename(LPCMINVOKECOMMANDINFO pici)
{
    HRESULT hr;

    if (EVAL((m_sfgao & SFGAO_CANRENAME) && m_pfd))
    {
        ASSERT(m_pflHfpl->GetCount() == 1);
        if (EVAL(pici->lpParameters))
        {
            TCHAR szParams[MAX_URL_STRING];

            ASSERT(pici->hwnd);
            SHAnsiToTChar(pici->lpParameters, szParams, ARRAYSIZE(szParams));
            hr = m_pfd->SetNameOf(m_pff, pici->hwnd, m_pflHfpl->GetPidl(0), szParams, SHGDN_INFOLDER, 0);
        }
        else
            hr = E_INVALIDARG;    // Arguments required
    }
    else
        hr = E_ACCESSDENIED;        // Can't rename this

    return hr;
}


/*****************************************************************************\
 *    _InvokeCutCopy
 *
 *    Cut or copy the selection to the OLE clipboard.  No big deal.
 *
 *    Note that GetUIObjectOfHfpl(IID_IDataObject) will fail if we
 *    are talking about ourself.  Maybe it shouldn't but it does today.
\*****************************************************************************/
HRESULT CFtpMenu::_InvokeCutCopy(UINT_PTR id, LPCMINVOKECOMMANDINFO pici)
{
    IDataObject * pdo;
    HRESULT hr;

    hr = m_pff->GetUIObjectOfHfpl(pici->hwnd, m_pflHfpl, IID_IDataObject, (LPVOID *)&pdo, m_fBackground);
    if (EVAL(SUCCEEDED(hr)))
    {
        DWORD dwEffect = ((DFM_CMD_COPY == id) ? DROPEFFECT_COPY : DROPEFFECT_MOVE);

        EVAL(SUCCEEDED(DataObj_SetPreferredEffect(pdo, dwEffect)));

        ShellFolderView_SetPoints(m_hwnd, pdo);
        hr = OleSetClipboard(pdo);    // Will do its own AddRef
        ShellFolderView_SetClipboard(m_hwnd, id);
        
        if (pdo)
            pdo->Release();
    }
    else
        ASSERT(0);         // BUGBUG -- error UI 

    return hr;
}

/*****************************************************************************\
    FUNCTION: _DoDrop

    DESCRIPTION:
        The user just did a Paste on FTP so we want to do the operation.
    We will use our Drag & Drop code to carry out the operation.  We don't
    currently support optimized FTP operations but a lot could be done if
    we did.

    First we need to find out if the caller did "Cut" or "Copy" to create
    the IDataObject.  We can find out by asking the IDataObject for the
    CFSTR_PREFERREDDROPEFFECT.
\*****************************************************************************/
HRESULT CFtpMenu::_DoDrop(IDropTarget * pdt, IDataObject * pdo)
{
    POINTL pt = {0, 0};
    DWORD dwEffect = DROPEFFECT_COPY;   // Default
    HRESULT hr = DataObj_GetDWORD(pdo, g_dropTypes[DROP_PrefDe].cfFormat, &dwEffect);

#ifndef FEATURE_CUT_MOVE    
    dwEffect = DROPEFFECT_COPY;     // Forcibly remove the MOVE effect
#endif // FEATURE_CUT_MOVE

    hr = pdt->DragEnter(pdo, MK_LBUTTON, pt, &dwEffect);
    if (EVAL(SUCCEEDED(hr)) && dwEffect)
    {
#ifndef FEATURE_CUT_MOVE    
        dwEffect = DROPEFFECT_COPY;     // Forcibly remove the MOVE effect
#endif // FEATURE_CUT_MOVE
        hr = pdt->Drop(pdo, MK_LBUTTON, pt, &dwEffect);
    }
    else
        pdt->DragLeave();

    return hr;
}

/*****************************************************************************\
 *
 *    _InvokePaste
 *
 *    Copy from the OLE clipboard into the selcted folder (which might
 *    be ourselves).
 *
\*****************************************************************************/

HRESULT CFtpMenu::_InvokePaste(LPCMINVOKECOMMANDINFO pici)
{
    HRESULT hres = E_FAIL;

    if (EVAL(m_sfgao & SFGAO_DROPTARGET))
    {
        IDataObject *pdto;
        hres = OleGetClipboard(&pdto);
        if (EVAL(SUCCEEDED(hres)))
        {
            IDropTarget *pdt;
            hres = m_pff->GetUIObjectOfHfpl(pici->hwnd, m_pflHfpl, IID_IDropTarget, (LPVOID *)&pdt, m_fBackground);
            if (EVAL(SUCCEEDED(hres)))
            {
                hres = _DoDrop(pdt, pdto);
                if (pdt)
                    pdt->Release();
            }
            else
            {
                // BUGBUG -- error UI
            }
            if (pdto)
                pdto->Release();
        }
        else
        {
            // BUGBUG -- error UI
        }
    }
    else
    {
        // BUGBUG -- error UI
    }

    return hres;
}


//===========================
// *** IContextMenu Interface ***
//===========================


/*****************************************************************************\
    FUNCTION: _ContainsForgroundItems
  
    DESCRIPTION:
        We want to know if the user selected items in the view and then invoked
    some menu (Context Menu, File Menu, CaptionBar icon menu, etc.).  Normally
    this is as simple as seeing if (0 == m_pflHfpl->GetCount()).  However,
    there is one other nasty case where (1 == m_pflHfpl->GetCount()) and
    the user still didn't select anything.  This case happens when the user
    is at the root of a FTP share and the CaptionBar menu is dropped down.
    In that case, the single pidl is the pidl to the ftp root.
\*****************************************************************************/
BOOL CFtpMenu::_ContainsForgroundItems(void)
{
    BOOL fIsForground = (0 != m_pflHfpl->GetCount());

    if (fIsForground && (1 == m_pflHfpl->GetCount()))
    {
        LPITEMIDLIST pidl = m_pflHfpl->GetPidl(0);

        if (FtpID_IsServerItemID(pidl) && ILIsEmpty(_ILNext(pidl)))
        {
            if (!m_pfd)
            {
                CFtpSite * pfs;

                // In this strange case, our m_pfd is NULL, so we need
                // to create it from pidl.
                if (EVAL(SUCCEEDED(SiteCache_PidlLookup(pidl, FALSE, m_pff->GetItemAllocatorDirect(), &pfs))))
                {
                    EVAL(SUCCEEDED(pfs->GetFtpDir(pidl, &m_pfd)));
                    pfs->Release();
                }
            }
            fIsForground = FALSE;
        }
    }

    return fIsForground;
}


BOOL CFtpMenu::_IsCallerCaptionBar(UINT indexMenu, UINT uFlags)
{
    BOOL fFromCaptionBar;

    if ((0 == uFlags) && (1 == indexMenu))
        fFromCaptionBar = TRUE;
    else
        fFromCaptionBar = FALSE;

    return fFromCaptionBar;
}


/*****************************************************************************\
    FUNCTION: IContextMenu::QueryContextMenu
  
    DESCRIPTION:
        Given an existing context menu hmenu, insert new context menu
    items at location indexMenu (indexMenu = index to menu indexMenu), returning the
    number of menu items added.

    The incoming flags control how much goop we add to the menu.
    It is important not to add "Delete", "Rename", etc., to context
    menus that come from shortcuts, else the user gets hit with
    two "Delete" verbs, one to delete the object from the FTP site,
    and the other to delete the shortcut.  How confusing...

    hmenu     - destination menu
    indexMenu - location at which menu items should be inserted
    idCmdFirst - first available menu identifier
    idCmdLast - first unavailable menu identifier

    _UNDOCUMENTED_:  The "shared" menu items are not documented.
    Particularly gruesome, because the "shared" menu items are the
    only way to get Rename, Delete, etc. to work.  You can't roll
    your own, because those magics are handled partly in the
    enclosing shell view.

    _UNOBVIOUS_:  The context menu for the folder itself is
    extremely squirly.  It's not like a normal context menu.
    Rather, you add the "New" verb, and any custom verbs, but
    none of the standard folder verbs.

    PARAMS:
        Often, we need to key off strange parameter heiristicts to
    determine who our caller is so we don't enable certain items.
    "Rename" from the from CaptionBar is one example.  Here are what
    we are passed in the different situations:

    CaptionBar:
        QCM(hmenu, 1, idCmdFirst, idCmdLast, 0) m_pflHfpl contains 1
    FileMenu w/1 Selected:
        QCM(hmenu, 0, idCmdFirst, idCmdLast, CMF_DVFILE | CMF_NODEFAULT) m_pflHfpl contains 1
    0 Items Selected:
        QCM(hmenu, -1, idCmdFirst, idCmdLast, 0) m_pflHfpl contains 0
    1 Items Selected:
        QCM(hmenu, 0, idCmdFirst, idCmdLast, CMF_CANRENAME) m_pflHfpl contains 1
    2 Items Selected:
        QCM(hmenu, 0, idCmdFirst, idCmdLast, CMF_CANRENAME) m_pflHfpl contains 2
\*****************************************************************************/
HRESULT CFtpMenu::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
{
    HRESULT hr = S_OK;

    //  HACK: I assume that they are querying during a WM_INITMENUPOPUP or equivelant
    GetCursorPos(&m_ptNewItem);
    m_uFlags = uFlags;

    if (!m_fBackground)
    {
        BOOL fAllFolders = m_pflHfpl->AreAllFolders();

        //  _UNDOCUMENTED_: CMF_DVFILE is not a documented flag.
        if (!(uFlags & (CMF_DVFILE | CMF_VERBSONLY)))
        {
            DWORD sfgao = m_sfgao;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -