9. 文本框控件¶
文本框控件在我们生活中,并不少见。如 图9_1,这是一个登录界面。我们输入账号和密码处,其实就是文本框控件。emXGUI也提供这样的功能,需要用户外加键盘作为输入设备。
图 9_1 常见的文本框控件
9.1. 创建文本框控件¶
9.1.1. 标准消息类型及参数说明¶
本章只是大致上讲解如何创建文本框控件,修稿控件的外观颜色,是禁止用户输入的。键盘输入,Emmmmm…
本章使用的消息类型,有WM_CREATE、WM_TIMER、WM_NOTIFY和WM_CTLCOLOR。WM_CREATE消息用于创建控件;这里使用WM_TIMER,主要是给大家演示一下, 如何在文本框显示变量。WM_NOTIFY消息用来处理 EXIT按钮消息。使用WM_CTLCOLOR消息来改变控件的外观颜色。
9.1.2. 创建文本框控件函数¶
1 2 3  | HWND CreateWindowEx( U32 dwExStyle, LPCVOID lpClass, LPCWSTR lpWindowName,
        U32 dwStyle, int x, int y, int nWidth, int nHeight,
        HWND hwndParent, UINT WinId,HINSTANCE hInstance,LPVOID lpParam);
 | 
lpClass:窗口类。对于系统标准控件,可以为:BUTTON(常规按钮,复选框,单选框,组合框),SCROLLBAR(水平/垂直滚动条), LISTBOX(列表框)。TEXTBOX(文本框)…等等。这里选择PROGRESSBAR。
dwStyle:文本框的风格。参数TBS_SUNK表示该控件具有凹下边框样式。文本框控件支持窗口风格参数。
至于其他的参数,也是同样的用法,这里不作描述。我们创建控件调用的CreateWindow函数,实际上就是CreateWindowEx函数。
9.2. 创建文本框控件实验¶
9.2.1. 设计要求¶
图9_2 ,是本章节的设计要求。左边这一列文本框显示的文本内容格式不同。右边的文本框第一个是显示变量,变量值实时更新。后两个是多行显示。下面看看,如何用代码实现该界面。
图 9-2 设计要求
9.2.2. 代码分析¶
创建父窗口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30  | void  GUI_DEMO_Textbox(void)
{
    HWND  hwnd;
    WNDCLASS  wcex;
    MSG msg;
    //配置wcex参数
    wcex.Tag        = WNDCLASS_TAG;
    wcex.Style      = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc  = win_proc;
    wcex.cbClsExtra   = 0;
    wcex.cbWndExtra   = 0;
    wcex.hInstance    = NULL;//hInst;
    wcex.hIcon  =  NULL;//LoadIcon(hInstance,(LPCTSTR)IDI_WIN32_APP_TEST);
    wcex.hCursor    = NULL;//LoadCursor(NULL, IDC_ARROW);
    //创建主窗口
    hwnd  =CreateWindowEx(  NULL,
                &wcex,
                L"GUI Demo - Textbox",
                WS_CAPTION| WS_DLGFRAME| WS_BORDER|WS_CLIPCHILDREN,
                0,0,GUI_XSIZE,GUI_YSIZE,
                NULL,NULL,NULL,NULL);
    //显示主窗口
    ShowWindow(hwnd,SW_SHOW);
    //开始窗口消息循环(窗口关闭并销毁时,GetMessage将返回FALSE,退出本消息循环)
    while(GetMessage(&msg,hwnd))
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
}
 | 
创建父窗口,标题栏为“GUI Demo - Textbox”,带有大小边框,设置win_proc作为窗口回调函数。
窗口回调函数
WM_CREATE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56  | case  WM_CREATE:
{
    GetClientRect(hwnd,&rc);
    CreateWindow(BUTTON,L"EXIT",WS_VISIBLE,rc.w-100,8,80,48,hwnd,ID_EXIT,NULL,NULL);
    rc.x =20;
    rc.y =30;
    rc.w =200;
    rc.h =80;
    //创建文本框控件,返回控件句柄wnd
    wnd=CreateWindow(TEXTBOX,L"Text1",WS_VISIBLE,
            rc.x,rc.y,rc.w,rc.h,hwnd,ID_TB1,NULL,NULL);
    //发送TBM_SET_TEXTFLAG,设置文本框的内容,lParam参数代表显示内容的格式
    SendMessage(wnd,TBM_SET_TEXTFLAG,0,DT_SINGLELINE| DT_LEFT| DT_VCENTER| DT_BKGND|DT_BORDER);
    //往下移动矩形位置(X轴不变,Y轴位置增加rc.h+10个像素)
    OffsetRect(&rc,0,rc.h+10);
    //创建文本框控件(可见,具有凹下边框样式),返回控件句柄wnd
    wnd=CreateWindow(TEXTBOX,L"Text2",TBS_SUNK|WS_VISIBLE,
            rc.x,rc.y,rc.w,rc.h,hwnd,ID_TB2,NULL,NULL);
    SendMessage(wnd,TBM_SET_TEXTFLAG,0,DT_SINGLELINE| DT_CENTER| DT_VCENTER|DT_BKGND);
    OffsetRect(&rc,0,rc.h+10);
    wnd=CreateWindow(TEXTBOX,L"Text3",WS_VISIBLE,
            rc.x,rc.y,rc.w,rc.h,hwnd,ID_TB3,NULL,NULL);
    SendMessage(wnd,TBM_SET_TEXTFLAG,0,DT_SINGLELINE| DT_RIGHT| DT_VCENTER| DT_BKGND|DT_BORDER);
    OffsetRect(&rc,0,rc.h+10);
    wnd=CreateWindow(TEXTBOX,L"Text4",WS_DISABLED|WS_VISIBLE,
            rc.x,rc.y,rc.w,rc.h,hwnd,ID_TB4,NULL,NULL);
    SendMessage(wnd,TBM_SET_TEXTFLAG,0,DT_SINGLELINE| DT_VCENTER| DT_BOTTOM| DT_BKGND|DT_BORDER);
    rc.x =250;
    rc.y =30;
    rc.w =200;
    rc.h =80;
    wnd=CreateWindow(TEXTBOX,L"Text5",WS_VISIBLE,
        rc.x,rc.y,rc.w,rc.h,hwnd,ID_TB5,NULL,NULL);
    SendMessage(wnd,TBM_SET_TEXTFLAG,0,DT_SINGLELINE| DT_CENTER| DT_VCENTER|DT_BKGND);
    OffsetRect(&rc,0,rc.h+10);
    rc.w =320;
    rc.h =140;
    //创建文本框控件Text6,返回控件句柄wnd
    wnd=CreateWindow(TEXTBOX,L"Text6\r\nMulti-Line\r\nVCENTER+CENTER",WS_VISIBLE,
            rc.x,rc.y,rc.w,rc.h,hwnd,ID_TB6,NULL,NULL);
    //发送TBM_SET_TEXTFLAG,设置文本框的内容,多行显示
    SendMessage(wnd,TBM_SET_TEXTFLAG,0,DT_VCENTER| DT_CENTER| DT_BKGND|DT_BORDER);
    OffsetRect(&rc,0,rc.h+10);
    wnd=CreateWindow(TEXTBOX,L"Text7\r\nMulti-Line\r\nBOTTOM+RIGHT",TBS_SUNK|WS_VISIBLE,
            rc.x,rc.y,rc.w,rc.h,hwnd,ID_TB7,NULL,NULL);
    SendMessage(wnd,TBM_SET_TEXTFLAG,0,DT_BOTTOM| DT_RIGHT| DT_BKGND|DT_BORDER);
    SetTimer(hwnd,ID_TMR1,200,TMR_START,NULL); //创建一个200ms定时器
    return TRUE;
}
 | 
WM_CREATE消息创建的控件,如 表格9_1 所示。
表格 9_1 控件的具体信息
控件类型  | 
名称  | 
ID值  | 
窗口风格  | 
文本格式  | 
|---|---|---|---|---|
BUTTON  | 
EXIT  | 
ID_EXIT  | 
WS_VISIBLE  | 
无  | 
TEXTBOX  | 
Text1  | 
ID_TB1  | 
WS_VISIBLE  | 
DT_SINGLELINE|DT_LEFT|DT_VCENTER|DT_BKGND|DT_BORDER  | 
Text2  | 
ID_TB2  | 
TBS_SUNK|WS_VISIBLE  | 
DT_SINGLELINE|DT_CENTER|DT_VCENTER|DT_BKGND  | 
|
Text3  | 
ID_TB3  | 
WS_VISIBLE  | 
DT_SINGLELINE|DT_RIGHT|DT_VCENTER|DT_BKGND|DT_BORDER  | 
|
Text4  | 
ID_TB4  | 
WS_DISABLED|WS_VISIBLE  | 
DT_SINGLELINE|DT_VCENTER|DT_BOTTOM|DT_BKGND|DT_BORDER  | 
|
Text5  | 
ID_TB5  | 
WS_VISIBLE  | 
DT_SINGLELINE|DT_CENTER|DT_VCENTER|DT_BKGND  | 
|
Text6  | 
ID_TB6  | 
WS_VISIBLE  | 
DT_VCENTER|DT_CENTER|DT_BKGND|DT_BORDER  | 
|
Text7  | 
ID_TB7  | 
TBS_SUNK|WS_VISIBLE  | 
DT_BOTTOM|DT_RIGHT|DT_BKGND|DT_BORDER  | 
点击EXIT按钮,产生WM_CLOSE消息关闭主窗口。调用CreateWindow函数,创建7个文本框,文本框的文本格式,见 表格9_2。
表格 9_2 文本框的文本格式说明
属性值  | 
文本格式  | 
|---|---|
DT_SINGLELINE  | 
单行模式。没有该参数时,为多行模式  | 
DT_CENTER  | 
水平居中对齐  | 
DT_LEFT  | 
水平居左对齐  | 
DT_RIGHT  | 
水平居右对齐  | 
DT_BOTTOM  | 
垂直底部对齐  | 
DT_VCENTER  | 
垂直中间对齐  | 
DT_BORDER  | 
是否绘制边框  | 
DT_BKGND  | 
是否绘制背景  | 
WM_NOTIFY
1 2 3 4 5 6 7 8 9 10 11 12  | case WM_NOTIFY:
{
    u16 id, code;
    id =LOWORD(wParam);
    code = HIWORD(wParam);
    //EXIT按钮弹起
    if(id == ID_EXIT && code == BN_CLICKED)
    {
        count = 0;
        PostCloseMessage(hwnd);//产生WM_CLOSE消息关闭主窗口
    }
}
 | 
ID_EXIT单击时,会调用PostCloseMessage发送窗口关闭消息WM_CLOSE,来关闭主窗口。
WM_TIMER
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18  | case  WM_TIMER:
{
    u16 id;
    //读取控件ID值
    id =LOWORD(wParam);
    if(id==ID_TMR1)
    {
        count++;
        x_wsprintf(wbuf,L"%04d",count);
    //获取控件句柄
        wnd =GetDlgItem(hwnd,ID_TB5);
    //设置控件显示文本框
        SetWindowText(wnd,wbuf);
    }
}
return TRUE;
 | 
WM_CREATE消息中,创建了ID为ID_TMR1的定时器。定时器到达设定值时,发送WM_TIMER消息。在WM_TIMER消息中,实现count变量自加,同时调用SetWindowText函数将变量值在文本框Text5显示。
WM_CTLCOLOR
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25  | case  WM_CTLCOLOR:
{
    /* 控件在绘制前,会发送 WM_CTLCOLOR到父窗口.
        * wParam参数指明了发送该消息的控件ID;lParam参数指向一个CTLCOLOR的结构体指针.
        * 用户可以通过这个结构体改变控件的颜色值.
        用户修改颜色参数后,需返回TRUE,否则,系统
        * 将忽略本次操作,继续使用默认的颜色进行绘制.
        *
        */
    u16 id;
    id =LOWORD(wParam);
    if(id== ID_TB5 || id== ID_TB6)
    {
        CTLCOLOR *cr;
        cr =(CTLCOLOR*)lParam;
        cr->TextColor =RGB888(255,180,180);//文字颜色(RGB888颜色格式)
        cr->BackColor =RGB888(100,0,0);//背景颜色(RGB888颜色格式)
        cr->BorderColor =RGB888(255,10,10);//边框颜色(RGB888颜色格式)
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}
 | 
改变控件窗口的文字颜色(TextColor),边框颜色(BorderColor), 背景颜色(BackColor),一定要返回TRUE,否则的话,则按照默认方案来配置。
最后,将GUI_DEMO_Textbox加入到GUI_AppMain中,见 代码清单9_7。