- PR -

WndProcメソッドを利用してUserControl上のコントロールで発生するメッセージを処理するには

投稿者投稿内容
taa
常連さん
会議室デビュー日: 2005/08/29
投稿数: 44
投稿日時: 2006-05-23 16:52
VB.NETのUserControlクラスにて、
 Protected Overrides Sub WndProc(ByRef m As Message)
を記述して、メッセージを処理しようとしています。

UserControl上で発生するキーストロークについては上記の処理でメッセージを捕えることができますが、UserControl上に作成されたコントロールのメッセージは捕えることができません。

WndProcの処理がUserControl上で発生するメッセージのみを対象としているため、そうなるのは理解できるのですが、UserControl上に配置されているコントロール上で発生するメッセージを捕えるにはどうしたらよいのでしょうか?

内容としては、UserControlクラスにMSFlexGridコントロールとスクロールバーを配置したカスタムコントロールを作成したいと思っており、MSFlexGridコントロール(ActiveX)を左クリックした時に、左クリック時のメッセージを取得し、1クリックで選択範囲のタイプを変更したいと思っています。
また、直接MSFlexGridコントロールを継承したクラスからは、左クリック時のメッセージを捕らえる事ができる事は確認しています。

よろしくお願いいたします。

<環境>
VS2003
VB.NET
.NET Framework1.1
むら
会議室デビュー日: 2006/04/11
投稿数: 11
お住まい・勤務地: さっぽろ
投稿日時: 2006-05-23 17:42
こんにちは

WndProcで捕捉せずとも、UserControl内で独自にEventを作成して、
UserControlから欲しいイベントを
RaiseEventステートメントで通知するようにしたほうが楽なような気がします。

じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-05-23 18:22
引用:

taaさんの書き込み (2006-05-23 16:52) より:

WndProcの処理がUserControl上で発生するメッセージのみを対象としているため、そうなるのは理解できるのですが、UserControl上に配置されているコントロール上で発生するメッセージを捕えるにはどうしたらよいのでしょうか?


NativeWindow から継承したクラスによるサブクラス化とかになるでしょうか...
各ハンドルを紐付けて、NativeWindow の継承クラスにアサインする。

引用:

内容としては、UserControlクラスにMSFlexGridコントロールとスクロールバーを配置したカスタムコントロールを作成したいと思っており、MSFlexGridコントロール(ActiveX)を左クリックした時に、左クリック時のメッセージを取得し、1クリックで選択範囲のタイプを変更したいと思っています。


それだったら、子コントロールから親コントロール (UserControl コンテナ) へ通知するのが筋だと思います。

# 関係ないところですが、MSFlexGrid だといろいろつらいですよ。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
ya
大ベテラン
会議室デビュー日: 2002/05/03
投稿数: 212
投稿日時: 2006-05-23 18:54
出来なくもないんですが、もう一度設計を見直したほうがよいです。

どうしても、といわれるなら、前書いたやつのコピペ。
C#ですが、コンバートなりして参考にどうぞ。


コード:

class SampleControl : System.Windows.Forms.UserControl {
	public SampleControl() { ... }

	private class MessageFilter : IMessageFilter {
		private SampleControl owner;

		private MessageFilter() { throw new InvalidOperationException(); }
		public MessageFilter(SampleControl owner) {
			this.owner = owner;
		}

		[DllImport("user32.dll")]
		private static extern bool IsChild(IntPtr hParentWnd, IntPtr hWnd);

		bool IMessageFilter.PreFilterMessage(ref Message msg) {
			return
				!owner.IsDisposed                  &&
				 owner.Visible                     &&
				 owner.Enabled                     &&
				 IsChild(owner.Handle, msg.HWnd)   &&
				 owner.PreProcessChildControlMessage(ref msg);
		}
	}

	private MessageFilter messageFilter = null;
	private void AttachMessageFilter() {
		if(messageFilter == null) {
			messageFilter = new MessageFilter(this);
		}
		Application.AddMessageFilter(messageFilter);
	}
	private void DetachMessageFilter() {
		Application.RemoveMessageFilter(messageFilter);
	}

	protected override void OnHandleCreated(EventArgs e) {
		AttachMessageFilter();
		base.OnHandleCreated(e);
	}
	protected override void OnHandleDestroyed(EventArgs e) {
		DetachMessageFilter();
		base.OnHandleDestroyed(e);
	}

	protected virtual bool PreProcessChildControlMessage(ref Message msg) {
		return false;
	}
}

taa
常連さん
会議室デビュー日: 2005/08/29
投稿数: 44
投稿日時: 2006-05-23 19:19
むらさん、じゃんぬねっとさん、回答ありがとうございます。

引用:

WndProcで捕捉せずとも、UserControl内で独自にEventを作成して、
UserControlから欲しいイベントを
RaiseEventステートメントで通知するようにしたほうが楽なような気がします。


本当はUserControl内で独自にEventを作成しようと思うのですが、
MSFlexGridにてクリック時のデフォルト動作を抑止するのにWndProcメソッドを
使用していました。

引用:

NativeWindow から継承したクラスによるサブクラス化とかになるでしょうか...
各ハンドルを紐付けて、NativeWindow の継承クラスにアサインする。


そういった方法しかないですかねぇ。
いっそこと、MSFlexGridに似たオリジナルコンポーネントを作成したい気分です。
でも、作り方がいまいちわからない・・・。
オリジナルコンポーネント作成する為のいい書籍があればいいんだけど・・・。



じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-05-23 19:35
引用:

taaさんの書き込み (2006-05-23 19:19) より:

そういった方法しかないですかねぇ。
いっそこと、MSFlexGridに似たオリジナルコンポーネントを作成したい気分です。


ところで、何故 MSFlexGrid コントロールを選択されたのですか?

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
taa
常連さん
会議室デビュー日: 2005/08/29
投稿数: 44
投稿日時: 2006-05-23 20:00
yaさん、回答ありがとうございます。
C#はよくわからないので、サンプルコードを解析して試してみます。
どうも、ありがとうございました。

引用:

yaさんの書き込み (2006-05-23 18:54) より:
出来なくもないんですが、もう一度設計を見直したほうがよいです。

どうしても、といわれるなら、前書いたやつのコピペ。
C#ですが、コンバートなりして参考にどうぞ。

taa
常連さん
会議室デビュー日: 2005/08/29
投稿数: 44
投稿日時: 2006-05-23 20:13
じゃんぬねっとさん、回答ありがとうございます。

引用:

じゃんぬねっとさんの書き込み (2006-05-23 19:35) より:

引用:

taaさんの書き込み (2006-05-23 19:19) より:

そういった方法しかないですかねぇ。
いっそこと、MSFlexGridに似たオリジナルコンポーネントを作成したい気分です。


ところで、何故 MSFlexGrid コントロールを選択されたのですか?



MSFlexGrid コントロールを選択した理由は以下の通りです。
今後のため、じゃんぬねっとさんが他に良い方法があれば
教えていただきたいと思っています。
本当はオリジナルコントロールを作りたかった・・・。

<要件>
億単位のデータを表示・加工するアプリケーションを作成したい。
操作性はExcelを基準。

<条件>
・GrapCity社などのサードパーティのコンポーネントは不可で、
一般的な、コントロールを使用する。

・VS2003の時代に開発がスタートし、.NET開発を基本とする。

<理由>
・オリジナルのGridコントロールを開発しようと思ったが、
参考になる書籍やサイトが少ない(英語だったりする)のと、開発期間が短かった為。

・.NETコンポーネントのDataGridだとExcelを基本とした操作性を実現するのができないor困難であり、MSFlexGridであればDataGridよりも開発しやすいと考えた為。
.NET開発にActiveXを含めるのがかなり抵抗ありましたが・・・。

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