Функция возвращает std :: wstring = NULL; - PullRequest
3 голосов
/ 01 мая 2011

Я пытаюсь сделать упаковщик для функции winapi GetWindowText. Функция возвращает std :: wstring, но я не знаю, как обрабатывать ошибки. Я возвращаю NULL, но знаю, что это неправильно.

std::wstring GetWindowText(HWND handle)
{
    const int size = 1024;
    TCHAR wnd_text[size] = {0};

    HRESULT hr = ::GetWindowText(handle,
                    wnd_text, size);
    if(SUCCEEDED(hr))
        return std::wstring(wnd_text);
    else
        return NULL;    
}

Ответы [ 7 ]

7 голосов
/ 01 мая 2011

Вместо этого выведите исключение .

std::wstring GetWindowText(HWND handle)
{
    const int size = 1024;
    TCHAR wnd_text[size] = {0};

    HRESULT hr = ::GetWindowText(handle,
                    wnd_text, size);
    if(SUCCEEDED(hr))
        return std::wstring(wnd_text);
    else
        throw std::runtime_error("insert error message here");    
}
5 голосов
/ 01 мая 2011

В качестве альтернативы исключениям вы также можете возвращать строку по ссылке в списке аргументов и указывать успех, возвращая истину или ложь, т.е.

bool GetWindowText(HWND handle, std::wstring& windowText)
{
    const int size = 1024;
    TCHAR wnd_text[size] = {0};

    HRESULT hr = ::GetWindowText(handle,
                    wnd_text, size);
    if(SUCCEEDED(hr))
    {
        windowText = wnd_text;
        return true;
    }
    else
        return false;    
}

Другая альтернатива, которая избегает ссылочного аргумента, - это возвращение экземпляра класса, который переносит значение, но также позволяет узнать, присутствует ли значение, например,

class ValueWrapper
{
public:
    ValueWrapper() : present( false ) {}
    ValueWrapper( const std::wstring& s ) : value( s ), present( true ) {}

    bool isPresent() const { return present; }
    const std::wstring& getValue() const { return value; }

private:
    std::wstring value;
    bool present;
};

Обратите внимание, что вы можете легко создать шаблон для этой оболочки. Ваша функция будет тогда

ValueWrapper GetWindowText(HWND handle)
{
    const int size = 1024;
    TCHAR wnd_text[size] = {0};

    HRESULT hr = ::GetWindowText(handle,
                    wnd_text, size);
    if(SUCCEEDED(hr))
        return ValueWrapper( wnd_text );
    else
        return ValueWrapper();
}
1 голос
/ 01 мая 2011

Еще одно решение (без исключений): используйте библиотеку Boost. Опционально .

0 голосов
/ 01 мая 2011

В зависимости от вашего приложения, есть несколько подходящих решений.Во-первых, выдается исключение в случае ошибки: если вы идете по этому пути, вы должны определить исключение WindowsError (происходящее из одного из стандартных исключений), которое включает в себя всю информацию, доступную из GetLastError, и, возможно, дополнительнуюинформация (название неисправной функции и т. д.) в удобном для анализа формате.Другой - вернуть что-то вроде Fallible;в этом случае вы можете расширить классическую идиому Fallible, чтобы она могла содержать дополнительную информацию о причине ошибки.Еще одна возможность - вернуть значение через параметр out и использовать код возврата (опять же, возможно, с дополнительной информацией и, возможно, с добавленным кодом, чтобы убедиться, что оно было проверено перед уничтожением).

0 голосов
/ 01 мая 2011

Прежде всего, GetWindowText () не возвращает HRESULT, поэтому ваш код в этом отношении неверен.

И, во-вторых, GetWindowTextW возвращает 0 при любой ошибке или количестве символов, если все в порядке. Так что просто верните пустую строку:

std::wstring GetWindowText(HWND handle)
{
    const int size = 1024;
    TCHAR wnd_text[size] = {0};

    INT n = ::GetWindowTextW(handle,
                    wnd_text, size);
    if(n > 0)
        return std::wstring(wnd_text,n);
    else
        return std::wstring();
}
0 голосов
/ 01 мая 2011

WinApi разработан таким образом, чтобы он никогда не создавал исключений. И чтобы получить причину некоторого неудачного возврата какой-либо функции, вам в большинстве случаев нужно получить последнюю ошибку через GetLastError () . Как я понимаю, ваша функция будет некоторым дополнением к WinApi, которое будет простым в использовании. Поэтому я предлагаю сохранить их дизайн. Т.е. в случае неудачи верните пустую строку и проверьте, что является последней ошибкой, если ваша функция ее возвращает.

0 голосов
/ 01 мая 2011

NULL определенно не нормально для строк, вам определенно не разрешено передавать нулевой указатель на строковый конструктор.

Если вы не хотите генерировать исключение, выможет вернуть пустую строку, return std::wstring();.

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