Ignore:
Timestamp:
Nov 9, 2000, 7:15:23 PM (25 years ago)
Author:
sandervl
Message:

Icon api rewrite + small fixes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/user32/winicon.cpp

    r3209 r4573  
    1 /* $Id: winicon.cpp,v 1.10 2000-03-23 23:06:54 sandervl Exp $ */
     1/* $Id: winicon.cpp,v 1.11 2000-11-09 18:15:23 sandervl Exp $ */
    22/*
    33 * Win32 Icon Code for OS/2
    44 *
    55 *
    6  * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
    7  *
    8  * Parts based on Wine code (objects\bitmap.c, loader\resource.c, objects\cursoricon.c):
     6 * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl) (OS/2 Port)
     7 *
     8 * Based on Wine code (objects\bitmap.c, loader\resource.c, objects\cursoricon.c):
    99 *
    1010 * Copyright 1993 Alexandre Julliard
     
    1919 */
    2020#include <os2win.h>
     21#include <stdio.h>
     22#include <string.h>
    2123#include <winicon.h>
    2224#include <win\cursoricon.h>
    23 
    24 #define DBG_LOCALLOG    DBG_winicon
     25#include "dib.h"
     26#include <heapstring.h>
     27#include <win\virtual.h>
     28#include "initterm.h"
     29
     30#define DBG_LOCALLOG    DBG_winicon
    2531#include "dbglocal.h"
    2632
     33static WORD ICON_HOTSPOT = 0x4242;
     34
     35static HGLOBAL CURSORICON_CreateFromResource( HINSTANCE hInstance, HGLOBAL hObj, LPBYTE bits,
     36                        UINT cbSize, BOOL bIcon, DWORD dwVersion,
     37                        INT width, INT height, UINT loadflags );
     38static HGLOBAL CURSORICON_Copy( HINSTANCE hInstance, HGLOBAL handle );
     39static CURSORICONDIRENTRY *CURSORICON_FindBestIcon( CURSORICONDIR *dir, int width,
     40                                                    int height, int colors );
     41static CURSORICONDIRENTRY *CURSORICON_FindBestCursor( CURSORICONDIR *dir,
     42                                                  int width, int height, int color);
     43BOOL CURSORICON_SimulateLoadingFromResourceW( LPWSTR filename, BOOL fCursor,
     44                                                CURSORICONDIR **res, LPBYTE **ptr);
     45
     46/***********************************************************************
     47 *           CreateIcon    (USER32.75)
     48 */
     49HICON WIN32API CreateIcon(HINSTANCE hInstance, INT nWidth,
     50                          INT nHeight, BYTE bPlanes, BYTE bBitsPixel,
     51                          LPCVOID lpANDbits, LPCVOID lpXORbits )
     52{
     53    CURSORICONINFO info;
     54
     55    dprintf(("USER32: CreateIcon (%d,%d), %d, %x, %x", nWidth, nHeight, bPlanes * bBitsPixel, lpXORbits, lpANDbits));
     56
     57    info.ptHotSpot.x = ICON_HOTSPOT;
     58    info.ptHotSpot.y = ICON_HOTSPOT;
     59    info.nWidth = nWidth;
     60    info.nHeight = nHeight;
     61    info.nWidthBytes = 0;
     62    info.bPlanes = bPlanes;
     63    info.bBitsPerPixel = bBitsPixel;
     64
     65    return CreateCursorIconIndirect(0, &info, lpANDbits, lpXORbits);
     66}
     67/**********************************************************************
     68 *          CreateIconFromResource          (USER32.76)
     69 */
     70HICON WIN32API CreateIconFromResource(LPBYTE bits, UINT cbSize,
     71                                      BOOL bIcon, DWORD dwVersion)
     72{
     73    return CreateIconFromResourceEx( bits, cbSize, bIcon, dwVersion, 0,0,0);
     74}
    2775//******************************************************************************
    2876//******************************************************************************
    29 HICON WIN32API CreateIcon( HINSTANCE arg1, INT arg2, INT arg3, BYTE arg4, BYTE arg5, LPCVOID arg6, LPCVOID arg7)
    30 {
    31     dprintf(("USER32:  CreateIcon\n"));
    32     return O32_CreateIcon(arg1, arg2, arg3, arg4, arg5, (const BYTE *)arg6, (const BYTE *)arg7);
    33 }
    34 //******************************************************************************
    35 //ASSERT dwVer == win31 (ok according to SDK docs)
    36 //******************************************************************************
    37 HICON WIN32API CreateIconFromResource(PBYTE presbits,  UINT dwResSize,
    38                                       BOOL  fIcon,     DWORD dwVer)
    39 {
    40  HICON hicon;
    41  DWORD OS2ResSize = 0;
    42  PBYTE OS2Icon    = ConvertWin32Icon(presbits, dwResSize, &OS2ResSize);
    43 
    44     hicon = O32_CreateIconFromResource(OS2Icon, OS2ResSize, fIcon, dwVer);
    45     dprintf(("USER32:  CreateIconFromResource returned %X (%X)\n", hicon, GetLastError()));
    46     if(OS2Icon)
    47         FreeIcon(OS2Icon);
    48 
    49     return(hicon);
    50 }
    51 //******************************************************************************
    52 //******************************************************************************
    53 HICON WIN32API CreateIconFromResourceEx(PBYTE presbits,  UINT dwResSize,
    54                                         BOOL  fIcon,     DWORD dwVer,
    55                                         int   cxDesired, int cyDesired,
    56                                         UINT  Flags)
    57 {
    58     dprintf(("USER32:  CreateIconFromResourceEx %X %d %d %X %d %d %X, not completely supported!\n", presbits, dwResSize, fIcon, dwVer, cxDesired, cyDesired, Flags));
    59     return CreateIconFromResource(presbits, dwResSize, fIcon, dwVer);
    60 }
    61 //******************************************************************************
    62 //******************************************************************************
    63 HICON WIN32API CreateIconIndirect(LPICONINFO pIcon)
    64 {
    65  HICON   hIcon;
    66  HDC     hdcSrc, hdcDst;
    67 
    68     dprintf(("USER32:  CreateIconIndirect\n"));
    69     if(pIcon->hbmMask && pIcon->hbmColor)
    70     {
    71         ICONINFO iconinfo;
    72         SIZE bmpsize;
    73 
    74         iconinfo = *pIcon;
    75         if(GetBitmapDimensionEx(pIcon->hbmColor, &bmpsize) == FALSE) {
    76                 return 0;
    77         }
    78         //if there's a color bitmap, the mask bitmap contains only the AND bits
    79         //Open32 calls WinCreatePointerIndirect which expects AND & XOR bits
    80         //To solve this we create a bitmap that's 2x height of the mask, copy
    81         //the AND bits and set the XOR bits to 0
    82         hdcSrc = CreateCompatibleDC(0);
    83         hdcDst = CreateCompatibleDC(0);
    84 
    85         iconinfo.hbmMask  = CreateCompatibleBitmap (hdcDst, bmpsize.cx, bmpsize.cy*2);
    86         SelectObject (hdcDst, iconinfo.hbmMask);
    87         SelectObject (hdcSrc, pIcon->hbmMask);
    88         BitBlt (hdcDst, 0, 0, bmpsize.cx, bmpsize.cy,
    89                 hdcSrc, 0, 0, SRCCOPY);
    90         PatBlt (hdcDst, bmpsize.cx, bmpsize.cy, bmpsize.cx, bmpsize.cy, BLACKNESS);
    91 
    92         hIcon = O32_CreateIconIndirect(&iconinfo);
    93 
    94         DeleteObject(iconinfo.hbmMask);
    95         DeleteDC(hdcSrc);
    96         DeleteDC(hdcDst);
    97 
    98         return hIcon;
    99     }
    100     hIcon = O32_CreateIconIndirect(pIcon);
    101     if(hIcon == 0) {
    102         dprintf(("CreateIconIndirect %d (%d,%d) %x %x failed with %x", pIcon->fIcon, pIcon->xHotspot, pIcon->yHotspot, pIcon->hbmMask, pIcon->hbmColor, GetLastError()));
    103     }
    104     return hIcon;
    105 }
    106 //******************************************************************************
    107 //******************************************************************************
    108 HICON CreateIconIndirect(LPICONINFO pIcon, BOOL bIsIcon, int desiredX, int desiredY, DWORD flags)
    109 {
    110  HICON   hIcon;
    111  HDC     hdcSrc, hdcDst;
    112  BITMAP  bmp;
    113 
    114     if(pIcon->hbmMask && pIcon->hbmColor)
    115     {
    116         ICONINFO iconinfo;
    117         HBITMAP hbmOldSrc, hbmOldDst;
    118 
    119         iconinfo = *pIcon;
    120         GetObjectA(pIcon->hbmColor, sizeof(BITMAP), (LPVOID)&bmp);
    121 
    122         //if there's a color bitmap, the mask bitmap contains only the AND bits
    123         //Open32 calls WinCreatePointerIndirect which expects AND & XOR bits
    124         //To solve this we create a bitmap that's 2x height of the mask, copy
    125         //the AND bits and set the XOR bits to 0
    126         hdcSrc = CreateCompatibleDC(0);
    127         hdcDst = CreateCompatibleDC(0);
    128 
    129         iconinfo.hbmMask  = CreateCompatibleBitmap (hdcDst, desiredX, desiredY*2);
    130         hbmOldDst = SelectObject (hdcDst, iconinfo.hbmMask);
    131         hbmOldSrc = SelectObject (hdcSrc, pIcon->hbmMask);
    132         if(desiredX != bmp.bmWidth || desiredY != bmp.bmHeight) {
    133                 StretchBlt(hdcDst, 0, 0, desiredX, desiredY, hdcSrc, 0, 0,
    134                            bmp.bmWidth, bmp.bmHeight, SRCCOPY);
    135         }
    136         else {
    137                 BitBlt (hdcDst, 0, 0, bmp.bmWidth, bmp.bmHeight,
    138                         hdcSrc, 0, 0, SRCCOPY);
    139         }
    140         PatBlt (hdcDst, desiredX, desiredY, desiredX, desiredY, BLACKNESS);
    141 
    142         if(desiredX != bmp.bmWidth || desiredY != bmp.bmHeight) {
    143                 iconinfo.hbmColor  = CreateCompatibleBitmap (hdcDst, desiredX, desiredY);
    144                 SelectObject (hdcDst, iconinfo.hbmColor);
    145                 SelectObject (hdcSrc, pIcon->hbmColor);
    146                 StretchBlt(hdcDst, 0, 0, desiredX, desiredY, hdcSrc, 0, 0,
    147                            bmp.bmWidth, bmp.bmHeight, SRCCOPY);
    148         }
    149 
    150         hIcon = O32_CreateIconIndirect(&iconinfo);
    151 
    152         DeleteObject(iconinfo.hbmMask);
    153         if(desiredX != bmp.bmWidth || desiredY != bmp.bmHeight) {
    154                 DeleteObject(iconinfo.hbmColor);
    155         }
    156         SelectObject (hdcDst, hbmOldDst);
    157         SelectObject (hdcSrc, hbmOldSrc);
    158         DeleteDC(hdcSrc);
    159         DeleteDC(hdcDst);
    160 
    161         return hIcon;
    162     }
    163     hIcon = O32_CreateIconIndirect(pIcon);
    164     if(hIcon == 0) {
    165         dprintf(("CreateIconIndirect %d (%d,%d) %x %x failed with %x", pIcon->fIcon, pIcon->xHotspot, pIcon->yHotspot, pIcon->hbmMask, pIcon->hbmColor, GetLastError()));
    166     }
    167     return hIcon;
     77HICON WIN32API CreateIconFromResourceEx(LPBYTE bits, UINT cbSize,
     78                                        BOOL bIcon, DWORD dwVersion,
     79                                        INT width, INT height,
     80                                        UINT cFlag )
     81{
     82    dprintf(("USER32:  CreateIconFromResourceEx %X %d %d %X %d %d %X,", bits, cbSize, bIcon, dwVersion, width, height, cFlag));
     83    return CURSORICON_CreateFromResource(0, 0, bits, cbSize, bIcon, dwVersion, width, height, cFlag );
     84}
     85/**********************************************************************
     86 *          CreateIconIndirect      (USER32.78)
     87 */
     88HICON WINAPI CreateIconIndirect(ICONINFO *iconinfo)
     89{
     90    BITMAP bmpXor,bmpAnd;
     91    HICON hObj;
     92    int sizeXor,sizeAnd;
     93
     94    dprintf(("USER32: CreateIconIndirect %x", iconinfo));
     95
     96    GetObjectA( iconinfo->hbmColor, sizeof(bmpXor), &bmpXor );
     97    GetObjectA( iconinfo->hbmMask, sizeof(bmpAnd), &bmpAnd );
     98
     99    sizeXor = bmpXor.bmHeight * bmpXor.bmWidthBytes;
     100    sizeAnd = bmpAnd.bmHeight * bmpAnd.bmWidthBytes;
     101
     102    hObj = GlobalAlloc( GMEM_MOVEABLE, sizeof(CURSORICONINFO) + sizeXor + sizeAnd );
     103    if (hObj)
     104    {
     105        CURSORICONINFO *info;
     106
     107        info = (CURSORICONINFO *)GlobalLock( hObj );
     108
     109        /* If we are creating an icon, the hotspot is unused */
     110        if (iconinfo->fIcon)
     111        {
     112            info->ptHotSpot.x   = ICON_HOTSPOT;
     113            info->ptHotSpot.y   = ICON_HOTSPOT;
     114        }
     115        else
     116        {
     117            info->ptHotSpot.x   = iconinfo->xHotspot;
     118            info->ptHotSpot.y   = iconinfo->yHotspot;
     119        }
     120
     121        info->nWidth        = bmpXor.bmWidth;
     122        info->nHeight       = bmpXor.bmHeight;
     123        info->nWidthBytes   = bmpXor.bmWidthBytes;
     124        info->bPlanes       = bmpXor.bmPlanes;
     125        info->bBitsPerPixel = bmpXor.bmBitsPixel;
     126
     127        /* Transfer the bitmap bits to the CURSORICONINFO structure */
     128        GetBitmapBits( iconinfo->hbmMask ,sizeAnd,(char*)(info + 1) );
     129        GetBitmapBits( iconinfo->hbmColor,sizeXor,(char*)(info + 1) +sizeAnd);
     130        GlobalUnlock(hObj);
     131    }
     132    else {
     133        dprintf(("ERROR: CreateIconIndirect GlobalAlloc failed!!"));
     134    }
     135    return hObj;
    168136}
    169137//******************************************************************************
     
    172140{
    173141    dprintf(("USER32: DestroyIcon %x", hIcon));
    174     return O32_DestroyIcon(hIcon);
     142    return CURSORICON_Destroy( hIcon, 0 );
    175143}
    176144//******************************************************************************
     
    179147{
    180148    dprintf(("USER32:  CopyIcon %x", hIcon));
    181     return O32_CopyIcon(hIcon);
    182 }
    183 //******************************************************************************
    184 //WARNING: MEMORY LEAK & DIRTY HACK TO WORK AROUND OPEN32 BUG
    185 //OS/2 icon masks must be twice the height of the color bitmap
    186 //In Windows, the mask only contains the AND data if there's a color bitmap
    187 //--->> We're allocating a bitmap to replace the mask bitmap, but DON'T DELETE it!
    188 //WARNING: DIRTY HACK TO WORK AROUND OPEN32 BUG
    189 //******************************************************************************
    190 BOOL WIN32API GetIconInfo( HICON hIcon, LPICONINFO pIconInfo)
    191 {
    192  BOOL rc;
    193  HBITMAP hbmMask, hbmOldSrc, hbmOldDst;
    194  BITMAP bmp;
    195 
    196     dprintf(("USER32: GetIconInfo %x", hIcon));
    197     rc = O32_GetIconInfo(hIcon, pIconInfo);
     149    return CURSORICON_Copy( 0, hIcon );
     150}
     151/**********************************************************************
     152 *          GetIconInfo     (USER32.242)
     153 */
     154BOOL WINAPI GetIconInfo(HICON hIcon, ICONINFO *iconinfo)
     155{
     156    CURSORICONINFO  *ciconinfo;
     157
     158    dprintf(("GetIconInfo %x %x", hIcon, iconinfo));
     159
     160    ciconinfo = (CURSORICONINFO *)GlobalLock((HGLOBAL)hIcon);
     161    if (!ciconinfo)
     162        return FALSE;
     163
     164    if((ciconinfo->ptHotSpot.x == ICON_HOTSPOT) &&
     165       (ciconinfo->ptHotSpot.y == ICON_HOTSPOT))
     166    {
     167        iconinfo->fIcon    = TRUE;
     168        iconinfo->xHotspot = ciconinfo->nWidth / 2;
     169        iconinfo->yHotspot = ciconinfo->nHeight / 2;
     170    }
     171    else
     172    {
     173        iconinfo->fIcon    = FALSE;
     174        iconinfo->xHotspot = ciconinfo->ptHotSpot.x;
     175        iconinfo->yHotspot = ciconinfo->ptHotSpot.y;
     176    }
     177
     178    //Create new bitmaps for the color and mask data; application is responsible
     179    //for deleteing them (according to docs & verified in NT4)
     180    if(ciconinfo->bBitsPerPixel > 1)
     181    {
     182        BITMAPINFO* pInfo;
     183        int colorsize = 0;
     184        int coloroff;
     185
     186        HDC hdc = CreateCompatibleDC(0);
     187
     188        if(ciconinfo->bBitsPerPixel <= 8) {
     189            colorsize = (1<<ciconinfo->bBitsPerPixel)*sizeof(RGBQUAD);
     190        }
     191        else {
     192            colorsize = 3*sizeof(DWORD); //color masks
     193        }
     194        pInfo = (BITMAPINFO *)malloc(ciconinfo->nHeight * ciconinfo->nWidthBytes + colorsize + sizeof(BITMAPINFO));
     195        memset(pInfo, 0, sizeof(BITMAPINFO)+colorsize);
     196
     197        pInfo->bmiHeader.biSize     = sizeof(BITMAPINFOHEADER);
     198        pInfo->bmiHeader.biWidth    = ciconinfo->nWidth;
     199        pInfo->bmiHeader.biHeight   = ciconinfo->nHeight,
     200        pInfo->bmiHeader.biPlanes   = ciconinfo->bPlanes;
     201        pInfo->bmiHeader.biBitCount = ciconinfo->bBitsPerPixel;
     202        pInfo->bmiHeader.biSizeImage= ciconinfo->nHeight * ciconinfo->nWidthBytes;
     203
     204        //offset in cursorinfo memory
     205        coloroff = ciconinfo->nHeight * BITMAP_GetWidthBytes (ciconinfo->nWidth, 1);
     206
     207        char *src  = (char *)(ciconinfo + 1) + coloroff;
     208        if(ciconinfo->bBitsPerPixel <= 8) {
     209            src += colorsize;       //no color masks in cursorinfo data for bpp > 8
     210        }
     211        if(ciconinfo->bBitsPerPixel <= 8) {
     212                memcpy(&pInfo->bmiColors[0], (char *)(ciconinfo + 1) + coloroff, colorsize);
     213        }
     214        //else TODO: color masks (curerntly unused in CreateDIBitmap)
     215
     216        iconinfo->hbmColor = CreateDIBitmap(hdc, &pInfo->bmiHeader, CBM_INIT, src, pInfo, DIB_RGB_COLORS);
     217
     218        free(pInfo);
     219        DeleteDC(hdc);
     220    }
     221    else {
     222        iconinfo->hbmColor = CreateBitmap ( ciconinfo->nWidth, ciconinfo->nHeight,
     223                                            ciconinfo->bPlanes, ciconinfo->bBitsPerPixel,
     224                                            (char *)(ciconinfo + 1)
     225                                            + ciconinfo->nHeight *
     226                                            BITMAP_GetWidthBytes (ciconinfo->nWidth, 1) );
     227    }
     228
     229    iconinfo->hbmMask = CreateBitmap ( ciconinfo->nWidth, ciconinfo->nHeight,
     230                                1, 1, (char *)(ciconinfo + 1));
     231
     232    GlobalUnlock(hIcon);
     233
     234    return TRUE;
     235}
     236/***********************************************************************
     237 *           CreateCursorIconIndirect    (USER.408)
     238 */
     239HGLOBAL WIN32API CreateCursorIconIndirect( HINSTANCE hInstance,
     240                                           CURSORICONINFO *info,
     241                                           LPCVOID lpANDbits,
     242                                           LPCVOID lpXORbits )
     243{
     244    HGLOBAL handle;
     245    char *ptr;
     246    int sizeAnd, sizeXor;
     247
     248    if (!lpXORbits || !lpANDbits || info->bPlanes != 1) return 0;
     249    info->nWidthBytes = BITMAP_GetWidthBytes(info->nWidth,info->bBitsPerPixel);
     250    sizeXor = info->nHeight * info->nWidthBytes;
     251    sizeAnd = info->nHeight * BITMAP_GetWidthBytes( info->nWidth, 1 );
     252    if (!(handle = GlobalAlloc( GMEM_MOVEABLE,
     253                                sizeof(CURSORICONINFO) + sizeXor + sizeAnd)))
     254        return 0;
     255    ptr = (char *)GlobalLock( handle );
     256    memcpy( ptr, info, sizeof(*info) );
     257    memcpy( ptr + sizeof(CURSORICONINFO), lpANDbits, sizeAnd );
     258    memcpy( ptr + sizeof(CURSORICONINFO) + sizeAnd, lpXORbits, sizeXor );
     259    GlobalUnlock( handle );
     260    return handle;
     261}
     262/**********************************************************************
     263 *          CURSORICON_Load
     264 *
     265 * Load a cursor or icon from resource or file.
     266 */
     267HGLOBAL CURSORICON_Load( HINSTANCE hInstance, LPCWSTR name,
     268                         INT width, INT height, INT colors,
     269                         BOOL fCursor, UINT loadflags )
     270{
     271    HANDLE handle = 0, h = 0;
     272    HANDLE hRsrc;
     273    CURSORICONDIR *dir;
     274    CURSORICONDIRENTRY *dirEntry;
     275    LPBYTE bits;
     276
     277    if ( loadflags & LR_LOADFROMFILE )    /* Load from file */
     278    {
     279        LPBYTE *ptr;
     280        if (!CURSORICON_SimulateLoadingFromResourceW((LPWSTR)name, fCursor, &dir, &ptr))
     281            return 0;
     282        if (fCursor)
     283            dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestCursor(dir, width, height, 1);
     284        else
     285            dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon(dir, width, height, colors);
     286        bits = ptr[dirEntry->wResId-1];
     287        h = CURSORICON_CreateFromResource( 0, 0, bits, dirEntry->dwBytesInRes,
     288                                           !fCursor, 0x00030000, width, height, loadflags);
     289        HeapFree( GetProcessHeap(), 0, dir );
     290        HeapFree( GetProcessHeap(), 0, ptr );
     291    }
     292    else  /* Load from resource */
     293    {
     294        HANDLE hGroupRsrc;
     295        WORD wResId;
     296        DWORD dwBytesInRes;
     297        BOOL  bIsGroup = TRUE;
     298
     299        /* Get directory resource ID */
     300        if (!hInstance)
     301        {
     302            hRsrc = FindResourceW(hInstanceUser32, name, fCursor ? RT_CURSORW : RT_ICONW);
     303            if(!hRsrc) {
     304                hRsrc = FindResourceW(hInstanceUser32, name, fCursor ? RT_GROUP_CURSORW : RT_GROUP_ICONW);
     305            }
     306            else bIsGroup = FALSE;
     307
     308            if(!hRsrc)  return 0;
     309
     310            hInstance = hInstanceUser32;
     311        }
     312        else {
     313            hRsrc = FindResourceW(hInstance, name, fCursor ? RT_GROUP_CURSORW : RT_GROUP_ICONW);
     314            if(!hRsrc)  return 0;
     315        }
     316        hGroupRsrc = hRsrc;
     317
     318        if(bIsGroup) {
     319            /* Find the best entry in the directory */
     320
     321            if (!(handle = LoadResource( hInstance, hRsrc ))) return 0;
     322            if (!(dir = (CURSORICONDIR*)LockResource( handle ))) return 0;
     323
     324            if (fCursor)
     325                dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestCursor( dir,
     326                                                                  width, height, 1);
     327            else
     328                dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon( dir,
     329                                                           width, height, colors );
     330            if (!dirEntry) return 0;
     331            wResId = dirEntry->wResId;
     332            dwBytesInRes = dirEntry->dwBytesInRes;
     333            FreeResource( handle );
     334
     335            /* Load the resource */
     336            if (!(hRsrc = FindResourceW(hInstance,MAKEINTRESOURCEW(wResId),
     337                                      fCursor ? RT_CURSORW : RT_ICONW ))) return 0;
     338        }
     339
     340        if (!(handle = LoadResource( hInstance, hRsrc ))) return 0;
     341        bits = (LPBYTE)LockResource( handle );
     342        h = CURSORICON_CreateFromResource( 0, 0, bits, dwBytesInRes,
     343                                           !fCursor, 0x00030000, width, height, loadflags);
     344        FreeResource( handle );
     345
     346    }
     347
     348    return h;
     349}
     350
     351/*********************************************************************
     352 * The main purpose of this function is to create fake resource directory
     353 * and fake resource entries. There are several reasons for this:
     354 *  -   CURSORICONDIR and CURSORICONFILEDIR differ in sizes and their
     355 *              fields
     356 *  There are some "bad" cursor files which do not have
     357 *      bColorCount initialized but instead one must read this info
     358 *      directly from corresponding DIB sections
     359 * Note: wResId is index to array of pointer returned in ptrs (origin is 1)
     360 */
     361BOOL CURSORICON_SimulateLoadingFromResourceW( LPWSTR filename, BOOL fCursor,
     362                                              CURSORICONDIR **res, LPBYTE **ptr)
     363{
     364    LPBYTE    _free;
     365    CURSORICONFILEDIR *bits;
     366    int        entries, size, i;
     367    HANDLE     hMapping = 0;
     368
     369    *res = NULL;
     370    *ptr = NULL;
     371
     372    hMapping = VIRTUAL_MapFileW( filename, (LPVOID *)&bits, TRUE);
     373    if(hMapping == INVALID_HANDLE_VALUE)
     374            return FALSE;
     375
     376    /* FIXME: test for inimated icons
     377     * hack to load the first icon from the *.ani file
     378     */
     379    if ( *(LPDWORD)bits==0x46464952 ) /* "RIFF" */
     380    {
     381        LPBYTE pos = (LPBYTE) bits;
     382        dprintf(("Animated icons not correctly implemented! %p \n", bits));
     383
     384        for (;;)
     385        {
     386            if (*(LPDWORD)pos==0x6e6f6369)      /* "icon" */
     387            {
     388                dprintf(("icon entry found! %p\n", bits));
     389                pos+=4;
     390                if ( !*(LPWORD) pos==0x2fe)       /* iconsize */
     391                {
     392                    goto fail;
     393                }
     394                bits=(CURSORICONFILEDIR*)(pos+4);
     395                dprintf(("icon size ok. offset=%p \n", bits));
     396                break;
     397            }
     398            pos+=2;
     399            if (pos>=(LPBYTE)bits+766) goto fail;
     400        }
     401    }
     402    if (!(entries = bits->idCount)) goto fail;
     403    size = sizeof(CURSORICONDIR) + sizeof(CURSORICONDIRENTRY) * (entries - 1);
     404    _free = (LPBYTE) size;
     405
     406    for (i=0; i < entries; i++)
     407      size += bits->idEntries[i].dwDIBSize + (fCursor ? sizeof(POINT16): 0);
     408
     409    if (!(*ptr = (LPBYTE *)HeapAlloc( GetProcessHeap(), 0,
     410                            entries * sizeof (CURSORICONDIRENTRY*)))) goto fail;
     411    if (!(*res = (CURSORICONDIR *)HeapAlloc( GetProcessHeap(), 0, size))) goto fail;
     412
     413    _free = (LPBYTE)(*res) + (int)_free;
     414    memcpy((*res), bits, 6);
     415    for (i=0; i<entries; i++)
     416    {
     417      ((LPBYTE*)(*ptr))[i] = _free;
     418      if (fCursor) {
     419        (*res)->idEntries[i].ResInfo.cursor.wWidth=bits->idEntries[i].bWidth;
     420        (*res)->idEntries[i].ResInfo.cursor.wHeight=bits->idEntries[i].bHeight;
     421        ((LPPOINT16)_free)->x=bits->idEntries[i].xHotspot;
     422        ((LPPOINT16)_free)->y=bits->idEntries[i].yHotspot;
     423        _free+=sizeof(POINT16);
     424      }
     425      else {
     426        (*res)->idEntries[i].ResInfo.icon.bWidth=bits->idEntries[i].bWidth;
     427        (*res)->idEntries[i].ResInfo.icon.bHeight=bits->idEntries[i].bHeight;
     428        (*res)->idEntries[i].ResInfo.icon.bColorCount = bits->idEntries[i].bColorCount;
     429      }
     430      (*res)->idEntries[i].wPlanes=1;
     431      (*res)->idEntries[i].wBitCount = ((LPBITMAPINFOHEADER)((LPBYTE)bits +
     432                                                   bits->idEntries[i].dwDIBOffset))->biBitCount;
     433      (*res)->idEntries[i].dwBytesInRes = bits->idEntries[i].dwDIBSize;
     434      (*res)->idEntries[i].wResId=i+1;
     435
     436      memcpy(_free,(LPBYTE)bits +bits->idEntries[i].dwDIBOffset,
     437             (*res)->idEntries[i].dwBytesInRes);
     438      _free += (*res)->idEntries[i].dwBytesInRes;
     439    }
     440    UnmapViewOfFile( bits );
     441    CloseHandle(hMapping);
     442    return TRUE;
     443
     444fail:
     445    if (*res) HeapFree( GetProcessHeap(), 0, *res );
     446    if (*ptr) HeapFree( GetProcessHeap(), 0, *ptr );
     447
     448    UnmapViewOfFile( bits );
     449    CloseHandle(hMapping);
     450    return FALSE;
     451}
     452
     453/**********************************************************************
     454 *      CURSORICON_CreateFromResource
     455 *
     456 * Create a cursor or icon from in-memory resource template.
     457 *
     458 * FIXME: Convert to mono when cFlag is LR_MONOCHROME. Do something
     459 *        with cbSize parameter as well.
     460 */
     461static HGLOBAL CURSORICON_CreateFromResource( HINSTANCE hInstance, HGLOBAL hObj, LPBYTE bits,
     462                        UINT cbSize, BOOL bIcon, DWORD dwVersion,
     463                        INT width, INT height, UINT loadflags )
     464{
     465    int sizeAnd, sizeXor;
     466    HBITMAP hAndBits = 0, hXorBits = 0; /* error condition for later */
     467    BITMAP bmpXor, bmpAnd;
     468    POINT16 hotspot;
     469    BITMAPINFO *bmi;
     470    HDC hdc = 0;
     471    BOOL DoStretch;
     472    INT size, colortablesize;
     473
     474    hotspot.x = ICON_HOTSPOT;
     475    hotspot.y = ICON_HOTSPOT;
     476
     477    if (dwVersion == 0x00020000)
     478    {
     479        dprintf(("CURSORICON_CreateFromResource 2.xx resources are not supported"));
     480        return 0;
     481    }
     482
     483    if (bIcon) {
     484        bmi = (BITMAPINFO *)bits;
     485    }
     486    else /* get the hotspot */
     487    {
     488        POINT16 *pt = (POINT16 *)bits;
     489        hotspot = *pt;
     490        bmi = (BITMAPINFO *)(pt + 1);
     491    }
     492    size = DIB_BitmapInfoSize(bmi, DIB_RGB_COLORS);
     493
     494    if (!width) width = bmi->bmiHeader.biWidth;
     495    if (!height) height = bmi->bmiHeader.biHeight/2;
     496
     497    DoStretch = (bmi->bmiHeader.biHeight/2 != height) || (bmi->bmiHeader.biWidth != width);
     498
     499    /* Check bitmap header */
     500    if ( (bmi->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) &&
     501     (bmi->bmiHeader.biSize != sizeof(BITMAPINFOHEADER)  ||
     502      bmi->bmiHeader.biCompression != BI_RGB) )
     503    {
     504        return 0;
     505    }
     506
     507    if( (hdc = GetDC( 0 )) )
     508    {
     509        BITMAPINFO* pInfo;
     510
     511        /* Make sure we have room for the monochrome bitmap later on.
     512         * Note that BITMAPINFOINFO and BITMAPCOREHEADER are the same
     513         * up to and including the biBitCount. In-memory icon resource
     514         * format is as follows:
     515         *
     516         *   BITMAPINFOHEADER   icHeader  // DIB header
     517         *   RGBQUAD         icColors[]   // Color table
     518         *   BYTE            icXOR[]      // DIB bits for XOR mask
     519         *   BYTE            icAND[]      // DIB bits for AND mask
     520         */
     521
     522        if ((pInfo = (BITMAPINFO *)HeapAlloc( GetProcessHeap(), 0,
     523                                              max(size, sizeof(BITMAPINFOHEADER) + 2*sizeof(RGBQUAD)))))
     524        {
     525            memcpy( pInfo, bmi, size );
     526            pInfo->bmiHeader.biHeight /= 2;
     527
     528            /* Create the XOR bitmap */
     529            if (DoStretch)
     530            {
     531                if(bIcon)
     532                {
     533                    hXorBits = CreateCompatibleBitmap(hdc, width, height);
     534                }
     535                else
     536                {
     537                    hXorBits = CreateBitmap(width, height, 1, 1, NULL);
     538                }
     539                if(hXorBits)
     540                {
     541                    HBITMAP hOld;
     542                    HDC hMem = CreateCompatibleDC(hdc);
     543                    BOOL res;
     544
     545                    if (hMem) {
     546                        hOld = SelectObject(hMem, hXorBits);
     547                        res = StretchDIBits(hMem, 0, 0, width, height, 0, 0,
     548                                            bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight/2,
     549                                            (char*)bmi + size, pInfo, DIB_RGB_COLORS, SRCCOPY);
     550                        SelectObject(hMem, hOld);
     551                        DeleteDC(hMem);
     552                    }
     553                    else res = FALSE;
     554                    if (!res) {
     555                        DeleteObject(hXorBits);
     556                        hXorBits = 0;
     557                    }
     558                }
     559            }
     560            else
     561            {
     562                hXorBits = CreateDIBitmap(hdc, &pInfo->bmiHeader,
     563                                          CBM_INIT, (char*)bmi + size, pInfo, DIB_RGB_COLORS );
     564            }
     565            if( hXorBits )
     566            {
     567                char* xbits = (char *)bmi + size + DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth,
     568                                                                        bmi->bmiHeader.biHeight,
     569                                                                        bmi->bmiHeader.biBitCount) / 2;
     570
     571                pInfo->bmiHeader.biBitCount = 1;
     572                if (pInfo->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
     573                {
     574                    RGBQUAD *rgb = pInfo->bmiColors;
     575
     576                    pInfo->bmiHeader.biClrUsed = pInfo->bmiHeader.biClrImportant = 2;
     577                    rgb[0].rgbBlue = rgb[0].rgbGreen = rgb[0].rgbRed = 0x00;
     578                    rgb[1].rgbBlue = rgb[1].rgbGreen = rgb[1].rgbRed = 0xff;
     579                    rgb[0].rgbReserved = rgb[1].rgbReserved = 0;
     580                }
     581                else
     582                {
     583                    RGBTRIPLE *rgb = (RGBTRIPLE *)(((BITMAPCOREHEADER *)pInfo) + 1);
     584
     585                    rgb[0].rgbtBlue = rgb[0].rgbtGreen = rgb[0].rgbtRed = 0x00;
     586                    rgb[1].rgbtBlue = rgb[1].rgbtGreen = rgb[1].rgbtRed = 0xff;
     587                }
     588
     589                /* Create the AND bitmap */
     590                if (DoStretch)
     591                {
     592                    if ((hAndBits = CreateBitmap(width, height, 1, 1, NULL)))
     593                    {
     594                        HBITMAP hOld;
     595                        HDC hMem = CreateCompatibleDC(hdc);
     596                        BOOL res;
     597
     598                        if (hMem) {
     599                            hOld = SelectObject(hMem, hAndBits);
     600                            res = StretchDIBits(hMem, 0, 0, width, height, 0, 0,
     601                                                pInfo->bmiHeader.biWidth, pInfo->bmiHeader.biHeight,
     602                                                xbits, pInfo, DIB_RGB_COLORS, SRCCOPY);
     603                            SelectObject(hMem, hOld);
     604                            DeleteDC(hMem);
     605                        }
     606                        else res = FALSE;
     607                        if (!res) {
     608                            DeleteObject(hAndBits); hAndBits = 0;
     609                        }
     610                    }
     611                }
     612                else {
     613//SvL: Must use CreateBitmap here as CreateDIBitmap converts data to 8bpp (GetObjectA info -> 8 bpp)
    198614#if 1
    199     if(rc && pIconInfo->hbmColor)
    200     {
    201         HDC  hdcSrc, hdcDst;
    202         hdcSrc = CreateCompatibleDC(0);
    203         hdcDst = CreateCompatibleDC(0);
    204 
    205         GetObjectA(pIconInfo->hbmColor, sizeof(BITMAP), (LPVOID)&bmp);
    206 
    207         hbmMask = CreateCompatibleBitmap (hdcDst, bmp.bmWidth, bmp.bmHeight);
    208         hbmOldDst = SelectObject (hdcDst, hbmMask);
    209         hbmOldSrc = SelectObject (hdcSrc, pIconInfo->hbmMask);
    210         BitBlt (hdcDst, 0, 0, bmp.bmWidth, bmp.bmHeight,
    211                 hdcSrc, 0, 0, SRCCOPY);
    212 
    213         SelectObject(hdcDst, hbmOldDst);
    214         SelectObject(hdcSrc, hbmOldSrc);
    215         DeleteDC(hdcDst);
    216         DeleteDC(hdcSrc);
    217         DeleteObject(pIconInfo->hbmMask);
    218         pIconInfo->hbmMask = hbmMask;
    219     }
     615                    int linewidth = BITMAP_GetWidthBytes(width, 1);
     616
     617                    char *newpix = (char *)malloc(linewidth*height);
     618
     619                    newpix += ((height-1)*linewidth);
     620
     621                    for(int i=0;i<height;i++) {
     622                        memcpy(newpix, xbits, linewidth);
     623                        newpix -= linewidth;
     624                        xbits  += linewidth;
     625                    }
     626                    newpix += linewidth;
     627                    hAndBits = CreateBitmap(width, height, 1, 1, newpix);
     628
     629                    free(newpix);
     630
     631#else
     632                    hAndBits = CreateDIBitmap(hdc, &pInfo->bmiHeader,
     633                                              CBM_INIT, xbits, pInfo, DIB_RGB_COLORS );
    220634#endif
    221     return rc;
    222 }
     635                }
     636                if( !hAndBits )
     637                    DeleteObject( hXorBits );
     638             }
     639             HeapFree( GetProcessHeap(), 0, pInfo );
     640        }
     641        ReleaseDC( 0, hdc );
     642    }
     643
     644    if( !hXorBits || !hAndBits )
     645    {
     646        dprintf(("\tunable to create an icon bitmap.\n"));
     647        return 0;
     648    }
     649
     650    /* Now create the CURSORICONINFO structure */
     651    GetObjectA( hXorBits, sizeof(bmpXor), &bmpXor );
     652    GetObjectA( hAndBits, sizeof(bmpAnd), &bmpAnd );
     653    colortablesize = 0;
     654
     655    if(bmpXor.bmBitsPixel <= 8) {
     656         colortablesize = sizeof(RGBQUAD)*(1<<bmpXor.bmBitsPixel);
     657         sizeXor = bmpXor.bmHeight * bmpXor.bmWidthBytes + colortablesize;
     658    }
     659    else sizeXor = bmpXor.bmHeight * bmpXor.bmWidthBytes;
     660
     661    sizeAnd = bmpAnd.bmHeight * bmpAnd.bmWidthBytes;
     662
     663    if (hObj) hObj = GlobalReAlloc( hObj,
     664             sizeof(CURSORICONINFO) + sizeXor + sizeAnd, GMEM_MOVEABLE );
     665    if (!hObj) hObj = GlobalAlloc( GMEM_MOVEABLE,
     666             sizeof(CURSORICONINFO) + sizeXor + sizeAnd );
     667    if (hObj)
     668    {
     669        CURSORICONINFO *info;
     670
     671        info = (CURSORICONINFO *)GlobalLock( hObj );
     672        info->ptHotSpot.x   = hotspot.x;
     673        info->ptHotSpot.y   = hotspot.y;
     674        info->nWidth        = bmpXor.bmWidth;
     675        info->nHeight       = bmpXor.bmHeight;
     676        info->nWidthBytes   = bmpXor.bmWidthBytes;
     677        info->bPlanes       = bmpXor.bmPlanes;
     678        info->bBitsPerPixel = bmpXor.bmBitsPixel;
     679        info->hColorBmp     = hXorBits;
     680
     681        /* Transfer the bitmap bits to the CURSORICONINFO structure */
     682        GetBitmapBits( hAndBits, sizeAnd, (char *)(info + 1));
     683
     684        if(bmpXor.bmBitsPixel > 1)
     685        {
     686            BITMAPINFO* pInfo = (BITMAPINFO *)malloc(sizeof(BITMAPINFO)+colortablesize+3*sizeof(DWORD)); //+ extra space for > 8bpp images
     687            HBITMAP oldbmp;
     688
     689            hdc = CreateCompatibleDC(0);
     690
     691            pInfo->bmiHeader.biSize     = sizeof(BITMAPINFOHEADER);
     692            pInfo->bmiHeader.biPlanes   = info->bPlanes;
     693            pInfo->bmiHeader.biBitCount = info->bBitsPerPixel;
     694
     695            GetDIBits(hdc, hXorBits, 0, bmpXor.bmHeight, (char *)(info + 1) + sizeAnd + colortablesize, pInfo, DIB_RGB_COLORS);
     696            if(colortablesize) {
     697                memcpy((char *)(info + 1) + sizeAnd, (char *)&pInfo->bmiHeader + pInfo->bmiHeader.biSize, colortablesize);
     698            }
     699
     700            DeleteDC(hdc);
     701            free(pInfo);
     702        }
     703        else {
     704            GetBitmapBits( hXorBits, sizeXor, (char *)(info + 1) + sizeAnd);
     705        }
     706        GlobalUnlock( hObj );
     707    }
     708
     709    DeleteObject( hAndBits );
     710    DeleteObject( hXorBits );
     711    return hObj;
     712}
     713
     714/**********************************************************************
     715 *      CURSORICON_Destroy   (USER.610)
     716 *
     717 * This routine is actually exported from Win95 USER under the name
     718 * DestroyIcon32 ...  The behaviour implemented here should mimic
     719 * the Win95 one exactly, especially the return values, which
     720 * depend on the setting of various flags.
     721 */
     722WORD WIN32API CURSORICON_Destroy( HGLOBAL handle, UINT flags )
     723{
     724    WORD retv;
     725
     726#if 0
     727    /* Check whether destroying active cursor */
     728
     729    if ( hActiveCursor == handle )
     730    {
     731        ERR_(cursor)("Destroying active cursor!\n" );
     732        SetCursor( 0 );
     733    }
     734    /* Try shared cursor/icon first */
     735
     736    if ( !(flags & CID_NONSHARED) )
     737    {
     738        INT count = CURSORICON_DelSharedIcon( handle );
     739
     740        if ( count != -1 )
     741            return (flags & CID_WIN32)? TRUE : (count == 0);
     742
     743        /* FIXME: OEM cursors/icons should be recognized */
     744    }
     745#endif
     746    /* Now assume non-shared cursor/icon */
     747
     748    retv = GlobalFree( handle );
     749    return (flags & CID_RESOURCE)? retv : TRUE;
     750}
     751
     752/***********************************************************************
     753 *           CURSORICON_Copy
     754 *
     755 * Make a copy of a cursor or icon.
     756 */
     757static HGLOBAL CURSORICON_Copy( HINSTANCE hInstance, HGLOBAL handle )
     758{
     759    char *ptrOld, *ptrNew;
     760    int size;
     761    HGLOBAL hNew;
     762
     763    if (!(ptrOld = (char *)GlobalLock( handle ))) return 0;
     764
     765    size = GlobalSize( handle );
     766    hNew = GlobalAlloc( GMEM_MOVEABLE, size );
     767    ptrNew = (char *)GlobalLock( hNew );
     768    memcpy( ptrNew, ptrOld, size );
     769    GlobalUnlock( handle );
     770    GlobalUnlock( hNew );
     771    return hNew;
     772}
     773
     774/*************************************************************************
     775 * CURSORICON_ExtCopy
     776 *
     777 * Copies an Image from the Cache if LR_COPYFROMRESOURCE is specified
     778 *
     779 * PARAMS
     780 *      Handle     [I] handle to an Image
     781 *      nType      [I] Type of Handle (IMAGE_CURSOR | IMAGE_ICON)
     782 *      iDesiredCX [I] The Desired width of the Image
     783 *      iDesiredCY [I] The desired height of the Image
     784 *      nFlags     [I] The flags from CopyImage
     785 *
     786 * RETURNS
     787 *     Success: The new handle of the Image
     788 *
     789 * NOTES
     790 *     LR_COPYDELETEORG and LR_MONOCHROME are currently not implemented.
     791 *     LR_MONOCHROME should be implemented by CURSORICON_CreateFromResource.
     792 *     LR_COPYFROMRESOURCE will only work if the Image is in the Cache.
     793 *
     794 *
     795 */
     796
     797HGLOBAL CURSORICON_ExtCopy(HGLOBAL Handle, UINT nType,
     798               INT iDesiredCX, INT iDesiredCY,
     799               UINT nFlags)
     800{
     801    HGLOBAL hNew=0;
     802
     803    if(Handle == 0)
     804    {
     805        return 0;
     806    }
     807
     808    hNew = CURSORICON_Copy(0, Handle);
     809    return hNew;
     810}
     811
    223812/**********************************************************************
    224813 *          CURSORICON_FindBestIcon
     
    329918}
    330919/**********************************************************************
    331  *          LookupIconIdFromDirectoryEx16       (USER.364)
     920 *          LookupIconIdFromDirectoryEx       (USER.364)
    332921 *
    333922 * FIXME: exact parameter sizes
     
    373962           bIcon ? GetSystemMetrics(SM_CYICON) : GetSystemMetrics(SM_CYCURSOR), bIcon ? 0 : LR_MONOCHROME );
    374963}
    375 /*************************************************************************
    376  * CURSORICON_ExtCopy
    377  *
    378  * Copies an Image from the Cache if LR_COPYFROMRESOURCE is specified
    379  *
    380  * PARAMS
    381  *      Handle     [I] handle to an Image
    382  *      nType      [I] Type of Handle (IMAGE_CURSOR | IMAGE_ICON)
    383  *      iDesiredCX [I] The Desired width of the Image
    384  *      iDesiredCY [I] The desired height of the Image
    385  *      nFlags     [I] The flags from CopyImage
    386  *
    387  * RETURNS
    388  *     Success: The new handle of the Image
    389  *
    390  * NOTES
    391  *     LR_COPYDELETEORG and LR_MONOCHROME are currently not implemented.
    392  *     LR_MONOCHROME should be implemented by CURSORICON_CreateFromResource.
    393  *     LR_COPYFROMRESOURCE will only work if the Image is in the Cache.
    394  *
    395  *
    396  * TODO: LR_COPYFROMRESOURCE doesn't work. Uses supplied icon instead
    397  *
    398  */
    399 HGLOBAL CopyCursorIcon(HGLOBAL Handle, UINT nType,
    400                        INT iDesiredCX, INT iDesiredCY,
    401                        UINT nFlags)
    402 {
    403     HGLOBAL hNew=0;
    404     BOOL bIsIcon = (nType == IMAGE_ICON);
    405 
    406     if(Handle == 0)
    407     {
    408         return 0;
    409     }
    410 
    411     /* Best Fit or Monochrome */
    412     if(!bIsIcon || (nFlags & LR_COPYFROMRESOURCE
    413         && (iDesiredCX > 0 || iDesiredCY > 0))
    414         || nFlags & LR_MONOCHROME)
    415     {
    416             LPBYTE pBits;
    417             HANDLE hMem;
    418             HRSRC hRsrc;
    419             DWORD dwBytesInRes;
    420             WORD wResId;
    421             CURSORICONDIR *pDir;
    422             CURSORICONDIRENTRY *pDirEntry;
    423 
    424             /* Completing iDesiredCX CY for Monochrome Bitmaps if needed
    425             */
    426             if(((nFlags & LR_MONOCHROME) && !(nFlags & LR_COPYFROMRESOURCE))
    427                 || (iDesiredCX == 0 && iDesiredCY == 0))
    428             {
    429                 iDesiredCY = GetSystemMetrics(bIsIcon ?
    430                     SM_CYICON : SM_CYCURSOR);
    431                 iDesiredCX = GetSystemMetrics(bIsIcon ?
    432                     SM_CXICON : SM_CXCURSOR);
    433             }
    434 
    435             /* Create a New Icon with the proper dimension
    436             */
    437             ICONINFO iconinfo;
    438 
    439             GetIconInfo(Handle, &iconinfo);
    440             hNew = CreateIconIndirect(&iconinfo, bIsIcon, iDesiredCX, iDesiredCY, nFlags);
    441     }
    442     else
    443     {
    444         if(bIsIcon) {
    445                 return CopyIcon(Handle);
    446         }
    447         else    return CopyCursor(Handle);
    448     }
    449     return hNew;
    450 }
    451964//******************************************************************************
    452965//******************************************************************************
Note: See TracChangeset for help on using the changeset viewer.