C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[9]: DateTimePickerでホイールを使う方法


(過去ログ 163 を表示中)

[トピック内 13 記事 (1 - 13 表示)]  << 0 >>

■94254 / inTopicNo.1)  DateTimePickerでホイールを使う方法
  
□投稿者/ paison (1回)-(2020/03/27(Fri) 15:33:59)

分類:[.NET 全般] 

VB2015を使用しています。


DateTimePickerでホイールを使いたいのですが
どこかのサイトに書かれてあったように

    Private Sub DateTimePicker1_MouseWheel(sender As Object, e As MouseEventArgs)

        If CType(sender, DateTimePicker).Focused Then

            If e.Delta > 0 Then

                System.Windows.Forms.SendKeys.Send("{UP}")

            Else

                System.Windows.Forms.SendKeys.Send("{DOWN}")

            End If

        End If

    End Sub

を使うと実現することができます。


しかし、ビルドして実行する場合には良いのですが、
デバッグモードで
DateTimePicker2_ValueChanged

の中のコードにブレイクポイントを付けた状態で起動すると
ホイールを回した時に、プログラムとマウスカーソルがフリーズしてしまいます。
マウスカーソルが動かせないので、PCの電源を切って強制終了するしか方法がなくなります。

一体、どうすればこのような現象が出なくなりますでしょうか?


引用返信 編集キー/
■94255 / inTopicNo.2)  Re[1]: DateTimePickerでホイールを使う方法
□投稿者/ 魔界の仮面弁士 (2647回)-(2020/03/27(Fri) 17:17:55)
No94254 (paison さん) に返信
> Private Sub DateTimePicker1_MouseWheel(sender As Object, e As MouseEventArgs)

通常であれば、イベントハンドラは
 Private Sub DateTimePicker1_MouseWheel(sender As Object, e As MouseEventArgs) Handles DateTimePicker1.MouseWheel
あるいは
 Private Sub DateTimePicker1_MouseWheel(sender As Object, e As MouseEventArgs) Handles DateTimePicker1.MouseWheel, DateTimePicker2.MouseWheel
などの形式になっているはずです。
AddHandler による動的割り当てを行っているのでしょうか?


> の中のコードにブレイクポイントを付けた状態で起動すると
> ホイールを回した時に、プログラムとマウスカーソルがフリーズしてしまいます。
コードウィンドウで [F5] を押せば再開できるはずですが、
フリーズする状況は再現できませんでした。


> 一体、どうすればこのような現象が出なくなりますでしょうか?
提示頂いた情報だけでは、再現テストを行えません。
新規プロジェクトを作成し、現象を再現可能な最小限のコードを作って提示することはできますか?



一応、SendKeys を使わないバージョンも置いておきます。
 
Public Class DateTimePickerWithWheel
  Inherits DateTimePicker
  Protected Overrides Sub OnMouseWheel(e As System.Windows.Forms.MouseEventArgs)
    MyBase.OnMouseWheel(e)
    Dim msgU As Message
    Dim msgD As Message
    If e.Delta > 0 Then
      msgU = Message.Create(Handle, &H100, New IntPtr(Keys.Up), New IntPtr(&H1480001))
      msgD = Message.Create(Handle, &H101, New IntPtr(Keys.Up), New IntPtr(&HC1480001))
    Else
      msgU = Message.Create(Handle, &H100, New IntPtr(Keys.Down), New IntPtr(&H1500001))
      msgD = Message.Create(Handle, &H101, New IntPtr(Keys.Down), New IntPtr(&HC1500001))
    End If
    MyBase.WndProc(msgU)
    MyBase.WndProc(msgD)
  End Sub
End Class


既存のコントロールを継承コントロールに置き換えできない事情がある場合は、
NativeWindow クラスで WndProc を捕らえて、WM_MOUSEWHEEL(&H020A) が飛んできた時に
同じように WM_KEYUP(&H100) と WM_KEYDOWN(&H101) を投げつけることでも実装できそう。
引用返信 編集キー/
■94257 / inTopicNo.3)  Re[2]: DateTimePickerでホイールを使う方法
□投稿者/ paison (2回)-(2020/03/27(Fri) 21:04:03)
ありがとうございます。
>NativeWindow クラスで WndProc を捕らえて、WM_MOUSEWHEEL(&H020A) が飛んできた時に

こちらの方法を試したいのですが、
ホイールの回転方向を取得するにはどのようにしたら良いですか?
検索してみたのですが
どのコードを使えば良いか分かりませんでしたのでお教え願います。

引用返信 編集キー/
■94258 / inTopicNo.4)  Re[3]: DateTimePickerでホイールを使う方法
□投稿者/ paison (4回)-(2020/03/27(Fri) 21:35:02)
https://social.msdn.microsoft.com/Forums/expression/de-DE/418e5a77-3cbe-47c1-9ace-fcdf4160387e/125101245412473124731246312525125401252312398wparam12364os2987222?forum=netfxgeneralja

ここに方法が書かれてありました。

しかし、OS環境やビット数によって
返り値が異なるようです。
どのような環境でも動作するようにしたいのですが
どのようにすれば良いですか?

引用返信 編集キー/
■94259 / inTopicNo.5)  Re[3]: DateTimePickerでホイールを使う方法
□投稿者/ 魔界の仮面弁士 (2648回)-(2020/03/27(Fri) 21:55:49)
No94257 (paison さん) に返信
>>NativeWindow クラスで WndProc を捕らえて、WM_MOUSEWHEEL(&H020A) が飛んできた時に
> ホイールの回転方向を取得するにはどのようにしたら良いですか?

WPARAM の上位ワードが Delta 値らしいです。
https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-mousewheel


ということは、こんな感じかな。

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
  If m.Msg = WM_MOUSEWHEEL Then
    '上位ワードY: y座標
    '下位ワードX: x座標
    Dim lp As New Point(m.LParam.ToInt32())
    '上位ワードY: ホイール回数数 Delta
    '下位ワードX: 仮想キーのビットフラグ
    Dim wp As New Point(m.WParam.ToInt32())
    Dim e As MouseEventArgs = New HandledMouseEventArgs(MouseButtons.None, 0, lp.X, lp.Y, wp.Y)

    If e.Delta > 0 Then

    Else

    End If

  End If
  MyBase.WndProc(m)
End Sub
引用返信 編集キー/
■94260 / inTopicNo.6)  Re[4]: DateTimePickerでホイールを使う方法
□投稿者/ paison (5回)-(2020/03/27(Fri) 22:16:36)
ありがとうございます。
試してみたのですが
Dim wp As New Point(m.WParam.ToInt32())

のところで、Int32では表せない64ビット数が来ることがあり、
そのときにエラーになります。
ToInt64にするとNew Pointが使えなくなります
どうすれば良いですか?

引用返信 編集キー/
■94261 / inTopicNo.7)  Re[5]: DateTimePickerでホイールを使う方法
□投稿者/ paison (7回)-(2020/03/27(Fri) 22:51:25)
Microsoftのページを見ると
GET_WHEEL_DELTA_WPARAM

で変換しろ、と書かれてありますが
GET_WHEEL_DELTA_WPARAMはどうやって宣言すれば良いか書かれてありません
リンクを巡ってもAPIの宣言コードが書かれていないのですが
どのようにすれば良いですか?

引用返信 編集キー/
■94262 / inTopicNo.8)  Re[5]: DateTimePickerでホイールを使う方法
□投稿者/ KOZ (103回)-(2020/03/27(Fri) 22:58:26)
No94260 (paison さん) に返信
> Dim wp As New Point(m.WParam.ToInt32())
> のところで、Int32では表せない64ビット数が来ることがあり、
> そのときにエラーになります。

これでどうぞ
http://kozhouse.homeip.net/JUNK/%A1%DAVB%A1%DBLParam%20%A4%AB%A4%E9%B0%CC%C3%D6%A4%F2%B7%D7%BB%BB/
引用返信 編集キー/
■94263 / inTopicNo.9)  Re[6]: DateTimePickerでホイールを使う方法
□投稿者/ paison (8回)-(2020/03/27(Fri) 23:09:12)
ありがとうございます。
うまくいきました。
フリーズする件に関してはもう少し調べてみます。

引用返信 編集キー/
■94264 / inTopicNo.10)  Re[6]: DateTimePickerでホイールを使う方法
□投稿者/ KOZ (104回)-(2020/03/27(Fri) 23:19:37)
No94261 (paison さん) に返信
> GET_WHEEL_DELTA_WPARAMはどうやって宣言すれば良いか書かれてありません

「GET_WHEEL_DELTA_WPARAM macro」
https://docs.microsoft.com/ja-jp/windows/win32/api/winuser/nf-winuser-get_wheel_delta_wparam

下のほうに Requirements というのがあって、Header に winuser.h (include Windows.h) とありますね。

「winuser.h github」でググってみると
https://github.com/tpn/winsdk-10/blob/master/Include/10.0.10240.0/um/WinUser.h

がヒットします。

GET_WHEEL_DELTA_WPARAM を検索すると

#define GET_WHEEL_DELTA_WPARAM(wParam) ((short)HIWORD(wParam))

なので

Dim delta As Integer = SignedHIWORD(m.WParam)

引用返信 編集キー/
■94268 / inTopicNo.11)  Re[7]: DateTimePickerでホイールを使う方法
□投稿者/ paison (9回)-(2020/03/28(Sat) 10:31:38)
ありがとうございます。

そこを見れば良かったんですね。

ただ、気になるのは
https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-mousewheel

このページには
Do not use the LOWORD or HIWORD macros to extract the x- and y- coordinates

と書かれてあります。
GET_WHEEL_DELTA_WPARAM
を辿ると
結局は、HIWORDを使うことになるのですが、
これはどう解釈すれば良いですか・

SignedHIWORDをご提示くださったのは
どういう流れで見つけられたのでしょうか?



引用返信 編集キー/
■94269 / inTopicNo.12)  Re[8]: DateTimePickerでホイールを使う方法
□投稿者/ 魔界の仮面弁士 (2649回)-(2020/03/28(Sat) 12:12:40)
2020/03/28(Sat) 14:29:47 編集(投稿者)

No94268 (paison さん) に返信
> Do not use the LOWORD or HIWORD macros to extract the x- and y- coordinates
> と書かれてあります。

垂直ホイールの WM_MOUSEWHEEL だけでなく
水平ホイールの WM_MOUSEHWHEEL でも同じようで。
https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-mousehwheel


> GET_WHEEL_DELTA_WPARAM
> を辿ると
> 結局は、HIWORDを使うことになるのですが、
> これはどう解釈すれば良いですか・

要するに、「Delta 値や X / Y 座標は符号付きの値として取得してくださいね」という意味です。
『LOWORD and HIWORD treat the coordinates as unsigned quantities.』と書かれていますよね。


GET_WHEEL_DELTA_WPARAM にて得られる値は SHORT 型。
HIWORD / LOWORD / GET_KEYSTATE_WPARAM で得られるのは WORD 型。

WORD 型は、System.UInt16 相当なので負数を扱えませんが、
SHORT 型は、System.Int16 相当なので負数を扱えます。


WPRAM 型は、Win16 が 16bit長、Win32 では 32bit長、Win64 では 64bit長で、
LPARAM 型は、Win16/Win32 では 32bit長、Win64 では 64bit長という違いがありますが、
.NET には 16bit 版が無いので、LPARAM/WPARAM 共に System.IntPtr とすることが多いですね。



> SignedHIWORDをご提示くださったのは
> どういう流れで見つけられたのでしょうか?
例えば、System.Windows.Forms.Control の
private void WmMouseWheel(ref Message m) のソースコードとか。

https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Control.cs,13546




引用返信 編集キー/
■94272 / inTopicNo.13)  Re[9]: DateTimePickerでホイールを使う方法
□投稿者/ KOZ (105回)-(2020/03/28(Sat) 13:37:13)
No94269 (魔界の仮面弁士 さん) に返信
> 要するに、「Delta 値や X / Y 座標は符号付きの値として取得してくださいね」という意味です。
> 『LOWORD and HIWORD treat the coordinates as unsigned quantities.』と書かれていますよね。

他に適したマクロがあるからそっちを使ってね(はぁと)ということでしょう。

GET_X_LPARAM
https://docs.microsoft.com/en-us/windows/win32/api/windowsx/nf-windowsx-get_x_lparam

GET_Y_LPARAM
https://docs.microsoft.com/ja-jp/windows/win32/api/windowsx/nf-windowsx-get_y_lparam

>>SignedHIWORDをご提示くださったのは
>>どういう流れで見つけられたのでしょうか?
> 例えば、System.Windows.Forms.Control の
> private void WmMouseWheel(ref Message m) のソースコードとか。

はい、そのとおり。(^_^;)
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -