Windows: use the shell progress dialog in your apps.

Share your advanced PureBasic knowledge/code with the community.
El_Choni
TailBite Expert
TailBite Expert
Posts: 1007
Joined: Fri Apr 25, 2003 6:09 pm
Location: Spain

Windows: use the shell progress dialog in your apps.

Post by El_Choni »

Code updated for 5.20+

Hi,

The subject says it all:

Code: Select all

; Tested on Windows XP Pro SP1

Procedure Ansi2Uni(st$)
  CompilerIf #PB_Compiler_Unicode ; Already in correct format, just copy it
    blen = (Len(st$)+1)*SizeOf(Character)
    wbuf = AllocateMemory(blen)
    CopyMemory(@st$, wbuf, blen)
  CompilerElse
    blen = (Len(st$)*2)+2
    wbuf = AllocateMemory(blen)
    MultiByteToWideChar_(#CP_ACP, 0, st$, -1, wbuf, blen)
  CompilerEndIf
  ProcedureReturn wbuf
EndProcedure

#CLSCTX_INPROC_SERVER = 1

#PROGDLG_NORMAL = 0
#PROGDLG_AUTOTIME = 2

#PDTIMER_RESET = 1

#IDA_COPY_ANIMATION = 160 ; AVI file resource ID (I use an arbitrary constant name)
; This one is from shell32.dll.
; You can use any AVI file resource as long as it's
; uncompressed or RLE8 compressed, silent and
; smaller or equal to 272 by 60 pixels in size.

ProgressLimit = 1000

CoInitialize_(0)
hr = CoCreateInstance_(?CLSID_ProgressDialog, #Null, #CLSCTX_INPROC_SERVER, ?IID_IProgressDialog, @ppv.IProgressDialog)
If hr=#S_OK
  *Title = Ansi2Uni("System progress dialog box")
  ppv\SetTitle(*Title)
  hShell = OpenLibrary(0, "shell32.dll")
  If hShell
    ppv\SetAnimation(hShell, #IDA_COPY_ANIMATION)
  EndIf
  *Cancel = Ansi2Uni("Cancel")
  ppv\SetCancelMsg(*Cancel, 0)
  *Line1 = Ansi2Uni("System progress dialog test in PureBasic")
  ppv\SetLine(1, *Line1, #True, 0)
  ppv\StartProgressDialog(#Null, 0, #PROGDLG_AUTOTIME|#PROGDLG_NORMAL, 0)
  ppv\Timer(#PDTIMER_RESET, 0)
  Repeat
    If ppv\HasUserCancelled()
      MessageRequester("Messsage", "Progress cancelled")
      Break
    Else
      ppv\SetProgress(dwCompleted, ProgressLimit)
      If dwCompleted>=ProgressLimit
        MessageRequester("Messsage", "Progress completed")
        Break
      Else
        dwCompleted+1
        *Line2 = Ansi2Uni("We are at progress point number "+Str(dwCompleted))
        ppv\SetLine(2, *Line2, #True, 0)
        FreeMemory(*Line2)
      EndIf
    EndIf
    Delay(100)
  ForEver
  ppv\StopProgressDialog()
  ppv\Release()
  FreeMemory(*Title)
  FreeMemory(*Cancel)
  FreeMemory(*Line1)
  If hShell:CloseLibrary(0):EndIf
Else
  Debug Hex(hr)
EndIf
CoUninitialize_()

DataSection
  CLSID_ProgressDialog:
  Data.l $f8383852
  Data.w $fcd3, $11d1
  Data.b $a6, $b9, 0, $60, $97, $df, $5b, $d4
  IID_IProgressDialog:
  Data.l $ebbc7c04
  Data.w $315e, $11d2
  Data.b $b6, $2f, 0, $60, $97, $df, $5b, $d4
EndDataSection
Regards,
Last edited by El_Choni on Wed Feb 02, 2005 10:56 am, edited 1 time in total.
El_Choni
User avatar
GeoTrail
Addict
Addict
Posts: 2794
Joined: Fri Feb 13, 2004 12:45 am
Location: Bergen, Norway
Contact:

Post by GeoTrail »

Abit over my head, but the result is really cool.
Great work El_Choni :)
I Stepped On A Cornflake!!! Now I'm A Cereal Killer!
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Post by TerryHough »

Thanks El_Choni, I have wondered how to do this.

Two questions.

1) How to make the progress bar smooth (like PB flag)

2) How is the time determined. Sorry, I don't recogninze that in the code.


Terry
User avatar
Le Soldat Inconnu
Enthusiast
Enthusiast
Posts: 306
Joined: Wed Jul 09, 2003 11:33 am
Location: France

Post by Le Soldat Inconnu »

very nice :D
LSI
eriansa
Enthusiast
Enthusiast
Posts: 277
Joined: Wed Mar 17, 2004 12:31 am
Contact:

Post by eriansa »

very handy! thanks.
User avatar
NoahPhense
Addict
Addict
Posts: 1999
Joined: Thu Oct 16, 2003 8:30 pm
Location: North Florida

Re: Windows: use the shell progress dialog in your apps.

Post by NoahPhense »

That's purty.. nice work

- np
El_Choni
TailBite Expert
TailBite Expert
Posts: 1007
Joined: Fri Apr 25, 2003 6:09 pm
Location: Spain

Post by El_Choni »

TerryHough wrote: Two questions.
1) How to make the progress bar smooth (like PB flag)
2) How is the time determined. Sorry, I don't recogninze that in the code.
1) I think you can't, this is a system-predefined dialog box, good to avoid doing the job yourself. If you want to modify it, better do your own dialog.
2) Windows estimates the remaining time. The more 'progress intermediate points' you use, the more accurate will be the result.

I've edited the snippet, now it uses 1000 instead of 100, and Windows estimates the remaining time much better.

You can change that value here:

Code: Select all

ProgressLimit = 1000
Anyway, in real life you would probably put the update stuff in a timer proc while you're, for example, copying a file. The timer proc would check for the amount of bytes copied (using a critical section, for example), and update the progress dialog according to that.

Regards,
El_Choni
sverson
Enthusiast
Enthusiast
Posts: 286
Joined: Sun Jul 04, 2004 12:15 pm
Location: Germany

Post by sverson »

Great work! :wink:

Tested on WIN NT4 SP6 - running fine!
User avatar
Le Soldat Inconnu
Enthusiast
Enthusiast
Posts: 306
Joined: Wed Jul 09, 2003 11:33 am
Location: France

Post by Le Soldat Inconnu »

Time estimation is only calculate with the progresslimit ??

when I change the delay, I always obtain the same time estimation.

ProgressLimit is the time in second * 10

example :
ProgressLimit = 10 * 60 gives 60s time remaining
ProgressLimit = 10 * 60 * 5 gives 5min time remaining
LSI
Post Reply