我以另一种形式编写了表单渲染设置数据库表 Dbgrid 的代码。这取决于所选项目在 Dbgrid 中定义 Chetsklistboks 可见列。我还编写了代码来移动与拖放项目和列 Chetsklistbox Dbgrid 一致性。但是,当从参数拖放超出范围以及关闭无效指针操作时,从某个点开始(在我看来,尝试更改具有大索引的项目中索引最低的项目)错误。帮助解决错误。
unit SettingOfShowData;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.CheckLst, Vcl.ExtCtrls,
VirtualTrees, DatabaseClasses, MainForm, ListOfTables;
type
TNodeField=record
NameField : string;
end;
PNodeField=^TNodeField;
type
TfmSettings = class(TForm)
Panel1: TPanel;
VT: TVirtualStringTree;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
CheckListBox1: TCheckListBox;
procedure VTGetNodeDataSize(Sender: TBaseVirtualTree;
var NodeDataSize: Integer);
procedure VTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
procedure FormCreate(Sender: TObject);
procedure VTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
procedure FormActivate(Sender: TObject);
function IsPrimaryKey(InputTableName : string; InputFieldName : string) : Boolean;
procedure VTNodeClick(Sender: TBaseVirtualTree; const HitInfo: THitInfo);
procedure VTNodeDblClick(Sender: TBaseVirtualTree; const HitInfo: THitInfo);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure CheckListBox1ClickCheck(Sender: TObject);
procedure CheckListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
procedure CheckListBox1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
procedure CheckListBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
end;
var
fmSettings: TfmSettings;
NumX, NumY : Integer;
implementation
{$R *.dfm}
procedure TfmSettings.CheckListBox1ClickCheck(Sender: TObject);
begin
fmShowData.DBGrid1.Columns[CheckListBox1.ItemIndex].Visible :=
not(fmShowData.DBGrid1.Columns[CheckListBox1.ItemIndex].Visible);
end;
procedure TfmSettings.CheckListBox1DragDrop(Sender, Source: TObject; X,
Y: Integer);
var
Num1, Num2, temp: Integer;
Point1, Point2: TPoint;
begin
Point1.X:=NumX;
Point1.Y:=NumY;
Point2.X:=X;
Point2.Y:=Y;
with Source as TCheckListBox do
begin
Num2:=CheckListBox1.ItemAtPos(Point1,True);
Num1:=CheckListBox1.ItemAtPos(Point2,True);
CheckListBox1.Items.Move(Num2, Num1);
if Num2>Num1 then
begin
temp:=Num2;
Num2:=Num1;
Num1:=temp;
end;
fmShowData.DBGrid1.Columns[Num1].Index:=Num2;
fmShowData.DBGrid1.Columns[Num2+1].Index:=Num1;
end;
end;
procedure TfmSettings.CheckListBox1DragOver(Sender, Source: TObject; X,
Y: Integer; State: TDragState; var Accept: Boolean);
begin
if Source=CheckListBox1 then Accept:=True;
end;
procedure TfmSettings.CheckListBox1MouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
NumY:=Y;
NumX:=X;
end;
procedure TfmSettings.FormActivate(Sender: TObject);
var
Index, i: Integer;
VTNodeField : PNodeField;
begin
VT.BeginUpdate();
//TableSpec:=TTableSpec(DBSchema.Tables.FindComponent(fmListOfTables.DisplayTable));
for Index := 0 to TTableSpec(DBSchema.Tables.FindComponent(fmListOfTables.DisplayTable)).Fields.ComponentCount-1 do
begin
if TTableSpec(DBSchema.Tables.FindComponent(fmListOfTables.DisplayTable)).Fields.Components[Index] is TFieldSpec then
begin
VTNodeField:=VT.GetNodeData(VT.AddChild(nil, nil));
VTNodeField^.NameField:=(TTableSpec(DBSchema.Tables.FindComponent(fmListOfTables.DisplayTable)).Fields.Components[Index] as TFieldSpec).name;
end;
end;
VT.EndUpdate();
for i := 0 to TTableSpec(DBSchema.Tables.FindComponent(fmListOfTables.DisplayTable)).Fields.ComponentCount-1 do
begin
if (TTableSpec(DBSchema.Tables.FindComponent(fmListOfTables.DisplayTable)).Fields.Components[i] is TFieldSpec) then
begin
CheckListBox1.Items.Add(TTableSpec(DBSchema.Tables.FindComponent(fmListOfTables.DisplayTable)).Fields.Components[i].Name);
CheckListBox1.Checked[i]:=true;
end;
end;
end;
procedure TfmSettings.FormClose(Sender: TObject; var Action: TCloseAction);
var i: integer;
begin
{ while VT.ComponentCount>0 do
begin
VT.DeleteNode(VT.Nodes.GetEnumerator.Current);
VT.DeleteChildren(VT.Nodes.GetEnumerator.Current);
VT.Nodes.GetEnumerator.MoveNext();
end; }
VT.Clear();
//fmTableData.DBGrid1.Columns
CheckListBox1.Clear;
end;
procedure TfmSettings.FormCreate(Sender: TObject);
var
Index: Integer;
VTNodeField : PNodeField;
//TableSpec : TTableSpec;
begin
{ VT.BeginUpdate();
//TableSpec:=TTableSpec(DBSchema.Tables.FindComponent(fmListOfTables.DisplayTable));
for Index := 0 to TTableSpec(DBSchema.Tables.FindComponent(fmListOfTables.DisplayTable)).ComponentCount-1 do
begin
if TTableSpec(DBSchema.Tables.FindComponent(fmListOfTables.DisplayTable)).Components[Index] is TFieldSpec then
begin
VTNodeField:=VT.GetNodeData(VT.AddChild(nil, nil));
VTNodeField.NameField:=(TTableSpec(DBSchema.Tables.FindComponent(fmListOfTables.DisplayTable)).Components[Index] as TFieldSpec).FieldName;
end;
end;
VT.EndUpdate();}
end;
procedure TfmSettings.VTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
var
Data: PNodeField;
begin
Data:=Sender.GetNodeData(Node);
if Assigned(Data) then
begin
Finalize(Data^);
end;
end;
procedure TfmSettings.VTGetNodeDataSize(Sender: TBaseVirtualTree;
var NodeDataSize: Integer);
begin
NodeDataSize:=SizeOf(TNodeField);
end;
procedure TfmSettings.VTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
var
Index: Integer;
VTNodeField : PNodeField;
begin
VTNodeField:=Sender.GetNodeData(Node);
for Index := 0 to DBSchema.Tables.FindComponent(fmListOfTables.DisplayTable).ComponentCount-1 do
begin
if DBSchema.Tables.FindComponent(fmListOfTables.DisplayTable).Components[Index] is TFieldSpec then
begin
VTNodeField:=Sender.GetNodeData(Sender.AddChild(nil, nil));
VTNodeField^.NameField:=(DBSchema.Tables.FindComponent(fmListOfTables.DisplayTable).Components[Index] as TFieldSpec).name;
end;
end;
CellText:=VTNodeField^.NameField;
end;
procedure TfmSettings.VTNodeClick(Sender: TBaseVirtualTree;
const HitInfo: THitInfo);
var
NewVTNodeField : PNodeField;
NewNode : PVirtualNode;
begin
{NewNode:=VT.AddChild(VT.FocusedNode);
NewVTNodeField:=VT.GetNodeData(NewNode); }
end;
procedure TfmSettings.VTNodeDblClick(Sender: TBaseVirtualTree;
const HitInfo: THitInfo);
var
NewVTNodeField, CurrentNode: PNodeField;
NewNode : PVirtualNode;
//CurrentNode : PDataNode;
i, j : integer;
begin
{ NewNode:=VT.AddChild(VT.FocusedNode);
NewVTNodeField:=VT.GetNodeData(NewNode); }
CurrentNode:=VT.GetNodeData(VT.FocusedNode);
if IsPrimaryKey(fmListOfTables.DisplayTable, {VT.Text[VT.FocusedNode, 0]} CurrentNode^.NameField) then
begin
for i:= 0 to DBSchema.Tables.ComponentCount-1 do
for j:=0 to TTableSpec(DBSchema.Tables.Components[i]).Constraints.ComponentCount-1 do
begin
if (TConstraintSpec(TTableSpec(DBSchema.Tables.Components[i]).Constraints.Components[j]).Reference=fmListOfTables.DisplayTable) then
begin
NewNode:=VT.AddChild(VT.FocusedNode);
NewVTNodeField:=VT.GetNodeData(NewNode);
NewVTNodeField^.NameField:=(TTableSpec(DBSchema.Tables.Components[i])).Name;
end;
end;
end;
end;
function TfmSettings.IsPrimaryKey(InputTableName : string; InputFieldName: string):Boolean;
var
i : integer;
flag: boolean;
begin
flag:=False;
for i:=0 to TTableSpec(DBSchema.Tables.FindComponent(InputTableName)).Constraints.ComponentCount-1 do
begin
if ((TConstraintSpec(TTableSpec(DBSchema.Tables.FindComponent(InputTableName)).Constraints.Components[i]).ConstraintType='PRIMARY') and (TFieldSpec(TConstraintDetailSpec(TConstraintSpec(TTableSpec(DBSchema.Tables.FindComponent(InputTableName)).Constraints.Components[i]).DetailList).FieldSpec).FieldName=InputFieldName){(TTableSpec(DBSchema.Tables.FindComponent(InputTableName)).Fields.FindComponent(InputFieldName).Name=TConstraintDetailSpec(TConstraintSpec(TTableSpec(DBSchema.Tables.FindComponent(InputTableName)).Constraints.Components[i]).DetailList).FieldName)}) then
flag:=True;
Edit1.Text:=TConstraintSpec(TTableSpec(DBSchema.Tables.FindComponent(InputTableName)).Constraints.Components[i]).Name;
Edit2.Text:=AnsiToUtf8(TFieldSpec(TConstraintDetailSpec(TConstraintSpec(TTableSpec(DBSchema.Tables.FindComponent(InputTableName)).Constraints.Components[i]).DetailList).FieldSpec).FieldName);
Edit3.Text:=InputFieldName;
end;
Result:=flag;
end;
end.
选择更改列顺序的程序代码
procedure TfmSettings.CheckListBox1DragDrop(Sender, Source: TObject; X,
Y: Integer);
var
Num1, Num2, temp: Integer;
Point1, Point2: TPoint;
begin
Point1.X:=NumX;
Point1.Y:=NumY;
Point2.X:=X;
Point2.Y:=Y;
with Source as TCheckListBox do
begin
Num2:=CheckListBox1.ItemAtPos(Point1,True);
Num1:=CheckListBox1.ItemAtPos(Point2,True);
CheckListBox1.Items.Move(Num2, Num1);
if Num2>Num1 then
begin
temp:=Num2;
Num2:=Num1;
Num1:=temp;
end;
fmShowData.DBGrid1.Columns[Num1].Index:=Num2;
fmShowData.DBGrid1.Columns[Num2+1].Index:=Num1;
end;
end;