Click here to Skip to main content
15,897,704 members
Articles / Desktop Programming / MFC
Article

A Spin Edit control with popup trackbar

Rate me:
Please Sign up or sign in to vote.
4.62/5 (17 votes)
22 Apr 20042 min read 93.2K   3.4K   28   16
An implementation of the spin-edit control used in Jasc Paint Shop Pro

Introduction

I've wanted to post an item for some time, so when I started working on this component, I decided it was going to be it. The image editing software "Paint Shop Pro" from Jasc software utilizes a unique combination of an edit, spin, and trackbar functionality. I decided to try to derive my own version of this and this is the result. Check the upper left are on the screenshot. I used VS 2003 but I see no reason why it can't be compiled and used with an earlier version. The only requirement is that IE5 is required because it requires 32 bit calls such as the GetPos32() API.

Using the code

Methods

  • int GetValue() - Get the current value
  • void SetValue(int nValue) - Sets the current value
  • BOOL GetReadOnly() - Gets the readonly state of the edit field
  • void SetReadOnly(BOOL fReadOnly) - Sets the readonly state of the edit field
  • void GetRange(int& nMin,int& nMax) - Gets the allowed value range
  • void SetRange(int nMin,int nMax) - Sets the allowed value range

Styles

  • NES_SPIN - Includes the spin control
  • NES_POPUP - Includes the button on the far right that pops up a floating trackbar
  • NES_LIVEUPDATE - Updates the parent about the value while tracking. NEW
  • NES_METER - Includes the small bar underneath the edit field.NEW

Messages

  • NEM_GETPOS - Returns the current value as return value
  • NEM_SETPOS - Sets the current value. Passed in LPARAM
  • NEM_GETRANGE - Returns allowed range. WPARAM and LPARAM are treated as pointers to int's
  • NEM_SETRANGE - Sets the allowed range. Min is in WPARAM and max in LPARAM
  • NEM_GETREADONLY - Gets the readonly state of the edit field. NEW
  • NEM_SETREADONLY - Sets the readonly state of the edit field. NEW

Notifications

  • NEN_CHANGED - Sent to the owner window when the value changes
// Declare a CNumericEdit
CNumericEdit m_Edit;        
        
//
// Creating the control
//
CRect</CODE> rcRect(10,10,142,40);
m_Edit.Create(WS_VISIBLE | WS_TABSTOP | NES_SPIN | NES_POPUP,rcRect,this,0);
m_Edit.SetValue(50);
m_Edit.SetRange(0,100);

Todo

  • Make the popup trackbar size configurable
  • XP support ??
  • Bitmap in popup trackbar (just like Paint Shop Pro) ?

History

4/13/2004 - 1.0

  • Initial version

4/20/2004 - 1.01

  • Fixed bug where the edit would only accept hex digits. Also now allow negative sign "-" to be entered
  • Added NES_METER style to make the small bar under the edit field optional
  • Control will now reconfigure itself when changing style bits
  • Fixed max value bug. The full range is now accesible with the popup
  • Added NES_LIVEUPDATE style. This style allows the control to notify it's parent during value tracking. Without this style, the parent is updated only at the end of tracking
  • Demo has been updated to show the new features
  • Added DDX_NumericEdit() function for DDX support
  • Now using the active window caption color for the bar colors
  • Changed hardcoded custom messages to use windows registered messages so as not to cause any conflict with other custom messages

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questionso good , thank you very muchi Pin
Tao craig5-Dec-17 15:31
Tao craig5-Dec-17 15:31 
GeneralMy vote of 5 Pin
Member 1159623114-Apr-15 21:17
Member 1159623114-Apr-15 21:17 
QuestionCan someone convert this for WTL? Pin
ehaerim17-Jun-09 9:41
ehaerim17-Jun-09 9:41 
GeneralCrash when I press enter Pin
prod@pt6-Dec-08 22:50
prod@pt6-Dec-08 22:50 
GeneralRe: Crash when I press enter Pin
ehaerim17-Jun-09 10:08
ehaerim17-Jun-09 10:08 
Generalcontrol have a bug & i correct it Pin
mohammadmot26-Aug-08 22:23
mohammadmot26-Aug-08 22:23 
Questionquestion about change notification with multiple CNumericEdit controls Pin
CelticDaddio17-Apr-08 7:30
CelticDaddio17-Apr-08 7:30 
AnswerSOLVED Re: question about change notification with multiple CNumericEdit controls Pin
CelticDaddio17-Apr-08 8:01
CelticDaddio17-Apr-08 8:01 
GeneralMake it no activating Pin
YYuri14-Sep-06 8:39
YYuri14-Sep-06 8:39 
GeneralA simple extension Pin
Steve Johnson (Sven)13-Jun-05 13:36
Steve Johnson (Sven)13-Jun-05 13:36 
Nice article and very useful. I have created a simple spinner derivation that could give the same results, while retaining much of the standard control operation.

This approach preserves the "buddy" relationship between the spin control and the edit box, and as well uses the dialog fonts mentioned by another reader. It also does not require a CWnd derived class to parent the edit and spin control.

Instead of having a separate button (CMyButton), this uses a right click on the up/down control to show the slider popup. I personally like more with less, so this works for me.

This also doesn't paint the bar below the edit control as yours does, but I would suggest overriding OnPaint() for your CMyEdit control and after calling CEdit::Paint(), simply draw a bar on the bottom two pixels of the edit control.

You can test this approach by using CMySpinEditCtrl instead of the CSpinEditCtrl for m_spnMin, m_spnMax, etc, in your demo program.

// Put this in NumericEdit.h ////////////////////////////////
class CMySpinButtonCtrl : public CSpinButtonCtrl
{
DECLARE_DYNAMIC(CMySpinButtonCtrl)

protected:
DECLARE_MESSAGE_MAP()

public:
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg LRESULT OnSetPos(WPARAM /*wParam*/,LPARAM nNewValue);
};

// Put this in NumericEdit.cpp /////////////////////////////
IMPLEMENT_DYNAMIC(CMySpinButtonCtrl, CSpinButtonCtrl)

BEGIN_MESSAGE_MAP(CMySpinButtonCtrl, CSpinButtonCtrl)
ON_WM_RBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_REGISTERED_MESSAGE(NEM_SETPOS,OnSetPos)
END_MESSAGE_MAP()

void CMySpinButtonCtrl::OnRButtonDown(UINT nFlags, CPoint point)
{
CSpinButtonCtrl::OnRButtonDown(nFlags,point);

CMyTrackPopup* pTrackPopup = new CMyTrackPopup();

CRect rcRect;
GetWindowRect(rcRect); // Get button location to determine popup location

int min, max, pos;

GetRange32( min, max );
pos = GetPos32();

pTrackPopup->Create( rcRect.left + point.x,rcRect.bottom + 4, min, max, pos, this);
}

void CMySpinButtonCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
CSpinButtonCtrl::OnLButtonUp(nFlags,point);

CEdit* editPtr = (CEdit*)this->GetBuddy();
editPtr->SetSel( -1, 0 ); // Turn off the edit selection
}

afx_msg LRESULT CMySpinButtonCtrl::OnSetPos(WPARAM /*wParam*/,LPARAM nNewValue)
{
SetPos32((int)nNewValue);
return 0;
}

Cheers,

Steve
GeneralRe: A simple extension Pin
niry18-Aug-05 6:19
niry18-Aug-05 6:19 
GeneralRe: A simple extension Pin
Steve Johnson (Sven)18-Aug-05 6:28
Steve Johnson (Sven)18-Aug-05 6:28 
GeneralCMyEdit Pin
vivadot24-Jun-04 7:42
vivadot24-Jun-04 7:42 
GeneralDoes not work for VC6. Pin
WREY25-Apr-04 11:57
WREY25-Apr-04 11:57 
GeneralNice, but two mods needed Pin
Robin Hilliard22-Apr-04 23:48
Robin Hilliard22-Apr-04 23:48 
GeneralRe: Nice, but two mods needed Pin
vivadot24-Jun-04 7:44
vivadot24-Jun-04 7:44 

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.