Qt提取EXE文件的大图标
2016-03-29 22:54
435 查看
曾经的自己是一个桌面控,有空没空总爱折腾自己的桌面。于是便想自己写一个类似于DOCK这样的小工具去管理自己的应用程序,鉴于Qt在做界面方面灰常方便,于是使用Qt去编写这么一个小玩意。
以下是一些笔记:
1. 提取exe的图标
Qt内可以直接调用windows提取图标的相关API,但是有个限制,只能提取到16*16或者32*32大小的图标,想要获得想文件管理器里面显示的大图标,需要通过SHELL相关接口。那么问题来了,如何才能在Qt里面使用到这些接口呢?答案是用VC先写一个Dll,对外提供一个获取HICON的接口,然后再Qt里面动态加载。
先用VS建一个Win32的Dll工程,然后添加下面接口:
EXTERN_C _declspec(dllexport) HICON CYCGetIcon(CONST TCHAR *filePath, CONST int iconSize=SHIL_LARGE)
{
// get ICON index
SHFILEINFOW sfi = {0};
SHGetFileInfo(filePath, -1, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX);
// get 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(iconSize, 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)
{
return hIcon;
}
}
return NULL;
}
接着就可以在Qt里面使用了,这里把HICON转成了QPixmap:
typedef HICON (*CYCGetIcon)(CONST TCHAR *, CONST INT);
QPixmap MainWindow::getIcon(QString filename)
{
QLibrary mylib("getIcon.dll");
HICON hIcon;
QPixmap pixmap;
if (mylib.load())
{
CYCGetIcon icon;
icon=(CYCGetIcon)mylib.resolve("CYCGetIcon");
if (icon!=NULL)
{
//#define SHIL_EXTRALARGE 2
//#define SHIL_JUMBO 4
hIcon=icon((CONST TCHAR *)filename.utf16(), 4);
pixmap=QtWin::fromHICON(hIcon);
if(!pixmapIsOnly48Bit(pixmap))
return pixmap;
else
{
//qDebug()<<"48 bits only";
hIcon=icon((CONST TCHAR *)filename.utf16(), 2);
return QtWin::fromHICON(hIcon);
}
}
}
QMessageBox::information(NULL,"NO","Cannot load 'getIcon.dll' correctly!");
return QPixmap(":/pic/chilun.png");
}
bool MainWindow::pixmapIsOnly48Bit(QPixmap pixmap)
{
QImage img=pixmap.toImage();
int row=img.height(), col=img.width();
for(int i=49; i<row; ++i)
{
for(int j=49; j<col; ++j)
{
if((img.pixel(i,j)&0xff000000)!=0)
return false;
}
}
return true;
}
效果图:
以下是一些笔记:
1. 提取exe的图标
Qt内可以直接调用windows提取图标的相关API,但是有个限制,只能提取到16*16或者32*32大小的图标,想要获得想文件管理器里面显示的大图标,需要通过SHELL相关接口。那么问题来了,如何才能在Qt里面使用到这些接口呢?答案是用VC先写一个Dll,对外提供一个获取HICON的接口,然后再Qt里面动态加载。
先用VS建一个Win32的Dll工程,然后添加下面接口:
EXTERN_C _declspec(dllexport) HICON CYCGetIcon(CONST TCHAR *filePath, CONST int iconSize=SHIL_LARGE)
{
// get ICON index
SHFILEINFOW sfi = {0};
SHGetFileInfo(filePath, -1, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX);
// get 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(iconSize, 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)
{
return hIcon;
}
}
return NULL;
}
接着就可以在Qt里面使用了,这里把HICON转成了QPixmap:
typedef HICON (*CYCGetIcon)(CONST TCHAR *, CONST INT);
QPixmap MainWindow::getIcon(QString filename)
{
QLibrary mylib("getIcon.dll");
HICON hIcon;
QPixmap pixmap;
if (mylib.load())
{
CYCGetIcon icon;
icon=(CYCGetIcon)mylib.resolve("CYCGetIcon");
if (icon!=NULL)
{
//#define SHIL_EXTRALARGE 2
//#define SHIL_JUMBO 4
hIcon=icon((CONST TCHAR *)filename.utf16(), 4);
pixmap=QtWin::fromHICON(hIcon);
if(!pixmapIsOnly48Bit(pixmap))
return pixmap;
else
{
//qDebug()<<"48 bits only";
hIcon=icon((CONST TCHAR *)filename.utf16(), 2);
return QtWin::fromHICON(hIcon);
}
}
}
QMessageBox::information(NULL,"NO","Cannot load 'getIcon.dll' correctly!");
return QPixmap(":/pic/chilun.png");
}
bool MainWindow::pixmapIsOnly48Bit(QPixmap pixmap)
{
QImage img=pixmap.toImage();
int row=img.height(), col=img.width();
for(int i=49; i<row; ++i)
{
for(int j=49; j<col; ++j)
{
if((img.pixel(i,j)&0xff000000)!=0)
return false;
}
}
return true;
}
效果图:
相关文章推荐
- 关于QT5 Failed to find or load platform plugin "windows" 问题
- QT隐藏鼠标
- Qt编译qsqlmysql.dll插件
- qt5.5.1的程序发布方法
- 在Ubuntu 10.04中文版下Qt编程,使用unixODBC和FreeTDS连接MS SQL Server 2005,并且中文不出现乱码的方法
- Qt自定义委托在QTableView中绘制控件、图片、文字(内容比较全)
- 跨平台开发之qt及开源组件qml material
- 分治——sqtx
- QT5读取中文乱码问题
- Qt 写bmp文件
- PyQt5(4)——控件事件响应与信号槽
- GDKOI2016Day2 T2 QT与泰剧 解题报告
- PyQt5应用与实践
- Qt5布局管理(一)——QSplitter分割窗口类
- Qt error : "No Target Architecture"
- QT5 动态链接库的创建和使用
- Qt中配置Winpcap
- qt中的tcp编程
- qt3d中shader内置变量
- PyQt5(3)——快速界面设计