DOBON.NET DOBON.NETプログラミング掲示板過去ログ

Tips フォームの移動 についての質問

分類:[(未選択)]

こちらのTips タイトルバーのないフォームを移動できるようにする
dobon.net/vb/dotnet/form/moveform.html
で恥ずかしい質問なのですが、
WndProc()メソッドはどのように扱うのでしょうか?
イベントハンドラでは引数が異なるので使えませんでした。
メソッド自体は動いているのですが、

>この方法もはじめの方法と同様、このままでは、フォーム上にあるコント
>ロールの上でマウスのボタンを押して移動させようとしてもウィンドウは
>移動しません。

記事の通りフォームは動きません。はじめの方法と同様という言葉から
イベントハンドラに登録するのかな?と思うのですが、どうも上手くいきません。
単語でもよいので、調べるべき事項などお知らせ頂ければ幸いです。
#2005VBにて3例とも動作確認してOKでした。

> WndProc()メソッドはどのように扱うのでしょうか?
> イベントハンドラでは引数が異なるので使えませんでした。
> メソッド自体は動いているのですが、

予想ですが、MessageをSystem.Windows.Forms.Messageにしたらエラーがなくなりませんか?

> 記事の通りフォームは動きません。はじめの方法と同様という言葉から
> イベントハンドラに登録するのかな?と思うのですが、どうも上手くいきません。

Tipsではイベントハンドラそのものなんですが、もう少し具体的に書けないでしょうか?
ご返信ありがとうございます。

質問事項を上手く表現できず申し訳ありませんでした。
何が解らないのかが解っていない状態なのです。

WndProcメソッドはそのままForm1クラス内へコピペしました。
このWndProcをMouseEventなどに追加しようとすると、引数の型が異なる為
登録できません。そこで新しく自分で
public delegate void MyEventHandler( ref Message m );
public event MyEventHandler myEventHandler;
を記述しForm1コンストラクタで
this.myEventHandler += new MyEventHandler( ref Message m );
としてもマウスイベントとは関係がありませんし、
マウスイベント中にWndProcを呼び出そうにも引数のMessageが解りません。

Messageを検索してもその役割などやMessageそのもので
どうやったらMessageを送れるのかが解らないのです。
■No15484に返信(もちさんの記事)
> WndProcメソッドはそのままForm1クラス内へコピペしました。
> このWndProcをMouseEventなどに追加しようとすると、引数の型が異なる為
> 登録できません。そこで新しく自分で
> public delegate void MyEventHandler( ref Message m );
> public event MyEventHandler myEventHandler;
> を記述しForm1コンストラクタで

オーバーライドなので、イベント ハンドラの設定は必要ありません。
IDE が Visual Studio であるならば、

protected overirde...

とタイプした時点でインテリセンスが表示されるはずです。

.........................................................................................................................
C# と VB.NET の入門サイト http://jeanne.wankuma.com/
じゃんぬねっと日誌      http://blogs.wankuma.com/jeanne/
> 何が解らないのかが解っていない状態なのです。

WndProcは特殊なプロシージャです。
WindowsOSはウィンドウ(クラス)というオブジェクト単位の集まりです。
#ウィンドウ=ウィンドウハンドルを持っているもの
#ウィンドウにはEdit、Static(ラベル)、Listなどがあります。
そのウィンドウごとにWindowProcという標準のプロシージャを実装しており
OSからのメッセージにより振る舞いをおこないます。
目に見えるコントロールの外観はそこにそのような描画ルーチンがあるからそのような外観になるのです。
よくサブクラス化という言葉を聞きますが、それはそのルーチンをトラップして
独自の挙動をおこなうというものです。
Frameworkでは、もともとのWndProcをオーバーライドすることで同様のことを実現しています。

今回の例だと、MyBase.WndProc(m)でまず標準の実装を呼び出したあと
フォームの内側がポイントされていたら、「タイトルバーがポイントされた」と結果をすり替えています。
その結果、OSが勘違いしてポインタの移動によりフォームが移動するわけです。

なのでWndProcはトラップするメッセージに対して独自の処理をおこなうということになり
そこへ何かを関連付けするというようなものではありません。
> オーバーライドなので、イベント ハンドラの設定は必要ありません。

あぁ、私もイベントハンドラなんて書いちゃいましたね。
混乱させてしまったかもしれません。
じゃんぬねっとさん、まどかさん、ご返信ありがとうございます。
詳細に説明してくだり、とても解り易かったです。

投稿するまでの経緯を少し詳細に述べると、

Messageを検索していた際にMessageはそのままメッセージ、伝言であり、
その伝言に対して各自はウィンドウを再描画する、アプリケーションを閉じる
などを行っており、Tipsの例では本来の伝言を"タイトルバーを選択しています"
と異なる伝言にすり替え、ベースの挙動をタイトルバー選択時の挙動としている。
と解釈していました。

WndProcをコピペして挙動をステップ実行で確認していた際、
メソッドは実行されており、すりかえ?命令文にも達していました。
ですが、Tipsでの記述通りフォームが移動しなかった為、何か設定が足りない。
と考えイベントに登録してみたり、メソッドを直接呼び出そうとしてみた次第です。

何が足りないのか、なぜコピペしただけではフォームが移動しないのか
が解っていないのです。

基礎知識が稚拙貧弱である為、もっと基礎からきちんと学習しみたいと思います。
まどかさん、じゃんぬめっとさん、ご指導ありがとうございました。
> WndProcをコピペして挙動をステップ実行で確認していた際、
> メソッドは実行されており、すりかえ?命令文にも達していました。
> ですが、Tipsでの記述通りフォームが移動しなかった為、何か設定が足りない。
> と考えイベントに登録してみたり、メソッドを直接呼び出そうとしてみた次第です。

ステップ実行だと動作しないでしょう。
なぜならVS(他のウィンドウ)に制御が移り、メッセージが寸断されるからです。
他にフォーカス系のイベントも確実な再現ができない代表例ですね。
> ステップ実行だと動作しないでしょう。
> なぜならVS(他のウィンドウ)に制御が移り、メッセージが寸断されるからです。
> 他にフォーカス系のイベントも確実な再現ができない代表例ですね。

ご進言ありがとうございます。
ステップ実行に関しては、フォームを移動させる動作の確認ではなく、
メソッドとして機能、認識されているかを判断する為でした。

正しくは起動初頭からのステップではなく、メソッド直前にブレイクポイントを
設けてからのステップでした。 あいまいな記述失礼しました。
> 正しくは起動初頭からのステップではなく、メソッド直前にブレイクポイントを
> 設けてからのステップでした。

少なくともWndProcでブレークするとだめですよ。
実装に書いたメッセージの種類に関わらず、受け取るすべてのメッセージの入り口ですし
ブレークしたときから先に書いたようにメッセージが途切れます。

DOBON.NET | プログラミング道 | プログラミング掲示板