什么是图标索引?

时间:2018-10-19 09:50:55

标签: winapi visual-c++

我正在尝试以编程方式创建Shell链接,即快捷方式。在Visual Studio C ++中。

快捷方式已创建,并且可以使用。但是该图标是默认图标(因为API并未考虑提供的图标)。阅读文档后,看来我必须提供一个图标 index 。那是什么目前只有一个.ico文件。

这是代码(请参阅###行)

#include "stdafx.h"
#include <iostream>
#include <string>
#include <ShlObj.h>

class MakeLnk
{

   public:
      MakeLnk(){}
      void SetLnkInfos
     (
     std::wstring i_target,
     std::wstring i_args,
     std::wstring i_savePath,
     std::wstring i_description,
     std::wstring i_icoloc
     )
  {
     target = i_target;
     args = i_args; 
     savePath = i_savePath;
     description = i_description;
     icolocation = i_icoloc;
  }

  // Utility function, to create a link
  HRESULT CreateLnk()
  {
     LPCWSTR lpszPathObj = target.c_str();
     LPCTSTR arguments = args.c_str();
     LPCWSTR lpszLinkPath = savePath.c_str();
     LPCWSTR lpszDesc = description.c_str();
// ##########################
     LPCWSTR lpszIcoPath = icolocation.c_str(); // a path like "C:\\tmp\\crab.ico"
// ##########################

     HRESULT hres;
     IShellLink* psl;
     CoInitialize(NULL);
     // Get a pointer to the IShellLink interface. It is assumed that CoInitialize
     // has already been called.
     hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl);
     if (SUCCEEDED(hres))
     {
        IPersistFile* ppf;

        // Set the path to the shortcut target and add description and args. 
        psl->SetPath(lpszPathObj);
        psl->SetDescription(lpszDesc);
        psl->SetArguments(arguments);
// ###############################################
        psl->SetIconLocation(lpszIcoPath, 0); // HERE! WHAT TO PUT INSTEAD OF "0" ?
// ###############################################
        // Query IShellLink for the IPersistFile interface, used for saving the 
        // shortcut in persistent storage. 
        hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);

        if (SUCCEEDED(hres))
        {
           // Save the link by calling IPersistFile::Save. 
           hres = ppf->Save(lpszLinkPath, TRUE);
           ppf->Release();
        }
        psl->Release();
     }
     CoUninitialize();
     return hres;
  }

private:
  std::wstring target, args, savePath, description;
  std::wstring icolocation;
};


int main()
{
    MakeLnk linkMaker;
    std::wstring exepath(L"C:\\Program Files\\Crab\\Exec.exe"), arguments(L"eat dance"), lnkPath(L"shortcut.lnk"), description(L"Click here to lanch the crab program"), icon(L"C:\\tmp\\crab.ico");
    linkMaker.SetLnkInfos(exepath, arguments, lnkPath, description, icon);
    bool res = linkMaker.CreateLnk();
    return res ? 0 : -1;
}

2 个答案:

答案 0 :(得分:3)

Windows可执行文件可以具有所谓的资源。一种资源是图标。因此,可执行文件可以包含0、1个或更多图标。如果您需要在可执行文件中使用第二个图标,请使用图标索引1(通常,它们从0开始编号)

如果您有.ico文件,则必须先 将其添加到可执行文件中,然后才能使用它。 SetIconLocation only works on executables (and DLL's)

答案 1 :(得分:2)

Shell链接可以从EXE和DLL文件中获取其图标,并将它们存储为嵌入式资源。由于EXE或DLL文件可以包含多个图标,因此外壳程序链接需要知道要使用哪个图标。这是由索引控制的。

ICO文件(如果我没记错的话)只能包含一个图标。