Ignore:
Timestamp:
Dec 20, 1999, 5:45:18 PM (26 years ago)
Author:
cbratschi
Message:

some icon bug fixes

File:
1 edited

Legend:

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

    r1810 r2160  
    1 /* $Id: winicon.cpp,v 1.5 1999-11-22 20:33:25 sandervl Exp $ */
     1/* $Id: winicon.cpp,v 1.6 1999-12-20 16:45:18 cbratschi Exp $ */
    22/*
    33 * Win32 Icon Code for OS/2
     
    7070
    7171    dprintf(("USER32:  CreateIconIndirect\n"));
    72     if(pIcon->hbmMask && pIcon->hbmColor) 
    73     {
    74         ICONINFO iconinfo;
    75         SIZE bmpsize;
    76 
    77         iconinfo = *pIcon;
    78         if(GetBitmapDimensionEx(pIcon->hbmColor, &bmpsize) == FALSE) {
    79                 return 0;
    80         }
    81         //if there's a color bitmap, the mask bitmap contains only the AND bits
     72    if(pIcon->hbmMask && pIcon->hbmColor)
     73    {
     74        ICONINFO iconinfo;
     75        SIZE bmpsize;
     76
     77        iconinfo = *pIcon;
     78        if(GetBitmapDimensionEx(pIcon->hbmColor, &bmpsize) == FALSE) {
     79                return 0;
     80        }
     81        //if there's a color bitmap, the mask bitmap contains only the AND bits
    8282        //Open32 calls WinCreatePointerIndirect which expects AND & XOR bits
    8383        //To solve this we create a bitmap that's 2x height of the mask, copy
    8484        //the AND bits and set the XOR bits to 0
    85         hdcSrc = CreateCompatibleDC(0);
    86         hdcDst = CreateCompatibleDC(0);
    87 
    88         iconinfo.hbmMask  = CreateCompatibleBitmap (hdcDst, bmpsize.cx, bmpsize.cy*2);
    89         SelectObject (hdcDst, iconinfo.hbmMask);
    90         SelectObject (hdcSrc, pIcon->hbmMask);
    91         BitBlt (hdcDst, 0, 0, bmpsize.cx, bmpsize.cy,
     85        hdcSrc = CreateCompatibleDC(0);
     86        hdcDst = CreateCompatibleDC(0);
     87
     88        iconinfo.hbmMask  = CreateCompatibleBitmap (hdcDst, bmpsize.cx, bmpsize.cy*2);
     89        SelectObject (hdcDst, iconinfo.hbmMask);
     90        SelectObject (hdcSrc, pIcon->hbmMask);
     91        BitBlt (hdcDst, 0, 0, bmpsize.cx, bmpsize.cy,
    9292                hdcSrc, 0, 0, SRCCOPY);
    93         PatBlt (hdcDst, bmpsize.cx, bmpsize.cy, bmpsize.cx, bmpsize.cy, BLACKNESS);
    94        
    95         hIcon = O32_CreateIconIndirect(&iconinfo);
    96 
    97         DeleteObject(iconinfo.hbmMask);
    98         DeleteDC(hdcSrc);
    99         DeleteDC(hdcDst);
    100 
    101         return hIcon;
     93        PatBlt (hdcDst, bmpsize.cx, bmpsize.cy, bmpsize.cx, bmpsize.cy, BLACKNESS);
     94
     95        hIcon = O32_CreateIconIndirect(&iconinfo);
     96
     97        DeleteObject(iconinfo.hbmMask);
     98        DeleteDC(hdcSrc);
     99        DeleteDC(hdcDst);
     100
     101        return hIcon;
    102102    }
    103103    hIcon = O32_CreateIconIndirect(pIcon);
    104104    if(hIcon == 0) {
    105         dprintf(("CreateIconIndirect %d (%d,%d) %x %x failed with %x", pIcon->fIcon, pIcon->xHotspot, pIcon->yHotspot, pIcon->hbmMask, pIcon->hbmColor, GetLastError()));
     105        dprintf(("CreateIconIndirect %d (%d,%d) %x %x failed with %x", pIcon->fIcon, pIcon->xHotspot, pIcon->yHotspot, pIcon->hbmMask, pIcon->hbmColor, GetLastError()));
    106106    }
    107107    return hIcon;
     
    115115 BITMAP  bmp;
    116116
    117     if(pIcon->hbmMask && pIcon->hbmColor) 
    118     {
    119         ICONINFO iconinfo;
    120         HBITMAP hbmOldSrc, hbmOldDst;
    121 
    122         iconinfo = *pIcon;
    123         GetObjectA(pIcon->hbmColor, sizeof(BITMAP), (LPVOID)&bmp);
    124 
    125         //if there's a color bitmap, the mask bitmap contains only the AND bits
     117    if(pIcon->hbmMask && pIcon->hbmColor)
     118    {
     119        ICONINFO iconinfo;
     120        HBITMAP hbmOldSrc, hbmOldDst;
     121
     122        iconinfo = *pIcon;
     123        GetObjectA(pIcon->hbmColor, sizeof(BITMAP), (LPVOID)&bmp);
     124
     125        //if there's a color bitmap, the mask bitmap contains only the AND bits
    126126        //Open32 calls WinCreatePointerIndirect which expects AND & XOR bits
    127127        //To solve this we create a bitmap that's 2x height of the mask, copy
    128128        //the AND bits and set the XOR bits to 0
    129         hdcSrc = CreateCompatibleDC(0);
    130         hdcDst = CreateCompatibleDC(0);
    131 
    132         iconinfo.hbmMask  = CreateCompatibleBitmap (hdcDst, desiredX, desiredY*2);
    133         hbmOldDst = SelectObject (hdcDst, iconinfo.hbmMask);
    134         hbmOldSrc = SelectObject (hdcSrc, pIcon->hbmMask);
    135         if(desiredX != bmp.bmWidth || desiredY != bmp.bmHeight) {
    136                 StretchBlt(hdcDst, 0, 0, desiredX, desiredY, hdcSrc, 0, 0,
     129        hdcSrc = CreateCompatibleDC(0);
     130        hdcDst = CreateCompatibleDC(0);
     131
     132        iconinfo.hbmMask  = CreateCompatibleBitmap (hdcDst, desiredX, desiredY*2);
     133        hbmOldDst = SelectObject (hdcDst, iconinfo.hbmMask);
     134        hbmOldSrc = SelectObject (hdcSrc, pIcon->hbmMask);
     135        if(desiredX != bmp.bmWidth || desiredY != bmp.bmHeight) {
     136                StretchBlt(hdcDst, 0, 0, desiredX, desiredY, hdcSrc, 0, 0,
    137137                           bmp.bmWidth, bmp.bmHeight, SRCCOPY);
    138         }
    139         else {
    140                 BitBlt (hdcDst, 0, 0, bmp.bmWidth, bmp.bmHeight,
    141                         hdcSrc, 0, 0, SRCCOPY);
    142         }
    143         PatBlt (hdcDst, desiredX, desiredY, desiredX, desiredY, BLACKNESS);
    144 
    145         if(desiredX != bmp.bmWidth || desiredY != bmp.bmHeight) {
    146                 iconinfo.hbmColor  = CreateCompatibleBitmap (hdcDst, desiredX, desiredY);
    147                 SelectObject (hdcDst, iconinfo.hbmColor);
    148                 SelectObject (hdcSrc, pIcon->hbmColor);
    149                 StretchBlt(hdcDst, 0, 0, desiredX, desiredY, hdcSrc, 0, 0,
     138        }
     139        else {
     140                BitBlt (hdcDst, 0, 0, bmp.bmWidth, bmp.bmHeight,
     141                        hdcSrc, 0, 0, SRCCOPY);
     142        }
     143        PatBlt (hdcDst, desiredX, desiredY, desiredX, desiredY, BLACKNESS);
     144
     145        if(desiredX != bmp.bmWidth || desiredY != bmp.bmHeight) {
     146                iconinfo.hbmColor  = CreateCompatibleBitmap (hdcDst, desiredX, desiredY);
     147                SelectObject (hdcDst, iconinfo.hbmColor);
     148                SelectObject (hdcSrc, pIcon->hbmColor);
     149                StretchBlt(hdcDst, 0, 0, desiredX, desiredY, hdcSrc, 0, 0,
    150150                           bmp.bmWidth, bmp.bmHeight, SRCCOPY);
    151         }
    152        
    153         hIcon = O32_CreateIconIndirect(&iconinfo);
    154 
    155         DeleteObject(iconinfo.hbmMask);
    156         if(desiredX != bmp.bmWidth || desiredY != bmp.bmHeight) {
    157                 DeleteObject(iconinfo.hbmColor);
    158         }
    159         SelectObject (hdcDst, hbmOldDst);
    160         SelectObject (hdcSrc, hbmOldSrc);
    161         DeleteDC(hdcSrc);
    162         DeleteDC(hdcDst);
    163 
    164         return hIcon;
     151        }
     152
     153        hIcon = O32_CreateIconIndirect(&iconinfo);
     154
     155        DeleteObject(iconinfo.hbmMask);
     156        if(desiredX != bmp.bmWidth || desiredY != bmp.bmHeight) {
     157                DeleteObject(iconinfo.hbmColor);
     158        }
     159        SelectObject (hdcDst, hbmOldDst);
     160        SelectObject (hdcSrc, hbmOldSrc);
     161        DeleteDC(hdcSrc);
     162        DeleteDC(hdcDst);
     163
     164        return hIcon;
    165165    }
    166166    hIcon = O32_CreateIconIndirect(pIcon);
    167167    if(hIcon == 0) {
    168         dprintf(("CreateIconIndirect %d (%d,%d) %x %x failed with %x", pIcon->fIcon, pIcon->xHotspot, pIcon->yHotspot, pIcon->hbmMask, pIcon->hbmColor, GetLastError()));
     168        dprintf(("CreateIconIndirect %d (%d,%d) %x %x failed with %x", pIcon->fIcon, pIcon->xHotspot, pIcon->yHotspot, pIcon->hbmMask, pIcon->hbmColor, GetLastError()));
    169169    }
    170170    return hIcon;
     
    189189//In Windows, the mask only contains the AND data if there's a color bitmap
    190190//--->> We're allocating a bitmap to replace the mask bitmap, but DON'T DELETE it!
    191 //WARNING: MEMORY LEAK & DIRTY HACK TO WORK AROUND OPEN32 BUG
     191//WARNING: DIRTY HACK TO WORK AROUND OPEN32 BUG
    192192//******************************************************************************
    193193BOOL WIN32API GetIconInfo( HICON hIcon, LPICONINFO pIconInfo)
     
    199199    dprintf(("USER32: GetIconInfo %x", hIcon));
    200200    rc = O32_GetIconInfo(hIcon, pIconInfo);
    201 #if 0
    202     if(rc && pIconInfo->hbmColor)
    203     {
    204         HDC  hdcSrc, hdcDst;
    205         hdcSrc = CreateCompatibleDC(0);
    206         hdcDst = CreateCompatibleDC(0);
    207 
    208         GetObjectA(pIconInfo->hbmMask, sizeof(BITMAP), (LPVOID)&bmp);
    209 
    210         hbmMask = CreateCompatibleBitmap (hdcDst, bmp.bmWidth, bmp.bmHeight/2);
    211         hbmOldDst = SelectObject (hdcDst, hbmMask);
    212         hbmOldSrc = SelectObject (hdcSrc, pIconInfo->hbmMask);
    213         BitBlt (hdcDst, 0, 0, bmp.bmWidth, bmp.bmHeight/2,
    214                 hdcSrc, 0, bmp.bmHeight/2, SRCCOPY);
    215 
    216         SelectObject(hdcDst, hbmOldDst);
    217         SelectObject(hdcSrc, hbmOldSrc);
    218         DeleteDC(hdcDst);
    219         DeleteDC(hdcSrc);
    220         pIconInfo->hbmMask = hbmMask;
     201#if 1
     202    if(rc && pIconInfo->hbmColor)
     203    {
     204        HDC  hdcSrc, hdcDst;
     205        hdcSrc = CreateCompatibleDC(0);
     206        hdcDst = CreateCompatibleDC(0);
     207
     208        GetObjectA(pIconInfo->hbmColor, sizeof(BITMAP), (LPVOID)&bmp);
     209
     210        hbmMask = CreateCompatibleBitmap (hdcDst, bmp.bmWidth, bmp.bmHeight);
     211        hbmOldDst = SelectObject (hdcDst, hbmMask);
     212        hbmOldSrc = SelectObject (hdcSrc, pIconInfo->hbmMask);
     213        BitBlt (hdcDst, 0, 0, bmp.bmWidth, bmp.bmHeight,
     214                hdcSrc, 0, 0, SRCCOPY);
     215
     216        SelectObject(hdcDst, hbmOldDst);
     217        SelectObject(hdcSrc, hbmOldSrc);
     218        DeleteDC(hdcDst);
     219        DeleteDC(hdcSrc);
     220        DeleteObject(pIconInfo->hbmMask);
     221        pIconInfo->hbmMask = hbmMask;
    221222    }
    222223#endif
     
    224225}
    225226/**********************************************************************
    226  *          CURSORICON_FindBestIcon
     227 *          CURSORICON_FindBestIcon
    227228 *
    228229 * Find the icon closest to the requested size and number of colors.
     
    231232                                                    int height, int colors )
    232233{
    233     int i; 
     234    int i;
    234235    CURSORICONDIRENTRY *entry, *bestEntry = NULL;
    235236    UINT iTotalDiff, iXDiff=0, iYDiff=0, iColorDiff;
     
    248249    for (i = 0, entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++)
    249250        {
    250         iTempXDiff = abs(width - entry->ResInfo.icon.bWidth);
    251         iTempYDiff = abs(height - entry->ResInfo.icon.bHeight);
     251        iTempXDiff = abs(width - entry->ResInfo.icon.bWidth);
     252        iTempYDiff = abs(height - entry->ResInfo.icon.bHeight);
    252253
    253254        if(iTotalDiff > (iTempXDiff + iTempYDiff))
     
    255256            iXDiff = iTempXDiff;
    256257            iYDiff = iTempYDiff;
    257             iTotalDiff = iXDiff + iYDiff;
     258            iTotalDiff = iXDiff + iYDiff;
    258259        }
    259260        }
     
    279280
    280281/**********************************************************************
    281  *          CURSORICON_FindBestCursor
     282 *          CURSORICON_FindBestCursor
    282283 *
    283284 * Find the cursor closest to the requested size.
     
    308309        if ((entry->ResInfo.cursor.wWidth <= width) && (entry->ResInfo.cursor.wHeight <= height) &&
    309310            (entry->ResInfo.cursor.wWidth > maxwidth) && (entry->ResInfo.cursor.wHeight > maxheight) &&
    310             (entry->wBitCount == 1))
     311            (entry->wBitCount == 1))
    311312        {
    312313            bestEntry = entry;
     
    321322    for(i = 0,entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++)
    322323        if ((entry->ResInfo.cursor.wWidth < maxwidth) && (entry->ResInfo.cursor.wHeight < maxheight) &&
    323             (entry->wBitCount == 1))
     324            (entry->wBitCount == 1))
    324325        {
    325326            bestEntry = entry;
     
    331332}
    332333/**********************************************************************
    333  *          LookupIconIdFromDirectoryEx16       (USER.364)
     334 *          LookupIconIdFromDirectoryEx16       (USER.364)
    334335 *
    335336 * FIXME: exact parameter sizes
    336337 */
    337338INT WIN32API LookupIconIdFromDirectoryEx(LPBYTE xdir, BOOL bIcon,
    338                                          INT width, INT height, UINT cFlag )
    339 {
    340     CURSORICONDIR       *dir = (CURSORICONDIR*)xdir;
     339                                         INT width, INT height, UINT cFlag )
     340{
     341    CURSORICONDIR       *dir = (CURSORICONDIR*)xdir;
    341342    UINT retVal = 0;
    342343
     
    344345    if( dir && !dir->idReserved && (dir->idType & 3) )
    345346    {
    346         CURSORICONDIRENTRY* entry;
    347         HDC hdc;
    348         UINT palEnts;
    349         int colors;
    350         hdc = GetDC(0);
    351         palEnts = GetSystemPaletteEntries(hdc, 0, 0, NULL);
    352         if (palEnts == 0)
    353             palEnts = 256;
    354         colors = (cFlag & LR_MONOCHROME) ? 2 : palEnts;
    355 
    356         ReleaseDC(0, hdc);
    357 
    358         if( bIcon )
    359             entry = CURSORICON_FindBestIcon( dir, width, height, colors );
    360         else
    361             entry = CURSORICON_FindBestCursor( dir, width, height, 1);
    362 
    363         if( entry ) retVal = entry->wResId;
     347        CURSORICONDIRENTRY* entry;
     348        HDC hdc;
     349        UINT palEnts;
     350        int colors;
     351        hdc = GetDC(0);
     352        palEnts = GetSystemPaletteEntries(hdc, 0, 0, NULL);
     353        if (palEnts == 0)
     354            palEnts = 256;
     355        colors = (cFlag & LR_MONOCHROME) ? 2 : palEnts;
     356
     357        ReleaseDC(0, hdc);
     358
     359        if( bIcon )
     360            entry = CURSORICON_FindBestIcon( dir, width, height, colors );
     361        else
     362            entry = CURSORICON_FindBestCursor( dir, width, height, 1);
     363
     364        if( entry ) retVal = entry->wResId;
    364365    }
    365366    else dprintf(("invalid resource directory\n"));
     
    367368}
    368369/**********************************************************************
    369  *          LookupIconIdFromDirectory           (USER32.379)
     370 *          LookupIconIdFromDirectory           (USER32.379)
    370371 */
    371372INT WIN32API LookupIconIdFromDirectory( LPBYTE dir, BOOL bIcon )
    372373{
    373     return LookupIconIdFromDirectoryEx( dir, bIcon, 
    374            bIcon ? GetSystemMetrics(SM_CXICON) : GetSystemMetrics(SM_CXCURSOR),
    375            bIcon ? GetSystemMetrics(SM_CYICON) : GetSystemMetrics(SM_CYCURSOR), bIcon ? 0 : LR_MONOCHROME );
     374    return LookupIconIdFromDirectoryEx( dir, bIcon,
     375           bIcon ? GetSystemMetrics(SM_CXICON) : GetSystemMetrics(SM_CXCURSOR),
     376           bIcon ? GetSystemMetrics(SM_CYICON) : GetSystemMetrics(SM_CYCURSOR), bIcon ? 0 : LR_MONOCHROME );
    376377}
    377378/*************************************************************************
    378  * CURSORICON_ExtCopy 
     379 * CURSORICON_ExtCopy
    379380 *
    380381 * Copies an Image from the Cache if LR_COPYFROMRESOURCE is specified
    381382 *
    382383 * PARAMS
    383  *      Handle     [I] handle to an Image 
     384 *      Handle     [I] handle to an Image
    384385 *      nType      [I] Type of Handle (IMAGE_CURSOR | IMAGE_ICON)
    385386 *      iDesiredCX [I] The Desired width of the Image
     
    395396 *     LR_COPYFROMRESOURCE will only work if the Image is in the Cache.
    396397 *
    397  *     
     398 *
    398399 * TODO: LR_COPYFROMRESOURCE doesn't work. Uses supplied icon instead
    399400 *
    400401 */
    401 HGLOBAL CopyCursorIcon(HGLOBAL Handle, UINT nType, 
    402                        INT iDesiredCX, INT iDesiredCY,
    403                        UINT nFlags)
     402HGLOBAL CopyCursorIcon(HGLOBAL Handle, UINT nType,
     403                       INT iDesiredCX, INT iDesiredCY,
     404                       UINT nFlags)
    404405{
    405406    HGLOBAL hNew=0;
     
    408409    if(Handle == 0)
    409410    {
    410         return 0;
     411        return 0;
    411412    }
    412413
     
    414415    if(!bIsIcon || (nFlags & LR_COPYFROMRESOURCE
    415416        && (iDesiredCX > 0 || iDesiredCY > 0))
    416         || nFlags & LR_MONOCHROME) 
     417        || nFlags & LR_MONOCHROME)
    417418    {
    418419            LPBYTE pBits;
     
    429430                || (iDesiredCX == 0 && iDesiredCY == 0))
    430431            {
    431                 iDesiredCY = GetSystemMetrics(bIsIcon ? 
     432                iDesiredCY = GetSystemMetrics(bIsIcon ?
    432433                    SM_CYICON : SM_CYCURSOR);
    433                 iDesiredCX = GetSystemMetrics(bIsIcon ? 
     434                iDesiredCX = GetSystemMetrics(bIsIcon ?
    434435                    SM_CXICON : SM_CXCURSOR);
    435436            }
    436      
     437
    437438            /* Create a New Icon with the proper dimension
    438439            */
    439             ICONINFO iconinfo;
    440 
    441             GetIconInfo(Handle, &iconinfo);
     440            ICONINFO iconinfo;
     441
     442            GetIconInfo(Handle, &iconinfo);
    442443            hNew = CreateIconIndirect(&iconinfo, bIsIcon, iDesiredCX, iDesiredCY, nFlags);
    443444    }
    444445    else
    445446    {
    446         if(bIsIcon) {
    447                 return CopyIcon(Handle);
    448         }
    449         else    return CopyCursor(Handle);
     447        if(bIsIcon) {
     448                return CopyIcon(Handle);
     449        }
     450        else    return CopyCursor(Handle);
    450451    }
    451452    return hNew;
Note: See TracChangeset for help on using the changeset viewer.