+
+HANDLE STATIC
+LoadCursorImage(HINSTANCE hinst, LPCWSTR lpszName, UINT fuLoad)
+{
+ HANDLE hResource;
+ HANDLE h2Resource;
+ HANDLE hFile;
+ HANDLE hSection;
+ CURSORICONDIR* IconDIR;
+ HDC hScreenDc;
+ HANDLE hIcon;
+ ULONG HeaderSize;
+ ULONG ColourCount;
+ PVOID Data;
+ CURSORICONDIRENTRY* dirEntry;
+ ICONIMAGE* SafeIconImage;
+ GRPCURSORICONDIR* IconResDir;
+ INT id;
+ ICONIMAGE *ResIcon;
+
+ if (fuLoad & LR_SHARED)
+ DbgPrint("FIXME: need LR_SHARED support Loading cursor images\n");
+
+ if (!(fuLoad & LR_LOADFROMFILE))
+ {
+ if (hinst == NULL)
+ {
+ hinst = GetModuleHandleW(L"USER32");
+ }
+ hResource = FindResourceW(hinst, lpszName, RT_GROUP_CURSOR);
+ if (hResource == NULL)
+ {
+ return(NULL);
+ }
+
+ 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);
+ }
+ return CreateIconFromResourceEx((PBYTE) ResIcon,
+ SizeofResource(hinst, h2Resource), FALSE, 0x00030000,
+ 32, 32, fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
+ }
+ else
+ {
+ 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);
+ }
+
+ //pick the best size.
+ dirEntry = (CURSORICONDIRENTRY *) CURSORICON_FindBestIcon( IconDIR, 32, 32, 1);
+
+
+ if (!dirEntry)
+ {
+ if (fuLoad & LR_LOADFROMFILE)
+ {
+ UnmapViewOfFile(IconDIR);
+ }
+ return(NULL);
+ }
+
+ SafeIconImage = RtlAllocateHeap(RtlGetProcessHeap(), 0, dirEntry->dwBytesInRes);
+
+ memcpy(SafeIconImage, ((PBYTE)IconDIR) + dirEntry->dwImageOffset, dirEntry->dwBytesInRes);
+ }
+
+ //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;
+ ColourCount = (Core->bcBitCount <= 8) ? (1 << Core->bcBitCount) : 0;
+ HeaderSize = sizeof(BITMAPCOREHEADER) + ColourCount * sizeof(RGBTRIPLE);
+ }
+ else
+ {
+ ColourCount = SafeIconImage->icHeader.biClrUsed;
+ if (ColourCount == 0 && SafeIconImage->icHeader.biBitCount <= 8)
+ {
+ ColourCount = 1 << SafeIconImage->icHeader.biBitCount;
+ }
+ HeaderSize = sizeof(BITMAPINFOHEADER) + ColourCount * sizeof(RGBQUAD);
+ }
+
+ //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(RtlGetProcessHeap(), 0, SafeIconImage);
+ UnmapViewOfFile(IconDIR);
+ }
+ return(NULL);
+ }
+
+ hIcon = ICON_CreateIconFromData(hScreenDc, Data, SafeIconImage, 32, 32, dirEntry->Info.cursor.wXHotspot, dirEntry->Info.cursor.wYHotspot);
+ RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage);
+ return hIcon;
+}
+
+
+HANDLE STATIC
+LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuLoad)
+{
+ HANDLE hResource;
+ HANDLE h2Resource;
+ HANDLE hFile;
+ HANDLE hSection;
+ CURSORICONDIR* IconDIR;
+ HDC hScreenDc;
+ HANDLE hIcon;
+ ULONG HeaderSize;
+ ULONG ColourCount;
+ PVOID Data;
+ CURSORICONDIRENTRY* dirEntry;
+ ICONIMAGE* SafeIconImage;
+ GRPCURSORICONDIR* IconResDir;
+ INT id;
+ ICONIMAGE *ResIcon;
+
+ if (fuLoad & LR_SHARED)
+ DbgPrint("FIXME: need LR_SHARED support Loading icon images\n");
+
+ if (!(fuLoad & LR_LOADFROMFILE))
+ {
+ if (hinst == NULL)
+ {
+ hinst = GetModuleHandleW(L"USER32");
+ }
+ hResource = FindResourceW(hinst, lpszName, RT_GROUP_ICON);
+ if (hResource == NULL)
+ {
+ return(NULL);
+ }
+
+ 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);
+ }
+ return CreateIconFromResourceEx((PBYTE) ResIcon,
+ SizeofResource(hinst, h2Resource), TRUE, 0x00030000,
+ width, height, fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
+ }
+ else
+ {
+ 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);
+ }
+
+ //pick the best size.
+ dirEntry = (CURSORICONDIRENTRY *) CURSORICON_FindBestIcon( IconDIR, width, height, 1);
+
+
+ if (!dirEntry)
+ {
+ if (fuLoad & LR_LOADFROMFILE)
+ {
+ UnmapViewOfFile(IconDIR);
+ }
+ return(NULL);
+ }
+
+ SafeIconImage = RtlAllocateHeap(RtlGetProcessHeap(), 0, dirEntry->dwBytesInRes);
+
+ memcpy(SafeIconImage, ((PBYTE)IconDIR) + dirEntry->dwImageOffset, dirEntry->dwBytesInRes);
+ }
+
+ //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;
+ ColourCount = (Core->bcBitCount <= 8) ? (1 << Core->bcBitCount) : 0;
+ HeaderSize = sizeof(BITMAPCOREHEADER) + ColourCount * sizeof(RGBTRIPLE);
+ }
+ else
+ {
+ ColourCount = SafeIconImage->icHeader.biClrUsed;
+ if (ColourCount == 0 && SafeIconImage->icHeader.biBitCount <= 8)
+ {
+ ColourCount = 1 << SafeIconImage->icHeader.biBitCount;
+ }
+ HeaderSize = sizeof(BITMAPINFOHEADER) + ColourCount * sizeof(RGBQUAD);
+ }
+
+ //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(RtlGetProcessHeap(), 0, SafeIconImage);
+ UnmapViewOfFile(IconDIR);
+ }
+ return(NULL);
+ }
+
+ hIcon = ICON_CreateIconFromData(hScreenDc, Data, SafeIconImage, width, height, width/2, height/2);
+ RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage);
+ return hIcon;
+}
+
+