ウィンドウの大きさを自由に変更できたらいいのに……と思うことがあります。自分で作成したアプリであれば表示位置とサイズを自由に設定できますが、他人がつくったアプリの場合はそうはいきません。さてどうしたものでしょうか?

ここはAPI関数をつかいましょう。

POINTからウィンドウハンドルを取得できます。

ウィンドウの位置とサイズを変更することができます。最後のuFlagsを指定することで、位置だけとかサイズだけとか常に最前面になるようにすることができます。

指定したウィンドウの祖先のハンドルを取得します。第二引数をGA_PARENTにすることで親ウィンドウを取得、GA_ROOTにすると親ウィンドウのチェーンをたどってルートウィンドウを取得、GA_ROOTOWNERにすることでGetParent 関数が返す親ウィンドウのチェーンをたどって所有されているルートウィンドウを取得します。

これであるポイントを指定すればそこにあるウィンドウのサイズを変更することができます。

デザイナで以下のようなものをつくります。

○と×が組み合わさったマークはビットマップ(64×64ピクセル)です。

コンストラクタ内でこのようにやっておけば背景が透明になります。

そしてピクチャーボックスのうえでクリックされたらカーソルを変更します。

これでマークがとれてカーソルになったように見えます。

ピクチャーボックスでクリックされたらマウスキャプチャします。そうすればこのフォームの外でマウスボタンが離されてもそれを検知することができます。

マウスキャプチャが解除されたらピクチャーボックス上のビットマップを元に戻します。そして自分自身の上でドロップされなかった場合はそのウィンドウの位置情報を表示させます。

さてどのような情報を表示させるかですが、ウィンドウをX、Y座標、幅、高さ、プロセス名、プロセスID、実行ファイルのパスを表示させます。

まずウィンドウハンドルを取得します。

これはウィンドウハンドルからウィンドウのタイトルを取得するメソッドです。

これはウィンドウハンドルからプロセスIDをメソッドです。

これはプロセスIDからプロセス名を取得するメソッドです。

さて実行ファイルのパスはプロセスIDを使って

で取得できるのですが、64ビット環境ではうまくいかない場合があります。プロジェクトのプロパティを適切にセットすればいいのですが、ここでは別の方法を考えます。

System.Management.dllを参照設定に追加すれば、以下の方法で実行されているすべてのプロセスのプロセスID、プロセス名、ファイル名が取得できます。そこで実行されているすべてのプロセスを取得してforeach文で探すという方法です。

このメソッドはプロセスIDから実行ファイルのパスを取得します。

このメソッドはウィンドウの左上の座標を取得します。

このメソッドはウィンドウのサイズを取得します。

したがって以下の方法で、マウスキャプチャが解除されたときのマウスポインタの位置からウィンドウのX、Y座標、幅、高さ、プロセス名、プロセスID、実行ファイルのパスを取得できます。

次にウィンドウの位置とサイズを変更する方法を考えます。さきほど保存しておいたウィンドウハンドルをSetWindowPos関数に渡せば可能です。ただその前に本当に有効なウィンドウハンドルが保存されているかどうか調べる必要があります。

API関数 IsWindow関数はウィンドウが存在すると0以外の値を返します。

SetWindowPosメソッドは指定した場所に指定したサイズでウィンドウを表示させるメソッドです。ウィンドウハンドルが不正な場合はfalseを返します。

有効なウィンドウハンドルが保存されている状態であれば、適切な座標とサイズを指定するとウィンドウを移動させます。そうでない場合はエラーを示すメッセージボックスが表示されます。