• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:C# の MDI)

C#のMDIの応用問題についての解決方法

このQ&Aのポイント
  • C#のMDIを使って複数の異なる子ウインドウを作りたい場合、子ウインドウごとにフラグを設けて、開くたびにフラグをセットする処理を行えば実現できます。
  • ただし、フラグがセットされたままになってしまい、二度と開けなくなる問題があります。子ウインドウが閉じられたことを知るためには、デストラクタを使用する方法が一般的ですが、C#ではデストラクタが呼び出されないため、別の方法で実現する必要があります。
  • 別の方法としては、子ウインドウを閉じる際にフラグをセット解除する処理を行うことが考えられます。子ウインドウのクローズイベントなどを利用してフラグのセット解除処理を行えば、問題を解決することができます。

質問者が選んだベストアンサー

  • ベストアンサー
noname#49664
noname#49664
回答No.1

C#ということは、.NET 1.1あたりでしょうか・・。 ウィンドウを閉じた際の処理をデストラクタで、というのはちょっと違うように思います。デストラクタは、インスタンスが破棄される際のものですので。ウィンドウを閉じたからといってその場で瞬時にデストラクタが呼び出されるとは限りません。例えば、他からそのインスタンスが参照されていれば、参照が切れるまで破棄はされませんから。  通常は、ウィンドウを閉じる際のイベントを利用するのが一般的だろうと思います。「Closing」「Closed」といったイベントが用意されているはずですので、それにメソッドをバインドして、その中で処理されてはいかがでしょう。

tttt23
質問者

お礼

回答ありがとうございました。 おっしゃるとおり「Closing」と「Closed」イベントがあり、この中でフラグのクリア処理を行えばうまく動作するようになりました。 「Closing」と「Closed」の差は何なのでしょうね。ウインドウを閉じる前と後に呼び出されるイベントかと思ってそれぞれの中でメッセージボックスを出力する処理を入れてみましたが、どちらの場合もウインドウが閉じられる前にメッセージボックスが現れます。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (1)

noname#49664
noname#49664
回答No.2

#1です。 Closingは、閉じる操作を行ったときに最初に送られるイベントです。これは、「クローズのキャンセル」のためにあるといっていいでしょう。例えば、多くのソフトではクローズボックスをクリックすると「ウィンドウを閉じるか、保存するか」といった確認のダイアログが現れ、キャンセルすることで閉じる操作を撤回できますね? そのためのものです。このイベントが無事に処理された後で、Closedイベントが発生します。こちらは本当に「閉じる際(直前)の処理」のためのものです。 Closingでは、引数にCancelEventArgsインスタンスが渡されます。この中のCancelをtrueに変更すると、クローズ操作がキャンセルされたと見なされ、次のClosedイベントは発生せず、ウィンドウも閉じられません。

tttt23
質問者

お礼

よく理解できました。 大変分かりやすい回答ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • MDIの子ウィンドウをスクリーンキャプチャ

    最近は少なくなりましたが、昔のOfficeなどMDI(マルチドキュメントインターフェース)のアプリケーションがあります。親ウィンドウの中に複数の子ウィンドウが表示されるインターフェースです。 このようなアプリで、子ウィンドウのみを簡単にキャプチャ出来るツールはないでしょうか?ALT+PrintScreenだと親ウィンドウを含むアプリケーション全体がキャプチャされます。 もちろん矩形指定でキャプチャすることは可能ですが、もっと手軽に出来ないかと。

  • MDIフォームとユーザコントロール

    VB.Netでの質問です。 ウィンドウメッセージを受け取りイベントを起こすユーザーコントロールクラス Class UserCtl Private Event MyKeyDown() Private Sub UserCtl_KeyDown() as Handels MyBase.KeyDown RaiseEvent MyKeyDown End Sub End Class プロセスA MDI子フォームにユーザーコントロールを追加し、子フォームにて、UserCtl.MyKeyDownイベントプロシージャでユーザーコントロールがウィンドウメッセージを受け取ったと認識し処理をします。 MDI子フォームはMDI親フォームより、CloseメソッドでしかCloseしません。 プロセスB FindWindowでMDI親フォーム, FindWindowExでMDI子フォーム、ユーザーコントロールハンドルを確認した上で、ユーザーコントロールにウィンドウメッセージをPostMessageします。 質問1 プロセスBからハンドルを探していますが、ウィンドウハンドル,ユーザーコントロールハンドルはいつまで有効なハンドルなのでしょうか? Closeでしょうか、それとも、Disposeでしょうか? 質問2 MDI親フォームでMDI子フォームをCloseした後でも、UserCtl.MyKeyDownは発生できるものなのでしょうか? 質問3 ユーザーコントロールで親フォーム(MDI子フォーム)がCloseされた事を認識する方法はないでしょうか? Me.Parent.IsDisposeでできるかなぁと考えているのですが。 よろしくお願いいたします。

  • MDIでのダイアログ生成

    VC++2005でMDIアプリケーションを作成しています。 ダイアログベースでは、DoModal()にてダイアログを生成していましたが、 MDIでのダイアログ生成の方法が分かりません。。 調べた結果、 (1)CreateWindow()にてクライアントウィンドウを作成 (2)CreateMDIWindow()にて子ウィンドウを作成 の順序で処理を行うことは分かりましたが、 関数の一部の引数に何を設定してやれば良いのかが不明です。。 ※下記はネット上にあったサンプルソースです。  「???」の箇所が不明な引数です。 (1) CreateWindow(   TEXT("MDICLIENT"), //MDICLIENT は固定です   NULL,   WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN,   0, 0, 0, 0,   hWnd,       //メインウィンドウのハンドル←???   (HMENU)1,    //←???   hInst,       //インスタンスハンドル←???   (LPSTR)&ccs    //CLIENTCREATESTRUCT構造体のポインタ←???  ); (2) HWND CreateMDIWindow(  MDI_CHILD ,   //ウィンドウクラス名  TITLE ,     //ウィンドウのタイトルバーテキスト  0 ,       //ウィンドウスタイル。WS_MAXIMIZE(最大化表示)など  CW_USEDEFAULT , //X座標  CW_USEDEFAULT , //Y座標  CW_USEDEFAULT , //幅  CW_USEDEFAULT , //高さ  hClientWindow , //クライアントウィンドウのハンドル ←???  hIns ,      //インスタンスハンドル       ←???  0        //アプリケーション定義の値 ); なお、行いたい処理の流れとしては、 CTestDialogクラスより、CTest2Dialogクラスのダイアログを、 呼び出したいのです。 うまく説明できず申し訳ありませんが、 お詳しい方おられましたら、具体例など交えてご説明頂けると幸いです。 お手数ですが、どうか宜しくお願い致します。

  • VB6でMDIフォームを使用しています。

    VB6でMDIフォームを使用しています。 MDIフォームで下記プログラムを作成しました。 (1)ツールバー上のボタン1を押し、子フォームAを表示させました。   ※子フォームAの WindowState を「2-最大化」に事前設定し、ウィンドウは最大化して表示されました。 (2)子フォームAを表示した状態で、同じツールバー上にあるボタン2を押し、子フォームB(ダイアログ)を表示させました。   ※子フォームBの WindowState を「0-標準」、BorderStyleを「3-固定ダイアログ」に事前設定し、表示されました。(一般的なオプション画面みたいなもの) 問題点はその際、子フォームAのウィンドウが勝手に「最大化」から「標準」に変わってしまうことです。 これを回避する方法はないのでしょうか? 以上、宜しくお願いいたします。

  • MDIプログラムで子ウィンドウの相対座標を得るには?

    VC++6.0でMDIプログラムを作っています。 Viewクラスでマウスの右ダブルクリックのメッセージを受け取って、 その関数の中で毎回、アクティブな子ウィンドウの左上の相対座標、 つまり、クライアント領域での子ウィンドウの左上の座標を知りたいのですが、 どのようにすれば得られるか分かりません。分かる方教えてください。

  • MFC:MDIにおけるビューのアクティブ化

    ・環境 VisualStudio2008SP1+FeaturePack Windows7 64bit タブドキュメント形式でMDIアプリを作っているのですが、複数ドキュメントがある際にプログラムから任意のビューを安全にアクティブ化させる方法がわからずに困っております。CMainFrame::SetActiveViewメソッドを使用すると指定したビューがアクティブになり所望の動作になるのですが、この方法だとドキュメントをクローズするときに以下の例外が出て怒られます。SetActiveViewはビューのOnCreate内で実行しています。  アクティブ化を解除しているアクティブ化コンテキストは、最近アクティブ化されたものではありません。 こういった状況に遭遇しない方法を探っているのですが使用するAPIと適切な使用タイミングがつかめず困っております。どなたかにご教授いただければ幸いです。

  • IE7でのタブ切り替え操作

    vista(IE7)に変えてからURLがひとつしか表示されなくなり次のURLを開くと今まで見ていたページは消えてしまいます。 ネットで調べたところIE7でのタブ切り替えです。と書いて在りましたが、どうしたら切り替えが出来るのかわかりません。 「MDIの原理を応用してひとつのウィンドウ内で複数のウィンドウを 管理できるようになりこれまで複数のウィンドウが同時に起動して 非常に、使いにくかったのが格段に改善されています。」

  • 30分ごとに更新

    現在前任者の作った ACCESS VBAのシステムのメンテナンスを任されています。 このシステムではフォームのボタンが押されるたびに (1)適当な値をTimerIntervalにセット。 (2)処理フラグ変数に値をセット。 (3)タイマー処理時に処理フラグ変数の値によっていろいろな処理を行う。 というものなのですが、 今回新しい仕様として、30分ごとに自動で更新処理を行う事になりました。 そこで教えていただきたいのですが、30分ごとに更新させるにはどのようにすればよいでしょうか? (ボタンを押すたびにtimerintervalが変更されてしまうのでいい時間の計り方がわからないです。) 更新するための更新ボタンはフォーム上にあります。 またこのシステムのなのですが、windowsの制限付きユーザーで ログインした状態で使用しようとすると、 「読み取り専用です」 とでて使用できないのですが、VBAを使ったシステムは Windowsの制限付きユーザーでは使用できないのでしょうか? (管理者権限のあるユーザーでログインすると使用できます。) ACCESSのバージョンは2003を使用しています。 よろしくお願いします。

  • windows プロセス間の連携で問題

    ウィンドウズで、dllと共有セクションを利用して複数のプロセスが協調して動作するシステムを開発しています。 あるプロセスが処理をしている間に他のプロセスが同じ処理をしたら困るので、フラグを処理中を意味する値にセットし処理が終わればフラグを戻し、という風にしているのですが、フラグをセットしている途中に他のプロセスに切り替わり、そこで他のプロセスが同じ処理をしてしまったら(確立はかなり低い)思った通りに動作しません。この問題に対して何か解決策はありますか?それともそこまで精密さを求めなくてもいいでしょうか?回答よろしくお願いします。

  • 子ウィンドウの操作について(VC++)

    Windows98 Visual C++6.0 雛型でMDIを作成して、アクティブな子ウィンドウに記述されている文字列を操作したいと思っています。 ダイアログボックスを表示して、その中のボタンを押したら、アクティブな子ウィンドウから文字列を取得しある処理した結果をダイアログボックスのtextに表示したいと考えています。 今のところダイアログボックスを表示する所まで出来ています。 問題点は 1.アクティブな子ウィンドウのハンドルはどのようすれば取得できるのでしょうか? 使用すべき関数名等を教えてください。 2.アクティブな子ウィンドウに記述されているデータを取得するには、GetWindowTextやsendMessageで出来るのでしょうか?(なるべくならSJISで処理をしたいと考えているのですが。) わかりずらい質問かも知れませんが宜しくお願いします。