Winapi 什么是图标索引?

Winapi 什么是图标索引?,winapi,visual-c++,Winapi,Visual C++,我试图以编程方式创建Shell链接,即快捷方式。在VisualStudioC++中. 快捷方式已创建,并且有效。但是图标是默认图标(因为API没有考虑提供的图标)。阅读文档时,似乎我必须提供一个图标索引。但这是什么?目前只有一个.ico文件 这是代码(请参见####行) #包括“stdafx.h” #包括 #包括 #包括 类MakeLnk { 公众: MakeLnk(){} 无效塞特金福斯 ( 标准::wstring i_目标, 标准::wstring i_args, std::wstring

我试图以编程方式创建Shell链接,即快捷方式。在VisualStudioC++中.

快捷方式已创建,并且有效。但是图标是默认图标(因为API没有考虑提供的图标)。阅读文档时,似乎我必须提供一个图标索引。但这是什么?目前只有一个.ico文件

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

#包括“stdafx.h”
#包括
#包括
#包括
类MakeLnk
{
公众:
MakeLnk(){}
无效塞特金福斯
(
标准::wstring i_目标,
标准::wstring i_args,
std::wstring i_savePath,
std::wstring i_说明,
标准::wstring i_icoloc
)
{
目标=i_目标;
args=i_args;
savePath=i_savePath;
描述=i_描述;
icolocation=i_icoloc;
}
//实用程序函数,用于创建链接
HRESULT CreateLnk()
{
LPCWSTR lpszpathbj=target.c_str();
LPCTSTR arguments=args.c_str();
LPCWSTR lpszLinkPath=savePath.c_str();
LPCWSTR lpszDesc=description.c_str();
// ##########################
LPCWSTR lpszIcoPath=icolocation.c_str();//类似于“c:\\tmp\\crab.ico”的路径
// ##########################
HRESULT hres;
IShellLink*psl;
共初始化(空);
//获取指向IShellLink接口的指针。假定为CoInitialize
//已经打过电话了。
hres=CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_服务器,IID_IShellLink,(LPVOID*)&psl);
如果(成功(hres))
{
IPersistFile*ppf;
//设置快捷方式目标的路径,并添加说明和参数。
psl->SetPath(lpszpathbj);
psl->SetDescription(LPSZSDESC);
psl->SetArguments(参数);
// ###############################################
psl->SetIconLocation(lpszIcoPath,0);//这里!放什么来代替“0”?
// ###############################################
//查询IPersistFile接口的IShellLink,用于保存
//持久存储中的快捷方式。
hres=psl->QueryInterface(IID_IPersistFile,(LPVOID*)和ppf);
如果(成功(hres))
{
//通过调用IPersistFile::Save保存链接。
hres=ppf->Save(lpszLinkPath,TRUE);
ppf->Release();
}
psl->Release();
}
coninitialize();
返回hres;
}
私人:
std::wstring目标、参数、存储路径、描述;
std::wstring位置;
};
int main()
{
MakeLnk-linkMaker;
std::wstring exepath(L“C:\\Program Files\\Crab\\Exec.exe)、参数(L“eat dance”)、lnkPath(L“shortcut.lnk”)、说明(L“单击此处打开Crab程序”)、图标(L“C:\\tmp\\Crab.ico”);
SetLnkInfos(exepath、参数、lnkPath、描述、图标);
bool res=linkMaker.CreateLnk();
返回res?0:-1;
}

Shell链接可以从EXE和DLL文件中获取图标,这些图标作为嵌入式资源存储在那里。由于EXE或DLL文件可以包含多个图标,因此shell链接需要知道使用哪个图标。这是由索引控制的


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

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


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

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


如果您有一个.ico文件,则必须先将它添加到可执行文件中,然后才能使用它

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


如果您有一个.ico文件,则必须先将它添加到可执行文件中,然后才能使用它

图标存储在可执行文件的资源数据中。可以有多个,索引选择您想要的。如果使用.ico文件而不是嵌入的图标,则索引不相关。@HansPassant Ok,但这里的图标是由外部.ico文件提供的。未嵌入可执行文件。如果您不喜欢它的外观,请选择另一个.ico文件。@HansPassant编辑了问题。我的意思是,SetIconLocation方法失败了。你怎么知道它失败了?您没有检查其返回值。对于.ico文件来说,像c:\tmp这样的路径是不健康的,只要快捷方式存在,该文件就需要存在。请注意,资源管理器缓存图标,如果它曾经看到该快捷方式具有不同的图标(或根本没有),那么您将看到旧的图标。点击Google“windows重置外壳图标缓存”。图标存储在可执行文件的资源数据中。可以有多个,索引选择您想要的。如果使用.ico文件而不是嵌入的图标,则索引不相关。@HansPassant Ok,但这里的图标是由外部.ico文件提供的。未嵌入可执行文件。如果您不喜欢它的外观,请选择另一个.ico文件。@HansPassant编辑了问题。我的意思是,SetIconLocation方法失败了。你怎么知道它失败了?您没有检查其返回值。对于.ico文件来说,像c:\tmp这样的路径是不健康的,只要快捷方式存在,该文件就需要存在。请注意,资源管理器缓存图标,如果它曾经看到该快捷方式具有不同的图标(或根本没有),那么您将看到旧的图标。谷歌“windows重置外壳图标缓存”点击。谢谢你的链接。但是如何将.ico添加到可执行文件中?@yO_u这是一个新的问题,应该问
#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;
}