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

GroupBox上のコントロールとWndProc

環境/言語:[WindowsXP,VB.NET]
分類:[.NET]

先日「DateTimePickerのカレンダークリック」でお世話になりました。
WndProc関数を使用することにより解決、と思ったのですが修正を進めていくうちに分からない点が発生してしまいました。

フォーム上に直接配置したDateTimePickerのカレンダークリックのイベントは
WndProc関数で捕捉することができたのですが、GroupBox上のDateTimePicker
では捕捉できませんでした。
調べてみるとControl毎にWndProc関数があるということが分かりましたので
DateTimePicker自身からイベントらしきものを発生できないものかと思い
DateTimePickerの継承コントロールを作成し、その中に以前教えていただいた
WndProc関数をOverrideしてみたところ、
「ウィンドウのハンドルを作成中にエラーが発生しました。」
とエラーが発生してしまいました。

分からないなりにやってみたことなので、とても見当違いなことをしているかも
しれませんが、もし何か解決方法がありましたらご教授いただけないでしょうか?

よろしくお願いします。
(以下は継承した(つもり)のコードです)

-----------------------------------------------
Public Class MyDateTimePicker
Inherits DateTimePicker

Private Structure NMHDR
Public hwndFrom As IntPtr
Public idFrom As Integer
Public code As Integer
End Structure

Private Structure NMDATETIMECHANGE
Public nmhdr As NMHDR
Public dwFlags As Integer
Public st As SYSTEMTIME
End Structure

Private Structure SYSTEMTIME
Public wYear As Short
Public wMonth As Short
Public wDayOfWeek As Short
Public wDay As Short
Public wHour As Short
Public wMinute As Short
Public wSecond As Short
Public wMilliseconds As Short
End Structure

Private Const WM_NOTIFY As Integer = &H4E
Private Const DTN_FIRST As Integer = (0 - 760)
Private Const DTN_DATETIMECHANGE As Integer = (DTN_FIRST + 1)

Protected Overrides Sub WndProc(ByRef m As Message)

Dim nmh As NMHDR = CType(m.GetLParam(nmh.GetType()), NMHDR)

If nmh.code = DTN_DATETIMECHANGE Then
Dim nmdate As NMDATETIMECHANGE = CType(m.GetLParam(nmdate.GetType()), NMDATETIMECHANGE)

Call MessageBox.Show("Click!")
End If

MyBase.WndProc(m)
End Sub
End Class
2005/07/08(Fri) 11:21:55 編集(投稿者)

■No11638に返信(ゆきねこさんの記事)

デバッグしました?
m.GetLParam で落ちてますよ?
WM_NOTIFY メッセージってなんですか?説明できますか?
勝手に If 条件を省略したらダメでしょう?
> ■No11485
改造する(特にコードを削除する)ならちゃんとコードの
意味を調べてからにしましょう。必要だからそのコードが
書いてあるんです。
るしぇ様

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

> デバッグしました?
> m.GetLParam で落ちてますよ?

Try-Catchを入れていなかったのは確かに私の落ち度でした。
大変初歩的なミスで申し訳ありませんでした。

> WM_NOTIFY メッセージってなんですか?説明できますか?
> 勝手に If 条件を省略したらダメでしょう?

説明できません、まだまだ努力が足りないということですね。
自分なりにがんばってコードも書いてみました、
すべてをこちらの掲示板に丸投げしているつもりは全くありません。
APIの部分が本当に分からなくてこちらに質問させて頂きましたが
もしそのように取られているのでしたら、この場を借りてお詫び申し上げます。
また、まだ質問できるレベルにありませんのでこれ以上の質問は控えます。
2005/07/12(Tue) 11:16:24 編集(投稿者)

なんか明後日の方向で反省してるね(^^;)
>説明できません、まだまだ努力が足りないということですね。
WEBの時代に努力なんて要らないでしょうに(^^;)ぐーぐるで
キーワード検索して引っ掛かったページ読むだけでは?ボクなら
調べて無くても、レスする時点で調べて『調べてましたが十分に
理解できてませんでした』って言っちゃうよw。30分で調べられる
内容ですから。そもそもプログラムは人間では面倒な事をコンピュ
ータにやらせようという考えですから、一番面倒な努力をしない為の
物です。
>自分なりにがんばってコードも書いてみました、
あれ?自分では書いてないでしょう???深山さんのコードを
コピペしてエラーの波線出た部分を削除しただけでは?…よく
勘違いする人がいますが、【program】予定。計画。です。
内容を理解し、自分の望む結果の為の計画を書くのがプログラムです。
内容の理解できてないコードをコピペするのをプログラムを
書くとは言いません。
>APIの部分が本当に分からなくてこちらに質問させて頂きましたが
あれれ??最初はそうだったかもしれませんが、前のスレッドで
API必要ありませんってコメントもらえたのでは?もはや関係ない
事です。

もう一度、自分の行動を見直してみて下さい。
例えば自動車の内部構造ってご存知ですか?詳しくは知らないとします。
では"内容の理解できてない"自動車のメンテナンスをゆきねこさんに
お願いします。…どうしますか?よく分からないけど調子の悪い(エラー
の出る)エンジンを削除しますか?当然動かなくなります。『なんで
動かないんですか?』って質問しますか?ヘンですよね???
怒ってませんよ?ヘンだって言ってるだけです。

関係ない所で内容の薄い反省をするくらいなら、なぜ
> If m.Msg = WM_NOTIFY AndAlso m.WParam.Equals(Me.DateTimePicker1.Handle) Then
の If 文を勝手に消去したのか?理由を教えて下さい。
本当に失礼なのは、ゆきねこさんが反省した部分ではなく、せっかく
提供してもらった動くコードの一部を、よく調べもせず、
『必要無いもの』と判断して削除した行動ですから。

あと、書き込みを終了するのであれば、スレッド閉じて下さい。
言いたいことは既にるしぇさんが仰ってくださってますし、このスレッドは放棄されてるような気もしますけど、関わった身としては半端なまま終わってしまうのも悲しいので少し。


> フォーム上に直接配置したDateTimePickerのカレンダークリックのイベントは
> WndProc関数で捕捉することができたのですが、GroupBox上のDateTimePicker
> では捕捉できませんでした。

 通知メッセージは親ウィンドウに送られるものです。 GroupBox 上に配置するということは親ウィンドウが GroupBox になるということですから、当然 Form の WndProc では拾えなくなります。

 ということで。
 ベタにやるなら GroupBox を継承したクラスを作成して WndProc をオーバーライド(案1)、でしょうか。けれども、スマートではありませんよね。
 NativeWindow を継承したクラスを作成して WndProc をオーバーライド。このインスタンスを GroupBox.Handle に AssignHandle する(案2)ようにすれば、使い回しも利きますしスッキリするかと思います。
# GC の対象にならないように気を付けてください。

 カスタムコントロール化するなら、 OnParentChanged などで案2の内容を行う(案3)ことになるでしょうか。
#必要に応じて ReleaseHandle もする必要があるでしょう。


 ここまでは普通に通知メッセージを扱う方法(?)ですが、別のアプローチもあります。
 .NET Freamwork で提供されているコントロール群は通知メッセージが自身に対して折り返されるようになっている※ようです。ですので、継承クラス内で WM_REFLECT + WM_NOTIFY を補足する(案4)ことでも実現できます。
※但し、これは文献等で確認した情報ではないので正確性を欠くかも知れません。

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