程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 定時顯示遠程計算機的桌面

定時顯示遠程計算機的桌面

編輯:關於VC++

一、前言

看了大家寫了這麼多的代碼,自己也想貢獻一點。呵呵,很多的時候我們在qq的時候都想看看和自己聊天的對方在和哪些人聊天,有什麼辦法沒有?直接一點的就是截獲對方的桌面。我看了一下一般的截獲的桌面都沒有及時的顯示和更新,而且每次顯示的時候如果從磁盤中讀取的話速度未免太慢了一點,可不可以直接將bitmap的數據直接傳到網絡的終端顯示呢?ok這個方法應該可以。閒話免說。開始正式進入我們的話題。

二、服務程序實現

首先要的是在對方的電腦上放入服務器程序:EmployerSever.exe。網絡的傳送自然少不了的,我采用的是mfc CSocket。控制端的程序是點擊“開始服務”就可以接受網絡的另一端的連接了。服務端的關鍵是截取屏幕 ,並且發送出去。如下所示:

void CEmployerSeverDlg::CatchScreen()
{
   // protect類型 只用於內部函數的調用,
   //截獲屏幕位圖信息和數據信息分別放在btm和lpdata
   CDC dc;
   dc.CreateDC("DISPLAY",NULL,NULL,NULL);
   CBitmap bm;
   int Width=GetSystemMetrics(SM_CXSCREEN);
   int Height=GetSystemMetrics(SM_CYSCREEN);
   bm.CreateCompatibleBitmap(&dc,Width,Height);
   CDC tdc;
   tdc.CreateCompatibleDC(&dc);
   CBitmap*pOld=tdc.SelectObject(&bm);
   tdc.BitBlt(0,0,Width,Height,&dc,0,0,SRCCOPY);
   tdc.SelectObject(pOld);

   bm.GetBitmap(&btm);
   size=btm.bmWidthBytes*btm.bmHeight;
   lpData=new char[size];
   /////////////////////////////////////////////
   BITMAPINFOHEADER bih;
   bih.biBitCount=btm.bmBitsPixel;
   bih.biClrImportant=0;
   bih.biClrUsed=0;
   bih.biCompression=0;
   bih.biHeight=btm.bmHeight;
   bih.biPlanes=1;
   bih.biSize=sizeof(BITMAPINFOHEADER);
   bih.biSizeImage=size;
   bih.biWidth=btm.bmWidth;
   bih.biXPelsPerMeter=0;
   bih.biYPelsPerMeter=0;
   ///////////////////////////////////
   GetDIBits(dc,bm,0,bih.biHeight,lpData,(BITMAPINFO*)&bih,DIB_RGB_COLORS);
}

三、客戶端程序實現

其次是客戶端 BossSeeClient.exe,只要是用來接收對方的發過來的字節,並且造型為bitmap顯示在客戶區。首先在編輯中寫入要監視的對方的ip地址,這樣主機就會出現在右邊的視圖中了,雙擊對應的圖標就可以連接了,在這裡雙擊的時候我加入了記時器settimer雙擊之後,如果連接順利就可以在右邊的客戶端顯示對方的桌面的情況了。並且由於有定時,所以顯示會及時的更新,你可以根據自己的需要改變監視的時間,只要右鍵對方的ip地址就可以有對話框彈出更改自己的要求了。

void CBossSeeClientView::OnGetScreen()
{  //通過網絡獲得bitmap的信息填寫lpdata
  // TODO: Add your command handler code here
  if(m_pRecBMPSocket==NULL) return;
  if(lpData!=NULL)
  {delete lpData;lpData=NULL;}
  char MSGTYPE1[30]="B";

  int BTMInfoSize=24;
  char BTMInfoBuf[24];
  m_pRecBMPSocket->Send(MSGTYPE1,30);
   int ret=m_pRecBMPSocket->Receive(BTMInfoBuf,sizeof(BITMAP));
  if (ret!=24)
  { MessageBox("failed recive 24"); return;}
  BITMAP *BTMBUF=(BITMAP *)BTMInfoBuf;
  btm.bmBits=BTMBUF->bmBits;
    btm.bmBitsPixel=BTMBUF->bmBitsPixel;
  btm.bmHeight=BTMBUF->bmHeight;
  btm.bmPlanes=BTMBUF->bmPlanes;
  btm.bmType=BTMBUF->bmType;
  btm.bmWidth=BTMBUF->bmWidth;
  btm.bmWidthBytes=BTMBUF->bmWidthBytes;
  char MSGTYPE2[30]="D";
  m_pRecBMPSocket->Send(MSGTYPE2,30);
    int size=btm.bmWidthBytes*btm.bmHeight;
  lpData=new char[size];
    if(lpData==NULL)
    MessageBox("faile memery");
  char *pch=lpData ;
  int nBytesRec=0;
  int nBytesThisTime;
  do{   //發送的內容較大采用循環發送完成為止
   nBytesThisTime=m_pRecBMPSocket->Receive(pch,size-nBytesRec);
   nBytesRec+=nBytesThisTime;
   pch+=nBytesThisTime;
  }while(nBytesRecUpdateAllViews(NULL,NULL,NULL);//更新視圖
  /////////////////////////////////////
}
void CClientView::OnDraw(CDC* pDC)
{//顯示接收到的位圖信息
  CDocument* pDoc = GetDocument();
  // TODO: add draw code here
  if(lpData==NULL) return;
  BITMAP myBITMAP;
  myBITMAP.bmBits=btm.bmBits;
  myBITMAP.bmBitsPixel=btm.bmBitsPixel;
  myBITMAP.bmHeight=btm.bmHeight;
  myBITMAP.bmPlanes=btm.bmPlanes;
  myBITMAP.bmType=btm.bmType;
  myBITMAP.bmWidth=btm.bmWidth;
  myBITMAP.bmWidthBytes=btm.bmWidthBytes;
  BITMAPINFOHEADER bih;
  bih.biBitCount=myBITMAP.bmBitsPixel;
  bih.biClrImportant=0;
  bih.biClrUsed=0;
  bih.biCompression=0;
  bih.biHeight=myBITMAP.bmHeight;
  bih.biPlanes=1;
  bih.biSize=sizeof(BITMAPINFOHEADER);
  bih.biSizeImage=myBITMAP.bmWidthBytes*myBITMAP.bmHeight;
  bih.biWidth=myBITMAP.bmWidth;
  bih.biXPelsPerMeter=0;
  bih.biYPelsPerMeter=0;
    /////////////////////////
      CBitmap tbitmap;
  if(tbitmap.CreateBitmapIndirect(&myBITMAP)==NULL)
    MessageBox("b mull");
  if(tbitmap.m_hObject==NULL)MessageBox("NULL");

// CPaintDC tdc(this);
  CDC tmemdc;
  tmemdc.CreateCompatibleDC(pDC);
  SetDIBits(tmemdc.m_hDC,tbitmap,0,btm.bmHeight,lpData,(BITMAPINFO*)&bih,DIB_RGB_COLORS);
  CRect trect;
  GetClientRect(&trect);

  CBitmap* lpOldbit=tmemdc.SelectObject(&tbitmap);
  pDC->StretchBlt(0,0,trect.Width(),trect.Height(),
            &tmemdc,0,0,myBITMAP.bmWidth,
            myBITMAP.bmHeight,SRCCOPY);
}

四、尾聲

我在本機上測試了程序,是可以運行得很好的,但是當我在我們寢室的兩台機子對聯的時候

出現了問題,我想可能是因為SetDIBits()函數的時間消耗比較的大,再又由於網絡的原因所以導致一些問題。而且默認的 settimer 是1.5秒是不是時間上應該多放一點。

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved