当模式对话框关闭时,Delphi CMExit 消息未发送?

标签 delphi validation focus delphi-5

在我正在开发的应用程序的一部分中,有一个表单控件在接收到 CMExit 消息时进行验证,这正是 Delphi 文档所说的操作方式(此代码示例来自 Delphi 帮助文件):

procedure TDBCalendar.CMExit(var Message: TWMNoParams);
begin
 try
  FDataLink.UpdateRecord;                          { tell data link to update database }
 except
  on Exception do SetFocus;                      { if it failed, don't let focus leave }
 end;
 inherited;
end;

这样做的目的是在控件失去焦点时立即执行验证。因此,例如,如果我单击“确定”按钮,表单控件将失去焦点,此方法将运行,并且在出现异常时会将焦点设置回该表单控件。 (因此“确定”按钮上的“单击”事件永远不会执行,并且对话框永远不会关闭)。

我遇到的问题是该表单控件位于模式对话框窗口内。单击“确定”确实会发送 CMExit 消息并导致记录更新(并进行验证)。但是,在表单控件中按 Enter 键会导致模式对话框关闭而不发送 CMExit 消息。就好像表单控件永远不会“失去焦点”。这意味着不仅对话框会在表单没有实际验证数据的情况下关闭,而且数据集也不会更新。

考虑到这个问题,我放置数据集更新/验证代码的最佳位置在哪里?我可以将其移至对话框表单本身并在 OnCloseQuery 处理程序中实现它,但这意味着逻辑在表单本身的表单控件中都会重复。 (表单控件在其他地方使用,我想避免改变它的行为)。

(我推测 CMExit 不会被触发,因为该控件实际上从未确实失去焦点。表单已关闭,但表单控件仍然“拥有焦点”在关闭的表单上。)

最佳答案

关闭窗体并不一定会触发 TControl 的退出事件。例如,用户可以按 Alt-F4。

我建议将验证移至单独的过程,并从退出时和关闭时事件中调用该单独的过程。

下面的代码无需太多修改即可工作:

function TDBCalendar.UpdateSuccessful: boolean;
begin
  { tell data link to update database }
  { if successful, return True, else return False }
  { this function must be Public if a form is gonna check this value }
  Result := True;
  try
    FDataLink.UpdateRecord;
  except on Exception do
    Result := False;
  end;
  inherited;
end;

procedure TDBCalendar.CMExit(var Message: TWMNoParams);
begin
  //if not valid, then don't let them leave
  if not(UpdateSuccessful) then begin
    SetFocus;
  end;
end;

///////////////////////////////////////////
//on the form that contains your control...
///////////////////////////////////////////

procedure TMyForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  //if not valid, then don't let them close the form
  if not(dbcal.ControlIsValid) then begin
    Action := caNone;
  end
  else begin
    inherited;
  end;
end;

关于当模式对话框关闭时,Delphi CMExit 消息未发送?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/722438/

相关文章:

wcf - 如何使用 Delphi XE 发送 WCF 的 ClientCredentials

delphi - Spring4D 无法对有序字典进行排序

delphi - 如何使我的 TCustomControl 后代组件停止闪烁?

javascript - 使用 Javascript/jQuery 进行 Bootstrap 4 表单验证

php - less 和 html 保存到数据库中

java - 如何让 android 相机预览保持专注?

delphi - FloatToStr Delphi 转换 EInvalidOp

c# - 对 PostBack 创建的类进行不显眼的验证

javascript - React 初学者问题 : Textfield Losing Focus On Update

Android 布局焦点问题 : layout clickable, 但其元素窃取焦点