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

📄 dllregshlext.cpp

📁 Windows Shell扩展编程完全指南 2
💻 CPP
字号:
// DLLRegShlExt.cpp : Implementation of CDLLRegShlExt

#include "stdafx.h"
#include "DLLReg.h"
#include "resource.h"
#include "DLLRegShlExt.h"
#include "ProgressDlg.h"


/////////////////////////////////////////////////////////////////////////////
// CDLLRegShlExt construction/destruction

CDLLRegShlExt::CDLLRegShlExt()
{
    m_hRegBmp = LoadBitmap ( _Module.GetModuleInstance(),
                             MAKEINTRESOURCE(IDB_REGISTERBMP) );

    m_hUnregBmp = LoadBitmap ( _Module.GetModuleInstance(),
                               MAKEINTRESOURCE(IDB_UNREGISTERBMP) );
}

CDLLRegShlExt::~CDLLRegShlExt()
{
    if ( NULL != m_hRegBmp )
        DeleteObject ( m_hRegBmp );

    if ( NULL != m_hUnregBmp )
        DeleteObject ( m_hUnregBmp );
}


/////////////////////////////////////////////////////////////////////////////
// CDLLRegShlExt IShellExtInit methods

//////////////////////////////////////////////////////////////////////////
//
// Function:    Initialize()
//
// Description:
//  Reads in the list of selected folders and stores them for later use.
//
//////////////////////////////////////////////////////////////////////////

HRESULT CDLLRegShlExt::Initialize (
    LPCITEMIDLIST pidlFolder, LPDATAOBJECT pDO, HKEY hProgID )
{
TCHAR     szFile[MAX_PATH], szCurrDir[MAX_PATH];
UINT      uNumFiles;
HDROP     hdrop;
FORMATETC etc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM stg = { TYMED_HGLOBAL };
HINSTANCE hinst;
bool      bChangedDir = false;
DWORD     dwLoadLibFlags = 0;
HRESULT (STDAPICALLTYPE* pfn)();

    if ( (GetVersion() & 0x80000000) == 0 )
        dwLoadLibFlags = DONT_RESOLVE_DLL_REFERENCES;

    // Read the list of folders from the data object.  They're stored in HDROP
    // form, so just get the HDROP handle and then use the drag 'n' drop APIs
    // on it.
    if ( FAILED( pDO->GetData ( &etc, &stg ) ))
        return E_INVALIDARG;

    // Get an HDROP handle.
    hdrop = (HDROP) GlobalLock ( stg.hGlobal );

    if ( NULL == hdrop )
        {
        ReleaseStgMedium ( &stg );
        return E_INVALIDARG;
        }

    // Determine how many files are involved in this operation.
    uNumFiles = DragQueryFile ( hdrop, 0xFFFFFFFF, NULL, 0 );

    for ( UINT uFile = 0; uFile < uNumFiles; uFile++ )
        {
        // Get the next filename.
        if ( 0 == DragQueryFile ( hdrop, uFile, szFile, MAX_PATH ) )
            continue;

        ATLTRACE("Checking file <%s>\n", szFile);

        // If this is the first time thru the for loop, we need to
        // change the current directory to the one that was open in
        // explorer.  This is done so the DLLs we're about to load
        // can load other DLLs they depend on to be in the same
        // directory.
        if ( !bChangedDir )
            {
            TCHAR szFolder[MAX_PATH];

            lstrcpyn ( szFolder, szFile, countof(szFolder) );
            PathRemoveFileSpec ( szFolder );

            // Save the current directory, and then change it.
            GetCurrentDirectory ( MAX_PATH, szCurrDir );

            if ( SetCurrentDirectory ( szFolder ) )
                bChangedDir = true;
            }   // end if

        // Try & load the DLL.
        hinst = LoadLibraryEx ( szFile, NULL, dwLoadLibFlags );
        
        if ( NULL == hinst )
            {
            ATLTRACE("Error: LoadLibraryEx() failed, error = %lu\n", GetLastError());
            continue;
            }

        // Get the address of DllRegisterServer();
        (FARPROC&) pfn = GetProcAddress ( hinst, "DllRegisterServer" );

        // If it wasn't found, skip the file.
        if ( NULL == pfn )
            {
            FreeLibrary ( hinst );
            ATLTRACE("DllRegisterServer export not found\n");
            continue;
            }

        // Get the address of DllUnregisterServer();
        (FARPROC&) pfn = GetProcAddress ( hinst, "DllUnregisterServer" );

        // If it was found, we can operate on the file, so add it to
        // our list o' files that we will register/unregister.
        if ( NULL != pfn )
            m_lsFiles.push_back ( szFile );
        else
            ATLTRACE("DllUnregisterServer export not found\n");

        FreeLibrary ( hinst );
        }   // end for

    // Change back to the original directory if we changed it.
    if ( bChangedDir )
        SetCurrentDirectory ( szCurrDir );

    // Release resources.
    GlobalUnlock ( stg.hGlobal );
    ReleaseStgMedium ( &stg );

    // If we found any files we can work with, return S_OK.  Otherwise,
    // return E_INVALIDARG so we don't get called again for this right-click
    // operation.
    return (m_lsFiles.size() > 0) ? S_OK : E_INVALIDARG;
}


/////////////////////////////////////////////////////////////////////////////
// CDLLRegShlExt IContextMenu methods

//////////////////////////////////////////////////////////////////////////
//
// Function:    QueryContextMenu()
//
// Description:
//  Adds our items to the supplied menu.
//
//////////////////////////////////////////////////////////////////////////

HRESULT CDLLRegShlExt::QueryContextMenu (
    HMENU hmenu, UINT uMenuIndex, UINT uidFirstCmd, UINT uidLastCmd, UINT uFlags )
{
UINT uCmdID = uidFirstCmd;

    // If the flags include CMF_DEFAULTONLY then we shouldn't do anything.
    if ( uFlags & CMF_DEFAULTONLY )
        return MAKE_HRESULT ( SEVERITY_SUCCESS, FACILITY_NULL, 0 );

    // Add our register/unregister items.
    InsertMenu ( hmenu, uMenuIndex, MF_STRING | MF_BYPOSITION, uCmdID++,
                 _T("Register server(s)") );

    // Set the bitmap for the register item.
    if ( NULL != m_hRegBmp )
        SetMenuItemBitmaps ( hmenu, uMenuIndex, MF_BYPOSITION, m_hRegBmp, NULL );

    uMenuIndex++;

    InsertMenu ( hmenu, uMenuIndex, MF_STRING | MF_BYPOSITION, uCmdID++,
                 _T("Unregister server(s)") );

    // Set the bitmap for the unregister item.
    if ( NULL != m_hUnregBmp )
        SetMenuItemBitmaps ( hmenu, uMenuIndex, MF_BYPOSITION, m_hUnregBmp, NULL );

    uMenuIndex++;

    // The return value tells the shell how many top-level items we added.
    return MAKE_HRESULT ( SEVERITY_SUCCESS, FACILITY_NULL, 2 );
}


//////////////////////////////////////////////////////////////////////////
//
// Function:    GetCommandString()
//
// Description:
//  Sets the flyby help string for the Explorer status bar.
//
//////////////////////////////////////////////////////////////////////////

HRESULT CDLLRegShlExt::GetCommandString (
    UINT uCmdID, UINT uFlags, UINT* puReserved, LPSTR szName, UINT cchMax )
{
USES_CONVERSION;
LPCTSTR szPrompt;

    if ( uFlags & GCS_HELPTEXT )
        {
        switch ( uCmdID )
            {
            case 0:
                szPrompt = _T("Register all selected COM servers");
            break;

            case 1:
                szPrompt = _T("Unregister all selected COM servers");
            break;

            default:
                ATLASSERT(0);           // should never get here
                return E_INVALIDARG;
            break;
            }

        // Copy the help text into the supplied buffer.  If the shell wants
        // a Unicode string, we need to case szName to an LPCWSTR.
        if ( uFlags & GCS_UNICODE )
            lstrcpynW ( (LPWSTR) szName, T2CW(szPrompt), cchMax );
        else
            lstrcpynA ( szName, T2CA(szPrompt), cchMax );
        }
    else if ( uFlags & GCS_VERB )
        {
        // Copy the verb name into the supplied buffer.  If the shell wants
        // a Unicode string, we need to case szName to an LPCWSTR.
        switch ( uCmdID )
            {
            case 0:
                if ( uFlags & GCS_UNICODE )
                    lstrcpynW ( (LPWSTR) szName, L"DllRegSvr", cchMax );
                else
                    lstrcpynA ( szName, "DllRegSvr", cchMax );
            break;

            case 1:
                if ( uFlags & GCS_UNICODE )
                    lstrcpynW ( (LPWSTR) szName, L"DllUnregSvr", cchMax );
                else
                    lstrcpynA ( szName, "DllUnregSvr", cchMax );
            break;

            default:
                ATLASSERT(0);           // should never get here
                return E_INVALIDARG;
            break;
            }
        }

    return S_OK;
}


//////////////////////////////////////////////////////////////////////////
//
// Function:    InvokeCommand()
//
// Description:
//  Carries out the selected command.
//
//////////////////////////////////////////////////////////////////////////

HRESULT CDLLRegShlExt::InvokeCommand ( LPCMINVOKECOMMANDINFO pInfo )
{
    // If lpVerb really points to a string, ignore this function call and bail out.  
    if ( 0 != HIWORD( pInfo->lpVerb ) )
        return E_INVALIDARG;

    // Check that lpVerb is one of our commands (0 or 1)
    switch ( LOWORD(pInfo->lpVerb) )
        {
        case 0:
        case 1:
            {
            CProgressDlg dlg ( &m_lsFiles, pInfo );

            dlg.DoModal ( pInfo->hwnd );
            return S_OK;
            }
        break;

        default:
            ATLASSERT(0);               // should never get here
            return E_INVALIDARG;
        break;
        }
}

⌨️ 快捷键说明

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