转自:http://www.vckbase.com
在阅读代码之前,先看一下关于“快捷方式”组件的结构示意图。
图二、快捷方式组件的接口结构示意图
从结构图中可以看出,“快捷方式”组件(CLSID_ShellLink),有3个(其实不止)接口,每个接口完成一组相关功能的函数。IShellLink 接口(IID_IShellLink)提供快捷方式的参数读写功能(见图三),IPersistFile 接口(IID_IPersistFile)提供快捷方式持续性文件的读写功能。对象的持续性(注5),是一个非常常用,并且功能强大的接口家族。但今天,我们只要了解其中两函数,就可以了:IPersistFile::Save()和IPersistFile:Load()。(注6)
图三、快捷方式中的各种属性
#include < atlconv.h > void CreateShortcut(LPCTSTR lpszExe, LPCTSTR lpszLnk) { // 建立块捷方式 // 参数 lpszExe: EXE 文件全路径名 // 参数 lpszLnk: 快捷方式文件全路径名 ::CoInitialize( NULL ); IShellLink * psl = NULL; IPersistFile * ppf = NULL; HRESULT hr = ::CoCreateInstance( // 启动组件 CLSID_ShellLink, // 快捷方式 CLSID NULL, // 聚合用(注4) CLSCTX_INPROC_SERVER, // 进程内(Shell32.dll)服务 IID_IShellLink, // IShellLink 的 IID (LPVOID *)&psl ); // 得到接口指针 if ( SUCCEEDED(hr) ) { psl->SetPath( lpszExe ); // 全路径程序名 // psl->SetArguments(); // 命令行参数 // psl->SetDescription(); // 备注 // psl->SetHotkey(); // 快捷键 // psl->SetIconLocation(); // 图标 // psl->SetShowCmd(); // 窗口尺寸 // 根据 EXE 的文件名,得到目录名 TCHAR szWorkPath[ MAX_PATH ]; ::lstrcpy( szWorkPath, lpszExe ); LPTSTR lp = szWorkPath; while( *lp ) lp++; while( ''//'' != *lp ) lp--; *lp=0; // 设置 EXE 程序的默认工作目录 psl->SetWorkingDirectory( szWorkPath ); hr = psl->QueryInterface( // 查找持续性文件接口指针 IID_IPersistFile, // 持续性接口 IID (LPVOID *)&ppf ); // 得到接口指针 if ( SUCCEEDED(hr) ) { USES_CONVERSION; // 转换为 UNICODE 字符串 ppf->Save( T2COLE( lpszLnk ), TRUE ); // 保存 } } if ( ppf ) ppf->Release(); if ( psl ) psl->Release(); ::CoUninitialize(); } void OnXXX() { CreateShortcut( _T("c://winnt//notepad.exe"), // 记事本程序。注意,你的系统是否也是这个目录? _T("c://Documents and Settings//Administrator//桌面//我的记事本.lnk") ); // 桌面上建立快捷方式(lnk)文件的全路径名。注意,你的系统是否也是这个目录? // 如果用程序实现寻找桌面的路径,则可以查注册表 // HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/Explorer/Shell Folders }