Qt5调用QPixmap::fromWinHICON Posted 2023-01-20 imxiangzi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt5调用QPixmap::fromWinHICON相关的知识,希望对你有一定的参考价值。
QPixmap QPixmap::fromWinHICON ( HICON icon ) [static]
Win32 only: Returns a QPixmap that is equivalent to the given icon. Warning: This function is only available on Windows. This function was introduced in Qt 4.6.
在5.2里面直接没有这个方法了,真是让人捉急.
去Qt4.7源码里翻了翻找到了 fromWinHICON的实现:
qt-everywhere-opensource-src-4.7.0\\src\\gui\\image\\qpixmap_win.cpp line:283
其中引用到的函数 qMalloc() 在
qt-everywhere-opensource-src-4.7.0\\src\\corelib\\global\\qmalloc.cpp line:53
相关功能全部代码:
void
*qMalloc(
size_t
size)
static
QImage qt_fromWinHBITMAP(
HDC
hdc,
HBITMAP
bitmap,
int
w,
int
h)
memset
(&bmi, 0,
sizeof
(bmi));
bmi.bmiHeader.biSize =
sizeof
(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = w;
bmi.bmiHeader.biHeight = -h;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = w * h * 4;
QImage image(w, h, QImage::Format_ARGB32_Premultiplied);
uchar *data = (uchar *) qMalloc(bmi.bmiHeader.biSizeImage);
if
(GetDIBits(hdc, bitmap, 0, h, data, &bmi, DIB_RGB_COLORS))
// Create image and copy data into image.
void
*dest = (
void
*) image.scanLine(y);
void
*src = data + y * image.bytesPerLine();
memcpy
(dest, src, image.bytesPerLine());
qWarning(
"qt_fromWinHBITMAP(), failed to get bitmap bits"
);
QPixmap fromWinHICON(
HICON
icon)
//qt4.7 QPixmap::fromWinHICON(hIcon)
HDC
screenDevice = GetDC(0);
HDC
hdc = CreateCompatibleDC(screenDevice);
ReleaseDC(0, screenDevice);
bool
result = GetIconInfo(icon, &iconinfo);
//x and y Hotspot describes the icon center
qWarning(
"QPixmap::fromWinHICON(), failed to GetIconInfo()"
);
int
w = iconinfo.xHotspot * 2;
int
h = iconinfo.yHotspot * 2;
BITMAPINFOHEADER bitmapInfo;
bitmapInfo.biSize =
sizeof
(BITMAPINFOHEADER);
bitmapInfo.biBitCount = 32;
bitmapInfo.biCompression = BI_RGB;
bitmapInfo.biSizeImage = 0;
bitmapInfo.biXPelsPerMeter = 0;
bitmapInfo.biYPelsPerMeter = 0;
bitmapInfo.biClrUsed = 0;
bitmapInfo.biClrImportant = 0;
HBITMAP
winBitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bitmapInfo, DIB_RGB_COLORS, (
VOID
**)&bits, NULL, 0);
HGDIOBJ
oldhdc = (
HBITMAP
)SelectObject(hdc, winBitmap);
DrawIconEx( hdc, 0, 0, icon, iconinfo.xHotspot * 2, iconinfo.yHotspot * 2, 0, 0, DI_NORMAL);
QImage image = qt_fromWinHBITMAP(hdc, winBitmap, w, h);
for
(
int
y = 0 ; y < h && !foundAlpha ; y++)
QRgb *scanLine=
reinterpret_cast
<QRgb *>(image.scanLine(y));
for
(
int
x = 0; x < w ; x++)
if
(qAlpha(scanLine[x]) != 0)
//If no alpha was found, we use the mask to set alpha values
DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_MASK);
QImage mask = qt_fromWinHBITMAP(hdc, winBitmap, w, h);
for
(
int
y = 0 ; y < h ; y++)
QRgb *scanlineImage =
reinterpret_cast
<QRgb *>(image.scanLine(y));
QRgb *scanlineMask = mask.isNull() ? 0 :
reinterpret_cast
<QRgb *>(mask.scanLine(y));
for
(
int
x = 0; x < w ; x++)
if
(scanlineMask && qRed(scanlineMask[x]) != 0)
scanlineImage[x] = 0;
//mask out this pixel
scanlineImage[x] |= 0xff000000;
// set the alpha channel to 255
//dispose resources created by iconinfo call
DeleteObject(iconinfo.hbmMask);
DeleteObject(iconinfo.hbmColor);
SelectObject(hdc, oldhdc);
//restore state
return
QPixmap::fromImage(image);
添加到 Qt5.2工程里,编译通过.
关键测试代码:
//add lib for ExtractIcon()
#pragma comment(lib,"Shell32.lib")
//使用winAPI获得dll,exe文件内所有图标资源
QString f1=ui->tx_icon->text();
HINSTANCE
hInstance = (
HINSTANCE
)::GetModuleHandle(NULL);
count = (
int
)ExtractIconA(hInstance, f1.toLocal8Bit(), -1);
qDebug()<<
"totalIcon:"
<<count;
QListWidget *list=ui->list_ico;
hIcon = ExtractIconA(hInstance, f1.toLocal8Bit(), i);
list->addItem(
new
QListWidgetItem(QIcon(img),QString::number(i)));
最终效果:
FROM: http://www.yurenchen.com/qt_fromWinHICON.htm
以上是关于Qt5调用QPixmap::fromWinHICON的主要内容,如果未能解决你的问题,请参考以下文章
Qt5调用QPixmap::fromWinHICON
Q_INVOKABLE 是不是需要在 Qt5 中从 QML 调用公共 QObject 函数?
在最新Qt5.4,使用QWebengine,如何js调用Qt
在最新Qt5.4,使用QWebengine,如何js调用Qt
带有 .ui 文件的 QT5 自定义小部件 - 显示时需要调用 Ui::myWidget.setupUi
QT5百度地图开发学习——JavaScript调用qt函数并传参给qt