#include <user32.h>
#include <wine/debug.h>
-
+WINE_DEFAULT_DEBUG_CHANNEL(user32);
/* FUNCTIONS *****************************************************************/
-HICON
-ICON_CreateIconFromData(HDC hDC, PVOID ImageData, ICONIMAGE* IconImage, int cxDesired, int cyDesired, int xHotspot, int yHotspot)
-{
- BYTE BitmapInfoBuffer[sizeof(BITMAPINFOHEADER) + 2 * sizeof(RGBQUAD)];
- BITMAPINFO *bwBIH = (BITMAPINFO *)BitmapInfoBuffer;
- ICONINFO IconInfo;
-
- IconInfo.fIcon = TRUE;
- IconInfo.xHotspot = xHotspot;
- IconInfo.yHotspot = yHotspot;
-
- /* Load the XOR bitmap */
- IconInfo.hbmColor = CreateDIBitmap(hDC, &IconImage->icHeader, CBM_INIT,
- ImageData, (BITMAPINFO*)IconImage,
- DIB_RGB_COLORS);
-
- /* Make ImageData point to the start of the AND image data. */
- ImageData = ((PBYTE)ImageData) + (((IconImage->icHeader.biWidth *
- IconImage->icHeader.biBitCount + 31) & ~31) >> 3) *
- (IconImage->icHeader.biHeight );
-
- /* Create a BITMAPINFO header for the monocrome part of the icon. */
- bwBIH->bmiHeader.biBitCount = 1;
- bwBIH->bmiHeader.biWidth = IconImage->icHeader.biWidth;
- bwBIH->bmiHeader.biHeight = IconImage->icHeader.biHeight;
- bwBIH->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bwBIH->bmiHeader.biPlanes = 1;
- bwBIH->bmiHeader.biSizeImage = 0;
- bwBIH->bmiHeader.biCompression = BI_RGB;
- bwBIH->bmiHeader.biClrImportant = 0;
- bwBIH->bmiHeader.biClrUsed = 0;
- bwBIH->bmiHeader.biXPelsPerMeter = 0;
- bwBIH->bmiHeader.biYPelsPerMeter = 0;
-
- bwBIH->bmiColors[0].rgbBlue = 0;
- bwBIH->bmiColors[0].rgbGreen = 0;
- bwBIH->bmiColors[0].rgbRed = 0;
- bwBIH->bmiColors[0].rgbReserved = 0;
-
- bwBIH->bmiColors[1].rgbBlue = 0xff;
- bwBIH->bmiColors[1].rgbGreen = 0xff;
- bwBIH->bmiColors[1].rgbRed = 0xff;
- bwBIH->bmiColors[1].rgbReserved = 0;
-
- /* Load the AND bitmap. */
- IconInfo.hbmMask = CreateDIBitmap(hDC, &bwBIH->bmiHeader, 0,
- ImageData, bwBIH, DIB_RGB_COLORS);
-
- SetDIBits(hDC, IconInfo.hbmMask, 0, IconImage->icHeader.biHeight,
- ImageData, bwBIH, DIB_RGB_COLORS);
-
- /* Create the icon based on everything we have so far */
- return NtUserCreateCursorIconHandle(&IconInfo, FALSE);
-}
HICON
-ICON_CreateCursorFromData(HDC hDC, PVOID ImageData, ICONIMAGE* IconImage, int cxDesired, int cyDesired, int xHotspot, int yHotspot)
+CreateCursorIconFromData(HDC hDC, PVOID ImageData, ICONIMAGE* IconImage, int cxDesired, int cyDesired, int xHotspot, int yHotspot, BOOL fIcon)
{
- /* FIXME - color cursors */
BYTE BitmapInfoBuffer[sizeof(BITMAPINFOHEADER) + 2 * sizeof(RGBQUAD)];
BITMAPINFO *bwBIH = (BITMAPINFO *)BitmapInfoBuffer;
ICONINFO IconInfo;
- PVOID XORImageData = ImageData;
- IconInfo.fIcon = FALSE;
+ IconInfo.fIcon = fIcon;
IconInfo.xHotspot = xHotspot;
IconInfo.yHotspot = yHotspot;
- /* Create a BITMAPINFO header for the monocrome part of the icon */
- bwBIH->bmiHeader.biBitCount = 1;
- bwBIH->bmiHeader.biWidth = IconImage->icHeader.biWidth;
- bwBIH->bmiHeader.biHeight = IconImage->icHeader.biHeight;
- bwBIH->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bwBIH->bmiHeader.biPlanes = 1;
- bwBIH->bmiHeader.biSizeImage = 0;
- bwBIH->bmiHeader.biCompression = BI_RGB;
- bwBIH->bmiHeader.biClrImportant = 0;
- bwBIH->bmiHeader.biClrUsed = 0;
- bwBIH->bmiHeader.biXPelsPerMeter = 0;
- bwBIH->bmiHeader.biYPelsPerMeter = 0;
-
- bwBIH->bmiColors[0].rgbBlue = 0;
- bwBIH->bmiColors[0].rgbGreen = 0;
- bwBIH->bmiColors[0].rgbRed = 0;
- bwBIH->bmiColors[0].rgbReserved = 0;
-
- bwBIH->bmiColors[1].rgbBlue = 0xff;
- bwBIH->bmiColors[1].rgbGreen = 0xff;
- bwBIH->bmiColors[1].rgbRed = 0xff;
- bwBIH->bmiColors[1].rgbReserved = 0;
-
- /* Load the AND bitmap */
- IconInfo.hbmMask = CreateDIBitmap(hDC, &bwBIH->bmiHeader, 0,
- XORImageData, bwBIH, DIB_RGB_COLORS);
- if (IconInfo.hbmMask)
+ if (IconImage->icHeader.biBitCount == 1)
+ {
+ IconInfo.hbmColor = (HBITMAP)0;
+ IconImage->icHeader.biHeight *= 2;
+ IconInfo.hbmMask = CreateDIBitmap(hDC, &IconImage->icHeader, CBM_INIT,
+ ImageData, (BITMAPINFO*)IconImage,
+ DIB_RGB_COLORS);
+ }
+ else
{
- SetDIBits(hDC, IconInfo.hbmMask, 0, IconImage->icHeader.biHeight,
- XORImageData, bwBIH, DIB_RGB_COLORS);
+ /* Create the XOR bitmap */
+ IconInfo.hbmColor = CreateDIBitmap(hDC, &IconImage->icHeader, CBM_INIT,
+ ImageData, (BITMAPINFO*)IconImage,
+ DIB_RGB_COLORS);
+
+ /* Make ImageData point to the start of the AND image data. */
+ ImageData = ((PBYTE)ImageData) + (((IconImage->icHeader.biWidth *
+ IconImage->icHeader.biBitCount + 31) & ~31) >> 3) *
+ (IconImage->icHeader.biHeight );
+
+ /* Create a BITMAPINFO header for the monochrome part of the icon. */
+ bwBIH->bmiHeader.biBitCount = 1;
+ bwBIH->bmiHeader.biWidth = IconImage->icHeader.biWidth;
+ bwBIH->bmiHeader.biHeight = IconImage->icHeader.biHeight;
+ bwBIH->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bwBIH->bmiHeader.biPlanes = 1;
+ bwBIH->bmiHeader.biSizeImage = 0;
+ bwBIH->bmiHeader.biCompression = BI_RGB;
+ bwBIH->bmiHeader.biClrImportant = 2;
+ bwBIH->bmiHeader.biClrUsed = 2;
+ bwBIH->bmiHeader.biXPelsPerMeter = 0;
+ bwBIH->bmiHeader.biYPelsPerMeter = 0;
+
+ bwBIH->bmiColors[0].rgbBlue = 0;
+ bwBIH->bmiColors[0].rgbGreen = 0;
+ bwBIH->bmiColors[0].rgbRed = 0;
+ bwBIH->bmiColors[0].rgbReserved = 0;
+
+ bwBIH->bmiColors[1].rgbBlue = 0xff;
+ bwBIH->bmiColors[1].rgbGreen = 0xff;
+ bwBIH->bmiColors[1].rgbRed = 0xff;
+ bwBIH->bmiColors[1].rgbReserved = 0;
+
+ /* Create the AND bitmap. */
+ IconInfo.hbmMask = CreateDIBitmap(hDC, &bwBIH->bmiHeader, 0,
+ ImageData, bwBIH, DIB_RGB_COLORS);
+
+ SetDIBits(hDC, IconInfo.hbmMask, 0, IconImage->icHeader.biHeight,
+ ImageData, bwBIH, DIB_RGB_COLORS);
}
- IconInfo.hbmColor = (HBITMAP)0;
/* Create the icon based on everything we have so far */
return NtUserCreateCursorIconHandle(&IconInfo, FALSE);
}
-
/*
* @implemented
*/
HICON
-STDCALL
-CopyIcon(
- HICON hIcon)
+WINAPI
+CopyIcon(HICON hIcon)
{
- ICONINFO IconInfo;
+ HICON hRetIcon = NULL;
+ ICONINFO IconInfo;
- if(NtUserGetCursorIconInfo((HANDLE)hIcon, &IconInfo))
- {
- return NtUserCreateCursorIconHandle(&IconInfo, FALSE);
- }
- return (HICON)0;
+ if(GetIconInfo(hIcon, &IconInfo))
+ {
+ hRetIcon = CreateIconIndirect(&IconInfo);
+ DeleteObject(IconInfo.hbmColor);
+ DeleteObject(IconInfo.hbmMask);
+ }
+
+ return hRetIcon;
}
* @implemented
*/
HICON
-STDCALL
+WINAPI
CreateIcon(
HINSTANCE hInstance,
int nWidth,
ICONINFO IconInfo;
IconInfo.fIcon = TRUE;
- IconInfo.xHotspot = nWidth / 2;
- IconInfo.yHotspot = nHeight / 2;
+
+ if (cBitsPixel == 1)
+ {
+ nHeight <<= 1;
+ }
IconInfo.hbmMask = CreateBitmap(nWidth, nHeight, 1, 1, ANDbits);
if(!IconInfo.hbmMask)
{
return (HICON)0;
}
- IconInfo.hbmColor = CreateBitmap(nWidth, nHeight, cPlanes, cBitsPixel, XORbits);
- if(!IconInfo.hbmColor)
+
+ if (cBitsPixel == 1)
{
- DeleteObject(IconInfo.hbmMask);
- return (HICON)0;
+ IconInfo.hbmColor = (HBITMAP)0;
+ }
+ else
+ {
+ IconInfo.hbmColor = CreateBitmap(nWidth, nHeight, cPlanes, cBitsPixel, XORbits);
+ if(!IconInfo.hbmColor)
+ {
+ DeleteObject(IconInfo.hbmMask);
+ return (HICON)0;
+ }
}
return NtUserCreateCursorIconHandle(&IconInfo, FALSE);
* @implemented
*/
HICON
-STDCALL
+WINAPI
CreateIconFromResource(
PBYTE presbits,
DWORD dwResSize,
BOOL fIcon,
DWORD dwVer)
{
- return CreateIconFromResourceEx(presbits, dwResSize, fIcon, dwVer, 0, 0, 0);
+ return CreateIconFromResourceEx(presbits, dwResSize, fIcon, dwVer, 0, 0, LR_DEFAULTSIZE|LR_SHARED );
}
* @implemented
*/
HICON
-STDCALL
+WINAPI
CreateIconFromResourceEx(
PBYTE pbIconBits,
DWORD cbIconBits,
}
*/
- DPRINT("dwVersion, cxDesired, cyDesired are all ignored in this implementation!\n");
+ TRACE("dwVersion, cxDesired, cyDesired are all ignored in this implementation!\n");
if (! fIcon)
{
wXHotspot = *(WORD*)pbIconBits;
- pbIconBits+=sizeof(WORD);
+ pbIconBits += sizeof(WORD);
wYHotspot = *(WORD*)pbIconBits;
- pbIconBits+=sizeof(WORD);
- cbIconBits-=2*sizeof(WORD);
+ pbIconBits += sizeof(WORD);
+ cbIconBits -= 2 * sizeof(WORD);
}
else
{
}
memcpy(SafeIconImage, pbIconBits, cbIconBits);
- /* take into acount the origonal height was for both the AND and XOR images */
- if(fIcon)
+ /* Take into acount the original height was for both the AND and XOR images */
SafeIconImage->icHeader.biHeight /= 2;
if (SafeIconImage->icHeader.biSize == sizeof(BITMAPCOREHEADER))
Data = (PBYTE)SafeIconImage + HeaderSize;
/* get a handle to the screen dc, the icon we create is going to be compatable with this */
+ // FIXME!!! This is a victim of the Win32k Initialization BUG!!!!!
+ //hScreenDc = CreateDCW(NULL, NULL, NULL, NULL);
hScreenDc = CreateCompatibleDC(NULL);
if (hScreenDc == NULL)
{
return(NULL);
}
- if(fIcon)
- hIcon = ICON_CreateIconFromData(hScreenDc, Data, SafeIconImage, cxDesired, cyDesired, wXHotspot, wYHotspot);
- else
- hIcon = ICON_CreateCursorFromData(hScreenDc, Data, SafeIconImage, cxDesired, cyDesired, wXHotspot, wYHotspot);
+ hIcon = CreateCursorIconFromData(hScreenDc, Data, SafeIconImage, cxDesired, cyDesired, wXHotspot, wYHotspot, fIcon);
RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
DeleteDC(hScreenDc);
* @implemented
*/
HICON
-STDCALL
+WINAPI
CreateIconIndirect(PICONINFO IconInfo)
{
BITMAP ColorBitmap;
BITMAP MaskBitmap;
+ HBITMAP hbmTemp;
if(!IconInfo)
{
{
return (HICON)0;
}
- /* FIXME - does there really *have* to be a color bitmap? monochrome cursors don't have one */
- if(IconInfo->hbmColor && !GetObjectW(IconInfo->hbmColor, sizeof(BITMAP), &ColorBitmap))
- {
- return (HICON)0;
- }
- /* FIXME - i doubt this is right (monochrome cursors */
- /*if(ColorBitmap.bmWidth != MaskBitmap.bmWidth ||
- ColorBitmap.bmHeight != MaskBitmap.bmWidth)
+ /* Try to get color bitmap */
+ if (GetObjectW(IconInfo->hbmColor, sizeof(BITMAP), &ColorBitmap))
{
- SetLastError(ERROR_INVALID_PARAMETER);
- return (HICON)0;
- }*/
-
+ /* Compare size of color and mask bitmap*/
+ if (ColorBitmap.bmWidth != MaskBitmap.bmWidth ||
+ ColorBitmap.bmHeight != MaskBitmap.bmHeight)
+ {
+ ERR("Color and mask size are different!");
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return (HICON)0;
+ }
+ /* Check if color and mask are switched and switch them back */
+ if (MaskBitmap.bmBitsPixel != 1 && ColorBitmap.bmBitsPixel == 1)
+ {
+ hbmTemp = IconInfo->hbmMask;
+ IconInfo->hbmMask = IconInfo->hbmColor;
+ IconInfo->hbmColor = hbmTemp;
+ }
+ }
return (HICON)NtUserCreateCursorIconHandle(IconInfo, TRUE);
}
* @implemented
*/
BOOL
-STDCALL
+WINAPI
DestroyIcon(
HICON hIcon)
{
- return (BOOL)NtUserDestroyCursorIcon((HANDLE)hIcon, 0);
+ return (BOOL)NtUserDestroyCursor((HANDLE)hIcon, 0);
}
* @implemented
*/
BOOL
-STDCALL
+WINAPI
DrawIcon(
HDC hDC,
int X,
* @implemented
*/
BOOL
-STDCALL
+WINAPI
DrawIconEx(
HDC hdc,
int xLeft,
* @implemented
*/
BOOL
-STDCALL
+WINAPI
GetIconInfo(
HICON hIcon,
PICONINFO IconInfo)
{
- /* FIXME - copy bitmaps */
- return (BOOL)NtUserGetCursorIconInfo((HANDLE)hIcon, IconInfo);
+ return NtUserGetIconInfo((HANDLE)hIcon, IconInfo, 0, 0, 0, 0);
}
* @implemented
*/
HICON
-STDCALL
+WINAPI
LoadIconA(
HINSTANCE hInstance,
LPCSTR lpIconName)
* @implemented
*/
HICON
-STDCALL
+WINAPI
LoadIconW(
HINSTANCE hInstance,
LPCWSTR lpIconName)
* @implemented
*/
int
-STDCALL
+WINAPI
LookupIconIdFromDirectory(
PBYTE presbits,
BOOL fIcon)
{
- return LookupIconIdFromDirectoryEx( presbits, fIcon,
- fIcon ? GetSystemMetrics(SM_CXICON) : GetSystemMetrics(SM_CXCURSOR),
- fIcon ? GetSystemMetrics(SM_CYICON) : GetSystemMetrics(SM_CYCURSOR), LR_DEFAULTCOLOR );
+ return LookupIconIdFromDirectoryEx(presbits,
+ fIcon,
+ fIcon ? GetSystemMetrics(SM_CXICON) : GetSystemMetrics(SM_CXCURSOR),
+ fIcon ? GetSystemMetrics(SM_CYICON) : GetSystemMetrics(SM_CYCURSOR),
+ LR_DEFAULTCOLOR);
}
-/* Ported from WINE20030408 */
-GRPCURSORICONDIRENTRY*
-CURSORICON_FindBestCursor( GRPCURSORICONDIR *dir, int width, int height, int colors)
+
+
+
+
+/*
+ * The following macro function accounts for the irregularities of
+ * accessing cursor and icon resources in files and resource entries.
+ */
+typedef BOOL
+(*fnGetCIEntry)(LPVOID dir, int n, int *width, int *height, int *bits );
+
+/**********************************************************************
+ * CURSORICON_FindBestIcon
+ *
+ * Find the icon closest to the requested size and number of colors.
+ */
+static int
+CURSORICON_FindBestIcon(LPVOID dir,
+ fnGetCIEntry get_entry,
+ int Width,
+ int Height,
+ int ColorBits)
{
- int i;
- GRPCURSORICONDIRENTRY *entry, *bestEntry = NULL;
+ int i, cx, cy, Bits, BestBits = 0, BestEntry = -1;
UINT iTotalDiff, iXDiff=0, iYDiff=0, iColorDiff;
UINT iTempXDiff, iTempYDiff, iTempColorDiff;
- if (dir->idCount < 1)
- {
- DPRINT("Empty directory!\n");
- return NULL;
- }
- if (dir->idCount == 1)
- return &dir->idEntries[0]; /* No choice... */
-
/* Find Best Fit */
iTotalDiff = 0xFFFFFFFF;
iColorDiff = 0xFFFFFFFF;
- for (i = 0, entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++)
+ for (i = 0; get_entry(dir, i, &cx, &cy, &Bits); i++ )
{
- iTempXDiff = abs(width - entry->ResInfo.icon.bWidth);
- iTempYDiff = abs(height - entry->ResInfo.icon.bHeight);
+ iTempXDiff = abs(Width - cx);
+ iTempYDiff = abs(Height - cy);
if(iTotalDiff > (iTempXDiff + iTempYDiff))
{
}
/* Find Best Colors for Best Fit */
- for (i = 0, entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++)
+ for (i = 0; get_entry(dir, i, &cx, &cy, &Bits); i++ )
{
- if(abs(width - entry->ResInfo.icon.bWidth) == (int) iXDiff &&
- abs(height - entry->ResInfo.icon.bHeight) == (int) iYDiff)
+ if(abs(Width - cx) == iXDiff && abs(Height - cy) == iYDiff)
{
- iTempColorDiff = abs(colors - entry->ResInfo.icon.bColorCount);
-
+ iTempColorDiff = abs(ColorBits - Bits);
if(iColorDiff > iTempColorDiff)
- {
- bestEntry = entry;
+ {
+ BestEntry = i;
+ BestBits = Bits;
iColorDiff = iTempColorDiff;
- }
+ }
}
}
- return bestEntry;
+ TRACE("Best Icon: ResId: %d, bits : %d\n", BestEntry, BestBits);
+
+ return BestEntry;
}
-/* Ported from WINE20030408 */
-GRPCURSORICONDIRENTRY*
-CURSORICON_FindBestIcon( GRPCURSORICONDIR *dir, int width, int height, int colorbits)
+
+
+/**********************************************************************
+ * CURSORICON_FindBestCursor
+ *
+ * Find the cursor closest to the requested size.
+ * FIXME: parameter 'color' ignored and entries with more than 1 bpp
+ * ignored too
+ */
+static int
+CURSORICON_FindBestCursor(LPVOID dir,
+ fnGetCIEntry get_entry,
+ int Width,
+ int Height,
+ int ColorBits)
{
- int i;
- GRPCURSORICONDIRENTRY *entry, *bestEntry = NULL;
+ int i, cx, cy, Bits, BestBits = 0, BestEntry = -1;
UINT iTotalDiff, iXDiff=0, iYDiff=0, iColorDiff;
UINT iTempXDiff, iTempYDiff, iTempColorDiff;
- if (dir->idCount < 1)
- {
- DPRINT("Empty directory!\n");
- return NULL;
- }
- if (dir->idCount == 1)
- return &dir->idEntries[0]; /* No choice... */
-
/* Find Best Fit */
iTotalDiff = 0xFFFFFFFF;
iColorDiff = 0xFFFFFFFF;
- for (i = 0, entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++)
- {
- iTempXDiff = abs(width - entry->ResInfo.icon.bWidth);
-
- iTempYDiff = abs(height - entry->ResInfo.icon.bHeight);
+ for (i = 0; get_entry(dir, i, &cx, &cy, &Bits); i++ )
+ {
+ iTempXDiff = abs(Width - cx);
+ iTempYDiff = abs(Height - cy);
if(iTotalDiff > (iTempXDiff + iTempYDiff))
{
iYDiff = iTempYDiff;
iTotalDiff = iXDiff + iYDiff;
}
- }
+ }
/* Find Best Colors for Best Fit */
- for (i = 0, entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++)
- {
- if(abs(width - entry->ResInfo.icon.bWidth) == (int) iXDiff &&
- abs(height - entry->ResInfo.icon.bHeight) == (int) iYDiff)
+ for (i = 0; get_entry(dir, i, &cx, &cy, &Bits); i++ )
+ {
+ if(abs(Width - cx) == iXDiff && abs(Height - cy) == iYDiff)
{
- iTempColorDiff = abs(colorbits - entry->wBitCount);
+ iTempColorDiff = abs(ColorBits - Bits);
if(iColorDiff > iTempColorDiff)
{
- bestEntry = entry;
+ BestEntry = i;
+ BestBits = Bits;
iColorDiff = iTempColorDiff;
}
}
}
- return bestEntry;
+ TRACE("Best Cursor: ResId: %d, bits : %d\n", BestEntry, BestBits);
+
+ return BestEntry;
}
-/* Ported from WINE20030408 */
-/*
- * @implemented
- */
-INT STDCALL
-LookupIconIdFromDirectoryEx(
- PBYTE presbits,
- BOOL fIcon,
- int cxDesired,
- int cyDesired,
- UINT Flags)
+
+static BOOL
+CURSORICON_GetResIconEntry(LPVOID dir,
+ int n,
+ int *Width,
+ int *Height,
+ int *Bits)
{
- GRPCURSORICONDIR *dir = (GRPCURSORICONDIR*)presbits;
- UINT retVal = 0;
+ GRPCURSORICONDIR *ResDir = dir;
+ ICONRESDIR *Icon;
- if (dir && !dir->idReserved && (IMAGE_ICON == dir->idType || IMAGE_CURSOR == dir->idType))
- {
- GRPCURSORICONDIRENTRY *entry;
- HDC hdc;
- int ColorBits;
-
- hdc = CreateICW(NULL, NULL, NULL, NULL);
- if (Flags & LR_MONOCHROME)
- {
- ColorBits = 1;
- }
- else
- {
- ColorBits = GetDeviceCaps(hdc, BITSPIXEL);
- if (ColorBits > 8)
- ColorBits = 8;
- }
- DeleteDC(hdc);
-
- entry = CURSORICON_FindBestIcon( dir, cxDesired, cyDesired, ColorBits );
-
- if (entry)
- retVal = entry->nID;
- }
- else
- {
- DbgPrint("invalid resource directory\n");
- }
- return retVal;
+ if (ResDir->idCount <= n)
+ return FALSE;
+
+ Icon = &ResDir->idEntries[n].ResInfo.icon;
+ *Width = Icon->bWidth;
+ *Height = Icon->bHeight;
+ *Bits = ResDir->idEntries[n].wBitCount;
+ return TRUE;
+}
+
+static BOOL
+CURSORICON_GetResCursorEntry(LPVOID dir,
+ int n,
+ int *Width,
+ int *Height,
+ int *Bits)
+{
+ GRPCURSORICONDIR *ResDir = dir;
+ CURSORRESDIR *Cursor;
+
+ if (ResDir->idCount <= n)
+ return FALSE;
+
+ Cursor = &ResDir->idEntries[n].ResInfo.cursor;
+ *Width = Cursor->wWidth;
+ *Height = Cursor->wHeight;
+ *Bits = ResDir->idEntries[n].wBitCount;
+ return TRUE;
+}
+
+static GRPCURSORICONDIRENTRY *
+CURSORICON_FindBestIconRes(GRPCURSORICONDIR * dir,
+ int Width,
+ int Height,
+ int ColorBits)
+{
+ int n;
+ n = CURSORICON_FindBestIcon(dir,
+ CURSORICON_GetResIconEntry,
+ Width,
+ Height,
+ ColorBits);
+ if (n < 0)
+ return NULL;
+
+ return &dir->idEntries[n];
+}
+
+static GRPCURSORICONDIRENTRY *
+CURSORICON_FindBestCursorRes(GRPCURSORICONDIR *dir,
+ int Width,
+ int Height,
+ int ColorBits)
+{
+ int n;
+ n = CURSORICON_FindBestCursor(dir,
+ CURSORICON_GetResCursorEntry,
+ Width,
+ Height,
+ ColorBits);
+ if (n < 0)
+ return NULL;
+
+ return &dir->idEntries[n];
+}
+
+
+INT WINAPI
+LookupIconIdFromDirectoryEx(PBYTE xdir,
+ BOOL bIcon,
+ INT width,
+ INT height,
+ UINT cFlag)
+{
+ GRPCURSORICONDIR *dir = (GRPCURSORICONDIR*)xdir;
+ UINT retVal = 0;
+
+ GetConnected();
+
+ if(dir && !dir->idReserved && (IMAGE_ICON == dir->idType || IMAGE_CURSOR == dir->idType))
+ {
+ GRPCURSORICONDIRENTRY *entry = NULL;
+ int ColorBits;
+
+ if (cFlag & LR_MONOCHROME)
+ {
+ ColorBits = 1;
+ }
+ else if (cFlag & LR_VGACOLOR)
+ {
+ ColorBits = 4;
+ }
+ else
+ {
+ ColorBits = gpsi->BitsPixel;
+ }
+
+ if(bIcon)
+ entry = CURSORICON_FindBestIconRes(dir, width, height, ColorBits);
+ else
+ entry = CURSORICON_FindBestCursorRes(dir, width, height, 1);
+
+ if (entry)
+ retVal = entry->nID;
+ }
+ else
+ WARN("%s() : Invalid resource directory\n", __FUNCTION__);
+
+ return retVal;
}