@Progi1984
Certes, mais "#PBM_GETRANGE" n'est pas définie dans PureBasic. Comment connaître sa valeur ?
[EDIT]: Je crois avoir trouvé et ça a l'air de marcher:
Code : Tout sélectionner
#PBM_GETRANGE = #WM_USER + 7
lo = SendMessage_(hwnd,#PBM_GETRANGE,#TRUE,0)
hi = SendMessage_(hwnd,#PBM_GETRANGE,#FALSE,0)
Sinon, voici une version prenant en compte les indications de Dobro.
Ce qui est marrant, c'est que si vous lancez en parallèle une copie d'un gros fichier dans l'explorateur (ou n'importe quoi qui affiche une barre de progression), le programme le prend en compte et en bidouille l'affichage. Normal, me direz-vous, mais ça fait quand même plaisir à voir...
[EDIT 18h40]: Petite modif' de l'affichage + effet "feu d'artifice" rudimentaire
Code : Tout sélectionner
#PBM_GETRANGE = #WM_USER + 7
#PBM_GETSTEP = $040D ; Vista
EnableExplicit
Structure addedWin_struct
hParentWnd.l
hProgressWnd.l
hAddedWnd.l
lo.i
hi.i
EndStructure
Global NewList addedWin.addedWin_struct()
Structure sparkle_struct
hWnd.l
x.f
y.f
oldX.i
oldY.i
xd.f
yd.f
maxY.i
EndStructure
Global NewList sparkle.sparkle_struct()
Procedure redrawProgressBar(hParentWnd.l,hwnd.l)
Protected rc.RECT,rcinv.RECT
Protected chaine.s
Protected oldrange.q,lo.l,hi.l,valeur.l
Protected posX.f
Protected found.b
Protected wndInfo.WINDOWINFO, refx.i, refy.i
Protected hDC.l,x.i,y.i,maxy.i
GetWindowInfo_(hParentWnd,wndInfo)
refx = wndInfo\rcClient\left
refy = wndInfo\rcClient\top
maxy = wndInfo\rcWindow\bottom - refy
; récupérer les coordonnées de la barre
GetWindowRect_(hwnd,@rc)
valeur = SendMessage_(hwnd,#PBM_DELTAPOS,0,0)
chaine=Space(255)
; GetWindowText_(hParentWnd,@chaine,255)
; Debug " Progress bar trouvée : "
; Debug " Fenêtre : " + chaine
; Debug " Position: " + Str(rc\left)+","+Str(rc\top)
; Debug " Taille : " + Str(rc\right - rc\left)+","+Str(rc\bottom - rc\top)
; Debug " Valeur : " + Str(valeur)
; Est-ce que l'on redessine déjà cette barre ?
ForEach addedWin()
If addedWin()\hProgressWnd = hwnd
found = #True
Break
EndIf
Next addedWin()
; Si ce n'est pas le cas, on le fait
If found = #False
AddElement(addedWin())
addedWin()\hParentWnd = hParentWnd
addedWin()\hProgressWnd = hwnd
addedWin()\lo = 0
addedWin()\hi = 100
;addedWin()\hAddedWnd = CreateWindowEx_(0,"button","X",#WS_CHILD|#WS_VISIBLE,rc\left- refX + Int(posX),rc\top - refY - 3,20,(rc\bottom - rc\top) + 6,hParentWnd,0,GetModuleHandle_(0),0)
EndIf
; Valeurs minimum/maximum de la barre (ce n'est pas forcément 0 / 100)
addedWin()\lo = SendMessage_(hwnd,#PBM_GETRANGE,#True,0)
addedWin()\hi = SendMessage_(hwnd,#PBM_GETRANGE,#False,0)
lo = addedWin()\lo
hi = addedWin()\hi
posX = ((valeur - lo) / (hi - lo)) ; Pourcentage de progression
posX * (rc\right - rc\left) ; Avancement dans la barre (en pixels)
; Repositionnement
;SetWindowPos_(addedWin()\hAddedWnd,addedWin()\hProgressWnd,rc\left - refX + Int(posX),rc\top - refY - 3,0,0,#SWP_NOSIZE|#SWP_FRAMECHANGED)
hDC = GetDC_( hParentWnd ) ; DC de la fenêtre.
For y=1 To (rc\bottom - rc\top) - 2
For x=1 To Int(posX)
SetPixel_(hDc,(rc\left - refx) + x, (rc\top - refy) + y,RGB((x * 3 + y * 7) % 255,(x * 11 - y * 3) % 255,(x * y) % 255) )
Next x
Next y
Rectangle_(hDc,(rc\left - refx) + Int(posX) + 1, (rc\top - refy) + 1,rc\right - refx - 1,rc\bottom - refy - 1)
If (valeur - lo) > 0 And Random(10000) > 6600
AddElement(sparkle())
sparkle()\hWnd = hParentWnd
sparkle()\x = (rc\left) + Int(posX)
sparkle()\y = (rc\top ) + (rc\bottom - rc\top)/2
sparkle()\xd = (20 - Random(40)) / 10.0
sparkle()\yd = Random(20) / -10.0
sparkle()\maxY = maxy
sparkle()\oldX = Int(sparkle()\x)
sparkle()\oldY = Int(sparkle()\y)
EndIf
ForEach sparkle()
If sparkle()\hWnd = hParentWnd
sparkle()\x + sparkle()\xd
sparkle()\y + sparkle()\yd
If sparkle()\oldX <> Int(sparkle()\x) Or sparkle()\oldY <> Int(sparkle()\y)
If sparkle()\y > sparkle()\maxY + refy
DeleteElement(sparkle())
Else
sparkle()\oldX = Int(sparkle()\x)
sparkle()\oldY = Int(sparkle()\y)
rcinv\left = sparkle()\oldX - refx
rcinv\right = sparkle()\oldX - refx + 3
rcinv\top = sparkle()\oldY - refy
rcinv\bottom = sparkle()\oldY - refy + 3
Rectangle_(hDC,rcinv\left,rcinv\top,rcinv\right,rcinv\bottom)
InvalidateRect_(sparkle()\hWnd,@rcinv,1)
sparkle()\yd + 0.1
EndIf
EndIf
EndIf
Next sparkle()
ReleaseDC_(hParentWnd,hDC)
EndProcedure
; Enumère les fenêtres filles
Procedure.l EnumChildWindowProc(hwnd.l, hParentWnd.l)
Protected classe.s
; Tester si on se trouve sur une progress bar
If GetParent_(hWnd) = hParentWnd
classe=Space(100)
GetClassName_(hwnd, @classe, 100)
If classe = "msctls_progress32"
; Si oui, on la redessine
redrawProgressBar(hParentWnd,hwnd)
EndIf
ProcedureReturn 1
EndIf
EndProcedure
; Parcourt toutes les fenêtre visibles
Procedure listWindows()
Protected hwnd.l
hWnd = FindWindow_( 0, 0 )
While hWnd <> 0
If GetWindowLong_(hWnd, #GWL_STYLE) & #WS_VISIBLE = #WS_VISIBLE
If GetWindowLong_(hWnd, #GWL_EXSTYLE) & #WS_EX_TOOLWINDOW <> #WS_EX_TOOLWINDOW
EnumChildWindows_(hWnd, @EnumChildWindowProc(),hWnd)
EndIf
EndIf
hWnd = GetWindow_(hWnd, #GW_HWNDNEXT)
Wend
EndProcedure
;- ************* Main *************
; Créer une fenêtre avec une barre de progression, pour le test
DisableExplicit
OpenWindow(0,0,0,320,200,"test progress bar");,#PB_Window_Invisible|#PB_Window_NoGadgets)
; Dessiner une barre de progression aux caractéristiques aléatoires
RandomSeed(ElapsedMilliseconds())
minvalue.i = Random(50)
maxvalue.i = minvalue + 50 + Random(200)
ProgressBarGadget(1,30,60,150 + Random(150),50,minvalue,maxvalue)
targetPos.i = 0
currentPos.f = 0
Repeat
While WindowEvent()
Delay(2)
Wend
; je fais bouger la progress bar
If Int(currentPos) = targetPos
targetPos = minvalue + Random(maxvalue - minvalue)
Else
If currentPos < targetPos
currentPos + 0.1
Else
currentPos - 0.1
EndIf
EndIf
SetGadgetState(1,Int(currentPos))
; Et là, je pars à sa recherche dans les fenêtres de Windows pour la trouver et la redessiner
listWindows()
; Nettoyage de la liste des fenêtres ajoutées
ForEach addedWin()
If IsWindow_(addedWin()\hProgressWnd) = #False
; Pas forcément nécessaire (les fenêtre filles sont détruites avec la mère)
If IsWindow_(addedWin()\hAddedWnd) = #True
DestroyWindow_(addedWin()\hAddedWnd)
EndIf
DeleteElement(addedWin())
EndIf
Next addedWin()
Delay(25)
Until quit = 1