{抓屏幕图像,保存为内存流--BMP流,压缩BMP流,JPG流,以及使用流}
{在网络中传送BMP流和JPG流的速度没测试过}
{BMP流的压缩是无损压缩}
{
全局变量
memoryStream:TMemoryStream;
memoryStream:=TMemoryStream.create;
}var
image:Timage;
jpgstream:TJPEGImage;
ss:tcanvas;begin
ss:=tcanvas.Create;
ss.Handle:=getdc(0);
image:=timage.Create(self);
image.width:=Screen.width;
image.Height:=screen.Height ;
image.picture.bitmap.PixelFormat:= pf16bit;
bitblt(image.canvas.handle,0,0,image.width,image.height,ss.handle,0,0,srccopy);{大大的BMP流
image.picture.bitmap.SaveToStream(memoryStream);
}{无损压缩BMP流 //uses Zlib.pas
//先定义变量count,DestStream,SourceStream
image.picture.bitmap.SaveToStream(memoryStream);
Count:=memoryStream.Size;
DestStream:=TMemoryStream.Create;
//压缩方式:clnone,clfastest,cldefault,clmax
SourceStream:=TCompressionStream.Create(cldefault, DestStream);
try
memoryStream.SaveToStream(SourceStream);
SourceStream.Free;
memoryStream.Clear;
memoryStream.WriteBuffer(Count, SizeOf(Count));
memoryStream.CopyFrom(DestStream, 0);
finally
DestStream.Free;
end;
}
{还原BMP流 //uses Zlib.pas
//先定义变量count,buffer,DestStream,SourceStream
//memoryStream是压缩的BMP流
memoryStream.ReadBuffer(Count, SizeOf(Count));
GetMem(Buffer, Count);
DestStream:=TMemoryStream.Create;
SourceStream:=TDecompressionStream.Create(memoryStream);
Try
SourceStream.ReadBuffer(Buffer^, Count);
DestStream.WriteBuffer(Buffer^, Count);
DestStream.Position:=0;
image.Picture.Bitmap.LoadFromStream(DestStream);
finally
FreeMem(Buffer);
DestStream.Free;
end;
}{JPG流 //uses jpeg
jpgstream:= TJPEGImage.Create;
jpgstream.Assign(image.picture.bitmap);
jpgstream.CompressionQuality:=50;//压缩质量
jpgstream.Compress;
jpgstream.SaveToStream(memoryStream);//保存为JPG流
//使用JPG流 image.Picture.Assign(jpgstream);
jpgstream.free;
}ReleaseDC(0,ss.Handle);
image.free;{发送内存流...}
end;
{在网络中传送BMP流和JPG流的速度没测试过}
{BMP流的压缩是无损压缩}
{
全局变量
memoryStream:TMemoryStream;
memoryStream:=TMemoryStream.create;
}var
image:Timage;
jpgstream:TJPEGImage;
ss:tcanvas;begin
ss:=tcanvas.Create;
ss.Handle:=getdc(0);
image:=timage.Create(self);
image.width:=Screen.width;
image.Height:=screen.Height ;
image.picture.bitmap.PixelFormat:= pf16bit;
bitblt(image.canvas.handle,0,0,image.width,image.height,ss.handle,0,0,srccopy);{大大的BMP流
image.picture.bitmap.SaveToStream(memoryStream);
}{无损压缩BMP流 //uses Zlib.pas
//先定义变量count,DestStream,SourceStream
image.picture.bitmap.SaveToStream(memoryStream);
Count:=memoryStream.Size;
DestStream:=TMemoryStream.Create;
//压缩方式:clnone,clfastest,cldefault,clmax
SourceStream:=TCompressionStream.Create(cldefault, DestStream);
try
memoryStream.SaveToStream(SourceStream);
SourceStream.Free;
memoryStream.Clear;
memoryStream.WriteBuffer(Count, SizeOf(Count));
memoryStream.CopyFrom(DestStream, 0);
finally
DestStream.Free;
end;
}
{还原BMP流 //uses Zlib.pas
//先定义变量count,buffer,DestStream,SourceStream
//memoryStream是压缩的BMP流
memoryStream.ReadBuffer(Count, SizeOf(Count));
GetMem(Buffer, Count);
DestStream:=TMemoryStream.Create;
SourceStream:=TDecompressionStream.Create(memoryStream);
Try
SourceStream.ReadBuffer(Buffer^, Count);
DestStream.WriteBuffer(Buffer^, Count);
DestStream.Position:=0;
image.Picture.Bitmap.LoadFromStream(DestStream);
finally
FreeMem(Buffer);
DestStream.Free;
end;
}{JPG流 //uses jpeg
jpgstream:= TJPEGImage.Create;
jpgstream.Assign(image.picture.bitmap);
jpgstream.CompressionQuality:=50;//压缩质量
jpgstream.Compress;
jpgstream.SaveToStream(memoryStream);//保存为JPG流
//使用JPG流 image.Picture.Assign(jpgstream);
jpgstream.free;
}ReleaseDC(0,ss.Handle);
image.free;{发送内存流...}
end;
解决方案 »
- 请问Delphi2007 广州报价是多少?
- delphi+ado访问数据库的书或者教程哪里有比较详细的?
- 新手问题
- 菜鸟问题!如何用DBGrid把ADODataSet的记录集显示出来?
- delphi 7中的QReport怎么没有了?
- 怎么样注册一个COM
- 我在研究Corba时出现了下面的问题:[Fatal Error] Project1_TLB.pas(32): File not found: 'OrbPas.dcu'
- 关于使用webbrowser读取 页面input信息的问题
- 小女子有礼了!
- 打印自定义大小的报表报表
- 一般说来:复杂、耗费资源的操作放在服务器端,在select,insert,delete,update,这四个操作中,哪些耗费资源多,网络流量大??//牛虻
- 换个问法!!!(ADO问题)
在网络管理中,有时需要通过监视远程计算机屏幕来了解网上微机的使用情况。虽然,市面上有很多软件可以实现该功能,有些甚至可以进行远程控制,但在使用上缺乏灵活性,如无法指定远程计算机屏幕区域的大小和位置,进而无法在一屏上同时监视多个屏幕。其实,可以用Delphi自行编制一个灵活的远程屏幕抓取工具,简述如下。
一、软硬件要求。
Windows95/98对等网,用来监视的计算机(以下简称主控机)和被监视的计算机(以下简称受控机)都必须装有TCP/IP 协议,并正确配置。如没有网络,也可以在一台计算机上进行调试。
二、实现方法。
编制两个应用程序,一个为VClient.exe,装在受控机上,另一个为VServer.exe,装在主控机上。VServer.exe指定要监视的受控机的IP地址和将要在受控机屏幕上抓取区域的大小和位置,并发出屏幕抓取指令给VClient.exe,VClient.exe得到指令后,在受控机屏幕上选取指定区域,生成数据流,将其发回主控机,并在主控机上显示出抓取区域的BMP图象。由以上过程可以看出,该方法的关键有二:一是如何在受控机上进行屏幕抓取,二是如何通过TCP/IP协议在两台计算机中传输数据。
UDP(User Datagram Protocol,意为用户报文协议)是Internet上广泛采用的通信协议之一。与TCP协议不同,它是一种非连接的传输协议,没有确认机制,可靠性不如TCP,但它的效率却比TCP高,用于远程屏幕监视还是比较适合的。同时,UDP控件不区分服务器端和客户端,只区分发送端和接收端,编程上较为简单,故选用UDP协议,使用Delphi 4.0提供的TNMUDP控件。
三、创建演示程序。
第一步,编制VClient.exe文件。新建Delphi工程,将默认窗体的Name属性设为“Client”。加入TNMUDP控件,Name属性设为“CUDP”;LocalPort属性设为“1111”,让控件CUDP监视受控机的1111端口,当有数据发送到该口时,触发控件CUDP的OnDataReceived事件;RemotePort属性设为“2222”,当控件CUDP发送数据时,将数据发到主控机的2222口。
在implementation后面加入变量定义
const BufSize=2048;{ 发送每一笔数据的缓冲区大小 }varBmpStream:TMemoryStream;LeftSize:Longint;{ 发送每一笔数据后剩余的字节数 }
为Client的OnCreate事件添加代码:procedure TClient.FormCreate(Sender: TObject);beginBmpStream:=TMemoryStream.Create;end;
为Client的OnDestroy事件添加代码:procedure TClient.FormDestroy(Sender: TObject);beginBmpStream.Free;end;
为控件CUDP的OnDataReceived事件添加代码:procedure TClient.CUDPDataReceived(Sender: TComponent;NumberBytes: Integer; FromIP: String);varCtrlCode:array[0..29] of char;Buf:array[0..BufSize-1] of char;TmpStr:string;SendSizeLeftPosTopPosRightPosBottomPos:integer;beginCUDP.ReadBuffer(CtrlCodeNumberBytes);{ 读取控制码 }if CtrlCode[0]+CtrlCode[1]+CtrlCode[2]+CtrlCode[3]='show' thenbegin { 控制码前4位为“show”表示主控机发出了抓屏指令 }if BmpStream.Size=0 then { 没有数据可发,必须截屏生成数据 }beginTmpStr:=StrPas(CtrlCode);TmpStr:=Copy(TmpStr5Length(TmpStr)-4);LeftPos:=StrToInt(Copy(TmpStr1Pos(':'TmpStr)-1));TmpStr:=Copy(TmpStrPos(':'TmpStr)+1Length(TmpStr)-Pos(':'TmpStr));TopPos:=StrToInt(Copy(TmpStr1Pos(':'TmpStr)-1));TmpStr:=Copy(TmpStrPos(':'TmpStr)+1Length(TmpStr)-Pos(':'TmpStr));RightPos:=StrToInt(Copy(TmpStr1Pos(':'TmpStr)-1));BottomPos:=StrToInt(Copy(TmpStrPos(':'TmpStr)+1Length(TmpStr)-Pos(':'TmpStr)));ScreenCap(LeftPosTopPosRightPosBottomPos); {截取屏幕 }end;if LeftSize>BufSize then SendSize:=BufSizeelse SendSize:=LeftSize;BmpStream.ReadBuffer(BufSendSize);LeftSize:=LeftSize-SendSize;if LeftSize=0 then BmpStream.Clear;{ 清空流 }CUDP.RemoteHost:=FromIP; { FromIP为主控机IP地址 }CUDP.SendBuffer(BufSendSize); { 将数据发到主控机的2222口 }end;end;
其中ScreenCap是自定义函数,截取屏幕指定区域,代码如下:procedure TClient.ScreenCap(LeftPosTopPos
RightPosBottomPos:integer);varRectWidthRectHeight:integer;SourceDCDestDCBhandle:integer;Bitmap:TBitmap;beginRectWidth:=RightPos-LeftPos;RectHeight:=BottomPos-TopPos;SourceDC:=CreateDC('DISPLAY'''''nil);DestDC:=CreateCompatibleDC(SourceDC);Bhandle:=CreateCompatibleBitmap(SourceDC
RectWidthRectHeight);SelectObject(DestDCBhandle);BitBlt(DestDC00RectWidthRectHeightSourceDC
LeftPosTopPosSRCCOPY);Bitmap:=TBitmap.Create;Bitmap.Handle:=BHandle;BitMap.SaveToStream(BmpStream);BmpStream.Position:=0;LeftSize:=BmpStream.Size;Bitmap.Free;DeleteDC(DestDC);ReleaseDC(BhandleSourceDC);end;存为“C:\VClient\ClnUnit.pas”和“C:\VClient\VClient.dpr”,并编译。
第二步,编制VServer.exe文件。新建Delphi工程,将窗体的Name属性设为“Server”。加入TNMUDP控件,Name属性设为“SUDP”;LocalPort属性设为“2222”,让控件SUDP监视主控机的2222端口,当有数据发送到该口时,触发控件SUDP的OnDataReceived事件;RemotePort属性设为“1111”,当控件SUDP发送数据时,将数据发到受控机的1111口。加入控件Image1,Align属性设为“alClient”;加入控件Button1,Caption属性设为“截屏”;加入控件Label1,Caption属性设为“左:上:右:下”;加入控件Edit1,Text属性设为“0:0:100:100”;加入控件Label2,Caption属性设为“受控机IP地址”;加入控件Edit2,Text属性设为“127.0.0.1”;
在implementation后面加入变量定义const BufSize=2048;varRsltStreamTmpStream:TMemoryStream;
为Server的OnCreate事件添加代码:procedure TServer.FormCreate(Sender: TObject);beginRsltStream:=TMemoryStream.Create;TmpStream:=TMemoryStream.Create;end;
为Client的OnDestroy事件添加代码:procedure TServer.FormDestroy(Sender: TObject);beginRsltStream.Free;TmpStream.Free;end;
为控件Button1的OnClick事件添加代码:procedure TServer.Button1Click(Sender: TObject);var ReqCode:array[0..29] of char;ReqCodeStr:string;beginReqCodeStr:='show'+Edit1.Text;StrpCopy(ReqCodeReqCodeStr);TmpStream.Clear;RsltStream.Clear;SUDP.RemoteHost:=Edit2.Text;SUDP.SendBuffer(ReqCode30);end;
为控件SUDP的OnDataReceived事件添加代码:procedure TServer.SUDPDataReceived(Sender: TComponent;NumberBytes: Integer; FromIP: String);var ReqCode:array[0..29] of char;ReqCodeStr:string;beginReqCodeStr:='show'+Edit1.text;StrpCopy(ReqCodeReqCodeStr);SUDP.ReadStream(TmpStream);RsltStream.CopyFrom(TmpStreamNumberBytes);if NumberBytes< BufSize then { 数据已读完 }beginRsltStream.Position:=0;Image1.Picture.Bitmap.LoadFromStream(RsltStream);TmpStream.Clear;RsltStream.Clear;endelsebeginTmpStream.Clear;ReqCode:='show';SUDP.RemoteHost:=Edit2.Text;SUDP.SendBuffer(ReqCode30);end;end;
存为“C:\VServer\SvrUnit.pas”和“C:\VServer\VServer.dpr”,并编译。四、测试。
1、本地机测试:在本地机同时运行Vserver.exe和VClient.exe,利用程序的默认设置,即可实现截屏。查看“控制面板”-“网络”-“TCP/IP”-“IP地址”,将程序的“客户IP地址”设为该地址 ,同样正常运行。
2、远程测试:选一台受控机,运行VClient.exe;另选一台主控机,运行VServer.exe,将“受控机IP地址”即Edit2的内容设为受控机的IP地址,“截屏”即可。以上简要介绍了远程屏幕抓取的实现方法,至于在主控机上一屏同时监视多个受控机,读者可自行完善。以上程序,在Windows98对等网、Delphi 4.0下调试通过。
OK,我试试 !
---- WinSock是一组API,用于在网络上传输数据和交换信息。虽然现在有很多工具如FTP程序可以在网络上传输数据和文件,但是通过WinSock编程有更大的灵活性,它不需要关心网络连接的细节,然而用WinSock编程却很复杂,但是在Delphi中我们并不需要直接与WinSock的API打交道,因为TClientSocket元件和TServerSocket元件(在Internet页)封装了WinSock的大部分API,使得对WinSock的访问大大简化。下面这个远程控制的例子就很清楚地说明了这个问题,它可以发送一个消息给对方,并能够使对方的电脑关闭、重新启动或重新登录。
一、实现原理
---- 实行远程控制,实际上就是一个服务器程序(以下简称被控程序)和一个客户程序(以下简称主控程序):被控方即为服务器程序,它监听客户的请求,并作出处理;主控方即为客户程序,它连接上服务器后,发出自己的请求,服务器便根据自已的请求进行不同的响应。
二、编写主控程序
---- 1、新建一个项目Client.dpr,并把一个TClientSocket元件放到Form上,它的属性设置如下:Port设为100(端口号可任意设置,只要求双方统一),其它属性按默认值。在窗体上添加两个TEdit:Edit1用来输入发送的字符,Edit2用来输入IP地址;添加两个TButton:Button1点击后用来连接被控机,Button2点击后用来发送字符,然后声明一个私有变量ConnectFlag,表示双方是否连接好:
private
ConnectFlag:Boolean;
---- 2、ClientSocket1的OnConnect事件代码如下:
procedure TForm1.ClientSocket1Connect
(Sender: TObject;Socket: TCustomWinSocket);
begin
ConnectFlag:=True; //表示连接成功
end;
---- 3、ClientSocket1的OnError事件代码如下:
procedure TForm1.ClientSocket1Error(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent:
TErrorEvent;var ErrorCode: Integer);
begin
Application.MessageBox(PChar(' 不能连接到IP地址
: ' + Edit2.Text+'。'+
#13+'可能是监听程序没有运行或网络故障!'),'
连接错误',MB_OK+MB_ICONSTOP);
ErrorCode := 0;
end;
---- 4、Button1的OnClick事件代码如下:
procedure TForm1.Button1Click(Sender: TObject);
begin
with ClientSocket1 do begin
if Active then begin
Active := False;//在连接之前首先关闭
ConnectFlag:=False; //置连接标志为假
end;
if Length(Edit2.Text) > 0 then begin
Host := Edit2.Text; //指定IP地址或主机名
Active := True;
end;
end;
end;
---- 5、Button2的OnClick事件代码如下:
procedure TForm1.Button2Click(Sender: TObject);
begin
if ConnectFlag then
ClientSocket1.Socket.SendText(Edit1.Text)
//如果连接成功则发送字符串
else
Application.MessageBox(PChar(' 没有连接到地址 :
' + Edit2.Text+'。'+
#13+'检查IP地址是否存在或是否已经连接!'),'
提示信息',MB_OK+MB_ICONSTOP);
end;
三、编写被控程序
---- 1、新建一个项目Server.dpr,并把一个TServerSocket元件放到Form上,它的属性设置如下:Active设为True;Port设为100,其它属性按默认值。
---- 2、ServerSocket1的OnClientRead事件代码如下:
procedure TForm1.ServerSocket1ClientRead
(Sender: TObject;Socket: TCustomWinSocket);
var
Str:PChar;
Code,V:Integer;
begin
Str:=PChar(Socket.ReceiveText); //接收字符串
Val(Str,V,Code); //处理接收的字符串,首先转换字符串为整数
if Code< >0 then
Application.MessageBox(Str,'提示信息',
MB_OK+MB_ICONINFORMATION)
//如果转换后的数据不是一个整型数就通过消息框来显示字符串
else
if (V=0)or(V=1)or(V=2) then
ExitWindowsEx(V,0)
//调用Windows的API函数(V=0表示重新登录、
V=1表示关机、V=2表示重启动)
else
Application.MessageBox(Str,'提示信息',
MB_OK+MB_ICONINFORMATION);
//转换后数据不为0、1、2时在消息框内显示字符串
end;
---- 3、修改项目文件,不让窗口显示并且防止它运行两次,修改begin和end之间的代码如下:
begin
Application.Initialize;
if FindWindow('TForm1','Form1')=0 then begin
//当没有找到Form1时执行下面代码
Application.ShowMainForm:=False; //不显示主窗口
Application.CreateForm(TForm1, Form1);
Application.Run;
end;
end.
四、注意事项
---- 1、网络要装配正确并安装TCP/IP协议,且要正常运行。
---- 2、首先要运行被控程序。
---- 3、必须知道对方的IP地址或主机名。
将远程控制应用于教学中,已成为目前计算机化教学的重要手段。一定有很多的网虫想了解
这种网络教学方式的编程原理吧。在此我们就以一个简单的远程控制程序作为示例,说明这
种网络编程的基本原理。本程序以Delphi编程为例。
其实该程序的工作机制很简单,受控方运行一个程序,用于侦听端口并接收数据包,而
主控方通过端口给受控方的端口发送数据包。根据这个原理,我们编写两个程序,一个是控
制方的,而另一个是受控方的,把这两个程序运行在两台不同的机器上,受控机等待控制机
发送过来的数据然后执行相应的操作(如本例中的重启)。
Delphi中有两类控件可以实现上面的目的。一类是控制方使用ClientSocket,受控方
使用ServerSocket(均在Internet页),另一类是双方都使用NMUDP(在FastNet页)。我们
知道网络传输都是不可靠的,也就是说传输的数据有可能丢失,而这两类控件的区别是前者
使用TCP(Transfer Control Protocol,传输控制协议)。TCP协议是面向连接,每次双方
建立连接(或断开)时需经过三次握手,较为耗时,但数据传输可靠;而后者使用UDP(User
Datagram Protocol,用户报文协议),它是面向无连接的,发出数据不需对方确认,这样
速度比TCP快,但数据有可能丢失,因此它不可靠。由于控制所需传送的数据量不大,而且需
要较高的可靠性,因此一般使用前者,程序说明如下:
第一步,开始控制方程序,在其中加入clientsocket控件,取名control,设置host属
性为受控机ip地址,port属性为1234(端口可以随便设置,但不要与一些默认端口重复,如80等)。
第二步,在FormCreate事件中加入代码control.open; //打开与受控机的通信
第三步,加入个Button,设置caption为“重新启动”,并在ButtonClick事件中加入
代码control.Socket.SendText('reboot');//通知受控机重新启动。这样就完成了控制
方的工作了。
第四步,开始受控方的程序,在其中加入serversocket控件,取名undercontrol,设置
port属性为1234(与控制方的端口一致),active属性为true;
第五步,在undercontrol的OnclientRead事件中加入代码if Socket.ReceiveText=
'reboot' then
ExitWindowsEx(EWX_REBOOT,2); //重启的API函数
这样就完成了代码的工作,然后编译这两个程序生成两个.exe文件分别放在两台机器上运行
(记得先运行Win98下的受控机程序),在控制机按下“重新启动”的Button(按钮),受控机就重
新启动了。远程控制机器重启成功实现。
由于篇幅的限制,以上忽略了很多细节的东西(如出错处理),而且只能完成远程控制的一种
功能,有兴趣者可在此基础上完善,可实现网络软件管理中的其它功能,如鼠标、键盘锁定、关
机、抓取屏幕、文件操作、视频传输等,在此就不多介绍了,有兴趣者可以上网多查看些这方面
的资料。 远程控制篇:测试IP地址使用 i:=1 to 254 do begin...end即可自动搜索地址
要知道这个IP地址是否中镖,可向它发一个字符串。如果接收到这个IP返回来的预定的字符串,
如发出"我是长江",返回"我是黄河",就可以控制这个IP地址了{uses winsock}
function testip(IP:string):string;
var
WSAData:TWSADATA;
Addr:DWORD;
begin
WSAStartup(2, WSAData);
Addr:=inet_addr(PChar(IP));
if gethostbyaddr(@Addr,sizeof(Addr),PF_INET)=nil then
result:=''
else result:=ip;
WSACleanup();
end;
远程控制篇:模拟按键模拟鼠标
鼠标移动(移动量dx,dy)
mouse_event(MOUSEEVENTF_MOVE,dx,dy,0, 0 );
鼠标在(x,y)处按下或释放
setcursorpos(x,y);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 );
mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0 );
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 );
mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0 );
鼠标双击由两次按下与释放来模拟键盘模拟
一般虚拟键值(VK_)由KeyDown或keyup事件得到
特殊键值
Tab--9
Shift--16
Ctrl--17
Alt--18
CapsLock--20
Esc--27
Win--91,92
NumLock--144
ScrollLock--145按下键
keybd_event(key, MapVirtualKey(key, 0 ), KEYEVENTF_KEYUP , 0 );
释放键
keybd_event(key, MapVirtualKey(key, 0 ), 0 , 0 );
以上做法对大多数键有效,少数键要用到不同的值远程控制篇:获得网络邻居所有机器名procedure TForm1.Button1Click(Sender: TObject);
VAR
command:string ;
comline: pchar ;
begin
command:='COMMAND.COM /C net view>c:\~~~.txt';
comline:=pchar(command);
WinExec(comline, sw_hide);
timer1.Enabled:=true;
end;每秒试一次
procedure TForm1.Timer1Timer(Sender: TObject);
var f:tstringlist;
ll,ii:integer;
s1,s:string;
b:bool;
begin
f:=tstringlist.Create;
try
f.LoadFromFile('c:\~~~.txt');
except
end;
if f.Count>10 then begin
memo1.Clear;
memo1.lines.add(f.text);
timer1.Enabled:=false;
f.Free;
{去掉多余的行和'\\'}
for ll:=memo1.lines.count-1 downto 0 do begin
if strpos(pchar(memo1.lines.strings[ll]),'\\')=nil then
memo1.lines.delete(ll)
else
memo1.lines.Strings[ll]:=delxxx(memo1.lines.Strings[ll]);
{自编1个去'\\'的函数}
end;
timer1.enabled:=False;
end;远程控制篇:通过机器名得到IP地址function procedure TForm1.nametoip(name:string):string;
var
WSAData: TWSAData;
HostEnt: PHostEnt;
begin
result:='';
WSAStartup(2, WSAData);
HostEnt := gethostbyname(PChar(name));
if HostEnt <> nil then
begin
with HostEnt^ do
result:= Format('%d.%d.%d.%d', [Byte(h_addr^[0]), Byte(h_addr^[1]), Byte(h_addr^[2]), Byte(h_addr^[3])]);
end;
WSACleanup;
end;通过IP地址得到机器名function iptoname(ip:string):string;
var
WSAData:TWSAData;
p:PHostEnt;
InetAddr:dword;
begin
WSAStartup(2, WSAData);
InetAddr:= inet_addr(PChar(IP));
try
p:=GetHostByAddr(@InetAddr, Length(IP), PF_Inet);
result:=p^.h_name;
except
result:='';
end;
end;远程控制篇:服务端程序的隐藏1 按ctrl+alt+del时不出现在关闭程序框
function RegisterServiceProcess (dwProcessID, dwType: DWord) : DWord;
stdcall; external 'KERNEL32.DLL';
不出现
RegisterServiceProcess(GetCurrentProcessID, RSPSIMPLESERVICE);
出现
RegisterServiceProcess(GetCurrentProcessID, RSPUNREGISTERSERVICE);2 程序的图标不出现在任务栏
在Application.Initialize;后加上
Application.ShowMainForm:=False;以上做法在WIN2000下是无效的。
编程软件如VC,DELPHI中都带有进程查看工具。
1
服务端关机时的处理一般这类程序在运行时,当进行关机操作,其它程序都被关掉了,只有它们不为所动。所以必须对
关机消息进行处理。procedure exitwin(var msg:TWMQUERYENDSESSION);message WM_QUERYENDSESSION;
procedure TServer.exitwin(var msg: TWMQUERYENDSESSION);
begin
inherited;
server.Close;
end;程序退出时写注册表,防止用regedit或msconfig把服务端程序从注册表中去。这样regedit或msconfig所作的工作白费,除非立即关电源
procedure TServer.FormDestroy(Sender: TObject);
var
reg:Tregistry;
s:string;
begin
s:=application.ExeName;
reg:=Tregistry.Create;
Reg.RootKey:=HKEY_LOCAL_MACHINE;
Reg.OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\RunServices',True);
Reg.WriteString(...);
reg.free;
end;连同上面的屏幕抓取,应该是相对完整的一份远程控制文档,good luck。
做出好东西不要忘了给我一份,不过不要黑我哦!