Page 1 of 3
How Syncronize scroll in two gadgets?
Posted: Tue Aug 08, 2006 10:29 pm
by chen
Hi,
Is there a way to syncronize vertical scrolling in two gadgets?
Im trying to manage 2 editorGadgets, one of them contains data and
the other one row numbers... thats the idea.
The editorGadgets showing the number has a hidden vertical scroll bar,
I get this placing this gadget in a ContainerGadget.
The second Editor contains the data and its vertical scroll bar is visible..
I want using this bar to syncronize the up-down movement using only
this scroll bar....
Code: Select all
If OpenWindow(0, 0, 0, 322, 150, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
ContainerGadget(2,5,5,50,133)
EditorGadget(0, 5, 5, 65, 133)
CloseGadgetList()
EditorGadget(1, 60, 10, 250, 133)
For a = 0 To 20
AddGadgetItem(0, a, Str(a))
AddGadgetItem(1, a, "Line "+Str(a))
Next
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Help required... thanks
Posted: Tue Aug 08, 2006 10:46 pm
by Xombie
You mean like ...
Code: Select all
EnableExplicit
;
Define.l HoldEvent, a, HoldLine, CurrentLine, lResult
;
Define.b DoQuit
;
If OpenWindow(0, 0, 0, 322, 150, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
ContainerGadget(2,5,5,50,133)
EditorGadget(0, 5, 5, 65, 133)
CloseGadgetList()
EditorGadget(1, 60, 10, 250, 133)
For a = 0 To 20
AddGadgetItem(0, a, Str(a))
AddGadgetItem(1, a, "Line "+Str(a))
Next
;
Repeat
;
HoldEvent = WaitWindowEvent()
;
If HoldEvent = #PB_Event_CloseWindow
; Close the program.
DoQuit = #True
;
ElseIf HoldEvent = #PB_Event_Gadget
;
If EventGadget() = 1
;
If EventType() = 1024
;
HoldLine = SendMessage_(GadgetID(1), #EM_GETFIRSTVISIBLELINE, 0, 0)
;
CurrentLine = SendMessage_(GadgetID(0), #EM_GETFIRSTVISIBLELINE, 0, 0)
;
lResult = SendMessage_(GadgetID(0), #EM_LINESCROLL, 0, HoldLine - CurrentLine)
;
EndIf
;
EndIf
;
EndIf
;
Until DoQuit
;
EndIf
;-
End
;-
... that?
EDIT: Incidentally, you can use...
Code: Select all
ShowScrollbar_(GadgetID(1), #SB_BOTH, #False)
... to turn off a control's scrollbar rather than using the container.
Posted: Tue Aug 08, 2006 10:53 pm
by chen
Yes, Like that...
One question?... Is there a way to do it without API or is the only way?
Thanks Xombie
Posted: Tue Aug 08, 2006 10:59 pm
by Xombie
Hmmm... not that I see. Maybe Fred could add it to the SetGadgetAttribute() and add something like a "#PB_Editor_LineNumber" constant?
Posted: Tue Aug 08, 2006 11:14 pm
by chen
Ok...
Im testing your code and I see this:
If you scroll down line by line the line number are sincronized with the data
But?
If you advance by page there are no one-one relation.... for example
65 point to line 66
Code: Select all
EnableExplicit
;
Define.l HoldEvent, a, HoldLine, CurrentLine, lResult
;
Define.b DoQuit
;
If OpenWindow(0, 0, 0, 322, 150, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
ContainerGadget(2,5,5,50,138)
EditorGadget(0, 5, 5, 65, 140)
CloseGadgetList()
EditorGadget(1, 60, 10, 250, 133)
For a = 0 To 1000
AddGadgetItem(0, a, Str(a))
AddGadgetItem(1, a, "Line "+Str(a))
Next
;
Repeat
;
HoldEvent = WaitWindowEvent()
;
If HoldEvent = #PB_Event_CloseWindow
; Close the program.
DoQuit = #True
;
ElseIf HoldEvent = #PB_Event_Gadget
;
If EventGadget() = 1
;
If EventType() = 1024
;
HoldLine = SendMessage_(GadgetID(1), #EM_GETFIRSTVISIBLELINE, 0, 0)
;
CurrentLine = SendMessage_(GadgetID(0), #EM_GETFIRSTVISIBLELINE, 0, 0)
;
lResult = SendMessage_(GadgetID(0), #EM_LINESCROLL, 0, HoldLine - CurrentLine)
;
EndIf
;
EndIf
;
EndIf
;
Until DoQuit
;
EndIf
;-
End
;-
DO I need to consider something else...?
Anyway Im going to try by myself.... thanks indeed...
Posted: Tue Aug 08, 2006 11:21 pm
by srod
Here's another way which synchronises even when dragging the thumb:
Code: Select all
Global oldproc
Procedure WindowCallback(hWnd, uMsg, wParam, lParam)
Protected topitem, currentitem
Result = CallWindowProc_(oldproc, hWnd, uMsg, wParam, lParam)
Select uMsg
Case #WM_VSCROLL
SendMessage_(GadgetID(0), #WM_VSCROLL, wParam, lParam)
Case #WM_KEYUP, #WM_KEYDOWN
topitem = SendMessage_(GadgetID(1),#EM_GETFIRSTVISIBLELINE,0,0)
currentitem = SendMessage_(GadgetID(0),#EM_GETFIRSTVISIBLELINE,0,0)
If topitem-currentitem
SendMessage_(GadgetID(1),#EM_LINESCROLL,0,0) ;Just for alignment!
SendMessage_(GadgetID(0),#EM_LINESCROLL,0,topitem-currentitem)
EndIf
EndSelect
ProcedureReturn Result
EndProcedure
If OpenWindow(0, 0, 0, 322, 150, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
ContainerGadget(2,5,5,50,133)
EditorGadget(0, 5, 5, 65, 133)
CloseGadgetList()
EditorGadget(1, 60, 10, 250, 133)
For a = 0 To 200
AddGadgetItem(0, a, Str(a))
AddGadgetItem(1, a, "Line "+Str(a))
Next
oldproc=SetWindowLong_(GadgetID(1), #GWL_WNDPROC, @WindowCallback())
Repeat
ev=WaitWindowEvent()
Until ev = #PB_Event_CloseWindow
EndIf
Incidentally, Sparkie posted some code which automatically placed line numbers in an editor gadget. That is, you do not need a second editor gadget etc.
Posted: Tue Aug 08, 2006 11:28 pm
by netmaestro
Dammit Srod!! where you buying your holster oil? [edit] Ha - tweaked my code to be 4 lines shorter than yours!
Code: Select all
Procedure Callback(hwnd, msg, wparam, lparam)
result = #PB_ProcessPureBasicEvents
If msg=#WM_COMMAND
If IsGadget(1)
If lparam = GadgetID(1)
If wparam >> 16 = 1024 ; EN_UPDATE
SendMessage_(GadgetID(1), #EM_GETSCROLLPOS, 0, @pt.point)
SendMessage_(GadgetID(0), #EM_SETSCROLLPOS, 0, @pt)
EndIf
EndIf
EndIf
result = 0
EndIf
ProcedureReturn result
EndProcedure
If OpenWindow(0, 0, 0, 322, 150, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
SetWindowCallback(@Callback())
ContainerGadget(2,5,5,50,133)
EditorGadget(0, 5, 5, 65, 133)
CloseGadgetList()
EditorGadget(1, 60, 10, 250, 133)
For a = 0 To 20
AddGadgetItem(0, a, Str(a))
AddGadgetItem(1, a, "Line "+Str(a))
Next
Repeat : Until WaitWindowEvent()=#WM_CLOSE
EndIf
End
Posted: Tue Aug 08, 2006 11:33 pm
by Xombie
chen wrote:Ok...
Im testing your code and I see this:
If you scroll down line by line the line number are sincronized with the data
But?
If you advance by page there are no one-one relation.... for example
65 point to line 66
DO I need to consider something else...?
Anyway Im going to try by myself.... thanks indeed...
It's checking the first visible line item and including anything that's even partially visible. Using a callback and checking for the scroll message rather than watching the line number of the edit control is much better - a la srod's code. That way they match exactly and you aren't constrained by PB's limitation of not providing events while moving the little scrollbar itself.
Posted: Tue Aug 08, 2006 11:37 pm
by srod
I like your code netmaestro. Pretty slick!
Which notification message corresponds to 1024?
Posted: Tue Aug 08, 2006 11:37 pm
by netmaestro
Posted: Tue Aug 08, 2006 11:40 pm
by srod
Pah, who needs a mousewheel?

Posted: Tue Aug 08, 2006 11:51 pm
by netmaestro
1024 is #EN_UPDATE:
MSDN wrote:The EN_UPDATE notification message is sent when an edit control is about to redraw itself.
Sorry, I really should have used the constant instead of the value, it would've been easier to read. I'm bad for that.

Posted: Tue Aug 08, 2006 11:58 pm
by srod
Yep, your's is definitely the best way. Very nice.
Posted: Wed Aug 09, 2006 12:57 am
by chen
Battle at the top
Help a lot thanks.....
Posted: Fri Oct 20, 2006 3:09 pm
by RegisLG
In my program i have the EnableExplicit activated.
I wanted to use netmastro's code, but i need to know the variable declation i must write in the procedure.
Can someone help me please ?