开发者

Function returns std::wstring = NULL;

I have trying to make wrapper for winapi function GetWindowText. Function returns std::wstring but i don't know how to handle where error happen. I return NULL but i know it's wrong.

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;    
}


Throw an exception instead.

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");    
}


As an alternative to exceptions you could also return the string by reference in the argument list and indicate sucess by returning true or false i.e.

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;    
}

Another alternative which avoids the reference argument is to return an instance of a class that wraps a value but also lets you know whether a value is present e.g.

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;
};

Note that you can template this wrapper pretty easily. Your function would then be

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();
}


Yet another solution (without throwing exceptions): use the Boost.Optional library.


NULL is definitely not ok for strings, you are specifically not allowed to pass a null pointer to the string constructor.

If you don't want to throw an exception, you can return the empty string, return std::wstring();.


WinApi designed so that it never throws exception. And to get reason of some unsuccessfull return of some function you in most cases have to get last error via GetLastError(). As I understand your function is going to be some addition to WinApi which will be easy to use. So I suggest keep their design as well. i.e. In case of failure return empty string and check what is last error if your function returns it.


First of all GetWindowText() does not return HRESULT so your code is just wrong in this respect.

And second, GetWindowTextW returns 0 on any error or number of characters if OK. So just return an empty string:

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();
}


Depending on your application, there are several appropriate solutions. The first is to throw an exception in case of an error: if you go this route, you should define a WindowsError exception (deriving from one of the standard exceptions), which includes all of the information available from GetLastError, and possibly additional information (name of the function which failed, etc.), in an easy to parse format. The other is to return some sort of Fallible; in this case, you may want to extend the classical Fallible idiom so that it can contain additional information concerning the cause of the error. Still another possibility is to return the value via an out parameter, and use a return code (again, possibly with additional information, and possibly with added code to ensure that it has been tested before being destructed).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜