关于CXGRID如何显示解密后的数据列问题?

hjrocket 2018-12-22 07:13:50
用DELPHI 10.2写了一个REST架构的C/S模式三层架构的人事管理系统,其中有一张人事信息表,包含姓名、性别、身份证、电话号码等数据,为了确保信息安全,身份证号和电话号码都用DES方式进行了加密,也就是说除了身份证号码和电话号码是是暗文存储,其他信息都是明文存储,数据库为SQL数据库。
加密方式是在DELPHI中写了一个DES加密函数,对需要加密的信息进行加密处理后,存储经SQL数据库。数据集控件为动态生成的FDMEMTABLE。

后台存储后的加密信息需要用客户端解密后进行查看,解密函数已在客户端中写好,但问题是如何如何用CXGRID控件将解密后的信息显示出来?我在CXGRID中使用的列是动态生成方式,因此无法使用“onGetDataContent”事件,当然主要我也不会给动态列添加onGetDataContent”事件的响应程序,如果会的大神请不吝赐教!
我查论坛,看到有人使用这个方法:
procedure Tfrm_people.cg_peopleCustomDrawCell(Sender: TcxCustomGridTableView;
ACanvas: TcxCanvas; AViewInfo: TcxGridTableDataCellViewInfo;
var ADone: Boolean);
var
ss: string;
cxColumn: TcxGridColumn;
i: integer;
begin
cxColumn := (Sender as TcxGridDBTableView).GetColumnByFieldName('身份证号');
if cxColumn = nil then
Exit;
// 这个条件用来限制是否只Paint指定的单元格, 去掉则Paint整行.
i := (Sender as TcxGridDBTableView).GetColumnByFieldName('身份证号').Index;
// 解决拖动出错问题;
if SameText(AViewInfo.Item.Name, cxColumn.Name) then
begin
AViewInfo.GridRecord.Values[i] := 'XXXX'; // 获取单元格
end;
end;
但是经过测试,程序报错....看各位大神还有没有其他解决方法!小弟不胜感激!
...全文
183 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
hjrocket 2018-12-25
  • 打赏
  • 举报
回复
感谢doloopcn和wdonghai!你们的方法都成功了!美中不足的是用cxgrid自带函数导出EXCEL后,还是解密前的文件,不过回头自己编写一个导出函数就行啦!再次感谢两位大神!各得25分!
doloopcn 2018-12-25
  • 打赏
  • 举报
回复
何必总是要对着Grid为难自己

在DataSet的Field的OnGetText事件中把密文解压不就行了
procedure DESFieldOnGetText(Sender: TField;
var Text: String; DisplayText: Boolean);
begin
Text:=DES(Sender.AsString);
end;
softdzz 2018-12-24
  • 打赏
  • 举报
回复
CustomDrawCell才是正解
BlueStorm 2018-12-24
  • 打赏
  • 举报
回复
如果你不需要把更改写回去数据库,可以在FDMemtable打开前设置一下FDMemtable.CachedUpdates := True, 数据更新完毕后不要运行FDMemtable.ApplyUpdates就可以了。
hjrocket 2018-12-24
  • 打赏
  • 举报
回复
引用 9 楼 wdonghai的回复:

procedure Tfrm_people.cg_peopleCustomDrawCell(Sender: TcxCustomGridTableView;
ACanvas: TcxCanvas; AViewInfo: TcxGridTableDataCellViewInfo;
var ADone: Boolean);
var
s:string;
R:TRect;
begin
s:=AViewInfo.GridRecord.DisplayTexts[AViewInfo.Item.Index];
ACanvas.Canvas.FillRect(AViewInfo.Bounds);
R:=AViewInfo.Bounds;
OffsetRect(R, 2, 2);
//身份证号列可以在一开始就赋值,没必要在这个事件里面取
if AViewInfo.Item.Index=身份证号列 then
s:=解密s
ACanvas.DrawText(s, R, 0);

ADone:=True;
end;
高手!我觉得你这个解决方案挺好!明天到了单位试试!
wdonghai 2018-12-24
  • 打赏
  • 举报
回复

procedure Tfrm_people.cg_peopleCustomDrawCell(Sender: TcxCustomGridTableView;
ACanvas: TcxCanvas; AViewInfo: TcxGridTableDataCellViewInfo;
var ADone: Boolean);
var
s:string;
R:TRect;
begin
s:=AViewInfo.GridRecord.DisplayTexts[AViewInfo.Item.Index];
ACanvas.Canvas.FillRect(AViewInfo.Bounds);
R:=AViewInfo.Bounds;
OffsetRect(R, 2, 2);
//身份证号列可以在一开始就赋值,没必要在这个事件里面取
if AViewInfo.Item.Index=身份证号列 then
s:=解密s
ACanvas.DrawText(s, R, 0);

ADone:=True;
end;
  • 打赏
  • 举报
回复
本地用TClientDataset缓冲,从数据库读出来之后解密,显示修改都是正常方式使用,写回之前加密,唯一的风险是如果电脑掉电或者程序异常终止会丢失比较多的修改数据。
hjrocket 2018-12-22
  • 打赏
  • 举报
回复
怎么修改fdmemtable?能给个具体的方案吗?
BlueStorm 2018-12-22
  • 打赏
  • 举报
回复
直接修改FDMEMTABLE不由可以了吗?
hjrocket 2018-12-22
  • 打赏
  • 举报
回复
这样做不就把原来加密的数据给解密后存回数据库了么?能否不修改原始数据,在cxgrid从fdmemtable取值过程中解密数据,然后显示出来?或者
BlueStorm 2018-12-22
  • 打赏
  • 举报
回复

var
  RN: Integer;
begin
  with FDMemTable do
  begin
    DisableControls;
    RN := RecNo;
    First;
    while not Eof do
    begin
      Edit;
      FieldByName('身份证号').Value := '解密后的身份证号';
      FieldByName('电话号码').Value := '解密后的电话号码';
      Post;
      Next;
    end;
    RecNo := RN;
    EnableControls;
  end;
end;
BlueStorm 2018-12-22
  • 打赏
  • 举报
回复

var
  RN: Integer;
begin
  with FDMemTable do
  begin
    DisableControls;
    RN := RecNo;
    First;
    while not Eof do
    begin
      FieldByName('身份证号').Value := '解密后的身份证号';
      FieldByName('电话号码').Value := '解密后的电话号码';
      Next;
    end;
    RecNo := RN;
    EnableControls;
  end;
end;

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧