上海同济大学 罗筱波
通过InstallShield for Microsoft Visual C++ 6等应用程序创建一个安装程序来建立菜单项或快捷方式并不复杂,但是如果希望做一个无须安装的“绿色软件”,那么就只有自己编程实现了。快捷方式的数据文件如果存放在“\Windows\Desktop"子目录下,这个快捷方式就会显示在桌面上,而如果存放在“\Windows\Start Menu\Programs" 子目录下,这个快捷方式就会作为“开始"菜单的一个菜单项出现。而桌面上的文件夹和“开始"菜单的菜单组则是上述两个子目录下的子目录的表现。
在了解了上述基本原理后,创建Windows的快捷方式就比较容易了。首先利用OLE通过调用CoCreateInstance()函数建立一个IID_IShellLink实例,并同时得到其接口指针。利用这个接口指针可以对其各项属性进行设置。为了使这些信息以快捷方式的数据文件(*.lnk)格式保存起来,还需要从IID_IShellLink对象取得其 IID_IPersistFile接口指针,以便于调用其成员函数Save(),保存前面设置的信息。
至于如何删除快捷方式以及创建和删除文件夹,则只需要简单地调用文件操作函数SHFileOperation()。
具体代码如下:
void CShoutcutDlg::OnButtonadd()
// 向开始菜单添加快捷方式按钮命令
{
AddToStartMenu();
}
void CShoutcutDlg::AddToStartMenu() ]
// 向开始菜单添加快捷方式
{
char chDir[512];
// 保存找到的\Windows\Start Menu\Programs路径
long result;
HKEY hKey; // 注册表打开键的句柄
DWORD dwType;
DWORD dwSize;
// 打开注册表
result=RegOpenKeyEx(HKEY_CURRENT_USER,
“Software\\Microsoft\\Windows\\CurrentVersion
\\Explorer\\Shell Folders",
NULL,KEY_QUERY_VALUE,&hKey);
if(result==ERROR_SUCCESS)
{
dwSize=512;
// 查询Programs的键值并把查询到的结果
保存在字符串“chDir”中(因为Windows
并不一定安装在c盘中,所以要查询注册表)
result=RegQueryValueEx(hKey,“Programs",0,
&dwType,(LPBYTE)chDir,&dwSize);
result=RegCloseKey(hKey); // 关闭注册表
strcat(chDir,“\\My_shortcut_example");
// 在“开始“菜单里建立
“My_shortcut_example”菜单组
CreateDirectory(chDir,NULL); // 创建目录
strcat(chDir,“\\Myshortcut.lnk");
//在“开始“菜单里建立“Myshortcut”菜单项
HRESULT hres;
IShellLink* pShellLink; // 得到IshellLink接口指针
CoInitialize(NULL); // 初始化COM类库
hres=CoCreateInstance(CLSID_ShellLink,
NULL,CLSCTX_INPROC_SERVER,IID_IShellLink,
(LPVOID *)&pShellLink);
// 建立一个IID_IShellLink实例
if(SUCCEEDED(hres))
{
// IpersistFile接口提供了允许
将一个对象从磁盘加载或保存到磁盘的方法
IPersistFile* pPf;
// 得到当前运行的可执行程序的全路径名
TCHAR exeFullPath[MAX_PATH];
GetModuleFileName(NULL,exeFullPath,MAX_PATH);
pShellLink->SetPath(exeFullPath);
// 设置快捷方式的路径
pShellLink->SetDescription
(“My shortcut example"); // 设置快捷方式的描述
hres=pShellLink->QueryInterface
(IID_IPersistFile,(LPVOID *)&pPf);
if(SUCCEEDED(hres))
{
WORD sz[MAX_PATH];
// 字符串为ANSI 格式,须转化为Unicode格式
MultiByteToWideChar(CP_ACP,0,chDir,
-1,sz,MAX_PATH);
hres=pPf->Save(sz,TRUE); // 保存链接
pPf->Release();
}
pShellLink->Release();
}
}
else
MessageBox(“创建菜单组和菜单项快捷方式失败",
NULL,MB_ICONINFORMATION | MB_OK);
}
void CShoutcutDlg::OnButtondelete()
// 从开始菜单删除快捷方式按钮命令
{
DeleteFromStartMenu();
}
void CShoutcutDlg::DeleteFromStartMenu()
// 删除向开始菜单添加的快捷方式
{
//与向开始菜单添加快捷方式时一样,
首先取得快捷方式所在的目录路径,
方法与向开始菜单添加快捷方式相同
char chDir[512];
long result;
HKEY hKey; // 注册表打开键的句柄
DWORD dwType;
DWORD dwSize;
// 打开注册表
result=RegOpenKeyEx(HKEY_CURRENT_USER,
“Software\\Microsoft\\Windows\\CurrentVersion
\\Explorer\\Shell Folders",
NULL,KEY_QUERY_VALUE,&hKey);
if(result==ERROR_SUCCESS)
{
dwSize=512;
// 查询Programs的键值并把查询到的
结果保存在字符串“chDir”中
(因为Windows并不一定安装在c盘中,
所以要查询注册表)
result=RegQueryValueEx(hKey,
“Programs",0,&dwType,(LPBYTE)chDir,&dwSize);
result=RegCloseKey(hKey); // 关闭注册表
strcat(chDir,“\\My_shortcut_example");
// 得到快捷方式的目录删除快捷方式的目录,
// 首先确保文件存在
CFileFind findfile;
char str[MAX_PATH]=“Myshortcut.lnk";
SetCurrentDirectory(chDir);
// 重新设置当前目录为快捷方式所在的目录
if(!findfile.FindFile(str))
// 在当前目录下搜索快捷方式文件
{
MessageBox(“找不到快捷方式文件
Myshortcut.lnk,可能已经被删除 ",
NULL,MB_ICONINFORMATION | MB_OK);
return;
}
char lpDelDir[512]; // 要删除的目录
for(int i=0; i<512; i++)
lpDelDir[i]='\0'; // 初始化
strcat(lpDelDir,chDir);
SHFILEOPSTRUCT fileOp; // 文件操作结构
ZeroMemory( &fileOp, sizeof( fileOp)) ;
// 初始化
fileOp.hwnd=NULL;
// 设置hwnd为NULL以便隐藏文件操作对话框
fileOp.wFunc=FO_DELETE; // 删除操作
fileOp.pFrom=lpDelDir; // 要删除的目录
fileOp.fFlags=FOF_NOCONFIRMATION | FOF_SILENT
| FOF_ALLOWUNDO; // 删除文件到
回收站
if(SHFileOperation(&fileOp)==0) // 删除
MessageBox(“从开始菜单上删除快捷方式完成",
NULL,MB_ICONINFORMATION | MB_OK);
else
MessageBox(“从开始菜单上删除快捷方式失败",
NULL,MB_ICONINFORMATION | MB_OK);
}
else
MessageBox(“打开注册表失败",
NULL,MB_ICONINFORMATION | MB_OK);
}
void CShoutcutDlg::OnButtondesktop()
// 向桌面上添加快捷方式按钮命令
{
AddToDesktop();
}
void CShoutcutDlg::AddToDesktop()
// 向桌面上添加快捷方式,因程序与向开始菜单上
//添加快捷方式基本一样,故不再给出注释。
{
char chDir[512];
long result;
HKEY hKey;
DWORD dwType;
DWORD dwSize;
result=RegOpenKeyEx(HKEY_CURRENT_USER,
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell
Folders",NULL,KEY_QUERY_VALUE,&hKey);
if(result==ERROR_SUCCESS)
{
dwSize=512;
// 查询Desktop的键值并把查询到的结果
保存在字符串“chDir”中(因为Windows
并不一定安装在c盘中,所以要查询注册表)
result=RegQueryValueEx(hKey,"Desktop",
0,&dwType,(LPBYTE)chDir,&dwSize);
result=RegCloseKey(hKey);
strcat(chDir,"\\Myshortcut.lnk");
HRESULT hres;
IShellLink* pShellLink;
CoInitialize(NULL);
hres=CoCreateInstance(CLSID_ShellLink,
NULL,CLSCTX_INPROC_SERVER,IID_
IShellLink,(LPVOID *)&pShellLink);
if(SUCCEEDED(hres))
{
IPersistFile* pPf;
TCHAR exeFullPath[MAX_PATH];
GetModuleFileName(NULL,exeFullPath,MAX_PATH);
pShellLink->SetPath(exeFullPath);
pShellLink->SetDescription(“My shortcut example");
hres=pShellLink->QueryInterface
(IID_IPersistFile,(LPVOID *)&pPf);
if(SUCCEEDED(hres))
{
WORD sz[MAX_PATH];
MultiByteToWideChar
(CP_ACP,0,chDir,-1,sz,MAX_PATH);
hres=pPf->Save(sz,TRUE);
pPf->Release();
}
pShellLink->Release();
}
}
else
MessageBox(“向桌面上添加快捷方式失败",
NULL,MB_ICONINFORMATION | MB_OK);
}
void CShoutcutDlg::OnButtondeletedesktop()
// 从桌面上删除快捷方式按钮命令
{
DeleteFromDesktop();
}
void CShoutcutDlg::DeleteFromDesktop()
// 删除向桌面上添加的快捷方式,
//因程序与删除开始菜单上添加快捷方式
//基本一样,故不再给出注释。
{
char chDir[512];
long result;
HKEY hKey;
DWORD dwType;
DWORD dwSize;
result=RegOpenKeyEx(HKEY_CURRENT_USER,
“Software\\Microsoft\\Windows\\CurrentVersion
\\Explorer\\Shell Folders",NULL,KEY_QUERY_VALUE,&hKey);
if(result==ERROR_SUCCESS)
{
dwSize=512;
result=RegQueryValueEx(hKey,“Desktop",
0,&dwType,(LPBYTE)chDir,&dwSize);
result=RegCloseKey(hKey);
CFileFind findfile;
char str[MAX_PATH]=“Myshortcut.lnk";
SetCurrentDirectory(chDir);
if(!findfile.FindFile(str))
{
MessageBox(“找不到快捷方式文件 Myshortcut.lnk,
可能已经被删除",NULL,MB_ICONINFORMATION | MB_OK);
return;
}
strcat(chDir,“\\Myshortcut.lnk");
char lpDelDir[512];
for(int i=0; i<512; i++)
lpDelDir[i]=‘\0';
strcat(lpDelDir,chDir);
SHFILEOPSTRUCT fileOp;
ZeroMemory( &fileOp, sizeof( fileOp)) ;
fileOp.hwnd=NULL;
fileOp.wFunc=FO_DELETE;
fileOp.pFrom=lpDelDir;
fileOp.fFlags=FOF_NOCONFIRMATION | FOF_
SILENT | FOF_ALLOWUNDO; // 删除文件到回收站
if(SHFileOperation(&fileOp)==0)
MessageBox(“从桌面上删除快捷方式完成",
NULL,MB_ICONINFORMATION | MB_OK);
else
MessageBox(“从桌面上删除快捷方式失败",NULL,
MB_ICONINFORMATION | MB_OK);
}
else
MessageBox(“打开注册表失败",NULL,
MB_ICONINFORMATION | MB_OK);
}
作者邮箱:luob@citiz.net