⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uihelper.cpp.svn-base

📁 wince c++ 下 开发的 rss 阅读器源代码
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c) 2003 Microsoft Corporation

Module Name:

    uihelper.cpp

Abstract:

    Helper functions for HIDPI/Landscape support.

--*/

#include "UIHelper.h"

HIDPI_ENABLE;

BOOL HIDPI_StretchBitmap(
    HBITMAP* phbm,
    int cxDstImg,
    int cyDstImg,
    int cImagesX,
    int cImagesY
    )
{
    BOOL fRet = FALSE;
    HBITMAP hbmNew;
    BITMAP  bm;
    HDC hdcSrc, hdcDst, hdcScreen;
    HBITMAP hbmOldSrc, hbmOldDst;
    int  cxSrcImg, cySrcImg;
    int  i, j, xDest, yDest, xBmp, yBmp;

    if (!phbm || !*phbm || (cxDstImg == 0 && cyDstImg == 0) || (cImagesX == 0 || cImagesY == 0))
        goto donestretch;

    if ((sizeof(bm) != GetObject(*phbm, sizeof(bm), &bm)))
        goto donestretch;

    // If you hit this ASSERT, that mean your passed in image count in row and
    //   the column number of images is not correct.
    ASSERT(((bm.bmWidth % cImagesX) == 0) && ((bm.bmHeight % cImagesY) == 0));

    cxSrcImg = bm.bmWidth / cImagesX;
    cySrcImg = bm.bmHeight / cImagesY;

    if (cxSrcImg == cxDstImg && cySrcImg == cyDstImg)
    {
        fRet = TRUE;
        goto donestretch;
    }

    if (cxDstImg == 0)
        cxDstImg = HIDPIMulDiv(cyDstImg, cxSrcImg, cySrcImg);
    else if (cyDstImg == 0)
        cyDstImg = HIDPIMulDiv(cxDstImg, cySrcImg, cxSrcImg);

    hdcSrc = CreateCompatibleDC(NULL);
    hdcDst = CreateCompatibleDC(NULL);
    hdcScreen = GetDC(NULL);
    hbmOldSrc = (HBITMAP)SelectObject(hdcSrc, *phbm);
    hbmNew = CreateCompatibleBitmap(hdcScreen, cxDstImg * cImagesX, cyDstImg * cImagesY);
    hbmOldDst = (HBITMAP)SelectObject(hdcDst, hbmNew);
    ReleaseDC(NULL, hdcScreen);

    // BLAST!
    for (j = 0, yDest = 0, yBmp = 0; j < cImagesY; j++, yDest += cyDstImg, yBmp += cySrcImg)
    {
        for (i = 0, xDest = 0, xBmp = 0; i < cImagesX; i++, xDest += cxDstImg, xBmp += cxSrcImg)
        {
            StretchBlt(hdcDst, xDest, yDest, cxDstImg, cyDstImg,
                       hdcSrc, xBmp, yBmp, cxSrcImg, cySrcImg,
                       SRCCOPY);
        }
    }

    // Free allocated memory
    SelectObject(hdcSrc, hbmOldSrc);
    SelectObject(hdcDst, hbmOldDst);
    DeleteDC(hdcSrc);
    DeleteDC(hdcDst);

    // Delete the passed in bitmap
    DeleteObject(*phbm);
    *phbm = hbmNew;

    fRet = TRUE;

donestretch:
    return fRet;
}

static BOOL HIDPI_StretchIcon_Internal(
    HICON hiconIn,
    HICON* phiconOut,
    int cxIcon,
    int cyIcon
)
{
    ICONINFO iconinfo;

    HDC hdc;
    HBITMAP hbmImage, hbmMask;
    HBITMAP hbmOld;

    *phiconOut = NULL;
    hdc = CreateCompatibleDC(NULL);

    hbmMask = CreateCompatibleBitmap(hdc, cxIcon, cyIcon);
    hbmOld = (HBITMAP)SelectObject(hdc, hbmMask);
    BOOL fDrawMaskOK = DrawIconEx(hdc, 0, 0, hiconIn, cxIcon, cyIcon, 0, NULL, DI_MASK);
    SelectObject(hdc, hbmOld);

    hbmImage = CreateBitmap(cxIcon, cyIcon, 1, GetDeviceCaps(hdc, BITSPIXEL), NULL);
    hbmOld = (HBITMAP)SelectObject(hdc, hbmImage);
    BOOL fDrawImageOK = DrawIconEx(hdc, 0, 0, hiconIn, cxIcon, cyIcon, 0, NULL, DI_IMAGE);
    SelectObject(hdc, hbmOld);

    if (fDrawImageOK && fDrawMaskOK)
    {
        iconinfo.fIcon = TRUE;
        iconinfo.hbmColor = hbmImage;
        iconinfo.hbmMask = hbmMask;
        *phiconOut = CreateIconIndirect(&iconinfo);
    }

    DeleteObject(hbmImage);
    DeleteObject(hbmMask);

    DeleteDC(hdc);

    return (fDrawImageOK && fDrawMaskOK && *phiconOut != NULL) ? TRUE : FALSE;
}

BOOL HIDPI_StretchIcon(
    HICON* phic,
    int cxIcon,
    int cyIcon
)
{
    HICON hiconOut;

    if (HIDPI_StretchIcon_Internal(*phic, &hiconOut, cxIcon, cyIcon))
    {
        DestroyIcon(*phic);
        *phic = hiconOut;
        return TRUE;
    }

    return FALSE;
}


BOOL HIDPI_GetBitmapLogPixels(
    HINSTANCE hinst,
    LPCTSTR lpbmp,
    int* pnLogPixelsX,
    int* pnLogPixelsY
    )
{
    BOOL fRet = FALSE;
    HRSRC hResource;
    HGLOBAL hResourceBitmap = NULL;
    BITMAPINFO* pBitmapInfo;
    int PelsPerMeterX, PelsPerMeterY;

    *pnLogPixelsX = 0;
    *pnLogPixelsY = 0;

    hResource = FindResource(hinst, lpbmp, RT_BITMAP);
    if (!hResource)
    {
        goto error;
    }
    hResourceBitmap = LoadResource(hinst, hResource);
    if (!hResourceBitmap)
    {
        goto error;
    }
    pBitmapInfo = (BITMAPINFO*)LockResource(hResourceBitmap);
    if (!pBitmapInfo)
    {
        goto error;
    }

    // There are at least three kind value of PslsPerMeter used for 96 DPI bitmap:
    //   0    - the bitmap just simply doesn't set this value
    //   2834 - 72 DPI
    //   3780 - 96 DPI
    // So any value of PslsPerMeter under 3780 should be treated as 96 DPI bitmap.
    PelsPerMeterX = (pBitmapInfo->bmiHeader.biXPelsPerMeter < 3780) ? 3780 : pBitmapInfo->bmiHeader.biXPelsPerMeter;
    PelsPerMeterY = (pBitmapInfo->bmiHeader.biYPelsPerMeter < 3780) ? 3780 : pBitmapInfo->bmiHeader.biYPelsPerMeter;

    // The formula for converting PelsPerMeter to LogPixels(DPI) is:
    //   LogPixels = PelsPerMeter / 39.37
    //   ( PelsPerMeter : Pixels per meter )
    //   ( LogPixels    : Pixels per inch  )
    // Note: We need to round up.
    *pnLogPixelsX = (int)((PelsPerMeterX * 100 + 1968) / 3937);
    *pnLogPixelsY = (int)((PelsPerMeterY * 100 + 1968) / 3937);

    fRet = TRUE;

error:
    return fRet;
}


HIMAGELIST HIDPI_ImageList_LoadImage(
    HINSTANCE hinst,
    LPCTSTR lpbmp,
    int cx,
    int cGrow,
    COLORREF crMask,
    UINT uType,
    UINT uFlags
    )
{
    HBITMAP hbmImage = NULL;
    HIMAGELIST piml = NULL;
    BITMAP bm;
    int cImages, cxImage, cy;
    int BmpLogPixelsX, BmpLogPixelsY;
    UINT flags;

    if ((uType != IMAGE_BITMAP) ||  // Image type is not IMAGE_BITMAP
        (cx == 0))                  // Caller doesn't care about the dimensions of the image - assumes the ones in the file
    {
        piml = ImageList_LoadImage(hinst, lpbmp, cx, cGrow, crMask, uType, uFlags);
        goto cleanup;
    }

    if (!HIDPI_GetBitmapLogPixels(hinst, lpbmp, &BmpLogPixelsX, &BmpLogPixelsY))
    {
        goto cleanup;
    }

    hbmImage = (HBITMAP)LoadImage(hinst, lpbmp, uType, 0, 0, uFlags);
    if (!hbmImage || (sizeof(bm) != GetObject(hbmImage, sizeof(bm), &bm)))
    {
        goto cleanup;
    }

    // do we need to scale this image?
    if (BmpLogPixelsX == g_HIDPI_LogPixelsX)
    {
        piml = ImageList_LoadImage(hinst, lpbmp, cx, cGrow, crMask, uType, uFlags);
        goto cleanup;
    }

    cxImage = HIDPIMulDiv(cx, BmpLogPixelsX, g_HIDPI_LogPixelsX);

    // Bitmap width should be multiple integral of image width.
    // If not, that means either your bitmap is wrong or passed in cx is wrong.
    ASSERT((bm.bmWidth % cxImage) == 0);

    cImages = bm.bmWidth / cxImage;

    cy = HIDPIMulDiv(bm.bmHeight, g_HIDPI_LogPixelsY, BmpLogPixelsY);

    if ((g_HIDPI_LogPixelsX % BmpLogPixelsX) == 0)
    {
        HIDPI_StretchBitmap(&hbmImage, cx * cImages, cy, 1, 1);
    }
    else
    {
        // Here means the DPI is not integral multiple of standard DPI (96DPI).
        // So if we stretch entire bitmap together, we are not sure each indivisual
        //   image will be stretch to right place. It is controled by StretchBlt().
        //   (for example, a 16 pixel icon, the first one might be stretch to 22 pixels
        //    and next one might be stretched to 20 pixels)
        // What we have to do here is stretching indivisual image separately to make sure
        //   every one is stretched properly.
        HIDPI_StretchBitmap(&hbmImage, cx, cy, cImages, 1);
    }

    flags = 0;
    // ILC_MASK is important for supporting CLR_DEFAULT
    if (crMask != CLR_NONE)
    {
        flags |= ILC_MASK;
    }
    // ILC_COLORMASK bits are important if we ever want to Merge ImageLists
    if (bm.bmBits)
    {
        flags |= (bm.bmBitsPixel & ILC_COLORMASK);
    }

    // bitmap MUST be de-selected from the DC
    // create the image list of the size asked for.
    piml = ImageList_Create(cx, cy, flags, cImages, cGrow);

    if (piml)
    {
        int added;

        if (crMask == CLR_NONE)
        {
            added = ImageList_Add(piml, hbmImage, NULL);
        }
        else
        {
            added = ImageList_AddMasked(piml, hbmImage, crMask);
        }

        if (added < 0)
        {
            ImageList_Destroy(piml);
            piml = NULL;
        }
    }

cleanup:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -