最近做一個程序,想從EXE,DLL或者其他什麼的文件中提取 圖標。
從網上搜集了一下資料發現只能夠提取到 比較小的圖標,小圖標為 16x16,大圖標為32x32,這遠遠滿足不了需求,下面是一般做法:
QString filePath;
QFileInfo fileInfo(filePath);
QFileIconProvider fileIcon();
QIcon icon=fileIcon ().icon (fileInfo);
QPixmap pixmap=icon.pixmap (128,128);
結果只能夠最多得到32x32的圖標。
於是我查看QFileIconProvider的實現源文件,發現主要由SHGetFileInfo這個函數實現。
//Get the small icon
#ifndef Q_OS_WINCE
val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_SMALLICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS|SHGFI_OVERLAYINDEX);
//Get the big icon
#ifndef Q_OS_WINCE
val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_LARGEICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS|SHGFI_OVERLAYINDEX);
這樣就只能夠得到16x16的小圖標和32x32的大圖標。
雖然上面用的是QPixmap pixmap=icon.pixmap (128,128); 但是還是只能夠得到32x32的圖標。
於是便琢磨著如何使用VS2010下的庫呢?
思來想去水平太低了沒想出個辦法,但突然想到咱可以用 VS2010做個DLL 給QT調用啊。
於是在VS2010下 寫個到出函數:
#include <ShellAPI.h>
#include <CommCtrl.h>
#include <commoncontrols.h>
#include <windows.h>
EXTERN_C _declspec(dllexport) HICON getJumbIcon(CONST TCHAR *filePath)
{
// Get the icon index using SHGetFileInfo
SHFILEINFOW sfi = {0};
SHGetFileInfo(filePath, -1, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX);
// Retrieve the system image list.
// To get the 48x48 icons, use SHIL_EXTRALARGE
// To get the 256x256 icons (Vista only), use SHIL_JUMBO
IImageList* imageList;
HRESULT hResult = SHGetImageList(SHIL_JUMBO, IID_IImageList, (void**)&imageList);
if (hResult == S_OK) {
// Get the icon we need from the list. Note that the HIMAGELIST we retrieved
// earlier needs to be casted to the IImageList interface before use.
HICON hIcon;
hResult = (imageList)->GetIcon(sfi.iIcon, ILD_TRANSPARENT, &hIcon);
if (hResult == S_OK) {
// Do something with the icon here.
return hIcon;
}
}
}
然後在QT裡面調用:
typedef HICON (*getIcon)(CONST TCHAR *filePath); //定義函數指針,以備調用
HICON test(QString filePath)
{
QLibrary mylib("./configure/dll/icon.dll"); //聲明所用到的dll文件
HICON jumbIcon;
if (mylib.load())
{
getIcon icon=(getIcon)mylib.resolve("getJumbIcon"); //援引 add() 函數
if (icon) //是否成功連接上 add() 函數
{
filePath.replace ("/","\\");
jumbIcon=icon((CONST TCHAR *)filePath.utf16 ()); //這裡函數指針調用dll中的 add() 函數
return jumbIcon;
}
else
QMessageBox::information(NULL,"NO","Linke to Function is not OK!!!!");
}
else
QMessageBox::information(NULL,"NO","DLL is not loaded!");
return NULL;
}
HICON hicon=test(filePath);
QPixmap icon=QPixmap::fromWinHICON (hicon);
DestroyIcon(hicon);
最後icon便可以顯示256X256的圖片了。
可以更改SHIL_JUMBO來決定 圖標的大小。
最後是DLL文件了。
本文出自 “悠悠幽幽” 博客