Synthesize a small icon if none given

svn path=/trunk/; revision=18764
This commit is contained in:
Gé van Geldorp 2005-10-24 22:02:39 +00:00
parent cc33d0bac1
commit e0968c78d0

View file

@ -400,6 +400,170 @@ RealGetWindowClassA(
return GetClassNameA(hwnd,pszType,cchType);
}
/*
* Create a small icon based on a standard icon
*/
static HICON
CreateSmallIcon(HICON StdIcon)
{
HICON SmallIcon = NULL;
ICONINFO StdInfo;
int SmallIconWidth;
int SmallIconHeight;
BITMAP StdBitmapInfo;
HDC hInfoDc = NULL;
HDC hSourceDc = NULL;
HDC hDestDc = NULL;
ICONINFO SmallInfo;
HBITMAP OldSourceBitmap = NULL;
HBITMAP OldDestBitmap = NULL;
SmallInfo.hbmColor = NULL;
SmallInfo.hbmMask = NULL;
/* We need something to work with... */
if (NULL == StdIcon)
{
goto cleanup;
}
SmallIconWidth = GetSystemMetrics(SM_CXSMICON);
SmallIconHeight = GetSystemMetrics(SM_CYSMICON);
if (! GetIconInfo(StdIcon, &StdInfo))
{
DPRINT1("Failed to get icon info for icon 0x%x\n", StdIcon);
goto cleanup;
}
if (! GetObjectW(StdInfo.hbmMask, sizeof(BITMAP), &StdBitmapInfo))
{
DPRINT1("Failed to get bitmap info for icon 0x%x bitmap 0x%x\n",
StdIcon, StdInfo.hbmColor);
goto cleanup;
}
if (StdBitmapInfo.bmWidth == SmallIconWidth &&
StdBitmapInfo.bmHeight == SmallIconHeight)
{
/* Icon already has the correct dimensions */
return StdIcon;
}
/* Get a handle to a info DC and handles to DCs which can be used to
select a bitmap into. This is done to avoid triggering a switch to
graphics mode (if we're currently in text/blue screen mode) */
hInfoDc = CreateICW(NULL, NULL, NULL, NULL);
if (NULL == hInfoDc)
{
DPRINT1("Failed to create info DC\n");
goto cleanup;
}
hSourceDc = CreateCompatibleDC(NULL);
if (NULL == hSourceDc)
{
DPRINT1("Failed to create source DC\n");
goto cleanup;
}
hDestDc = CreateCompatibleDC(NULL);
if (NULL == hDestDc)
{
DPRINT1("Failed to create dest DC\n");
goto cleanup;
}
OldSourceBitmap = SelectObject(hSourceDc, StdInfo.hbmColor);
if (NULL == OldSourceBitmap)
{
DPRINT1("Failed to select source color bitmap\n");
goto cleanup;
}
SmallInfo.hbmColor = CreateCompatibleBitmap(hInfoDc, SmallIconWidth,
SmallIconHeight);
if (NULL == SmallInfo.hbmColor)
{
DPRINT1("Failed to create color bitmap\n");
goto cleanup;
}
OldDestBitmap = SelectObject(hDestDc, SmallInfo.hbmColor);
if (NULL == OldDestBitmap)
{
DPRINT1("Failed to select dest color bitmap\n");
goto cleanup;
}
if (! StretchBlt(hDestDc, 0, 0, SmallIconWidth, SmallIconHeight,
hSourceDc, 0, 0, StdBitmapInfo.bmWidth,
StdBitmapInfo.bmHeight, SRCCOPY))
{
DPRINT1("Failed to stretch color bitmap\n");
goto cleanup;
}
if (NULL == SelectObject(hSourceDc, StdInfo.hbmMask))
{
DPRINT1("Failed to select source mask bitmap\n");
goto cleanup;
}
SmallInfo.hbmMask = CreateBitmap(SmallIconWidth, SmallIconHeight, 1, 1,
NULL);
if (NULL == SmallInfo.hbmMask)
{
DPRINT1("Failed to create mask bitmap\n");
goto cleanup;
}
if (NULL == SelectObject(hDestDc, SmallInfo.hbmMask))
{
DPRINT1("Failed to select dest mask bitmap\n");
goto cleanup;
}
if (! StretchBlt(hDestDc, 0, 0, SmallIconWidth, SmallIconHeight,
hSourceDc, 0, 0, StdBitmapInfo.bmWidth,
StdBitmapInfo.bmHeight, SRCCOPY))
{
DPRINT1("Failed to stretch mask bitmap\n");
goto cleanup;
}
SmallInfo.fIcon = TRUE;
SmallInfo.xHotspot = SmallIconWidth / 2;
SmallInfo.yHotspot = SmallIconHeight / 2;
SmallIcon = CreateIconIndirect(&SmallInfo);
if (NULL == SmallIcon)
{
DPRINT1("Failed to create icon\n");
goto cleanup;
}
cleanup:
if (NULL != SmallInfo.hbmMask)
{
DeleteObject(SmallInfo.hbmMask);
}
if (NULL != OldDestBitmap)
{
SelectObject(hDestDc, OldDestBitmap);
}
if (NULL != SmallInfo.hbmColor)
{
DeleteObject(SmallInfo.hbmColor);
}
if (NULL != hDestDc)
{
DeleteDC(hDestDc);
}
if (NULL != OldSourceBitmap)
{
SelectObject(hSourceDc, OldSourceBitmap);
}
if (NULL != hSourceDc)
{
DeleteDC(hSourceDc);
}
if (NULL != hInfoDc)
{
DeleteDC(hInfoDc);
}
return SmallIcon;
}
/*
* @implemented
*/
@ -439,6 +603,11 @@ RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
RtlCopyMemory(&WndClass, lpwcx, sizeof(WNDCLASSEXW));
if (NULL == WndClass.hIconSm)
{
WndClass.hIconSm = CreateSmallIcon(WndClass.hIcon);
}
if (IS_ATOM(lpwcx->lpszMenuName) || lpwcx->lpszMenuName == 0)
{
MenuName.Length =
@ -514,6 +683,11 @@ RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
RtlCopyMemory(&WndClass, lpwcx, sizeof(WNDCLASSEXW));
if (NULL == WndClass.hIconSm)
{
WndClass.hIconSm = CreateSmallIcon(WndClass.hIcon);
}
if (IS_ATOM(lpwcx->lpszMenuName))
{
MenuName.Length =