后一页
前一页
回目录
回首页
DELPHI与INTERNET(二)

FTP 使用 WININET  
  
    现在您阅读的是本文的第二部分,它包含了WININET的内容。正如前文提及的那样,  这个部分与第一部分完全无关。  
  
    让我们先来对您在FTP部分使用WININET DLL时需要编写的代码作一个做一个概括的了解。这并不是一个详尽的学习,但却能够让您进门。为了知晓这项技术,您要做的第一件 事情是明白 WININET.PAS 中的一些函数返回的是一个叫做 HINTERNET 类的指针变量:  
  
  
var  
  HINTERNET: Pointer;  
  
    这个指针扮演一个您正在使用的不同的因特网服务的句柄的角色。获得了这个句柄之后,你应当把它作为第一个参数传递给在这个进程周期[注:指FTP的整个存在时间(译者)]中调用的其他WININET函数。  
  
    您要记住的适当您在使用它的时间内要把句柄返回给系统,通常是通过调用 WININET 函数 InternetCloseHandle 来实现:  
  
  
function InternetCloseHandle(hInet: HINTERNET): BOOL; stdcall;  
  
     为了让一个WININET进程开始,您调用 InternetOpen :  
  
function InternetOpen(lpszCallerName: PChar; dwAccessType: DWORD;   
  lpszServerName: PChar; nServerPort: INTERNET_PORT;   
  dwFlags: DWORD): HINTERNET; stdcall;  
  
  
    第一个参数时打开这个进程的应用程序的名字。您可以在这个参数中传递任何您所要 的任意符串。微软公司的文献声称"这个名字作为HTTP协议中的用户代理器的名字而被使用"。这个保留的参数可以设为0或空。      
  
  
var  
  MyHandle: HINTERNET;  
…  
begin  
  MyHandle := InternetOpen('MyApp', 0, nil, 0, 0);  
end;  
  
    如果您想要关于这个函数的更多信息,从 www.microsoft.com 那里下载   
WININET.HLP 。  
  
    打开了这这个进程之后,下一步是通过 InternetConnect 函数来连接到服务器上。  
  
  
function InternetConnect(  
   hInet: HINTERNET;           // Handle from InternetOpen  
   lpszServerName: PChar;      // Server: i.e., www.borland.com  
   nServerPort: INTERNET_PORT; // Usually 0  
   lpszUsername: PChar;        // usually anonymous  
   lpszPassword: PChar;        // usually your email address  
   dwService: DWORD;           // FTP, HTTP, or Gopher?  
   dwFlags: DWORD;             // Usually 0  
   dwContext: DWORD):          // User defined number for callback  
HINTERNET; stdcall;  
  
    这里有三个可能的可以通过 dwService 参数传递的自说明旗标,它们是互斥的:  
  
  
INTERNET_SERVICE_FTP  
INTERNET_SERVICE_GOPHER  
INTERNET_SERVICE_HTTP  
  
    下面是 dwFlags 参数的选择:  
  
  
INTERNET_CONNECT_FLAG_PASSIVE  
    
    这个选项仅当您在前一个参数中传递了 INTERNET_SERVER_FTP 才有效。这时候这个 参数没有其他有效的选项。  
  
  
    如果这个进程成功的话会返回一个有效的指针,否则它返回空。  
  
  
连接上之后  
  
    当您连接上之后,您可以调用来 GetCurrentDirectory 获得当前的路径的名字:  
  
  
function TMyFtp.GetCurrentDirectory: string;  
var  
  Len: Integer;  
  S: string;  
begin  
  Len := 0;  
  ftpGetCurrentDirectory(FFTPHandle, PChar(S), Len);  
  SetLength(S, Len);  
  ftpGetCurrentDirectory(FFTPHandle, PChar(S), Len);  
  Result := S;  
end;  
  
这个函数声明如下:  
  
  
function FtpGetCurrentDirectory(  
  hFtpSession: HINTERNET;           // handle from InternetConnect  
  lpszCurrentDirectory: PChar;      // directory returned here  
  var lpdwCurrentDirectory: DWORD): // buf size of 2nd parameter  
BOOL; stdcall;                      // True on success  
  
    如果您把最后一个参数设为0,那么WININET会使用这个参数来返回路径字符串的长度 。接着您可以为您的字符串分配内存,也可以在调用一次这个函数来获得路径的名字。这 个过程在上面的方法中已经演示过了。(注意到*设定长度*的那个调用,Delphi要求您在类似这样的情况下为新的长字符串分配内存!这是因为这个字符串必须在操作系 统中指定值,而不是在 Delphi 应用程序中指定。结果就是 Delphi 不能在类似的情况下(像它通常那样悄悄地为字符串分配内存)    
    下面是返回在特定路径下当前可用的文件的一系列函数:  
  
  
function GetFindDataStr(FindData: TWin32FindData): string;  
var  
  S: string;  
  Temp: string;  
begin  
  case FindData.dwFileAttributes of  
    FILE_ATTRIBUTE_ARCHIVE: S := 'A';  
//  FILE_ATTRIBUTE_COMPRESSED: S := 'C';  
    FILE_ATTRIBUTE_DIRECTORY: S := 'D';  
    FILE_ATTRIBUTE_HIDDEN: S := 'H';  
    FILE_ATTRIBUTE_NORMAL: S := 'N';  
    FILE_ATTRIBUTE_READONLY: S := 'R';  
    FILE_ATTRIBUTE_SYSTEM: S := 'S';  
    FILE_ATTRIBUTE_TEMPORARY: S := 'T';  
  else  
    S := IntToStr(FindData.dwFileAttributes);  
  end;  
  S := S + GetDots(75);  
  Move(FindData.CFilename[0], S[6], StrLen(FindData.CFileName));  
  Temp := IntToStr(FindData.nFileSizeLow);  
  Move(Temp[1], S[25], Length(Temp));  
  Result := S;  
end;  
  
function TMyFtp.FindFiles: TStringList;  
var  
  FindData: TWin32FindData;  
  FindHandle: HInternet;  
begin  
   FindHandle := FtpFindFirstFile(FFtphandle, '*.*',  
     FindData, 0, 0);  
   if FindHandle = nil then begin  
     Result := nil;  
     Exit;  
   end;  
   FCurFiles.Clear;  
   FCurFiles.Add(GetFindDataStr(FindData));  
   while InternetFindnextFile(FindHandle, @FindData) do  
     FCurFiles.Add(GetFindDataStr(FindData));  
   InternetCloseHandle(Findhandle);  
   GetCurrentDirectory;  
   Result := FCurFiles;  
end;  
  
      这里需要注意的关键函数是 ftpFindFirstFile, InternetFindNextFile &   InternetCloseHandle 。您可以像调用 Delphi 函数 FindFirst、FindNext & FinClose   一样调用这些函数。特别的是,您使用函数 tpFindFirstFile 来取得这个路径下的第一 个函数。您可以不断地调用   InternetFindNextFile ,直到函数返回"False"为止。当这个进程结束时,调用   InternetCloseHandle 来通知操作系统回收与这个进程相关的内存。    
     我不准备在这里进一步解析这个进程。如果您想要更多的信息,您可以在 Delphi   帮助中查找 FindFirst 。最后提醒一句:并不向前文提及的函数,TWin32FindData 并不  是在  WININET.PAS 中定义的, 但可以在随 Delphi 分发的 WIN32 帮助文件中找到它。  它在随 Delphi   分发的 WINDOWS.PAS 文件中被定义。    

FTP 使用 WININET  
  
    现在您阅读的是本文的第二部分,它包含了WININET的内容。正如前文提及的那样,  这个部分与第一部分完全无关。  
  
    让我们先来对您在FTP部分使用WININET DLL时需要编写的代码作一个做一个概括的了 解。这并不是一个详尽的学习,但却能够让您进门。为了知晓这项技术,您要做的第一件  事情是明白 WININET.PAS 中的一些函数返回的是一个叫做 HINTERNET 类的指针变量:  
  
  
var  
  HINTERNET: Pointer;  
  
    这个指针扮演一个您正在使用的不同的因特网服务的句柄的角色。获得了这个句柄之  后,你应当把它作为第一个参数传递给在这个进程周期[注:指FTP的整个存在时间(译者  )]中调用的其他WININET函数。  
  
    您要记住的适当您在使用它的时间内要把句柄返回给系统,通常是通过调用   WININET 函数InternetCloseHandle 来实现:  
  
  
function InternetCloseHandle(hInet: HINTERNET): BOOL; stdcall;  
  
     为了让一个WININET进程开始,您调用 InternetOpen :  
  
function InternetOpen(lpszCallerName: PChar; dwAccessType: DWORD;   
  lpszServerName: PChar; nServerPort: INTERNET_PORT;   
  dwFlags: DWORD): HINTERNET; stdcall;  
  
  
    第一个参数时打开这个进程的应用程序的名字。您可以在这个参数中传递任何您所要  的任意符串。微软公司的文献声称"这个名字作为HTTP协议中的用户代理器的名字而被使  用"。这个保留的参数可以设为0或空。      
  
  
var  
  MyHandle: HINTERNET;  
…  
begin  
  MyHandle := InternetOpen('MyApp', 0, nil, 0, 0);  
end;  
  
    如果您想要关于这个函数的更多信息,从 www.microsoft.com 那里下载   WININET.HLP 。  
  
    打开了这这个进程之后,下一步是通过 InternetConnect 函数来连接到服务器上。  
  
  
function InternetConnect(  
   hInet: HINTERNET;           // Handle from InternetOpen  
   lpszServerName: PChar;      // Server: i.e., www.borland.com  
   nServerPort: INTERNET_PORT; // Usually 0  
   lpszUsername: PChar;        // usually anonymous  
   lpszPassword: PChar;        // usually your email address  
   dwService: DWORD;           // FTP, HTTP, or Gopher?  
   dwFlags: DWORD;             // Usually 0  
   dwContext: DWORD):          // User defined number for callback  
HINTERNET; stdcall;  
  
    这里有三个可能的可以通过 dwService 参数传递的自说明旗标,它们是互斥的:  
  
  
INTERNET_SERVICE_FTP  
INTERNET_SERVICE_GOPHER  
INTERNET_SERVICE_HTTP  
  
    下面是 dwFlags 参数的选择:  
  
  
INTERNET_CONNECT_FLAG_PASSIVE  
    
    这个选项仅当您在前一个参数中传递了 INTERNET_SERVER_FTP 才有效。这时候这个  参数没有其他有效的选项。  
  
  
    如果这个进程成功的话会返回一个有效的指针,否则它返回空。  
  
  
连接上之后  
  
    当您连接上之后,您可以调用来 GetCurrentDirectory 获得当前的路径的名字:  
  
  
function TMyFtp.GetCurrentDirectory: string;  
var  
  Len: Integer;  
  S: string;  
begin  
  Len := 0;  
  ftpGetCurrentDirectory(FFTPHandle, PChar(S), Len);  
  SetLength(S, Len);  
  ftpGetCurrentDirectory(FFTPHandle, PChar(S), Len);  
  Result := S;  
end;  
  
这个函数声明如下:  
  
  
function FtpGetCurrentDirectory(  
  hFtpSession: HINTERNET;           // handle from InternetConnect  
  lpszCurrentDirectory: PChar;      // directory returned here  
  var lpdwCurrentDirectory: DWORD): // buf size of 2nd parameter  
BOOL; stdcall;                      // True on success  
  
    如果您把最后一个参数设为0,那么WININET会使用这个参数来返回路径字符串的长度  。接着您可以为您的字符串分配内存,也可以在调用一次这个函数来获得路径的名字。这  个过程在上面的方法中已经演示过了。(注意到*设定长度*的那个调用,Delphi   要求您在类似这样的情况下为新的长字符串分配内存!这是因为这个字符串必须在操作系  统中指定值,而不是在 Delphi 应用程序中指定。结果就是Delphi 不能在类似的情况下  像它通常那样悄悄地为字符串分配内存)   
    下面是返回在特定路径下当前可用的文件的一系列函数:  
  
  
function GetFindDataStr(FindData: TWin32FindData): string;  
var  
  S: string;  
  Temp: string;  
begin  
  case FindData.dwFileAttributes of  
    FILE_ATTRIBUTE_ARCHIVE: S := 'A';  
//  FILE_ATTRIBUTE_COMPRESSED: S := 'C';  
    FILE_ATTRIBUTE_DIRECTORY: S := 'D';  
    FILE_ATTRIBUTE_HIDDEN: S := 'H';  
    FILE_ATTRIBUTE_NORMAL: S := 'N';  
    FILE_ATTRIBUTE_READONLY: S := 'R';  
    FILE_ATTRIBUTE_SYSTEM: S := 'S';  
    FILE_ATTRIBUTE_TEMPORARY: S := 'T';  
  else  
    S := IntToStr(FindData.dwFileAttributes);  
  end;  
  S := S + GetDots(75);  
  Move(FindData.CFilename[0], S[6], StrLen(FindData.CFileName));  
  Temp := IntToStr(FindData.nFileSizeLow);  
  Move(Temp[1], S[25], Length(Temp));  
  Result := S;  
end;  
  
function TMyFtp.FindFiles: TStringList;  
var  
  FindData: TWin32FindData;  
  FindHandle: HInternet;  
begin  
   FindHandle := FtpFindFirstFile(FFtphandle, '*.*',  
     FindData, 0, 0);  
   if FindHandle = nil then begin  
     Result := nil;  
     Exit;  
   end;  
   FCurFiles.Clear;  
   FCurFiles.Add(GetFindDataStr(FindData));  
   while InternetFindnextFile(FindHandle, @FindData) do  
     FCurFiles.Add(GetFindDataStr(FindData));  
   InternetCloseHandle(Findhandle);  
   GetCurrentDirectory;  
   Result := FCurFiles;  
end;  
  
      这里需要注意的关键函数是 ftpFindFirstFile, InternetFindNextFile &   InternetCloseHandle 。您可以像调用 Delphi 函数 FindFirst、FindNext & FinClose   一样调用这些函数。特别的是,您使用函数ftpFindFirstFile 来取得这个路径下的第一  个函数。您可以不断地调用   InternetFindNextFile ,直到函数返回"False"为止。当这个进程结束时,调用   InternetCloseHandle 来通知操作系统回收与这个进程相关的内存。  
  
I'm not going to explain this process further in this newsletter. 
If you want   more information, you might look up FindFirst 
in the Delphi help. One final   note: Unlike the functions 
mentioned in the previous paragraph,TWin32FindData is
 not defined in   WININET.PAS, but instead can be found
 in the WIN32 help file that ships with   Delphi. It is declared
 in the WINDOWS.PAS file that ships with Delphi.  

     我不准备在这里进一步解析这个进程。如果您想要更多的信息,您可以在 Delphi   帮助中查找 FindFirst 。最后提醒一句:并不向前文提及的函数,TWin32FindData 并不  是在  WININET.PAS 中定义的, 但可以在随 Delphi 分发的 WIN32 帮助文件中找到它。  它在随 Delphi   分发的 WINDOWS.PAS 文件中被定义。  
  
接受一个文件  
  
您可以使用 WININET.PAS 文件中的 ftpGetFile 函数来从FTP取回一个文件:  
  
function FtpGetFile(  
  hFtpSession: HINTERNET;        // Returned by InternetConnect  
  lpszRemoteFile: PChar;         // File to get  
  lpszNewFile: PChar;            // Where to put it on your PC  
  fFailIfExists: BOOL;           // Overwrite existing files?  
  dwFlagsAndAttributes: DWORD;   // File attribute-See CreateFile.  
  dwFlags: DWORD;                // Binary or ASCII transfer  
  dwContext: DWORD):             // Usually zero  
BOOL stdcall;                    // True on success  
  
下面是一个如何使用该函数的例子:  
  
  
function TMyFtp.GetFile(FTPFile, NewFile: string): Boolean;  
begin  
  Result := FtpGetFile(FFTPHandle, PChar(FTPFile), PChar(NewFile),  
               False, File_Attribute_Normal,  
               Ftp_Transfer_Type_Binary, 0);  
end;  
  
    如果要知道 dwFlagsAndAttributes 参数中的变量是怎样传递的,请查阅随 Delphi   附送的 WIN32 帮助文件。  
  
  
典型控制  
  
   下面的 Delphi 控制给了你一个通过 WININET FTP 部分建立可视工具的起点。只是因  为,这个控制可以让您是用 Object Inspector 来定义远程服务器(RemoteServer)、用户  身份(UserID)和密码(Password)。  
  
  
unit Ftp1;  
  
{ FTP example using WININET.PAS rather than   
  an ACTIVEX control. Requires WININET.PAS and  
  WININET.DLL. WININET.DLL you can get from   
  Microsoft, WININET.PAS is available from  
  www.borland.com, or with some versions of  
  Delphi 2.0.   
    
  You might Respond to OnNewDir events as follows:  
  
  procedure TForm1.FTP1NewDir(Sender: TObject);  
  begin  
    ListBox1.Items := MyFtp1.FindFiles; // Get the directory list  
  end;     
}  
  
interface  
  
uses  
  Windows, Classes, WinINet,  
  SysUtils;  
    
type  
  TMyFtp = class(TComponent)  
  private  
    FContext: Integer;  
    FINet: HInternet;  
    FFtpHandle: HInternet;  
    FCurFiles: TStringList;  
    FServer: string;  
    FOnNewDir: TNotifyEvent;  
    FCurDir: string;  
    FUserID: string;  
    FPassword: string;  
    function GetCurrentDirectory: string;  
    procedure SetUpNewDir;  
  protected  
    destructor Destroy; override;  
  public  
    constructor Create(AOwner: TComponent); override;  
    function Connect: Boolean;  
    function FindFiles: TStringList;  
    function ChangeDirExact(S: string): Boolean;  
    function ChangeDirCustom(S: string): Boolean;  
    function BackOneDir: Boolean;  
    function GetFile(FTPFile, NewFile: string): Boolean;  
    function SendFile1(FTPFile, NewFile: string): Boolean;  
    function SendFile2(FTPFile, NewFile: string): Boolean;  
    function CustomToFileName(S: string): string;  
  published  
    property CurFiles: TStringList read FCurFiles;  
    property CurDir: string read FCurDir;  
    property UserID: string read FUserID write FUserID;  
    property Password: string read FPassword write FPassword;  
    property Server: string read FServer write FServer;  
    property OnNewDir: TNotifyEvent read FOnNewDir   
                write FOnNewDir;  
  end;  
  
procedure Register;  
  
implementation  
  
uses  
  Dialogs;  
  
// A few utility functions  
  
function GetFirstToken(S: string; Token: Char): string;  
var  
  Temp: string;  
  Index: INteger;  
begin  
  Index := Pos(Token, S);  
  if Index < 1 then begin  
    GetFirstToken := '';  
    Exit;  
  end;  
  Dec(Index);  
  SetLength(Temp, Index);  
  Move(S[1], Temp[1], Index);  
  GetFirstToken := Temp;  
end;  
  
function StripFirstToken(S: string; Ch: Char): string;  
var  
  i, Size: Integer;  
begin  
  i := Pos(Ch, S);  
  if i = 0 then begin  
    StripFirstToken := S;  
    Exit;  
  end;  
  Size := (Length(S) - i);  
  Move(S[i + 1], S[1], Size);  
  SetLength(S, Size);  
  StripFirstToken := S;  
end;  
  
function ReverseStr(S: string): string;  
var  
  Len: Integer;  
  Temp: String;  
  i,j: Integer;  
begin  
  Len := Length(S);  
  SetLength(Temp, Len);  
  j := Len;  
  for i := 1 to Len do begin  
    Temp[i] := S[j];  
    dec(j);  
  end;  
  ReverseStr := Temp;  
end;  
  
function StripLastToken(S: string; Token: Char): string;  
var  
  Temp: string;  
  Index: INteger;  
begin  
  SetLength(Temp, Length(S));  
  S := ReverseStr(S);  
  Index := Pos(Token, S);  
  Inc(Index);  
  Move(S[Index], Temp[1], Length(S) - (Index - 1));  
  SetLength(Temp, Length(S) - (Index - 1));  
  StripLastToken := ReverseStr(Temp);  
end;  
  
  
procedure Register;  
begin  
  RegisterComponents('Unleash', [TMyFtp]);  
end;  
  
constructor TMyFtp.Create(AOwner: TComponent);  
begin  
  inherited Create(AOwner);  
  FCurFiles := TStringList.Create;  
  FINet := InternetOpen('WinINet1', 0, nil, 0, 0);  
end;  
  
destructor TMyFtp.Destroy;  
begin  
  if FINet <> nil then  
    InternetCloseHandle(FINet);  
  if FFtpHandle <> nil then  
    InternetCloseHandle(FFtpHandle);  
  inherited Destroy;  
end;  
  
function TMyFtp.Connect: Boolean;  
begin  
  FContext := 255;  
  FftpHandle := InternetConnect(FINet, PChar(FServer), 0,  
   PChar(FUserID), PChar(FPassWord),  
   Internet_Service_Ftp, 0, FContext);  
  if FFtpHandle = nil then  
    Result := False  
  else begin  
    SetUpNewDir;  
    Result := True;  
  end;  
end;  
  
function TMyFtp.GetCurrentDirectory: string;  
var  
  Len: Integer;  
  S: string;  
begin  
  Len := 0;  
  ftpGetCurrentDirectory(FFTPHandle, PChar(S), Len);  
  SetLength(S, Len);  
  ftpGetCurrentDirectory(FFTPHandle, PChar(S), Len);  
  Result := S;  
end;  
  
procedure TMyFtp.SetUpNewDir;  
begin  
  FCurDir := GetCurrentDirectory;  
  if Assigned(FOnNewDir) then  
    FOnNewDir(Self);               
end;  
  
function GetDots(NumDots: Integer): string;  
var  
  S: string;  
  i: Integer;  
begin  
  S := '';  
  for i := 1 to NumDots do  
    S := S + ' ';  
  Result := S;  
end;  
  
function GetFindDataStr(FindData: TWin32FindData): string;  
var  
  S: string;  
  Temp: string;  
begin  
  case FindData.dwFileAttributes of  
    FILE_ATTRIBUTE_ARCHIVE: S := 'A';  
//    FILE_ATTRIBUTE_COMPRESSED: S := 'C';  
    FILE_ATTRIBUTE_DIRECTORY: S := 'D';  
    FILE_ATTRIBUTE_HIDDEN: S := 'H';  
    FILE_ATTRIBUTE_NORMAL: S := 'N';  
    FILE_ATTRIBUTE_READONLY: S := 'R';  
    FILE_ATTRIBUTE_SYSTEM: S := 'S';  
    FILE_ATTRIBUTE_TEMPORARY: S := 'T';  
  else  
    S := IntToStr(FindData.dwFileAttributes);  
  end;  
  S := S + GetDots(75);  
  Move(FindData.CFilename[0], S[6], StrLen(FindData.CFileName));  
  Temp := IntToStr(FindData.nFileSizeLow);  
  Move(Temp[1], S[25], Length(Temp));  
  Result := S;  
end;  
  
function TMyFtp.FindFiles: TStringList;  
var  
  FindData: TWin32FindData;  
  FindHandle: HInternet;  
begin  
   FindHandle := FtpFindFirstFile(FFtphandle, '*.*',  
     FindData, 0, 0);  
   if FindHandle = nil then begin  
     Result := nil;  
     Exit;  
   end;  
   FCurFiles.Clear;  
   FCurFiles.Add(GetFindDataStr(FindData));  
   while InternetFindnextFile(FindHandle, @FindData) do  
     FCurFiles.Add(GetFindDataStr(FindData));  
   InternetCloseHandle(Findhandle);  
   GetCurrentDirectory;  
   Result := FCurFiles;  
end;  
  
function TMyFtp.CustomToFileName(S: string): string;  
const  
  PreSize = 6;  
var  
  Temp: string;  
  TempSize: Integer;  
begin  
  Temp := '';  
  TempSize := Length(S) - PreSize;   
  SetLength(Temp, TempSize);  
  Move(S[PreSize], Temp[1], TempSize);  
  Temp := GetFirstToken(Temp, ' ');  
  Result := Temp;  
end;  
  
function TMyFtp.BackOneDir: Boolean;  
var  
  S: string;  
begin  
  S := FCurDir;  
  S := StripLastToken(S, '/');  
  if S = '/' then begin  
    Result := False;  
    Exit;  
  end;  
  
  if S <> '' then begin  
    ChangeDirExact(S);  
    Result := True;  
  end else begin  
    ChangeDirExact('/');  
    Result := True;  
  end;  
  
end;  
  
// Changes to specific directory in S  
function TMyFtp.ChangeDirExact(S: string): Boolean;  
begin  
  if S <> '' then  
    FtpSetCurrentDirectory(FFTPHandle, PChar(S));  
  Result := True;  
  FindFiles;  
  SetUpNewDir;  
end;  
  
// Assumes S has been returned by GetFindDataString;  
function TMyFtp.ChangeDirCustom(S: string): Boolean;  
begin  
  S := CustomToFileName(S);  
  if S <> '' then  
    FtpSetCurrentDirectory(FFTPHandle, PChar(S));  
  Result := True;  
  FindFiles;  
  SetUpNewDir;  
end;  
  
function TMyFtp.GetFile(FTPFile, NewFile: string): Boolean;  
begin  
  Result := FtpGetFile(FFTPHandle, PChar(FTPFile), PChar(NewFile),  
               False, File_Attribute_Normal,  
               Ftp_Transfer_Type_Binary, 0);  
end;  
  
function TMyFtp.SendFile1(FTPFile, NewFile: string): Boolean;  
const  
  Size:DWord = 3000;  
var  
  Transfer: Bool;  
  Error: DWord;  
  S: string;  
begin  
  Transfer := FtpPutFile(FFTPHandle, PChar(FTPFile),   
                         PChar(NewFile),  
                         Ftp_Transfer_Type_Binary, 0);  
  
  if not Transfer then begin  
    Error := GetLastError;  
    ShowMessage(Format('Error Number: %d. Hex: %x',   
                       [Error, Error]));  
    SetLength(S, Size);  
    if not InternetGetLastResponseInfo(Error, PChar(S), Size) then   
    begin  
      Error := GetLastError;  
      ShowMessage(Format('Error Number: %d. Hex: %x',   
        [Error, Error]));  
    end;  
    ShowMessage(Format('Error Number: %d. Hex: %x Info: %s',   
                       [Error, Error, S]));  
  end else  
    ShowMessage('Success');  
  Result := Transfer;  
end;  
  
function TMyFtp.SendFile2(FTPFile, NewFile: string): Boolean;  
var  
  FHandle: HInternet;  
begin  
  FHandle :=  FtpOpenFile(FFTPHandle, 'sam.txt', GENERIC_READ,  
                           FTP_TRANSFER_TYPE_BINARY, 0);  
  if FHandle <> nil then  
  InternetCloseHandle(FHandle)  
  else  
    ShowMessage('Failed');  
  Result := True;  
end;  
  
end. 


后一页
前一页
回目录
回首页