windows-nt/Source/XPSP1/NT/enduser/stuff/hhctrl/dibcls.cpp
2020-09-26 16:20:57 +08:00

196 lines
3.8 KiB
C++

#include "header.h"
#include "DibCls.H"
#define _HRESULT_TYPEDEF_(_sc) ((HRESULT)_sc)
#include <urlmon.h>
#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)
//=--------------------------------------------------------------------------=
// DIB Utitilty Classes
//=--------------------------------------------------------------------------=
// Not wholey generic but getting there...
//
// Notes:
//
CDibFile::CDibFile()
{
m_headerSize = 0;
m_bmi.p = 0;
}
CDibFile::~CDibFile()
{
if( m_bmi.p )
delete m_bmi.p;
}
DWORD CDibFile::CalcImageSize()
{
DWORD & dw = m_bmi.p->bmiHeader.biSizeImage;
if( dw == 0)
dw = WIDTHBYTES((DWORD)m_bmi.p->bmiHeader.biWidth *
m_bmi.p->bmiHeader.biBitCount) * m_bmi.p->bmiHeader.biHeight;
return(dw);
}
HRESULT CDibFile::GetInfoHeader( IStream * strm )
{
HRESULT hr = S_OK;
m_bmi.bytes = new unsigned char[ m_headerSize ];
if( !m_bmi.bytes )
hr = E_OUTOFMEMORY;
if( SUCCEEDED(hr) )
hr = strm->Read(m_bmi.bytes,m_headerSize,0);
if( SUCCEEDED(hr) )
CalcImageSize();
return(hr);
}
HRESULT CDibFile::GetFileHeader(IStream * strm)
{
BITMAPFILEHEADER bmfh;
HRESULT hr = strm->Read(&bmfh,sizeof(bmfh),0);
if( SUCCEEDED(hr) && (bmfh.bfType != 0x4d42 ))
hr = E_UNEXPECTED;
if( SUCCEEDED(hr) )
m_headerSize = bmfh.bfOffBits - sizeof(bmfh);
return(hr);
}
CDibSection::CDibSection()
{
m_bitsBase = 0;
m_current = 0;
m_memDC = 0;
m_handle =
m_oldBitmap = 0;
m_w =
m_h = 32; // totally arbitrary
}
CDibSection::~CDibSection()
{
if( m_memDC )
{
if( m_oldBitmap )
::SelectObject( m_memDC, m_oldBitmap );
::DeleteDC(m_memDC);
}
if( m_handle )
::DeleteObject(m_handle);
}
HRESULT CDibSection::Create(CDibFile& dibFile)
{
HRESULT hr = S_OK;
BITMAPINFOHEADER * bmih = dibFile; // will convert itself
m_handle = ::CreateDIBSection(
m_memDC, // handle to device context
dibFile, // pointer to structure containing bitmap size,
// format, and color data
DIB_RGB_COLORS, // color data type indicator: RGB values or
// palette indices
(void **)&m_bitsBase, // pointer to variable to receive a pointer
// to the bitmap's bit values
0, // optional handle to a file mapping object
0 // offset to the bitmap bit values
// within the file mapping object
);
if( !m_handle )
hr = E_FAIL;
if( SUCCEEDED(hr) )
{
m_oldBitmap = ::SelectObject( m_memDC, m_handle );
if( !m_oldBitmap )
hr = E_FAIL;
}
if( SUCCEEDED(hr) )
{
m_current = m_bitsBase;
m_w = bmih->biWidth;
m_h = bmih->biHeight;
if( m_h < 0 )
m_h *= -1;
}
return(hr);
}
HRESULT CDibSection::ReadFrom( IStream * strm, DWORD amount )
{
DWORD dwRead = 0;
DWORD dwReadTotal = 0;
HRESULT hr;
do
{
hr = strm->Read(m_current,amount,&dwRead);
if( SUCCEEDED(hr) || hr == E_PENDING )
{
m_current += dwRead;
dwReadTotal += dwRead;
}
}
while ( (hr == S_OK) && (dwReadTotal <= amount) );
return (hr);
}
HRESULT CDibSection::Setup(HDC hdc)
{
m_memDC = ::CreateCompatibleDC(hdc);
return( m_memDC ? NOERROR : E_FAIL );
}
HRESULT CDibSection::PaintTo(HDC hdc, int x, int y)
{
BOOL b = BitBlt(
hdc, // handle to destination device context
x, // x-coordinate of destination rectangle's upper-left corner
y, // x-coordinate of destination rectangle's upper-left corner
m_w, // width of destination rectangle
m_h, // height of destination rectangle
m_memDC, // handle to source device context
0, // x-coordinate of source rectangle's upper-left corner
0, // y-coordinate of source rectangle's upper-left corner
SRCCOPY // raster operation code
);
return( b ? NOERROR : E_FAIL );
}
HRESULT CDibSection::GetSize(SIZEL &sz)
{
sz.cx = m_w;
sz.cy = m_h;
return(S_OK);
}