├── Demo ├── Binary │ └── HttpDownloadDemo.exe ├── HttpDownloadDemo.dpr ├── HttpDownloadDemo.dproj ├── HttpDownloadDemo.dproj.local ├── HttpDownloadDemo.identcache ├── HttpDownloadDemo.res ├── HttpDownloadDemo.skincfg ├── HttpDownloadDemo_Icon.ico ├── HttpDownloadDemo_Icon1.ico ├── MainForm.fmx ├── MainForm.pas ├── MultiCircularProgress.pas └── __history │ └── HttpDownloadDemo.dpr.~1~ ├── DemoCapture.png ├── LICENSE ├── Package ├── HttpParallelDownloader.dpk ├── HttpParallelDownloader.dproj ├── HttpParallelDownloader.dproj.local ├── HttpParallelDownloader.identcache ├── HttpParallelDownloader.res ├── ThredingFileDownloader.pas └── __history │ ├── HttpParallelDownloader.dpk.~1~ │ ├── ThredingFileDownloader.pas.~1~ │ └── ThredingFileDownloader.pas.~2~ ├── README.md └── ThredingFileDownloader.pas /Demo/Binary/HttpDownloadDemo.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamel78/Multi-Threading-Advanced-Http-Downloader/318cbd18f6515799eb7c33fa8f0f22d3bd5dd282/Demo/Binary/HttpDownloadDemo.exe -------------------------------------------------------------------------------- /Demo/HttpDownloadDemo.dpr: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------- 2 | 3 | // This software is Copyright (c) 2015 Embarcadero Technologies, Inc. 4 | // You may only use this software if you are an authorized licensee 5 | // of an Embarcadero developer tools product. 6 | // This software is considered a Redistributable as defined under 7 | // the software license agreement that comes with the Embarcadero Products 8 | // and is subject to that software license agreement. 9 | 10 | //--------------------------------------------------------------------------- 11 | 12 | program HttpDownloadDemo; 13 | 14 | uses 15 | System.StartUpCopy, 16 | FMX.Forms, 17 | MultiCircularProgress in 'MultiCircularProgress.pas', 18 | MainForm in 'MainForm.pas' {Form1}, 19 | ThredingFileDownloader in '..\ThredingFileDownloader.pas'; 20 | 21 | {$R *.res} 22 | 23 | begin 24 | Application.Initialize; 25 | Application.CreateForm(TForm1, Form1); 26 | Application.Run; 27 | end. 28 | -------------------------------------------------------------------------------- /Demo/HttpDownloadDemo.dproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | {C012BE5A-E320-4F64-B4B8-09CA88732176} 4 | 18.7 5 | FMX 6 | HttpDownloadDemo.dpr 7 | True 8 | Release 9 | Win32 10 | 5215 11 | Application 12 | 13 | 14 | true 15 | 16 | 17 | true 18 | Base 19 | true 20 | 21 | 22 | true 23 | Base 24 | true 25 | 26 | 27 | true 28 | Base 29 | true 30 | 31 | 32 | true 33 | Base 34 | true 35 | 36 | 37 | true 38 | Base 39 | true 40 | 41 | 42 | true 43 | Base 44 | true 45 | 46 | 47 | true 48 | Base 49 | true 50 | 51 | 52 | true 53 | Base 54 | true 55 | 56 | 57 | true 58 | Base 59 | true 60 | 61 | 62 | true 63 | Cfg_1 64 | true 65 | true 66 | 67 | 68 | true 69 | Cfg_1 70 | true 71 | true 72 | 73 | 74 | true 75 | Cfg_1 76 | true 77 | true 78 | 79 | 80 | true 81 | Cfg_1 82 | true 83 | true 84 | 85 | 86 | true 87 | Base 88 | true 89 | 90 | 91 | true 92 | Cfg_2 93 | true 94 | true 95 | 96 | 97 | System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) 98 | true 99 | true 100 | HttpDownloadDemo 101 | true 102 | true 103 | $(BDS)\bin\delphi_PROJECTICON.ico 104 | true 105 | true 106 | true 107 | $(BDS)\bin\delphi_PROJECTICNS.icns 108 | true 109 | true 110 | true 111 | .\$(Platform)\$(Config) 112 | .\$(Platform)\$(Config) 113 | false 114 | false 115 | false 116 | false 117 | false 118 | 119 | 120 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png 121 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png 122 | FireDACSqliteDriver;FireDACDSDriver;DBXSqliteDriver;fmx;IndySystem;tethering;DataSnapClient;DataSnapCommon;DBXInterBaseDriver;DataSnapProviderClient;DbxCommonDriver;dbxcds;fmxFireDAC;CustomIPTransport;dsnap;IndyIPServer;IndyCore;CloudService;IndyIPCommon;FireDACIBDriver;DataSnapFireDAC;FireDACDBXDriver;soapserver;dsnapxml;bindcompfmx;RESTBackendComponents;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;ibmonitor;xmlrtl;DataSnapNativeClient;ibxpress;IndyProtocols;FireDACCommonDriver;bindcompdbx;bindengine;soaprtl;emsclient;FireDAC;inet;soapmidas;RESTComponents;dbexpress;IndyIPClient;$(DCC_UsePackage) 123 | true 124 | $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png 125 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png 126 | $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png 127 | Debug 128 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png 129 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png 130 | android-support-v4.dex.jar;apk-expansion.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar 131 | package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=preferExternal;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=;apiKey= 132 | $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png 133 | $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png 134 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png 135 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png 136 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png 137 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png 138 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png 139 | 140 | 141 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x1136.png 142 | iPhoneAndiPad 143 | true 144 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_180x180.png 145 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_72x72.png 146 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png 147 | $(MSBuildProjectName) 148 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_50x50.png 149 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_114x114.png 150 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png 151 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png 152 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1242x2208.png 153 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x748.png 154 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png 155 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png 156 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_100x100.png 157 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png 158 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png 159 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png 160 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png 161 | $(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_29x29.png 162 | CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSCameraUsageDescription=The reason for accessing the camera;CFBundleShortVersionString=1.0.0;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSFaceIDUsageDescription=The reason for accessing the face id;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false 163 | fmxhrh;FireDACSqliteDriver;FireDACDSDriver;DBXSqliteDriver;fmx;IndySystem;tethering;DataSnapClient;DataSnapCommon;DBXInterBaseDriver;DataSnapProviderClient;DbxCommonDriver;dbxcds;fmxFireDAC;CustomIPTransport;dsnap;IndyIPServer;fmxase;IndyCore;CloudService;IndyIPCommon;FireDACIBDriver;DataSnapFireDAC;FireDACDBXDriver;soapserver;dsnapxml;bindcompfmx;RESTBackendComponents;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;ibmonitor;xmlrtl;DataSnapNativeClient;ibxpress;IndyProtocols;FireDACCommonDriver;bindcompdbx;bindengine;soaprtl;emsclient;FireDAC;inet;soapmidas;RESTComponents;dbexpress;IndyIPClient;$(DCC_UsePackage) 164 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_144x144.png 165 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png 166 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png 167 | Debug 168 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2208x1242.png 169 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1496.png 170 | $(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_58x58.png 171 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_320x480.png 172 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x960.png 173 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_87x87.png 174 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_57x57.png 175 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png 176 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2008.png 177 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_58x58.png 178 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_29x29.png 179 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_750x1334.png 180 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1004.png 181 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1125x2436.png 182 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2436x1125.png 183 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_120x120.png 184 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_828x1792.png 185 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1136x640.png 186 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1242x2688.png 187 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1334x750.png 188 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1792x828.png 189 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2688x1242.png 190 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_167x167.png 191 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1668x2224.png 192 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1668x2388.png 193 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_2048x2732.png 194 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2224x1668.png 195 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2388x1668.png 196 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2732x2048.png 197 | 198 | 199 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x1136.png 200 | iPhoneAndiPad 201 | true 202 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_180x180.png 203 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_72x72.png 204 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png 205 | $(MSBuildProjectName) 206 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_50x50.png 207 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_114x114.png 208 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png 209 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png 210 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1242x2208.png 211 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x748.png 212 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png 213 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png 214 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_100x100.png 215 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png 216 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png 217 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png 218 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png 219 | $(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_29x29.png 220 | CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSCameraUsageDescription=The reason for accessing the camera;CFBundleShortVersionString=1.0.0;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSFaceIDUsageDescription=The reason for accessing the face id;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false 221 | fmxhrh;FireDACSqliteDriver;FireDACDSDriver;DBXSqliteDriver;fmx;IndySystem;tethering;DataSnapClient;DataSnapCommon;DBXInterBaseDriver;DataSnapProviderClient;DbxCommonDriver;dbxcds;fmxFireDAC;CustomIPTransport;dsnap;IndyIPServer;fmxase;IndyCore;CloudService;IndyIPCommon;FireDACIBDriver;DataSnapFireDAC;FireDACDBXDriver;soapserver;dsnapxml;bindcompfmx;RESTBackendComponents;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;ibmonitor;xmlrtl;DataSnapNativeClient;ibxpress;IndyProtocols;FireDACCommonDriver;bindcompdbx;bindengine;soaprtl;emsclient;FireDAC;inet;soapmidas;RESTComponents;dbexpress;IndyIPClient;$(DCC_UsePackage) 222 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_144x144.png 223 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png 224 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png 225 | Debug 226 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2208x1242.png 227 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1496.png 228 | $(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_58x58.png 229 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_320x480.png 230 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x960.png 231 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_87x87.png 232 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_57x57.png 233 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png 234 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2008.png 235 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_58x58.png 236 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_29x29.png 237 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_750x1334.png 238 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1004.png 239 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1125x2436.png 240 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2436x1125.png 241 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_120x120.png 242 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_828x1792.png 243 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1136x640.png 244 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1242x2688.png 245 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1334x750.png 246 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1792x828.png 247 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2688x1242.png 248 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_167x167.png 249 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1668x2224.png 250 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1668x2388.png 251 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_2048x2732.png 252 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2224x1668.png 253 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2388x1668.png 254 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2732x2048.png 255 | 256 | 257 | true 258 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x1136.png 259 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_180x180.png 260 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_72x72.png 261 | iPhoneAndiPad 262 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_50x50.png 263 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png 264 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_114x114.png 265 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png 266 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png 267 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x748.png 268 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png 269 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png 270 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png 271 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1242x2208.png 272 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png 273 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_100x100.png 274 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png 275 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png 276 | fmxhrh;FireDACSqliteDriver;FireDACDSDriver;DBXSqliteDriver;fmx;IndySystem;tethering;DataSnapClient;DataSnapCommon;DBXInterBaseDriver;DataSnapProviderClient;DbxCommonDriver;dbxcds;fmxFireDAC;CustomIPTransport;dsnap;IndyIPServer;fmxase;IndyCore;CloudService;IndyIPCommon;FireDACIBDriver;DataSnapFireDAC;FireDACDBXDriver;soapserver;dsnapxml;bindcompfmx;RESTBackendComponents;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;ibmonitor;xmlrtl;DataSnapNativeClient;ibxpress;IndyProtocols;FireDACCommonDriver;bindcompdbx;bindengine;soaprtl;emsclient;FireDAC;inet;soapmidas;RESTComponents;dbexpress;IndyIPClient;$(DCC_UsePackage) 277 | $(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_29x29.png 278 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_144x144.png 279 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png 280 | CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSCameraUsageDescription=The reason for accessing the camera;CFBundleShortVersionString=1.0.0;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSFaceIDUsageDescription=The reason for accessing the face id;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false 281 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2208x1242.png 282 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png 283 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1496.png 284 | $(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_58x58.png 285 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_58x58.png 286 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_87x87.png 287 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_320x480.png 288 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_57x57.png 289 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png 290 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x960.png 291 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_29x29.png 292 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2008.png 293 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_750x1334.png 294 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1004.png 295 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1125x2436.png 296 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2436x1125.png 297 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_120x120.png 298 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_828x1792.png 299 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1136x640.png 300 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1242x2688.png 301 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1334x750.png 302 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1792x828.png 303 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2688x1242.png 304 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_167x167.png 305 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1668x2224.png 306 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1668x2388.png 307 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_2048x2732.png 308 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2224x1668.png 309 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2388x1668.png 310 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2732x2048.png 311 | 312 | 313 | true 314 | fmxhrh;FireDACTDataDriver;FireDACSqliteDriver;FireDACDSDriver;DBXSqliteDriver;FireDACPgDriver;fmx;IndySystem;tethering;DataSnapClient;DataSnapServer;DataSnapCommon;DBXInterBaseDriver;DataSnapProviderClient;DbxCommonDriver;dbxcds;fmxFireDAC;DBXOracleDriver;CustomIPTransport;dsnap;IndyIPServer;fmxase;IndyCore;CloudService;IndyIPCommon;FireDACIBDriver;DataSnapFireDAC;FireDACDBXDriver;soapserver;dsnapxml;FireDACASADriver;bindcompfmx;FireDACODBCDriver;RESTBackendComponents;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;ibmonitor;xmlrtl;DataSnapNativeClient;ibxpress;IndyProtocols;DBXMySQLDriver;FireDACCommonDriver;bindcompdbx;bindengine;soaprtl;emsclient;FireDAC;DBXInformixDriver;FireDACMSSQLDriver;DataSnapServerMidas;DBXFirebirdDriver;inet;fmxobj;FireDACMySQLDriver;soapmidas;DBXSybaseASADriver;FireDACOracleDriver;fmxdae;RESTComponents;DataSnapIndy10ServerTransport;dbexpress;IndyIPClient;$(DCC_UsePackage) 315 | CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSContactsUsageDescription=The reason for accessing the contacts;CFBundleShortVersionString=1.0.0;NSLocationUsageDescription=The reason for accessing the location information of the user 316 | 317 | 318 | CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSContactsUsageDescription=The reason for accessing the contacts;CFBundleShortVersionString=1.0.0;NSLocationUsageDescription=The reason for accessing the location information of the user 319 | Debug 320 | true 321 | true 322 | Base 323 | true 324 | fmxhrh;FireDACTDataDriver;FireDACSqliteDriver;FireDACDSDriver;DBXSqliteDriver;FireDACPgDriver;fmx;IndySystem;tethering;DataSnapClient;DataSnapServer;DataSnapCommon;DBXInterBaseDriver;DataSnapProviderClient;DbxCommonDriver;dbxcds;fmxFireDAC;DBXOracleDriver;CustomIPTransport;dsnap;IndyIPServer;fmxase;IndyCore;CloudService;IndyIPCommon;FireDACIBDriver;DataSnapFireDAC;FireDACDBXDriver;soapserver;dsnapxml;FireDACASADriver;bindcompfmx;FireDACODBCDriver;RESTBackendComponents;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;ibmonitor;xmlrtl;DataSnapNativeClient;ibxpress;IndyProtocols;DBXMySQLDriver;FireDACCommonDriver;bindcompdbx;bindengine;soaprtl;emsclient;FireDAC;DBXInformixDriver;FireDACMSSQLDriver;DataSnapServerMidas;DBXFirebirdDriver;inet;fmxobj;FireDACMySQLDriver;soapmidas;DBXSybaseASADriver;FireDACOracleDriver;fmxdae;RESTComponents;DataSnapIndy10ServerTransport;dbexpress;IndyIPClient;$(DCC_UsePackage);$(DCC_UsePackage) 325 | 326 | 327 | true 328 | true 329 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) 330 | $(BDS)\bin\default_app.manifest 331 | 1033 332 | CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName) 333 | fmxhrh;FireDACTDataDriver;FireDACSqliteDriver;FireDACDSDriver;DBXSqliteDriver;FireDACPgDriver;fmx;IndySystem;TeeDB;tethering;vclib;DataSnapClient;DataSnapServer;DataSnapCommon;DBXInterBaseDriver;DataSnapProviderClient;DBXSybaseASEDriver;DbxCommonDriver;vclimg;DUnitXRuntime;dbxcds;DatasnapConnectorsFreePascal;vcldb;vcldsnap;fmxFireDAC;DBXDb2Driver;DBXOracleDriver;CustomIPTransport;vclribbon;dsnap;IndyIPServer;fmxase;vcl;IndyCore;CloudService;DBXMSSQLDriver;IndyIPCommon;FireDACIBDriver;DataSnapFireDAC;FireDACDBXDriver;soapserver;dsnapxml;FireDACInfxDriver;FireDACDb2Driver;adortl;FireDACASADriver;bindcompfmx;vcldbx;FireDACODBCDriver;RESTBackendComponents;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;Tee;DBXOdbcDriver;ibmonitor;vclFireDAC;xmlrtl;DataSnapNativeClient;ibxpress;svnui;IndyProtocols;DBXMySQLDriver;FireDACCommonDriver;bindcompdbx;bindengine;vclactnband;soaprtl;TeeUI;bindcompvcl;vclie;FireDACADSDriver;vcltouch;emsclient;VCLRESTComponents;FireDAC;DBXInformixDriver;FireDACMSSQLDriver;Intraweb;VclSmp;DataSnapConnectors;DataSnapServerMidas;DBXFirebirdDriver;dsnapcon;inet;fmxobj;FireDACMySQLDriver;soapmidas;vclx;svn;DBXSybaseASADriver;FireDACOracleDriver;fmxdae;RESTComponents;bdertl;FireDACMSAccDriver;DataSnapIndy10ServerTransport;dbexpress;IndyIPClient;$(DCC_UsePackage) 334 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png 335 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png 336 | 337 | 338 | true 339 | true 340 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) 341 | $(BDS)\bin\default_app.manifest 342 | 1033 343 | CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName) 344 | fmxhrh;FireDACTDataDriver;FireDACSqliteDriver;FireDACDSDriver;DBXSqliteDriver;FireDACPgDriver;fmx;IndySystem;TeeDB;tethering;vclib;DataSnapClient;DataSnapServer;DataSnapCommon;DBXInterBaseDriver;DataSnapProviderClient;DBXSybaseASEDriver;DbxCommonDriver;vclimg;dbxcds;DatasnapConnectorsFreePascal;vcldb;vcldsnap;fmxFireDAC;DBXDb2Driver;DBXOracleDriver;CustomIPTransport;vclribbon;dsnap;IndyIPServer;fmxase;vcl;IndyCore;CloudService;DBXMSSQLDriver;IndyIPCommon;FireDACIBDriver;DataSnapFireDAC;FireDACDBXDriver;soapserver;dsnapxml;FireDACInfxDriver;FireDACDb2Driver;adortl;FireDACASADriver;bindcompfmx;FireDACODBCDriver;RESTBackendComponents;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;Tee;DBXOdbcDriver;ibmonitor;vclFireDAC;xmlrtl;DataSnapNativeClient;ibxpress;IndyProtocols;DBXMySQLDriver;FireDACCommonDriver;bindcompdbx;bindengine;vclactnband;soaprtl;TeeUI;bindcompvcl;vclie;FireDACADSDriver;vcltouch;emsclient;VCLRESTComponents;FireDAC;DBXInformixDriver;FireDACMSSQLDriver;Intraweb;VclSmp;DataSnapConnectors;DataSnapServerMidas;DBXFirebirdDriver;dsnapcon;inet;fmxobj;FireDACMySQLDriver;soapmidas;vclx;DBXSybaseASADriver;FireDACOracleDriver;fmxdae;RESTComponents;FireDACMSAccDriver;DataSnapIndy10ServerTransport;dbexpress;IndyIPClient;$(DCC_UsePackage) 345 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png 346 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png 347 | 348 | 349 | DEBUG;$(DCC_Define) 350 | true 351 | false 352 | true 353 | true 354 | true 355 | 356 | 357 | Debug 358 | 359 | 360 | true 361 | Cfg_1 362 | true 363 | 364 | 365 | false 366 | Debug 367 | true 368 | 1033 369 | true 370 | download-ga42fd477b_640 (1).ico 371 | 372 | 373 | Debug 374 | 375 | 376 | false 377 | RELEASE;$(DCC_Define) 378 | 0 379 | 0 380 | 381 | 382 | true 383 | 1033 384 | download-ga42fd477b_640 (1).ico 385 | true 386 | 387 | 388 | 389 | MainSource 390 | 391 | 392 | 393 |
Form1
394 | fmx 395 |
396 | 397 | 398 | Cfg_2 399 | Base 400 | 401 | 402 | Base 403 | 404 | 405 | Cfg_1 406 | Base 407 | 408 |
409 | 410 | Delphi.Personality.12 411 | Application 412 | 413 | 414 | 415 | HttpDownloadDemo.dpr 416 | 417 | 418 | Composants Microsoft Office 2000 Sample Automation Server Wrapper 419 | Composants Microsoft Office XP Sample Automation Server Wrapper 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | true 455 | 456 | 457 | 458 | 459 | 460 | 461 | true 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | HttpDownloadDemo.exe 476 | true 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | true 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 1 512 | 513 | 514 | Contents\MacOS 515 | 1 516 | 517 | 518 | 0 519 | 520 | 521 | 522 | 523 | classes 524 | 1 525 | 526 | 527 | 528 | 529 | res\xml 530 | 1 531 | 532 | 533 | 534 | 535 | library\lib\armeabi-v7a 536 | 1 537 | 538 | 539 | 540 | 541 | library\lib\armeabi 542 | 1 543 | 544 | 545 | 546 | 547 | library\lib\mips 548 | 1 549 | 550 | 551 | 552 | 553 | library\lib\armeabi-v7a 554 | 1 555 | 556 | 557 | 558 | 559 | res\drawable 560 | 1 561 | 562 | 563 | 564 | 565 | res\values 566 | 1 567 | 568 | 569 | 570 | 571 | res\values-v21 572 | 1 573 | 574 | 575 | 576 | 577 | res\values 578 | 1 579 | 580 | 581 | 582 | 583 | res\drawable 584 | 1 585 | 586 | 587 | 588 | 589 | res\drawable-xxhdpi 590 | 1 591 | 592 | 593 | 594 | 595 | res\drawable-ldpi 596 | 1 597 | 598 | 599 | 600 | 601 | res\drawable-mdpi 602 | 1 603 | 604 | 605 | 606 | 607 | res\drawable-hdpi 608 | 1 609 | 610 | 611 | 612 | 613 | res\drawable-xhdpi 614 | 1 615 | 616 | 617 | 618 | 619 | res\drawable-mdpi 620 | 1 621 | 622 | 623 | 624 | 625 | res\drawable-hdpi 626 | 1 627 | 628 | 629 | 630 | 631 | res\drawable-xhdpi 632 | 1 633 | 634 | 635 | 636 | 637 | res\drawable-xxhdpi 638 | 1 639 | 640 | 641 | 642 | 643 | res\drawable-xxxhdpi 644 | 1 645 | 646 | 647 | 648 | 649 | res\drawable-small 650 | 1 651 | 652 | 653 | 654 | 655 | res\drawable-normal 656 | 1 657 | 658 | 659 | 660 | 661 | res\drawable-large 662 | 1 663 | 664 | 665 | 666 | 667 | res\drawable-xlarge 668 | 1 669 | 670 | 671 | 672 | 673 | res\values 674 | 1 675 | 676 | 677 | 678 | 679 | 1 680 | 681 | 682 | Contents\MacOS 683 | 1 684 | 685 | 686 | 0 687 | 688 | 689 | 690 | 691 | Contents\MacOS 692 | 1 693 | .framework 694 | 695 | 696 | Contents\MacOS 697 | 1 698 | .framework 699 | 700 | 701 | 0 702 | 703 | 704 | 705 | 706 | 1 707 | .dylib 708 | 709 | 710 | 1 711 | .dylib 712 | 713 | 714 | 1 715 | .dylib 716 | 717 | 718 | Contents\MacOS 719 | 1 720 | .dylib 721 | 722 | 723 | Contents\MacOS 724 | 1 725 | .dylib 726 | 727 | 728 | 0 729 | .dll;.bpl 730 | 731 | 732 | 733 | 734 | 1 735 | .dylib 736 | 737 | 738 | 1 739 | .dylib 740 | 741 | 742 | 1 743 | .dylib 744 | 745 | 746 | Contents\MacOS 747 | 1 748 | .dylib 749 | 750 | 751 | Contents\MacOS 752 | 1 753 | .dylib 754 | 755 | 756 | 0 757 | .bpl 758 | 759 | 760 | 761 | 762 | 0 763 | 764 | 765 | 0 766 | 767 | 768 | 0 769 | 770 | 771 | 0 772 | 773 | 774 | Contents\Resources\StartUp\ 775 | 0 776 | 777 | 778 | Contents\Resources\StartUp\ 779 | 0 780 | 781 | 782 | 0 783 | 784 | 785 | 786 | 787 | 1 788 | 789 | 790 | 1 791 | 792 | 793 | 1 794 | 795 | 796 | 797 | 798 | 1 799 | 800 | 801 | 1 802 | 803 | 804 | 1 805 | 806 | 807 | 808 | 809 | 1 810 | 811 | 812 | 1 813 | 814 | 815 | 1 816 | 817 | 818 | 819 | 820 | 1 821 | 822 | 823 | 1 824 | 825 | 826 | 1 827 | 828 | 829 | 830 | 831 | 1 832 | 833 | 834 | 1 835 | 836 | 837 | 1 838 | 839 | 840 | 841 | 842 | 1 843 | 844 | 845 | 1 846 | 847 | 848 | 1 849 | 850 | 851 | 852 | 853 | 1 854 | 855 | 856 | 1 857 | 858 | 859 | 1 860 | 861 | 862 | 863 | 864 | 1 865 | 866 | 867 | 1 868 | 869 | 870 | 1 871 | 872 | 873 | 874 | 875 | 1 876 | 877 | 878 | 1 879 | 880 | 881 | 1 882 | 883 | 884 | 885 | 886 | 1 887 | 888 | 889 | 1 890 | 891 | 892 | 1 893 | 894 | 895 | 896 | 897 | 1 898 | 899 | 900 | 1 901 | 902 | 903 | 1 904 | 905 | 906 | 907 | 908 | 1 909 | 910 | 911 | 1 912 | 913 | 914 | 1 915 | 916 | 917 | 918 | 919 | 1 920 | 921 | 922 | 1 923 | 924 | 925 | 1 926 | 927 | 928 | 929 | 930 | 1 931 | 932 | 933 | 1 934 | 935 | 936 | 1 937 | 938 | 939 | 940 | 941 | 1 942 | 943 | 944 | 1 945 | 946 | 947 | 1 948 | 949 | 950 | 951 | 952 | 1 953 | 954 | 955 | 1 956 | 957 | 958 | 1 959 | 960 | 961 | 962 | 963 | 1 964 | 965 | 966 | 1 967 | 968 | 969 | 1 970 | 971 | 972 | 973 | 974 | 1 975 | 976 | 977 | 1 978 | 979 | 980 | 1 981 | 982 | 983 | 984 | 985 | 1 986 | 987 | 988 | 1 989 | 990 | 991 | 1 992 | 993 | 994 | 995 | 996 | 1 997 | 998 | 999 | 1 1000 | 1001 | 1002 | 1 1003 | 1004 | 1005 | 1006 | 1007 | 1 1008 | 1009 | 1010 | 1 1011 | 1012 | 1013 | 1 1014 | 1015 | 1016 | 1017 | 1018 | 1 1019 | 1020 | 1021 | 1 1022 | 1023 | 1024 | 1 1025 | 1026 | 1027 | 1028 | 1029 | 1 1030 | 1031 | 1032 | 1 1033 | 1034 | 1035 | 1 1036 | 1037 | 1038 | 1039 | 1040 | 1 1041 | 1042 | 1043 | 1 1044 | 1045 | 1046 | 1 1047 | 1048 | 1049 | 1050 | 1051 | 1 1052 | 1053 | 1054 | 1055 | 1056 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1057 | 1 1058 | 1059 | 1060 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1061 | 1 1062 | 1063 | 1064 | 1065 | 1066 | 1 1067 | 1068 | 1069 | 1 1070 | 1071 | 1072 | 1073 | 1074 | ..\ 1075 | 1 1076 | 1077 | 1078 | ..\ 1079 | 1 1080 | 1081 | 1082 | 1083 | 1084 | 1 1085 | 1086 | 1087 | 1 1088 | 1089 | 1090 | 1 1091 | 1092 | 1093 | 1094 | 1095 | 1 1096 | 1097 | 1098 | 1 1099 | 1100 | 1101 | 1 1102 | 1103 | 1104 | 1105 | 1106 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1107 | 1 1108 | 1109 | 1110 | 1111 | 1112 | ..\ 1113 | 1 1114 | 1115 | 1116 | ..\ 1117 | 1 1118 | 1119 | 1120 | 1121 | 1122 | Contents 1123 | 1 1124 | 1125 | 1126 | Contents 1127 | 1 1128 | 1129 | 1130 | 1131 | 1132 | Contents\Resources 1133 | 1 1134 | 1135 | 1136 | Contents\Resources 1137 | 1 1138 | 1139 | 1140 | 1141 | 1142 | library\lib\armeabi-v7a 1143 | 1 1144 | 1145 | 1146 | 1 1147 | 1148 | 1149 | 1 1150 | 1151 | 1152 | 1 1153 | 1154 | 1155 | 1 1156 | 1157 | 1158 | Contents\MacOS 1159 | 1 1160 | 1161 | 1162 | Contents\MacOS 1163 | 1 1164 | 1165 | 1166 | 0 1167 | 1168 | 1169 | 1170 | 1171 | 1 1172 | 1173 | 1174 | 1 1175 | 1176 | 1177 | 1178 | 1179 | Assets 1180 | 1 1181 | 1182 | 1183 | Assets 1184 | 1 1185 | 1186 | 1187 | 1188 | 1189 | Assets 1190 | 1 1191 | 1192 | 1193 | Assets 1194 | 1 1195 | 1196 | 1197 | 1198 | 1199 | 1200 | 1201 | 1202 | 1203 | 1204 | 1205 | 1206 | 1207 | 1208 | True 1209 | True 1210 | True 1211 | True 1212 | True 1213 | True 1214 | True 1215 | True 1216 | 1217 | 1218 | 12 1219 | 1220 | 1221 | 1222 | 1223 |
1224 | -------------------------------------------------------------------------------- /Demo/HttpDownloadDemo.dproj.local: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 2022/05/26 12:11:43.000.871,=C:\Users\Kamel\Desktop\HttpDownload\MultiCircularProgress.pas 8 | 2022/05/26 15:47:02.000.574,=C:\Users\Kamel\Desktop\HttpDownload\Unit1.pas 9 | 2022/05/26 15:47:30.000.395,C:\Users\Kamel\Desktop\HttpDownload\Unit1.pas=C:\Users\Kamel\Desktop\HttpDownload\ThredingFileDownloader.pas 10 | 2022/05/26 17:41:11.000.190,=C:\Users\Kamel\Desktop\HttpDownload\Unit1.pas 11 | 2022/05/26 17:41:50.000.115,C:\Users\Kamel\Desktop\HttpDownload\Unit1.fmx=C:\Users\Kamel\Desktop\HttpDownload\MainForm.fmx 12 | 2022/05/26 17:41:50.000.115,C:\Users\Kamel\Desktop\HttpDownload\Unit1.pas=C:\Users\Kamel\Desktop\HttpDownload\MainForm.pas 13 | 2022/05/29 14:09:32.000.815,C:\Users\Kamel\Desktop\HttpDownload\FDownloadDemo.pas= 14 | 2022/06/01 21:22:18.000.405,=C:\Users\neptune\Desktop\HttpDownload\ThredingFileDownloader.pas 15 | 16 | 17 | -------------------------------------------------------------------------------- /Demo/HttpDownloadDemo.identcache: -------------------------------------------------------------------------------- 1 | DC:\Users\neptune\Desktop\HttpDownload\Demo\MultiCircularProgress.pas?C:\Users\neptune\Desktop\HttpDownload\Demo\HttpDownloadDemo.dpr@C:\Users\neptune\Desktop\HttpDownload\ThredingFileDownloader.pas7C:\Users\neptune\Desktop\HttpDownload\Demo\MainForm.pas -------------------------------------------------------------------------------- /Demo/HttpDownloadDemo.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamel78/Multi-Threading-Advanced-Http-Downloader/318cbd18f6515799eb7c33fa8f0f22d3bd5dd282/Demo/HttpDownloadDemo.res -------------------------------------------------------------------------------- /Demo/HttpDownloadDemo.skincfg: -------------------------------------------------------------------------------- 1 | [ExpressSkins] 2 | Default=1 3 | ShowNotifications=1 4 | Enabled=1 5 | dxSkinsDefaultPainters=1 6 | -------------------------------------------------------------------------------- /Demo/HttpDownloadDemo_Icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamel78/Multi-Threading-Advanced-Http-Downloader/318cbd18f6515799eb7c33fa8f0f22d3bd5dd282/Demo/HttpDownloadDemo_Icon.ico -------------------------------------------------------------------------------- /Demo/HttpDownloadDemo_Icon1.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamel78/Multi-Threading-Advanced-Http-Downloader/318cbd18f6515799eb7c33fa8f0f22d3bd5dd282/Demo/HttpDownloadDemo_Icon1.ico -------------------------------------------------------------------------------- /Demo/MainForm.fmx: -------------------------------------------------------------------------------- 1 | object Form1: TForm1 2 | Left = 0 3 | Top = 0 4 | BorderIcons = [biSystemMenu, biMinimize] 5 | Caption = 'Multi-Threading Download Demo' 6 | ClientHeight = 621 7 | ClientWidth = 596 8 | Position = DesktopCenter 9 | FormFactor.Width = 320 10 | FormFactor.Height = 480 11 | FormFactor.Devices = [Desktop] 12 | OnCreate = FormCreate 13 | DesignerMasterStyle = 0 14 | object Rectangle1: TRectangle 15 | Align = Top 16 | Fill.Color = claWhite 17 | Size.Width = 596.000000000000000000 18 | Size.Height = 257.000000000000000000 19 | Size.PlatformDefault = False 20 | Stroke.Kind = None 21 | object Layout11: TLayout 22 | Align = Contents 23 | Size.Width = 596.000000000000000000 24 | Size.Height = 257.000000000000000000 25 | Size.PlatformDefault = False 26 | TabOrder = 3 27 | object Label5: TLabel 28 | Align = Top 29 | StyledSettings = [Family, Size] 30 | Margins.Left = 10.000000000000000000 31 | Margins.Top = 5.000000000000000000 32 | Position.X = 10.000000000000000000 33 | Position.Y = 5.000000000000000000 34 | Size.Width = 586.000000000000000000 35 | Size.Height = 17.000000000000000000 36 | Size.PlatformDefault = False 37 | TextSettings.Font.StyleExt = {00070000000000000004000000} 38 | TextSettings.FontColor = claRoyalblue 39 | Text = 40 | 'Multi-Threading for Http files download FMX Demo (kamel_mh@yahoo' + 41 | '.fr)' 42 | TabOrder = 0 43 | end 44 | end 45 | object Layout1: TLayout 46 | Align = Left 47 | Margins.Left = 10.000000000000000000 48 | Margins.Top = 40.000000000000000000 49 | Margins.Bottom = 20.000000000000000000 50 | Position.X = 10.000000000000000000 51 | Position.Y = 40.000000000000000000 52 | Size.Width = 205.000000000000000000 53 | Size.Height = 197.000000000000000000 54 | Size.PlatformDefault = False 55 | TabOrder = 0 56 | end 57 | object Layout2: TLayout 58 | Align = Client 59 | Margins.Left = 20.000000000000000000 60 | Margins.Top = 40.000000000000000000 61 | Size.Width = 301.000000000000000000 62 | Size.Height = 217.000000000000000000 63 | Size.PlatformDefault = False 64 | TabOrder = 1 65 | object Layout3: TLayout 66 | Align = Top 67 | Size.Width = 301.000000000000000000 68 | Size.Height = 30.000000000000000000 69 | Size.PlatformDefault = False 70 | TabOrder = 6 71 | object Label14: TLabel 72 | Align = FitLeft 73 | Size.Width = 100.000000000000000000 74 | Size.Height = 30.000000000000000000 75 | Size.PlatformDefault = False 76 | Text = 'File Name :' 77 | TabOrder = 2 78 | end 79 | object Label15: TLabel 80 | Align = Client 81 | Margins.Left = 5.000000000000000000 82 | Size.Width = 196.000000000000000000 83 | Size.Height = 30.000000000000000000 84 | Size.PlatformDefault = False 85 | Text = '-' 86 | TabOrder = 13 87 | end 88 | end 89 | object Layout4: TLayout 90 | Align = Top 91 | Position.Y = 120.000000000000000000 92 | Size.Width = 301.000000000000000000 93 | Size.Height = 30.000000000000000000 94 | Size.PlatformDefault = False 95 | TabOrder = 5 96 | object Label20: TLabel 97 | Align = Client 98 | Margins.Left = 5.000000000000000000 99 | Size.Width = 196.000000000000000000 100 | Size.Height = 30.000000000000000000 101 | Size.PlatformDefault = False 102 | Text = '-' 103 | TabOrder = 13 104 | end 105 | object Label21: TLabel 106 | Align = FitLeft 107 | Size.Width = 100.000000000000000000 108 | Size.Height = 30.000000000000000000 109 | Size.PlatformDefault = False 110 | Text = 'Progress :' 111 | TabOrder = 2 112 | end 113 | end 114 | object Layout5: TLayout 115 | Align = Top 116 | Position.Y = 60.000000000000000000 117 | Size.Width = 301.000000000000000000 118 | Size.Height = 30.000000000000000000 119 | Size.PlatformDefault = False 120 | TabOrder = 1 121 | object Label18: TLabel 122 | Align = Client 123 | Margins.Left = 5.000000000000000000 124 | Size.Width = 196.000000000000000000 125 | Size.Height = 30.000000000000000000 126 | Size.PlatformDefault = False 127 | Text = '-' 128 | TabOrder = 13 129 | end 130 | object Label19: TLabel 131 | Align = FitLeft 132 | Size.Width = 100.000000000000000000 133 | Size.Height = 30.000000000000000000 134 | Size.PlatformDefault = False 135 | Text = 'Download Speed :' 136 | TabOrder = 2 137 | end 138 | end 139 | object Layout6: TLayout 140 | Align = Top 141 | Position.Y = 30.000000000000000000 142 | Size.Width = 301.000000000000000000 143 | Size.Height = 30.000000000000000000 144 | Size.PlatformDefault = False 145 | TabOrder = 0 146 | object Label16: TLabel 147 | Align = Client 148 | Margins.Left = 5.000000000000000000 149 | Size.Width = 196.000000000000000000 150 | Size.Height = 30.000000000000000000 151 | Size.PlatformDefault = False 152 | Text = '-' 153 | TabOrder = 13 154 | end 155 | object Label17: TLabel 156 | Align = FitLeft 157 | Size.Width = 100.000000000000000000 158 | Size.Height = 30.000000000000000000 159 | Size.PlatformDefault = False 160 | Text = 'File Size :' 161 | TabOrder = 2 162 | end 163 | end 164 | object Layout7: TLayout 165 | Align = Top 166 | Position.Y = 150.000000000000000000 167 | Size.Width = 301.000000000000000000 168 | Size.Height = 30.000000000000000000 169 | Size.PlatformDefault = False 170 | TabOrder = 4 171 | object Label22: TLabel 172 | Align = Client 173 | Margins.Left = 5.000000000000000000 174 | Size.Width = 196.000000000000000000 175 | Size.Height = 30.000000000000000000 176 | Size.PlatformDefault = False 177 | Text = '-' 178 | TabOrder = 13 179 | end 180 | object Label23: TLabel 181 | Align = FitLeft 182 | Size.Width = 100.000000000000000000 183 | Size.Height = 30.000000000000000000 184 | Size.PlatformDefault = False 185 | Text = 'Remaining time :' 186 | TabOrder = 2 187 | end 188 | end 189 | object Layout8: TLayout 190 | Align = Top 191 | Position.Y = 90.000000000000000000 192 | Size.Width = 301.000000000000000000 193 | Size.Height = 30.000000000000000000 194 | Size.PlatformDefault = False 195 | TabOrder = 2 196 | object Label24: TLabel 197 | Align = Client 198 | Margins.Left = 5.000000000000000000 199 | Size.Width = 196.000000000000000000 200 | Size.Height = 30.000000000000000000 201 | Size.PlatformDefault = False 202 | Text = '-' 203 | TabOrder = 13 204 | end 205 | object Label25: TLabel 206 | Align = FitLeft 207 | Size.Width = 100.000000000000000000 208 | Size.Height = 30.000000000000000000 209 | Size.PlatformDefault = False 210 | Text = 'Downloaded :' 211 | TabOrder = 2 212 | end 213 | end 214 | object Layout9: TLayout 215 | Align = Top 216 | Position.Y = 180.000000000000000000 217 | Size.Width = 301.000000000000000000 218 | Size.Height = 30.000000000000000000 219 | Size.PlatformDefault = False 220 | TabOrder = 3 221 | object Label3: TLabel 222 | Align = Client 223 | StyledSettings = [Family, Size, Style] 224 | Margins.Left = 5.000000000000000000 225 | Size.Width = 196.000000000000000000 226 | Size.Height = 30.000000000000000000 227 | Size.PlatformDefault = False 228 | TextSettings.FontColor = claGreen 229 | Text = '-' 230 | TabOrder = 13 231 | end 232 | object Label4: TLabel 233 | Align = FitLeft 234 | Size.Width = 100.000000000000000000 235 | Size.Height = 30.000000000000000000 236 | Size.PlatformDefault = False 237 | Text = 'Resume :' 238 | TabOrder = 2 239 | end 240 | end 241 | end 242 | object Layout10: TLayout 243 | Align = Right 244 | Position.X = 536.000000000000000000 245 | Size.Width = 60.000000000000000000 246 | Size.Height = 257.000000000000000000 247 | Size.PlatformDefault = False 248 | TabOrder = 2 249 | object Image1: TImage 250 | MultiResBitmap.Height = 128 251 | MultiResBitmap.Width = 128 252 | MultiResBitmap = < 253 | item 254 | Width = 128 255 | Height = 128 256 | PNG = { 257 | 89504E470D0A1A0A0000000D4948445200000080000000800806000000C33E61 258 | CB000000017352474200AECE1CE90000000467414D410000B18F0BFC61050000 259 | 10BB49444154785EED9D799055D59DC7BFF7DCB7F5EB85160D448A0470012B38 260 | FCA1A4A69CB12A24450F0C49662A33461A824B32C649395366B4B0C2D4202392 261 | A492312513323191D4B810C4069724236023B4518362149360109BA5A15B4016 262 | E9A6D7B7DE7BEE9CDFEDD3F89ADEDE72D7D7F753D5727FBF07C2BBDFEF39BF73 263 | EE728E8232C230A0E019840D8669486116B2B84AE43ECD38A6EA1C938D2C2671 264 | 15B51A47B5F8ED5124A09A7F300E5DFC371D62E8613A3A9530CEAA0C6738C309 265 | 45C10708E3086238A870B4E1ABC88A9C61FEB932C0D70620C18D064C85861B8D 266 | 0C6E3074CC4D03B3D12B041692C62BADF97E893E213859A50A3D51E03D45C55E 267 | 25823D0861B7526F9AC4B786F09D01F81BA810ED709E91C022CE313FA363665C 268 | 0773FC9B08C9132A7844C521C6B04B8963BBE8775E617F85A4FC1DBEC01706E0 269 | DB4577DD813A2385C5A28BFEB268DD13E447DE42459728312F28316CC644EC64 270 | 8B203A246FE36903F0E731D3388F6F6A3A9669DD981C8FFBC3B089048C500DCE 271 | 84546C542EC12FD83FE090FCC87378EE848ABACE8C8D982F6AFADDA94E2C8C57 272 | C8819A4F4924A1C76AD128C60CEB9465A25428E0F2234FE01903185B84D029D1 273 | BDA7B132D185EBFCD2DAF3857A85F804FC4114B3EF8A19C50BCACDE6CCC3753C 274 | 7192F9062CE429AC4977E3FA7213FE62C808D11ABCC362B89FDD8A4699760D57 275 | 4F36DF84D96234FF2396C142991A57F088280D712C674BF19E4C398E2B06102D 276 | BED2E058954AE1DB712E3AC5714C82211D8BE1C70AC383A247E89369C770DC00 277 | 4603E66B5D7834A4E30A990A10682A8E8626E09F957AEC92294770CC007C8768 278 | F527F083540677C5C5485FA60372488819422C824794A958C11638D31B386200 279 | DE806B790F36A959FC854C058C821EC69F593596B27AEC9729DBB0BD25F25F62 280 | 59B2137B02F1F387CE159D333A7732651BB6F500C66F11E2ADF861AA03F7C42B 281 | DC196CFA9D4412466C22D6B2E9F88EF27968326D29B608239C5B63A4F19498DE 282 | 7D49A6024A8047B14D898892700BBA65CA322C378098DB4F56FAB00D595C2F53 283 | CEA03BD0C950C1545CBAF31BC63B4625BEC896E28CCC5882A5678D3F8B697A3B 284 | 768829DE2C997286F044E01FF7C8C03ECEED5C894BDB9F71AD9E89A9E241F552 285 | 2C6037A14DA64AC6B2EFC29FC6957A2F7686B2982153CE11FE0470C7697160EF 286 | 98F6E0C67F82D1F218664DB2A976E68116C631B50A756C095A64AA242C396366 287 | CB774B7C87E9E81546386B3E0FE20A748EE95CD33997A99228D90054F3CD6E7F 288 | 1C883F80274C20CE399D7B992A9A920CC0B7A386F762ABE335DF03B86E0271CE 289 | E9DC9306325514451B80E6F9C687784AD53057A6C61D6E9B80CE3D69405AC854 290 | C1146D007E143F0CE6F9EE9B8034202D6458304519803F8165A94EDC23C3718F 291 | DB26202D4813191644C106A01B3BC9147E165CDE1D8C9B26202D4813D246A6F2 292 | A62003D0831CBC0B4FC739AA642A2007574D2034216D482399CA8B820C6064F1 293 | 03552FDC65E309374D40DA904632CC8BBC0D603C89F9F430870C0346C14D1390 294 | 46A4950CC7242F03185B50A5A5F1F3E0499EFC71CB04A49196C1CF4933991A95 295 | 3105A51730790F5685345C29530179E2960942595C499A996F4B8FC1D8067812 296 | 9F4925F16D190614885B2620CD483B198EC8D806C8E0477186880C038AC00D13 297 | 9066A49D0C47645403F0C7B19069E3F3A50DAB71C304A41D6928C36119D100F4 298 | AE1ECF628D0C032CC00D139086E67B972330B20112F83B7A574F860116E1B409 299 | 4843D252864318D600C67F822929FC47B9BFA8E9164E9A8034242D4953991AC4 300 | F006B80275895E5C27C3001B70D204A425692AC3410C3180B9F0520A7707ADDF 301 | 7E9C320169499A0E775D60A80136E0EA140F46FE4EE194094853D2568617186A 302 | 802CEE0C2EF93A8B1326204D495B195E6090D0B41A97C6F13519063888132620 303 | 6DCD15D77218DCD23B5047AB71C928C061EC3681A9ADD0588626830C40EBF005 304 | 833F77B1D3047230B8588626170CC037A3C25C8431C075EC3401694C5ACB30A7 305 | 07C8629E6757E01C87D86602D23829B496980630E7FE692C3233019EC12E1318 306 | 3A160D5C13F8B804F0FC1F230A700E3B4C90AB757F0FD080A9B4EAB69909F01C 307 | 569B80B43697D917F4F7001A6E8CF39CF14080E7B0D204E6F2FA42733AEEEF01 308 | 52B8817E0DF03696994054FF01CD993900043E6B7E10E079AC3201694EDA33DA 309 | 6327CDC77E7830C03B5861025373A13DDD2098863E7313A5001F51B20984E6A4 310 | 3D838E6BBCB5854140BE946402D25C68AFF0C7F16F4A126BFBB31E60D23CA0A6 311 | C0D566D44AE00BEBC481BDB7314EEDFE5FF4B4BE2EA3FCD0B3099C7F6FB3ADFF 312 | B48955286AE12AA302F728FA637898A53CF4AE7FD54C60F15B40A4D0954FEC15 313 | FF630A686FE2B7363F792B3ADEDB2813F6518C09780C6B196DAA28636FD07B08 314 | D8F52D71405FA5901FA718EEEF1EFEE7D4EBEBD1BEDF7EF18962CA0169CF6847 315 | 4D197B87D60660DF2332F027BDC7F7A1F5FFEE81425E7088424D40DAD32C4074 316 | 1C1E834EDA9E7B8133EFF4C73E434B7689AEFF261886F37B48166202D29ED15E 317 | BA32F616461AD8B1584C583B65C23F1C7EFA4E64BA8EC8C879F2350169CFE446 318 | CADEA4AF05D8F90D71504865739793AFFC0FCE1FD82223F7C8C704A43DDD0BF0 319 | F6A64DC77F05FCF12732F0363DAD7BD1B67D797F09F300799820CA2E6CA1EE65 320 | DEBC4F4CC27F2F036FA2253AD0BCE1E6FED2E521463581D0DE27B78033623C50 321 | 0FA43A64EC350C1CDA7807B23DC764EC2D46330143DC1B5B988E49B21578E936 322 | 71E0BDEBD6279AD6A2F39028551E66581308EDA907F0FC16E71738B10DD8FBB0 323 | 0CBC41F7D13DF8A0718567EAFE680C6382340B31F4C8C0FBD0930B6FFFBB186A 324 | EF960977C9F6B6E3E02F97D0517FC207E49A80B4674C87CF26DA9A28054B4549 325 | 3827639730380E6EBC5598C0B2DD5B1C63C004A43D53C210873E23755C0C0A97 326 | 0911DC1BBE1CDFF910BA8F6C9791FF20131CFE08E798980758BA0B95639CDA21 327 | CA41D1ABA49744D7E1D770FCA595BEA8FBA3D197C459C6194EC8D87FEC5D259A 328 | E22B3270864CCF59D1F58B12A4D8B28FA3A388C6FF2153147C2063FFA18812B0 329 | 5388D1E7502746757FC33268899332E1730CB431A868492486BD46E00FD2A7C4 330 | 784098C081F1405BE3F7D1D3EAE8EEEEB6D167C0A8AC400B19A0D9F7AF849C79 331 | 1978D3DE250DCF3737E144D303E2C8BF6D2517F31AB082669A05B4A1D247D702 332 | 46E28FC2006D3B65602D99AED338BC6919142A3965424C4122A2E318C357918D 333 | 321C9079FFA27060D72D40EF8732610D06D7D0BC6109B424ED4C5A3E4418DE9F 334 | FE00D2340834C46CE66D99F7371931186C5C0208D1ACA26DDB1AF47EE0EC4CC3 335 | 0984EE7B497BB3FA2B31D8BFF3B2537CF41AF0C6FD32288D8E038D38F96A792E 336 | 971C57FB35EF1FFE85B03BC1CAE8F59077FF0B38F6A20C8A237DFEA4A8FBB789 337 | 96521E83BE5C52D4EBAB102D451A40A9C789888A43745C16D078A0498C07BA8B 338 | BBC461F02C9A9F5C023DEDBFABE4F95065A0E51AF45FFFB93001640CE531C11D 339 | 20DB2EC70385DFA96BFDCDFDE83BF93B19951F91B0D07A75FF7CB6BF07E8EF12 340 | FC7B676324DADF0076AF1007F977E3ED7FDE8A0F5F1725A48C0947F0A218F87F 341 | 6C00930ABC02155D322A1FF6AF055A5E90C1E8A4DADB70A4E1F6B2ACFB03A862 342 | A27C69159A649853021623C955E477A6FC0489F9F2ED40D75199181EAE6744DD 343 | AF879E11A5A38C5119B65D7E1FFA6498D30308C47470B3AFEF0B8C8476BE7F3C 344 | A08FFCF4DBB15FAF40E2D49B322A4F12A2DB8F46B1598626830C8089D819AAF1 345 | E9F30163D1F116F0DA72190CE6DC9F7E8DD37BBCF386BC5D541B3857DB8B4619 346 | 9A0C32005B847488E12919961FEFFF1438FC9C0CFA497ED482235BBE4E03E1B2 347 | 271CC2D39F7A1829199A0CEE01044A18EB134A99AE1942E381DF7E03387FD80C 348 | B99646F313F562A6E8BFF70F0B259304AFA9C47A9AF1C994C95003DC8AC33136 349 | B89B282BF46E311EA817E382148E3E772F9267F7CA0FCA9BEA6A345DB56AE84D 350 | BFA106A06B0231AC2BCBC1E0009D7F4062CBDFE0CC5BFE5E83205F68F0178F62 351 | DDC0DC3F97612B9FB9C5D8E5784B1402FBF60D548678CF714EF588D1FF47A6E9 352 | 3D81C1EDA9BC6115EF7EF67A5CA7DC3CF42DB011BF3A7F025F499EC373B66C20 353 | C1C5FFB2EE57E26F77FFBDD4AEA4A88F1E78CE434BB6E3E8B36230AA5ADBF18A 354 | AF674C8A62F19CEFE119991AC488E2D276A37A27DE5435CC9529EBD044EBFF17 355 | D131316FBF99EE24E9CE36BCFDC00CB0B0B5068800FB7A2B31F7F3ABE98D9AA1 356 | 8CD80F5377C1C2B0E6C67A806B54C4B06A24F189510B31FB3A1A79A88C670465 357 | 4E4445D3EC35A35FDE1F7324A644B03CC1E905FD003F915290AD8961F9C5F3FE 358 | 8B19DB00B7E140AC023F9661804FA855F1C8ACD5F8930C47646C030807B16A3C 359 | A885D12253011E27A4A2AD3A8A55321C95310D408801616F28826F95ED25E232 360 | 22291A6C551877CD5C8D6E991A95BC0C408852B02B16C1F8B874E6632E0B63FD 361 | ECEFE6FF7457DE0620943056E82AF6CBB0340C1A9B043F1FFF948EAAA0399AC5 362 | 7D32CC8B82AFF2F1065C9BECC49E3847954C158EF8BE676BEA70963A29EBAF33 363 | FA1243CFA0A7F5D5A2CF47862331A51A7F9DCFC02F97A2FE3AFE049625DBB121 364 | 5E519A7C47CE0923E455A90246C3BCDC1BC11D73BE8FC7642A6F0A2A0103B0DB 365 | B131565BFA2613575D064C2A745B80802108F11F29467CA2280310EC0A7C8747 366 | B05586451398A0346261BC943957FC861F2575E17C3B6A94937819D9D26F1B07 367 | E5A070E846CF659598376375F12BBD953C04E3BFC164FD345E0DE99825534513 368 | 98207FD4105AA654E1739F5E8992D6AB29BA040CC0FE1E67D44BB1400BA3E485 369 | 728372901FA2B19DB8BC120B4A159F28D90004BB096D6A15EA340426B01D86E3 370 | 136A5037ED7E6B2ECD975C0272E1CF629ADE8E1D4139B08790382D9F9C808556 371 | 894F58D2030C60F604D5F89C189D94BCD94FD0130C86067CB5B59867A5F884A5 372 | 0620D8529C31A2F8423045B40E9AEAD1687F960535FF622C3700C16E4137BB12 373 | 5FE1157838912CED42F77836015DE1AB8EE1A7C6747CA994A9DE68583A06180E 374 | F3B2710A3F2BE9DE8160BC8D09E8DAFE27AAF0AFD73E88C765CA166C37004137 375 | 9078279E5239E6C854518C17138443785F88BF74C6CAC26EEC14832D25E06258 376 | 3DF6AB5370038FE227A53C5452EEE580DEDFAB8CE0D11997E02F9D109F70A407 377 | C8C568C07CAD0B8F8AA9E215325530E5D813D0635C5531DC357BB5B34BF538D2 378 | 03E4A2D463975A81393C8E878A7DDAB89C7A82B4826C6518FF7D490C739C169F 379 | 70BC07C8856FC26CA30F0FB12CFE56A60AC2EF3D41348C5DD515583E6B15F6C9 380 | 94E3B86A8001F8062CE429AC4977E3FA42DF45F49B09E84DDD4B54ECAB8960D5 381 | D50F62EB58CFEDDB8D270C40D0BB88C8E2CB62F2BB32D189EB0A31821F4C40C2 382 | D786F06E3C82EF7DE65A3C3FDC9BBA6EE019030C601860C626D41949DC9DEAC2 383 | 827805AD6C36365E354126015E5383A6EA28D65D3D1B2F7A45F8013C67805CF8 384 | F3986974E24E4DC3D7B46E4C1EAB57F08A09A8B5D3824CE1303609E1D7CF5CED 385 | DDE5F83D6D8001F87644D1217A851416335D94091D13E4474370D30421A0371C 386 | C2D658185BAA6AD1F8A97B9172BBC68F852F0C900B7F031568C33C238145DCC0 387 | FC8C8699715D4C6773BE8913262055C514CEA08597454BDF5511C18BB55568CA 388 | 5D84D10FF8CE000388B182F96F371A30151A6E3432B8C1D031370DCC462FAA8F 389 | 74013D7DD6ACFE421B2CD11E3B31864444C1FBA2A5BF1D51B18785F03B73D5ED 390 | 076078BDA58F846F0D301CA6299E41D8C8629A183A5E73E0006666B298AE734C 391 | 111F7F52D3318933D42A6954F585118DCBEF4F35BB328BB411452FE3E80CA9E6 392 | 6EAAA7CD7DF518DA62211C8946D03C7D0A5A71BB68F83E157B28C0FF032953D1 393 | 09FE65A60D0000000049454E44AE426082} 394 | FileName = 'C:\Users\Kamel\Desktop\download-ga42fd477b_640 (1).ico' 395 | end> 396 | Align = Top 397 | Size.Width = 60.000000000000000000 398 | Size.Height = 50.000000000000000000 399 | Size.PlatformDefault = False 400 | end 401 | end 402 | end 403 | object OpenDialog1: TOpenDialog 404 | Left = 544 405 | Top = 96 406 | end 407 | object Panel1: TPanel 408 | Align = Top 409 | Position.Y = 257.000000000000000000 410 | Size.Width = 596.000000000000000000 411 | Size.Height = 144.000000000000000000 412 | Size.PlatformDefault = False 413 | TabOrder = 1 414 | object Label9: TLabel 415 | Position.X = 9.000000000000000000 416 | Position.Y = 11.000000000000000000 417 | Size.Width = 80.000000000000000000 418 | Size.Height = 17.000000000000000000 419 | Size.PlatformDefault = False 420 | Text = 'Url Samples :' 421 | TabOrder = 9 422 | end 423 | object Label1: TLabel 424 | Position.X = 8.000000000000000000 425 | Position.Y = 85.000000000000000000 426 | Size.Width = 112.000000000000000000 427 | Size.Height = 24.000000000000000000 428 | Size.PlatformDefault = False 429 | Text = 'Number of Threads :' 430 | TabOrder = 6 431 | end 432 | object ComboBox1: TComboBox 433 | Items.Strings = ( 434 | '2' 435 | '4' 436 | '8' 437 | '16') 438 | ItemIndex = 2 439 | Position.X = 120.000000000000000000 440 | Position.Y = 88.000000000000000000 441 | Size.Width = 65.000000000000000000 442 | Size.Height = 22.000000000000000000 443 | Size.PlatformDefault = False 444 | TabOrder = 17 445 | OnChange = ComboBox1Change 446 | end 447 | object Button1: TButton 448 | Position.X = 258.000000000000000000 449 | Position.Y = 99.000000000000000000 450 | TabOrder = 2 451 | Text = 'Start' 452 | OnClick = Button1Click 453 | end 454 | object Button2: TButton 455 | Enabled = False 456 | Position.X = 347.000000000000000000 457 | Position.Y = 99.000000000000000000 458 | TabOrder = 4 459 | Text = 'Pause' 460 | OnClick = Button2Click 461 | end 462 | object Label2: TLabel 463 | Position.X = 9.000000000000000000 464 | Position.Y = 64.000000000000000000 465 | Size.Width = 96.000000000000000000 466 | Size.Height = 17.000000000000000000 467 | Size.PlatformDefault = False 468 | Text = 'Save location :' 469 | TabOrder = 7 470 | end 471 | object Edit2: TEdit 472 | Touch.InteractiveGestures = [LongTap, DoubleTap] 473 | TabOrder = 0 474 | ReadOnly = True 475 | Text = 476 | 'https://www.reaconverter.com/download/reaConverterStandard-Setup' + 477 | '.exe' 478 | Position.X = 104.000000000000000000 479 | Position.Y = 61.000000000000000000 480 | Enabled = False 481 | Size.Width = 457.000000000000000000 482 | Size.Height = 22.000000000000000000 483 | Size.PlatformDefault = False 484 | end 485 | object Button3: TButton 486 | Position.X = 561.000000000000000000 487 | Position.Y = 61.000000000000000000 488 | Size.Width = 24.000000000000000000 489 | Size.Height = 22.000000000000000000 490 | Size.PlatformDefault = False 491 | TabOrder = 1 492 | Text = '....' 493 | OnClick = Button3Click 494 | end 495 | object Label6: TLabel 496 | Position.X = 7.000000000000000000 497 | Position.Y = 110.000000000000000000 498 | Size.Width = 89.000000000000000000 499 | Size.Height = 24.000000000000000000 500 | Size.PlatformDefault = False 501 | Text = 'Progress Style :' 502 | TabOrder = 5 503 | end 504 | object ComboBox2: TComboBox 505 | Items.Strings = ( 506 | 'Arcs and Pies' 507 | 'Arcs Only' 508 | 'Pies Only') 509 | ItemIndex = 0 510 | Position.X = 119.000000000000000000 511 | Position.Y = 114.000000000000000000 512 | Size.Width = 108.000000000000000000 513 | Size.Height = 22.000000000000000000 514 | Size.PlatformDefault = False 515 | TabOrder = 3 516 | OnChange = ComboBox2Change 517 | end 518 | object Button4: TButton 519 | Position.X = 464.000000000000000000 520 | Position.Y = 98.000000000000000000 521 | Size.Width = 121.000000000000000000 522 | Size.Height = 22.000000000000000000 523 | Size.PlatformDefault = False 524 | TabOrder = 18 525 | Text = 'Mask details <<' 526 | OnClick = Button4Click 527 | end 528 | object ComboBox3: TComboBox 529 | Items.Strings = ( 530 | 531 | 'http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflo' + 532 | 'wer_1080p_30fps_normal.mp4' 533 | 534 | 'https://downloads.realvnc.com/download/file/vnc.files/VNC-Server' + 535 | '-6.9.1-Windows.exe?_gda=2.224252188.641449548.1654009827-21240' 536 | 'https://github.com/kamel78/DBPL/archive/refs/heads/master.zip') 537 | Position.X = 96.000000000000000000 538 | Position.Y = 9.000000000000000000 539 | Size.Width = 489.000000000000000000 540 | Size.Height = 22.000000000000000000 541 | Size.PlatformDefault = False 542 | TabOrder = 19 543 | OnChange = ComboBox3Change 544 | end 545 | object Label7: TLabel 546 | Position.X = 9.000000000000000000 547 | Position.Y = 36.000000000000000000 548 | Size.Width = 33.000000000000000000 549 | Size.Height = 17.000000000000000000 550 | Size.PlatformDefault = False 551 | Text = 'URL :' 552 | TabOrder = 8 553 | end 554 | object Edit1: TEdit 555 | Touch.InteractiveGestures = [LongTap, DoubleTap] 556 | TabOrder = 20 557 | Position.X = 40.000000000000000000 558 | Position.Y = 35.000000000000000000 559 | Size.Width = 545.000000000000000000 560 | Size.Height = 22.000000000000000000 561 | Size.PlatformDefault = False 562 | end 563 | end 564 | object Layout12: TLayout 565 | Align = Client 566 | Size.Width = 596.000000000000000000 567 | Size.Height = 220.000000000000000000 568 | Size.PlatformDefault = False 569 | TabOrder = 3 570 | object StringGrid1: TStringGrid 571 | Align = Client 572 | CanFocus = True 573 | ClipChildren = True 574 | Size.Width = 596.000000000000000000 575 | Size.Height = 220.000000000000000000 576 | Size.PlatformDefault = False 577 | TabOrder = 0 578 | RowCount = 0 579 | Viewport.Width = 592.000000000000000000 580 | Viewport.Height = 195.000000000000000000 581 | object StringColumn1: TStringColumn 582 | Size.Width = 41.000000000000000000 583 | end 584 | object StringColumn2: TStringColumn 585 | end 586 | object StringColumn3: TStringColumn 587 | Size.Width = 178.000000000000000000 588 | end 589 | object StringColumn4: TStringColumn 590 | Size.Width = 247.000000000000000000 591 | end 592 | end 593 | end 594 | end 595 | -------------------------------------------------------------------------------- /Demo/MainForm.pas: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamel78/Multi-Threading-Advanced-Http-Downloader/318cbd18f6515799eb7c33fa8f0f22d3bd5dd282/Demo/MainForm.pas -------------------------------------------------------------------------------- /Demo/MultiCircularProgress.pas: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamel78/Multi-Threading-Advanced-Http-Downloader/318cbd18f6515799eb7c33fa8f0f22d3bd5dd282/Demo/MultiCircularProgress.pas -------------------------------------------------------------------------------- /Demo/__history/HttpDownloadDemo.dpr.~1~: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------- 2 | 3 | // This software is Copyright (c) 2015 Embarcadero Technologies, Inc. 4 | // You may only use this software if you are an authorized licensee 5 | // of an Embarcadero developer tools product. 6 | // This software is considered a Redistributable as defined under 7 | // the software license agreement that comes with the Embarcadero Products 8 | // and is subject to that software license agreement. 9 | 10 | //--------------------------------------------------------------------------- 11 | 12 | program HttpDownloadDemo; 13 | 14 | uses 15 | System.StartUpCopy, 16 | FMX.Forms, 17 | MultiCircularProgress in 'MultiCircularProgress.pas', 18 | ThredingFileDownloader in 'ThredingFileDownloader.pas', 19 | MainForm in 'MainForm.pas' {Form1}; 20 | 21 | {$R *.res} 22 | 23 | begin 24 | Application.Initialize; 25 | Application.CreateForm(TForm1, Form1); 26 | Application.Run; 27 | end. 28 | -------------------------------------------------------------------------------- /DemoCapture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamel78/Multi-Threading-Advanced-Http-Downloader/318cbd18f6515799eb7c33fa8f0f22d3bd5dd282/DemoCapture.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Faraoun Kamel Mohamed 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Package/HttpParallelDownloader.dpk: -------------------------------------------------------------------------------- 1 | package HttpParallelDownloader; 2 | 3 | {$R *.res} 4 | {$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} 5 | {$ALIGN 8} 6 | {$ASSERTIONS ON} 7 | {$BOOLEVAL OFF} 8 | {$DEBUGINFO OFF} 9 | {$EXTENDEDSYNTAX ON} 10 | {$IMPORTEDDATA ON} 11 | {$IOCHECKS ON} 12 | {$LOCALSYMBOLS ON} 13 | {$LONGSTRINGS ON} 14 | {$OPENSTRINGS ON} 15 | {$OPTIMIZATION OFF} 16 | {$OVERFLOWCHECKS OFF} 17 | {$RANGECHECKS OFF} 18 | {$REFERENCEINFO ON} 19 | {$SAFEDIVIDE OFF} 20 | {$STACKFRAMES ON} 21 | {$TYPEDADDRESS OFF} 22 | {$VARSTRINGCHECKS ON} 23 | {$WRITEABLECONST OFF} 24 | {$MINENUMSIZE 1} 25 | {$IMAGEBASE $400000} 26 | {$DEFINE DEBUG} 27 | {$ENDIF IMPLICITBUILDING} 28 | {$IMPLICITBUILD ON} 29 | 30 | requires 31 | rtl; 32 | 33 | contains 34 | ThredingFileDownloader in 'ThredingFileDownloader.pas'; 35 | 36 | end. 37 | -------------------------------------------------------------------------------- /Package/HttpParallelDownloader.dproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | {7C82F406-AC23-4785-8CA7-A16BBEFFEB24} 4 | HttpParallelDownloader.dpk 5 | 18.7 6 | FMX 7 | True 8 | Debug 9 | Win32 10 | 1 11 | Package 12 | 13 | 14 | true 15 | 16 | 17 | true 18 | Base 19 | true 20 | 21 | 22 | true 23 | Base 24 | true 25 | 26 | 27 | true 28 | Base 29 | true 30 | 31 | 32 | true 33 | Base 34 | true 35 | 36 | 37 | true 38 | Base 39 | true 40 | 41 | 42 | true 43 | Base 44 | true 45 | 46 | 47 | true 48 | Cfg_1 49 | true 50 | true 51 | 52 | 53 | true 54 | Base 55 | true 56 | 57 | 58 | .\$(Platform)\$(Config) 59 | .\$(Platform)\$(Config) 60 | false 61 | false 62 | false 63 | false 64 | false 65 | true 66 | true 67 | System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) 68 | All 69 | HttpParallelDownloader 70 | 71 | 72 | None 73 | android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar 74 | 75 | 76 | None 77 | 78 | 79 | None 80 | 81 | 82 | None 83 | 84 | 85 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) 86 | Debug 87 | true 88 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= 89 | 1033 90 | 91 | 92 | DEBUG;$(DCC_Define) 93 | true 94 | false 95 | true 96 | true 97 | true 98 | 99 | 100 | false 101 | 102 | 103 | false 104 | RELEASE;$(DCC_Define) 105 | 0 106 | 0 107 | 108 | 109 | 110 | MainSource 111 | 112 | 113 | 114 | 115 | Cfg_2 116 | Base 117 | 118 | 119 | Base 120 | 121 | 122 | Cfg_1 123 | Base 124 | 125 | 126 | 127 | Delphi.Personality.12 128 | Package 129 | 130 | 131 | 132 | HttpParallelDownloader.dpk 133 | 134 | 135 | 136 | 137 | 138 | true 139 | 140 | 141 | 142 | 143 | true 144 | 145 | 146 | 147 | 148 | true 149 | 150 | 151 | 152 | 153 | HttpParallelDownloader.bpl 154 | true 155 | 156 | 157 | 158 | 159 | 1 160 | 161 | 162 | 0 163 | 164 | 165 | 166 | 167 | classes 168 | 1 169 | 170 | 171 | 172 | 173 | res\xml 174 | 1 175 | 176 | 177 | 178 | 179 | library\lib\armeabi-v7a 180 | 1 181 | 182 | 183 | 184 | 185 | library\lib\armeabi 186 | 1 187 | 188 | 189 | 190 | 191 | library\lib\mips 192 | 1 193 | 194 | 195 | 196 | 197 | library\lib\armeabi-v7a 198 | 1 199 | 200 | 201 | 202 | 203 | res\drawable 204 | 1 205 | 206 | 207 | 208 | 209 | res\values 210 | 1 211 | 212 | 213 | 214 | 215 | res\values-v21 216 | 1 217 | 218 | 219 | 220 | 221 | res\values 222 | 1 223 | 224 | 225 | 226 | 227 | res\drawable 228 | 1 229 | 230 | 231 | 232 | 233 | res\drawable-xxhdpi 234 | 1 235 | 236 | 237 | 238 | 239 | res\drawable-ldpi 240 | 1 241 | 242 | 243 | 244 | 245 | res\drawable-mdpi 246 | 1 247 | 248 | 249 | 250 | 251 | res\drawable-hdpi 252 | 1 253 | 254 | 255 | 256 | 257 | res\drawable-xhdpi 258 | 1 259 | 260 | 261 | 262 | 263 | res\drawable-mdpi 264 | 1 265 | 266 | 267 | 268 | 269 | res\drawable-hdpi 270 | 1 271 | 272 | 273 | 274 | 275 | res\drawable-xhdpi 276 | 1 277 | 278 | 279 | 280 | 281 | res\drawable-xxhdpi 282 | 1 283 | 284 | 285 | 286 | 287 | res\drawable-xxxhdpi 288 | 1 289 | 290 | 291 | 292 | 293 | res\drawable-small 294 | 1 295 | 296 | 297 | 298 | 299 | res\drawable-normal 300 | 1 301 | 302 | 303 | 304 | 305 | res\drawable-large 306 | 1 307 | 308 | 309 | 310 | 311 | res\drawable-xlarge 312 | 1 313 | 314 | 315 | 316 | 317 | res\values 318 | 1 319 | 320 | 321 | 322 | 323 | 1 324 | 325 | 326 | 1 327 | 328 | 329 | 0 330 | 331 | 332 | 333 | 334 | 1 335 | .framework 336 | 337 | 338 | 1 339 | .framework 340 | 341 | 342 | 0 343 | 344 | 345 | 346 | 347 | 1 348 | .dylib 349 | 350 | 351 | 1 352 | .dylib 353 | 354 | 355 | 0 356 | .dll;.bpl 357 | 358 | 359 | 360 | 361 | 1 362 | .dylib 363 | 364 | 365 | 1 366 | .dylib 367 | 368 | 369 | 1 370 | .dylib 371 | 372 | 373 | 1 374 | .dylib 375 | 376 | 377 | 1 378 | .dylib 379 | 380 | 381 | 0 382 | .bpl 383 | 384 | 385 | 386 | 387 | 0 388 | 389 | 390 | 0 391 | 392 | 393 | 0 394 | 395 | 396 | 0 397 | 398 | 399 | 0 400 | 401 | 402 | 0 403 | 404 | 405 | 0 406 | 407 | 408 | 409 | 410 | 1 411 | 412 | 413 | 1 414 | 415 | 416 | 1 417 | 418 | 419 | 420 | 421 | 1 422 | 423 | 424 | 1 425 | 426 | 427 | 1 428 | 429 | 430 | 431 | 432 | 1 433 | 434 | 435 | 1 436 | 437 | 438 | 1 439 | 440 | 441 | 442 | 443 | 1 444 | 445 | 446 | 1 447 | 448 | 449 | 1 450 | 451 | 452 | 453 | 454 | 1 455 | 456 | 457 | 1 458 | 459 | 460 | 1 461 | 462 | 463 | 464 | 465 | 1 466 | 467 | 468 | 1 469 | 470 | 471 | 1 472 | 473 | 474 | 475 | 476 | 1 477 | 478 | 479 | 1 480 | 481 | 482 | 1 483 | 484 | 485 | 486 | 487 | 1 488 | 489 | 490 | 1 491 | 492 | 493 | 1 494 | 495 | 496 | 497 | 498 | 1 499 | 500 | 501 | 1 502 | 503 | 504 | 1 505 | 506 | 507 | 508 | 509 | 1 510 | 511 | 512 | 1 513 | 514 | 515 | 1 516 | 517 | 518 | 519 | 520 | 1 521 | 522 | 523 | 1 524 | 525 | 526 | 1 527 | 528 | 529 | 530 | 531 | 1 532 | 533 | 534 | 1 535 | 536 | 537 | 1 538 | 539 | 540 | 541 | 542 | 1 543 | 544 | 545 | 1 546 | 547 | 548 | 1 549 | 550 | 551 | 552 | 553 | 1 554 | 555 | 556 | 1 557 | 558 | 559 | 1 560 | 561 | 562 | 563 | 564 | 1 565 | 566 | 567 | 1 568 | 569 | 570 | 1 571 | 572 | 573 | 574 | 575 | 1 576 | 577 | 578 | 1 579 | 580 | 581 | 1 582 | 583 | 584 | 585 | 586 | 1 587 | 588 | 589 | 1 590 | 591 | 592 | 1 593 | 594 | 595 | 596 | 597 | 1 598 | 599 | 600 | 1 601 | 602 | 603 | 1 604 | 605 | 606 | 607 | 608 | 1 609 | 610 | 611 | 1 612 | 613 | 614 | 1 615 | 616 | 617 | 618 | 619 | 1 620 | 621 | 622 | 1 623 | 624 | 625 | 1 626 | 627 | 628 | 629 | 630 | 1 631 | 632 | 633 | 1 634 | 635 | 636 | 1 637 | 638 | 639 | 640 | 641 | 1 642 | 643 | 644 | 1 645 | 646 | 647 | 1 648 | 649 | 650 | 651 | 652 | 1 653 | 654 | 655 | 1 656 | 657 | 658 | 1 659 | 660 | 661 | 662 | 663 | 1 664 | 665 | 666 | 1 667 | 668 | 669 | 1 670 | 671 | 672 | 673 | 674 | 1 675 | 676 | 677 | 678 | 679 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 680 | 1 681 | 682 | 683 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 684 | 1 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 1 693 | 694 | 695 | 1 696 | 697 | 698 | 1 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | Contents\Resources 707 | 1 708 | 709 | 710 | Contents\Resources 711 | 1 712 | 713 | 714 | 715 | 716 | library\lib\armeabi-v7a 717 | 1 718 | 719 | 720 | 1 721 | 722 | 723 | 1 724 | 725 | 726 | 1 727 | 728 | 729 | 1 730 | 731 | 732 | 1 733 | 734 | 735 | 1 736 | 737 | 738 | 0 739 | 740 | 741 | 742 | 743 | 1 744 | 745 | 746 | 1 747 | 748 | 749 | 750 | 751 | Assets 752 | 1 753 | 754 | 755 | Assets 756 | 1 757 | 758 | 759 | 760 | 761 | Assets 762 | 1 763 | 764 | 765 | Assets 766 | 1 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | False 781 | False 782 | False 783 | False 784 | False 785 | False 786 | False 787 | True 788 | False 789 | 790 | 791 | 12 792 | 793 | 794 | 795 | 796 | 797 | -------------------------------------------------------------------------------- /Package/HttpParallelDownloader.dproj.local: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 2022/06/01 20:46:35.136,=rtl.dcp 5 | 2022/06/01 20:47:13.713,C:\Users\neptune\Desktop\HttpDownload\Package\HttpParallelDownloader.dproj=C:\Users\neptune\Documents\Embarcadero\Studio\Projets\Package1.dproj 6 | 2022/06/01 20:50:38.107,=C:\Users\neptune\Desktop\HttpDownload\Package\ThredingFileDownloader.pas 7 | 8 | 9 | -------------------------------------------------------------------------------- /Package/HttpParallelDownloader.identcache: -------------------------------------------------------------------------------- 1 | HC:\Users\neptune\Desktop\HttpDownload\Package\ThredingFileDownloader.pas@C:\Users\neptune\Desktop\HttpDownload\ThredingFileDownloader.pas -------------------------------------------------------------------------------- /Package/HttpParallelDownloader.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamel78/Multi-Threading-Advanced-Http-Downloader/318cbd18f6515799eb7c33fa8f0f22d3bd5dd282/Package/HttpParallelDownloader.res -------------------------------------------------------------------------------- /Package/ThredingFileDownloader.pas: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamel78/Multi-Threading-Advanced-Http-Downloader/318cbd18f6515799eb7c33fa8f0f22d3bd5dd282/Package/ThredingFileDownloader.pas -------------------------------------------------------------------------------- /Package/__history/HttpParallelDownloader.dpk.~1~: -------------------------------------------------------------------------------- 1 | package HttpParallelDownloader; 2 | 3 | {$R *.res} 4 | {$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} 5 | {$ALIGN 8} 6 | {$ASSERTIONS ON} 7 | {$BOOLEVAL OFF} 8 | {$DEBUGINFO OFF} 9 | {$EXTENDEDSYNTAX ON} 10 | {$IMPORTEDDATA ON} 11 | {$IOCHECKS ON} 12 | {$LOCALSYMBOLS ON} 13 | {$LONGSTRINGS ON} 14 | {$OPENSTRINGS ON} 15 | {$OPTIMIZATION OFF} 16 | {$OVERFLOWCHECKS OFF} 17 | {$RANGECHECKS OFF} 18 | {$REFERENCEINFO ON} 19 | {$SAFEDIVIDE OFF} 20 | {$STACKFRAMES ON} 21 | {$TYPEDADDRESS OFF} 22 | {$VARSTRINGCHECKS ON} 23 | {$WRITEABLECONST OFF} 24 | {$MINENUMSIZE 1} 25 | {$IMAGEBASE $400000} 26 | {$DEFINE DEBUG} 27 | {$ENDIF IMPLICITBUILDING} 28 | {$IMPLICITBUILD ON} 29 | 30 | requires 31 | rtl; 32 | 33 | end. 34 | -------------------------------------------------------------------------------- /Package/__history/ThredingFileDownloader.pas.~1~: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamel78/Multi-Threading-Advanced-Http-Downloader/318cbd18f6515799eb7c33fa8f0f22d3bd5dd282/Package/__history/ThredingFileDownloader.pas.~1~ -------------------------------------------------------------------------------- /Package/__history/ThredingFileDownloader.pas.~2~: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamel78/Multi-Threading-Advanced-Http-Downloader/318cbd18f6515799eb7c33fa8f0f22d3bd5dd282/Package/__history/ThredingFileDownloader.pas.~2~ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Multi Threading Advanced Http Downloader 2 | 3 | TThredingFileDownloader 4 | 5 | An Embarcadero Rad Studio/Delphi component (FMX) for parallelized http/https files downloading. Download is parallelized using variable number of threads for acceleration. Several additional options are implemented including: 6 | - Pause/Resume of the download task at any progress phase. It is far away from a simple a threads suspension, while an internal progression state is automatically saved so the resume can be performed either is the application is close and restarted (a method ResumeFromTempFile permit to restart the download again at any time). 7 | - Automatic estimation of download speed (instant speed) and remaining time. 8 | - A sufficiently large set of event permitting a powerful control of the download progression : OnThredDownloadingData, OnDownloadTerminated, OnDownloadError, OnDownloadInfoUpdate, OnDownloadStarted, OnDownloadPaused, OnCannotResume, OnDownloadResumed, OnDownloadCanceled 9 | - Detailed download information per individual thread 10 | 11 | The included Demo program illustrate the use of the component conjointly with a special progress bar developed for such applications (installation of the package is not necessary to Run the Demo since the creation of the objects is done explicitly in the code). 12 | Tested on Rad 10.2/10.3 and should work for 10.4 and Alexandria. 13 | Designed for FMX Multi-resolution applications (Windows, Android and Mac …) 14 | 15 | Remarks and bugs report are welcome. 16 | 17 | 18 | 19 | 20 | ![plot](https://github.com/kamel78/Multi-Threading-Advanced-Http-Downloader-/blob/main/DemoCapture.png) 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /ThredingFileDownloader.pas: -------------------------------------------------------------------------------- 1 | unit ThredingFileDownloader; 2 | 3 | {******************************************************************************************** 4 | Développer par Faraoun Kamel Mohamed 5 | Université Djilali Liabes -Sidi Bel Abbes - Algérie 6 | kamel_mh@yahoo.fr 7 | 8 | Multi-Thread Http Downloader component for FMX:Windows/Android/Mac... 9 | 01 June 2022 10 | ********************************************************************************************} 11 | 12 | 13 | interface 14 | 15 | uses System.Net.HttpClient,System.Classes,System.SysUtils,FMX.Types,System.SyncObjs,FMX.Forms,System.NetEncoding,System.ioutils; 16 | 17 | Type 18 | 19 | TSaveDownloadTrackState=Record 20 | tStart,tEnd, 21 | tProgress:Int64; 22 | End; 23 | TSaveDownloadState=array of TSaveDownloadTrackState; 24 | TDownloadThreadDataEvent = procedure(const Sender: TObject; ThreadNo, ASpeed: Integer;AReadCount: Int64; APercentage:Double; var Abort: Boolean) of object; 25 | TDownloadInfoUpdateEvent=procedure(const Sender: TObject;AverageSpeed:Double;DownloadedAmount:Int64;DownloadedPercentage:Double;EstimatedReminingTime:Int64)of object; 26 | TFilenameChangedEvent=procedure(const Sender:TObject;Oldname:string;NewName:string)of object; 27 | TCannotResumeInfo=procedure(Const Sender: TObject;var cancel:boolean)of object; 28 | TTrackDownloader = class(TThread) 29 | private 30 | FOnThreadData: TDownloadThreadDataEvent; 31 | protected 32 | FURL, FFileName: string; 33 | FStartPoint, FEndPoint: Int64; 34 | FThreadNo: Integer; 35 | FTimeStart: Cardinal; 36 | FThSaveState:TSaveDownloadState; 37 | FFileSize:Int64; 38 | procedure ReceiveDataEvent(const Sender: TObject; AContentLength: Int64; AReadCount: Int64; var Abort: Boolean); 39 | public 40 | constructor Create(const URL, FileName: string; ThreadNo: Integer; StartPoint, EndPoint: Int64); 41 | destructor Destroy; override; 42 | procedure Execute; override; 43 | property OnThreadData: TDownloadThreadDataEvent write FOnThreadData; 44 | end; 45 | 46 | TThredingFileDownloader= class 47 | private 48 | FDownloadThreads: array of TTrackDownloader; 49 | FCriticalSection:TCriticalSection; 50 | FThreadsDownloadedAmout:array of Int64; 51 | FDownloadedAmount:Int64; 52 | [volatile]FIncrementTester:Int64; 53 | FDownloadedPerCentage:Double; 54 | [volatile]FDownloadSpeed:Double; 55 | FEstimatedRemainingTime:Int64; 56 | FNumOfThreads,FDefaultNumOfThreads:integer; 57 | [volatile]FFinished:boolean; 58 | [volatile]FStopDownload: Boolean; 59 | FIsDownloading:boolean; 60 | FFileSize:int64; 61 | FCanResume:boolean; 62 | FFilename,FUrl:String; 63 | FSaveStateStream:TFileStream; 64 | FOnDownloadThreadData:TDownloadThreadDataEvent; 65 | FONDownloadStarted,FOnDownloadTerminated, 66 | FOnDownloadPaused,FOnDownloadResumed, 67 | FOnDownloadError,FOnDownloadCanceled:TNotifyEvent; 68 | FOnDownloadInfoUpdate:TDownloadInfoUpdateEvent; 69 | FOnCannotResume:TCannotResumeInfo; 70 | FonFilenameChanged:TFilenameChangedEvent; 71 | FSpeedCalculator:TTimer; // Used to compute 72 | FStartingDownload,FEndingDownload:Int64; // true instant download speed 73 | FStartingTime,FEndingTime:Cardinal; 74 | FSaveResumeProgress:TSaveDownloadState; 75 | FOutputPath:string; 76 | procedure ThreadReceiveDataHandler(const Sender: TObject; ThreadNo, ASpeed: Integer;AReadCount: Int64; APercentage:Double; var Abort: Boolean); 77 | procedure SpeedCalculatorEvent(Sender:Tobject); 78 | procedure _DoDownload(AskForResume:boolean=True); 79 | procedure _SaveDownloadState; 80 | procedure _SaveDownloadInfo; 81 | function _LoadDownloadState(wFilename:string):boolean; 82 | function _LoadDownloadInfo(wFilename: string):boolean; 83 | procedure _ResumeDownload; 84 | function _IndirectlyGetFileSize(wUrl:string):int64; 85 | procedure _IndirecrReceiveDataEvent(const Sender: TObject; AContentLength:Int64; AReadCount: Int64; var Abort: Boolean); 86 | function _CleanURL(wURL:string):string; 87 | public 88 | constructor Create; 89 | destructor destroy;override; 90 | procedure DoDownload; 91 | procedure PauseDownload; 92 | procedure ResumeDownload; 93 | procedure CancelDownload; 94 | function StandarizedSize(value:Int64):string; 95 | function ResumeFromTempFile(wFilename:String):integer; 96 | property NumOfThreads:integer read FDefaultNumOfThreads write FDefaultNumOfThreads default 4; 97 | property Filename:string read FFilename; 98 | property URL:string read FUrl write FUrl; 99 | property OnThredDownloadingData:TDownloadThreadDataEvent read FOnDownloadThreadData write FOnDownloadThreadData; 100 | property OnDownloadTerminated:TNotifyEvent read FOnDownloadTerminated write FOnDownloadTerminated; 101 | property OnDownloadError:TNotifyEvent read FOnDownloadError write FOnDownloadError; 102 | property OnDownloadInfoUpdate:TDownloadInfoUpdateEvent read FOnDownloadInfoUpdate write FOnDownloadInfoUpdate; 103 | property OnDownloadStarted :TNotifyEvent read FONDownloadStarted write FONDownloadStarted; 104 | property OnDownloadPaused:TNotifyEvent read FOnDownloadPaused write FOnDownloadPaused; 105 | property OnDownloadResumed:TNotifyEvent read FOnDownloadResumed write FOnDownloadResumed; 106 | property OnCannotResume:TCannotResumeInfo read FOnCannotResume write FOnCannotResume; 107 | property OnDownloadCanceled:TNotifyEvent read FOnDownloadCanceled write FOnDownloadCanceled; 108 | property ActiveFileSize:int64 read FFileSize; 109 | property OutputPath:string read FOutputPath write FOutputPath; 110 | property IsDownloading:boolean read FIsDownloading; 111 | property IsResumeSupported:boolean read FCanResume; 112 | end; 113 | 114 | 115 | implementation 116 | uses MainForm; 117 | { TThredingFileDownloader } 118 | 119 | ///*******************************************************************************************************************************************************// 120 | constructor TThredingFileDownloader.Create; 121 | begin 122 | FDefaultNumOfThreads:=4; 123 | FFinished:=False; 124 | FStopDownload:=False; 125 | FDownloadedAmount:=0; 126 | FDownloadedPerCentage:=0; 127 | FDownloadSpeed:=0; 128 | FSpeedCalculator:=TTimer.Create(nil); 129 | FSpeedCalculator.Parent:=nil; 130 | FSpeedCalculator.Interval:=2000; 131 | FSpeedCalculator.OnTimer:=SpeedCalculatorEvent; 132 | Setlength(FSaveResumeProgress,0); 133 | FOutputPath:=ExtractFilePath(ParamStr(0)); 134 | end; 135 | 136 | ///*******************************************************************************************************************************************************// 137 | function TThredingFileDownloader._CleanURL(wURL: string): string; 138 | var tmp:string; 139 | begin 140 | tmp:=wURL; 141 | if not UpperCase(tmp).StartsWith('HTTP') then begin 142 | Result:=''; 143 | exit; 144 | end; 145 | if pos('?',tmp)>0 then tmp:=Copy(tmp,1,Pos('?',tmp)-1); 146 | Result:=Tmp; 147 | end; 148 | 149 | ///*******************************************************************************************************************************************************// 150 | procedure TThredingFileDownloader._DoDownload; 151 | var wClient: THTTPClient; 152 | wResponse: IHTTPResponse; 153 | wStrmFile: TFileStream; 154 | wStart, wEnd, wSize, wFragSize: Int64; 155 | i: Integer; 156 | wFilename,zFilename:String; 157 | CancelDownload:boolean; 158 | begin 159 | wClient := THTTPClient.Create; 160 | wResponse := wClient.Head(FURL); 161 | if wResponse.StatusCode<>200 then begin 162 | if Assigned(FOnDownloadError) then TThread.Synchronize(nil,procedure 163 | begin 164 | FOnDownloadError(Self); 165 | end); 166 | exit; 167 | end; 168 | FStartingTime:=TThread.GetTickCount; 169 | FStartingDownload:=0; 170 | FCriticalSection:=TCriticalSection.Create; 171 | try 172 | try 173 | FURL:=_CleanURL(FURL); 174 | if FURL='' then begin 175 | raise Exception.Create('Invalid Url for download, only http/https protocols are supported .....'); 176 | exit; 177 | end; 178 | FCanResume:=wClient.CheckDownloadResume(FURL); 179 | if FCanResume then FNumOfThreads:=FDefaultNumOfThreads 180 | else begin 181 | FNumOfThreads:=1; 182 | CancelDownload:=False; 183 | if Assigned(FOnCannotResume)and AskForResume then TThread.Synchronize(nil,procedure begin FOnCannotResume(Self,CancelDownload);end); 184 | if CancelDownload then exit; 185 | end; 186 | wSize := wResponse.ContentLength; 187 | if wSize=-1 then wSize:=_IndirectlyGetFileSize(Furl); 188 | FFilename:=ExtractFileName(URL.Replace('/','\')); 189 | if wResponse.ContainsHeader('Content-Disposition') 190 | then wFilename:=wResponse.GetHeaderValue('Content-Disposition') 191 | else if wResponse.ContainsHeader('content-disposition') 192 | then wFilename:=wResponse.GetHeaderValue('content-disposition') 193 | else wFilename:=''; 194 | if wFilename<>'' then begin 195 | if pos('"',wFilename)>0 then wFilename:=wFilename.Split(['"'])[1] 196 | else wFilename:=wFilename.Split(['='])[1]; 197 | end; 198 | if wFilename<>'' then FFilename:=wFilename 199 | else if FFilename='' then raise Exception.Create('Unknown file name, download cannot be performed ...'); 200 | FFileSize:=wSize; 201 | SetLength(FDownloadThreads, FNumOfThreads); 202 | SetLength(FThreadsDownloadedAmout, FNumOfThreads); 203 | SetLength(FSaveResumeProgress, FNumOfThreads); 204 | wStrmFile := TFileStream.Create(FOutputPath+'_'+FFileName+'.temporary', fmCreate); 205 | try 206 | wStrmFile.Size := wSize+(FNumOfThreads*24+1)+(Length(TEncoding.UTF8.GetBytes(FURL))+2); 207 | finally 208 | wStrmFile.Free; 209 | end; 210 | FSaveStateStream:= TFileStream.Create(FOutputPath+'_'+FFileName+'.temporary', fmOpenWrite or fmShareDenyNone); 211 | _SaveDownloadInfo; 212 | wFragSize := wSize div FNumOfThreads; 213 | wStart := 0; 214 | wEnd := wStart + wFragSize; 215 | for i := 0 to FNumOfThreads-1 do begin 216 | if FFinished then Break; 217 | FThreadsDownloadedAmout[i]:=0; 218 | FDownloadThreads[I] := TTrackDownloader.Create(URL, FOutputPath+'_'+FFileName+'.temporary', i, wStart, wEnd); 219 | FDownloadThreads[I].OnThreadData := ThreadReceiveDataHandler; 220 | FDownloadThreads[I].FThSaveState:=FSaveResumeProgress; 221 | FDownloadThreads[I].FFileSize:=FFileSize; 222 | FSaveResumeProgress[I].tStart:=wStart; 223 | FSaveResumeProgress[I].tEnd:=wEnd; 224 | FSaveResumeProgress[i].tProgress:=0; 225 | wStart := wStart + wFragSize; 226 | wEnd := wStart + wFragSize; 227 | end; 228 | for i := 0 to FNumOfThreads-1 do FDownloadThreads[I].Start; 229 | FIsDownloading:=True; 230 | if Assigned(FONDownloadStarted) then TThread.Synchronize(nil,procedure begin FONDownloadStarted(Self);end); 231 | FSpeedCalculator.Enabled:=True; 232 | FFinished := False; 233 | while not FFinished do begin 234 | FFinished := True; 235 | for i := 0 to FNumOfThreads-1 do FFinished := FFinished and FDownloadThreads[I].Finished; 236 | end; 237 | FSpeedCalculator.Enabled:=False; 238 | FIsDownloading:=False; 239 | FFinished:=False; 240 | for i := 0 to FNumOfThreads-1 do FDownloadThreads[I].Free; 241 | SetLength(FDownloadThreads,0); 242 | SetLength(FThreadsDownloadedAmout,0); 243 | if not FStopDownload then begin 244 | SetLength(FSaveResumeProgress,0); 245 | if Assigned(FOnDownloadTerminated) then TThread.Synchronize(nil,procedure begin FOnDownloadTerminated(Self);end); 246 | end; 247 | Except 248 | if Assigned(FOnDownloadError) then TThread.Synchronize(nil,procedure begin FOnDownloadError(Self);end); 249 | end; 250 | finally 251 | wClient.Free; 252 | FCriticalSection.Free; 253 | if not CancelDownload then begin 254 | if not FStopDownload then FSaveStateStream.Size:=FSaveStateStream.Size-FNumOfThreads*24-1-Length(TEncoding.UTF8.GetBytes(FURL))-2; 255 | FSaveStateStream.Free; 256 | if not FStopDownload then begin 257 | i:=0; 258 | wFilename:=FFilename; 259 | zFilename:=FFilename; 260 | if FileExists(wFilename) then begin 261 | repeat 262 | i:=i+1; 263 | wFilename:=Tpath.GetFileNameWithoutExtension(FFilename)+i.ToString+ExtractFileExt(FFilename); 264 | until (not FileExists(wFilename)); 265 | RenameFile(FOutputPath+'_'+FFileName+'.temporary',FOutputPath+wFilename); 266 | FFilename:=wFilename; 267 | if Assigned(FonFilenameChanged) then TThread.Synchronize(nil,procedure 268 | begin 269 | FonFilenameChanged(Self,zFilename,FFilename); 270 | end); 271 | end 272 | else RenameFile(FOutputPath+'_'+FFileName+'.temporary',FOutputPath+FFilename); 273 | end; 274 | end; 275 | FStopDownload:=False; 276 | end; 277 | end; 278 | 279 | ///*******************************************************************************************************************************************************// 280 | procedure TThredingFileDownloader.CancelDownload; 281 | begin 282 | if not FIsDownloading then exit; 283 | FStopDownload:=True; 284 | Sleep(50); 285 | Repeat 286 | Application.ProcessMessages; 287 | until not FStopDownload; 288 | if Assigned(FOnDownloadCanceled) then FOnDownloadCanceled(Self); 289 | end; 290 | 291 | ///*******************************************************************************************************************************************************// 292 | procedure TThredingFileDownloader._ResumeDownload; 293 | var wClient: THTTPClient; 294 | wResponse: IHTTPResponse; 295 | wStrmFile: TFileStream; 296 | wStart, wEnd, wSize, wFragSize: Int64; 297 | i: Integer; 298 | wFilename,zFilename:String; 299 | cancel:boolean; 300 | begin 301 | wClient := THTTPClient.Create; 302 | FStartingTime:=TThread.GetTickCount; 303 | FStartingDownload:=0; 304 | FCriticalSection:=TCriticalSection.Create; 305 | try 306 | try 307 | if FCanResume then begin 308 | FNumOfThreads:=length(FSaveResumeProgress); 309 | wFragSize := wSize div FNumOfThreads; 310 | SetLength(FDownloadThreads, FNumOfThreads); 311 | SetLength(FThreadsDownloadedAmout, FNumOfThreads); 312 | for i := 0 to FNumOfThreads-1 do 313 | begin 314 | if FFinished then Break; 315 | FDownloadThreads[I] := TTrackDownloader.Create(URL, FOutputPath+'_'+FFileName+'.temporary', i, FSaveResumeProgress[i].tStart+FSaveResumeProgress[i].tProgress, FSaveResumeProgress[i].tEnd); 316 | FDownloadThreads[I].OnThreadData := ThreadReceiveDataHandler; 317 | FDownloadThreads[I].FThSaveState:=FSaveResumeProgress; 318 | FDownloadThreads[I].FFileSize:=FFileSize; 319 | end; 320 | FSaveStateStream:= TFileStream.Create(FOutputPath+'_'+FFileName+'.temporary', fmOpenWrite or fmShareDenyNone); 321 | for i := 0 to FNumOfThreads-1 do FDownloadThreads[I].Start; 322 | if Assigned(FOnDownloadResumed) then TThread.Synchronize(nil,procedure begin FOnDownloadResumed(Self);end); 323 | FSpeedCalculator.Enabled:=True; 324 | FFinished := False; 325 | while not FFinished do 326 | begin 327 | FFinished := True; 328 | for i := 0 to FNumOfThreads-1 do FFinished := FFinished and FDownloadThreads[I].Finished; 329 | end; 330 | FSpeedCalculator.Enabled:=False; 331 | for i := 0 to FNumOfThreads-1 do FDownloadThreads[I].Free; 332 | FIsDownloading:=False; 333 | FFinished:=False; 334 | if not FStopDownload then 335 | if Assigned(FOnDownloadTerminated) then TThread.Synchronize(nil,procedure begin FOnDownloadTerminated(Self);end); 336 | end 337 | else begin 338 | Cancel:=true; 339 | if Assigned(FOnCannotResume) then TThread.Synchronize(nil,procedure begin FOnCannotResume(Self,Cancel);end); 340 | if not cancel then _DoDownload(False); 341 | end; 342 | Except 343 | if Assigned(FOnDownloadError) then FOnDownloadError(Self); 344 | end; 345 | finally 346 | wClient.Free; 347 | FCriticalSection.Free; 348 | if not FStopDownload then FSaveStateStream.Size:=FSaveStateStream.Size-FNumOfThreads*24-1-Length(TEncoding.UTF8.GetBytes(FURL))-2; 349 | FSaveStateStream.Free; 350 | if not FStopDownload then begin 351 | i:=0; 352 | wFilename:=FFilename; 353 | zFilename:=FFilename; 354 | if FileExists(wFilename) then begin 355 | repeat 356 | i:=i+1; 357 | wFilename:=Tpath.GetFileNameWithoutExtension(FFilename)+i.ToString+ExtractFileExt(FFilename); 358 | until (not FileExists(wFilename)); 359 | RenameFile('_'+FFileName+'.temporary',wFilename); 360 | FFilename:=wFilename; 361 | if Assigned(FonFilenameChanged) then TThread.Synchronize(nil,procedure 362 | begin 363 | FonFilenameChanged(Self,zFilename,FFilename); 364 | end); 365 | end 366 | else RenameFile('_'+FFileName+'.temporary',FFilename); 367 | 368 | end; 369 | FStopDownload:=False; 370 | end; 371 | end; 372 | 373 | ///*******************************************************************************************************************************************************// 374 | procedure TThredingFileDownloader._SaveDownloadInfo; 375 | var Tmp:TBytes; 376 | wSaveResumeInfo:TSaveDownloadState; 377 | i:integer; 378 | wLength:Word; 379 | begin 380 | Tmp:=TEncoding.UTF8.GetBytes(FURL); 381 | wLength:=Length(Tmp); 382 | Setlength(Tmp,Length(Tmp)+2); 383 | Tmp[Length(Tmp)-2]:=Hi(wLength); 384 | Tmp[Length(Tmp)-1]:=Lo(wLength); 385 | try 386 | FSaveStateStream.Seek(FFileSize, TSeekOrigin.soBeginning); 387 | FSaveStateStream.Write(Tmp,length(Tmp)); 388 | finally 389 | end; 390 | end; 391 | 392 | ///*******************************************************************************************************************************************************// 393 | procedure TThredingFileDownloader._SaveDownloadState; 394 | var Tmp:TBytes; 395 | wSaveResumeProgress:TSaveDownloadState; 396 | i:integer; 397 | begin 398 | Setlength(wSaveResumeProgress,length(FSaveResumeProgress)); 399 | for i:=0 to Length(FSaveResumeProgress)-1 do begin 400 | wSaveResumeProgress[i].tStart:=FSaveResumeProgress[i].tStart; 401 | wSaveResumeProgress[i].tEnd:=FSaveResumeProgress[i].tEnd; 402 | wSaveResumeProgress[i].tProgress:=FThreadsDownloadedAmout[i]; 403 | end; 404 | 405 | SetLength(Tmp,length(wSaveResumeProgress)*24+1); 406 | Tmp[length(Tmp)-1]:=length(FSaveResumeProgress); 407 | Move(wSaveResumeProgress[0],Tmp[0],Length(Tmp)-1); 408 | try 409 | FSaveStateStream.Seek(FFileSize+Length(TEncoding.UTF8.GetBytes(FURL))+2, TSeekOrigin.soBeginning); 410 | FSaveStateStream.Write(Tmp,length(Tmp)); 411 | finally 412 | end; 413 | end; 414 | 415 | ///*******************************************************************************************************************************************************// 416 | function TThredingFileDownloader._LoadDownloadState(wFilename: string):boolean; 417 | var LStream: TFileStream; 418 | Tmp:TBytes; 419 | begin 420 | SetLength(Tmp,1); 421 | Result:=True; 422 | Setlength(FSaveResumeProgress,0); 423 | LStream := TFileStream.Create(FOutputPath+wFileName, fmOpenRead); 424 | Try 425 | try 426 | LStream.Seek(LStream.Size-1, TSeekOrigin.soBeginning); 427 | LStream.Read(Tmp[0],1); 428 | setlength(FSaveResumeProgress,Tmp[0]); 429 | SetLength(Tmp,Tmp[0]*24); 430 | LStream.Seek(LStream.Size-1-Length(Tmp), TSeekOrigin.soBeginning); 431 | LStream.Read(Tmp[0],Length(Tmp)); 432 | Move(Tmp[0],FSaveResumeProgress[0],Length(Tmp)); 433 | except 434 | Result:=False; 435 | end; 436 | finally 437 | LStream.Free; 438 | end; 439 | end; 440 | 441 | ///*******************************************************************************************************************************************************// 442 | function TThredingFileDownloader._LoadDownloadInfo(wFilename: string):boolean; 443 | var LStream: TFileStream; 444 | Tmp:TBytes; 445 | wLength:Word; 446 | begin 447 | Result:=true; 448 | SetLength(Tmp,2); 449 | LStream := TFileStream.Create(FOutputPath+wFileName, fmOpenRead); 450 | try 451 | try 452 | LStream.Seek(LStream.Size-(Length(FSaveResumeProgress)*24+1)-2, TSeekOrigin.soBeginning); 453 | LStream.Read(Tmp[0],2); 454 | wLength:=Tmp[0]*256+Tmp[1]; 455 | SetLength(Tmp,wLength); 456 | FFileSize:=LStream.Size-(Length(FSaveResumeProgress)*24+1)-(Length(Tmp)+2); 457 | LStream.Seek(FFileSize , TSeekOrigin.soBeginning); 458 | LStream.Read(Tmp,Length(Tmp)); 459 | FUrl:=TEncoding.UTF8.GetString(Tmp); 460 | except 461 | Result:=false; 462 | end; 463 | finally 464 | LStream.Free; 465 | end; 466 | end; 467 | 468 | ///*******************************************************************************************************************************************************// 469 | destructor TThredingFileDownloader.destroy; 470 | begin 471 | inherited; 472 | end; 473 | 474 | ///*******************************************************************************************************************************************************// 475 | procedure TThredingFileDownloader.DoDownload; 476 | begin 477 | TThread.CreateAnonymousThread(procedure begin 478 | _DoDownload; 479 | end).Start; 480 | end; 481 | 482 | ///*******************************************************************************************************************************************************// 483 | procedure TThredingFileDownloader.PauseDownload; 484 | begin 485 | FStopDownload:=True; 486 | if Assigned(FOnDownloadPaused) then TThread.Synchronize(nil,procedure begin FOnDownloadPaused(Self);end); 487 | end; 488 | 489 | ///*******************************************************************************************************************************************************// 490 | procedure TThredingFileDownloader.ResumeDownload; 491 | begin 492 | _LoadDownloadState('_'+FFileName+'.temporary'); 493 | _LoadDownloadInfo('_'+FFileName+'.temporary'); 494 | if Length(FSaveResumeProgress)>0 then TThread.CreateAnonymousThread(procedure begin 495 | _ResumeDownload; 496 | end).Start 497 | else raise Exception.Create('No saved state exist to resume download '); 498 | end; 499 | 500 | ///*******************************************************************************************************************************************************// 501 | function TThredingFileDownloader.ResumeFromTempFile(wFilename: String):integer; 502 | var LStream:TFileStream; 503 | begin 504 | Result:=0; 505 | if not _LoadDownloadState(wFilename) or(wFilename[1]<>'_')or(ExtractFileExt(wFilename)<>'.temporary') then raise Exception.Create('Invalid temporary file for download resume...') 506 | else begin 507 | FFilename:=wFilename.Replace('_','').Replace('.temporary',''); 508 | Result:=Length(FSaveResumeProgress); 509 | FCanResume:=True; 510 | ResumeDownload; 511 | end; 512 | end; 513 | 514 | ///*******************************************************************************************************************************************************// 515 | procedure TThredingFileDownloader.SpeedCalculatorEvent(Sender: Tobject); 516 | var wTime:Cardinal; 517 | wSpeed:Double; 518 | wDownloaded:Int64; 519 | begin 520 | FEndingTime:=TThread.GetTickCount; 521 | FEndingDownload:=FDownloadedAmount; 522 | wTime:=FEndingTime-FStartingTime; 523 | wDownloaded:=FEndingDownload-FStartingDownload; 524 | FStartingTime:=FEndingTime; 525 | FStartingDownload:=FEndingDownload; 526 | wSpeed:=Round(((wDownloaded*1000)/wTime)*100)/100; 527 | FDownloadSpeed:=wSpeed; 528 | end; 529 | 530 | ///*******************************************************************************************************************************************************// 531 | function TThredingFileDownloader.StandarizedSize(value: Int64): string; 532 | begin 533 | if Value<1024 then Result:=value.ToString+' Byte' 534 | else if value<1024*1024 then Result:=(Round((Value/1024)*100)/100).ToString+' KB' 535 | else if value<1024*1024*1024 then Result:=(Round((Value/(1024*1024))*100)/100).ToString+' MB' 536 | else Result:=(Round((Value/(1024*1024*1024))*100)/100).ToString+' GB'; 537 | end; 538 | 539 | ///*******************************************************************************************************************************************************// 540 | procedure TThredingFileDownloader.ThreadReceiveDataHandler(const Sender: TObject; ThreadNo, ASpeed: Integer;AReadCount: Int64;APercentage:Double; var Abort: Boolean); 541 | var i:integer; 542 | wAverageDownloaded:Double; 543 | wRemainingTime:Int64; 544 | wAbort:boolean; 545 | begin 546 | if not FStopDownload then begin 547 | FCriticalSection.Enter; 548 | FThreadsDownloadedAmout[ThreadNo]:=AReadCount+FSaveResumeProgress[ThreadNo].tProgress; 549 | _SaveDownloadState; 550 | FDownloadedAmount :=0; 551 | for i:=0 to FNumOfThreads-1 do FDownloadedAmount:=FDownloadedAmount+FThreadsDownloadedAmout[i]; 552 | if FDownloadedAmount>FFileSize then 553 | i:=1; 554 | 555 | if FFileSize>-1 then begin 556 | FDownloadedPerCentage:=(FDownloadedAmount/FFileSize)*100; 557 | FDownloadedPerCentage:=Round(FDownloadedPerCentage*100)/100; 558 | end 559 | else FDownloadedPerCentage:=-1; 560 | if FFileSize>-1 then wRemainingTime:=Round((FFileSize-FDownloadedAmount)/FdownloadSpeed) // Estimated Remaining time in second 561 | else wRemainingTime:=-1; 562 | FEstimatedRemainingTime:=wRemainingTime; 563 | FCriticalSection.Release; 564 | if Assigned(FOnDownloadThreadData) then begin 565 | wAbort:=Abort; 566 | TThread.Synchronize(nil,procedure begin 567 | FOnDownloadThreadData(Sender,ThreadNo,ASpeed,AReadCount+FSaveResumeProgress[ThreadNo].tProgress, APercentage,wAbort); 568 | end); 569 | Abort:=wAbort; 570 | end; 571 | if Assigned(FOnDownloadInfoUpdate) then 572 | TThread.Synchronize(nil, procedure begin 573 | FOnDownloadInfoUpdate(Self,FDownloadSpeed,FDownloadedAmount,FDownloadedPerCentage,FEstimatedRemainingTime); 574 | end); 575 | end; 576 | Abort:=FStopDownload; 577 | end; 578 | 579 | { TDownloadThread } 580 | 581 | ///*******************************************************************************************************************************************************// 582 | constructor TTrackDownloader.Create(const URL, FileName: string; ThreadNo: Integer; StartPoint, EndPoint: Int64); 583 | begin 584 | inherited Create(True); 585 | FURL := URL; 586 | FFileName := FileName; 587 | FThreadNo := ThreadNo; 588 | FStartPoint := StartPoint; 589 | FEndPoint := EndPoint; 590 | end; 591 | 592 | ///*******************************************************************************************************************************************************// 593 | destructor TTrackDownloader.Destroy; 594 | begin 595 | inherited; 596 | end; 597 | 598 | ///*******************************************************************************************************************************************************// 599 | procedure TTrackDownloader.Execute; 600 | var LResponse: IHTTPResponse; 601 | LStream: TFileStream; 602 | LHttpClient: THTTPClient; 603 | begin 604 | inherited; 605 | LHttpClient := THTTPClient.Create; 606 | try 607 | LHttpClient.OnReceiveData := ReceiveDataEvent; 608 | LStream := TFileStream.Create(FFileName, fmOpenWrite or fmShareDenyNone); 609 | try 610 | FTimeStart := GetTickCount; 611 | LStream.Seek(FStartPoint, TSeekOrigin.soBeginning); 612 | LResponse := LHttpClient.GetRange(FURL, FStartPoint, FEndPoint, LStream); 613 | finally 614 | LStream.Free; 615 | end; 616 | finally 617 | LHttpClient.Free; 618 | end; 619 | end; 620 | 621 | ///*******************************************************************************************************************************************************// 622 | procedure TTrackDownloader.ReceiveDataEvent(const Sender: TObject; AContentLength:Int64; AReadCount: Int64; var Abort: Boolean); 623 | var LTime: Cardinal; 624 | LSpeed: Integer; 625 | LPrecentage:Double; 626 | begin 627 | if Assigned(FOnThreadData) then begin 628 | LTime := GetTickCount - FTimeStart; 629 | if AReadCount = 0 then LSpeed := 0 630 | else LSpeed := (AReadCount * 1000) div LTime; // Byte per Second 631 | if FFileSize>-1 then 632 | LPrecentage:=Round(((AReadCount+FThSaveState[FThreadNo].tProgress)/(AContentLength+FThSaveState[FThreadNo].tProgress))*10000)/100 633 | else LPrecentage:=-1; 634 | FOnThreadData(Sender, FThreadNo, LSpeed,AReadCount, LPrecentage, Abort); 635 | end; 636 | end; 637 | 638 | ///*******************************************************************************************************************************************************// 639 | procedure TThredingFileDownloader._IndirecrReceiveDataEvent(const Sender: TObject; AContentLength:Int64; AReadCount: Int64; var Abort: Boolean); 640 | begin 641 | FIncrementTester:=AContentLength; 642 | Abort:=True 643 | end; 644 | 645 | function TThredingFileDownloader._IndirectlyGetFileSize(wUrl: string): int64; 646 | var wClient:THTTPClient; 647 | wResponce:IHTTPResponse; 648 | begin 649 | wClient:=THTTPClient.Create; 650 | wClient.OnReceiveData:=_IndirecrReceiveDataEvent; 651 | FIncrementTester:=0; 652 | try 653 | wResponce:=wClient.Get(wUrl); 654 | Sleep(100); 655 | Result:=FIncrementTester; 656 | finally 657 | wClient.Free; 658 | end; 659 | end; 660 | 661 | 662 | 663 | end. 664 | --------------------------------------------------------------------------------