Greetings:
I am attempting to implement toolbar window message 0x463 -- which, as far as I can tell, is undocumented. If anyone has any information about it, I would love to hear it.
I currently have a question about a difference in the implementation of comctl32.dll under Wine vs Windows. In both Wine and Windows, the function ToolbarWindowProc starts by calling GetWindowLongA (hwnd, 0) and treats the returned value as a pointer to a structure.
Under wine the structure is the TOOLBAR_INFO structure defined in dlls/comctl32/toolbar.c. Under Windows, I have no idea what the structure looks like. Using the debugger, I can see that the first two elements of the structure are the hwnd numbers of the window and its parent -- but after that it is not very obvious. The structure is over 150 bytes in size.
Does anyone know what the structure under Windows looks like?
Thanks, Jeremy Shaw.
jeremy@lindows.com
----- Original Message ----- From: "Jeremy Shaw" jeremy@lindows.com To: wine-devel@winehq.com Sent: Thursday, February 21, 2002 4:07 PM Subject: Question about ToolbarWindowProc
Greetings:
I am attempting to implement toolbar window message 0x463 -- which, as far as I can tell, is undocumented. If anyone has any information about it, I would love to hear it.
I currently have a question about a difference in the implementation of comctl32.dll under Wine vs Windows. In both Wine and Windows, the function ToolbarWindowProc starts by calling GetWindowLongA (hwnd, 0) and treats the returned value as a pointer to a structure.
Under wine the structure is the TOOLBAR_INFO structure defined in dlls/comctl32/toolbar.c. Under Windows, I have no idea what the structure looks like. Using the debugger, I can see that the first two elements of the structure are the hwnd numbers of the window and its parent -- but after that it is not very obvious. The structure is over 150 bytes in size.
Does anyone know what the structure under Windows looks like?
1. Most (if not all) the extended common controls (those in comctl32) seem to store their main implementation data via GetWindowLong(hwnd, 0). However we really don't care about the format of the MS version since our code *should* never interface with it. I have not personally seen any access to that in Rebar, Toolbar, or ComboEx. To avoid *trouble* I would suggest staying away from MS's version of the implementation data.
2. From looking at relay traces, Toolbar messages 0x045d and 0x0463 seem to be a pair. They also seem to invoke comctl32.413 which is also undocumented. The relay traces seem to suggest that .413 somehow redirects the message to another Winproc. All windows that process through .413 seem to have the atom for "CC32SubClassInfo" added as a property (GetProp/SetProp). I suspect that this whole thing may be related to the "nativefont" control. There seems to be no ill-effect to the messages not being implemented (except for the annoying fixme). Note that comctl32.413 may also be related to comctl32.410 and .412.
If you can somehow get the "nativefont" control to make a visual difference, then maybe we can implement some of this.
Good Luck,
Guy
"Guy L. Albertelli" galberte@neo.lrun.com wrote:
- From looking at relay traces, Toolbar messages 0x045d and 0x0463 seem
to
be a pair. They also seem to invoke comctl32.413 which is also undocumented.
The
relay traces seem to suggest that .413 somehow redirects the message to another Winproc. All windows that process through .413 seem to have the
atom
for "CC32SubClassInfo" added as a property (GetProp/SetProp). I suspect
that
this whole thing may be related to the "nativefont" control. There seems
to
be no ill-effect to the messages not being implemented (except for the annoying fixme). Note that comctl32.413 may also be related to
comctl32.410
and .412.
IMO, the undocumented functions comctl32.410 to comctl32.413 are some kind of a subclass manager. They seem to be the functions DefSubclassProc(), SetWindowSubclass(), GetWindowSubclass() and RemoveWindowSubclass() which are documented in the new Windows XP Platform SDK.
Regards,
Eric Kohl
----- Original Message ----- From: "Eric Kohl" ekohl@rz-online.de To: "Wine Devel" wine-devel@winehq.com Sent: Friday, February 22, 2002 8:11 AM Subject: Re: Question about ToolbarWindowProc
"Guy L. Albertelli" galberte@neo.lrun.com wrote:
- From looking at relay traces, Toolbar messages 0x045d and 0x0463 seem
to
be a pair. They also seem to invoke comctl32.413 which is also undocumented.
The
relay traces seem to suggest that .413 somehow redirects the message to another Winproc. All windows that process through .413 seem to have the
atom
for "CC32SubClassInfo" added as a property (GetProp/SetProp). I suspect
that
this whole thing may be related to the "nativefont" control. There seems
to
be no ill-effect to the messages not being implemented (except for the annoying fixme). Note that comctl32.413 may also be related to
comctl32.410
and .412.
IMO, the undocumented functions comctl32.410 to comctl32.413 are some kind of a subclass manager. They seem to be the functions DefSubclassProc(), SetWindowSubclass(), GetWindowSubclass() and RemoveWindowSubclass() which are documented in the new Windows XP Platform SDK.
Having just read the MSDN artical at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/pla tform/CommCtls/Userex/subclassingcontrols.asp I agree. The things being done are the "Subclassing controls Prior to Comctl32.dll version 6". I still feel that the subclassing is done by the "nativefont" control.
Guy
Hello,
Let me ask a different question on the same subject. I am going to start with a bit of background first.
Under internet explorer, the favorites menu is not really a 'menu' but a toolbar that is laid out top to bottom instead of left to right. (that is somewhat of a simplification, there are actually two toolbar windows, a SysPager window, and a few others involved). Under wine, when the Favorites menu is displayed it has the correct width but is only 8 pixels tall. If I use the native comctl32.dll from Windows ME, the menu works correctly.
Now, If I use the WindomsME comctl32.dll BUT modify SendMessageA to block the Favorites menu from receiving message 0x463, then the Favorites menu reverts to only being 8 pixel tall.
Here are some brief traces using the wine builtin and WinME comctl32.dll (this is WITHOUT the patch to block msg 0x463)
** Builtin **
0806b4a8:CALL SHLWAPI.136: @(00010040,00000463,00000001,405c2fb4) ret=7102dc2e 0806b4a8:Call user32.SendMessageA(00010040,00000463,00000001,405c2fb4) ret=70bd2540 0806b4a8:Call window proc 0x40fe2d74 (hwnd=00010040,msg=WM_USER+0063,wp=00000001,lp=405c2fb4) 0806b4a8:Call user32.GetWindowLongA(00010040,00000000) ret=40fe2dcb 0806b4a8:Ret user32.GetWindowLongA() retval=428c2544 ret=40fe2dcb err:toolbar:ToolbarWindowProc unknown msg 0463 wp=00000001 lp=405c2fb4 0806b4a8:Call user32.DefWindowProcA(00010040,00000463,00000001,405c2fb4) ret=40fe3c81 0806b4a8:Ret user32.DefWindowProcA() retval=00000000 ret=40fe3c81 0806b4a8:Ret window proc 0x40fe2d74 (hwnd=00010040,msg=WM_USER+0063,wp=00000001,lp=405c2fb4) retval=00000000 0806b4a8:Ret user32.SendMessageA() retval=00000000 ret=70bd2540 0806b4a8:RET SHLWAPI.136: @() retval = 00000000 ret=7102dc2e
** Native (comctl32.dll from WinMe) **
0806b4d8:CALL SHLWAPI.136: @(0001003d,00000463,00000001,405c29e0) ret=7102dc2e 0806b4d8:Call user32.SendMessageA(0001003d,00000463,00000001,405c29e0) ret=70bd2540 0806b4d8:Call window proc 0x77b562ef (hwnd=0001003d,msg=WM_USER+0063,wp=00000001,lp=405c29e0) 0806b4d8:Call user32.GetPropW(0001003d,0000c050) ret=77b56337 0806b4d8:Ret user32.GetPropW() retval=4044e410 ret=77b56337 0806b4d8:CALL COMCTL32.413: @(0001003d,00000463,00000001,405c29e0) ret=7103f54b 0806b4d8:Call user32.IsWindow(0001003d) ret=77b564ca 0806b4d8:Ret user32.IsWindow() retval=00000001 ret=77b564ca 0806b4d8:Call user32.GetPropW(0001003d,0000c050) ret=77b564eb 0806b4d8:Ret user32.GetPropW() retval=4044e410 ret=77b564eb 0806b4d8:Call kernel32.GetCurrentThreadId() ret=77b564f7 0806b4d8:Ret kernel32.GetCurrentThreadId() retval=0806b4d8 ret=77b564f7 0806b4d8:Call user32.CallWindowProcW(77b5655c,0001003d,00000463,00000001,405c29e0) ret=77b56535 0806b4d8:Call window proc 0x77b5655c (hwnd=0001003d,msg=WM_USER+0063,wp=00000001,lp=405c29e0) 0806b4d8:Call user32.GetWindowLongA(0001003d,00000000) ret=77b56571 0806b4d8:Ret user32.GetWindowLongA() retval=4044e688 ret=77b56571 0806b4d8:Ret window proc 0x77b5655c (hwnd=0001003d,msg=WM_USER+0063,wp=00000001,lp=405c29e0) retval=00000001 0806b4d8:Ret user32.CallWindowProcW() retval=00000001 ret=77b56535 0806b4d8:RET COMCTL32.413: @() retval = 00000001 ret=7103f54b 0806b4d8:Call user32.IsWindow(0001003d) ret=77b56396 0806b4d8:Ret user32.IsWindow() retval=00000001 ret=77b56396 0806b4d8:Ret window proc 0x77b562ef (hwnd=0001003d,msg=WM_USER+0063,wp=00000001,lp=405c29e0) retval=00000001 0806b4d8:Ret user32.SendMessageA() retval=00000001 ret=70bd2540 0806b4d8:RET SHLWAPI.136: @() retval = 00000001 ret=7102dc2e
As mentioned later in this thread, it appears that there is some sort of subclassing going on here.
Currently I have only been working on trying to figure out what happens when you call window proc 0x77b5655c and pass it msg WM_USER + 0063. Obviously, its not doing a whole lot since the only function it calls is "GetWindowLongA". GetWindowLongA is presumably returning a pointer to a structure similar to TOOLBAR_INFO. My best guess is that the function is calcaluting the height of the favorites menu (by adding together the heights of all the buttons in the toolbar) and copying the height to another field in the TOOLBAR_INFO-like structure.
So, my question is, where do I go from here? Since message 0x463 is undocumented, I do not know how to proceed except by disassembling the windows version of comctl32.dll. And, as part of that, it would be very beneficial to know what the structure returned by GetWindowLongA looks like.
Thanks for your help! Jeremy Shaw.
----- Original Message ----- From: "Jeremy Shaw" jeremy@lindows.com To: "Wine Devel" wine-devel@winehq.com Sent: Wednesday, February 27, 2002 7:30 PM Subject: Re: Question about ToolbarWindowProc
Now, If I use the WindomsME comctl32.dll BUT modify SendMessageA to block
the
Favorites menu from receiving message 0x463, then the Favorites menu
reverts to
only being 8 pixel tall.
Jeremy,
I do believe I have been totally wrong about toolbar message [0463].
0806f388:trace:message:SPY_EnterMessage (00010044) L"Menu" message [043a] TB_GETBUTTONSIZE sent from self wp=00000000 lp=00000000 0806f388:trace:message:SPY_ExitMessage (00010044) L"Menu" message [043a] TB_GETBUTTONSIZE returned 001500a5 0806f388:trace:message:SPY_EnterMessage (00010044) L"Menu" message [0463] WM_USER+0063 sent from self wp=00000001 lp=405243ac 0806f388:trace:message:SPY_ExitMessage (00010044) L"Menu" message [0463] WM_USER+0063 returned 00000000 0806f388:trace:message:SPY_EnterMessage (00010046) L"{ToolbarWindow}" message [043a] TB_GETBUTTONSIZE sent from self wp=00000000 lp=00000000 0806f388:trace:message:SPY_ExitMessage (00010046) L"{ToolbarWindow}" message [043a] TB_GETBUTTONSIZE returned 00150173 0806f388:trace:message:SPY_EnterMessage (00010046) L"{ToolbarWindow}" message [0463] WM_USER+0063 sent from self wp=00000001 lp=405243ac 0806f388:trace:message:SPY_ExitMessage (00010046) L"{ToolbarWindow}" message [0463] WM_USER+0063 returned 00000000 ... 0806f388:Call user32.AdjustWindowRectEx(4052463c,86400000,00000000,00000088) ret=7113f8d6 0806f388:trace:win:InflateRect r (-3,-3)-(374,4) 0806f388:Ret user32.AdjustWindowRectEx() retval=00000001 ret=7113f8d6
The above trace is from work I've been doing on IE5.5. It shows the entries just before the first known point of failure. If I fudge AdjustWindowRectEx and force the rectangle to be deeper (larger y value), it displays the Favorites "menu" window. Note that the app code touches, with both TB_GETBUTTONSIZE and [0463], both toolbars that are part of the rebar just before the call.
Based on your note, I added some code (bottom) to toolbar.c to display the data pointed to by the lParam of the [0463] message. I chose 2 dwords after looking at memory with the debugger. The third and fourth dwords are the stack pointer and return address, so the max size of the data must be 2 dwords.
The trace below shows the values displayed.
Then I guessed that the code in native probably sets the second word.
AND THAT STARTED TO WORK!!!!
No, not correctly, but it is definitely bigger.
err:toolbar:ToolbarWindowProc [0463] lParam 0x40523c70 -> 0x000000a5 0x00000000 err:toolbar:ToolbarWindowProc [0463] lParam 0x40523c68 -> 0x00000173 0x00000000
case 0x0463: { LPDWORD hoho = (LPDWORD)lParam; ERR("[0463] lParam 0x%08lx -> 0x%08lx 0x%08lx\n", lParam, *hoho, *(hoho+1)); /* guess - level 1 */ if (!*(hoho+1)) { *(hoho+1) = *hoho; /* set second word to first */ } return 0; /* really should be 1 */ }
BTW, The interior windowproc is the "real" toolbar windowproc. You can check the windowproc addresses by running the ControlSpy samples with "+relay,+message" and noting which addresses are used for which window classes.
I really think we are closer.
If we add another case to windows/spy.c to trap the [0463] message and dump the two dwords at the lParam on entry and exit, I think we can understand what this thing really does.
Guy