VC 为程序创建快捷方式的详细讲解

有时候,为了方便用户使用我们编写的程序,需要在桌面,快速启动或程序组中创建程序的快捷方式。下面就介绍在VC下如何为程序创建快捷方式。

一.得到桌面,快速启动或程序组的路径
这里介绍二个win32 API函数来完成这个任务。
第一个函数 获得系统特殊路径
HRESULT SHGetSpecialFolderLocation(

HWND hwndOwner,  int nFolder, PIDLIST_ABSOLUTE *ppidl
);
第一个参数表示所有者窗口句柄,一般传入NULL就可以了。
第二个参数要示是一个整数id,决定哪个目录是待查找目录,它的取值可能是
CSIDL_BITBUCKET            回收站
CSIDL_CONTROLS            控制面板
CSIDL_DESKTOP              Windows桌面desktop;
CSIDL_DESKTOPDIRECTORY   desktop的目录;
CSIDL_DRIVES                我的电脑
CSIDL_FONTS                 字体目录
CSIDL_NETHOOD             网上邻居
CSIDL_NETWORK             网上邻居virtual folder
CSIDL_PERSONAL             我的文档
CSIDL_PRINTERS              打印机
CSIDL_PROGRAMS             程序组
CSIDL_RECENT                最近打开文档
CSIDL_SENDTO                发送到菜单项
CSIDL_STARTMENU            快速启动菜单
CSIDL_STARTUP               启动目录
CSIDL_TEMPLATES            临时文档
第三个参数表示一个条目标识符列表指针,可以传入一个LPITEMIDLIST类型变量,再从这个变量中得到表示路径的字符串。使用完后,要用void CoTaskMemFree(void * pv)来释放资源。
 
第二个函数 将一个条目标识符列表转换为一个文件系统路径
BOOL SHGetPathFromIDList( 
PCIDLIST_ABSOLUTE pidl,  LPTSTR pszPath
);
第一个参数 pidl就是用第一个函数所得到的条目标识符列表指针。
第二个参数pszPath返回表示路径的字符串。
 
这二个函数的头文件均为<shlobj.h>并要引入shell32.lib。
 
下面给出了一个程序,用来列举你电脑上一些系统特殊路径:
#include <stdio.h>
#include <windows.h>
#include <shlobj.h>
#pragma comment(lib, "shell32.lib")
 
int main()
{
       const int ENDNUMBER = -1;//哨兵,在遍历数组时遇到此数表示已经到达了数组的最后。
       //设置这个后,你可以在nFolders数组中任意添加删除数据而不用在遍历数组时考虑其中有多少个数据。
 
       CoInitialize(NULL);
       int nFolders[] = {
              CSIDL_BITBUCKET, CSIDL_CONTROLS, CSIDL_DESKTOP, CSIDL_DESKTOPDIRECTORY,
              CSIDL_DRIVES, CSIDL_FONTS, CSIDL_NETHOOD, CSIDL_NETWORK, CSIDL_PERSONAL,
              CSIDL_PRINTERS, CSIDL_PROGRAMS, CSIDL_RECENT, CSIDL_SENDTO, CSIDL_STARTMENU,
              CSIDL_STARTUP, CSIDL_TEMPLATES, ENDNUMBER
       };
 
       HRESULT       hr;
       LPITEMIDLIST  ppidl;
       char          szPath[MAX_PATH];
 
       int i = 0; 
       while (nFolders[i] != ENDNUMBER)
       {
              hr = SHGetSpecialFolderLocation(NULL, nFolders[i], &ppidl);
              if (hr != S_OK)
              {
                     printf("SHGetSpecialFolderLocation Error\n");
              }
              else
              {
                     if (SHGetPathFromIDList(ppidl, szPath))
                            printf("%s\n", szPath);
                     else
                            printf("SHGetPathFromIDList Error\n");
                     CoTaskMemFree(ppidl);
              }
 
              i++;
       }
       CoUninitialize();
       return 0;
}
由于系统的差异,有时会输出“SHGetPathFromIDList Error”,在我电脑上就输出了5次。有了这个例子,相信不难写出得到桌面桌面(CSIDL_DESKTOP),快速启动(CSIDL_APPDATA),程序组(CSIDL_PROGRAMS)的路径函数。
不过要稍稍注意下快捷启动,要再加上"\\Microsoft\\Internet Explorer\\Quick Launch"。
 
二.创建快捷方式文件
完成第一步的任务后接下来的问题是如何创建快捷方式文件即.lnk文件。首先要了解快捷方式文件要设置什么,然后了了解怎样设置。
2.1快捷方式文件有哪些要设置的内容
下面给出了Spy++和Kmplayer Plus二个程序的快捷方式。
快捷方式必须设置目标,起始位置,快捷键,备注都可以选择性的设置,运行方式一般取默认值----常规窗口。

2.2如何设置快捷方式文件的内容
这要用到二个COM接口IShellLink和IPersistFile。由于篇幅问题,这里只讲解二个接口的部分函数。
IShellLink的部分函数
HRESULT SetPath(LPCTSTR pszFile);             设置目标
HRESULT SetWorkingDirectory(LPCTSTR pszDir);  设置起始位置
HRESULT SetHotkey(WORD wHotkey);           设置快捷键
HRESULT SetShowCmd(int iShowCmd);           设置运行方式
       有三种选择SW_SHOWNORMAL常规窗口
SW_SHOWMAXIMIZED最大化SW_SHOWMINNOACTIVE最小化
HRESULT SetDescription(LPCTSTR pszName);      设置备注
要特别说下SetHotkey()中的参数WORD wHotkey。MSDN上对其的解释为:
The address of the hot key. The virtual key code is in the low-order byte, and the modifier flags are in the high-order byte. The modifier flags can be a combination of the following values.
HOTKEYF_ALT        ALT key
HOTKEYF_CONTROL   CTRL key
HOTKEYF_EXT        Extended key
HOTKEYF_SHIFT      SHIFT key
意思就是对这个WORD值,低位上是virtual key code,高位上可以是ALT,CTRL等组合键。可以用MAKEWORD(low, high)来生成一个WORD,如Ctrl+F12可以用MAKEWORD(VK_F12, HOTKEYF_CONTROL)表示。
 
IPersistFile的部分函数
HRESULT Save(          保存快捷方式
  LPCOLESTR pszFileName, BOOL fRemember
);
第一个参数是要保存文件的文件名,要求是绝对路径。
第二个参数涉及COM的持续性问题(注1),一般传入TRUE即可。
 
要创建COM对象可以用CoCreateInstance()函数(见注2)和QueryInterface()函数(见注3)。下面给出了创建的代码:
IShellLink     *pLink;   //IShellLink对象指针
IPersistFile    *ppf;      //IPersisFil对象指针
创建IShellLink实例
CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLink,(void**)&pLink);
从IShellLink对象中获取IPersistFile接口
pLink->QueryInterface(IID_IPersistFile, (void**)&ppf);
创建之后就可以对pLink设置目标,快捷键,备注等,设置完后再用ppf创建快捷方式文件就可以了。当然最后要记得释放资源,pLink->Release(); ppf->Release()。
 
 
 
三.已封装好的函数代码
下面给出封装好的函数代码,可以在程序中直接使用(在XP+VC6.0下测试过)。
//得到当前桌面路径
BOOL GetDesktopPath(char *pszDesktopPath)
{
       LPITEMIDLIST  ppidl = NULL;
      
       if (SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &ppidl) == S_OK)
       {
              BOOL flag =   SHGetPathFromIDList(ppidl, pszDesktopPath);
              CoTaskMemFree(ppidl);
              return flag;
       }
 
       return FALSE;
}    
//得到快速启动栏的路径
BOOL GetIEQuickLaunchPath(char *pszIEQueickLaunchPath)
{    
       LPITEMIDLIST  ppidl;                   
      
       if (SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &ppidl) == S_OK)
       {
              BOOL flag =   SHGetPathFromIDList(ppidl, pszIEQueickLaunchPath);
              strcat(pszIEQueickLaunchPath, "\\Microsoft\\Internet Explorer\\Quick Launch");
              CoTaskMemFree(ppidl);
              return flag;
       }
 
       return FALSE;
}
//得到 开始->程序组 的路径
BOOL GetProgramsPath(char *pszProgramsPath)
{
       LPITEMIDLIST  ppidl;
      
       if (SHGetSpecialFolderLocation(NULL, CSIDL_PROGRAMS, &ppidl) == S_OK)
       {
              BOOL flag = SHGetPathFromIDList(ppidl, pszProgramsPath);
              CoTaskMemFree(ppidl);
              return flag;
       }
 
       return FALSE;
}
/*
函数功能:对指定文件在指定的目录下创建其快捷方式
函数参数:
lpszFileName    指定文件,为NULL表示当前进程的EXE文件。
lpszLnkFileDir  指定目录,不能为NULL。
lpszLnkFileName 快捷方式名称,为NULL表示EXE文件名。
wHotkey         为0表示不设置快捷键
pszDescription  备注
iShowCmd        运行方式,默认为常规窗口
*/
BOOL CreateFileShortcut(LPCSTR lpszFileName, LPCSTR lpszLnkFileDir, LPCSTR lpszLnkFileName,       LPCSTR lpszWorkDir, WORD wHotkey,LPCTSTR lpszDescription, int iShowCmd = SW_SHOWNORMAL)
{
       if (lpszLnkFileDir == NULL)
              return FALSE;
 
       HRESULT hr;
       IShellLink     *pLink;  //IShellLink对象指针
       IPersistFile   *ppf; //IPersisFil对象指针
      
       //创建IShellLink对象
       hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pLink);
       if (FAILED(hr))
              return FALSE;
      
       //从IShellLink对象中获取IPersistFile接口
       hr = pLink->QueryInterface(IID_IPersistFile, (void**)&ppf);
       if (FAILED(hr))
       {
              pLink->Release();
              return FALSE;       }

//目标
       if (lpszFileName == NULL)
              pLink->SetPath(_pgmptr);       else

pLink->SetPath(lpszFileName);

//工作目录
       if (lpszWorkDir != NULL)
              pLink->SetPath(lpszWorkDir);

//快捷键
       if (wHotkey != 0)
              pLink->SetHotkey(wHotkey);

//备注
       if (lpszDescription != NULL)
              pLink->SetDescription(lpszDescription);

//显示方式
       pLink->SetShowCmd(iShowCmd);

//快捷方式的路径 + 名称
       char szBuffer[MAX_PATH];
       if (lpszLnkFileName != NULL) //指定了快捷方式的名称
              sprintf(szBuffer, "%s\\%s", lpszLnkFileDir, lpszLnkFileName);       else         {

//没有指定名称,就从取指定文件的文件名作为快捷方式名称。
              char *pstr;
              if (lpszFileName != NULL)
                     pstr = strrchr(lpszFileName, ‘\\‘);              else

pstr = strrchr(_pgmptr, ‘\\‘);

if (pstr == NULL)              {

ppf->Release();
                     pLink->Release();
                     return FALSE;              }

//注意后缀名要从.exe改为.lnk
              sprintf(szBuffer, "%s\\%s", lpszLnkFileDir, pstr);
              int nLen = strlen(szBuffer);
              szBuffer[nLen - 3] = ‘l‘;
              szBuffer[nLen - 2] = ‘n‘;
              szBuffer[nLen - 1] = ‘k‘;       }

//保存快捷方式到指定目录下
       WCHAR  wsz[MAX_PATH];  //定义Unicode字符串
       MultiByteToWideChar(CP_ACP, 0, szBuffer, -1, wsz, MAX_PATH);

hr = ppf->Save(wsz, TRUE);

ppf->Release();
       pLink->Release();
       return SUCCEEDED(hr);}调用如下例:int main(){

char  szPath[MAX_PATH];
       CoInitialize(NULL);

GetDesktopPath(szPath);
       if (CreateFileShortcut(NULL, szPath, NULL, NULL, MAKEWORD(VK_F12, HOTKEYF_CONTROL), "That is a test"))
              printf("创建成功\n");

CoUninitialize();       return 0;}头文件及引用库:

#include <stdio.h>
#include <windows.h>
#include <shlobj.h>
#pragma comment(lib, "shell32.lib")效果如图:

时间: 2024-08-28 16:17:17

VC 为程序创建快捷方式的详细讲解的相关文章

Ubuntu系统应用程序创建快捷方式的方法

大家安装了最新版的Ubuntu 14.0系统之后可能觉得很不习惯,因为Ubuntu的桌面干干净净没有任何快捷方式,任务栏的图标拖不下来,右键点击程序图标也没有创建快捷方式的菜单选项: 那如何把自己经常使用的软件和文件夹放到桌面来呢?大家搜索时可能发现要通过命令行输入命令来实现,其实还有更方便的方法: 1.首先是软件快捷方式的创建方法: 进入你安装的程序目录,找到可执行文件,首先按住左键把它拖到桌面先不放开,然后按下Alt,此时出现一个菜单,选择“链接到此处”,松开之后就创建好了,你可以修改名称和

Android实例-为程序创建快捷方式(未测试)

结果: 1.因为只有小米手机,没有三星手机,没法测试.如果哪位神测试过的话,记得M我哦,谢了. 实例代码:  1 unit Unit1; 2 3 interface 4 5 uses 6 System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, 7 FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrl

vc++HOOK详细讲解

消息钩子函数入门 Windows 系统是建立在事件驱动的机制上的,说穿了就是整个系统都是通过消息的传递来实现的.而钩子是 Windows 系统中非常重要的系统接口,用它可以截获并处理送给其他应用程序的消息,来完成普通应用程序难以实现的功能.钩子可以监视系统或进程中的各种事件消息,截获发往目标窗口的消息并进行处理.这样,我们就可以在系统中安装自定义的钩子,监视系统中特定事件的发生,完成特定的功能,比如截获键盘.鼠标的输入,屏幕取词,日志监视等等.可见,利用钩子可以实现许多特殊而有用的功能.因此,对

(转)Inno Setup入门(四)——为程序创建桌面快捷方式

本文转载自:http://blog.csdn.net/augusdi/article/details/8564810 Icons这一可选段定义所有创建在开始菜单和\或其它位置 (比如桌面) 的快捷方式.一个例子如下: [setup] ;全局设置,本段必须 AppName=Test AppVerName=TEST DefaultDirName="E:\TEST" AppVersion=1.0 [files] Source: "F:\desktop\ipmsg.exe"

[No.000002]2015-03-20 编写好的程序如何安装时在WIN7/8任务栏创建快捷方式

在XP时代,有一个快速启动栏,这里创建快捷方式只需要把快捷方式放在“%AppData%\Roaming\Microsoft\Internet Explorer\Quick Launch”文件夹下即可,最近做了一个项目,要在WIN7/8的任务栏上创建快捷方式,搞了半天终于搞定,在这里大概记录一下,如果能因此帮到各位,也算功德一件: 我只需提醒各位注意注册表中[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\T

如何在Linux的桌面上创建快捷方式或启动器

如果在Linux桌面系统中你经常使用一个程序,你可能想去创建一个“桌面快捷方式”,以便于你在桌面只要点击一下快捷方式就可以启动它.虽然不少带有图形界面的程序会在安装时自动在桌面上创建快捷方式,还有一些图形界面程序或者命令行程序可能需要你手动创建快捷方式. 在这个教程里,我将告诉你如何在不同的Linux桌面上添加桌面快捷方式.(译注:其实除了作者所述的这些方法外,各种桌面上也还有更简便的方法,大家可以评论分享自己的经验) 一个桌面快捷方式是由内含该APP元信息(例如,app的名字,启动命令或者图标

C++语言堆栈的详细讲解

本文主要向大家介绍了C++语言堆栈的详细讲解,通过具体的内容向大家展示,希望对大家学习C++语言有所帮助. 一.预备知识—程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. 2.堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 .注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵. 3.全局区(静态区)(stati

[WinForm] VS2010发布、打包安装程序(超全超详细)

1. 在vs2010 选择"新建项目"→" 其他项目类型"→" Visual Studio Installer→"安装项目": 命名为:Setup1 . 这是在VS2010中将有三个文件夹, 1."应用程序文件夹"表示要安装的应用程序需要添加的文件: 2."用户的'程序'菜单"表示:应用程序安装完,用户的"开始菜单"中的显示的内容,一般在这个文件夹中,需要再创建一个文件用来存放

创建快捷方式

这是微软用来创建快捷方式的类库,当在项目中添加Com引用"Windows Script Host Object Model  "时,此类库就会出现在项目中.下面以C#项目为例介绍使用方法: 1.首先要添加引用.  添加引用的方法非常简单,右击你的项目并选择添加引用,  选择 COM 选项卡并选择 Windows Script Host Object Model 2.引用命名空间  using System.Runtime.InteropServices;//互动服务  using IW