user32 - set_active_window uses SendMessage instead
ofPostMessage for WM_ACTIVATEAPP messages.
Peter Dons Tychsen
donpedro at tdcadsl.dk
Sun Aug 5 14:13:59 CDT 2007
On Sun, 2007-08-05 at 21:12 +0200, Peter Dons Tychsen wrote:
> On Sat, 2007-08-04 at 12:04 +0900, Dmitry Timoshkov wrote:
> > "Peter Dons Tychsen" <donpedro at tdcadsl.dk> wrote:
> >
> > > 1) Yes i did testing on Windows-XP. I did it by putting together various
> > > examples and by checking with InSendMessage() for all cases. This
> > > clearly showed that WM_ACTIVATEAPP was always posted and never sent.
> >
> > Looks like you misunderstood the InSendMessage behaviour and that led to
> > some confusion.
> >
> > Wine test harness for message sequences works just fine, there is no need
> > to blame it.
> >
>
> I have found a new way of proving that ACTIVATEAPP must be sent using
> the PostMessage call and not the SendMessage call. I have also found a
> way to extend the unit test system to cover this.
>
> After realizing my bummer with InSendMessage() i set out to create a new
> function that would do what i want: Check if a message was sent with
> PostMessage() or SendMessage() on windows. I could not find any function
> that would do this so i made my own hack (below):
>
> This piece of code, if inserted into the test system, could (on original
> Windows) show us which messages we are incorrectly posting or sending. I
> can probably also be used for other test purposes. I works by checking
> the call stack for the calls SendMessageA() and SendMessageW(). Works
> like charm on Windows-XP. Will need some work to also work inside Wine,
> but that is not important for now.
>
> Usage:
>
> 1) Call call_stack_check_init().
> 2) Call called_from_send_message() inside the Proc handler.
>
> Cheers,
>
> /Pedro
>
> ------ CODE BEGIN --------
>
> void call_stack_check_init(void)
> {
> HANDLE process = GetCurrentProcess();
> SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
> SymInitialize(process, NULL, TRUE);
> }
>
> #define SYM_MAX_NAME_SIZE 1000
> BOOL call_stack_check_search(char *func)
> {
> STACKFRAME64 call_stack;
> CONTEXT context;
> HANDLE thread = GetCurrentThread();
> SYMBOL_INFO *sym = (SYMBOL_INFO *) malloc(sizeof(SYMBOL_INFO) +
> SYM_MAX_NAME_SIZE);
> CHAR name[SYM_MAX_NAME_SIZE];
> HANDLE process = GetCurrentProcess();
>
> /* Setup symbol buffer */
> ZeroMemory(sym, sizeof(SYMBOL_INFO) + SYM_MAX_NAME_SIZE);
> sym->SizeOfStruct = sizeof(SYMBOL_INFO);
> sym->MaxNameLen = SYM_MAX_NAME_SIZE;
>
> /* Get thread context */
> ZeroMemory(&context, sizeof(context));
> context.ContextFlags = CONTEXT_FULL;
> __asm call x;
> __asm x: pop eax;
> __asm mov context.Eip, eax;
> __asm mov context.Ebp, ebp;
> __asm mov context.Esp, esp;
>
> /* Setup stack walk offset */
> ZeroMemory(&call_stack, sizeof(call_stack));
> call_stack.AddrPC.Offset = context.Eip;
> call_stack.AddrStack.Offset = context.Esp;
> call_stack.AddrFrame.Offset = context.Ebp;
> call_stack.AddrPC.Mode = AddrModeFlat;
> call_stack.AddrStack.Mode = AddrModeFlat;
> call_stack.AddrFrame.Mode = AddrModeFlat;
>
> while(1)
> {
> DWORD64 disp = 0;
>
> /* Walk that rusty old stack... */
> if(!StackWalk64(
> IMAGE_FILE_MACHINE_I386,
> process,
> thread,
> &call_stack,
> NULL,
> NULL,
> SymFunctionTableAccess64,
> SymGetModuleBase64,
> NULL)) return FALSE;
>
> /* Get the next symbol on stack */
> if(SymFromAddr(GetCurrentProcess(), call_stack.AddrPC.Offset, &disp,
> sym))
> {
> /* Make it readable */
> UnDecorateSymbolName(sym->Name, name, SYM_MAX_NAME_SIZE,
> UNDNAME_COMPLETE |
> UNDNAME_NO_THISTYPE |
> UNDNAME_NO_SPECIAL_SYMS |
> UNDNAME_NO_MEMBER_TYPE |
> UNDNAME_NO_MS_KEYWORDS |
> UNDNAME_NO_ACCESS_SPECIFIERS);
>
> /* Check for match */
> if(!strcmp(func, name)) return TRUE;
> }
> }
>
> return FALSE;
> }
> BOOL called_from_send_message(void)
> {
> if (call_stack_check_search("SendMessageW")) return TRUE;
> if (call_stack_check_search("SendMessageA")) return TRUE;
>
> return FALSE;
> }
>
> ----- CODE END -----
By the way, this code does prove (if run on Windows-XP), that
ACTIVATEAPP should be posted and not sent.
/pedro
More information about the wine-devel
mailing list