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

モードレスメッセージボックスの作成について

環境/言語:[OS : Windows XP Professional / 言語 : C# / .NET Framework : 1.1]
分類:[.NET]

【解決したい問題】

子ウィンドウがあるMDI形式のアプリケーションで、
以下の動作を実現する方法はあるのでしょうか。
1) ある子ウィンドウがメッセージを表示
2) メッセージを表示した子ウィンドウはメッセージ表示画面の"OK"ボタンを
押下するまで操作不可
3) メインフォームと他の子ウィンドウは動作する

メッセージ表示画面は自作しました。(モードレスで表示しています)
メッセージの振り分け方法などがあるのでしょうか...

なにか良い方法はありますでしょうか。
よろしくお願い致します。
> 子ウィンドウがあるMDI形式のアプリケーションで、
> 以下の動作を実現する方法はあるのでしょうか。
> 1) ある子ウィンドウがメッセージを表示
> 2) メッセージを表示した子ウィンドウはメッセージ表示画面の"OK"ボタンを
> 押下するまで操作不可
> 3) メインフォームと他の子ウィンドウは動作する

試してませんが、子ウィンドウを Enable = false にすると「そんな感じ」にならないですかね?
■No13687に返信(渋木宏明(ひどり)さんの記事)
>>子ウィンドウがあるMDI形式のアプリケーションで、
>>以下の動作を実現する方法はあるのでしょうか。
>>1) ある子ウィンドウがメッセージを表示
>>2) メッセージを表示した子ウィンドウはメッセージ表示画面の"OK"ボタンを
>> 押下するまで操作不可
>>3) メインフォームと他の子ウィンドウは動作する
>
> 試してませんが、子ウィンドウを Enable = false にすると「そんな感じ」にならないですかね?
>

渋木宏明(ひどり)さん、ありがとうございます。
早速、試してみました。しかし、以下の問題がありました。

1) 各子ウィンドウには、リストビューとリストビューで選択された詳細を
表示するテキストボックス及びラベルが、スプリッタで上下に2分割し
てあります。子ウィンドウを Enable = false とすると、リストビュー
の背景が"グレー"になってしまう。また、ラベルの文字が"薄く"表示さ
れてしまう。
2) 子ウィンドウの Enable が false の時に、他の子ウィンドウを表示し、
他の子ウィンドウを全部消すと、メニュー構成が1つも子ウィンドウを
表示していない構成になってします。(各子ウィンドウがメニューを持っ
ていて、各子ウィンドウが表示されるとマージしております。)

実現したい動作は以下となります。
※ある子ウィンドウがメッセージを表示中
1) 表示した子ウィンドウに対する操作は全て行えない(モーダル的)
操作を要求されたら画面を"フラッシュ"させる(モーダル的)
2) 他の子ウィンドウに対する操作は全て行える(モードレス的)
3) 表示した子ウィンドウ以外のメニューやツールバーは全て動作す
る(モードレス的)

依頼主からの要求自体に無理があるような気がするのですが...
宜しくお願い致します。
2005/11/13(Sun) 11:24:18 編集(投稿者)

お世話になります。

■No13688に返信(あららさんの記事)
> 実現したい動作は以下となります。
> ※ある子ウィンドウがメッセージを表示中
> 1) 表示した子ウィンドウに対する操作は全て行えない(モーダル的)
> 操作を要求されたら画面を"フラッシュ"させる(モーダル的)
> 2) 他の子ウィンドウに対する操作は全て行える(モードレス的)
> 3) 表示した子ウィンドウ以外のメニューやツールバーは全て動作す
> る(モードレス的)
泥臭いですが、こんな方法はいかがでしょう。

'画面と表示した人を管理するクラス
Public NotInheritable Class Class1
  Public Shared MessageForm As Form
  Public Shared Owner As Form
End Class

'Form3 を表示している時にアクティブにしてもよいクラス
Public Class Form1
  Inherits System.Windows.Forms.Form

#Region " Windows フォーム デザイナで生成されたコード "
...略
#End Region

  Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim f2 As Form2 = New Form2
    f2.Show()
  End Sub
End Class

'Form3 を表示している時にアクティブにしたくないクラス
Public Class Form2
  Inherits System.Windows.Forms.Form

#Region " Windows フォーム デザイナで生成されたコード "
...略
#End Region

  Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim f3 As Form3 = New Form3(Me)
    f3.Show()
  End Sub

  '自身がActiveになった時、Class1の保持している内容を確認する
  Private Sub Form2_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Activated
    If Not Class1.Owner Is Nothing AndAlso _
     Class1.Owner Is Me AndAlso _
     Not Class1.MessageForm Is Nothing Then
      Class1.MessageForm.Activate()
    End If
  End Sub
End Class

'メッセージを表示する画面
Public Class Form3
  Inherits System.Windows.Forms.Form

  Public Sub New(ByVal owner As Form)
    Me.New()
    Class1.Owner = owner
    Class1.MessageForm = Me
  End Sub

#Region " Windows フォーム デザイナで生成されたコード "

  Private Sub New()
    MyBase.New()

    ' この呼び出しは Windows フォーム デザイナで必要です。
    InitializeComponent()

    ' InitializeComponent() 呼び出しの後に初期化を追加します。
  End Sub

  ' Form は、コンポーネント一覧に後処理を実行するために dispose をオーバーライドします。
  Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
    If disposing Then
      If Not (components Is Nothing) Then
        components.Dispose()
      End If
    End If
    MyBase.Dispose(disposing)
    Class1.Owner = Nothing
    Class1.MessageForm = Nothing
  End Sub
...略
#End Region
End Class
> 早速、試してみました。しかし、以下の問題がありました。

じゃあ、WndProc をオーバーライドして、入力系のメッセージを全部握りつぶしてしまうとか。
■No13690に返信(渋木宏明(ひどり)さんの記事)
>>早速、試してみました。しかし、以下の問題がありました。
>
> じゃあ、WndProc をオーバーライドして、入力系のメッセージを全部握りつぶしてしまうとか。
>

なおこ(・∀・) さん、渋木宏明(ひどり) さんありがとうございます。

検討の結果、渋木宏明(ひどり) さんのWndProc をオーバーライドする方法で
実装することにいたしました。なかなかうまくいかないのですが、いろいろと
試してみます。また問題が発生したら新たに質問させて頂こうと考えてます
ので、そのときにはまたよろしくお願いします。
ありがとうございました。
解決済み!
■No13726に返信(あららさんの記事)
> 検討の結果、渋木宏明(ひどり) さんのWndProc をオーバーライドする方法で
> 実装することにいたしました。なかなかうまくいかないのですが、いろいろと
> 試してみます。また問題が発生したら新たに質問させて頂こうと考えてます

GetMessage() API のヘルプの「解説」をよく読むと分かることですが、WM_KEYFIRST 〜 WM_KEYLAST がキー入力系の、WM_MOUSEFIRST 〜 WM_MOUSELAST がマウス入力系の一般的なメッセージ ID の範囲を表していることが分かります。

これをうまく活用すれば、知っている限りのメッセージ ID を書き並べて処理を振り分けるような無駄をしなくて済むかもしれません。

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