Unify the icon and cursor loading code for LoadImage. Modified: trunk/reactos/lib/user32/windows/bitmap.c _____
Modified: trunk/reactos/lib/user32/windows/bitmap.c --- trunk/reactos/lib/user32/windows/bitmap.c 2005-12-13 18:56:49 UTC (rev 20146) +++ trunk/reactos/lib/user32/windows/bitmap.c 2005-12-13 19:07:08 UTC (rev 20147) @@ -72,7 +72,13 @@
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 h2Resource; @@ -84,27 +90,28 @@ HICON hIcon; ULONG HeaderSize; ULONG ColorCount; + ULONG ColorBits; PVOID Data; CURSORICONDIRENTRY* dirEntry; ICONIMAGE* SafeIconImage; GRPCURSORICONDIR* IconResDir; INT id; ICONIMAGE *ResIcon; - UINT ColorBits; + BOOL Icon = (uType == IMAGE_ICON);
if (!(fuLoad & LR_LOADFROMFILE)) { if (hinst == NULL) hinst = User32Instance;
- hResource = hfRes = FindResourceW(hinst, lpszName, RT_GROUP_CURSOR); + hResource = hfRes = FindResourceW(hinst, lpszName, + Icon ? RT_GROUP_ICON : RT_GROUP_CURSOR); if (hResource == NULL) return NULL;
if (fuLoad & LR_SHARED) { - /* FIXME - pass size! */ - hIcon = NtUserFindExistingCursorIcon(hinst, (HRSRC)hfRes, 0, 0); + hIcon = NtUserFindExistingCursorIcon(hinst, (HRSRC)hfRes, width, height); if (hIcon) return hIcon; } @@ -121,11 +128,13 @@ * Find the best fitting in the IconResDir for this resolution */
- id = LookupIconIdFromDirectoryEx((PBYTE)IconResDir, TRUE, 32, 32, + id = LookupIconIdFromDirectoryEx((PBYTE)IconResDir, Icon, width, height, fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME)); + + h2Resource = FindResourceW(hinst, MAKEINTRESOURCEW(id), + Icon ? MAKEINTRESOURCEW(RT_ICON) : + MAKEINTRESOURCEW(RT_CURSOR));
- h2Resource = FindResourceW(hinst, MAKEINTRESOURCEW(id), MAKEINTRESOURCEW(RT_CURSOR)); - hResource = LoadResource(hinst, h2Resource); if (hResource == NULL) return NULL; @@ -136,7 +145,7 @@
hIcon = CreateIconFromResourceEx((PBYTE)ResIcon, SizeofResource(hinst, h2Resource), - FALSE, 0x00030000, 32, 32, + Icon, 0x00030000, width, height, fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME)); if (hIcon && 0 != (fuLoad & LR_SHARED)) { @@ -147,9 +156,17 @@ return hIcon; }
+ /* + * FIXME: This code is incorrect and is likely to crash in many cases. + * In the file the cursor/icon directory records are stored like + * CURSORICONFILEDIR, but we treat them like CURSORICONDIR. In Wine + * this is solved by creating a fake cursor/icon directory in memory + * and passing that to CURSORICON_FindBestIcon. + */ + if (fuLoad & LR_SHARED) { - DbgPrint("FIXME: need LR_SHARED support for loading cursor images from files\n"); + DbgPrint("FIXME: need LR_SHARED support for loading icon images from files\n"); }
hFile = CreateFileW(lpszName, GENERIC_READ, FILE_SHARE_READ, NULL, @@ -174,14 +191,13 @@ 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); + /* 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; }
@@ -201,9 +217,10 @@ }
/* Pick the best size. */ - dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon(IconDIR, 32, 32, ColorBits); + dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon(IconDIR, width, height, ColorBits); if (!dirEntry) { + DeleteDC(hScreenDc); UnmapViewOfFile(IconDIR); return NULL; } @@ -211,165 +228,11 @@ SafeIconImage = RtlAllocateHeap(GetProcessHeap(), 0, dirEntry->dwBytesInRes); if (SafeIconImage == NULL) { + DeleteDC(hScreenDc); 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) - return NULL; - - if (fuLoad & LR_SHARED) - { - hIcon = NtUserFindExistingCursorIcon(hinst, (HRSRC)hfRes, width, height); - 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, width, height, - fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME)); - - h2Resource = FindResourceW(hinst, MAKEINTRESOURCEW(id), MAKEINTRESOURCEW(RT_ICON)); - - hResource = LoadResource(hinst, h2Resource); - if (hResource == NULL) - return NULL; - - ResIcon = LockResource(hResource); - if (ResIcon == NULL) - return NULL; - - hIcon = CreateIconFromResourceEx((PBYTE)ResIcon, - SizeofResource(hinst, h2Resource), - TRUE, 0x00030000, width, height, - fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME)); - if (hIcon && 0 != (fuLoad & LR_SHARED)) - { - NtUserSetCursorIconData((HICON)hIcon, NULL, NULL, hinst, (HRSRC)hfRes, - (HRSRC)NULL); - } - - return hIcon; - } - - /* - * FIXME: This code is incorrect and is likely to crash in many cases. - * In the file the cursor/icon directory records are stored like - * CURSORICONFILEDIR, but we treat them like CURSORICONDIR. In Wine - * this is solved by creating a fake cursor/icon directory in memory - * and passing that to CURSORICON_FindBestIcon. - */ - - if (fuLoad & LR_SHARED) - { - DbgPrint("FIXME: need LR_SHARED support for loading icon 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; - } - - /* Pick the best size. */ - dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon(IconDIR, width, height, 1); - 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);
@@ -394,16 +257,6 @@ /* Make data point to the start of the XOR image data. */ 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); RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage); DeleteDC(hScreenDc); @@ -552,9 +405,9 @@ case IMAGE_BITMAP: return LoadBitmapImage(hinst, lpszName, fuLoad); case IMAGE_CURSOR: - return LoadCursorImage(hinst, lpszName, fuLoad); case IMAGE_ICON: - return LoadIconImage(hinst, lpszName, cxDesired, cyDesired, fuLoad); + return LoadCursorIconImage(hinst, lpszName, cxDesired, cyDesired, + fuLoad, uType); default: break; }