218 lines
5.0 KiB
C++
Executable File
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;
|
|
}
|
|
}
|