2011-02-01 6 views
4

私はフォーム上で発生するイベントを聴くように設計された "ControlMonitor"クラスを持っています。どのように動作するかは、監視したいフォームをこのクラスのインスタンスに渡し、フォームのコントロールのすべてを反復処理し、関連するイベントを登録することです。たとえば、コントロールがTextBoxの場合、TextChangedに登録します。コントロールがComboBoxの場合、SelectedIndexChangedとTextChangedの両方に登録されます。このようにして、 "ControlMonitor"インスタンスは、ユーザーがフォームに入力したすべての重要なアクションについて、フォームコード自体への侵入を最小限に抑えながら報告することができます。私のアプリケーションでMessageBoxとDialogの結果を聞く

フォームのコントロールのレポートには効果的ですが、フォームによって起動された共通のダイアログボックス/メッセージボックスと、ユーザーがどのように応答したかも知る必要があります。ここでのより大きな目標は自動化です。私たちは、自動化ツールで再生されるものにスクリプトで記述できる一連の繰り返し可能なステップを作成したいと考えています。そのために、ユーザーが「ファイル/開く」をクリックしたことを知るだけでは不十分です。起動されたOpenFileDialogのウィンドウタイトル、ユーザーが選択したパス、DialogResultも知っておく必要があります。同じことがMessageBoxの呼び出しにも当てはまります。ウィンドウのタイトルとDialogResultを知る必要があります。

一般的なダイアログボックスではイベントのサポートが最小限に抑えられているようです(FolderBrowserDialogはイベントがまったく発生しません)。また、MessageBox呼び出しの結果をリスンするときにどこから開始するのかもわかりません。もちろん、一般的なダイアログとMessageBoxの呼び出しをカプセル化し、その結果を "ControlMonitor"インスタンスに渡すラッパークラスを書くこともできますが、プログラムの残りの部分はこのラッパークラスを常に使用する必要があり、プライマリ私の "ControlMonitor"クラスの目的は、それをプロジェクトに組み込み、元のコードへの侵入を最小限に抑えてフォームの1つを聴くことができることです。

"ControlMonitor"クラス内でできることはありますか? DialogResultsとすべてのダイアログボックス/メッセージボックスのウィンドウタイトルが必要です。また、OpenFileDialogなどのより複雑なダイアログでは、ユーザーが選択したパスなども知る必要があります。 "ControlMonitor"クラスは、プログラムのコンパイル済み部分です。 toに渡されるので、渡されたFormオブジェクトに直接アクセスできます。私はここに近づいている。私はアプリケーションの95%を監視することができます。なぜなら、そのほとんどはフォーム上のコントロールだけなので...ダイアログを監視する方法が必要です。

+0

hmmm ...この機能が必要なのは何ですか?フォームにユーザーのアクションのプロファイルを作成するのが好きなようです。 – MacX

+0

私が言ったように、主に自動化の目的のために。私たちは、自動化ツールで再生されるものにスクリプトで記述できる一連の繰り返し可能なステップを完成させたいと考えています。監査および診断の目的にも望ましい。 –

答えて

0

私は、MessageBox.Show()呼び出しのラッパー関数を作成してから、アプリケーション内のすべての呼び出しをこの関数に置き換えて同様の問題を解決しました。

に似て何か:

Public Function My_MessageBox(ByVal pstrMsg As String, _ 
    Optional ByVal pstrCaption As String = "", _ 
    Optional ByVal pButtons As Windows.Forms.MessageBoxButtons = MessageBoxButtons.OK, _ 
    Optional ByVal pIcon As Windows.Forms.MessageBoxIcon = MessageBoxIcon.None, _ 
    Optional ByVal pDefButton As Windows.Forms.MessageBoxDefaultButton = MessageBoxDefaultButton.Button1) _ 
    As Windows.Forms.DialogResult 

    Dim rval As Windows.Forms.DialogResult 

    If glAutomated Then 
     ' if automation is running, we don't want to show 
     ' the box to the user, just retrieve the result stored 
     rval = AutomateThisMessageBox("MsgBox" & pstrCaption.Replace(" ", "")) 
    Else 
     rval = MessageBox.Show(pstrMsg, pstrCaption, pButtons, pIcon, pDefButton) 

     If glRecording Then 'Only record the result when in "record" mode 
      Hooks.RecordMessageBox(pstrCaption.Replace(" ", ""), rval.ToString) 
     End If 
    End If 

    Return rval 

End Function 

使用法:Messagebox.Showとまったく同じが現在使用されている、ちょうど例えば新しい関数名 に置き換える:

MessageBox.Show("This is a test", "Test Msg", 
    MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk, 
    MessageBoxDefaultButton.Button1) 

My_MessageBox("This is a test", "Test Msg", 
    MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk, 
    MessageBoxDefaultButton.Button1) 
なり

編集:

すべての異なるダイアログについて質問の終わりをもう一度読んでください。私は、同様のテクニックを一般的な意味で使うことができると推測しています。

+0

私はフォームの自動化を行い、このルートを正確に実行しました。幸い、このようなラッピングが必要なものはほんの少数です。そのうちの1人は、新しいフォーム/ダイアログのインスタンスを起動しています。実行中にブロックしたり、閉じたときにコールバックしたりしないようにします。 – Tom

+0

唯一の問題は、既存のコードに最小限の影響を与えようとしていることと、ラッパークラスの恩恵を受けるために、アプリケーション全体を変更する必要があることです。これはあまり望ましくないような広範なコード変更を行う)。本当に必要な場合はラッパールートに進むことができますが、実際には、これが "ControlMonitor"クラス自体の中で、モニターに渡されるフォームインスタンスか、グローバルなリスニングメカニズム。 –

+0

私はあまりにも正確にあなたのものを構築していたので、コードに最小限の影響を与えたいと思っていましたが、これは私が当時考え出した最高のものでした。数年後に再訪したわけではありません。それを行うより良い方法があるかどうかを確認してください。私は実際にマウスとキーボードのフックを登録するルートと、どのコントロールが操作されたのかを記録する関数のセットを行った。 WindowsのメッセージWM_MSGBOXなどを聞いてダイアログを表示させる方法を考え出すことができますが、信頼できるものは得られませんでした。 –

1

私はそれにはかなり大きな変更が必要かもしれないことは知っていますが、代わりに疎結合されたイベントブローカーのデザインにはいかがですか?イベントに対処する方法の柔軟性が向上します。

The Composite UI Application Block Microsoftがリリースしたサンプルイベントブローカーがありますが、自分で作成することはあまりありません。アイデアの要点は、あなたのコントロールがイベントを公開する中央ブローカーがあることです。その後、他のクラスがこれらのイベントのいずれかにサブスクライブすることは可能です。これにより、イベントのパブリッシュ/サブスクライブが緩やかに結合され、異なるコントロール間の強い依存関係が取り除かれます。

関連する問題