4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[AutoHotKey]OnClipboardChange()関数でクリップボード監視

Last updated at Posted at 2017-05-20

だいたい引用。

OnClipboardChangeサブルーチンラベルの問題

AutoHotKeyにはOnClipboardChangeという組み込みラベルがあり、このラベルのサブルーチンに記述した処理が、クリップボードが変更された時に自動的に実行されます。
常駐スクリプトとして実行すれば、クリップボードを監視してなにかをしてくれるわけです。

ただし、この「クリップボードが変更された時」というのに、スクリプトの起動時も含まれるのが問題でした。

スクリプトを起動した時(あるいはリロードした時)、あたかも同時になにかをコピーしたかのように反応するので、常駐スクリプトの編集中などはウザいことこの上ない感じでした。

問題を解決したOnClipboardChange()関数

しかし、現在の最新バージョンではOnClipboardChange()関数が実装されており、これはスクリプト起動時を除くクリップボードの変更に反応してくれます。
上記の問題が解消されている以外、機能的には旧来のラベルと全く同じです。

そこで、元々ラベルで書いていた、クリップボードの変更を監視してコピーした文章をツールチップで表示するスクリプトを手直ししてみました。
元のスクリプトは以下のページを参考にしました。

; Includeして使っているので#Persistentなし
OnClipboardChange("ClipChanged")
Return

ClipChanged(Type) {
    if (Type = 1) { ;テキストの場合は内容を表示
        StringLen, length, Clipboard
        if (length>200) { ;長いテキストの場合は最初の200文字を表示
            ShortCB := SubStr(Clipboard, 1, 200)
            ToolTip テキストをコピーしました`n%ShortCB%
            RemoveToolTip(1500)
        }
        else { ;短いテキストの場合は内容を表示
            ToolTip テキストをコピーしました`n%Clipboard%
            RemoveToolTip(1500)
        }
    }
    else if (Type = 2) { ;テキスト以外の場合は適当に表示
        ToolTip 非テキストデータをコピーしました
        RemoveToolTip(1500)
    }
}

基本的にはラベルサブルーチンの内容をOnClipboardChange()の引数として指定した名前の関数に放り込めば問題ありませんが、クリップボードのデータ種別を示す値の取り扱いが変わっています。
組み込み変数A_EventInfoは利用できず、代わりに関数のパラメータとして代入されます。この場合はTypeです。
取りうる値は、「0:空」「1:テキストデータ」「2:非テキストデータ」で変わりありません。

クリップボードの監視を停止する

特にホットストリングでスニペットのペースト処理をしてる場合などは、都度停止させないとツールチップが邪魔です。

そこで、グローバル変数でフラグを管理してペーストする関数でフラグを切り替え、とかやっていたのですが、実はOnClipboardChange()関数自体に動作を停止するオプションがありました。

AddRemove

One of the following values:
1 (the default): Call the function after any previously > > registered functions.
-1: Call the function before any previously registered functions.
0: Do not call the function.

というわけで、ペースト関数を以下のようにすれば誤動作は防げます。

ahk
PasteString(String)
{
	OnClipboardChange("ClipChanged",0)
	Backup := ClipboardAll
	Clipboard := String
	Sleep, 100 ; 削除が間に合わないので
	SendPlay, ^v
	Clipboard := Backup
	OnClipboardChange("ClipChanged",1)
}
4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?