[ros-kernel] Re: Status of Explorer under ReactOS - Bug #42 (I know the fix)

Jonathan Wilson jonwil at tpgi.com.au
Sat Nov 8 22:43:32 CET 2003


ok, I have the solution here.
Basicly, what we need is this:
1.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.

2.A new version of NtUserRegisterClassExWOW (and therefore IntCreateClass) 
such that it takes both ansi and unicode window procedures and sets the 
fields of the internal class structure as appropriate.

3.changes to how controls are registered to pass both window procedures.

4.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.

Not sure how things like common controls work but based on my analysis of 
user32, doing this for the controls that are inside user32.dll will make 
things work like they do on windows (even with respect to subclassing, 
sending messages and so on).

What would (I hope) now happen in the ANSI version of explorer explorer is 
this:
1.the BUTTON class gets registered at startup with both ANSI and Unicode 
window procedures. The ANSI window procedure field points to ButtonWndProcA 
and the Unicode window procedure field points to ButtonWndProcW.

2.explorer creates an instance of the BUTTON class which contains both ANSI 
and Unicode window procedures and has the unicode field set to FALSE. The 
ANSI window procedure field points to ButtonWndProcA and the Unicode window 
procedure field points to ButtonWndProcW.

3.explorer subclasses the button with its own window procedure (lets call 
it ExplorerButtonWndProc since I dont have actual code for explorer to look 
up the real name), using SetWindowLongA. SetWindowLongA returns pointer to 
ButtonWndProcA, sets ANSI window procedure field to <address of 
ExplorerButtonWndProc>, sets Unicode window procedure field to <address of 
ExplorerButtonWndProc + 0x80000000> and sets Unicode field to FALSE.

4.explorer calls GetWindowTextA on the button. This calls SendMessageA.
That in turn thunks down into kernel mode, ending up calling IntCallWindowProc.
IntCallWindowProc then tests the Unicode field. Since its false, 
IntCallWindowProc then calls CallWindowProcW passing it the contents of the 
Ansi window procedure field (in this case its ExplorerButtonWndProc).
CallWindowProcW tests to see if the window is unicode. Since it is not, the 
message passed to CallWindowProcW is converted into ANSI. Then, the window 
procedure (ExplorerButtonWndProc) is called. ExplorerButtonWndProc doesnt 
know how to handle WM_GETTEXT (I assume) so it calls CallWindowProcA and 
passes it the Window Procedure that was saved when the subclassing happened 
(in this case its ButtonWindowProcA) along with the message details.
Since IsWindowUnicode returns false, all CallWindowProcA needs to do is to 
call the procedure (i.e. ButtonWindowProcA).
Then, ButtonWindowProcA does the appropriate processing for WM_GETTEXT and 
returns the results as an ANSI string.

The unicode version of explorer would do something similar but with unicode 
calls and stuff instead of ANSI.




More information about the Ros-kernel mailing list