简体   繁体   English

为文本框使用单独的滚动条

[英]Use a separate scroll bar for a textbox

I am developing a touch screen application that has to display a possibly large amount of text. 我正在开发一种必须显示可能大量文本的触摸屏应用程序。 The problem I am having is that the default scroll bar attached to text boxes is just too small to be practically used in a touch screen application. 我遇到的问题是,附加到文本框的默认滚动条太小,无法在触摸屏应用程序中实际使用。 I have tried adding a separate scroll bar control and using it to control the scrolling of the text box. 我尝试添加一个单独的滚动条控件,并使用它来控制文本框的滚动。 So far I have only come up with two ways of doing this. 到目前为止,我只想出两种方法。

The first way I came up with was to use the ScrollToCaret() subroutine. 我想到的第一种方法是使用ScrollToCaret()子例程。 However I do not like this approach because it feels as if there should be a better way to tie in a scroll bar to a text box without changing the text selection 但是,我不喜欢这种方法,因为感觉好像应该有一个更好的方法将滚动条绑定到文本框,而不更改文本选择

Here is an example: 这是一个例子:

Dim oSelectionStart As Integer = CInt((TextBox1.Text.Length \ (VScrollBar1.Maximum - VScrollBar1.LargeChange - 1)) * VScrollBar1.Value)
If oSelectionStart >= TextBox1.Text.Length - 10 Then
    oSelectionStart = TextBox1.Text.Length
End If
If oSelectionStart <= 10 Or VScrollBar1.Value < 2 Then
    oSelectionStart = 0
End If
If Not TextBox1.SelectionStart = oSelectionStart Then
    TextBox1.SelectionStart = oSelectionStart
    TextBox1.ScrollToCaret()
End If

The second method I came up with uses windows API calls to set the scroll bars position and to get its current position. 我想出的第二种方法使用Windows API调用来设置滚动条位置并获取其当前位置。 There are however some flaws to this approach as well. 但是,这种方法也存在一些缺陷。 I am unable to get the large change value from the textboxes scrolling info. 我无法从文本框滚动信息中获得较大的更改值。 Most of the time this doesn't matter but when the default scroll bar on the textbox gets bigger it means that my scroll bar does not scale properly with it, giving my scroll bar the effect of scrolling to the bottom of the text while only being half way down the bar. 在大多数情况下,这无关紧要,但是当文本框上的默认滚动条变大时,这意味着我的滚动条无法正确缩放,从而使滚动条具有滚动到文本底部的效果,而只是在酒吧的中间。 Another problem with this approach that I found is that the default scroll bar for the textbox must be visible in order for me to be able to retrieve and set the current scrolling info. 我发现的这种方法的另一个问题是,文本框的默认滚动条必须可见,以便我能够检索和设置当前的滚动信息。 The last problem I have is one that plagues both methods I have discovered. 我遇到的最后一个问题困扰着我发现的两种方法。 I am unable to find an appropriate event to fire for when the user scrolls the text with anything other than my scroll bar, this means that I cannot update the position of my scroll bar even though the text has changed its scrolled position. 当用户使用滚动条以外的任何内容滚动文本时,我找不到合适的事件触发,这意味着即使文本已更改其滚动位置,我也无法更新滚动条的位置。

Heres the example code: 这里是示例代码:

Private Sub VScrollBar1_Scroll(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ScrollEventArgs)
    Dim minPos As Integer = 0
    Dim maxPos As Integer = 0
    Dim newPos As Integer = 0
    GetScrollRange(TextBox1.Handle, SBS_VERT, minPos, maxPos)
    Dim vScrollPerc As Double = ((100 / (VScrollBar1.Maximum - (VScrollBar1.LargeChange - 1))) * VScrollBar1.Value) * 0.01
    newPos = CInt(((maxPos - minPos) * vScrollPerc) + minPos)
    SetScrollPos(TextBox1.Handle, SBS_VERT, newPos, True)
    PostMessageA(TextBox1.Handle, WM_VSCROLL, SB_THUMBPOSITION + &H10000 * newPos, Nothing)
End Sub

'Scrollbar direction
Const SBS_HORZ = 0
Const SBS_VERT = 1
'Windows Messages
Const WM_VSCROLL = &H115
Const WM_HSCROLL = &H114
Const SB_THUMBPOSITION = 4
<Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Sequential)> Private Structure SCROLLINFO
    Public cbSize As Integer
    Public fMask As Integer
    Public nMin As Integer
    Public nMax As Integer
    Public nPage As Integer
    Public nPos As Integer
    Public nTrackPos As Integer
End Structure
Private Enum ScrollBarDirection
    SB_HORZ = 0
    SB_VERT = 1
    SB_CTL = 2
    SB_BOTH = 3
End Enum
Private Enum ScrollInfoMask
    SIF_RANGE = &H1
    SIF_PAGE = &H2
    SIF_POS = &H4
    SIF_DISABLENOSCROLL = &H8
    SIF_TRACKPOS = &H10
    SIF_ALL = (SIF_RANGE Or SIF_PAGE Or SIF_POS Or SIF_TRACKPOS)
End Enum
Private Declare Function GetScrollPos Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal nBar As Integer) As Integer
Private Declare Function SetScrollPos Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal nBar As Integer, ByVal nPos As Integer, ByVal bRedraw As Boolean) As Integer
Private Declare Function PostMessageA Lib "user32.dll" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Boolean
Private Declare Function GetScrollRange Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal nBar As Integer, ByRef lpMinPos As Integer, ByRef lpMaxPos As Integer) As Integer
Private Declare Function GetScrollInfo Lib "user32" (ByVal hWnd As IntPtr, ByVal fnBar As ScrollBarDirection, ByRef lpsi As SCROLLINFO) As Integer

I know there must be a better way out there to do this, but so far I have not been able to come up with anything that would be an appropriate solution to my problem. 我知道一定有更好的方法可以做到这一点,但是到目前为止,我还没有提出能够解决我的问题的任何方法。 Any help would be appreciated. 任何帮助,将不胜感激。

I think, there is way how to change size of scrollbar wint Win32API. 我认为,有一种方法可以更改Win32API滚动条的大小。 Look at: http://pinvoke.net/search.aspx?search=scrollbar&namespace=[All] http://pinvoke.net/default.aspx/user32/FindWindowEx.html http://pinvoke.net/default.aspx/user32/GetScrollBarInfo.html http://pinvoke.net/default.aspx/user32/ShowScrollBar.html 查看: http : //pinvoke.net/search.aspx? search= scrollbar & namespace= [全部] http://pinvoke.net/default.aspx/user32/FindWindowEx.html http://pinvoke.net/default.aspx /user32/GetScrollBarInfo.html http://pinvoke.net/default.aspx/user32/ShowScrollBar.html

You should be able change size of scroll bar with Win32API and scrollbar's handle. 您应该能够使用Win32API和滚动条的句柄更改滚动条的大小。

We have been using WPF in our most recent project. 我们在最近的项目中一直使用WPF。 Is WPF an option for you? WPF是您的选择吗? If yes, it appears as if everything UI can be altered in WPF apps. 如果是,则似乎可以在WPF应用程序中更改所有UI。 We use 2 UI artists. 我们使用2位UI艺术家。 One works in in Adope Photoshop, then converts the output to XAML. 一个可以在Adope Photoshop中工作,然后将输出转换为XAML。 The second works in Expression Blend, which natively produces XAML. 第二个在Expression Blend中起作用,后者本身会生成XAML。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM