【问题标题】:Why does TEdit.OnChange trigger when Ctrl+A is pressed?为什么按下 Ctrl+A 时 TEdit.OnChange 会触发?
【发布时间】:2017-02-14 15:30:30
【问题描述】:

我在 Windows 7 上运行 Delphi XE7 VCL 应用程序。

我观察到当按下 Ctrl+A(全选)时会触发TEdit.OnChange 事件。这是为什么呢?

只有当TEdit 中的文本真正改变时,我才需要可靠地触发OnChange 事件。不幸的是,没有可用的OnBeforeChange 事件,因此我可以比较更改前后的文本。

那么,如何为TEdit 实现可靠的OnChange 事件?

【问题讨论】:

  • 这是 VCL 还是 FMX?
  • OnChange 触发为什么重要?也许有更优雅的解决方案?
  • @J... - 也许,但 OnChange 在没有实际更改时触发的事实很有趣:) 原因:在 OnChange 中,即使我创建并为输入的文件分配一个唯一 ID由用户在编辑框中。如果事件多次触发,则会生成多个 ID,我不希望这样。但正如你所说,我可以改变设计来绕过那个讨厌的 OnChange。
  • @NAZCA 通过使用 OnChange,您将在每次用户键入新字符时生成一个新 ID。为什么不要求用户在完全输入后单击按钮或菜单项或其他内容?
  • @RemyLebeau - 是的,我会改变设计。

标签: delphi vcl delphi-xe7


【解决方案1】:

是的,这不是一个糟糕的基础实现:

procedure TCustomEdit.CNCommand(var Message: TWMCommand);
begin
  if (Message.NotifyCode = EN_CHANGE) and not FCreating then Change;
end;

此消息未考虑到触发 EN_CHANGE 的按钮“A”当前与 ctrl 按下状态一起出现。

您可以做的是检查是否按下了Ctrl:

procedure TForm44.edt1Change(Sender: TObject);

  function IsCtrlPressed: Boolean;
  var
    State: TKeyboardState;
  begin
    GetKeyboardState(State);
    Result := ((State[VK_CONTROL] and 128) <> 0);
  end;
begin
  if IsCtrlPresed then
    Exit;

  Caption := 'Ctrl is not pressed';
end;

为避免读取整个键盘的状态,您可以按照 David Heffernan 的建议进行操作:

procedure TForm44.edt1Change(Sender: TObject);

  function IsCtrlPresed: Boolean;
  begin
    Result := GetKeyState(VK_CONTROL) < 0;
  end;
begin
  if IsCtrlPresed then
    Exit;

  Caption := 'Ctrl is not pressed';
end;

【讨论】:

  • GetKeyState(VK_CONTROL)&lt;0 是这里的成语。读取整个键盘状态很浪费。
  • 性能不是问题,但我同意大卫的观点
  • 不,性能不会成为问题,但是如果这样做很容易并且代码更简单,那么您也可以提高效率。
  • 完全同意大卫,我回家后附上你的决议
  • 我想知道,除了使用 Ctrl 键之外,还有其他事件会在不更改文本的情况下触发 OnChange 事件吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-28
  • 1970-01-01
  • 2014-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多