On Sat, 2007-08-04 at 12:04 +0900, Dmitry Timoshkov wrote: > "Peter Dons Tychsen" <[EMAIL PROTECTED]> 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 -----