Handle = LoadImageW(hinst, (LPCWSTR)lpszName, uType, cxDesired,
cyDesired, fuLoad);
}
-
+
return 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 h2Resource;
HANDLE hSection;
CURSORICONDIR *IconDIR;
HDC hScreenDc;
- HANDLE hIcon;
+ HICON hIcon;
ULONG HeaderSize;
ULONG ColorCount;
+ ULONG ColorBits;
PVOID Data;
CURSORICONDIRENTRY* dirEntry;
- ICONIMAGE* SafeIconImage;
+ ICONIMAGE* SafeIconImage = NULL;
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 = (HANDLE)NtUserFindExistingCursorIcon(hinst, (HRSRC)hfRes, 0, 0);
+ hIcon = NtUserFindExistingCursorIcon(hinst, (HRSRC)hfRes, width, height);
if (hIcon)
return hIcon;
}
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));
+ /*
+ * Find the best fitting in the IconResDir for this resolution
+ */
+
+ id = LookupIconIdFromDirectoryEx((PBYTE)IconResDir, Icon, width, height,
+ fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
h2Resource = FindResourceW(hinst, MAKEINTRESOURCEW(id),
- MAKEINTRESOURCEW(RT_CURSOR));
+ Icon ? MAKEINTRESOURCEW(RT_ICON) :
+ MAKEINTRESOURCEW(RT_CURSOR));
+ if (h2Resource == NULL)
+ return NULL;
hResource = LoadResource(hinst, h2Resource);
if (hResource == NULL)
if (ResIcon == NULL)
return NULL;
- hIcon = (HANDLE)CreateIconFromResourceEx((PBYTE)ResIcon,
- SizeofResource(hinst, h2Resource), FALSE, 0x00030000,
- 32, 32, fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
+ hIcon = CreateIconFromResourceEx((PBYTE)ResIcon,
+ SizeofResource(hinst, h2Resource),
+ Icon, 0x00030000, width, height,
+ fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
if (hIcon && 0 != (fuLoad & LR_SHARED))
{
NtUserSetCursorIconData((HICON)hIcon, NULL, NULL, hinst, (HRSRC)hfRes,
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 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,
OPEN_EXISTING, 0, NULL);
- if (hFile == NULL)
+ if (hFile == INVALID_HANDLE_VALUE)
return NULL;
hSection = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
return NULL;
}
- /*
- * Get a handle to the screen dc, the icon we create is going to be
- * compatable with it.
- */
- hScreenDc = CreateCompatibleDC(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;
}
}
/* 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;
}
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);
/* 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 = CreateDCW(L"DISPLAY", 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);
return hIcon;
}
{
hFile = CreateFileW(lpszName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, NULL);
- if (hFile == NULL)
+ if (hFile == INVALID_HANDLE_VALUE)
return NULL;
hSection = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
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;
}
-
+
return NULL;
}
return CopyCursor(hnd);
}
}
-
+
return NULL;
}