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.18 2003/10/15 19:39:08 navaraf 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_CreateIconFromData(HDC hDC
, PVOID ImageData
, ICONIMAGE
* IconImage
, int cxDesired
, int cyDesired
, int xHotspot
, int yHotspot
);
39 CURSORICONDIRENTRY
*CURSORICON_FindBestIcon( CURSORICONDIR
*dir
, int width
, int height
, int colors
);
40 CURSORICONDIRENTRY
*CURSORICON_FindBestCursor( CURSORICONDIR
*dir
, int width
, int height
, int colors
);
43 /* FUNCTIONS *****************************************************************/
49 LoadImageA(HINSTANCE hinst
,
58 UNICODE_STRING NameString
;
62 RtlCreateUnicodeStringFromAsciiz(&NameString
, (LPSTR
)lpszName
);
63 lpszWName
= NameString
.Buffer
;
64 Handle
= LoadImageW(hinst
, lpszWName
, uType
, cxDesired
,
66 RtlFreeUnicodeString(&NameString
);
70 Handle
= LoadImageW(hinst
, (LPCWSTR
)lpszName
, uType
, cxDesired
,
78 LoadCursorImage(HINSTANCE hinst
, LPCWSTR lpszName
, UINT fuLoad
)
84 CURSORICONDIR
* IconDIR
;
90 CURSORICONDIRENTRY
* dirEntry
;
91 ICONIMAGE
* SafeIconImage
;
92 GRPCURSORICONDIR
* IconResDir
;
96 if (fuLoad
& LR_SHARED
)
97 DbgPrint("FIXME: need LR_SHARED support Loading cursor images\n");
99 if (!(fuLoad
& LR_LOADFROMFILE
))
103 hinst
= GetModuleHandleW(L
"USER32");
105 hResource
= FindResourceW(hinst
, lpszName
, RT_GROUP_CURSOR
);
106 if (hResource
== NULL
)
111 hResource
= LoadResource(hinst
, hResource
);
112 if (hResource
== NULL
)
116 IconResDir
= LockResource(hResource
);
117 if (IconResDir
== NULL
)
122 //find the best fitting in the IconResDir for this resolution
123 id
= LookupIconIdFromDirectoryEx((PBYTE
) IconResDir
, TRUE
,
124 32, 32, fuLoad
& (LR_DEFAULTCOLOR
| LR_MONOCHROME
));
126 h2Resource
= FindResourceW(hinst
,
127 MAKEINTRESOURCEW(id
),
128 MAKEINTRESOURCEW(RT_CURSOR
));
130 hResource
= LoadResource(hinst
, h2Resource
);
131 if (hResource
== NULL
)
136 ResIcon
= LockResource(hResource
);
141 return CreateIconFromResourceEx((PBYTE
) ResIcon
,
142 SizeofResource(hinst
, h2Resource
), FALSE
, 0x00030000,
143 32, 32, fuLoad
& (LR_DEFAULTCOLOR
| LR_MONOCHROME
));
147 hFile
= CreateFileW(lpszName
,
159 hSection
= CreateFileMappingW(hFile
,
167 if (hSection
== NULL
)
171 IconDIR
= MapViewOfFile(hSection
,
177 CloseHandle(hSection
);
183 //pick the best size.
184 dirEntry
= (CURSORICONDIRENTRY
*) CURSORICON_FindBestIcon( IconDIR
, 32, 32, 1);
189 if (fuLoad
& LR_LOADFROMFILE
)
191 UnmapViewOfFile(IconDIR
);
196 SafeIconImage
= RtlAllocateHeap(RtlGetProcessHeap(), 0, dirEntry
->dwBytesInRes
);
198 memcpy(SafeIconImage
, ((PBYTE
)IconDIR
) + dirEntry
->dwImageOffset
, dirEntry
->dwBytesInRes
);
201 //at this point we have a copy of the icon image to play with
203 SafeIconImage
->icHeader
.biHeight
= SafeIconImage
->icHeader
.biHeight
/2;
205 if (SafeIconImage
->icHeader
.biSize
== sizeof(BITMAPCOREHEADER
))
207 BITMAPCOREHEADER
* Core
= (BITMAPCOREHEADER
*)SafeIconImage
;
208 ColourCount
= (Core
->bcBitCount
<= 8) ? (1 << Core
->bcBitCount
) : 0;
209 HeaderSize
= sizeof(BITMAPCOREHEADER
) + ColourCount
* sizeof(RGBTRIPLE
);
213 ColourCount
= SafeIconImage
->icHeader
.biClrUsed
;
214 if (ColourCount
== 0 && SafeIconImage
->icHeader
.biBitCount
<= 8)
216 ColourCount
= 1 << SafeIconImage
->icHeader
.biBitCount
;
218 HeaderSize
= sizeof(BITMAPINFOHEADER
) + ColourCount
* sizeof(RGBQUAD
);
221 //make data point to the start of the XOR image data
222 Data
= (PBYTE
)SafeIconImage
+ HeaderSize
;
225 //get a handle to the screen dc, the icon we create is going to be compatable with this
226 hScreenDc
= CreateDCW(L
"DISPLAY", NULL
, NULL
, NULL
);
227 if (hScreenDc
== NULL
)
229 if (fuLoad
& LR_LOADFROMFILE
)
231 RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage
);
232 UnmapViewOfFile(IconDIR
);
237 hIcon
= ICON_CreateIconFromData(hScreenDc
, Data
, SafeIconImage
, 32, 32, dirEntry
->Info
.cursor
.wXHotspot
, dirEntry
->Info
.cursor
.wYHotspot
);
238 RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage
);
244 LoadIconImage(HINSTANCE hinst
, LPCWSTR lpszName
, INT width
, INT height
, UINT fuLoad
)
250 CURSORICONDIR
* IconDIR
;
256 CURSORICONDIRENTRY
* dirEntry
;
257 ICONIMAGE
* SafeIconImage
;
258 GRPCURSORICONDIR
* IconResDir
;
262 if (fuLoad
& LR_SHARED
)
263 DbgPrint("FIXME: need LR_SHARED support Loading icon images\n");
265 if (!(fuLoad
& LR_LOADFROMFILE
))
269 hinst
= GetModuleHandleW(L
"USER32");
271 hResource
= FindResourceW(hinst
, lpszName
, RT_GROUP_ICON
);
272 if (hResource
== NULL
)
277 hResource
= LoadResource(hinst
, hResource
);
278 if (hResource
== NULL
)
282 IconResDir
= LockResource(hResource
);
283 if (IconResDir
== NULL
)
288 //find the best fitting in the IconResDir for this resolution
289 id
= LookupIconIdFromDirectoryEx((PBYTE
) IconResDir
, TRUE
,
290 width
, height
, fuLoad
& (LR_DEFAULTCOLOR
| LR_MONOCHROME
));
292 h2Resource
= FindResourceW(hinst
,
293 MAKEINTRESOURCEW(id
),
294 MAKEINTRESOURCEW(RT_ICON
));
296 hResource
= LoadResource(hinst
, h2Resource
);
297 if (hResource
== NULL
)
302 ResIcon
= LockResource(hResource
);
307 return CreateIconFromResourceEx((PBYTE
) ResIcon
,
308 SizeofResource(hinst
, h2Resource
), TRUE
, 0x00030000,
309 width
, height
, fuLoad
& (LR_DEFAULTCOLOR
| LR_MONOCHROME
));
313 hFile
= CreateFileW(lpszName
,
325 hSection
= CreateFileMappingW(hFile
,
332 if (hSection
== NULL
)
337 IconDIR
= MapViewOfFile(hSection
,
346 CloseHandle(hSection
);
350 //pick the best size.
351 dirEntry
= (CURSORICONDIRENTRY
*) CURSORICON_FindBestIcon( IconDIR
, width
, height
, 1);
357 CloseHandle(hSection
);
358 UnmapViewOfFile(IconDIR
);
362 SafeIconImage
= RtlAllocateHeap(RtlGetProcessHeap(), 0, dirEntry
->dwBytesInRes
);
364 memcpy(SafeIconImage
, ((PBYTE
)IconDIR
) + dirEntry
->dwImageOffset
, dirEntry
->dwBytesInRes
);
367 CloseHandle(hSection
);
370 //at this point we have a copy of the icon image to play with
372 SafeIconImage
->icHeader
.biHeight
= SafeIconImage
->icHeader
.biHeight
/2;
374 if (SafeIconImage
->icHeader
.biSize
== sizeof(BITMAPCOREHEADER
))
376 BITMAPCOREHEADER
* Core
= (BITMAPCOREHEADER
*)SafeIconImage
;
377 ColourCount
= (Core
->bcBitCount
<= 8) ? (1 << Core
->bcBitCount
) : 0;
378 HeaderSize
= sizeof(BITMAPCOREHEADER
) + ColourCount
* sizeof(RGBTRIPLE
);
382 ColourCount
= SafeIconImage
->icHeader
.biClrUsed
;
383 if (ColourCount
== 0 && SafeIconImage
->icHeader
.biBitCount
<= 8)
385 ColourCount
= 1 << SafeIconImage
->icHeader
.biBitCount
;
387 HeaderSize
= sizeof(BITMAPINFOHEADER
) + ColourCount
* sizeof(RGBQUAD
);
390 //make data point to the start of the XOR image data
391 Data
= (PBYTE
)SafeIconImage
+ HeaderSize
;
394 //get a handle to the screen dc, the icon we create is going to be compatable with this
395 hScreenDc
= CreateDCW(L
"DISPLAY", NULL
, NULL
, NULL
);
396 if (hScreenDc
== NULL
)
398 if (fuLoad
& LR_LOADFROMFILE
)
400 RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage
);
401 UnmapViewOfFile(IconDIR
);
406 hIcon
= ICON_CreateIconFromData(hScreenDc
, Data
, SafeIconImage
, width
, height
, width
/2, height
/2);
407 RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage
);
413 LoadBitmapImage(HINSTANCE hInstance
, LPCWSTR lpszName
, UINT fuLoad
)
418 BITMAPINFO
* BitmapInfo
;
419 BITMAPINFO
* PrivateInfo
;
426 if (!(fuLoad
& LR_LOADFROMFILE
))
428 if (hInstance
== NULL
)
430 hInstance
= GetModuleHandleW(L
"USER32");
432 hResource
= FindResourceW(hInstance
, lpszName
, RT_BITMAP
);
433 if (hResource
== NULL
)
437 hResource
= LoadResource(hInstance
, hResource
);
438 if (hResource
== NULL
)
442 BitmapInfo
= LockResource(hResource
);
443 if (BitmapInfo
== NULL
)
450 hFile
= CreateFileW(lpszName
,
461 hSection
= CreateFileMappingW(hFile
,
468 if (hSection
== NULL
)
472 BitmapInfo
= MapViewOfFile(hSection
,
477 CloseHandle(hSection
);
478 if (BitmapInfo
== NULL
)
482 /* offset BitmapInfo by 14 bytes to acount for the size of BITMAPFILEHEADER
483 unfortunatly sizeof(BITMAPFILEHEADER) = 16, but the acutal size should be 14!
485 BitmapInfo
= (BITMAPINFO
*)(((PBYTE
)BitmapInfo
) + 14);
488 if (BitmapInfo
->bmiHeader
.biSize
== sizeof(BITMAPCOREHEADER
))
490 BITMAPCOREHEADER
* Core
= (BITMAPCOREHEADER
*)BitmapInfo
;
491 ColourCount
= (Core
->bcBitCount
<= 8) ? (1 << Core
->bcBitCount
) : 0;
492 HeaderSize
= sizeof(BITMAPCOREHEADER
) + ColourCount
* sizeof(RGBTRIPLE
);
496 ColourCount
= BitmapInfo
->bmiHeader
.biClrUsed
;
497 if (ColourCount
== 0 && BitmapInfo
->bmiHeader
.biBitCount
<= 8)
499 ColourCount
= 1 << BitmapInfo
->bmiHeader
.biBitCount
;
501 HeaderSize
= sizeof(BITMAPINFOHEADER
) + ColourCount
* sizeof(RGBQUAD
);
503 Data
= (PVOID
)BitmapInfo
+ HeaderSize
;
505 PrivateInfo
= RtlAllocateHeap(RtlGetProcessHeap(), 0, HeaderSize
);
506 if (PrivateInfo
== NULL
)
508 if (fuLoad
& LR_LOADFROMFILE
)
510 UnmapViewOfFile(BitmapInfo
);
514 memcpy(PrivateInfo
, BitmapInfo
, HeaderSize
);
516 /* FIXME: Handle colour conversion and transparency. */
518 hScreenDc
= CreateDCW(L
"DISPLAY", NULL
, NULL
, NULL
);
519 if (hScreenDc
== NULL
)
521 if (fuLoad
& LR_LOADFROMFILE
)
523 UnmapViewOfFile(BitmapInfo
);
528 if (fuLoad
& LR_CREATEDIBSECTION
)
532 hBitmap
= CreateDIBSection(hScreenDc
, PrivateInfo
, DIB_RGB_COLORS
, NULL
,
534 GetObjectA(hBitmap
, sizeof(DIBSECTION
), &Dib
);
535 SetDIBits(hScreenDc
, hBitmap
, 0, Dib
.dsBm
.bmHeight
, Data
, BitmapInfo
,
540 hBitmap
= CreateDIBitmap(hScreenDc
, &PrivateInfo
->bmiHeader
, CBM_INIT
,
541 Data
, PrivateInfo
, DIB_RGB_COLORS
);
544 RtlFreeHeap(RtlGetProcessHeap(), 0, PrivateInfo
);
545 /*DeleteDC(hScreenDc);*/
546 if (fuLoad
& LR_LOADFROMFILE
)
548 UnmapViewOfFile(BitmapInfo
);
554 LoadImageW(HINSTANCE hinst
,
561 if (fuLoad
& LR_DEFAULTSIZE
)
563 if (uType
== IMAGE_ICON
)
567 cxDesired
= GetSystemMetrics(SM_CXICON
);
571 cyDesired
= GetSystemMetrics(SM_CYICON
);
574 else if (uType
== IMAGE_CURSOR
)
578 cxDesired
= GetSystemMetrics(SM_CXCURSOR
);
582 cyDesired
= GetSystemMetrics(SM_CYCURSOR
);
591 return(LoadBitmapImage(hinst
, lpszName
, fuLoad
));
595 return(LoadCursorImage(hinst
, lpszName
, fuLoad
));
599 return(LoadIconImage(hinst
, lpszName
, cxDesired
, cyDesired
, fuLoad
));
613 LoadBitmapA(HINSTANCE hInstance
, LPCSTR lpBitmapName
)
615 return(LoadImageA(hInstance
, lpBitmapName
, IMAGE_BITMAP
, 0, 0, 0));
623 LoadBitmapW(HINSTANCE hInstance
, LPCWSTR lpBitmapName
)
625 return(LoadImageW(hInstance
, lpBitmapName
, IMAGE_BITMAP
, 0, 0, 0));