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

Last change on this file since 2388 was 2388, checked in by sandervl, 26 years ago

titlebar/sysmenu fixes + LoadBitmap fix for system bitmaps

File size: 17.9 KB
Line 
1/* $Id: loadres.cpp,v 1.20 2000-01-09 16:52:53 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 <winres.h>
23#include <heapstring.h>
24#include <oslibres.h>
25#include <win\virtual.h>
26#include "dib.h"
27#include "initterm.h"
28#include <win\cursoricon.h>
29
30//******************************************************************************
31//******************************************************************************
32INT WIN32API LoadStringA(HINSTANCE instance, UINT resource_id,
33 LPSTR buffer, INT buflen )
34{
35 INT retval;
36 LPWSTR buffer2 = NULL;
37
38 if (buffer && buflen)
39 buffer2 = (LPWSTR)HeapAlloc( GetProcessHeap(), 0, buflen * 2 );
40
41 retval = LoadStringW(instance,resource_id,buffer2,buflen);
42
43 if (buffer2)
44 {
45 if (retval) {
46 lstrcpynWtoA( buffer, buffer2, buflen );
47 retval = lstrlenA( buffer );
48 }
49 else
50 *buffer = 0;
51 HeapFree( GetProcessHeap(), 0, buffer2 );
52 }
53 return retval;
54}
55//******************************************************************************
56//******************************************************************************
57int WIN32API LoadStringW(HINSTANCE hinst, UINT wID, LPWSTR lpBuffer, int cchBuffer)
58{
59 Win32Resource *winres;
60 WCHAR *p;
61 int string_num;
62 int i = 0;
63
64 /* Use bits 4 - 19 (incremented by 1) as resourceid, mask out
65 * 20 - 31. */
66 winres = (Win32Resource *)FindResourceW(hinst, (LPWSTR)(((wID>>4)&0xffff)+1), RT_STRINGW);
67 if(winres == NULL) {
68 dprintf(("LoadStringW NOT FOUND from %X, id %d buffersize %d\n", hinst, wID, cchBuffer));
69 *lpBuffer = 0;
70 return 0;
71 }
72
73 p = (LPWSTR)winres->lockResource();
74 if(p) {
75 string_num = wID & 0x000f;
76 for (i = 0; i < string_num; i++)
77 p += *p + 1;
78
79 if (lpBuffer == NULL) return *p;
80 i = min(cchBuffer - 1, *p);
81 if (i > 0) {
82 memcpy(lpBuffer, p + 1, i * sizeof (WCHAR));
83 lpBuffer[i] = (WCHAR) 0;
84 }
85 else {
86 if (cchBuffer > 1) {
87 lpBuffer[0] = (WCHAR) 0;
88 return 0;
89 }
90 }
91 }
92 delete winres;
93
94#ifdef DEBUG_ENABLELOG_LEVEL2
95 if(i) {
96 char *astring = (char *)HEAP_strdupWtoA(GetProcessHeap(), 0, lpBuffer);
97 dprintf(("LoadStringW from %X, id %d %s\n", hinst, wID, astring));
98 HEAP_free(astring);
99 }
100#else
101 dprintf(("LoadStringW from %X, id %d buffersize %d\n", hinst, wID, cchBuffer));
102#endif
103 return(i);
104}
105//******************************************************************************
106//******************************************************************************
107HICON WIN32API LoadIconA(HINSTANCE hinst, LPCSTR lpszIcon)
108{
109 Win32Resource *winres;
110 HICON hIcon;
111
112 if (!hinst)
113 {
114 winres = (Win32Resource*)FindResourceA(hInstanceUser32,lpszIcon,RT_ICONA);
115 if (!winres) winres = (Win32Resource*)FindResourceA(hInstanceUser32,lpszIcon,RT_GROUP_ICONA);
116 if (winres)
117 {
118 hIcon = OSLibWinCreateIcon(winres->lockOS2Resource());
119 delete winres;
120 } else hIcon = OSLibWinQuerySysIcon((ULONG)lpszIcon,GetSystemMetrics(SM_CXICON),GetSystemMetrics(SM_CYICON));
121 } else
122 { //not a system icon
123 winres = (Win32Resource *)FindResourceA(hinst, lpszIcon, RT_ICONA);
124 if(winres == 0) {
125 winres = (Win32Resource *)FindResourceA(hinst, lpszIcon, RT_GROUP_ICONA);
126 }
127 if(winres) {
128 hIcon = OSLibWinCreateIcon(winres->lockOS2Resource());
129 delete winres;
130 } else hIcon = 0;
131 }
132 dprintf(("LoadIconA (%X) returned %x\n", hinst, hIcon));
133
134 return(hIcon);
135}
136//******************************************************************************
137//******************************************************************************
138HICON WIN32API LoadIconW(HINSTANCE hinst, LPCWSTR lpszIcon)
139{
140 Win32Resource *winres;
141 HICON hIcon;
142
143 if (!hinst)
144 {
145 winres = (Win32Resource*)FindResourceW(hInstanceUser32,lpszIcon,RT_ICONW);
146 if (!winres) winres = (Win32Resource*)FindResourceW(hInstanceUser32,lpszIcon,RT_GROUP_ICONW);
147 if (winres)
148 {
149 hIcon = OSLibWinCreateIcon(winres->lockOS2Resource());
150 delete winres;
151 } else hIcon = OSLibWinQuerySysIcon((ULONG)lpszIcon,GetSystemMetrics(SM_CXICON),GetSystemMetrics(SM_CYICON));
152 } else
153 {//not a system icon
154 winres = (Win32Resource *)FindResourceW(hinst, lpszIcon, RT_ICONW);
155 if(winres == 0) {
156 winres = (Win32Resource *)FindResourceW(hinst, lpszIcon, RT_GROUP_ICONW);
157 }
158 if(winres) {
159 hIcon = OSLibWinCreateIcon(winres->lockOS2Resource());
160 delete winres;
161 } else hIcon = 0;
162 }
163 dprintf(("LoadIconW (%X) returned %x\n", hinst, hIcon));
164
165 return(hIcon);
166}
167//******************************************************************************
168//******************************************************************************
169HCURSOR WIN32API LoadCursorA(HINSTANCE hinst, LPCSTR lpszCursor)
170{
171 Win32Resource *winres;
172 HCURSOR hCursor;
173
174 if (!hinst)
175 {
176 winres = (Win32Resource*)FindResourceA(hInstanceUser32,lpszCursor,RT_CURSORA);
177 if (!winres) winres = (Win32Resource*)FindResourceA(hInstanceUser32,lpszCursor,RT_GROUP_CURSORA);
178 if (winres)
179 {
180 hCursor = OSLibWinCreatePointer(winres->lockOS2Resource());
181 delete winres;
182 } else hCursor = OSLibWinQuerySysPointer((ULONG)lpszCursor,GetSystemMetrics(SM_CXCURSOR),GetSystemMetrics(SM_CYCURSOR));
183 } else
184 {//not a system pointer
185 winres = (Win32Resource *)FindResourceA(hinst, lpszCursor, RT_CURSORA);
186 if(winres == 0) {
187 winres = (Win32Resource *)FindResourceA(hinst, lpszCursor, RT_GROUP_CURSORA);
188 }
189 if(winres) {
190 hCursor = OSLibWinCreatePointer(winres->lockOS2Resource());
191 delete winres;
192 } else hCursor = 0;
193 }
194 if(HIWORD(lpszCursor)) {
195 dprintf(("LoadCursorA %s from %x returned %x\n", lpszCursor, hinst, hCursor));
196 }
197 else dprintf(("LoadCursorA %x from %x returned %x\n", lpszCursor, hinst, hCursor));
198
199 return(hCursor);
200}
201//******************************************************************************
202//******************************************************************************
203HCURSOR WIN32API LoadCursorW(HINSTANCE hinst, LPCWSTR lpszCursor)
204{
205 Win32Resource *winres;
206 HCURSOR hCursor;
207
208 if (!hinst)
209 {
210 winres = (Win32Resource*)FindResourceW(hInstanceUser32,lpszCursor,RT_CURSORW);
211 if (!winres) winres = (Win32Resource*)FindResourceW(hInstanceUser32,lpszCursor,RT_GROUP_CURSORW);
212 if (winres)
213 {
214 hCursor = OSLibWinCreatePointer(winres->lockOS2Resource());
215 delete winres;
216 } else hCursor = OSLibWinQuerySysPointer((ULONG)lpszCursor,GetSystemMetrics(SM_CXCURSOR),GetSystemMetrics(SM_CYCURSOR));
217 } else
218 {//not a system pointer
219 winres = (Win32Resource *)FindResourceW(hinst, lpszCursor, RT_CURSORW);
220 if(winres == 0) {
221 winres = (Win32Resource *)FindResourceW(hinst, lpszCursor, RT_GROUP_CURSORW);
222 }
223 if(winres) {
224 hCursor = OSLibWinCreatePointer(winres->lockOS2Resource());
225 delete winres;
226 } else hCursor = 0;
227 }
228 dprintf(("LoadCursorW (%X) returned %x\n", hinst, hCursor));
229
230 return(hCursor);
231}
232//******************************************************************************
233//******************************************************************************
234BOOL IsSystemBitmap(ULONG *id)
235{
236 switch(*id)
237 {
238 case OBM_UPARROW:
239 case OBM_DNARROW:
240 case OBM_RGARROW:
241 case OBM_LFARROW:
242 case OBM_RESTORE:
243 case OBM_RESTORED:
244 case OBM_UPARROWD:
245 case OBM_DNARROWD:
246 case OBM_RGARROWD:
247 case OBM_LFARROWD:
248 case OBM_OLD_UPARROW:
249 case OBM_OLD_DNARROW:
250 case OBM_OLD_RGARROW:
251 case OBM_OLD_LFARROW:
252 case OBM_CHECK:
253 case OBM_CHECKBOXES:
254 case OBM_BTNCORNERS:
255 case OBM_COMBO:
256 case OBM_REDUCE:
257 case OBM_REDUCED:
258 case OBM_ZOOM:
259 case OBM_ZOOMD:
260 case OBM_SIZE:
261 case OBM_CLOSE:
262 case OBM_MNARROW:
263 case OBM_UPARROWI:
264 case OBM_DNARROWI:
265 case OBM_RGARROWI:
266 case OBM_LFARROWI:
267 case OBM_CLOSED:
268 case OBM_OLD_CLOSE:
269 case OBM_BTSIZE:
270 case OBM_OLD_REDUCE:
271 case OBM_OLD_ZOOM:
272 case OBM_OLD_RESTORE:
273 return TRUE;
274
275 default:
276 return FALSE;
277 }
278}
279//******************************************************************************
280//NOTE: LR_CREATEDIBSECTION flag doesn't work (crash in GDI32)!
281//******************************************************************************
282HANDLE LoadBitmapA(HINSTANCE hinst, LPCSTR lpszName, int cxDesired, int cyDesired,
283 UINT fuLoad)
284{
285 HBITMAP hbitmap = 0;
286 HDC hdc;
287 HRSRC hRsrc;
288 HGLOBAL handle, hMapping = 0;
289 char *ptr = NULL;
290 BITMAPINFO *info, *fix_info=NULL;
291 HGLOBAL hFix;
292 int size;
293
294 if (!(fuLoad & LR_LOADFROMFILE)) {
295 if (!(hRsrc = FindResourceA( hinst, lpszName, RT_BITMAPA ))) return 0;
296 if (!(handle = LoadResource( hinst, hRsrc ))) return 0;
297
298 if ((info = (BITMAPINFO *)LockResource( handle )) == NULL) return 0;
299 }
300 else
301 {
302 hMapping = VIRTUAL_MapFileA( lpszName, (LPVOID *)&ptr, TRUE);
303 if (hMapping == INVALID_HANDLE_VALUE) return 0;
304 info = (BITMAPINFO *)(ptr + sizeof(BITMAPFILEHEADER));
305 }
306
307 //TODO: This has to be removed once pe2lx stores win32 resources!!!
308 if (info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER) &&
309 info->bmiHeader.biSize != sizeof(BITMAPINFOHEADER))
310 {//assume it contains a file header first
311 info = (BITMAPINFO *)((char *)info + sizeof(BITMAPFILEHEADER));
312 }
313
314 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) {
315 size = sizeof(BITMAPINFOHEADER) +
316 (sizeof (RGBTRIPLE) << ((BITMAPCOREHEADER *)info)->bcBitCount);
317 } else
318 size = DIB_BitmapInfoSize(info, DIB_RGB_COLORS);
319
320 if ((hFix = GlobalAlloc(0, size)) != NULL) fix_info = (BITMAPINFO *)GlobalLock(hFix);
321 if (fix_info) {
322 BYTE pix;
323
324 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) {
325 ULONG colors;
326 ULONG *p, *q;
327
328 memset (fix_info, 0, sizeof (BITMAPINFOHEADER));
329 fix_info->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
330 fix_info->bmiHeader.biWidth = ((BITMAPCOREHEADER *)info)->bcWidth;
331 fix_info->bmiHeader.biHeight = ((BITMAPCOREHEADER *)info)->bcHeight;
332 fix_info->bmiHeader.biPlanes = ((BITMAPCOREHEADER *)info)->bcPlanes;
333 fix_info->bmiHeader.biBitCount = ((BITMAPCOREHEADER *)info)->bcBitCount;
334
335 p = (PULONG)((char *)info + sizeof(BITMAPCOREHEADER));
336 q = (PULONG)((char *)fix_info + sizeof(BITMAPINFOHEADER));
337 for (colors = 1 << fix_info->bmiHeader.biBitCount; colors > 0; colors--) {
338 *q = *p & 0x00FFFFFFUL;
339 q++;
340 p = (PULONG)((char *)p + sizeof (RGBTRIPLE));
341 }
342 } else
343 memcpy(fix_info, info, size);
344
345 size = DIB_BitmapInfoSize(info, DIB_RGB_COLORS);
346 pix = *((LPBYTE)info + size);
347 DIB_FixColorsToLoadflags(fix_info, fuLoad, pix);
348 if ((hdc = GetDC(0)) != 0) {
349 char *bits = (char *)info + size;
350 if (fuLoad & LR_CREATEDIBSECTION) {
351 DIBSECTION dib;
352 hbitmap = CreateDIBSection(hdc, fix_info, DIB_RGB_COLORS, NULL, 0, 0);
353 GetObjectA(hbitmap, sizeof(DIBSECTION), &dib);
354 SetDIBits(hdc, hbitmap, 0, dib.dsBm.bmHeight, bits, info,
355 DIB_RGB_COLORS);
356 }
357 else {
358 hbitmap = CreateDIBitmap( hdc, &fix_info->bmiHeader, CBM_INIT,
359 bits, fix_info, DIB_RGB_COLORS );
360 }
361 ReleaseDC( 0, hdc );
362 }
363 GlobalUnlock(hFix);
364 GlobalFree(hFix);
365 }
366 if (fuLoad & LR_LOADFROMFILE) CloseHandle( hMapping );
367 return hbitmap;
368}
369//******************************************************************************
370//TODO: No support for RT_NEWBITMAP
371//******************************************************************************
372HBITMAP WIN32API LoadBitmapA(HINSTANCE hinst, LPCSTR lpszBitmap)
373{
374 HBITMAP hBitmap = 0;
375
376 if (!hinst)
377 {
378 if(IsSystemBitmap((ULONG *)&lpszBitmap))
379 {
380 hBitmap = LoadBitmapA(hInstanceUser32, lpszBitmap, 0, 0, 0);
381 }
382 }
383 if(!hBitmap)
384 hBitmap = LoadBitmapA(hinst, lpszBitmap, 0, 0, 0);
385
386 dprintf(("LoadBitmapA returned %08xh\n", hBitmap));
387
388 return(hBitmap);
389}
390//******************************************************************************
391//TODO: No support for RT_NEWBITMAP
392//******************************************************************************
393HBITMAP WIN32API LoadBitmapW(HINSTANCE hinst, LPCWSTR lpszBitmap)
394{
395 HBITMAP hBitmap = 0;
396
397 if(HIWORD(lpszBitmap) != 0)
398 lpszBitmap = (LPWSTR)UnicodeToAsciiString((LPWSTR)lpszBitmap);
399
400 hBitmap = LoadBitmapA((hinst == 0) ? hInstanceUser32:hinst, (LPSTR)lpszBitmap, 0, 0, 0);
401
402 if(HIWORD(lpszBitmap) != 0)
403 FreeAsciiString((LPSTR)lpszBitmap);
404
405 dprintf(("LoadBitmapW returned %08xh\n", hBitmap));
406
407 return(hBitmap);
408}
409//******************************************************************************
410//TODO: Far from complete, but works for loading resources from exe
411//fuLoad flag ignored
412//******************************************************************************
413HANDLE WIN32API LoadImageA(HINSTANCE hinst, LPCSTR lpszName, UINT uType,
414 int cxDesired, int cyDesired, UINT fuLoad)
415{
416 HANDLE hRet = 0;
417
418 if(HIWORD(lpszName)) {
419 dprintf(("LoadImageA NOT COMPLETE %x %s %d (%d,%d)\n", hinst, lpszName, uType, cxDesired, cyDesired));
420 }
421 else dprintf(("LoadImageA NOT COMPLETE %x %x %d (%d,%d)\n", hinst, lpszName, uType, cxDesired, cyDesired));
422
423 if (fuLoad & LR_DEFAULTSIZE) {
424 if (uType == IMAGE_ICON) {
425 if (!cxDesired) cxDesired = GetSystemMetrics(SM_CXICON);
426 if (!cyDesired) cyDesired = GetSystemMetrics(SM_CYICON);
427 }
428 else if (uType == IMAGE_CURSOR) {
429 if (!cxDesired) cxDesired = GetSystemMetrics(SM_CXCURSOR);
430 if (!cyDesired) cyDesired = GetSystemMetrics(SM_CYCURSOR);
431 }
432 }
433 if (fuLoad & LR_LOADFROMFILE) fuLoad &= ~LR_SHARED;
434
435 switch(uType) {
436 case IMAGE_BITMAP:
437 hRet = (HANDLE)LoadBitmapA(hinst, lpszName, cxDesired, cyDesired, fuLoad);
438 break;
439 case IMAGE_CURSOR:
440 hRet = (HANDLE)LoadCursorA(hinst, lpszName);
441 break;
442 case IMAGE_ICON:
443 hRet = (HANDLE)LoadIconA(hinst, lpszName);
444 break;
445 default:
446 dprintf(("LoadImageA: unsupported type %d!!", uType));
447 return 0;
448 }
449 dprintf(("LoadImageA returned %d\n", (int)hRet));
450
451 return(hRet);
452}
453//******************************************************************************
454//******************************************************************************
455HANDLE WIN32API LoadImageW(HINSTANCE hinst, LPCWSTR lpszName, UINT uType,
456 int cxDesired, int cyDesired, UINT fuLoad)
457{
458 HANDLE hRet = 0;
459
460 dprintf(("LoadImageW NOT COMPLETE (%d,%d)\n", cxDesired, cyDesired));
461
462 if (fuLoad & LR_DEFAULTSIZE) {
463 if (uType == IMAGE_ICON) {
464 if (!cxDesired) cxDesired = GetSystemMetrics(SM_CXICON);
465 if (!cyDesired) cyDesired = GetSystemMetrics(SM_CYICON);
466 }
467 else if (uType == IMAGE_CURSOR) {
468 if (!cxDesired) cxDesired = GetSystemMetrics(SM_CXCURSOR);
469 if (!cyDesired) cyDesired = GetSystemMetrics(SM_CYCURSOR);
470 }
471 }
472 if (fuLoad & LR_LOADFROMFILE) fuLoad &= ~LR_SHARED;
473
474 switch(uType) {
475 case IMAGE_BITMAP:
476 hRet = (HANDLE)LoadBitmapW(hinst, lpszName);
477 break;
478 case IMAGE_CURSOR:
479 hRet = (HANDLE)LoadCursorW(hinst, lpszName);
480 break;
481 case IMAGE_ICON:
482 hRet = (HANDLE)LoadIconW(hinst, lpszName);
483 break;
484 default:
485 dprintf(("LoadImageW: unsupported type %d!!", uType));
486 return 0;
487 }
488 dprintf(("LoadImageW returned %d\n", (int)hRet));
489
490 return(hRet);
491}
492/******************************************************************************
493 * CopyImage32 [USER32.61] Creates new image and copies attributes to it
494 *
495 * PARAMS
496 * hnd [I] Handle to image to copy
497 * type [I] Type of image to copy
498 * desiredx [I] Desired width of new image
499 * desiredy [I] Desired height of new image
500 * flags [I] Copy flags
501 *
502 * RETURNS
503 * Success: Handle to newly created image
504 * Failure: NULL
505 *
506 * FIXME: implementation still lacks nearly all features, see LR_*
507 * defines in windows.h
508 *
509 */
510HICON WINAPI CopyImage( HANDLE hnd, UINT type, INT desiredx,
511 INT desiredy, UINT flags )
512{
513 dprintf(("CopyImage %x %d (%d,%d) %x", hnd, type, desiredx, desiredy, flags));
514 switch (type)
515 {
516// case IMAGE_BITMAP:
517// return BITMAP_CopyBitmap(hnd);
518 case IMAGE_ICON:
519 return CopyIcon(hnd);
520 case IMAGE_CURSOR:
521 return CopyCursor(hnd);
522// return CopyCursorIcon(hnd,type, desiredx, desiredy, flags);
523 default:
524 dprintf(("CopyImage: Unsupported type"));
525 }
526 return 0;
527}
528//******************************************************************************
529//******************************************************************************
Note: See TracBrowser for help on using the repository browser.