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.
19 /* $Id: bitmap.c,v 1.20 2003/11/18 19:59:50 weiden Exp $
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 ******************************************************************/
37 /*forward declerations... actualy in user32\windows\icon.c but usful here****/
38 HICON
ICON_CreateCursorFromData(HDC hDC
, PVOID ImageData
, ICONIMAGE
* IconImage
, int cxDesired
, int cyDesired
, int xHotspot
, int yHotspot
);
39 HICON
ICON_CreateIconFromData(HDC hDC
, PVOID ImageData
, ICONIMAGE
* IconImage
, int cxDesired
, int cyDesired
, int xHotspot
, int yHotspot
);
40 CURSORICONDIRENTRY
*CURSORICON_FindBestIcon( CURSORICONDIR
*dir
, int width
, int height
, int colors
);
41 CURSORICONDIRENTRY
*CURSORICON_FindBestCursor( CURSORICONDIR
*dir
, int width
, int height
, int colors
);
44 /* FUNCTIONS *****************************************************************/
50 LoadImageA(HINSTANCE hinst
,
59 UNICODE_STRING NameString
;
63 RtlCreateUnicodeStringFromAsciiz(&NameString
, (LPSTR
)lpszName
);
64 lpszWName
= NameString
.Buffer
;
65 Handle
= LoadImageW(hinst
, lpszWName
, uType
, cxDesired
,
67 RtlFreeUnicodeString(&NameString
);
71 Handle
= LoadImageW(hinst
, (LPCWSTR
)lpszName
, uType
, cxDesired
,
79 LoadCursorImage(HINSTANCE hinst
, LPCWSTR lpszName
, UINT fuLoad
)
86 CURSORICONDIR
* IconDIR
;
92 CURSORICONDIRENTRY
* dirEntry
;
93 ICONIMAGE
* SafeIconImage
;
94 GRPCURSORICONDIR
* IconResDir
;
98 if (!(fuLoad
& LR_LOADFROMFILE
))
102 hinst
= GetModuleHandleW(L
"USER32");
104 hResource
= hfRes
= FindResourceW(hinst
, lpszName
, RT_GROUP_CURSOR
);
105 if (hResource
== NULL
)
110 if (fuLoad
& LR_SHARED
)
112 hIcon
= (HANDLE
)NtUserFindExistingCursorIcon(hinst
, (HRSRC
)hfRes
);
117 hResource
= LoadResource(hinst
, hResource
);
118 if (hResource
== NULL
)
122 IconResDir
= LockResource(hResource
);
123 if (IconResDir
== NULL
)
128 //find the best fitting in the IconResDir for this resolution
129 id
= LookupIconIdFromDirectoryEx((PBYTE
) IconResDir
, TRUE
,
130 32, 32, fuLoad
& (LR_DEFAULTCOLOR
| LR_MONOCHROME
));
132 h2Resource
= FindResourceW(hinst
,
133 MAKEINTRESOURCEW(id
),
134 MAKEINTRESOURCEW(RT_CURSOR
));
136 hResource
= LoadResource(hinst
, h2Resource
);
137 if (hResource
== NULL
)
142 ResIcon
= LockResource(hResource
);
147 hIcon
= (HANDLE
)CreateIconFromResourceEx((PBYTE
) ResIcon
,
148 SizeofResource(hinst
, h2Resource
), FALSE
, 0x00030000,
149 32, 32, fuLoad
& (LR_DEFAULTCOLOR
| LR_MONOCHROME
));
152 NtUserSetCursorIconData((HICON
)hIcon
, NULL
, NULL
, hinst
, (HRSRC
)hfRes
,
159 if (fuLoad
& LR_SHARED
)
161 DbgPrint("FIXME: need LR_SHARED support loading cursor images from files\n");
164 hFile
= CreateFileW(lpszName
,
176 hSection
= CreateFileMappingW(hFile
,
184 if (hSection
== NULL
)
188 IconDIR
= MapViewOfFile(hSection
,
194 CloseHandle(hSection
);
200 //pick the best size.
201 dirEntry
= (CURSORICONDIRENTRY
*) CURSORICON_FindBestIcon( IconDIR
, 32, 32, 1);
206 if (fuLoad
& LR_LOADFROMFILE
)
208 UnmapViewOfFile(IconDIR
);
213 SafeIconImage
= RtlAllocateHeap(RtlGetProcessHeap(), 0, dirEntry
->dwBytesInRes
);
215 memcpy(SafeIconImage
, ((PBYTE
)IconDIR
) + dirEntry
->dwImageOffset
, dirEntry
->dwBytesInRes
);
218 //at this point we have a copy of the icon image to play with
220 SafeIconImage
->icHeader
.biHeight
= SafeIconImage
->icHeader
.biHeight
/2;
222 if (SafeIconImage
->icHeader
.biSize
== sizeof(BITMAPCOREHEADER
))
224 BITMAPCOREHEADER
* Core
= (BITMAPCOREHEADER
*)SafeIconImage
;
225 ColourCount
= (Core
->bcBitCount
<= 8) ? (1 << Core
->bcBitCount
) : 0;
226 HeaderSize
= sizeof(BITMAPCOREHEADER
) + ColourCount
* sizeof(RGBTRIPLE
);
230 ColourCount
= SafeIconImage
->icHeader
.biClrUsed
;
231 if (ColourCount
== 0 && SafeIconImage
->icHeader
.biBitCount
<= 8)
233 ColourCount
= 1 << SafeIconImage
->icHeader
.biBitCount
;
235 HeaderSize
= sizeof(BITMAPINFOHEADER
) + ColourCount
* sizeof(RGBQUAD
);
238 //make data point to the start of the XOR image data
239 Data
= (PBYTE
)SafeIconImage
+ HeaderSize
;
242 //get a handle to the screen dc, the icon we create is going to be compatable with this
243 hScreenDc
= CreateDCW(L
"DISPLAY", NULL
, NULL
, NULL
);
244 if (hScreenDc
== NULL
)
246 if (fuLoad
& LR_LOADFROMFILE
)
248 RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage
);
249 UnmapViewOfFile(IconDIR
);
254 hIcon
= ICON_CreateCursorFromData(hScreenDc
, Data
, SafeIconImage
, 32, 32, dirEntry
->Info
.cursor
.wXHotspot
, dirEntry
->Info
.cursor
.wYHotspot
);
255 RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage
);
261 LoadIconImage(HINSTANCE hinst
, LPCWSTR lpszName
, INT width
, INT height
, UINT fuLoad
)
268 CURSORICONDIR
* IconDIR
;
274 CURSORICONDIRENTRY
* dirEntry
;
275 ICONIMAGE
* SafeIconImage
;
276 GRPCURSORICONDIR
* IconResDir
;
280 if (!(fuLoad
& LR_LOADFROMFILE
))
284 hinst
= GetModuleHandleW(L
"USER32");
286 hResource
= hfRes
= FindResourceW(hinst
, lpszName
, RT_GROUP_ICON
);
287 if (hResource
== NULL
)
292 if (fuLoad
& LR_SHARED
)
294 hIcon
= NtUserFindExistingCursorIcon(hinst
, (HRSRC
)hfRes
);
299 hResource
= LoadResource(hinst
, hResource
);
300 if (hResource
== NULL
)
304 IconResDir
= LockResource(hResource
);
305 if (IconResDir
== NULL
)
310 //find the best fitting in the IconResDir for this resolution
311 id
= LookupIconIdFromDirectoryEx((PBYTE
) IconResDir
, TRUE
,
312 width
, height
, fuLoad
& (LR_DEFAULTCOLOR
| LR_MONOCHROME
));
314 h2Resource
= FindResourceW(hinst
,
315 MAKEINTRESOURCEW(id
),
316 MAKEINTRESOURCEW(RT_ICON
));
318 hResource
= LoadResource(hinst
, h2Resource
);
319 if (hResource
== NULL
)
324 ResIcon
= LockResource(hResource
);
329 hIcon
= (HANDLE
)CreateIconFromResourceEx((PBYTE
) ResIcon
,
330 SizeofResource(hinst
, h2Resource
), TRUE
, 0x00030000,
331 width
, height
, fuLoad
& (LR_DEFAULTCOLOR
| LR_MONOCHROME
));
334 NtUserSetCursorIconData((HICON
)hIcon
, NULL
, NULL
, hinst
, (HRSRC
)hfRes
,
341 if (fuLoad
& LR_SHARED
)
343 DbgPrint("FIXME: need LR_SHARED support for loading icon images from files\n");
346 hFile
= CreateFileW(lpszName
,
358 hSection
= CreateFileMappingW(hFile
,
365 if (hSection
== NULL
)
370 IconDIR
= MapViewOfFile(hSection
,
379 CloseHandle(hSection
);
383 //pick the best size.
384 dirEntry
= (CURSORICONDIRENTRY
*) CURSORICON_FindBestIcon( IconDIR
, width
, height
, 1);
390 CloseHandle(hSection
);
391 UnmapViewOfFile(IconDIR
);
395 SafeIconImage
= RtlAllocateHeap(RtlGetProcessHeap(), 0, dirEntry
->dwBytesInRes
);
397 memcpy(SafeIconImage
, ((PBYTE
)IconDIR
) + dirEntry
->dwImageOffset
, dirEntry
->dwBytesInRes
);
400 CloseHandle(hSection
);
403 //at this point we have a copy of the icon image to play with
405 SafeIconImage
->icHeader
.biHeight
= SafeIconImage
->icHeader
.biHeight
/2;
407 if (SafeIconImage
->icHeader
.biSize
== sizeof(BITMAPCOREHEADER
))
409 BITMAPCOREHEADER
* Core
= (BITMAPCOREHEADER
*)SafeIconImage
;
410 ColourCount
= (Core
->bcBitCount
<= 8) ? (1 << Core
->bcBitCount
) : 0;
411 HeaderSize
= sizeof(BITMAPCOREHEADER
) + ColourCount
* sizeof(RGBTRIPLE
);
415 ColourCount
= SafeIconImage
->icHeader
.biClrUsed
;
416 if (ColourCount
== 0 && SafeIconImage
->icHeader
.biBitCount
<= 8)
418 ColourCount
= 1 << SafeIconImage
->icHeader
.biBitCount
;
420 HeaderSize
= sizeof(BITMAPINFOHEADER
) + ColourCount
* sizeof(RGBQUAD
);
423 //make data point to the start of the XOR image data
424 Data
= (PBYTE
)SafeIconImage
+ HeaderSize
;
427 //get a handle to the screen dc, the icon we create is going to be compatable with this
428 hScreenDc
= CreateDCW(L
"DISPLAY", NULL
, NULL
, NULL
);
429 if (hScreenDc
== NULL
)
431 if (fuLoad
& LR_LOADFROMFILE
)
433 RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage
);
434 UnmapViewOfFile(IconDIR
);
439 hIcon
= ICON_CreateIconFromData(hScreenDc
, Data
, SafeIconImage
, width
, height
, width
/2, height
/2);
440 RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage
);
446 LoadBitmapImage(HINSTANCE hInstance
, LPCWSTR lpszName
, UINT fuLoad
)
451 BITMAPINFO
* BitmapInfo
;
452 BITMAPINFO
* PrivateInfo
;
459 if (!(fuLoad
& LR_LOADFROMFILE
))
461 if (hInstance
== NULL
)
463 hInstance
= GetModuleHandleW(L
"USER32");
465 hResource
= FindResourceW(hInstance
, lpszName
, RT_BITMAP
);
466 if (hResource
== NULL
)
470 hResource
= LoadResource(hInstance
, hResource
);
471 if (hResource
== NULL
)
475 BitmapInfo
= LockResource(hResource
);
476 if (BitmapInfo
== NULL
)
483 hFile
= CreateFileW(lpszName
,
494 hSection
= CreateFileMappingW(hFile
,
501 if (hSection
== NULL
)
505 BitmapInfo
= MapViewOfFile(hSection
,
510 CloseHandle(hSection
);
511 if (BitmapInfo
== NULL
)
515 /* offset BitmapInfo by 14 bytes to acount for the size of BITMAPFILEHEADER
516 unfortunatly sizeof(BITMAPFILEHEADER) = 16, but the acutal size should be 14!
518 BitmapInfo
= (BITMAPINFO
*)(((PBYTE
)BitmapInfo
) + 14);
521 if (BitmapInfo
->bmiHeader
.biSize
== sizeof(BITMAPCOREHEADER
))
523 BITMAPCOREHEADER
* Core
= (BITMAPCOREHEADER
*)BitmapInfo
;
524 ColourCount
= (Core
->bcBitCount
<= 8) ? (1 << Core
->bcBitCount
) : 0;
525 HeaderSize
= sizeof(BITMAPCOREHEADER
) + ColourCount
* sizeof(RGBTRIPLE
);
529 ColourCount
= BitmapInfo
->bmiHeader
.biClrUsed
;
530 if (ColourCount
== 0 && BitmapInfo
->bmiHeader
.biBitCount
<= 8)
532 ColourCount
= 1 << BitmapInfo
->bmiHeader
.biBitCount
;
534 HeaderSize
= sizeof(BITMAPINFOHEADER
) + ColourCount
* sizeof(RGBQUAD
);
536 Data
= (PVOID
)BitmapInfo
+ HeaderSize
;
538 PrivateInfo
= RtlAllocateHeap(RtlGetProcessHeap(), 0, HeaderSize
);
539 if (PrivateInfo
== NULL
)
541 if (fuLoad
& LR_LOADFROMFILE
)
543 UnmapViewOfFile(BitmapInfo
);
547 memcpy(PrivateInfo
, BitmapInfo
, HeaderSize
);
549 /* FIXME: Handle colour conversion and transparency. */
551 hScreenDc
= CreateDCW(L
"DISPLAY", NULL
, NULL
, NULL
);
552 if (hScreenDc
== NULL
)
554 if (fuLoad
& LR_LOADFROMFILE
)
556 UnmapViewOfFile(BitmapInfo
);
561 if (fuLoad
& LR_CREATEDIBSECTION
)
565 hBitmap
= CreateDIBSection(hScreenDc
, PrivateInfo
, DIB_RGB_COLORS
, NULL
,
567 GetObjectA(hBitmap
, sizeof(DIBSECTION
), &Dib
);
568 SetDIBits(hScreenDc
, hBitmap
, 0, Dib
.dsBm
.bmHeight
, Data
, BitmapInfo
,
573 hBitmap
= CreateDIBitmap(hScreenDc
, &PrivateInfo
->bmiHeader
, CBM_INIT
,
574 Data
, PrivateInfo
, DIB_RGB_COLORS
);
577 RtlFreeHeap(RtlGetProcessHeap(), 0, PrivateInfo
);
578 /*DeleteDC(hScreenDc);*/
579 if (fuLoad
& LR_LOADFROMFILE
)
581 UnmapViewOfFile(BitmapInfo
);
587 LoadImageW(HINSTANCE hinst
,
594 if (fuLoad
& LR_DEFAULTSIZE
)
596 if (uType
== IMAGE_ICON
)
600 cxDesired
= GetSystemMetrics(SM_CXICON
);
604 cyDesired
= GetSystemMetrics(SM_CYICON
);
607 else if (uType
== IMAGE_CURSOR
)
611 cxDesired
= GetSystemMetrics(SM_CXCURSOR
);
615 cyDesired
= GetSystemMetrics(SM_CYCURSOR
);
624 return(LoadBitmapImage(hinst
, lpszName
, fuLoad
));
628 return(LoadCursorImage(hinst
, lpszName
, fuLoad
));
632 return(LoadIconImage(hinst
, lpszName
, cxDesired
, cyDesired
, fuLoad
));
646 LoadBitmapA(HINSTANCE hInstance
, LPCSTR lpBitmapName
)
648 return(LoadImageA(hInstance
, lpBitmapName
, IMAGE_BITMAP
, 0, 0, 0));
656 LoadBitmapW(HINSTANCE hInstance
, LPCWSTR lpBitmapName
)
658 return(LoadImageW(hInstance
, lpBitmapName
, IMAGE_BITMAP
, 0, 0, 0));