source: trunk/src/user32/loadres.cpp@ 6496

Last change on this file since 6496 was 6348, checked in by sandervl, 24 years ago

allocate more memory for GpiCreateBitmap (icon)

File size: 16.2 KB
Line 
1/* $Id: loadres.cpp,v 1.38 2001-07-16 19:32:55 sandervl Exp $ */
2
3/*
4 * Win32 resource API functions for OS/2
5 *
6 * Copyright 1998 Sander van Leeuwen
7 *
8 * Parts based on Wine code (objects\bitmap.c, loader\resource.c, objects\cursoricon.c):
9 *
10 * Copyright 1993 Alexandre Julliard
11 * 1993 Robert J. Amstadt
12 * 1996 Martin Von Loewis
13 * 1997 Alex Korobka
14 * 1998 Turchanov Sergey
15 * 1998 Huw D M Davies
16 *
17 * Project Odin Software License can be found in LICENSE.TXT
18 *
19 */
20#include <os2win.h>
21#include <user32.h>
22#include <heapstring.h>
23#include <oslibres.h>
24#include <win\virtual.h>
25#include "dib.h"
26#include "initterm.h"
27#include <winres.h>
28#include "pmwindow.h"
29
30#define DBG_LOCALLOG DBG_loadres
31#include "dbglocal.h"
32
33//******************************************************************************
34//******************************************************************************
35INT WIN32API LoadStringA(HINSTANCE instance, UINT resource_id,
36 LPSTR buffer, INT buflen )
37{
38 INT retval;
39 LPWSTR buffer2 = NULL;
40
41 if (buffer && buflen)
42 buffer2 = (LPWSTR)HeapAlloc( GetProcessHeap(), 0, buflen * 2 );
43
44 retval = LoadStringW(instance,resource_id,buffer2,buflen);
45
46 if (buffer2)
47 {
48 if (retval) {
49 lstrcpynWtoA( buffer, buffer2, buflen );
50 retval = lstrlenA( buffer );
51 }
52 else
53 *buffer = 0; //NT4, SP6 clears first character
54 HeapFree( GetProcessHeap(), 0, buffer2 );
55 }
56 return retval;
57}
58//******************************************************************************
59//******************************************************************************
60int WIN32API LoadStringW(HINSTANCE hinst, UINT wID, LPWSTR lpBuffer, int cchBuffer)
61{
62 WCHAR *p;
63 int string_num;
64 int i = 0;
65 HRSRC hRes;
66
67 /* Use bits 4 - 19 (incremented by 1) as resourceid, mask out
68 * 20 - 31. */
69 hRes = FindResourceW(hinst, (LPWSTR)(((wID>>4)&0xffff)+1), RT_STRINGW);
70 if(hRes == NULL) {
71 dprintf(("LoadStringW NOT FOUND from %X, id %d buffersize %d\n", hinst, wID, cchBuffer));
72 *lpBuffer = 0; //NT4, SP6 clears first character
73 return 0;
74 }
75
76 p = (LPWSTR)LockResource(LoadResource(hinst, hRes));
77 if(p) {
78 string_num = wID & 0x000f;
79 for (i = 0; i < string_num; i++)
80 p += *p + 1;
81
82 if (lpBuffer == NULL) return *p;
83 i = min(cchBuffer - 1, *p);
84 if (i > 0) {
85 memcpy(lpBuffer, p + 1, i * sizeof (WCHAR));
86 lpBuffer[i] = (WCHAR) 0;
87 }
88 else {
89 if (cchBuffer > 1) {
90 lpBuffer[0] = (WCHAR) 0; //NT4, SP6 clears first character
91 return 0;
92 }
93 }
94 }
95
96 if(i) {
97 dprintf(("LoadStringW from %X, id %d %ls buffersize %d", hinst, wID, lpBuffer, cchBuffer));
98 }
99 else dprintf(("LoadStringW from %X, id %d buffersize %d", hinst, wID, cchBuffer));
100 return(i);
101}
102//******************************************************************************
103//******************************************************************************
104HICON WIN32API LoadIconA(HINSTANCE hinst, LPCSTR lpszIcon)
105{
106 if(HIWORD(lpszIcon)) {
107 dprintf(("LoadIconA %x %s", hinst, lpszIcon));
108 }
109 else dprintf(("LoadIconA %x %x", hinst, lpszIcon));
110 return LoadImageA(hinst, lpszIcon, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE);
111}
112//******************************************************************************
113//******************************************************************************
114HICON WIN32API LoadIconW(HINSTANCE hinst, LPCWSTR lpszIcon)
115{
116 if(HIWORD(lpszIcon)) {
117 dprintf(("LoadIconW %x %ls", hinst, lpszIcon));
118 }
119 else dprintf(("LoadIconW %x %x", hinst, lpszIcon));
120 return LoadImageW(hinst, lpszIcon, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE);
121}
122//******************************************************************************
123//******************************************************************************
124HCURSOR WIN32API LoadCursorA(HINSTANCE hinst, LPCSTR lpszCursor)
125{
126 return LoadImageA(hinst, lpszCursor, IMAGE_CURSOR, 0, 0,
127 LR_SHARED | LR_DEFAULTSIZE );
128}
129//******************************************************************************
130//******************************************************************************
131HCURSOR WIN32API LoadCursorW(HINSTANCE hinst, LPCWSTR lpszCursor)
132{
133 return LoadImageW(hinst, lpszCursor, IMAGE_CURSOR, 0, 0,
134 LR_SHARED | LR_DEFAULTSIZE );
135}
136/***********************************************************************
137* LoadCursorFromFileW (USER32.361)
138*/
139HCURSOR WIN32API LoadCursorFromFileW (LPCWSTR name)
140{
141 return LoadImageW(0, name, IMAGE_CURSOR, 0, 0,
142 LR_LOADFROMFILE | LR_DEFAULTSIZE );
143}
144/***********************************************************************
145* LoadCursorFromFileA (USER32.360)
146*/
147HCURSOR WIN32API LoadCursorFromFileA (LPCSTR name)
148{
149 return LoadImageA(0, name, IMAGE_CURSOR, 0, 0,
150 LR_LOADFROMFILE | LR_DEFAULTSIZE );
151}
152//******************************************************************************
153//NOTE: LR_CREATEDIBSECTION flag doesn't work (crash in GDI32)! (still??)
154//******************************************************************************
155HANDLE LoadBitmapW(HINSTANCE hinst, LPCWSTR lpszName, int cxDesired, int cyDesired,
156 UINT fuLoad)
157{
158 HBITMAP hbitmap = 0;
159 HDC hdc;
160 HRSRC hRsrc;
161 HGLOBAL handle, hMapping = 0;
162 char *ptr = NULL;
163 BITMAPINFO *info, *fix_info=NULL;
164 HGLOBAL hFix;
165 int size;
166
167 if (!(fuLoad & LR_LOADFROMFILE))
168 {
169 handle = 0;
170 if(!hinst)
171 {
172 hRsrc = FindResourceW( hInstanceUser32, lpszName, RT_BITMAPW );
173 if(hRsrc) {
174 handle = LoadResource( hInstanceUser32, hRsrc );
175 }
176 }
177 if(handle == 0)
178 {
179 if (!(hRsrc = FindResourceW( hinst, lpszName, RT_BITMAPW ))) return 0;
180 if (!(handle = LoadResource( hinst, hRsrc ))) return 0;
181 }
182
183 if ((info = (BITMAPINFO *)LockResource( handle )) == NULL) return 0;
184 }
185 else
186 {
187 hMapping = VIRTUAL_MapFileW( lpszName, (LPVOID *)&ptr, TRUE);
188 if (hMapping == INVALID_HANDLE_VALUE) {
189 //TODO: last err set to ERROR_OPEN_FAILED if file not found; correct??
190 dprintf(("LoadBitmapW: failed to load file %x (lasterr=%x)", lpszName, GetLastError()));
191 return 0;
192 }
193 info = (BITMAPINFO *)(ptr + sizeof(BITMAPFILEHEADER));
194 }
195
196 //TODO: This has to be removed once pe2lx stores win32 resources!!!
197 if (info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER) &&
198 info->bmiHeader.biSize != sizeof(BITMAPINFOHEADER))
199 {//assume it contains a file header first
200 info = (BITMAPINFO *)((char *)info + sizeof(BITMAPFILEHEADER));
201 }
202
203 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
204 {//determine size of converted header
205 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
206
207 int colors = 0;
208 if (core->bcBitCount <= 8) {
209 colors = (1 << core->bcBitCount);
210 }
211 size = sizeof(BITMAPINFOHEADER) + colors * sizeof(RGBQUAD);
212 }
213 else size = DIB_BitmapInfoSize(info, DIB_RGB_COLORS);
214
215 if ((hFix = GlobalAlloc(0, size)) != NULL) fix_info = (BITMAPINFO *)GlobalLock(hFix);
216 if (fix_info)
217 {
218 BYTE pix;
219
220 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
221 {//convert old bitmap header to new format
222 ULONG colors;
223 ULONG *p, *q;
224
225 memset (fix_info, 0, sizeof (BITMAPINFOHEADER));
226 fix_info->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
227 fix_info->bmiHeader.biWidth = ((BITMAPCOREHEADER *)info)->bcWidth;
228 fix_info->bmiHeader.biHeight = ((BITMAPCOREHEADER *)info)->bcHeight;
229 fix_info->bmiHeader.biPlanes = ((BITMAPCOREHEADER *)info)->bcPlanes;
230 fix_info->bmiHeader.biBitCount = ((BITMAPCOREHEADER *)info)->bcBitCount;
231
232 if(fix_info->bmiHeader.biBitCount <= 8)
233 {
234 p = (PULONG)((char *)info + sizeof(BITMAPCOREHEADER));
235 q = (PULONG)((char *)fix_info + sizeof(BITMAPINFOHEADER));
236 //convert RGBTRIPLE to RGBQUAD
237 for (colors = 1 << fix_info->bmiHeader.biBitCount; colors > 0; colors--) {
238 *q = *p & 0x00FFFFFFUL;
239 q++;
240 p = (PULONG)((char *)p + sizeof (RGBTRIPLE));
241 }
242 }
243 }
244 else {
245 memcpy(fix_info, info, size);
246 }
247
248 size = DIB_BitmapInfoSize(info, DIB_RGB_COLORS);
249
250 pix = *((LPBYTE)info + size);
251 DIB_FixColorsToLoadflags(fix_info, fuLoad, pix);
252 if ((hdc = CreateCompatibleDC(0)) != 0)
253 {
254 char *bits = (char *)info + size;
255 if (fuLoad & LR_CREATEDIBSECTION) {
256 DIBSECTION dib;
257 hbitmap = CreateDIBSection(hdc, fix_info, DIB_RGB_COLORS, NULL, 0, 0);
258 GetObjectA(hbitmap, sizeof(DIBSECTION), &dib);
259 SetDIBits(hdc, hbitmap, 0, dib.dsBm.bmHeight, bits, info,
260 DIB_RGB_COLORS);
261 }
262 else
263 {
264#if 0
265 if(fix_info->bmiHeader.biBitCount == 1) {
266 hbitmap = CreateBitmap(fix_info->bmiHeader.biWidth,
267 fix_info->bmiHeader.biHeight,
268 fix_info->bmiHeader.biPlanes,
269 fix_info->bmiHeader.biBitCount,
270 (PVOID)bits);
271 }
272 else {
273#endif
274 hbitmap = CreateDIBitmap(hdc, &fix_info->bmiHeader, CBM_INIT,
275 bits, fix_info, DIB_RGB_COLORS );
276// }
277 if(hbitmap == 0) {
278 dprintf(("LoadBitmapW: CreateDIBitmap failed!!"));
279 }
280 }
281 DeleteDC(hdc);
282 }
283 GlobalUnlock(hFix);
284 GlobalFree(hFix);
285 }
286 if(fuLoad & LR_LOADFROMFILE) {
287 UnmapViewOfFile(ptr);
288 CloseHandle(hMapping);
289 }
290 return hbitmap;
291}
292//******************************************************************************
293//TODO: scale bitmap
294//******************************************************************************
295HANDLE CopyBitmap(HANDLE hBitmap, DWORD desiredx, DWORD desiredy)
296{
297 HBITMAP res = 0;
298 BITMAP bm;
299
300 if(GetObjectA(hBitmap, sizeof(BITMAP), &bm) == FALSE) {
301 dprintf(("CopyBitmap: GetObject failed!!"));
302 return 0;
303 }
304
305 bm.bmBits = NULL;
306 res = CreateBitmapIndirect(&bm);
307
308 if(res)
309 {
310 char *buf = (char *)HeapAlloc( GetProcessHeap(), 0, bm.bmWidthBytes *
311 bm.bmHeight );
312 GetBitmapBits (hBitmap, bm.bmWidthBytes * bm.bmHeight, buf);
313 SetBitmapBits (res, bm.bmWidthBytes * bm.bmHeight, buf);
314 HeapFree( GetProcessHeap(), 0, buf );
315 }
316 return res;
317}
318//******************************************************************************
319//TODO: No support for RT_NEWBITMAP
320//******************************************************************************
321HBITMAP WIN32API LoadBitmapA(HINSTANCE hinst, LPCSTR lpszBitmap)
322{
323 HBITMAP hBitmap = 0;
324
325 hBitmap = LoadImageA(hinst, lpszBitmap, IMAGE_BITMAP, 0, 0, 0);
326
327 if(HIWORD(lpszBitmap)) {
328 dprintf(("LoadBitmapA %x %s returned %08xh\n", hinst, lpszBitmap, hBitmap));
329 }
330 else dprintf(("LoadBitmapA %x %x returned %08xh\n", hinst, lpszBitmap, hBitmap));
331
332 return(hBitmap);
333}
334//******************************************************************************
335//TODO: No support for RT_NEWBITMAP
336//******************************************************************************
337HBITMAP WIN32API LoadBitmapW(HINSTANCE hinst, LPCWSTR lpszBitmap)
338{
339 HBITMAP hBitmap = 0;
340
341 hBitmap = LoadBitmapW((hinst == 0) ? hInstanceUser32:hinst, lpszBitmap, 0, 0, 0);
342
343 if(HIWORD(lpszBitmap)) {
344 dprintf(("LoadBitmapW %x %ls returned %08xh\n", hinst, lpszBitmap, hBitmap));
345 }
346 else dprintf(("LoadBitmapW %x %x returned %08xh\n", hinst, lpszBitmap, hBitmap));
347
348 return(hBitmap);
349}
350//******************************************************************************
351//******************************************************************************
352HANDLE WIN32API LoadImageA(HINSTANCE hinst, LPCSTR lpszName, UINT uType,
353 int cxDesired, int cyDesired, UINT fuLoad)
354{
355 HANDLE res = 0;
356 LPCWSTR u_name;
357
358 if(HIWORD(lpszName)) {
359 dprintf(("LoadImageA %x %s %d (%d,%d)\n", hinst, lpszName, uType, cxDesired, cyDesired));
360 }
361 else dprintf(("LoadImageA %x %x %d (%d,%d)\n", hinst, lpszName, uType, cxDesired, cyDesired));
362
363 if (HIWORD(lpszName)) {
364 u_name = HEAP_strdupAtoW(GetProcessHeap(), 0, lpszName);
365 }
366 else u_name=(LPWSTR)lpszName;
367
368 res = LoadImageW(hinst, u_name, uType, cxDesired, cyDesired, fuLoad);
369
370 if (HIWORD(lpszName))
371 HeapFree(GetProcessHeap(), 0, (LPVOID)u_name);
372
373 return res;
374}
375//******************************************************************************
376//******************************************************************************
377HANDLE WIN32API LoadImageW(HINSTANCE hinst, LPCWSTR lpszName, UINT uType,
378 int cxDesired, int cyDesired, UINT fuLoad)
379{
380 HANDLE hRet = 0;
381
382 if(HIWORD(lpszName)) {
383 dprintf(("LoadImageW %x %ls %d (%d,%d)\n", hinst, lpszName, uType, cxDesired, cyDesired));
384 }
385 else dprintf(("LoadImageW %x %x %d (%d,%d)\n", hinst, lpszName, uType, cxDesired, cyDesired));
386
387 if (fuLoad & LR_DEFAULTSIZE) {
388 if (uType == IMAGE_ICON) {
389 if (!cxDesired) cxDesired = GetSystemMetrics(SM_CXICON);
390 if (!cyDesired) cyDesired = GetSystemMetrics(SM_CYICON);
391 }
392 else if (uType == IMAGE_CURSOR) {
393 if (!cxDesired) cxDesired = GetSystemMetrics(SM_CXCURSOR);
394 if (!cyDesired) cyDesired = GetSystemMetrics(SM_CYCURSOR);
395 }
396 }
397 if (fuLoad & LR_LOADFROMFILE) fuLoad &= ~LR_SHARED;
398
399 switch (uType)
400 {
401 case IMAGE_BITMAP:
402 {
403 hRet = (HANDLE)LoadBitmapW(hinst, lpszName, cxDesired, cyDesired, fuLoad);
404 break;
405 }
406 case IMAGE_ICON:
407 {
408#ifdef __WIN32OS2__
409 ULONG palEnts = (1 << ScreenBitsPerPel);
410#else
411 HDC hdc = GetDC(0);
412 UINT palEnts = GetSystemPaletteEntries(hdc, 0, 0, NULL);
413 if (palEnts == 0)
414 palEnts = 256;
415 ReleaseDC(0, hdc);
416#endif
417
418 hRet = CURSORICON_Load(hinst, lpszName, cxDesired, cyDesired, palEnts, FALSE, fuLoad);
419 break;
420 }
421
422 case IMAGE_CURSOR:
423 return CURSORICON_Load(hinst, lpszName, cxDesired, cyDesired, 1, TRUE, fuLoad);
424
425 default:
426 dprintf(("LoadImageW: unsupported type %d!!", uType));
427 return 0;
428 }
429 dprintf(("LoadImageW returned %x\n", (int)hRet));
430
431 return(hRet);
432}
433/******************************************************************************
434 * CopyImage32 [USER32.61] Creates new image and copies attributes to it
435 *
436 * PARAMS
437 * hnd [I] Handle to image to copy
438 * type [I] Type of image to copy
439 * desiredx [I] Desired width of new image
440 * desiredy [I] Desired height of new image
441 * flags [I] Copy flags
442 *
443 * RETURNS
444 * Success: Handle to newly created image
445 * Failure: NULL
446 *
447 * FIXME: implementation still lacks nearly all features, see LR_*
448 * defines in windows.h
449 *
450 */
451HICON WINAPI CopyImage(HANDLE hnd, UINT type, INT desiredx,
452 INT desiredy, UINT flags )
453{
454 dprintf(("CopyImage %x %d (%d,%d) %x", hnd, type, desiredx, desiredy, flags));
455 switch (type)
456 {
457 case IMAGE_BITMAP:
458 return CopyBitmap(hnd, desiredx, desiredy);
459 case IMAGE_ICON:
460 return (HANDLE)CURSORICON_ExtCopy(hnd, type, desiredx, desiredy, flags);
461 case IMAGE_CURSOR:
462 /* Should call CURSORICON_ExtCopy but more testing
463 * needs to be done before we change this
464 */
465 return CURSORICON_ExtCopy(hnd,type, desiredx, desiredy, flags);
466 default:
467 dprintf(("CopyImage: Unsupported type"));
468 }
469 return 0;
470}
471//******************************************************************************
472//******************************************************************************
Note: See TracBrowser for help on using the repository browser.