views:

1742

answers:

2

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. 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. 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.

+1  A: 

I think, there is way how to change size of scrollbar wint Win32API. Look at: http://pinvoke.net/search.aspx?search=scrollbar&amp;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

You should be able change size of scroll bar with Win32API and scrollbar's handle.

TcKs
A: 

We have been using WPF in our most recent project. Is WPF an option for you? If yes, it appears as if everything UI can be altered in WPF apps. We use 2 UI artists. One works in in Adope Photoshop, then converts the output to XAML. The second works in Expression Blend, which natively produces XAML.

GregUzelac