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

📄 view.cpp

📁 很好用的ftp源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*****************************************************************************\
    FILE: view.cpp

    DESCRIPTION:
        This is our ShellView which implements FTP specific behavior.  We get
    the default DefView implementation and then use IShellFolderViewCB to 
    override behavior specific to us.
\*****************************************************************************/

#include "priv.h"
#include "view.h"
#include "ftpobj.h"
#include "statusbr.h"
#include "dialogs.h"
#include <inetcpl.h>
#include <htmlhelp.h>
#include "newmenu.h"


extern ULONG g_cRef_CFtpView;

// {FBDB45F0-DBF8-11d2-BB9B-006097DF5BD4}   Private to msieftp.dll, NEVER EVER use outside of this DLL
const GUID IID_CFtpViewPrivThis = { 0xfbdb45f0, 0xdbf8, 0x11d2, { 0xbb, 0x9b, 0x0, 0x60, 0x97, 0xdf, 0x5b, 0xd4 } };


/*****************************************************************************
 *
 *      COLINFO, c_rgci
 *
 *      Column information for DVM_GETDETAILSOF.
 *
 *****************************************************************************/

const struct COLINFO {
    UINT cchCol;
    UINT uiFmt;
} c_rgci[] = {
    {   30, LVCFMT_LEFT },
    {   10, LVCFMT_RIGHT },
    {   20, LVCFMT_LEFT },
    {   20, LVCFMT_LEFT },
};


BOOL CFtpView::IsForegroundThread(void)
{
    return (GetCurrentThreadId() == m_nThreadID);
}


/*****************************************************************************\
    FUNCTION: _MOTDDialogProc

    DESCRIPTION:
\*****************************************************************************/
INT_PTR CALLBACK CFtpView::_MOTDDialogProc(HWND hDlg, UINT wm, WPARAM wParam, LPARAM lParam)
{
    LRESULT lResult = FALSE;

    switch (wm)
    {
    case WM_INITDIALOG:
        {
            CFtpView * pThis = (CFtpView *) lParam;
            CFtpGlob * pfg = pThis->m_pff->GetSiteMotd();

            if (EVAL(pfg))
            {
                // TODO: NT #250018. Format the message and make it look pretty.
                //       so it doesn't have the FTP status numbers.  We may also
                //       want to filter only the message that comes thru with
                //       status numbers 230
                EVAL(SetWindowText(GetDlgItem(hDlg, IDC_MOTDDLG_MESSAGE), pfg->GetHGlobAsTCHAR()));
                pfg->Release();
            }

        }
        break;

    case WM_COMMAND:
        if ((IDOK == GET_WM_COMMAND_ID(wParam, lParam)) ||
            (IDCANCEL == GET_WM_COMMAND_ID(wParam, lParam)))
            EndDialog(hDlg, TRUE);
        break;
    }

    return lResult;
}


/*****************************************************************************
 *
 *      _ShowMotdPsf
 *
 *      Show the motd for a particular psf.
 *
 *****************************************************************************/
void CFtpView::_ShowMotdPsf(HWND hwndOwner)
{
    DialogBoxParam(HINST_THISDLL, MAKEINTRESOURCE(IDD_MOTDDLG), hwndOwner, _MOTDDialogProc, (LPARAM)this);
}

/*****************************************************************************
 *
 *      _ShowMotd
 *
 *      When Explorer finally goes idle, this procedure will be called,
 *      and we will show the FTP site's (new) motd.
 *
 *****************************************************************************/
void CFtpView::_ShowMotd(void)
{
    m_hgtiWelcome = 0;

    if (EVAL(m_pff))
        _ShowMotdPsf(m_hwndOwner);
    else
    {
        // We got cancelled prematurely
    }
}

/*****************************************************************************
 *
 *      _OnGetDetailsOf
 *
 *      ici     - column for which information is requested
 *      pdi     -> DETAILSINFO
 *
 *      If pdi->pidl is 0, then we are asking for information about
 *      what columns to display.  If pdi->pidl is nonzero, then we
 *      are asking for particular information about the specified pidl.
 *
 *      _UNDOCUMENTED_: This callback and the DETAILSINFO structure
 *      are not documented.  Nor is the quirk about pdi->pidl as
 *      noted above.
 *
 *****************************************************************************/
#define MAX_SIZE_STR        30

HRESULT CFtpView::_OnGetDetailsOf(UINT ici, PDETAILSINFO pdi)
{
    HRESULT hr;

    if (ici < COL_MAX)
    {
        pdi->str.uType = STRRET_CSTR;
        pdi->str.cStr[0] = '\0';

        if (pdi->pidl)
        {
            switch (ici)
            {
            case COL_NAME:
                {
                    WCHAR wzDisplayName[MAX_PATH];
                    hr = FtpItemID_GetDisplayName(pdi->pidl, wzDisplayName, ARRAYSIZE(wzDisplayName));
                    if (EVAL(SUCCEEDED(hr)))
                        StringToStrRetW(wzDisplayName, &pdi->str);
                }
                break;

            case COL_SIZE:
                //  (Directories don't get a size.  Shell rules.)
                if (!FtpPidl_IsDirectory(pdi->pidl, TRUE))
                {
                    LONGLONG llSize = (LONGLONG) FtpItemID_GetFileSize(pdi->pidl);
                    WCHAR wzSizeStr[MAX_SIZE_STR];

                    if (StrFormatByteSizeW(llSize, wzSizeStr, ARRAYSIZE(wzSizeStr)))
                        SHUnicodeToAnsi(wzSizeStr, pdi->str.cStr, ARRAYSIZE(pdi->str.cStr));
                    else
                        StrFormatByteSizeA(FtpItemID_GetFileSizeLo(pdi->pidl), pdi->str.cStr, ARRAYSIZE(pdi->str.cStr));
                }
                hr = S_OK;
            break;

            case COL_TYPE:
                hr = FtpPidl_GetFileTypeStrRet(pdi->pidl, &pdi->str);
                break;

            case COL_MODIFIED:
                {
                    TCHAR szDateTime[MAX_PATH];
                    FILETIME ftLastModified = FtpPidl_GetFTPFileTime(pdi->pidl);
                    DWORD dwFlags = FDTF_SHORTDATE | FDTF_SHORTTIME;
                    switch (pdi->fmt)
                    {
                        case LVCFMT_LEFT_TO_RIGHT :
                            dwFlags |= FDTF_LTRDATE;
                        break;

                        case LVCFMT_RIGHT_TO_LEFT :
                            dwFlags |= FDTF_RTLDATE;
                        break;
                    }
                    Misc_StringFromFileTime(szDateTime, ARRAYSIZE(szDateTime), &ftLastModified, dwFlags);
                    hr = StringToStrRetW(szDateTime, &pdi->str);
                }
                break;
            }

        }
        else
        {
            WCHAR wzColumnLable[MAX_PATH];

            pdi->fmt = c_rgci[ici].uiFmt;
            pdi->cxChar = c_rgci[ici].cchCol;

            EVAL(LoadStringW(HINST_THISDLL, IDS_HEADER_NAME(ici), wzColumnLable, ARRAYSIZE(wzColumnLable)));
            hr = StringToStrRetW(wzColumnLable, &pdi->str);
        }
    }
    else
        hr = E_NOTIMPL;

    return hr;
}


/*****************************************************************************\
    FUNCTION: _OnColumnClick

    DESCRIPTION:
      _UNDOCUMENTED_: This callback and its parameters are not documented.
      _UNDOCUMENTED_: ShellFolderView_ReArrange is not documented.

    PARAMETERS:
      hwnd    - view window
      ici     - column that was clicked
\*****************************************************************************/
HRESULT CFtpView::_OnColumnClick(UINT ici)
{
    ShellFolderView_ReArrange(m_hwndOwner, ici);

    return S_OK;
}


HRESULT CFtpView::_OnAddPropertyPages(SFVM_PROPPAGE_DATA * pData)
{
    return AddFTPPropertyPages(pData->pfn, pData->lParam, &m_hinstInetCpl, m_psfv);
}


/*****************************************************************************\
    FUNCTION: _OnInitMenuPopup

    DESCRIPTION:
        We use IContextMenu::QueryContectMenu() to merge background items into
    the File menu.  This doesn't work on browser only because it's not supported
    so we would like to see if this works.

    PARAMETERS:
\*****************************************************************************/
HRESULT CFtpView::_OnInitMenuPopup(HMENU hmenu, UINT idCmdFirst, UINT nIndex)
{
    return S_OK;
}


/*****************************************************************************\
    FUNCTION: _OnMergeMenu

    DESCRIPTION:
      _UNDOCUMENTED_: This callback and its parameters are not documented.
      _UNDOCUMENTED_: Nothing about menu merging is documented.

    PARAMETERS:
      pqcm    - QueryContextMenu info
\*****************************************************************************/
HRESULT CFtpView::_OnMergeMenu(LPQCMINFO pqcm)
{
    HRESULT hr;
    HMENU hmenu = LoadMenu(HINST_THISDLL, MAKEINTRESOURCE(IDM_FTPMERGE));

    if (SHELL_VERSION_W95NT4 != GetShellVersion())
    {
        // We prefer to add "New" and "Login As" via
        // IContextMenu::QueryContextMenu() but it wasn't implemented
        // in browser only.  The IDM_FTPMERGE menu contains a second
        // copy for the browser only case so we need to remove them
        // if it's not browser only.
        EVAL(DeleteMenu(hmenu, FCIDM_MENU_FILE, MF_BYCOMMAND));
    }

    if (SHELL_VERSION_IE4 < GetShellVersion())
    {
        // Remove "Help.FTP Help" because we will have that work done
        // in "Help.Help Topics" on NT5 and after.  We don't do this for
        // earlier versions of shell32 because shell32 in NT5 is the 
        // first version to support "HtmlHelp" over WinHelp.  This is
        // needed because FTP's help is stored in IE's HTML Help files.
        EVAL(DeleteMenu(hmenu, IDC_ITEM_FTPHELP, MF_BYCOMMAND));
    }

    if (hmenu)
    {
        MergeMenuHierarchy(pqcm->hmenu, hmenu, pqcm->idCmdFirst, pqcm->idCmdLast);
        m_idMergedMenus = pqcm->idCmdFirst;
        m_nMenuItemsAdded = GetMenuItemCount(hmenu);
        DestroyMenu(hmenu);

        // Remove duplicate items. (Browser Only)
        _SHPrettyMenu(pqcm->hmenu);
        hr = S_OK;
    }
    else
    {
        hr = E_OUTOFMEMORY;
    }

    // NT #267081, some other people (IE) will reformat the StatusBar during the
    // asynch navigation.  I take this event (MergeMenus) and reformat the
    // status bar if necessary.
    _InitStatusBar();

    return hr;
}


/*****************************************************************************\
    FUNCTION: UnMergeMenu

    DESCRIPTION:

    PARAMETERS:
\*****************************************************************************/
HRESULT UnMergeMenu(HMENU hMenu, UINT idOffset, HMENU hMenuTemplate)
{
    HRESULT hr = S_OK;
    UINT nIndex;
    UINT nEnd = GetMenuItemCount(hMenuTemplate);

    for (nIndex = 0; nIndex < nEnd; nIndex++)
    {
        UINT idToDelete = GetMenuItemID(hMenuTemplate, nIndex);

        if (-1 != idToDelete)
            DeleteMenu(hMenu, (idToDelete + idOffset), MF_BYPOSITION);
        else
        {
            // It may be a submenu, so we may need to recurse.
            MENUITEMINFO mii;

            mii.cbSize = sizeof(mii);
            mii.fMask = MIIM_SUBMENU;
            mii.cch = 0;     // just in case

            if (GetMenuItemInfo(hMenuTemplate, nIndex, TRUE, &mii) && mii.hSubMenu)
            {
                // It is a sub menu, so delete those items also.
                hr = UnMergeMenu(hMenu, idOffset, mii.hSubMenu);
            }
        }
    }

    return hr;
}


HRESULT CFtpView::_OnUnMergeMenu(HMENU hMenu)
{
    HRESULT hr = S_OK;

    // Did I merge anything?
    if (m_idMergedMenus && m_nMenuItemsAdded)
    {
        HMENU hMenuFTP = LoadMenu(HINST_THISDLL, MAKEINTRESOURCE(IDM_FTPMERGE));

        if (hMenuFTP)
        {
            hr = UnMergeMenu(hMenu, m_idMergedMenus, hMenuFTP);
            DestroyMenu(hMenuFTP);
        }

        m_idMergedMenus = 0;
    }

    return hr;
}


⌨️ 快捷键说明

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