I am trying to synchronize the scrolling of two TDBGrid components in a VCL Forms application, I am having difficulty intercepting the WndProc of each grid component without any stack problems. I tried to send WM_VSCROLL messages when scrolling events, but this still leads to the wrong operation. It should work to click on the scroll bar, and also select a cell or mouse button up or down. The whole idea is that two grids next to each other display the corresponding dialog.
I tried
SendMessage( gridX.Handle, WM_VSCROLL, SB_LINEDOWN, 0 );
AND
procedure TForm1.GridXCustomWndProc( var Msg: TMessage );
begin
Msg.Result := CallWindowProc( POldWndProc, gridX.Handle, Msg.Msg, Msg.wParam, Msg.lParam );
if ( Msg.Msg = WM_VSCROLL ) then
begin
gridY.SetActiveRow( gridX.GetActiveRow );
gridY.Perform( Msg.Msg, Msg.wParam, Msg.lParam );
SetScrollPos( gridY.Handle, SB_VERT, HIWORD( Msg.wParam ), True );
end;
end;
AND
procedure TForm1.GridxCustomWndProc( var Msg: TMessage );
begin
if ( Msg.Msg = WM_VSCROLL ) then
begin
gridY.SetActiveRow( gridX.GetActiveRow );
gridY.Perform( Msg.Msg, Msg.wParam, Msg.lParam );
SetScrollPos( gridY.Handle, SB_VERT, HIWORD( Msg.wParam ), True );
end;
inherited WndProc( Msg );
end;
, - , - . . , ! .
:
private
[...]
GridXWndProc, GridXSaveWndProc: Pointer;
GridYWndProc, GridYSaveWndProc: Pointer;
procedure GridXCustomWndProc( var Msg: TMessage );
procedure GridYCustomWndProc( var Msg: TMessage );
procedure TForm1.FormCreate(Sender: TObject);
begin
GridXWndProc := classes.MakeObjectInstance( GridXCustomWndProc );
GridXSaveWndProc := Pointer( GetWindowLong( GridX.Handle, GWL_WNDPROC ) );
SetWindowLong( GridX.Handle, GWL_WNDPROC, LongInt( GridXWndProc ) );
GridYWndProc := classes.MakeObjectInstance( GridYCustomWndProc );
GridYSaveWndProc := Pointer( GetWindowLong( GridY.Handle, GWL_WNDPROC ) );
SetWindowLong( GridY.Handle, GWL_WNDPROC, LongInt( GridYWndProc ) );
end;
procedure TForm1.GridXCustomWndProc( var Msg: TMessage );
begin
Msg.Result := CallWindowProc( GridXSaveWndProc, GridX.Handle, Msg.Msg, Msg.WParam, Msg.LParam );
case Msg.Msg of
WM_KEYDOWN:
begin
case TWMKey( Msg ).CharCode of VK_UP, VK_DOWN, VK_PRIOR, VK_NEXT:
GridY.Perform( Msg.Msg, Msg.WParam, Msg.LParam );
end;
end;
WM_VSCROLL:
GridY.Perform( Msg.Msg, Msg.WParam, Msg.LParam );
WM_HSCROLL:
GridY.Perform( Msg.Msg, Msg.WParam, Msg.LParam );
WM_MOUSEWHEEL:
begin
ActiveControl := GridY;
GridY.Perform( Msg.Msg, Msg.WParam, Msg.LParam );
end;
WM_DESTROY:
begin
SetWindowLong( GridX.Handle, GWL_WNDPROC, Longint( GridXSaveWndProc ) );
Classes.FreeObjectInstance( GridXWndProc );
end;
end;
end;
procedure TForm1.GridXMouseDown( Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer );
begin
GridY.SetActiveRow( GridX.GetActiveRow );
end;
procedure TForm1.GridYCustomWndProc( var Msg: TMessage );
begin
Msg.Result := CallWindowProc( GridYSaveWndProc, GridY.Handle, Msg.Msg, Msg.WParam, Msg.LParam );
case Msg.Msg of
WM_KEYDOWN:
begin
case TWMKey( Msg ).CharCode of VK_UP, VK_DOWN, VK_PRIOR, VK_NEXT:
GridX.Perform( Msg.Msg, Msg.WParam, Msg.LParam );
end;
end;
WM_VSCROLL:
GridX.Perform( Msg.Msg, Msg.WParam, Msg.LParam );
WM_HSCROLL:
GridX.Perform( Msg.Msg, Msg.WParam, Msg.LParam );
WM_MOUSEWHEEL:
begin
ActiveControl := GridX;
GridX.Perform( Msg.Msg, Msg.WParam, Msg.LParam );
end;
WM_DESTROY:
begin
SetWindowLong( GridY.Handle, GWL_WNDPROC, Longint( GridYSaveWndProc ) );
Classes.FreeObjectInstance( GridYWndProc );
end;
end;
end;
procedure TForm1.GridYMouseDown( Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer );
begin
GridX.SetActiveRow( GridY.GetActiveRow );
end;
- Sertac Akyuz . VCL , .