2

TextBox がに設定されていても、Multiline-TextBox でのスクロールを許可しようとしています

textbox.Enabled = False

スクロールバーはEnabledコマンドでも無効になっているため、これは不可能です。

ここでのデフォルトの解決策は、設定することです

textbox.ReadOnly = True
textbox.Enabled = True

しかし、これは私にとってはうまくいきません。ReadOnlyを使用すると、TextBox のテキストを選択したり、その中にカーソルを配置したりできます。しかし、同じフォームに通常の ( Multiline -TextBoxes 以外の) コントロールと他のコントロールがあるので、それが発生することは望ましくありません。他のすべての無効な TextBox とまったく同じ動作をさせたいと考えています。

無効なテキストボックスの色を模倣するなど、他のすべてについては、ReadOnly -Property を使用した正当な回避策がありますが、テキストを選択してカーソルを配置する方法は見つかりませんでした。

アップデート:

ここからのいくつかのヒントで、私は WIN32 API を使用しようとしましたが、期待どおりに動作しませんでした:

Imports System.Windows.Forms
Imports System.Runtime.InteropServices

Public Class TestTextBox
    Inherits TextBox

    Private Class Native
        <DllImport("user32.dll")> _
        Friend Shared Function EnableScrollBar(ByVal hWnd As IntPtr, ByVal wSBflags As UInteger, ByVal wArrows As UInteger) As Boolean
        End Function
        <DllImport("User32.dll")> _
        Friend Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As UInteger, ByVal wparam As Integer, ByVal lparam As Integer) As Integer
        End Function

        Public Const WM_SETREDRAW As Long = &HB
        Public Const ESB_ENABLE_BOTH As UInteger = 0
        Public Const SB_VERT As UInteger = 1
    End Class

    Public Sub Change() 'Gets called by a Button in my example.
        'Native.SendMessage(Me.Handle, Native.WM_SETREDRAW, New IntPtr(0), IntPtr.Zero)
        Native.EnableScrollBar(Me.Handle, Native.SB_VERT, Native.ESB_ENABLE_BOTH)
        'Native.SendMessage(Me.Handle, Native.WM_SETREDRAW, New IntPtr(1), IntPtr.Zero)
        Me.PerformLayout()
    End Sub

End Class
4

1 に答える 1

2

これはうまくいくはずだと思います。HideCaret は、テキスト ボックスが読み取り専用の場合に、キャレットが確実に非表示になるようにします。他の WM インターセプトは、ユーザーがマウスやキーボードで何かを選択できないようにします。

Imports System.Runtime.InteropServices

Public Class CustomTextbox
    Inherits System.Windows.Forms.TextBox

    Private Const WM_KEYDOWN = &H100
    Private Const WM_SYSKEYDOWN = &H104
    Private Const WM_MOUSEMOVE = &H200

    <DllImport("user32.dll")> _
    Private Shared Function HideCaret(ByVal hwnd As IntPtr) As Integer
    End Function

    Protected Overrides Sub OnGotFocus(ByVal e As System.EventArgs)
        If Me.ReadOnly Then HideCaret(Me.Handle)
        MyBase.OnGotFocus(e)
    End Sub

    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        If Me.ReadOnly And (m.Msg = WM_MOUSEMOVE) Or _
                           (m.Msg = WM_KEYDOWN) Or _
                           (m.Msg = WM_SYSKEYDOWN) Then Exit Sub
        MyBase.WndProc(m)
    End Sub
End Class
于 2012-06-04T17:34:52.690 に答える