根据文件绝对路径得到其图标

说明:极少文件无法得到图标,原因不明。如下图,左边全部得到图标,右边有两个文件夹图标没有得到

 关键函数:SHGetFileInfo

                                     

主函数:

HICON hIcon = getIconOfPath(string2LPCWSTR(str),1);//string2LPCWSTR为将string转换为LPCWSTR的函数,本文不说明
if(hIcon == NULL){
  //...没有得到.ico格式图标
}
else{
  HBITMAP hBmp = IconToBitmap(hIcon);
  CDuiString sCtrlKey = wstr;//wstr为wchar_t*型,存储了文件的绝对路径
  m_PaintManager.AddImage(sCtrlKey,hBmp,16,16,true);//16,16是要显示的图片的大小,如果图片大于16*16,会裁剪而不是整体缩小
  pItem->SetItemIcon(sCtrlKey);
}
DestroyIcon(hIcon);

getIconOfPath:

 1 HICON getIconOfPath(LPCTSTR pszPath,UINT flag){//第二个参数默认值为0
 2   HICON hIcon = NULL;
 3   if(flag == 0){
 4     hIcon = ExtractExtraLargeIcon(pszPath);
 5   }
 6   else{
 7     hICon = ExtractExtraLargeIcon(pszPath,1);
 8   }
 9   
10   if(hIcon == NULL){
11     hIcon = ExtractArbitrarySizeIcon(pszPath,32);
12   }
13   if(hIcon == NULL){
14     //之后导入一张通用的ico图
15     return NULL;
16   }
17   return hIcon;
18 }
ExtractExtraLargeIcon:
 1 HICON ExtractExtraLargeIcon(LPCTSTR pszPath,UINT flag)//第二个参数默认值为0
 2  3   SHFILEINFO sfi;  //shellapi.h
 4   SHGetFileInfo(pszPath, 0, &sfi, sizeof(sfi),SHGFI_SYSICONINDEX);
 5   IImageList* piml; //CommonControls.h
 6   if(SHGetImageList(SHIL_SMALL, IID_IImageList,(void**)&piml) == S_OK){
 7     HICON hIcon;
 8     int x = 0, y = 0;
 9     if(piml->GetIcon(sfi.iIcon,ILD_TRANSPARENT,&hIcon) == S_OK){
10       return hIcon;
11     }
12   }
13   return NULL;
14
ExtractArbitrarySizeIcon:
1 HICON ExtractArbitrarySizeIcon(LPCTSTR pszPath,int size){
2   HICON hIcon;
3   if(SHDefExtractIcon(pszPath, 0, 0, &hIcon, NULL, size) == S_OK){
4     return hIcon;
5   }
6   return NULL;
7 }

IconToBitmap(icon转bitmap):

HBITMAP IconToBitmap(HICON hIcon,SIZE* pTargetSize){
  ICONINFO info = {0};  //WinUser.h
  if(hIcon == NULL || !GetIconInfo(hIcon,&info) || !info.fIcon){
    return NULL;
  }
  INT nWidth = 0;
  INT nHeight = 0;
  if(pTargetSize != NULL){
    nWidth = pTargetSize->cx;
    nHeight = pTargetSize->cy;
  }
  else{
    if(info.hbmColor != NULL){
      BITMAP bmp = {0};
      GetObject(info.hbmColor,sizeof(bmp),&bmp);
      nWidth = bmp.bmWidth;
      nHeight = bmp.bmHeight;
    }
  }
  if(info.hbmColor != NULL){
    DeleteObject(info.hbmColor);
    info.hbmColor = NULL;
  }
  if(info.hbmMask != NULL){
    DeleteObject(info.hbmMask );
    info.hbmMask = NULL;
  }
  if(nWidth <= 0 || nHeight <= 0){
    return NULL;
  }
  INT nPixelCount = nWidth * nHeight;
  HDC dc = GetDC(NULL);
  INT* pData = NULL;
  HDC dcMem = NULL;
  HBITMAP hBmpOld = NULL;
  bool* pOpaque = NULL;
  HBITMAP dib = NULL;
  BOOL bSuccess = False;

  do{
    BITMAPINFOHEADER bi = {0};
    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biWidth = nWidth;
    bi.biHeight = -nHeight;
    bi.biPlanes = 1;
    bi.biBitCount = 32;
    bi.biCompression = BI_RGB;
    dib = CreateDIBSection(dc, (BITMAPINFO*)&bi, DIB_RGB_COLORS, (VOID**)&pData, NULL, 0);
    if(dib == NULL) break;
    memset(pData, 0, nPixelCount*4);
    dcMem = CreateCompatibleDC(dc);
    if(dcMem == NULL) break;
    hBmpOld = (HBITMAP)SelecObject(dcMem, dib);
    ::DrawIconEx(dcMem, 0, 0, hIcon, nWidth, nHeight, 0, NULL, DI_MASK);
    pOpaque = new(std::nothorw)bool[nPixelCount];
    if(pOpaque == NULL) break;
    for(INT i = 0; i < nPixelCount; ++i){
      pOpaque[i] = !pData[i];
    }
    memset(pData, 0, nPixelCount*4);
    ::DrawIconEx(dcMem, 0, 0, hIcon, nWidth, nHeight, 0, NULL, DT_NORMAL);
    BOOL bPixelCount = FALSE;
    UINT* pPixel = (UINT*)pData;
    for(INT i = 0; i < nPixelCount; ++i, ++pPixel){
      if((*pPixel & 0xff000000) != 0){
        bPixelHasAlpha = TRUE;
        break;
      }
    }
    if(!bPixelHasAlpha){
      pPixel = (UINT*)pData;
      for(INT i = 0; i < nPixelCount; ++i, ++pPixel){
        if(pOpaque[i]){
          *pPixel |= 0xFF000000;
        }
        else
        {
          *pPixel &= 0x00FFFFFF;   
        }
      }
    }
    bSuccess = TRUE;
  }while(FALSE);
  if(!bSuccess){
    if(dib = NULL){
      DeleteObject(dib);
      dib = NULL;
    }
  }
  return dib;
}
 
原文地址:https://www.cnblogs.com/Toya/p/11447855.html