Spin box control本是用于对话框中的控件。但有时需要将它放到工具栏上。VC++ 2008里实现如下:
一、在工具栏上新增一个工具按钮项,资源命名为ID_TOOL_EDIT_TIME。再增加一个工具项,资源命名为ID_TOOL_INTEGRA_TIME。
二、在工程里增加一个新MFC Class,base class选CToolBar,新类命名为CMainToolBar。
三、在MainToolBar.h中声明两个对象:
CSpinButtonCtrl m_wndIntegrationTime;
CEdit m_wndEditTime;
四、在MainFrm.h中加上 #include "MainToolBar.h",然后找到CToolBar m_wndToolBar; 改为CMainToolBar m_wndToolBar;
五、在MainFrm.cpp中,CMainFrame::OnCreate函数里,后面(return TRUE 语句前)前添加:
int index = 0;
RECT rect;
//添加Edit控件
while(m_wndToolBar.GetItemID(index)!=ID_TOOL_EDIT_TIME)
index++;
m_wndToolBar.SetButtonInfo(index, ID_TOOL_EDIT_TIME, TBBS_SEPARATOR, 80);
m_wndToolBar.GetItemRect(index, &rect);
//设置位置,几个数字是调出来的,可以根据自己的情况改变
rect.left+=6;
rect.right+=10;
rect.top+=2;
rect.bottom -= 3;
if(!m_wndToolBar.m_wndEditTime.Create(ES_CENTER | ES_NUMBER |ES_LOWERCASE, rect, &m_wndToolBar, ID_TOOL_EDIT_TIME)) //创建Edit控件
{
TRACE0("Failed to create spin-box\n");
return FALSE;
}
m_wndToolBar.m_wndEditTime.ShowWindow(SW_SHOW);
//添加Spin box control控件
// 创建并显示控件
if(!m_wndToolBar.m_wndIntegrationTime.Create(UDS_ALIGNRIGHT| UDS_NOTHOUSANDS |UDS_ARROWKEYS |UDS_SETBUDDYINT , rect, &m_wndToolBar, ID_TOOL_INTEGRA_TIME))
{
TRACE0("Failed to create spin-box\n");
return FALSE;
}
m_wndToolBar.m_wndIntegrationTime.SetBuddy(m_wndToolBar.GetDlgItem(ID_TOOL_EDIT_TIME)); //set the Edit box to be the buddy window
m_wndToolBar.m_wndIntegrationTime.SetRange32(1,100000); //set the Edit time limits
UDACCEL v_accel={0,100}; //set the increasing step
m_wndToolBar.m_wndIntegrationTime.SetAccel(1,&v_accel); //set spin control interval/step to be 100
m_wndToolBar.m_wndIntegrationTime.ShowWindow(SW_SHOW);
六、编译,运行,此时工具栏上出现如下所示的Spin box和Edit Box。
上面语句中的UDACCEL v_accel={0,100};是指定加速键,即按下向上或向下的按钮后,每次增量步长为100,按下键0秒后开始加速。
m_wndToolBar.m_wndIntegrationTime.SetAccel(1,&v_accel);这句使加速设置有效。
注意到,此时的spin box控件是如下所示的2000风格,比较难看。
可根据需要改为XP风格。VS 2005和2008中,如果Project->Property -- General -- Character Set 为Use Unicode Character Set,那么程序的界面自然就是XP风格,不需要手动添加任何东西。但是如果这里是Use Multi-Byte Character Set,那么就要自己动手加东西了。
1、建一个名为XPStyle.manifest的文件
2、把下面的内容拷到这个文件中
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="X86"
type="win32"
/>
<description>Your app description here</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>
3、Project->Add Existing Item...将XPStyle.manifest添加到工程中。
4、Project->***properties-> configuration properties ->Manifest tool->Input and Output->Embed Manifest选no
5、Rebuild.....就可以了。
此时的spin box和edit box其实什么都做不了,因为没有添加消息相应函数。很不幸,ClassWizard上看不到这些消息。所以我们只能写代码添加。由于spin box此时已与edit box是关联控件(buddy window),已实现联动,即spin box值的改变将自动引起edit box相应变化。所以,只需要添加edit box变化时的消息相应函数即可。
首先,在MainFrm.h里声明消息相应函数
protected:
afx_msg void OnEditIntegrationTimeChange();
再在MainFrm.cpp里的消息映射中添加语句
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_EN_CHANGE(ID_TOOL_EDIT_TIME, &CMainFrame::OnEditIntegrationTimeChange)
END_MESSAGE_MAP()
然后在MainFrm.cpp里加入消息函数的定义
void CMainFrame::OnEditIntegrationTimeChange()
{
//add your own code here
}
最后再次编译,运行。应该是正常工作了。
最后要说明的是,这里是利用了set buddy window功能,利用设置关联窗口实现编辑控件的自动更新变化。也可以稍作修改,不设置关联。添加spin box的消息处理函数,手动添加改变edit box的代码。最简单的spin box消息是UDN_DELTAPOS消息,对应函数映射方式为:
ON_NOTIFY(UDN_DELTAPOS , ID_TOOL_INTEGRA_TIME, &CMainFrame::OnSpinBoxChange)
但是这个消息有个缺点,就是它是在点击spin box上下箭头后,更新spin box value前发出消息的。所以,消息处理函数中得到的值仍是变化前的spin box position值。这样就会导致每次都滞后一个变化。还有一个消息是WM_VSCROLL,但是Windows消息的处理过程就稍复杂了,需要switch(uMsg)判断。所以,推荐最好还是尽量使用上面提到的关联来实现edit box的变化。
有问题请致skpsun@163.com
Reference web pages:
如何在工具栏上添加平面下拉控件:http://www.moon-soft.com/doc/10127.htm
VC中Spin控件的使用:http://www.cnblogs.com/adamite/archive/2008/12/23/1360711.html
使程序具有XP风格:http://www.cppblog.com/zgysx/archive/2006/10/31/14413.aspx
Manifest问题:http://blog.macd.cn/391424/viewspace-3445
Spin Control用法: http://woshiyouyouchen.blog.163.com/blog/static/1039989420090161029903/
Spin Control使用心得: http://www.cppblog.com/gohan/archive/2008/02/06/42558.aspx
Customizing Toolbars: http://www.codeguru.com/cpp/controls/toolbar/