Probably the best way to advance is thru records skipping not by scrolling bars (this last is more difficult to know which is the first visible row).
There are following situations for displaying row at grid:
- When we click on specific record
- When move thry arrows key
- When scrollingbar are used
Then reading MSDN I saw LVM_GETTOPINDEX which returns top visible record and then I used to assign for Value propose. It's works, but not 100%
Code: Select all
#include <hmg.ch>
#define SB_VERT 1
#define LVM_FIRST 0x1000
#define LVM_GETTOPINDEX (LVM_FIRST+39)
Function Main()
Local i, aItems:={}
For I=1 To 50
Aadd(aItems,{"Item "+AllTrim(Str(i))})
Next
DEFINE WINDOW Form_1 AT 132 , 235 WIDTH 795 HEIGHT 328 TITLE "ScrollBars at both Grids" MAIN
DEFINE GRID Grid_1
ROW 30
COL 20
WIDTH 320
HEIGHT 190
ITEMS aItems
VALUE Nil
WIDTHS { 100 }
HEADERS {'Items'}
FONTNAME "Arial"
FONTSIZE 9
TOOLTIP ""
ONCHANGE ChangePos(This.Value)
ONGOTFOCUS Nil // Grid_Left()
ONLOSTFOCUS Nil // Grid_Right()
FONTBOLD .F.
FONTITALIC .F.
FONTUNDERLINE .F.
FONTSTRIKEOUT .F.
ONDBLCLICK Nil
ONHEADCLICK Nil
ONQUERYDATA Nil
MULTISELECT .F.
ALLOWEDIT .F.
VIRTUAL .F.
DYNAMICBACKCOLOR Nil
DYNAMICFORECOLOR Nil
COLUMNWHEN Nil
COLUMNVALID Nil
COLUMNCONTROLS Nil
SHOWHEADERS .T.
CELLNAVIGATION .F.
NOLINES .F.
HELPID Nil
IMAGE Nil
JUSTIFY Nil
ITEMCOUNT Nil
BACKCOLOR Nil
FONTCOLOR Nil
HEADERIMAGES Nil
ROWSOURCE Nil
COLUMNFIELDS Nil
ALLOWAPPEND .F.
ALLOWDELETE .F.
BUFFERED .F.
DYNAMICDISPLAY Nil
ONSAVE Nil
LOCKCOLUMNS Nil
END GRID
DEFINE GRID Grid_2
ROW 30
COL 440
WIDTH 330
HEIGHT 190
ITEMS aItems
VALUE Nil
WIDTHS { 100 }
HEADERS {'Items'}
FONTNAME "Arial"
FONTSIZE 9
TOOLTIP ""
ONCHANGE ChangePos(This.Value)
ONGOTFOCUS Nil // Grid_Right()
ONLOSTFOCUS Nil // Grid_Right()
FONTBOLD .F.
FONTITALIC .F.
FONTUNDERLINE .F.
FONTSTRIKEOUT .F.
ONDBLCLICK Nil
ONHEADCLICK Nil
ONQUERYDATA Nil
MULTISELECT .F.
ALLOWEDIT .F.
VIRTUAL .F.
DYNAMICBACKCOLOR Nil
DYNAMICFORECOLOR Nil
COLUMNWHEN Nil
COLUMNVALID Nil
COLUMNCONTROLS Nil
SHOWHEADERS .T.
CELLNAVIGATION .F.
NOLINES .F.
HELPID Nil
IMAGE Nil
JUSTIFY Nil
ITEMCOUNT Nil
BACKCOLOR Nil
FONTCOLOR Nil
HEADERIMAGES Nil
ROWSOURCE Nil
COLUMNFIELDS Nil
ALLOWAPPEND .F.
ALLOWDELETE .F.
BUFFERED .F.
DYNAMICDISPLAY Nil
ONSAVE Nil
LOCKCOLUMNS Nil
END GRID
DEFINE BUTTON Button_1
ROW 40
COL 366
WIDTH 48
HEIGHT 30
ACTION Grid_Up()
CAPTION "&Up"
FONTNAME "Arial"
FONTSIZE 9
TOOLTIP ""
FONTBOLD .F.
FONTITALIC .F.
FONTUNDERLINE .F.
FONTSTRIKEOUT .F.
ONGOTFOCUS Nil
ONLOSTFOCUS Nil
HELPID Nil
FLAT .F.
TABSTOP .T.
VISIBLE .T.
TRANSPARENT .F.
MULTILINE .F.
PICTURE Nil
PICTALIGNMENT TOP
END BUTTON
DEFINE BUTTON Button_2
ROW 90
COL 366
WIDTH 48
HEIGHT 28
ACTION Grid_Down()
CAPTION "&Down"
FONTNAME "Arial"
FONTSIZE 9
TOOLTIP ""
FONTBOLD .F.
FONTITALIC .F.
FONTUNDERLINE .F.
FONTSTRIKEOUT .F.
ONGOTFOCUS Nil
ONLOSTFOCUS Nil
HELPID Nil
FLAT .F.
TABSTOP .T.
VISIBLE .T.
TRANSPARENT .F.
MULTILINE .F.
PICTURE Nil
PICTALIGNMENT TOP
END BUTTON
DEFINE SPINNER Spinner_1
ROW 200
COL 360
WIDTH 60
HEIGHT 24
RANGEMIN 1
RANGEMAX 10
VALUE 1
FONTNAME "Arial"
FONTSIZE 9
TOOLTIP ""
ONCHANGE Nil
ONGOTFOCUS Nil
ONLOSTFOCUS Nil
FONTBOLD .F.
FONTITALIC .F.
FONTUNDERLINE .F.
FONTSTRIKEOUT .F.
HELPID Nil
TABSTOP .T.
VISIBLE .T.
WRAP .F.
READONLY .F.
INCREMENT 1
BACKCOLOR Nil
FONTCOLOR Nil
END SPINNER
DEFINE STATUSBAR FONT "Courier New" SIZE 9
STATUSITEM PadC("",75)
END STATUSBAR
END WINDOW
CREATE EVENT PROCNAME Check_Grid_Events()
CENTER WINDOW Form_1
ACTIVATE WINDOW Form_1
Return Nil
Function ChangePos(nRow)
Form_1.Grid_1.Value := SetProperty("Form_1","Grid_1","Value",nRow)
Form_1.Grid_2.Value := SetProperty("Form_1","Grid_2","Value",nRow)
Return Nil
Function Grid_Down()
Local nRow := GetProperty("Form_1","Grid_1","Value")
ChangePos(nRow + GetProperty("Form_1","Spinner_1","Value"))
Return Nil
Function Grid_Up()
Local nRow := GetProperty("Form_1","Grid_1","Value")
ChangePos(nRow - GetProperty("Form_1","Spinner_1","Value"))
Return Nil
Function GetScrollBarPos()
Local cControl := GetProperty("Form_1","FocusedControl")
Local nHandle_Left:=GetControlHandle ( "Grid_1", "Form_1" )
Local nHandle_Right:=GetControlHandle ( "Grid_2", "Form_1" )
Local nPos:=GetScrollPos ( If(cControl="Grid_1",nHandle_Left,nHandle_Right), 1 )
Local nRow:=GetProperty("Form_1",cControl,"Value")
SetScrollPos ( If(cControl="Grid_1",nHandle_Right,nHandle_Left), SB_VERT, nPos, .T. )
ChangePos(SendMessage( If(cControl="Grid_1",nHandle_Left,nHandle_Right), LVM_GETTOPINDEX, 0, 0 )+2)
Return Nil
Function Check_Grid_Events()
Local nMsg := EventMsg()
Local wParam := EventWPARAM()
Local lScrollMove:=.F.
If wParam <> Form_1.HANDLE
DO CASE
CASE nMsg == WM_KEYUP
lScrollMove:=.T.
CASE nMsg == WM_KEYDOWN
lScrollMove:=.T.
CASE nMsg == 161
If LoWord(wParam) < 8
lScrollMove:=.T.
EndIf
CASE nMsg == WM_MOUSEWHEEL
lScrollMove:=.T.
OTHERWISE
Form_1.StatusBar.Item(1):=Str(nMsg)
ENDCASE
If lScrollMove
GetScrollBarPos()
Endif
Endif
Return Nil

But let know something Serge: Why are you needing for this syncronized grids ? You need for what ?
Good guitar for you !Serge wrote:I try tomorrow. Now off to guitar playing!