⌨
Windows, F# - グローバルホットキーを設定する
概要
起動している間、グローバルホットキーを有効にするタスクトレイ常駐型のアプリを F# で作る。
実装例
「Windows
+ Alt
+ C
」を入力すると空のメッセージボックスが表示されるサンプル。
open System.Windows.Forms
let createIcon () =
let toolStripMenuItem = new ToolStripMenuItem(Text = "&終了")
toolStripMenuItem.Click.Add(fun e -> Application.Exit())
let contextMenuStrip = new ContextMenuStrip()
contextMenuStrip.Items.Add toolStripMenuItem |> ignore
new NotifyIcon(
Icon = new System.Drawing.Icon @"icon.ico",
Visible = true,
Text = "TestApp",
ContextMenuStrip = contextMenuStrip
)
open System
open System.Runtime.InteropServices
[<DllImport("user32.dll")>]
extern int RegisterHotKey(IntPtr HWnd, int ID, int MOD_KEY, int KEY)
[<DllImport("user32.dll")>]
extern int UnregisterHotKey(IntPtr HWnd, int ID)
type HotkeyForm () as this =
inherit Form()
let icon = createIcon()
do
RegisterHotKey(this.Handle, 0x0000, 0x0001 ||| 0x0008, int Keys.C) |> ignore
Application.ApplicationExit.Add(fun e ->
UnregisterHotKey(this.Handle, 0x0000) |> ignore
)
override this.WndProc m =
base.WndProc(&m)
if m.Msg = 0x0312 && int m.WParam = 0x0000 then
MessageBox.Show("") |> ignore
interface IDisposable with
member this.Dispose() =
icon.Dispose()
do
use form = new HotkeyForm()
Application.Run()
解説
System.Windows.Forms
.NET 5 で参照できない場合は下記の記事にて設定方法を紹介しています。
タスクトレイにアイコンを表示する
open System.Windows.Forms
let createIcon () =
// アイコンをホバーした時に表示されるメニューの定義
// - クリックしたらアプリを終了する「終了」ボタンの作成
let toolStripMenuItem = new ToolStripMenuItem(Text = "&終了")
toolStripMenuItem.Click.Add(fun e -> Application.Exit())
// - メニューに「終了」ボタンを追加
let contextMenuStrip = new ContextMenuStrip()
contextMenuStrip.Items.Add toolStripMenuItem |> ignore
// アイコンの生成
new NotifyIcon(
// 表示する画像 (.ico)
Icon = new System.Drawing.Icon @"icon.ico",
// 表示/非表示
Visible = true,
// ホバー時に表示するテキスト (アプリ名など)
Text = "TestApp",
// 上で作成したメニューを追加
ContextMenuStrip = contextMenuStrip
)
グローバルホットキーを設定する
// System.Windows.Forms は前の部分で読み込み済み
open System
open System.Runtime.InteropServices
// Windows API
// - ホットキーの登録用
[<DllImport("user32.dll")>]
extern int RegisterHotKey(IntPtr HWnd, int ID, int MOD_KEY, int KEY)
// - ホットキーの解除用
[<DllImport("user32.dll")>]
extern int UnregisterHotKey(IntPtr HWnd, int ID)
type HotkeyForm () as this =
inherit Form()
let icon = createIcon()
do
// ホットキーを登録する
RegisterHotKey(this.Handle, 0x0000, 0x0001 ||| 0x0008, int Keys.C) |> ignore
// アプリ終了時にホットキーを解除する
Application.ApplicationExit.Add(fun e ->
UnregisterHotKey(this.Handle, 0x0000) |> ignore
)
override this.WndProc m =
base.WndProc(&m)
// グローバルホットキーが入力された時の処理
// && の左辺は固定
if m.Msg = 0x0312 && int m.WParam = 0x0000 then
MessageBox.Show("") |> ignore
interface IDisposable with
member this.Dispose() =
icon.Dispose()
ホットキーの登録
RegisterHotKey
第2引数
0x0000
~ 0xbfff
内の適当な値を渡す。また、以下の部分で同じ値を使う。
- 解除時
UnregisterHotKey
の第2引数 -
WndProc
内でのint m.WParam
との等価判定
第3引数
修飾キー (Alt
, Ctrl
, Shift
, Windows
) の指定。
複数の場合は |||
で区切る。
修飾キー | 値 |
---|---|
Alt | 0x0001 |
Ctrl | 0x0002 |
Shift | 0x0004 |
Windows | 0x0008 |
第4引数
キーコードの指定。
int Keys.キー
で取得できる。
実行する
do
use form = new HotkeyForm()
// フォームを表示しない場合、引数なしで実行
Application.Run()
更新履歴
日付 | 内容 |
---|---|
2021/03/25 |
Dispose を呼び出す処理を追加。 |
Discussion