VC 为程序创建快捷方式的详细讲解.docx
《VC 为程序创建快捷方式的详细讲解.docx》由会员分享,可在线阅读,更多相关《VC 为程序创建快捷方式的详细讲解.docx(17页珍藏版)》请在冰豆网上搜索。
VC为程序创建快捷方式的详细讲解
VC为程序创建快捷方式的详细讲解
有时候,为了方便用户使用我们编写的程序,需要在桌面,快速启动或程序组中创建程序的快捷方式。
下面就介绍在VC下如何为程序创建快捷方式。
一.得到桌面,快速启动或程序组的路径
这里介绍二个win32API函数来完成这个任务。
第一个函数获得系统特殊路径
1.HRESULTSHGetSpecialFolderLocation(
2.
3.HWNDhwndOwner,intnFolder,PIDLIST_ABSOLUTE*ppidl
4.
5.);
第一个参数表示所有者窗口句柄,一般传入NULL就可以了。
第二个参数要示是一个整数id,决定哪个目录是待查找目录,它的取值可能是
CSIDL_BITBUCKET回收站
CSIDL_CONTROLS控制面板
CSIDL_DESKTOPWindows桌面desktop;
CSIDL_DESKTOPDIRECTORYdesktop的目录;
CSIDL_DRIVES我的电脑
CSIDL_FONTS字体目录
CSIDL_NETHOOD网上邻居
CSIDL_NETWORK网上邻居virtualfolder
CSIDL_PERSONAL我的文档
CSIDL_PRINTERS打印机
CSIDL_PROGRAMS程序组
CSIDL_RECENT最近打开文档
CSIDL_SENDTO发送到菜单项
CSIDL_STARTMENU快速启动菜单
CSIDL_STARTUP启动目录
CSIDL_TEMPLATES临时文档
第三个参数表示一个条目标识符列表指针,可以传入一个LPITEMIDLIST类型变量,再从这个变量中得到表示路径的字符串。
使用完后,要用voidCoTaskMemFree(void*pv)来释放资源。
第二个函数将一个条目标识符列表转换为一个文件系统路径
1.BOOLSHGetPathFromIDList(
2.
3.PCIDLIST_ABSOLUTEpidl,LPTSTRpszPath
4.
5.);
第一个参数pidl就是用第一个函数所得到的条目标识符列表指针。
第二个参数pszPath返回表示路径的字符串。
这二个函数的头文件均为并要引入shell32.lib。
下面给出了一个程序,用来列举你电脑上一些系统特殊路径:
1.#include
2.
3.#include
4.
5.#include
6.
7.#pragmacomment(lib,"shell32.lib")
8.
9.
10.
11.intmain()
12.
13.{
14.
15.constintENDNUMBER=-1;//哨兵,在遍历数组时遇到此数表示已经到达了数组的最后。
16.
17.//设置这个后,你可以在nFolders数组中任意添加删除数据而不用在遍历数组时考虑其中有多少个数据。
18.
19.
20.
21.CoInitialize(NULL);
22.
23.intnFolders[]={
24.
25.CSIDL_BITBUCKET,CSIDL_CONTROLS,CSIDL_DESKTOP,CSIDL_DESKTOPDIRECTORY,
26.
27.CSIDL_DRIVES,CSIDL_FONTS,CSIDL_NETHOOD,CSIDL_NETWORK,CSIDL_PERSONAL,
28.
29.CSIDL_PRINTERS,CSIDL_PROGRAMS,CSIDL_RECENT,CSIDL_SENDTO,CSIDL_STARTMENU,
30.
31.CSIDL_STARTUP,CSIDL_TEMPLATES,ENDNUMBER
32.
33.};
34.
35.
36.
37.HRESULThr;
38.
39.LPITEMIDLISTppidl;
40.
41.charszPath[MAX_PATH];
42.
43.
44.
45.inti=0;
46.
47.while(nFolders[i]!
=ENDNUMBER)
48.
49.{
50.
51.hr=SHGetSpecialFolderLocation(NULL,nFolders[i],&ppidl);
52.
53.if(hr!
=S_OK)
54.
55.{
56.
57.printf("SHGetSpecialFolderLocationError\n");
58.
59.}
60.
61.else
62.
63.{
64.
65.if(SHGetPathFromIDList(ppidl,szPath))
66.
67.printf("%s\n",szPath);
68.
69.else
70.
71.printf("SHGetPathFromIDListError\n");
72.
73.CoTaskMemFree(ppidl);
74.
75.}
76.
77.
78.
79.i++;
80.
81.}
82.
83.CoUninitialize();
84.
85.return0;
86.
87.}
由于系统的差异,有时会输出“SHGetPathFromIDListError”,在我电脑上就输出了5次。
有了这个例子,相信不难写出得到桌面桌面(CSIDL_DESKTOP),快速启动(CSIDL_APPDATA),程序组(CSIDL_PROGRAMS)的路径函数。
不过要稍稍注意下快捷启动,要再加上"\\Microsoft\\InternetExplorer\\QuickLaunch"。
二.创建快捷方式文件
完成第一步的任务后接下来的问题是如何创建快捷方式文件即.lnk文件。
首先要了解快捷方式文件要设置什么,然后了了解怎样设置。
2.1快捷方式文件有哪些要设置的内容
下面给出了Spy++和KmplayerPlus二个程序的快捷方式。
快捷方式必须设置目标,起始位置,快捷键,备注都可以选择性的设置,运行方式一般取默认值----常规窗口。
2.2如何设置快捷方式文件的内容
这要用到二个COM接口IShellLink和IPersistFile。
由于篇幅问题,这里只讲解二个接口的部分函数。
IShellLink的部分函数
HRESULTSetPath(LPCTSTRpszFile);设置目标
HRESULTSetWorkingDirectory(LPCTSTRpszDir);设置起始位置
HRESULTSetHotkey(WORDwHotkey);设置快捷键
HRESULTSetShowCmd(intiShowCmd);设置运行方式
有三种选择SW_SHOWNORMAL常规窗口
SW_SHOWMAXIMIZED最大化SW_SHOWMINNOACTIVE最小化
HRESULTSetDescription(LPCTSTRpszName);设置备注
要特别说下SetHotkey()中的参数WORDwHotkey。
MSDN上对其的解释为:
Theaddressofthehotkey.Thevirtualkeycodeisinthelow-orderbyte,andthemodifierflagsareinthehigh-orderbyte.Themodifierflagscanbeacombinationofthefollowingvalues.
HOTKEYF_ALTALTkey
HOTKEYF_CONTROLCTRLkey
HOTKEYF_EXTExtendedkey
HOTKEYF_SHIFTSHIFTkey
意思就是对这个WORD值,低位上是virtualkeycode,高位上可以是ALT,CTRL等组合键。
可以用MAKEWORD(low,high)来生成一个WORD,如Ctrl+F12可以用MAKEWORD(VK_F12,HOTKEYF_CONTROL)表示。
IPersistFile的部分函数
HRESULTSave(保存快捷方式
LPCOLESTRpszFileName,BOOLfRemember
);
第一个参数是要保存文件的文件名,要求是绝对路径。
第二个参数涉及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下测试过)。
[cpp]viewplaincopyprint?
1.//得到当前桌面路径
2.
3.BOOLGetDesktopPath(char*pszDesktopPath)
4.
5.{
6.
7.LPITEMIDLISTppidl=NULL;
8.
9.
10.
11.if(SHGetSpecialFolderLocation(NULL,CSIDL_DESKTOP,&ppidl)==S_OK)
12.
13.{
14.
15.BOOLflag=SHGetPathFromIDList(ppidl,pszDesktopPath);
16.
17.CoTaskMemFree(ppidl);
18.
19.returnflag;
20.
21.}
22.
23.
24.
25.returnFALSE;
26.
27.}
28.
29.//得到快速启动栏的路径
30.
31.BOOLGetIEQuickLaunchPath(char*pszIEQueickLaunchPath)
32.
33.{
34.
35.LPITEMIDLISTppidl;
36.
37.
38.
39.if(SHGetSpecialFolderLocation(NULL,CSIDL_APPDATA,&ppidl)==S_OK)
40.
41.{
42.
43.BOOLflag=SHGetPathFromIDList(ppidl,pszIEQueickLaunchPath);
44.
45.strcat(pszIEQueickLaunchPath,"\\Microsoft\\InternetExplorer\\QuickLaunch");
46.
47.CoTaskMemFree(ppidl);
48.
49.returnflag;
50.
51.}
52.
53.
54.
55.returnFALSE;
56.
57.}
58.
59.//得到开始->程序组的路径
60.
61.BOOLGetProgramsPath(char*pszProgramsPath)
62.
63.{
64.
65.LPITEMIDLISTppidl;
66.
67.
68.
69.if(SHGetSpecialFolderLocation(NULL,CSIDL_PROGRAMS,&ppidl)==S_OK)
70.
71.{
72.
73.BOOLflag=SHGetPathFromIDList(ppidl,pszProgramsPath);
74.
75.CoTaskMemFree(ppidl);
76.
77.returnflag;
78.
79.}
80.
81.
82.
83.returnFALSE;
84.
85.}
86.
87./*
88.
89.函数功能:
对指定文件在指定的目录下创建其快捷方式
90.
91.函数参数:
92.
93.lpszFileName指定文件,为NULL表示当前进程的EXE文件。
94.
95.lpszLnkFileDir指定目录,不能为NULL。
96.
97.lpszLnkFileName快捷方式名称,为NULL表示EXE文件名。
98.
99.wHotkey为0表示不设置快捷键
100.
101.pszDescription备注
102.
103.iShowCmd运行方式,默认为常规窗口
104.
105.*/
106.
107.BOOLCreateFileShortcut(LPCSTRlpszFileName,LPCSTRlpszLnkFileDir,LPCSTRlpszLnkFileName,LPCSTRlpszWorkDir,WORDwHotkey,LPCTSTRlpszDescription,intiShowCmd=SW_SHOWNORMAL)
108.
109.{
110.
111.if(lpszLnkFileDir==NULL)
112.
113.returnFALSE;
114.
115.
116.
117.HRESULThr;
118.
119.IShellLink*pLink;//IShellLink对象指针
120.
121.IPersistFile*ppf;//IPersisFil对象指针
122.
123.
124.
125.//创建IShellLink对象
126.
127.hr=CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLink,(void**)&pLink);
128.
129.if(FAILED(hr))
130.
131.returnFALSE;
132.
133.
134.
135.//从IShellLink对象中获取IPersistFile接口
136.
137.hr=pLink->QueryInterface(IID_IPersistFile,(void**)&ppf);
138.
139.if(FAILED(hr))
140.
141.{
142.
143.pLink->Release();
144.
145.returnFALSE;
146.
147.}
148.
149.
150.
151.//目标
152.
153.if(lpszFileName==NULL)
154.
155.pLink->SetPath(_pgmptr);
156.
157.else
158.
159.pLink->SetPath(lpszFileName);
160.
161.
162.
163.//工作目录
164.
165.if(lpszWorkDir!
=NULL)
166.
167.pLink->SetPath(lpszWorkDir);
168.
169.
170.
171.//快捷键
172.
173.if(wHotkey!
=0)
174.
175.pLink->SetHotkey(wHotkey);
176.
177.
178.
179.//备注
180.
181.if(lpszDescription!
=NULL)
182.
183.pLink->SetDescription(lpszDescription);
184.
185.
186.
187.//显示方式
188.
189.pLink->SetShowCmd(iShowCmd);
190.
191.
192.
193.
194.
195.//快捷方式的路径+名称
196.
197.charszBuffer[MAX_PATH];
198.
199.if(lpszLnkFileName!
=NULL)//指定了快捷方式的名称
200.
201.sprintf(szBuffer,"%s\\%s",lpszLnkFileDir,lpszLnkFileName);
202.
203.else
204.
205.{
206.
207.//没有指定名称,就从取指定文件的文件名作为快捷方式名称。
208.
209.char*pstr;
210.
211.if(lpszFileName!
=NULL)
212.
213.pstr=strrchr(lpszFileName,'\\');
214.
215.else
216.
217.pstr=strrchr(_pgmptr,'\\');
218.
219.
220.
221.if(pstr==NULL)
222.
223.{
224.
225.ppf->Release();
226.
227.pLink->Release();
228.
229.returnFALSE;
230.
231.}
232.
233.//注意后缀名要从.exe改为.lnk
234.
235.sprintf(szBuffer,"%s\\%s",lpszLnkFileDir,pstr);
236.
237.intnLen=strlen(szBuffer);
238.
239.szBuffer[nLen-3]='l';
240.
241.szBuffer[nLen-2]='n';
242.
243.szBuffer[nLen-1]='k';
244.
245.}
246.
247.//保存快捷方式到指定目录下
248.
249.WCHARwsz[MAX_PATH];//定义Unicode字符串
250.
251.MultiByteToWideChar(CP_ACP,0,szBuffer,-1,wsz,MAX_PATH);
252.
253.
254.
255.hr=ppf->Save(wsz,TRUE);
256.
257.
258.
259.ppf->Release();
260.
261.pLink->Release();
262.
263.returnSUCCEEDED(hr);
264.
265.}
调用如下例:
1.intmain()
2.
3.{
4.
5.charszPath[MAX_PATH];
6.
7.CoInitialize(NULL);
8.
9.
10.
11.GetDesktopPath(szPath);
12.
13.if(CreateFileShortcut(NULL,szPath,NULL,NULL,MAKEWORD(VK_F12,HOTKEYF_CONTROL),"Thatisatest"))
14.
15.printf("创建成功\n");
16.
17.
18.
19.CoUninitialize();
20.
21.return0;
22.
23.}
头文件及引用库:
1.#include
2.#include
3.#include
4.#pragmacomment(lib,"shell32.lib")