Visual C++程序开发范例宝典(软件工程师典藏版)
上QQ阅读APP看书,第一时间看更新

2.2 编辑框控件典型实例

编辑框控件主要用来显示、获取、编辑和修改文本信息,是程序与用户交流的一个主要控件。在程序运行中,具有良好的交互性。本节主要介绍应用编辑框控件的典型实例。

实例044 为编辑框设带为编辑框设置新的系统菜单

这是一个可以提高基础技能的实例

实例位置:光盘\mingrisoft\02\044

实例说明

默认情况下编辑框控件的菜单是针对文本的菜单命令:剪切、复制和粘贴等,本实例实现将编辑框控件的菜单改为用户自定义菜单,程序运行结果如图2.5所示。

图2.5 为编辑框设置新的系统菜单

技术要点

本实例实现覆写PreTranslateMessage函数,实现在Text Box控件窗体上对WM_RBUTTONUP消息的处理,当程序产生WM_RBUTTONUP消息时调用TrackPopupMenu函数来显示右键菜单,它的语法如下:

BOOL TrackPopupMenu( UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT lpRect = NULL );

参数说明:

● nFlags:鼠标按钮标识和屏幕位置标识,取值如下。

■ TPM_CENTERALIGN:根据x坐标水平居中。

■ TPM_LEFTALIGN:根据x坐标左对齐。

■ TPM_RIGHTALIGN:根据x坐标右对齐。

■ TPM_LEFTBUTTON:左键菜单。

■ TPM_RIGHTBUTTON:右键菜单。

● x:菜单左顶点x轴坐标。

● y:菜单左顶点y轴坐标。

● pWnd:菜单显示的窗体指针。

● lpRect:窗体矩形指针。

实现过程

(1)新建一个基于对话框的应用程序。

(2)在对话框上添加一个静态文本控件,设置Caption属性为“通过右键菜单可以对编辑框中字符进行特殊操作”;添加一个编辑框控件,设置ID属性为IDC_EDTEXT。

(3)在工程中添加Menu资源,设置ID属性为IDR_TEXTMENU。

(4)在TextNewMenuDlg.h文件中加入变量声明:

CMenu menu;

(5)在OnInitDialog中装载菜单,代码如下:

        BOOL CTextNewMenuDlg::OnInitDialog()
        {
        CDialog::OnInitDialog();
        …//此处代码省略
        menu.LoadMenu(IDR_TEXTMENU);                     //加载菜单资源
        return TRUE;
        }

(6)通过PreTranslateMessage对鼠标右键进行处理,代码如下:

        BOOL CTextNewMenuDlg::PreTranslateMessage(MSG* pMsg)
        {
        if(pMsg->message==WM_RBUTTONUP && pMsg->hwnd== m_mytext.m_hWnd)//在编辑框中释放鼠标右键
        {
            CMenu*pPopup=menu.GetSubMenu(0);                      //获得子菜单
            CRect rc;
            CPoint point=pMsg->pt;
            rc.top=point.x;
            rc.left=point.y;
            pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_VERTICAL,rc.top
                      ,rc.left,this,&rc);                         //显示弹出菜单
            }
            return CDialog::PreTranslateMessage(pMsg);
        }

(7)右键菜单项的单击事件处理函数代码如下:

        void CTextNewMenuDlg::OnView1()
        {
            AfxMessageBox("获取字符");
        }
        void CTextNewMenuDlg::OnView2()
        {
            AfxMessageBox("去除空字符");
        }
        void CTextNewMenuDlg::OnView3()
        {
            AfxMessageBox("去除非英文字符");
        }
        void CTextNewMenuDlg::OnView4()
        {
            AfxMessageBox("去除非数字字符");
        }

举一反三

根据本实例,读者可以:

实现列表控件的右键菜单。

实例045为编辑框控件添加列表选择框

本实例可以方便操作、提高效率

实例位置:光盘\mingrisoft\02\045

实例说明

编辑框控件需要用户输入文本,反复输入相同的内容是很麻烦的。本实例实现在用户输入文本时,程序自动在数据库中查询,如果查到有类似的信息后,则以列表形式显示在编辑框控件下,用户可以根据需要选择列表中的内容。程序运行结果如图2.6所示。

图2.6 为编辑框控件添加列表选择框

技术要点

本实例的实现需要覆写PreTranslateMessage函数以及对编辑框控件的EN_CHANGE消息进行处理。EN_CHANGE消息在编辑框控件中的文本内容发生变化时产生,用户每输入一个字符文本内容都会产生EN_CHANGE消息,处理EN_CHANGE消息主要是在数据库中查找编辑框控件中的文本内容。覆写PreTranslateMessage函数主要是在出现列表控件以后,处理用户按上下方向键及鼠标单击列表控件时产生的消息。

实现过程

(1)新建一个基于对话框的应用程序。

(2)在对话框上添加一个编辑框控件,设置ID属性为IDC_EDOBJ,添加成员变量m_edobj;添加一个列表视图控件,设置ID属性为IDC_TIPLIST,添加成员变量m_tiplist。

(3)为编辑框控件添加EN_CHANGE消息处理函数OnChangeEdobj;为列表视图控件添加NM_DBLCLK消息处理函数OnDblclkTiplist。

(4)在TextboxListDlg.h文件中添加变量声明:

        CString xm,xb,csrq,gzdw,yddh,gddh ;
        bool IsShowing;

(5)通过PreTranslateMessage对键盘按键进行处理,代码如下:

        BOOL CTextboxListDlg::PreTranslateMessage(MSG* pMsg)
        {
            if(pMsg->message==WM_KEYDOWN && pMsg->wParam==VK_ESCAPE)//按下<ESC>键
            {
                m_tiplist.ShowWindow(SW_HIDE);                             //不显示提示列表
                IsShowing=false;
                pMsg->wParam=VK_CONTROL;
            }
            if(pMsg->message==WM_LBUTTONDOWN)                              //按下鼠标左键
            {
                if(pMsg->hwnd!=m_tiplist.m_hWnd)                           //当前窗口不是列表视图控件
                {
                    m_tiplist.ShowWindow(SW_HIDE);                         //隐藏提示列表
                    IsShowing=false;
                }
            }
            if(pMsg->message==WM_KEYDOWN&&pMsg->wParam==13)                //按下回车键
            {
                if(IsShowing)
                    m_edobj.SetWindowText(xm);                             //设置编辑框显示数据
                m_tiplist.ShowWindow(SW_HIDE);                             //隐藏提示列表
                IsShowing=false;
                i=0;
                pMsg->wParam=VK_CONTROL;
            }
            if(pMsg->hwnd==m_tiplist.m_hWnd&& pMsg->message==WM_LBUTTONDBLCLK) //在提示列表中双击鼠标左键
            {
                m_edobj.SetWindowText(xm);                                 //设置编辑框显示数据
                m_tiplist.ShowWindow(SW_HIDE);                             //隐藏提示列表
                IsShowing=false;
            }
            if(pMsg->message==WM_KEYDOWN&&pMsg->wParam==VK_DOWN) //按下下箭头
            {
                if(IsShowing)                                              //列表以显示
                {
                    if(i==m_tiplist.GetItemCount())                        //获得列表记录数
                    i=0;
                    m_tiplist.SetHotItem(i);
                    xm=m_tiplist.GetItemText(i,0);                         //获得列表项数据
                    i+=1;
                }
            }
            return CDialog::PreTranslateMessage(pMsg);
        }

(6)自定义函数AutoPostion,实现提示窗体位置的调整,代码如下:

        void CTextboxListDlg::AutoPostion()
        {
          this->m_tiplist.MoveWindow(15,36,210,100);
        }

(7)编辑框IDC_EDOBJ的EN_CHANGE消息的实现函数的代码如下:

        void CTextboxListDlg::OnChangeEdobj()
        {
            CString edit;
            m_edobj.GetWindowText(edit);                                  //获得编辑框中数据
            if(!edit.IsEmpty())                                           //如果数据不为空
            {
                this->AutoPostion();                                      //设计提示列表位置
                m_tiplist.DeleteAllItems();                               //删除提示列表中数据
                this->SetDataBase(edit);                                  //在数据库中查找编辑框中数据
                if(m_tiplist.GetItemCount()>0)                            //如果列表项数量大于0
                {
                    m_tiplist.ShowWindow(SW_SHOW);                        //显示提示列表
                    IsShowing=true;
                }
            }
            else                                                          //否则
            {
                m_tiplist.ShowWindow(SW_HIDE);                            //隐藏提示列表
                IsShowing=false;
            }
        }

(8)控件IDC_TIPLIST的NM_DBLCLK消息的函数的代码如下:

        void CTextboxListDlg::OnDblclkTiplist(NMHDR* pNMHDR, LRESULT* pResult)
        {
            int i=m_tiplist.GetHotItem();
            CString text;
            xm=m_tiplist.GetItemText(i,1);                                   //获得列表项数据
            *pResult = 0;
        }

举一反三

根据本实例,读者可以:

实现多个编辑框控件的列表提示。

实例046 多彩边框的编辑框

本实例是一个提高效率、人性化的程序

实例位置:光盘\mingrisoft\02\046

实例说明

本实例改变了传统的编辑框风格。运行程序,五颜六色的编辑框将显示在窗体中,如图2.7所示。

图2.7 多彩边框的编辑框

技术要点

以CEdit类为基类派生CcolourEdit类,然后设置WM_CTLCOLOR消息,使用FrameRect函数重绘编辑框的边框。

FrameRect函数:在矩形周围绘制边框。函数原型如下:

void FrameRect( LPCRECT lpRect, CBrush* pBrush );

参数说明:

● lpRect:对要描绘的边框进行描述的一个矩形。这等效于将画笔设置成一个单位的宽度,然后用矩形函数画出一个矩形。

● pBrush:欲使用的刷子的句柄。

实现过程

(1)新建一个基于对话框的应用程序。

(2)向窗体中添加8个编辑框控件。

(3)通过New Class窗口生成一个新类CcolourEdit,基类为CEdit。添加一个COLORREF类型的成员变量m_Colour。

(4)主要程序代码如下:

            HBRUSH CColourEdit::CtlColor(CDC*pDC,UINT nCtlColor)
            {
            CDC*dc=GetDC();                              //获取画布对象
            CRect rect;
            GetClientRect(rect);                         //获取客户区域
            rect.InflateRect(1,1,1,1);                   //将客户区域增大一个像素
            CBrush brush(m_Colour);                       //创建画刷
            dc->FrameRect(rect,&brush);                  //绘制边框
            return NULL;
            }

举一反三

根据本实例,读者可以:

设置文本框的边框颜色。

实例047 改变编辑框文本颜色

本实例是一个提高基础技能的程序

实例位置:光盘\mingrisoft\02\047

实例说明

在实际的应用程序中,除了改变编辑框的背景和边框颜色外,还可以改变编辑框中字体的颜色。运行程序,在编辑框中输入文本,在单选按钮组中选择文本的颜色,运行结果如图2.8所示。

图2.8 改变编辑框文本颜色

技术要点

可以使用SetTextColor函数改变编辑框中文本的颜色,通过对消息WM_CTLCOLOR的响应函数来实现对SetTextColor函数的调用。在控件被显示之前,WM_CTLCOLOR消息被发送到控件所在的对话框,这个消息的响应函数会修改对话框及其中控件的颜色。该消息的响应函数原型如下:

afx_msg HBRUSH OnCtlColor( CDC* pDC, CWnd* pWnd, UINT nCtlColor );

参数说明:

● pDC:指向绘图设备的指针。

● pWnd:指向具体控件的指针。

● nCtlColor:控件的类型,其值如表2.1所示。

表2.1 nCtlColor参数可选值表

SetTextColor函数的原型如下:

virtual COLORREF SetTextColor( COLORREF crColor );

参数说明:

● crColor:要设置的字体颜色。

实现过程

(1)新建一个基于对话框的应用程序。

(2)在窗体上添加1个编辑框控件和8个单选按钮控件。

(3)主要程序代码如下:

        HBRUSH CColourTextDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
        {
          HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
          if(nCtlColor==CTLCOLOR_EDIT)              //是编辑框
            pDC->SetTextColor(colour);              //设置文本颜色
          return hbr;
}

举一反三

根据本实例,读者可以:

设置其他控件的字体颜色;

设置控件的背景颜色。

实例048 不同文本颜色的编辑框

本实例是一个提高效率、人性化的程序

实例位置:光盘\mingrisoft\02\048

实例说明

编辑框的文本颜色常用的是黑色,白色的背景衬托黑色的字体,本实例改变了传统的编辑框风格。运行程序,在编辑框中显示的文字将具有不同的文本颜色,如图2.9所示。

图2.9 不同文本颜色的编辑框

技术要点

在设置文本颜色时需要使用CreateStockObject函数,该函数获取预定义的Windows GDI的画笔、画刷和字体句柄,并将GDI对象与CGdiObject类对象相关联。语法如下:

BOOL CreateStockObject( int nIndex );

参数说明:

● nIndex:定义标准对象类型的常量,可选值如下。

■ BLACK_BRUSH:黑色刷子。

■ DKGRAY_BRUSH:黑灰色刷子。

■ GRAY_BRUSH:灰色刷子。

■ HOLLOW_BRUSH:凹刷子。

■ LTGRAY_BRUSH:浅灰色刷子。

■ NULL_BRUSH:空刷子。

■ WHITE_BRUSH:白色刷子。

■ BLACK_PEN:黑色画笔。

■ WHITE_PEN:白色画笔。

■ ANSI_FIXED_FONT:采用Windows(ANSI)字符集的等宽字体。

■ ANSI_VAR_FONT:采用Windows(ANSI)字符集的不等宽字体。

■ DEVICE_DEFAULT_FONT:设备使用的默认字体(NT)。

■ DEFAULT_GUI_FONT:用户界面的默认字体,包括菜单和对话框字体。

■ OEM_FIXED_FONT:OEM字符集的固有字体。

■ SYSTEM_FONT:屏幕系统字体。这是用于菜单、对话框等的默认不等宽字体。

■ SYSTEM_FIXED_FONT:屏幕系统字体。这是用于菜单、对话框等的默认等宽字体。

■ DEFAULT_PALETTE:默认调色板。

实现过程

(1)新建一个基于对话框的应用程序。

(2)创建一个以CEdit类为基类的派生类CColorEdit。

(3)在CColorEdit类的头文件中声明一个COLORREF类型变量m_Color。

(4)向对话框中添加6个编辑框控件,通过类向导为控件关联CColorEdit类成员变量。

(5)手动添加一个SetColor函数,用来设置文本颜色的变量赋值,代码如下:

        void CColorEdit::SetColor(COLORREF color)                     //SetColor函数
        {
            m_Color=color;                                          //为变量m_Color赋值
        }

(6)处理CColorEdit类的WM_CTLCOLOR消息,在该消息的处理函数中设置文本颜色,代码如下:

        HBRUSH CColorEdit::CtlColor(CDC*pDC,UINT nCtlColor)          //WM_CTLCOLOR消息处理函数
        {
            CBrush m_Brush;                                         //声明画刷对象
            m_Brush.CreateStockObject(WHITE_BRUSH);                //创建画刷
            pDC->SetTextColor(m_Color);                            //设置文本颜色
            return m_Brush;                                         //返回画刷
        }

(7)在对话框的OnInitDialog函数中为编辑框控件设置文本显示颜色,代码如下:

            m_Edit1.SetColor(RGB(255,0,0));
            m_Edit2.SetColor(RGB(0,0,255));
            m_Edit3.SetColor(RGB(255,0,255));
            m_Edit4.SetColor(RGB(0,255,0));

举一反三

根据本实例,读者可以:

设置编辑框控件显示不同字体。

实例049 位图背景编辑框

本实例是一个提高基础技能的程序

实例位置:光盘\mingrisoft\02\049

实例说明

图2.10 位图背景编辑框

在实际的应用程序中,白色背景的编辑框让人看起来觉得乏味,为了更好地美化程序,从而吸引用户,可以设置位图背景编辑框。运行程序,在编辑框中输入文本,运行结果如图2.10所示。

技术要点

首先使用SetBkMode函数设置编辑框中文本背景透明,然后在WM_ERASEBKGND消息的响应函数中来实现对编辑框背景的绘制。SetBkMode函数的语法如下:

int SetBkMode( int nBkMode );

参数说明:

● nBkMode:指向绘图设备的指针。

■ OPAQUE:默认背景模式。

■ TRANSPARENT:背景在绘图之前不改变。

实现过程

(1)新建一个基于对话框的应用程序。

(2)创建一个以CEdit类为基类的派生类CBmpEdit。

(3)选择工作区窗口的RecourceView选项卡,向对话框中导入一个位图资源。

(4)在CBmpEdit类的头文件中声明一个CBitmap类对象m_Bitmap。

(5)在CBmpEdit类的构造函数中加载位图资源,代码如下:

            m_Bitmap.LoadBitmap(IDB_BITMAP1);           //加载位图资源

(6)处理CBmpEdit类的WM_CTLCOLOR消息,在该消息的处理函数中设置文本的背景透明,代码如下:

        HBRUSH CBmpEdit::CtlColor(CDC*pDC,UINT nCtlColor)     //WM_CTLCOLOR消息处理函数
        {
            pDC->SetBkMode(TRANSPARENT);                    //设置文本背景透明
            return NULL;
        }

(7)处理CBmpEdit类的WM_ERASEBKGND消息,在该消息的处理函数中绘制编辑框背景,代码如下:

        BOOL CBmpEdit::OnEraseBkgnd(CDC*pDC)                                             //消息处理函数
        {
            CDC memDC;                                                                   //设备上下文
            memDC.CreateCompatibleDC(pDC);                                              //创建内存设备上下文
            memDC.SelectObject(&m_Bitmap);                                              //将位图选入设备上下文
            BITMAP m_Bmp;                                                                //声明BITMAP对象
            m_Bitmap.GetBitmap(&m_Bmp);                                                 //获得位图信息
            int x=m_Bmp.bmWidth;                                                         //获得位图的宽度
            int y=m_Bmp.bmHeight;                                                        //获得位图的高度
            CRect rect;                                                                  //声明区域对象
            GetClientRect(rect);                                                        //获得编辑框客户区域
            pDC->StretchBlt(0,0,rect.Width(),rect.Height(),&memDC,0,0,x,y,SRCCOPY);     //绘制位图背景
            memDC.DeleteDC();                                                           //释放内存设备上下文
            return TRUE;                                                                 //返回真值
            //return CEdit::OnEraseBkgnd(pDC);                                           //禁止调用基类方法
        }

(8)处理CBmpEdit类的EN_CHANGE消息,在该消息的处理函数中重绘背景,代码如下:

        void CBmpEdit::OnChange()                                            //EN_CHANGE消息处理函数
        {
            Invalidate();                                                   //重绘背景
        }

举一反三

根据本实例,读者可以:

自绘编辑框控件。