📄 wt.txt
字号:
1、Drawc函数改了一下:对于节点的文字为空时,右、下线条绘制后相连。
{StartRow:从第几行开始判断画线;其中ACOL:需要画图的列,BCOL:由此列来决定某行的级别,Ccol:由此行判断主键如此行是否为空。如:神机:图在第一列,决定级别的列为第二列}
procedure Drawc(StrGrid:TStringGrid;StartRow: Integer;ARow: Integer;ACol: Integer;Bcol: Integer;Rect:TRect);
var
I:integer;
J:integer;
Mrect:TRect;
Lsigle:Integer; //级别之间的线条间距
Hsigle:integer; //对下面节点是子节点的节点,文字不为空时,线条绘制时留出一个空缺
Vsigle:integer;
begin
if strgrid.RowHeights[arow]=-1 then exit;
GetStrArry(StrGrid,ARow,Bcol);
i:=High(a);
if (i=2) and (a[0]=-1) and (a[1]=4) and (a[2]=1) then exit;
Mrect:=rect;
Lsigle:=11;
IF StrGrid.Cells[ACol,Arow]<>'' then begin
// FillRect将清楚掉Delphi绘制的文字
Vsigle:=7;
Hsigle:=5;
StrGrid.Canvas.FillRect(Rect);
//按照不同的级别显示单元格里的文字
if A[i-1]=2 then
Mrect.Left:=round(rect.Left-(Lsigle-5)+(A[0]+1)*Lsigle+3)-6
else
Mrect.Left:=round(rect.Left-(Lsigle-5)+(A[0]+1)*Lsigle+3);
DrawText(StrGrid.Canvas.Handle,
pChar(StrGrid.Cells[ACol,ARow]),
Length(StrGrid.Cells[ACol,ARow]),
Mrect,DT_LEFT or DT_SINGLELINE or DT_VCENTER) // 水平居左,不换行,垂直居中
end
else begin
Vsigle:=0;
Hsigle:=0;
end;
StrGrid.Canvas.Pen.Color:=clblack;//RGB(212,208,200);//clblack;//grb(212,208,200);
// StrGrid.Canvas.pen.Style:=psdot;
for j:=0 to i-2 do
IF (j=0) and (a[j]<>-1) then //节点处的绘制
begin
if A[i-1]=2 then //该节点的下一个节点是子
begin
StrGrid.Canvas.Draw(round(rect.Left-(Lsigle-5)+A[0]*Lsigle-mainform.Expand_Image.Height/2),round((rect.top+rect.Bottom-mainform.Expand_Image.Height)/2),mainform.Expand_Image.Picture.Graphic);
//上边线
if arow<>StartRow then
begin
StrGrid.Canvas.moveto(rect.Left-(Lsigle-5)+A[J]*Lsigle,rect.top);
StrGrid.Canvas.lineto(rect.Left-(Lsigle-5)+A[J]*Lsigle,round((rect.Bottom - rect.Top - mainform.Expand_Image.Height) / 2) + rect.Top);
end;
//下边线
StrGrid.Canvas.moveto(round(rect.Left-(Lsigle-5)+(A[J]+1)*Lsigle),round(rect.top+(rect.Bottom - rect.Top)/2+Vsigle));
StrGrid.Canvas.lineto(rect.Left-(Lsigle-5)+(A[J]+1)*Lsigle,rect.Bottom);
//右边线
StrGrid.Canvas.moveto(round(rect.Left-(Lsigle-5)+A[J]*Lsigle+mainform.Expand_Image.Width/2),round(rect.top+(rect.Bottom - rect.Top)/2));
StrGrid.Canvas.lineto(round(rect.Left-(Lsigle-5)+(A[J]+1)*Lsigle)-Hsigle,round(rect.top+(rect.Bottom - rect.Top)/2));
If A[i]=1 Then //该节点是否有弟
//图片下面的线条
begin
StrGrid.Canvas.moveto(round(rect.Left-(Lsigle-5)+A[J]*Lsigle),round((rect.Bottom - rect.Top + mainform.Expand_Image.Height) / 2 + rect.Top));
StrGrid.Canvas.lineto(rect.Left-(Lsigle-5)+A[J]*Lsigle,rect.Bottom);
end;
end
else if A[i-1]=3 then //该节点下一个节点是未展开子(隐藏的行)
begin
StrGrid.Canvas.Draw(round(rect.Left-(Lsigle-5)+A[0]*Lsigle-mainform.Collapse_Image.Height/2),round((rect.top+rect.Bottom-mainform.Collapse_Image.Height)/2),mainform.Collapse_Image.Picture.Graphic);
//上边线
if arow<>StartRow then
begin
StrGrid.Canvas.moveto(rect.Left-(Lsigle-5)+A[J]*Lsigle,rect.top);
StrGrid.Canvas.lineto(rect.Left-(Lsigle-5)+A[J]*Lsigle,round((rect.Bottom - rect.Top - mainform.Collapse_Image.Height) / 2) + rect.Top);
end;
//右边线
StrGrid.Canvas.moveto(round(rect.Left-(Lsigle-5)+A[J]*Lsigle+mainform.Collapse_Image.Width/2),round(rect.top+(rect.Bottom - rect.Top)/2));
StrGrid.Canvas.lineto(round(rect.Left-(Lsigle-5)+(A[J]+1)*Lsigle),round(rect.top+(rect.Bottom - rect.Top)/2));
If A[i]=1 Then //该节点是否有弟
//图片下面的线条
begin
StrGrid.Canvas.moveto(round(rect.Left-(Lsigle-5)+A[J]*Lsigle),round((rect.Bottom - rect.Top + mainform.Collapse_Image.Height) / 2 + rect.Top));
StrGrid.Canvas.lineto(rect.Left-(Lsigle-5)+A[J]*Lsigle,rect.Bottom);
end;
end
else if A[i-1]=1 then //该节点的下一个节点是弟
begin
//竖线
if arow<>StartRow then
StrGrid.Canvas.moveto(rect.Left-(Lsigle-5)+A[J]*Lsigle,rect.top)
else
StrGrid.Canvas.moveto(rect.Left-(Lsigle-5)+A[J]*Lsigle,round((rect.Bottom - rect.Top) / 2)+ rect.Top);
StrGrid.Canvas.lineto(rect.Left-(Lsigle-5)+A[J]*Lsigle,rect.Bottom);
//右边线
StrGrid.Canvas.moveto(rect.Left-(Lsigle-5)+A[J]*Lsigle,round((rect.Bottom - rect.Top) / 2 + rect.Top));
StrGrid.Canvas.lineto(rect.Left-(Lsigle-5)+(A[J]+1)*Lsigle,round((rect.Bottom - rect.Top) / 2 + rect.Top));
end
else //该节点无弟\无子
begin
//上边线
if arow<>StartRow then
begin
StrGrid.Canvas.moveto(rect.Left-(Lsigle-5)+A[J]*Lsigle,rect.top);
StrGrid.Canvas.lineto(rect.Left-(Lsigle-5)+A[J]*Lsigle,round((rect.Bottom - rect.Top) / 2 + rect.Top));
end;
//右边线
StrGrid.Canvas.moveto(rect.Left-(Lsigle-5)+A[J]*Lsigle,round((rect.Bottom - rect.Top) / 2 + rect.Top));
StrGrid.Canvas.lineto(rect.Left-(Lsigle-5)+(A[J]+1)*Lsigle,round((rect.Bottom - rect.Top) / 2 + rect.Top));
end
end
else if j<>0 then //经过的其他级别的竖线
begin
StrGrid.Canvas.moveto(rect.Left-(Lsigle-5)+A[J]*Lsigle,rect.top);
StrGrid.Canvas.lineto(rect.Left-(Lsigle-5)+A[J]*Lsigle,rect.Bottom);
end;
end;
2、通过文字来识别级别有些麻烦,麻烦在于:对分部工程有一点没有考虑到,分部工程下来可以建立无穷的子分部。
所以需要做如下改动:
A:分部那一条记录,是可以插入子分部(后插)的。应该在工具条上做一些这种按钮:插入分项工程,分部工程等,
而分部工程又分为下级和同级。
B:需要一个隐藏的列,记录*号。根据和上一行记录的关系来确定*的个数。
C:对于改变某行的属性,如果从高级改为低级,不用处理,因为绘制树的代码中已经处理了。(其实是*超过了改级应有的个数的情况)
但对于从低级改为高级的,如:把一个分部工程改为分项工程:应该这样处理改变后的*个数:从改行往上遍例,即:从该行到第一行,
发现的第一个高于或等于改变后的级别的,即为分项工程或单位工程的,则可得出结果:改变后的*个数,如找到的这行也是分项工程,则
和此行的*个数一样,如果是单位工程或分项工程等的,则应该等于此行的个数-1个。
procedure THintWindow.Paint;
var
R: TRect;
begin
R := ClientRect;
Inc(R.Left, 2);
Inc(R.Top, 2);
Canvas.Font.Color := Screen.HintFont.Color;
DrawText(Canvas.Handle, PChar(Caption), -1, R, DT_LEFT or DT_NOPREFIX or
DT_WORDBREAK or DrawTextBiDiModeFlagsReadingOnly);
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -