BITMAPS.CXX
//+--------------------------------------------------------------------------- 
// 
//  Microsoft Windows 
//  Copyright 1992 - 1998 Microsoft Corporation. 
// 
//  File:       bitmaps.cxx 
// 
//  Contents:   bitmap helper functions 
// 
//  Classes: 
// 
//  Functions:  DDBChangeColor 
//              LoadAndStretch 
// 
//  History:    6-24-94   stevebl   Created 
// 
//---------------------------------------------------------------------------- 
 
#include <windows.h> 
#include "bitmaps.h" 
 
//+--------------------------------------------------------------------------- 
// 
//  Function:   LoadAndStretch 
// 
//  Synopsis:   Loads a bitmap from our resources, and creates a bitmap 
//              "array."  The red portions of the bitmap are considered 
//              clear.  Each resource consists of two bitmaps side by 
//              side:  an "open folder" and a "closed folder".  These 
//              bitmaps are turned into 4 bitmaps:  two selected, and 
//              two unselected bitmaps. 
// 
//  Arguments:  [hinst]        - instance containing the bitmap 
//              [hbmpDest]     - destination bitmap array 
//              [lpszResource] - name of the bitmap resource 
//              [cxBitmap]     - width to stretch to 
//              [cyBitmap]     - height to stretch to 
//              [crHigh]       - color of the highlighted background 
//              [crNorm]       - color of the normal background 
// 
//  Returns:    TRUE on success. 
//              FALSE on failure. 
// 
//  History:    6-24-94   stevebl   Stolen and modified from original DFView 
// 
//---------------------------------------------------------------------------- 
 
BOOL LoadAndStretch ( 
    HINSTANCE hinst, 
    HBITMAP hbmpDest, 
    LPTSTR lpszResource, 
    UINT cxBitmap, 
    UINT cyBitmap, 
    COLORREF crHigh, 
    COLORREF crNorm) 
{ 
    HBITMAP hbmpOld1, hbmpOld2, hbmp; 
    BITMAP bm; 
    int i; 
    HDC hdcDest = CreateCompatibleDC(NULL); 
    HDC hdcSrc = CreateCompatibleDC(NULL); 
 
    if (NULL == hdcDest || NULL == hdcSrc) 
    { 
        DeleteDC(hdcSrc); 
        DeleteDC(hdcDest); 
        return(FALSE); 
    } 
    for (i=0;  i < 2;  i++) 
    { 
        hbmp = LoadBitmap(hinst, lpszResource); 
        if (NULL == hbmp) 
        { 
            DeleteDC(hdcSrc); 
            DeleteDC(hdcDest); 
            return FALSE; 
        } 
 
        DDBChangeColor(hbmp, RGB (255,0,0), ((i == 0) ? crHigh : crNorm)); 
        GetObject(hbmp, sizeof (bm), &bm); 
 
        hbmpOld1 = (HBITMAP) SelectObject(hdcDest, hbmpDest); 
        hbmpOld2 = (HBITMAP) SelectObject(hdcSrc, hbmp); 
 
        SetStretchBltMode(hdcDest, COLORONCOLOR); 
        StretchBlt( 
            hdcDest, 
            i * cxBitmap * 2, 
            0, 
            cxBitmap * 2, 
            cyBitmap, 
            hdcSrc, 
            0, 
            0, 
            bm.bmWidth, 
            bm.bmHeight, 
            SRCCOPY); 
 
        SelectObject(hdcDest, hbmpOld1); 
        SelectObject(hdcSrc,  hbmpOld2); 
        DeleteObject(hbmp); 
    } 
 
    DeleteDC(hdcSrc); 
    DeleteDC(hdcDest); 
    return TRUE; 
} 
 
 
 
//+--------------------------------------------------------------------------- 
// 
//  Function:   DDBChangeColor 
// 
//  Synopsis:   Change a particular color in a bitmap to another color. 
//              Strategy is to create a monochrome mask, where each pixel 
//              in the source bitmap that matches the color we're converting 
//              from is set to white (1), and all other colors to black. 
//              We then Blt this mask into the original bitmap, with a ROP 
//              code that does: 
// 
//                (~Mask&Source) | (~Mask&Pattern) 
// 
//              where Pattern is the color we're changing to. 
// 
//              In other words, wherever the Mask is 1, we want to put the pattern; 
//              wherever the Mask is 0, we want to leave the source alone.  By 
//              using a Truth Table, you'll find that this ROP code is equivalent 
//              to DSPDxax or ROP code 0x00E20746. 
// 
//              For info on figuring out ROP codes given a set of boolean ops, 
//              check out the Windows 3.0 SDK, Reference Volume 2, chapter 11. 
// 
//  Arguments:  [hBitmap] - bitmap handle 
//              [crFrom]  - color to change 
//              [crTo]    - new color 
// 
//  Returns:    TRUE on success.  FALSE on failur 
// 
//  History:    6-24-94   stevebl   Stolen from original DFView code 
// 
//---------------------------------------------------------------------------- 
 
BOOL DDBChangeColor (HBITMAP hBitmap, COLORREF crFrom, COLORREF crTo) 
{ 
    register int cx, cy; 
    BITMAP       bm; 
    HDC          hdcBmp, hdcMask; 
    HBITMAP      hbmMask, hbmOld1, hbmOld2; 
    HBRUSH       hBrush, hbrOld; 
 
    if (!hBitmap) 
          return FALSE; 
 
    GetObject (hBitmap, sizeof (bm), &bm); 
    cx = bm.bmWidth; 
    cy = bm.bmHeight; 
 
    hbmMask = CreateBitmap(cx, cy, 1, 1, NULL); 
    hdcMask = CreateCompatibleDC(NULL); 
    hdcBmp = CreateCompatibleDC(NULL); 
    hBrush = CreateSolidBrush(crTo); 
 
    if (!hdcMask || !hdcBmp || !hBrush || !hbmMask) 
    { 
        DeleteObject(hbmMask); 
        DeleteObject(hBrush); 
        DeleteDC(hdcMask); 
        DeleteDC(hdcBmp); 
        return FALSE; 
    } 
 
    hbmOld1 = (HBITMAP) SelectObject (hdcBmp,  hBitmap); 
    hbmOld2 = (HBITMAP) SelectObject (hdcMask, hbmMask); 
    hbrOld  = (HBRUSH) SelectObject (hdcBmp, hBrush); 
 
    SetBkColor(hdcBmp, crFrom); 
    BitBlt(hdcMask, 0, 0, cx, cy, hdcBmp,  0, 0, SRCCOPY); 
    SetBkColor(hdcBmp, RGB(255,255,255)); 
    BitBlt(hdcBmp,  0, 0, cx, cy, hdcMask, 0, 0, DSPDxax); 
 
    SelectObject(hdcBmp,  hbrOld); 
    SelectObject(hdcBmp,  hbmOld1); 
    SelectObject(hdcMask, hbmOld2); 
    DeleteDC(hdcBmp); 
    DeleteDC(hdcMask); 
    DeleteObject(hBrush); 
    DeleteObject(hbmMask); 
 
    return TRUE; 
}