gps/GPSProject/ImageViewer/STScreenBuffer.cpp

218 lines
5.0 KiB
C++
Executable File

#include "stdafx.h"
#include "STScreenBuffer.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
int CSTScreenBuffer::CorrectedWidth(int nWidth)
{
return ( ( nWidth + 3 ) / 4 ) * 4;
}
/////////////////////////////////////////////////////////////////////////////
// CSTScreenBuffer
CSTScreenBuffer::CSTScreenBuffer()
: m_hBitmap(NULL),
m_pBuffer(NULL),
m_pDC(NULL)
{
}
CSTScreenBuffer::~CSTScreenBuffer()
{
if (m_hBitmap!=NULL) {
ReleaseDC();
::DeleteObject(m_hBitmap);
}
}
BOOL CSTScreenBuffer::CreateBitmap(int nWidth, int nHeight)
{
ASSERT(nWidth>0);
ASSERT(nHeight>0);
if (m_hBitmap!=NULL) DeleteObject(m_hBitmap);
m_nCorrectedWidth = CorrectedWidth(nWidth);
m_nWidth = nWidth;
m_nHeight = nHeight;
DIBINFO dibInfo;
dibInfo.bmiHeader.biBitCount = 24;
dibInfo.bmiHeader.biClrImportant = 0;
dibInfo.bmiHeader.biClrUsed = 0;
dibInfo.bmiHeader.biCompression = 0;
dibInfo.bmiHeader.biHeight = m_nHeight;
dibInfo.bmiHeader.biPlanes = 1;
dibInfo.bmiHeader.biSize = 40;
dibInfo.bmiHeader.biSizeImage = m_nCorrectedWidth*m_nHeight*3;
dibInfo.bmiHeader.biWidth = m_nCorrectedWidth;
dibInfo.bmiHeader.biXPelsPerMeter = 3780;
dibInfo.bmiHeader.biYPelsPerMeter = 3780;
dibInfo.bmiColors[0].rgbBlue = 0;
dibInfo.bmiColors[0].rgbGreen = 0;
dibInfo.bmiColors[0].rgbRed = 0;
dibInfo.bmiColors[0].rgbReserved = 0;
HDC hDC = ::GetDC(NULL);
ASSERT(hDC);
m_hBitmap = CreateDIBSection(hDC, (const BITMAPINFO*)dibInfo, DIB_RGB_COLORS, (void**)&m_pBuffer, NULL, 0);
::ReleaseDC(NULL, hDC);
ASSERT(m_hBitmap);
ASSERT(m_pBuffer);
return TRUE;
}
void CSTScreenBuffer::Create(int nWidth, int nHeight)
{
ASSERT(nWidth>0);
ASSERT(nHeight>0);
CreateBitmap(nWidth, nHeight);
}
void CSTScreenBuffer::Create(int nWidth, int nHeight, COLORREF clr)
{
ASSERT(nWidth>0);
ASSERT(nHeight>0);
CreateBitmap(nWidth, nHeight);
BGRColor bgrColor = BGRColor(GetBValue(clr), GetGValue(clr), GetRValue(clr));
int nPosition = 0;
for (int y=0; y<nHeight; y++) {
nPosition = m_nCorrectedWidth*y;
for (int x=0; x<nWidth; x++) {
m_pBuffer[nPosition] = bgrColor;
nPosition++;
}
}
}
void CSTScreenBuffer::Create(HBITMAP hBitmap)
{
BITMAP bm;
GetObject(hBitmap, sizeof(BITMAP), &bm);
CreateBitmap(bm.bmWidth, bm.bmHeight);
CDC memDc;
CDC targetDc;
memDc.CreateCompatibleDC(NULL);
targetDc.CreateCompatibleDC(NULL);
HBITMAP hOldBitmap1 = (HBITMAP)::SelectObject(memDc.GetSafeHdc(), hBitmap);
HBITMAP hOldBitmap2 = (HBITMAP)::SelectObject(targetDc.GetSafeHdc(), m_hBitmap);
targetDc.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &memDc, 0, 0, SRCCOPY);
::SelectObject(memDc.GetSafeHdc(), hOldBitmap1);
::SelectObject(targetDc.GetSafeHdc(), hOldBitmap2);
memDc.DeleteDC();
targetDc.DeleteDC();
}
void CSTScreenBuffer::Create(CDC *pDC, CRect rect)
{
ASSERT(pDC);
CreateBitmap(rect.Width(), rect.Height());
GetDC()->BitBlt(0,0, rect.Width(), rect.Height(), pDC, rect.left, rect.top, SRCCOPY);
}
void CSTScreenBuffer::CreateRGB(void *pData, int nWidth, int nHeight)
{
ASSERT(pData);
ASSERT(nWidth>0);
ASSERT(nHeight>0);
CreateBitmap(nWidth, nHeight);
byte *pByteData = (byte*)pData;
int nPosition = 0;
int nDataPosition = 0;
for (int y=0; y<nHeight; y++) {
nPosition = m_nCorrectedWidth*(m_nHeight-y-1);
nDataPosition = nWidth*3*y;
for (int x=0; x<nWidth; x++) {
m_pBuffer[nPosition].m_R = pByteData[nDataPosition++];
m_pBuffer[nPosition].m_G = pByteData[nDataPosition++];
m_pBuffer[nPosition].m_B = pByteData[nDataPosition++];
nPosition++;
}
}
}
BOOL CSTScreenBuffer::Draw(CDC* pDC, CPoint ptDest)
{
ASSERT(m_hBitmap);
ReleaseDC();
CPoint ptOrigin = CPoint(0,0);
BOOL bResult = FALSE;
CDC memDc;
if (!memDc.CreateCompatibleDC(pDC)) {
return FALSE;
}
HBITMAP m_hOldBitmap = (HBITMAP)::SelectObject(memDc.GetSafeHdc(), m_hBitmap);
bResult = pDC->BitBlt(ptDest.x, ptDest.y, m_nWidth, m_nHeight, &memDc, ptOrigin.x, ptOrigin.y, SRCCOPY);
::SelectObject(memDc.GetSafeHdc(), m_hOldBitmap);
memDc.DeleteDC();
return bResult;
}
HBITMAP CSTScreenBuffer::CreateBitmapByRGBArray(void *pData, int nWidth, int nHeight)
{
HBITMAP hResult = NULL;
CSTScreenBuffer sb;
sb.CreateRGB(pData, nWidth, nHeight);
hResult = sb.m_hBitmap;
sb.m_hBitmap = NULL;
sb.m_pBuffer = NULL;
return hResult;
}
CDC *CSTScreenBuffer::GetDC()
{
if (m_pDC) return m_pDC;
m_pDC = new CDC;
if (!m_pDC->CreateCompatibleDC(NULL)) {
delete m_pDC;
return NULL;
}
m_hSaveBitmap = (HBITMAP)m_pDC->SelectObject(GetHBitmap());
return m_pDC;
}
void CSTScreenBuffer::ReleaseDC()
{
if (m_pDC) {
m_pDC->SelectObject(m_hSaveBitmap);
m_pDC->DeleteDC();
delete m_pDC;
m_pDC = NULL;
}
}