Jump to content

Are "CoProc.au3" and "Adlib.au3" the 2 best solutions for multithreading and multi-processes ?


Recommended Posts

Opt("MustDeclareVars", 1)

Global $hGui = GUICreate("Time", 350, 270)
Global $hLabel = GUICtrlCreateLabel("", 270, 250, 80, 20)
GUICtrlSetColor(-1, 0x0000CC)
GUICtrlSetFont(-1, 11.5, 600)


Global $hButton = GUICtrlCreateButton("MsgBox", 125, 220, 100, 25)
_ClockThisInAnotherThread($hLabel)


GUISetState()


While 1

    Switch GUIGetMsg()
        Case - 3
            Exit
        Case $hButton
            If MsgBox(4 + 32, "", "Is this blocking the clock?", 0, $hGui) = 6 Then
                MsgBox(0, Chr(0x4C) & Chr(105) & Chr(194 / 2) & Chr(0x72) & "...", BinaryToString(0x20756F79) & Chr(Sqrt(0x24C1)) & BinaryToString("0x72652E"))
            EndIf
    EndSwitch

WEnd



Func _ClockThisInAnotherThread($hControl)

    ; Get kernel32.dll handle
    Local $aCall = DllCall("kernel32.dll", "ptr", "GetModuleHandleW", "wstr", "kernel32.dll")

    If @error Or Not $aCall[0] Then
        Return SetError(1, 0, 0)
    EndIf

    Local $hHandle = $aCall[0]

    ; Get addresses of functions from kernel32.dll. Sleep first:
    Local $aSleep = DllCall("kernel32.dll", "ptr", "GetProcAddress", _
            "ptr", $hHandle, _
            "str", "Sleep")

    If @error Or Not $aCall[0] Then
        Return SetError(2, 0, 0)
    EndIf

    Local $pSleep = $aSleep[0]

    ; GetTimeFormatW then:
    Local $aGetTimeFormatW = DllCall("kernel32.dll", "ptr", "GetProcAddress", _
            "ptr", $hHandle, _
            "str", "GetTimeFormatW")

    If @error Or Not $aCall[0] Then
        Return SetError(3, 0, 0)
    EndIf

    Local $pGetTimeFormatW = $aGetTimeFormatW[0]

    ; Get user32.dll handle
    $aCall = DllCall("kernel32.dll", "ptr", "GetModuleHandleW", "wstr", "user32.dll")

    If @error Or Not $aCall[0] Then
        Return SetError(4, 0, 0)
    EndIf

    $hHandle = $aCall[0]

    ; Get address of function from user32.dll, SendMessageW:
    Local $aSendMessageW = DllCall("kernel32.dll", "ptr", "GetProcAddress", _
            "ptr", $hHandle, _
            "str", "SendMessageW")

    If @error Or Not $aCall[0] Then
        Return SetError(5, 0, 0)
    EndIf

    Local $pSendMessageW = $aSendMessageW[0]

    ; Allocate enough memory with PAGE_EXECUTE_READWRITE for code to run
    $aCall = DllCall("kernel32.dll", "ptr", "VirtualAlloc", _
            "ptr", 0, _
            "dword", 82, _
            "dword", 4096, _ ; MEM_COMMIT
            "dword", 64) ; PAGE_EXECUTE_READWRITE

    If @error Or Not $aCall[0] Then
        Return SetError(6, 0, 0)
    EndIf

    Local $pRemoteCode = $aCall[0]

    ; Make structure in reserved space
    Local $CodeBuffer = DllStructCreate("byte[82]", $pRemoteCode)

    ; Allocate global memory with PAGE_READWRITE. This can be done with ByRef-ing too.
    $aCall = DllCall("kernel32.dll", "ptr", "VirtualAlloc", _
            "ptr", 0, _
            "dword", 36, _
            "dword", 4096, _ ; MEM_COMMIT
            "dword", 4) ; PAGE_READWRITE

    If @error Or Not $aCall[0] Then
        Return SetError(7, 0, 0)
    EndIf

    Local $pStrings = $aCall[0]

    ; Arrange strings in reserved space
    Local $tSpace = DllStructCreate("wchar Format[9];wchar Result[9]", $pStrings)
    DllStructSetData($tSpace, "Format", "hh:mm:ss")

    ; Write assembly on the fly
    DllStructSetData($CodeBuffer, 1, _
            "0x" & _
            "68" & SwapEndian(9) & _                                           ; push output size
            "68" & SwapEndian(DllStructGetPtr($tSpace, "Result")) & _          ; push pointer to output container
            "68" & SwapEndian(DllStructGetPtr($tSpace, "Format")) & _          ; push pointer to format string
            "68" & SwapEndian(0) & _                                           ; push NULL
            "68" & SwapEndian(4) & _                                           ; push TIME_FORCE24HOURFORMAT
            "68" & SwapEndian(0) & _                                           ; push Locale
            "B8" & SwapEndian($pGetTimeFormatW) & _                            ; mov eax, [$pGetTimeFormatW]
            "FFD0" & _                                                         ; call eax
            "68" & SwapEndian(DllStructGetPtr($tSpace, "Result")) & _          ; push pointer to the result
            "68" & SwapEndian(0) & _                                           ; push wParam
            "68" & SwapEndian(12) & _                                          ; push WM_SETTEXT
            "68" & SwapEndian(GUICtrlGetHandle($hControl)) & _                 ; push HANDLE
            "B8" & SwapEndian($pSendMessageW) & _                              ; mov eax, [$pSendMessageW]
            "FFD0" & _                                                         ; call eax
            "68" & SwapEndian(491) & _                                         ; push Milliseconds
            "B8" & SwapEndian($pSleep) & _                                     ; mov eax, [$pSleep]
            "FFD0" & _                                                         ; call eax
            "E9" & SwapEndian(-81) & _                                         ; jump back 81 bytes (start address)
            "C3" _                                                             ; Ret
            )

    ; Create new thread to execute code in
    $aCall = DllCall("kernel32.dll", "ptr", "CreateThread", _
            "ptr", 0, _
            "dword", 0, _
            "ptr", $pRemoteCode, _
            "ptr", 0, _
            "dword", 0, _
            "dword*", 0)

    If @error Or Not $aCall[0] Then
        Return SetError(8, 0, 0)
    EndIf

    Local $hThread = $aCall[0]

    ; Return thread handle
    Return $hThread

EndFunc   ;==>_ClockThisInAnotherThread


Func SwapEndian($iValue)
    Return Hex(BinaryMid($iValue, 1, 4))
EndFunc   ;==>SwapEndian

(I don't remember an author of this)

Edited by Godless

_____________________________________________________________________________

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...