Becky!のカラーラベルを自動で操作

Becky! Plugin SDKを使うと、外部(プラグイン)から色々な操作をできますが、残念ながらカラーラベルや優先度を操作することはできません。

それでもタグ機能を実装するからにはやはりカラーラベルは付けたいところ。
あれこれ考え、APIが用意されていないなら強引にキーイベントを送信してみようと思いつきました。


通常Javaからは非Javaアプリの外部操作はできませんが、SWTを使うとWindowsAPIが使えるのでできてしまうわけです。

WindowsAPIを調べてみると、PostMessage()かSendMessage()を使うと任意のウィンドウへキーイベントを送信できるみたいです。
ただし今回の場合Becky!のメール一覧画面(リストビュー)のウィンドウハンドルを指定するには、Becky2MainFrameツリーの下にあるSysListView32を探す必要がありますが、SysListView32は汎用的な名前なので、FindWindow()で簡単に探すことは出来ません。


VC++/VBであればFindWindowEx()で簡単に検索できますが、残念ながらJavaからはFindWindow()しか使えないので自分で検索しました。

int hWnd = OS.FindWindow(new TCHAR(OS.CP_INSTALLED, "Becky2MainFrame", true), null);

ArrayList list = new ArrayList();
list.add(String.valueOf( OS.GetWindow(hWnd, OS.GW_CHILD) ));

while (list.size() > 0) {
	int i = Integer.parseInt( list.get(list.size()-1).toString() );
	list.remove(list.size()-1);

	TCHAR buf = new TCHAR(OS.CP_INSTALLED, 256);
	OS.GetClassName(i, buf, 256);
	    
	if (buf.toString(0, buf.strlen()).equals("SysListView32")) {
		hWnd = i;
		break;
	}
	
	int c = OS.GetWindow(i, OS.GW_CHILD);
	
	if (c == 0) {
		int n = OS.GetWindow(i, OS.GW_HWNDNEXT);
		if (n == 0) {
			continue;
		} else {
			list.add(String.valueOf(n));
		}
	} else {
		int n = OS.GetWindow(i, OS.GW_HWNDNEXT);
		if (n != 0)
			list.add(String.valueOf(n));
		list.add(String.valueOf(c));
	}
}


ウィンドウハンドルが見つかれば後はPostMessage()でキーイベントを送信するだけです。

// 右クリックの代わりにコンテキストメニューのキーイベントを送信
OS.PostMessage(hWnd, OS.WM_CONTEXTMENU, 0xffffffff, 0xffffffff);

// ↓キーのキーイベントを送信
OS.PostMessage(h, OS.WM_KEYDOWN, OS.VK_DOWN, 0);

// 同様に↑キー
OS.PostMessage(h, OS.WM_KEYDOWN, OS.VK_UP, 0);

// 同様にエンターキー
OS.PostMessage(h, OS.WM_KEYDOWN, OS.VK_RETURN, 0);

// 同様にBキー
OS.PostMessage(h, OS.WM_CHAR, 'B', 0)


これらのキーイベントを組み合わせて、

メールを選択→右クリック→「カラーラベルを付ける(B)」を選択→色を選択する

という流れを自動的に行うことができます。


勝手にカラーラベルが付くのを見ると面白いものです。
BkTagを使うとそれを体験できますよ。