This article was contributed by chensu.
Have you seen an installation program that has a gradient color background? Yes, you have. How do you paint such a background?
First, you need to create a gradient color palette (CGradpalWnd::CreateGradPalette()). Then, you can paint the background with the colors in the palette (CGradpalWnd::PaintGradiantRect()).
This program allows you to paint with four directions
m_nPaintDir:
GPD_TTOB – top to bottom,
GPD_BTOT – bottom to top,
GPD_LTOR – left to right,
GPD_RTOL – right to left
and seven colors
m_nPaintRGB:
GPC_RED – Red
GPC_GREEN – Green
GPC_BLUE – Blue
GPC_RED | GPC_GREEN – Yellow
GPC_RED | GPC_BLUE – Purple
GPC_GREEN | GPC_BLUE – Cyan
GPC_RED | GPC_GREEN | GPC_BLUE – Grey
And specify m_nPaintSteps with the number of steps it takes to paint.
Source:
// GRADPAL.H // Written by chensu // m_nPaintDir: // GPD_TTOB - top to bottom, // GPD_BTOT - bottom to top, // GPD_LTOR - left to right, // GPD_RTOL - right to left #define GPD_TTOB 0 #define GPD_BTOT 1 #define GPD_LTOR 2 #define GPD_RTOL 3 // m_nPaintRGB: a combination of one or more of the following values // i.e.: // GPC_RED - Red // GPC_GREEN - Green // GPC_BLUE - Blue // GPC_RED | GPC_GREEN - Yellow // GPC_RED | GPC_BLUE - Purple // GPC_GREEN | GPC_BLUE - Cyan // GPC_RED | GPC_GREEN | GPC_BLUE - Grey #define GPC_RED 0x0001 #define GPC_GREEN 0x0002 #define GPC_BLUE 0x0004 //----------------------------------------------------------------------------- class CGradpalApp : public CWinApp { public: virtual BOOL InitInstance(); }; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- class CGradpalWnd : public CFrameWnd { public: CGradpalWnd(); inline BOOL CreateWnd(); protected: afx_msg BOOL OnQueryNewPalette(); afx_msg void OnPaletteChanged(CWnd *pFocusWnd); afx_msg void OnPaint(); DECLARE_MESSAGE_MAP() private: const int m_nPaintSteps, m_nPaintDir; const UINT m_nPaintRGB; CPalette m_Pal; void PaintGradiantRect(CDC *pDC, const RECT &rect) const; BOOL CreateGradPalette(); }; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- inline BOOL CGradpalWnd::CreateWnd() { return this->Create(NULL, _T("Gradient Palette")); } //----------------------------------------------------------------------------- // End of GRADPAL.H // GRADPAL.CPP // Written by chensu #include <afxwin.h> #include "gradpal.h" //***************************************************************************** //----------------------------------------------------------------------------- CGradpalApp GradpalApp; //----------------------------------------------------------------------------- //***************************************************************************** //***************************************************************************** //----------------------------------------------------------------------------- BOOL CGradpalApp::InitInstance() { CGradpalWnd *pMainFrame = new CGradpalWnd(); if (!pMainFrame->CreateWnd()) return FALSE; pMainFrame->ShowWindow(m_nCmdShow); pMainFrame->UpdateWindow(); m_pMainWnd = pMainFrame; return TRUE; } //----------------------------------------------------------------------------- //***************************************************************************** //***************************************************************************** //----------------------------------------------------------------------------- CGradpalWnd::CGradpalWnd() : m_nPaintSteps(236), // the number of steps m_nPaintDir(GPD_BTOT), // the direction m_nPaintRGB(GPC_BLUE) // the color { VERIFY(this->CreateGradPalette()); } //----------------------------------------------------------------------------- BEGIN_MESSAGE_MAP(CGradpalWnd, CFrameWnd) ON_WM_QUERYNEWPALETTE() ON_WM_PALETTECHANGED() ON_WM_PAINT() END_MESSAGE_MAP() //----------------------------------------------------------------------------- BOOL CGradpalWnd::OnQueryNewPalette() { CClientDC dc(this); CPalette *pPalOld = dc.SelectPalette(&m_Pal, FALSE); BOOL bRet = dc.RealizePalette(); dc.SelectPalette(pPalOld, FALSE); if (bRet) // some colors changed this->Invalidate(); return bRet; } //----------------------------------------------------------------------------- void CGradpalWnd::OnPaletteChanged(CWnd *pFocusWnd) { if (pFocusWnd != this) this->OnQueryNewPalette(); } //----------------------------------------------------------------------------- void CGradpalWnd::OnPaint() { CPaintDC dc(this); CPalette *pPalOld = dc.SelectPalette(&m_Pal, FALSE); dc.RealizePalette(); RECT rect; this->GetClientRect(&rect); this->PaintGradiantRect(&dc, rect); dc.SelectPalette(pPalOld, FALSE); } //----------------------------------------------------------------------------- void CGradpalWnd::PaintGradiantRect(CDC *pDC, const RECT &rect) const { ASSERT(pDC != NULL); ASSERT_KINDOF(CDC, pDC); // initialize RECT rectVar = { rect.left, rect.top, rect.left, rect.top }; int nTotalSize; if (m_nPaintDir == GPD_TTOB || m_nPaintDir == GPD_BTOT) { rectVar.right = rect.right; nTotalSize = rect.bottom - rect.top; } else { rectVar.bottom = rect.bottom; nTotalSize = rect.right - rect.left; } // paint nSteps times for (int nIndex = 0; nIndex < m_nPaintSteps; nIndex++) { // calculate the rectangle if (m_nPaintDir == GPD_TTOB || m_nPaintDir == GPD_BTOT) { rectVar.top = rectVar.bottom; rectVar.bottom = rect.top + ::MulDiv(nIndex + 1, nTotalSize, m_nPaintSteps); } else { rectVar.left = rectVar.right; rectVar.right = rect.left + ::MulDiv(nIndex + 1, nTotalSize, m_nPaintSteps); } // calculate the color value int nColor = ::MulDiv(nIndex, 255, m_nPaintSteps); if (m_nPaintDir == GPD_BTOT || m_nPaintDir == GPD_RTOL) nColor = 255 - nColor; const COLORREF clrBr = PALETTERGB((BYTE)(m_nPaintRGB & GPC_RED ? nColor : 0), (BYTE)(m_nPaintRGB & GPC_GREEN ? nColor : 0), (BYTE)(m_nPaintRGB & GPC_BLUE ? nColor : 0)); // paint the rectangle with the brush CBrush brush(clrBr); pDC->FillRect(&rectVar, &brush); } } //----------------------------------------------------------------------------- BOOL CGradpalWnd::CreateGradPalette() { if (m_Pal.GetSafeHandle() != NULL) return FALSE; BOOL bSucc = FALSE; const int nNumColors = 236; LPLOGPALETTE lpPal = (LPLOGPALETTE)new BYTE[sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * nNumColors]; if (lpPal != NULL) { lpPal->palVersion = 0x300; lpPal->palNumEntries = nNumColors; PALETTEENTRY *ppe = lpPal->palPalEntry; for (int nIndex = 0; nIndex < nNumColors; nIndex++) { const int nColor = ::MulDiv(nIndex, 255, nNumColors); ppe->peRed = (BYTE)(m_nPaintRGB & GPC_RED ? nColor : 0); ppe->peGreen = (BYTE)(m_nPaintRGB & GPC_GREEN ? nColor : 0); ppe->peBlue = (BYTE)(m_nPaintRGB & GPC_BLUE ? nColor : 0); ppe->peFlags = (BYTE)0; ppe++; } bSucc = m_Pal.CreatePalette(lpPal); delete [](PBYTE)lpPal; } return bSucc; } //----------------------------------------------------------------------------- //***************************************************************************** // End of GRADPAL.CPP
Download sample project – 53KB
Last updated: 27 July 1998
Posted on: 19 Aug 1998