在.net里C#与vb里已经提供了NumericUpDown这个控件,
但在vc里却就另人失望了。
大多数时候就是用一个Edit控件与Spin控件组合而成,
把spin的属性Auto Buddy设置为true,两个控件的Group属性设置为true
按Tab顺序给这两个控件赋上,
这样spin就自动归依到edit的怀抱里去了。
如此设定后,控件表现出来的功能与NumericUpDown还相差甚远,
要达到点击箭头实现数值自动增减,还需要在窗体上添加个监听它的滚动事件,如下:
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
(当然初始化时,要把edit框的值与spin的pos保持一致)
具体实现示例如下:
void CMyPage::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar * pScrollBar)
{
CSpinButtonCtrl *pSpn = (CSpinButtonCtrl *) pScrollBar;
// update the edit = nPos
......
CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
}
现在能通过击箭头实现数值自动增减了,但Edit框可以输入一个数字,然后点击箭头,
你会发现它是基于没有输入前的数值的,要达到输入后的点击正常,你可能会想到
用edit的lostfocus事件里修改spin的pos值,这在正常情况下也是可行的,
但如果这样来操作:输入后直接点箭头,由于edit框的事件没有被触发,spin的pos值还是原来的值。
这个时候spin的UDN_DELTAPOS事件就用上派场了
void CMyPage::OnDeltaposSpn(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
CString str;
int t,tmp;
this->GetDlgItemText(IDC_EDT_ID, str);
t = atoi(str.GetBuffer(str.GetLength()));
tmp = (int)pNMUpDown->iPos;
tmp = t-tmp;
((CSpinButtonCtrl *)this->FromHandle(pNMUpDown->hdr.hwndFrom))->SetPos(pNMUpDown->iPos+tmp);
*pResult = 0;
}
当然这其中可以穿插数据校验等操作,不在螯述,以此方法供交流。