旋转按钮SPIN与编辑框的联合

来源:互联网 发布:小米抢购技巧知乎 编辑:程序博客网 时间:2024/05/18 00:08

旋转按钮SPIN与编辑框的联合

要使Spin与edit更好的成为伙伴关系,实现联动效应,且支持浮点型,Spin还可以以任意精度调整,重新写了这两个类,以后只要加入这两个类的头文件和源文件就可以实现联动效应了。参考大牛们的。名字忘记了,不好意思。

///NumEdit.h

#if!defined(AFX_NUMEDIT_H__7482F7FF_A479_11D2_A6A7_00600844997A__INCLUDED_)

#defineAFX_NUMEDIT_H__7482F7FF_A479_11D2_A6A7_00600844997A__INCLUDED_

 

#if _MSC_VER >= 1000

#pragma once

#endif // _MSC_VER >= 1000

// NumEdit.h : header file

//

 

/////////////////////////////////////////////////////////////////////////////

// CNumEdit window

 

#ifndef CLASS_EXPORT

       #defineCLASS_EXPORT

#endif

 

class CLASS_EXPORT CNumEdit : public CEdit

{

       DECLARE_DYNAMIC(CNumEdit)

// Construction

public:

       CNumEdit();

 

// Attributes

public:

       enum{VALID = 0x00, OUT_OF_RANGE = 0x01, INVALID_CHAR = 0x02};

// Operations

public:

 

// Overrides

       //ClassWizard generated virtual function overrides

       //{{AFX_VIRTUAL(CNumEdit)

       //}}AFX_VIRTUAL

 

// Implementation

public:

       virtualvoid ChangeAmount(int step);

       virtualfloat GetDelta();

       virtualvoid SetDelta(float delta);

       virtualvoid GetRange(float &min, float &max)const;

       virtualvoid SetRange(float min, float max);

       virtualvoid Verbose(BOOL v);

       virtualBOOL Verbose()const;

       virtualint IsValid()const;

       virtualint IsValid(const CString &str)const;

 

       virtualBOOL SetValue(float val);

       virtualfloat GetValue()const;

       virtual~CNumEdit();

 

       //Generated message map functions

protected:

       virtualCString& ConstructFormat(CString &str, float num);

       BYTEm_NumberOfNumberAfterPoint;

       BOOLm_Verbose;

       floatm_Delta, m_MinValue, m_MaxValue;

       //{{AFX_MSG(CNumEdit)

       afx_msgvoid OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);

       //}}AFX_MSG

 

       DECLARE_MESSAGE_MAP()

};

 

/////////////////////////////////////////////////////////////////////////////

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Developer Studio will insertadditional declarations immediately before the previous line.

 

#endif //!defined(AFX_NUMEDIT_H__7482F7FF_A479_11D2_A6A7_00600844997A__INCLUDED_)

 

 

///NumEdit.cpp

// NumEdit.cpp : implementation file

//

 

#include "stdafx.h"

#include "NumEdit.h"

#include "Float.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

/////////////////////////////////////////////////////////////////////////////

// CNumEdit

 

IMPLEMENT_DYNAMIC(CNumEdit, CEdit)

 

CNumEdit::CNumEdit()

{

       m_NumberOfNumberAfterPoint= 0;

       m_Verbose= FALSE;

       m_MinValue= -FLT_MAX;

       m_MaxValue= FLT_MAX;

       m_Delta= FLT_ROUNDS;

}

 

CNumEdit::~CNumEdit()

{

}

 

 

BEGIN_MESSAGE_MAP(CNumEdit, CEdit)

       //{{AFX_MSG_MAP(CNumEdit)

       ON_WM_CHAR()

       //}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

/////////////////////////////////////////////////////////////////////////////

// CNumEdit message handlers

 

float CNumEdit::GetValue() const

{

       floatf = 0.0f;

       if(IsValid() == VALID)

       {

              CStringstr;

              GetWindowText(str);

              sscanf(str,"%f", &f);

       }

       returnf;

}

 

BOOL CNumEdit::SetValue(float val)

{

       if(val > m_MaxValue || val < m_MinValue) return FALSE;

       CStringstr, s;

       str.Format(ConstructFormat(s,val), val);

       SetWindowText(str);

       returnTRUE;

}

 

int CNumEdit::IsValid() const//此函数不能修改数据成员

{

       CStringstr;

       GetWindowText(str);

       intres = VALID;

       floatf;

       charlp[10];

       if(sscanf(str, "%f%s", &f, lp) != 1) res = INVALID_CHAR;//把

       if(f > m_MaxValue || f < m_MinValue) res = OUT_OF_RANGE;

       if(m_Verbose && res != VALID)

       {

              str.Empty();

              if(res & OUT_OF_RANGE) str += _T("Given value is out of range.\n");

              if(res & INVALID_CHAR) str += _T("Characters must be a number.\n");

              AfxMessageBox(str,MB_OK | MB_ICONSTOP);

       }

       returnres;

}

 

int CNumEdit::IsValid(const CString&str) const

{

       intres = VALID;

       floatf;

       charlp[10];

       if(sscanf(str, "%f%s", &f, lp) != 1) res = INVALID_CHAR;

       if(f > m_MaxValue && f < m_MinValue) res = OUT_OF_RANGE;

       if(m_Verbose && res != VALID)

       {

              CStringmsg;

              msg.Empty();

              if(res & OUT_OF_RANGE) msg += _T("Given value is out of range.\n");

              if(res & INVALID_CHAR) msg += _T("Characters must be a number.\n");

              AfxMessageBox(str,MB_OK | MB_ICONSTOP);

       }

       returnres;

}

 

void CNumEdit::OnChar(UINT nChar, UINTnRepCnt, UINT nFlags)

{

       if(nChar == ' ') return;

       floatoldValue;

       oldValue= GetValue();

       CEdit::OnChar(nChar,nRepCnt, nFlags);

       if(IsValid() != VALID)

       {

              SetValue(oldValue);//把先前的字符写入框

              SetSel(0,-1);//选中框里的所有内容

              MSGmsg;

              while(::PeekMessage(&msg, m_hWnd, WM_CHAR, WM_CHAR, PM_REMOVE));

       }else

       {

              CStrings;

              ConstructFormat(s,GetValue());

       }

}

 

BOOL CNumEdit::Verbose() const

{

       returnm_Verbose;

}

 

void CNumEdit::Verbose(BOOL v)

{

       m_Verbose= v;

}

 

void CNumEdit::SetRange(float min, floatmax)

{

       m_MinValue= min;

       m_MaxValue= max;

}

 

void CNumEdit::GetRange(float & min,float & max) const

{

       min= m_MinValue;

       max= m_MaxValue;

}

 

void CNumEdit::SetDelta(float delta)

{

       m_Delta= delta;

}

 

float CNumEdit::GetDelta()

{

       returnm_Delta;

}

 

void CNumEdit::ChangeAmount(int step)

{

       floatf = GetValue() + step * m_Delta;

       if(f > m_MaxValue) f = m_MaxValue;

       elseif (f < m_MinValue) f = m_MinValue;

       SetValue(f);

}

 

CString&CNumEdit::ConstructFormat(CString &str, float num)

{

       str.Format("%G",num);//%g选择以%f(小数十进制)或%e(科学计数法)输出。如何选择呢,是选择输出比较短的那个

       intn = str.Find('.');//返回以0为基数的序号

       if(n >= 0)

       {

              n= str.GetLength() - n - 1;

              if(n > m_NumberOfNumberAfterPoint) m_NumberOfNumberAfterPoint = n;

       }

       str.Format("%%.%df",m_NumberOfNumberAfterPoint);

       returnstr;

}

 

//NumSpinCtrl.h

#if!defined(AFX_NUMSPINCTRL_H__C2BD95A2_A482_11D2_A6A7_00600844997A__INCLUDED_)

#defineAFX_NUMSPINCTRL_H__C2BD95A2_A482_11D2_A6A7_00600844997A__INCLUDED_

 

#if _MSC_VER >= 1000

#pragma once

#endif // _MSC_VER >= 1000

// NumSpinCtrl.h : header file

//

 

/////////////////////////////////////////////////////////////////////////////

// CNumSpinCtrl window

#include "NumEdit.h"

 

#ifndef CLASS_EXPORT

       #defineCLASS_EXPORT

#endif

 

class CLASS_EXPORT CNumSpinCtrl : publicCSpinButtonCtrl

{

       DECLARE_DYNAMIC(CNumSpinCtrl)

// Construction

public:

       CNumSpinCtrl();

 

// Attributes

public:

 

// Operations

public:

 

// Overrides

       //ClassWizard generated virtual function overrides

       //{{AFX_VIRTUAL(CNumSpinCtrl)

       //}}AFX_VIRTUAL

 

// Implementation

public:

       virtualvoid SetDelta(float delta);

       virtualfloat GetDelta();

       virtualvoid SetBuddy(CNumEdit *edit);

       virtualCNumEdit* GetBuddy() const;

       virtualvoid GetRange(float &lower, float& upper ) const;

       virtualvoid SetRange(float nLower, float nUpper );

       virtualfloat GetPos();

       virtualvoid SetPos(float val);

       virtual~CNumSpinCtrl();

 

       //Generated message map functions

protected:

       //{{AFX_MSG(CNumSpinCtrl)

       afx_msgvoid OnDeltapos(NMHDR* pNMHDR, LRESULT* pResult);

       //}}AFX_MSG

 

       DECLARE_MESSAGE_MAP()

};

 

/////////////////////////////////////////////////////////////////////////////

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Developer Studio will insertadditional declarations immediately before the previous line.

 

#endif //!defined(AFX_NUMSPINCTRL_H__C2BD95A2_A482_11D2_A6A7_00600844997A__INCLUDED_)

 

//NumSpinCtrl.cpp

//NumSpinCtrl.cpp : implementation file

//

 

#include"stdafx.h"

#include"NumSpinCtrl.h"

 

#ifdef_DEBUG

#definenew DEBUG_NEW

#undefTHIS_FILE

staticchar THIS_FILE[] = __FILE__;

#endif

 

/////////////////////////////////////////////////////////////////////////////

//CNumSpinCtrl

 

IMPLEMENT_DYNAMIC(CNumSpinCtrl,CSpinButtonCtrl)

 

CNumSpinCtrl::CNumSpinCtrl()

{

}

 

CNumSpinCtrl::~CNumSpinCtrl()

{

}

 

 

BEGIN_MESSAGE_MAP(CNumSpinCtrl,CSpinButtonCtrl)

       //{{AFX_MSG_MAP(CNumSpinCtrl)

       ON_NOTIFY_REFLECT(UDN_DELTAPOS,OnDeltapos)

       //}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

/////////////////////////////////////////////////////////////////////////////

//CNumSpinCtrl message handlers

 

voidCNumSpinCtrl::SetPos(float val)

{

       CSpinButtonCtrl::SetPos(500);

       CNumEdit *m_Edit = GetBuddy();

       if (m_Edit)

              if(m_Edit->IsKindOf(RUNTIME_CLASS(CNumEdit)))

                     m_Edit->SetValue(val);

}

 

floatCNumSpinCtrl::GetPos()

{

       CNumEdit *m_Edit = GetBuddy();

       if (m_Edit)

              if(m_Edit->IsKindOf(RUNTIME_CLASS(CNumEdit)))

                     returnm_Edit->GetValue();

       return 0.0f;

}

 

voidCNumSpinCtrl::SetRange(float nLower, float nUpper)

{

       CSpinButtonCtrl::SetRange(0, 1000);

       CNumEdit *m_Edit = GetBuddy();

       if (m_Edit)

              if(m_Edit->IsKindOf(RUNTIME_CLASS(CNumEdit)))

                     m_Edit->SetRange(nLower,nUpper);

}

 

voidCNumSpinCtrl::GetRange(float & lower, float & upper) const

{

       CNumEdit *m_Edit = GetBuddy();

       if (m_Edit)

              if(m_Edit->IsKindOf(RUNTIME_CLASS(CNumEdit)))

                     m_Edit->GetRange(lower,upper);

}

 

CNumEdit*CNumSpinCtrl::GetBuddy() const

{

       return (CNumEdit*)CSpinButtonCtrl::GetBuddy();

}

 

voidCNumSpinCtrl::SetBuddy(CNumEdit * edit)

{

       CSpinButtonCtrl::SetBuddy(edit);

       if (edit)

              if(edit->IsKindOf(RUNTIME_CLASS(CNumEdit)))

                     edit->SetValue(0.0f);

}

 

voidCNumSpinCtrl::OnDeltapos(NMHDR* pNMHDR, LRESULT* pResult)

{

       NM_UPDOWN* pNMUpDown =(NM_UPDOWN*)pNMHDR;

       // TODO: Add your control notificationhandler code here

       if ((pNMUpDown->iPos <=pNMUpDown->iDelta) ||

              (pNMUpDown->iPos >= 1000 -pNMUpDown->iDelta)) pNMUpDown->iPos = 500;

       CNumEdit *m_Edit = GetBuddy();

       if (m_Edit)

              if(m_Edit->IsKindOf(RUNTIME_CLASS(CNumEdit)))

                     m_Edit->ChangeAmount(pNMUpDown->iDelta);

       *pResult = 0;

}

 

floatCNumSpinCtrl::GetDelta()

{

       CNumEdit *m_Edit = GetBuddy();

       if (m_Edit)

              if(m_Edit->IsKindOf(RUNTIME_CLASS(CNumEdit)))

                     returnm_Edit->GetDelta();

       return 0.0f;

}

 

voidCNumSpinCtrl::SetDelta(float delta)

{

       CNumEdit *m_Edit = GetBuddy();

       if (m_Edit)

              if(m_Edit->IsKindOf(RUNTIME_CLASS(CNumEdit)))

                     m_Edit->SetDelta(delta);

}


原创粉丝点击