您的位置:首页 > 其它

VC创建快捷方式

2014-09-08 16:10 337 查看
快捷方式:

现在,几乎所有的安装 程序都是在“开始”菜单中添加新的菜单项,或者在桌面上建立新的快捷方式(Shortcut)(有时还要建立相应的菜单组或文件夹来包含多个菜单项或快捷

方式),以便于用户使用时方便快捷地启动软件。当启动一个安装程序后,程序安装完成后会自动创建相应的快捷方式。

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

Windows外壳(Shell)的快捷方式是以OLE技术的组件对象模型COM(Component Object Modal)为基础而设计的。利用COM模型,一个应用程序可以调用另一应用程序的某些功能。这方面的技术细节请参阅有关文献。

在了解了上述基本原理后,创建Windows的快捷方式就比较容易了。首先利用OLE通过调用CoCreateInstance()函数建立一个 IID_IShellLink实例,并同时得到其接口指针。利用这个接口指针可以对其各项属性进行设置。为了使这些信息以快捷方式的数据文件 (*.lnk)格式保存起来,还需要从IID_IShellLink对象取得其IID_IPersistFile接口指针,以便于调用其成员函数Save()保存前面设置的信息。至于如何删除快捷方式以及创建和删除文件夹,则只需要简单地调用文件操作函数SHFileOperation()就可以了。另外应该注意,在完成上述操作之后,都要调用SHChangeNotify()函数通知Windows外壳有关变化以使之及时更新其显示状态。

相关函数与说明:

1、获得系统特殊路径:

HRESULT SHGetSpecialFolderLocation(HWND hwndOwner, int nFolder, PIDLIST_ABSOLUTE *ppidl);

1.第一个参数表示所有者窗口句柄,一般传入NULL就可以了。

2.第二个参数要示是一个整数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 临时文档

3.第三个参数表示一个条目标识符列表指针,可以传入一个LPITEMIDLIST类型变量,再从这个变量中得到

表示路径的字符串。使用完后,要用void CoTaskMemFree(void * pv)来释放资源。

2、将一个条目标识符列表转换为一个文件系统路径:

BOOL SHGetPathFromIDList( PCIDLIST_ABSOLUTE pidl, LPTSTR pszPath);

1.第一个参数pidl就是用第一个函数所得到的条目标识符列表指针。

2.第二个参数pszPath返回表示路径的字符串。

这二个函数的头文件均为<shlobj.h>并要引入shell32.lib。

3、设置快捷方式文件的内容:

这要用到二个COM接口IShellLink和IPersistFile。这里只讲解二个接口的部分函数。

1.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:

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)表示。

2.IPersistFile的部分函数:

HRESULT Save(LPCOLESTR pszFileName, BOOL fRemember); 保存快捷方式

第一个参数是要保存文件的文件名,要求是绝对路径。

第二个参数涉及COM的持续性问题,一般传入TRUE即可。

要创建COM对象可以用CoCreateInstance()函数和QueryInterface()函数。下面给出了创建的代码:

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()。

以下提供一个已封装相关功能的完整代码:

#include <stdio.h>
#include <windows.h>
#include <shlobj.h>
#pragma comment(lib, "shell32.lib")

//得到当前桌面路径
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: