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

Last change on this file since 4573 was 4573, checked in by sandervl, 25 years ago

Icon api rewrite + small fixes

File size: 17.7 KB
Line 
1/* $Id: loadres.cpp,v 1.33 2000-11-09 18:15:18 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 <win\cursoricon.h>
28#include <winres.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;
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;
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;
91 return 0;
92 }
93 }
94 }
95
96#ifdef DEBUG_ENABLELOG_LEVEL2
97 if(i) {
98 char *astring = (char *)HEAP_strdupWtoA(GetProcessHeap(), 0, lpBuffer);
99 dprintf(("LoadStringW from %X, id %d %s\n", hinst, wID, astring));
100 HEAP_free(astring);
101 }
102#else
103 dprintf(("LoadStringW from %X, id %d buffersize %d\n", hinst, wID, cchBuffer));
104#endif
105 return(i);
106}
107//******************************************************************************
108//******************************************************************************
109HICON WIN32API LoadIconA(HINSTANCE hinst, LPCSTR lpszIcon)
110{
111 if(HIWORD(lpszIcon)) {
112 dprintf(("LoadIconA %x %s", hinst, lpszIcon));
113 }
114 else dprintf(("LoadIconA %x %x", hinst, lpszIcon));
115 return LoadImageA(hinst, lpszIcon, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE);
116}
117//******************************************************************************
118//******************************************************************************
119HICON WIN32API LoadIconW(HINSTANCE hinst, LPCWSTR lpszIcon)
120{
121 dprintf(("LoadIconA %x %x", hinst, lpszIcon));
122 return LoadImageW(hinst, lpszIcon, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE);
123}
124//******************************************************************************
125//******************************************************************************
126HCURSOR LoadCursorW(HINSTANCE hinst, LPCWSTR lpszCursor, DWORD cxDesired,
127 DWORD cyDesired, DWORD fuLoad)
128{
129 HCURSOR hCursor;
130 HANDLE hMapping = 0;
131 char *ptr = NULL;
132 HRSRC hRes;
133 LPSTR restype = RT_CURSORA;
134 LPVOID lpOS2Resdata = NULL;
135
136 if(fuLoad & LR_LOADFROMFILE)
137 {
138 hMapping = VIRTUAL_MapFileW( lpszCursor, (LPVOID *)&ptr, TRUE);
139 if(hMapping == INVALID_HANDLE_VALUE)
140 return 0;
141
142 lpOS2Resdata = ConvertCursorToOS2(ptr);
143 hCursor = OSLibWinCreatePointer(lpOS2Resdata, cxDesired, cyDesired);
144 FreeOS2Resource(lpOS2Resdata);
145
146 UnmapViewOfFile(ptr);
147 CloseHandle(hMapping);
148 }
149 else
150 {
151 if(!hinst)
152 {
153 hRes = FindResourceW(hInstanceUser32,lpszCursor,RT_CURSORW);
154 if(!hRes) {
155 hRes = FindResourceW(hInstanceUser32,lpszCursor,RT_GROUP_CURSORW);
156 restype = RT_GROUP_CURSORA;
157 }
158 if(hRes)
159 {
160 lpOS2Resdata = ConvertResourceToOS2(hInstanceUser32, restype, hRes);
161 hCursor = OSLibWinCreatePointer(lpOS2Resdata, cxDesired, cyDesired);
162 FreeOS2Resource(lpOS2Resdata);
163 }
164 else hCursor = OSLibWinQuerySysPointer((ULONG)lpszCursor, cxDesired, cyDesired);
165 }
166 else
167 { //not a system icon
168 hRes = FindResourceW(hinst,lpszCursor,RT_CURSORW);
169 if(!hRes) {
170 hRes = FindResourceW(hinst,lpszCursor,RT_GROUP_CURSORW);
171 restype = RT_GROUP_CURSORA;
172 }
173 if(hRes) {
174 lpOS2Resdata = ConvertResourceToOS2(hinst, restype, hRes);
175 hCursor = OSLibWinCreatePointer(lpOS2Resdata, cxDesired, cyDesired);
176 FreeOS2Resource(lpOS2Resdata);
177 }
178 else hCursor = 0;
179 }
180 }
181 dprintf(("LoadCursorA %x from %x returned %x\n", lpszCursor, hinst, hCursor));
182
183 return(hCursor);
184}
185//******************************************************************************
186//******************************************************************************
187HCURSOR WIN32API LoadCursorA(HINSTANCE hinst, LPCSTR lpszCursor)
188{
189 return LoadImageA(hinst, lpszCursor, IMAGE_CURSOR, 0, 0,
190 LR_SHARED | LR_DEFAULTSIZE );
191}
192//******************************************************************************
193//******************************************************************************
194HCURSOR WIN32API LoadCursorW(HINSTANCE hinst, LPCWSTR lpszCursor)
195{
196 return LoadImageW(hinst, lpszCursor, IMAGE_CURSOR, 0, 0,
197 LR_SHARED | LR_DEFAULTSIZE );
198}
199/***********************************************************************
200* LoadCursorFromFileW (USER32.361)
201*/
202HCURSOR WIN32API LoadCursorFromFileW (LPCWSTR name)
203{
204 return LoadImageW(0, name, IMAGE_CURSOR, 0, 0,
205 LR_LOADFROMFILE | LR_DEFAULTSIZE );
206}
207/***********************************************************************
208* LoadCursorFromFileA (USER32.360)
209*/
210HCURSOR WIN32API LoadCursorFromFileA (LPCSTR name)
211{
212 return LoadImageA(0, name, IMAGE_CURSOR, 0, 0,
213 LR_LOADFROMFILE | LR_DEFAULTSIZE );
214}
215//******************************************************************************
216//NOTE: LR_CREATEDIBSECTION flag doesn't work (crash in GDI32)! (still??)
217//******************************************************************************
218HANDLE LoadBitmapW(HINSTANCE hinst, LPCWSTR lpszName, int cxDesired, int cyDesired,
219 UINT fuLoad)
220{
221 HBITMAP hbitmap = 0;
222 HDC hdc;
223 HRSRC hRsrc;
224 HGLOBAL handle, hMapping = 0;
225 char *ptr = NULL;
226 BITMAPINFO *info, *fix_info=NULL;
227 HGLOBAL hFix;
228 int size;
229
230 if (!(fuLoad & LR_LOADFROMFILE))
231 {
232 handle = 0;
233 if(!hinst)
234 {
235 hRsrc = FindResourceW( hInstanceUser32, lpszName, RT_BITMAPW );
236 if(hRsrc) {
237 handle = LoadResource( hInstanceUser32, hRsrc );
238 }
239 }
240 if(handle == 0)
241 {
242 if (!(hRsrc = FindResourceW( hinst, lpszName, RT_BITMAPW ))) return 0;
243 if (!(handle = LoadResource( hinst, hRsrc ))) return 0;
244 }
245
246 if ((info = (BITMAPINFO *)LockResource( handle )) == NULL) return 0;
247 }
248 else
249 {
250 hMapping = VIRTUAL_MapFileW( lpszName, (LPVOID *)&ptr, TRUE);
251 if (hMapping == INVALID_HANDLE_VALUE) {
252 //TODO: last err set to ERROR_OPEN_FAILED if file not found; correct??
253 dprintf(("LoadBitmapW: failed to load file %x (lasterr=%x)", lpszName, GetLastError()));
254 return 0;
255 }
256 info = (BITMAPINFO *)(ptr + sizeof(BITMAPFILEHEADER));
257 }
258
259 //TODO: This has to be removed once pe2lx stores win32 resources!!!
260 if (info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER) &&
261 info->bmiHeader.biSize != sizeof(BITMAPINFOHEADER))
262 {//assume it contains a file header first
263 info = (BITMAPINFO *)((char *)info + sizeof(BITMAPFILEHEADER));
264 }
265
266 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) {
267 size = sizeof(BITMAPINFOHEADER) +
268 (sizeof (RGBTRIPLE) << ((BITMAPCOREHEADER *)info)->bcBitCount);
269 } else
270 size = DIB_BitmapInfoSize(info, DIB_RGB_COLORS);
271
272 if ((hFix = GlobalAlloc(0, size)) != NULL) fix_info = (BITMAPINFO *)GlobalLock(hFix);
273 if (fix_info) {
274 BYTE pix;
275
276 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) {
277 ULONG colors;
278 ULONG *p, *q;
279
280 memset (fix_info, 0, sizeof (BITMAPINFOHEADER));
281 fix_info->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
282 fix_info->bmiHeader.biWidth = ((BITMAPCOREHEADER *)info)->bcWidth;
283 fix_info->bmiHeader.biHeight = ((BITMAPCOREHEADER *)info)->bcHeight;
284 fix_info->bmiHeader.biPlanes = ((BITMAPCOREHEADER *)info)->bcPlanes;
285 fix_info->bmiHeader.biBitCount = ((BITMAPCOREHEADER *)info)->bcBitCount;
286
287 p = (PULONG)((char *)info + sizeof(BITMAPCOREHEADER));
288 q = (PULONG)((char *)fix_info + sizeof(BITMAPINFOHEADER));
289 for (colors = 1 << fix_info->bmiHeader.biBitCount; colors > 0; colors--) {
290 *q = *p & 0x00FFFFFFUL;
291 q++;
292 p = (PULONG)((char *)p + sizeof (RGBTRIPLE));
293 }
294 } else
295 memcpy(fix_info, info, size);
296
297 size = DIB_BitmapInfoSize(info, DIB_RGB_COLORS);
298 pix = *((LPBYTE)info + size);
299 DIB_FixColorsToLoadflags(fix_info, fuLoad, pix);
300 if ((hdc = GetDC(0)) != 0) {
301 char *bits = (char *)info + size;
302 if (fuLoad & LR_CREATEDIBSECTION) {
303 DIBSECTION dib;
304 hbitmap = CreateDIBSection(hdc, fix_info, DIB_RGB_COLORS, NULL, 0, 0);
305 GetObjectA(hbitmap, sizeof(DIBSECTION), &dib);
306 SetDIBits(hdc, hbitmap, 0, dib.dsBm.bmHeight, bits, info,
307 DIB_RGB_COLORS);
308 }
309 else {
310// if(fix_info->bmiHeader.biBitCount == 1) {
311// hbitmap = CreateBitmap(fix_info->bmiHeader.biWidth,
312// fix_info->bmiHeader.biHeight,
313// fix_info->bmiHeader.biPlanes,
314// fix_info->bmiHeader.biBitCount,
315// (PVOID)bits);
316// }
317// else {
318 hbitmap = CreateDIBitmap(hdc, &fix_info->bmiHeader, CBM_INIT,
319 bits, fix_info, DIB_RGB_COLORS );
320 if(hbitmap == 0) {
321 dprintf(("LoadBitmapW: CreateDIBitmap failed!!"));
322 }
323// }
324 }
325 ReleaseDC( 0, hdc );
326 }
327 GlobalUnlock(hFix);
328 GlobalFree(hFix);
329 }
330 if(fuLoad & LR_LOADFROMFILE) {
331 UnmapViewOfFile(ptr);
332 CloseHandle(hMapping);
333 }
334 return hbitmap;
335}
336//******************************************************************************
337//TODO: scale bitmap
338//******************************************************************************
339HANDLE CopyBitmap(HANDLE hBitmap, DWORD desiredx, DWORD desiredy)
340{
341 HBITMAP res = 0;
342 BITMAP bm;
343
344 if(GetObjectA(hBitmap, sizeof(BITMAP), &bm) == FALSE) {
345 dprintf(("CopyBitmap: GetObject failed!!"));
346 return 0;
347 }
348
349 bm.bmBits = NULL;
350 res = CreateBitmapIndirect(&bm);
351
352 if(res)
353 {
354 char *buf = (char *)HeapAlloc( GetProcessHeap(), 0, bm.bmWidthBytes *
355 bm.bmHeight );
356 GetBitmapBits (hBitmap, bm.bmWidthBytes * bm.bmHeight, buf);
357 SetBitmapBits (res, bm.bmWidthBytes * bm.bmHeight, buf);
358 HeapFree( GetProcessHeap(), 0, buf );
359 }
360 return res;
361}
362//******************************************************************************
363//TODO: No support for RT_NEWBITMAP
364//******************************************************************************
365HBITMAP WIN32API LoadBitmapA(HINSTANCE hinst, LPCSTR lpszBitmap)
366{
367 HBITMAP hBitmap = 0;
368
369 hBitmap = LoadImageA(hinst, lpszBitmap, IMAGE_BITMAP, 0, 0, 0);
370
371 if(HIWORD(lpszBitmap)) {
372 dprintf(("LoadBitmapA %x %s returned %08xh\n", hinst, lpszBitmap, hBitmap));
373 }
374 else dprintf(("LoadBitmapA %x %x returned %08xh\n", hinst, lpszBitmap, hBitmap));
375
376 return(hBitmap);
377}
378//******************************************************************************
379//TODO: No support for RT_NEWBITMAP
380//******************************************************************************
381HBITMAP WIN32API LoadBitmapW(HINSTANCE hinst, LPCWSTR lpszBitmap)
382{
383 HBITMAP hBitmap = 0;
384
385 hBitmap = LoadBitmapW((hinst == 0) ? hInstanceUser32:hinst, lpszBitmap, 0, 0, 0);
386
387 if(HIWORD(lpszBitmap)) {
388 dprintf(("LoadBitmapW %x %s returned %08xh\n", hinst, lpszBitmap, hBitmap));
389 }
390 else dprintf(("LoadBitmapW %x %x returned %08xh\n", hinst, lpszBitmap, hBitmap));
391
392 return(hBitmap);
393}
394//******************************************************************************
395//******************************************************************************
396HANDLE WIN32API LoadImageA(HINSTANCE hinst, LPCSTR lpszName, UINT uType,
397 int cxDesired, int cyDesired, UINT fuLoad)
398{
399 HANDLE res = 0;
400 LPCWSTR u_name;
401
402 if(HIWORD(lpszName)) {
403 dprintf(("LoadImageA %x %s %d (%d,%d)\n", hinst, lpszName, uType, cxDesired, cyDesired));
404 }
405 else dprintf(("LoadImageA %x %x %d (%d,%d)\n", hinst, lpszName, uType, cxDesired, cyDesired));
406
407 if (HIWORD(lpszName)) {
408 u_name = HEAP_strdupAtoW(GetProcessHeap(), 0, lpszName);
409 }
410 else u_name=(LPWSTR)lpszName;
411
412 res = LoadImageW(hinst, u_name, uType, cxDesired, cyDesired, fuLoad);
413
414 if (HIWORD(lpszName))
415 HeapFree(GetProcessHeap(), 0, (LPVOID)u_name);
416
417 return res;
418}
419//******************************************************************************
420//******************************************************************************
421HANDLE WIN32API LoadImageW(HINSTANCE hinst, LPCWSTR lpszName, UINT uType,
422 int cxDesired, int cyDesired, UINT fuLoad)
423{
424 HANDLE hRet = 0;
425
426 dprintf(("LoadImageW %x %x %d (%d,%d)\n", hinst, lpszName, uType, cxDesired, cyDesired));
427
428 if (fuLoad & LR_DEFAULTSIZE) {
429 if (uType == IMAGE_ICON) {
430 if (!cxDesired) cxDesired = GetSystemMetrics(SM_CXICON);
431 if (!cyDesired) cyDesired = GetSystemMetrics(SM_CYICON);
432 }
433 else if (uType == IMAGE_CURSOR) {
434 if (!cxDesired) cxDesired = GetSystemMetrics(SM_CXCURSOR);
435 if (!cyDesired) cyDesired = GetSystemMetrics(SM_CYCURSOR);
436 }
437 }
438 if (fuLoad & LR_LOADFROMFILE) fuLoad &= ~LR_SHARED;
439
440 switch (uType)
441 {
442 case IMAGE_BITMAP:
443 {
444 hRet = (HANDLE)LoadBitmapW(hinst, lpszName, cxDesired, cyDesired, fuLoad);
445 break;
446 }
447 case IMAGE_ICON:
448 {
449 HDC hdc = GetDC(0);
450 UINT palEnts = GetSystemPaletteEntries(hdc, 0, 0, NULL);
451 if (palEnts == 0)
452 palEnts = 256;
453 ReleaseDC(0, hdc);
454
455 hRet = CURSORICON_Load(hinst, lpszName, cxDesired, cyDesired, palEnts, FALSE, fuLoad);
456 break;
457 }
458
459 case IMAGE_CURSOR:
460 hRet = (HANDLE)LoadCursorW(hinst, lpszName, cxDesired, cyDesired, fuLoad);
461 break;
462// return CURSORICON_Load(hinst, name, desiredx, desiredy, 1, TRUE, loadflags);
463
464 default:
465 dprintf(("LoadImageW: unsupported type %d!!", uType));
466 return 0;
467 }
468 dprintf(("LoadImageW returned %x\n", (int)hRet));
469
470 return(hRet);
471}
472/******************************************************************************
473 * CopyImage32 [USER32.61] Creates new image and copies attributes to it
474 *
475 * PARAMS
476 * hnd [I] Handle to image to copy
477 * type [I] Type of image to copy
478 * desiredx [I] Desired width of new image
479 * desiredy [I] Desired height of new image
480 * flags [I] Copy flags
481 *
482 * RETURNS
483 * Success: Handle to newly created image
484 * Failure: NULL
485 *
486 * FIXME: implementation still lacks nearly all features, see LR_*
487 * defines in windows.h
488 *
489 */
490HICON WINAPI CopyImage(HANDLE hnd, UINT type, INT desiredx,
491 INT desiredy, UINT flags )
492{
493 dprintf(("CopyImage %x %d (%d,%d) %x", hnd, type, desiredx, desiredy, flags));
494 switch (type)
495 {
496 case IMAGE_BITMAP:
497 return CopyBitmap(hnd, desiredx, desiredy);
498 case IMAGE_ICON:
499 return (HANDLE)CURSORICON_ExtCopy(hnd, type, desiredx, desiredy, flags);
500 case IMAGE_CURSOR:
501 /* Should call CURSORICON_ExtCopy but more testing
502 * needs to be done before we change this
503 */
504 return O32_CopyCursor(hnd);
505// return CopyCursorIcon(hnd,type, desiredx, desiredy, flags);
506 default:
507 dprintf(("CopyImage: Unsupported type"));
508 }
509 return 0;
510}
511//******************************************************************************
512//******************************************************************************
Note: See TracBrowser for help on using the repository browser.