【转】VC2008在工具栏Toolbar里添加XP风格spin box control控件

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风格,比较难看。

VC2008在Toolbar里添加XP风格spin box control控件 - freetrain_sk - sk

可根据需要改为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.....就可以了。

VC2008在Toolbar里添加XP风格spin box control控件 - freetrain_sk - sk

此时的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

}

最后再次编译,运行。应该是正常工作了。

VC2008在Toolbar里添加XP风格spin box control控件 - freetrain_sk - sk

最后要说明的是,这里是利用了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/

posted @ 2010-02-25 17:08  西风残照  阅读(1330)  评论(0编辑  收藏  举报