Dmitry Timoshkov wrote:
Since you didn't provide your test app I wrote my own (attached).
My comments are based on its results.
Well, since I was lazy I wrote it in Delphi and you'd have to enter
window handles yourself, I didn't attach it but since I keep being
accused of tainted sources I tried to clarify this.
The results of the research I just did:
1. GetComboBoxInfo works with all handles, even with handles not
belonging to the calling process
Most likely it's true.
That's right, the reason I mentioned is that Christoph's implementation
won't work because of different address spaces. Even if it points to the
desktop heap (which ReactOS doesn't have yet) it's not guaranteed to
work because it might have gotten mapped to another base address. So the
implementation basically can't work this way.
2. It does NOT send a message, not even in the case it doesn't belong
to the calling process
True, but that might be an internal message catched by the message
handling
code.
I of course only checked if a message would get dispatched to the window
procedure of the owning thread. I don't know how windows handles it
internally but I assume it reads the information from the desktop heap
without reading the ptr using GetWindowLongPtr. If of course might send
an internal message that only gets dispatched internally, but that'd be
much overhead that could easily be a avoided. I forgot to mention that
the function even works if the thread that owns the combo box hangs, it
immediately returns the requested information. So sending a (internal)
special message is not likely in my opinion.
3. It sets the last error code to ERROR_WINDOW_NOT_COMBOBOX and
returns FALSE if the window handle isn't a combo box
True. That might be accomplished by retrieving a window data pointer with
GetWindowLongPtrW and testing some internal fields.
That however only works for controls owned by a thread of the same process.
5. If the cbSize field of the COMBOBOXINFO structure doesn't match,
it sets the last error code to ERROR_INVALID_PARAMETER and returns FALSE
Poor Microsoft programmers even decided to fail if cbi.cbSize =
sizeof(cbi) + 1,
i.e. if it's enough space to store the result.
That actually is common in the native api. Unless the buffer needed may
vary depending on the content it returns, in most cases the size fields
have to match. There are however a few exceptions I found by tests. One
reason however might be to support different structure versions (.e.g.
GetVersionEx()). So I don't think it's a "bad thing(tm)". Plus you might
find bugs caused by using incorrect structure layouts.
In Wine we can always send our custom WINE_GETCOMBOBOXINFO message if
a window
belongs to other process.
Unless the window owner thread hangs, that then causes the caller to
hang as well, which is not the case in windows. Sending a message with a
timout would not work correctly if the system is too busy to process the
request in time, even if the target thread doesn't hang.
My test app shows that Windows correctly handles a superclassed
window, so
the thesis that it checks the class name is wrong.
As I haven't tested that case, I guess you're right.
Best Regards,
Thomas