Windows下的shell扩展的种类以及相关的实例

表一

Windows 外壳扩展

类型
适用于
版本
有关的接口 描述
上下文菜单

Context Menu

文件类和外壳对象 Windows 95+
IContextMenu, IContextMenu2, or IContextMenu3
允许在外壳对象的上下文菜单中增加新的才单项
右拖拽

Right drag and drop

文件类和外壳对象 Windows 95+
IContextMenu, IContextMenu2, or IContextMenu3
允许在右拖拽后出现的上下文菜单中增加新的才单项
绘制外壳图标

Drawing shell Icons

文件类和外壳对象

File class and shell's object

Windows 95+
IExtractIcon
对于一个文件类来说,可以选择文件在运行时应该显示那个图标
属性页

Property Sheet

文件类和外壳对象

File class and shell's object

Windows 95+
IShellPropSheetExt
向文件类属性对话框中加入另外的属性表页。也适用于控制面板应用
左拖拽

Left drag and drop

文件类和外壳对象

File class and shell's object

Windows 95+
IDropTarget
决定在外壳内用鼠标左键拖拽一个对象到另一个对象上时做什么
剪贴板

Clipboard

文件类和外壳对象

File class and shell's object

Windows 95+
IDataObject
定义如何将对象拷贝到剪贴板以及如何从剪贴板吸取对象
文件钩

File Hook


Windows 95+
ICopyHook
控制整个外壳内的任何文件操作。您可以允许或拒绝这些对文件的操作,但不会通知您成功或失败

 

外壳执行程序

Program Execution

资源管理器

Explorer

Desktop Update
IShellExecuteHook
钩住外壳内任何程序的执行
信息条提示

Infotip

文件类和外壳对象

File class and shell's object

Desktop Update
IQueryInfo
当鼠标移到某个文件类型文档上时显示简短文本信息
栏目

Column

文件夹

Folders

Windows 2000
IColumnProvider
在资源管理器“查看”菜单的“详细资料”视图中增加新的栏目
Icon Overlay
资源管理器

Explorer

Windows 2000
IShellIconOverlay
用定制的图像覆盖图标
搜索

Search

资源管理器

Explorer

Windows 2000
IContextMenu
在“开始”菜单的“搜索”菜单项中增加新的搜索入口

 

清除

Cleanup

清除管理器

Cleanup Manager

Windows 2000
IEmptyVolumeCache2
向清除管理器中增加新的入口来恢复磁盘空间

Figure 3

Implementing the BMP Infotip

// IPersistFileImpl.h


#include 

class ATL_NO_VTABLE IPersistFileImpl : public IPersistFile{
public:
    TCHAR m_szFile[MAX_PATH];

    // IUnknown
    STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject) = 0;
    _ATL_DEBUG_ADDREF_RELEASE_IMPL(IPersistFileImpl)

    // IPersistFile
    STDMETHOD(Load)(LPCOLESTR wszFile, DWORD dwMode){
        USES_CONVERSION;
        _tcscpy(m_szFile, OLE2T((WCHAR*)wszFile)); 
        return S_OK;    
    };

    STDMETHOD(GetClassID)(LPCLSID){ return E_NOTIMPL; }

    STDMETHOD(IsDirty)(VOID){ return E_NOTIMPL; }

    STDMETHOD(Save)(LPCOLESTR, BOOL){ return E_NOTIMPL; }

    STDMETHOD(SaveCompleted)(LPCOLESTR){ return E_NOTIMPL; }

    STDMETHOD(GetCurFile)(LPOLESTR FAR*){ return E_NOTIMPL; }
};

// IQueryInfoImpl.h


#include 
#include 

class ATL_NO_VTABLE IQueryInfoImpl : public IQueryInfo{
public:
    // IUnknown
    STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject) = 0;
    _ATL_DEBUG_ADDREF_RELEASE_IMPL(IQueryInfoImpl)

    // IQueryInfo::GetInfoTip
    STDMETHOD(GetInfoTip)(DWORD dwFlags, LPWSTR *ppwszTip){
        wcscpy(*ppwszTip, L"InfoTip");
        return S_OK;
    }

    // IQueryInfo::GetInfoFlags
    STDMETHOD(GetInfoFlags)(LPDWORD pdwFlags){ 
        *pdwFlags = 0;
        return E_NOTIMPL; 
    }
};

// BmpTip.h : Declaration of the CBmpTip coclass


#ifndef __BMPTIP_H_
#define __BMPTIP_H_

#include "resource.h"              // main symbols
#include "comdef.h"                // GUIDs    
#include "IPersistFileImpl.h"      // IPersistFile
#include "IQueryInfoImpl.h"        // IQueryInfo

// CBmpTip
class ATL_NO_VTABLE CBmpTip : 
    public CComObjectRootEx,
    public CComCoClass,
    public IQueryInfoImpl,
    public IPersistFileImpl,
    public IDispatchImpl{
public:
    CBmpTip(){
        HRESULT hr;
        hr = SHGetMalloc(&m_pAlloc);
        if (FAILED(hr)) m_pAlloc = NULL;
    }
    ~CBmpTip(){
        m_pAlloc->Release();
    }
DECLARE_REGISTRY_RESOURCEID(IDR_BMPTIP)
DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CBmpTip)
    COM_INTERFACE_ENTRY(IBmpTip)
    COM_INTERFACE_ENTRY(IQueryInfo)
    COM_INTERFACE_ENTRY(IPersistFile)
    COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()

// IQueryInfo
public:
    STDMETHOD(GetInfoTip)(DWORD, LPWSTR*);

private:
    STDMETHOD(GetBitmapInfo)(CComBSTR*);
    LPMALLOC m_pAlloc;
};

#endif //__BMPTIP_H_

Figure 7

A Column Handler Extension

// IColumnProviderImpl.h


#include 
#include 

class ATL_NO_VTABLE IColumnProviderImpl : public IColumnProvider 
{
protected:
    TCHAR m_szFolder[MAX_PATH];
public:
    // IUnknown
    STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject) = 0;
    _ATL_DEBUG_ADDREF_RELEASE_IMPL(IColumnProviderImpl)

    // IColumnProvider 
    // IColumnProvider::Initialize
    STDMETHOD(Initialize)(LPCSHCOLUMNINIT psci){
        USES_CONVERSION;
        _tcscpy(m_szFolder, OLE2T((WCHAR*)psci->wszFolder)); 
        return S_OK;
    }
    // IColumnProvider::GetColumnInfo
    STDMETHOD(GetColumnInfo)(DWORD dwIndex, 
                             SHCOLUMNINFO *psci){ 
        return S_FALSE; 
    }
    // IColumnProvider::GetItemData
    STDMETHOD(GetItemData)(LPCSHCOLUMNID pscid, 
                           LPCSHCOLUMNDATA pscd, 
                           VARIANT *pvarData){ 
        return S_FALSE; 
    }
};

// BmpColInfo.h : Declaration of the CBmpColInfo


#ifndef __BMPCOLINFO_H_
#define __BMPCOLINFO_H_

#include "resource.h"            // main symbols
#include              // GUID of IColumnProvider
#include "IColumnProviderImpl.h" // IColumnProvider base impl

const UINT BMPCH_DEFWIDTH = 16;// column default width in chars 
const UINT BMPCH_MAXSIZE = 80;  // max text size 
const DWORD BMPCH_NUMOFCOLS = 1;// number of columns handled 
                                // here

// CBmpColInfo
class ATL_NO_VTABLE CBmpColInfo : 
    public CComObjectRootEx,
    public CComCoClass,
    public IColumnProviderImpl,
    public IDispatchImpl{
public:
    CBmpColInfo(){}

DECLARE_REGISTRY_RESOURCEID(IDR_BMPCOLINFO)
DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CBmpColInfo)
    COM_INTERFACE_ENTRY(IBmpColInfo)
    COM_INTERFACE_ENTRY_IID(IID_IColumnProvider, CBmpColInfo)
    COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()

// IColumnProvider
public:
    STDMETHOD(GetColumnInfo)(DWORD, SHCOLUMNINFO *);
    STDMETHOD(GetItemData)(LPCSHCOLUMNID, LPCSHCOLUMNDATA, 
                           VARIANT *);
private:
    STDMETHOD(GetBitmapInfo)(LPCWSTR, LPTSTR);
};

#endif //__BMPCOLINFO_H_

// BmpColInfo.cpp : Implementation of CBmpColInfo


#include "stdafx.h"
#include "BmpCol.h"
#include "BmpColInfo.h"

HRESULT CBmpColInfo::GetColumnInfo(DWORD dwIndex, 
                                   SHCOLUMNINFO *psci){ 
    // Since this extension might provide more columns, the
    // index is used to enumerate them. The shell calls 
    // this method repeatedly with progressive indexes, until
    // you return S_FALSE. Return S_FALSE only when you've
    // finished with all your columns. dwIndex is a 0-based 
    // index. Notice that without this checking you enter
    // an infinite loop!
    if (dwIndex >= BMPCH_NUMOFCOLS)
        return S_FALSE;

    // Now fills out the SHCOLUMNINFO structure to let the 
    // shell know about general-purpose features of the column

    // Identifies the column with a FMTID/PID pair. You'd
    // define one of these pairs for each column you're
    // adding here.
    psci->scid.fmtid = *_Module.pguidVer; // use object's CLSID
    psci->scid.pid = 1;

    // Sets type, alignment and default width
    psci->vt = VT_LPSTR;              // data is LPSTR
    psci->fmt = LVCFMT_LEFT;          // left alignment
    psci->cChars = BMPCH_DEFWIDTH;    // default width in chars
    
    // Other flags
    psci->csFlags = SHCOLSTATE_TYPE_STR;
        
    // Caption and description
    wcsncpy(psci->wszTitle, L"Dimensions", MAX_COLUMN_NAME_LEN);
    wcsncpy(psci->wszDescription, 
            L"Provides dimensions and colors for BMPs", 
            MAX_COLUMN_DESC_LEN);

    return S_OK; 
}

// IColumnProvider::GetItemData
HRESULT CBmpColInfo::GetItemData(LPCSHCOLUMNID pscid,
                                 LPCSHCOLUMNDATA pscd, 
                                 VARIANT *pvarData){ 
    USES_CONVERSION;
    // The shell calls this method for each file displayed
    // in the folder where this column has been selected. 
    // The SHCOLUMNID structure identifies the column
    // unequivocally just in case you're handling more than one.

    // In this case, I'm managing just one column so I'll
    // ignore the SHCOLUMNID param.

    // Information about the specific file is contained in the 
    // SHCOLUMNDATA structure. I'm interested only in .BMP.
    if (wcsicmp(pscd->pwszExt, L".bmp")) return S_FALSE;

    // Reads dimensions and palette size from the BMP file
    TCHAR szBuf[BMPCH_MAXSIZE];
    GetBitmapInfo(pscd->wszFile, szBuf);

    // The return value (a string in this case) must be 
    // packed as a Variant.
    CComVariant cv(szBuf);
    cv.Detach(pvarData); 

    return S_OK; 
}

HRESULT CBmpColInfo::GetBitmapInfo(LPCWSTR wszFile, LPTSTR p){
    USES_CONVERSION;
    BITMAPFILEHEADER bf;
    BITMAPINFOHEADER bi;
    HFILE h;

    // Reads the file header
    h = _lopen(OLE2T(wszFile), OF_READ);
    if (h==HFILE_ERROR) return S_OK;

    _lread(h, (LPBITMAPFILEHEADER)&bf, sizeof(BITMAPFILEHEADER));
    _lread(h, (LPBITMAPINFOHEADER)&bi, sizeof(BITMAPINFOHEADER));
    _lclose(h);

    // Formats the string 
    wsprintf(p, _T("%d x %d x %d"), bi.biWidth, bi.biHeight, 
             bi.biBitCount);  

    return S_OK;
}

Figure 11

Cleanup Extension

// IEmptyVolumeCache2Impl.h


#include 
#include 

class ATL_NO_VTABLE IEmptyVolumeCache2Impl : public IEmptyVolumeCache2{

public:
    // IUnknown
    STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject) = 
        0;
    _ATL_DEBUG_ADDREF_RELEASE_IMPL(IEmptyVolumeCache2Impl)

    // IEmptyVolumeCache::Initialize
    STDMETHOD(Initialize)(HKEY hkRegKey, LPCWSTR pcwszVolume, 
                          LPWSTR *ppwszDisplayName, 
                          LPWSTR *ppwszDescription, 
                          DWORD *pdwFlags){
        // Allows to initialize a Windows 98 handler
        MessageBox(0, _T("Initialize"), 0, 0);
        return S_OK;
    }

    // IEmptyVolumeCache::Deactivate 
    STDMETHOD(Deactivate)(DWORD *pdwFlags){ 
        // Called when the handler is going to be unloaded
        MessageBox(0, _T("Deactivate"), 0, 0);
        return S_OK; 
    }

    // IEmptyVolumeCache::GetSpaceUsed
    STDMETHOD(GetSpaceUsed)(DWORDLONG *pdwSpaceUsed, 
                            IEmptyVolumeCacheCallBack *picb){ 
        // Returns the amount of space the handler can free
        MessageBox(0, _T("GetSpaceUsed"), 0, 0);
        return S_OK;  
    }

    // IEmptyVolumeCache::Purge
    STDMETHOD(Purge)(DWORDLONG dwSpaceToFree, 
                     IEmptyVolumeCacheCallBack *picb){ 
        // Actually deletes the files
        MessageBox(0, _T("Purge"), 0, 0);
        return S_OK; 
    }

    // IEmptyVolumeCache::ShowProperties
    STDMETHOD(ShowProperties)(HWND hwnd){ 
        // Provides a UI 
        MessageBox(0, _T("ShowProperties"), 0, 0);
        return S_OK; 
    }

    // IEmptyVolumeCache2::InitializeEx
    STDMETHOD(InitializeEx)(HKEY hkRegKey, LPCWSTR pcwszVolume, 
                          LPCWSTR pcwszKeyName, 
                          LPWSTR *ppwszDisplayName, 
                          LPWSTR *ppwszDescription, 
                          LPWSTR *ppwszBtnText, 
                          DWORD *pdwFlags){
        // Initializes the handler under Windows 2000
        MessageBox(0, _T("InitializeEx"), 0, 0);
        return S_OK;
    }
};

// CleanSomething.h : Declaration of the CCleanSomething


#ifndef __CLEANSOMETHING_H_
#define __CLEANSOMETHING_H_

#include "resource.h"               // main symbols
#include "IEmptyVolumeCache2Impl.h" // IEmptyVolumeCache2

/////////////////////////////////////////////////////////////////
// CCleanSomething
class ATL_NO_VTABLE CCleanSomething : 
    public CComObjectRootEx,
    public CComCoClass,
    public IEmptyVolumeCache2Impl,
    public IDispatchImpl{
public:
    CCleanSomething(){}

DECLARE_REGISTRY_RESOURCEID(IDR_CLEANSOMETHING)
DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CCleanSomething)
    COM_INTERFACE_ENTRY(IEmptyVolumeCache)
    COM_INTERFACE_ENTRY(IEmptyVolumeCache2)
    COM_INTERFACE_ENTRY(ICleanSomething)
    COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()

// IEmptyVolumeCache2
public:
    STDMETHOD(InitializeEx)(HKEY hkRegKey, LPCWSTR pcwszVolume, 
                  LPCWSTR pcwszKeyName, 
                  LPWSTR *ppwszDisplayName, 
                  LPWSTR *ppwszDescription, 
                  LPWSTR *ppwszBtnText, 
                  DWORD *pdwFlags);

    STDMETHOD(GetSpaceUsed)(DWORDLONG *pdwSpaceUsed, 
        IEmptyVolumeCacheCallBack *picb);
};

#endif //__CLEANSOMETHING_H_

// CleanSomething.cpp : Implementation of CCleanSomething


#include "stdafx.h"
#include "DCHDemo.h"
#include "CleanSomething.h"

// CCleanSomething

HRESULT CCleanSomething::InitializeEx(HKEY hkRegKey,
        LPCWSTR pcwszVolume, LPCWSTR pcwszKeyName, 
        LPWSTR *ppwszDisplayName, LPWSTR *ppwszDescription, 
        LPWSTR *ppwszBtnText, DWORD *pdwFlags){
    USES_CONVERSION;
    MessageBoxW(0, pcwszVolume, 0, 0);
    *ppwszDisplayName = (LPWSTR)CoTaskMemAlloc(100);
    *ppwszDescription = (LPWSTR)CoTaskMemAlloc(100);
    *ppwszBtnText = (LPWSTR)CoTaskMemAlloc(100);
    lstrcpyW(*ppwszDisplayName, T2OLE("DCHDemo"));
    lstrcpyW(*ppwszDescription, T2OLE("Clean Something"));
    lstrcpyW(*ppwszBtnText, T2OLE("Click Me!"));
    *pdwFlags |= EVCF_HASSETTINGS;
    return S_OK;
}

HRESULT CCleanSomething::GetSpaceUsed(DWORDLONG *pdwSpaceUsed, 
    IEmptyVolumeCacheCallBack *picb){
    *pdwSpaceUsed = 1024000;
    return S_OK;
}

Figure 16

Invoking the Command Prompt



TCHAR                szCommand[MAX_PATH] = TEXT("");
STARTUPINFO          sui;
PROCESS_INFORMATION  pi;
OSVERSIONINFO        osi;

GetEnvironmentVariable(TEXT("ComSpec"), szCommand, 
    ARRAYSIZE(szCommand));

if(!*szCommand){
   osi.dwOSVersionInfoSize = sizeof(osi);
   GetVersionEx(&osi);
   if(VER_PLATFORM_WIN32_NT == osi.dwPlatformId){
      lstrcpy(szCommand, TEXT("cmd.exe"));
   } else{
      lstrcpy(szCommand, TEXT("command.com"));
   }
}

//set up the STARTUPINFO structure
ZeroMemory(&sui, sizeof(sui));
sui.cb = sizeof(sui);

//create the process
CreateProcess( NULL, szCommand, NULL, NULL,
               FALSE, NORMAL_PRIORITY_CLASS,
               NULL, szInitialDirectory,
               &sui, &pi);

参照msdn,vckbase

你可能感兴趣的:(Window编程,windows,shell,扩展,interface,class,structure)