通知アイコンの高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変更の場合は編集、再起動の場合は追加が必要であり、注意が必要である。