加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

如何使Delphi表单上的所有控件都不可编辑/可更改,但仍允许用户复

发布时间:2020-12-15 04:11:45 所属栏目:大数据 来源:网络整理
导读:我有一个显示数据库数据的表单,它有几个按钮和几个面板.这些面板包含各种组件,特别是TEdits,TComboBox,TDateTimePicker,TCheckBox,TListBox和TstringGrid. 当打开表单时,用户可以查看但不能编辑我当前禁用除使用按钮之外的所有组件的数据 for i := 0 to FrmA
我有一个显示数据库数据的表单,它有几个按钮和几个面板.这些面板包含各种组件,特别是TEdits,TComboBox,TDateTimePicker,TCheckBox,TListBox和TstringGrid.

当打开表单时,用户可以查看但不能编辑我当前禁用除使用按钮之外的所有组件的数据

for i := 0 to FrmAddNewMember.ComponentCount-1 do
    if FrmAddNewMember.Components[i] is TPanel then
      (FrmAddNewMember.Components[ i ] as TPanel).enabled := false;

这工作正常,但我现在希望用户能够将TEdits中的文本,TDateTimePicker中的日期,TComboBox中的所选项目等复制到剪贴板,但仍然不能更改它.

我将代码更改为以下内容,将TEdits设置为只读.这样做我想要的TEdits,但其他类型的控件没有只读属性,所以我像以前一样禁用它们.

for i := 0 to FrmAddNewMember.ComponentCount-1 do
    if not (FrmAddNewMember.Components[i] is TButton) then //(keep buttons working)
       case FrmAddNewMember.Components[i] of
          TEdit: (FrmAddNewMember.Components[ i ] as TEdit).readonly := true; //allows copying but not editing
          TComboBox: (FrmAddNewMember.Components[ i ] as TComboBox).enabled := false;  //no read only propert?
          TDateTimePicker: (FrmAddNewMember.Components[ i ] as TDateTimePicker).enabled := false;  //ditto
          TCheckBox: (FrmAddNewMember.Components[ i ] as TCheckBox).enabled := false;
          TListBox:  (FrmAddNewMember.Components[ i ] as TListBox).enabled := false;
          TstringGrid: (FrmAddNewMember.Components[ i ] as TstringGrid).enabled := false;
       end;

有没有办法让其他控件不可编辑但仍允许将其内容复制到剪贴板?

PS
我看过了

disable-edits-on-datagridview-but-still-allow-for-highlighting-to-copy-and-paste

make-all-controls-on-a-form-read-only-at-once-without-one-linkbutton

并在其他地方搜索也许它不能简单地完成.

解决方法

我认为,您可以为组件模拟弹出菜单(因为标准弹出菜单不适用于已禁用的菜单).

但是如果你有窗体和FormMouseDown事件处理程序的弹出菜单,你可以分析鼠标指针的位置(我指的是在哪个组件下)并使用复制菜单项调用弹出窗口.

列表框的快速示例:

unit Unit6;

interface

uses
  Winapi.Windows,Winapi.Messages,System.SysUtils,System.Variants,System.Classes,Vcl.Graphics,Vcl.Controls,Vcl.Forms,Vcl.Dialogs,Vcl.Menus,Vcl.StdCtrls,Vcl.ExtCtrls,Clipbrd;

type
  TForm6 = class(TForm)
    Panel1: TPanel;
    ListBox1: TListBox;
    ListBox2: TListBox;
    PopupMenu1: TPopupMenu;
    miCopy: TMenuItem;
    procedure miCopyClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X,Y: Integer);
  private
    { Private declarations }
    selectedText: string;
  public
    { Public declarations }
  end;

var
  Form6: TForm6;

implementation

{$R *.dfm}

procedure TForm6.FormCreate(Sender: TObject);
begin
  ListBox1.ItemIndex := 1;
  ListBox2.ItemIndex := 1;
  Panel1.OnMouseDown := FormMouseDown;
end;

procedure TForm6.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X,Y: Integer);
var
  i,parentX,parentY: integer;
  p: TPoint;
  lb: TListBox;
begin
  if Button <> mbRight then
    exit;

  selectedText := '';
  for i := 0 to ComponentCount - 1 do
    if Components[i] is TListBox then
    begin
      lb := TListBox(Components[i]);
      begin
        p := lb.ParentToClient(Point(X,Y));
        if lb.ClientRect.Contains(p) then
        begin
          parentX := 0;
          parentY := 0;
          if Assigned(lb.Parent) then
          begin
            parentX := lb.Parent.ClientOrigin.X;
            parentY := lb.Parent.ClientOrigin.Y;
          end;

          if lb.ItemIndex > -1 then
          begin
            selectedText := lb.Items[lb.ItemIndex];
            PopupMenu1.Popup(lb.Left + parentX + p.X,lb.Top + parentY + p.Y);
          end;
          break;
        end;
      end;
    end;
end;

procedure TForm6.miCopyClick(Sender: TObject);
begin
  if selectedText = '' then
    exit;

  Clipboard.AsText := selectedText;
end;

end.

这里ListBox1放在TPanel组件上.请注意,您应该将表单的OnMouseDown处理程序分配给所有面板或其他容器.此外,如果您有嵌套容器,则需要使用递归算法来查找parentX,parentY.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读