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

わんくま同盟

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

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

■96254 / 6階層)  トラックバーの一部に色を付ける方法
□投稿者/ KOZ (148回)-(2020/11/06(Fri) 11:47:50)
No96251 (KOZ) に返信
> TrackBar で動作するか未確認ですが、
> 「WM_PAINTでTextBoxがちらつく」
> https://social.msdn.microsoft.com/Forums/ja-JP/d5ac1426-1082-43a1-a02f-677dad1ee3ca/wmpaint12391textbox1236412385124251238812367?forum=csharpgeneralja
> のように、ビットマップから hdc を作成し、WM_PAINT の WPARAM にセットしてやるとコントロールが描画をしてくれるので、それを加工して表示する、といった方法が使えるかもしれません。

うまくいったかも。

Imports System.Runtime.InteropServices

Public Class TrackBarEx
    Inherits TrackBar

    Private Const WM_PAINT As Integer = &HF
    Private Const WM_ERASEBKGND As Integer = &H14

    Private Const WM_USER As Integer = &H400
    Private Const TBM_GETPOS As Integer = WM_USER               'スライダーの位置を取得
    Private Const TBM_GETRANGEMIN As Integer = WM_USER + 1      'スライダーの位置の最小位置の取得
    Private Const TBM_GETRANGEMAX As Integer = WM_USER + 2      'スライダーの位置の最大位置の取得
    Private Const TBM_GETTIC As Integer = WM_USER + 3           '特定のチックマークの位置を取得
    Private Const TBM_SETTIC As Integer = WM_USER + 4           '特定のチックマークの位置を設定
    Private Const TBM_SETPOS As Integer = WM_USER + 5           'スライダーの位置を設定
    Private Const TBM_SETRANGE As Integer = WM_USER + 6         'スライダー位置の可変範囲の設定
    Private Const TBM_SETRANGEMIN As Integer = WM_USER + 7      'スライダー位置の可変範囲の最小値の設定
    Private Const TBM_SETRANGEMAX As Integer = WM_USER + 8      'スライダー位置の可変範囲の最大値の設定
    Private Const TBM_CLEARTICS As Integer = WM_USER + 9        '現在のチックマークを削除
    Private Const TBM_SETSEL As Integer = WM_USER + 10          'チックマークの選択範囲の設定
    Private Const TBM_SETSELSTART As Integer = WM_USER + 11     'チックマークの選択範囲の終了値の設定
    Private Const TBM_SETSELEND As Integer = WM_USER + 12       'チックマークの選択範囲の開始値の設定
    Private Const TBM_GETPTICS As Integer = WM_USER + 14        'チックマーク位置を示す配列を指すポインタの取得
    Private Const TBM_GETTICPOS As Integer = WM_USER + 15       'チックマークの物理位置の取得
    Private Const TBM_GETNUMTICS As Integer = WM_USER + 16      'チックマークの数の取得
    Private Const TBM_GETSELSTART As Integer = WM_USER + 17     '選択範囲の開始位置の取得
    Private Const TBM_GETSELEND As Integer = WM_USER + 18       '選択範囲の終了位置の取得
    Private Const TBM_CLEARSEL As Integer = WM_USER + 19        '選択範囲の解除
    Private Const TBM_SETTICFREQ As Integer = WM_USER + 20      'チックマークの間隔の設定
    Private Const TBM_SETPAGESIZE As Integer = WM_USER + 21     'ページサイズの設定
    Private Const TBM_GETPAGESIZE As Integer = WM_USER + 22     'ページサイズの取得
    Private Const TBM_SETLINESIZE As Integer = WM_USER + 23     'ラインサイズの設定
    Private Const TBM_GETLINESIZE As Integer = WM_USER + 24     'ラインサイズの取得
    Private Const TBM_GETTHUMBRECT As Integer = WM_USER + 25    'つまみの境界矩形の取得
    Private Const TBM_GETCHANNELRECT As Integer = WM_USER + 26  'スライダーが動くチャンネルの境界矩形の取得
    Private Const TBM_SETTHUMBLENGTH As Integer = WM_USER + 27  'つまみの長さの設定
    Private Const TBM_GETTHUMBLENGTH As Integer = WM_USER + 28  'つまみの長さの取得

    Private Structure RECT
        Public Left, Top, Right, Bottom As Integer

        Public ReadOnly Property Width As Integer
            Get
                Return Right - Left
            End Get
        End Property

        Public ReadOnly Property Height As Integer
            Get
                Return Bottom - Top
            End Get
        End Property

        Public Shared Widening Operator CType(ByVal r As RECT) As Rectangle
            Return Rectangle.FromLTRB(r.Left, r.Top, r.Right, r.Bottom)
        End Operator

    End Structure

    <StructLayout(LayoutKind.Sequential)>
    Private Structure PAINTSTRUCT
        Public hdc As IntPtr
        Public fErase As Boolean
        Public rcPaint As RECT
        Public fRestore As Boolean
        Public fIncUpdate As Boolean
        Public reserved1 As Integer
        Public reserved2 As Integer
        Public reserved3 As Integer
        Public reserved4 As Integer
        Public reserved5 As Integer
        Public reserved6 As Integer
        Public reserved7 As Integer
        Public reserved8 As Integer
    End Structure

    <DllImport("user32.dll")>
    Private Shared Function BeginPaint(ByVal hWnd As HandleRef,
                                       ByRef lpPaint As PAINTSTRUCT) As IntPtr
    End Function

    <DllImport("user32.dll")>
    Private Shared Function EndPaint(ByVal hWnd As HandleRef,
                                     ByRef lpPaint As PAINTSTRUCT) As Boolean
    End Function

    <DllImport("user32.dll", CharSet:=CharSet.Auto)>
    Private Shared Function SendMessage(ByVal hWnd As HandleRef,
                                        ByVal Msg As Integer,
                                        ByVal wParam As IntPtr,
                                        ByRef rect As RECT) As IntPtr
    End Function

    Protected Overrides Sub WndProc(ByRef m As Message)
        Select Case m.Msg
            Case WM_PAINT
                Using bmp As New Bitmap(ClientSize.Width, ClientSize.Height)
                    Using bmpGraphics = Graphics.FromImage(bmp)
                        Dim bmphdc = bmpGraphics.GetHdc()
                        Dim msg = Message.Create(m.HWnd, WM_PAINT, bmphdc, IntPtr.Zero)
                        MyBase.WndProc(msg)
                        bmpGraphics.ReleaseHdc()
                        Using pe As New PaintEventArgs(bmpGraphics, ClientRectangle)
                            CustomDraw(pe)
                        End Using
                    End Using
                    If m.WParam = IntPtr.Zero Then
                        Dim hWnd As New HandleRef(Me, m.HWnd)
                        Dim ps As New PAINTSTRUCT()
                        Dim controlHdc = BeginPaint(hWnd, ps)
                        Using controlGraphics = Graphics.FromHdc(controlHdc)
                            controlGraphics.DrawImage(bmp, 0, 0)
                        End Using
                        EndPaint(hWnd, ps)
                    Else
                        Using controlGraphics = Graphics.FromHdc(m.WParam)
                            controlGraphics.DrawImage(bmp, 0, 0)
                        End Using
                    End If
                End Using
            Case WM_ERASEBKGND
                '無視
            Case Else
                MyBase.WndProc(m)
        End Select
    End Sub

    Protected Overridable Sub CustomDraw(e As PaintEventArgs)
        'チャネルおよびつまみの領域を取得
        Dim channel As New RECT()
        Dim thumb As New RECT()
        Dim hWnd As New HandleRef(Me, Me.Handle)
        SendMessage(hWnd, TBM_GETCHANNELRECT, IntPtr.Zero, channel)
        SendMessage(hWnd, TBM_GETTHUMBRECT, IntPtr.Zero, thumb)

        ' チャネルおよびつまみの領域を背景色で塗りつぶす
        Using b As New SolidBrush(BackColor)
            e.Graphics.FillRectangle(b, New Rectangle(channel.Left, thumb.Top, channel.Width, thumb.Height))
        End Using

        'チャネルを描く
        e.Graphics.FillRectangle(Brushes.Black, channel)
        If thumb.Left > channel.Left Then
            'つまみの左側を塗りつぶす
            Dim leftchannel As New Rectangle(channel.Left, channel.Top, thumb.Left - channel.Left, channel.Height)
            e.Graphics.FillRectangle(Brushes.Red, leftchannel)
        End If
        e.Graphics.DrawRectangle(Pens.White, channel)

        'つまみを描く
        e.Graphics.FillEllipse(Brushes.White, thumb)
        e.Graphics.DrawEllipse(Pens.Black, thumb)
    End Sub

    Protected Overrides Sub OnValueChanged(e As EventArgs)
        MyBase.OnValueChanged(e)
        MyBase.Invalidate()
    End Sub

End Class

編集キー/

前の記事(元になった記事) 次の記事(この記事の返信)
←Re[5]: トラックバーの一部に色を付ける方法 /KOZ →Re[7]: トラックバーの一部に色を付ける方法 /鮭
 
上記関連ツリー

トラックバーの一部に色を付ける方法 / 鮭 (20/11/03(Tue) 20:55) #96227
Re[1]: トラックバーの一部に色を付ける方法 / 鮭 (20/11/03(Tue) 21:15) #96228
  └ Re[2]: トラックバーの一部に色を付ける方法 / KOZ (20/11/05(Thu) 08:57) #96240
    └ Re[3]: トラックバーの一部に色を付ける方法 / KOZ (20/11/05(Thu) 14:49) #96244
      └ Re[4]: トラックバーの一部に色を付ける方法 / 鮭 (20/11/05(Thu) 21:42) #96250
        └ Re[5]: トラックバーの一部に色を付ける方法 / KOZ (20/11/06(Fri) 09:07) #96251
          └ トラックバーの一部に色を付ける方法 / KOZ (20/11/06(Fri) 11:47) #96254 ←Now
            └ Re[7]: トラックバーの一部に色を付ける方法 / 鮭 (20/11/06(Fri) 18:00) #96255
              └ Re[8]: トラックバーの一部に色を付ける方法 / 魔界の仮面弁士 (20/11/06(Fri) 18:12) #96256
                └ Re[9]: トラックバーの一部に色を付ける方法 / 鮭 (20/11/06(Fri) 22:47) #96257
                  └ Re[10]: トラックバーの一部に色を付ける方法 / 魔界の仮面弁士 (20/11/07(Sat) 01:08) #96258
                    └ Re[11]: トラックバーの一部に色を付ける方法 / 鮭 (20/11/07(Sat) 11:04) #96263
                      └ Re[12]: トラックバーの一部に色を付ける方法 / KOZ (20/11/09(Mon) 09:13) #96274
                        └ Re[13]: トラックバーの一部に色を付ける方法 / 鮭 (20/11/09(Mon) 20:45) #96287 解決済み

上記ツリーを一括表示 / 上記ツリーをトピック表示
 
上記の記事へ返信