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 <AtlCom.h>

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 <AtlCom.h>
#include <ShlObj.h>

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<CComSingleThreadModel>,
    public CComCoClass<CBmpTip, &CLSID_BmpTip>,
    public IQueryInfoImpl,
    public IPersistFileImpl,
    public IDispatchImpl<IBmpTip, &IID_IBmpTip, 
                         &LIBID_BMPEXTLib>{
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 <AtlCom.h>
#include <ShlObj.h>

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 <shlguid.h>             // 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<CComSingleThreadModel>,
    public CComCoClass<CBmpColInfo, &CLSID_BmpColInfo>,
    public IColumnProviderImpl,
    public IDispatchImpl<IBmpColInfo, &IID_IBmpColInfo, 
                         &LIBID_BMPCOLLib>{
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 <AtlCom.h>
#include <emptyvc.h>

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<CComSingleThreadModel>,
    public CComCoClass<CCleanSomething, &CLSID_CleanSomething>,
    public IEmptyVolumeCache2Impl,
    public IDispatchImpl<ICleanSomething, &IID_ICleanSomething, 
                         &LIBID_DCHDEMOLib>{
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
Windows Shell扩展编程完全指南 第一节 - 一步步教你如何编写Shell扩展 第二节 - 如何编写一次操作多个文件对象的Shell扩展 第三节-如何编写为文件对象弹出提示信息框的Shell扩展 第四节 - 如何编写提供定制拖放功能的Shell扩展 第五节-如何编写添加属性页到文件属性对话框中的Shell扩展 第六节-如何编写定制”发送到”菜单的Shell扩展 第七节-如何编写自画上下文菜单项的Shell扩展, 以及如何使上下文菜单扩展响应文件夹窗口背景上的鼠标右击事件 第八节-如何使用信息栏扩展添加定制的信息栏到资源浏览器详细资料列表中 Windows Shell扩展编程完全指南 目录与资料简介 第一节 - 一步步教你如何编写Shell扩展 简要概述了Shell扩展及如何对之进行调试. 所附的例子演示了如何为文本文件对象添加上下文菜单项。 -------------------------------------------------------------------------------- 第二节 - 如何编写一次操作多个文件对象的Shell扩展 示范了如何编写一次操作多个被选择文件的上下文菜单扩展。所附的例子为DLL文件的上下文菜单项添加”注册”和”注销”两项以方便DLL服务器的注册操作. -------------------------------------------------------------------------------- 第三节-如何编写为文件对象弹出提示信息框的Shell扩展 示范了如何使用QueryInfo 扩展为文本文件对象提供提示信息框,同时还解释了如何在Shell扩展中使用 MFC. -------------------------------------------------------------------------------- 第四节 - 如何编写提供定制拖放功能的Shell扩展 示范了如何添加菜单项到 用户用右键拖放文件对象时弹出的上下文菜单. 所附的例子为文件对象生成硬链接(hard link). (注: 该扩展只在Windows 2000下起作用, 但你可以在以前版本的Windows中编译并运行该扩展(具体使用请见文章内容) -------------------------------------------------------------------------------- 第六节-如何编写定制”发送到”菜单的Shell扩展 讨论了如何使用放置目标处理器扩展添加菜单项到”发送到”菜单. 所附的例子实现了将文件发送到任一文件夹的功能。 第五节-如何编写添加属性页到文件属性对话框中的Shell扩展 示范了如何添加新定制的属性页到文件属性对话框中. 所附的例子添加一个定制的属性页,使用它你可以编辑文件对象的创建,修改和最后访问时间. -------------------------------------------------------------------------------- 第七节-如何编写自画上下文菜单项的Shell扩展, 以及如何使上下文菜单扩展响应文件夹窗口背景上的鼠标右击事件 解决了读者提出的两个问题: 自画菜单项和文件夹窗口背景上的上下文菜单. 所附的例子包含两个扩展: 位图预览 (如上图) 在上下文菜单上显示BMP文件的缩略图;另一个扩展添加菜单项到文件夹窗口背景上下文菜单. -------------------------------------------------------------------------------- 第八节-如何使用信息栏扩展添加定制的信息栏到资源浏览器详细资料列表中 示范了如何添加定制信息栏到Windows 2000资源浏览器的详细信息列表. 所附的例子添加若干个信息栏以显示MP3文件的资料标签数据 (改扩展仅用于Windows 2000.) -------------------------------------------------------------------------------- 第九节-如何编写定制文件类型显示图标的Shell扩展
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值