TypeCodes

图文实例说MFC制作工具的心得(一)

上篇文章说了用MFC制作一个十六进制字符串异或的工具,这篇文章就以这个工具为演示总结一下自己的学习心得。

MFC十六进制异或工具

1 控制用户输入数据的长度

在给用于用户输入十六进制字符串数据的Edit Control控件添加变量时,可以在“最大字符数”这个选项中填入一个整数,例如这个工具最大字节就限制在500内。这样就会生成如下代码,作用是在数据交互时自动截取前面500个字符。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
void CHexStrXorDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    //用于控件1和第一个十六进制字符串变量交互
    DDX_Text(pDX, IDC_EDIT1, HexStr1);
    DDV_MaxChars(pDX, HexStr1, 500);
    //用于控件2和第二个十六进制字符串变量交互
    DDX_Text(pDX, IDC_EDIT2, HexStr2);
    DDV_MaxChars(pDX, HexStr2, 500);
    //用于控件3和异或结果变量交互
    DDX_Text(pDX, IDC_EDIT3, HexStr);
    DDV_MaxChars(pDX, HexStr, 500);
}

但是,这样只是截取用户输入的字符串前面的500字节,而不是提示用户输入的数据不合法。

所以,改进的方法就是为控件1和控件2添加对应的EN_KILLFOCUS控件事件(OnEnKillfocusEdit1、OnEnKillfocusEdit2)。然后自己写了一个验证方法CheckInputHex,用于检查长度和字符串中是否都是十六进制字符,完整的实现代码如下:

 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
//检查输入的十六进制字符串是否合法
int CheckInputHex(CEdit* pEdit, CString HexInput)
{
    //获取字符串的长度
    int i, HexInputLen;
    HexInputLen = HexInput.GetLength();

    //检查长度是否合适
    if (HexInputLen > 500)
    {
        //弹出一个错误框,提示用户输入的数据不合法
        AfxMessageBox(_T("长度不能大于500!"));
        //重新将焦点聚集在这个数据不合法的控件框内
        pEdit->SetFocus();
        pEdit->SetSel(0, HexInputLen);
        return -1;
    }

    //检查是否是十六进制字符
    for (i = 0; i < HexInputLen; i++)
    {
        if (HexInput[i]<0x30 || (HexInput[i]>0x39 && HexInput[i]<0x41) || (HexInput[i]>0x46 && HexInput[i]<0x61) || HexInput[i]> 0x66)
        {
            AfxMessageBox(_T("请输入正确的十六进制字符串!"));
            pEdit->SetFocus();
            pEdit->SetSel(0, HexInputLen);
            return -1;
        }
    }
    return 0;
}

void CHexStrXorDlg::OnEnKillfocusEdit1()
{
    // TODO:  在此添加控件通知处理程序代码
    CEdit* pEdit;

    //获得第一个字符串控件 
    pEdit = (CEdit*)GetDlgItem(IDC_EDIT1);

    //获取Edit Control内的内容,即第一个十六进制字符串  
    pEdit->GetWindowText(HexStr1);

    //检查合法性
    int iCheckData;
    iCheckData = CheckInputHex(pEdit, HexStr1);

    //出错则直接返回
    if (iCheckData)
        return;
}
2 检测用户输入数据是否合法

因为用户输入的数据并不一定是你设想的,可能还是有害的,所以在使用前必须予以检查。由于我的这个工具要求用户输入的必须是十六进制字符串,所以必须要检查每个字符是否合法。检查方法已经包含在上面CheckInputHex方法了,如果用户输入了非法字符,例如'G'、'h'等非十六进制字符,那么就会弹出错误框如下

检测用户输入数据是否合法的十六进制字符串

3 统计用户输入字符串的长度

如果用户输入了一个合法的字符串,然后离开了输入框,这时应该自动在输入框的右侧统计出用户输入的字符串的长度。方法依然是在控件对应的EN_KILLFOCUS事件处理方法OnEnKillfocusEdit1中实现:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
void CHexStrXorDlg::OnEnKillfocusEdit1()
{
    /**
     * 省略小节1中的OnEnKillfocusEdit1()已有的代码
     * /

    //更新长度
    CString UpdateHexStr1Len;
    UpdateHexStr1Len.Format("%s%d%s", "字节=[", HexStr1.GetLength(), "]");
    //SetDlgItemText(IDC_STATIC_STR1, UpdateHexStr1Len );
    GetDlgItem(IDC_STATIC_STR1)->SetWindowTextA(UpdateHexStr1Len);
}
4 设置TAB键切换连续输入

如何让用户在输入完第一个字符串后,按TAB键直接跳到第二个十六进制字符串输入框中?这个就涉及到对话框中所有空间的排序了。在visual studio 2013中按“Ctrl+D”就会显示对话框所有空间的序号了,分别点击两个不同的控件,就能交换二者的序号。

如图所示,只要将第一个字符串输入框控件和第二个字符串输入框控件的序号设置为1、2这两个连续的序号即可实现TAB键连续输入,而不用使用鼠标了。

mfc设置控件序号实现TAB键切换连续输入

5 避免回车键直接关闭工具(对话框)

直接将“进行异或”这个按钮属性中的Default Button设置为"TRUE",这样如果用户直接回车就不会关闭工具(对话框)了。

同时,用户的回车会直接触发这个按钮对应的事件OnBnClickedButton1,也就相当于用户点击了这个按钮,直接对这两个字符串进行异或处理。

设置按钮属性中的Default Button为TRUE

6 结语

由于篇幅较长,所以把剩余内容放在了第二部分

打赏支持

Comments »