23.09.2025, 06:04 AM
(This post was last modified: 23.09.2025, 06:05 AM by Gary Beene.)
gbScroller is the companion app to gbClientCapture. Both are intended to support viewing of sheet music in a horizontal format.
gbClientCapture captures multiple images from a music sheet and merges them into a single horizontal image.
gbScroller displays the merged image, scrolling it to the left.
Both are discussed in the same thread. http://pump.richheimer.de/showthread.php...562#pid562
Features:
1. Zoom the merged image
2. Scroll the merged image, with speed control
3. Display a vertical line between individual images
![[Image: gbscroller.jpg]](https://garybeene.com/files/gbscroller.jpg)
Files for both gbClientCapture and gbScroller are in the zip https://garybeene.com/files/gbclientcapture.zip
gbClientCapture captures multiple images from a music sheet and merges them into a single horizontal image.
gbScroller displays the merged image, scrolling it to the left.
Both are discussed in the same thread. http://pump.richheimer.de/showthread.php...562#pid562
Features:
1. Zoom the merged image
2. Scroll the merged image, with speed control
3. Display a vertical line between individual images
![[Image: gbscroller.jpg]](https://garybeene.com/files/gbscroller.jpg)
Files for both gbClientCapture and gbScroller are in the zip https://garybeene.com/files/gbclientcapture.zip
Code:
'Compilable Example: Jose Includes
#Compile Exe "gbscroller.exe"
#Dim All
#Debug Error On
#Debug Display On
%Unicode = 1
#Include "WIN32API.INC"
#Include "cgdiplus.inc" '<-replace with Jose or you own GDI+ include file.
Enum Equates Singular
IDC_Toolbar = 500
IDC_Graphic
IDT_Exit
IDT_Faster
IDT_Slower
IDT_View
IDT_ShowLine
IDT_Scroll
IDC_StatusBar
IDT_ResetZoom
IDT_ResetScroll
IDC_Up
IDC_Down
IDT_StopScroll
IDT_Plus
IDT_Minus
ID_Timer
End Enum
#Resource Manifest, 1, "icons\xptheme_dpiaware.xml"
#Resource Icon logo, "icons\scroll2.ico"
#Resource Icon zexit, "icons\power.ico"
#Resource Icon zview, "icons\view.ico"
#Resource Icon zleft, "icons\scrollleft.ico"
#Resource Icon zright, "icons\scrollright.ico"
#Resource Icon zstop, "icons\stop.ico"
#Resource Icon zplus, "icons\plus.ico"
#Resource Icon zminus, "icons\minus.ico"
#Resource Icon zreset, "icons\reset.ico"
$Ver = "1.1"
Global hDlg, hToolbar, hList, hFont As Dword
Global Scroll, ShowLine, TimerInterval, ImageWidth, ImageHeight,XDelta As Long
Global SBW, SBH, TBW, TBH As Long, Zoom As Single
Function PBMain() As Long
Dialog New Pixels, 0, "gbScroller v" + $Ver,,,100,100, %WS_OverlappedWindow To hDlg
Dialog Set Icon hDlg, "logo"
Font New "Tahoma",10, 0 To hFont
CreateImageList
CreateToolbar
CreateStatusBar
Dialog Show Modal hDlg, Call DlgMain
End Function
CallBack Function DlgMain()
Local iReturn As Long
Select Case As Long Cb.Msg
Case %WM_InitDialog
BuildAcceleratorTable
settings_ini "get"
GetImageSize
CreateGraphic
Statusbar Set Text hDlg, %IDC_StatusBar, 1, 0, "gbScroller v" + $Ver + " Zoom = " + Str$(Zoom) + " Timer Interval = " + Str$(TimerInterval)
Case %WM_Size : ResizeDialog
Case %WM_Timer : ScrollImage : SetStatusBar
Case %WM_Help
Case %WM_Command
Select Case Cb.Ctl
Case %IdCancel : sBeep : Dialog End hDlg
Case %IDT_Exit : sBeep : Dialog End hDlg
Case %IDT_Scroll : sBeep : ManageScroll : CreateToolbar
Case %IDT_StopScroll : sBeep : ManageScroll : CreateToolbar
Case %IDT_Faster : sBeep : ChangeSpeed(-1) : CreateToolbar
Case %IDT_Slower : sBeep : ChangeSpeed(+1) : CreateToolbar
Case %IDT_Plus : sBeep : Magnify(+1)
Case %IDT_Minus : sBeep : Magnify(-1)
Case %IDT_ResetZoom : sBeep : Magnify(0)
Case %IDT_ResetScroll : sBeep : ResetScroll
Case %IDT_ShowLine : sBeep : ShowLine Xor=1 : DrawLines(IIf(ShowLine,%Red,-2)) : Graphic ReDraw
Case %IDT_View : sBeep : iReturn = ShellExecute(hDlg, "Open", "merge.bmp", $Nul, $Nul, %SW_ShowNormal)
End Select
Case %WM_Destroy
settings_ini "save"
End Select
End Function
Sub CreateStatusBar
Control Add Statusbar, hDlg, %IDC_StatusBar, "Welcome to gbScroller v" + $Ver, 0,0,0,0, %CCS_Bottom Or %SBars_SizeGrip
Control Get Size hDlg, %IDC_StatusBar To SBW, SBH
Control Set Font hDlg, %IDC_StatusBar, hFont
End Sub
Sub CreateGraphic
Local w,h As Long
Dialog Get Client hDlg To w,h
Control Add Graphic, hDlg, %IDC_Graphic, "", 10, TBH, w-20,h, %WS_Border
Graphic Attach hDlg, %IDC_Graphic, ReDraw
Graphic Set Virtual ImageWidth, ImageHeight
Graphic Color %Black, %White
Graphic Clear
End Sub
Sub CreateImageList
ImageList New Icon 48,48,32,20 To hList
ImageList Add Icon hList, "zexit" '1
ImageList Add Icon hList, "zleft" '2
ImageList Add Icon hList, "zright" '3
ImageList Add Icon hList, "zstop" '4
ImageList Add Icon hList, "zplus" '5
ImageList Add Icon hList, "zminus" '6
ImageList Add Icon hList, "zreset" '7
ImageList Add Icon hList, "zview" '8
End Sub
Sub CreateToolbar
Control Kill hDlg, %IDC_Toolbar
Control Add Toolbar, hDlg, %IDC_Toolbar, "", 0,0,0,0 , %TbStyle_Flat Or %CCS_NoDivider
Control Handle hDlg, %IDC_Toolbar To hToolbar
Toolbar Set ImageList hDlg, %IDC_Toolbar, hList, 0
Toolbar Add Button hDlg, %IDC_Toolbar, 1, %IDT_Exit, %TbStyle_Button, " Exit "
Toolbar Add Separator hDlg, %IDC_Toolbar, 50
Toolbar Add Button hDlg, %IDC_Toolbar, 5, %IDT_Plus, %TbStyle_Button, " ZoomIn "
Toolbar Add Button hDlg, %IDC_Toolbar, 6, %IDT_Minus, %TbStyle_Button, " ZoomOut "
Toolbar Add Button hDlg, %IDC_Toolbar, 7, %IDT_ResetZoom, %TbStyle_Button, " Reset "
Toolbar Add Separator hDlg, %IDC_Toolbar, 50
If Scroll = 0 Then Toolbar Add Button hDlg, %IDC_Toolbar, 8, %IDT_Scroll, %TbStyle_Button, " Scroll "
If Scroll = 1 Then Toolbar Add Button hDlg, %IDC_Toolbar, 4, %IDT_StopScroll, %TbStyle_Button, " Stop "
Toolbar Add Button hDlg, %IDC_Toolbar, 2, %IDT_Slower, %TbStyle_Button, " Slower "
Toolbar Add Button hDlg, %IDC_Toolbar, 3, %IDT_Faster, %TbStyle_Button, " Faster "
Toolbar Add Button hDlg, %IDC_Toolbar, 7, %IDT_ResetScroll, %TbStyle_Button, " Reset "
Control Set Font hDlg, %IDC_StatusBar, hToolbar
Control Get Size hDlg, %IDC_Toolbar To TBW, TBH
End Sub
Sub Settings_INI(Task$)
Local x,y,w,h, tempz, INIFileName As WStringZ * %Max_Path, WinPla As WindowPlacement
'set ini filename
INIFileName = Exe.Path$ + Exe.Name$ + ".ini" 'get INI file name
Select Case Task$
Case "get"
'get dialog width/height from INI file and use to set Dialog size
GetPrivateProfileString "All", "Width", "1200", w, %Max_Path, INIFileName
GetPrivateProfileString "All", "Height", "300", h, %Max_Path, INIFileName
Dialog Set Size hDlg,Val(w), Val(h) 'width/height
'get dialog top/left from INI file and use to set Dialog location
Getprivateprofilestring "All", "Left", "0", x, %Max_Path, INIFileName
Getprivateprofilestring "All", "Top", "0", y, %Max_Path, INIFileName
If IsFile(INIFileName) Then Dialog Set Loc hDlg, Val(x), Val(y) 'left/top but only once INIFileName exists
'get value for string variables
' GetPrivateProfileString "All", "FontName", "Arial Black", FontName, %Max_Path, INIFileName
'get value for numeric variables
Getprivateprofilestring "All", "ImageWidth", "", tempz, %Max_Path, INIFileName : ImageWidth = Val(tempz)
Getprivateprofilestring "All", "ImageHeight", "", tempz, %Max_Path, INIFileName : ImageHeight = Val(tempz)
Getprivateprofilestring "All", "TimerIntereval", "50", tempz, %Max_Path, INIFileName : TimerInterval = Val(tempz)
Getprivateprofilestring "All", "Zoom", "1", tempz, %Max_Path, INIFileName : Zoom = Val(tempz)
Getprivateprofilestring "All", "XDelta", "2", tempz, %Max_Path, INIFileName : XDelta = Val(tempz)
Getprivateprofilestring "All", "ShowLine", "1", tempz, %Max_Path, INIFileName : ShowLine = Val(tempz)
Case "save"
If IsFile(INIFileName) Then Kill INIFileName 'clear the INI file Name to remove residual entries before saving
WinPla.Length = SizeOf(WinPla)
GetWindowPlacement hDlg, WinPla
WritePrivateProfileString "All", "Left", Str$(WinPla.rcNormalPosition.nLeft), INIFileName
WritePrivateProfileString "All", "Top", Str$(WinPla.rcNormalPosition.nTop), INIFileName
WritePrivateProfileString "All", "Width", Str$(WinPla.rcNormalPosition.nRight - WinPla.rcNormalPosition.nLeft), INIFileName
WritePrivateProfileString "All", "Height", Str$(WinPla.rcNormalPosition.nBottom - WinPla.rcNormalPosition.nTop), INIFileName
'save string variables
' WritePrivateProfileString "All", "FontName", FontName, INIFileName
'save numeric variables
WritePrivateProfileString "All", "ImageHeight", Str$(ImageHeight), INIFileName
WritePrivateProfileString "All", "ImageWidth", Str$(ImageWidth), INIFileName
WritePrivateProfileString "All", "TimerInterval", Str$(TimerInterval), INIFileName
WritePrivateProfileString "All", "Zoom", Str$(Zoom), INIFileName
WritePrivateProfileString "All", "XDelta", Str$(XDelta), INIFileName
WritePrivateProfileString "All", "ShowLine", Str$(ShowLine), INIFileName
End Select
End Sub
Sub sBeep : WinBeep(275,150) : End Sub
Sub BuildAcceleratorTable
Local ac() As ACCELAPI, hAccelerator As Dword, c As Long ' for keyboard accelator table values
Dim ac(2)
ac(c).fvirt = %FVIRTKEY : ac(c).key = %VK_V : ac(c).cmd = %IDT_View : Incr c
ac(c).fvirt = %FVIRTKEY : ac(c).key = %VK_L : ac(c).cmd = %IDT_ShowLine : Incr c
ac(c).fvirt = %FVIRTKEY : ac(c).key = %VK_S : ac(c).cmd = %IDT_Scroll : Incr c
Accel Attach hDlg, AC() To hAccelerator
End Sub
Sub ResizeDialog
Local w,h, x1,y1 As Long
Dialog Get Client hDlg To w,h
Control Set Size hDlg, %IDC_Graphic, w-20, h-TBH-SBH-10
Control Get Client hDlg, %IDC_Graphic To w,h
x1 = 0
y1 = (h-Zoom*ImageHeight)/2
Graphic Color %Black, %White
Graphic Width 2
Graphic Clear
Graphic Set StretchMode %HalfTone
Graphic Render Bitmap "merge.bmp", (x1,y1)-(x1+Zoom*ImageWidth,y1+Zoom*ImageHeight)
If ShowLine Then DrawLines (%Red)
Graphic ReDraw
SetStatusBar
End Sub
Sub DrawLines (LineColor As Long)
Local w,h,i, SingleImageX As Long
Graphic Get Canvas To w,h
SingleImageX = w / ImageCount
Graphic Color LineColor, %White
For i = 1 To ImageCount-1
Graphic Line (i*SingleImageX-5,0)-(i*SingleImageX-5,h)
Next i
End Sub
Sub SetStatusBar
Statusbar Set Text hDlg, %IDC_StatusBar, 1, 0, "gbScroller v" + $Ver + " Zoom = " + Str$(Zoom) + " Timer Interval = " + Str$(TimerInterval) + " " + Time$
End Sub
Function ImageCount As Long
Local iCount As Long, temp$
temp$ = Dir$("images\*.*")
While Len(temp$)
Incr iCount
temp$ = Dir$(Next)
Wend
Function = iCount
End Function
Sub GetImageSize 'get image size for bmp$
Local hBMP As Dword
Graphic Bitmap Load "merge.bmp", 0, 0 To hBMP
Graphic Attach hBMP, 0
Graphic Get Canvas To ImageWidth, ImageHeight
Graphic Bitmap End
End Sub
Sub ChangeSpeed(iDelta As Long)
Select Case iDelta
Case 0 : TimerInterval = 0 : Scroll = 0 'stopped
Case 1 : TimerInterval += 10 : Scroll = 1 'slower
Case -1 : TimerInterval -= 10 : Scroll = 1 'faster
End Select
If TimerInterval < 10 Then TimerInterval = 10 : sBeep
KillTimer hDlg, %ID_Timer
SetTimer hDlg, %ID_Timer, TimerInterval, %Null
SetStatusBar
End Sub
Sub Magnify(iDelta As Long)
Select Case iDelta
Case 0 : Zoom = 1
Case 1 : Zoom += 0.25
Case -1 : Zoom -= 0.25
End Select
If Zoom < 1 Then Zoom = 1
ResizeDialog
End Sub
Sub ManageScroll
Scroll Xor=1
If Scroll Then
SetTimer hDlg, %ID_Timer, TimerInterval, %Null
Else
KillTimer hDlg, %ID_Timer
End If
End Sub
Sub ResetScroll
Local w,h As Long
Graphic Get View To w,h
Graphic Set View 0, h
End Sub
Sub ScrollImage
Local w,h,ww,hh,www,hhh As Long
Graphic Get View To w,h
Graphic Set View w+XDelta, h
Control Get Client hDlg, %IDC_Graphic To www,hhh
Graphic Get Canvas To ww,hh
'Dialog Set Text hDlg, Str$(w+XDelta) + Str$(ImageWidth)
If w+XDelta >= (ImageWidth-www) Then
sBeep : sBeep
ManageScroll : CreateToolbar
End If
End Sub