Пожалуйста, не сочтите за наглость, но приведу свой код. Ткните меня плз в те места, где по вашему мнению "так делать нельзя!"...
// модуль downloadmanager.cpp
<pre>
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#pragma package(smart_init)
#include "download_manager.h"
#ifdef _DEBUG
#define StartProc(val) //OutputDebugString(("enter to: "+AnsiString(__FUNC__)+val).c_str())
#define EndProc(val) //OutputDebugString(("exit from: "+AnsiString(__FUNC__)+val).c_str())
#define OutputDebugString(val) //
#else
#define StartProc(val)
#define EndProc(val)
#define OutputDebugString(val) //
#endif
const AnsiString Pages[] = {
"
http://localhost/index.html",
"
http://localhost/page1.html",
"
http://localhost/page2.html",
"
http://localhost/page3.html",
"
http://localhost/page4.html",
"
http://localhost/page5.html",
"
http://localhost/tasm/i1.html",
"
http://localhost/tasm/i2.html",
"
http://localhost/tasm/0.html",
"
http://localhost/tasm/1.html",
"
http://localhost/tasm/2.html",
"
http://localhost/tasm/3.html",
"
http://localhost/tasm/4.html",
"
http://localhost/tasm/5.html",
"
http://localhost/tasm/6.html",
"
http://localhost/tasm/7.html",
"
http://localhost/tasm/8.html",
"
http://localhost/tasm/9.html",
"
http://localhost/tasm/10.html",
"
http://localhost/tasm/11.html",
"
http://localhost/tasm/12.html",
"
http://localhost/tasm/13.html",
"
http://localhost/tasm/14.html",
"
http://localhost/tasm/15.html",
"
http://localhost/tasm/16.html",
"
http://localhost/tasm/17.html",
"
http://localhost/tasm/18.html",
"
http://localhost/tasm/19.html",
"
http://localhost/tasm/20.html",
"
http://localhost/tasm/21.html",
"
http://localhost/tasm/22.html",
"
http://localhost/tasm/23.html",
"
http://localhost/tasm/24.html",
"
http://localhost/tasm/25.html",
"
http://localhost/tasm/26.html",
"
http://localhost/tasm/27.html",
"
http://localhost/tasm/28.html",
"
http://localhost/tasm/29.html",
"
http://localhost/tasm/30.html",
"
http://localhost/tasm/31.html",
"
http://localhost/tasm/32.html",
"
http://localhost/tasm/33.html",
"
http://localhost/tasm/34.html",
"
http://localhost/tasm/35.html",
"
http://localhost/tasm/36.html",
"
http://localhost/tasm/37.html",
"
http://localhost/tasm/38.html",
"
http://localhost/tasm/39.html",
"
http://localhost/tasm/40.html",
"
http://localhost/tasm/41.html",
"
http://localhost/tasm/42.html",
"
http://localhost/tasm/43.html",
"
http://localhost/tasm/44.html",
"
http://localhost/tasm/45.html"
};
int Count = 10;
//---------------------------------------------------------------------------
__fastcall THttpDownloadManager::THttpDownloadManager(const AnsiString &PathForSave)
{
StartProc("");
InitializeCriticalSection(&CS);
FOnFinished = NULL;
FTerminate = FPause = false;
FAddressCount = FAddressWaiting = FAddressDownloading =
FAddressReady = FAddressError = FInAnalyse = FAddressDownloaded = 0;
FState = DM_BUSY;
Tag = 0;
if (PathForSave[PathForSave.Length()] != '\\' &&
PathForSave[PathForSave.Length()] != '/') FTempDirectory = PathForSave + "/";
else FTempDirectory = PathForSave;
FAddresses = new TThreadList();
FOnAddressStateChange = NULL;
FCacheAddress = new TStringList();
FCacheAddress->Sorted = true;
FCacheAddress->Duplicates = dupError;
Document = new THTMLDocument();
EndProc("");
};
__fastcall THttpDownloadManager::~THttpDownloadManager()
{
StartProc("");
DeleteCriticalSection(&CS);
TList *FAddressesData = FAddresses->LockList();
for (int i=FAddressesData->Count-1; i>=0; i--)
{
TAddressInfo *Info = (TAddressInfo*)FAddressesData->Items[i];
if (Info != NULL)
{
if (Info->Address != NULL) { delete Info->Address; Info->Address = NULL; };
delete Info; Info = NULL;
};
FAddressesData->Delete(i);
};
FAddresses->UnlockList();
delete FAddresses; FAddresses = NULL;
delete FCacheAddress; FCacheAddress = NULL;
delete Document; Document = NULL;
EndProc("");
};
void __fastcall THttpDownloadManager::Terminate()
{
if (!FTerminate)
{
FTerminate = true;
Update();
};
};
void __fastcall THttpDownloadManager::Pause()
{
if (!FTerminate && !FPause) FPause = true;
};
void __fastcall THttpDownloadManager::Resume()
{
if (!FTerminate && FPause)
{
FPause = false;
Update();
};
};
void __fastcall THttpDownloadManager::OnFinishDownloadThread(TObject *Sender)
{
EnterCriticalSection(&CS);
try
{
T_HAS_Adapter *Thread = (T_HAS_Adapter*)Sender;
if (Thread != NULL && Thread->State)
{
--FAddressDownloading;
++FAddressDownloaded;
Thread->Info->State = Thread->TempState;
Thread->Info->Thread = NULL;
}
else OutputDebugString("error thread: out of memory");
}__finally
{
Update();
LeaveCriticalSection(&CS);
};
return;
// EnterCriticalSection(&CS);
/* StartProc("");
try
{try{
if (Tag > 0)
{
DebugBreak();
return;
// throw Exception("blya!");
// Application->Terminate();
};
InterlockedIncrement(&Tag);
T_HAS_Adapter *Thread = dynamic_cast<T_HAS_Adapter*>(Sender);
if (Thread != NULL)
{
try
{
int RetValue = Thread->RetValue;
TAddressInfo *Info = Thread->Info;
Info->Thread = NULL;
--FAddressDownloading;
++FAddressReady;
if (RetValue != HA_RV_OK) ++FAddressError;
if (FAddresses->IndexOf(Info) != -1)
{
if (RetValue == HA_RV_OK)
{
try
{
Info->State = AS_READY;
if (Info->Recursive)
try{
ParsePage(Info);
}catch(...)
{
DebugBreak();
OutputDebugString("Error in 3_OnFinishThread:: ParsePage");
OutputDebugString(Info->Address->Address.c_str());
// Application->Terminate();
};
DoAddressStateChange(Info);
}catch(...)
{
DebugBreak();
OutputDebugString("Error in 2_OnFinishThread");
// Application->Terminate();
};
}
else
{
try{
Info->State = AS_ERROR;
DoAddressStateChange(Info);
}catch(...)
{
DebugBreak();
OutputDebugString("Error in 1_OnFinishThread");
// Application->Terminate();
};
};
};
}catch(...)
{
DebugBreak();
OutputDebugString("Error in _OnFinishThread");
// Application->Terminate();
};
};
}catch(...)
{
DebugBreak();
OutputDebugString("Error in OnFinishThread!");
// Application->Terminate();
};
}__finally
{
InterlockedDecrement(&Tag);
Update();
EndProc("");
// LeaveCriticalSection(&CS);
};
*/
};
void __fastcall THttpDownloadManager::StartByDomain(const AnsiString &HttpAddress)
// íà÷èíàåò ðåêóðñèâíîå ñêà÷èâàíèå ñòðàíèö ñ ãëàâíîãî àäðåñà
{
StartProc("");
FState = DM_DOWNLOAD;
AnsiString Address = HttpAddress;
if (CorrectAddress(Address)) PushAddress(Address);
// else throw EDownloadManager(DM_ERROR_ADDRESS);
Update();
EndProc("");
};
void __fastcall THttpDownloadManager::PushAddress(const THttpAddress &Address, TAddressInfo *Parent, bool Recursive)
{
EnterCriticalSection(&CS);
try
{
try
{
StartProc("");
if (!Address.IsCreated) return;
bool Added = false;
FState = DM_DOWNLOAD;
AnsiString LocalFileName = CreateLocalAddress(Address.Address);
AnsiString LocalDir = ExtractFilePath(LocalFileName);
if (LocalDir == "" || ForceDirectories(LocalDir)) // íåëüçÿ âûçûâàòü ForxeDirectories ñ ïóñòîé ñòðîêîé
{
try
{
TAddressInfo *Info = new TAddressInfo();
try
{
Info->Address = new THttpAddress(Address);
try
{
FCacheAddress->Add(Address.Address); // may be catch if address alerady exists
Added = true;
Info->State = AS_INORDER;
Info->LocalFileName = LocalFileName;
Info->Thread = NULL;
if (Parent == NULL)
{
Info->Recursive = Recursive;
Info->Parent = NULL;
}
else
{
Info->Recursive = Parent->Recursive;
Info->Parent = Parent;
};
FAddresses->Add(Info);
DoAddressStateChange(Info);
++FAddressWaiting;
++FAddressCount;
}catch(...)
{
delete Info->Address; Info->Address = NULL;
delete Info; Info = NULL;
OutputDebugString(("Push: url: "+Address.Address+" already exist!").c_str());
};
}catch(...)
{
delete Info; Info = NULL;
throw Exception("Out of Memory httpaddress");
};
}catch(...)
{
throw Exception("Out of Memory addressinfo!");
};
}
else
{
OutputDebugString(("ForceDirectories error! Folder not create.\r\nDirectory: "+LocalDir).c_str());
DebugBreak();
};
}catch(...)
{
OutputDebugString("Error in putshpage");
DebugBreak();
};
}__finally
{
EndProc("");
LeaveCriticalSection(&CS);
};
};
void __fastcall THttpDownloadManager::Update()
{
EnterCriticalSection(&CS);
StartProc("");
try
{
#define MaxThreadCount 3
while ((FAddressWaiting > 0 || FAddressDownloaded > 0) && FAddressDownloading < MaxThreadCount && !FPause && !FTerminate)
{
TAddressInfo *Info = NULL;
TList *FAddressesData = FAddresses->LockList();
for (int i=FAddressesData->Count-1; i>=0 && FAddressDownloading < MaxThreadCount; --i)
{
Info = (TAddressInfo*)FAddressesData->Items[i];
if (Info == NULL) continue;
switch (Info->State)
{
case AS_INORDER: {
if ((FAddressWaiting > 0) /*&& (FAddressDownloading < MaxThreadCount)*/) DownloadPage(Info);
break;
};
case AS_ERROR: {
++FAddressError;
--FAddressDownloaded;
++FAddressReady;
Info->State = AS_IDLE;
DoAddressStateChange(Info);
break;
};
case AS_DOWNLOADED: {
--FAddressDownloaded;
++FAddressReady;
if (Info->Recursive)
ParsePage(Info);
Info->State = AS_READY;
DoAddressStateChange(Info);
break;
};
};
};
FAddresses->UnlockList();
};
if (FAddressReady == FAddressCount | FTerminate)
{
FState = (FTerminate) ? DM_TERMINATE: DM_READY;
if (FOnFinished != NULL) FOnFinished(NULL);
};
}__finally
{
EndProc("");
LeaveCriticalSection(&CS);
};
};
void __fastcall THttpDownloadManager::DownloadPage(TAddressInfo *Info)
{
EnterCriticalSection(&CS);
try
{
T_HAS_Adapter *Thread = NULL;
try
{
Thread = new T_HAS_Adapter(true, Info);
if (Thread->State == 0)
{
Thread->OnTerminate = OnFinishDownloadThread;
Thread->Info = Info;
Info->Thread = Thread;
Info->State = AS_DOWNLOADING;
Thread->Resume();
--FAddressWaiting;
++FAddressDownloading;
DoAddressStateChange(Info);
}
else throw Exception("Error create in thread");
}catch(Exception &E)
{
Info->Thread = NULL;
Info->State = AS_IDLE;
throw Exception(E.Message);
};
}__finally
{
LeaveCriticalSection(&CS);
};
};
bool __fastcall THttpDownloadManager::CorrectAddress(AnsiString &Address)
// êîððåêòèðóåò àäðåñ
{
StartProc("");
Address = AnsiLowerCase(StringReplace(Address, "\\", "/", TReplaceFlags() << rfReplaceAll));
if (Address.SubString(1, 7) != "
http://") Address = "
http://"+Address;
EndProc("");
return true;
};
AnsiString __fastcall THttpDownloadManager::CreateLocalAddress(const AnsiString &Address)
{
AnsiString LocalFileName = "";
StartProc("");
try
{
LocalFileName = Address;
if (LocalFileName.SubString(1, 7) == "
http://") LocalFileName.Delete(1, 7);
LocalFileName = StringReplace(LocalFileName, ":", "_", TReplaceFlags() << rfReplaceAll);
LocalFileName = StringReplace(FTempDirectory + LocalFileName, "/", "\\", TReplaceFlags() << rfReplaceAll);
AnsiString Ext = ExtractFileExt(LocalFileName);
if (Ext == "") { LocalFileName += "index.html"; Ext = ".html"; };
if (int P = Ext.Pos("?"))
{
// Ext = Ext.SubString(P+1, Ext.Length())+Ext.SubString(1, P-1);
LocalFileName = ChangeFileExt(LocalFileName, Ext.SubString(P+1, Ext.Length())+Ext.SubString(1, P-1));
};
LocalFileName = StringReplace(LocalFileName, "?", "_", TReplaceFlags() << rfReplaceAll);
}catch(...)
{
OutputDebugString(("ERROR: CreateLocalAddress: "+Address).c_str());
DebugBreak();
LocalFileName = "";
}
return LocalFileName;
};
void __fastcall THttpDownloadManager::DoAddressStateChange(TAddressInfo *Info)
{
EnterCriticalSection(&CS);
if (FOnAddressStateChange != NULL) FOnAddressStateChange((void*)this, Info);
LeaveCriticalSection(&CS);
};
int __fastcall THttpDownloadManager::GetState()
{
return FState;
};
void __fastcall THttpDownloadManager::ParsePage(TAddressInfo *Info)
{
#define StaticPages
EnterCriticalSection(&CS);
try
{
Info->State = AS_ANALYZE;
DoAddressStateChange(Info);
#if defined(StaticPages)
++FInAnalyse;
for (int i=0; i<Count; i++)
{
PushAddress(THttpAddress(Info->Address->Address, Pages[i]), Info);
};
/* if (Count > 0)
{
Count--;
try
{
PushAddress(THttpAddress(Info->Address->Address, Pages[Count]), Info);
}catch(...)
{
DebugBreak();
OutputDebugString("ERROR: in ParsePage1");
OutputDebugString(Info->Address->Address.c_str());
};
AnsiString S = "";
try
{
try
{
S = Pages[random(40)];
}catch(...)
{
DebugBreak();
OutputDebugString("ERROR: in ParsePage3");
};
PushAddress(THttpAddress(Info->Address->Address, S), Info);
}catch(...)
{
DebugBreak();
OutputDebugString("ERROR: in ParsePage2");
};
};
*/
--FInAnalyse;
#else
try
{
if (Info == NULL || FInAnalyse > 0) return;
// if (Info->State != AS_DOWNLOADED) return;
++FInAnalyse;
Info->State = AS_ANALYZE;
DoAddressStateChange(Info);
try
{
// THTMLDocument *Document = new THTMLDocument();
// if (Document == NULL)
// {
// OutputDebugString("Out Of Memory!");
// Application->Terminate();
// }
// else
{
if (Document->LoadFromFile(Info->LocalFileName.c_str()))
{
IHTMLDocument2 *Doc = Document->Document;
if (Doc != NULL)
{
IHTMLElementCollection *All;
Doc->get_all(&All);
if (All != NULL)
{
wchar_t *TagsName[] = {L"a", L"frame"};
for (int TagsCount = 0; TagsCount < 2; TagsCount++)
{
IDispatch *pDisp = NULL;
VARIANT name;
name.vt = VT_BSTR;
name.bstrVal = TagsName[TagsCount];
All->tags(name, &pDisp);
if (pDisp != NULL)
{
IHTMLElementCollection *Tags;
pDisp->QueryInterface(IID_IHTMLElementCollection, (void**)&Tags);
if (Tags != NULL)
{
long Count = 0;
Tags->get_length(&Count);
for (int i=0; i<Count; i++)
{
IDispatch *disp;
Tags->item(OleVariant(i), OleVariant(0), &disp);
if (disp != NULL) //
{
IHTMLElement *Anchor;
disp->QueryInterface(IID_IHTMLElement, (void**)&Anchor);
if (Anchor != NULL)
{
wchar_t *tag;
Anchor->get_tagName(&tag);
AnsiString Tag = AnsiLowerCase(WideString(tag));
wchar_t *AttribName = NULL;
if (Tag == "a") AttribName = L"href";
else
if (Tag == "frame") AttribName = L"src";
if (AttribName != NULL)
{
VARIANT Attribute;
Anchor->getAttribute( AttribName, 2, &Attribute);
AnsiString href = VarToStr(Attribute);
int ddd = 0;
try
{
if (Attribute.vt == VT_BSTR)
{
THttpAddress Adr(Info->Address->Address, href);
ddd++;
try
{
PushAddress(Adr, Info);
}catch(...)
{
DebugBreak();
OutputDebugString("ERROR IN PARSE: PUSH");
// Application->Terminate();
};
ddd++;
};
}catch(...)
{
DebugBreak();
OutputDebugString("Error in parse");
// Application->Terminate();
};
}; // attribname != NULL
Anchor->Release();
}; //anchor != NULL
disp->Release();
}; //disp != NULL
}; // for i
Tags->Release();
}; // Tags != NULL
pDisp->Release();
}; // pDisp != NULL;
}; // for TagsCount
All->Release();
}; // All != NULL;
}; // Doc != NULL;
}; // LoadFromFile
// delete Document;
} // else
}catch(...)
{
DebugBreak();
OutputDebugString("Out of Memory!!!!");
// Application->Terminate();
};
}__finally
{
--FInAnalyse;
EndProc("");
// LeaveCriticalSection(&CS);
};
#endif
}__finally
{
LeaveCriticalSection(&CS);
};
};
</pre>
// его хидер
<pre>
//---------------------------------------------------------------------------
#ifndef download_managerH
#define download_managerH
//---------------------------------------------------------------------------
#include <sysutils.hpp>
#include <classes.hpp>
#include <filectrl.hpp>
#pragma hdrstop
#include "address.h"
#include "HTMLDoc.h"
#include "downloader_thread.h"
#define DM_ERROR_ADDRESS "error start address!"
typedef enum {DM_BUSY = 0, DM_DOWNLOAD, DM_READY, DM_TERMINATE, DM_COUNT_EVENTS } TDMState;
typedef Exception EDownloadManager;
typedef void __fastcall (__closure *TAddressEvent)(void* Sender, TAddressInfo *Info);
typedef void __fastcall (__closure *TFinishEvent)(void* Sender);
class THttpDownloadManager
{
private:
int FAddressCount; // âñåãî àäðåñîâ ïîëó÷åíî
int FAddressWaiting; // àäðåñîâ â îæèäàíèè ñêà÷èâàíèÿ
int FAddressDownloading; // â ïðîöåññå ñêà÷èâàíèÿ
int FAddressDownloaded; // ñêà÷àíî, íî íå ïðîàíàëèçèðîâàíî
int FAddressReady; // óæå ñêà÷àíî
int FInAnalyse;
int FAddressError; // ñêà÷àíî ñ îøèáêîé
TDMState FState;
long Tag;
// ïî èäåå FAddressCount = FAddressWaiting + FAddressDownloading + FAddressReady
CRITICAL_SECTION CS;
AnsiString FTempDirectory;
TThreadList *FAddresses;
TAddressEvent FOnAddressStateChange;
TStringList *FCacheAddress;
TFinishEvent FOnFinished;
bool FPause;
bool FTerminate;
THTMLDocument *Document;
void __fastcall OnFinishDownloadThread(TObject *Sender);
void __fastcall PushAddress(const THttpAddress &Address, TAddressInfo *Parent = NULL, bool Recursive = true);
bool __fastcall CorrectAddress(AnsiString &Address);
AnsiString __fastcall CreateLocalAddress(const AnsiString &Address);
void __fastcall DoAddressStateChange(TAddressInfo *Info);
void __fastcall ParsePage(TAddressInfo *Info);
public:
__fastcall THttpDownloadManager(const AnsiString &PathForSave);
__fastcall ~THttpDownloadManager();
void __fastcall Update();
void __fastcall StartByDomain(const AnsiString &HttpAddress);
void __fastcall DownloadPage(TAddressInfo *Info);
int __fastcall GetState();
void __fastcall Terminate();
void __fastcall Pause();
void __fastcall Resume();
__property int AddressCount = {read = FAddressCount};
__property int AddressWaiting = {read = FAddressWaiting};
__property int AddressDownloading = {read = FAddressDownloading };
__property int AddressReady = {read = FAddressReady };
__property int AddressError = {read = FAddressError };
__property int AddressAnalyze = {read = FInAnalyse };
__property TAddressEvent OnAddressStateChange = {read = FOnAddressStateChange, write = FOnAddressStateChange};
__property TFinishEvent OnFinish = {read = FOnFinished, write = FOnFinished };
__property bool Paused = {read = FPause };
__property bool Terminated = {read = FTerminate };
};
#endif
</pre>
// модуль потока downloader_thread.cpp
<pre>
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "downloader_thread.h"
#pragma package(smart_init)
//****************************************************************************//
//* T_HAS_ADAPTER *//
//****************************************************************************//
//* Ïîòîê äëÿ ñêà÷èâàíèÿ ôàéëà â ëîêàëüíûé ôàéë íà äèñêå *//
//****************************************************************************//
#ifdef _DEBUG
#define StartProc(val) //OutputDebugString(("enter to: "+AnsiString(__FUNC__)+val).c_str())
#define EndProc(val) //OutputDebugString(("exit from: "+AnsiString(__FUNC__)+val).c_str())
#else
#define StartProc(val)
#define EndProc(val)
#endif
#define OutputDebugString(val) ;//
__fastcall T_HAS_Adapter::T_HAS_Adapter(bool aSuspended, TAddressInfo *aInfo)
: TThread(true)
{
Priority = tpIdle;
FInfo = aInfo;
FreeOnTerminate = true;
Msg = "idle";
TempState = aInfo->State;
FIsDownloaded = 0;
State = 0;
RetValue = HA_RV_OK;
try
{
http = new TIdHTTP(NULL);
Suspended = aSuspended;
}catch(...)
{
State = -1;
Terminate();
};
}
//---------------------------------------------------------------------------
__fastcall T_HAS_Adapter::~T_HAS_Adapter()
{
if (http) { delete http; http = NULL; };
};
//---------------------------------------------------------------------------
void __fastcall T_HAS_Adapter::Execute()
{
State = 1;
// while (!Terminated)
{
// if (!Terminated && !FIsDownloaded)
{
State = 2;
InterlockedIncrement(&FIsDownloaded);
AnsiString FUrl = Info->Address->Address;
if (AnsiLowerCase(FUrl).SubString(1, 5) == "http:") // download by web
{
http->Request->UserAgent = "Mozilla/3.0 (compatible
";
http->Request->AcceptLanguage = "es-us";
http->ReadTimeout = 30000;
try
{
TFileStream *File = new TFileStream(Info->LocalFileName, fmCreate);
try
{
try
{
http->Get(FUrl, File);
RetValue = HA_RV_OK;
TempState = AS_DOWNLOADED;
}catch(...)
{
try
{
AnsiString Ext = ExtractFileExt(FUrl);
if (Ext == "") http->Get(FUrl+"/", File);
else http->Get(FUrl, File);
RetValue = HA_RV_OK;
TempState = AS_DOWNLOADED;
}catch(...)
{
RetValue = HA_RV_DOWNLOADERROR;
TempState = AS_ERROR;
};
}
}__finally
{
delete File;
};
}catch(...)
{
RetValue = HA_RV_ERRORSAVE;
};
}
else // other protocol
{
RetValue = HA_RV_UNKNOWNPROTOCOL;
/*
SetFileAttributes(FLocalName.c_str(), FILE_ATTRIBUTE_ARCHIVE);
if (CopyFile(FUrl.c_str(), FLocalName.c_str(), false))
{
SetFileAttributes(FLocalName.c_str(), FILE_ATTRIBUTE_ARCHIVE);
RetValue = HA_RV_OK;
}
else
{
RetValue = HA_RV_DOWNLOADERROR;
}
*/ };
State = 2;
InterlockedDecrement(&FIsDownloaded);
Terminate();
};
};
}
//---------------------------------------------------------------------------
/*bool __fastcall T_HAS_Adapter::StartPage(TAddressInfo *Info)
{
if (Info == NULL || Info->LocalFileName == "") return false;
FInfo = Info;
RetValue = HA_RV_START;
// SetEvent(FDownloadEvent);
// if (State == 2) State = 1;
// else
// if (State == 0)
Resume();
return true;
};*/
//---------------------------------------------------------------------------
void __fastcall T_HAS_Adapter::Terminate()
{
TThread::Terminate();
// SetEvent(FDownloadEvent);
};
//---------------------------------------------------------------------------
</pre>
// и его хидер
<pre>
//---------------------------------------------------------------------------
#ifndef Unit2H
#define Unit2H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include "IdHTTP.hpp"
#pragma hdrstop
#include "address.h"
#define HA_ERROR_DOWNLOAD(val) "["+IntToHex(RetValue, 8)+"] Îøèáêà ïðè ñêà÷èâàíèè èëè êîïèðîâàíèè ôàéëà! \n["+FUrl+"]\n\nÈíôîðìàöèÿ äëÿ îòëàäêè:\nôàéë: "+__FILE__+"\nñòðîêà: "+IntToStr(__LINE__)
#define HA_RV_OK 0x0000000
#define HA_RV_START 0x0000001
#define HA_RV_ERRORSAVE 0x0000002
#define HA_RV_UNKNOWNERROR 0x0000003
#define HA_RV_UNKNOWNPROTOCOL 0x0000004
#define HA_RV_OUTOFMEMORY 0x0000005
#define HA_RV_DOWNLOADERROR 0x0181315
typedef enum {AS_INORDER = 0, AS_DOWNLOADING, AS_DOWNLOADED, AS_ANALYZE, AS_READY, AS_ERROR, AS_IDLE } TASState;
extern AnsiString ASStateStr[] = {"In order", "Downloading", "Downloaded", "Analyze", "Ready", "Error"};
class T_HAS_Adapter;
struct TAddressInfo
{
THttpAddress *Address;
TASState State;
AnsiString LocalFileName;
bool Recursive;
T_HAS_Adapter *Thread;
TAddressInfo *Parent;
};
//---------------------------------------------------------------------------
class T_HAS_Adapter : public TThread
{
private:
TAddressInfo *FInfo;
HANDLE FDownloadEvent;
long FIsDownloaded;
protected:
void __fastcall Execute();
public:
int RetValue;
TASState TempState;
AnsiString Msg;
TIdHTTP *http;
int State;
__fastcall T_HAS_Adapter(bool aSuspended, TAddressInfo *aInfo);
virtual __fastcall ~T_HAS_Adapter();
__property TAddressInfo *Info = {read = FInfo, write = FInfo};
// bool __fastcall StartPage(TAddressInfo *Info);
void __fastcall Terminate();
};
//---------------------------------------------------------------------------
#endif
</pre>
и соотв. цикл проверки
//кнопка старт (инициализация)
<pre>
Manager = new THttpDownloadManager(ExtractFilePath(ParamStr(0))+"download");
Manager->OnAddressStateChange = OnAddress;
Manager->StartByDomain("
http://localhost/index_f.html");
</pre>
// кнопка очистки памяти от менеджера
<pre>
delete Manager;
Manager = NULL;
ListBox1->Items->Clear();
ListBox2->Items->Clear();
</pre>
// и сам цикл проверки
<pre>
int Cnt = 0;
while (!Application->Terminated)
{
Label2->Caption = IntToStr(++Cnt);
Button1Click(this); // кнопка старт
while (Manager->GetState() < DM_READY && Manager->GetState() != DM_BUSY)
Application->ProcessMessages();
Button2Click(this); // кнопка очистки памяти
Application->ProcessMessages();
};
</pre>
p.s. при всем при этом где-то жрется память, но CodeGuard молчит!
p.s.s. я уже практически в отчаянии, помогите плз!!!!