It's written on request of our dear friend SKAN.
It was become possible due to the ingenious work by JGR, callback.dll, which is absolutely needed in the script.
Many thanks to him.
PS. I used DebugView here to display the percentage.
And, please keep in mind that this is only a test version, so there may be problems. Then, please inform me.
RegisterCallback version:
sUrl := "http://www.autohotkey.com/download/AutoHotkeyInstall.exe" sFile := A_Temp . "\AutoHotkeyInstall.exe" Progress, % "M W" . A_ScreenWidth//2, 0, 0 of 0 VarSetCapacity(vt, 4*11), nParam = 31132253353 Loop, Parse, nParam NumPut(RegisterCallback("DownloadProgress", "Fast", A_LoopField, A_Index-1), vt, 4*(A_Index-1)) DllCall("urlmon\URLDownloadToFileA", "Uint", 0, "str", sUrl, "str", sFile, "Uint", 0, "UintP", &vt) DownloadProgress(pthis, nProgress = 0, nProgressMax = 0, nStatusCode = 0, pStatusText = 0) { If A_EventInfo = 6 Progress, % p := 100 * nProgress//nProgressMax, %p%, % nProgress . " of " . nProgressMax Return 0 }callback.dll version:
sUrl := "http://download.sysinternals.com/Files/DebugView.zip" sFile := "C:\DebugView.zip" DetectHiddenWindows, On Process, Exist hAHK := WinExist("ahk_pid " . ErrorLevel) OnMessage(WM_AHK_Callback := DllCall("RegisterWindowMessage", "str", "WM_AHK_Callback"), "WM_AHK_Callback") VarSetCapacity(vt, 4*11), hModule := DllCall("LoadLibrary", "str", "callback"), nParams = 31132253353 Loop, Parse, nParams EncodeInteger(&vt + 4*(A_Index-1), hCallback%A_Index% := DllCall("callback\callbackit", "Uint", A_LoopField, "Uint", hAHK, "Uint", WM_AHK_Callback, "Uint", A_Index-1)) MsgBox, % DllCall("urlmon\URLDownloadToFileA", "Uint", 0, "str", sUrl, "str", sFile, "Uint", 0x10, "UintP", &vt) . "|" . ErrorLevel . "|" . A_LastError Loop, 11 DllCall("GlobalFree", "Uint", hCallback%A_Index%) DllCall("FreeLibrary", "Uint", hModule) ExitApp WM_AHK_Callback(wParam, lParam) { OutputDebug, % wParam <> 6 ? wParam : DecodeInteger(lParam+4)/DecodeInteger(lParam+8) * 100 Return 0 } DecodeInteger(ref, nSize = 4) { DllCall("RtlMoveMemory", "int64P", val, "Uint", ref, "Uint", nSize) Return val } EncodeInteger(ref, val = 0, nSize = 4) { DllCall("RtlMoveMemory", "Uint", ref, "int64P", val, "Uint", nSize) }