「かえかえ君」のプレビューは高速です。対象とほぼ同じように表示され、ほぼ遅延はありません。
フレームレートの高いゲームでも遅延やフレーム落ちがしないのは、画面キャプチャや録画的な手法を使用していないためです。
この仕組みなどについて簡単にまとめてみました。
いきなり結論
Windows開発に詳しい方は「Desktop Window Manager (DWM)のAPIを使用している」と聞くだけで仕組みが分かると思います。
デスクトップ ウィンドウ マネージャー (Windows)
https://msdn.microsoft.com/ja-jp/library/windows/desktop/ff684179(v=vs.85).aspx
Desktop Window Manager – Wikipedia
https://ja.wikipedia.org/wiki/Desktop_Window_Manager
DWM Reference (Windows)
https://msdn.microsoft.com/ja-jp/library/windows/desktop/aa969499(v=vs.85).aspx
要は、4分割した領域それぞれにDwmRegisterThumbnailで表示しているだけです。
いわゆるAero無効になる環境だと使用できないのはそういうわけです。
実際どのような仕組みなのか
DWMを使用しない(使用できない)場合、アプリケーションそれぞれが画面に直接描画します。
それぞれが描画に責任を持つため、重ね合わせた際に半透明にするなど結構な負荷になります。
また、別のウィンドウの表示の変化を把握するには監視する必要があり、リアルタイムなプレビュー表示には大きな負荷が伴います。
DWMを使う場合、アプリケーションはDWMが管理する領域(オフスクリーンサーフェイス)に描画します。
DWMはそれらの領域を合成して画面に描画します。
最終的な描画をDWMが行うため、重ね合わせの半透明化などの負荷が小さくなります。
もちろんDWM自身の処理負荷があるため、スペックが足りなければ逆に負荷となります。
DWM(かつてはDCE)が出たての頃は「Aero無効にする(DWM無効にする)とパフォーマンスが上がる!」なんてのもパフォーマンス改善の定石となっていました。
DWMはGPUを使った描画ができるため、今は無効にした時の方がパフォーマンスが悪くなる環境の方が多いかと思います。
このDWMが管理している描画領域は複数の箇所に合成させることができます。
本来の場所ではない領域への描画を「サムネイル」と言います。つまり見本として別の場所に描画するということです。
これを利用してOSはタスクバーのプレビューやタスク切り替えのプレビューを実現しているわけです。
同じことを「かえかえ君」でもやっています。
図のように、「かえかえ君」からWDMへサムネイル表示箇所を指定させています。
こうすることで、「かえかえ君」の指定した場所にサムネイルが描画されているわけです。
対象のアプリケーションに影響を与えることなく、描画時に場所を増やしているだけなので軽快に表示されるわけです。
キャプチャや録画などの手法では実現できないパフォーマンスなのはこれが理由なのです。
ところでサムネイル対象の識別で怪しいことやっていないよね?
プレビューの描画自体はWDMを使用しているため、実行中のアプリケーションに触れておらず、もちろん侵入もしていないということが分かると思います。
しかし、そのプレビュー対象自体を識別する際に何か危ないことやってるんじゃないかという疑いはあると思います。
その疑いが集約されるのがこのウィンドウ選択ダイアログでしょう。一覧表示アイコン表示プレビュー表示と怪しいところが一式揃っています。
最初に結論から言うと、全ての情報はタスクマネージャ等の管理機能と同じ手法で取得しています。
マルウェアのように、実行中のアプリケーションに侵入するような手法は使用していません。
まず、この画面の動作から。
リスト表示から選択までの流れはざっとこんな感じです。
- プロセス一覧を取得する(System.Diagnostics.Process.GetProcesses)。
- プロセスのファイル名を取得し、ファイルからアイコンを取得する(System.Drawing.Icon.ExtractAssociatedIcon)。
- プロセスのメインウィンドウのタイトル・起動日時・プロセスID・メインウィンドウハンドルを取得する。
- 全てのプロセスに対して2~3を行う。
ただし、メインウィンドウのタイトルが空のものと、「かえかえ君」自身は除外する。 - リストで項目が選択されたら、DWMへメインウィンドウハンドルを渡してサムネイルをダイアログ右側に表示させる。
- 「ウィンドウ全体を選択」もしくは「ウィンドウの内側を選択」が押されたら、選択中のプロセスのメインウィンドウハンドルを返す。
要は、タスクマネージャーなどと同様にOS上に公開されているプロセス情報から各種情報を引き出している、ということになります。
アプリケーションに直接侵入して情報は取ってきていないのでご安心ください。
他にこのツールに怪しいところはないの?
気になるポイントとしてはこのあたりかと思います。
- 何かを記録していないか。
- 何かを送信していないか。
どちらも行っていません。
記録に関しては表示したウィンドウの履歴すら取っていませんし、画面キャプチャなども取っていません。
このツールが保存するのは設定ファイルのみであり、それもオプションダイアログで表示している項目だけです。
今後の機能拡張でも「記録」というキーワードに触れる機能を実装する予定はありません。
当然ながら送信も行っていません。
そもそもネットワークを使用するタイプのツールではないため、外部とのトラフィックは発生しません。
もし何らかの怪しいトラフィックがある場合は、ウィルス汚染の可能性も考えられますので直ちに使用を中止してください。
最後に
このツールの開発は友人の「ゲーム中に手元で簡単にウィンドウ切り替えられるツールが欲しい」という要望で始まりました。
最初は単純にホットキーで切り替える機能だけでしたが、使ってるとこを見ていてプレビューもあると便利なのかなと。
プレビューは当初定期的な画面キャプチャでやっていましたが、それではあまりに遅く表示状態に左右される。そこでその昔サンプルコードだけ動かしたDWMのAPIを使ってみることに。軽快にプレビューが動いたときは感激したもんです。
プログラム量としてはそんなに大きくなく、やってることも難しくないです。
Windows FormsでのWindowsデスクトップアプリケーションの開発経験がある方は、さほど苦労せず似たようなプログラムが組めると思います。
※画面はTableLayoutPanelで分割してDWMの描画先アンカーとなるLabelを置いてるだけ。
いかんせん需要がニッチで現在の実装も友人専用な感じなので、使える人がどのくらいいるか分かりません。
もし改善案や要望などありましたらコメントやお問い合わせからご意見いただければと思います。
2件の返信
Thank you for being my coach on this area. I enjoyed your article very much and most of all enjoyed reading the way you handled the aspect I considered to be coalroversint. You are always very kind towards readers like me and assist me to in my life. Thank you.
141Salutation right now there! Could you control only reveal your website together with my personal cheep forgather? There¡¯s plenty of fill that I believe would really experience your own proportionality. Please i want to cognise. Many thanks.