FIREWND.CPP
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:15k
源码类别:
Windows编程
开发平台:
Visual C++
- // firewnd.cpp : implementation file
- //
- // This is a part of the Microsoft Foundation Classes C++ library.
- // Copyright (C) 1992-1998 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Microsoft Foundation Classes Reference and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Microsoft Foundation Classes product.
- #include "stdafx.h"
- #include "fire.h"
- #include "firewnd.h"
- #include <math.h> // for HSI conversion
- #ifdef _DEBUG
- #undef THIS_FILE
- static char BASED_CODE THIS_FILE[] = __FILE__;
- #endif
- static RGBQUAD rgbStd256[] =
- {
- { 0, 0, 0, 0 }, { 0, 0,128, 0 }, { 0,128, 0, 0 }, { 0,128,128, 0 },
- { 128, 0, 0, 0 }, { 128, 0,128, 0 }, { 128,128, 0, 0 }, { 192,192,192, 0 },
- { 192,220,192, 0 }, { 240,202,166, 0 }, { 238,238,238, 0 }, { 221,221,221, 0 },
- { 204,204,204, 0 }, { 187,187,187, 0 }, { 170,170,170, 0 }, { 153,153,153, 0 },
- { 136,136,136, 0 }, { 119,119,119, 0 }, { 102,102,102, 0 }, { 85, 85, 85, 0 },
- { 68, 68, 68, 0 }, { 51, 51, 51, 0 }, { 34, 34, 34, 0 }, { 17, 17, 17, 0 },
- { 204,255,255, 0 }, { 153,255,255, 0 }, { 102,255,255, 0 }, { 51,255,255, 0 },
- { 255,204,255, 0 }, { 204,204,255, 0 }, { 153,204,255, 0 }, { 102,204,255, 0 },
- { 51,204,255, 0 }, { 0,204,255, 0 }, { 255,153,255, 0 }, { 204,153,255, 0 },
- { 153,153,255, 0 }, { 102,153,255, 0 }, { 51,153,255, 0 }, { 0,153,255, 0 },
- { 255,102,255, 0 }, { 204,102,255, 0 }, { 153,102,255, 0 }, { 102,102,255, 0 },
- { 51,102,255, 0 }, { 0,102,255, 0 }, { 255, 51,255, 0 }, { 204, 51,255, 0 },
- { 153, 51,255, 0 }, { 102, 51,255, 0 }, { 51, 51,255, 0 }, { 0, 51,255, 0 },
- { 204, 0,255, 0 }, { 153, 0,255, 0 }, { 102, 0,255, 0 }, { 51, 0,255, 0 },
- { 255,255,204, 0 }, { 204,255,204, 0 }, { 153,255,204, 0 }, { 102,255,204, 0 },
- { 51,255,204, 0 }, { 0,255,204, 0 }, { 255,204,204, 0 }, { 153,204,204, 0 },
- { 102,204,204, 0 }, { 51,204,204, 0 }, { 0,204,204, 0 }, { 255,153,204, 0 },
- { 204,153,204, 0 }, { 153,153,204, 0 }, { 102,153,204, 0 }, { 51,153,204, 0 },
- { 0,153,204, 0 }, { 255,102,204, 0 }, { 204,102,204, 0 }, { 153,102,204, 0 },
- { 102,102,204, 0 }, { 51,102,204, 0 }, { 0,102,204, 0 }, { 255, 51,204, 0 },
- { 204, 51,204, 0 }, { 153, 51,204, 0 }, { 102, 51,204, 0 }, { 51, 51,204, 0 },
- { 0, 51,204, 0 }, { 255, 0,204, 0 }, { 204, 0,204, 0 }, { 153, 0,204, 0 },
- { 102, 0,204, 0 }, { 51, 0,204, 0 }, { 255,255,153, 0 }, { 204,255,153, 0 },
- { 153,255,153, 0 }, { 102,255,153, 0 }, { 51,255,153, 0 }, { 0,255,153, 0 },
- { 255,204,153, 0 }, { 204,204,153, 0 }, { 153,204,153, 0 }, { 102,204,153, 0 },
- { 51,204,153, 0 }, { 0,204,153, 0 }, { 255,153,153, 0 }, { 204,153,153, 0 },
- { 102,153,153, 0 }, { 51,153,153, 0 }, { 0,153,153, 0 }, { 255,102,153, 0 },
- { 204,102,153, 0 }, { 153,102,153, 0 }, { 102,102,153, 0 }, { 51,102,153, 0 },
- { 0,102,153, 0 }, { 255, 51,153, 0 }, { 204, 51,153, 0 }, { 153, 51,153, 0 },
- { 102, 51,153, 0 }, { 51, 51,153, 0 }, { 0, 51,153, 0 }, { 255, 0,153, 0 },
- { 204, 0,153, 0 }, { 153, 0,153, 0 }, { 102, 0,153, 0 }, { 51, 0,153, 0 },
- { 255,255,102, 0 }, { 204,255,102, 0 }, { 153,255,102, 0 }, { 102,255,102, 0 },
- { 51,255,102, 0 }, { 0,255,102, 0 }, { 255,204,102, 0 }, { 204,204,102, 0 },
- { 153,204,102, 0 }, { 102,204,102, 0 }, { 51,204,102, 0 }, { 0,204,102, 0 },
- { 255,153,102, 0 }, { 204,153,102, 0 }, { 153,153,102, 0 }, { 102,153,102, 0 },
- { 51,153,102, 0 }, { 0,153,102, 0 }, { 255,102,102, 0 }, { 204,102,102, 0 },
- { 153,102,102, 0 }, { 51,102,102, 0 }, { 0,102,102, 0 }, { 255, 51,102, 0 },
- { 204, 51,102, 0 }, { 153, 51,102, 0 }, { 102, 51,102, 0 }, { 51, 51,102, 0 },
- { 0, 51,102, 0 }, { 255, 0,102, 0 }, { 204, 0,102, 0 }, { 153, 0,102, 0 },
- { 102, 0,102, 0 }, { 51, 0,102, 0 }, { 255,255, 51, 0 }, { 204,255, 51, 0 },
- { 153,255, 51, 0 }, { 102,255, 51, 0 }, { 51,255, 51, 0 }, { 0,255, 51, 0 },
- { 255,204, 51, 0 }, { 204,204, 51, 0 }, { 153,204, 51, 0 }, { 102,204, 51, 0 },
- { 51,204, 51, 0 }, { 0,204, 51, 0 }, { 255,153, 51, 0 }, { 204,153, 51, 0 },
- { 153,153, 51, 0 }, { 102,153, 51, 0 }, { 51,153, 51, 0 }, { 0,153, 51, 0 },
- { 255,102, 51, 0 }, { 204,102, 51, 0 }, { 153,102, 51, 0 }, { 102,102, 51, 0 },
- { 51,102, 51, 0 }, { 0,102, 51, 0 }, { 255, 51, 51, 0 }, { 204, 51, 51, 0 },
- { 153, 51, 51, 0 }, { 102, 51, 51, 0 }, { 0, 51, 51, 0 }, { 255, 0, 51, 0 },
- { 204, 0, 51, 0 }, { 153, 0, 51, 0 }, { 102, 0, 51, 0 }, { 51, 0, 51, 0 },
- { 204,255, 0, 0 }, { 153,255, 0, 0 }, { 102,255, 0, 0 }, { 51,255, 0, 0 },
- { 255,204, 0, 0 }, { 204,204, 0, 0 }, { 153,204, 0, 0 }, { 102,204, 0, 0 },
- { 51,204, 0, 0 }, { 255,153, 0, 0 }, { 204,153, 0, 0 }, { 153,153, 0, 0 },
- { 102,153, 0, 0 }, { 0, 0,238, 0 }, { 0, 0,221, 0 }, { 0, 0,204, 0 },
- { 0, 0,187, 0 }, { 0, 0,170, 0 }, { 0, 0,153, 0 }, { 0, 0,136, 0 },
- { 0, 0,119, 0 }, { 0, 0,102, 0 }, { 0, 0, 85, 0 }, { 0, 0, 68, 0 },
- { 0, 0, 51, 0 }, { 0, 0, 34, 0 }, { 0, 0, 17, 0 }, { 0,238, 0, 0 },
- { 0,221, 0, 0 }, { 0,204, 0, 0 }, { 0,187, 0, 0 }, { 0,170, 0, 0 },
- { 0,153, 0, 0 }, { 0,136, 0, 0 }, { 0,119, 0, 0 }, { 0,102, 0, 0 },
- { 0, 85, 0, 0 }, { 0, 68, 0, 0 }, { 0, 51, 0, 0 }, { 0, 34, 0, 0 },
- { 0, 17, 0, 0 }, { 238, 0, 0, 0 }, { 221, 0, 0, 0 }, { 204, 0, 0, 0 },
- { 187, 0, 0, 0 }, { 170, 0, 0, 0 }, { 153, 0, 0, 0 }, { 136, 0, 0, 0 },
- { 119, 0, 0, 0 }, { 102, 0, 0, 0 }, { 85, 0, 0, 0 }, { 68, 0, 0, 0 },
- { 51, 0, 0, 0 }, { 34, 0, 0, 0 }, { 240,251,255, 0 }, { 164,160,160, 0 },
- { 128,128,128, 0 }, { 0, 0,255, 0 }, { 0,255, 0, 0 }, { 0,255,255, 0 },
- { 255, 0, 0, 0 }, { 255, 0,255, 0 }, { 255,255, 0, 0 }, { 255,255,255, 0 }
- };
- /////////////////////////////////////////////////////////////////////////////
- // CFireWnd
- // Initialize the seed for random number generation. For a more random
- // flame this could be initialized by a call to ::rand(). Declaring it
- // this way causes the same flame to be drawn each time the application
- // is executed.
- unsigned long CFireWnd::m_RandSeed = 0x38549391;
- CFireWnd::CFireWnd()
- {
- m_nDecay = 5;
- m_nFlammability = 385;
- m_nMaxHeat = 223;
- m_nSpreadRate = 20;
- m_nSmoothness = 1;
- m_nDistribution = 1;
- m_nChaos = 50;
- m_nSize = 0;
- m_MaxBurn = 0;
- m_Fire = NULL;
- m_pMemDC = NULL;
- m_pWinDC = NULL;
- m_pOldPalette = NULL;
- m_pOldBitmap = NULL;
- }
- CFireWnd::~CFireWnd()
- {
- }
- BEGIN_MESSAGE_MAP(CFireWnd, CStatic)
- //{{AFX_MSG_MAP(CFireWnd)
- ON_WM_PAINT()
- ON_WM_DESTROY()
- ON_WM_PALETTECHANGED()
- ON_WM_QUERYNEWPALETTE()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CFireWnd Operations
- void CFireWnd::InitFire(int nColor)
- {
- CreatePalette(nColor);
- CreateBitmap();
- {
- CWnd* pActiveWnd = CWnd::GetActiveWindow();
- if (pActiveWnd != NULL)
- pActiveWnd->SendMessage(WM_QUERYNEWPALETTE);
- }
- }
- CPalette* CFireWnd::GetPalette()
- {
- if (m_Palette.m_hObject != NULL)
- return &m_Palette;
- else
- return NULL;
- }
- void CFireWnd::CreatePalette(int nColor)
- {
- UINT i;
- if (m_Palette.m_hObject != NULL)
- m_Palette.DeleteObject();
- memcpy( m_rgbPalette, rgbStd256, sizeof(RGBQUAD) * 256 );
- int r,g,b;
- switch(nColor)
- {
- case blue:
- b = 256+256+255;
- g = 256+255;
- r = 255;
- break;
- case green:
- g = 256+256+255;
- r = 256+255;
- b = 255;
- break;
- case red:
- default:
- r = 256+256+255;
- g = 256+255;
- b = 255;
- break;
- }
- for(i = 239; i > 15; i--)
- {
- m_rgbPalette[i].rgbRed = (r > 255) ? 255 : r;
- m_rgbPalette[i].rgbGreen = (g > 255) ? 255 : g;
- m_rgbPalette[i].rgbBlue = (b > 255) ? 255 : b;
- r = (r > 3) ? (r - 4) : 0;
- g = (g > 3) ? (g - 4) : 0;
- b = (b > 3) ? (b - 4) : 0;
- }
- LPLOGPALETTE lpLogPal;
- lpLogPal = (LPLOGPALETTE) new BYTE[sizeof(LOGPALETTE) + ((255) * sizeof(PALETTEENTRY))];
- lpLogPal->palVersion = 0x0300;
- lpLogPal->palNumEntries = 256;
- for (i = 0; i < 256; i++)
- {
- lpLogPal->palPalEntry[i].peRed = m_rgbPalette[i].rgbRed;
- lpLogPal->palPalEntry[i].peGreen = m_rgbPalette[i].rgbGreen;
- lpLogPal->palPalEntry[i].peBlue = m_rgbPalette[i].rgbBlue;
- lpLogPal->palPalEntry[i].peFlags = 0;
- }
- VERIFY( m_Palette.CreatePalette( lpLogPal ) );
- delete [] (BYTE *)lpLogPal;
- }
- CSize CFireWnd::GetBitmapSize()
- {
- if (m_Bitmap.m_hObject == NULL)
- return CSize(0,0);
- BITMAP bm;
- m_Bitmap.GetObject( sizeof(BITMAP), &bm );
- return CSize(bm.bmWidth, bm.bmHeight);
- }
- #define WIDTHBYTES(bits) ((((bits) + 31) / 32) * 4)
- void CFireWnd::CreateBitmap()
- {
- if (m_pMemDC != NULL)
- {
- m_pMemDC->SelectObject(m_pOldBitmap);
- delete m_pMemDC;
- m_pMemDC = NULL;
- m_pOldBitmap = NULL;
- }
- if (m_pWinDC != NULL)
- {
- m_pWinDC->SelectObject(m_pOldPalette);
- delete m_pWinDC;
- m_pWinDC = NULL;
- m_pOldPalette = NULL;
- }
- if (m_Bitmap.m_hObject != NULL)
- m_Bitmap.DeleteObject();
- if (m_Fire != NULL)
- {
- delete m_Fire;
- m_Fire = NULL;
- }
- CRect rect;
- CSize size;
- GetClientRect(&rect);
- size = rect.Size();
- if (m_MaxBurn == 0)
- m_MaxBurn = (int)(size.cy * 0.75);
- if (m_nSize == 0)
- m_nSize = (int)(size.cx / 2);
- m_Fire = new BYTE[size.cx];
- LPBITMAPINFO lpbi;
- // Fill in the BITMAPINFOHEADER
- lpbi = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER) + (256 * sizeof(RGBQUAD))];
- lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- lpbi->bmiHeader.biWidth = size.cx;
- lpbi->bmiHeader.biHeight = size.cy;
- lpbi->bmiHeader.biPlanes = 1;
- lpbi->bmiHeader.biBitCount = 8;
- lpbi->bmiHeader.biCompression = BI_RGB;
- lpbi->bmiHeader.biSizeImage = WIDTHBYTES((DWORD)size.cx * 8) * size.cy;
- lpbi->bmiHeader.biXPelsPerMeter = 0;
- lpbi->bmiHeader.biYPelsPerMeter = 0;
- lpbi->bmiHeader.biClrUsed = 0;
- lpbi->bmiHeader.biClrImportant = 0;
- // Fill in the color table
- UINT uUsage = DIB_RGB_COLORS;
- memcpy( lpbi->bmiColors, m_rgbPalette, sizeof(RGBQUAD) * 256 );
- m_pWinDC = new CWindowDC(this);
- HBITMAP hBitmap = CreateDIBSection( m_pWinDC->m_hDC, lpbi, uUsage, (void **)&m_pBits, NULL, 0 );
- delete [] (BYTE *)lpbi;
- ASSERT(hBitmap != NULL);
- m_Bitmap.Attach( hBitmap );
- for (int y = 0; y < size.cy; y++ )
- {
- BYTE* pRow = (m_pBits + WIDTHBYTES((DWORD)size.cx * 8) * y);
- for (int x = 0; x < size.cx; x++ )
- *pRow++ = 16;
- }
- m_pMemDC = new CDC;
- VERIFY( m_pMemDC->CreateCompatibleDC(m_pWinDC) );
- m_pOldPalette = m_pWinDC->SelectPalette( &m_Palette, FALSE );
- m_pWinDC->RealizePalette();
- m_pOldBitmap = m_pMemDC->SelectObject( &m_Bitmap );
- for (int x = 0; x < size.cx; x++ )
- m_Fire[x] = 16;
- }
- //
- // This routine was adapted from a pascal routine written by
- // Frank Jan Sorensen Alias:Frank Patxi (fjs@lab.jt.dk)
- //
- // See AboutBox for a special thank you for all his work.
- //
- void CFireWnd::RenderFlame()
- {
- CSize size = GetBitmapSize();
- int xStart, xEnd, x, y;
- BYTE* pRow;
- BYTE* pNextRow;
- xStart = (size.cx - m_nSize) / 2;
- xEnd = xStart + m_nSize + 1;
- {
- pRow = m_pBits;
- for (x=0;x<size.cx;x++)
- {
- if (x < (xStart + m_nDistribution) || x >= (xEnd - m_nDistribution))
- m_Fire[x] = 16;
- *pRow++ = m_Fire[x];
- }
- }
- for (y = m_MaxBurn; y > 0; y--)
- {
- pRow = (m_pBits + WIDTHBYTES((DWORD)size.cx * 8) * y);
- pNextRow = (m_pBits + WIDTHBYTES((DWORD)size.cx * 8) * (y - 1));
- if ((rand() % 2) == 0)
- {
- for (x = 0; x < size.cx; x++)
- {
- BurnPoint(pRow, pNextRow);
- pRow++;
- pNextRow++;
- }
- }
- else
- {
- pRow += size.cx - 1;
- pNextRow += size.cx - 1;
- for (x = 0; x < size.cx; x++)
- {
- BurnPoint(pRow, pNextRow);
- pRow--;
- pNextRow--;
- }
- }
- }
- int MaxHeat = m_nMaxHeat + 16;
- if ( rand() % (400 - m_nFlammability) == 0)
- {
- int off = m_nSize - 5;
- off = rand() % off;
- off += xStart;
- for (x = off; x < off + 5; x++)
- m_Fire[x] = 239;
- }
- for (x = xStart; x < xEnd; x++)
- {
- if (m_Fire[x] < MaxHeat)
- {
- int val = rand() % m_nChaos+1;
- val -= m_nChaos / 2;
- val += m_nSpreadRate;
- val += m_Fire[x];
- if ( val > MaxHeat)
- m_Fire[x] = MaxHeat;
- else if ( val < 16)
- m_Fire[x] = 16;
- else
- m_Fire[x] = val;
- }
- else
- m_Fire[x] = MaxHeat;
- }
- if (m_nSmoothness > 0)
- {
- xStart += m_nSmoothness;
- xEnd -= m_nSmoothness;
- for (x = xStart; x < xEnd; x++)
- {
- int val = 0;
- for (y = x - m_nSmoothness; y < x + 1 + m_nSmoothness; y++)
- val += m_Fire[y];
- m_Fire[x] = val / (2*m_nSmoothness+1);
- }
- }
- }
- void CFireWnd::PaintFlame(CDC* pDC)
- {
- if (m_Palette.m_hObject != NULL && m_Bitmap.m_hObject != NULL)
- {
- CSize size = GetBitmapSize();
- if (pDC != NULL)
- {
- CDC dc;
- CPalette *pOldPalette;
- pOldPalette = pDC->SelectPalette( &m_Palette, FALSE );
- pDC->RealizePalette();
- VERIFY( dc.CreateCompatibleDC(pDC) );
- CBitmap* pOldBitmap = dc.SelectObject( &m_Bitmap );
- pDC->BitBlt( 0, 0, size.cx, size.cy, &dc, 0, 0, SRCCOPY );
- dc.SelectObject(pOldBitmap);
- pDC->SelectPalette( pOldPalette, TRUE );
- }
- else
- {
- m_pWinDC->BitBlt( 0, 0, size.cx, size.cy, m_pMemDC, 0, 0, SRCCOPY );
- }
- }
- }
- void CFireWnd::SetMaxBurn(int nMax)
- {
- if (m_Palette.m_hObject != NULL && m_Bitmap.m_hObject != NULL)
- {
- CSize size = GetBitmapSize();
- m_MaxBurn = (int)(size.cy * (nMax/100.0));
- int y;
- for (y = (size.cy - 1); y > m_MaxBurn; y--)
- {
- BYTE* pRow = (m_pBits + WIDTHBYTES((DWORD)size.cx * 8) * y);
- for (int x = 0; x < size.cx; x++)
- *pRow++ = 16;
- }
- }
- }
- int CFireWnd::GetMaxBurn()
- {
- return m_MaxBurn;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CFireWnd message handlers
- void CFireWnd::OnDestroy()
- {
- CStatic::OnDestroy();
- if (m_pMemDC != NULL)
- {
- m_pMemDC->SelectObject(m_pOldBitmap);
- delete m_pMemDC;
- m_pMemDC = NULL;
- m_pOldBitmap = NULL;
- }
- if (m_pWinDC != NULL)
- {
- m_pWinDC->SelectObject(m_pOldPalette);
- delete m_pWinDC;
- m_pWinDC = NULL;
- m_pOldPalette = NULL;
- }
- if (m_Bitmap.m_hObject != NULL)
- m_Bitmap.DeleteObject();
- if (m_Palette.m_hObject != NULL)
- m_Palette.DeleteObject();
- if (m_Fire != NULL)
- {
- delete m_Fire;
- m_Fire = NULL;
- }
- }
- void CFireWnd::OnPaint()
- {
- CPaintDC dc(this); // device context for painting
- PaintFlame(&dc);
- }
- void CFireWnd::OnPaletteChanged(CWnd* pFocusWnd)
- {
- if (pFocusWnd == this || IsChild(pFocusWnd))
- return;
- OnQueryNewPalette();
- }
- BOOL CFireWnd::OnQueryNewPalette()
- {
- if (GetPalette() == NULL)
- return FALSE;
- {
- CClientDC dc(this);
- CPalette* pOldPalette = dc.SelectPalette(&m_Palette,
- GetCurrentMessage()->message == WM_PALETTECHANGED);
- UINT nChanged = dc.RealizePalette();
- dc.SelectPalette(pOldPalette, TRUE);
- if (nChanged == 0) // no change to our mapping
- return FALSE;
- }
- // some changes have been made; invalidate
- Invalidate(FALSE);
- return TRUE;
- }