⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pjaimage.cpp

📁 MiniCA V2.0版本源码。《小型CA系统V2.1含源码》发表以来
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
PJAImage.cpp : implementation file for the PJAImage class
written by PJ Arends
pja@telus.net

For updates check http://www3.telus.net/pja/PJAImage.htm

-----------------------------------------------------------------------------
This code is provided as is, with no warranty as to it's suitability or usefulness
in any application in which it may be used. This code has not been tested for
UNICODE builds, nor has it been tested on a network ( with UNC paths ).

This code may be used in any way you desire. This file may be redistributed by any
means as long as it is not sold for profit, and providing that this notice and the
authors name are included.

If any bugs are found and fixed, a note to the author explaining the problem and
fix would be nice.
-----------------------------------------------------------------------------
****************************************************************************/

/////////////////////////////////////////////////////////////////////////////
// CPJAImage class

#include "stdafx.h"
#include "pjaimage.h"

#define BRUSHWIDTH  8
#define BRUSHHEIGHT 8

/////////////////////////////////////////////////////////////////////////////
//
//  CPJAImage constructor  (public member function)
//    Initializes member variables
//
//  Parameters :
//    None
//
//  Returns :
//    Nothing
//
/////////////////////////////////////////////////////////////////////////////

CPJAImage::CPJAImage()
{
    m_ImageFlags = 0;
    m_DrawFlags = 0;
    m_hImage = NULL;
    m_size.cx = 0;
    m_size.cy = 0;
    m_TransparentColour = CLR_DEFAULT;
}

/////////////////////////////////////////////////////////////////////////////
//
//  CPJAImage destructor  (public member function)
//    frees the memory held by the image handle
//
//  Parameters :
//    None
//
//  Returns :
//    Nothing
//
/////////////////////////////////////////////////////////////////////////////

CPJAImage::~CPJAImage()
{
    if (m_ImageFlags & PJAI_AUTODELETE)
    {
        if (m_ImageFlags & PJAI_ICON)
            DestroyIcon((HICON)m_hImage);
        else
            DeleteObject((HGDIOBJ)m_hImage);
    }
}

/////////////////////////////////////////////////////////////////////////////
//
//  CPJAImage::DitherBlt  (protected member function)
//    Draws the image on the FromDC as a disabled (grayed) image onto the pToDC
//
//  Parameters :
//    pToDC  [in] - pointer to the DC to draw the bitmap onto
//    x      [in] - the left side of the image on the destination DC
//    y      [in] - the top  of the image on the destination DC
//    w      [in] - the width of the image on the destination DC
//    h      [in] - the height of the image on the destination DC
//    FromDC [in] - The DC containing the bitmap to be grayed
//
//  Returns :
//    Nothing
//
//  Note : modified from code found at http://www.codeguru.com/bitmap/dither_blt.shtml
//         original author Jean-Edouard Lachand-Robert (iamwired@geocities.com)
//
/////////////////////////////////////////////////////////////////////////////

void CPJAImage::DitherBlt(CDC *pToDC, int x, int y, int w, int h, CDC *pFromDC)
{
    CDC MonoDC;
    if (MonoDC.CreateCompatibleDC(pToDC))
    {
        struct {
            BITMAPINFOHEADER bmiHeader; 
            RGBQUAD          bmiColors[2]; 
        } RGBBWBITMAPINFO = { { sizeof(BITMAPINFOHEADER),
            w,
            h,
            1,
            1,
            BI_RGB,
            0,
            0,
            0,
            0,
            0},
        { { 0x00, 0x00, 0x00, 0x00 },
        { 0xFF, 0xFF, 0xFF, 0x00 }}};
        VOID *pbitsBW;
        HBITMAP hbmBW = CreateDIBSection(MonoDC.m_hDC,
            (LPBITMAPINFO)&RGBBWBITMAPINFO,
            DIB_RGB_COLORS,
            &pbitsBW,
            NULL,
            0);
        ASSERT(hbmBW);

        if (hbmBW)
        {
            int SavedMonoDC = MonoDC.SaveDC();
            int SavedpToDC = pToDC->SaveDC();

            // Attach the monochrome DIB section to the MonoDC
            MonoDC.SelectObject(hbmBW);
            
            // BitBlt the bitmap into the monochrome DIB section
            MonoDC.BitBlt(0, 0, w, h, pFromDC, 0, 0, SRCCOPY);
            
            // BitBlt the black bits in the monochrome bitmap into COLOR_3DHILIGHT bits in the destination DC
            // The magic ROP comes from the Charles Petzold's book
            HBRUSH hb = CreateSolidBrush(GetSysColor(COLOR_3DHILIGHT));
            pToDC->SelectObject(hb);
            pToDC->BitBlt(x + 1, y + 1, w, h, &MonoDC, 0, 0, 0x00B8074A);
            
            // BitBlt the black bits in the monochrome bitmap into COLOR_3DSHADOW bits in the destination DC
            hb = CreateSolidBrush(GetSysColor(COLOR_3DSHADOW));
            DeleteObject(pToDC->SelectObject(hb));
            pToDC->BitBlt(x, y, w, h, &MonoDC, 0, 0, 0x00B8074A);
            
            pToDC->RestoreDC(SavedpToDC);
            MonoDC.RestoreDC(SavedMonoDC);
            DeleteObject(hb);
        }
        DeleteObject(hbmBW);
        MonoDC.DeleteDC();
    }
}

/////////////////////////////////////////////////////////////////////////////
//
//  CPJAImage::DrawImage  (public member function)
//    Draws the image (set with the SetImage() function) on the given device 
//    context
//
//  Parameters :
//    pDC       [in] - a pointer to the the device context to draw the image on
//    x         [in] - the left side of the image on the destination DC
//    y         [in] - the top  of the image on the destination DC
//    w         [in] - the width of the image on the destination DC
//    h         [in] - the height of the image on the destination DC
//    DrawFlags [in] - How to draw the image
//
//  Returns :
//    Nothing
//
//  Note :
//    See the PJAImage.h file for a description of the flags used
//
//    If the image is an icon or a transparent bitmap, the brush that is selected
//    into the pDC will be used as the background. The brush can be a pattern
//    or bitmap brush. This code assumes the brush is an 8x8 pixel brush
//    (Set with the BUTTONWIDTH an BUTTONHEIGHT macros).
//
//    The image will be drawn entirely within the rectangle specified by the
//    x, y, w, and h parameters.
//
/////////////////////////////////////////////////////////////////////////////

void CPJAImage::DrawImage(CDC *pDC, int x, int y, int w, int h, DWORD DrawFlags /* = 0 */)
{   // sanity check
    if (!m_hImage)
        return;

    // verify flags
#ifdef _DEBUG
    if (DrawFlags & PJAI_DISABLED)
        ASSERT (!(DrawFlags & PJAI_GRAYSCALE));
    if (DrawFlags & PJAI_CENTERED)
        ASSERT (!(DrawFlags & PJAI_STRETCHED));
#endif

    m_DrawFlags = DrawFlags;

    // Get the background brush for transparent images
    CBrush *BackGround = pDC->GetCurrentBrush();
    BackGround->UnrealizeObject();

    // handle for the grayscale bitmap
    HBITMAP GrayBmp = NULL;

    // set the clip region to the specified rectangle
    CRgn ClipRgn;
    ClipRgn.CreateRectRgn(x, y, x + w, y + h);
    pDC->SelectClipRgn(&ClipRgn);
    ClipRgn.DeleteObject();

    // create memory DC
    CDC memDC;
    memDC.CreateCompatibleDC(pDC);
    int savedmemDC = memDC.SaveDC();
    CBitmap memDCBmp;

    CDC* pOutputDC = &memDC;

    int left = x;
    int top = y;
    int width = m_size.cx;
    int height = m_size.cy;

    if (m_DrawFlags & PJAI_CENTERED)
    {   // center the image on the output rectangle
        left = x + (w / 2) - (m_size.cx / 2);
        top = y + (h / 2) - (m_size.cy / 2);
    }

    // Create a DC and bitmap for the stretched image
    CDC StretchDC;
    int savedStretchDC = 0;
    CBitmap stretchbmp;
    if (m_DrawFlags & PJAI_STRETCHED)
    {   // stretch image to fit output rectangle
        width = w;
        height = h;
    }

    // get the brush origins in case we are using a bitmap or pattern brush
    CPoint BrushOrg;
    CPoint Origin = pDC->GetBrushOrg();
    BrushOrg.x = (BRUSHWIDTH - (left - Origin.x) % BRUSHWIDTH);
    BrushOrg.y = (BRUSHHEIGHT - (top - Origin.y) % BRUSHHEIGHT);

    // Create a DC and bitmap for the transparent image
    CDC TransparentDC;
    int savedTransparentDC = 0;
    CBitmap Transparentbmp;

    if (m_ImageFlags & PJAI_ICON)
    {   // draw the icon onto the memory DC
        HICON TheIcon = (HICON)m_hImage;
        if (m_DrawFlags & PJAI_GRAYSCALE)
        {   // convert the colour icon to grayscale
            ICONINFO iconinfo;
            GetIconInfo(TheIcon, &iconinfo);
            if (iconinfo.hbmColor)
            {
                HBITMAP grayscale = GrayScale(pDC, iconinfo.hbmColor);

                ::DeleteObject(iconinfo.hbmColor);
                iconinfo.hbmColor = grayscale;
                TheIcon = ::CreateIconIndirect(&iconinfo);
                ::DeleteObject(iconinfo.hbmColor);
                ::DeleteObject(iconinfo.hbmMask);
            }
        }

        memDCBmp.CreateCompatibleBitmap(pDC, width, height);
        memDC.SelectObject(&memDCBmp);
        memDC.SetBrushOrg(BrushOrg);
        memDC.SelectObject(BackGround);
        memDC.FillRect(CRect(0, 0, width + 1, height + 1), BackGround);

        ::DrawIconEx(memDC.m_hDC, 0, 0, TheIcon, width, height, 0, NULL, DI_NORMAL);
        
        if (TheIcon != m_hImage)
            ::DestroyIcon(TheIcon);
    }
    else if (m_ImageFlags & PJAI_BITMAP)
    {   // place bitmap image into the memory DC
        memDC.SelectObject((HBITMAP)m_hImage);

        if (m_TransparentColour == CLR_DEFAULT)
            m_TransparentColour = memDC.GetPixel(0, 0);

        if (m_DrawFlags & PJAI_STRETCHED)
        {   // stretch the image
            StretchDC.CreateCompatibleDC(pDC);
            savedStretchDC = StretchDC.SaveDC();
            stretchbmp.CreateCompatibleBitmap(pDC, w, h);
            StretchDC.SelectObject(stretchbmp);
            StretchDC.SetStretchBltMode(COLORONCOLOR);
            StretchDC.StretchBlt(0, 0, width, height, &memDC, 0, 0, m_size.cx, m_size.cy, SRCCOPY);
            pOutputDC = &StretchDC;
        }

        if (m_DrawFlags & PJAI_TRANSPARENT)
        {   // draw the image transparently
            TransparentDC.CreateCompatibleDC(pDC);
            savedTransparentDC = TransparentDC.SaveDC();
            Transparentbmp.CreateCompatibleBitmap(pDC, width, height);
            TransparentDC.SelectObject(&Transparentbmp);
            TransparentDC.SetBrushOrg(BrushOrg);
            TransparentDC.SelectObject(BackGround);
            TransparentDC.FillRect(CRect(0, 0, width + 1, height + 1), BackGround);
            DrawTransparent(&TransparentDC, width, height, pOutputDC);
            pOutputDC = &TransparentDC;
        }
        else if (m_DrawFlags & PJAI_GRAYSCALE)
        {   // convert the image to grayscale
            GrayBmp = GrayScale(pDC, *pOutputDC->GetCurrentBitmap());
            pOutputDC->SelectObject(GrayBmp);
        }
    }
    else
    {
        ASSERT (FALSE);  // m_Flags improperly set (should never get here)
    }

    if (m_DrawFlags & PJAI_DISABLED)  // draw the image disabled
        DitherBlt(pDC, left, top, width, height, pOutputDC);
    else   // draw the image
        pDC->BitBlt(left, top, width, height, pOutputDC, 0, 0, SRCCOPY);

    // clean up after ourselves
    if (savedTransparentDC)
    {
        TransparentDC.RestoreDC(savedTransparentDC);
        TransparentDC.DeleteDC();
    }

    if (savedStretchDC)
    {
        StretchDC.RestoreDC(savedStretchDC);
        StretchDC.DeleteDC();
    }

    memDC.RestoreDC(savedmemDC);
    memDC.DeleteDC();

    if (GrayBmp)
        ::DeleteObject(GrayBmp);
}

/////////////////////////////////////////////////////////////////////////////
//
//  CPJAImage::DrawTransparent  (protected member function)
//    transparently draws the image in the source device context onto the 
//    destination device context 
//
//  Parameters :
//    pToDC         [in] - pointer to the destination device context
//    w             [in] - the width of the image
//    h             [in] - the height of the image
//    pFromDC       [in] - pointer to the source DC containing the bitmap to be drawn
//
//  Returns :
//    Nothing
//

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -