Click here to Skip to main content
15,867,568 members
Articles / Desktop Programming / MFC

An Adobe style slider control

Rate me:
Please Sign up or sign in to vote.
4.85/5 (6 votes)
3 Jan 2012CPOL2 min read 29.2K   1.1K   16   6
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. 

C++
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 :) !!)

License

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


Written By
Technical Lead Kotha Technologies
Bangladesh Bangladesh
If you are not in - you are out !
- Chapter 1

Comments and Discussions

 
AnswerVery good article Pin
Michael Haephrati18-Aug-22 3:33
professionalMichael Haephrati18-Aug-22 3:33 
Suggestiongood Pin
ligang_yt@aliyun.com24-May-16 23:27
ligang_yt@aliyun.com24-May-16 23:27 
GeneralRe: good Pin
Mukit, Ataul26-May-16 11:15
Mukit, Ataul26-May-16 11:15 
GeneralMy vote of 5 Pin
Manoj Kumar Choubey26-Feb-12 20:52
professionalManoj Kumar Choubey26-Feb-12 20:52 
GeneralMy vote of 5 Pin
imei.name3-Jan-12 2:20
imei.name3-Jan-12 2:20 
GeneralRe: My vote of 5 Pin
Mukit, Ataul27-Feb-12 18:33
Mukit, Ataul27-Feb-12 18:33 

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

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