Click here to Skip to main content
Click here to Skip to main content

Tagged as

Go to top

An Adobe style slider control

, 3 Jan 2012
Rate this:
Please Sign up or sign in to vote.
Customize the standard slider control to appear like an Adobe style slider control

Introduction

adobeslider.JPG

This article is about customizing the Windows standard slider control through Custom Drawing fuctionalities provided by Windows itself. Although, here a Adobe photoshop style slider control is drawn, but it is upto the user to follow the guideline and come up with a nice slider control with custom looks.

Background

In one of my projects I was asked to provide a control which looks like the adobe section cut control, but have all the APIs and features of a slider. Therefore I just handled the NM_CUSTOMDRAW Reflection message of the slider and came up with this nice looking (though i do say so myself) slider. 

Using the code

Place a slider control in your Dialog from resource, add a member variable for the slider through the MFC Wizard and change the classname to CAdobeSliderCtrl so that it would look similar to this in your header file of the parent dialog. 

CAdobeSliderCtrl m_adobeSliderCtrl; 

Guess what, you are finished. Now your slider should look like the one you see in the image on top.

Points of Interest

void CCustomDrawSliderCtrl::OnCustomDraw ( NMHDR* pNMHDR, LRESULT* pResult)
{		
	NMCUSTOMDRAW nmcd = *(LPNMCUSTOMDRAW) pNMHDR;

	UINT drawStage = nmcd.dwDrawStage;
	UINT itemSpec = (UINT)nmcd.dwItemSpec;
	
	switch ( drawStage )
	{
		case CDDS_PREPAINT:
			// most important of the drawing stages must return CDRF_NOTIFYITEMDRAW or else we will not get further 
			// NM_CUSTOMDRAW notifications for this drawing cycle we also return CDRF_NOTIFYPOSTPAINT 
			// so that we will get post-paint notifications		
			*pResult = CDRF_NOTIFYITEMDRAW | CDRF_NOTIFYPOSTPAINT ;
		break;

		case CDDS_PREERASE:		// Before the erase cycle begins
		case CDDS_POSTERASE:	// After the erase cycle is complete
		case CDDS_ITEMPREERASE:	// Before an item is erased
		case CDDS_ITEMPOSTERASE:	// After an item has been erased
			*pResult = CDRF_DODEFAULT;
		break;

		case CDDS_ITEMPREPAINT:
			switch (itemSpec)
			{
				case TBCD_CHANNEL:					
					*pResult = CDRF_SKIPDEFAULT;					
				break;

				case TBCD_TICS:					
					*pResult = CDRF_DODEFAULT;
				break;

				case TBCD_THUMB:
				{										
					CDC* pDC = CDC::FromHandle( nmcd.hdc );
					Draw(pDC, &nmcd);

					*pResult = CDRF_SKIPDEFAULT;
				}
				break;
			}
		break;

		case CDDS_ITEMPOSTPAINT:	// After an item has been drawn
			switch ( itemSpec )
			{				
				case TBCD_TICS:					
					*pResult = CDRF_DODEFAULT;
				break;

				case TBCD_THUMB:
					*pResult = CDRF_DODEFAULT;	
				break;
			}

		break;
	}	
}

I would like to attract the reader's attention to the code pasted above.

See how the the item prepaints and post paints are handled and the place where Draw is invoked. This is not standard coding when it comes to the slider, but this is a trick to easily achieve any type of drawing overriding for the slider.

And to address the nonstandard invokation of drawing of the whole slider control from inside drawing the thumb, the Draw function has a minor hack as you can see below nicely pointed out in the code comments:

void CCustomDrawSliderCtrl::Draw(CDC *pDC, LPNMCUSTOMDRAW lpcd)
{	
	CRect rc;
	GetWindowRect(rc);
	GetClientRect(rc);
	// The first drawing is to make sure the thumb area is painted properly with the background
	// and the edges
	OnDraw(pDC, rc);	

	// The next drawing is to make sure the control is drawn properly covering the whole client area
	CClientDC dc(this);
	OnDraw(&dc, rc);	
}

I hope you can guess that the CCustomDrawSliderCtrl gives a base for complete owner drawing of the slider control which should be done by the derived controls in the OnDraw overridable method like it is done in the CAdobeSliderCtrl (inherited of-course from CCustomDrawSliderCtrl).

So, the purpose of this article is to provide a base for drawing the slider at your will. Of-course, apart from very few specific cases I personally wouldn't advise to change too much the drawing of the standard windows control unless absolutely required.

History

Article posted: 3rd January, 2012 (How about that.. begining the new year with an article Smile | :) !!)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Mukit, Ataul
Chief Technology Officer Rational Technologies
Bangladesh Bangladesh
You don't learn patterns, you just code it.
Follow on   Twitter

Comments and Discussions

 
GeneralMy vote of 5 Pinmembermanoj kumar choubey26-Feb-12 20:52 
GeneralMy vote of 5 Pinmemberimei.name3-Jan-12 2:20 
GeneralRe: My vote of 5 PinmemberMukit, Ataul27-Feb-12 18:33 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140922.1 | Last Updated 3 Jan 2012
Article Copyright 2012 by Mukit, Ataul
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid