- PR -

MDI子フォームのタイトルバーをクリックで最大化されてしまう。

1
投稿者投稿内容
Hidering
常連さん
会議室デビュー日: 2007/05/22
投稿数: 33
投稿日時: 2007-09-24 14:01
お世話になります。

MDI子フォームのタイトルバーをクリックすると
最大化されてしまい困っております。

この現象は子フォームのForm_Activateに
Application.DoEvents()を追加したことで発生するようになりました。

Application.DoEvents()は子フォームのロードからアクティブ化終了間際までに
発生したマウスイベントを処理するのに使用しています。
マウスイベントを処理するのは子フォーム内にあるPanelコントロール(Paintイベントは自分で処理しています)
が中途半端な状態で描画されてしまうのを防ぐためにフラグ(Me.boMouseEnabled )を用いていて
Falseの場合はMouseDown処理を受け付けなくし、
以降のMouseMove(描画処理。boMouseDown=Trueで描画)を行わないように
しているためです。
要するにApplication.DoEventsでフラグがFalseのうちにマウスイベントを処理して、
Form_Activate終了間際でフラグをTrueにもどし、
以降通常の描画処理を可能にしています。
Application.DoEventsを行わない場合、フラグ=falseの効果はなく
Form_Activate終了後にマウスイベントが発生して描画処理が上手くいかなくなります。

最大化されることを避けるためにメッセージフィルターを使用し
メッセージの削除をおこなったところ最大化はしなくなったのですが、
子フォームの端っこをクリックするとサイズ変更ができる状態になってしまいます。
(通常ですと、端っこをクリックしてドラッグする動作が
マウスの移動だけでサイズが変わるようになってしまう)

長くなってしまいましたが、この現象を回避できる方法はあるでしょうか?
どうかお知恵をお貸し下さい。宜しくお願いします。

以下ソースです。

Sub 子フォーム_Activated()
Me.boMouseEnabled = False
Me.Cursor = Cursors.WaitCursor
If Me.MessageFilter Is Nothing Then
Me.MessageFilter = New MsgFilter
Application.AddMessageFilter(Me.MessageFilter)
End If

処理

Application.DoEvents()
Application.RemoveMessageFilter(Me.MessageFilter)
Me.MessageFilter = Nothing
Me.Cursor = Cursors.Default
Me.boMouseEnabled = True
End Sub

Private Sub MyPanel1_MouseDown()
If Not boMouseEnabled The
Exit Try
End If

処理

End Sub

Public Class MsgFilter
Implements IMessageFilter

Public Function PreFilterMessage(ByRef m As System.Windows.Forms.Message) As Boolean Implements System.Windows.Forms.IMessageFilter.PreFilterMessage
If ((m.Msg >= 513) And (m.Msg <= 515)) Or (m.Msg >= 161 And m.Msg <= 163) Then
Return True
End If
Return False
End Function
End Class
れい
ぬし
会議室デビュー日: 2005/11/01
投稿数: 346
投稿日時: 2007-09-27 06:20
引用:

Hideringさんの書き込み (2007-09-24 14:01) より:
長くなってしまいましたが、この現象を回避できる方法はあるでしょうか?



きっとできると思いますが、
説明を読むのも、対応策を考えるのもめんどくさいです。
検証は更にめんどくさいものになるでしょう。

こういったことになるのは、
イベントの使い方を間違っているからです。

DoEventsは、互換性維持みたいなもので、殆どの場合必要ありません。

イベントの意味をよく考え、
DoEventsを使わない方法を考えたほうが早いですよ。
Hidering
常連さん
会議室デビュー日: 2007/05/22
投稿数: 33
投稿日時: 2007-10-03 06:44
れいさん。いつもご回答ありがとうございます。

イベントについて精査してみましたが、
子フォーム_ActivatedではMDI子フォームの切り替え処理、
MyPanel1_MouseDownでは描画開始判定処理等、
どうも間違った箇所に書いている気がしませんでしたので

MouseDown処理で不具合が起こる原因をもう一度調査したところ
一度もMypanel1に画像を描画していない状態で
MouseDownイベントを処理していることで発生していることが
分かりました。

Mypanel1.Invalidate()
Mypanel1.Update()

と明示的に記述はしていたのですが、Paintイベントが後回しになっていたようです。
そこで

Mypanel1.Invalidate()
Mypanel1.Update()
Application.DoEvents()

としてやることで即座に描画され、MouseDown処理での不具合が解決されました。

引用:
DoEventsを使わない方法を考えたほうが早いですよ。


とのご指摘でしたが、
イベントが処理されずに溜まっている限り
他の方法では解決できそうもなかったので
このような方法をとりました。

ありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)