Paint a gradient color background | CodeGuru

Paint a gradient color background

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 […]

Written By
CodeGuru Staff
CodeGuru Staff
Aug 19, 1998
1 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More


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_REDRed
GPC_GREENGreen
GPC_BLUEBlue
GPC_RED | GPC_GREENYellow
GPC_RED | GPC_BLUEPurple
GPC_GREEN | GPC_BLUECyan
GPC_RED | GPC_GREEN | GPC_BLUEGrey

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

CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.