CGDevTools Forum

Welcome to the Official CGDevTools Support Community Forums.

SaveImage followed by LoadFromFile

by zsleo » 15 Dec 2016 02:36

Wish I could do this using streams... all help and suggestions will be appreciated!

Code: Select all
procedure TIWForm3.qryPagesBeforePost(DataSet: TDataSet);
var
  lv_FN:string;
begin
  if qryPages.State = dsInsert then
  begin
    qry1.Close;
    qry1.SQL.Text := 'Select isnull(max(PageNum) + 1, 1) from Pages where BookRecID = ' + qryBooks.FieldByName('RecID').AsString;
    qry1.Open;
    qryPages.FieldByName('PageNum').AsInteger := qry1.Fields[0].AsInteger;
    qry1.Close;
  end;
  if qryPages.FieldByName('PageTitle').AsString = '' then
    qryPages.FieldByName('PageTitle').AsString := 'Page ' + qryPages.FieldByName('PageNum').AsString;

  iwcgjqwpnt1.ExportToImage(JQwPaintImg); {iwcgjqwpnt1 is a TIWCGJQWPaint and JQwPaintImg is a TIWCGJQImage}
  lv_FN := 'wwwroot/tmp/' + CGGenAutoID + '.jpg';
  JQwPaintImg.SaveImage(gv_FN);
  qryPagesPageImg.LoadFromFile(gv_FN);

end;


Here is my problem. The last two lines have very "unacceptable" behaviour.
After calling "JQwPaintImg.SaveImage(gv_FN);" I expect the file will be saved before "qryPagesPageImg.LoadFromFile(gv_FN);" is called but it is not.

I have tried many different methodologies including multiple timers but without success. Is there any way I can force a flush and close of the file to disk before the load to the database record?

The file does get saved BUT only after the procedure exited/completed.

TIA
zsleo
 
Posts: 776
Joined: 03 Feb 2013 03:33

by ScottWGast » 15 Dec 2016 16:41

The first thing that I would try would be to run a loop that sleeps for a second and then checks for the existence of the file. Exit after n loops or file found or whatever other criteria you deem required.
ScottWGast
 
Posts: 875
Joined: 23 May 2012 11:02

by Alexander Bulei » 15 Dec 2016 16:46

Hi zsleo,

In fact, you can't execute LoadFromFile soon after the SaveImage.
SaveImage can have delay (depend on connection / data transfare)...

I will implement some event (e.g: OnAfterSave), where you will able do that...

Best Regards.
Group: Developers | Support Team

  • info [at] cgdevtools.com - General information
  • sales [at] cgdevtools.com - Sales department
  • support [at] cgdevtools.com - Product and Technical Support
User avatar
Alexander Bulei
Site Admin
 
Posts: 3635
Joined: 15 May 2012 08:52
Location: Mealhada, Portugal

by zsleo » 15 Dec 2016 18:06

Thanks Alexander. I look forward to the release.

Scott, I do actually have it working with an iw timer triggered in the after lost event. The problem with this solution is that the time interval on some computers was approaching 1000 msec before the file save would complete. Two issues with this
- grid "happy clickers" could intervene and disrupt the DB update
- the time interval needs to be adjusted by experimenting for every server the app is deployed on.
zsleo
 
Posts: 776
Joined: 03 Feb 2013 03:33

by ScottWGast » 15 Dec 2016 18:08

Clearly .OnAfterSave is the way to go...
ScottWGast
 
Posts: 875
Joined: 23 May 2012 11:02

by ScottWGast » 15 Dec 2016 18:31

I've thwarted click-happy users by overlaying a transparent image over the entire screen immediately after the user clicks the button and then hide said overlay once the file has been saved. I even added an OnAsyncClick event to pop up a "Jeeze! Stop Clicking!" message if the user clicks the transparent image.

Since SaveImage happens on the server, I cannot imagine that it takes very long to save the file.

If you want all processing to stop until the file is saved and available for loading, then something like:
(please regard as psudo-code)

Code: Select all
function WaitUntilFileExists(Filename: String; MaxWaitSeconds: Integer): Boolean;
var
  boolFileExists: Boolean;
  iMyLoopCount, iMaxLoopCount: Integer;
begin
  boolFileExists := False;
  iMyLoopCount := 0;
  iMaxLoopCount := MaxWaitSeconds;
  while not FileExists(Filename) and (iMyLoopCount < iMaxLoopCount) do
  begin
    Inc(iMyLoopCount);
    Sleep(1000);  // pause for 1 second.
  end;
  Result := FileExists(Filename);
end;


If you don't want to halt all operations for the user, then using .OnAfterSave or creating a Thread is the way to go.

HTH,
Scott
ScottWGast
 
Posts: 875
Joined: 23 May 2012 11:02

by zsleo » 15 Dec 2016 19:42

Scott, thanks. I will look at implementing your suggestion.

Alexander,

While you are looking at this issue may I request another fix. The TIWCGJQWPaint menu does not display correctly.

The design time setting I have is in Image 1.

This results in the following 2 row horizontal menu - Image 2

When I click the fonts menu item this is what is displayed - Image 3

Two menu popups is fine but I would like to see everything display in one horizontal row.

2016-12-16 05_16_03-02.png

2016-12-16 05_15_42-01.png

2016-12-16 05_17_42-00.png



TIA
You do not have the required permissions to view the files attached to this post.
zsleo
 
Posts: 776
Joined: 03 Feb 2013 03:33

by Alexander Bulei » 16 Dec 2016 10:25

Hi zsleo,

It's NOT a bug or issue!

Best Regards.
Group: Developers | Support Team

  • info [at] cgdevtools.com - General information
  • sales [at] cgdevtools.com - Sales department
  • support [at] cgdevtools.com - Product and Technical Support
User avatar
Alexander Bulei
Site Admin
 
Posts: 3635
Joined: 15 May 2012 08:52
Location: Mealhada, Portugal

by Alexander Bulei » 16 Dec 2016 15:24

Hello,

Implemented new event OnAfterSave in next beta build.

Best Regards.
Group: Developers | Support Team

  • info [at] cgdevtools.com - General information
  • sales [at] cgdevtools.com - Sales department
  • support [at] cgdevtools.com - Product and Technical Support
User avatar
Alexander Bulei
Site Admin
 
Posts: 3635
Joined: 15 May 2012 08:52
Location: Mealhada, Portugal

by ScottWGast » 16 Dec 2016 16:46

thank you for .OnAfterSave event! :)
ScottWGast
 
Posts: 875
Joined: 23 May 2012 11:02

Next

Return to JQWPaint

cron

Who is online

Users browsing this forum: No registered users and 0 guests

Contact Us.