📄 uihelper.cpp.svn-base
字号:
/*++
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 + -