Recent

Author Topic: Progress Bar Fails with too high of a Max  (Read 8126 times)

Tony Stone

  • Full Member
  • ***
  • Posts: 219
Progress Bar Fails with too high of a Max
« on: July 11, 2021, 07:59:12 am »
I have a progressbar I am using to indicate file manipulation progress.

I try to set the total to the bytes of all files to be processed.  Once i set the max over 2.xbillion the progressbar wont display anything...

I have tried doing some things like dividing the total bytes to a smaller number.... my problem here is if the user is only processing a thousand bytes or so i end up with negative numbers.

I know there is a simple solution... can someone just give me a couple ideas how to handle this.  I am at a loss right now...

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Progress Bar Fails with too high of a Max
« Reply #1 on: July 11, 2021, 10:30:33 am »
The problem is that the property is a signed 32bit Integer so it maxs out at about two "megas" (2.147.483.647).

What is normally done in those cases is to set Max to 100 and calculate Position as the percentage of file(s) completed, i.e.
Code: Pascal  [Select][+][-]
  1. Position := (CurrentByteCount * 100) div TotalFilesSize;
« Last Edit: July 11, 2021, 10:32:09 am by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: Progress Bar Fails with too high of a Max
« Reply #2 on: July 11, 2021, 10:39:18 am »
It still could be that the byte-sum is larger than the 2 "megas". In this case declare the byte sum as DWord (goes up to 4 "megas") or even better, as Int64.

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: Progress Bar Fails with too high of a Max
« Reply #3 on: July 11, 2021, 11:01:32 am »
Or QWord...

Normally I just have Min and Max set to 0 and 100, so Position will be the percentage of the task completed (as suggested above).

Notice that, on Windows, the progressbar does not immediately "grow" to the position you set it to: Windows animates it for you.
And setting Position to Max in common use cases (e.g. repeatedly showing the progres oof a file copy) won't show the progressbar ever reaching Max.

As so many have done, I wrote my own custom progressbar.
It does not have a Min or Max nor Position. It only has Percentage as a way of setting the value.
This way it is clear from the start what it is showing and that it is the responsibility of the programmer to calculate the percentage always (no need to adjust Max value all the time).
(And, of course it immediately shows the value you set it to, no interference of Windows.)

Bart

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Progress Bar Fails with too high of a Max
« Reply #4 on: July 11, 2021, 11:20:20 am »
It still could be that the byte-sum is larger than the 2 "megas". In this case declare the byte sum as DWord (goes up to 4 "megas") or even better, as Int64.

Would that really help? TProgressBar.Max is declared as Integer which, according to the docs, makes it equivalent to LongInt (in ObjFPC and Delphi modes) so whatever type you use for the total it will have to be converted back down to signed 32 bit. Or am I wrong? :-\

Never mind; guess you both meant for calculating the percentage ... I'm still half asleep :-[
« Last Edit: July 11, 2021, 11:22:55 am by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: Progress Bar Fails with too high of a Max
« Reply #5 on: July 11, 2021, 11:28:32 am »
I'm not talking of the progressbar. He wants to process a series of files and show the progress. The first thing to do is to determine the sum of all bytes - this is the 100% value. And when there are many files, and large files - the total of all bytes easiyl can be larger than 2GB

Tony Stone

  • Full Member
  • ***
  • Posts: 219
Re: Progress Bar Fails with too high of a Max
« Reply #6 on: July 11, 2021, 02:28:17 pm »
I'm not talking of the progressbar. He wants to process a series of files and show the progress. The first thing to do is to determine the sum of all bytes - this is the 100% value. And when there are many files, and large files - the total of all bytes easiyl can be larger than 2GB

This is exactly the issue I was having... Even when imade a 100% value
  I was getting very tired last night so maybe a fresh look later tonight and I will be kicking myself.  I just keep thinking there is an extremely simple solution that I overlooked.  I mean I actually understand what I need to do but nothing was working.  Tonight I will report my solution back. 

ASerge

  • Hero Member
  • *****
  • Posts: 2249
Re: Progress Bar Fails with too high of a Max
« Reply #7 on: July 11, 2021, 11:01:51 pm »
Just call that during update cycles.
And it is better to put the update procedure in a timer, for example, with an interval of 300 ms. Then it will be fast enough for users, and rare enough for a computer to do something else. In addition, then the update speed will depend not on the size, but on the speed of the computer, and with a large load, it will simply be postponed.

Tony Stone

  • Full Member
  • ***
  • Posts: 219
Re: Progress Bar Fails with too high of a Max
« Reply #8 on: July 11, 2021, 11:18:04 pm »
Just call that during update cycles.
And it is better to put the update procedure in a timer, for example, with an interval of 300 ms. Then it will be fast enough for users, and rare enough for a computer to do something else. In addition, then the update speed will depend not on the size, but on the speed of the computer, and with a large load, it will simply be postponed.

What I currently do is call my current procedure(the non functioning one) from athe loop that is processing the files.  It calls the progress at routine every 3 seconds.... I just use getticjcount64 thought the loop and when the tick count is 3000ms larger that the last time it fired it will fire again.  But a timer would be good too.  Unfortunately I hurt my back this morning and haven't had time or ability to sit long enough to go and tackle this again.

I appreciate all of you guys!  The people on this forum have always been very helpful!  Lazarus is the absolute best... In big part because of this community!

Tony Stone

  • Full Member
  • ***
  • Posts: 219
Re: Progress Bar Fails with too high of a Max
« Reply #9 on: July 12, 2021, 03:32:33 am »
Ok so the reason I was struggling all along was pretty simple!  The suggestions some users had were basically things I have tried(in my own way).  But still ended up with issues.

So here was my problem.  The files are processed in a seperate thread.  I am sending the file size information as a message to the main thread in a long string containing other information!  When I was converting my strings to an integer is where the issue was!  I was using StrToInt.  The solution was simply StrToInt64!  :-[

Hope this thread on the forum is helpful to someone in the future!

alpine

  • Hero Member
  • *****
  • Posts: 1067
Re: Progress Bar Fails with too high of a Max
« Reply #10 on: July 12, 2021, 11:19:48 am »
Ok so the reason I was struggling all along was pretty simple!  The suggestions some users had were basically things I have tried(in my own way).  But still ended up with issues.

So here was my problem.  The files are processed in a seperate thread.  I am sending the file size information as a message to the main thread in a long string containing other information!  When I was converting my strings to an integer is where the issue was!  I was using StrToInt.  The solution was simply StrToInt64!  :-[

Hope this thread on the forum is helpful to someone in the future!
At that point I'm little bit curious to see your implementation, what do you mean with "sending a message" and the reason it is a string message? PostMessage(hwnd,...), SendMessage(hwnd,...)?
I think the event mechanism is entirely sufficient for the job as in my latest post in https://forum.lazarus.freepascal.org/index.php/topic,55307.msg411396.html#msg411396 and no need for GetTickCount64, TTimer and so.
BTW, your insistence for doing it "your own way"  is very much praised, but as long you call for experts opinion, let's get it done in "your right way" ;)

Edit: My latest post was actually: https://forum.lazarus.freepascal.org/index.php/topic,55307.msg411435.html#msg411435
« Last Edit: July 12, 2021, 11:23:59 am by y.ivanov »
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

Tony Stone

  • Full Member
  • ***
  • Posts: 219
Re: Progress Bar Fails with too high of a Max
« Reply #11 on: July 12, 2021, 10:11:16 pm »
I actually ended up using almost exactly the implementation jamie suggested.  And it does work great.   So the reason I send it from the file parsing thread as a string is because I had the thread sending a string, including data other than just the file size... I am using the wcthread component for multi threading which I happen to like.  It makes threading a little bit simpler... at least for an amateur like myself. lol  So I do already understand there is other ways to share this data among threads, and that is by implementing critical sections.  I honestly have yet to put the effort into understanding it all so far.  So currently using the message procedures of the components seems to be the safest way for me to pass information.  It is actually quite clean(IMO) and I don't think I am being too "hacky" but I have been leaving todo comments throughout my code to find the 'proper' ways to implement certain things.   Your feedback is appreciated... even thought you made me feel like a butcher with your questions! haha. just kidding.

Ok so the reason I was struggling all along was pretty simple!  The suggestions some users had were basically things I have tried(in my own way).  But still ended up with issues.

So here was my problem.  The files are processed in a seperate thread.  I am sending the file size information as a message to the main thread in a long string containing other information!  When I was converting my strings to an integer is where the issue was!  I was using StrToInt.  The solution was simply StrToInt64!  :-[

Hope this thread on the forum is helpful to someone in the future!
At that point I'm little bit curious to see your implementation, what do you mean with "sending a message" and the reason it is a string message? PostMessage(hwnd,...), SendMessage(hwnd,...)?
I think the event mechanism is entirely sufficient for the job as in my latest post in https://forum.lazarus.freepascal.org/index.php/topic,55307.msg411396.html#msg411396 and no need for GetTickCount64, TTimer and so.
BTW, your insistence for doing it "your own way"  is very much praised, but as long you call for experts opinion, let's get it done in "your right way" ;)

Edit: My latest post was actually: https://forum.lazarus.freepascal.org/index.php/topic,55307.msg411435.html#msg411435

Tony Stone

  • Full Member
  • ***
  • Posts: 219
Re: Progress Bar Fails with too high of a Max
« Reply #12 on: July 12, 2021, 10:15:18 pm »


Edit: My latest post was actually: https://forum.lazarus.freepascal.org/index.php/topic,55307.msg411435.html#msg411435

Oh man!  I completely missed your reply in my other topic!  I will look at your example later tonight for sure!  Thank you.  A majority of my implementation is now working but I am still always open to looking at the right way to do things.  That is me just assuming I am not always doing things right. ::)

 

TinyPortal © 2005-2018