mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +00:00
Unify the icon and cursor loading code for LoadImage.
svn path=/trunk/; revision=20147
This commit is contained in:
parent
b666bbf296
commit
bc49f0f151
1 changed files with 47 additions and 194 deletions
|
@ -72,7 +72,13 @@ LoadImageA(HINSTANCE hinst,
|
||||||
|
|
||||||
|
|
||||||
static HANDLE
|
static HANDLE
|
||||||
LoadCursorImage(HINSTANCE hinst, LPCWSTR lpszName, UINT fuLoad)
|
LoadCursorIconImage(
|
||||||
|
HINSTANCE hinst,
|
||||||
|
LPCWSTR lpszName,
|
||||||
|
INT width,
|
||||||
|
INT height,
|
||||||
|
UINT fuLoad,
|
||||||
|
ULONG uType)
|
||||||
{
|
{
|
||||||
HANDLE hResource;
|
HANDLE hResource;
|
||||||
HANDLE h2Resource;
|
HANDLE h2Resource;
|
||||||
|
@ -84,194 +90,22 @@ LoadCursorImage(HINSTANCE hinst, LPCWSTR lpszName, UINT fuLoad)
|
||||||
HICON hIcon;
|
HICON hIcon;
|
||||||
ULONG HeaderSize;
|
ULONG HeaderSize;
|
||||||
ULONG ColorCount;
|
ULONG ColorCount;
|
||||||
|
ULONG ColorBits;
|
||||||
PVOID Data;
|
PVOID Data;
|
||||||
CURSORICONDIRENTRY* dirEntry;
|
CURSORICONDIRENTRY* dirEntry;
|
||||||
ICONIMAGE* SafeIconImage;
|
ICONIMAGE* SafeIconImage;
|
||||||
GRPCURSORICONDIR* IconResDir;
|
GRPCURSORICONDIR* IconResDir;
|
||||||
INT id;
|
INT id;
|
||||||
ICONIMAGE *ResIcon;
|
ICONIMAGE *ResIcon;
|
||||||
UINT ColorBits;
|
BOOL Icon = (uType == IMAGE_ICON);
|
||||||
|
|
||||||
if (!(fuLoad & LR_LOADFROMFILE))
|
if (!(fuLoad & LR_LOADFROMFILE))
|
||||||
{
|
{
|
||||||
if (hinst == NULL)
|
if (hinst == NULL)
|
||||||
hinst = User32Instance;
|
hinst = User32Instance;
|
||||||
|
|
||||||
hResource = hfRes = FindResourceW(hinst, lpszName, RT_GROUP_CURSOR);
|
hResource = hfRes = FindResourceW(hinst, lpszName,
|
||||||
if (hResource == NULL)
|
Icon ? RT_GROUP_ICON : RT_GROUP_CURSOR);
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (fuLoad & LR_SHARED)
|
|
||||||
{
|
|
||||||
/* FIXME - pass size! */
|
|
||||||
hIcon = NtUserFindExistingCursorIcon(hinst, (HRSRC)hfRes, 0, 0);
|
|
||||||
if (hIcon)
|
|
||||||
return hIcon;
|
|
||||||
}
|
|
||||||
|
|
||||||
hResource = LoadResource(hinst, hResource);
|
|
||||||
if (hResource == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
IconResDir = LockResource(hResource);
|
|
||||||
if (IconResDir == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Find the best fitting in the IconResDir for this resolution
|
|
||||||
*/
|
|
||||||
|
|
||||||
id = LookupIconIdFromDirectoryEx((PBYTE)IconResDir, TRUE, 32, 32,
|
|
||||||
fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
|
|
||||||
|
|
||||||
h2Resource = FindResourceW(hinst, MAKEINTRESOURCEW(id), MAKEINTRESOURCEW(RT_CURSOR));
|
|
||||||
|
|
||||||
hResource = LoadResource(hinst, h2Resource);
|
|
||||||
if (hResource == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
ResIcon = LockResource(hResource);
|
|
||||||
if (ResIcon == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
hIcon = CreateIconFromResourceEx((PBYTE)ResIcon,
|
|
||||||
SizeofResource(hinst, h2Resource),
|
|
||||||
FALSE, 0x00030000, 32, 32,
|
|
||||||
fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
|
|
||||||
if (hIcon && 0 != (fuLoad & LR_SHARED))
|
|
||||||
{
|
|
||||||
NtUserSetCursorIconData((HICON)hIcon, NULL, NULL, hinst, (HRSRC)hfRes,
|
|
||||||
(HRSRC)NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hIcon;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fuLoad & LR_SHARED)
|
|
||||||
{
|
|
||||||
DbgPrint("FIXME: need LR_SHARED support for loading cursor images from files\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
hFile = CreateFileW(lpszName, GENERIC_READ, FILE_SHARE_READ, NULL,
|
|
||||||
OPEN_EXISTING, 0, NULL);
|
|
||||||
if (hFile == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
hSection = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
|
|
||||||
CloseHandle(hFile);
|
|
||||||
if (hSection == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
IconDIR = MapViewOfFile(hSection, FILE_MAP_READ, 0, 0, 0);
|
|
||||||
CloseHandle(hSection);
|
|
||||||
if (IconDIR == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (0 != IconDIR->idReserved ||
|
|
||||||
(IMAGE_ICON != IconDIR->idType && IMAGE_CURSOR != IconDIR->idType))
|
|
||||||
{
|
|
||||||
UnmapViewOfFile(IconDIR);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get a handle to the screen dc, the icon we create is going to be
|
|
||||||
* compatable with it.
|
|
||||||
*/
|
|
||||||
hScreenDc = CreateICW(NULL, NULL, NULL, NULL);
|
|
||||||
if (hScreenDc == NULL)
|
|
||||||
{
|
|
||||||
UnmapViewOfFile(IconDIR);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fuLoad & LR_MONOCHROME)
|
|
||||||
{
|
|
||||||
ColorBits = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ColorBits = GetDeviceCaps(hScreenDc, BITSPIXEL);
|
|
||||||
/*
|
|
||||||
* FIXME:
|
|
||||||
* Remove this after proper support for alpha icons will be finished.
|
|
||||||
*/
|
|
||||||
if (ColorBits > 8)
|
|
||||||
ColorBits = 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Pick the best size. */
|
|
||||||
dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon(IconDIR, 32, 32, ColorBits);
|
|
||||||
if (!dirEntry)
|
|
||||||
{
|
|
||||||
UnmapViewOfFile(IconDIR);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
SafeIconImage = RtlAllocateHeap(GetProcessHeap(), 0, dirEntry->dwBytesInRes);
|
|
||||||
if (SafeIconImage == NULL)
|
|
||||||
{
|
|
||||||
UnmapViewOfFile(IconDIR);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
memcpy(SafeIconImage, ((PBYTE)IconDIR) + dirEntry->dwImageOffset, dirEntry->dwBytesInRes);
|
|
||||||
UnmapViewOfFile(IconDIR);
|
|
||||||
|
|
||||||
/* At this point we have a copy of the icon image to play with. */
|
|
||||||
|
|
||||||
SafeIconImage->icHeader.biHeight = SafeIconImage->icHeader.biHeight /2;
|
|
||||||
|
|
||||||
if (SafeIconImage->icHeader.biSize == sizeof(BITMAPCOREHEADER))
|
|
||||||
{
|
|
||||||
BITMAPCOREHEADER* Core = (BITMAPCOREHEADER*)SafeIconImage;
|
|
||||||
ColorCount = (Core->bcBitCount <= 8) ? (1 << Core->bcBitCount) : 0;
|
|
||||||
HeaderSize = sizeof(BITMAPCOREHEADER) + ColorCount * sizeof(RGBTRIPLE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ColorCount = SafeIconImage->icHeader.biClrUsed;
|
|
||||||
if (ColorCount == 0 && SafeIconImage->icHeader.biBitCount <= 8)
|
|
||||||
ColorCount = 1 << SafeIconImage->icHeader.biBitCount;
|
|
||||||
HeaderSize = sizeof(BITMAPINFOHEADER) + ColorCount * sizeof(RGBQUAD);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make data point to the start of the XOR image data. */
|
|
||||||
Data = (PBYTE)SafeIconImage + HeaderSize;
|
|
||||||
|
|
||||||
hIcon = ICON_CreateCursorFromData(hScreenDc, Data, SafeIconImage, 32, 32, dirEntry->Info.cursor.wXHotspot, dirEntry->Info.cursor.wYHotspot);
|
|
||||||
DeleteDC(hScreenDc);
|
|
||||||
RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
|
|
||||||
|
|
||||||
return hIcon;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static HANDLE
|
|
||||||
LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuLoad)
|
|
||||||
{
|
|
||||||
HANDLE hResource;
|
|
||||||
HANDLE h2Resource;
|
|
||||||
HANDLE hfRes;
|
|
||||||
HANDLE hFile;
|
|
||||||
HANDLE hSection;
|
|
||||||
CURSORICONDIR *IconDIR;
|
|
||||||
HDC hScreenDc;
|
|
||||||
HICON hIcon;
|
|
||||||
ULONG HeaderSize;
|
|
||||||
ULONG ColorCount;
|
|
||||||
PVOID Data;
|
|
||||||
CURSORICONDIRENTRY* dirEntry;
|
|
||||||
ICONIMAGE* SafeIconImage;
|
|
||||||
GRPCURSORICONDIR* IconResDir;
|
|
||||||
INT id;
|
|
||||||
ICONIMAGE *ResIcon;
|
|
||||||
|
|
||||||
if (!(fuLoad & LR_LOADFROMFILE))
|
|
||||||
{
|
|
||||||
if (hinst == NULL)
|
|
||||||
hinst = User32Instance;
|
|
||||||
|
|
||||||
hResource = hfRes = FindResourceW(hinst, lpszName, RT_GROUP_ICON);
|
|
||||||
if (hResource == NULL)
|
if (hResource == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -294,10 +128,12 @@ LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuL
|
||||||
* Find the best fitting in the IconResDir for this resolution
|
* Find the best fitting in the IconResDir for this resolution
|
||||||
*/
|
*/
|
||||||
|
|
||||||
id = LookupIconIdFromDirectoryEx((PBYTE)IconResDir, TRUE, width, height,
|
id = LookupIconIdFromDirectoryEx((PBYTE)IconResDir, Icon, width, height,
|
||||||
fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
|
fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
|
||||||
|
|
||||||
h2Resource = FindResourceW(hinst, MAKEINTRESOURCEW(id), MAKEINTRESOURCEW(RT_ICON));
|
h2Resource = FindResourceW(hinst, MAKEINTRESOURCEW(id),
|
||||||
|
Icon ? MAKEINTRESOURCEW(RT_ICON) :
|
||||||
|
MAKEINTRESOURCEW(RT_CURSOR));
|
||||||
|
|
||||||
hResource = LoadResource(hinst, h2Resource);
|
hResource = LoadResource(hinst, h2Resource);
|
||||||
if (hResource == NULL)
|
if (hResource == NULL)
|
||||||
|
@ -309,7 +145,7 @@ LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuL
|
||||||
|
|
||||||
hIcon = CreateIconFromResourceEx((PBYTE)ResIcon,
|
hIcon = CreateIconFromResourceEx((PBYTE)ResIcon,
|
||||||
SizeofResource(hinst, h2Resource),
|
SizeofResource(hinst, h2Resource),
|
||||||
TRUE, 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))
|
||||||
{
|
{
|
||||||
|
@ -355,10 +191,36 @@ LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuL
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get a handle to the screen dc, the icon we create is going to be
|
||||||
|
* compatable with this. */
|
||||||
|
hScreenDc = CreateDCW(NULL, NULL, NULL, NULL);
|
||||||
|
if (hScreenDc == NULL)
|
||||||
|
{
|
||||||
|
UnmapViewOfFile(IconDIR);
|
||||||
|
RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fuLoad & LR_MONOCHROME)
|
||||||
|
{
|
||||||
|
ColorBits = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ColorBits = GetDeviceCaps(hScreenDc, BITSPIXEL);
|
||||||
|
/*
|
||||||
|
* FIXME:
|
||||||
|
* Remove this after proper support for alpha icons will be finished.
|
||||||
|
*/
|
||||||
|
if (ColorBits > 8)
|
||||||
|
ColorBits = 8;
|
||||||
|
}
|
||||||
|
|
||||||
/* Pick the best size. */
|
/* Pick the best size. */
|
||||||
dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon(IconDIR, width, height, 1);
|
dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon(IconDIR, width, height, ColorBits);
|
||||||
if (!dirEntry)
|
if (!dirEntry)
|
||||||
{
|
{
|
||||||
|
DeleteDC(hScreenDc);
|
||||||
UnmapViewOfFile(IconDIR);
|
UnmapViewOfFile(IconDIR);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -366,6 +228,7 @@ LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuL
|
||||||
SafeIconImage = RtlAllocateHeap(GetProcessHeap(), 0, dirEntry->dwBytesInRes);
|
SafeIconImage = RtlAllocateHeap(GetProcessHeap(), 0, dirEntry->dwBytesInRes);
|
||||||
if (SafeIconImage == NULL)
|
if (SafeIconImage == NULL)
|
||||||
{
|
{
|
||||||
|
DeleteDC(hScreenDc);
|
||||||
UnmapViewOfFile(IconDIR);
|
UnmapViewOfFile(IconDIR);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -394,16 +257,6 @@ LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuL
|
||||||
/* Make data point to the start of the XOR image data. */
|
/* Make data point to the start of the XOR image data. */
|
||||||
Data = (PBYTE)SafeIconImage + HeaderSize;
|
Data = (PBYTE)SafeIconImage + HeaderSize;
|
||||||
|
|
||||||
/* Get a handle to the screen dc, the icon we create is going to be
|
|
||||||
* compatable with this. */
|
|
||||||
hScreenDc = CreateICW(NULL, NULL, NULL, NULL);
|
|
||||||
if (hScreenDc == NULL)
|
|
||||||
{
|
|
||||||
if (fuLoad & LR_LOADFROMFILE)
|
|
||||||
RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
hIcon = ICON_CreateIconFromData(hScreenDc, Data, SafeIconImage, width, height, width/2, height/2);
|
hIcon = ICON_CreateIconFromData(hScreenDc, Data, SafeIconImage, width, height, width/2, height/2);
|
||||||
RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
|
RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
|
||||||
DeleteDC(hScreenDc);
|
DeleteDC(hScreenDc);
|
||||||
|
@ -552,9 +405,9 @@ LoadImageW(
|
||||||
case IMAGE_BITMAP:
|
case IMAGE_BITMAP:
|
||||||
return LoadBitmapImage(hinst, lpszName, fuLoad);
|
return LoadBitmapImage(hinst, lpszName, fuLoad);
|
||||||
case IMAGE_CURSOR:
|
case IMAGE_CURSOR:
|
||||||
return LoadCursorImage(hinst, lpszName, fuLoad);
|
|
||||||
case IMAGE_ICON:
|
case IMAGE_ICON:
|
||||||
return LoadIconImage(hinst, lpszName, cxDesired, cyDesired, fuLoad);
|
return LoadCursorIconImage(hinst, lpszName, cxDesired, cyDesired,
|
||||||
|
fuLoad, uType);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue