#include <windows.h>
#include <user32.h>
#include <debug.h>
+#include <stdlib.h>
+
+/*forward declerations... actualy in user32\windows\icon.c but usful here****/
+HICON ICON_CreateIconFromData(HDC hDC, PVOID ImageData, ICONIMAGE* IconImage, int cxDesired, int cyDesired, int xHotspot, int yHotspot);
+CURSORICONDIRENTRY *CURSORICON_FindBestIcon( CURSORICONDIR *dir, int width, int height, int colors);
+CURSORICONDIRENTRY *CURSORICON_FindBestCursor( CURSORICONDIR *dir, int width, int height, int colors);
+
/* FUNCTIONS *****************************************************************/
+/*
+ * @implemented
+ */
HANDLE STDCALL
LoadImageA(HINSTANCE hinst,
LPCSTR lpszName,
}
else
{
- Handle = LoadImageW(hinst, lpszWName, uType, cxDesired,
+ Handle = LoadImageW(hinst, (LPCWSTR)lpszName, uType, cxDesired,
cyDesired, fuLoad);
}
return(Handle);
}
+
+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;
+}
+
+
HANDLE STATIC
LoadBitmapImage(HINSTANCE hInstance, LPCWSTR lpszName, UINT fuLoad)
{
{
if (hInstance == NULL)
{
- hInstance = GetModuleHandle(L"USER32");
+ hInstance = GetModuleHandleW(L"USER32");
}
hResource = FindResourceW(hInstance, lpszName, RT_BITMAP);
if (hResource == NULL)
}
else
{
- hFile = CreateFile(lpszName,
+ hFile = CreateFileW(lpszName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
{
return(NULL);
}
- hSection = CreateFileMapping(hFile,
+ hSection = CreateFileMappingW(hFile,
NULL,
PAGE_READONLY,
0,
{
return(NULL);
}
- BitmapInfo = MapViewOfFile(hSection,
+ BitmapInfo = MapViewOfFile(hSection,
FILE_MAP_READ,
- 0,
+ 0,
0,
0);
CloseHandle(hSection);
{
return(NULL);
}
+ /* offset BitmapInfo by 14 bytes to acount for the size of BITMAPFILEHEADER
+ unfortunatly sizeof(BITMAPFILEHEADER) = 16, but the acutal size should be 14!
+ */
+ BitmapInfo = (BITMAPINFO*)(((PBYTE)BitmapInfo) + 14);
}
if (BitmapInfo->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
}
case IMAGE_CURSOR:
{
- DbgPrint("FIXME: Need support for loading cursors.\n");
- return(NULL);
+ return(LoadCursorImage(hinst, lpszName, fuLoad));
+ }
+ case IMAGE_ICON:
+ {
+ return(LoadIconImage(hinst, lpszName, cxDesired, cyDesired, fuLoad));
}
default:
DbgBreakPoint();
}
+/*
+ * @implemented
+ */
HBITMAP STDCALL
LoadBitmapA(HINSTANCE hInstance, LPCSTR lpBitmapName)
{
return(LoadImageA(hInstance, lpBitmapName, IMAGE_BITMAP, 0, 0, 0));
}
+
+/*
+ * @implemented
+ */
HBITMAP STDCALL
LoadBitmapW(HINSTANCE hInstance, LPCWSTR lpBitmapName)
{