News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

CreateThread parameter proc

Started by Aiva, July 01, 2008, 12:18:16 AM

Previous topic - Next topic

Aiva

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









jj2007

.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

donkey

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

"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

jj2007

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

Aiva

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

donkey

#6
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

"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Farabi

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
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"