通知アイコンの高DPI対応

複数の解像度に対応した.icoを持っておけば、高DPIは簡単に対応できるけど、アニメーションとかのためにアイコンを動的生成したい。 今回のお話は動的生成自体ではなく、DPIの変更時にアイコンが酷い見た目になるのを対策することである。

結論としてはMSのドキュメントの「タスク バーの作成通知」に記載の通り、「TaskbarCreated」イベントを受け取れば問題ない。

一般的なWindowの高DPI対応

Window側で、「WM_DISPLAYCHANGE」と「WM_DPICHANGED」の二つのメッセージをハンドルすればいい。 上で挙げたメッセージ自体はTaskBarでも上のメッセージがしっかり生じている。

タスクバーのメッセージ

TaskBarの場合(解決策)

冒頭のMSのドキュメントのように、TaskbarCreatedのウィンドウメッセージがDPI変更時に届く。

タスクバーのメッセージ

重要なのは[登録された"TaskbarCreated"]の部分である。 ググっても出ないメッセージID (動的生成されるメッセージIDの方を検索していた?) だと思ったが普通にMSのドキュメントに記載されていた。Spy++ではしっかり名前も教えてくれるのが便利。 これがDPIが変更されたり、DPIが違うウィンドウの間でタスクバーを移動させたりすると呼び出される。

この際の注意点

DPIが変更された場合、あくまでもアイコンの変更のため、NotifyIconはNIM_MODIFYで呼び出す必要がある。しかし、同じメッセージでエクスプローラーが再起動された後のパターンが存在し、その場合はNIM_ADDで呼び出す必要がある。

まとめ

適当なウィンドウでRegisterWindowMessage("TaskbarCreated")の返り値と同じIDのメッセージを監視すればDPIの変更とエクスプローラーの再起動を検知できる。 ただし、DPI変更の場合は編集、再起動の場合は追加が必要であり、注意が必要である。

再読み込み