远程监视器(客户端)

源码下载:http://user.qzone.qq.com/58408454/blog/1255252449

//
//*
//*工程: 远程监视器
//*作者: 童方
//*时间: 2009-9-11
//*说明: 1 客户端,即: 主监视端
//*      2 未做数据压缩处理(如果您为本例程加入压缩算法或扩展功能,希望您可以发给我一份您更新后的源码)
//*      3 愿我的代码给您带来小小的启发和帮助
//*      4 也希望您给我提供宝贵的意见,互相学习,共同进步
//*
//*联系方式: QQ 58408454  Email shfhere@qq.com
//*
//

#include "stdafx.h"
#include "MonitorClient.h"
#include "MonitorClientDlg.h"
//#include "../zlib/zlib.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CAboutDlg dialog used for App About

//*工作线程,用于实时接收服务端图象,并实时绘制
UINT WorkThread(LPVOID lpParam)
{
 CMonitorClientDlg* me = (CMonitorClientDlg*)lpParam;
 return me->WorkProc();
}
//*
BOOL MySend(SOCKET sock, LPVOID lpData, int nSize)
{
 //*自订义数据发送,直到发送完成时才返回
 char* Buf = (char*)lpData;
 int nLen = nSize;
 int n;
 int nIndex = 0;
 while(nLen > 0)
 {
  n = send(sock, &Buf[nIndex], nLen, 0);
  if(n == SOCKET_ERROR)
   return FALSE;
  nIndex += n;
  nLen -= n;
 }
 return TRUE;
}

BOOL MyReceive(SOCKET sock, LPVOID lpData, int nSize)
{
 //*自订义数据接收,直到接收到指定大小的数据后才返回
 char* Buf = (char*)lpData;
 int nLen = nSize;
 int n;
 int nIndex = 0;
 while(nLen > 0)
 {
  n = recv(sock, &Buf[nIndex], nLen, 0);
  if(n == SOCKET_ERROR)
   return FALSE;
  nIndex += n;
  nLen -= n;
 }
 return TRUE;
}

class CAboutDlg : public CDialog
{
public:
 CAboutDlg();

// Dialog Data
 //{{AFX_DATA(CAboutDlg)
 enum { IDD = IDD_ABOUTBOX };
 //}}AFX_DATA

 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CAboutDlg)
 protected:
 virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
 //}}AFX_VIRTUAL

// Implementation
protected:
 //{{AFX_MSG(CAboutDlg)
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
 //{{AFX_DATA_INIT(CAboutDlg)
 //}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CAboutDlg)
 //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
 //{{AFX_MSG_MAP(CAboutDlg)
  // No message handlers
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CMonitorClientDlg dialog

CMonitorClientDlg::CMonitorClientDlg(CWnd* pParent /*=NULL*/)
 : CDialog(CMonitorClientDlg::IDD, pParent)
{
 //{{AFX_DATA_INIT(CMonitorClientDlg)
  // NOTE: the ClassWizard will add member initialization here
 //}}AFX_DATA_INIT
 // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMonitorClientDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CMonitorClientDlg)
  // NOTE: the ClassWizard will add DDX and DDV calls here
 //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CMonitorClientDlg, CDialog)
 //{{AFX_MSG_MAP(CMonitorClientDlg)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 ON_COMMAND(ID_RD_CONNECT, OnRdConnect)
 ON_COMMAND(ID_RD_EXIT, OnRdExit)
 ON_WM_TIMER()
 ON_WM_HSCROLL()
 ON_WM_VSCROLL()
 ON_WM_CLOSE()
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CMonitorClientDlg message handlers

BOOL CMonitorClientDlg::OnInitDialog()
{
 CDialog::OnInitDialog();

 // Add "About..." menu item to system menu.

 // IDM_ABOUTBOX must be in the system command range.
 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
 ASSERT(IDM_ABOUTBOX < 0xF000);

 CMenu* pSysMenu = GetSystemMenu(FALSE);
 if (pSysMenu != NULL)
 {
  CString strAboutMenu;
  strAboutMenu.LoadString(IDS_ABOUTBOX);
  if (!strAboutMenu.IsEmpty())
  {
   pSysMenu->AppendMenu(MF_SEPARATOR);
   pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  }
 }

 // Set the icon for this dialog.  The framework does this automatically
 //  when the application's main window is not a dialog
 SetIcon(m_hIcon, TRUE);   // Set big icon
 SetIcon(m_hIcon, FALSE);  // Set small icon
 
 // TODO: Add extra initialization here

 //*初始化窗口大小和位置(本例程为:800×600大小的窗口,超出部分拖滚动条查看)
 CRect RectWindow, RectClient;
 GetClientRect(&RectClient);
 GetWindowRect(&RectWindow);
 int w = RectWindow.Width() - RectClient.Width();
 int h = RectWindow.Height() - RectClient.Height();
 SetWindowPos(&wndTop, 0, 0, w + 800, h + 600, SWP_DRAWFRAME);
 //*初始化标志
 bRunning = FALSE;
 //*初始化缓存
 BitmapBuffer = NULL;
 ZipBuffer = NULL;
 return TRUE;  // return TRUE  unless you set the focus to a control
}

void CMonitorClientDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
 {
  CAboutDlg dlgAbout;
  dlgAbout.DoModal();
 }
 else
 {
  CDialog::OnSysCommand(nID, lParam);
 }
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CMonitorClientDlg::OnPaint()
{
 if (IsIconic())
 {
  CPaintDC dc(this); // device context for painting

  SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

  // Center icon in client rectangle
  int cxIcon = GetSystemMetrics(SM_CXICON);
  int cyIcon = GetSystemMetrics(SM_CYICON);
  CRect rect;
  GetClientRect(&rect);
  int x = (rect.Width() - cxIcon + 1) / 2;
  int y = (rect.Height() - cyIcon + 1) / 2;

  // Draw the icon
  dc.DrawIcon(x, y, m_hIcon);
 }
 else
 {
  if(!BitmapBuffer)
  {
   CDialog::OnPaint();
   return;
  }
  else
  {
   
   csMem.Lock();
   CClientDC dc(this);
   dc.BitBlt(0, 0, 800, 600, &MemDC, GetScrollPos(SB_HORZ), GetScrollPos(SB_VERT), SRCCOPY);
   csMem.Unlock();
  }
 }
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CMonitorClientDlg::OnQueryDragIcon()
{
 return (HCURSOR) m_hIcon;
}

void CMonitorClientDlg::OnOK()
{
 // TODO: Add extra validation here
 
 CDialog::OnOK();
}

void CMonitorClientDlg::OnCancel()
{
 // TODO: Add extra cleanup here
 
 CDialog::OnCancel();
}

void CMonitorClientDlg::OnRdConnect()
{
 // TODO: Add your command handler code here
 //*如果已经连接,则直接返回
 if(bRunning)
  return;
 //*输入要连监视的主机IP
 if(dlgIP.DoModal() != IDOK)
  return;
 IP = dlgIP.IP;
 bRunning = TRUE;
 //*启动工作线程
 AfxBeginThread(WorkThread, this);
}

void CMonitorClientDlg::OnRdExit()
{
 // TODO: Add your command handler code here
 SendMessage(WM_CLOSE);
}

UINT CMonitorClientDlg::WorkProc()
{
 //*工作线程,用于连接到主机,并读取主机传来的屏幕图象,并绘制
 //*建立套接字
 SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
 SOCKADDR_IN SockAddr;
 SockAddr.sin_family = AF_INET;
 SockAddr.sin_port = htons(3517);
 SockAddr.sin_addr.s_addr =inet_addr(IP);
 int SockAddrLen = sizeof(sockaddr);
 int nZero = 0;
 setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*)&nZero, sizeof(int));
 //*连接到目标主机
 if(connect(sock, (SOCKADDR*)&SockAddr, SockAddrLen) == SOCKET_ERROR)
 {
  closesocket(sock);
  AfxMessageBox(_T("连接不到服务器..."));
  bRunning = FALSE;
  AfxEndThread(0);
  return 0;
 }
 while(bRunning)
 {
  //*接收图象
  if(!ProcessReceive(sock))
  {
   //*接收失败,则退出线程
   closesocket(sock);
   break;
  }
  //*处理解压过程
//  ProcessUncompress();
  //*内存DC锁
  csMem.Lock();
  //*向内存DC和内存位图绘制接收来的图象
  SetDIBits(MemDC.GetSafeHdc(), (HBITMAP)MemBitmap.GetSafeHandle(), 0, BitmapInfoHeader.biHeight, (LPVOID)BitmapBuffer, (LPBITMAPINFO)&BitmapInfoHeader, DIB_RGB_COLORS);
  //*内存DC解锁
  csMem.Unlock();
  //*更新画面
  Invalidate(FALSE);
 }
 //*退出线程时,释放各种资源
 bRunning = FALSE;
 if(BitmapBuffer)
  delete [] BitmapBuffer;
 if(ZipBuffer)
  delete [] ZipBuffer;
 BitmapBuffer = NULL;
 ZipBuffer = NULL;
 MemDC.DeleteDC();
 MemBitmap.DeleteObject();
 AfxEndThread(0);
 return 0;
}

void CMonitorClientDlg::ProcessUncompress()
{
 //*处理解压
// if(BitmapBuffer)
//  uncompress(BitmapBuffer, &BitmapBufferSize, ZipBuffer, ZipBufferSize);
}

void CMonitorClientDlg::ProcessFirst()
{
 //*首包数据,分配用于绘图的内存资源
 csMem.Lock();
 CDC DeskDC;
 DeskDC.CreateDC("DISPLAY", NULL, NULL, NULL);
 MemDC.CreateCompatibleDC(&DeskDC);
 MemBitmap.CreateCompatibleBitmap(&DeskDC, BitmapWidth, BitmapHeight);
 MemDC.SelectObject(&MemBitmap);
 DeskDC.DeleteDC();
 csMem.Unlock();
 //*根据对方桌面分辨率,处理滚动条信息
 CRect Rect;
 //*得到客户区大小
 GetClientRect(&Rect);
 if(Rect.Width() < BitmapWidth)
 {
  SCROLLINFO si = {0};
  si.cbSize = sizeof(SCROLLINFO);
  //*设置掩码
  si.fMask = SIF_ALL;
  //*滚动条最小值
  si.nMin = 0;
  //*滚动条中可拖动按钮的大小(页大小)
  si.nPage = Rect.Width()/(BitmapWidth / (BitmapWidth - Rect.Width()));
  if(si.nPage == 0)
   si.nPage = Rect.Width();
  //*滚动条最大值
  si.nMax = BitmapWidth - Rect.Width() + si.nPage;
  //*滚动条当前位置
  si.nPos = 0;
  si.nTrackPos = 0;
  //*设置为水平滚动条信息
  SetScrollInfo(SB_HORZ, &si, TRUE);
 }
 if(Rect.Height() < BitmapHeight)
 {
  SCROLLINFO si = {0};
  si.cbSize = sizeof(SCROLLINFO);
  //*设置掩码
  si.fMask = SIF_ALL;
  //*滚动条最小值
  si.nMin = 0;
  //*滚动条中可拖动按钮的大小(页大小)
  si.nPage = Rect.Height()/(BitmapHeight / (BitmapHeight - Rect.Height()));
  if(si.nPage == 0)
   si.nPage = Rect.Height();
  //*滚动条最大值
  si.nMax = BitmapHeight - Rect.Height() + si.nPage;
  //*滚动条当前位置
  si.nPos = 0;
  si.nTrackPos = 0;
  //*设置为垂直滚动条信息
  SetScrollInfo(SB_VERT, &si, TRUE);
 }
}

BOOL CMonitorClientDlg::ProcessReceive(SOCKET sock)
{
 //*接收包头
 if(!ReceivePackageHead(sock))
  return FALSE;
 //*接收位图头
 if(!ReceiveBitmapHead(sock))
  return FALSE;
 //*接收位图数据
 if(!ReceiveBitmapData(sock))
  return FALSE;
 //*接收包尾
 if(!ReceivePackageTail(sock))
  return FALSE;
 return TRUE;
}

BOOL CMonitorClientDlg::ReceivePackageHead(SOCKET sock)
{
 //*接收并校验包头
 char PackageHead[] = "TF Remote Package Head.../0";
 char Buf[512];
 int nLen = strlen(PackageHead);
 if(MyReceive(sock, Buf, nLen) == FALSE)
  return FALSE;
 Buf[nLen] = '/0';
 if(strcmp(Buf, PackageHead) != 0)
  return FALSE;
 return TRUE;
}

BOOL CMonitorClientDlg::ReceiveBitmapHead(SOCKET sock)
{
 //*接位图头

 //*位图缓存大小
 if(MyReceive(sock, &BitmapBufferSize, 4) == FALSE)
  return FALSE;
 BOOL First = FALSE;//*首幅图标志
 if(!BitmapBuffer)
 {
  //*如果位图缓存为空,则说明是首幅图象,分配缓存资源
  BitmapBuffer = new BYTE[BitmapBufferSize];
  //*计算压缩缓存大小,当前没有进行压缩
  // ZipBufferSize = compressBound(BitmapBufferSize);
  ZipBufferSize = BitmapBufferSize;
  //*分配压缩缓存
  ZipBuffer = new BYTE[ZipBufferSize];
  //*当前为连接后第一幅图
  First = TRUE;
 }
 //*压缩数据大小
 if(MyReceive(sock, &ZipBufferSize, 4) == FALSE)
  return FALSE;
 //*位图宽
 if(MyReceive(sock, &BitmapWidth, 2) == FALSE)
  return FALSE;
 //*位图高
 if(MyReceive(sock, &BitmapHeight, 2) == FALSE)
  return FALSE;
 //*位图信息
 if(MyReceive(sock, &BitmapInfoHeader, sizeof(BITMAPINFOHEADER)) == FALSE)
  return FALSE;
 if(First)
 {
  //*如果第一幅图,则初始化绘图信息
  ProcessFirst();
 }
 return TRUE;
}

BOOL CMonitorClientDlg::ReceiveBitmapData(SOCKET sock)
{
 //*如果压缩数据,则接收压缩缓存
// return MyReceive(sock, ZipBuffer, ZipBufferSize);
 //*当前例程未进行压缩,则直接将数据接收至位图缓存
 return MyReceive(sock, BitmapBuffer, BitmapBufferSize);
}

BOOL CMonitorClientDlg::ReceivePackageTail(SOCKET sock)
{
 //*接收并校验包尾
 char PackageTail[] = "TF Remote Package Tail.../0";
 char Buf[512];
 int nLen = strlen(PackageTail);
 if(MyReceive(sock, Buf, nLen) == FALSE)
  return FALSE;
 Buf[nLen] = '/0';
 if(strcmp(Buf, PackageTail) != 0)
  return FALSE;
 return TRUE;
}

void CMonitorClientDlg::OnTimer(UINT nIDEvent)
{
 // TODO: Add your message handler code here and/or call default
 
 CDialog::OnTimer(nIDEvent);
}

void CMonitorClientDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
 // TODO: Add your message handler code here and/or call default
 //*处理水平滚动条事件
 SCROLLINFO si;
 GetScrollInfo(SB_HORZ, &si, SIF_ALL);
 switch (nSBCode)
 {
 case SB_LEFT:
 case SB_LINELEFT:
  si.nPos -= si.nMax/20;
  if(si.nPos < si.nMin)
   si.nPos = si.nMin;
  ScrollWindow(si.nPos, 0);
  SetScrollInfo(SB_HORZ, &si, TRUE);
  break;
 case SB_RIGHT:
 case SB_LINERIGHT:
  si.nPos += si.nMax/20;
  if(si.nPos > si.nMax)
   si.nPos = si.nMax;
  ScrollWindow(si.nPos, 0);
  SetScrollInfo(SB_HORZ, &si, TRUE);
  break;
 case SB_PAGELEFT:
  si.nPos -= si.nPage;
  if(si.nPos < si.nMin)
   si.nPos = si.nMin;
  ScrollWindow(si.nPos, 0);
  SetScrollInfo(SB_HORZ, &si, TRUE);
  break;
 case SB_PAGERIGHT:
  si.nPos += si.nPage;
  if(si.nPos > si.nMax)
   si.nPos = si.nMax;
  ScrollWindow(si.nPos, 0);
  SetScrollInfo(SB_HORZ, &si, TRUE);
  break;
 case SB_THUMBPOSITION:
  break;
 case SB_THUMBTRACK:
  ScrollWindow((si.nPos-nPos)*10, 0);
  si.nPos = nPos;
  SetScrollInfo(SB_HORZ, &si, SIF_ALL);
  break;
 case SB_ENDSCROLL:
  break;
 }
 
 CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CMonitorClientDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
 // TODO: Add your message handler code here and/or call default
 //*处理垂直滚动条事件
 SCROLLINFO si;
 GetScrollInfo(SB_VERT,&si,SIF_ALL);
 switch (nSBCode)
 {
 case SB_TOP:
 case SB_LINEUP:
  si.nPos -= si.nMax/20;
  if(si.nPos < si.nMin)
   si.nPos = si.nMin;
  ScrollWindow(0, si.nPos);
  SetScrollInfo(SB_VERT, &si, TRUE);
  break;
 case SB_BOTTOM:
 case SB_LINEDOWN:
  si.nPos += si.nMax/20;
  if(si.nPos > si.nMax)
   si.nPos = si.nMax;
  ScrollWindow(0, si.nPos);
  SetScrollInfo(SB_VERT, &si, TRUE);
  break;
 case SB_PAGEUP:
  si.nPos -= si.nPage;
  if(si.nPos < si.nMin)
   si.nPos = si.nMin;
  ScrollWindow(0, si.nPos);
  SetScrollInfo(SB_VERT, &si, TRUE);
  break;
 case SB_PAGEDOWN:
  si.nPos += si.nPage;
  if(si.nPos > si.nMax)
   si.nPos = si.nMax;
  ScrollWindow(0, si.nPos);
  SetScrollInfo(SB_VERT, &si, TRUE);
  break;
 case SB_THUMBPOSITION:
  break;
 case SB_THUMBTRACK:
  ScrollWindow(0, (si.nPos-nPos)*10);
  si.nPos = nPos;
  SetScrollInfo(SB_VERT, &si, SIF_ALL);
  break;
 case SB_ENDSCROLL:
  break;
 }
 CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
}

void CMonitorClientDlg::OnClose()
{
 // TODO: Add your message handler code here and/or call default
 
 CDialog::OnClose();
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值