The GetWindowText function's return value is documented as follows:
If the function succeeds, the return value is the length, in characters, of the copied string, not including the terminating null character. If the window has no title bar or text, if the title bar is empty, or if the window or control handle is invalid, the return value is zero. To get extended error information, call GetLastError.
Now, when calling this method and receiving a return value of zero, how do I know whether GetLastError would return a sensible value? After all, zero is not only used to indicate failure, but could also mean that the window text is empty, in which case GetLastError would not return an undefined value.
My own ideas:
GetWindowText might set the last error to 0 on success. But testing shows it doesn't (and if it did, I couldn't rely on it anyway, since this isn't documented).GetWindowText might leave the last error unchanged on success, so setting it to 0 myself before the call would allow me to check whether the last error has changed. Testing shows this might work, but since it's not doumented this way, I can't rely on it. (And I guess this would depend heavily on the concrete circumstances and implementation of GetWindowText.)GetWindowTextLength and then call GetWindowText only if the length was greater than 0. However, what if the window changes its text between my calls to GetWindowTextLength and GetWindowText? I, again, couldn't rely on a return value of zero denoting an error.So, what can I do to definitely decide whether GetWindowText failed?
SetLastError(ERROR_SUCCESS) beforehand is perfectly safe and supported.
The documentation for last-error codes make it clear that a function may or may not clear the last-error value on success. What is certain, however, is that if a function succeeds, it will either leave the last-error value unchanged, or set it to zero, but never change it to an error value.
The implementation rules for WinAPI functions may be summarized as:
SetLastError if no error occurs.SetLastError(0) so the non-fatal internal error isn't visible to the caller, or call RestoreLastError and pass whatever GetLastError returned on entry to your API
SetLastError to report it (unless a helper function already did).The documented behavior "some functions call SetLastError with a zero when they succeed" is a consequence of point #2.
Yes, you are right, you cannot actually use GetLastError() to see the difference. Not pretty. The only workaround I can think of is to use IsWindow() afterward. If that returns TRUE then a zero return really means "empty string". That, however, doesn't deal with passing a bad buffer pointer, hopefully easily avoided in your code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With