上一讲我们与大家还是比较详细地介绍了编辑控件,其实我们也可以将编辑控件绑定一个整型变量,或者做一些其他的设置,而有一些控件就自然成了一种编辑控件的周边控件。什么意思呢?
例如旋钮控件,滚动条控件,等等,主要负责一些输入,而还有一些控件,如进度条控件等,主要负责一些输出。
甚至旋钮控件本身根本不需要去编程,只要在编辑框画出来之后,再画一个旋钮控件,然后设置一些属性就可以自动使用了,很是方便:
大家看图,设置两个参数,我们连编程都没有必要,就可以直接使用了,这让牛刀想起了 VB ,呵呵,我们 VC 中一样可以做得非常出色,当然,为了实现一些特殊的目的,我们也可以对其进行编程,当然,我们先定义一个指针指向这个控件,然后去设置就行了:
例如,我们可以在 OnInitDialog 中去设定一些参数,例如我们要设置1到12 十二个月,那么我们就可以这样设置:
- CSpinButtonCtrl *pSpin=(CSpinButtonCtrl*)GetDlgItem(IDC_SPIN1);
- pSpin->SetRange(1,12);
当然,有时候我们也会需要使用一些小数,例如我们需要其值从 0.0 到 20.0 每次变动 0.2 个数据,那么我们也可以这样设置:
- CSpinButtonCtrl *pSpin=(CSpinButtonCtrl*)GetDlgItem(IDC_SPIN1);
- pSpin->SetRange(0,100);
然后,我们响应 WM_VSCROLL 消息,输入以下的代码:
- void CDlgTestDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
- {
- if(nSBCode==SB_ENDSCROLL)
- {
- return;
- }
- if(pScrollBar->GetDlgCtrlID()==IDC_SPIN1)
- {
- CString strValue;
- strValue.Format("%3.1f",(double)nPos/5.0);
- ((CSpinButtonCtrl*)pScrollBar)->GetBuddy()->SetWindowText(strValue);
- }
- CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
- }
我们就可以运行试试效果了:
当然,我们看看上面的程序,显然我们按这些旋钮时,会出现这种调用,前面一个是看我们有没有调到头,调到头了就不调了,而后面是测试看是不是旋钮,如果是旋钮(对了,有些书上也会称之为“微调按钮”,一样的,呵呵,反之,牛刀没看到其在哪儿旋转了,呵呵)。
里面的程序就显然很简单的了,定义一个字符串,给这个微调按钮的伙伴贴上,呵呵。
滚动条也一样:
- CScrollBar *pSBar=(CScrollBar*)GetDlgItem(IDC_SCROLLBAR1);
- pSBar->SetScrollRange(1,12);
上面的代码应该放在哪里大家还有数吧?好下面我们就响应滚动消息:
- void CDlgTestDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
- {
- int i=pScrollBar->GetScrollPos();
- CEdit *pEdit=(CEdit*)GetDlgItem(IDC_EDIT2);
- switch(nSBCode)
- {
- case SB_THUMBPOSITION:
- pScrollBar->SetScrollPos(i);
- break;
- case SB_LINEDOWN:
- pScrollBar->SetScrollPos(++i);
- break;
- case SB_LINEUP:
- pScrollBar->SetScrollPos(--i);
- }
- CString str;
- str.Format("你输入的是%d月",i);
- pEdit->SetWindowText(str);
- CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
- }
这个消息应该同样好理解吧,我们建立的是竖直滚动条,如果我们建立横向滚动条则需要响应 WM_HSCROLL 消息,不做编起程序来是一样的:
当然,上面我们没有响应所有的消息,消息有如下几种:
- SB_BOTTOM
- SB_ENDSCROLL
- SB_LINEDOWN
- SB_LINEUP
- SB_PAGEDOWN
- SB_PAGEUP
- SB_THUMBPOSITION
- SB_THUMBTRACKSB_TOP
大家看了应该能明白是什么意思吧?呵呵。
下面我们对上面的程序解释一下:
上面的程序,我们对控件,都使用了 定义一个对象指针的办法,直接去指向控件,然后操作,这种办法十分有效、安全,并且使用起来特别地舒服,效果和我们在“建立类向导”中定义差不多,但由于我们是直接指向控件的指针,所以我们不需要用 UpdateDate 去与类交换数据了。
还有一类控件,称之为单选按钮与复选按钮,单选按钮有点像我们老式录音机的按钮,按下一个,其他的就弹起了,我们可以弄几个试试:
大家看,点点看,当然,我们可以将这些按钮用一个组框给框起来,复选按钮也一样,看效果:
属性的第二个选项卡上有 Push-like 选起来,就好像按钮一样,效果很好:
我们甚至可以为其插入一个图标或者位图,大家玩过一些软件吗?上面一个小锁,一点就开了,一点又锁上了,特别地好玩,你通过自己的努力,当然也可以去实现一个,当然喽,牛刀在这里不和大家玩这种花活了,呵呵,那种就不是技术问题了。咱们这儿与大家讲的是编程的技术,呵呵。
当然,属性面板的第一个选项卡上有一个组标志 Group 咱们使用单选按钮一定要使用这个标志的,当然是第一个单选按钮使用这一个标志,然后就可以在“建立类向导”的第二个选项卡中看到这一个 ID 号了,(不选组看不到这个ID号嘀)。
当然喽,我们去定义一个 ID 号,
int m_rec;
请注意,使用“建立类向导”去定义啊,除非你对整个 MFC 的来龙去脉都熟悉了,你可以直接在你的头文件或 CPP 文件中直接加代码,没有熟悉到那种程序,还建议大家按规矩来。
好了,我们响应四个单选钮与组选钮的BN_CLICKED 消息:
- void CDlgTestDlg::OnRadio1()
- {
- CString str;
- UpdateData();
- str.Format("你选择的第%d个按钮",m_rec+1);
- GetDlgItem(IDC_EDIT3)->SetWindowText(str);
- }
- void CDlgTestDlg::OnRadio2()
- {
- CString str;
- UpdateData();
- str.Format("你选择的第%d个按钮",m_rec+1);
- GetDlgItem(IDC_EDIT3)->SetWindowText(str);
- }
- void CDlgTestDlg::OnRadio3()
- {
- CString str;
- UpdateData();
- str.Format("你选择的第%d个按钮",m_rec+1);
- GetDlgItem(IDC_EDIT3)->SetWindowText(str);
- }
- void CDlgTestDlg::OnRadio4()
- {
- CString str;
- UpdateData();
- str.Format("你选择的第%d个按钮",m_rec+1);
- GetDlgItem(IDC_EDIT3)->SetWindowText(str);
- }
- void CDlgTestDlg::OnCheck1()
- {
- CString str;
- GetDlgItem(IDC_EDIT4)->GetWindowText(str);
- str+="牛";
- GetDlgItem(IDC_EDIT4)->SetWindowText(str);
- }
- void CDlgTestDlg::OnCheck2()
- {
- CString str;
- GetDlgItem(IDC_EDIT4)->GetWindowText(str);
- str+="刀";
- GetDlgItem(IDC_EDIT4)->SetWindowText(str);
- }
- void CDlgTestDlg::OnCheck3()
- {
- CString str;
- GetDlgItem(IDC_EDIT4)->GetWindowText(str);
- str+="小";
- GetDlgItem(IDC_EDIT4)->SetWindowText(str);
- }
- void CDlgTestDlg::OnCheck4()
- {
- CString str;
- GetDlgItem(IDC_EDIT4)->GetWindowText(str);
- str+="试";
- GetDlgItem(IDC_EDIT4)->SetWindowText(str);
- }
好了,我们看看效果:
上面的复选框其实牛刀没有对其数据导出,真正使用时,也应该在“建立类向导”中,将数据导出,然后作出判断,从而使得我们的程序真正地做到名符其实,呵呵。
进度条,其实这个控件有点暧昧,应该属于输出型的控件,但我们一般不认为其是输出型的控件,而一般的用途是视觉安慰。
当然我们运行一个软件时,软件由于设置的不完善,运行过程比较慢,怎么办?用一个进度条放在上面,告诉你到哪儿了,你可能会看着高兴,哇,要结束了,要结束了,你还不要说,离开这东东还就真的不行。特别是一些大型的软件,如果运行速度真的很慢,如果没能进度条,你很可能就认为电脑已经“死机了”,恨不得把电脑砸了,但现实就是有了进度条,你的眼前就一片光明。
所以牛刀没有将这个控件与电脑的输出扯上一些关系,好了,不多说了,在窗体上建立一个吧,下面我们就来做程序:
- CProgressCtrl * pProg=(CProgressCtrl*)GetDlgItem(IDC_PROGRESS1);
- pProg->SetRange(0,100);
- pProg->SetPos(20);
大家看效果:
当然,大家可以到属性的第二个选项卡将“平滑”选上,我们的选项卡上就会显得“平滑”了,呵呵显然的嘛。
一个进度条,如果不动,那么什么感觉也没有咱们下面想将其整动起来,咋整呢?
计时器呗,显然的哟,好,咱们来启动计时器:(当然首先得创建是也不是?)
- int CDlgTestDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- if (CDialog::OnCreate(lpCreateStruct) == -1)
- return -1;
- SetTimer(0,100,NULL);
- return 0;
- }
- void CDlgTestDlg::OnTimer(UINT nIDEvent)
- {
- CProgressCtrl * pProg=(CProgressCtrl*)GetDlgItem(IDC_PROGRESS1);
- int i=pProg->GetPos();
- i=(i+1)%100;
- pProg->SetPos(i);
- CDialog::OnTimer(nIDEvent);
- }
当然,这个贴图贴不出效果来,大家在机上试试就知道怎么个好玩了,呵呵。
有一点遗憾的就是,我们的进度条如果能够在中央显示百分比那该多好啊!!!
怎么办?大家想出办法来了吗?
对,父子插足,咱们来做一个:
CMyProg m_prog;
制作过程咱们不说喽,省空间,呵呵:
- void CMyProg::OnPaint()
- {
- CPaintDC dc(this);
- int nPos=GetPos();
- CRect rect,recttest;
- GetClientRect(&rect);
- CString str;
- str.Format("%d%%",nPos);
- CPoint pt=rect.CenterPoint();
- CBrush brush;
- brush.CreateSolidBrush(RGB(255,0,0));
- CBrush *pOldBrush=dc.SelectObject(&brush);
- recttest=rect;
- recttest.right=rect.right*nPos/100;
- dc.Rectangle(recttest);
- recttest=rect;
- recttest.left=rect.right*nPos/100;
- brush.DeleteObject();
- brush.CreateSolidBrush(RGB(0,255,0));
- dc.SelectObject(&brush);
- dc.Rectangle(&recttest);
- dc.SetBkMode(TRANSPARENT);
- dc.TextOut(pt.x,0,str);
- DeleteObject(brush);
- dc.SelectObject(pOldBrush);
- }
感觉怎么样?咱们给这进度条的 WM_PAINT 给改了,下面是效果,当然是不能给你显示动态的喽,当然,你自己可以做出软件来看看效果:
从效果,从感觉上来看,都还不错,你说呢?
其实牛刀在做上面的程序之前,牛刀也试过其他的办法,当然牛刀这个办法是最省事的,就是用两个不同的刷子画两个矩形,然后在中央(其实不是正中央啊,呵呵)贴上汉字,就一切 OK 了嘛。
当然,是不是突然有一种冲动,将这个进度条的显示给改了,弄一幅位图放上面该是什么情况啊,呵呵。真是个美妙的想法,这个想法牛刀就不去做了,大家自己去实现一下,看看你的能力有多高,你会被你自己的编程水平吓一跳的。
显然滚动条我们也可以用贴图的办法去贴上一幅图,将其效果也改了,那个微调按钮嘛……改,那个单选框、复选框嘛——改。
反正这种“父子插足”的技术,可以这样说,是“通吃一切”的技术。
当我们回顾这种技术时,我们不经要惊叹微软那些家伙的聪明,还有好多的计算机前辈们,给我们的编程制造了多么美妙的空间,可以任我们的思路自由地发挥,我们愿意怎么干,我们就怎么干,我们的一切,都掌控在我们自己的手中。
当然喽,周边控件还有“滑杆控件”,我们不讲了,我们现在的水平其实已经可以自己去任造一款控件了,使用这种控件还不是小菜一喋?
当然还有什么日期控件啊,热点控件啊,IP地址控件啊,这些控件,大家随便拖进对话框,然后用和以前一样的技术,我们只要将这些控件的指针指过去,然后一打“->”,立马后面会有一个列表,我们要的函数全在这里,然后看看名称,一般什么意思可以猜出来,如果还不明白的话……
大家千万要记住,按“F1”,你不要告诉牛刀你的电脑上没有 MSDN ,呵呵,那可惨了。那么就上网找找吧,如果不怕病毒的话,用搜索引擎,或者建议大家干脆就在网页的首页多链几个编程的网站,我们有空就点过去好了,呵呵。
还是那句话,牛刀是不会与你详细地讲控件的每一个细节,但牛刀会告诉你怎么做,我们“实践”的目的就在于此。
当然,这也应该是牛刀这套教材的一大特色吧,呵呵,希望对大家有所帮助,以后看到的东西,都是我们熟悉的东西,那么,牛刀这套教材的目的也就达到了。