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 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



Comments

  • Find It Here

    Posted by Legacy on 06/08/2003 12:00am

    Originally posted by: Mike McNasty

    http://www.google.com
    

    Reply
  • http://www.google.com

    Posted by Legacy on 06/08/2003 12:00am

    Originally posted by: Mike McNasty

    http://www.google.com
    

    Reply
  • http://www.google.com

    Posted by Legacy on 06/08/2003 12:00am

    Originally posted by: Find It Here

    http://www.google.com
    

    Reply
  • Flickering while resizing...

    Posted by Legacy on 02/24/2003 12:00am

    Originally posted by: dunkel

    Everything's very good but flickering while resizing...

    Reply
  • Text over gradient backgound

    Posted by Legacy on 05/29/2002 12:00am

    Originally posted by: Mustafa

    Hi,

    Tried to implement the gradient background effect, it works fine but when I displayed text on to the window with :-

    dc.SetBkColor(TRANSPARENT)..it gave me a black background...could you help???

    Thanks and regards

    Mustafa

    Reply
  • Sorry my mistake.....

    Posted by Legacy on 05/29/2002 12:00am

    Originally posted by: Mustafa

    Shud use dc.SetBkMode(TRANSPARENT) instead....:-(


    sorry....thanks for sharing your knowledge...


    regards

    Mustafa

    Reply
  • Re: Help me do it to my existing dialogbox

    Posted by Legacy on 08/13/1999 12:00am

    Originally posted by: chensu

    A dialog box is a window and CDialog is derived from CWnd. You may use the OnPaint(), PaintGradiantRect() and CreateGradPalette() functions directly. But the WM_PALETTECHANGED message is sent to all top-level and overlapped windows. You've got to pass the WM_PALETTECHANGED and WM_QUERYNEWPALETTE messages on to the dialog box if it is not the main frame window.

    Reply
  • Help me do it to my existing dialogbox

    Posted by Legacy on 04/15/1999 12:00am

    Originally posted by: Keith Smith

    This example works fine.
    
    

    I changed the paint directions, and colors, and I just love the effects, but I now would like to add this effect to application that I already have created.

    I have several dialog based applications that I would like to add your Paint a Gradient Color Background to, but I don't know where to start.

    I would also like to impliment this effect on dialog doxes that are accesed within an application.

    Can you help ?

    KSmith:=}

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • As all sorts of data becomes available for storage, analysis and retrieval - so called 'Big Data' - there are potentially huge benefits, but equally huge challenges...
  • The agile organization needs knowledge to act on, quickly and effectively. Though many organizations are clamouring for "Big Data", not nearly as many know what to do with it...
  • Cloud-based integration solutions can be confusing. Adding to the confusion are the multiple ways IT departments can deliver such integration...

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date