Hello everyone,
I am trying to create a new thread, which has a procedure and that procedure is supposed to act as a hotkey monitor.
There are few things i would like to find out:
does this procedure need prototype in mASM or there is something else i don't know about. I assumed it does need a prototype, and as win32.hlp says it is supposed to be a DWORD, now when writing the actual procedure you have to pass that DWORD parameter, otherwise I get an error (reference below) after PROC directive and i have no idea what to pass. This is a piece of c++ which I am trying to convert.
CreateThread( NULL, NULL, (LPTHREAD_START_ROUTINE)htk, NULL, NULL, NULL );
DWORD htk()
{
while( !Exit )
{
if( GetAsyncKeyState( VK_F1 )&1 )
...
...
...
}
return 0;
}
and i have tried to invoke it like this
invoke CreateThread,0,0,addr HotkeyMonitor,0,0,0
htk PROC xxx <== (What parameter does it need here?) If i pass no parameter here i get an error: "error A2111: conflicting parameter definition"
...
...
...
ret
htk endp
http://msdn.microsoft.com/en-us/library/ms682453(VS.85).aspx
.data?
htk dd ?
.code
.While htk==0
invoke GetAsyncKeyState, VK_F1
and eax, 1
mov htk, eax
.Endw
invoke CreateThread, NULL, NULL, htk, NULL, NULL, NULL
I think there are a few miconceptions here, first of all htk is not the return value, it is the name of the procedure. There are no paramters to pass to the thread so it makes it a bit simpler. However you have not posted the whole routine, how does the thread signal the main thread that the F1 key has been pressed ? What event signals the thread to shut down ? Also the F1 key is used for help and should not be used for anything else. Obviously jj2007's response will result in a GPF since the value in htk can only be 1 and CreateThread is expecting an address to the thread procedure, this will cause the thread to attempt execution starting at address 1, which is not allowed. Here's a quick (untested) example...
or fControlFlag, 1 ; The thread will exit normally if bit 0 is reset
invoke CreateThread,NULL,NULL,OFFSET htk,NULL,NULL,NULL
mov hThread, eax
; Run the thread at lower priority so it doesn't slow down your main program
invoke SetThreadPriority, hThread, THREAD_PRIORITY_BELOW_NORMAL
htk proc lParam:DWORD
TOPLOOP:
invoke GetAsyncKeyState, VK_F1
test eax,1
jz @F
; Signal the main thread here that the key has been pressed
; Just using a posted message to the main window as an example...
invoke PostMessage, hMainWindow, WM_USER+256, VK_F1, 0
@@:
; Check a signalling device to see if the thread should terminate
; Here I'm just using a flags low order bit (set = continue)
test fControlFlag, 1
jnz TOPLOOP
invoke ExitThread, 0
htk endproc
Quote from: donkey on July 09, 2008, 04:35:10 PMObviously jj2007's response will result in a GPF since the value in htk can only be 1
Obviously, Edgar! I must have been very tired; interesting though that it took more than a week until somebody noticed :P
The main thread does not signal the hotkey monitoring thread, that is why i chose threading over timer , so that it will not interrupt already over cumbered main thread.
the hotkey monitor thread is destroyed when WM_CLOSE message is recieved by seting flag in main thread which is checked in hotkey thread and if TRUE is destroyed.
I have not used the F1 key in my program , i have used it here as an example, yes i was aware of F1 being help key in most programs.
htk PROC prm:LPTHREAD_START_ROUTINE
(The highlighted part is what i was missing, didnt know that i need to declare it this way which i found out after some more testing soon after posting this question on the forums -_-;
...
...
...
ret
htk endp
It works by looping itself just as you have posted above (just not @@ @B @F as it is much more complicated, so for readability i have used unique labels) and checks the flag after passing through the loop each time.
lParam cannot be used , it has to be LPTHREAD_START_ROUTINE (a pointer to starting address of PROC htk in this case).
Thanks for trying to help
Quote from: Aiva on July 10, 2008, 07:38:50 PMthe hotkey monitor thread is destroyed when WM_CLOSE message is recieved by seting flag in main thread which is checked in hotkey thread and if TRUE is destroyed.
This is the same method I chose, the main thread signals the worker thread by setting or resetting the flag, fControlFlag in my case.
QuoteI have not used the F1 key in my program , i have used it here as an example, yes i was aware of F1 being help key in most programs.
Excellent, it is always good practice to follow the guidelines in the Windows BUI.
QuoteIt works by looping itself just as you have posted above (just not @@ @B @F as it is much more complicated, so for readability i have used unique labels) and checks the flag after passing through the loop each time.
You can use whatever labels you like, as I said without the whole procedure it is impossible to determine what you were looking for.
QuotelParam cannot be used , it has to be LPTHREAD_START_ROUTINE (a pointer to starting address of PROC htk in this case).
Actually lParam is a DWORD, any DWORD will do, the LPTHREAD_START_ROUTINE is C typing and is not necessary in assembler and in this case is part of the CreateThread call and not part of the ThreadProc, the lParam in the ThreadProc is an application defined value passed to the thread at initialization. It is certainly not a pointer to the thread procedure, that is passed elsewhere in the call. ThreadProc as defined at MSDN...
DWORD WINAPI ThreadProc(
LPVOID lpParameter
);
Parameters
lpParameter
[in] Thread data passed to the function using the lpParameter parameter of the CreateThread or CreateRemoteThread function.
I used lParam for clarity, the name and type are not significant in assembly language, it is simply 4 bytes on the stack. Since I use only GoAsm and not MASM I am even less concerned with C types as they are not used at all in that assembler.
However, as they say "whatever floats your boat". If you feel more comfortable using C data types then by all means use them but understand they have no significant meaning in assembly language other than the width of the data in bytes.
Donkey
Here is my function, maybe you will need it.
fNewThread proc lpThreadName:dword
LOCAL ThreadID:dword
mov edx,lpThreadName
invoke CreateThread,NULL,NULL,edx,\
NULL,NORMAL_PRIORITY_CLASS,\
ADDR ThreadID
invoke CloseHandle,eax
ret
fNewThread endp