zoukankan      html  css  js  c++  java
  • VC创建windwos快捷方式[转]

    原文地址:http://www.cnblogs.com/morewindows/archive/2011/08/14/2138412.html

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

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

    这里介绍二个win32 API函数来完成这个任务。

    第一个函数 获得系统特殊路径

    HRESULT SHGetSpecialFolderLocation(

    HWND hwndOwner,  int nFolderPIDLIST_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 pidlLPTSTR 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
    ");
    
                  }
    
                  else
    
                  {
    
                         if (SHGetPathFromIDList(ppidl, szPath))
    
                                printf("%s
    ", szPath);
    
                         else
    
                                printf("SHGetPathFromIDList Error
    ");
    
                         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("创建成功
    ");
    
     
    
           CoUninitialize();
    
           return 0;
    
    }

    头文件及引用库:

    #include <stdio.h>

    #include <windows.h>

    #include <shlobj.h>

    #pragma comment(lib, "shell32.lib")

    效果如图:

     

    注1          参见http://www.vckbase.com/document/viewdoc/?id=1546

    注2          参见http://baike.baidu.com/view/1141927.htm

    注3          参见http://baike.baidu.com/view/5395542.htm

  • 相关阅读:
    Spring Boot → 08:嵌入式Servlet容器自定义
    Spring Boot → 09:使用外置Servlet容器_tomcat9.0
    Spring Boot → 07:错误处理机制
    Spring Boot → 06:项目实战-账单管理系统
    Spring Boot → 05:Web开发
    zzz Objective-C的消息传递机制
    Objective-C中的SEL、IMP和Class类型(转)
    zzzObjective-C的动态特性
    zzz KVC/KVO原理详解及编程指南
    zzzzz iOS绘图教程
  • 原文地址:https://www.cnblogs.com/yc-only-blog/p/8687593.html
Copyright © 2011-2022 走看看