Delphi проверяет, закончил ли Tabsheet загружать данные перед созданием изображения в буфер обмена

Я работаю в Delphi XE3. Я сделал цикл, который проходит через Pagecontrol с 6 таблицами, в котором есть фреймы с множеством полей редактирования, которые загружают данные MDB.

При циклическом перемещении по страницам я делаю снимок экрана для активной вкладки и помещаю его на изображение в fastreport.

Все работает отлично, но при тестировании на некоторых более медленных компьютерах он делает все кадры, но данные не были загружены. Как проверить, что все данные загружены в компоненты редактирования фрейма, которые размещены на вкладке, прежде чем перейти на следующую страницу?

Код выглядит так:

  begin
   Screen.Cursor := crHourGlass;
    p := PageControlKalkyl.ActivePageIndex; // Get page index

  for i := 0 to 7 do begin
   MyPage := frxReport1.FindObject('Page' + IntToStr(i)) as TfrxPage;
   MyPage.Visible := True;
  end;

  try
   for i := 0 to PageControlKalkyl.PageCount - 1 do
   If PageControlKalkyl.Pages[i].TabVisible then
   Begin
   PageControlKalkyl.ActivePageIndex := i;
    PageControlKalkyl.ActivePage.Repaint;
    Bilder := 'Pic' + IntToStr(i);


    if FLaddardata = False then //Check if page changed   
    Try
      Bitmap := TBitmap.Create;
      Assert(HandleAllocated);
      DC := GetWindowDC(Handle);
      Win32Check(DC <> 0);
      Bitmap.SetSize(Width, Height);
      Win32Check(BitBlt(Bitmap.Canvas.Handle, 0, 0, Width, Height, DC, 0, 0, SRCCOPY));

      //Load data in to Images in Fastreport 
      if PageControlKalkyl.ActivePageIndex > 0  then
      Begin
      Ver:= 'Version NR: ' + Trim(DataModuleTrakop.ADOTableKALKYL.FieldByName('VERSION').AsString);                      
       Raid:= 'Kalkyl ID: ' +   Trim(DataModuleTrakop.ADOTableKALKYL.FieldByName('DENH').AsString);
       RepImage := frxReport1.FindObject('Pic'+IntTostr(i)) as TfrxPictureView;
       RepImage.Picture.Assign(Bitmap);
       Rappid := frxReport1.FindObject('Rapdata' + IntToStr(i)) as TfrxMemoView;
       Rappid.Font.Style:= [fsBold];
       Rappid.Text := Ver +'  '+Raid;
     end;
    Finally
      ReleaseDC(Handle, DC);
      Bitmap.Free;
    End;
  end
  else
  begin
    MyPage := frxReport1.FindObject('Page' + IntToStr(i)) as TfrxPage;
    MyPage.Visible := False;
  end;


if Fskaparapport = True then
begin
  Fskaparapport := False;
  frxReport1.PrepareReport;
  if FEpost = False then
    frxReport1.ShowPreparedReport;
  Screen.Cursor := crDefault;
end;
PageControlKalkyl.ActivePageIndex := p;

 except
  on E: Exception do
  ShowMessage(E.Message);
 end;

 end;

1 ответ

Решение

Так как вы используете TADOTableЯ подозреваю, что ваша таблица настроена на асинхронную работу.

Это можно сделать через property ExecuteOptions: TExecuteOptions;

Конечно, если вы установите ExecuteOptions := [];Ваши данные должны загружаться синхронно, но с неприятным побочным эффектом блокировки вашего интерфейса.

Опция 'friendlier' - перехватывать событие OnFetchComplete, которое будет объявлено следующим образом: procedure (DataSet: TCustomADODataSet; const Error: Error; var EventStatus: TEventStatus) of object;

Точная специфика требует больше информации о том, что именно вы пытаетесь достичь. Вы могли бы:

  • Вызовите свой метод отчета напрямую из OnFetchComplete обработчик.
  • Используйте ваш обработчик, чтобы включить опцию меню / кнопку / действие, которое отключено во время загрузки данных.
  • Используйте объект синхронизации (например, TSimpleEvent) и сигнализировать о событии внутри OnFetchComplete обработчик. Тогда другой код может просто вызвать WaitFor код блокировки метода, пока событие не будет сигнализировано.
Другие вопросы по тегам