2010年2月2日 星期二

CuImageWnd

// CuImageWnd.h



class CuImageWnd : public IuImageWnd
{

    // Image 的控制代碼
    HBITMAP m_hBitmap;

    // GetDC 時 暫存用的控制代碼
    HBITMAP m_hOldBitmap;

    // GetDC 時 暫存的DC控制代碼
    HDC m_hDC;

    // DC使用參考計數
    UINT m_nDCRefCount;

    CuImageEx m_ImageEx;
public:

    CuImageWnd();
    virtual ~CuImageWnd();

    //////////////////////////////////////////////////////////////////
    // IuUnknown 公開虛擬界面 
    virtual ULONG Release();

    //////////////////////////////////////////////////////////////////
    // IuImage 公開虛擬界面 
    virtual BOOL Create( int nWidth, int nHeight, int nBPP);

    virtual UINT    Height(){ return m_ImageEx.Height(); }
    virtual void    Height(UINT nHeight){ m_ImageEx.Height(nHeight); }

    virtual UINT    Width(){ return m_ImageEx.Width(); }
    virtual void    Width(UINT nWidth){ m_ImageEx.Width(nWidth); }

    virtual UINT    BitCount(){ return m_ImageEx.BitCount(); }
    virtual void    BitCount(UINT nBitCount){ m_ImageEx.BitCount(nBitCount); }

    virtual COLORREF GetPixel( int x, int y){ return m_ImageEx.GetPixel(x,y); }
    virtual BYTE*   Data(void){ return m_ImageEx.Data(); }

    //////////////////////////////////////////////////////////////////
    // IuImageWnd 公開虛擬界面 

        // window 支援函式


    virtual HDC GetDC();
    virtual void ReleaseDC();

    virtual BOOL BitBlt( HDC hDestDC, int xDest, int yDest, int nDestWidth, 
        int nDestHeight, int xSrc, int ySrc, DWORD dwROP = SRCCOPY );

    virtual BOOL StretchBlt( HDC hDestDC, int xDest, int yDest, 
        int nDestWidth, int nDestHeight, int xSrc, int ySrc, int nSrcWidth, 
        int nSrcHeight, DWORD dwROP = SRCCOPY );

    virtual operator HBITMAP() const;

    ///////////////////////////////////////////////////////////////////


    //////////////////////////////////////////////////////////////////
    // 未公開虛擬界面 的 public 函式
    void Destroy();

};



// CuImageWnd.cpp


CuImageWnd::CuImageWnd()
:m_hBitmap(NULL)
,m_hOldBitmap(NULL)
,m_hDC(NULL)
,m_nDCRefCount(0)
{
}


CuImageWnd::~CuImageWnd()
{

    Destroy();
}

ULONG CuImageWnd::Release()
{
    delete this;
    return 0;
}

BOOL CuImageWnd::Create( int nWidth, int nHeight, int nBPP)
{

    Destroy();

    BITMAPINFO  dibInfo;
    dibInfo.bmiHeader.biBitCount = nBPP;
    dibInfo.bmiHeader.biClrImportant = 0;
    dibInfo.bmiHeader.biClrUsed = 0;
    dibInfo.bmiHeader.biCompression = BI_RGB;
    dibInfo.bmiHeader.biHeight = nHeight;
    dibInfo.bmiHeader.biPlanes = 1;
    dibInfo.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
    dibInfo.bmiHeader.biSizeImage = nWidth * nHeight * (nBPP >> 3 );
    dibInfo.bmiHeader.biWidth = nWidth;
    dibInfo.bmiHeader.biXPelsPerMeter = 0;
    dibInfo.bmiHeader.biYPelsPerMeter = 0;
    dibInfo.bmiColors[0].rgbBlue = 0;
    dibInfo.bmiColors[0].rgbGreen = 0;
    dibInfo.bmiColors[0].rgbRed = 0;
    dibInfo.bmiColors[0].rgbReserved = 0;

    Height(nHeight);
    Width(nWidth);
    BitCount(nBPP);

    void* ppvBits ;//= Data();

    m_hBitmap = ::CreateDIBSection(NULL, &dibInfo, DIB_RGB_COLORS,
        (void**)&ppvBits, NULL, 0);

    m_ImageEx.Data((BYTE*)ppvBits);
    
    return (BOOL)m_hBitmap;

}

void CuImageWnd::Destroy()
{
    if( m_hBitmap )
    {
        ::DeleteObject(m_hBitmap);
        m_hBitmap = NULL;
    }

    m_ImageEx.Data(0);

    Height(0);
    Width(0);
    BitCount(0);

}

HDC CuImageWnd::GetDC() 
{

    Assert(m_hBitmap != NULL, L" CuImage::GetDC() m_hBitmap != NULL");
    
    m_nDCRefCount++;
    if( m_hDC == NULL )
    {
        m_hDC = ::CreateCompatibleDC(NULL);
        m_hOldBitmap = HBITMAP(::SelectObject( m_hDC, m_hBitmap ));
    }

    return m_hDC;
}

void CuImageWnd::ReleaseDC() 
{
    HBITMAP hBitmap;

    Assert( m_hDC != NULL, L"");

    m_nDCRefCount--;
    if( m_nDCRefCount == 0 )
    {
        hBitmap = HBITMAP( ::SelectObject( m_hDC, m_hOldBitmap ) );
        Assert( hBitmap == m_hBitmap ,L"");
        ::DeleteDC( m_hDC );
        m_hDC = NULL;
    }
}


BOOL CuImageWnd::StretchBlt( HDC hDestDC, int xDest, int yDest, 
    int nDestWidth, int nDestHeight, int xSrc, int ySrc, int nSrcWidth, 
    int nSrcHeight, DWORD dwROP ) 
{

    BOOL bResult;

    Assert( m_hBitmap != NULL, L"" );
    Assert( hDestDC != NULL, L"" );

    HDC hDC = this->GetDC();

    bResult = ::StretchBlt( hDestDC, xDest, yDest, nDestWidth, nDestHeight, hDC,
        xSrc, ySrc, nSrcWidth, nSrcHeight, dwROP );

    this->ReleaseDC();

    return( bResult );

}


BOOL CuImageWnd::BitBlt( HDC hDestDC, int xDest, int yDest, int nDestWidth, 
    int nDestHeight, int xSrc, int ySrc, DWORD dwROP )
{
    BOOL bResult;
 
    Assert( m_hBitmap != NULL, L"");
    Assert( hDestDC != NULL, L"");

    GetDC();

    bResult = ::BitBlt( hDestDC, xDest, yDest, nDestWidth, nDestHeight, m_hDC, 
        xSrc, ySrc, dwROP );

    ReleaseDC();

    return( bResult );
}

CuImageWnd::operator HBITMAP() const
    { return m_hBitmap; }

支援Windows 專用的部份函式型別轉換: HDC HBITMAP 當然還有最重要的 點陣資料集

沒有留言:

張貼留言