Patch by Jonathon Wilson: Implemented loading cursors with LoadImage()

svn path=/trunk/; revision=5702
This commit is contained in:
Thomas Bluemel 2003-08-20 14:08:19 +00:00
parent 545e6f33fb
commit f8dadc910b
5 changed files with 251 additions and 54 deletions

View file

@ -15,27 +15,50 @@ typedef struct _ICONIMAGE
BYTE icAND[1]; // DIB bits for AND mask
} ICONIMAGE, *LPICONIMAGE __attribute__((packed));
typedef struct _CURSORIMAGE
{
BITMAPINFOHEADER icHeader; // DIB header
RGBQUAD icColors[1]; // Color table
BYTE icXOR[1]; // DIB bits for XOR mask
BYTE icAND[1]; // DIB bits for AND mask
} CURSORIMAGE, *LPCURSORIMAGE __attribute__((packed));
typedef struct
{
BYTE bWidth;
BYTE bHeight;
BYTE bColorCount;
BYTE bReserved;
} ICONRESDIR __attribute__((packed));
typedef struct
{
WORD wWidth;
WORD wHeight;
} CURSORRESDIR __attribute__((packed));
typedef struct
{
WORD wPlanes; // Number of Color Planes in the XOR image
WORD wBitCount; // Bits per pixel in the XOR image
} ICONDIR __attribute__((packed));
typedef struct
{
WORD wXHotspot; // Number of Color Planes in the XOR image
WORD wYHotspot; // Bits per pixel in the XOR image
} CURSORDIR __attribute__((packed));
typedef struct
{
BYTE bWidth; // Width, in pixels, of the icon image
BYTE bHeight; // Height, in pixels, of the icon image
BYTE bColorCount; // Number of colors in image (0 if >=8bpp)
BYTE bReserved; // Reserved ( must be 0)
} ICONDIR __attribute__((packed));
typedef struct
{
WORD wWidth; //Width, in pixels of the cursor image
WORD wHeight; //Hight, in pixles of the cursor image
} CURSORDIR __attribute__((packed));
typedef struct
{ union
union
{ ICONDIR icon;
CURSORDIR cursor;
} Info;
WORD wPlanes; // Number of Color Planes in the XOR image
WORD wBitCount; // Bits per pixel in the XOR image
DWORD dwBytesInRes; // How many bytes in this resource?
DWORD dwImageOffset; // Where in the file is this image?
} CURSORICONDIRENTRY __attribute__((packed));
@ -49,23 +72,24 @@ typedef struct
} CURSORICONDIR __attribute__((packed));
typedef struct
{ union
{ ICONDIR icon;
CURSORDIR cursor;
} Info;
WORD wPlanes; // Color Planes
WORD wBitCount; // Bits per pixel
DWORD dwBytesInRes; // how many bytes in this resource?
WORD nID; // the ID
} GRPICONDIRENTRY __attribute__((packed));
{
union
{ ICONRESDIR icon;
CURSORRESDIR cursor;
} ResInfo;
WORD wPlanes; // Color Planes
WORD wBitCount; // Bits per pixel
DWORD dwBytesInRes; // how many bytes in this resource?
WORD nID; // the ID
} GRPCURSORICONDIRENTRY __attribute__((packed));
typedef struct
{
WORD idReserved; // Reserved (must be 0)
WORD idType; // Resource type (1 for icons)
WORD idCount; // How many images?
GRPICONDIRENTRY idEntries[1] __attribute__((packed)); // The entries for each image
} GRPICONDIR __attribute__((packed));
GRPCURSORICONDIRENTRY idEntries[1] __attribute__((packed)); // The entries for each image
} GRPCURSORICONDIR __attribute__((packed));
/* GDI logical Icon/Cursor object */
typedef struct _ICONCURSOROBJ

View file

@ -441,8 +441,7 @@ LockWindowUpdate@4
LockWorkStation@0
LookupIconIdFromDirectory@8
LookupIconIdFromDirectoryEx@20
;MBToWCSEx
;MB_GetString
MBToWCSEx@24
MapDialogRect@8
MapVirtualKeyA@8
MapVirtualKeyExA@12
@ -680,7 +679,7 @@ VkKeyScanA@4
VkKeyScanExA@8
VkKeyScanExW@8
VkKeyScanW@4
;WCSToMBEx
WCSToMBEx@24
;WINNLSEnableIME
;WINNLSGetEnableStatus
;WINNLSGetIMEHotkey

View file

@ -442,8 +442,7 @@ LockWindowUpdate=LockWindowUpdate@4
LockWorkStation=LockWorkStation@0
LookupIconIdFromDirectory=LookupIconIdFromDirectory@8
LookupIconIdFromDirectoryEx=LookupIconIdFromDirectoryEx@20
;MBToWCSEx
;MB_GetString
MBToWCSEx=MBToWCSEx@24
MapDialogRect=MapDialogRect@8
MapVirtualKeyA=MapVirtualKeyA@8
MapVirtualKeyExA=MapVirtualKeyExA@12
@ -684,7 +683,7 @@ VkKeyScanA=VkKeyScanA@4
VkKeyScanExA=VkKeyScanExA@8
VkKeyScanExW=VkKeyScanExW@8
VkKeyScanW=VkKeyScanW@4
;WCSToMBEx
WCSToMBEx=WCSToMBEx@24
;WINNLSEnableIME
;WINNLSGetEnableStatus
;WINNLSGetIMEHotkey

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: bitmap.c,v 1.12 2003/08/07 04:03:24 royce Exp $
/* $Id: bitmap.c,v 1.13 2003/08/20 14:08:18 weiden Exp $
*
* PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/input.c
@ -35,8 +35,9 @@
#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);
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 *****************************************************************/
@ -76,8 +77,166 @@ LoadImageA(HINSTANCE hinst,
HANDLE STATIC
LoadCursorImage(HINSTANCE hinst, LPCWSTR lpszName, UINT fuLoad)
{
DbgPrint("FIXME: Need support for loading cursor images.\n");
return(NULL);
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_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), 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;
}
@ -96,7 +255,7 @@ LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuL
PVOID Data;
CURSORICONDIRENTRY* dirEntry;
ICONIMAGE* SafeIconImage;
GRPICONDIR* IconResDir;
GRPCURSORICONDIR* IconResDir;
INT id;
ICONIMAGE *ResIcon;
@ -241,7 +400,7 @@ LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuL
return(NULL);
}
hIcon = ICON_CreateIconFromData(hScreenDc, Data, SafeIconImage, width, height);
hIcon = ICON_CreateIconFromData(hScreenDc, Data, SafeIconImage, width, height, width/2, height/2);
RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage);
return hIcon;
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: icon.c,v 1.8 2003/08/19 11:48:49 weiden Exp $
/* $Id: icon.c,v 1.9 2003/08/20 14:08:19 weiden Exp $
*
* PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/icon.c
@ -37,7 +37,7 @@
/* FUNCTIONS *****************************************************************/
HICON
ICON_CreateIconFromData(HDC hDC, PVOID ImageData, ICONIMAGE* IconImage, int cxDesired, int cyDesired)
ICON_CreateIconFromData(HDC hDC, PVOID ImageData, ICONIMAGE* IconImage, int cxDesired, int cyDesired, int xHotspot, int yHotspot)
{
HANDLE hXORBitmap;
HANDLE hANDBitmap;
@ -87,8 +87,8 @@ ICON_CreateIconFromData(HDC hDC, PVOID ImageData, ICONIMAGE* IconImage, int cxDe
RtlFreeHeap(RtlGetProcessHeap(), 0, bwBIH);
IconInfo.fIcon = TRUE;
IconInfo.xHotspot = cxDesired/2;
IconInfo.yHotspot = cyDesired/2;
IconInfo.xHotspot = xHotspot;
IconInfo.yHotspot = yHotspot;
IconInfo.hbmColor = hXORBitmap;
IconInfo.hbmMask = hANDBitmap;
@ -179,8 +179,24 @@ CreateIconFromResourceEx(
ULONG ColourCount;
PVOID Data;
HDC hScreenDc;
WORD wXHotspot;
WORD wYHotspot;
DPRINT("fIcon, dwVersion, cxDesired, cyDesired are all ignored in this implementation!\n");
DPRINT("dwVersion, cxDesired, cyDesired are all ignored in this implementation!\n");
if (!fIcon)
{
wXHotspot = (WORD)*pbIconBits;
pbIconBits+=2;
wYHotspot = (WORD)*pbIconBits;
pbIconBits+=2;
cbIconBits-=4;
}
else
{
wXHotspot = cxDesired / 2;
wYHotspot = cyDesired / 2;
}
//get an safe copy of the icon data
SafeIconImage = RtlAllocateHeap(RtlGetProcessHeap(), 0, cbIconBits);
@ -213,7 +229,7 @@ CreateIconFromResourceEx(
return(NULL);
}
hIcon = ICON_CreateIconFromData(hScreenDc, Data, SafeIconImage, cxDesired, cyDesired);
hIcon = ICON_CreateIconFromData(hScreenDc, Data, SafeIconImage, cxDesired, cyDesired, wXHotspot, wYHotspot);
RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage);
return hIcon;
}
@ -497,8 +513,8 @@ CURSORICON_FindBestCursor( CURSORICONDIR *dir, int width, int height, int colors
iColorDiff = 0xFFFFFFFF;
for (i = 0, entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++)
{
iTempXDiff = abs(width - entry->Info.icon.bWidth);
iTempYDiff = abs(height - entry->Info.icon.bHeight);
iTempXDiff = abs(width - entry->bWidth);
iTempYDiff = abs(height - entry->bHeight);
if(iTotalDiff > (iTempXDiff + iTempYDiff))
{
@ -511,10 +527,10 @@ CURSORICON_FindBestCursor( CURSORICONDIR *dir, int width, int height, int colors
/* Find Best Colors for Best Fit */
for (i = 0, entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++)
{
if(abs(width - entry->Info.icon.bWidth) == (int) iXDiff &&
abs(height - entry->Info.icon.bHeight) == (int) iYDiff)
if(abs(width - entry->bWidth) == (int) iXDiff &&
abs(height - entry->bHeight) == (int) iYDiff)
{
iTempColorDiff = abs(colors - entry->Info.icon.bColorCount);
iTempColorDiff = abs(colors - entry->bColorCount);
if(iColorDiff > iTempColorDiff)
{
@ -549,9 +565,9 @@ CURSORICON_FindBestIcon( CURSORICONDIR *dir, int width, int height, int colors)
iColorDiff = 0xFFFFFFFF;
for (i = 0, entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++)
{
iTempXDiff = abs(width - entry->Info.icon.bWidth);
iTempXDiff = abs(width - entry->bWidth);
iTempYDiff = abs(height - entry->Info.icon.bHeight);
iTempYDiff = abs(height - entry->bHeight);
if(iTotalDiff > (iTempXDiff + iTempYDiff))
{
@ -564,10 +580,10 @@ CURSORICON_FindBestIcon( CURSORICONDIR *dir, int width, int height, int colors)
/* Find Best Colors for Best Fit */
for (i = 0, entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++)
{
if(abs(width - entry->Info.icon.bWidth) == (int) iXDiff &&
abs(height - entry->Info.icon.bHeight) == (int) iYDiff)
if(abs(width - entry->bWidth) == (int) iXDiff &&
abs(height - entry->bHeight) == (int) iYDiff)
{
iTempColorDiff = abs(colors - entry->Info.icon.bColorCount);
iTempColorDiff = abs(colors - entry->bColorCount);
if(iColorDiff > iTempColorDiff)
{
bestEntry = entry;
@ -592,12 +608,12 @@ LookupIconIdFromDirectoryEx(
int cyDesired,
UINT Flags)
{
GRPICONDIR *dir = (GRPICONDIR*)presbits;
GRPCURSORICONDIR *dir = (GRPCURSORICONDIR*)presbits;
UINT retVal = 0;
if( dir && !dir->idReserved && (dir->idType & 3) )
{
GRPICONDIRENTRY* entry;
GRPCURSORICONDIRENTRY* entry;
HDC hdc;
UINT palEnts;
int colors;
@ -612,7 +628,7 @@ LookupIconIdFromDirectoryEx(
ReleaseDC(0, hdc);
entry = (GRPICONDIRENTRY*)CURSORICON_FindBestIcon( (CURSORICONDIR*)dir,
entry = (GRPCURSORICONDIRENTRY*)CURSORICON_FindBestIcon( (CURSORICONDIR*)dir,
cxDesired,
cyDesired,
colors );