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
CreateCursorIconFromData(HDC hDC
, PVOID ImageData
, ICONIMAGE
* IconImage
, int cxDesired
, int cyDesired
, int xHotspot
, int yHotspot
, BOOL fIcon
);
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 /* Pick the best size. */
334 dirEntry
= CURSORICON_FindBestCursorFile( IconDIR
, width
, height
, ColorBits
);
338 UnmapViewOfFile(IconDIR
);
342 if ( dirEntry
->dwDIBOffset
> filesize
)
345 UnmapViewOfFile(IconDIR
);
349 if ( dirEntry
->dwDIBOffset
+ dirEntry
->dwDIBSize
> filesize
){
351 UnmapViewOfFile(IconDIR
);
355 SafeIconImage
= RtlAllocateHeap(GetProcessHeap(), 0, dirEntry
->dwDIBSize
);
356 if (SafeIconImage
== NULL
)
359 UnmapViewOfFile(IconDIR
);
363 memcpy(SafeIconImage
, ((PBYTE
)IconDIR
) + dirEntry
->dwDIBOffset
, dirEntry
->dwDIBSize
);
364 UnmapViewOfFile(IconDIR
);
366 /* At this point we have a copy of the icon image to play with. */
368 SafeIconImage
->icHeader
.biHeight
= SafeIconImage
->icHeader
.biHeight
/2;
370 if (SafeIconImage
->icHeader
.biSize
== sizeof(BITMAPCOREHEADER
))
372 BITMAPCOREHEADER
* Core
= (BITMAPCOREHEADER
*)SafeIconImage
;
373 ColorCount
= (Core
->bcBitCount
<= 8) ? (1 << Core
->bcBitCount
) : 0;
374 HeaderSize
= sizeof(BITMAPCOREHEADER
) + ColorCount
* sizeof(RGBTRIPLE
);
378 ColorCount
= SafeIconImage
->icHeader
.biClrUsed
;
379 if (ColorCount
== 0 && SafeIconImage
->icHeader
.biBitCount
<= 8)
380 ColorCount
= 1 << SafeIconImage
->icHeader
.biBitCount
;
381 HeaderSize
= sizeof(BITMAPINFOHEADER
) + ColorCount
* sizeof(RGBQUAD
);
384 /* Make data point to the start of the XOR image data. */
385 Data
= (PBYTE
)SafeIconImage
+ HeaderSize
;
387 hIcon
= CreateCursorIconFromData(hScreenDc
, Data
, SafeIconImage
, width
, height
, width
/2, height
/2, Icon
);
388 RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage
);
396 LoadBitmapImage(HINSTANCE hInstance
, LPCWSTR lpszName
, UINT fuLoad
)
401 LPBITMAPINFO BitmapInfo
;
402 LPBITMAPINFO PrivateInfo
;
410 if (!(fuLoad
& LR_LOADFROMFILE
))
412 if (hInstance
== NULL
)
413 hInstance
= User32Instance
;
415 hResource
= FindResourceW(hInstance
, lpszName
, RT_BITMAP
);
416 if (hResource
== NULL
)
418 hResource
= LoadResource(hInstance
, hResource
);
419 if (hResource
== NULL
)
421 BitmapInfo
= LockResource(hResource
);
422 if (BitmapInfo
== NULL
)
427 hFile
= CreateFileW(lpszName
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
428 OPEN_EXISTING
, 0, NULL
);
429 if (hFile
== INVALID_HANDLE_VALUE
)
432 hSection
= CreateFileMappingW(hFile
, NULL
, PAGE_READONLY
, 0, 0, NULL
);
434 if (hSection
== NULL
)
437 BitmapInfo
= MapViewOfFile(hSection
, FILE_MAP_READ
, 0, 0, 0);
438 CloseHandle(hSection
);
439 if (BitmapInfo
== NULL
)
442 BitmapInfo
= (LPBITMAPINFO
)((ULONG_PTR
)BitmapInfo
+ sizeof(BITMAPFILEHEADER
));
445 HeaderSize
= BitmapInfo
->bmiHeader
.biSize
;
446 if (HeaderSize
== sizeof(BITMAPCOREHEADER
))
448 BITMAPCOREHEADER
* Core
= (BITMAPCOREHEADER
*)BitmapInfo
;
449 ColorCount
= (Core
->bcBitCount
<= 8) ? (1 << Core
->bcBitCount
) : 0;
450 HeaderSize
+= ColorCount
* sizeof(RGBTRIPLE
);
454 if (BitmapInfo
->bmiHeader
.biCompression
== BI_BITFIELDS
)
456 HeaderSize
+= 3 * sizeof(RGBQUAD
);
460 ColorCount
= BitmapInfo
->bmiHeader
.biClrUsed
;
461 if (ColorCount
== 0 && BitmapInfo
->bmiHeader
.biBitCount
<= 8)
462 ColorCount
= 1 << BitmapInfo
->bmiHeader
.biBitCount
;
463 HeaderSize
+= ColorCount
* sizeof(RGBQUAD
);
466 Data
= (PVOID
)((ULONG_PTR
)BitmapInfo
+ HeaderSize
);
468 PrivateInfo
= RtlAllocateHeap(GetProcessHeap(), 0, HeaderSize
);
469 if (PrivateInfo
== NULL
)
471 if (fuLoad
& LR_LOADFROMFILE
)
472 UnmapViewOfFile(BitmapInfo
);
478 memcpy(PrivateInfo
, BitmapInfo
, HeaderSize
);
480 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
488 ERR("We have a thread overrun, these are already freed! pi -> %d, bi -> %d\n", PrivateInfo
, BitmapInfo
);
489 RtlFreeHeap(GetProcessHeap(), 0, PrivateInfo
);
490 if (fuLoad
& LR_LOADFROMFILE
)
491 UnmapViewOfFile(BitmapInfo
);
495 /* FIXME: Handle color conversion and transparency. */
497 hScreenDc
= CreateCompatibleDC(NULL
);
498 if (hScreenDc
== NULL
)
500 RtlFreeHeap(GetProcessHeap(), 0, PrivateInfo
);
501 if (fuLoad
& LR_LOADFROMFILE
)
502 UnmapViewOfFile(BitmapInfo
);
506 if (fuLoad
& LR_CREATEDIBSECTION
)
510 hBitmap
= CreateDIBSection(hScreenDc
, PrivateInfo
, DIB_RGB_COLORS
, NULL
,
512 GetObjectA(hBitmap
, sizeof(DIBSECTION
), &Dib
);
513 SetDIBits(hScreenDc
, hBitmap
, 0, Dib
.dsBm
.bmHeight
, Data
, BitmapInfo
,
518 hBitmap
= CreateDIBitmap(hScreenDc
, &PrivateInfo
->bmiHeader
, CBM_INIT
,
519 Data
, PrivateInfo
, DIB_RGB_COLORS
);
522 RtlFreeHeap(GetProcessHeap(), 0, PrivateInfo
);
524 if (fuLoad
& LR_LOADFROMFILE
)
525 UnmapViewOfFile(BitmapInfo
);
539 if (fuLoad
& LR_DEFAULTSIZE
)
541 if (uType
== IMAGE_ICON
)
544 cxDesired
= GetSystemMetrics(SM_CXICON
);
546 cyDesired
= GetSystemMetrics(SM_CYICON
);
548 else if (uType
== IMAGE_CURSOR
)
551 cxDesired
= GetSystemMetrics(SM_CXCURSOR
);
553 cyDesired
= GetSystemMetrics(SM_CYCURSOR
);
560 return LoadBitmapImage(hinst
, lpszName
, fuLoad
);
563 return LoadCursorIconImage(hinst
, lpszName
, cxDesired
, cyDesired
,
577 LoadBitmapA(HINSTANCE hInstance
, LPCSTR lpBitmapName
)
579 return LoadImageA(hInstance
, lpBitmapName
, IMAGE_BITMAP
, 0, 0, 0);
587 LoadBitmapW(HINSTANCE hInstance
, LPCWSTR lpBitmapName
)
589 return LoadImageW(hInstance
, lpBitmapName
, IMAGE_BITMAP
, 0, 0, 0);
605 objSize
= GetObjectW( hnd
, sizeof(ds
), &ds
);
606 if (!objSize
) return 0;
607 if ((desiredx
< 0) || (desiredy
< 0)) return 0;
609 if (flags
& LR_COPYFROMRESOURCE
)
611 FIXME("FIXME: The flag LR_COPYFROMRESOURCE is not implemented for bitmaps\n");
614 if (desiredx
== 0) desiredx
= ds
.dsBm
.bmWidth
;
615 if (desiredy
== 0) desiredy
= ds
.dsBm
.bmHeight
;
617 /* Allocate memory for a BITMAPINFOHEADER structure and a
618 color table. The maximum number of colors in a color table
619 is 256 which corresponds to a bitmap with depth 8.
620 Bitmaps with higher depths don't have color tables. */
621 bi
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(BITMAPINFOHEADER
) + 256 * sizeof(RGBQUAD
));
624 bi
->bmiHeader
.biSize
= sizeof(bi
->bmiHeader
);
625 bi
->bmiHeader
.biPlanes
= ds
.dsBm
.bmPlanes
;
626 bi
->bmiHeader
.biBitCount
= ds
.dsBm
.bmBitsPixel
;
627 bi
->bmiHeader
.biCompression
= BI_RGB
;
629 if (flags
& LR_CREATEDIBSECTION
)
631 /* Create a DIB section. LR_MONOCHROME is ignored */
633 HDC dc
= CreateCompatibleDC(NULL
);
635 if (objSize
== sizeof(DIBSECTION
))
637 /* The source bitmap is a DIB.
638 Get its attributes to create an exact copy */
639 memcpy(bi
, &ds
.dsBmih
, sizeof(BITMAPINFOHEADER
));
642 /* Get the color table or the color masks */
643 GetDIBits(dc
, hnd
, 0, ds
.dsBm
.bmHeight
, NULL
, bi
, DIB_RGB_COLORS
);
645 bi
->bmiHeader
.biWidth
= desiredx
;
646 bi
->bmiHeader
.biHeight
= desiredy
;
647 bi
->bmiHeader
.biSizeImage
= 0;
649 res
= CreateDIBSection(dc
, bi
, DIB_RGB_COLORS
, &bits
, NULL
, 0);
654 /* Create a device-dependent bitmap */
656 BOOL monochrome
= (flags
& LR_MONOCHROME
);
658 if (objSize
== sizeof(DIBSECTION
))
660 /* The source bitmap is a DIB section.
661 Get its attributes */
662 HDC dc
= CreateCompatibleDC(NULL
);
663 bi
->bmiHeader
.biSize
= sizeof(bi
->bmiHeader
);
664 bi
->bmiHeader
.biBitCount
= ds
.dsBm
.bmBitsPixel
;
665 GetDIBits(dc
, hnd
, 0, ds
.dsBm
.bmHeight
, NULL
, bi
, DIB_RGB_COLORS
);
668 if (!monochrome
&& ds
.dsBm
.bmBitsPixel
== 1)
670 /* Look if the colors of the DIB are black and white */
673 (bi
->bmiColors
[0].rgbRed
== 0xff
674 && bi
->bmiColors
[0].rgbGreen
== 0xff
675 && bi
->bmiColors
[0].rgbBlue
== 0xff
676 && bi
->bmiColors
[0].rgbReserved
== 0
677 && bi
->bmiColors
[1].rgbRed
== 0
678 && bi
->bmiColors
[1].rgbGreen
== 0
679 && bi
->bmiColors
[1].rgbBlue
== 0
680 && bi
->bmiColors
[1].rgbReserved
== 0)
682 (bi
->bmiColors
[0].rgbRed
== 0
683 && bi
->bmiColors
[0].rgbGreen
== 0
684 && bi
->bmiColors
[0].rgbBlue
== 0
685 && bi
->bmiColors
[0].rgbReserved
== 0
686 && bi
->bmiColors
[1].rgbRed
== 0xff
687 && bi
->bmiColors
[1].rgbGreen
== 0xff
688 && bi
->bmiColors
[1].rgbBlue
== 0xff
689 && bi
->bmiColors
[1].rgbReserved
== 0);
692 else if (!monochrome
)
694 monochrome
= ds
.dsBm
.bmBitsPixel
== 1;
699 res
= CreateBitmap(desiredx
, desiredy
, 1, 1, NULL
);
703 HDC screenDC
= GetDC(NULL
);
704 res
= CreateCompatibleBitmap(screenDC
, desiredx
, desiredy
);
705 ReleaseDC(NULL
, screenDC
);
711 /* Only copy the bitmap if it's a DIB section or if it's
712 compatible to the screen */
715 if (objSize
== sizeof(DIBSECTION
))
721 HDC screenDC
= GetDC(NULL
);
722 int screen_depth
= GetDeviceCaps(screenDC
, BITSPIXEL
);
723 ReleaseDC(NULL
, screenDC
);
725 copyContents
= (ds
.dsBm
.bmBitsPixel
== 1 || ds
.dsBm
.bmBitsPixel
== screen_depth
);
730 /* The source bitmap may already be selected in a device context,
731 use GetDIBits/StretchDIBits and not StretchBlt */
736 dc
= CreateCompatibleDC(NULL
);
738 bi
->bmiHeader
.biWidth
= ds
.dsBm
.bmWidth
;
739 bi
->bmiHeader
.biHeight
= ds
.dsBm
.bmHeight
;
740 bi
->bmiHeader
.biSizeImage
= 0;
741 bi
->bmiHeader
.biClrUsed
= 0;
742 bi
->bmiHeader
.biClrImportant
= 0;
744 /* Fill in biSizeImage */
745 GetDIBits(dc
, hnd
, 0, ds
.dsBm
.bmHeight
, NULL
, bi
, DIB_RGB_COLORS
);
746 bits
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, bi
->bmiHeader
.biSizeImage
);
752 /* Get the image bits of the source bitmap */
753 GetDIBits(dc
, hnd
, 0, ds
.dsBm
.bmHeight
, bits
, bi
, DIB_RGB_COLORS
);
755 /* Copy it to the destination bitmap */
756 oldBmp
= SelectObject(dc
, res
);
757 StretchDIBits(dc
, 0, 0, desiredx
, desiredy
,
758 0, 0, ds
.dsBm
.bmWidth
, ds
.dsBm
.bmHeight
,
759 bits
, bi
, DIB_RGB_COLORS
, SRCCOPY
);
760 SelectObject(dc
, oldBmp
);
762 HeapFree(GetProcessHeap(), 0, bits
);
768 if (flags
& LR_COPYDELETEORG
)
773 HeapFree(GetProcessHeap(), 0, bi
);
779 GetIconCurBpp(PICONINFO pIconInfo
)
783 pbi
= (PBITMAPINFO
)pIconInfo
->hbmColor
;
784 return pbi
->bmiHeader
.biBitCount
;
798 if (!Handle
|| !pIconInfo
)
801 RtlInitUnicodeString(&Res
, lpResName
);
803 return NtUserSetCursorIconData(Handle
, hMod
, &Res
, pIconInfo
);
808 /* bare bones icon copy implementation */
810 CopyIcoCur(HANDLE hIconCur
,
816 HANDLE hNewIcon
= NULL
;
817 ICONINFO origIconInfo
, newIconInfo
;
824 if (flags
& LR_COPYFROMRESOURCE
)
826 TRACE("FIXME: LR_COPYFROMRESOURCE is yet not implemented for icons\n");
829 if (NtUserGetIconSize(hIconCur
, 0, &origSize
.cx
, &origSize
.cy
))
831 if (desiredx
== 0) desiredx
= origSize
.cx
;
832 if (desiredx
== 0) desiredy
= origSize
.cy
;
834 if (NtUserGetIconInfo(hIconCur
, &origIconInfo
, NULL
, NULL
, &origBpp
, TRUE
))
836 hNewIcon
= (HANDLE
)NtUserCallOneParam(0, ONEPARAM_ROUTINE_CREATECURICONHANDLE
);
840 /* the bitmaps returned from the NtUserGetIconInfo are copies of the original,
841 * so we can use these directly to build up our icon/cursor copy */
842 RtlCopyMemory(&newIconInfo
, &origIconInfo
, sizeof(ICONINFO
));
844 if (!SetCursorIconData(hNewIcon
, NULL
, NULL
, &newIconInfo
))
846 if (newIconInfo
.fIcon
)
847 DestroyIcon(hNewIcon
);
849 DestroyCursor(hNewIcon
);
855 DeleteObject(origIconInfo
.hbmMask
);
856 DeleteObject(origIconInfo
.hbmColor
);
860 if (hNewIcon
&& (flags
& LR_COPYDELETEORG
))
862 DestroyCursor((HCURSOR
)hIconCur
);
882 * Only Windows NT 4.0 supports the LR_COPYRETURNORG flag for bitmaps,
883 * all other versions (95/2000/XP have been tested) ignore it.
886 * If LR_CREATEDIBSECTION is absent, the copy will be monochrome for
887 * a monochrome source bitmap or if LR_MONOCHROME is present, otherwise
888 * the copy will have the same depth as the screen.
889 * The content of the image will only be copied if the bit depth of the
890 * original image is compatible with the bit depth of the screen, or
891 * if the source is a DIB section.
892 * The LR_MONOCHROME flag is ignored if LR_CREATEDIBSECTION is present.
897 return CopyBmp(hnd
, type
, desiredx
, desiredy
, flags
);
900 //return CopyIcoCur(hnd, type, desiredx, desiredy, flags);
901 return CopyIcon(hnd
);
905 static BOOL IconMsgDisplayed
= FALSE
;
906 /* FIXME: support loading the image as shared from an instance */
907 if (!IconMsgDisplayed
)
909 FIXME("FIXME: CopyImage doesn't support IMAGE_CURSOR correctly!\n");
910 IconMsgDisplayed
= TRUE
;
912 /* Should call CURSORICON_ExtCopy but more testing
913 * needs to be done before we change this
915 if (flags
) FIXME("FIXME: Flags are ignored\n");
916 return CopyCursor(hnd
);