如何在不使用全局变量的情况下从DialogBox获取文本

时间:2018-12-06 00:33:55

标签: windows winapi

除了全局变量之外,还有什么方法可以从DialogBox创建的对话框窗口中获取文本?

我的意思是,这是我目前的做法:

wchar_t str[80];
INT_PTR CALLBACK DialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case IDOK:
            if (GetDlgItemText(hDlg, IDC_EDIT, str, sizeof(str) / sizeof(*str)) == 0)
                *str = 0;

            EndDialog(hDlg, wParam);
            return (INT_PTR)TRUE;

        case IDCANCEL:
            EndDialog(hDlg, wParam);
            return (INT_PTR)TRUE;
        }
    }
    return (INT_PTR)FALSE;
}

但是我想知道是否有可能摆脱该str全局变量吗?

2 个答案:

答案 0 :(得分:1)

您可以使用DialogBoxParam创建对话框,该对话框允许将初始化数据传递到对话框。

WM_INITDIALOG中,使用SetWindowLongPtr保存此数据,然后在对话框过程中访问数据。

请注意,使用此方法将传递一个指针,因此sizeof(ptr)/sizeof(*ptr)不会返回正确的分配大小。

理想情况下,您可能需要声明局部变量wchar_t *str = NULL;并传递其地址,然后允许对话框分配内存。然后,调用方将负责释放内存。

INT_PTR CALLBACK DialogProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    switch(msg)
    {
    case WM_INITDIALOG:
        SetWindowLongPtr(hwnd, GWL_USERDATA, lparam);
        break;
    case WM_COMMAND:
        switch(LOWORD(wparam))
        {
        case IDOK:
        {
            wchar_t *str = (wchar_t*)GetWindowLongPtr(hwnd, GWL_USERDATA);
            if(str)
                GetDlgItemText(hwnd, IDC_EDIT1, str, 80);
            EndDialog(hwnd, wparam);
            return (INT_PTR)TRUE;
        }
        }
    }
    return (INT_PTR)FALSE;
}

int WINAPI WinMain(HINSTANCE hinst, HINSTANCE, LPSTR, int)
{
    wchar_t str[80];
    if(IDOK == DialogBoxParam(hinst, MAKEINTRESOURCE(IDD_DIALOG1), 0, 
        DialogProc, (LPARAM)(&str)))
        MessageBox(0, str, 0, 0);
    return 0;
}

答案 1 :(得分:0)

首先,由于未使用lParam,可以设置lParam = (LPARAM )str来保存str的地址吗? 其次,返回类型为INT_PTR,但是您仅用于返回TURE / FALSE,为什么不返回指针值而不是返回TRUE(因为str指针始终为!= NULL):

INT_PTR CALLBACK DialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case IDOK:
            wchar_t* str = new wchar_t[80];
            if (!str)   return (INT_PTR)FALSE;
            if (GetDlgItemText(hDlg, IDC_EDIT, str, 80) == 0)
                *str = 0;

            EndDialog(hDlg, wParam);
            return (INT_PTR)str;

        case IDCANCEL:
            EndDialog(hDlg, wParam);
            return (INT_PTR)TRUE;
        }
    }
    return (INT_PTR)FALSE;
}

请注意,您最好为回调中的str分配内存,以免其他人覆盖数据。 您当然也可以使用任何IPC方法,但是它将变得更加复杂。