3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * PROJECT: ReactOS user32.dll
22 * FILE: lib/user32/windows/input.c
24 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
26 * 09-05-2001 CSH Created
29 /* INCLUDES ******************************************************************/
33 #include <wine/debug.h>
34 WINE_DEFAULT_DEBUG_CHANNEL(user32
);
47 } CURSORICONFILEDIRENTRY
;
54 CURSORICONFILEDIRENTRY idEntries
[1];
59 /* forward declarations... actually in user32\windows\icon.c but useful here */
60 HICON
ICON_CreateIconFromData(HDC hDC
, PVOID ImageData
, ICONIMAGE
* IconImage
, int cxDesired
, int cyDesired
, int xHotspot
, int yHotspot
);
61 CURSORICONDIRENTRY
*CURSORICON_FindBestIcon( CURSORICONDIR
*dir
, int width
, int height
, int colors
);
62 CURSORICONDIRENTRY
*CURSORICON_FindBestCursor( CURSORICONDIR
*dir
, int width
, int height
, int colors
);
64 /* FUNCTIONS *****************************************************************/
70 LoadImageA(HINSTANCE hinst
,
79 UNICODE_STRING NameString
;
83 RtlCreateUnicodeStringFromAsciiz(&NameString
, (LPSTR
)lpszName
);
84 lpszWName
= NameString
.Buffer
;
85 Handle
= LoadImageW(hinst
, lpszWName
, uType
, cxDesired
,
87 RtlFreeUnicodeString(&NameString
);
91 Handle
= LoadImageW(hinst
, (LPCWSTR
)lpszName
, uType
, cxDesired
,
100 * The following macro functions account for the irregularities of
101 * accessing cursor and icon resources in files and resource entries.
103 typedef BOOL (*fnGetCIEntry
)( LPVOID dir
, int n
,
104 int *width
, int *height
, int *bits
);
106 /**********************************************************************
107 * CURSORICON_FindBestCursor2
109 * Find the cursor closest to the requested size.
110 * FIXME: parameter 'color' ignored and entries with more than 1 bpp
113 static int CURSORICON_FindBestCursor2( LPVOID dir
, fnGetCIEntry get_entry
,
114 int width
, int height
, int color
)
116 int i
, maxwidth
, maxheight
, cx
, cy
, bits
, bestEntry
= -1;
118 /* Double height to account for AND and XOR masks */
122 /* First find the largest one smaller than or equal to the requested size*/
124 maxwidth
= maxheight
= 0;
125 for ( i
= 0; get_entry( dir
, i
, &cx
, &cy
, &bits
); i
++ )
127 if ((cx
<= width
) && (cy
<= height
) &&
128 (cx
> maxwidth
) && (cy
> maxheight
) &&
136 if (bestEntry
!= -1) return bestEntry
;
138 /* Now find the smallest one larger than the requested size */
140 maxwidth
= maxheight
= 255;
141 for ( i
= 0; get_entry( dir
, i
, &cx
, &cy
, &bits
); i
++ )
143 if (((cx
< maxwidth
) && (cy
< maxheight
) && (bits
== 1)) ||
155 static BOOL
CURSORICON_GetFileEntry( LPVOID dir
, int n
,
156 int *width
, int *height
, int *bits
)
158 CURSORICONFILEDIR
*filedir
= dir
;
159 CURSORICONFILEDIRENTRY
*entry
;
161 if ( filedir
->idCount
<= n
)
163 entry
= &filedir
->idEntries
[n
];
164 *width
= entry
->bWidth
;
165 *height
= entry
->bHeight
;
166 *bits
= entry
->bColorCount
;
170 static CURSORICONFILEDIRENTRY
*CURSORICON_FindBestCursorFile( CURSORICONFILEDIR
*dir
,
171 int width
, int height
, int color
)
173 int n
= CURSORICON_FindBestCursor2( dir
, CURSORICON_GetFileEntry
,
174 width
, height
, color
);
177 return &dir
->idEntries
[n
];
193 CURSORICONFILEDIR
*IconDIR
;
200 CURSORICONFILEDIRENTRY
* dirEntry
;
201 ICONIMAGE
* SafeIconImage
= NULL
;
202 GRPCURSORICONDIR
* IconResDir
;
205 BOOL Icon
= (uType
== IMAGE_ICON
);
208 if (!(fuLoad
& LR_LOADFROMFILE
))
211 hinst
= User32Instance
;
213 hResInfo
= FindResourceW(hinst
, lpszName
,
214 Icon
? RT_GROUP_ICON
: RT_GROUP_CURSOR
);
215 if (hResInfo
== NULL
)
218 hResource
= LoadResource(hinst
, hResInfo
);
219 if (hResource
== NULL
)
222 IconResDir
= LockResource(hResource
);
223 if (IconResDir
== NULL
)
228 /* Find the best fitting in the IconResDir for this resolution */
229 id
= LookupIconIdFromDirectoryEx((PBYTE
)IconResDir
, Icon
, width
, height
,
230 fuLoad
& (LR_DEFAULTCOLOR
| LR_MONOCHROME
));
232 hResInfo
= FindResourceW(hinst
, MAKEINTRESOURCEW(id
),
233 Icon
? (LPCWSTR
) RT_ICON
:
234 (LPCWSTR
) RT_CURSOR
);
235 if (hResInfo
== NULL
)
240 /* Now we have found the icon we want to load.
241 * Let's see if we already loaded it */
242 if (fuLoad
& LR_SHARED
)
244 hIcon
= NtUserFindExistingCursorIcon(hinst
, hResInfo
, 0, 0);
250 TRACE("Didn't find the shared icon!!\n");
253 hResource
= LoadResource(hinst
, hResInfo
);
254 if (hResource
== NULL
)
259 ResIcon
= LockResource(hResource
);
265 hIcon
= CreateIconFromResourceEx((PBYTE
)ResIcon
,
266 SizeofResource(hinst
, hResInfo
),
267 Icon
, 0x00030000, width
, height
,
268 (fuLoad
& (LR_DEFAULTSIZE
| LR_SHARED
)) | LR_DEFAULTCOLOR
);
270 if (hIcon
&& 0 != (fuLoad
& LR_SHARED
))
273 NtUserSetCursorIconData((HICON
)hIcon
, NULL
, NULL
, hinst
, hResInfo
,
278 if(NtUserGetIconInfo(ResIcon
, &iconInfo
, NULL
, NULL
, NULL
, FALSE
))
279 NtUserSetCursorIconData((HICON
)hIcon
, hinst
, NULL
, &iconInfo
);
286 if (fuLoad
& LR_SHARED
)
288 FIXME("Need LR_SHARED support for loading icon images from files\n");
291 hFile
= CreateFileW(lpszName
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
292 OPEN_EXISTING
, 0, NULL
);
293 if (hFile
== INVALID_HANDLE_VALUE
)
296 hSection
= CreateFileMappingW(hFile
, NULL
, PAGE_READONLY
, 0, 0, NULL
);
297 filesize
= GetFileSize( hFile
, NULL
);
299 if (hSection
== NULL
)
302 IconDIR
= MapViewOfFile(hSection
, FILE_MAP_READ
, 0, 0, 0);
303 CloseHandle(hSection
);
307 if (0 != IconDIR
->idReserved
||
308 (IMAGE_ICON
!= IconDIR
->idType
&& IMAGE_CURSOR
!= IconDIR
->idType
))
310 UnmapViewOfFile(IconDIR
);
314 /* Get a handle to the screen dc, the icon we create is going to be
315 * compatable with this. */
316 hScreenDc
= CreateDCW(NULL
, NULL
, NULL
, NULL
);
317 if (hScreenDc
== NULL
)
319 UnmapViewOfFile(IconDIR
);
320 RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage
);
324 if (fuLoad
& LR_MONOCHROME
)
330 ColorBits
= GetDeviceCaps(hScreenDc
, BITSPIXEL
);
333 * Remove this after proper support for alpha icons will be finished.
339 /* Pick the best size. */
340 dirEntry
= CURSORICON_FindBestCursorFile( IconDIR
, width
, height
, ColorBits
);
344 UnmapViewOfFile(IconDIR
);
348 if ( dirEntry
->dwDIBOffset
> filesize
)
351 UnmapViewOfFile(IconDIR
);
355 if ( dirEntry
->dwDIBOffset
+ dirEntry
->dwDIBSize
> filesize
){
357 UnmapViewOfFile(IconDIR
);
361 SafeIconImage
= RtlAllocateHeap(GetProcessHeap(), 0, dirEntry
->dwDIBSize
);
362 if (SafeIconImage
== NULL
)
365 UnmapViewOfFile(IconDIR
);
369 memcpy(SafeIconImage
, ((PBYTE
)IconDIR
) + dirEntry
->dwDIBOffset
, dirEntry
->dwDIBSize
);
370 UnmapViewOfFile(IconDIR
);
372 /* At this point we have a copy of the icon image to play with. */
374 SafeIconImage
->icHeader
.biHeight
= SafeIconImage
->icHeader
.biHeight
/2;
376 if (SafeIconImage
->icHeader
.biSize
== sizeof(BITMAPCOREHEADER
))
378 BITMAPCOREHEADER
* Core
= (BITMAPCOREHEADER
*)SafeIconImage
;
379 ColorCount
= (Core
->bcBitCount
<= 8) ? (1 << Core
->bcBitCount
) : 0;
380 HeaderSize
= sizeof(BITMAPCOREHEADER
) + ColorCount
* sizeof(RGBTRIPLE
);
384 ColorCount
= SafeIconImage
->icHeader
.biClrUsed
;
385 if (ColorCount
== 0 && SafeIconImage
->icHeader
.biBitCount
<= 8)
386 ColorCount
= 1 << SafeIconImage
->icHeader
.biBitCount
;
387 HeaderSize
= sizeof(BITMAPINFOHEADER
) + ColorCount
* sizeof(RGBQUAD
);
390 /* Make data point to the start of the XOR image data. */
391 Data
= (PBYTE
)SafeIconImage
+ HeaderSize
;
393 hIcon
= ICON_CreateIconFromData(hScreenDc
, Data
, SafeIconImage
, width
, height
, width
/2, height
/2);
394 RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage
);
402 LoadBitmapImage(HINSTANCE hInstance
, LPCWSTR lpszName
, UINT fuLoad
)
407 LPBITMAPINFO BitmapInfo
;
408 LPBITMAPINFO PrivateInfo
;
416 if (!(fuLoad
& LR_LOADFROMFILE
))
418 if (hInstance
== NULL
)
419 hInstance
= User32Instance
;
421 hResource
= FindResourceW(hInstance
, lpszName
, RT_BITMAP
);
422 if (hResource
== NULL
)
424 hResource
= LoadResource(hInstance
, hResource
);
425 if (hResource
== NULL
)
427 BitmapInfo
= LockResource(hResource
);
428 if (BitmapInfo
== NULL
)
433 hFile
= CreateFileW(lpszName
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
434 OPEN_EXISTING
, 0, NULL
);
435 if (hFile
== INVALID_HANDLE_VALUE
)
438 hSection
= CreateFileMappingW(hFile
, NULL
, PAGE_READONLY
, 0, 0, NULL
);
440 if (hSection
== NULL
)
443 BitmapInfo
= MapViewOfFile(hSection
, FILE_MAP_READ
, 0, 0, 0);
444 CloseHandle(hSection
);
445 if (BitmapInfo
== NULL
)
448 BitmapInfo
= (LPBITMAPINFO
)((ULONG_PTR
)BitmapInfo
+ sizeof(BITMAPFILEHEADER
));
451 HeaderSize
= BitmapInfo
->bmiHeader
.biSize
;
452 if (HeaderSize
== sizeof(BITMAPCOREHEADER
))
454 BITMAPCOREHEADER
* Core
= (BITMAPCOREHEADER
*)BitmapInfo
;
455 ColorCount
= (Core
->bcBitCount
<= 8) ? (1 << Core
->bcBitCount
) : 0;
456 HeaderSize
+= ColorCount
* sizeof(RGBTRIPLE
);
460 if (BitmapInfo
->bmiHeader
.biCompression
== BI_BITFIELDS
)
462 HeaderSize
+= 3 * sizeof(RGBQUAD
);
466 ColorCount
= BitmapInfo
->bmiHeader
.biClrUsed
;
467 if (ColorCount
== 0 && BitmapInfo
->bmiHeader
.biBitCount
<= 8)
468 ColorCount
= 1 << BitmapInfo
->bmiHeader
.biBitCount
;
469 HeaderSize
+= ColorCount
* sizeof(RGBQUAD
);
472 Data
= (PVOID
)((ULONG_PTR
)BitmapInfo
+ HeaderSize
);
474 PrivateInfo
= RtlAllocateHeap(GetProcessHeap(), 0, HeaderSize
);
475 if (PrivateInfo
== NULL
)
477 if (fuLoad
& LR_LOADFROMFILE
)
478 UnmapViewOfFile(BitmapInfo
);
484 memcpy(PrivateInfo
, BitmapInfo
, HeaderSize
);
486 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
494 ERR("We have a thread overrun, these are already freed! pi -> %d, bi -> %d\n", PrivateInfo
, BitmapInfo
);
495 RtlFreeHeap(GetProcessHeap(), 0, PrivateInfo
);
496 if (fuLoad
& LR_LOADFROMFILE
)
497 UnmapViewOfFile(BitmapInfo
);
501 /* FIXME: Handle color conversion and transparency. */
503 hScreenDc
= CreateCompatibleDC(NULL
);
504 if (hScreenDc
== NULL
)
506 RtlFreeHeap(GetProcessHeap(), 0, PrivateInfo
);
507 if (fuLoad
& LR_LOADFROMFILE
)
508 UnmapViewOfFile(BitmapInfo
);
512 if (fuLoad
& LR_CREATEDIBSECTION
)
516 hBitmap
= CreateDIBSection(hScreenDc
, PrivateInfo
, DIB_RGB_COLORS
, NULL
,
518 GetObjectA(hBitmap
, sizeof(DIBSECTION
), &Dib
);
519 SetDIBits(hScreenDc
, hBitmap
, 0, Dib
.dsBm
.bmHeight
, Data
, BitmapInfo
,
524 hBitmap
= CreateDIBitmap(hScreenDc
, &PrivateInfo
->bmiHeader
, CBM_INIT
,
525 Data
, PrivateInfo
, DIB_RGB_COLORS
);
528 RtlFreeHeap(GetProcessHeap(), 0, PrivateInfo
);
530 if (fuLoad
& LR_LOADFROMFILE
)
531 UnmapViewOfFile(BitmapInfo
);
545 if (fuLoad
& LR_DEFAULTSIZE
)
547 if (uType
== IMAGE_ICON
)
550 cxDesired
= GetSystemMetrics(SM_CXICON
);
552 cyDesired
= GetSystemMetrics(SM_CYICON
);
554 else if (uType
== IMAGE_CURSOR
)
557 cxDesired
= GetSystemMetrics(SM_CXCURSOR
);
559 cyDesired
= GetSystemMetrics(SM_CYCURSOR
);
566 return LoadBitmapImage(hinst
, lpszName
, fuLoad
);
569 return LoadCursorIconImage(hinst
, lpszName
, cxDesired
, cyDesired
,
583 LoadBitmapA(HINSTANCE hInstance
, LPCSTR lpBitmapName
)
585 return LoadImageA(hInstance
, lpBitmapName
, IMAGE_BITMAP
, 0, 0, 0);
593 LoadBitmapW(HINSTANCE hInstance
, LPCWSTR lpBitmapName
)
595 return LoadImageW(hInstance
, lpBitmapName
, IMAGE_BITMAP
, 0, 0, 0);
611 objSize
= GetObjectW( hnd
, sizeof(ds
), &ds
);
612 if (!objSize
) return 0;
613 if ((desiredx
< 0) || (desiredy
< 0)) return 0;
615 if (flags
& LR_COPYFROMRESOURCE
)
617 FIXME("FIXME: The flag LR_COPYFROMRESOURCE is not implemented for bitmaps\n");
620 if (desiredx
== 0) desiredx
= ds
.dsBm
.bmWidth
;
621 if (desiredy
== 0) desiredy
= ds
.dsBm
.bmHeight
;
623 /* Allocate memory for a BITMAPINFOHEADER structure and a
624 color table. The maximum number of colors in a color table
625 is 256 which corresponds to a bitmap with depth 8.
626 Bitmaps with higher depths don't have color tables. */
627 bi
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(BITMAPINFOHEADER
) + 256 * sizeof(RGBQUAD
));
630 bi
->bmiHeader
.biSize
= sizeof(bi
->bmiHeader
);
631 bi
->bmiHeader
.biPlanes
= ds
.dsBm
.bmPlanes
;
632 bi
->bmiHeader
.biBitCount
= ds
.dsBm
.bmBitsPixel
;
633 bi
->bmiHeader
.biCompression
= BI_RGB
;
635 if (flags
& LR_CREATEDIBSECTION
)
637 /* Create a DIB section. LR_MONOCHROME is ignored */
639 HDC dc
= CreateCompatibleDC(NULL
);
641 if (objSize
== sizeof(DIBSECTION
))
643 /* The source bitmap is a DIB.
644 Get its attributes to create an exact copy */
645 memcpy(bi
, &ds
.dsBmih
, sizeof(BITMAPINFOHEADER
));
648 /* Get the color table or the color masks */
649 GetDIBits(dc
, hnd
, 0, ds
.dsBm
.bmHeight
, NULL
, bi
, DIB_RGB_COLORS
);
651 bi
->bmiHeader
.biWidth
= desiredx
;
652 bi
->bmiHeader
.biHeight
= desiredy
;
653 bi
->bmiHeader
.biSizeImage
= 0;
655 res
= CreateDIBSection(dc
, bi
, DIB_RGB_COLORS
, &bits
, NULL
, 0);
660 /* Create a device-dependent bitmap */
662 BOOL monochrome
= (flags
& LR_MONOCHROME
);
664 if (objSize
== sizeof(DIBSECTION
))
666 /* The source bitmap is a DIB section.
667 Get its attributes */
668 HDC dc
= CreateCompatibleDC(NULL
);
669 bi
->bmiHeader
.biSize
= sizeof(bi
->bmiHeader
);
670 bi
->bmiHeader
.biBitCount
= ds
.dsBm
.bmBitsPixel
;
671 GetDIBits(dc
, hnd
, 0, ds
.dsBm
.bmHeight
, NULL
, bi
, DIB_RGB_COLORS
);
674 if (!monochrome
&& ds
.dsBm
.bmBitsPixel
== 1)
676 /* Look if the colors of the DIB are black and white */
679 (bi
->bmiColors
[0].rgbRed
== 0xff
680 && bi
->bmiColors
[0].rgbGreen
== 0xff
681 && bi
->bmiColors
[0].rgbBlue
== 0xff
682 && bi
->bmiColors
[0].rgbReserved
== 0
683 && bi
->bmiColors
[1].rgbRed
== 0
684 && bi
->bmiColors
[1].rgbGreen
== 0
685 && bi
->bmiColors
[1].rgbBlue
== 0
686 && bi
->bmiColors
[1].rgbReserved
== 0)
688 (bi
->bmiColors
[0].rgbRed
== 0
689 && bi
->bmiColors
[0].rgbGreen
== 0
690 && bi
->bmiColors
[0].rgbBlue
== 0
691 && bi
->bmiColors
[0].rgbReserved
== 0
692 && bi
->bmiColors
[1].rgbRed
== 0xff
693 && bi
->bmiColors
[1].rgbGreen
== 0xff
694 && bi
->bmiColors
[1].rgbBlue
== 0xff
695 && bi
->bmiColors
[1].rgbReserved
== 0);
698 else if (!monochrome
)
700 monochrome
= ds
.dsBm
.bmBitsPixel
== 1;
705 res
= CreateBitmap(desiredx
, desiredy
, 1, 1, NULL
);
709 HDC screenDC
= GetDC(NULL
);
710 res
= CreateCompatibleBitmap(screenDC
, desiredx
, desiredy
);
711 ReleaseDC(NULL
, screenDC
);
717 /* Only copy the bitmap if it's a DIB section or if it's
718 compatible to the screen */
721 if (objSize
== sizeof(DIBSECTION
))
727 HDC screenDC
= GetDC(NULL
);
728 int screen_depth
= GetDeviceCaps(screenDC
, BITSPIXEL
);
729 ReleaseDC(NULL
, screenDC
);
731 copyContents
= (ds
.dsBm
.bmBitsPixel
== 1 || ds
.dsBm
.bmBitsPixel
== screen_depth
);
736 /* The source bitmap may already be selected in a device context,
737 use GetDIBits/StretchDIBits and not StretchBlt */
742 dc
= CreateCompatibleDC(NULL
);
744 bi
->bmiHeader
.biWidth
= ds
.dsBm
.bmWidth
;
745 bi
->bmiHeader
.biHeight
= ds
.dsBm
.bmHeight
;
746 bi
->bmiHeader
.biSizeImage
= 0;
747 bi
->bmiHeader
.biClrUsed
= 0;
748 bi
->bmiHeader
.biClrImportant
= 0;
750 /* Fill in biSizeImage */
751 GetDIBits(dc
, hnd
, 0, ds
.dsBm
.bmHeight
, NULL
, bi
, DIB_RGB_COLORS
);
752 bits
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, bi
->bmiHeader
.biSizeImage
);
758 /* Get the image bits of the source bitmap */
759 GetDIBits(dc
, hnd
, 0, ds
.dsBm
.bmHeight
, bits
, bi
, DIB_RGB_COLORS
);
761 /* Copy it to the destination bitmap */
762 oldBmp
= SelectObject(dc
, res
);
763 StretchDIBits(dc
, 0, 0, desiredx
, desiredy
,
764 0, 0, ds
.dsBm
.bmWidth
, ds
.dsBm
.bmHeight
,
765 bits
, bi
, DIB_RGB_COLORS
, SRCCOPY
);
766 SelectObject(dc
, oldBmp
);
768 HeapFree(GetProcessHeap(), 0, bits
);
774 if (flags
& LR_COPYDELETEORG
)
779 HeapFree(GetProcessHeap(), 0, bi
);
785 GetIconCurBpp(PICONINFO pIconInfo
)
789 pbi
= (PBITMAPINFO
)pIconInfo
->hbmColor
;
790 return pbi
->bmiHeader
.biBitCount
;
804 if (!Handle
|| !pIconInfo
)
807 RtlInitUnicodeString(&Res
, lpResName
);
809 return NtUserSetCursorIconData(Handle
, hMod
, &Res
, pIconInfo
);
814 /* bare bones icon copy implementation */
816 CopyIcoCur(HANDLE hIconCur
,
822 HANDLE hNewIcon
= NULL
;
823 ICONINFO origIconInfo
, newIconInfo
;
830 if (flags
& LR_COPYFROMRESOURCE
)
832 TRACE("FIXME: LR_COPYFROMRESOURCE is yet not implemented for icons\n");
835 if (NtUserGetIconSize(hIconCur
, 0, &origSize
.cx
, &origSize
.cy
))
837 if (desiredx
== 0) desiredx
= origSize
.cx
;
838 if (desiredx
== 0) desiredy
= origSize
.cy
;
840 if (NtUserGetIconInfo(hIconCur
, &origIconInfo
, NULL
, NULL
, &origBpp
, TRUE
))
842 hNewIcon
= (HANDLE
)NtUserCallOneParam(0, ONEPARAM_ROUTINE_CREATECURICONHANDLE
);
846 /* the bitmaps returned from the NtUserGetIconInfo are copies of the original,
847 * so we can use these directly to build up our icon/cursor copy */
848 RtlCopyMemory(&newIconInfo
, &origIconInfo
, sizeof(ICONINFO
));
850 if (!SetCursorIconData(hNewIcon
, NULL
, NULL
, &newIconInfo
))
852 if (newIconInfo
.fIcon
)
853 DestroyIcon(hNewIcon
);
855 DestroyCursor(hNewIcon
);
861 DeleteObject(origIconInfo
.hbmMask
);
862 DeleteObject(origIconInfo
.hbmColor
);
866 if (hNewIcon
&& (flags
& LR_COPYDELETEORG
))
868 DestroyCursor((HCURSOR
)hIconCur
);
888 * Only Windows NT 4.0 supports the LR_COPYRETURNORG flag for bitmaps,
889 * all other versions (95/2000/XP have been tested) ignore it.
892 * If LR_CREATEDIBSECTION is absent, the copy will be monochrome for
893 * a monochrome source bitmap or if LR_MONOCHROME is present, otherwise
894 * the copy will have the same depth as the screen.
895 * The content of the image will only be copied if the bit depth of the
896 * original image is compatible with the bit depth of the screen, or
897 * if the source is a DIB section.
898 * The LR_MONOCHROME flag is ignored if LR_CREATEDIBSECTION is present.
903 return CopyBmp(hnd
, type
, desiredx
, desiredy
, flags
);
906 //return CopyIcoCur(hnd, type, desiredx, desiredy, flags);
907 return CopyIcon(hnd
);
911 static BOOL IconMsgDisplayed
= FALSE
;
912 /* FIXME: support loading the image as shared from an instance */
913 if (!IconMsgDisplayed
)
915 FIXME("FIXME: CopyImage doesn't support IMAGE_CURSOR correctly!\n");
916 IconMsgDisplayed
= TRUE
;
918 /* Should call CURSORICON_ExtCopy but more testing
919 * needs to be done before we change this
921 if (flags
) FIXME("FIXME: Flags are ignored\n");
922 return CopyCursor(hnd
);