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
код блокировки метода, пока событие не будет сигнализировано.