说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

DELPHI 和 THE INTERNET

HTML文档下载 WORD文档下载 PDF文档下载
DELPHI 和 THE 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

一样调用这些函数。特别的是,您使用函数 ftpFindFirstFile 来取得这个路径下的第一

个函数。您可以不断地调用

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.

【直击美国云计算】出货量达x86的20多倍 ARM或将成为数据中心主角 孙小群:将SAP HANA打造为开放的PaaS平台 GitHub推出重大改进:强调速度、内容和交互性 如何打造测试工程师精英团队? 如何做个有“钱”途的测试工程师? 苹果开始关注企业移动化 iOS 7的10大办公功能 “开源群英会2013” 参会名单(持续更新中) 微软Builder2013前瞻 主打跨平台工具及服务 CMDN 29期:软件测试与管理之路 微软IE10与HIT FM 携手打造全新HTML5官网 专访GenMyModel CTO:一款全新在线建模工具背后的故事 【直击美国云计算】Jason Hoffman:数据和计算的融合将破坏全球利润 【直击美国云计算】如何做Hadoop、流处理框架等技术的采用选择 【直击美国云计算】细数云技术领域成王败寇:从SaaS到SDN 【直击美国云计算】谷歌Jeff Dean:成功的关键是专注 致远V5发布:强调大协同,企业移动化真来了 Mailbox:六星期实现从零到百万用户及日处理亿条消息 代码审查,也要天时地利人和 Clash of Clans产品总监:游戏中的商品定价一开始就要高 移动互联网最核心的竞争是:设计的竞争 【直击美国云计算】面对AWS,VMware不会畏缩 美国白宫任命Twitter法务总监Nicole Wong为副CTO Keek宣布推出首款视频Update API 专访阿里前端工程师:淘宝移动Web开发那些事儿 【直击美国云计算】为什么eBay用燃料电池来驱动他的犹他州数据中心 【直击美国云计算】6周发布新产品,LinkedIn的trunk-based开发 移动周报:疯狂吐槽还是更得欢心?细数iOS 7的是与非 国内最受欢迎的开源项目集锦 开始3D编程前需注意的十件事 [CTO俱乐部第100期]软件平台的新思维及2345技术团队管理经验分享 失败怪圈:今天的移动App在重蹈1999年的覆辙 我写了1个ip变域名的软件,发现现在都用防火墙,根本的不到域名,能不能用dns服务器或者其他方法写代码获得? 难道真的要去请电脑技术人员来帮忙了吗?急!急!急!!! 为什么有两个连接查询变量就不行呢代码如下: Rose进行JavaOOM的超级菜问题No.1:如何设置一个类MyButton成为JButton类的子类 如何在显示汉字 有关staroffice的问题 谁能告诉我完整的正式版本Dream_controls_collection for D6的下载地址呢? 百分求解有关ODBC的问题 那位知道最好的局域网聊天软件是什么? 数据库的问题 请问PB远程备份,恢复SQL SERVER2000应该怎样实现。(备份到本地硬盘)高分赠送 VCKBASE改版了,已经重新开张了!感激我的快给分!多少不限,呵呵... 那里有FrontPage server extension下载? 我什么我的程序从数据库取不出数据 C++Builder 中有没有关于SNMP 的控件啊? if not myrecord.bof then中的BOF是什么意思啊 Sybase数据库设备存放的地方? 高分救助:300分 一個通用的聯結sql server不能運行,help me 请大虾帮忙!这个SQL语句怎么写?多谢! 求教如何将enter转换为tab? win98下如何使用命令行方式共享文件夹 请问一个关于Iterator的问题. 我想把Access数据库里的内容只保留 1 天,超过 1 天的数据自动被删掉,请问该怎样设置。 拷贝构造函数实现多态性?!!你知道吗?........... 有多少人喜欢CCTV的张越和王小丫? 请问DES的最短代码的长度是多少?急急急,多多送分! 一个关于FlexGrid与MSChart的问题 请问有没有办法把一个报表导到一个Excel中? 数据管道对象....my_pipe.dataobject="p_pipe"(已经建好的数据管道对象)为什么提示 空对象?? 好象无法调用一个动态嵌入式框架中的函数 zhq2000(俗子) 谢谢你帮忙!我还有些不明白的地方想请教一下! cmos 如何下载JDK1.3版? 在DBGrid怎样移动一行数据?高分赠送 这个问题很奇怪!关于弹出菜单。 为什么 Rs->GetFieldValue 取两个字段的时候出错,只能一次去一个字段么? 用C#如何实现在form上画一条曲线,然后用鼠标托动曲线上的某一个点,该曲线的弧度根据鼠标的移动而变化 如何选择一行数据,条件是该数据的date类型的列为空(oracle)? 强烈建议!!!! 用过MSComm的朋友看过来。 清详细介绍ActiveX 请教众英雄: 怎么用C#写一个ComboBox Web Control 谢了!to anybody1 中国共享软件注册中心的2002年2月份汇款为什么现在还没到? 请问用DELPHI的ADO挂接的VFP数据库,进行删除只能是加删除标记,如何应DELPHI彻底删? 为什么 Rs->GetFieldValue 取两个字段的时候出错,只能一次去一个字段么? 请问用DELPHI的ADO挂接的VFP数据库,进行删除只能是加删除标记,如何应DELPHI彻底删? 怎样在weblogic5.1下建虚拟主机 ?xml+xsl=fo? 百分求解!!!!!!(给个思路也好呀) 如何判断酸碱性的强弱不用ph试纸判定 碳酸氢根离子以水解还是电离为主? 硫酸铁的电离方程式? 关于元素周期表的氧化性金属性稳定性酸碱性的强弱问题一直搞不懂. H2中氢元素的化合价 已知硫酸钾,硫酸镁,硫酸铁在水溶液中电离方程式如下(急)K2SO4=2K++SO42-,MgSO4=Mg2++SO42-,Fe2(SO4)3=2Fe3++3SO42-测得100ml混合液在c(SO42-)=1.2mol/L,c(k+)=0,2mol/L,c(Mg2+)=0.2mol/L,c(Fe3+)是多少 问几个有关盐的化学式!至少5个!急啊~~~ 氢元素有几种化合价最好有例子 元素周期表的前二十位是什么?初中是不是要背“氢氦锂铍;硼碳氮氧;氟氖钠镁;铝硅磷硫;氯氩钾钙” 这20个就OK了?请回答, 圆柱体的侧面积怎么求?大哥们 二氧化氢中氢元素的化合价是多少 元素周期表前20号元素的化合价 两个圆柱体的侧面积相等,它们的什么一定相等 溴化氢中氢元素化合价 硝酸铵加热分解的不同情况的产物是些什么? 2有一个圆柱体,它的底面积与侧面积正好相等.如果这个圆柱体的底面积不变,高增加2厘米,它的表面积就增加94.2m².原来这个圆柱的表面积是多少平方厘米? 硝酸铵受热分解的2个反应(普通的和有反应条件的) 我想用酒精灯加热硝酸铵制取硝酸.会不会爆炸. 元素周期表里非金属性强弱的问题如硫上面的是氧,硫右边的是氯,由于元素周期表里,向上向右非金属性都增强,那怎样判定他们氧和氯谁非金属性强呢 碳酸氢根离子的电离程度大还是水解程度大? 加热硝酸铵生成什么? 元素周期表中非金属元素的无恙酸与含氧酸酸性强弱针对高中时期 水解大于电离会怎么样,比如:NAHCO3,是溶液中的电离的碳酸氢根比水解的H2CO3少么? 甘蔗属于水果吗? 怎样通过原子结构或元素周期表上看出的非金属性强弱比较硝酸、磷酸、硫酸的酸性强弱?要通过原子结构或元素周期表啊!化学必修二课本上的练习题.从元素周期表上从左到右从下到上只能 碳酸氢根的电离和水解问题碳酸氢根电离出氢离子和碳酸根水解出氢氧根和碳酸那么水解出的氢氧根会和电离出的氢离子反应吗,那么不相互促进了吗 甘蔗的皮是什么组织 过氧化氢中氧元素和氢元素的化合价 削了皮的甘蔗怎么存放?买了甘蔗现场就削皮了但一次又吃不完能放冰箱存放吗? 锌和氯化铜溶液反应的方程式是什么? 一定条件下硝酸铵受热分解的化学方程式为5NH4NO3=2HNO3+4N2+9H2O,请用双线桥法写出,并标出电子转移数量和谁做氧化剂,谁做还原剂. 硝酸铵应具有的性质A.易溶于水B.有挥发性C.受热易分解 氯化铜溶液中加入一定量的铁和锌那个先反应啊?还是同时? 硝酸铵受热(或其他条件)分解产物!(希望全面一点)110 ℃时按下式分解:NH4NO3=HNO3+NH3↑ (无氧化还原反应) 在185 200 ℃,分解反应如下:NH4NO3=N2O↑+2H2O 氧化产物与还原产物物质的量 硝酸铵 有无挥发性 (2/2))锌粒与氯化铜溶液反应 硝酸铵受热分解方程式 在实验室中的应用 将某紫黑色固体粉末A加热,可产生无色气体B,同时生成一种黑色固体C和另一种固体物质D.黑色固体C通常可用于加热氯酸钾制氧气时的催化剂.另一黑色固体E在无色气体B中燃烧,产生使澄清石 加热硝酸铵制造笑气的注意事项 Jazz,Rock and Roll,Western and country music are the main type of popular music.这里是西部乡村乐,还是西部音乐和乡村音乐 无色气体A、B、C黑色粉末D、E、F已知A+C→B;B+D→A;E+D→B+Cu加热紫黑色固体得到F和C.求A、E化学式 我准备加热硝酸铵制笑气,但我知道硝酸铵很危险,请问有什么注意事项?要保证温度在什么范围内制得的是笑气,如何保证?同时笑气如何收集? 有什么好听的英文歌,最好是jazz.超级好听的哦~ 将暗紫色固体粉末A加热,可产生无色气体B,同时生成一种黑色固体C和另一种固体物质D.加热黑色固体C和氯酸钾混合物制氧气的文字表达式是什么?所发生的反应属于什么反应? 硝酸铵分解出氧化亚氮(一氧化二氮)是多少温度?还有,它分解成氨气和硝酸是什么温度? 希望大家介绍一点好听的爵士英文歌.最好是像Straight To Number One这种风格的,性感暧昧的爵士风格慢摇英文歌,不要雷死人的那种强劲版的,我很厌.由于我是新手,所以没有很多悬赏分,希望各位 甘蔗皮上的 白色物质 可以止血吗?在吃甘蔗的时候,剥皮的时候会从皮上掉下薄薄的一点白色东西,偶尔能粘在手上.谁知道那是什么东西吗?有止血的作用吗? 铵根的化合价为什么是正一价为什么呀 是怎么计算的? 氢氧化钙中钙元素的化合价~ 元素周期表中各族元素最外层电子数分别是多少? 铵根中氢的化合价是多少? 不能电离出硫酸根离子的是?1,Na2s2,Ba(OH)23,KMnO44,KCl这些哪个不能电离出硫酸根离子?为什么 讲讲 求轻爵士英文歌类似Norah Jones 的 don't know why 还有像Shelley Harland 的 In the dark,Laura Fygi的dream a Little dream 这样的,很有味道的英文歌,五六十年代的复古曲风都ok,比较抒情的~请不要复制别人的答案 元素周期表副族元素最外层电子数有什么特点? 知道圆柱体的侧面积咋算高? 氢氧根和氨根中各元素的化合价是多少 在元素周期表中最外层电子数指的是什么就是元素周期表中元素下的nsnpnd是什么?就像铜3d104s1 是最外层电子数吗?如果不是 那是什么? 圆柱体的侧面积和体积计算(在线等)一个圆柱体底面半径为3厘米,侧面展开后是一个正方形,则这个圆柱体的侧面积是多少平方厘米?体积是多少立方厘米? 好听的爵士乐或英文歌把谁唱的补充下 (多选)硝酸铵应具有的性质是( )A.易溶于水B.有挥发性C.受热易分解P.S 为什么不具有挥发性?不是要密封储存吗?
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘