AutoHotkey官方教程(一) 初學(xué)者向?qū)?/h1>

1 - 基礎(chǔ)

在我們開始我們的旅程之前, 讓我給你一些建議吧. 在本向?qū)е? 你會看到大量的文字和大量代碼. 為了更有效的學(xué)習(xí), 建議你閱讀這些文字并嘗試這些代碼. 然后再深入學(xué)習(xí)這些代碼. 你可以復(fù)制并粘貼此頁上的大多數(shù)示例. 如果你弄糊涂了, 試著再看一遍.

a. 下載并安裝 AutoHotkey

在學(xué)習(xí)使用 AutoHotkey(AHK) 之前, 你需要下載它. 下載后, 你可能會需要安裝它. 但這取決于你下載的版本. 對于本指南, 我們將使用安裝版, 因為對于新手來說, 它最容易設(shè)置.

文字指導(dǎo):

  1. 訪問 AutoHotkey 主頁: https://autohotkey.com/
  2. 點擊下載: https://autohotkey.com/download/ahk-install.exe
  3. 在安裝 Autohotkey 過程中, 需要你選擇安裝 UNICODE 或者 ANSI 版本. 你很可能需要 UNICODE 版本, 簡單點說, 如果你想要它支持非英文字符和數(shù)字, 那就選擇 UNICODE 版. 版本選擇之后, 一直點下一步直到你看到安裝(Install) 按鈕.
  4. 裝完了? 棒極了! 我們接著往下看.

b. 如何創(chuàng)建一個腳本

Autohotkey 安裝完成后, 你也許會想它能做些什么. AutoHotkey 不是魔法, 雖然我們都希望它是. 所以需要我們告訴它要去干什么. 而這個過程叫做 "寫腳本".

文字指導(dǎo):

  1. 右鍵點桌面空白處.

  2. 點擊"新建"菜單.

  3. 點擊里面的"AutoHotkey Script"新建一個腳本.

  4. 給腳本命名. 備注: 文件名必須帶 .ahk 后綴, 例如 MyScript.ahk

  5. 找到剛剛新建的腳本并右鍵點擊它.

  6. 點擊"Edit Script".

  7. 一個新窗口被彈出, 也許是記事本. 如果是這樣就成功了!

    現(xiàn)在你已經(jīng)創(chuàng)建了一個腳本, 我們需要加點內(nèi)容到腳本中. 如果需要用到內(nèi)置命令, 函數(shù)和變量, 請查看第 5 節(jié).

    這是一個使用 Send 命令創(chuàng)建的一個包含熱鍵的簡單腳本, 當(dāng)你按下熱鍵后, 它會向窗口發(fā)送一段文字.

    ^j::
    Send, My First Script
    Return
    

    稍后我們將進行更深入的研究. 在此之前, 我們先解釋一下上面的代碼:

    • 第一行: ^j:: 是熱鍵. ^ 代表 Ctrl, j 是字母 J. 任何在 :: 左邊 的字符表示您需要按下的熱鍵.
    • 第二行: Send, My First Script 表示如何發(fā)送按鍵. Send 是命令, 任何在逗號(,) 之后的內(nèi)容將會被鍵入.
    • 第三行: Return. Return 將會成為你最好的朋友. 它將停止執(zhí)行之后的代碼. 當(dāng)你的腳本包含越來越多的東西時, 使用 Return 會避免很多問題.
  8. 保存文件.

  9. 雙擊桌面上的文件來運行它, 打開記事本或者其它可以輸入文字的地方然后按下 Ctrl 和 J.

  10. 太好了! 你的第一個腳本完成了. 給自己一些獎勵, 然后返回閱讀本教程的其余部分.

c. 不要合并命令

當(dāng)你在寫代碼的時候, 你可能有強烈的沖動想在同一行放下幾個命令, 或者在一個命令中嵌套多個命令, 千萬不要這樣做. 在第 5 節(jié)我們將會告訴你為什么不要這么做, 同時, 我們還將告訴你應(yīng)該怎么做.

d. 如何在你的電腦上找到幫助文件

有幾種方法可以做到這一點, 假設(shè)你已將 AutoHotkey 安裝到默認位置:

方案 1:

  1. 找到開始菜單或屏幕上的開始按鈕, 通常在左下角.
  2. 點擊程序或者所有程序.
  3. 在列表中查找 AutoHotkey.
  4. 你會看到 AutoHotkey Help File. 點擊它.
  5. 完成!

方案 2:

  1. 去你的桌面.
  2. 找到我的電腦或者計算機. 然后打開它.
  3. 進入安裝 AutoHotkey 的硬盤. 可能是 *C:* 盤.
  4. Program Files 文件夾里找到 AutoHotkey.
  5. 查找 AutoHotkey.chm 或者找一個名叫 Autohotkey 并帶有黃色問號圖標(biāo)的文件.
  6. 完成!

2 - 快捷鍵 & 熱字串

什么是熱鍵? 熱鍵是一個發(fā)熱的按鍵, 開個玩笑. 熱鍵是用來觸發(fā)某些動作的按鍵或組合按鍵. 例如:

^j::
   Send, My First Script
Return

什么是熱字串? 當(dāng)你鍵入它們時, 熱字串主要用于擴展縮寫(自動替換). 當(dāng)然, 它也可以用來啟動任何腳本動作. 例如:

::ftw::Free the whales

這兩個例子的區(qū)別在于, 當(dāng)你按下 Ctrl+J 時, 熱鍵將會觸發(fā), 而熱字串會將你輸入的"ftw"轉(zhuǎn)換為"Free the whales".

"那么, 該如何創(chuàng)建一個熱鍵?" 好問題. 熱鍵是通過一對 :: 創(chuàng)建的. 按鍵名或組合按鍵名必須在 :: 左邊. 代碼則跟在后面, 以 Return 結(jié)束.

注意:: 當(dāng)然也有例外情況, 但很多時候容易引起混亂, 所以在向?qū)ы撝胁粫婕暗剿? 至少不是現(xiàn)在.

esc::
   MsgBox Escape!!!!
Return

熱字串在要觸發(fā)的文本兩邊各有一對 ::. 替換后的文本在第二對 :: 的右邊.

如上所述, 熱字串也可以啟動腳本動作. 和熱鍵一樣能干好多事, 真棒!

::btw::
   MsgBox You typed "btw".
Return

有一個好消息是: 你可以為每一個熱鍵, 熱字串, 標(biāo)簽等寫上多行的代碼.

^j::
MsgBox Wow!
MsgBox this is
Run, Notepad.exe
Winactivate, Untitled - Notepad  ; 無標(biāo)題 - 記事本
WinWaitActive, Untitled - Notepad  ; 無標(biāo)題 - 記事本
Send, 7 lines{!}{enter}
SendInput, inside the ctrl{+}j hotkey
Return

a. 鍵和其神秘符號

你可能會問"我怎么知道 ^ 代表 Ctrl?!". 好問題! 為了幫助你學(xué)習(xí) ^ 和其它符號的意思, 注意看這個表:

符號 描述
# Win(Windows 徽標(biāo)鍵)
! Alt
^ Control
+ Shift
& 用于連接兩個按鍵(含鼠標(biāo)按鍵) 合并成一個自定義熱鍵.

(完整的符號列表, 請查看熱鍵頁面)

此外, 對于所有/大多數(shù)能用于熱鍵雙冒號左邊的熱鍵名稱, 請參閱按鍵列表.

你可以通過在兩個按鍵(除手柄鍵) 之間, 使用 & 來定義一個組合熱鍵. 在下面的例子中, 你要按下Numpad0, 再按下Numpad1 或 Numpad2, 才能觸發(fā)熱鍵:

Numpad0 & Numpad1::
MsgBox You pressed Numpad1 while holding down Numpad0.
Return

Numpad0 & Numpad2::
Run Notepad
Return

如果你想知道熱字串是否和熱鍵一樣有很酷的修飾符, 答案是有!熱字串的修飾符在第一對 :: 之間, 例如:

:*:ftw::Free the whales

想要查看更多關(guān)于熱鍵和熱字串修飾符的信息和實例, 請訪問: 熱鍵熱字串.

b. 窗口特定的熱鍵/熱字串

有時候你也許想要熱鍵或熱字串只在某些特定窗口上工作(或禁用). 要做到這一點, 您需要使用其中的任意一個"高級"命令, 在它們前面帶有一個 #:

#IfWinActive
#IfWinExist

這些特殊的命令(技術(shù)上稱為"指令") 可以創(chuàng)建對上下文敏感的熱鍵和熱字串. 只需指定一個窗口標(biāo)題. 但在某些情況下, 你可能需要指定一個窗口句柄, 組或類. 如果想深入了解這些高級內(nèi)容, 點這里: #IfWinActive.

#IfWinActive Untitled - Notepad  ; 無標(biāo)題 - 記事本
#space::
MsgBox You pressed Win+Spacebar in Notepad.
Return

要關(guān)閉后續(xù)熱鍵或熱字串的上下文敏感性, 請指定任意 #IfWin 指令, 但將其所有參數(shù)留空. 例如:

; 無標(biāo)題 - 記事本
#IfWinActive Untitled - Notepad
!q::
MsgBox, You pressed Alt+Q in Notepad.
Return

; 任何不是無標(biāo)題 - 記事本的窗口
#IfWinActive
!q::
MsgBox, You pressed Alt+Q in any window.
Return

當(dāng) #ifwin 指令在腳本中從未使用, 所有的熱鍵和熱字串對所有窗口生效.

#IfWin 指令是與位置相關(guān)的: 它們將影響腳本中的位于他們之間所有熱鍵和熱字串. 它們也相互排斥的; 也就是說, 只有最近的一個會有效.

; 記事本
#IfWinActive ahk_class Notepad
#space::
MsgBox, You pressed Win+Spacebar in Notepad.
Return
::msg::You typed msg in Notepad

; 畫圖
#IfWinActive Untitled - Paint  ; 無標(biāo)題 - 畫圖
#space::
MsgBox, You pressed Win+Spacebar in MSPaint!
Return
::msg::You typed msg in MSPaint!

想要了解更多信息以及相似的命令, 請查看: #IfWinActive 頁面.

c. 一個文件包含多個熱鍵/熱字串

這是一些人的想法. 因此, 我在這里聲明一下: AutoHotkey 有能力將任意多 的熱鍵和熱字串放在一個文件中. 不管是 1 個, 還是 3253 個(或者更多).

#i::
Run, http://www.google.com/
Return

^p::
Run, notepad.exe
Return

~j::
Send, ack
Return

:*:acheiv::achiev
::achievment::achievement
::acquaintence::acquaintance
:*:adquir::acquir
::aquisition::acquisition
:*:agravat::aggravat
:*:allign::align
::ameria::America

上面的代碼是完全可以接受的. 多個熱鍵, 多個熱字串, 都包含在一個大的腳本文件里.

d. 示例

::btw::By the way  ; 替換"btw"為"By the way", 當(dāng)你按下結(jié)束符的時候.
:*:btw::By the way  ; 替換"btw"為"By the way"而不需要按下結(jié)束符.
^n::  ; Ctrl+N 熱鍵.
Run, notepad.exe  ; 當(dāng)你按下Ctrl+N, 將啟動記事本.
Return   ; 熱鍵內(nèi)容結(jié)束, 這之后的內(nèi)容將不會觸發(fā).
^b::  ; Ctrl+B 熱鍵
Send, {ctrl down}c{ctrl up}  ; 復(fù)制選定的文本. 也可以使用 ^c, 但這種方法更加可靠.
SendInput, [b]{ctrl down}v{ctrl up}[/b] ; 粘貼所復(fù)制的文本, 并在文本前后加上加粗標(biāo)簽.
Return  ; 熱鍵內(nèi)容結(jié)束, 這之后的內(nèi)容將不會觸發(fā).

3 - 發(fā)送按鍵

現(xiàn)在你決定發(fā)送(輸入) 一些按鍵到一個程序中. 你可以使用 Send 命令. 該命令表示發(fā)送按鍵, 模擬打字或按鍵操作.

但是在我們準(zhǔn)備使用 Send 之前, 還有一些常見問題要注意.

就像熱鍵一樣, Send 命令也有一些特殊的鍵. 這里列出 4 個最常見的特殊按鍵:

符號 描述
! 發(fā)送 Alt 鍵. 例如, Send This is text!a 將發(fā)送按鍵序列 "This is text" 并接著按下 Alt+A. 注意: !A 在某些程序中產(chǎn)生的效果與 !a 不同. 這是因為 !A 表示按下 Alt+Shift+A 而 !a 表示按下 Alt+A. 如果不確定, 請使用小寫字母.
+ 發(fā)送 Shift 鍵. 例如, Send +abC 會發(fā)送文本 "AbC", 而 Send !+a 會按下 Alt+Shift+A.
^ 發(fā)送 Control(Ctrl) 鍵. 例如, Send ^!a 會按下 Ctrl+Alt+A, 而 Send ^{Home} 則發(fā)送 Ctrl+Home. 注意: ^A 在某些程序中產(chǎn)生的效果與 ^a 不同. 這是因為 ^A 表示按下 Ctrl+Shift+A 而 ^a 表示按下 Ctrl+A. 如果不確定, 請使用小寫字母.
# 發(fā)送 Win 鍵(帶有 Windows logo 的按鍵), 因此 Send #e 會在按住 Win 鍵時按下字母 "e".

Send 頁面中有個很大的表格展示了 AHK 內(nèi)置的幾乎所有特殊鍵. 請點擊查看. 例如: {Enter}{Space}.

警告: 這個表并不適用于熱鍵. 也就是說, 當(dāng)你使用 Ctrl 或 Enter(或其它按鍵) 作為熱鍵時, 不要將它們括在 {} 中.

一個例子顯示了不應(yīng)該對熱鍵做的情景:

; 當(dāng)你創(chuàng)建熱鍵時...
; 錯誤的
{LCtrl}::
Send, AutoHotkey
Return

; 正確的
LCtrl::
Send, AutoHotkey
Return

很多人都有一個共同的問題, 他們認為花括號放在文檔中僅僅是為了好玩. 而實際上花括號是需要的. 它將告訴 AutoHotkey {!} 表示 "感嘆號" , 而不是要 "按下 Alt 鍵". 所以要仔細查看 Send 頁上的特殊鍵表格, 確保在合適的地方加上花括號. 例如:

Send, This text has been typed{!}
; 注意 {} 中的 !? 這是因為, 如果沒有 {}, AHK 將按下 Alt 鍵.
; 跟上面的例子類似, 只是這次是 Enter 鍵. AHK 將會輸出 "Enter"
; 如果 Enter 沒有加上 {} 的話.
Send, Multiple Enter lines have Enter been sent. ; 錯誤
Send, Multiple{Enter}lines have{Enter}been sent. ; 正確

另一個常見的錯誤是, 人們認為當(dāng)使用 Send 命令時, 所有內(nèi)容都需要加上花括號. 這是不對的. 如果不在特殊按鍵列表中, 沒必要加花括號. 你需要給普通字符, 數(shù)字加上括號, 甚至像.(句點) 這些符號加上{}. 而且, 當(dāng)你在使用 Send 命令時, 你可以一次性發(fā)送多個字符, 數(shù)字或符號. 所以沒有必要為每一個字符寫上一條 Send 命令. 例如:

Send, {a}       ; 錯誤
Send, 钝尸       ; 錯誤
Send, {c}       ; 錯誤
Send, {a}{c} ; 錯誤
Send, {abc}     ; 錯誤
Send, abc       ; 正確

想要表示按住或松開某個按鍵, 可以將這個鍵用花括號圍起來, 同時加上單詞 UP 或 DOWN. 例如:

; 下面這個例子表示按下一個鍵的時候再按下另一個鍵(或多個鍵).
; 如果其中一個方法不奏效, 試試另一個.
Send, ^s                     ; 都表示發(fā)送 CTRL+s 鍵擊
Send, {ctrl down}s{ctrl up}  ; 都表示發(fā)送 CTRL+s 鍵擊
Send, {ctrl down}c{ctrl up}
Send, {b down}{b up}
Send, {Tab down}{Tab up}
Send, {Up down}  ; 按下向上鍵.
Sleep, 1000      ; 保持1秒.
Send, {Up up}    ; 然后松開向上鍵.

現(xiàn)在你可能會想, "怎樣才能讓我在發(fā)送超長文本時保證文本的可讀性?". 很簡單. 使用我們所說的延續(xù)片段. 只需要在新行指定一個開括號, 然后是內(nèi)容, 最后在它自己的行上加上一個閉括號. 想了解更多信息, 請閱讀有關(guān)的 Continuation Sections(延續(xù)片段).

Send,
(
Line 1
Line 2
Apples are a fruit.
)

注意: Send 命令有幾種不同的形式. 每種形式有其特性. 如果一種形式的 Send 命令不能滿足你的需要, 可以試試另一種形式. 只需要將 "Send" 命令替換成接下來的其中一個: SendRaw, SendInput, SendPlay, SendEvent. 想要了解每一個命令的詳細內(nèi)容, 請閱讀這里.

a. 游戲

非常重要: 很多游戲, 尤其是新出的游戲, 都有反作弊系統(tǒng), 例如 GameGuard, Hackshield, PunkBuster 等. 且不說繞開反作弊系統(tǒng)是違反游戲規(guī)定的, 繞開反作弊本身也不太容易實現(xiàn).

如果游戲的反作弊系統(tǒng)導(dǎo)致你的熱鍵, 熱字串和 Send 命令失效, 你是不走運的. 然而有一些方法也許能提高在某些游戲中使用熱鍵的可能性, 但沒人能打包票一定能行. 所以, 盡可能嘗試所有你能想到的辦法, 不要輕易放棄.

還有一個關(guān)于 DirectX 的問題要注意. 當(dāng)你在 DirectX 游戲中使用 AutoHotkey 碰到問題時, 試試 FAQ 頁面中描述的情況. 當(dāng)你使用 PixelSearch, PixelGetColor或 ImageSearch 命令時, 你可能會碰到更多關(guān)于 DirectX 的問題. 畫面顏色可能會變成黑色(0x000000), 不管你設(shè)置的是什么顏色. 如果可能的話, 試試用窗口模式運行游戲. 這樣做能夠解決一些 DirectX 問題.

沒有萬能的辦法能確保 AutoHotkey 能運行在所有程序里. 如果你試了所有的辦法還是不行, 也許 AutoHotkey 暫時無法滿足你的需要.

4 - 打開程序 & 網(wǎng)頁

想要打開諸如畫圖(mspaint.exe), 計算器(calc.exe), 腳本.ahk 或一個文件夾, 你可以使用 Run 命令. 你還可以用這個命令打開一個網(wǎng)址, 比如 https://autohotkey.com/. 如果你想打開一個已經(jīng)安裝好的程序, 也很簡單, 就像這樣:

; 運行一個程序. 注意 大部分的程序可能需要完整路徑.
Run, %A_ProgramFiles%\Some_Program\Program.exe

; 打開一個網(wǎng)址
Run, https://autohotkey.com

還有其它一些高級特性, 比如命令行參數(shù)和 CLSID(Windows 類標(biāo)識符).

下面是一些關(guān)于 Run 命令的示例:

; 一些程序并不需要完整路徑, 如 Windows 標(biāo)準(zhǔn)程序.
Run, notepad.exe
Run, msPaint.exe

; 使用 AHK 內(nèi)置變量來打開"我的文檔"
Run, %A_MyDocuments%

; 打開一些網(wǎng)頁 
Run, https://autohotkey.com
Run, http://www.google.com

想要深入了解更多信息和示例, 請查看: Run 頁面.

5 - 命令和函數(shù)

AutoHotkey 有兩個重要的工具供開發(fā)者使用: 命令和函數(shù).

所有命令和內(nèi)置函數(shù)的列表可以在這里找到.

命令

你可以通過語法來分辨命令和函數(shù). 命令后面的參數(shù)無需使用圓括號, 而函數(shù)需要使用. 所以命令就像下面這樣:

Command, 參數(shù)1, 參數(shù)2, 參數(shù)3

當(dāng)你使用命令時, 不能將幾條命令放在同一行(IfEqual 除外). 也不能將一個命令作為參數(shù)插入到另一個命令. 例如:

MsgBox, Hello Run, Notepad.exe   ; 錯誤
MsgBox, Hello, Run, Notepad.exe  ; 錯誤

MsgBox, Hello      ; 正確
Run, Notepad.exe

跟函數(shù)不同的是, 命令使用"傳統(tǒng)語法". 也就是說: 當(dāng)你使用參數(shù)時, 你需要在參數(shù)的前后加上 %, 比如 %variable%. 而文本和數(shù)字則不需要加雙引號. This is some text. 另外, 與函數(shù)不同, 命令的參數(shù)不能進行運算.

如果確實想要在參數(shù)中進行運算, 可以使用單個 % 來強制定義一個表達式, 但我們這里將不涉及這些內(nèi)容.

函數(shù)

如上所述, 函數(shù)不同于命令的地方在于函數(shù)需要使用圓括號. 一個典型的函數(shù)是這樣的:

Function(參數(shù)1, 參數(shù)2, 參數(shù)3)

與命令相比, 函數(shù)有下面幾個主要差異:

  1. 你可以使用運算.

    SubStr(37*12, 1, 2)
    SubStr(A_Hour-12, 2)
    
  2. 參數(shù)前后不需要加上百分號:

    SubStr(A_Now, 7, 2)
    
  3. 函數(shù)可以嵌套另一個函數(shù):

    SubStr(A_AhkPath, InStr(A_AhkPath, "AutoHotkey"))
    
  4. 文本前后需要加上雙引號:

    SubStr("I'm scripting, awesome!", 16)
    

函數(shù)通常會返回一個值, 這一點與命令也不一樣. 命令需要設(shè)置 OutputVar 參數(shù)來保存結(jié)果, 而函數(shù)不需要. 將函數(shù)值賦給變量的最常用方法, 只需要這樣做:

MyVar := SubStr("I'm scripting, awesome!", 16)

這不是賦值的唯一方法, 但這是最常用的. 您使用 MyVar 來存儲函數(shù)的返回值, 即寫在 := 操作符的右邊, 更多信息, 請參閱函數(shù)頁面.

簡而言之:

; 這些是命令
MsgBox, This is some text.
StringReplace, Output, Input, AutoHotKey, AutoHotkey, ALL
SendInput, This is awesome{!}{!}{!}

; 這些是函數(shù)
SubStr("I'm scripting, awesome!", 16)
FileExist(VariableContainingPath)
Output:=SubStr("I'm scripting, awesome!", 16)

a. 代碼塊

代碼塊就是用一對花括號({}) 包圍起來的一段代碼, AutoHotkey 以此來判斷這些代碼是一個整體. 代碼塊經(jīng)常用于 IfLoop 中. 如果不使用花括號, 整塊代碼中只有第一行代碼能被執(zhí)行.

下面的代碼中, 當(dāng) MyVar 等于 5 時, 所有行都會執(zhí)行.

if (MyVar=5)
{
   MsgBox, MyVar equals %MyVar%!!
   ExitApp
}

下面的代碼中, 當(dāng) MyVar 等于 5 時, 才能顯示消息框. 但不管 MyVar 是否等于 5, 腳本都會終止:

if (MyVar = 5)
   MsgBox, MyVar equals %MyVar%!!
   ExitApp

If 后面只有一行與它有關(guān)的代碼, 下面的例子做了一個非常好的代碼編寫示范. 它實現(xiàn)的功能跟上面的代碼一樣, 但是我將第二行代碼進行了縮進排版, 這樣寫讓我們很容易就知道這行代碼是跟 If 相關(guān)的:

if (MyVar = 5)
   MsgBox, MyVar equals %MyVar%!!
MsgBox, We are now 'outside' of the if-statement. We did not need curly brackets since there was only one line below it.

6 - 變量

變量就像一個包含信息的便利貼. 它可以用于函數(shù), 命令或數(shù)學(xué)表達式中, 充當(dāng)存儲文本, 數(shù)字, 數(shù)據(jù)的作用. 如果沒有變量, 程序和腳本將會非常乏味.

給變量賦值有很多方法, 我們將會討論最常見的幾種方法. 請?zhí)貏e留意等號(=).

  • 傳統(tǒng)的文本賦值

    MyVar = Text

    這是給變量賦值最簡單的方法, 也是傳統(tǒng)的賦值方法. 只需要在等號后面輸入文本就行了.

  • 傳統(tǒng)的變量賦值

    MyVar = %MyVar2%

    和上面的方法類似, 只是你將一個變量所對應(yīng)的值賦給了另一個變量.

  • 傳統(tǒng)的混合賦值

    MyVar = %MyVar2% some text %MyVar3%.

    以上兩個傳統(tǒng)賦值的組合.

  • 表達式文本賦值

    MyVar := "Text"

    這是一個表達式賦值, 因為 := 之前. 任何文本都需要在引號中間.

  • 表達式變量賦值

    MyVar := MyVar2

    在表達式模式中, 變量不需要百分號.

  • 表達式數(shù)字賦值

    MyVar := 6 + 8 / 3 * 2 - Sqrt(9)

    感謝表達式, 你能進行計算!

  • 表達式混合賦值

    MyVar := "The value of 5 + " MyVar2 " is: " 5 + MyVar2

    以上三個表達式賦值的組合.

等號 (=) 和它前面的符號, 如 := += -= .= 等等, 這些被稱為賦值運算符, 并且總是需要一個表達式.

a. 什么時候使用百分號

關(guān)于變量一個最常見的問題是什么時候使用百分號(%). 希望下面這些內(nèi)容能夠消除一些困惑.

什么時候要使用百分號:

  • 當(dāng)你使用命令時(見前文), 參數(shù)是輸出變量 OutputVar 或輸入變量 InputVar 時除外.
  • 當(dāng)你使用傳統(tǒng)模式(等號前面沒有其它符號) 給一個變量賦值時.

什么時候不要使用百分號:

  • 參數(shù)中的輸入或輸出變量. 例如: StringLen, **OutputVar**, **InputVar**

  • 賦值時左邊的變量: 例如: **Var** = 123abc

  • 在傳統(tǒng) If 語句(不包括表達式) 中, 中左邊的變量: If Var1 < %Var2%

  • 在表達式中的變量, 例如:

    If (Var1 != Var2)
      Var1 := Var2 + 100
    

b. 獲取用戶輸入

有時候你想讓用戶來選擇某些值. 這可以有很多種方法, 但其中最簡單的辦法就是使用 InputBox 命令. 下面的例子展示了如何向用戶提出一堆問題并根據(jù)用戶的輸入完成一些事情:

InputBox, OutputVar, Question 1, What is your first name?
if (OutputVar="Bill")
   MsgBox, That's an awesome name`, %OutputVar%.

InputBox, OutputVar2, Question 2, Do you like AutoHotkey?
if (OutputVar2 = "yes")
   MsgBox, Thank you for answering %OutputVar2%`, %OutputVar%! We will become great friends.
 else
   MsgBox, %OutputVar%`, That makes me sad.

c. 其它示例

MsgBox, 4,, Would you like to continue?
IfMsgBox, No
    return  ; 如果選擇 No, 腳本將會終止.
MsgBox You pressed YES.  ; 否則, 用戶選擇了YES.
; 下面的例子展示了什么時候該使用百分號, 什么時候不該.
Var = Text  ; 賦值一些文本給一個變量(傳統(tǒng)的).
Number := 6  ; 賦值一個數(shù)字給一個變量(表達式).
Var2 = %Var%  ; 賦值一個變量給另一個(傳統(tǒng)的).
Var3 := Var  ; 賦值一個變量給另一個(表達式).
Var4 .= Var  ; 追加一個變量到另一個的末尾(表達式).
Var5 += Number  ; 將變量的值與另一個相加(表達式).
Var5 -= Number  ; 將變量的值減去另一個(表達式).
Var6 := SubStr(Var, 2, 2)  ; 變量在函數(shù)中. 這總是一個表達式.
Var7 = %Var% Text  ; 賦值一個變量給另一個變量并帶有一些額外的文本(傳統(tǒng)的).
Var8 := Var " Text"  ; 賦值一個變量給另一個變量并帶有一些額外的文本(表達式).
MsgBox, %Var%  ; 變量在命令中.
StringSplit, Var, Var, x  ; 在命令中的變量, 但是它們作為輸入或輸出變量.
if (Number = 6)  ; 只要 IF 有括號, 它就是一個表達式, 所以不需要百分號.
if (Var != Number)  ; 只要 IF 有括號, 它就是一個表達式, 所以不需要百分號.
if Number = 6  ; 如果沒有括號, 那么 IF 是傳統(tǒng)的. 不過, 只有賦值語句"右邊"的變量需要百分號. 
if Var1 < %Var2%  ; 如果沒有括號, 那么 IF 是傳統(tǒng)的. 不過, 只有賦值語句"右邊"的變量需要百分號. 

7 - 對象

對象是一種組織數(shù)據(jù)以實現(xiàn)更高效使用的方法. 有時候?qū)ο蟊划?dāng)作數(shù)組, 在這重點聲明一下所有的數(shù)組都是對象. 我們調(diào)用對象不同的東西取決于我們使用它們的目的, 但是所有對象都是相同的.

對象基本上是變量的集合. 變量的名稱叫做"鍵", 變量的內(nèi)容叫做"值".

當(dāng)你聽到人們把一個對象叫做 數(shù)組索引數(shù)組時, 說明這個對象的鍵是從 1 開始遞增的連續(xù)數(shù)字. 當(dāng)你聽到人們把一個對象叫做 關(guān)聯(lián)數(shù)組, 說明這個對象的鍵要么使用字符串(或文本), 要么使用不連續(xù)的數(shù)字. 有時可能是兩者的混合, 也有可能是數(shù)列!

一個對象的鍵和值可以是什么, 沒有任何限制, 它們甚至可以是另一個數(shù)組! 如果一個對象的值也是數(shù)組, 我們把它叫做 嵌套數(shù)組, 這個我們以后再解釋.

您可能想要使用對象的原因有很多, 一些例子:

  • 當(dāng)你需要描述一組有序列表時, 比如雜貨店列表(這種情況最好使用索引數(shù)組)
  • 當(dāng)你需要描述一個圖形方格時, 比如一個棋盤游戲(這種情況最好使用嵌套對象)
  • 當(dāng)你需要描述一組事物而每樣事物都有自己的名稱時, 比如描述水果的特性(這種情況最好使用關(guān)聯(lián)數(shù)組)

a. 創(chuàng)建對象

我們有很多方法可以創(chuàng)建對象, 下面介紹最常用的幾種方法:

  • 方括號語法

    MyObject := ["one", "two", "three", 17]

    這將從有時被稱為"索引數(shù)組"的內(nèi)容開始. 索引數(shù)組是一個表示項目列表的對象, 索引號從 1 開始連續(xù)遞增. 在本例中, 值 "one" 存儲在對象鍵 1(又叫做索引號1), 值 17 存儲在對象鍵 4(又叫做索引號 4).

  • 大括號語法

    Banana := {"Color": "Yellow", "Taste": "Delicious", "Price": 3}

    這將通過定義有時被稱為"關(guān)聯(lián)數(shù)組"來開始. 關(guān)聯(lián)數(shù)組是數(shù)據(jù)的集合, 其中每個條目都有自己的名稱. 在這個例子中, 值 "Yellow" 存儲在對象鍵 "Color" 中. 同樣的, 值 3 存儲在對象鍵 "Price" 中.

  • 數(shù)組函數(shù)

    MyObject := Array("one", "two", "three", 17)

    這種方式跟方括號語法形式一樣, 區(qū)別僅僅是采用了函數(shù)的形式.

  • 對象函數(shù)

    Banana := Object("Color", "Yellow", "Taste", "Delicious", "Price", 3)

    這種方式跟大括號語法形式一樣, 區(qū)別僅僅是采用了函數(shù)的形式.

請注意, 所有這些方法都創(chuàng)建了同一樣?xùn)|西(也就是對象), 區(qū)別僅僅是對象的鍵不一樣.

b. 使用對象

使用對象有很多方式, 包括檢索值, 設(shè)置值, 添加更多的值等等.

設(shè)置值:

  • 方括號表示法

    Banana["Pickled"] := True *; 這個香蕉爛透了. 呃...*

    在對象中設(shè)置值跟設(shè)置變量的值一樣簡單. 你需要做的是把方括號所代表的值在表達式賦值運算符 := 的左邊.

  • 句點表示法

    Banana.Consistency := "Mushy"

    和上面一樣, 但是用點(.) 符號.

檢索值:

  • 方括號表示法

    Value := Banana["Color"]

    這允許你使用表達式作為鍵從對象中獲取值. 在這個例子中, 我使用表達式 "Color", 不要驚訝我僅使用鍵 Color 就會得到一個包含單詞 "Yellow" 的值, 因為我們事先(在上一節(jié)) 就設(shè)置了鍵 Color.

  • 句點表示法

    Value := Banana.Color

    僅允許使用原樣的字串作為鍵名. 在句點表示法中鍵名不能使用變量.

增加新的鍵和值:

  • 方括號表示法

    MyObject["NewerKey"] := 3.1415

    想要直接添加一對鍵和值, 只需設(shè)置一個尚不存在的鍵即可.

  • 句點表示法

    MyObject.NewKey := "Shiny"

    和上面一樣, 但是用點符號.

  • InsertAt(在..插入) 法

    MyObject.InsertAt(Index, Value1, Value2, Value3...)

    Index(索引) 為任意整數(shù)鍵. 這會將所有更高的整數(shù)鍵的索引向上移動插入值的數(shù)量, 即使是空缺的也一樣(例如, 假設(shè)只有鍵 1 和 100 存在, 當(dāng)插入一個值到第 50 個鍵的位置時, 將導(dǎo)致原來位于 100 的鍵的索引變成 101).

  • Push(推送) 法

    MyObject.Push(Value1, Value2, Value3...)

    "追加" 值到數(shù)組 MyObject 的尾部. 換句話說, 它將插入的值放在 最高整數(shù)鍵 + 1 的位置.

移除鍵和值:

  • 用空白填充值

    Banana.Consistency := ""最簡單的刪除值的方法就是用空白填充. 你可以將其賦值為 ""(兩個連續(xù)的雙引號), 也就是常說的 空字符串. 這不會刪除鍵, 但是它將使值看起來與從未賦值一樣. 可以通過使用 HasKey 方法得知鍵依然存在, 而且鍵也會出現(xiàn)在 for 循環(huán)中. (我們一會再解釋 For 循環(huán))

  • 刪除法

    RemovedValue := MyObject.Delete(AnyKey)這和接下來的方法將刪除鍵 值. MyObject[AnyKey] 先前的值將存儲在 RemovedValue 中.NumberOfRemovedKeys := MyObject.Delete(FirstKey, LastKey)允許你刪除 FirstKeyLastKey 之間的一系列的編號/整數(shù)或字符串鍵. 它給出的值將是被刪除的鍵的數(shù)量, 如果你的鍵之間有間隙, 這是有用的(例如你指定鍵從 1 到 4, 但是鍵 2 不存在, 這將設(shè)置 NumberOfRemovedKeys 為 3, 因為只有三個鍵被移除).

  • Pop(拋出) 法

    MyObject.Pop()這將刪除最高的整數(shù)鍵, 并返回這個鍵對應(yīng)的值. 而且這種形式不會影響其它鍵的索引順序(因為沒有比它更高的序列了).

  • RemoveAt(在..刪除) 方法

    RemovedValue := MyObject.RemoveAt(Index)``NumberOfRemovedKeys := MyObject.RemoveAt(Index, Length)這將移除從 IndexIndex + Length - 1(包含) 之間的所有鍵(例如 Index 為 5, Length 為 3, 則將刪除鍵 5, 6, 7 這三個鍵). 如果 Length 省略則默認為 1. 移除這些鍵之后, 更高數(shù)字或整數(shù)的鍵將向下填充空缺, 所以如果有個值位于 Index + Length 那么它現(xiàn)在的位置就是 Index. 這很像 InsertAt 方法操作多個指定值的操作.

8 - 其它有用的東西

親愛的朋友, 當(dāng)你閱讀到這里, 說明快要結(jié)束我們這段旅程了. 我希望你有所收獲. 最后, 我將告訴你一些我認為你可能有用的東西. 希望你過的愉快!

a. 神秘的 [ ]

在幫助文檔中, 你可能會發(fā)現(xiàn)有兩個符號([]) 經(jīng)常出現(xiàn)在幾乎每一頁開頭的黃色代碼框中. 方括號中的內(nèi)容代表可選的. 也就是說, 如果你不需要這些參數(shù)你完全可以不管它. 不過要強調(diào)一點, 當(dāng)你在寫代碼時, 千萬不要把 [ ] 也寫上了.

p>例如, 在 ControlGetText命令頁面, 你可能會看到這段代碼:

ControlGetText, OutputVar , Control, WinTitle, WinText, ExcludeTitle, ExcludeText

所以你可以簡單的寫成這樣:

ControlGetText, OutputVar

或者再加上一些細節(jié):

ControlGetText, OutputVar, Control, WinTitle

如果你想只使用參數(shù) ExcludeTitle 而不想使用參數(shù) WinTextWinTitle, 怎么辦? 很簡單!

ControlGetText, OutputVar, Control,,, ExcludeTitle

請注意, 你不能忽略參數(shù), 只是需要將它們的位置留空. 如果你像下面這樣忽略 WinTitle, WinText, 將會產(chǎn)生錯誤:

ControlGetText, OutputVar, Control, ExcludeTitle

b. 查找你的 AHK 版本

你可以運行下面的代碼來查看你的 AHK 版本信息:

MsgBox, %A_AhkVersion%

你也可以到開始菜單或安裝路徑下的幫助文件(即本文) 中去找.

c. 嘗試與錯誤

嘗試和錯誤是非常普遍而高效的學(xué)習(xí)方法. 與動不動就問這問那相比, 有時候花點時間(也許是長年累月) 親手嘗試可能會學(xué)的更快.

如果你在嘗試新東西的過程碰到錯誤, 不要緊, 就從解決這個錯誤開始. 嘗試解決這個錯誤, 一次不行就兩次. 多次嘗試后還是解決不了, 可以打開幫助文件學(xué)習(xí)哪些能做哪些不能做, 然后修改你的代碼再試試. 試試, 失敗, 試試, 失敗, 試試, 試試, 再試試, 失敗, 失敗, 成功!

這也是很多大師們的學(xué)習(xí)經(jīng)歷. 不過也不要害怕提問, 我們不會咬人(至少不會咬的太狠). 學(xué)習(xí)總需要時間慢慢積累, 大師也不是一天練成的.

"若最初你沒有成功, 努力, 努力, 不斷的努力." - 威廉 · 愛德華 · 希克森.

d. 縮進

縮進這個事非常重要! 你的代碼沒有它也能正常運行, 可是如果沒有縮進會讓閱讀代碼變成一件非常痛苦的事. 也許一小段代碼(少于 25 行) 不用縮進也沒有太大關(guān)系, 但是代碼一旦增多, 縮進就非常有必要. 所以, 學(xué)習(xí)使用縮進越快越好. 縮進沒有固定的風(fēng)格, 但最好保持一種風(fēng)格.

"什么是縮進?" 你可能會問? 簡單的說就是在代碼和頁面邊界保留一段距離, 這樣可以區(qū)分這一段代碼是屬于哪一段代碼. 有些人習(xí)慣使用 3, 4 個空格或 1 個 tab 來表示縮進, 每一級用一次縮進.

不用縮進:

if (car="old")
{
MsgBox, The car is really old.
if (wheels = "flat")
{
MsgBox, This car is not safe to drive.
Return
}
else
{
MsgBox, Be careful! This old car will be dangerous to drive.
}
}
else
{
MsgBox, My`, what a shiny new vehicle you have there.
}

使用縮進:

if (car="old")
{
   MsgBox, The car is really old
   if (wheels = "flat")
   {
      MsgBox, This car is not safe to drive.
      Return
   }
   else
   {
      MsgBox, Be careful! This old car will be dangerous to drive.
   }
}
else
{
   MsgBox, My`, what a shiny new vehicle you have there.
}

關(guān)于縮進, 維基百科上縮進樣式頁面有很多風(fēng)格示例. 建議選一種你喜歡的或你認為最容易閱讀的風(fēng)格來學(xué)習(xí).

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者

  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子揣非,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件卓研,死亡現(xiàn)場離奇詭異,居然都是意外死亡睹簇,警方通過查閱死者的電腦和手機奏赘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來带膀,“玉大人志珍,你說我怎么就攤上這事《膺叮” “怎么了伦糯?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長嗽元。 經(jīng)常有香客問我敛纲,道長,這世上最難降的妖魔是什么剂癌? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任淤翔,我火速辦了婚禮,結(jié)果婚禮上佩谷,老公的妹妹穿的比我還像新娘旁壮。我一直安慰自己监嗜,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布抡谐。 她就那樣靜靜地躺著裁奇,像睡著了一般。 火紅的嫁衣襯著肌膚如雪麦撵。 梳的紋絲不亂的頭發(fā)上刽肠,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天,我揣著相機與錄音免胃,去河邊找鬼音五。 笑死,一個胖子當(dāng)著我的面吹牛羔沙,可吹牛的內(nèi)容都是我干的躺涝。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼扼雏,長吁一口氣:“原來是場噩夢啊……” “哼诞挨!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起呢蛤,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤惶傻,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后其障,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體银室,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年励翼,在試婚紗的時候發(fā)現(xiàn)自己被綠了蜈敢。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡汽抚,死狀恐怖抓狭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情造烁,我是刑警寧澤否过,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站惭蟋,受9級特大地震影響苗桂,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜告组,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一煤伟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦便锨、人聲如沸围辙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽酌畜。三九已至,卻和暖如春卿叽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背恳守。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工考婴, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人催烘。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓沥阱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親伊群。 傳聞我的和親對象是個殘疾皇子考杉,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 枳花落,微風(fēng)訪舰始,今宵酒醒歸何方崇棠? 風(fēng)塵起,流年傷丸卷,昨昔追憶成迷惘枕稀。 念凡塵,又別觴谜嫉,觥籌交錯能幾望萎坷? 怕將離,也息...
    七里塵思逸成香閱讀 1,260評論 19 16
  • 一個人和青蛙神聯(lián)姻的故事以及青蛙神趣事沐兰。 有一個地方哆档,信奉青蛙神,當(dāng)?shù)赜星嗤軓R住闯,里面全都是大大小小的青蛙瓜浸。 有一家...
    Hushering閱讀 2,014評論 0 0
  • 男主在西餐廳的觥籌交錯中深深地感到孤獨,那些吃飯的人比原,那些談笑的話斟叼,那些飄散的煙霧。什么都很真實春寿,唯獨沒有人在聽他...
    阿阿阿當(dāng)閱讀 688評論 3 3
  • 這是白云蘭子陪伴你的第407天 認真閱讀工作群里绑改,分享好文“山本耀司為何滿嘴雞湯谢床?”有感: 一兄一、山本耀司內(nèi)心反叛精...
    白云蘭子閱讀 3,468評論 0 4