From 84607219c0e1e01a82132af9172e350529c3eb38 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Thu, 9 Feb 2012 17:39:31 +0100 Subject: [PATCH] Add qt_pixmapFromWinHICON again for Windows CE. qt_pixmapFromWinHICON is used by qfileiconprovider and qwindowsstyle. So use this one from Qt 4.8. Also put functions of qguifunctions_wince in here, because this was splitted. Change-Id: I00ffb9d66a84884f7338648982e516ca016b9bd6 Reviewed-by: Friedemann Kleint --- src/gui/image/qpixmap_win.cpp | 179 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp index 6b0ec38..227e70e 100644 --- a/src/gui/image/qpixmap_win.cpp +++ b/src/gui/image/qpixmap_win.cpp @@ -47,8 +47,91 @@ #include #include +#ifdef Q_OS_WINCE +#define UNDER_NT +#include +#endif + QT_BEGIN_NAMESPACE +#ifdef Q_OS_WINCE +#define GetDIBits(a,b,c,d,e,f,g) qt_wince_GetDIBits(a,b,c,d,e,f,g) +int qt_wince_GetDIBits(HDC /*hdc*/ , HBITMAP hSourceBitmap, uint, uint, LPVOID lpvBits, LPBITMAPINFO, uint) +{ + if (!lpvBits) { + qWarning("::GetDIBits(), lpvBits NULL"); + return 0; + } + BITMAP bm; + GetObject(hSourceBitmap, sizeof(BITMAP), &bm); + bm.bmHeight = qAbs(bm.bmHeight); + + HBITMAP hTargetBitmap; + void *pixels; + + BITMAPINFO dibInfo; + memset(&dibInfo, 0, sizeof(dibInfo)); + dibInfo.bmiHeader.biBitCount = 32; + dibInfo.bmiHeader.biClrImportant = 0; + dibInfo.bmiHeader.biClrUsed = 0; + dibInfo.bmiHeader.biCompression = BI_RGB;; + dibInfo.bmiHeader.biHeight = -bm.bmHeight; + dibInfo.bmiHeader.biWidth = bm.bmWidth; + dibInfo.bmiHeader.biPlanes = 1; + dibInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + dibInfo.bmiHeader.biSizeImage = bm.bmWidth * bm.bmHeight * 4; + + HDC displayDC = GetDC(NULL); + if (!displayDC) { + qWarning("::GetDIBits(), failed to GetDC"); + return 0; + } + + int ret = bm.bmHeight; + + hTargetBitmap = CreateDIBSection(displayDC, (const BITMAPINFO*) &dibInfo, DIB_RGB_COLORS, + (void**)&pixels, NULL, 0); + if (!hTargetBitmap) { + qWarning("::GetDIBits(), failed to CreateDIBSection"); + return 0; + } + + HDC hdcSrc = CreateCompatibleDC(displayDC); + HDC hdcDst = CreateCompatibleDC(displayDC); + + if (!(hdcDst && hdcSrc)) { + qWarning("::GetDIBits(), failed to CreateCompatibleDC"); + ret = 0; + } + + HBITMAP hOldBitmap1 = (HBITMAP) SelectObject(hdcSrc, hSourceBitmap); + HBITMAP hOldBitmap2 = (HBITMAP) SelectObject(hdcDst, hTargetBitmap); + + if (!(hOldBitmap1 && hOldBitmap2)) { + qWarning("::GetDIBits(), failed to SelectObject for bitmaps"); + ret = 0; + } + + if (!BitBlt(hdcDst, 0, 0, bm.bmWidth, bm.bmHeight, hdcSrc, 0, 0, SRCCOPY)) { + qWarning("::GetDIBits(), BitBlt failed"); + ret = 0; + } + + SelectObject(hdcSrc, hOldBitmap1); + SelectObject(hdcDst, hOldBitmap2); + + DeleteDC(hdcSrc); + DeleteDC(hdcDst); + + ReleaseDC(NULL, displayDC); + + memcpy(lpvBits, pixels, dibInfo.bmiHeader.biSizeImage); + + DeleteObject(hTargetBitmap); + return ret; +} +#endif + enum HBitmapFormat { HBitmapNoAlpha, @@ -128,6 +211,8 @@ Q_GUI_EXPORT HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat = return bitmap; } +#ifndef Q_OS_WINCE + Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0) { // Verify size @@ -191,6 +276,8 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = return QPixmap::fromImage(image); } +#endif //ifndef Q_OS_WINCE + Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &p) { QBitmap maskBitmap = p.mask(); @@ -214,6 +301,8 @@ Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &p) return hIcon; } +#ifndef Q_OS_WINCE + Q_GUI_EXPORT QImage qt_imageFromWinHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h) { BITMAPINFO bmi; @@ -315,5 +404,95 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon) DeleteDC(hdc); return QPixmap::fromImage(image); } +#else //ifndef Q_OS_WINCE +Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon) +{ + HDC screenDevice = GetDC(0); + HDC hdc = CreateCompatibleDC(screenDevice); + ReleaseDC(0, screenDevice); + + ICONINFO iconinfo; + bool result = GetIconInfo(icon, &iconinfo); + if (!result) + qWarning("QPixmap::fromWinHICON(), failed to GetIconInfo()"); + + int w = 0; + int h = 0; + if (!iconinfo.xHotspot || !iconinfo.yHotspot) { + // We could not retrieve the icon size via GetIconInfo, + // so we try again using the icon bitmap. + BITMAP bm; + int result = GetObject(iconinfo.hbmColor, sizeof(BITMAP), &bm); + if (!result) result = GetObject(iconinfo.hbmMask, sizeof(BITMAP), &bm); + if (!result) { + qWarning("QPixmap::fromWinHICON(), failed to retrieve icon size"); + return QPixmap(); + } + w = bm.bmWidth; + h = bm.bmHeight; + } else { + // x and y Hotspot describes the icon center + w = iconinfo.xHotspot * 2; + h = iconinfo.yHotspot * 2; + } + const DWORD dwImageSize = w * h * 4; + + BITMAPINFO bmi; + memset(&bmi, 0, sizeof(bmi)); + bmi.bmiHeader.biSize = sizeof(BITMAPINFO); + bmi.bmiHeader.biWidth = w; + bmi.bmiHeader.biHeight = -h; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; + bmi.bmiHeader.biCompression = BI_RGB; + bmi.bmiHeader.biSizeImage = dwImageSize; + + uchar* bits; + + HBITMAP winBitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**) &bits, 0, 0); + if (winBitmap ) + memset(bits, 0xff, dwImageSize); + if (!winBitmap) { + qWarning("QPixmap::fromWinHICON(), failed to CreateDIBSection()"); + return QPixmap(); + } + + HGDIOBJ oldhdc = (HBITMAP)SelectObject(hdc, winBitmap); + if (!DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_NORMAL)) + qWarning("QPixmap::fromWinHICON(), failed to DrawIcon()"); + + uint mask = 0xff000000; + // Create image and copy data into image. + QImage image(w, h, QImage::Format_ARGB32); + + if (!image.isNull()) { // failed to alloc? + int bytes_per_line = w * sizeof(QRgb); + for (int y=0; y < h; ++y) { + QRgb *dest = (QRgb *) image.scanLine(y); + const QRgb *src = (const QRgb *) (bits + y * bytes_per_line); + for (int x=0; x < w; ++x) { + dest[x] = src[x]; + } + } + } + if (!DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_MASK)) + qWarning("QPixmap::fromWinHICON(), failed to DrawIcon()"); + if (!image.isNull()) { // failed to alloc? + int bytes_per_line = w * sizeof(QRgb); + for (int y=0; y < h; ++y) { + QRgb *dest = (QRgb *) image.scanLine(y); + const QRgb *src = (const QRgb *) (bits + y * bytes_per_line); + for (int x=0; x < w; ++x) { + if (!src[x]) + dest[x] = dest[x] | mask; + } + } + } + SelectObject(hdc, oldhdc); //restore state + DeleteObject(winBitmap); + DeleteDC(hdc); + return QPixmap::fromImage(image); +} +#endif //ifndef Q_OS_WINCE QT_END_NAMESPACE -- 2.7.4