在桌面建立快捷方式

/ns/wz/comp/data/20010716225940.htm

Harold Howe(翻译:抱雪)

API提供了一个COM接口:调用 IShellLink 将允许你建立一个快捷方式,要在桌面建立一个快捷方式,只要把这个快捷方式保存到桌面目录就可以了。

下面的示例代码演示怎样建立一个快捷方式,在这个例子里,快捷方式将保存在C:\ drive。

//----------------------------------------------------------------------
#include <shlobj.h>

void __fastcall TForm1::Button1Click(TObject *Sender)
{
// Allow the user to find a file with a common dialog box,
// then create a shortcut to that file.
if(OpenDialog1->Execute())
CreateShortCut(OpenDialog1->FileName);
}
//----------------------------------------------------------------------
void TForm1::CreateShortCut(const AnsiString &file)
{
// IShellLink allows us to create the shortcut.
// IPersistFile saves the link to the hard drive.
IShellLink* pLink;
IPersistFile* pPersistFile;

// First, we have to initialize the COM library
if(SUCCEEDED(CoInitialize(NULL)))
{
// If CoInitialize doesn't fail, then instantiate an
// IShellLink object by calling CoCreateInstance.
if(SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL,
CLSCTX_INPROC_SERVER,
IID_IShellLink, (void **) &pLink)))
{
// if that succeeds, then fill in the shortcut attributes
pLink->SetPath(file.c_str());
pLink->SetDescription("Woo hoo, look at Homer's shortcut");
pLink->SetShowCmd(SW_SHOW);

// Now we need to save the shortcut to the hard drive. The
// IShellLink object also implements the IPersistFile interface.
// Get the IPersistFile part of the object using QueryInterface.
if(SUCCEEDED(pLink->QueryInterface(IID_IPersistFile,
(void **)&pPersistFile)))
{
// If that succeeds, then call the Save method of the
// IPersistFile object to write the shortcut to the desktop.
WideString strShortCutLocation("C:\\bcbshortcut.lnk");
pPersistFile->Save(strShortCutLocation.c_bstr(), TRUE);
pPersistFile->Release();
}
pLink->Release();
}

// Calls to CoInitialize need a corresponding CoUninitialize call
CoUninitialize();
}
}
//----------------------------------------------------------------------

如果你执行这个代码,你将在你的C:\ drive下看见一个新的快捷方式,这非常好,但我们的问题是在桌面建立快捷方式。其实这也很简单,只要把快捷方式保存在桌面目录中就可以了(译者注:参见本站收录的:判断Windows相关目录)。

//----------------------------------------------------------------------
void TForm1::CreateShortCut(const AnsiString &file)
{
IShellLink* pLink;
IPersistFile* pPersistFile;
LPMALLOC ShellMalloc;
LPITEMIDLIST DesktopPidl;
char DesktopDir[MAX_PATH];

// We are going to create a pidl, and it will need to be
// freed by the shell mallocator. Get the shell mallocator
// object using API SHGetMalloc function. Return if failure.
if(FAILED(SHGetMalloc(&ShellMalloc)))
return;

// use the API to get a pidl for the desktop directory
// if function fails, return without proceeding
if(FAILED(SHGetSpecialFolderLocation(NULL,
CSIDL_DESKTOPDIRECTORY,
&DesktopPidl)))
return;

// Now convert the pidl to a character string
// return if function fails
if(!SHGetPathFromIDList(DesktopPidl, DesktopDir))
{
ShellMalloc->Free(DesktopPidl);
ShellMalloc->Release();
return;
}

// At this point, we are done with the pidl and the
// mallocator, so free them up
ShellMalloc->Free(DesktopPidl);
ShellMalloc->Release();

if(SUCCEEDED(CoInitialize(NULL)))
{
if(SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL,
CLSCTX_INPROC_SERVER,
IID_IShellLink, (void **) &pLink)))
{
pLink->SetPath(file.c_str());
pLink->SetDescription("Woo hoo, look at Homer's shortcut");
pLink->SetShowCmd(SW_SHOW);

if(SUCCEEDED(pLink->QueryInterface(IID_IPersistFile,
(void **)&pPersistFile)))
{

WideString strShortCutLocation(DesktopDir);
strShortCutLocation += "\\bcbshortcut.lnk";
pPersistFile->Save(strShortCutLocation.c_bstr(), TRUE);
pPersistFile->Release();
}
pLink->Release();
}
CoUninitialize();
}
}
//----------------------------------------------------------------------

不要陷入COM的泥沼
建立快捷方式要涉及一些COM的知识,COM是一个很复杂的内容,很容易就会出错,最好是使用与其等价的C++代码。

COM 代码 C++ 等价的代码
IShellLink* pLink; TShellLink *Link;
IPersistFile* pPersistFile; TPersistFile *PersistFile;

CoInitialize();

// CoCreateInstance is like new
CoCreateInstance(CLSID_ShellLink, Link = new TShellLink;
NULL,
CLSCTX_INPROC_SERVER,
IID_IShellLink,
(void **) &pLink)

// These are like member functions
pLink->SetPath(file.c_str()); Link->SetPath(file.c_str());
pLink->SetShowCmd(SW_SHOW); Link->SetShowCmd(SW_SHOW);


// QueryInterface is like casting
pLink->QueryInterface(IID_IPersistFile PersistFile =
(void **)&pPersistFile))) dynamic_cast&LT;TPersistFile*&GT;(Link);

pPersistFile->Save("C:\\", TRUE); PersistFile->Save("C:\\");


// Release is like delete
pPersistFile->Release(); delete PersistFile
pLink->Release(); delete Link;

CoUninitialize();

IShellLink 接口
示例代码只是使用了 IShellLink 的三个方法: SetPath, SetDescritpion, 以及 SetShowCmd. IShellLink 还支持其他的几个成员函数,下面就是最常用的几个函数:

SetArguments 传递给快捷方式程序的命令行参数
SetDescription 设置描述 (还不知用在什么场合)

SetHotkey 为快捷方式建立一个全局的热键
SetIconLocation 允许你自己指定快捷方式的图标
SetIDList SetPath中pidl的替代形式
SetPath 建立快捷方式的位置
SetShowCmd 快捷方式程序运行的方式:隐藏,最小化,最大化
SetWorkingDirectory 快捷方式的工作目录

GetXXX 与前面的SetXXX函数相对应,取得相应的信息
查看API帮助文件得到更多的关于 IShellLink 的信息。