在CEF4Delphi的 TChromium.OnDownloadUpdated事件中显示的TForm的 DFM数据流有问题

前端开发 2026-07-10

我有一个使用CEF4Delphi的项目,在下载文件时使用自定义的打开/保存对话框。

这是我创建自定义表单时触发的事件

procedure TMainForm.ChromiumDownloadUpdated(Sender: TObject;
  const browser: ICefBrowser; const downloadItem: ICefDownloadItem;
  const callback: ICefDownloadItemCallback);

var
  FileIcon: TIcon;
  Descripcion: string;
  originalFilename: string;
  openSaveForm: TOpenSaveForm;
begin
  else if downloadItem.IsComplete then
  begin
    FileIcon := TIcon.Create;
    openSaveForm := TOpenSaveForm.Create(Self);
    try
      try
        openSaveForm.LabelFilename.Caption := OpenSaveFormCaptionMsg(originalFilename, downloadItem.ReceivedBytes);
        GetFileIconAndDescription(downloadItem.GetFullPath, FileIcon, Descripcion);
        openSaveForm.RadioButtonOpen.Caption := openSaveForm.RadioButtonOpen.Caption + ' ' + Descripcion;
        openSaveForm.FileIcon.Picture.Icon := FileIcon;
        if openSaveForm.ShowModal = mrOk then
          ChooseShowSaveDialog(downloadItem.GetFullPath, openSaveForm.RadioButtonSave.Checked);
      except
        on E: Exception do
          ShowMessage('Excepcion opensaveform: ' + E.Message);
      end;
    finally
      openSaveForm.Free;
      FileIcon.Free;
    end;
  end;
end;

这个表单通常像这样显示:

正确的表单

但有时DFM流式加载会失败,表单看起来就破损了:

损坏的表单

如果我检查按钮、标签等的属性,在创建后、调用OnShow之前,它们的Width=0、Left=0等值。

解决方案

正如 @Sebastian Z指出的,问题在于我是在单独的线程中创建表单。

我将下载处理改为在主线程执行,使用PostMessage

procedure TMainForm.ChromiumDownloadUpdated(Sender: TObject;
  const browser: ICefBrowser; const downloadItem: ICefDownloadItem;
  const callback: ICefDownloadItemCallback);
begin

  if downloadItem.IsComplete then
  begin
    FOriginalFilename := downloadItem.SuggestedFileName;
    if FOriginalFilename = '' then
      FOriginalFilename := ExtractFileName(downloadItem.GetFullPath);

    FBytesRecibidos := downloadItem.ReceivedBytes;
    FRutaCompletaDescarga := downloadItem.GetFullPath;

    // 5514 - 'Descarga completa del documento %1. Seleccione una opción, por favor...'
    ActualizarStatusBar(MensajeQuiter5000(5514, [FOriginalFilename]), True);

    // preparar descarga completa
    PostMessage(Handle, CEF_AFTERDOWNLOAD, 0, 0);
  end;
end;




    procedure NotificacionDescargaFinalizada(var aMessage : TMessage); message CEF_AFTERDOWNLOAD;


procedure TMainForm.NotificacionDescargaFinalizada(var aMessage: TMessage);
var
  FileIcon: TIcon;
  Descripcion: string;
  openSaveForm: TOpenSaveForm;
  c: TComponent;
  i: integer;
begin
    FileIcon := TIcon.Create;
    openSaveForm := TOpenSaveForm.Create(self);
    try
      try
        openSaveForm.LabelFilename.Caption := OpenSaveFormCaptionMsg(FOriginalFilename, FBytesRecibidos);

        GetFileIconAndDescription(FRutaCompletaDescarga, FileIcon, Descripcion);
        openSaveForm.RadioButtonOpen.Caption := openSaveForm.RadioButtonOpen.Caption + ' ' + Descripcion;
        openSaveForm.FileIcon.Picture.Icon := FileIcon;

        if openSaveForm.ShowModal = mrOk then
          ChooseShowSaveDialog(FRutaCompletaDescarga, openSaveForm.RadioButtonSave.Checked);
      except
        on E: Exception do
          ShowMessage('Excepcion opensaveform: ' + E.Message);
      end;
    finally
      openSaveForm.Free;
      FileIcon.Free;
    end;
end;

现在表单工作正常。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章