编程实现向开始菜单和桌面上添加快捷方式

发表于:2007-07-04来源:作者:点击数: 标签:
上海同济大学 罗筱波 通过InstallShield for Microsoft Visual C++ 6等应用程序创建一个安装程序来建立菜单项或快捷方式并不复杂,但是如果希望做一个无须安装的“绿色软件”,那么就只有自己编程实现了。 一、快捷方式的实质 Windows 的快捷方式实际上是一
上海同济大学 罗筱波

  通过InstallShield for Microsoft Visual C++ 6等应用程序创建一个安装程序来建立菜单项或快捷方式并不复杂,但是如果希望做一个无须安装的“绿色软件”,那么就只有自己编程实现了。 一、快捷方式的实质

  Windows的快捷方式实际上是一个带有扩展名LNK的数据文件,其中包含有用于访问Windows某一对象(即在资源管理器中所能浏览的所有对象,包括文件、文件夹、驱动器及打印机等)的有关信息,如目标对象的路径和名称,工作目录,要传递的命令行参数,运行时的初始显示状态,图标及其快捷键等。通过在快捷方式上单击鼠标右键并在弹出菜单中选择“属性"可以观察该快捷方式的这些性质。

  快捷方式的数据文件如果存放在“\Windows\Desktop"子目录下,这个快捷方式就会显示在桌面上,而如果存放在“\Windows\Start Menu\Programs" 子目录下,这个快捷方式就会作为“开始"菜单的一个菜单项出现。而桌面上的文件夹和“开始"菜单的菜单组则是上述两个子目录下的子目录的表现。 二、编程思想

  Windows外壳(Shell)的快捷方式是以OLE技术的组件对象模型COM(Component Object Model)为基础而设计的。利用COM模型,一个应用程序可以调用另一个应用程序的某些功能。

  在了解了上述基本原理后,创建Windows的快捷方式就比较容易了。首先利用OLE通过调用CoCreateInstance()函数建立一个IID_IShellLink实例,并同时得到其接口指针。利用这个接口指针可以对其各项属性进行设置。为了使这些信息以快捷方式的数据文件(*.lnk)格式保存起来,还需要从IID_IShellLink对象取得其 IID_IPersistFile接口指针,以便于调用其成员函数Save(),保存前面设置的信息。

  至于如何删除快捷方式以及创建和删除文件夹,则只需要简单地调用文件操作函数SHFileOperation()。 三、应用举例

  笔者用VC6.0编写了如下示例程序。该示例程序为一个基于对话框的应用程序,其中两个按钮分别用于实现向开始菜单和桌面上添加快捷方式,另两个按钮分别用于实现删除开始菜单和桌面上添加快捷方式。

  具体代码如下: 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

原文转自:http://www.ltesting.net