カテゴリー別

お絵描き、デザイン

写真、動画関連ソフト

アメーバピグ専用ソフト

ホームページ関連

画像処理

スキャナー用

SEO 関連

お楽しみ

その他

過去ログ

2018年07月10日(火)

Windows API、ウィンドウクリック時にアクティブ化しないようにする

写真閲覧ソフトのミルノ PC フォトフレーム の修正中。
現在、メニューを「表示スケール」に対応させる作業中です。

写真をミルノに!

で覚えてね。キラーン。

Windows API の TrackPopupMenu
モニター毎の DPI に対応していないので
自作のポップアップメニューを改良中です。

自作のポップアップメニューとは、
ウィンドウの描画やマウスメッセージの処理など、
全て自分のコードで行うものです。

で、今日困ったのが、自作のポップアップメニューを
クリックしたときに、メニューにフォーカスが来てしまう問題です。

フォーカスは、メニューを表示したときのまま、
メニューのウィンドウは取得しないのが正しい挙動です。

色々と試しましたが、うまくいった方法は次の通り。

フォーカスを阻止する方法

ポップアップウィンドウに届く、
WM_MOUSEACTIVATE メッセージに、
MA_NOACTIVATE を返します。

これだけで OK です。

ポップアップメニューは、オーナーウィンドウの
外に、はみだして表示する必要があるので、
必然的に、トップレベルウィンドウになります。

トップレベルウィンドウは、クリックすると、
ディフォルトの挙動ではアクティブになるので、
MA_NOACTIVATE で防ぎます。

フォーカスは、アクティブ化の副作用で発生するので、
アクティブ化を阻止すれば、フォーカスも発生しません。

その他の試した方法1

よくわかりませんが、ウィンドウの拡張スタイルに、
WS_EX_NOACTIVATE を設定する方法は効きませんでした。

効かなかった原因は不明です。

その他の試した方法2

WM_ACTIVATE で、メニューがアクティブ化したときに
元のウィンドウを、SetActiveWindow しても
一回アクティブになっちゃってるので、
フォーカスが発生しちゃいます。

その他の試した方法3

WM_SETFOCUS メッセージで、
元のウィンドウを、SetFocus すると
フォーカスを元に戻せますが難点があります。

元のフォーカス先のウィンドウ (のルート) がアクティブ化し、
最前面にくるので、メニューのウィンドウが
z オーダー的に、後ろに隠れちゃいます。

SetFocus した後、むりやり z オーダー
を調節できますが、ちらつきます。

メニュー表示元のウィンドウが
「最前面」で無い場合は、メニューを
最前面にするとちらつきを抑制できますが、
表示元が「最前面」の場合は回避不能です。

また、フォーカスが一瞬は移動するので、
フォーカスのあるなしで描画が変わる
ウィンドウも、ちらつきます。

例えば、ツリービューはフォーカスがある状態では
選択項目が「青色」ですが、フォーカスが無いと
「灰色」になるため、ちらつきます。

おまけ

トリッキーな方法を使うと、
フォーカスを戻したウィンドウの後ろに
メニューが一瞬隠れる「ちらつき」は回避できました。

その方法は、フォーカスを戻す先のウィンドウの
トップレベルウィンドウのウィンドウプロシージャーで、
WM_WINDOWPOSCHANGING メッセージの処理をいじります。

具体的には、ポップアップメニューをクリックした場合のみ
SWP_NOZORDER フラグを立てて、z オーダーの変更を阻止します。

ただ、この方法はフォーカスの戻し先の
ウィンドウプロシージャーをいじる必要があるので、
あまり、よい解決方法にはならないでしょう。

・・・

日本語の最新版はこちらのページから、ダウンロードできます
You can download the latest version of Miruno PC Photoframe here.

x64 の最新版はこちらのページから、ダウンロードできます
Download the latest version of Miruno PC Photoframe x64 here.

・・・

月額会員専用のx64 版 もあります。
月額会員には、こちらのページから参加できます

・・・

WM_SETFOCUS のところで
なんとかしようとしてたら、
無駄に、時間かかったわー。

ミルノ PC フォトフレーム
ミルノ PC フォトフレームのダウンロード
ミルノ PC フォトフレームの更新履歴
ご意見・ご要望連絡窓口


コメント
コメントする