在桌面建立快捷方式
/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<TPersistFile*>(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 的信息。