のら(NORA)のブログ

主にソフトについて備忘録で(手抜き)書いているのです!ご自由に観覧しやがれ、です。

autohotkey2.0勉強中(翻訳)その8-2(関数編その2)

はじめに

翻訳とかあんま得意じゃないんだけど、関数編その2
その1はこちら
間違いあったらコメくれれば訂正します。というか自分用だし、間違えて覚えてしまうから(´・ω・`)

参考:公式ヘルプ

以下その1からの続き

ローカル変数とグローバル変数

ローカル変数

  • 関数の中で使用される変数(組み込み変数を除く)は、関数の呼出しごとに作成され、関数から戻る際に破棄される
  • そのため、関数外からは参照できないローカル変数となる
  • その結果、ローカル変数はグローバル変数と同じ名前を持ったとしても、両方とも別の内容を持つ
  • 分離された関数は、同じ変数名を(安全に)使用できる
  • staticでないすべてのローカル変数は、関数が戻るときに自動的に解放される(空になる)
  • 関数内で作成された変数は、デフォルトではローカルだが、次の例外がある
  • 以下のスクリプトは期待通りの動作をしない
ex: xの値を設定する関数を作りたい  
x := 0  
SetX(10)  
MsgBox,%x%  

SetX(val){  
 x := val  
}

グローバル変数

  • 関数外の既存のグローバル変数を参照する(または新しい関数を作成する)には、その変数を使用する前にその変数をグローバルとして宣言する必要がある
  • 変数名の前に「global」と書くとその変数はグローバル変数として扱われる
  • 複数の変数名を「,」で区切ってまとめて書くことができる(例はその他参照)
  • 関数内で「Array%i%」のような動的変数を使用した場合、ローカル変数として扱われる
  • StringSplitコマンドなどで配列を作成する場合、通常はローカル変数として作成される
    • ただし、配列の最初の要素がglobal宣言されている場合は、全ての要素がグローバル変数として作成される
ex: LogToFile(TextToLog)  
{  
    global LogFileName  ;この関数はすでにほかの部分で値がセットされている  
    FileAppend, %TextToLog%`n, %LogFileName%  
}  
仮定(前提)グローバルモード

関数が大量のグローバル変数にアクセスしたり作成したりする必要がある場合、関数の最初の行に"global"という単語をつけて、すべての変数がグローバル変数になるように定義することができる

ex: SetDefaults() { global MyGlobal := 33 ;グローバル変数を作成、必要に応じて変数に初期値を代入する Global1 ;これもグローバル変数になる local x, y:=0, z ;ローカル変数にしたい場合はこのように宣言しなければならない }

この仮定グローバルモードは、関数がArray%A_Index%に値を代入するループなどのグローバル擬似配列を作成するために関数で使用することもできる

スーパーグローバル変数

  • グローバル宣言が関数の外に出現する場合は、デフォルトですべての関数に(グローバルが)適用される
  • これにより、各関数の変数を再宣言する必要がなくなる
  • ただし、同じ名前のパラメータまたはローカル変数が宣言されている場合は、グローバル変数よりもそちいが優先される
  • また、classキーワードによって作成された変数もスーパーグローバルになる

static変数

  • static変数は常に暗黙的にローカルだが、ローカル変数との違いは呼び出し間でその値が記憶されるという点
  • 宣言方法はグローバル変数と同様でいい
  • 複数の変数名を「,」で区切ってまとめて書くことができる(例はその他参照)
ex: LogToFile(TextToLog)  
{  
    static LoggedLines := 0  
    LoggedLines += 1  ; Maintain a tally locally (its value is remembered between calls).  
    global LogFileName  
    FileAppend, %LoggedLines%: %TextToLog%`n, %LogFileName%  
}  
  • static変数は、宣言と同じ行で := の後に任意の式をつけて初期化することができる
  • たとえば、static X:=0, Y:=“fox"など
  • 各静的変数は1回だけ初期化される
  • static変数は、スクリプトファイルに表示される順序で、スクリプトの自動実行セクションの実行前に初期化される

仮定(前提)staticモード

関数の最初の行に"static"という単語を付けることによって、すべての変数がstatic(そのパラメータを除く)であると仮定するように定義できる

ex: GetFromStaticArray(WhichItemNumber) { static static FirstCallToUs := true ;static宣言のイニシャライザは、起動時に1回だけ実行される if FirstCallToUs ;最初の呼び出しではstatic配列を作成しるが、それ以降の呼び出しでは作成されない { FirstCallToUs := false Loop 10 StaticArray%A_Index% := "Value #" . A_Index } return StaticArray%WhichItemNumber% }

staticモードでは、staticであってはならない変数は、ローカルまたはグローバルとして宣言する必要がある

ローカルとグローバルについてその他

  • 以下の例のように、複数の変数をカンマで区切って同じ行に宣言することができる
ex: global LogFileName, MaxRetries := 5  
static TotalAttempts := 0, PrevResult
  • ローカル変数またはグローバル変数は、宣言と同じ行で:=の後に任意の式を付けて初期化することができる
  • static初期化子とは異なり、ローカルとグローバルのイニシャライザは、関数が呼び出されるたびに実行されるが、コントロールのフローが実際にそれらに到達する場合にのみ実行される
  • つまり、「local x := 0」のような行は、「local x」の宣言とそれに続く「x := 0」という2つの別々の行を書くのと同じ効果を持つということ
  • ローカル、グローバル、およびstaticという単語は、スクリプトの起動時にすぐに処理されるため、変数はif文によって条件付きで宣言することはできない
  • つまり、ifまたはelseのブロック内の宣言は、宣言と関数の閉じ括弧の間のすべての行に対して無条件に有効になる
  • また現在、グローバル配列%i%などの動的変数を宣言することはできない

関数の動的呼び出し

  • 関数(組み込み関数でさえ)は、パーセント記号で動的に呼び出すことができる
  • たとえば、%Var%(x, “fox”)は名前がVarに含まれる関数を呼び出す
  • 同様に、 Func%A_Index%()は、A_Indexの現在の値に応じて、Func1()またはFunc2()などを呼び出す
  • Var in %Var%()には、関数名または関数オブジェクトを含めることができる
  • 関数が存在しない場合は、デフォルトの基本オブジェクトのCallメソッドが代わりに呼び出される(通常、このメソッドが定義されていない場合は、__Callメタ関数が呼び出される)
  • 以下のいずれかの理由により関数を呼び出せない場合は、例外がスローされる
  • 存在しない関数を呼び出すことはIf IsFunc(VarContainingFuncName)を使用して回避することができる
  • 組み込み関数を除いて、呼び出される関数の定義は、#Includeやライブラリ関数への非動的呼び出しなどの手段によってスクリプトに明示的に存在しなければならない
  • IsFunc()の戻り値(必須パラメータの数に1を足した値)をチェックすることによって避けることができるパラメータは少ない
  • 注:あまりにも多くのパラメータを渡すことは許容されるが、余分なパラメータは完全に評価され(関数への呼び出しを含む)、破棄される
  • 関数への動的呼び出しは、スクリプトの実行が開始される前に通常の呼び出しが参照されるため、通常の呼び出しよりもわずかに遅くなる

再帰呼び出し

  • 関数の中からその関数自身を呼び出すテクニックを再帰呼び出しという
  • 下記の例は、パラメータで与えられたnの階乗を求める関数である
ex: Factorial(n){  
If n := 1  
Return 1  
Else  
Return n * Factorial(n * 1)  
}
  • なお、再帰呼び出しを行う関数で、「ByRef」による参照渡しのパラメータにローカル変数を与えると、呼び出し先の当該変数が参照されるようになってしまうため、以下のスクリプトは正しく動作しない
ex: Factorial(ByRef n){  
If n := 1 ;(2)ここのnでは呼び出し元のxではなく、呼び出された側のxが参照されてしまう    
Return  
x := n * 1  
Factorial(x) ;(1)ここでローカル変数xを参照渡しすると  
n *:= x  
}

boolean型の短絡評価

  • 式の中でAND、OR、および3項演算子が使用されている場合、それらは短絡してパフォーマンスを向上させる(関数呼び出しが存在するかどうかにかかわらず)
  • 短絡は、最終結果に影響を及ぼし得ない部分の評価を省略すること
  • 概念の説明
ex: if (ColorName <> "" AND not FindColor(ColorName))  
MsgBox %ColorName% could not be found.
  • 上記の例では、ColorName変数が空の場合、FindColor()関数は呼び出されない
  • これは、ANDの左側が偽であるため、右側が最終結果を真にすることができないから
  • この振る舞いにより、関数がグローバル変数の内容を変更するなどの副作用が起こる
  • また、副作用はその関数がANDまたはORの右側で呼び出されると、決して発生しないことを認識することが重要
  • また、短絡評価がネストされたANDおよびORにカスケードすることにも注意する必要がある
  • たとえば、次の式では、ColorNameが空白のときは常に一番左の比較が行われるこれは、左側が確実に最終的な答えを決定するのに十分であるから
ex: if (ColorName = "" OR FindColor(ColorName, Region1) OR FindColor(ColorName, Region2))
break   ; Nothing to search for, or a match was found.
  • 上記の例で示されているように、パフォーマンスの向上のために、ANDまたはORの右側では、関数が呼び出されないことがある
  • この技法は、パラメータの1つが空の文字列など、不適切とみなされる値を渡されるときに関数が呼び出されないようにするためにも使用できる
  • 三項条件演算子(?:)も、不必要な分岐を評価しないことによって短絡する

関数内でのサブルーチンの使用

  • 関数は他の関数の定義を含むことはできないが、サブルーチンを含めることができる
  • 他のサブルーチンと同様に、Gosubを使用してそれらを起動し、Returnで戻る(この場合、ReturnはGosubに属し、関数ではない)
  • 関数がGosubを使用して関数外にあるサブルーチンにジャンプする場合、外部の変数はすべてグローバルであり、サブルーチンが戻るまで関数のローカル変数にはアクセスできまない
  • ただし、A_ThisFuncには引き続き関数の名前が含まれる
  • Gotoは関数の内部から外部にジャンプすることはできないが、Gosubに外部/パブリックサブルーチンを関数として渡し、そこからGotoを実行することは可能
  • Gotoの使用は一般的には推奨されないが、関数内で同じ関数内の別の位置(ラベル)にジャンプすることがでる
  • これにより、多くのリターンポイントを持つ複雑な関数を簡単にすることができる
  • また、関数外のラベルにGotoでジャンプしようとした場合、その行は無視される
  • これらの関数のすべては、返される前にクリーンアップを行う必要がある
  • 関数には、タイマー、GUI g-label、メニュー項目などの外部呼び出しサブルーチンが含まれている場合がある
  • これは#Includeで使用し、別のファイルにカプセル化するために一般的に行われ、スクリプトの自動実行セクションとの干渉を防げる
  • ただし、次の制限が適用される
  • このようなサブルーチンでは、関数が正常に呼び出される場合は、ローカル変数ではなくstatic変数のみを使用する必要がある
    • これは、関数呼び出しスレッドを中断するサブルーチンスレッド(またはその逆)が中断されたスレッドによって見られるローカル変数の値を変更できるため
    • さらに、関数が呼び出し元に戻ると、そのローカル変数はすべて空白になってメモリが解放される
  • このようなサブルーチンでは、GUI制御変数としてグローバル変数(static変数ではない)のみを使用する必要がある
  • 関数がサブルーチンスレッドによって入力されると、そのスレッドによって作成された動的変数への参照はすべて(配列を作成するコマンドを含む)グローバルとして扱われる
  • 同様に、ローカルラベルは動的に参照することはできない

Return、Exit、および一般的な備考

  • 関数内の実行フローが関数の閉じ括弧(関数の終了地点)に到達する前にReturnに到達すると、関数は終了し、空の値(空文字列)を呼び出し元に返す
  • 関数が明示的にReturnのパラメータを省略するときも、空の値が返される
  • 関数がExitコマンドを使用して現在のスレッドを終了すると、その呼び出し元は戻り値をまったく受け取らない
  • たとえば、Var= Add(2,3)ステートメントは、Add()が終了するとVarを変更しない
  • 存在しないファイルを実行するなどのランタイムエラーが発生した場合(UseErrorLevelが有効でない場合)も同じことが起こる
  • 関数は、覚えやすい余分な値を返す目的で、ErrorLevelの値を変更することがある
  • 空白の値(空文字列)が1つ以上ある関数を呼び出すには、以下の例のように空のクォートペアを使用する
ex: FindColor(ColorName、 "")
  • 関数を呼び出すことは新しいスレッドを開始しないので、SendModeやSetTitleMatchModeなどの設定に対して関数が行った変更は、呼び出し元に対しても有効である
  • 関数の呼び出し元は、存在しない変数または配列要素を渡すことがありるこれは、関数が対応するパラメータがByRefであると期待している場合に便利
  • たとえば、GetNextLine(BlankArray%i%)を呼び出すと、呼び出し元が関数内にあるかどうか、および仮定グローバルモードが有効かどうかによって、変数BlankArray%i%がローカルまたはグローバルとして自動的に作成される
  • 関数内で使用すると、ListVarsは関数のローカル変数とその内容を表示するこれは、スクリプトデバッグに役立つ

スタイルと命名規則

  • 特別な変数に別個の接頭辞が与えられていると、複雑な関数が読みやすく保守的になることがある
  • たとえば、関数のパラメータリストの先頭に “p"または "p_"を付けて名前を付けると、特別な性質が一目でわかりやすくなる
  • 同様に、接頭辞「r」または「r」はByRefパラメータに使用でき、「s」または「s」はstatic変数に使用できる
  • One True Brace(OTB)スタイルは、オプションで関数を定義するために使用できる
ex:  Add(x,y){  
Return x + y  
}

#Includeを使用して複数のスクリプト間で関数を共有する

  • #Includeディレクティブは、外部ファイルから関数をロードするために(スクリプトの先頭でも)使用できる

関数のライブラリ:標準ライブラリとユーザライブラリ

  • スクリプトは、#Includeを使わなくても、外部ファイルの関数を呼び出すことができる
  • これが機能するには、関数と同じ名前のファイルが以下のライブラリディレクトリのいずれかに存在している必要がある
ex: 
%A_ScriptDir%\Lib\  ; ローカルライブラリ  
%A_MyDocuments%\AutoHotkey\Lib\  ; ユーザーライブラリ  
path-to-the-currently-running-AutoHotkey.exe\Lib\  ; 標準ライブラリ
  • たとえば、存在しない関数MyFunc()を呼び出すと、プログラムはユーザーライブラリ内の"MyFunc.ahk"という名前のファイルを検索する
  • そこで見つからなければ、標準ライブラリで検索される
  • まだ見つからず、関数の名前にアンダースコア(たとえばMyPrefix_MyFunc)が含まれている場合、プログラムは両方のライブラリでMyPrefix.ahkという名前のファイルを検索し、存在する場合は読み込まれる
  • これにより、MyPrefix.ahkに、関数MyPrefix_MyFuncと名前がMyPrefix_で始まる他の関連関数の両方が含まれるようになる

  • ローカルライブラリは、ユーザライブラリと標準ライブラリの前に検索される

  • MyFunc()のような直接的な関数呼び出しだけでは、ライブラリを自動インクルードすることができる

  • タイマーやGUIイベントなど、関数が動的にまたは間接的にしか呼び出されない場合は、ライブラリーをスクリプトに明示的に組み込む必要がある

  • ライブラリファイルには通常、ファイル名と同じ名前の関数が1つしか含まれていませんが、プライベート関数とそれによってのみ呼び出されるサブルーチンも含まれている

  • これらの関数はグローバルな名前空間にあるため、別の名前にすべきで、スクリプト内のどこからでも呼び出すことができる

  • ライブラリファイルが#Includeを使用する場合、#Includeの作業ディレクトリはライブラリファイル自身のディレクトリになる

  • これは、その関数とそれに関連する他の関数を含む大きなライブラリファイルへのリダイレクトを作成するために使用できる

  • スクリプトコンパイラ(ahk2exe)は、ライブラリ関数もサポートしている

  • ただし、AutoHotkey.exeのコピーは、コンパイラディレクトリの上のディレクトリに存在する必要がある(通常の状態)
  • AutoHotkey.exeが存在しない場合、コンパイラは引き続き動作しるが、ライブラリ関数は自動的には使用できない

  • ライブラリから取り込まれた関数は、スクリプトの実行が開始される前にプリロードされているため、他の関数と同様に機能する

組み込み関数

  • 組み込み関数のパラメータリストの末尾にある任意のオプションパラメータは、完全に省略することができる
  • たとえば、WinExist(“Untitled - 注意pad”)は、他の3つのパラメータが空白とみなされるため有効
  • スクリプトが同じ名前の独自の関数を定義している場合、組み込み関数はオーバーライドされる
  • たとえば、標準のスクリプトの代わりに呼び出される独自のカスタムWinExist()関数をスクリプトに含めることができる
  • ただし、スクリプトは元の関数を呼び出す方法はない
  • DLLファイルに存在する外部関数は、DllCall()で呼び出すことができる
  • 下の特定の組み込み関数の詳細については、各リンク先を参照(後日)

組み込み関数一覧

よく使うもの

使い始めでもよく使ってるから実際結構使うんじゃない

関数名 関数の説明
FileExist ファイルまたはフォルダが存在するかを判定してその属性を返す
GetKeyState 指定したキーが下げられている場合はtrue(1)を下げられてない場合はfalse(2)を返す
InStr 指定した文字列が存在するかを右または左から検索
RegExMatch 文字列にパターン(正規表現での指定)が含まれているか判定
RegExReplace 文字列内のパターン(正規表現での指定)を置換する
StrLen 文字列の文字数の取得
StrReplace 指定した文字列を置換する(正規表現でない)
StrSplit 指定した区切り文字を使用して、文字列を分割して、配列にする(配列が返る)
SubStr 文字列の指定した位置の文字を取得
WinActive 指定したウィンドウが存在していて、アクティブなのかを判定し、ID(HWND)を返す
WinExist 指定したウィンドウが存在するかを判定し、ID(HWND)を返す

その他の関数

Dllcallとかは使いそうだけどまだ使ったことないのばかり

関数名 関数の説明
Chr 指定した番号の文字コードに対応する文字列を返す
DllCall 標準のWindows API関数など、DLL内の関数を呼び出す
FileOpen オブジェクト指向のファイルのI/Oが可能
Func 指定された関数への参照を取得
GetKeyName/VK/SC キー名/仮想キーコード/スキャンコードを取得
IsByRef 指定した関数内の変数がByRefかどうかを判定し、そうであれば0以外を返す
IsFunc 指定した関数がスクリプト内に存在するか判定し、そうであれば0以外を返す
IsLabel 指定されたラベルがスクリプト内に存在するか判定し、そうであれば0以外を返す
IsObject 指定された値がオブジェクトかどうか判定し、そうであれば0以外を返す
ListView ListViewの行/列を追加/挿入/変更/削除を行う、またはデータの取得ができる
NumGet 指定されたアドレス+オフセットに格納されているバイナリ値を返す
NumPut 指定されたアドレス+オフセットにバイナリ形式の数値を格納する
OnMessage メッセージ/イベントを監視する
Ord 指定された文字列の最初の文字の文字コード(数値)を返す
StrGet メモリアドレスから文字列をコピーする、必要に応じてコードページ間で変換する
StrPut 文字列をメモリアドレスから文字列にコピーする、必要に応じてコードページ間で変換する
RegisterCallBack 呼び出し時にスクリプト内の関数に呼び出しをリダイレクトとするマシンコードアドレスを作成する
TreeView TreeViewアイテムの追加/挿入/変更/削除を行う、またはデータの取得ができる
Trim 文字列の先頭及び/または末尾の文字を切り除く
VarSetCapacity 変数のメモリの保持容量を拡大する、またはメモリの開放ができる

数学関連

パラメータは基本的に数をとる

関数名 関数の説明
Abs パラメータ(数)の絶対値を返す
Ceil パラメータ(数)を最も近い整数(.00のように小数点以下はつかない)になるように切り上げた数値を返す
Exp e(ネイピア数)を返す
Floor パラメータ(数)を最も近い整数(.00のように小数点以下はつかない)になるように切り捨てた数値を返す
Log パラメータ(数)に対する常用対数(底10)を返す
Ln パラメータ(数)に対する自然対数(底e)を返す(eはネイピア数)
Mod パラメータ(数)を指定した数値での剰余を返す
Round 小数点以下を第四位までになるように丸める
Squrt パラメータ(数)の平方根を返す
Sin/Cos/Tan パラメータ(数)の三角関数のサイン(正弦)/コサイン(余弦)/タンジェント(正接)を返す
ASin/ACos/ATan パラメータ(数)の逆三角関数のアークサイン/アークコサイン/アークタンジェントラジアンで返す

autohotkey2.0勉強中(翻訳)その8-1(関数編その1)

はじめに

翻訳とかあんま得意じゃないんだけど、関数の所らへん自分なりにまとめたやつのその1
というか関数長すぎだしプログラミング学んで浅いから知らない用語とかいろいろでわけわかめ( 一一)
その2はこちら
間違いあったらコメくれれば訂正します。というか自分用だし、間違えて覚えてしまうから(´・ω・`)

参考:ahkwiki日本語版様及び公式ヘルプ

関数編

  • 関数とは、呼び出し元からのパラメータ(入力)を受け入れることができる点を除けば、サブルーチン(Gosub)と似ている
  • さらに、関数は呼び出し元に値を返すこともできる

関数について基本事項

関数の定義方法

関数の定義は、以下のようにする、関数の内容が1行だけでも、「{」「}」は省略できない

ex: 関数名(パラメータリスト){  
関数本体  
}
  • 関数名には、半角英数字と「_」(アンダーバー)などが使用できる
  • 関数名は大文字と小文字は区別されない
  • パラメータリストには、パラメータの名前を「,」で区切って列挙する
  • パラメータを受けとらなくていい場合は、括弧内は空にする、必ず括弧は書かないといけない
  • 関数名と「(」の間には、スペースなどを入れてはいけない
  • 関数本体は、必ず「{」と「}」の行で囲んでブロック化しなければならない
  • 関数内では、パラメータとして与えられた値を変数のように参照することができる
  • 「Return」に続いて記述した式が返り値として呼び出し元に返される
  • 「Return」がない場合、空の文字列が返される
  • 関数の定義は、関数定義の内部以外ならどこに書いてもかまわない
  • スクリプト実行中に、関数定義の行に実行が移った場合、関数定義の終わりまではスキップされ、実行されない
ex: 2つの数値を受け取り、その合計を返す関数Addを定義する例  
Add(x、y)  
{  
 Return x + y "Return"のあとには式が使える  
}

関数の呼び出し

関数を呼び出す一般的な方法は、 := 演算子で変数に関数の結果を代入するように呼び出す
また、戻り値を無視して関数を呼び出すこともできるが、関数が返す値は破棄される

ex: 関数を呼び出して代入する例(↑)と呼び出すだけの例(↓)  
Var := Add(2,3)  ;上の例の関数"Add"を呼び出して、返り値の5がVarに代入される  
Add(2,3)  ;呼び出してるだけ
  • 例外もあるが、パラメータリストと同じ個数のパラメータを入力しなければならない
  • 関数はコマンドのパラメータ内で呼び出すことができる(OutputVarパラメータを除く)
  • 関数呼び出しは式なので、関数のパラメータ内(パラメータリスト)の変数名はパーセント記号で囲まないこと
  • 対照的に、文字列は二重引用符で囲む必要がある
  • ただし、式をサポートしていないパラメータ内で呼び出すには、以下の例のように接頭辞「%」を使用する必要がある
    • また接頭辞「%」は、式をネイティブにサポートするパラメータでも使用できるが、単に無視される
ex: 関数のパラメータに単語(文字列)foxを設定したい場合(↑)と式をサポートしていないパラメータ内で関数を呼びだす例(↓)  
InStr(MyVar, "fox")  
MsgBox % "The answer is: " . Add(3, 2)
  • 関数の中からほかの関数を呼び出すことも可能である
  • 呼び出しの深度の上限は159回で、160回目の呼び出しをしようとするとAutoHotkeyのプログラムが不正終了する

呼び出し元に値を返す

  • 序文で説明したように、関数は呼び出し元に値を返すことができる  
ex: Test := returnTest()  
MsgBox % Test  

returnTest() {  
return 123 ;returnのあとに値(数値、文字列、boolean値)を書くとそれが返る
}  
  • 関数から余分な結果を返す場合は、ByRef(後述)を使用することで可能
ex: returnByRef(A,B,C)  
MsgBox % A "," B "," C  

returnByRef(ByRef val1, ByRef val2, ByRef val3)  
{  
val1 := "A"  
val2 := 100  
val3 := 1  
return  
}
  • オブジェクトと配列を使用すると、複数の値や名前付きの値を返すことができる

ex:

Test1 := returnArray1()  
MsgBox % Test1[1] "," Test1[2]  
  
Test2 := returnArray2()  
MsgBox % Test2[1] "," Test2[2]  
  
Test3 := returnObject()  
MsgBox % Test3.id "," Test3.val  
  
returnArray1() {  
  Test := [123,"ABC"]  
  return Test  
}  
  
returnArray2() {  
  x := 456  
  y := "EFG"  
  return [x, y]  
}  
  
returnObject() {  
  Test := {id: 789, val: "HIJ"}  
  return Test  
}  

関数のパラメータ

  • 関数が定義の時に、パラメータは隣の括弧にリスト化して囲む
  • 名前と括弧の間にスペースは入れてはいけない
  • パラメータを受けとらなくていい場合は、括弧内は空にする、必ず括弧は書かないといけない
ex: パラメータいくつかの例(↑)といらない空の例(↓)  
function(x,y)  
GetCurrentTimestamp( )

ByRefパラメータ(パラメータの参照渡し)

  • ByRefを定義していない限り、パラメータは基本的にローカル変数として扱われる
  • ByRefを使用すると、各パラメータが呼び出し元から渡された変数のエイリアス(違う名前だけど参照は一致)になる
  • つまり、パラメータに値ではなく変数の参照を渡すこと
ex: ByRefにより変数Left,Rightはグローバル変数(それぞれxとy)として扱われ、元のx,yが入れ替わる  
x := 12 , y := 13  
Swap(x,y)  
MsgBox, %x% %y%  

Swap(ByRef Left,ByRef Right){  
    temp := Left  
    Left := Right  
    Right := temp  
}
  • 上記の関数は、呼び出し元の変数を入れ替えるすることができる
  • もし、ByRefが使用されなかった場合、LeftとRightは呼び出し元の変数のコピーであり、このSwap関数は機能しない
  • returnは関数の呼び出し側に1つの値だけを返すことができるため、ByRefを使用したならば余分な結果を返すことができる
    • これは、関数が値を格納する変数(通常は空)に呼び出し元を渡すことによって実現される
    • 何言ってるかよくわかんない、試してみたけど解釈と違う結果になった

Tips

  • 長い文字列を関数に渡すとき、ByRefを用いればその文字列のコピーを作成しなくていいので、パフォーマンスが向上するうえにメモリを節約できる
  • 同様に、ByRefを使って長い文字列を呼び出し側に返すのは、普通にReturnで返すのよりも優れてる
  • 中身が変更可能な変数以外の値がByRefパラメーターに渡された場合、関数はキーワード"ByRef"が存在しないかのように動作する
ex: 下記の例では、A_Indexの値をiに代入するが、スワップ関数が返されると、Leftに割り当てられた値は破棄される  
(一個↑のSwap関数を使用してる)
Swap(A_Index, i)  
  • IsByRef()関数を使用すると、呼び出し元が指定されたByRefパラメータに変数を提供したかどうかを判断できる

既知の制限

  • オブジェクトのプロパティ(foo.barなど)、クリップボードまたはその他の組み込み変数を、参照によって関数に渡すことはできず、代わりに、関数はByRefが省略されたように機能する
  • 関数は自身を再帰的に呼び出すかもしれませんが、独自のローカル変数またはByRef以外のパラメータのいずれかをByRefに渡すと、新しいレイヤのByRefパラメータは、前のレイヤではなくその名前のローカル変数を参照する
    • ただし、関数がグローバル変数、静的変数、またはByRefパラメーターを自身に渡すとき、この問題は発生しない
    • 関数呼び出しのパラメータが変数(たとえば、Varまたは++ VarまたはVar * = 2)に解決された場合、その変数の左または右の他のパラメータは、関数に渡される前にその変数を変更できる
      • たとえば、関数の最初のパラメータがByRefでなくても、Varが最初は0である場合、func(Var、Var ++)は予期せず1と0を渡す
      • この動作は直感的ではないため、将来のリリースで変更される可能性がある
  • ByRefは、COMクライアントが呼び出す関数やCOMメソッドを呼び出すときに直接サポートされていず、代わりに、スクリプトは、VarTypeと値のアドレスを含むラッパー・オブジェクトを受け取るか、渡す必要がある

パラメータのデフォルト値(パラメータのオプション)

  • 関数を定義するとき、そのパラメータの1つ以上をデフォルト値を設定することができまる
  • 下記のように、パラメータリストのパラメータ名の後に「:=」に続いてデフォルト値を記述することで、パラメータを省略した場合にはその値が使われるようにすることが可能である
  • デフォルト値として設定できるのは、数値(定数)と「"“」、true、falseのみである
  • 次の関数の「Z」パラメータはオプションパラメータとして認識されている
ex: Add(X、Y、Z := 0){  
Return X + Y + Z  
}
  • 呼び出し元が上記の関数に3つのパラメータを渡すと、Zのデフォルト値は無視されるが、呼び出し側が2つのパラメータだけを渡すと、Zは自動的に値0を受け取る
  • オプションのパラメータをパラメータリストの途中に挿入することはできない
  • 言い換えれば、最初のオプションパラメータの右側にあるすべてのパラメータもデフォルト値を設定する必要がある
  • ただし、以下のように、関数を呼び出すときにパラメータリストの途中から省略可能なパラメータを省略することができる
ex: Func(1、3)    
Func(X、Y:= 2、Z:= 0){  ;この場合、Zはオプションでなければならないことに注意  
MsgBox%X%、%Y%、%Z%  
}
  • ByRefパラメータはデフォルト値もサポートしている
  • たとえば:Func(ByRef p1 = “”)
  • 呼び出し元がこのようなパラメータを省略すると、関数はデフォルト値を含むローカル変数を作成する
  • 言い換えれば、関数はキーワード “ByRef"が存在しないかのように振る舞う
  • パラメータメータのデフォルト値は、true、false、リテラル整数、リテラル浮動小数点数、または “fox"や ”“などの引用符/リテラル​​文字列のいずれかでなければならない

可変長パラメータ関数(バリアディック関数)

  • 関数を定義するときに、最後のパラメータの後ろにアスタリスクを書いて、可変長変数としてマークし、可変数のパラメータを受け取るようにする
ex: Join(sep, params*) {  
for index,param in params  
  str .= param . sep  
return SubStr(str, 1, -StrLen(sep))  
}  
MsgBox % Join("`n", "one", "two", "three")  
MsgBox%Join( "n"、 "one"、 "two"、 "three")  
  • 可変長パラメータ関数が呼び出されると、関数の最終パラメータに格納されているオブジェクトを介して余剰パラメータにアクセスできる
  • 第1の余剰パラメータはparams [1]にあり、第2の余剰パラメータはparams [2]に、、これは標準オブジェクトであるため、params.Length()を使用してパラメータの数を決定できる

Tips

  • 可変長パラメータはパラメータリストの最後にのみ使用できる
  • RegExコールアウトは可変ではない 可変長パラメータは許容されるがブランクのままになる
  • コールバックは、余剰パラメータを配列ではなくアドレスで渡す

可変長パラメータ関数呼び出し

可変長子パラメータ関数は可変長のパラメータを受け入れることができるが、関数呼び出しに同じ構文を適用することによって、任意の関数にパラメータの配列を渡すことができる

ex: substrings := ["one", "two", "three"]  
MsgBox % Join("`n", substrings*)
Tips
  • ソース配列内のパラメータの番号は1から始まる
  • オプションパラメータは、配列から完全に省略することができる
  • パラメータの配列には、ユーザ定義関数を呼び出すときに名前付き項目を含めることができる
  • それ以外の場合はサポートされない
  • ターゲット関数は、可変長パラメータであってもよく、この場合、名前付き項目は、対応する仮パラメータを持たなくてもコピーされる
  • この構文は、メソッドを呼び出したり、オブジェクトのプロパティを設定または取得したりするときにも使用できる
  • たとえば、Object.Property[Params*]
既知の制限
  • 右端のパラメータのみを可変長パラメータとすることができる
  • たとえば、Func(x, y)は可能だが、Func(x, y)は不可能
  • アスタリスク(*)とパラメータリストを終了するシンボル「)」の間に空白以外の文字を入れてはならない

次→(関数編その2)

autohotkey2.0勉強中(翻訳)その7(繰り返しや分岐編)

はじめに

翻訳とかあんま得意じゃないんだけど、繰り返しと条件分岐の所らへん自分なりにまとめたやつ
間違いあったらコメくれれば訂正します。というか自分用だし、間違えて覚えてしまうから(´・ω・`)

参考:ahkwiki日本語版様及び公式ヘルプ

繰り返しや条件分岐

繰り返し処理

  • Loop文で繰り返し処理が使用できる
    • 繰り返し回数や、対象データは組み込み変数として取得できる
  • Continue、Break文が使用できる
  • whileやforのような終了条件を使った繰り返しは出来ないので、自前でIf文とBreak文で記述する必要がある

その他の繰り返し

  • Loop 指定回数の繰り返し
  • LoopFile ワイルドカードなどにマッチするファイルやフォルダそれぞれに対する処理
  • LoopReg レジストリの指定キー以下のキーに対する処理
  • LoopReadFile ファイルを1行ずつ読みながら処理
  • LoopParse 文字列の1文字ごと、あるいは指定の区切り記号で区切られたフィールドごとに処理

サブルーチン呼び出し、ジャンプ

  • Gosub文でサブルーチン呼び出しが、Gotoでジャンプが使用できる
  • Gosubから戻るには、Return文を使用する
  • Goto文はプログラムの可読性が損なわれるので、あまり推奨されない
  • ジャンプ先のラベルは、「LabelName:」のようなコロンで終わる行で記述される
  • また、ホットキーラベルも指定できる

スレッド割り込み

  • 以下のコマンドでも、ラベルによるサブルーチン指定を行う
  • これらの理由によるサブルーチン呼び出しでは、スレッドの割り込みが行われる
    • SetTimer タイマーで定期的に実行されるサブルーチンを指定
    • Menu カスタムメニューを作成し、選択されたときに実行されるサブルーチンを指定
    • GUI GUIを作成し、ボタンが押されたときなどに実行されるサブルーチンを指定
    • OnExit スクリプトが終了するときに実行されるサブルーチンを指定
    • ホットキー 指定されたホットキーが押されたときに実行されるサブルーチンを指定
    • ホットストリング 特定の文字列をタイプしたときにサブルーチンが実行されるように設定

式の代入/条件分岐

  • 前述の変数の代入・計算・条件分岐とは別に、複雑な式を用いた代入や条件分岐も使用できる
  • また、一部のコマンドにある単独で数値を指定するパラメータでは、式で値を指定することもできる
  • それ以外のパラメータでは、「% a+b」のようにパラメータの最初に「%」と半角スペースをつければ、式を指定できる
  • 式の代入/条件分岐では、他のコマンドとは変数の扱い方などが違っている
ex:
Var1 := 100 
Var2 := Var1+10
  • 式の代入には、「:=」を使う
    • 式中で変数を使うときは、「%」ではさまずに、そのまま記述する
    • 数字列は数値として計算される
    • ahk1で使えた「=」は使えない、「:=」に統一されたそのくせ例はそのままで「=」のままなんだよな混乱する(´・ω・`)
ex:
Var1 := 100  
  Var2 := 10  
  Index := 1  
  VarName := Var2  
  Var3 := Var%Index%+%VarName%  
  a := 1  
  b := 2  
  c := 3  
  xxx1xxx23xxx := 10000    
  Var := xxx%a%xxx%b%%c%xxx
  • 式中に「%」ではさんで変数名を書くと、その内容が展開された上で、変数名として扱われる
  • 前後の変数名として妥当な文字とあわせて変数名として扱われる
  • 変数参照を展開した結果が式などになる場合、不正な変数名としてエラーになる
ex: 
If(Name:="Taro" or Name:="太郎")  
MsgBox,He is Taro.
  • 式による条件分岐は上記のように、Ifに続いて式を括弧で囲んで書く 文字列は、「"」で挟む
  • 空の文字列を表すには、「"“」と2つ続けて書けばよい
  • 式中に「"」を含む文字列を使用したい場合、「"」の代わりに「"“」と2つ続けて書く
ex: 
SetFormat,FLOAT,0.1  
Var := 0.0 * 0.0  
 MsgBox,%Var%  
Var := 10/3  
 MsgBox,%Var%  
Var := 10/3 * 10/3 * 10/3  
 MsgBox,%Var%
  • 算術演算子のどちらかが小数値だった場合、結果は小数値になる また、演算結果が小数になる場合も、自動的に小数値になる
  • 算術演算の結果が小数の場合、計算途中は浮動小数点値で保持され、最終的にSetFormatコマンドで指定された形式で変数に格納される
  • 「1/0」「x+*y」などのように、正常に処理できない演算は、空の文字列として扱われる

その他の条件分岐

  • If / IfEqual / IfNotequal / IfLess / IfLessOrEqual / IfGreater / IfGreaterOrEqual 変数の比較(「:=」「<>」「>」「<」「>=」「<=」と同じ)
  • IfExist / IfNotexist ファイルの存在の有無
  • IfInString / IfNotInString 文字列中に指定の文字列が含まれるかどうか
  • If var [not] in values / If var [not] contains values varの内容がvaluesに列挙した文字列と一致するかどうか
  • If var is [not] type 変数のデータ形式
  • IfMsgBox 一番最近のMsgBoxコマンドで押されたボタン
  • IfWinActive / IfWinNotActive 指定したウィンドウがアクティブかどうか
  • IfWinExist / IfWinNotexist 指定したウィンドウが存在するかどうか

各種演算子

文字列演算子

  • Exp1 . Exp2 2つの変数や文字列、式の結果を文字列として連結する
  • Exp1と「.」、「.」とExp2の間にはスペースを空けなければいけない

算術演算子

  • A: 「-」をつけられた項や式は負の値を表す
  • A+B: 加算
  • A-B: 除算
  • A*B: 乗算
  • A/B: 除算
  • A//B: 割り切らない除算
    • たとえば、「7//3」 は 2に、「7//-3」 は -2になる
    • いずれかの被演算子が小数表現だった場合、小数として除算した商を超えない最大の整数に丸められる
    • また、この場合結果は小数表現になる(「7//3.0」 は 2.0、「7//-3.0」 は -3.0になる)
  • A**B: 累乗、AのB乗
  • AとBは共に小数値が使用できる

ビット演算子

  • ビット演算を使用できるのは整数値のみ
  • 小数値は、整数値に変換してから計算される
  • つまり誤差が出る
  • 内部的には64ビット符号付整数で扱われている模様
  • 符号付64ビット整数の範囲(-9223372036854775808..9223372036854775807)の範囲に収まらない場合、65ビット目より上は切り捨てられる
  • ~A: Aのビットを反転する
    • 32ビット符号なし整数の範囲内の値は、下位32ビットだけ反転される
    • (負の値の場合、32ビットでも64ビットでも結果は同じ)
  • A|B: ビットの論理和
  • A&B: ビットの論理積
  • AB: ビットの排他的論理和
  • A>>B: Aを右にBビットだけシフトする
    • 論理右シフトなので、最上位ビットが1でも、開いた左側には常に0が詰められる
    • 算術右シフトをしたいときは、2**Bで割る
  • A<<B Aを左にBビットだけシフトする

論理演算子

  • 数値のゼロや空の文字列は偽(False)として扱われ、それ以外は真(True)として扱われる
  • 論理演算の結果を変数に代入すると、偽(False)の場合「0」、真(True)の場合「1」が代入される
  • ! A(NOT A) 真偽を反転する
    • !のほうが演算子の優先度が高い
  • A || B(A OR B) 論理和
  • A && B(A AND B) 論理積

比較演算子

  • 主に条件分岐で使用するが、比較演算の結果を変数に代入する場合、偽(False)なら「0」、真(True)なら「1」が代入される
  • 数値でないものを比較する場合、文字列として文字コードの並び順で比較される
  • 数値であっても、「"」で囲まれている場合は、文字列とみなされる(ex: 「"10"」)
    • このとき、StringCaseSenseコマンドで設定が変更されない限り、大文字小文字の違いは無視される(「=」「==」を除く)
  • 文字列の演算における大文字小文字の違いは常に無視される

  • A > B: AがBより大きいなら真(True)になる

  • A < B: AがBより小さいなら真(True)になる
  • A >= B: AがB以上なら真(True)になる
  • A <= B: AがB以下なら真(True)になる
  • A = B: AとBが同値のとき真(True)になる
  • A == B: AとBが同値のとき真(True)になる
  • A != B(A <> B): AとBが同値でないとき真(True)になる

アドレス演算子

  • &Var 変数Varの格納されたメモリ領域のアドレスになる
  • *Addr アドレスが整数Addrで表されるメモリ領域のバイト値(0…255)になる
  • 「*Addr := Asc(“x”)」のように代入先にはできない
  • 値を変更するには、「DllCall(“RtlFillMemory”, UInt, Addr, UInt, 1 , UChar, Asc(“x”))」のようにする

次→(autohotkey勉強中その7)

autohotkey2.0勉強中(翻訳)その6(式編)

はじめに

翻訳とかあんま得意じゃないんだけど、とりあえず式の所らへん自分なりにまとめたやつ
間違いあったらコメくれれば訂正します。というか自分用だし、間違えて覚えてしまうから(´・ω・`)
参考:公式ヘルプ

式編

  • 式は、一連の変数、リテラル文字列、および/またはリテラル番号に対して1つまたは複数の操作を実行するために使用される
  • 式内の変数は、パーセント記号で囲まなくていい(引用符付きの文字列内の変数、擬似配列およびその他の二重引用符を除く)
  • したがって、リテラル文字列は変数と区別するために二重引用符で囲む必要がある

    ex: if (CurrentSetting > 100 or FoundColor <> "Blue")

  • 式に空の文字列を指定するには、空の引用符を使用する

    ex: if (CurrentSetting > 100 or FoundColor <> "")

  • 式の結果を変数に代入するには、:= 演算子を使用する

    ex: NetPrice := Price * (1 - Discount/100)

ブーリアン(boolean)型

  • 式が真または偽(IF文など)で評価する必要がある場合、空白またはゼロならは偽とみなされ、他のすべての結果は真とみなされる
  • 変数を空白にするか0を代入するだけで、偽の値を保持することができる
ex: 変数*ItemCount*が空白または0の場合  
if ItemCount  はfalse(偽)の判定(結果)になる
ex: if Done とすると(Doneは変数)変数の値がtrueかfalseか判定できる
  • NOT / > / = / < のような演算子は、真または偽の値を自動的に生成する
    • 真の場合は1、偽の場合は0が生成される
  • ただし、AND/OR演算子は常に入力値の1つを生成する
ex: A_Indexが5より大きい場合は変数Doneに1が、それ以外の場合にはFoundItの値が割り当てられる
Done := A_Index> 5 or FoundIt
  • 式中では、trueとfalseは1と0に解決される
ex: スクリプトをより読みやすくするためにこう書いてもいいっていうか書くなら普通こう書くでしょっていう  
CaseSensitive := false  
ContinueSearch := true

イント(整数)及びフロート(浮動小数点数)(Integers,floating point)型

  • 式中で、小数点や科学的表記法を含む数値は浮動小数点数と見なされる
  • それ以外の場合は整数として見なされる
  • 加算や乗算などのほとんどの演算子では、いずれかの入力が浮動小数点数の場合、結果も浮動小数点数になる
  • 式と非式の両方で、整数は16進数または10進数のいずれかの形式で記述できる
  • 16進数はすべて0xで始まる、例えば、Sleep 0xFFはSleep 255と同じ
  • 浮動小数点数は、オプションで小数点の有無にかかわらず科学的表記法(ex: 1e4または-2.1E-4)で記述することができる
  • 式中では、128、0x7F、1.0などの引用符で囲まれていない数値は、スクリプトが実行を開始する前に純粋な数値(十進数)に変換されるため、数値を文字列に変換すると、元のとは異なる値が生成されることがある
  • 3/2では1.5が得られ、4/2では2ではなく2.0が得られる
  • 1.0、5.0 // -3 は -2.0になる

autohotkey2.0勉強中(翻訳)その5(変数編)

はじめに

翻訳とかあんま得意じゃないんだけど、とりあえず変数の所らへん自分なりにまとめたやつ
変数と式がひとまとめになってたけど長いので分けた
まあwiki見ればいいよねこんなん見るより。
間違いあったらコメくれれば訂正します。というか自分用だし、間違えて覚えてしまうから(´・ω・`)

参考:ahkwiki日本語版様及び公式ヘルプ

変数編

変数の型

  • 変数やコマンドの引数として使われる値は、すべて文字列として保持される
  • 明示的に定義された変数の型はなくて、任意の変数に文字列、整数、浮動小数点数、またはオブジェクトへの参照を代入することができる
  • また、数値は必要に応じて文字列に自動的に変換される
  • 変数の型を判別したい場合はType関数を使用することで判別することができる
  • 値が特定のフォーマットの場合、整数、小数、日付時刻として計算などで使うことができる
  • どのような書式が 各コマンドが出力する整数・小数の文字列表現フォーマットなのかは、SetFormatコマンドで設定できる

変数のスコープと宣言

  • 関数のローカル変数を除いて、すべての変数はグローバルで、その内容はスクリプトの任意の部分によって読み取られたり変更されたりする可能性がある
  • 関数ページに記載されている場合を除いて、変数は宣言する必要はなく、変数を使用することによって存在するようになる(そして、各変数はemptyまたはblankで始まりる)

変数の名前

  • 変数名では大文字と小文字は区別されない(たとえばCurrentDateはcurrentdateと同じ)
  • 変数名は最大253文字で、文字、数字、アンダースコア、ASCII以外の文字で構成され、変数名は数字で始めることはできない

予約語

以下の単語は演算子として、もしくは制御フロー文の名前として予約または使用されているため、変数名として使用できない
関数、クラス、およびウィンドウグループでも変数と同じ検証を使用するためこれらの単語が使えない
abc順

andbreakcatch
containscontinueelse
FinallyForGosub
GotoIfin
isLoopLoopF​​ile
LoopParseLoopReadLoopReg
newnotor
ReturnThrowTry
UntilWhile

変数への値の代入(格納)

  • 変数に値を代入するには「:=」の後に数字、引用符付き文字列、または他のタイプの式を書く
  • ahk2からは「=」は使えず、「:=」に統一された←ここ重要
ex: 代入の例  
Var := 123  ;数値*123*の代入  
Var := "Var" ;文字列*Var*の代入
  • 値が割り当てられていない変数には、デフォルトで空(blank/null)の文字列が含まれている

変数に割り当てられたメモリの解放

ex: Var := "" という風に空の値を割り当てることで、割り当てられたメモリを開放できる
  • 変数には、コマンドの出力変数として間接的に値を割り当てることもできる

関数の出力変数を用いて間接的に変数への代入

ex: WinGetTitle *Title*, A アクティブウィンドウのタイトルを関数の出力変数*Title*に代入
  • 変数が整数の場合、64ビット整数(long)相当の値が扱える
  • 変数が少数の場合、double値相当の値が扱える
  • 変数とは別に、環境変数(後述)も扱うことが出来る
  • EnvSetコマンドで環境変数に代入する
  • この環境変数は、Runコマンドなどで起動したプログラム内から参照できる
  • 変数の展開では、通常の変数も環境変数も展開できるが、未定義の変数は長さ0の文字列に展開される
  • 1変数の容量の上限は64KBである(#MaxMem指令で変更可能)
  • 組み込み変数は「組み込み変数」を参照

変数の値(内容)を取得する

  • 変数の内容を文字列に含めるには、変数名をパーセント記号「%」で囲めばいい
ex: MsgBox、変数Varの値は%Var%です  
MsgBox( "変数Varの値は%Var%です" )
  • また、パーセント記号「%」は式の変数参照(引用符付き文字列以外、式内など)では省略していい
ex: MsgBox( "XとYの合計は(X + Y)です" )

エスケープシーケンス

  • ファイルパスの「\」のエスケープの必要をなくすため、エスケープ文字は「`」(Shift+@)になっている
  • 以下に示すエスケープシーケンスが使える
  • それ以外の文字をエスケープした場合、その文字自身になる(例:「`x」→「x」)
  • EscapeChar指令でエスケープ文字を変更できるらしい

  • 任意のコマンドの最初のカンマを省略することができる
  • (最初の引数が空白の場合や::=などの代入演算子で開始する場合、またはコマンドが継続セクションの一番上にある場合を除く)
  • 例外1:MsgBox内のカンマはエスケープする必要はない
  • 例外2:コマンドの最後の引数のカンマはエスケープする必要はない

エスケープシーケンス一覧

  • コマンドの区切りと区別するため、エスケープが必要
  • なお、コマンドの最後の引数内では、文字としてのカンマであることが自明なため、カンマをエスケープする必要は無い
  • `; 「;」で、半角スペースかTab文字の次に来る場合のみ、コメントの開始記号と区別するためにエスケープする必要がある
  • `:: 文字列「::」(コロン二つ)ホットストリングなどで使用
  • `% 「%」(パーセント記号)
  • `n 改行(LF/0x0A)
  • `r 復帰(CR/0x0D)
  • `t Tab文字(0x09)
  • `v 垂直Tab(0x0B)
  • `b BackSpace文字(0x08)
  • `a Bell文字(0x07)
  • `f 改ページ(0x0C)
  • `` 「`」自身なんかバックスラッシュ二個と同じ意味合いをもつらしい
  • `, 「,」(カンマ)の文字 プログラム最後のカンマとMsgBoxではエスケープしなくていい
  • `“または`‘ 一重引用符と二重引用符は同じ意味を持つが、一重引用符で囲まれた文字列の中では二重引用符を使用するとそのまま二重引用符が扱える、説明しにくいので以下の例を見て
ex:一重引用符の中に二重引用符を用いる例で、以下の二つは同じ結果  
Var := "The color \`"red\`" was found."  ;「"」をエスケープ「\`"」して書いた場合  
Var := 'The color "red" was found.'  ;「'」で囲んでいるので中にある「"」はエスケープしなくてもよい

Sendモードにおけるエスケープシーケンス

Sendコマンドまたはホットストリングをデフォルト(非raw)モードで使用すると、{} ^!+#などの文字は特別な意味を持つため、
これらを文字通り使用するには、中括弧で囲む

ex: Send {^} {!} {{}

次→(autohotkey勉強中その6)

setpointさんがまじでsetpointさんなので強制的にアプリ設定がリセットされないようにした(autohotkey2)

はじめに

setpointさんがパソコン(win10)が起動するたんびにアプリケーションの設定がリセットされるのでautohotkeyさんを使って強制的にリセットされないようにした
setpoint(無能)さんまじでsetpoint(無能)さん
いくつかのサイトではデバイスのappoverrideだったかなんかを消せば解決するってなっていたけども自分のバージョンではできなかった
ダウングレードすればできたけどなんか気に入らなかったからというかいろいろあったから最新版にした(最新版でも解決してるならなんのせいだろうね)
autohotkeyさんについては検索でもしてほかの方の説明を見ればいいんじゃないかな
かなり細かく書いているので、操作がわかる人は基本的に太字の文のみ読めば大丈夫
まあ自己責任で
ということで環境とやり方↓

環境

  • win10 1703(アップデートしてなければ)
  • setpoint コントロールセンター : 6.67.83
  • setpoint ドライババージョン : 5.90.41 (関係ないと思うけどまあなんとなく)
  • Autohotkey2.0a3なんちゃらだった気が

やり方

事前にuser.xml(setpointの設定)とsetpointの起動ショートカットのコピーを別の場所に作成しておき、PCの起動時に上書きをする
その後、setpointさんの起動をする
このため、元から設定されているスタートアップは消すもしくは無効化しておく
スタートアップとかuser.xmlのコピーとかの説明はいらないんだよってひとはこれをクリック

  1. まずはsetpointのスタートアップを無効にする

    1. タスクマネージャーを開く

      • キーボードだけでやるやり方

        1. 「Ctrlキー」「Shiftキー」「Escキー」を同時に押す
        2. windowsキー」に「Xキー」を同時に押す、その後「Tキー」を押す
      • マウスでやるやり方

        1. タスクバーのスタートボタンを右クリック、出てきたタスクマネージャーをクリック(「Tキー」でもいい)
        2. タスクバーの何もないところを右クリック、出てきたタスクマネージャーをクリック(「Kキー」でもいい)
    2. スタートアップをクリック

    3. Logicool setpoint ・・・ を右クリック
    4. 無効をクリック
  2. setpointの設定のコピーを作成する

    1. setpointのAppdataフォルダを開く
    2. C:\Users\ユーザー名\AppData\Roaming\Logitech\SetPoint\エクスプローラーなどで開く 表示されていない場合

      • windows10なら「windowsキー」と「iキー」を同時に押し、検索欄で「フォルダ」で検索をし、出てきた「すべてのファイルとフォルダの表示」をクリック
      • windows7ならコントロールパネルを開いて「デスクトップのカスタマイズ」をクリックし、「エクスプローラーのオプション」のすべてのファイルとフォルダを表示をクリック
        その後、ファイルとフォルダの表示の「隠しファイル…を表示する」をクリックをすれば表示されるようになる
    3. 中にある user.xml をコピーする

    4. autohotkeyスクリプトなどを格納するためのフォルダとバックアップのためのフォルダを作成する
    5. 作成した両方のフォルダにペーストする
  3. setpointのショートカットのコピーを作成する

    1. setpointのプログラムフォルダを開く
    2. 64bit版ならC:\Program Files\Logicool\SetPointP\ 、32bit版ならC:\Program Files\Logicool\SetPointP\エクスプローラーなどで開く 自分のOSが何bitかわからない場合はスタートボタンを右クリックして出てきたメニューのシステムをクリック、出てきた画面の中にある64ビットもしくは32ビットと書いてあるのを探し、それが自分のOSのビットになる
    3. マウスおよびキーボードの設定.lnkをコピーする
    4. 先ほど作った二つのファルダにペーストする
    5. setpoint.lnk に名前を変更する
  4. autohotkeyスクリプトを書く

    1. なんでもいいのでテキストエディタ(メモ帳)で以下のコードをコピー&ペーストする - 何の変更もしなくて大丈夫

    FileCopy, user.xml, %A_Appdata%\Logitech\SetPoint\user.xml, 1 Run, setpoint.lnk Return

    1. 「名前を付けて保存」で、先ほど作ったフォルダに好きな名前を付けて末尾に「.ahk」をつけて保存する これがスクリプトファイルになる
      ※今までのすべてのファイルが同じフォルダにないと正常に動作しない
  5. 保存したスクリプトをスタートアップに登録する

    1. 保存したスクリプトのショートカットを作成する
    2. 作成したショートカットをカットする
    3. C:\Users\ユーザー名\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\ を開く
    4. ペーストする
  6. 設定してない人向け) 「.ahk」ファイルにアイコン(緑色のアイコン)がついてない人は「.ahk」ファイルの関連付けを行う

    1. 先ほど保存したスクリプト(.ahk)を右クリックし、「プログラムから開く」の「別のプログラムを開く」を選択
    2. 「その他のアプリ」の「このPCで別のアプリを探す」をクリック
    3. autohotkeyの実行ファイル(Autohotkey.exe)があるところに移動し、選択し、OKを押す

あとがき

疲れた
とりあえず写真欲しいね
ていうかautohotkeyで各ソフトにも割り当てればいいと思ったけどいいや
まあいつも通り困ってる人がいてその役に立てばいいかなっていう記事

autohotkey2.0勉強中(翻訳)その4-2(スクリプト編その2)

スクリプト編(その2)

その1はこちら

スクリプトの起動とAuto-execute(自動実行)セクション(以下自動実行セクション)

  • スクリプトは読み込み時に解析され最適化される
    • これにより思ったように動作しないこともありそう、そんなことないかもね
  • スクリプトの文法エラーは読み込み時にチェックされ、修正されるまでプログラムを実行できない(例外あり)
  • スクリプトが読み込まれると、Return、Exit、ホットキー、ホットストリング、スクリプトの終わりのいずれかに達するまで自動で実行される
  • この部分(スクリプトが自動実行される範囲)のことを、自動実行セクションと呼ぶ
  • ホットキー、ホットストリング、、Lock系キーの固定などで常駐状態にされない場合、自動実行セクションが終了したらスクリプトは終了する
  • 上記以外の場合は、ホットキー、ホットストリング、GUIイベント、カスタムメニュー項目、タイマーなどのイベントに応答して、待機(アイドル)状態で動作し続ける
  • 自動実行セクションの完了後にこれらの条件が変更された場合や、(たとえば、最後のタイマーが無効になった場合)、最後に実行されたスレッドが完了するか、最後のGUIが終了すると、スクリプト(自動実行セクション)が終了する
  • ホットキー、ホットストリングなどがある場合はプログラムはそのまま駐屯する(待機状態になる)

自動実行セクションが終了しない例

  • ホットキー
  • ホットストリング
  • 可視GUI(アクティブなGUI)
  • アクティブなメッセージモニタ
  • タイマー
  • OnClipboardChangeコールバック関数
  • カスタムトレイメニュー項目
  • および#Persistent指令(ディレクトリ)
  • Lock系キーの固定
ホットキー、カスタムメニューアイテム、タイマーで起動されるスレッドでは、下記に記載するコマンドでの設定はそれぞれ独立している
  • これらの初期値は自動実行セクション内で設定できる
  • 設定が行われる前にスレッドが呼び出されると、期待した動作にならないことがあるので、自動実行セクションのできるだけ最初の方で設定しよう
  • 自動実行セクションが完了するまでに長い時間がかかる場合(または完了しない場合)、設定のデフォルト値は100ミリ秒後に有効になる - 長い時間ってどんぐらいなんだよっていうまあいいや
  • デフォルトでは自動実行セクションが完了すると、下記の設定は再度初期値に更新される。
  • だからホットキー、ホットストリング、タイマー、またはカスタムメニュー項目を含むスクリプトの一番上でデフォルト値を変更するのがいい
  • これらの設定に加えられた変更は、他のスレッドには影響しない

実行時に設定が初期化される該当コマンド設定一覧(詳細はまた今度)

  • DetectHiddenWindows
  • DetectHiddenText
  • SetTitleMatchMode
  • SetBatchLines
  • SetKeyDelay
  • SetMouseDelay
  • SetWinDelay
  • SetControlDelay
  • SetDefaultMouseSpeed
  • Thread attributes
  • CoordMode
  • SetStoreCapslockMode
  • AutoTrim
  • SetFormat
  • StringCaseSense

プログラムのコマンドライン引数

AutoHotkeyコマンドラインの書式は以下の通り
* AutoHotkey.exe [Switches] [Script Filename] [Script Parameters] * CompiledScript.exe [Switches] [Script Parameters]

[Switches] には以下のものを指定もしくは入力なし

コンパイル後でも使えるもの

  • /f(または/force):警告ダイアログを出さずに、強制的に起動
    • #SingleInstance Offと同じ効果
  • /r(または/restart):スクリプトを再読み込みしたいときに使用
  • /ErrorStdOut:文法エラーをダイアログ表示せずに標準出力に出力する
    • 詳細については「#ErrorStdOut」を参照(後ほど)
    • これを/iLibと組み合わせて、スクリプトを実行せずに検証することができる コンパイル後では使えないもの
  • /Debug:デバッグクライアントに接続する
    • 詳細については、「対話型デバッグ」を参照(後ほど)
  • /CP「n」:スクリプトファイルの読み取りに使用されるデフォルトの文字コードを上書きする
  • /iLib “Outfile” AutoHotkeyスクリプトをロードしますが、実行せず、ライブラリ機構を介して自動的にインクルードされるスクリプトファイルごとに、OutFileで指定されたファイルに2行づつ書き込まれる
  • これらの行は、次の形式で記述される
LibDirはLibフォルダのフルパスで、LibFileはライブラリのファイル名  
\#Include LibDir\  
\#IncludeAgain LibDir\LibFile.ahk
  • 出力ファイルが既に存在する場合は上書きされる
  • OutFileは、"の代わりに*で囲むと標準出力(stdout{standardout})できる
    • 詳細は「標準出力」を参照(後ほど)
  • スクリプトに構文エラーが含まれていると、出力ファイルが空になることがある
    • プロセス終了コードを使用してこの状態を検出できる
    • 構文エラーがある場合、終了コードは2
    • /ErrorStdOutスイッチを使用すると、エラーメッセージを抑制またはキャプチャできる

[Script Filename]について

  • [Script Filename] は引数がない場合は省略可能
  • [Script Filename] を省略した場合(スタートメニューから直接AutoHotkeyを実行する場合など)は、「~.ahk」の名前のファイル(詳細は後述)を以下の順で検索する
1.AutoHotkey実行可能ファイルを含むディレクトリ
2.現在のユーザーのドキュメントフォルダの順番で検索される
  • ファイルが存在しない場合、デフォルトのファイルを作成するかをたずねるダイアログが出る
  • スクリプトに引数を渡したい場合は省略できない
  • また、検索するファイル名(上記の「~.ahk」)は、スクリプトを実行するために使用される実行ファイルの名前によって異なる
    • AutoHotkey.exeの名前をMyScript.exeに変更すると、MyScript.ahkが検索される
引数なしで*AutoHotkeyU64*.exeを実行すると、*AutoHotkeyU64*.ahkが検索される

[Script Parameters]について

  • [Script Parameters] には任意の数の文字列をスペース区切りで渡せる
  • 文字列スペースを含みたい場合は「"」で囲む
    • 引用符で囲まれた引数(「"C:\ My Documents \“」など)のバックスラッシュは、リテラルの引用符として扱われる(つまり、スクリプトは「"C:\ My Documents"」という文字列を受け取る)
    • この引用符を削除するには、A_Args [1] := StrReplace(A_Args [1]、 “”)とすればいい
  • 渡された引数は、組み込み変数「A_Args」に配列に格納され、配列構文を使用して参照できる
  • 「A_Args [0]」には引数の数が格納されるらしい
  • スクリプトに渡される引数の数がわからない場合(一連のファイルをスクリプトドラッグアンドドロップした時など)、次の例を使用してそれらを1つずつ抽出できる
ex:  
for n, param in A_Args  ; For each parameter:  
{  
    MsgBox, Parameter number %n% is %param%.  
}
  • 引数がファイル名である場合、次の例を使用して、ファイルシステムに格納されている大文字と小文字を区別した長い名前に変換できる(完全/完全パスを含む)
ex:  
for n, param in A_Args  ; For each parameter:
{
    MsgBox, Parameter number %n% is %param%.
}

スクリプトファイルの文字コード

スクリプトファイルに含まれる文字は、ファイルのロードに使用される文字コードによって制限される

  • ファイルがUTF-8またはUTF-16(LE)バイト順序マークで始まる場合、適切な文字コードが使用され、/CP「n」スイッチ(コマンドライン引数のswitchオプションの/CPnのこと前述済み)は無視される
  • /CP「n」スイッチがコマンドラインで渡されると、文字コード「n」が使用される
    • 有効な文字コード識別子の数値一覧については、「MSDN」を参照(後ほど)
  • それ以外の場合は、システムのデフォルトの「ANSI」が使用される
    • まあ大体UTF-8で書くだろうからあんま気にしなくていいんじゃないかな
    • ボム付きにすれば基本的に問題ない
  • これは、AutoHotkeyで読み込まれたスクリプトファイルにのみ適用され、スクリプト自体の中でI/Oファイルには適用されないことに注意
  • FileEncodingは、スクリプトによって読み書きされるファイルのデフォルトのエンコーディングを制御する
  • IniReadおよびIniWriteは常にUTF-16またはANSIを処理する
  • すべてのテキストが(必要な場合)ネイティブの文字列形式に変換されるため、無効またはネイティブコードページに存在しない文字は、プレースホルダ' ‘に置き換えられる
  • これは、スクリプトファイルにエンコーディングエラーがある場合、またはファイルの保存とロードに使用されたコードページが一致しない場合にのみ発生する
  • RegWriteを使用して、エクスプローラから起動されたスクリプトのデフォルトを設定することができる(ファイルをダブルクリックするなど)

ex:HELPそのまま、autohotkeyがインストールされている前提

; 下の行のコメントを外すか、コメントにすべてコメントしておく
; 現在のビルドのデフォルトにリセットするなど、必要に応じて変更する
; ↑のコメント二つ適当に訳した
; codepage := 0        ; システムデフォルトのANSI  
; codepage := 65001    ; UTF-8  
; codepage := 1200     ; UTF-16  
; codepage := 1252     ; ANSI ラテン語 1; 西ヨーロッパ(Windows)  
if (codepage != \\"\\")  
    codepage := \\" /CP\\" . codepage  
cmd := \\'\\"%A_AhkPath%\\" %codepage% \\"\\\`%1\\" \\\`%*\\'  
key := \\"AutoHotkeyScript\\Shell\\Open\\Command\\"  
if A_IsAdmin    ; 全ユーザーへ設定  
    RegWrite, REG_SZ, HKCR\\%key%,, %cmd%  
else            ; 現在のユーザーのみに設定  
    RegWrite, REG_SZ, HKCU\\Software\\Classes\\%key%,, %cmd%

スクリプトデバッグ

  • スクリプトが期待通りに動作しているかを確認するには、スクリプト要所要所にMsgBoxコマンドを入れて、動作状況や変数の内容を表示すればよい
  • ListVarsやPauseなどのコマンドは、スクリプトに挿入した所に「ブレークポイント」を作成する
  • スクリプトがこれらの2つの行に遭遇すると、検証のためにすべての変数の現在の内容が表示される
  • 再開する準備ができたら、[ファイル]メニューまたは[トレイ]メニューからスクリプトの一時停止を解除する、すると、スクリプトは、次の「ブレークポイント」(存在する場合)に達するまで続く
  • これらのデバッグは、アクティブウィンドウが変わってしまうと正常に動作しないようなところでは使用できないので注意が必要である
  • これらのデバックはWinActivateコマンドの直前など、アクティブなウィンドウがスクリプトに関係しない位置に、これらの「ブレークポイント」を挿入するのが一般的で、こうすれば、スクリプトを再開したときに正常な動作で再開することができる
  • また、ListLines,KeyHistory,OutputDebug といったコマンドもデバッグには有用である
  • 誤字や欠落した「グローバル」宣言などの一般的なエラーは、警告を有効にすることで検出できる(デフォルトの状態)

対話型デバッグ

  • DBGpクライアントを用いた対話型デバッグが可能である
    • ブレイクポイントの設置と撤去(ブレイクポイントに達するとスクリプトの実行は一時停止される)
    • 1行ずつコードをステップ実行することができる(関数やサブルーチン自体、あるいはそれらをまたいでも可)
    • 全て、あるいは特定の変数の検査
    • 実行中のサブルーチンや関数のスタックを表示できる
  • 対話型デバックをするにはまず対応しているデバッガクライアントを起動し、/ Debugコマンドラインスイッチを使用してスクリプトを起動する
ex:  
  AutoHotkey.exe /Debug[=SERVER:PORT] ...
  • Server および Port は省略可能で、以下の二つは同じ
ex:  
  AutoHotkey /Debug "myscript.ahk"  
  AutoHotkey /Debug=localhost:9000 "myscript.ahk"
  • 実行中のスクリプトにデバッガを接続するには、以下のようにメッセージを送信すればいい
ex:実行中のスクリプトをデバッガに接続  
ScriptPath := "" ;スクリプトのフルパスを入れる  
DetectHiddenWindows On  
if WinExist("%ScriptPath% ahk_class AutoHotkey")  
    ; オプションの引数:  
    ;   wParam  = the IPv4 address of the debugger client, as a 32-bit integer.  
    ;   lParam  = the port which the debugger client is listening on.  
PostMessage, % DllCall("RegisterWindowMessage", "str", "AHK_ATTACH_DEBUGGER")
  • デバッガクライアントが接続されると、"detach" DBGpコマンドを送信してスクリプトを終了することなく切断されることがある
  • なおコンパイルしたスクリプトではこの機能は利用できない

スクリプトのEXE(実行ファイル)化-ahk2は未対応っぽい?

方法

  • ahk2exe.exeを使うことで、スクリプトを実行ファイル化することが可能
  • ahk1には同封されていたが2はないので別途ダウンが必要というかダウンしてコード変えないとじゃね疑惑
  • Ahk2Exeは、以下の三つの方法で使用できる

    1.GUIインターフェイス:スタートメニューの「.ahkから.exeへの変換」を実行
    2.右クリック:開いているエクスプローラウィンドウ内で任意の.ahkファイルを右クリックし、[スクリプトコンパイル]を選択(AutoHotkeyのインストール時にスクリプトコンパイラオプションが選択されている場合のみ使用可能)
    これにより、スクリプトと同じ基本ファイル名のEXEファイルが作成される
    このファイルは、同じディレクトリに短時間で表示される
    注:EXEファイルは、同じカスタムアイコン、.binファイルを使用して作成され、上記の方法1で最後に使用されたMPRESS設定を使用される
    3.コマンドラインコンパイラは、コマンドラインから次の引数を指定して実行できる

Ahk2Exe.exe / in MyScript.ahk [/ out MyScript.exe] [/ icon MyIcon.ico] [/ bin AutoHotkeySC.bin] [/ mpress 0or1]
スペースを含む引数は二重引用符で囲む必要がある  
"out"項目を省略すると、EXEはスクリプト自体と同じベースファイル名を持つようになる
ex)Ahk2Exe.exe /in "MyScript.ahk" /icon "MyIcon.ico"
  • 引数がAhk2Exeに渡されると、コンパイルプロセスの成功または失敗を示すメッセージがstdoutに書き込まれる。メッセージはコマンドプロンプトに表示されないが、出力をファイルにリダイレクトするなどの手段で「キャッチ」できる
  • さらに、エラーの場合、Ahk2Exeには、発生したエラーの種類を示す終了コードがあり、これらのエラーコードはGitHub(ErrorCodes.md)にあるってさ
  • リソースハッカー(フリーウェア)などのユーティリティを使用して"AutoHotkeySC.bin"ファイルを編集することで、コンパイル済みのスクリプトにバージョン情報(エクスプローラのファイルプロパティダイアログに表示されるやつ)を編集(追加)できる
  • また、Compile_AHK IIを使うとこのプロセスを容易にできる

コンパイルされたスクリプトを圧縮するには

Tips

  • コンパイルされたスクリプトでは通常、タスクトレイメニューからメインウィンドウを表示することは出来ない
  • #NoTrayIconコマンドと “Menu、Tray、ShowMainWindow"コマンドは、コンパイルされたスクリプトの動作に影響する
  • 「Menu,TRAY,MainWindow」でメインウィンドウを表示可能にできる
  • スクリプト側が、コンパイルされた状態で実行されているかどうかを知るには、「A_IsCompiled」変数を使用する、「1」ならコンパイルされている(それ以外は「0」)
  • コンパイラも公開されているが、パスワードで暗号化すれば逆コンパイルを防げる
  • 作成した実行ファイルの配布は自由
  • 実行可能ファイルを圧縮すると、メモ帳やPEリソースエディタなどのプレーンテキストエディタを使用してスクリプトソースコードを簡単に検査することはできませんが、その目的専用のツールでソースコードを抽出することができなくなる

次→(autohotkey勉強中その5)