[8/10] user: Fix loading of .cur cursors
H. Verbeet
hverbeet at gmail.com
Sat Aug 5 16:40:28 CDT 2006
- When loading a cursor, the hotspot should be scaled as well as the image.
- Allow multicolor cursors
- Don't use CreateIconFromResourceEx() to load .cur cursors, it
doesn't handle the hotspot correctly. Instead, use load_cursor_frame()
directly.
-------------- next part --------------
diff --git a/dlls/user/cursoricon.c b/dlls/user/cursoricon.c
index 4b498da..6fe12b0 100644
--- a/dlls/user/cursoricon.c
+++ b/dlls/user/cursoricon.c
@@ -1050,6 +1050,13 @@ static BOOL load_cursor_frame( LPBYTE bi
DoStretch = (bmi->bmiHeader.biHeight/2 != height) ||
(bmi->bmiHeader.biWidth != width);
+ /* Scale the hotspot */
+ if (DoStretch && hotspot.x != ICON_HOTSPOT && hotspot.y != ICON_HOTSPOT)
+ {
+ hotspot.x = (hotspot.x * width) / bmi->bmiHeader.biWidth;
+ hotspot.y = (hotspot.y * height) / (bmi->bmiHeader.biWidth / 2);
+ }
+
if (!screen_dc) screen_dc = CreateDCW( DISPLAYW, NULL, NULL, NULL );
if (screen_dc)
{
@@ -1075,14 +1082,7 @@ static BOOL load_cursor_frame( LPBYTE bi
/* Create the XOR bitmap */
if (DoStretch) {
- if(bIcon)
- {
- hXorBits = CreateCompatibleBitmap(screen_dc, width, height);
- }
- else
- {
- hXorBits = CreateBitmap(width, height, 1, 1, NULL);
- }
+ hXorBits = CreateCompatibleBitmap(screen_dc, width, height);
if(hXorBits)
{
HBITMAP hOld;
@@ -1250,9 +1250,11 @@ static HICON CURSORICON_LoadFromFile( LP
BOOL fCursor, UINT loadflags)
{
CURSORICONFILEDIRENTRY *entry;
+ cursor_frame_t frame = {0};
CURSORICONFILEDIR *dir;
DWORD filesize = 0;
HICON hIcon = 0;
+ POINT16 hotspot;
LPBYTE bits;
TRACE("loading %s\n", debugstr_w( filename ));
@@ -1261,6 +1263,12 @@ static HICON CURSORICON_LoadFromFile( LP
if (!bits)
return hIcon;
+ /* If the data contains the magic for an .ICO it's an .ICO,
+ * regardless of what fCursor says. */
+ if (!memcmp( bits, "\x00\x00\x01\x00", 4 )) fCursor = FALSE;
+ /* Same thing for .CUR */
+ else if (!memcmp( bits, "\x00\x00\x02\x00", 4 )) fCursor = TRUE;
+
dir = (CURSORICONFILEDIR*) bits;
if ( filesize < sizeof(*dir) )
goto end;
@@ -1269,7 +1277,7 @@ static HICON CURSORICON_LoadFromFile( LP
goto end;
if ( fCursor )
- entry = CURSORICON_FindBestCursorFile( dir, width, height, 1 );
+ entry = CURSORICON_FindBestCursorFile( dir, width, height, colors );
else
entry = CURSORICON_FindBestIconFile( dir, width, height, colors );
@@ -1282,8 +1290,23 @@ static HICON CURSORICON_LoadFromFile( LP
if ( entry->dwDIBOffset + entry->dwDIBSize > filesize )
goto end;
- hIcon = CreateIconFromResourceEx( &bits[entry->dwDIBOffset], entry->dwDIBSize,
- !fCursor, 0x00030000, width, height, loadflags );
+ if ( fCursor )
+ {
+ hotspot.x = entry->xHotspot;
+ hotspot.y = entry->yHotspot;
+ }
+ else
+ {
+ hotspot.x = ICON_HOTSPOT;
+ hotspot.y = ICON_HOTSPOT;
+ }
+
+ hIcon = create_cursor( 1, 0 );
+ load_cursor_frame( &bits[entry->dwDIBOffset], entry->dwDIBSize, hotspot,
+ 0x00030000, width, height, loadflags, &frame );
+ set_cursor_frame( hIcon, 0, &frame );
+ HeapFree( GetProcessHeap(), 0, frame.bits );
+
end:
TRACE("loaded %s -> %p\n", debugstr_w( filename ), hIcon );
UnmapViewOfFile( bits );
More information about the wine-patches
mailing list