小弟想做一个像PCAnywhere一样的能显示远程屏幕一举一动的程序,但如果每次用全屏截取再数据传输,那肯定是不可取的.我想PCAnywhere一定是获取了哪个消息,然后截取其中的刷新区域来的.不知道应该如何做?

解决方案 »

  1.   

    建议你去看VNC开放源码,是VC的,都用DELPHI来实现,效率太差吧
    你如果用DELPHI重写了,欢迎共享出来,我先预定一份
      

  2.   

    如果你想抓到windows API InvalidateRect所發出的消息,我對你所要做的東西是沒用的!
    頻率太高了!
      

  3.   

    出处:http://expert.csdn.net/Expert/topic/2298/2298878.xml?temp=.1626093很多木马程序支持了屏幕回传的功能,其根本的原理是先捕获屏幕画面,然后回 
    传给客户机,由于画面的数据量很大所以,很多木马程序都是在画面改变的时候才回传改变 
    部分的画面,常用的手段是最小矩形法,下面以好友“古老传说”的一段算法举例: 
    #define MAXXCount 10 //屏幕X方向最多分割块数 
    #define MAXYCount 5 //... Y................ 
    #define DestNum 1000 //每块的偏移检测点最大个数 
    COLORREF Colors[MAXXCount][MAXYCount][DestNum]; 
    COLORREF BakColors[MAXXCount]{MAXYCount][DestNum]; 
    TPoint Dests[DestNum]; 
    int Sw; 
    int Sh; 
    int xCount; 
    int yCount; 
    int ItemWidth; 
    int ItemHeight; 
    int Dnum; 
    int Qlity; 
    //得到消息后执行: 
    //另外:接收到的数据包中分析出 Dnum ,Qlity 
    //Dnum:偏移观测点数量 
    //Qlity:图象要求质量 
    __fastcall TForm1::CopyScreen(int DNum,int Qlity){ 
    ItemWidth=Sw/xCount; 
    ItemHeight=Sh/yCount; 
    Sw=Screen->Width; 
    Sh=Screen->Height; 
    xCount=(Sw>1000)?8:6; 
    yCount=(Sh>1000)?3:2; 
    for (int num1=0;num1 Dests[num1].x=random(ItemWidth); 
    Dests[num1].y=random(ItemHeight); 

    CatchScreen(DNum,Qlity); 

    //收到刷屏消息后只执行: 
    CatchScreen(DNum,Qlity); 
    __fastcall TForm1::CatchScreen(int DNum,int Qlity){ 
    //函数功能:扫描改变的屏幕区域,并切经过优化处理,最后发送这些区域数据 
    //DNum: 偏移量 Qlity:图象质量 
    HDC dc=GetDC(GetDesktopWindow()); 
    Graphics::TBitmap *bm=new Graphics::TBitmap; 
    bm->Width=Sw; 
    bm->Height=Sh; 
    BitBlt(bm->Canvas->Handle,0,0,Sw-1,Sh-1,dc,0,0); 
    int num1,num2,num3; 
    int nowx,nowy; 
    bool Change; 
    bool ItemChange[MAXXCount][MAXYCount]; 
    for (num1=0;num1 nowx=ItemWidth*num1; 
    for (num2=0;num2 nowy=ItemHeight*num2; 
    Change=false; 
    for (num3=0;num3 Colors[num1][num2][num3]=bm->Canvas->Pixels[nowx+Dests[num3].x] 
    [nowy+Dests[num3].y]; 
    if (Colors[num1][num2][num3]!=BakColors[num1][num2][num3]){ 
    BakColors[num1][num2][num3]=Colors[num1][num2][num3]; 
    ItemChange[num1][num2]=true; 



    } int CNum,MaxCNum; 
    int ChangedNum=0; 
    TRect *Rect; 
    int num4; 
    int MinSize=10000; 
    int m; 
    TRect MinRect; 
    Graphics::TBitmap *bt2=new Graphics::TBitmap; 
    TJPEGImage *j=new TJPEGImage; 
    //************************ 
    j->Quality=Qlity; 
    //************************ 
    CopyScreenUint CopyScreen; 
    CopyScreenItemUint CopyScreenItem; 
    TMemoryStream *ms=new TMemoryStream; 
    ms->Write(&TcpMsg,sizeof(TcpMsgUint)); 
    ms->Write(&CopyScreen,sizeof(CopyScreenUint)); 
    do{ 
    for (num1=0;num1 for (num2=0;num2 for (num3=num1+1;num3<=xCount;num3++){ 
    MaxCNum=0; 
    for (num4=num2+1;num4<=yCount;num4++){ //遍历所有矩形 
    CNum=GetChangedNum(TRect(num1,num2,num3,num4)); 
    if (CNum>MaxCNum) MaxCNum=CNum; 
    m=(num3-num1)*(num4-num2); 
    if (2*m-CNum MinSize=2*m-CNum; 
    MinRect=TRect(num1,num2,num3,num4); 



    TMemoryStream *ms; 
    BitBlt(bt2->Canvas->Handle,0,0,ItemWidth-1,ItemHeight-1,bt->Canvas->Handle,0,0); 
    j->Assign(bt2); 
    j->SaveToStream(ms2); 
    CopyScreenItem.Rect=TRect(num1,num2,num3,num4); 
    CopyScreenItem.FileType=JPEGFILE; //JPEGFILE 定义为:#define JPEGFILE 1 
    ms2->Position=0; 
    CopyScreenItem.Length=ms2->Size; 
    ms->Write(&CopyScreenItem,sizeof(ScreenItemUint)); 
    ms->CopyFrom(ms2,ms2->Size); 
    ChangedNum++; 
    }while(MaxCNum>0); 
    TcpMsg.Type=MsgCopyScreen; 
    ms->Position=0; 
    TcpMsg.Length=ms->Size-sizeof(TcpMsgUint); 
    CopyScreen.Count=ChangedNum; 
    ms->Write(&TcpMsg,sizeof(TcpMsgUint)); 
    ms->Write(&CopyScreen,sizeof(CopyScreenUInt)); 
    ms->Position=0; 
    sock->SendStream(ms); 
    }   这个程序把屏幕画面切分为了多个部分,并存储画面为JPG格式,这样压缩率就变的十分 
    的高了。通过这种方法压缩处理过的数据,变得十分小.
      

  4.   

    使用系统钩子, Hook 键盘和鼠标, 及 Windows 的消息即可, 若是屏幕改变可以钩 WM_PAINT 消息.