#include "stdafx.h"
#include "PinAppToTaskbar.h"
#include <Shlwapi.h>
#include <atlpath.h>
#include <shobjidl.h>
#define RETURN_IF_NULL_EX(ret, pPointer) { \
if (!(pPointer)) \
{ \
return ret; \
} \
}
#define RETURN_IF_FALSE_EX(ret, val) { \
if (!(val)) \
{ \
return ret; \
} \
}
//1. 得到IShellDispatch
//2. 得到Folder
//3. 得到FolderItem
//4. 得到Verb
//5. 执行verb
long PinAppToTaskbar(const CString& csFullName)
{
if (!PathFileExists(csFullName))
{
return ERROR_FILE_NOT_FOUND;
}
//加载字符串,形如"锁定到任务栏(K)"
//如果找不到,则可能系统版本低于win7
HINSTANCE hInst = ::LoadLibrary(_T("Shell32.dll"));
CString csVerb;
::LoadString(hInst, 5386, csVerb.GetBuffer(256), 256);
::FreeLibrary(hInst);
csVerb.ReleaseBuffer();
if (csVerb.IsEmpty())
{
//只有在win7及以上才支持
return CO_E_WRONGOSFORAPP;
}
CLSID clsid;
::CLSIDFromProgID(_T("Shell.Application"), &clsid);
CComQIPtr<IShellDispatch> pShell;
HRESULT hr = ::CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (void**)&pShell);
ASSERT(SUCCEEDED(hr));
RETURN_IF_FALSE_EX(hr, SUCCEEDED(hr));
CString csName = PathFindFileName(csFullName);
CPath path(csFullName);
path.RemoveFileSpec();
CString csPath = path;
CComVariant varPath(csPath);
CComQIPtr<Folder> pFolder;
//NameSpace方法
//Creates and returns a Folder object for the specified folder.
pShell->NameSpace(varPath, &pFolder);
ASSERT(pFolder);
RETURN_IF_NULL_EX(E_NOINTERFACE, pFolder);
CComBSTR bstrName(csName);
CComQIPtr<FolderItem> pFolderItem;
//ParseName方法 Creates and returns a FolderItem object that represents a specified item.
pFolder->ParseName(bstrName, &pFolderItem);
ASSERT(pFolderItem);
RETURN_IF_NULL_EX(E_NOINTERFACE, pFolderItem);
CComQIPtr<FolderItemVerbs> pVerbs;
pFolderItem->Verbs(&pVerbs);
ASSERT(pVerbs);
long lCount = 0;
pVerbs->get_Count(&lCount);
for (long i = 0; i < lCount; ++i)
{
CComQIPtr<FolderItemVerb> pOneVerb;
pVerbs->Item(CComVariant(i), &pOneVerb);
CComBSTR bstrVerbName;
pOneVerb->get_Name(&bstrVerbName);
if (CString(bstrVerbName).Compare(csVerb) == 0)
{
pOneVerb->DoIt();
return S_OK;
}
}
return E_FAIL;
}