弹出(子)对话框以及对其控件进行操作

【弹出对话框】

1,添加对话框。

要想弹出对话框,首先肯定要先新建一个对话框。这里默认你已经建立了主MFC的情况,这样才会在解决方案资源管理器那边有【资源视图】这一选项卡。

【资源视图】——【Dialog】——右键【insert dialog】

一个dialog新建完毕。

2,为dialog添加对应的类

右击【dialog】——【添加类】——输入类名(假设为 A)点击确定

完成这两步,一个对话框就能被调用了。

3,弹出对话框

例如需要点击主对话框的确定按钮弹出上述dialog,那么双击【确定】按钮,或右击【确定】添加单击的消息响应函数。

在其中添加:

A a;

a.DoModal();

这里DoModal是以【模态对话框】形式展现,即这个对话框弹出后别的对话框不能使用直到当前对话框关闭。

需要注意的是,新建对话框时,默认有确定和取消两个按钮的,它们的ID默认为IDOK和IDCancel,DoModal函数返回值为可以为这两个ID,表示点击了某个按钮。例如:

INT_PTR  flag = a.DoModal();

if (flag == IDOK)

{...}

====================================================================

【对其控件进行操作】

最头疼的是如何对子对话框的控件进行操作。这里用【如何在主程序中获得子窗口编辑框中键盘键入的数据】为例。

1,首先肯定要给这个eidtBox关联一个变量。

右击dialog中的编辑框控件,添加变量,假设为g_getName。

做完这一步,在A.cpp中的DoDataExchange函数中已经自动将变量和编辑框的ID关联起来了。

但是,这并不代表输入编辑框的值会自动赋给getName变量,也就是说,DoDataExchange函数不会自动执行

2.编辑框变量值g_getName能够响应用户用键盘输入的值

之前我还费尽心思添加一个OnInitDialog虚函数,并在虚函数里采用

bool get_peopleid::oninitdialog()
{
    cdialogex::oninitdialog();

    // todo:  在此添加额外的初始化
    char id_num[20] = { 0 };
    cstring str;
    str= _t("");
    str.format(_t("gfdgh"));
    g_getname.setwindowtext(str);
    
    updatedata(true);

    g_getname.getwindowtext(str);
        return TRUE;
}

类似这种方法,希望能够利用updatedata函数来更新编辑框的变量值。然并卵,除了能初始化显示gfdfh在对话框中之外,其他都行不通。

后来看了这篇文章http://wenku.baidu.com/view/04a27d6a561252d380eb6e49.html。想起,此处只要相应一个消息函数即可。

//sample代码,下面还会说到
void get_PeopleID::OnBnClickedOk()
{
    // TODO:  在此添加控件通知处理程序代码
    CString str;
    g_getName.GetWindowText(str);    
    std::cout << str << std::endl;   //a
    AfxMessageBox(str);                 //b
    CDialogEx::OnOK();

}

这样str就是你输入的值啦。

3,获取编辑框的值

a,句柄说(获取子对话框空间值,反正我是行不通)

char id_num[10]="";
SendMessageA(h, WM_GETTEXT, sizeof(id_num), LPARAM(id_num));

据说这样可以将h句柄的值读入id_num中,所以我们只要找到编辑框的句柄值就好了嘛。

网上有好几种方法获取句柄,代表性的为:

a.1 GetDlgItem函数, h= GetDlgItem(getName)->GetSafeHwnd();

然而,这样得出的id_num是主MFC中编辑框的值。是的,虽然我填的是子对话框editBox的ID,但是得出的仍然是主对话框的值。 GetDlgItem()函数是不能获取子对话框的句柄的。

a.2 spy++

据说,【工具】中有个spy的东东可以查看控件的句柄,而且可视化,点哪显示哪,试一下(自行百度spy的用法),果然名不虚传。But,
HWND h = (HWND)0x000003ed;//手工spy查到的editBox的句柄值
SendMessageA(h, WM_GETTEXT, sizeof(id_num), LPARAM(id_num));

显示的结果是 id_num的空,多试几次后发现每次的h值都不一样,原来每次程序都会分配新的句柄值嘛!所以怎么能用上一次的值来查找这次的句柄呢~

a.3 FindWindowEx函数

HWND hWnd = ::GetForegroundWindow();
HWND handle1 = ::FindWindowEx(hWnd, 0, NULL, "getName"); //handle1=00000

先找到当前窗口的句柄值,各种窗口的句柄值获取请参照:http://my.oschina.net/u/2314763/blog/422622?fromerr=SobXFhyw

然而事实证明还是不能显示

a.4 既然在主函数中总是获取不到子对话框控件的句柄值,那我在A.cpp中设置好返回总可以吧。

// A.cpp
char* get_PeopleID::get_handle()
{

    char id_num[10] = "";
    SendMessageA(g_getName.m_hWnd, WM_GETTEXT, sizeof(id_num), LPARAM(id_num)); //g_getName.m_hWnd直接获取控件句柄
    std::cout << id_num << std::endl;
    return id_num;
}

调用get_handle之前我有在单击确定按钮中加入g_getName.GetWindowText(str);将对话框的值与变量连接。在main.cpp中先点击确定执行此处,在调用get_handle,想返回id_num,无果。依然为空。

 

b,GetWindowText及CString to char* 的转换

上述sample代码中已经已经获取到了输入的值,并保存在str(可以设置为A的全局变量,方便在其他类中获取)中,但是如果不采用AfxMessageBox,在std中看到的类似于地址的输出,这是怎回事呢?原来CString用cout输出的是str地址

如果你单纯的要显示在控制台中,只需要printf(“%S”,str)即可,注意S大写。

但是如果你之后还要用,需要进行转换,例如转换成char*,可以参照博文http://blog.163.com/ming__nan/blog/static/6783288200991111281852/

此处将最有效代码直接贴出,网上其他的什么强制转换经实验大部分都是扯淡。

// CString str to char* c
int len = WideCharToMultiByte(CP_ACP, 0,str, -1, NULL, 0, NULL, NULL);//Cstring To char * in Unicode character set
char* c = new char[len + 1];
WideCharToMultiByte(CP_ACP, 0, str, -1, c, len, NULL, NULL);

 

posted @ 2016-03-10 10:03  Daringoo  阅读(960)  评论(0编辑  收藏  举报