home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Windows Gam…ming Gurus (2nd Edition)
/
Disc2.iso
/
msdn_vcb
/
samples
/
vc98
/
atl
/
atltangram
/
atltangramcanvas
/
atltangramcanvasimpl.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1998-03-26
|
6KB
|
252 lines
// AtlTangramCanvasImpl.cpp : Implementation of CAtlTangramCanvas
//
// This is a part of the Active Template Library.
// Copyright (C) 1996-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Active Template Library Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Active Template Library product.
#include "stdafx.h"
#include "ATLTangramCanvas.h"
#include "AtlTangramCanvasImpl.h"
/////////////////////////////////////////////////////////////////////////////
// CAtlTangramCanvas
//
///////////////////////////////////////////////////////////
//
// Initialize
//
HRESULT CAtlTangramCanvas::Initialize(HWND hWnd, long cx, long cy)
{
// Hard coded to 8 bits per pixel.
int ibitcount = 8 ;
// Preconditions.
if ( hWnd == NULL || !::IsWindow(hWnd) || cx <= 0 || cy <= 0)
{
// Definsive code.
ASSERT(hWnd != NULL) ;
ASSERT(::IsWindow(hWnd)) ;
ASSERT(cx > 0);
ASSERT(cy > 0);
return E_INVALIDARG ;
}
// Cache a copy of the window handle.
m_hWnd = hWnd ;
// Destroy parts of objects if we are recreating it.
if ((m_hdc != NULL) || (m_hbmp != NULL))
{
// destroy() ;
}
// Save size for drawing later.
m_sizeDIB.cx = cx ;
m_sizeDIB.cy = cy ;
// Create a BITMAPINFOHEADER structure to describe the DIB
BITMAPINFOHEADER BIH ;
int iSize = sizeof(BITMAPINFOHEADER) ;
memset(&BIH, 0, iSize);
// Fill in the header info.
BIH.biSize = iSize;
BIH.biWidth = cx;
BIH.biHeight = cy;
BIH.biPlanes = 1;
BIH.biBitCount = ibitcount;
BIH.biCompression = BI_RGB;
// Create a new DC.
m_hdc = ::CreateCompatibleDC(NULL) ;
// Create the DIB section.
m_hbmp = CreateDIBSection( m_hdc,
(BITMAPINFO*)&BIH,
DIB_PAL_COLORS,
&m_pBits,
NULL,
0);
ASSERT(m_hbmp);
ASSERT(m_pBits);
// Select the new bitmap into the buffer DC
if (m_hbmp)
{
m_hbmOld = (HBITMAP)::SelectObject( m_hdc,
m_hbmp);
}
return S_OK ;
}
///////////////////////////////////////////////////////////
//
// Transfer the dib section to a DC.
// Called in response to paint and draw messages.
//
HRESULT CAtlTangramCanvas::Paint(HDC hdcDest, RECT rectUpdate)
{
// Preconditions
if ( hdcDest == NULL)
{
ASSERT(hdcDest != NULL) ;
return E_INVALIDARG ;
}
// Select in a palette if we have one.
HPALETTE hPalOld = NULL;
if (m_hPal)
{
hPalOld = ::SelectPalette(hdcDest, (HPALETTE)m_hPal, 0);
::RealizePalette(hdcDest);
}
// If the rectangle is empty or null, repaint the entire area.
RECT rect, rectNull ;
::SetRectEmpty(&rectNull) ;
::CopyRect(&rect, &rectUpdate) ;
if (::EqualRect(&rect, &rectNull) || ::IsRectEmpty(&rect))
{
// Note: you do not need to select the palette into
// the memory DC because the DIB section is using palette
// index values not colors
::BitBlt(hdcDest, 0, 0,
m_sizeDIB.cx, m_sizeDIB.cy,
m_hdc,
0,0,
SRCCOPY);
}
else
{
// Just repaint the updated area.
::BitBlt(hdcDest,
rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top,
m_hdc,
rect.left, rect.top,
SRCCOPY);
}
// We are done with the palette
if (hPalOld)
{
::SelectPalette(hdcDest, hPalOld, 0);
}
return S_OK ;
}
///////////////////////////////////////////////////////////
//
// Update
//
HRESULT CAtlTangramCanvas::Update(RECT rectUpdate)
{
HDC hdcDest = ::GetDC(m_hWnd) ;
Paint(hdcDest, rectUpdate) ;
::ReleaseDC(m_hWnd, hdcDest);
return S_OK ;
}
///////////////////////////////////////////////////////////
//
// GetHDC
//
HRESULT CAtlTangramCanvas::GetHDC(HDC* phdc)
{
// Pre conditions.
if (!IsValidAddress(phdc, sizeof(HDC), TRUE))
{
ASSERT(0) ;
return E_FAIL ;
}
// Return device context.
*phdc = m_hdc ;
return S_OK ;
}
///////////////////////////////////////////////////////////
//
// Set the color table in the DIB section.
//
HRESULT __stdcall CAtlTangramCanvas::SetPalette(HPALETTE hPal)
{
if (hPal == NULL)
{
ASSERT(hPal != NULL);
return E_INVALIDARG ;
}
// Keep a copy of the palette around for painting.
m_hPal = hPal ;
// get the colors from the palette
int iColors = 0;
::GetObject(hPal, sizeof(iColors), &iColors) ;
ASSERT(iColors > 0);
PALETTEENTRY* pPE = new PALETTEENTRY[iColors];
::GetPaletteEntries(hPal, 0, iColors, pPE);
// Build a table of RGBQUADS
RGBQUAD* pRGB = new RGBQUAD[iColors];
ASSERT(pRGB);
for (int i = 0; i < iColors; i++) {
pRGB[i].rgbRed = pPE[i].peRed;
pRGB[i].rgbGreen = pPE[i].peGreen;
pRGB[i].rgbBlue = pPE[i].peBlue;
pRGB[i].rgbReserved = 0;
}
::SetDIBColorTable(m_hdc,
0, iColors,
pRGB);
delete [] pRGB;
delete [] pPE;
return S_OK ;
}
///////////////////////////////////////////////////////////
//
// Called when the main window gets a QueryNewPalette or a
// PaletteChanged message.
//
HRESULT __stdcall CAtlTangramCanvas::OnQueryNewPalette(HWND hWndReceived)
{
if (hWndReceived == NULL)
{
return E_FAIL ;
}
if (m_hPal)
{
HDC hdc = ::GetDC(hWndReceived) ;
::SelectPalette(hdc, m_hPal, FALSE) ;
UINT u = ::RealizePalette(hdc) ;
::ReleaseDC(hWndReceived, hdc) ;
if (u != 0)
{
::InvalidateRect(hWndReceived, NULL, TRUE) ;
}
}
return S_OK ;
}