[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