Grid之间的滚动轴拖动事件响应 怎样实现两个Grid之间的滚动轴拖动事件响应既是左边的Grid滚动轴拖动,右边的Grid的滚动轴也跟着移动。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 两个Grid的同步滚动 在实际制作一个项目当中,有时候需要几个grid一起同步滚动以减少用户的操作量。希望下面那段代码对您有一定的参考价值。{1.}unit SyncStringGrid;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,Dialogs, Grids;type TSyncKind = (skBoth, skVScroll, skHScroll); TSyncStringGrid = class(TStringGrid)private FInSync: Boolean; FsyncGrid: TSyncStringGrid; FSyncKind: TSyncKind;{ Private declarations } procedure WMVScroll(var Msg: TMessage); message WM_VSCROLL; procedure WMHScroll(var Msg: TMessage); message WM_HSCROLL;protected{ Protected declarations }public{ Public declarations } procedure DoSync(Msg, wParam: Integer; lParam: Longint); virtual;published{ Published declarations } property SyncGrid: TSyncStringGrid read FSyncGrid write FSyncGrid; property SyncKind: TSyncKind read FSyncKind write FSyncKind default skBoth;end;procedure Register;implementationprocedure Register;begin RegisterComponents('Samples', [TSyncStringGrid]);end;procedure TSyncStringGrid.WMVScroll(var Msg: TMessage);begin if not FInSync and Assigned(FSyncGrid) and (FSyncKind in [skBoth, skVScroll]) then FSyncGrid.DoSync(WM_VSCROLL, Msg.wParam, Msg.lParam); inherited;end;procedure TSyncStringGrid.WMHScroll(var Msg: TMessage);begin if not FInSync and Assigned(FSyncGrid) and (FSyncKind in [skBoth, skHScroll]) then FSyncGrid.DoSync(WM_HSCROLL, Msg.wParam, Msg.lParam); inherited;end;procedure TSyncStringGrid.DoSync(Msg, wParam: Integer; lParam: Longint);begin FInSync := True; Perform(Msg, wParam, lParam); FinSync := False;end;end.{****************************************}{2.}private OldGridProc1, OldGridProc2: TWndMethod; procedure Grid1WindowProc(var Message: TMessage); procedure Grid2WindowProc(var Message: TMessage);public{...}procedure TForm1.Grid1WindowProc(var Message: TMessage);begin OldGridProc1(Message); if ((Message.Msg = WM_VSCROLL) or (Message.Msg = WM_HSCROLL) or Message.msg = WM_Mousewheel)) then begin OldGridProc2(Message); end;end;procedure TForm1.Grid2WindowProc(var Message: TMessage);begin OldGridProc2(Message); if ((Message.Msg = WM_VSCROLL) or (Message.Msg = WM_HSCROLL) or (Message.msg = WM_Mousewheel)) then begin OldGridProc1(Message); end;end;procedure TForm1.FormCreate(Sender: TObject);begin OldGridProc1 := StringGrid1.WindowProc; OldGridProc2 := StringGrid2.WindowProc; StringGrid1.WindowProc := Grid1WindowProc; StringGrid2.WindowProc := Grid2WindowProc;end; meiqingsong(阿飛) 老兄,你这个用 ((Message.Msg = WM_VSCROLL) or (Message.Msg = WM_HSCROLL) or Message.msg = WM_Mousewheel)) 的方法好复杂,暂时还看不懂。我目前就是找不到,什么事件是反映鼠标拖动了滚动轴。我下面这个方法是使用鼠标点击来实现数据指针的移动的。可是不尽如人意。procedure TFormTwoGrid.FormShow(Sender: TObject);begin YDBGrid1.OnCellClick := OneCellClick; YDBGrid2.OnCellClick := TwoCellClick;end;procedure TFormTwoGrid.OneCellClick(Column: TColumnEh);var Row,MaxRow: Integer;begin if (DatasetOne.RecordCount = DatasetTwo.RecordCount) then begin MaxRow := DatasetOne.RecordCount; Row := StrToInt(DatasetOne.FieldByName('IdentPart').AsString) + MaxRow; DatasetTwo.Locate('IdentPart',IntToStr(Row),[loCaseInsensitive]); //确定右边 Row := StrToInt(DatasetTwo.FieldByName('IdentPart').AsString) - MaxRow; DatasetOne.Locate('IdentPart',IntToStr(Row),[loCaseInsensitive]); //重新确定左边 end;end;procedure TFormTwoGrid.TwoCellClick(Column: TColumnEh);var Row,MaxRow: Integer;begin if (DatasetOne.RecordCount = DatasetTwo.RecordCount) then begin MaxRow := DatasetOne.RecordCount; Row := StrToInt(DatasetTwo.FieldByName('IdentPart').AsString) - MaxRow; DatasetOne.Locate('IdentPart',IntToStr(Row),[loCaseInsensitive]); //确定左边 Row := StrToInt(DatasetOne.FieldByName('IdentPart').AsString) + MaxRow; DatasetTwo.Locate('IdentPart',IntToStr(Row),[loCaseInsensitive]); //重新确定右边 end;end; procedure TForm1.FormCreate(Sender: TObject);begin OldGridProc1 := StringGrid1.WindowProc; //保存StringGrid1的窗口处理过程 OldGridProc2 := StringGrid2.WindowProc; //保存StringGrid2的窗口处理过程 StringGrid1.WindowProc := Grid1WindowProc; //设置StringGrid1的窗口处理为Grid1WindowProc StringGrid2.WindowProc := Grid2WindowProc; //设置StringGrid2的窗口处理为Grid2WindowProcend;WindowProc过程 处理该控件的各种消息((Message.Msg = WM_VSCROLL) 垂直滚动条滚动产生的消息 or (Message.Msg = WM_HSCROLL) 水平滚动条滚动产生的消息 or Message.msg = WM_Mousewheel)) 鼠标的滑轮滚动产生的消息 meiqingsong(阿飛) 老兄: 你只给出了滚动条的消息代码是:WM_VSCROLL,WM_HSCROLL,WM_Mousewheel要实现完美,还要鼠标“点击”,和按“上下键”的代码。 要实现完美,还要鼠标“点击”,和按“上下键”的代码1。鼠标“点击”, 鼠标“点击”滚动条会产生滚动条的滚动消息,无需再处理2。按“上下键”的代码--你把 procedure TForm1.Grid1WindowProc(var Message: TMessage); 和 procedure TForm1.Grid2WindowProc(var Message: TMessage); 中的 if ((Message.Msg = WM_VSCROLL) or (Message.Msg = WM_HSCROLL) or (Message.msg = WM_Mousewheel)) then改为 if ((Message.Msg = WM_VSCROLL) or (Message.Msg = WM_HSCROLL) or (Message.msg = WM_Mousewheel) or ((Message.Msg = wm_keydown) and (TWMKeyDown(Message).CharCode in[VK_DOWN, VK_UP, VK_LEFT, VK_RIGHT]))) then就可以了 有没有简单的办法来实现统计文章中单词的个数 DBGridEh在繁体系统下显示简体中文的问题!急!!! 关于ADOCONNECTION的问题,请各位高手帮忙看看 怎么退出EXCEL,要完全关闭后台进程! 关于TIdSMTP和TIdMessage的问题 ★★★ 如何实现图片的鱼眼效果!!! ★★★ TWebBrowser如何获取其文件内容? 为什么dbcombobox不能选择? delphi下用QuickRep打印时为什么纸张滚动不受控制。 如何判断mouse滚动listbox滚动条? TBLOBFIELD类型字段如何赋值? 100分~~~~~~~如何实现根据多个下拉菜单,动态生成SQL语句!!
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,Dialogs, Grids;type
TSyncKind = (skBoth, skVScroll, skHScroll);
TSyncStringGrid = class(TStringGrid)private
FInSync: Boolean;
FsyncGrid: TSyncStringGrid;
FSyncKind: TSyncKind;
{ Private declarations }
procedure WMVScroll(var Msg: TMessage); message WM_VSCROLL;
procedure WMHScroll(var Msg: TMessage); message WM_HSCROLL;protected
{ Protected declarations }public
{ Public declarations }
procedure DoSync(Msg, wParam: Integer; lParam: Longint); virtual;published
{ Published declarations }
property SyncGrid: TSyncStringGrid read FSyncGrid write FSyncGrid;
property SyncKind: TSyncKind read FSyncKind write FSyncKind default skBoth;
end;procedure Register;implementationprocedure Register;
begin
RegisterComponents('Samples', [TSyncStringGrid]);
end;procedure TSyncStringGrid.WMVScroll(var Msg: TMessage);
begin
if not FInSync and Assigned(FSyncGrid) and (FSyncKind in [skBoth, skVScroll]) then
FSyncGrid.DoSync(WM_VSCROLL, Msg.wParam, Msg.lParam);
inherited;
end;procedure TSyncStringGrid.WMHScroll(var Msg: TMessage);
begin
if not FInSync and Assigned(FSyncGrid) and (FSyncKind in [skBoth, skHScroll]) then
FSyncGrid.DoSync(WM_HSCROLL, Msg.wParam, Msg.lParam);
inherited;
end;procedure TSyncStringGrid.DoSync(Msg, wParam: Integer; lParam: Longint);
begin
FInSync := True;
Perform(Msg, wParam, lParam);
FinSync := False;
end;end.{****************************************}{2.}
private
OldGridProc1, OldGridProc2: TWndMethod;
procedure Grid1WindowProc(var Message: TMessage);
procedure Grid2WindowProc(var Message: TMessage);public
{...}procedure TForm1.Grid1WindowProc(var Message: TMessage);begin
OldGridProc1(Message);
if ((Message.Msg = WM_VSCROLL) or (Message.Msg = WM_HSCROLL) or Message.msg = WM_Mousewheel)) then
begin
OldGridProc2(Message);
end;
end;procedure TForm1.Grid2WindowProc(var Message: TMessage);
begin
OldGridProc2(Message);
if ((Message.Msg = WM_VSCROLL) or (Message.Msg = WM_HSCROLL) or (Message.msg = WM_Mousewheel)) then
begin
OldGridProc1(Message);
end;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
OldGridProc1 := StringGrid1.WindowProc;
OldGridProc2 := StringGrid2.WindowProc;
StringGrid1.WindowProc := Grid1WindowProc;
StringGrid2.WindowProc := Grid2WindowProc;
end;
我下面这个方法是使用鼠标点击来实现数据指针的移动的。
可是不尽如人意。procedure TFormTwoGrid.FormShow(Sender: TObject);
begin
YDBGrid1.OnCellClick := OneCellClick;
YDBGrid2.OnCellClick := TwoCellClick;
end;procedure TFormTwoGrid.OneCellClick(Column: TColumnEh);
var
Row,MaxRow: Integer;
begin
if (DatasetOne.RecordCount = DatasetTwo.RecordCount) then
begin
MaxRow := DatasetOne.RecordCount;
Row := StrToInt(DatasetOne.FieldByName('IdentPart').AsString) + MaxRow;
DatasetTwo.Locate('IdentPart',IntToStr(Row),[loCaseInsensitive]); //确定右边
Row := StrToInt(DatasetTwo.FieldByName('IdentPart').AsString) - MaxRow;
DatasetOne.Locate('IdentPart',IntToStr(Row),[loCaseInsensitive]); //重新确定左边
end;
end;procedure TFormTwoGrid.TwoCellClick(Column: TColumnEh);
var
Row,MaxRow: Integer;
begin
if (DatasetOne.RecordCount = DatasetTwo.RecordCount) then
begin
MaxRow := DatasetOne.RecordCount;
Row := StrToInt(DatasetTwo.FieldByName('IdentPart').AsString) - MaxRow;
DatasetOne.Locate('IdentPart',IntToStr(Row),[loCaseInsensitive]); //确定左边
Row := StrToInt(DatasetOne.FieldByName('IdentPart').AsString) + MaxRow;
DatasetTwo.Locate('IdentPart',IntToStr(Row),[loCaseInsensitive]); //重新确定右边
end;
end;
begin
OldGridProc1 := StringGrid1.WindowProc; //保存StringGrid1的窗口处理过程
OldGridProc2 := StringGrid2.WindowProc; //保存StringGrid2的窗口处理过程
StringGrid1.WindowProc := Grid1WindowProc; //设置StringGrid1的窗口处理为Grid1WindowProc
StringGrid2.WindowProc := Grid2WindowProc; //设置StringGrid2的窗口处理为Grid2WindowProc
end;WindowProc过程 处理该控件的各种消息
((Message.Msg = WM_VSCROLL) 垂直滚动条滚动产生的消息
or (Message.Msg = WM_HSCROLL) 水平滚动条滚动产生的消息
or Message.msg = WM_Mousewheel)) 鼠标的滑轮滚动产生的消息
你只给出了滚动条的消息代码是:WM_VSCROLL,WM_HSCROLL,WM_Mousewheel
要实现完美,还要鼠标“点击”,和按“上下键”的代码。
1。鼠标“点击”,
鼠标“点击”滚动条会产生滚动条的滚动消息,无需再处理
2。
按“上下键”的代码
--你把
procedure TForm1.Grid1WindowProc(var Message: TMessage); 和
procedure TForm1.Grid2WindowProc(var Message: TMessage); 中的 if ((Message.Msg = WM_VSCROLL) or (Message.Msg = WM_HSCROLL) or (Message.msg = WM_Mousewheel)) then
改为
if ((Message.Msg = WM_VSCROLL)
or (Message.Msg = WM_HSCROLL)
or (Message.msg = WM_Mousewheel)
or ((Message.Msg = wm_keydown) and
(TWMKeyDown(Message).CharCode in[VK_DOWN, VK_UP, VK_LEFT, VK_RIGHT]))) then
就可以了