SPDL : 得到桌面,快速启动或程序组的路径

有时候,为了方便用户使用我们编写的程序,需要在桌面,快速启动或程序组中创建程序的快捷方式。下面就介绍在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类型变量,再从这个变量中得到表示路径的字符串。使用完后,要用voidCoTaskMemFree(void * pv)来释放资源。

 

第二个函数将一个条目标识符列表转换为一个文件系统路径

BOOL SHGetPathFromIDList( 

PCIDLIST_ABSOLUTE pidl,  LPTSTR pszPath

);

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

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

 

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

 

下面给出了一个程序,用来列举你电脑上一些系统特殊路径:

#include<stdio.h>

#include<windows.h>

#include<shlobj.h>

#pragmacomment(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接口IShellLinkIPersistFile。由于篇幅问题,这里只讲解二个接口的部分函数。

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 wHotkeyMSDN上对其的解释为:

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)

      {

             BOOLflag =  SHGetPathFromIDList(ppidl,pszDesktopPath);

             CoTaskMemFree(ppidl);

             return flag;

      }

 

      return FALSE;

}    

//得到快速启动栏的路径

BOOL GetIEQuickLaunchPath(char *pszIEQueickLaunchPath)

{    

      LPITEMIDLIST ppidl;                  

      

      if (SHGetSpecialFolderLocation(NULL,CSIDL_APPDATA, &ppidl) ==S_OK)

      {

             BOOLflag =  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)

      {

             BOOLflag =SHGetPathFromIDList(ppidl,pszProgramsPath);

             CoTaskMemFree(ppidl);

             return flag;

      }

 

      return FALSE;

}

/*

函数功能:对指定文件在指定的目录下创建其快捷方式

函数参数:

lpszFileName   指定文件,为NULL表示当前进程的EXE文件。

lpszLnkFileDir 指定目录,不能为NULL

lpszLnkFileName快捷方式名称,为NULL表示EXE文件名。

wHotkey        0表示不设置快捷键

pszDescription 备注

iShowCmd       运行方式,默认为常规窗口

*/

BOOL CreateFileShortcut(LPCSTRlpszFileName,LPCSTRlpszLnkFileDir,LPCSTRlpszLnkFileName,      LPCSTRlpszWorkDir,WORDwHotkey,LPCTSTRlpszDescription, intiShowCmd =SW_SHOWNORMAL)

{

      if (lpszLnkFileDir ==NULL)

             return FALSE;

 

      HRESULThr;

      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>

#pragmacomment(lib, "shell32.lib")

效果如图:




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值