[ros-kernel] Re: Status of Explorer under ReactOS - Bug #42 (more
fixes)
Jonathan Wilson
jonwil at tpgi.com.au
Sun Nov 9 07:59:51 CET 2003
Here is what happens on real windows under different cases:
(note that anytime I refer to GetWindowLong, I also mean the return value
one would get from calling SetWindowLong since its the same thing)
Anytime I refer to [SetGet]WindowLong[AW], I refer to calling it with
GWL_WNDPROC as the parameter
If you call GetWindowLongA on a window of the BUTTON class, you get a
pointer to ButtonWndProcA.
If you call GetWindowLongW on a window of the BUTTON class, you get a
pointer to ButtonWndProcW.
If you call IsWindowUnicode on a button window, what you get depends on if
CreateWindowExA or CreateWindowExW was called.
If you then call SetWindowLongA on a window of the BUTTON class, it sets
the ANSI window procedure to your new window procedure (lets call it
SubClassProc). This is assumed to be an ANSI window. The Unicode field is
set to the "magic handle" value. It will return a pointer to ButtonWndProcA
regardless of the setting of the "Unicode" flag (i.e. regardless of which
version of CreateWindowEx was called)
Also, IsWindowUnicode will now return FALSE.
With the fix I descirbed, ReactOS will now work like this.
As for general cases, here is what I have found in my testing:
1.those "window procedure handles" (the ones that on ROS are just the
address of the procedure + 0x80000000) are actually a pointer to a data
structure (or are somehow turned into one). This structure specifies if its
a pointer to an ANSI window procedure or a Unicode window procedure. This
would be set at any time one modifies the Window Procedure addresses (i.e.
in SetClassLong or SetWindowLong or RegisterClassEx)
2.when CallWindowProc is called with a "handle", it uses the "handle" to
identify if it is an ANSI window procedure or a unicode window procedure.
If CallWindowProcW is called, it assumes the message is Unicode and if
CallWindowProcA is called, it assumes the message is ANSI.
3.when CallWindowProc is called with an address, it passes the message
without doing any ansi/unicode conversion whatsoever. (i.e. it doesnt test
IsWindowUnicode or anything else). This means that if you have an address
of an ANSI window procedure and send it a WM_SETTEXT with a unicode string,
a unicode string is what ends up in the lParam (i.e. windows doesnt know
that the address points to an ANSI wndproc)
here is the complete set of fixes should be done to make this stuff work
like windows:
A.those "window procedure handles" (the ones that on ROS are just the
address of the procedure + 0x80000000) should "encode" somehow if they are
an ANSI window procedure or a Unicode window procedure
B.Any time we modify the window procedure, we should make sure that the
"encoding" is set properly. (i.e. whether its Unicode or Ansi)
C.we fix CallWindowProc to work as described above in points 2 and 3.
D.we change things so that anytime we call IntCallWindowProc, we only ever
pass the Unicode window procedure (since we are only ever passing a Unicode
message and since the Unicode window procedure is always going to be able
to accept Unicode messages).
E.For standard controlls, we create both an ANSI window procedure and a
Unicode window procedure for the standard controls (buttons, statics etc).
These should ideally be implemented as stubs that call a shared procedure
to do all the work (like how MS does it), that way they are sharing all the
data thats needed.
F.We create a new version of RegisterClassEx that accepts and stores both
window procedures.
G.We change the registration of standard controls to call this new function
(and pass both procedures)
and H.We make changes to CreateWindowEx so that if one is creating a
"standard" window class (i.e. those defined in user32.dll and having both
an ansi and a unicode window procedure defined in the user32.dll symbol
table), it will ignore the class Unicode field and instead set the window
unicode field to either Ansi or Unicode based on which version of
CreateWindowEx was called. This test should ONLY be done for standard
controls, all other calls to CreateWindowEx should rely on the class
unicode field.
All these fixes should make things work like how windows XP SP1 (based on
my observations) works when it comes to CallWindowProc, window procedures,
subclassing, standard controls and so on.
More information about the Ros-kernel
mailing list