This message does not what I expect: it delivers IDs that look plausible but don't exist for Task Manager. What's going on? Full source attached, pure Masm32 SDK.
CASE WM_ACTIVATEAPP
print str$(lParam), " is the thread ID", 13, 10
invoke LoadLibrary, chr$("Kernel32")
push eax
invoke GetProcAddress, eax, chr$("GetProcessIdOfThread")
.if eax
push lParam
call eax ; invoke GetProcessIdOfThread, lParam
pushad
print str$(eax), " is the process ID from GetProcessIdOfThread", 13, 10
popad
.endif
.if !eax
mov eax, lParam
.endif
pushad
print str$(eax), " is the process ID", 13, 10
popad
call FreeLibrary
When switching with Alt Tab to this window from my browser, I get this:
2236 is the thread ID
0 is the process ID from GetProcessIdOfThread (which probably means thread=process)
2236 is the process ID
There is absolutely no process with ID 2236 :cool:
I'm very likely the wrong person to "answer" a Windoze question, since I switched to other OSes long ago,
but I vaguely remember that there is a difference between a thread ID and a thread handle - they cannot be mixed because they are different animals.
Thanks, Andreas :thup:
QuoteWM_ACTIVATEAPP (https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-activateapp)
lParam
The thread identifier. If the wParam parameter is TRUE, lParam is the identifier of the thread that owns the window being deactivated. If wParam is FALSE, lParam is the identifier of the thread that owns the window being activated.
The numbers I see are always in the n....2500 range. These are IDs, not handles.
This is the first time I try to use WM_ACTIVATEAPP. It's not that important for me, but I wonder what can go wrong with such an old and well-documented message :rolleyes:
After reading a bit and looking your code maybe this can help you a bit:
Windows documentation says that GetProcessIdOfThread needs a handle to the thread, but you are passing to it a thread id. How you get this handle? You need to use OpenThread which, in one of its parameters expects a thread id. The return value of this last function (in case of success) will be the thread handle. Then use that one for the function GetProcessIdOfThread and you should end up with the process id. :icon_idea:
Thanks, Felipe. What you write is correct, and I had not seen it. However, in practice I never used GetProcessIdOfThread simply because it always returned zero (and now you've told me why - it expects a handle, not an ID). So I took lParam instead, which clearly should be an "identifier". Knowing Microsoft, I wonder whether they mean "handle" when they write "identifier", but it's not very probable :sad:
I have done a little test program that shows that actually that info is correct :thup:. Attached below. Here's the output:
Process ID: 0000000000000CA0
And below an image with the process id. (In hex ca0 = 3232).
Here with the more friendly indentation :toothy::
; Program that shows the process id.
option casemap:none
include \masm64\include64\win64.inc
include \masm64\include64\kernel32.inc
includelib \masm64\lib64\kernel32.lib
.data
con_title byte "Process ID",0h
process_id byte "Process ID: ", 16 dup(0h)
input_buff qword 0h
chars_written qword 0h
chars_readed qword 0h
.code
start proc
sub rsp,28h
call GetCurrentThreadId
mov r12,rax ; Thread ID.
mov rcx,THREAD_QUERY_INFORMATION
xor rdx,rdx
mov r8,r12
call OpenThread
mov r13,rax ; Thread handle.
mov rcx,r13
call GetProcessIdOfThread
mov rsi,rax ; Process ID.
mov rcx,rsi
lea rdx,process_id
mov r8,sizeof process_id
mov r9,16 ; 16 nibbles.
call reg_value ; Get value of rsi.
call FreeConsole ; Detach process of inherited console
call AllocConsole ; and create a new one.
lea rcx,con_title
call SetConsoleTitle
mov rcx,STD_OUTPUT_HANDLE
call GetStdHandle
mov r15,rax ; Output handle.
mov rcx,r15
lea rdx,process_id
mov r8,sizeof process_id
lea r9,chars_written
mov qword ptr[rsp+20h],NULL
call WriteConsole
mov rcx,STD_INPUT_HANDLE
call GetStdHandle
mov r15,rax ; Input handle.
mov rcx,r15
mov rdx,ENABLE_LINE_INPUT
call SetConsoleMode
mov rcx,r15
lea rdx,input_buff
mov r8,1 ; Read just the character CR.
lea r9,chars_readed
mov qword ptr[rsp+20h],NULL
call ReadConsole
xor rcx,rcx
call ExitProcess
start endp
reg_value proc
push rbp
mov rbp,rsp
next_nibble:
mov rsp,rcx
and rcx,0fh ; Isolate lsb.
cmp rcx,09h
ja can_be_a
or rcx,30h ; To ascii.
dec r8
mov [rdx+r8],cl
dec r9
and r9,r9
jz all_done
mov rcx,rsp
shr rcx,4
jmp next_nibble
can_be_a:
cmp rcx,0ah
jne can_be_b
mov rcx,'A'
dec r8
mov [rdx+r8],cl
dec r9
and r9,r9
jz all_done
mov rcx,rsp
shr rcx,4
jmp next_nibble
can_be_b:
cmp rcx,0bh
jne can_be_c
mov rcx,'B'
dec r8
mov [rdx+r8],cl
dec r9
and r9,r9
jz all_done
mov rcx,rsp
shr rcx,4
jmp next_nibble
can_be_c:
cmp rcx,0ch
jne can_be_d
mov rcx,'C'
dec r8
mov [rdx+r8],cl
dec r9
and r9,r9
jz all_done
mov rcx,rsp
shr rcx,4
jmp next_nibble
can_be_d:
cmp rcx,0dh
jne can_be_e
mov rcx,'D'
dec r8
mov [rdx+r8],cl
dec r9
and r9,r9
jz all_done
mov rcx,rsp
shr rcx,4
jmp next_nibble
can_be_e:
cmp rcx,0eh
jne is_f
mov rcx,'E'
dec r8
mov [rdx+r8],cl
dec r9
and r9,r9
jz all_done
mov rcx,rsp
shr rcx,4
jmp next_nibble
is_f:
mov rcx,'F'
dec r8
mov [rdx+r8],cl
dec r9
and r9,r9
jz all_done
mov rcx,rsp
shr rcx,4
jmp next_nibble
all_done:
mov rsp,rbp
pop rbp
ret
reg_value endp
end