- ICON_CreateCursorFromData should pass a header that fits to the bitmap data to...
[reactos.git] / reactos / dll / win32 / user32 / windows / icon.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
4 *
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.
9 *
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.
14 *
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.
18 */
19 /* $Id$
20 *
21 * PROJECT: ReactOS user32.dll
22 * FILE: lib/user32/windows/icon.c
23 * PURPOSE: Icon
24 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
25 * UPDATE HISTORY:
26 * 09-05-2001 CSH Created
27 */
28
29 /* INCLUDES ******************************************************************/
30
31 #include <user32.h>
32
33 #include <wine/debug.h>
34 WINE_DEFAULT_DEBUG_CHANNEL(user32);
35
36 /* FUNCTIONS *****************************************************************/
37
38
39 HICON
40 ICON_CreateIconFromData(HDC hDC, PVOID ImageData, ICONIMAGE* IconImage, int cxDesired, int cyDesired, int xHotspot, int yHotspot)
41 {
42 BYTE BitmapInfoBuffer[sizeof(BITMAPINFOHEADER) + 2 * sizeof(RGBQUAD)];
43 BITMAPINFO *bwBIH = (BITMAPINFO *)BitmapInfoBuffer;
44 ICONINFO IconInfo;
45
46 IconInfo.fIcon = TRUE;
47 IconInfo.xHotspot = xHotspot;
48 IconInfo.yHotspot = yHotspot;
49
50 /* Load the XOR bitmap */
51 IconInfo.hbmColor = CreateDIBitmap(hDC, &IconImage->icHeader, CBM_INIT,
52 ImageData, (BITMAPINFO*)IconImage,
53 DIB_RGB_COLORS);
54
55 /* Make ImageData point to the start of the AND image data. */
56 ImageData = ((PBYTE)ImageData) + (((IconImage->icHeader.biWidth *
57 IconImage->icHeader.biBitCount + 31) & ~31) >> 3) *
58 (IconImage->icHeader.biHeight );
59
60 /* Create a BITMAPINFO header for the monocrome part of the icon. */
61 bwBIH->bmiHeader.biBitCount = 1;
62 bwBIH->bmiHeader.biWidth = IconImage->icHeader.biWidth;
63 bwBIH->bmiHeader.biHeight = IconImage->icHeader.biHeight;
64 bwBIH->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
65 bwBIH->bmiHeader.biPlanes = 1;
66 bwBIH->bmiHeader.biSizeImage = 0;
67 bwBIH->bmiHeader.biCompression = BI_RGB;
68 bwBIH->bmiHeader.biClrImportant = 0;
69 bwBIH->bmiHeader.biClrUsed = 0;
70 bwBIH->bmiHeader.biXPelsPerMeter = 0;
71 bwBIH->bmiHeader.biYPelsPerMeter = 0;
72
73 bwBIH->bmiColors[0].rgbBlue = 0;
74 bwBIH->bmiColors[0].rgbGreen = 0;
75 bwBIH->bmiColors[0].rgbRed = 0;
76 bwBIH->bmiColors[0].rgbReserved = 0;
77
78 bwBIH->bmiColors[1].rgbBlue = 0xff;
79 bwBIH->bmiColors[1].rgbGreen = 0xff;
80 bwBIH->bmiColors[1].rgbRed = 0xff;
81 bwBIH->bmiColors[1].rgbReserved = 0;
82
83 /* Load the AND bitmap. */
84 IconInfo.hbmMask = CreateDIBitmap(hDC, &bwBIH->bmiHeader, 0,
85 ImageData, bwBIH, DIB_RGB_COLORS);
86
87 SetDIBits(hDC, IconInfo.hbmMask, 0, IconImage->icHeader.biHeight,
88 ImageData, bwBIH, DIB_RGB_COLORS);
89
90 /* Create the icon based on everything we have so far */
91 return NtUserCreateCursorIconHandle(&IconInfo, FALSE);
92 }
93
94 HICON
95 ICON_CreateCursorFromData(HDC hDC, PVOID ImageData, ICONIMAGE* IconImage, int cxDesired, int cyDesired, int xHotspot, int yHotspot)
96 {
97 BYTE BitmapInfoBuffer[sizeof(BITMAPINFOHEADER) + 2 * sizeof(RGBQUAD)];
98 BITMAPINFO *bwBIH = (BITMAPINFO *)BitmapInfoBuffer;
99 BITMAPINFO *orgBIH = (BITMAPINFO *)IconImage;
100 ICONINFO IconInfo;
101 PVOID XORImageData = ImageData;
102
103 IconInfo.fIcon = FALSE;
104 IconInfo.xHotspot = xHotspot;
105 IconInfo.yHotspot = yHotspot;
106
107 /* Create a BITMAPINFO header for the monochrome part of the icon */
108 bwBIH->bmiHeader.biBitCount = 1;
109 bwBIH->bmiHeader.biWidth = IconImage->icHeader.biWidth;
110 bwBIH->bmiHeader.biHeight = IconImage->icHeader.biHeight;
111 bwBIH->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
112 bwBIH->bmiHeader.biPlanes = 1;
113 bwBIH->bmiHeader.biSizeImage = 0;
114 bwBIH->bmiHeader.biCompression = BI_RGB;
115 bwBIH->bmiHeader.biClrImportant = 0;
116 bwBIH->bmiHeader.biClrUsed = 0;
117 bwBIH->bmiHeader.biXPelsPerMeter = 0;
118 bwBIH->bmiHeader.biYPelsPerMeter = 0;
119
120 bwBIH->bmiColors[0].rgbBlue = 0;
121 bwBIH->bmiColors[0].rgbGreen = 0;
122 bwBIH->bmiColors[0].rgbRed = 0;
123 bwBIH->bmiColors[0].rgbReserved = 0;
124
125 bwBIH->bmiColors[1].rgbBlue = 0xff;
126 bwBIH->bmiColors[1].rgbGreen = 0xff;
127 bwBIH->bmiColors[1].rgbRed = 0xff;
128 bwBIH->bmiColors[1].rgbReserved = 0;
129
130 /* Load the AND bitmap */
131 IconInfo.hbmMask = CreateDIBitmap(hDC, &bwBIH->bmiHeader, 0,
132 XORImageData, bwBIH, DIB_RGB_COLORS);
133 if (IconInfo.hbmMask)
134 {
135 SetDIBits(hDC, IconInfo.hbmMask, 0, IconImage->icHeader.biHeight,
136 XORImageData, orgBIH, DIB_RGB_COLORS);
137 }
138
139 if (IconImage->icHeader.biBitCount == 1)
140 {
141 IconInfo.hbmColor = (HBITMAP)0;
142 }
143 else
144 {
145 /* Create the color part of the icon */
146 IconInfo.hbmColor = CreateDIBitmap(hDC, &IconImage->icHeader, 0,
147 XORImageData, orgBIH, DIB_RGB_COLORS);
148 if (IconInfo.hbmColor)
149 {
150 SetDIBits(hDC, IconInfo.hbmColor, 0, IconImage->icHeader.biHeight,
151 XORImageData, orgBIH, DIB_RGB_COLORS);
152 }
153 }
154
155 /* Create the icon based on everything we have so far */
156 return NtUserCreateCursorIconHandle(&IconInfo, FALSE);
157 }
158
159
160 /*
161 * @implemented
162 */
163 HICON
164 WINAPI
165 CopyIcon(HICON hIcon)
166 {
167 HICON hRetIcon = NULL;
168 ICONINFO IconInfo;
169
170 if(GetIconInfo(hIcon, &IconInfo))
171 {
172 hRetIcon = CreateIconIndirect(&IconInfo);
173 DeleteObject(IconInfo.hbmColor);
174 DeleteObject(IconInfo.hbmMask);
175 }
176
177 return hRetIcon;
178 }
179
180
181 /*
182 * @implemented
183 */
184 HICON
185 WINAPI
186 CreateIcon(
187 HINSTANCE hInstance,
188 int nWidth,
189 int nHeight,
190 BYTE cPlanes,
191 BYTE cBitsPixel,
192 CONST BYTE *ANDbits,
193 CONST BYTE *XORbits)
194 {
195 ICONINFO IconInfo;
196
197 IconInfo.fIcon = TRUE;
198 IconInfo.xHotspot = nWidth / 2;
199 IconInfo.yHotspot = nHeight / 2;
200 IconInfo.hbmMask = CreateBitmap(nWidth, nHeight, 1, 1, ANDbits);
201 if(!IconInfo.hbmMask)
202 {
203 return (HICON)0;
204 }
205 IconInfo.hbmColor = CreateBitmap(nWidth, nHeight, cPlanes, cBitsPixel, XORbits);
206 if(!IconInfo.hbmColor)
207 {
208 DeleteObject(IconInfo.hbmMask);
209 return (HICON)0;
210 }
211
212 return NtUserCreateCursorIconHandle(&IconInfo, FALSE);
213 }
214
215
216 /*
217 * @implemented
218 */
219 HICON
220 WINAPI
221 CreateIconFromResource(
222 PBYTE presbits,
223 DWORD dwResSize,
224 BOOL fIcon,
225 DWORD dwVer)
226 {
227 return CreateIconFromResourceEx(presbits, dwResSize, fIcon, dwVer, 0, 0, LR_DEFAULTSIZE|LR_SHARED );
228 }
229
230
231 /*
232 * @implemented
233 */
234 HICON
235 WINAPI
236 CreateIconFromResourceEx(
237 PBYTE pbIconBits,
238 DWORD cbIconBits,
239 BOOL fIcon,
240 DWORD dwVersion,
241 int cxDesired,
242 int cyDesired,
243 UINT uFlags)
244 {
245 ICONIMAGE* SafeIconImage;
246 HICON hIcon;
247 ULONG HeaderSize;
248 ULONG ColourCount;
249 PVOID Data;
250 HDC hScreenDc;
251 WORD wXHotspot;
252 WORD wYHotspot;
253
254 /*
255 FIXME - does win support LR_SHARED? According to msdn it does but we don't
256 have useful information to identify the icon
257 if (uFlags & LR_SHARED)
258 {
259 DbgPrint("FIXME: need LR_SHARED support in CreateIconFromResourceEx()\n");
260 }
261 */
262
263 TRACE("dwVersion, cxDesired, cyDesired are all ignored in this implementation!\n");
264
265 if (! fIcon)
266 {
267 wXHotspot = *(WORD*)pbIconBits;
268 pbIconBits += sizeof(WORD);
269 wYHotspot = *(WORD*)pbIconBits;
270 pbIconBits += sizeof(WORD);
271 cbIconBits -= 2 * sizeof(WORD);
272 }
273 else
274 {
275 wXHotspot = cxDesired / 2;
276 wYHotspot = cyDesired / 2;
277 }
278
279 /* get an safe copy of the icon data */
280 SafeIconImage = RtlAllocateHeap(GetProcessHeap(), 0, cbIconBits);
281 if (SafeIconImage == NULL)
282 {
283 return NULL;
284 }
285 memcpy(SafeIconImage, pbIconBits, cbIconBits);
286
287 /* take into acount the original height was for both the AND and XOR images */
288 if(fIcon)
289 SafeIconImage->icHeader.biHeight /= 2;
290
291 if (SafeIconImage->icHeader.biSize == sizeof(BITMAPCOREHEADER))
292 {
293 BITMAPCOREHEADER* Core = (BITMAPCOREHEADER*)SafeIconImage;
294 ColourCount = (Core->bcBitCount <= 8) ? (1 << Core->bcBitCount) : 0;
295 HeaderSize = sizeof(BITMAPCOREHEADER) + ColourCount * sizeof(RGBTRIPLE);
296 }
297 else
298 {
299 ColourCount = (SafeIconImage->icHeader.biBitCount <= 8) ?
300 (1 << SafeIconImage->icHeader.biBitCount) : 0;
301 HeaderSize = sizeof(BITMAPINFOHEADER) + ColourCount * sizeof(RGBQUAD);
302 }
303
304 /* make data point to the start of the XOR image data */
305 Data = (PBYTE)SafeIconImage + HeaderSize;
306
307 /* get a handle to the screen dc, the icon we create is going to be compatable with this */
308 // FIXME!!! This is a victim of the Win32k Initialization BUG!!!!!
309 //hScreenDc = CreateDCW(NULL, NULL, NULL, NULL);
310 hScreenDc = CreateCompatibleDC(NULL);
311 if (hScreenDc == NULL)
312 {
313 RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
314 return(NULL);
315 }
316
317 if(fIcon)
318 hIcon = ICON_CreateIconFromData(hScreenDc, Data, SafeIconImage, cxDesired, cyDesired, wXHotspot, wYHotspot);
319 else
320 hIcon = ICON_CreateCursorFromData(hScreenDc, Data, SafeIconImage, cxDesired, cyDesired, wXHotspot, wYHotspot);
321 RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
322 DeleteDC(hScreenDc);
323
324 return hIcon;
325 }
326
327
328 /*
329 * @implemented
330 */
331 HICON
332 WINAPI
333 CreateIconIndirect(PICONINFO IconInfo)
334 {
335 BITMAP ColorBitmap;
336 BITMAP MaskBitmap;
337
338 if(!IconInfo)
339 {
340 SetLastError(ERROR_INVALID_PARAMETER);
341 return (HICON)0;
342 }
343
344 if(!GetObjectW(IconInfo->hbmMask, sizeof(BITMAP), &MaskBitmap))
345 {
346 return (HICON)0;
347 }
348 /* FIXME - does there really *have* to be a color bitmap? monochrome cursors don't have one */
349 if(/*IconInfo->hbmColor &&*/ !GetObjectW(IconInfo->hbmColor, sizeof(BITMAP), &ColorBitmap))
350 {
351 return (HICON)0;
352 }
353
354 /* FIXME - i doubt this is right (monochrome cursors */
355 /*if(ColorBitmap.bmWidth != MaskBitmap.bmWidth ||
356 ColorBitmap.bmHeight != MaskBitmap.bmWidth)
357 {
358 SetLastError(ERROR_INVALID_PARAMETER);
359 return (HICON)0;
360 }*/
361
362 return (HICON)NtUserCreateCursorIconHandle(IconInfo, TRUE);
363 }
364
365
366 /*
367 * @implemented
368 */
369 BOOL
370 WINAPI
371 DestroyIcon(
372 HICON hIcon)
373 {
374 return (BOOL)NtUserDestroyCursor((HANDLE)hIcon, 0);
375 }
376
377
378 /*
379 * @implemented
380 */
381 BOOL
382 WINAPI
383 DrawIcon(
384 HDC hDC,
385 int X,
386 int Y,
387 HICON hIcon)
388 {
389 return DrawIconEx(hDC, X, Y, hIcon, 0, 0, 0, NULL, DI_NORMAL | DI_DEFAULTSIZE);
390 }
391
392 /*
393 * @implemented
394 */
395 BOOL
396 WINAPI
397 DrawIconEx(
398 HDC hdc,
399 int xLeft,
400 int yTop,
401 HICON hIcon,
402 int cxWidth,
403 int cyWidth,
404 UINT istepIfAniCur,
405 HBRUSH hbrFlickerFreeDraw,
406 UINT diFlags)
407 {
408 return (BOOL)NtUserDrawIconEx(hdc, xLeft, yTop, hIcon, cxWidth, cyWidth,
409 istepIfAniCur, hbrFlickerFreeDraw, diFlags,
410 0, 0);
411 }
412
413
414 /*
415 * @implemented
416 */
417 BOOL
418 WINAPI
419 GetIconInfo(
420 HICON hIcon,
421 PICONINFO IconInfo)
422 {
423 return NtUserGetIconInfo((HANDLE)hIcon, IconInfo, 0, 0, 0, 0);
424 }
425
426
427 /*
428 * @implemented
429 */
430 HICON
431 WINAPI
432 LoadIconA(
433 HINSTANCE hInstance,
434 LPCSTR lpIconName)
435 {
436 return(LoadImageA(hInstance, lpIconName, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE));
437 }
438
439
440 /*
441 * @implemented
442 */
443 HICON
444 WINAPI
445 LoadIconW(
446 HINSTANCE hInstance,
447 LPCWSTR lpIconName)
448 {
449 return(LoadImageW(hInstance, lpIconName, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE));
450 }
451
452
453 /*
454 * @implemented
455 */
456 int
457 WINAPI
458 LookupIconIdFromDirectory(
459 PBYTE presbits,
460 BOOL fIcon)
461 {
462 return LookupIconIdFromDirectoryEx(presbits,
463 fIcon,
464 fIcon ? GetSystemMetrics(SM_CXICON) : GetSystemMetrics(SM_CXCURSOR),
465 fIcon ? GetSystemMetrics(SM_CYICON) : GetSystemMetrics(SM_CYCURSOR),
466 LR_DEFAULTCOLOR);
467 }
468
469
470
471
472
473 /*
474 * The following macro function accounts for the irregularities of
475 * accessing cursor and icon resources in files and resource entries.
476 */
477 typedef BOOL
478 (*fnGetCIEntry)(LPVOID dir, int n, int *width, int *height, int *bits );
479
480 /**********************************************************************
481 * CURSORICON_FindBestIcon
482 *
483 * Find the icon closest to the requested size and number of colors.
484 */
485 static int
486 CURSORICON_FindBestIcon(LPVOID dir,
487 fnGetCIEntry get_entry,
488 int Width,
489 int Height,
490 int ColorBits)
491 {
492 int i, cx, cy, Bits, BestBits = 0, BestEntry = -1;
493 UINT iTotalDiff, iXDiff=0, iYDiff=0, iColorDiff;
494 UINT iTempXDiff, iTempYDiff, iTempColorDiff;
495
496 /* Find Best Fit */
497 iTotalDiff = 0xFFFFFFFF;
498 iColorDiff = 0xFFFFFFFF;
499 for (i = 0; get_entry(dir, i, &cx, &cy, &Bits); i++ )
500 {
501 iTempXDiff = abs(Width - cx);
502 iTempYDiff = abs(Height - cy);
503
504 if(iTotalDiff > (iTempXDiff + iTempYDiff))
505 {
506 iXDiff = iTempXDiff;
507 iYDiff = iTempYDiff;
508 iTotalDiff = iXDiff + iYDiff;
509 }
510 }
511
512 /* Find Best Colors for Best Fit */
513 for (i = 0; get_entry(dir, i, &cx, &cy, &Bits); i++ )
514 {
515 if(abs(Width - cx) == iXDiff && abs(Height - cy) == iYDiff)
516 {
517 iTempColorDiff = abs(ColorBits - Bits);
518 if(iColorDiff > iTempColorDiff)
519 {
520 BestEntry = i;
521 BestBits = Bits;
522 iColorDiff = iTempColorDiff;
523 }
524 }
525 }
526
527 TRACE("Best Icon: ResId: %d, bits : %d\n", BestEntry, BestBits);
528
529 return BestEntry;
530 }
531
532
533
534 /**********************************************************************
535 * CURSORICON_FindBestCursor
536 *
537 * Find the cursor closest to the requested size.
538 * FIXME: parameter 'color' ignored and entries with more than 1 bpp
539 * ignored too
540 */
541 static int
542 CURSORICON_FindBestCursor(LPVOID dir,
543 fnGetCIEntry get_entry,
544 int Width,
545 int Height,
546 int ColorBits)
547 {
548 int i, cx, cy, Bits, BestBits = 0, BestEntry = -1;
549 UINT iTotalDiff, iXDiff=0, iYDiff=0, iColorDiff;
550 UINT iTempXDiff, iTempYDiff, iTempColorDiff;
551
552 /* Find Best Fit */
553 iTotalDiff = 0xFFFFFFFF;
554 iColorDiff = 0xFFFFFFFF;
555 for (i = 0; get_entry(dir, i, &cx, &cy, &Bits); i++ )
556 {
557 iTempXDiff = abs(Width - cx);
558 iTempYDiff = abs(Height - cy);
559
560 if(iTotalDiff > (iTempXDiff + iTempYDiff))
561 {
562 iXDiff = iTempXDiff;
563 iYDiff = iTempYDiff;
564 iTotalDiff = iXDiff + iYDiff;
565 }
566 }
567
568 /* Find Best Colors for Best Fit */
569 for (i = 0; get_entry(dir, i, &cx, &cy, &Bits); i++ )
570 {
571 if(abs(Width - cx) == iXDiff && abs(Height - cy) == iYDiff)
572 {
573 iTempColorDiff = abs(ColorBits - Bits);
574 if(iColorDiff > iTempColorDiff)
575 {
576 BestEntry = i;
577 BestBits = Bits;
578 iColorDiff = iTempColorDiff;
579 }
580 }
581 }
582
583 TRACE("Best Cursor: ResId: %d, bits : %d\n", BestEntry, BestBits);
584
585 return BestEntry;
586 }
587
588
589 static BOOL
590 CURSORICON_GetResIconEntry(LPVOID dir,
591 int n,
592 int *Width,
593 int *Height,
594 int *Bits)
595 {
596 GRPCURSORICONDIR *ResDir = dir;
597 ICONRESDIR *Icon;
598
599 if (ResDir->idCount <= n)
600 return FALSE;
601
602 Icon = &ResDir->idEntries[n].ResInfo.icon;
603 *Width = Icon->bWidth;
604 *Height = Icon->bHeight;
605 *Bits = ResDir->idEntries[n].wBitCount;
606 return TRUE;
607 }
608
609 static BOOL
610 CURSORICON_GetResCursorEntry(LPVOID dir,
611 int n,
612 int *Width,
613 int *Height,
614 int *Bits)
615 {
616 GRPCURSORICONDIR *ResDir = dir;
617 CURSORRESDIR *Cursor;
618
619 if (ResDir->idCount <= n)
620 return FALSE;
621
622 Cursor = &ResDir->idEntries[n].ResInfo.cursor;
623 *Width = Cursor->wWidth;
624 *Height = Cursor->wHeight;
625 *Bits = ResDir->idEntries[n].wBitCount;
626 return TRUE;
627 }
628
629 static GRPCURSORICONDIRENTRY *
630 CURSORICON_FindBestIconRes(GRPCURSORICONDIR * dir,
631 int Width,
632 int Height,
633 int ColorBits)
634 {
635 int n;
636 n = CURSORICON_FindBestIcon(dir,
637 CURSORICON_GetResIconEntry,
638 Width,
639 Height,
640 ColorBits);
641 if (n < 0)
642 return NULL;
643
644 return &dir->idEntries[n];
645 }
646
647 static GRPCURSORICONDIRENTRY *
648 CURSORICON_FindBestCursorRes(GRPCURSORICONDIR *dir,
649 int Width,
650 int Height,
651 int ColorBits)
652 {
653 int n;
654 n = CURSORICON_FindBestCursor(dir,
655 CURSORICON_GetResCursorEntry,
656 Width,
657 Height,
658 ColorBits);
659 if (n < 0)
660 return NULL;
661
662 return &dir->idEntries[n];
663 }
664
665
666 INT WINAPI
667 LookupIconIdFromDirectoryEx(PBYTE xdir,
668 BOOL bIcon,
669 INT width,
670 INT height,
671 UINT cFlag)
672 {
673 GRPCURSORICONDIR *dir = (GRPCURSORICONDIR*)xdir;
674 UINT retVal = 0;
675
676 GetConnected();
677
678 if(dir && !dir->idReserved && (IMAGE_ICON == dir->idType || IMAGE_CURSOR == dir->idType))
679 {
680 GRPCURSORICONDIRENTRY *entry = NULL;
681 int ColorBits;
682
683 if (cFlag & LR_MONOCHROME)
684 {
685 ColorBits = 1;
686 }
687 else if (cFlag & LR_VGACOLOR)
688 {
689 ColorBits = 4;
690 }
691 else
692 {
693 ColorBits = g_psi->BitsPixel;
694 }
695
696 if(bIcon)
697 entry = CURSORICON_FindBestIconRes(dir, width, height, ColorBits);
698 else
699 entry = CURSORICON_FindBestCursorRes(dir, width, height, 1);
700
701 if (entry)
702 retVal = entry->nID;
703 }
704 else
705 WARN("%s() : Invalid resource directory\n", __FUNCTION__);
706
707 return retVal;
708 }