[ros-kernel] Suggested implementation ideas for the various WndProc, CallWndProc etc fixes

Jonathan Wilson jonwil at tpgi.com.au
Sun Nov 9 19:16:27 CET 2003


Implementation suggestions for each of these:
> 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
We should store this info in a structure:
struct WndProcHandle
{
   WNDPROC WindowProc;
   BOOL IsUnicode;
};
with the structures being stored in win32k, in some kind of array or linked 
list thats indexable via the lower WORD of the WNDPROC handle.

> 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)
In all 3 places where we need to handle this (i.e. IntCreateClass, 
IntSetClassLong & NtUserSetWindowLong),
we allocate a new WndProcHandle, fill it in & add it to the list or array.

> C.we fix CallWindowProc to work as described above in points 2 and 3.
We add a new syscall of some kind that takes a window procedure handle (we 
test to see if its a handle or
an address first) and returns the relavent WndProcHandle structure. Then, 
in CallWndProcA, we do the following:
CallWndProcA() {
    if (address is not a handle)
    {
       call window procedure
    } else {
       WndProcHandle x = GetWndProcHandle(handle)
       if (WndProcHandle.IsUnicode == TRUE) {
          convert message to unicode
       }
       call window procedure
       if (WndProcHandle.IsUnicode == TRUE) {
          clean up conversion and convert reply
       }
    }
}
and for CallWndProcW:
CallWndProcW() {
    if (address is not a handle)
    {
       call window procedure
    } else {
       WndProcHandle x = GetWndProcHandle(handle)
       if (WndProcHandle.IsUnicode == FALSE) {
          convert message to ANSI
       }
       call window procedure
       if (WndProcHandle.IsUnicode == FALSE) {
          clean up conversion and convert reply
       }
    }
}

> 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).
We need to change the code like this:
   if (WindowObject->Unicode == TRUE)
   {
	Result = IntCallWindowProc(WindowObject->WndProcW,
					Msg.hwnd,
					Msg.message,
					Msg.wParam,
					Msg.lParam);
   }
   else
   {
	Result = IntCallWindowProc(WindowObject->WndProcA,
					Msg.hwnd,
					Msg.message,
					Msg.wParam,
					Msg.lParam);
   }
to this:
Result = IntCallWindowProc(WindowObject->WndProcW,
				Msg.hwnd,
				Msg.message,
				Msg.wParam,
				Msg.lParam);

> E.For standard controls, 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.
This just requires creating the new window procedures (if they dont exist yet)

For these next ones, we add a field to the class structure that specifies 
that its a standard class, something like IsStandardClass. Then, that gets 
set when the classes are registered. Any time we need to add a new standard 
class (i.e. one with 2 WNDPROCs), we just register it with the right 
function and the rest just "works".

> F.We create a new version of RegisterClassEx that accepts and stores 
> both window procedures.
We just clone NtUserRegisterClassExWOW and give it the extra parameter (or 
modify NtUserRegisterClassExWOW to accept the extra parameter somehow).
This needs to handle storing both window procedures plus setting of the 
IsStandardClass field in the class structure

> G.We change the registration of standard controls to call this new 
> function (and pass both procedures)
Just some changes in regcontrol.c needed here

> 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.
This is easy, we just test on the IsStandardClass field and if so, set the 
Unicode field of the window structure based on which version of 
CreateWindowEx was called, otherwise we set it based on what the class 
field is set to.



More information about the Ros-kernel mailing list