From ac7fca3606d1a7dd5985b6fc284c40c0f2682fe5 Mon Sep 17 00:00:00 2001 From: miniak Date: Tue, 22 Sep 2009 10:33:27 +0200 Subject: * QPixmap: Add toWinHICON() & fromWinHICON() method Duplicate QPixmap <-> HICON conversion code removed from qwidget_win.cpp & qsystemtrayicon_win.cpp. Task-number: 218533 Merge-request: 1570 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/image/qpixmap.cpp | 36 ++++++- src/gui/image/qpixmap.h | 3 + src/gui/image/qpixmap_win.cpp | 43 ++++++++ src/gui/kernel/qwidget_win.cpp | 36 +------ src/gui/util/qsystemtrayicon_win.cpp | 34 +----- .../auto/qpixmap/convertFromToHICON/icon_32bpp.ico | Bin 0 -> 285478 bytes .../convertFromToHICON/icon_32bpp_16x16.png | Bin 0 -> 754 bytes .../convertFromToHICON/icon_32bpp_256x256.png | Bin 0 -> 16269 bytes .../convertFromToHICON/icon_32bpp_32x32.png | Bin 0 -> 1745 bytes .../convertFromToHICON/icon_32bpp_48x48.png | Bin 0 -> 2618 bytes .../auto/qpixmap/convertFromToHICON/icon_8bpp.ico | Bin 0 -> 7406 bytes .../qpixmap/convertFromToHICON/icon_8bpp_16x16.png | Bin 0 -> 1454 bytes .../qpixmap/convertFromToHICON/icon_8bpp_32x32.png | Bin 0 -> 1721 bytes .../qpixmap/convertFromToHICON/icon_8bpp_48x48.png | Bin 0 -> 1967 bytes tests/auto/qpixmap/tst_qpixmap.cpp | 115 ++++++++++++++++++++- 15 files changed, 192 insertions(+), 75 deletions(-) create mode 100644 tests/auto/qpixmap/convertFromToHICON/icon_32bpp.ico create mode 100644 tests/auto/qpixmap/convertFromToHICON/icon_32bpp_16x16.png create mode 100644 tests/auto/qpixmap/convertFromToHICON/icon_32bpp_256x256.png create mode 100644 tests/auto/qpixmap/convertFromToHICON/icon_32bpp_32x32.png create mode 100644 tests/auto/qpixmap/convertFromToHICON/icon_32bpp_48x48.png create mode 100644 tests/auto/qpixmap/convertFromToHICON/icon_8bpp.ico create mode 100644 tests/auto/qpixmap/convertFromToHICON/icon_8bpp_16x16.png create mode 100644 tests/auto/qpixmap/convertFromToHICON/icon_8bpp_32x32.png create mode 100644 tests/auto/qpixmap/convertFromToHICON/icon_8bpp_48x48.png diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 4f145af..558ae54 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1678,12 +1678,15 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode) operation, you can use QBitmap::fromImage() instead. In addition, on Windows, the QPixmap class supports conversion to - and from HBitmap: the toWinHBITMAP() function creates a HBITMAP + and from HBITMAP: the toWinHBITMAP() function creates a HBITMAP equivalent to the QPixmap, based on the given HBitmapFormat, and returns the HBITMAP handle. The fromWinHBITMAP() function returns a QPixmap that is equivalent to the given bitmap which has the - specified format. - + specified format. The QPixmap class also supports conversion to + and from HICON: the toWinHICON() function creates a HICON equivalent + to the QPixmap, and returns the HICON handle. The fromWinHICON() + function returns a QPixmap that is equivalent to the given icon. + In addition, on Symbian, the QPixmap class supports conversion to and from CFbsBitmap: the toSymbianCFbsBitmap() function creates CFbsBitmap equivalent to the QPixmap, based on given mode and returns @@ -2040,7 +2043,7 @@ QPixmapData* QPixmap::pixmapData() const \warning This function is only available on Windows. - \sa fromWinHBITMAP() + \sa fromWinHBITMAP(), {QPixmap#Pixmap Conversion}{Pixmap Conversion} */ /*! \fn QPixmap QPixmap::fromWinHBITMAP(HBITMAP bitmap, HBitmapFormat format) @@ -2054,6 +2057,31 @@ QPixmapData* QPixmap::pixmapData() const */ +/*! \fn HICON QPixmap::toWinHICON() const + \since 4.6 + + \bold{Win32 only:} Creates a \c HICON equivalent to the QPixmap. + Returns the \c HICON handle. + + It is the caller's responsibility to free the \c HICON data after use. + + \warning This function is only available on Windows. + + \sa fromWinHICON(), {QPixmap#Pixmap Conversion}{Pixmap Conversion} +*/ + +/*! \fn QPixmap QPixmap::fromWinHICON(HICON icon) + \since 4.6 + + \bold{Win32 only:} Returns a QPixmap that is equivalent to the given + \a icon. + + \warning This function is only available on Windows. + + \sa toWinHICON(), {QPixmap#Pixmap Conversion}{Pixmap Conversion} + +*/ + /*! \fn const QX11Info &QPixmap::x11Info() const \bold{X11 only:} Returns information about the configuration of the X display used to display the widget. diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h index 54e89ff..2ed65ea 100644 --- a/src/gui/image/qpixmap.h +++ b/src/gui/image/qpixmap.h @@ -149,7 +149,10 @@ public: }; HBITMAP toWinHBITMAP(HBitmapFormat format = NoAlpha) const; + HICON toWinHICON() const; + static QPixmap fromWinHBITMAP(HBITMAP hbitmap, HBitmapFormat format = NoAlpha); + static QPixmap fromWinHICON(HICON hicon); #endif #if defined(Q_WS_MAC) diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp index 9042840..7f0c8e3 100644 --- a/src/gui/image/qpixmap_win.cpp +++ b/src/gui/image/qpixmap_win.cpp @@ -236,6 +236,49 @@ QPixmap QPixmap::fromWinHBITMAP(HBITMAP bitmap, HBitmapFormat format) return fromImage(result); } +HBITMAP qt_createIconMask(const QBitmap &bitmap) +{ + QImage bm = bitmap.toImage().convertToFormat(QImage::Format_Mono); + int w = bm.width(); + int h = bm.height(); + int bpl = ((w+15)/16)*2; // bpl, 16 bit alignment + uchar *bits = new uchar[bpl*h]; + bm.invertPixels(); + for (int y=0; yinternalWinId(), (wchar_t*)caption.utf16()); } -/* - Create an icon mask the way Windows wants it using CreateBitmap. -*/ - -HBITMAP qt_createIconMask(const QBitmap &bitmap) -{ - QImage bm = bitmap.toImage().convertToFormat(QImage::Format_Mono); - int w = bm.width(); - int h = bm.height(); - int bpl = ((w+15)/16)*2; // bpl, 16 bit alignment - uchar *bits = new uchar[bpl*h]; - bm.invertPixels(); - for (int y=0; y("image"); + QTest::addColumn("width"); + QTest::addColumn("height"); + + const QString prefix = QLatin1String(SRCDIR) + "/convertFromToHICON"; + + QTest::newRow("32bpp_16x16") << prefix + QLatin1String("/icon_32bpp") << 16 << 16; + QTest::newRow("32bpp_32x32") << prefix + QLatin1String("/icon_32bpp") << 32 << 32; + QTest::newRow("32bpp_48x48") << prefix + QLatin1String("/icon_32bpp") << 48 << 48; + QTest::newRow("32bpp_256x256") << prefix + QLatin1String("/icon_32bpp") << 256 << 256; + + QTest::newRow("8bpp_16x16") << prefix + QLatin1String("/icon_8bpp") << 16 << 16; + QTest::newRow("8bpp_32x32") << prefix + QLatin1String("/icon_8bpp") << 32 << 32; + QTest::newRow("8bpp_48x48") << prefix + QLatin1String("/icon_8bpp") << 48 << 48; +} + +void tst_QPixmap::toWinHICON() +{ + QFETCH(int, width); + QFETCH(int, height); + QFETCH(QString, image); + + QPixmap empty(width, height); + empty.fill(Qt::transparent); + + HDC display_dc = GetDC(0); + HDC bitmap_dc = CreateCompatibleDC(display_dc); + HBITMAP bitmap = empty.toWinHBITMAP(QPixmap::Alpha); + SelectObject(bitmap_dc, bitmap); + + QImage imageFromFile(image + QString(QLatin1String("_%1x%2.png")).arg(width).arg(height)); + imageFromFile = imageFromFile.convertToFormat(QImage::Format_ARGB32_Premultiplied); + + HICON icon = QPixmap::fromImage(imageFromFile).toWinHICON(); + + DrawIconEx(bitmap_dc, 0, 0, icon, width, height, 0, 0, DI_NORMAL); + + DestroyIcon(icon); + DeleteDC(bitmap_dc); + + QImage imageFromHICON = QPixmap::fromWinHBITMAP(bitmap, QPixmap::Alpha).toImage(); + + ReleaseDC(0, display_dc); + + // fuzzy comparison must be used, as the pixel values change slightly during conversion + // between QImage::Format_ARGB32 and QImage::Format_ARGB32_Premultiplied, or elsewhere + + // QVERIFY(imageFromHICON == imageFromFile); + compareImages(imageFromHICON, imageFromFile); +} + +void tst_QPixmap::fromWinHICON_data() +{ + toWinHICON_data(); +} + +void tst_QPixmap::fromWinHICON() +{ + QFETCH(int, width); + QFETCH(int, height); + QFETCH(QString, image); + + HICON icon = (HICON)LoadImage(0, (wchar_t*)(image + QLatin1String(".ico")).utf16(), IMAGE_ICON, width, height, LR_LOADFROMFILE); + QImage imageFromHICON = QPixmap::fromWinHICON(icon).toImage(); + DestroyIcon(icon); + + QImage imageFromFile(image + QString(QLatin1String("_%1x%2.png")).arg(width).arg(height)); + imageFromFile = imageFromFile.convertToFormat(QImage::Format_ARGB32_Premultiplied); + + // fuzzy comparison must be used, as the pixel values change slightly during conversion + // between QImage::Format_ARGB32 and QImage::Format_ARGB32_Premultiplied, or elsewhere + + // QVERIFY(imageFromHICON == imageFromFile); + compareImages(imageFromHICON, imageFromFile); +} + +#endif // Q_WS_WIN #if defined(Q_WS_S60) Q_DECLARE_METATYPE(TDisplayMode) -- cgit v0.12