// FileTimeShlExt.cpp : CFileTimeShlExt 的實現
#include "stdafx.h"
#include "FileTimeShlExt.h"
# pragma comment(lib, "Comctl32.lib")
// CFileTimeShlExt
BOOL static CALLBACK ProPageDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
UINT static CALLBACK PropPageCallbackProc(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp);
//初始化
HRESULT CFileTimeShlExt::Initialize(LPCITEMIDLIST pidFolder, LPDATAOBJECT pDataObj, HKEY hProgID)
{
TCHAR szFile[MAX_PATH];
UINT uNumFiles;
HDROP hdrop;
FORMATETC etc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM stg;
INITCOMMONCONTROLSEX iccex = { sizeof(INITCOMMONCONTROLSEX), ICC_DATE_CLASSES };
//初始化通用控件使用
InitCommonControlsEx(&iccex);
//從數據對象中讀取項目,它們以HDOP格式存放,因此只需獲得HDROP句柄並對它們使用拖放APIS
if (FAILED(pDataObj ->GetData(&etc, &stg)))
{
return E_INVALIDARG;
}
//獲取HDROP句柄
hdrop = (HDROP)GlobalLock(stg.hGlobal);
if (NULL == hdrop)
{
ReleaseStgMedium(&stg);
return E_INVALIDARG;
}
//判斷操作涉及幾個文件
uNumFiles = DragQueryFile(hdrop, 0xFFFFFFFF, NULL, 0);
//循環列舉所選擇的文件,該擴展將只對文件進行操作,對文件夾不起作用,所以忽略文件夾
for (UINT uFile = 0; uFile < uNumFiles; uFile++)
{
//取得下一文件名
if (0 == DragQueryFile(hdrop, uFile, szFile, MAX_PATH))
{
continue;
}
//跳過文件夾,也可以處理文件夾
if (PathIsDirectory(szFile))
{
continue;
}
//添加文件名到我們的文件名列表中。
m_lsFiles.push_back(szFile);
}
//釋放資源
GlobalUnlock(stg.hGlobal);
ReleaseStgMedium(&stg);
//檢查有幾個文件被選中,如果大於屬性表能有的最大屬性頁的個數,刪減列表
if (m_lsFiles.size() > MAXPROPPAGES)
{
m_lsFiles.resize(MAXPROPPAGES);
}
//如果我們發現可以操作的任一文件返回S_OK,否則返回E_FAIL
return (m_lsFiles.size() > 0) ? S_OK : E_FAIL;
}
HRESULT CFileTimeShlExt::AddPages(LPFNADDPROPSHEETPAGE lpfnAddPageProc, LPARAM lParam)
{
PROPSHEETPAGE psp;
TCHAR szPageTitle[MAX_PATH];
string_list::const_iterator it, itEnd;
for (it = m_lsFiles.begin(), itEnd = m_lsFiles.end(); it != itEnd; it++)
{
//it 指向下一個文件名,分配一個給頁面使用弄個的字符串拷貝
LPCTSTR szFile = _tcsdup(it->c_str());
//從文件名中截去路徑和擴張名,用其作為頁面標題,該名稱截取為24個字符以適合Tab的大小
lstrcpy(szPageTitle, it->c_str());
PathStripPath(szPageTitle);
PathRemoveExtension(szPageTitle);
szPageTitle[24] = '\0';
//由於直接使用SDK調用完成屬性頁,我們得親自處理PROPSHEETPAGE結構
psp.dwSize = sizeof(PROPSHEETPAGE);
psp.dwFlags = PSP_USEREFPARENT | PSP_USETITLE | PSP_DEFAULT | PSP_USEHICON | PSP_USECALLBACK;
psp.hInstance = _pModule->GetModuleInstance();
psp.pszTemplate = MAKEINTRESOURCE(IDD_PROPPAGE);
psp.pszIcon = MAKEINTRESOURCE(IDC_ICON);
psp.pszTitle = szPageTitle;
psp.pfnDlgProc = (DLGPROC)ProPageDlgProc;
psp.lParam = (LPARAM)szFile;
psp.pfnCallback = PropPageCallbackProc;
psp.pcRefParent = (UINT *)_pModule->GetModuleInstance();
HPROPSHEETPAGE hPage = CreatePropertySheetPage(&psp);
if (NULL != hPage)
{
//調用Shell的回調函數添加新創建的屬性頁到屬性對話框中
if (!lpfnAddPageProc(hPage, lParam))
{
DestroyPropertySheetPage(hPage);
}
}
}
return S_OK;
}
BOOL CALLBACK ProPageDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_BUTTON:
MessageBox(NULL, L"您點擊了第一個按鈕。", L"提示", MB_OK);
break;
}
break;
}
return TRUE;
}
UINT CALLBACK PropPageCallbackProc(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp)
{
if (PSPCB_RELEASE == uMsg)
{
free((void *)ppsp->lParam);
}
return 1;
}
需要注銷下才能看到效果,假使你的代碼沒問題的話。