Quote:
Originally Posted by bilbo
I now see your problem: you must not intercept the first WM_NOTIFY which arrives, with notify code NM_CLICK (0xFFFFFFFE), but the following WM_NOTIFY, with notify code TVN_SELCHANGED (0xFFFFFE6E in ascii version, 0xFFFFFE3D in Unicode version)!
Best regards
bilbo
|
Yes, I wish I could intercept WM_NOTIFY with code TVN_SELCHANGED
instead of NM_CLICK, but that program was not written by myself. It
stubbornly sticks to NM_CLICK.
I have done several experiments to defy GetMessagePos(), but got
no success:
Experiment1: It did not trigger the WM_NOTIFY event processing.
And if I change hWnd to hTreeView itself instead of its father,
the result is the same.
Code:
POINT ap={0x0027, 0x0289}, cp={0x0025, 0x00AE};
SetFocus(GetParent((HWND)hTreeView));
SetCursorPos(ap.x, ap.y);
ScreenToClient(GetParent((HWND)hTreeView), &ap);
cp = ap;
PostMessage(GetParent((HWND)hTreeView), WM_LBUTTONDOWN, MK_LBUTTON, cp.y<<16 | cp.x);
Experiment2: It triggered the WM_NOTIFY event processing,
but GetMessagePos() got the wrong coordinates.
Code:
POINT ap={0x0027, 0x0289}, cp={0x0025, 0x00AE};
SetFocus(GetParent((HWND)hTreeView));
SetCursorPos(ap.x, ap.y);
ScreenToClient(GetParent((HWND)hTreeView), &ap);
cp = ap;
PostMessage(GetParent((HWND)hTreeView), WM_LBUTTONDOWN, MK_LBUTTON, cp.y<<16 | cp.x);
NMHDR notify;
notify.hwndFrom = (HWND)hTreeView;
notify.idFrom = 0xE901;
notify.code = NM_CLICK; // 0xFFFFFFFE
SendMessage(GetParent((HWND)hTreeView), WM_NOTIFY, 0xE901, (long)¬ify);
Experiment3: It did not triggered the WM_NOTIFY event processing.
Code:
TV_ITEM ti;
POINT ap={0x0027, 0x0289}, cp={0x0025, 0x00AE};
ti.hItem = (HTREEITEM)hLstRetract;
ti.mask = TVIF_HANDLE | TVIF_STATE | TVIF_PARAM;
ti.stateMask = TVIF_HANDLE | TVIF_STATE | TVIF_PARAM;
SendMessage((HWND)hTreeView, TVM_GETITEM, 0, (long)&ti);
NM_TREEVIEW tvnm;
memset(&tvnm, 0, sizeof(tvnm));
tvnm.itemNew = ti;
tvnm.action = TVC_BYMOUSE; // by mouse click
tvnm.ptDrag.x = cp.x; // client
tvnm.ptDrag.y = cp.y; // coordinates
tvnm.hdr.hwndFrom = (HWND)hTreeView;
tvnm.hdr.idFrom = 0xE901;
tvnm.hdr.code = TVN_SELCHANGED;
SendMessage(GetParent((HWND)hTreeView), WM_NOTIFY, 0xE901, (long)&tvnm);
I have traced that program by using OllyDbg & Soft-ICE to figure out
why Experiment3 failed:
Code:
73D322C3 FF75 08 push dword ptr [ebp+8]
73D322C6 FF75 0C push dword ptr [ebp+C]
73D322C9 53 push ebx
73D322CA FF76 04 push dword ptr [esi+4]
73D322CD E8 DDFEFFFF call #AfxFindMessageEntry_1145;[!]=>*73D321AF
73D322D2 85C0 test eax, eax; in simulating case, EAX=0
73D322D4 75 0F jnz short 73D322E5; in physical click case, EAX=4471860h
this_is_bad:
...
that_is_good:
73D322E5 FF75 14 push dword ptr [ebp+14]
73D322E8 FF70 10 push dword ptr [eax+10]; 0x26
73D322EB FF75 10 push dword ptr [ebp+10]
73D322EE FF70 14 push dword ptr [eax+14]; 0x442D470=message_processing_function_ptr
73D322F1 FF75 0C push dword ptr [ebp+C]
73D322F4 FF75 08 push dword ptr [ebp+8]
73D322F7 57 push edi
73D322F8 E8 6E000000 call 73D3236B; [!]
73D322FD ^ EB DF jmp short 73D322DE
||
\||/
\/
;[!]*73D3236B
73D3236B 55 push ebp
73D3236C 8BEC mov ebp, esp
73D3236E 8B45 20 mov eax, [ebp+20]
73D32371 53 push ebx
73D32372 33DB xor ebx, ebx
73D32374 43 inc ebx
73D32375 85C0 test eax, eax
73D32377 74 12 je short 73D3238B
...
73D323C2 8B45 18 mov eax, [ebp+18]
73D323C5 FF30 push dword ptr [eax]
73D323C7 8B4D 08 mov ecx, [ebp+8]
73D323CA FF70 04 push dword ptr [eax+4]
73D323CD FF55 14 call [ebp+14]; [!]=>*0x442D470=message_processing_function_ptr
73D323D0 E9 97000000 jmp 73D3246C
||
\||/
\/
;[!]73D321AF;#AfxFindMessageEntry_1145
73D321AF > 55 push ebp
73D321B0 8BEC mov ebp, esp
73D321B2 53 push ebx
73D321B3 8B5D 08 mov ebx, [ebp+8]; EBX=4471848h->MessageMap
73D321B6 8B45 0C mov eax, [ebp+C]; EAX=EventCodePrefix=0xBC4E
73D321B9 8B55 10 mov edx, [ebp+10]; EDX=EventCode=TVN_SELCHANGED=0xFE6E
73D321BC 8B4D 14 mov ecx, [ebp+14]
73D321BF 837B 10 00 cmp dword ptr [ebx+10], 0; is_it_null_message_map_item
73D321C3 74 1D je short 73D321E2; has reached the end of message map
73D321C5 3B03 cmp eax, [ebx]; check EventCodePrefix
73D321C7 74 05 je short 73D321CE
73D321C9 83C3 18 add ebx, 18; EBX->next_message_map_item
73D321CC ^ EB F1 jmp short 73D321BF
73D321CE 3B53 04 cmp edx, [ebx+4]; check EventCode
73D321D1 ^ 75 F6 jnz short 73D321C9
73D321D3 3B4B 08 cmp ecx, [ebx+8]
73D321D6 ^ 72 F1 jb short 73D321C9
73D321D8 3B4B 0C cmp ecx, [ebx+C]
73D321DB ^ 77 EC ja short 73D321C9
73D321DD 895D 08 mov [ebp+8], ebx; save message_map_item_ptr
73D321E0 EB 05 jmp short 73D321E7
73D321E2 33C0 xor eax, eax
73D321E4 8945 08 mov [ebp+8], eax
73D321E7 8B45 08 mov eax, [ebp+8]; EAX=message_map_item_ptr
73D321EA 5B pop ebx ; [EAX+14h]=message_processing_function_ptr
73D321EB 5D pop ebp
73D321EC C2 1000 retn 10
;This is the message map. It contains 3 items. Every item holds 18h bytes.
04471848 64 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00
04471858 0C 00 00 00 40 D4 42 04 4E BC 00 00 FE FF 00 00
04471868 00 00 00 00 00 00 00 00 26 00 00 00 70 D4 42 04
04471878 0F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
04471888 0C 00 00 00 90 D5 42 04 00 00 00 00 00 00 00 00
04471898 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
According to the above analysis, that program's message map does not
contain an item related to TVN_SELCHANGED.
So I have fallen into a dilemma. If I PostMessage(WM_LBUTTON), that
will not trigger WM_NOTIFY's processing; If I SendMessage(WM_NOTIFY),
that program gets the wrong coordinates.
Do you have any good idea to defeat that damn program?