网学网为广大网友收集整理了,基于VC++学校实验室监控系统,希望对大家有所帮助!
客服咨询,网学网竭诚为您服务,本站永久域名:myeducs.cn |
4系统的实现 4.1用户界面的实现 如下图所示,用户界面为友好的Win32应用程序,在服务器程序界面左边停靠的工具条中,有一个树控件,该控件列出了系统中正在管理的客户端ip。选中其中的某个,就可以进行响应的操作,比如“截取屏幕”,那么就可以获取客户端的屏幕画面,并显示到用户界面中。
图4-1 服务器端运行效果图 在客户端,用户被要求填入服务器ip,用户名以及密码,然后登录。如下图所示: 图4-2 客户器端运行效果图 4.2核心算法的实现 由于整个系统基本使用MFC开发,而且涉及到很多方面,代码量比较大,不可能一一介绍,下面选择几个较为重要的核心功能的实现进行介绍。 4.2.1客户端和服务器端的通信 无论是屏幕截图还是锁定屏幕,都是在服务器端管理员进行命令,在客户端进行响应。因此,之间涉及大量的网络通信。在整个系统中,网络通信至关重要,主要通过两个类实现:CClient和CServer。 class CServer { public: bool Check(char* name, char* pass); bool UnlockScreen(char* ip); bool LockScreen(char* ip); bool SendMsg(char* ip, char* msg); CString GetNextClientIP(); void PreEnum(); bool SnapScreen(char *ip, CxImage& x); void AliveAll(); void AddClient(const Client &client); void Run(); CServer() { InitializeCriticalSection(&cs); }; ~CServer() { DeleteCriticalSection(&cs); closesocket(srvsock); WSACleanup(); }; BOOL Init(int port); private: static DWORD WINAPI ListenThreadPrc(LPVOID lpParam); SOCKET srvsock; SOCKADDR_IN srvaddr; vector<Client> clients; CRITICAL_SECTION cs; int pos; }; class CClient { private: SOCKET local; sockaddr_in remote_addr; int remote_addr_len; HWND hWnd; BOOL bLocked; public: BOOL bConnected; bool UnlockScreen(); bool LockSrceen(); static DWORD WINAPI ResponseThreadPrc(LPVOID lpParam); void Run(); CClient() { WSADATA wsaData; WSAStartup(MAKEWORD(2,2),&wsaData); remote_addr_len=sizeof(remote_addr); local=INVALID_SOCKET; bLocked = FALSE; bConnected = FALSE; }; ~CClient() { closesocket(local); WSACleanup(); }; void Attach(HWND hWnd){this->hWnd=hWnd;}; bool Connect(char* ip, int port, char* name, char* pass); }; 服务器端有一个CServer的对象m_server,该对象创建后: m_server.Init(22221); //设置监听端口为22221 m_server.Run(); //进行监听 而如果服务器要进行某种操作,比如,锁定屏幕,则这样使用m_server: if(theApp.m_server.LockScreen(ip.GetBuffer(0))) { AfxMessageBox(ip+"屏幕已锁住"); } else { AfxMessageBox(ip+"屏幕未锁住"); } 在客户端,CClient有个对象m_client,该对象创建后: m_client.Attach(this->m_hWnd); //绑定屏幕锁定下可以操作的窗口 m_client.LockSrceen(); //锁定窗口 首先把自身窗口设置为屏幕锁定下可以操作的窗口,然后把屏幕锁定,等待用户登录。 在用户进行登录时: if(!m_client.bConnected) //若未连接 { if(m_client.Connect(m_strIP.GetBuffer(0), 20001, m_strName.GetBuffer(0), m_strPass.GetBuffer(0))) { //连接成功 TRACE(m_strName+"\r\n"); PostMessage( MYWM_SHOWAPPICONIC ); m_client.UnlockScreen(); //屏幕解除锁定 m_client.Run(); //开启监听线程 m_strInfo = "登录成功!"; } else { m_strInfo = "登录失败!"; } } else { m_strInfo = "重复登录!"; } 首先检查是否已经建立了连接,避免重复登录。然后调用Connect,连接向指定的服务器端,如果连接成功,屏幕解锁并开启监听线程,准备接收来自服务器的命令并进行响应。 4.2.2屏幕截图 屏幕截图的基本功能是通过两个函数来实现的:Bmp2Stream和Screen2Bitmap。正如他们的名字所示,Screen2Bitmap的作用是将屏幕截图,并保存到一个位图中,然后返回这个位图的句柄;而Bmp2Stream则是为了网络传输作准备,它接收一个位图句柄,对这个位图进行编码,并拷贝到一个缓冲区里。下面是这两个函数的具体实现: HBITMAP Screen2Bitmap() { HDC hscrdc, hmemdc;// 屏幕和内存设备描述表 HBITMAP hbitmap, holdbitmap;// 位图句柄 int nwidth, nheight;// 位图宽度和高度 int xscrn, yscrn;// 屏幕分辨率 //为屏幕创建设备描述表 hscrdc = CreateDC("display", NULL, NULL, NULL); //为屏幕设备描述表创建兼容的内存设备描述表 hmemdc = CreateCompatibleDC(hscrdc); // 获得屏幕分辨率 xscrn = GetDeviceCaps(hscrdc, HORZRES); yscrn = GetDeviceCaps(hscrdc, VERTRES); nwidth = xscrn; nheight = yscrn; // 创建一个与屏幕设备描述表兼容的位图 hbitmap = CreateCompatibleBitmap(hscrdc, nwidth, nheight); // 把新位图选到内存设备描述表中 holdbitmap = (HBITMAP)SelectObject(hmemdc, hbitmap); // 把屏幕设备描述表拷贝到内存设备描述表中 BitBlt(hmemdc, 0, 0, nwidth, nheight, hscrdc, 0, 0, SRCCOPY); //得到屏幕位图的句柄 hbitmap = (HBITMAP)SelectObject(hmemdc, holdbitmap); //清除 DeleteDC(hscrdc); DeleteDC(hmemdc); // 返回位图句柄 return hbitmap; } BOOL Bmp2Stream( HBITMAP& hBmp, BYTE* &bBuf, long &size, DWORD type = CXIMAGE_FORMAT_JPG, int nWidth=0, int nHeight=0 ) { if(hBmp != INVALID_HANDLE_VALUE) { CxImage img; if(img.CreateFromHBITMAP(hBmp)) //位图句柄构建对象 { if(nWidth <= 0) { nWidth = img.GetWidth(); } if(nHeight <= 0) { nHeight = img.GetHeight(); } if(!img.Resample(nWidth, nHeight)) //缩放位图 { return FALSE; } if(img.Encode(bBuf, size, type)) //编码 return TRUE; } } return FALSE; } 补充一点,普通情况下,屏幕截图只能获得一幅位图,而这幅位图的大小一般都在1M以上,这不利于网络传输,因此,应该进行图像压缩,即图像格式转换。在本系统中,使用CxImage(CxImage类库是一个优秀的图像操作类库。它可以快捷地存取、显示、转换各种图像)这个开源项目提供的强大的库进行编码,将位图转化为Jpg格式再进行传输,这正是Bmp2Stream函数存在的目的。 4.2.3锁屏和解屏 屏幕的锁定功能可以通过多种方式实现,本系统使用的是Windows钩子(Hook)技术进行实现的。所谓钩子,钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理window消息或特定事件。钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。 钩子有很多种,每一种类型的Hook可以使应用程序能够监视不同类型的系统消息处理机制。该系统只需要处理键盘和鼠标的输入,因此只需要在应用程序中安装WH_KEYBOARD Hook用来监视WM_KEYDOWN and WM_KEYUP消息,还有安装WH_MOUSE Hook监视从GetMessage 或者 PeekMessage 函数返回的鼠标消息,使用这个Hook监视输入到消息队列中的鼠标消息。按照Hook的技术规范,Hook API必须写到一个另一个dll中,而在主程序中调用这个dll中的Hook函数。
|
本站发布的计算机毕业设计均是完整无错的全套作品,包含开题报告+程序+论文+源代码+翻译+答辩稿PPT |
本文选自计算机毕业设计http://myeducs.cn |