Qt5调用QPixmap::fromWinHICON

转载 2015年11月21日 15:11:26

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)
{
    return ::malloc(size);
}
void qFree(void *ptr)
{
    ::free(ptr);
}
static QImage qt_fromWinHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h)
{
    BITMAPINFO bmi;
    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);
    if (image.isNull())
        return image;
 
    // Get bitmap bits
    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.
        for (int y=0; y<h; ++y) {
            void *dest = (void *) image.scanLine(y);
            void *src = data + y * image.bytesPerLine();
            memcpy(dest, src, image.bytesPerLine());
        }
    else {
        qWarning("qt_fromWinHBITMAP(), failed to get bitmap bits");
    }
    qFree(data);
 
    return image;
}
QPixmap fromWinHICON(HICON icon)//qt4.7 QPixmap::fromWinHICON(hIcon)
{
    bool foundAlpha = false;
    HDC screenDevice = GetDC(0);
    HDC hdc = CreateCompatibleDC(screenDevice);
    ReleaseDC(0, screenDevice);
 
    ICONINFO iconinfo;
    bool result = GetIconInfo(icon, &iconinfo); //x and y Hotspot describes the icon center
    if (!result)
        qWarning("QPixmap::fromWinHICON(), failed to GetIconInfo()");
 
    int w = iconinfo.xHotspot * 2;
    int h = iconinfo.yHotspot * 2;
 
    BITMAPINFOHEADER bitmapInfo;
    bitmapInfo.biSize        = sizeof(BITMAPINFOHEADER);
    bitmapInfo.biWidth       = w;
    bitmapInfo.biHeight      = h;
    bitmapInfo.biPlanes      = 1;
    bitmapInfo.biBitCount    = 32;
    bitmapInfo.biCompression = BI_RGB;
    bitmapInfo.biSizeImage   = 0;
    bitmapInfo.biXPelsPerMeter = 0;
    bitmapInfo.biYPelsPerMeter = 0;
    bitmapInfo.biClrUsed       = 0;
    bitmapInfo.biClrImportant  = 0;
    DWORD* bits;
 
    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) {
                foundAlpha = true;
                break;
            }
        }
    }
    if (!foundAlpha) {
        //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
                else
                    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
    DeleteObject(winBitmap);
    DeleteDC(hdc);
    return QPixmap::fromImage(image);
}

添加到 Qt5.2工程里,编译通过.

关键测试代码:


//add lib for ExtractIcon()
#include <shellapi.h>
#pragma comment(lib,"Shell32.lib")
 
//使用winAPI获得dll,exe文件内所有图标资源
QString f1=ui->tx_icon->text();
HINSTANCE hInstance = (HINSTANCE)::GetModuleHandle(NULL);
int count;
count = (int)ExtractIconA(hInstance, f1.toLocal8Bit(), -1);
HICON hIcon;
qDebug()<<"totalIcon:"<<count;
 
QListWidget *list=ui->list_ico;
list->clear();
QPixmap img;
 
for(int i=0;i<count;i++){
    hIcon = ExtractIconA(hInstance, f1.toLocal8Bit(), i);
 
    img=fromWinHICON(hIcon);
    list->addItem(new QListWidgetItem(QIcon(img),QString::number(i)));
 
    DestroyIcon(hIcon);
}</shellapi.h>

最终效果:

viewIconInDll.png

 




FROM: http://www.yurenchen.com/qt_fromWinHICON.htm

相关文章推荐

QT中位图bitmap与VC的区别

Bitmap即每位代表一个像素的图片,VC和QT对bitmap的理解不一样,主要是大小端的理解不一样。   QBitmap::fromData(QSize(cx, cy), mask, QImag...

QPixmap注意事项

来源:QPixmap 我想qt 中QPixmap这个类大家都很熟悉,它可以很简单的在标签上贴图;例如: QPixmap p; p.load("1.png"); label-...

QPixmap

我想qt 中QPixmap这个类大家都很熟悉,它可以很简单的在标签上贴图;例如:QPixmap p;p.load("1.png");label->setPixmap(p); 就这么简单,但是我今天突然...

QPixmap

QPixmap 分类: QT开发 qt 我想qt 中QPixmap这个类大家都很熟悉,它可以很简单的在标签上贴图;例如: QPixmap p; p.loa...

给定A, B两个整数,不使用除法和取模运算,求A/B的商和余数

给定A, B两个整数,不使用除法和取模运算,求A/B的商和余数。 1.   最基本的算法是,从小到大遍历: for (i = 2 to A -1)          if (i * B > A)...

利用K-means聚类算法根据经纬度坐标对中国省市进行聚类

K-means聚类算法是一种非层次聚类算法,在最小误差的基础上将数据划分了特定的类,类间利用距离作为相似度指标,两个向量之间的距离越小,其相似度就越高。程序读取全国省市经纬度坐标,然后根据经纬度坐标进...

Radon变换理论介绍与matlab实现--经验交流

本人最近在研究Radon变换,在查阅了各种资料之后在此写下个人的理解,希望与各位牛牛进行交流共同进步,也使得理解更加深刻些。 Radon变换的本质是将原来的函数做了一个空间转换,即,将原来的XY平...

CT图像重建技术

由于csdn贴图不方便,并且不能上传附件,我把原文上传到了资源空间CT图像重建技术 1.引言 计算机层析成像(Computed Tomography,CT)是通过对物体进行不同角度的射线投影测量而...

Matlab绘图-很详细,很全面

Matlab绘图强大的绘图功能是Matlab的特点之一,Matlab提供了一系列的绘图函数,用户不需要过多的考虑绘图的细节,只需要给出一些基本参数就能得到所需图形,这类函数称为高层绘图函数。此外,Ma...

linux查找目录下的所有文件中是否含有某个字符串

查找目录下的所有文件中是否含有某个字符串  find .|xargs grep -ri "IBM"  查找目录下的所有文件中是否含有某个字符串,并且只打印出文件名  find .|xargs g...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Qt5调用QPixmap::fromWinHICON
举报原因:
原因补充:

(最多只允许输入30个字)