Как получить текст из DialogBox без использования глобальной переменной - PullRequest
0 голосов
/ 06 декабря 2018

Есть ли способ получить текст из диалогового окна, созданного 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 голосов
/ 06 декабря 2018

Вы можете создать диалоговое окно с помощью 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;
}
0 голосов
/ 06 декабря 2018

Во-первых, поскольку 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, но он станет более сложным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...