mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
fix icon loading code to load the correct icon for the current display bpp settings
svn path=/trunk/; revision=25466
This commit is contained in:
parent
d673aa2616
commit
3bd87918a1
2 changed files with 203 additions and 120 deletions
|
@ -231,10 +231,7 @@ LoadCursorIconImage(
|
||||||
if (IconResDir == NULL)
|
if (IconResDir == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/*
|
/* Find the best fitting in the IconResDir for this resolution */
|
||||||
* Find the best fitting in the IconResDir for this resolution
|
|
||||||
*/
|
|
||||||
|
|
||||||
id = LookupIconIdFromDirectoryEx((PBYTE)IconResDir, Icon, width, height,
|
id = LookupIconIdFromDirectoryEx((PBYTE)IconResDir, Icon, width, height,
|
||||||
fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
|
fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
|
||||||
|
|
||||||
|
@ -256,6 +253,7 @@ LoadCursorIconImage(
|
||||||
SizeofResource(hinst, h2Resource),
|
SizeofResource(hinst, h2Resource),
|
||||||
Icon, 0x00030000, width, height,
|
Icon, 0x00030000, width, height,
|
||||||
fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
|
fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
|
||||||
|
|
||||||
if (hIcon && 0 != (fuLoad & LR_SHARED))
|
if (hIcon && 0 != (fuLoad & LR_SHARED))
|
||||||
{
|
{
|
||||||
NtUserSetCursorIconData((HICON)hIcon, NULL, NULL, hinst, (HRSRC)hfRes,
|
NtUserSetCursorIconData((HICON)hIcon, NULL, NULL, hinst, (HRSRC)hfRes,
|
||||||
|
|
|
@ -440,35 +440,47 @@ LookupIconIdFromDirectory(
|
||||||
PBYTE presbits,
|
PBYTE presbits,
|
||||||
BOOL fIcon)
|
BOOL fIcon)
|
||||||
{
|
{
|
||||||
return LookupIconIdFromDirectoryEx( presbits, fIcon,
|
return LookupIconIdFromDirectoryEx(presbits,
|
||||||
fIcon ? GetSystemMetrics(SM_CXICON) : GetSystemMetrics(SM_CXCURSOR),
|
fIcon,
|
||||||
fIcon ? GetSystemMetrics(SM_CYICON) : GetSystemMetrics(SM_CYCURSOR), LR_DEFAULTCOLOR );
|
fIcon ? GetSystemMetrics(SM_CXICON) : GetSystemMetrics(SM_CXCURSOR),
|
||||||
|
fIcon ? GetSystemMetrics(SM_CYICON) : GetSystemMetrics(SM_CYCURSOR),
|
||||||
|
LR_DEFAULTCOLOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ported from WINE20030408 */
|
|
||||||
GRPCURSORICONDIRENTRY*
|
|
||||||
CURSORICON_FindBestCursor( GRPCURSORICONDIR *dir, int width, int height, int colors)
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following macro function accounts for the irregularities of
|
||||||
|
* accessing cursor and icon resources in files and resource entries.
|
||||||
|
*/
|
||||||
|
typedef BOOL
|
||||||
|
(*fnGetCIEntry)(LPVOID dir, int n, int *width, int *height, int *bits );
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* CURSORICON_FindBestIcon
|
||||||
|
*
|
||||||
|
* Find the icon closest to the requested size and number of colors.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
CURSORICON_FindBestIcon(LPVOID dir,
|
||||||
|
fnGetCIEntry get_entry,
|
||||||
|
int Width,
|
||||||
|
int Height,
|
||||||
|
int ColorBits)
|
||||||
{
|
{
|
||||||
int i;
|
int i, cx, cy, Bits, BestBits = 0, BestEntry = -1;
|
||||||
GRPCURSORICONDIRENTRY *entry, *bestEntry = NULL;
|
|
||||||
UINT iTotalDiff, iXDiff=0, iYDiff=0, iColorDiff;
|
UINT iTotalDiff, iXDiff=0, iYDiff=0, iColorDiff;
|
||||||
UINT iTempXDiff, iTempYDiff, iTempColorDiff;
|
UINT iTempXDiff, iTempYDiff, iTempColorDiff;
|
||||||
|
|
||||||
if (dir->idCount < 1)
|
|
||||||
{
|
|
||||||
DPRINT("Empty directory!\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (dir->idCount == 1)
|
|
||||||
return &dir->idEntries[0]; /* No choice... */
|
|
||||||
|
|
||||||
/* Find Best Fit */
|
/* Find Best Fit */
|
||||||
iTotalDiff = 0xFFFFFFFF;
|
iTotalDiff = 0xFFFFFFFF;
|
||||||
iColorDiff = 0xFFFFFFFF;
|
iColorDiff = 0xFFFFFFFF;
|
||||||
for (i = 0, entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++)
|
for (i = 0; get_entry(dir, i, &cx, &cy, &Bits); i++ )
|
||||||
{
|
{
|
||||||
iTempXDiff = abs(width - entry->ResInfo.icon.bWidth);
|
iTempXDiff = abs(Width - cx);
|
||||||
iTempYDiff = abs(height - entry->ResInfo.icon.bHeight);
|
iTempYDiff = abs(Height - cy);
|
||||||
|
|
||||||
if(iTotalDiff > (iTempXDiff + iTempYDiff))
|
if(iTotalDiff > (iTempXDiff + iTempYDiff))
|
||||||
{
|
{
|
||||||
|
@ -479,118 +491,191 @@ CURSORICON_FindBestCursor( GRPCURSORICONDIR *dir, int width, int height, int col
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find Best Colors for Best Fit */
|
/* Find Best Colors for Best Fit */
|
||||||
for (i = 0, entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++)
|
for (i = 0; get_entry(dir, i, &cx, &cy, &Bits); i++ )
|
||||||
{
|
{
|
||||||
if(abs(width - entry->ResInfo.icon.bWidth) == (int) iXDiff &&
|
if(abs(Width - cx) == iXDiff && abs(Height - cy) == iYDiff)
|
||||||
abs(height - entry->ResInfo.icon.bHeight) == (int) iYDiff)
|
|
||||||
{
|
{
|
||||||
iTempColorDiff = abs(colors - entry->ResInfo.icon.bColorCount);
|
iTempColorDiff = abs(ColorBits - Bits);
|
||||||
|
|
||||||
if(iColorDiff > iTempColorDiff)
|
|
||||||
{
|
|
||||||
bestEntry = entry;
|
|
||||||
iColorDiff = iTempColorDiff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return bestEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ported from WINE20030408 */
|
|
||||||
GRPCURSORICONDIRENTRY*
|
|
||||||
CURSORICON_FindBestIcon( GRPCURSORICONDIR *dir, int width, int height, int colorbits)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
GRPCURSORICONDIRENTRY *entry, *bestEntry = NULL;
|
|
||||||
UINT iTotalDiff, iXDiff=0, iYDiff=0, iColorDiff;
|
|
||||||
UINT iTempXDiff, iTempYDiff, iTempColorDiff;
|
|
||||||
|
|
||||||
if (dir->idCount < 1)
|
|
||||||
{
|
|
||||||
DPRINT("Empty directory!\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (dir->idCount == 1)
|
|
||||||
return &dir->idEntries[0]; /* No choice... */
|
|
||||||
|
|
||||||
/* Find Best Fit */
|
|
||||||
iTotalDiff = 0xFFFFFFFF;
|
|
||||||
iColorDiff = 0xFFFFFFFF;
|
|
||||||
for (i = 0, entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++)
|
|
||||||
{
|
|
||||||
iTempXDiff = abs(width - entry->ResInfo.icon.bWidth);
|
|
||||||
|
|
||||||
iTempYDiff = abs(height - entry->ResInfo.icon.bHeight);
|
|
||||||
|
|
||||||
if(iTotalDiff > (iTempXDiff + iTempYDiff))
|
|
||||||
{
|
|
||||||
iXDiff = iTempXDiff;
|
|
||||||
iYDiff = iTempYDiff;
|
|
||||||
iTotalDiff = iXDiff + iYDiff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find Best Colors for Best Fit */
|
|
||||||
for (i = 0, entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++)
|
|
||||||
{
|
|
||||||
if(abs(width - entry->ResInfo.icon.bWidth) == (int) iXDiff &&
|
|
||||||
abs(height - entry->ResInfo.icon.bHeight) == (int) iYDiff)
|
|
||||||
{
|
|
||||||
iTempColorDiff = abs(colorbits - entry->wBitCount);
|
|
||||||
if(iColorDiff > iTempColorDiff)
|
if(iColorDiff > iTempColorDiff)
|
||||||
{
|
{
|
||||||
bestEntry = entry;
|
BestEntry = i;
|
||||||
|
BestBits = Bits;
|
||||||
iColorDiff = iTempColorDiff;
|
iColorDiff = iTempColorDiff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return bestEntry;
|
DPRINT1("Best Icon: ResId: %d, bits : %d\n", BestEntry, BestBits);
|
||||||
|
|
||||||
|
return BestEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ported from WINE20030408 */
|
|
||||||
/*
|
|
||||||
* @implemented
|
/**********************************************************************
|
||||||
|
* CURSORICON_FindBestCursor
|
||||||
|
*
|
||||||
|
* Find the cursor closest to the requested size.
|
||||||
|
* FIXME: parameter 'color' ignored and entries with more than 1 bpp
|
||||||
|
* ignored too
|
||||||
*/
|
*/
|
||||||
INT STDCALL
|
static int
|
||||||
LookupIconIdFromDirectoryEx(
|
CURSORICON_FindBestCursor(LPVOID dir,
|
||||||
PBYTE presbits,
|
fnGetCIEntry get_entry,
|
||||||
BOOL fIcon,
|
int Width,
|
||||||
int cxDesired,
|
int Height,
|
||||||
int cyDesired,
|
int ColorBits)
|
||||||
UINT Flags)
|
|
||||||
{
|
{
|
||||||
GRPCURSORICONDIR *dir = (GRPCURSORICONDIR*)presbits;
|
int i, MaxWidth, MaxHeight, cx, cy, Bits, BestEntry = -1;
|
||||||
UINT retVal = 0;
|
|
||||||
|
|
||||||
if (dir && !dir->idReserved && (IMAGE_ICON == dir->idType || IMAGE_CURSOR == dir->idType))
|
/* Double height to account for AND and XOR masks */
|
||||||
{
|
Height *= 2;
|
||||||
GRPCURSORICONDIRENTRY *entry;
|
|
||||||
HDC hdc;
|
|
||||||
int ColorBits;
|
|
||||||
|
|
||||||
hdc = CreateICW(NULL, NULL, NULL, NULL);
|
/* First find the largest one smaller than or equal to the requested size*/
|
||||||
if (Flags & LR_MONOCHROME)
|
MaxWidth = MaxHeight = 0;
|
||||||
{
|
for (i = 0; get_entry(dir, i, &cx, &cy, &Bits); i++ )
|
||||||
ColorBits = 1;
|
{
|
||||||
}
|
if ((cx <= Width) && (cy <= Height) &&
|
||||||
else
|
(cx > MaxWidth) && (cy > MaxHeight) &&
|
||||||
{
|
(Bits == 1))
|
||||||
ColorBits = GetDeviceCaps(hdc, BITSPIXEL);
|
{
|
||||||
if (ColorBits > 8)
|
BestEntry = i;
|
||||||
ColorBits = 8;
|
MaxWidth = cx;
|
||||||
}
|
MaxHeight = cy;
|
||||||
DeleteDC(hdc);
|
}
|
||||||
|
}
|
||||||
|
if (BestEntry != -1)
|
||||||
|
return BestEntry;
|
||||||
|
|
||||||
entry = CURSORICON_FindBestIcon( dir, cxDesired, cyDesired, ColorBits );
|
/* Now find the smallest one larger than the requested size */
|
||||||
|
MaxWidth = MaxHeight = 255;
|
||||||
|
for (i = 0; get_entry(dir, i, &cx, &cy, &Bits); i++ )
|
||||||
|
{
|
||||||
|
if (((cx < MaxWidth) && (cy < MaxHeight) && (Bits == 1)) ||
|
||||||
|
(BestEntry == -1))
|
||||||
|
{
|
||||||
|
BestEntry = i;
|
||||||
|
MaxWidth = cx;
|
||||||
|
MaxHeight = cy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (entry)
|
return BestEntry;
|
||||||
retVal = entry->nID;
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
static BOOL
|
||||||
DbgPrint("invalid resource directory\n");
|
CURSORICON_GetResIconEntry(LPVOID dir,
|
||||||
}
|
int n,
|
||||||
return retVal;
|
int *Width,
|
||||||
|
int *Height,
|
||||||
|
int *Bits)
|
||||||
|
{
|
||||||
|
GRPCURSORICONDIR *ResDir = dir;
|
||||||
|
ICONRESDIR *Icon;
|
||||||
|
|
||||||
|
if (ResDir->idCount <= n)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
Icon = &ResDir->idEntries[n].ResInfo.icon;
|
||||||
|
*Width = Icon->bWidth;
|
||||||
|
*Height = Icon->bHeight;
|
||||||
|
*Bits = ResDir->idEntries[n].wBitCount;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL
|
||||||
|
CURSORICON_GetResCursorEntry(LPVOID dir,
|
||||||
|
int n,
|
||||||
|
int *Width,
|
||||||
|
int *Height,
|
||||||
|
int *Bits)
|
||||||
|
{
|
||||||
|
GRPCURSORICONDIR *ResDir = dir;
|
||||||
|
CURSORRESDIR *Cursor;
|
||||||
|
|
||||||
|
if (ResDir->idCount <= n)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
Cursor = &ResDir->idEntries[n].ResInfo.cursor;
|
||||||
|
*Width = Cursor->wWidth;
|
||||||
|
*Height = Cursor->wHeight;
|
||||||
|
*Bits = ResDir->idEntries[n].wBitCount;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GRPCURSORICONDIRENTRY *
|
||||||
|
CURSORICON_FindBestIconRes(GRPCURSORICONDIR * dir,
|
||||||
|
int Width,
|
||||||
|
int Height,
|
||||||
|
int ColorBits)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
n = CURSORICON_FindBestIcon(dir,
|
||||||
|
CURSORICON_GetResIconEntry,
|
||||||
|
Width,
|
||||||
|
Height,
|
||||||
|
ColorBits);
|
||||||
|
if (n < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return &dir->idEntries[n];
|
||||||
|
}
|
||||||
|
|
||||||
|
static GRPCURSORICONDIRENTRY *
|
||||||
|
CURSORICON_FindBestCursorRes(GRPCURSORICONDIR *dir,
|
||||||
|
int Width,
|
||||||
|
int Height,
|
||||||
|
int ColorBits)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
n = CURSORICON_FindBestCursor(dir,
|
||||||
|
CURSORICON_GetResCursorEntry,
|
||||||
|
Width,
|
||||||
|
Height,
|
||||||
|
ColorBits);
|
||||||
|
if (n < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return &dir->idEntries[n];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
INT WINAPI
|
||||||
|
LookupIconIdFromDirectoryEx(PBYTE xdir,
|
||||||
|
BOOL bIcon,
|
||||||
|
INT width,
|
||||||
|
INT height,
|
||||||
|
UINT cFlag)
|
||||||
|
{
|
||||||
|
GRPCURSORICONDIR *dir = (GRPCURSORICONDIR*)xdir;
|
||||||
|
UINT retVal = 0;
|
||||||
|
if(dir && !dir->idReserved && (IMAGE_ICON == dir->idType || IMAGE_CURSOR == dir->idType))
|
||||||
|
{
|
||||||
|
GRPCURSORICONDIRENTRY *entry = NULL;
|
||||||
|
int ColorBits;
|
||||||
|
|
||||||
|
if (cFlag & LR_MONOCHROME)
|
||||||
|
{
|
||||||
|
ColorBits = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HDC hdc = GetDC(0);
|
||||||
|
ColorBits = GetDeviceCaps(hdc, BITSPIXEL);
|
||||||
|
ReleaseDC(0, hdc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bIcon)
|
||||||
|
entry = CURSORICON_FindBestIconRes(dir, width, height, ColorBits);
|
||||||
|
else
|
||||||
|
entry = CURSORICON_FindBestCursorRes(dir, width, height, 1);
|
||||||
|
|
||||||
|
if (entry)
|
||||||
|
retVal = entry->nID;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DPRINT1("%s() : Invalid resource directory\n", __FUNCTION__);
|
||||||
|
|
||||||
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue