1、快捷方式的实质
Windows的快捷方式实际上是一个带有扩展名LNK的数据文件,其中包含有用于访问Windows某一对象(即在资源管理器中所能浏览的所有对象,包括文件,文件夹,驱动器及打印机等)的有关信息,如目标对象的路径和名称,工作目录,要传递的命令行参数,运行时的初始显示状态,图标及其快捷键等。通过在快捷方式上单击鼠标右键并在弹出菜单中选择“属性”可以观察该快捷方式的这些性质。
2、编程思想
Windows外壳(Shell)的快捷方式是以OLE技术的组件对象模型COM(Component ObjectModal)为基础而设计的。利用COM模型,一个应用程序可以调用另一应用程序的某些功能。
Windows提供了一个COM接口IshellLink,它能够帮助我们创建、修改、删除快捷方式。要使用COM接口提供的功能,必须首先调用CoCreateInstance()函数建立一个IID_IShellLink实例,并同时得到其接口指针。利用这个接口指针可以对其各项属性进行设置。创建实例后,通过调用SetPath()方法设置快捷方式指向的源程序的路径,快捷方式的存储位置应该是:“程序”的位置+程序组名称+快捷方式名称+扩展名.lnk;通过SetDescription()方法设置快捷方式的描述,当然你还可以调用比如SetHotKey()等方法设置热键、显示的图标(默认为实际程序的图标)等。为了使这些信息以快捷方式的数据文件(*.lnk)格式保存起来,还需要从IID_IShellLink对象取得其IID_IPersistFile接口指针,以便于调用其成员函数Save()保存前面设置的信息。
需要注意的是:快捷方式应该使用Unicode存储,所以必须调用wcscpy()函数将其转换。
//Create
BOOL CMainDlg::CreateLink(LPCSTR pszShortcutFile,/*源*/
LPCSTR pszLink, /*lnk名*/
LPCSTR pszDesc/*描述*/)
{
HRESULT hres;
CComPtr<IShellLink> psl;
CComPtr<IPersistFile> ppf;
hres = CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
IID_IShellLink, (void **)&psl);
if (FAILED(hres))
{
return FALSE;
}
hres = psl->QueryInterface (IID_IPersistFile, (void **)&ppf);
if (FAILED(hres))
{
return FALSE;
}
WORD wsz [MAX_PATH];
hres = psl->SetPath (pszShortcutFile);
if (FAILED(hres))
{
return FALSE;
}
hres = psl->SetDescription (pszDesc);
if (FAILED(hres))
{
return FALSE;
}
#ifndef _UNICODE
MultiByteToWideChar (CP_ACP, 0, pszLink, -1, wsz, MAX_PATH);
#else
wcscpy(wsz,szLink);
#endif
hres = ppf->Save (wsz, TRUE);
if (FAILED(hres))
{
return FALSE;
}
return TRUE;
}
string CMainDlg::GetShortcutTarget(LPCSTR pszLinkFileName)
{
HRESULT hres;
CString Link, Temp = pszLinkFileName;
Temp.MakeLower();
if (Temp.Find(".lnk")==-1) //Check if the name ends with .lnk
{
Link = pszLinkFileName;
Link +=_T(".lnk"); //if not, append it
}
else
{
Link = pszLinkFileName;
}
string Info;
CComPtr<IShellLink> psl;
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
IID_IShellLink, (LPVOID*) &psl);
if (SUCCEEDED(hres))
{
CComPtr<IPersistFile> ppf;
hres = psl->QueryInterface( IID_IPersistFile, (LPVOID *) &ppf);
if (SUCCEEDED(hres))
{
WORD wsz[MAX_PATH];
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, Link, -1, wsz,MAX_PATH);
hres = ppf->Load(wsz, 0);
if (SUCCEEDED(hres))
{
hres = psl->Resolve(NULL,SLR_ANY_MATCH | SLR_NO_UI);
if(SUCCEEDED(hres))
{
psl->GetPath(Temp.GetBuffer(1024), 1024, NULL,SLGP_UNCPRIORITY);
Temp.ReleaseBuffer();
Info = Temp;
return Info;
}
}
}
}
return NULL;