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.11 2003/07/10 21:04:31 chorns 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
);
39 CURSORICONDIRENTRY
*CURSORICON_FindBestIcon( CURSORICONDIR
*dir
, int width
, int height
, int colors
);
42 /* FUNCTIONS *****************************************************************/
48 LoadImageA(HINSTANCE hinst
,
57 UNICODE_STRING NameString
;
61 RtlCreateUnicodeStringFromAsciiz(&NameString
, (LPSTR
)lpszName
);
62 lpszWName
= NameString
.Buffer
;
63 Handle
= LoadImageW(hinst
, lpszWName
, uType
, cxDesired
,
65 RtlFreeUnicodeString(&NameString
);
69 Handle
= LoadImageW(hinst
, (LPCWSTR
)lpszName
, uType
, cxDesired
,
77 LoadCursorImage(HINSTANCE hinst
, LPCWSTR lpszName
, UINT fuLoad
)
79 DbgPrint("FIXME: Need support for loading cursor images.\n");
85 LoadIconImage(HINSTANCE hinst
, LPCWSTR lpszName
, INT width
, INT height
, UINT fuLoad
)
91 CURSORICONDIR
* IconDIR
;
97 CURSORICONDIRENTRY
* dirEntry
;
98 ICONIMAGE
* SafeIconImage
;
99 GRPICONDIR
* IconResDir
;
103 if (fuLoad
& LR_SHARED
)
104 DbgPrint("FIXME: need LR_SHARED support Loading icon images\n");
106 if (!(fuLoad
& LR_LOADFROMFILE
))
110 hinst
= GetModuleHandle(L
"USER32");
112 hResource
= FindResourceW(hinst
, lpszName
, RT_GROUP_ICON
);
113 if (hResource
== NULL
)
118 hResource
= LoadResource(hinst
, hResource
);
119 if (hResource
== NULL
)
123 IconResDir
= LockResource(hResource
);
124 if (IconResDir
== NULL
)
129 //find the best fitting in the IconResDir for this resolution
130 id
= LookupIconIdFromDirectoryEx((PBYTE
) IconResDir
, TRUE
,
131 width
, height
, fuLoad
& (LR_DEFAULTCOLOR
| LR_MONOCHROME
));
133 h2Resource
= FindResource(hinst
,
135 MAKEINTRESOURCE(RT_ICON
));
137 hResource
= LoadResource(hinst
, h2Resource
);
138 if (hResource
== NULL
)
143 ResIcon
= LockResource(hResource
);
148 return CreateIconFromResourceEx((PBYTE
) ResIcon
,
149 SizeofResource(hinst
, h2Resource
), TRUE
, 0x00030000,
150 width
, height
, fuLoad
& (LR_DEFAULTCOLOR
| LR_MONOCHROME
));
154 hFile
= CreateFile(lpszName
,
166 hSection
= CreateFileMapping(hFile
,
174 if (hSection
== NULL
)
178 IconDIR
= MapViewOfFile(hSection
,
184 CloseHandle(hSection
);
190 //pick the best size.
191 dirEntry
= (CURSORICONDIRENTRY
*) CURSORICON_FindBestIcon( IconDIR
, width
, height
, 1);
196 if (fuLoad
& LR_LOADFROMFILE
)
198 UnmapViewOfFile(IconDIR
);
203 SafeIconImage
= RtlAllocateHeap(RtlGetProcessHeap(), 0, dirEntry
->dwBytesInRes
);
205 memcpy(SafeIconImage
, ((PBYTE
)IconDIR
) + dirEntry
->dwImageOffset
, dirEntry
->dwBytesInRes
);
208 //at this point we have a copy of the icon image to play with
210 SafeIconImage
->icHeader
.biHeight
= SafeIconImage
->icHeader
.biHeight
/2;
212 if (SafeIconImage
->icHeader
.biSize
== sizeof(BITMAPCOREHEADER
))
214 BITMAPCOREHEADER
* Core
= (BITMAPCOREHEADER
*)SafeIconImage
;
215 ColourCount
= (Core
->bcBitCount
<= 8) ? (1 << Core
->bcBitCount
) : 0;
216 HeaderSize
= sizeof(BITMAPCOREHEADER
) + ColourCount
* sizeof(RGBTRIPLE
);
220 ColourCount
= SafeIconImage
->icHeader
.biClrUsed
;
221 if (ColourCount
== 0 && SafeIconImage
->icHeader
.biBitCount
<= 8)
223 ColourCount
= 1 << SafeIconImage
->icHeader
.biBitCount
;
225 HeaderSize
= sizeof(BITMAPINFOHEADER
) + ColourCount
* sizeof(RGBQUAD
);
228 //make data point to the start of the XOR image data
229 Data
= (PBYTE
)SafeIconImage
+ HeaderSize
;
232 //get a handle to the screen dc, the icon we create is going to be compatable with this
233 hScreenDc
= CreateDCW(L
"DISPLAY", NULL
, NULL
, NULL
);
234 if (hScreenDc
== NULL
)
236 if (fuLoad
& LR_LOADFROMFILE
)
238 RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage
);
239 UnmapViewOfFile(IconDIR
);
244 hIcon
= ICON_CreateIconFromData(hScreenDc
, Data
, SafeIconImage
, width
, height
);
245 RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage
);
251 LoadBitmapImage(HINSTANCE hInstance
, LPCWSTR lpszName
, UINT fuLoad
)
256 BITMAPINFO
* BitmapInfo
;
257 BITMAPINFO
* PrivateInfo
;
264 if (!(fuLoad
& LR_LOADFROMFILE
))
266 if (hInstance
== NULL
)
268 hInstance
= GetModuleHandle(L
"USER32");
270 hResource
= FindResourceW(hInstance
, lpszName
, RT_BITMAP
);
271 if (hResource
== NULL
)
275 hResource
= LoadResource(hInstance
, hResource
);
276 if (hResource
== NULL
)
280 BitmapInfo
= LockResource(hResource
);
281 if (BitmapInfo
== NULL
)
288 hFile
= CreateFile(lpszName
,
299 hSection
= CreateFileMapping(hFile
,
306 if (hSection
== NULL
)
310 BitmapInfo
= MapViewOfFile(hSection
,
315 CloseHandle(hSection
);
316 if (BitmapInfo
== NULL
)
320 /* offset BitmapInfo by 14 bytes to acount for the size of BITMAPFILEHEADER
321 unfortunatly sizeof(BITMAPFILEHEADER) = 16, but the acutal size should be 14!
323 BitmapInfo
= (BITMAPINFO
*)(((PBYTE
)BitmapInfo
) + 14);
326 if (BitmapInfo
->bmiHeader
.biSize
== sizeof(BITMAPCOREHEADER
))
328 BITMAPCOREHEADER
* Core
= (BITMAPCOREHEADER
*)BitmapInfo
;
329 ColourCount
= (Core
->bcBitCount
<= 8) ? (1 << Core
->bcBitCount
) : 0;
330 HeaderSize
= sizeof(BITMAPCOREHEADER
) + ColourCount
* sizeof(RGBTRIPLE
);
334 ColourCount
= BitmapInfo
->bmiHeader
.biClrUsed
;
335 if (ColourCount
== 0 && BitmapInfo
->bmiHeader
.biBitCount
<= 8)
337 ColourCount
= 1 << BitmapInfo
->bmiHeader
.biBitCount
;
339 HeaderSize
= sizeof(BITMAPINFOHEADER
) + ColourCount
* sizeof(RGBQUAD
);
341 Data
= (PVOID
)BitmapInfo
+ HeaderSize
;
343 PrivateInfo
= RtlAllocateHeap(RtlGetProcessHeap(), 0, HeaderSize
);
344 if (PrivateInfo
== NULL
)
346 if (fuLoad
& LR_LOADFROMFILE
)
348 UnmapViewOfFile(BitmapInfo
);
352 memcpy(PrivateInfo
, BitmapInfo
, HeaderSize
);
354 /* FIXME: Handle colour conversion and transparency. */
356 hScreenDc
= CreateDCW(L
"DISPLAY", NULL
, NULL
, NULL
);
357 if (hScreenDc
== NULL
)
359 if (fuLoad
& LR_LOADFROMFILE
)
361 UnmapViewOfFile(BitmapInfo
);
366 if (fuLoad
& LR_CREATEDIBSECTION
)
370 hBitmap
= CreateDIBSection(hScreenDc
, PrivateInfo
, DIB_RGB_COLORS
, NULL
,
372 GetObjectA(hBitmap
, sizeof(DIBSECTION
), &Dib
);
373 SetDIBits(hScreenDc
, hBitmap
, 0, Dib
.dsBm
.bmHeight
, Data
, BitmapInfo
,
378 hBitmap
= CreateDIBitmap(hScreenDc
, &PrivateInfo
->bmiHeader
, CBM_INIT
,
379 Data
, PrivateInfo
, DIB_RGB_COLORS
);
382 RtlFreeHeap(RtlGetProcessHeap(), 0, PrivateInfo
);
383 /*DeleteDC(hScreenDc);*/
384 if (fuLoad
& LR_LOADFROMFILE
)
386 UnmapViewOfFile(BitmapInfo
);
392 LoadImageW(HINSTANCE hinst
,
399 if (fuLoad
& LR_DEFAULTSIZE
)
401 if (uType
== IMAGE_ICON
)
405 cxDesired
= GetSystemMetrics(SM_CXICON
);
409 cyDesired
= GetSystemMetrics(SM_CYICON
);
412 else if (uType
== IMAGE_CURSOR
)
416 cxDesired
= GetSystemMetrics(SM_CXCURSOR
);
420 cyDesired
= GetSystemMetrics(SM_CYCURSOR
);
429 return(LoadBitmapImage(hinst
, lpszName
, fuLoad
));
433 return(LoadCursorImage(hinst
, lpszName
, fuLoad
));
437 return(LoadIconImage(hinst
, lpszName
, cxDesired
, cyDesired
, fuLoad
));
451 LoadBitmapA(HINSTANCE hInstance
, LPCSTR lpBitmapName
)
453 return(LoadImageA(hInstance
, lpBitmapName
, IMAGE_BITMAP
, 0, 0, 0));
461 LoadBitmapW(HINSTANCE hInstance
, LPCWSTR lpBitmapName
)
463 return(LoadImageW(hInstance
, lpBitmapName
, IMAGE_BITMAP
, 0, 0, 0));