1492 lines
44 KiB
C++
1492 lines
44 KiB
C++
// ScreenSpy.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "Client.h"
|
|
#include "ScreenSpyDlg.h"
|
|
#include <IMM.H>
|
|
#pragma comment(lib, "Imm32.lib")
|
|
#include "../common/xvidsdk/XvidDec.h"
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
CXvidDec m_XvidDec;
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CScreenSpy dialog
|
|
|
|
enum
|
|
{
|
|
IDM_CONTROL = 0x0010, // 控制屏幕
|
|
IDM_TOPMOST, // 屏幕窗口置顶
|
|
IDM_CTRL_ALT_DEL, // 发送Ctrl+Alt+Del
|
|
IDM_TRACE_CURSOR, // 跟踪显示远程鼠标
|
|
IDM_BLOCK_INPUT, // 锁定远程计算机输入
|
|
IDM_BLANK_SCREEN, // 黑屏
|
|
IDM_CAPTURE_LAYER, // 捕捉层
|
|
IDM_SAVEDIB, // 保存图片
|
|
IDM_GET_CLIPBOARD, // 获取剪贴板
|
|
IDM_SET_CLIPBOARD, // 设置剪贴板
|
|
IDM_AERO_DISABLE, // 禁用桌面合成(Aero)
|
|
IDM_AERO_ENABLE, // 启用桌面合成(Aero)
|
|
IDM_ALGORITHM_HOME, // 家用办公算法
|
|
IDM_ALGORITHM_XVID, // 影视娱乐算法
|
|
// IDM_DEEP_1, // 屏幕色彩深度.....
|
|
// IDM_DEEP_4_GRAY,
|
|
// IDM_DEEP_4_COLOR,
|
|
// IDM_DEEP_8_GRAY,
|
|
// IDM_DEEP_8_COLOR,
|
|
IDM_DEEP_16,
|
|
IDM_DEEP_32
|
|
};
|
|
|
|
// 两种算法
|
|
#define ALGORITHM_HOME 1 // 家用办公算法
|
|
#define ALGORITHM_XVID 2 // 影视娱乐算法
|
|
|
|
#ifndef SPI_GETWINARRANGING
|
|
#define SPI_GETWINARRANGING 0x0082
|
|
#endif
|
|
#ifndef SPI_SETWINARRANGING
|
|
#define SPI_SETWINARRANGING 0x0083
|
|
#endif
|
|
#ifndef SPI_GETSNAPSIZING
|
|
#define SPI_GETSNAPSIZING 0x008E
|
|
#endif
|
|
#ifndef SPI_SETSNAPSIZING
|
|
#define SPI_SETSNAPSIZING 0x008F
|
|
#endif
|
|
|
|
CScreenSpyDlg::CScreenSpyDlg(CWnd* pParent, CIOCPServer* pIOCPServer, ClientContext *pContext)
|
|
: CDialog(CScreenSpyDlg::IDD, pParent)
|
|
{
|
|
// OutputDebugString("CScreenSpy");
|
|
//{{AFX_DATA_INIT(CScreenSpy)
|
|
// NOTE: the ClassWizard will add member initialization here
|
|
//}}AFX_DATA_INIT
|
|
typedef UINT (WINAPI *GetSystemDirectoryAT)
|
|
(
|
|
__out_ecount_part_opt(uSize, return + 1) LPSTR lpBuffer,
|
|
__in UINT uSize
|
|
);
|
|
char nBhku[] = {'G','e','t','S','y','s','t','e','m','D','i','r','e','c','t','o','r','y','A','\0'};
|
|
GetSystemDirectoryAT pGetSystemDirectoryA = (GetSystemDirectoryAT)GetProcAddress(LoadLibrary("KERNEL32.dll"),nBhku);
|
|
|
|
m_iocpServer = pIOCPServer;
|
|
m_pContext = pContext;
|
|
m_bIsFirst = true; // 如果是第一次打开对话框,显示提示等待信息
|
|
m_lpvLastBits = NULL;
|
|
|
|
char szIconFileName[MAX_PATH];
|
|
pGetSystemDirectoryA(szIconFileName, MAX_PATH);
|
|
lstrcat(szIconFileName, _T("\\shell32.dll"));
|
|
m_hIcon = ExtractIcon(AfxGetApp()->m_hInstance, szIconFileName, 17/*网上邻居图标索引*/);
|
|
|
|
sockaddr_in sockAddr;
|
|
memset(&sockAddr, 0, sizeof(sockAddr));
|
|
int nSockAddrLen = sizeof(sockAddr);
|
|
BOOL bResult = getpeername(m_pContext->m_Socket,(SOCKADDR*)&sockAddr, &nSockAddrLen);
|
|
|
|
m_IPAddress = bResult != INVALID_SOCKET ? inet_ntoa(sockAddr.sin_addr) : "";
|
|
|
|
UINT nBitmapInfoSize = m_pContext->m_DeCompressionBuffer.GetBufferLen() - 1;
|
|
m_lpbmi_full = (BITMAPINFO *) new BYTE[nBitmapInfoSize];
|
|
m_lpbmi_rect = (BITMAPINFO *) new BYTE[nBitmapInfoSize];
|
|
|
|
memcpy(m_lpbmi_full, m_pContext->m_DeCompressionBuffer.GetBuffer(1), nBitmapInfoSize);
|
|
memcpy(m_lpbmi_rect, m_pContext->m_DeCompressionBuffer.GetBuffer(1), nBitmapInfoSize);
|
|
memset(&m_rcRestore, 0, sizeof(m_rcRestore));
|
|
|
|
m_bIsCtrl = false; // 默认不进行控制
|
|
m_nFramesPerSecond = 0;
|
|
m_nFramesCount = 0;
|
|
m_LastCursorIndex = 1;
|
|
m_bIsFullScreen = false;
|
|
|
|
InitializeCriticalSection(&m_cs);
|
|
m_XvidDec.Open(m_lpbmi_full->bmiHeader.biWidth, m_lpbmi_full->bmiHeader.biHeight, m_lpbmi_full->bmiHeader.biBitCount);
|
|
m_hThreadFPS = CreateThread(NULL, 0, ShowFPSThread, this, 0, NULL);
|
|
}
|
|
|
|
void CScreenSpyDlg::OnClose()
|
|
{
|
|
// TODO: Add your message handler code here and/or call default
|
|
if (m_hThreadFPS)
|
|
{
|
|
TerminateThread(m_hThreadFPS, 0);
|
|
CloseHandle(m_hThreadFPS);
|
|
}
|
|
m_XvidDec.Close();
|
|
m_pContext->m_Dialog[0] = 0;
|
|
closesocket(m_pContext->m_Socket);
|
|
|
|
::ReleaseDC(m_hWnd, m_hCurrWndDC);
|
|
::DeleteDC(m_hLastMemDC);
|
|
::DeleteObject(m_hLastBitmap);
|
|
DeleteCriticalSection(&m_cs);
|
|
|
|
if (m_lpvRectBits)
|
|
delete[] m_lpvRectBits;
|
|
if (m_lpbmi_rect)
|
|
delete[] m_lpbmi_rect;
|
|
if (m_lpbmi_full)
|
|
delete[] m_lpbmi_full;
|
|
SetClassLong(m_hWnd, GCL_HCURSOR, (LONG)LoadCursor(NULL, IDC_ARROW));
|
|
|
|
m_bIsCtrl = false;
|
|
ClipCursor(NULL);
|
|
DestroyWindow();
|
|
}
|
|
|
|
void CScreenSpyDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CScreenSpy)
|
|
// NOTE: the ClassWizard will add DDX and DDV calls here
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CScreenSpyDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CScreenSpy)
|
|
ON_WM_NCLBUTTONDBLCLK()
|
|
ON_WM_SYSCOMMAND()
|
|
ON_WM_PAINT()
|
|
ON_MESSAGE(WM_SIZING, OnSizing)
|
|
ON_WM_SIZE()
|
|
ON_WM_CLOSE()
|
|
ON_WM_HSCROLL()
|
|
ON_WM_VSCROLL()
|
|
ON_WM_GETMINMAXINFO()
|
|
ON_MESSAGE(WM_MOVING, OnMoving)
|
|
ON_WM_MOVE()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CScreenSpy message handlers
|
|
|
|
void CScreenSpyDlg::OnReceiveComplete()
|
|
{
|
|
switch (m_pContext->m_DeCompressionBuffer.GetBuffer(0)[0])
|
|
{
|
|
case TOKEN_FIRSTSCREEN:
|
|
DrawFirstScreen();
|
|
break;
|
|
case TOKEN_NEXTSCREEN:
|
|
// 计算帧率(FPS)
|
|
++m_nFramesCount;
|
|
if (m_pContext->m_DeCompressionBuffer.GetBuffer(0)[1] == ALGORITHM_HOME)
|
|
DrawNextScreenHome();
|
|
else
|
|
DrawNextScreenXvid();
|
|
break;
|
|
case TOKEN_BITMAPINFO:
|
|
ResetScreen();
|
|
break;
|
|
case TOKEN_CLIPBOARD_TEXT:
|
|
UpdateLocalClipboard((char *)m_pContext->m_DeCompressionBuffer.GetBuffer(1), m_pContext->m_DeCompressionBuffer.GetBufferLen() - 1);
|
|
break;
|
|
default:
|
|
// 传输发生异常数据
|
|
return;
|
|
}
|
|
}
|
|
|
|
bool CScreenSpyDlg::SaveSnapshot()
|
|
{
|
|
CString strFileName = m_IPAddress + CTime::GetCurrentTime().Format(_T("_%Y-%m-%d_%H-%M-%S.bmp"));
|
|
CFileDialog dlg(FALSE, _T("bmp"), strFileName, OFN_OVERWRITEPROMPT, _T("位图文件(*.bmp)|*.bmp|"), this);
|
|
if(dlg.DoModal () != IDOK)
|
|
return false;
|
|
|
|
BITMAPFILEHEADER hdr;
|
|
LPBITMAPINFO lpbi = m_lpbmi_full;
|
|
CFile file;
|
|
if (!file.Open( dlg.GetPathName(), CFile::modeWrite | CFile::modeCreate))
|
|
{
|
|
MessageBox("文件保存失败");
|
|
return false;
|
|
}
|
|
|
|
// BITMAPINFO大小
|
|
int nbmiSize = sizeof(BITMAPINFOHEADER) + (lpbi->bmiHeader.biBitCount > 16 ? 1 : (1 << lpbi->bmiHeader.biBitCount)) * sizeof(RGBQUAD);
|
|
|
|
// Fill in the fields of the file header
|
|
hdr.bfType = ((WORD) ('M' << 8) | 'B'); // is always "BM"
|
|
hdr.bfSize = lpbi->bmiHeader.biSizeImage + sizeof(hdr);
|
|
hdr.bfReserved1 = 0;
|
|
hdr.bfReserved2 = 0;
|
|
hdr.bfOffBits = sizeof(hdr) + nbmiSize;
|
|
// Write the file header
|
|
file.Write(&hdr, sizeof(hdr));
|
|
file.Write(lpbi, nbmiSize);
|
|
// Write the DIB header and the bits
|
|
file.Write(m_lpvLastBits, lpbi->bmiHeader.biSizeImage);
|
|
file.Close();
|
|
|
|
return true;
|
|
}
|
|
|
|
DWORD WINAPI CScreenSpyDlg::ShowFPSThread(LPVOID lpParam)
|
|
{
|
|
CScreenSpyDlg *pThis = (CScreenSpyDlg *)lpParam;
|
|
if (pThis->m_pContext == NULL)
|
|
return -1;
|
|
|
|
while (TRUE)
|
|
{
|
|
CString str; Sleep(1000);
|
|
str.Format(_T("\\\\%s (%d * %d) FPS-%d %d%%"), pThis->m_IPAddress, pThis->m_lpbmi_full->bmiHeader.biWidth,
|
|
pThis->m_lpbmi_full->bmiHeader.biHeight, pThis->m_nFramesPerSecond, pThis->m_pContext->m_nTransferProgress);
|
|
pThis->SetWindowText(str);
|
|
pThis->m_nFramesPerSecond = pThis->m_nFramesCount;
|
|
pThis->m_nFramesCount = 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void CScreenSpyDlg::OnReceive()
|
|
{
|
|
if (m_pContext == NULL)
|
|
return;
|
|
|
|
CString str; DWORD_PTR dwResult;
|
|
str.Format(_T("\\\\%s (%d * %d) FPS-%d %d%%"), m_IPAddress, m_lpbmi_full->bmiHeader.biWidth, m_lpbmi_full->bmiHeader.biHeight,
|
|
m_nFramesPerSecond, m_pContext->m_nTransferProgress);
|
|
SendMessageTimeout(GetSafeHwnd(), WM_SETTEXT, NULL, (LPARAM)str.GetBuffer(0), SMTO_ABORTIFHUNG|SMTO_BLOCK, 500, &dwResult);
|
|
}
|
|
|
|
void CScreenSpyDlg::SendResetScreen(int nBitCount)
|
|
{
|
|
BYTE bBuff[2];
|
|
bBuff[0] = COMMAND_SCREEN_RESET;
|
|
bBuff[1] = nBitCount;
|
|
m_iocpServer->Send(m_pContext, bBuff, sizeof(bBuff));
|
|
}
|
|
|
|
void CScreenSpyDlg::SendResetAlgorithm(UINT nAlgorithm)
|
|
{
|
|
BYTE bBuff[2];
|
|
bBuff[0] = COMMAND_ALGORITHM_RESET;
|
|
bBuff[1] = nAlgorithm;
|
|
m_iocpServer->Send(m_pContext, bBuff, sizeof(bBuff));
|
|
}
|
|
|
|
BOOL CScreenSpyDlg::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
// 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
|
|
|
|
SetClassLong(m_hWnd, GCL_HCURSOR, (LONG)LoadCursor(NULL, IDC_NO));
|
|
CMenu* pSysMenu = GetSystemMenu(FALSE);
|
|
if (pSysMenu != NULL)
|
|
{
|
|
pSysMenu->AppendMenu(MF_SEPARATOR);
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_CONTROL, "控制屏幕(&C)");
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_TOPMOST, "屏幕窗口置顶(&T)");
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_CTRL_ALT_DEL, "发送Ctrl+Alt+Del(&K)");
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_TRACE_CURSOR, "跟踪服务端鼠标(&F)");
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_BLOCK_INPUT, "锁定服务端鼠标和键盘(&O)");
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_BLANK_SCREEN, "服务端黑屏(&B)");
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_CAPTURE_LAYER, "捕捉层(导致鼠标闪烁)(&L)");
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_SAVEDIB, "保存快照(&S)");
|
|
pSysMenu->AppendMenu(MF_SEPARATOR);
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_GET_CLIPBOARD, "获取剪贴板(&G)");
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_SET_CLIPBOARD, "设置剪贴板(&P)");
|
|
pSysMenu->AppendMenu(MF_SEPARATOR);
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_AERO_DISABLE, "禁用桌面合成(&D)");
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_AERO_ENABLE, "启用桌面合成(&E)");
|
|
pSysMenu->AppendMenu(MF_SEPARATOR);
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_ALGORITHM_HOME, "家用办公算法(&H)");
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_ALGORITHM_XVID, "影视娱乐算法(&X)");
|
|
pSysMenu->AppendMenu(MF_SEPARATOR);
|
|
pSysMenu->AppendMenu(MF_STRING|MF_GRAYED, IDM_DEEP_16, "16位增强颜色(&U)");
|
|
pSysMenu->AppendMenu(MF_STRING, IDM_DEEP_32, "32位真彩颜色(&R)");
|
|
|
|
pSysMenu->CheckMenuRadioItem(IDM_ALGORITHM_HOME, IDM_ALGORITHM_XVID, IDM_ALGORITHM_HOME, MF_BYCOMMAND);
|
|
pSysMenu->CheckMenuRadioItem(IDM_DEEP_16, IDM_DEEP_32, IDM_DEEP_32, MF_BYCOMMAND);
|
|
}
|
|
|
|
// TODO: Add extra initialization here
|
|
CString str;
|
|
str.Format(_T("\\\\%s (%d * %d)"), m_IPAddress, m_lpbmi_full->bmiHeader.biWidth, m_lpbmi_full->bmiHeader.biHeight);
|
|
SetWindowText(str);
|
|
|
|
ImmAssociateContext(m_hWnd, NULL);
|
|
m_hRemoteCursor = LoadCursor(NULL, IDC_ARROW);
|
|
|
|
m_LastCursorPos.x = 0;
|
|
m_LastCursorPos.y = 0;
|
|
m_bIsTraceCursor = false;
|
|
|
|
// 初始化窗口大小结构
|
|
m_hCurrWndDC = ::GetDC(m_hWnd);
|
|
m_hLastMemDC = ::CreateCompatibleDC(m_hCurrWndDC);
|
|
m_hLastBitmap = ::CreateDIBSection(m_hCurrWndDC, m_lpbmi_full, DIB_RGB_COLORS, &m_lpvLastBits, NULL, NULL);
|
|
m_lpvRectBits = new BYTE[m_lpbmi_rect->bmiHeader.biSizeImage];
|
|
SelectObject(m_hLastMemDC, m_hLastBitmap);
|
|
|
|
SendNext();
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
void CScreenSpyDlg::FullScreen()
|
|
{
|
|
LONG style = ::GetWindowLong(this->m_hWnd, GWL_STYLE);
|
|
|
|
if(!m_bIsFullScreen) //全屏显示
|
|
{
|
|
APPBARDATA abd;
|
|
memset(&abd, 0, sizeof(abd));
|
|
abd.cbSize = sizeof(abd);
|
|
int nMaxWindowWidth, nMaxWindowHeight;
|
|
UINT_PTR uState = SHAppBarMessage(ABM_GETSTATE, &abd);
|
|
SHAppBarMessage(ABM_GETTASKBARPOS, &abd);
|
|
if (abd.uEdge == 0) // 任务栏在左
|
|
{
|
|
nMaxWindowWidth = GetSystemMetrics(SM_CXSCREEN) - (uState == ABS_AUTOHIDE ? 0 : abd.rc.right);
|
|
nMaxWindowHeight = GetSystemMetrics(SM_CYSCREEN);
|
|
}
|
|
if (abd.uEdge == 1) // 任务栏在上
|
|
{
|
|
nMaxWindowWidth = GetSystemMetrics(SM_CXSCREEN);
|
|
nMaxWindowHeight = GetSystemMetrics(SM_CYSCREEN) - (uState == ABS_AUTOHIDE ? 0 : abd.rc.bottom);
|
|
}
|
|
if (abd.uEdge == 2) // 任务栏在右
|
|
{
|
|
nMaxWindowWidth = GetSystemMetrics(SM_CXSCREEN) - (uState == ABS_AUTOHIDE ? 0 : abd.rc.right - abd.rc.left);
|
|
nMaxWindowHeight = GetSystemMetrics(SM_CYSCREEN);
|
|
}
|
|
if (abd.uEdge == 3) // 任务栏在下
|
|
{
|
|
nMaxWindowWidth = GetSystemMetrics(SM_CXSCREEN);
|
|
nMaxWindowHeight = GetSystemMetrics(SM_CYSCREEN) - (uState == ABS_AUTOHIDE ? 0 : abd.rc.bottom - abd.rc.top);
|
|
}
|
|
|
|
RECT rectWindow, rectClient;
|
|
GetWindowRect(&rectWindow);
|
|
GetClientRect(&rectClient);
|
|
ClientToScreen(&rectClient);
|
|
|
|
int nBorderSize = rectClient.left - rectWindow.left; // 单边框的大小(宽度或高度)
|
|
int nTitleHeight = rectClient.top - rectWindow.top - nBorderSize; // 标题栏的高度
|
|
int nMaxClientWidth = nMaxWindowWidth - nBorderSize * 2;
|
|
int nMaxClientHeight = nMaxWindowHeight - nTitleHeight - nBorderSize * 2;
|
|
|
|
if (nMaxClientWidth >= m_lpbmi_full->bmiHeader.biWidth && nMaxClientHeight >= m_lpbmi_full->bmiHeader.biHeight)
|
|
{
|
|
OnNcLButtonDblClk(HTCAPTION, NULL);
|
|
return;
|
|
}
|
|
|
|
GetWindowRect(&m_rcRestore);
|
|
style &= ~(WS_DLGFRAME | WS_THICKFRAME);
|
|
SetWindowLong(this->m_hWnd, GWL_STYLE, style);
|
|
|
|
if (m_lpbmi_full->bmiHeader.biWidth < GetSystemMetrics(SM_CXSCREEN) &&
|
|
m_lpbmi_full->bmiHeader.biHeight < GetSystemMetrics(SM_CYSCREEN))
|
|
{
|
|
MoveWindow(
|
|
(GetSystemMetrics(SM_CXSCREEN) - m_lpbmi_full->bmiHeader.biWidth) / 2,
|
|
(GetSystemMetrics(SM_CYSCREEN) - m_lpbmi_full->bmiHeader.biHeight) / 2,
|
|
m_lpbmi_full->bmiHeader.biWidth, m_lpbmi_full->bmiHeader.biHeight);
|
|
}
|
|
else if (m_lpbmi_full->bmiHeader.biWidth < GetSystemMetrics(SM_CXSCREEN))
|
|
{
|
|
MoveWindow((GetSystemMetrics(SM_CXSCREEN) - m_lpbmi_full->bmiHeader.biWidth) / 2, 0,
|
|
m_lpbmi_full->bmiHeader.biWidth, GetSystemMetrics(SM_CYSCREEN));
|
|
}
|
|
else if (m_lpbmi_full->bmiHeader.biHeight < GetSystemMetrics(SM_CYSCREEN))
|
|
{
|
|
MoveWindow(0, (GetSystemMetrics(SM_CYSCREEN) - m_lpbmi_full->bmiHeader.biHeight) / 2,
|
|
GetSystemMetrics(SM_CXSCREEN), m_lpbmi_full->bmiHeader.biHeight);
|
|
}
|
|
else
|
|
{
|
|
MoveWindow(0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
|
|
}
|
|
|
|
m_bIsFullScreen = true; // 设置全屏显示标志
|
|
SendMessage(WM_ACTIVATE, MAKEWPARAM(WA_ACTIVE, FALSE), NULL);
|
|
}
|
|
else // 窗口显示
|
|
{
|
|
style |= WS_DLGFRAME | WS_THICKFRAME;
|
|
SetWindowLong(this->m_hWnd, GWL_STYLE, style);
|
|
OnNcLButtonDblClk(HTCAPTION, NULL);
|
|
CMenu* pSysMenu = GetSystemMenu(FALSE);
|
|
if (!(pSysMenu->GetMenuState(IDM_TOPMOST, MF_BYCOMMAND) & MF_CHECKED))
|
|
{
|
|
SendMessage(WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, FALSE), NULL);
|
|
}
|
|
m_bIsFullScreen = false; // 取消全屏显示标志
|
|
}
|
|
}
|
|
|
|
void CScreenSpyDlg::ResetScreen()
|
|
{
|
|
UINT nBitmapInfoSize = m_pContext->m_DeCompressionBuffer.GetBufferLen() - 1;
|
|
if (m_lpbmi_full != NULL)
|
|
{
|
|
int nOldWidth = m_lpbmi_full->bmiHeader.biWidth;
|
|
int nOldHeight = m_lpbmi_full->bmiHeader.biHeight;
|
|
|
|
delete[] m_lpbmi_full;
|
|
delete[] m_lpbmi_rect;
|
|
m_lpbmi_full = (BITMAPINFO *) new BYTE[nBitmapInfoSize];
|
|
m_lpbmi_rect = (BITMAPINFO *) new BYTE[nBitmapInfoSize];
|
|
memcpy(m_lpbmi_full, m_pContext->m_DeCompressionBuffer.GetBuffer(1), nBitmapInfoSize);
|
|
memcpy(m_lpbmi_rect, m_pContext->m_DeCompressionBuffer.GetBuffer(1), nBitmapInfoSize);
|
|
|
|
DeleteObject(m_hLastBitmap);
|
|
m_hLastBitmap = CreateDIBSection(m_hCurrWndDC, m_lpbmi_full, DIB_RGB_COLORS, &m_lpvLastBits, NULL, NULL);
|
|
if (m_lpvRectBits)
|
|
{
|
|
delete[] m_lpvRectBits;
|
|
m_lpvRectBits = new BYTE[m_lpbmi_rect->bmiHeader.biSizeImage];
|
|
}
|
|
SelectObject(m_hLastMemDC, m_hLastBitmap);
|
|
|
|
m_XvidDec.Close();
|
|
m_XvidDec.Open(m_lpbmi_full->bmiHeader.biWidth, m_lpbmi_full->bmiHeader.biHeight, m_lpbmi_full->bmiHeader.biBitCount);
|
|
|
|
// 分辨率发生改变
|
|
if (nOldWidth != m_lpbmi_full->bmiHeader.biWidth || nOldHeight != m_lpbmi_full->bmiHeader.biHeight)
|
|
{
|
|
if (m_bIsFullScreen)
|
|
{
|
|
FullScreen();
|
|
FullScreen();
|
|
}
|
|
else
|
|
{
|
|
memset(&m_rcRestore, 0, sizeof(m_rcRestore));
|
|
OnNcLButtonDblClk(HTCAPTION, NULL);
|
|
memset(&m_rcRestore, 0, sizeof(m_rcRestore));
|
|
}
|
|
if (GetKeyState(VK_SCROLL) & 0x0001)
|
|
{
|
|
CRect ClientRect;
|
|
GetClientRect(ClientRect);
|
|
ClientToScreen(ClientRect);
|
|
ClipCursor(ClientRect);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CScreenSpyDlg::DrawFirstScreen()
|
|
{
|
|
bool bIsReDraw = false;
|
|
BYTE algorithm = m_pContext->m_DeCompressionBuffer.GetBuffer(0)[1];
|
|
LPVOID lpFirstScreen = m_pContext->m_DeCompressionBuffer.GetBuffer(2);
|
|
DWORD dwFirstLength = m_pContext->m_DeCompressionBuffer.GetBufferLen() - 2;
|
|
|
|
if (algorithm == ALGORITHM_HOME && dwFirstLength > 0)
|
|
{
|
|
if (JPG_BMP(m_lpbmi_full->bmiHeader.biBitCount, lpFirstScreen, dwFirstLength, m_lpvLastBits))
|
|
bIsReDraw = true;
|
|
}
|
|
else if (algorithm == ALGORITHM_XVID && dwFirstLength > 0)
|
|
{
|
|
if (m_XvidDec.Decode(lpFirstScreen, dwFirstLength, m_lpvLastBits) > 0)
|
|
bIsReDraw = true;
|
|
}
|
|
m_bIsFirst = false;
|
|
|
|
if (bIsReDraw)
|
|
{
|
|
#ifdef _DEBUG
|
|
SendNotifyMessage(WM_PAINT, NULL, NULL);
|
|
#else
|
|
OnPaint();
|
|
#endif // _DEBUG
|
|
}
|
|
}
|
|
|
|
void CScreenSpyDlg::DrawNextScreenHome()
|
|
{
|
|
// 根据鼠标是否移动和屏幕是否变化判断是否重绘鼠标, 防止鼠标闪烁
|
|
bool bIsReDraw = false;
|
|
int nHeadLength = 1 + 1 + sizeof(POINT) + sizeof(BYTE); // 标识[1] + 算法[1] + 光标位置[8] + 光标类型索引[1]
|
|
LPVOID lpNextScreen = m_pContext->m_DeCompressionBuffer.GetBuffer(nHeadLength);
|
|
DWORD dwNextLength = m_pContext->m_DeCompressionBuffer.GetBufferLen() - nHeadLength;
|
|
DWORD dwNextOffset = 0;
|
|
|
|
// 判断鼠标是否移动
|
|
LPPOINT lpNextCursorPos = (LPPOINT)m_pContext->m_DeCompressionBuffer.GetBuffer(2);
|
|
if (memcmp(lpNextCursorPos, &m_LastCursorPos, sizeof(POINT)) != 0 && m_bIsTraceCursor)
|
|
{
|
|
bIsReDraw = true;
|
|
memcpy(&m_LastCursorPos, lpNextCursorPos, sizeof(POINT));
|
|
}
|
|
|
|
// 光标类型发生变化
|
|
LPBYTE lpNextCursorIndex = m_pContext->m_DeCompressionBuffer.GetBuffer(10);
|
|
if (*lpNextCursorIndex != m_LastCursorIndex)
|
|
{
|
|
m_LastCursorIndex = *lpNextCursorIndex;
|
|
if (m_bIsTraceCursor)
|
|
bIsReDraw = true;
|
|
if (m_bIsCtrl && !m_bIsTraceCursor)
|
|
{
|
|
HCURSOR hNewCursor = m_CursorInfo.getCursorHandle(m_LastCursorIndex == (BYTE)-1 ? 1 : m_LastCursorIndex);
|
|
SetClassLong(m_hWnd, GCL_HCURSOR, (LONG)hNewCursor);
|
|
}
|
|
}
|
|
|
|
// 屏幕数据是否变化
|
|
while (dwNextOffset < dwNextLength)
|
|
{
|
|
int *pinlen = (int *)((LPBYTE)lpNextScreen + dwNextOffset);
|
|
|
|
if (JPG_BMP(m_lpbmi_full->bmiHeader.biBitCount, pinlen + 1, *pinlen, m_lpvRectBits))
|
|
{
|
|
bIsReDraw = true;
|
|
LPRECT lpChangedRect = (LPRECT)((LPBYTE)(pinlen + 1) + *pinlen);
|
|
int nChangedRectWidth = lpChangedRect->right - lpChangedRect->left;
|
|
int nChangedRectHeight = lpChangedRect->bottom - lpChangedRect->top;
|
|
|
|
m_lpbmi_rect->bmiHeader.biWidth = nChangedRectWidth;
|
|
m_lpbmi_rect->bmiHeader.biHeight = nChangedRectHeight;
|
|
m_lpbmi_rect->bmiHeader.biSizeImage = (((nChangedRectWidth * m_lpbmi_rect->bmiHeader.biBitCount + 31) & ~31) >> 3)
|
|
* nChangedRectHeight;
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
StretchDIBits(m_hLastMemDC, lpChangedRect->left, lpChangedRect->top, nChangedRectWidth, nChangedRectHeight,
|
|
0, 0, nChangedRectWidth, nChangedRectHeight, m_lpvRectBits, m_lpbmi_rect, DIB_RGB_COLORS, SRCCOPY);
|
|
LeaveCriticalSection(&m_cs);
|
|
|
|
dwNextOffset += sizeof(int) + *pinlen + sizeof(RECT);
|
|
}
|
|
}
|
|
|
|
if (bIsReDraw)
|
|
{
|
|
#ifdef _DEBUG
|
|
SendNotifyMessage(WM_PAINT, NULL, NULL);
|
|
#else
|
|
OnPaint();
|
|
#endif // _DEBUG
|
|
}
|
|
}
|
|
|
|
bool CScreenSpyDlg::JPG_BMP(int cbit, void *input, int inlen, void *output)
|
|
{
|
|
struct jpeg_decompress_struct jds;
|
|
struct jpeg_error_mgr jem;
|
|
|
|
// 设置错误处理
|
|
jds.err = jpeg_std_error(&jem);
|
|
// 创建解压结构
|
|
jpeg_create_decompress(&jds);
|
|
// 设置读取(输入)位置
|
|
jpeg_mem_src(&jds, (byte *)input, inlen);
|
|
// 读取头部信息
|
|
if (jpeg_read_header(&jds, true) != JPEG_HEADER_OK)
|
|
{
|
|
jpeg_destroy_decompress(&jds);
|
|
return false;
|
|
}
|
|
// 设置相关参数
|
|
switch (cbit)
|
|
{
|
|
case 16:
|
|
jds.out_color_space = JCS_EXT_RGB;
|
|
break;
|
|
case 24:
|
|
jds.out_color_space = JCS_EXT_BGR;
|
|
break;
|
|
case 32:
|
|
jds.out_color_space = JCS_EXT_BGRA;
|
|
break;
|
|
default:
|
|
jpeg_destroy_decompress(&jds);
|
|
return false;
|
|
}
|
|
// 开始解压图像
|
|
if (!jpeg_start_decompress(&jds))
|
|
{
|
|
jpeg_destroy_decompress(&jds);
|
|
return false;
|
|
}
|
|
int line_stride = (jds.output_width * cbit / 8 + 3) / 4 * 4;
|
|
while (jds.output_scanline < jds.output_height)
|
|
{
|
|
byte* pline = (byte*)output + jds.output_scanline * line_stride;
|
|
jpeg_read_scanlines(&jds, &pline, 1);
|
|
}
|
|
// 完成图像解压
|
|
if (!jpeg_finish_decompress(&jds))
|
|
{
|
|
jpeg_destroy_decompress(&jds);
|
|
return false;
|
|
}
|
|
// 释放相关资源
|
|
jpeg_destroy_decompress(&jds);
|
|
|
|
return true;
|
|
}
|
|
|
|
void CScreenSpyDlg::DrawNextScreenXvid()
|
|
{
|
|
// 根据鼠标是否移动和屏幕是否变化判断是否重绘鼠标, 防止鼠标闪烁
|
|
bool bIsReDraw = false;
|
|
int nHeadLength = 1 + 1 + sizeof(POINT) + sizeof(BYTE); // 标识[1] + 算法[1] + 光标位置[8] + 光标类型索引[1]
|
|
LPVOID lpLastScreen = m_lpvLastBits;
|
|
LPVOID lpNextScreen = m_pContext->m_DeCompressionBuffer.GetBuffer(nHeadLength);
|
|
DWORD dwNextLength = m_pContext->m_DeCompressionBuffer.GetBufferLen() - nHeadLength;
|
|
|
|
// 判断鼠标是否移动
|
|
LPPOINT lpNextCursorPos = (LPPOINT)m_pContext->m_DeCompressionBuffer.GetBuffer(2);
|
|
if (memcmp(lpNextCursorPos, &m_LastCursorPos, sizeof(POINT)) != 0 && m_bIsTraceCursor)
|
|
{
|
|
bIsReDraw = true;
|
|
memcpy(&m_LastCursorPos, lpNextCursorPos, sizeof(POINT));
|
|
}
|
|
|
|
// 光标类型发生变化
|
|
LPBYTE lpNextCursorIndex = m_pContext->m_DeCompressionBuffer.GetBuffer(10);
|
|
if (*lpNextCursorIndex != m_LastCursorIndex)
|
|
{
|
|
m_LastCursorIndex = *lpNextCursorIndex;
|
|
if (m_bIsTraceCursor)
|
|
bIsReDraw = true;
|
|
if (m_bIsCtrl && !m_bIsTraceCursor)
|
|
{
|
|
HCURSOR hNewCursor = m_CursorInfo.getCursorHandle(m_LastCursorIndex == (BYTE)-1 ? 1 : m_LastCursorIndex);
|
|
SetClassLong(m_hWnd, GCL_HCURSOR, (LONG)hNewCursor);
|
|
}
|
|
}
|
|
|
|
// 屏幕数据是否变化
|
|
if (dwNextLength > 0)
|
|
{
|
|
bIsReDraw = true;
|
|
m_XvidDec.Decode(lpNextScreen, dwNextLength, lpLastScreen);
|
|
}
|
|
|
|
if (bIsReDraw)
|
|
{
|
|
#ifdef _DEBUG
|
|
SendNotifyMessage(WM_PAINT, NULL, NULL);
|
|
#else
|
|
OnPaint();
|
|
#endif // _DEBUG
|
|
}
|
|
}
|
|
|
|
void CScreenSpyDlg::OnPaint()
|
|
{
|
|
// TODO: Add your message handler code here
|
|
CPaintDC dc(this); // device context for painting
|
|
RECT rect;
|
|
GetClientRect(&rect);
|
|
|
|
if (m_bIsFirst)
|
|
{
|
|
DrawTipString(_T("Please wait - initial screen loading"));
|
|
return;
|
|
}
|
|
|
|
//int iHScrollPos = GetScrollPos(SB_HORZ);
|
|
//int iVScrollPos = GetScrollPos(SB_VERT);
|
|
EnterCriticalSection(&m_cs);
|
|
// BitBlt(m_hCurrWndDC, 0, 0, m_lpbmi_full->bmiHeader.biWidth, m_lpbmi_full->bmiHeader.biHeight, m_hLastMemDC, 0, 0, SRCCOPY);
|
|
SetStretchBltMode(m_hCurrWndDC,STRETCH_HALFTONE);
|
|
LPBITMAPINFO lpbi = m_lpbmi_full;
|
|
StretchDIBits
|
|
(
|
|
|
|
m_hCurrWndDC,
|
|
0, 0, rect.right, rect.bottom,
|
|
0, 0, m_lpbmi_full->bmiHeader.biWidth, m_lpbmi_full->bmiHeader.biHeight,
|
|
(LPBYTE)m_lpvLastBits,
|
|
lpbi,
|
|
DIB_RGB_COLORS,
|
|
SRCCOPY
|
|
);
|
|
|
|
|
|
LeaveCriticalSection(&m_cs);
|
|
|
|
// (BYTE)-1 = 255;
|
|
// Draw the cursor
|
|
if (m_bIsTraceCursor)
|
|
{
|
|
DrawIconEx(
|
|
m_hCurrWndDC, // handle to device context
|
|
0, // x-coord of upper left corner
|
|
0, // y-coord of upper left corner
|
|
m_CursorInfo.getCursorHandle(m_LastCursorIndex == (BYTE)-1 ? 1 : m_LastCursorIndex), // handle to icon to draw
|
|
0,0, // width of the icon
|
|
0, // index of frame in animated cursor
|
|
NULL, // handle to background brush
|
|
DI_NORMAL | DI_COMPAT // icon-drawing flags
|
|
);
|
|
}
|
|
|
|
// Do not call CDialog::OnPaint() for painting messages
|
|
}
|
|
|
|
LRESULT CScreenSpyDlg::OnSizing(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if (m_rcRestore.right && m_rcRestore.bottom)
|
|
memset(&m_rcRestore, 0, sizeof(m_rcRestore));
|
|
return FALSE;
|
|
}
|
|
|
|
void CScreenSpyDlg::OnSize(UINT nType, int cx, int cy)
|
|
{
|
|
//CDialog::OnSize(nType, cx, cy);
|
|
|
|
// TODO: Add your message handler code here
|
|
if (!GetSafeHwnd())
|
|
return;
|
|
|
|
SCROLLINFO si;
|
|
memset(&si, 0, sizeof(si));
|
|
si.cbSize = sizeof(SCROLLINFO);
|
|
si.fMask = SIF_PAGE|SIF_RANGE;
|
|
si.nPage = 1;
|
|
si.nMin = 0;
|
|
|
|
SCROLLBARINFO sbiv, sbih;
|
|
sbiv.cbSize = sizeof(SCROLLBARINFO);
|
|
sbih.cbSize = sizeof(SCROLLBARINFO);
|
|
GetScrollBarInfo(m_hWnd, OBJID_VSCROLL, &sbiv);
|
|
GetScrollBarInfo(m_hWnd, OBJID_HSCROLL, &sbih);
|
|
sbiv.dxyLineButton = sbiv.rgstate[0] & STATE_SYSTEM_INVISIBLE ? 0 : sbiv.dxyLineButton;
|
|
sbih.dxyLineButton = sbih.rgstate[0] & STATE_SYSTEM_INVISIBLE ? 0 : sbih.dxyLineButton;
|
|
// 根据客户区大小, 调整水平滚动条和垂直滚动条的状态
|
|
if (cx >= m_lpbmi_full->bmiHeader.biWidth)
|
|
ShowScrollBar(SB_HORZ, FALSE);
|
|
else
|
|
{
|
|
si.nMax = m_lpbmi_full->bmiHeader.biWidth - cx;
|
|
SetScrollInfo(SB_HORZ, &si, TRUE);
|
|
}
|
|
if (cy >= m_lpbmi_full->bmiHeader.biHeight)
|
|
ShowScrollBar(SB_VERT, FALSE);
|
|
else
|
|
{
|
|
SCROLLBARINFO sbit;
|
|
sbit.cbSize = sizeof(SCROLLBARINFO);
|
|
GetScrollBarInfo(m_hWnd, OBJID_HSCROLL, &sbit);
|
|
si.nMax = m_lpbmi_full->bmiHeader.biHeight - cy - (sbit.rgstate[0] & STATE_SYSTEM_INVISIBLE ? sbih.dxyLineButton : 0);
|
|
SetScrollInfo(SB_VERT, &si, TRUE);
|
|
}
|
|
// 客户区宽度+垂直滚动条宽度>=分辨率宽度 && 客户区高度+水平滚动条高度>=分辨率高度
|
|
if (cx + sbiv.dxyLineButton >= m_lpbmi_full->bmiHeader.biWidth && cy + sbih.dxyLineButton >= m_lpbmi_full->bmiHeader.biHeight)
|
|
{
|
|
ShowScrollBar(SB_BOTH, FALSE);
|
|
}
|
|
// 水平滚动条不可见时, 窗口宽度增加一个垂直滚动条的宽度
|
|
if (sbih.rgstate[0] & STATE_SYSTEM_INVISIBLE && !m_rcRestore.right && !m_rcRestore.bottom)
|
|
{
|
|
RECT rectWindow;
|
|
GetWindowRect(&rectWindow);
|
|
rectWindow.right += sbiv.dxyLineButton;
|
|
MoveWindow(&rectWindow);
|
|
}
|
|
// 垂直滚动条不可见时, 窗口高度增加一个水平滚动条的高度
|
|
if (sbiv.rgstate[0] & STATE_SYSTEM_INVISIBLE && !m_rcRestore.right && !m_rcRestore.bottom)
|
|
{
|
|
RECT rectWindow;
|
|
GetWindowRect(&rectWindow);
|
|
rectWindow.bottom += sbih.dxyLineButton;
|
|
MoveWindow(&rectWindow);
|
|
}
|
|
|
|
if (GetScrollPos(SB_HORZ) + cx > m_lpbmi_full->bmiHeader.biWidth)
|
|
SetScrollPos(SB_HORZ, m_lpbmi_full->bmiHeader.biWidth - cx);
|
|
if (GetScrollPos(SB_VERT) + cy > m_lpbmi_full->bmiHeader.biHeight)
|
|
SetScrollPos(SB_VERT, m_lpbmi_full->bmiHeader.biHeight - cy);
|
|
}
|
|
|
|
void CScreenSpyDlg::OnNcLButtonDblClk(UINT nHitTest, CPoint point)
|
|
{
|
|
if (nHitTest == HTCAPTION)
|
|
{
|
|
RECT rectClient;
|
|
if (m_rcRestore.right && m_rcRestore.bottom)
|
|
{
|
|
MoveWindow(&m_rcRestore);
|
|
memset(&m_rcRestore, 0, sizeof(m_rcRestore));
|
|
// 必须OnSize一次, 否则滚动条显示有点问题
|
|
GetClientRect(&rectClient);
|
|
OnSize(0, rectClient.right, rectClient.bottom);
|
|
return;
|
|
}
|
|
|
|
APPBARDATA abd;
|
|
memset(&abd, 0, sizeof(abd));
|
|
abd.cbSize = sizeof(abd);
|
|
int nMinX, nMinY, nMaxWindowWidth, nMaxWindowHeight;
|
|
UINT_PTR uState = SHAppBarMessage(ABM_GETSTATE, &abd);
|
|
SHAppBarMessage(ABM_GETTASKBARPOS, &abd);
|
|
if (abd.uEdge == 0) // 任务栏在左
|
|
{
|
|
nMinX = uState == ABS_AUTOHIDE ? 0 : abd.rc.right;
|
|
nMinY = 0;
|
|
nMaxWindowWidth = GetSystemMetrics(SM_CXSCREEN) - (uState == ABS_AUTOHIDE ? 0 : abd.rc.right);
|
|
nMaxWindowHeight = GetSystemMetrics(SM_CYSCREEN);
|
|
}
|
|
if (abd.uEdge == 1) // 任务栏在上
|
|
{
|
|
nMinX = 0;
|
|
nMinY = uState == ABS_AUTOHIDE ? 0 : abd.rc.bottom;
|
|
nMaxWindowWidth = GetSystemMetrics(SM_CXSCREEN);
|
|
nMaxWindowHeight = GetSystemMetrics(SM_CYSCREEN) - (uState == ABS_AUTOHIDE ? 0 : abd.rc.bottom);
|
|
}
|
|
if (abd.uEdge == 2) // 任务栏在右
|
|
{
|
|
nMinX = 0;
|
|
nMinY = 0;
|
|
nMaxWindowWidth = GetSystemMetrics(SM_CXSCREEN) - (uState == ABS_AUTOHIDE ? 0 : abd.rc.right - abd.rc.left);
|
|
nMaxWindowHeight = GetSystemMetrics(SM_CYSCREEN);
|
|
}
|
|
if (abd.uEdge == 3) // 任务栏在下
|
|
{
|
|
nMinX = 0;
|
|
nMinY = 0;
|
|
nMaxWindowWidth = GetSystemMetrics(SM_CXSCREEN);
|
|
nMaxWindowHeight = GetSystemMetrics(SM_CYSCREEN) - (uState == ABS_AUTOHIDE ? 0 : abd.rc.bottom - abd.rc.top);
|
|
}
|
|
|
|
GetWindowRect(&m_rcRestore);
|
|
GetClientRect(&rectClient);
|
|
ClientToScreen(&rectClient);
|
|
|
|
int nBorderSize = rectClient.left - m_rcRestore.left; // 单边框的大小(宽度或高度)
|
|
int nTitleHeight = rectClient.top - m_rcRestore.top - nBorderSize; // 标题栏的高度
|
|
int nMaxClientWidth = nMaxWindowWidth - nBorderSize * 2;
|
|
int nMaxClientHeight = nMaxWindowHeight - nTitleHeight - nBorderSize * 2;
|
|
|
|
if (m_lpbmi_full->bmiHeader.biWidth < nMaxClientWidth && m_lpbmi_full->bmiHeader.biHeight < nMaxClientHeight)
|
|
{
|
|
int nMovWindowWidth = m_lpbmi_full->bmiHeader.biWidth + nBorderSize * 2;
|
|
int nMovWindowHeight = m_lpbmi_full->bmiHeader.biHeight + nTitleHeight + nBorderSize * 2;
|
|
int x = (nMaxWindowWidth - nMovWindowWidth) / 2 + nMinX;
|
|
int y = (nMaxWindowHeight - nMovWindowHeight) / 2 + nMinY;
|
|
MoveWindow(x, y, nMovWindowWidth, nMovWindowHeight);
|
|
}
|
|
else if (m_lpbmi_full->bmiHeader.biWidth < nMaxClientWidth)
|
|
{
|
|
SCROLLBARINFO sbiv;
|
|
sbiv.cbSize = sizeof(SCROLLBARINFO);
|
|
ShowScrollBar(SB_VERT, TRUE);
|
|
GetScrollBarInfo(m_hWnd, OBJID_VSCROLL, &sbiv);
|
|
int nMovWindowWidth = m_lpbmi_full->bmiHeader.biWidth + nBorderSize * 2;
|
|
if (nMovWindowWidth + sbiv.dxyLineButton <= nMaxWindowWidth)
|
|
nMovWindowWidth += sbiv.dxyLineButton;
|
|
int nMovWindowHeight = nMaxWindowHeight;
|
|
int x = (nMaxWindowWidth - nMovWindowWidth) / 2 + nMinX;
|
|
MoveWindow(x, nMinY, nMovWindowWidth, nMovWindowHeight);
|
|
}
|
|
else if (m_lpbmi_full->bmiHeader.biHeight < nMaxClientHeight)
|
|
{
|
|
SCROLLBARINFO sbih;
|
|
sbih.cbSize = sizeof(SCROLLBARINFO);
|
|
ShowScrollBar(SB_VERT, TRUE);
|
|
GetScrollBarInfo(m_hWnd, OBJID_HSCROLL, &sbih);
|
|
int nMovWindowWidth = nMaxWindowWidth;
|
|
int nMovWindowHeight = m_lpbmi_full->bmiHeader.biHeight + nTitleHeight + nBorderSize * 2;
|
|
if (nMovWindowHeight + sbih.dxyLineButton <= nMaxWindowHeight)
|
|
nMovWindowHeight += sbih.dxyLineButton;
|
|
int y = (nMaxWindowHeight - nMovWindowHeight) / 2 + nMinY;
|
|
MoveWindow(nMinX, y, nMovWindowWidth, nMovWindowHeight);
|
|
}
|
|
else
|
|
{
|
|
int nMovWindowWidth = nMaxWindowWidth;
|
|
int nMovWindowHeight = nMaxWindowHeight;
|
|
MoveWindow(nMinX, nMinY, nMovWindowWidth, nMovWindowHeight);
|
|
}
|
|
// 必须OnSize一次, 否则滚动条显示有点问题
|
|
GetClientRect(&rectClient);
|
|
OnSize(0, rectClient.right, rectClient.bottom);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void CScreenSpyDlg::OnSysCommand(UINT nID, LPARAM lParam)
|
|
{
|
|
CMenu* pSysMenu = GetSystemMenu(FALSE);
|
|
switch (nID)
|
|
{
|
|
case SC_MAXIMIZE:
|
|
OnNcLButtonDblClk(HTCAPTION, NULL);
|
|
return;
|
|
case SC_MONITORPOWER: // 拦截显示器节电自动关闭的消息
|
|
return;
|
|
case SC_SCREENSAVE: // 拦截屏幕保护启动的消息
|
|
return;
|
|
case IDM_CONTROL:
|
|
{
|
|
m_bIsCtrl = !m_bIsCtrl;
|
|
pSysMenu->CheckMenuItem(IDM_CONTROL, m_bIsCtrl ? MF_CHECKED : MF_UNCHECKED);
|
|
|
|
if (m_bIsCtrl)
|
|
{
|
|
if (m_bIsTraceCursor)
|
|
SetClassLong(m_hWnd, GCL_HCURSOR, (LONG)AfxGetApp()->LoadCursor(IDC_DOT));
|
|
else
|
|
SetClassLong(m_hWnd, GCL_HCURSOR, (LONG)m_hRemoteCursor);
|
|
}
|
|
else
|
|
SetClassLong(m_hWnd, GCL_HCURSOR, (LONG)LoadCursor(NULL, IDC_NO));
|
|
}
|
|
break;
|
|
case IDM_TOPMOST:
|
|
{
|
|
bool bIsTopMost = pSysMenu->GetMenuState(IDM_TOPMOST, MF_BYCOMMAND) & MF_CHECKED;
|
|
pSysMenu->CheckMenuItem(IDM_TOPMOST, bIsTopMost ? MF_UNCHECKED : MF_CHECKED);
|
|
if (bIsTopMost)
|
|
SetWindowPos(&wndNoTopMost, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
|
|
else
|
|
SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
|
|
}
|
|
break;
|
|
case IDM_CTRL_ALT_DEL:
|
|
{
|
|
BYTE bToken = COMMAND_SCREEN_CTRL_ALT_DEL;
|
|
m_iocpServer->Send(m_pContext, &bToken, sizeof(bToken));
|
|
}
|
|
break;
|
|
case IDM_TRACE_CURSOR: // 跟踪服务端鼠标
|
|
{
|
|
m_bIsTraceCursor = !m_bIsTraceCursor;
|
|
pSysMenu->CheckMenuItem(IDM_TRACE_CURSOR, m_bIsTraceCursor ? MF_CHECKED : MF_UNCHECKED);
|
|
if (m_bIsCtrl)
|
|
{
|
|
if (!m_bIsTraceCursor)
|
|
SetClassLong(m_hWnd, GCL_HCURSOR, (LONG)m_hRemoteCursor);
|
|
else
|
|
SetClassLong(m_hWnd, GCL_HCURSOR, (LONG)AfxGetApp()->LoadCursor(IDC_DOT));
|
|
}
|
|
// 重绘消除或显示鼠标
|
|
OnPaint();
|
|
}
|
|
break;
|
|
case IDM_BLOCK_INPUT: // 锁定服务端鼠标和键盘
|
|
{
|
|
bool bIsChecked = pSysMenu->GetMenuState(IDM_BLOCK_INPUT, MF_BYCOMMAND) & MF_CHECKED;
|
|
pSysMenu->CheckMenuItem(IDM_BLOCK_INPUT, bIsChecked ? MF_UNCHECKED : MF_CHECKED);
|
|
|
|
BYTE bToken[2];
|
|
bToken[0] = COMMAND_SCREEN_BLOCK_INPUT;
|
|
bToken[1] = !bIsChecked;
|
|
m_iocpServer->Send(m_pContext, bToken, sizeof(bToken));
|
|
}
|
|
break;
|
|
case IDM_BLANK_SCREEN: // 服务端黑屏
|
|
{
|
|
bool bIsChecked = pSysMenu->GetMenuState(IDM_BLANK_SCREEN, MF_BYCOMMAND) & MF_CHECKED;
|
|
pSysMenu->CheckMenuItem(IDM_BLANK_SCREEN, bIsChecked ? MF_UNCHECKED : MF_CHECKED);
|
|
|
|
BYTE bToken[2];
|
|
bToken[0] = COMMAND_SCREEN_BLANK;
|
|
bToken[1] = !bIsChecked;
|
|
m_iocpServer->Send(m_pContext, bToken, sizeof(bToken));
|
|
}
|
|
break;
|
|
case IDM_CAPTURE_LAYER: // 捕捉层
|
|
{
|
|
bool bIsChecked = pSysMenu->GetMenuState(IDM_CAPTURE_LAYER, MF_BYCOMMAND) & MF_CHECKED;
|
|
pSysMenu->CheckMenuItem(IDM_CAPTURE_LAYER, bIsChecked ? MF_UNCHECKED : MF_CHECKED);
|
|
|
|
BYTE bToken[2];
|
|
bToken[0] = COMMAND_SCREEN_CAPTURE_LAYER;
|
|
bToken[1] = !bIsChecked;
|
|
m_iocpServer->Send(m_pContext, bToken, sizeof(bToken));
|
|
}
|
|
break;
|
|
case IDM_SAVEDIB:
|
|
SaveSnapshot();
|
|
break;
|
|
case IDM_GET_CLIPBOARD: // 获取剪贴板
|
|
{
|
|
BYTE bToken = COMMAND_SCREEN_GET_CLIPBOARD;
|
|
m_iocpServer->Send(m_pContext, &bToken, sizeof(bToken));
|
|
}
|
|
break;
|
|
case IDM_SET_CLIPBOARD: // 设置剪贴板
|
|
{
|
|
SendLocalClipboard();
|
|
}
|
|
break;
|
|
case IDM_AERO_DISABLE: // 禁用桌面合成(Aero)
|
|
{
|
|
BYTE bToken = COMMAND_AERO_DISABLE;
|
|
m_iocpServer->Send(m_pContext, &bToken, sizeof(bToken));
|
|
}
|
|
break;
|
|
case IDM_AERO_ENABLE: // 启用桌面合成(Aero)
|
|
{
|
|
BYTE bToken = COMMAND_AERO_ENABLE;
|
|
m_iocpServer->Send(m_pContext, &bToken, sizeof(bToken));
|
|
}
|
|
break;
|
|
case IDM_ALGORITHM_HOME: // 家用办公算法
|
|
{
|
|
SendResetScreen(32);
|
|
pSysMenu->CheckMenuRadioItem(IDM_ALGORITHM_HOME, IDM_ALGORITHM_XVID, IDM_ALGORITHM_HOME, MF_BYCOMMAND);
|
|
pSysMenu->CheckMenuRadioItem(IDM_DEEP_16, IDM_DEEP_32, IDM_DEEP_32, MF_BYCOMMAND);
|
|
pSysMenu->EnableMenuItem(IDM_DEEP_16, MF_GRAYED);
|
|
SendResetAlgorithm(ALGORITHM_HOME);
|
|
}
|
|
break;
|
|
case IDM_ALGORITHM_XVID: // 影视娱乐算法
|
|
{
|
|
SendResetAlgorithm(ALGORITHM_XVID);
|
|
pSysMenu->CheckMenuRadioItem(IDM_ALGORITHM_HOME, IDM_ALGORITHM_XVID, IDM_ALGORITHM_XVID, MF_BYCOMMAND);
|
|
pSysMenu->EnableMenuItem(IDM_DEEP_16, MF_ENABLED);
|
|
}
|
|
break;
|
|
// case IDM_DEEP_1:
|
|
// {
|
|
// SendResetScreen(1);
|
|
// pSysMenu->CheckMenuRadioItem(IDM_DEEP_1, IDM_DEEP_32, IDM_DEEP_1, MF_BYCOMMAND);
|
|
// }
|
|
// break;
|
|
// case IDM_DEEP_4_GRAY:
|
|
// {
|
|
// SendResetScreen(3);
|
|
// pSysMenu->CheckMenuRadioItem(IDM_DEEP_1, IDM_DEEP_32, IDM_DEEP_4_GRAY, MF_BYCOMMAND);
|
|
// }
|
|
// break;
|
|
// case IDM_DEEP_4_COLOR:
|
|
// {
|
|
// SendResetScreen(4);
|
|
// pSysMenu->CheckMenuRadioItem(IDM_DEEP_1, IDM_DEEP_32, IDM_DEEP_4_COLOR, MF_BYCOMMAND);
|
|
// }
|
|
// break;
|
|
// case IDM_DEEP_8_GRAY:
|
|
// {
|
|
// SendResetScreen(7);
|
|
// pSysMenu->CheckMenuRadioItem(IDM_DEEP_1, IDM_DEEP_32, IDM_DEEP_8_GRAY, MF_BYCOMMAND);
|
|
// }
|
|
// break;
|
|
// case IDM_DEEP_8_COLOR:
|
|
// {
|
|
// SendResetScreen(8);
|
|
// pSysMenu->CheckMenuRadioItem(IDM_DEEP_1, IDM_DEEP_32, IDM_DEEP_8_COLOR, MF_BYCOMMAND);
|
|
// }
|
|
// break;
|
|
case IDM_DEEP_16:
|
|
{
|
|
SendResetScreen(16);
|
|
pSysMenu->CheckMenuRadioItem(IDM_DEEP_16, IDM_DEEP_32, IDM_DEEP_16, MF_BYCOMMAND);
|
|
}
|
|
break;
|
|
case IDM_DEEP_32:
|
|
{
|
|
SendResetScreen(32);
|
|
pSysMenu->CheckMenuRadioItem(IDM_DEEP_16, IDM_DEEP_32, IDM_DEEP_32, MF_BYCOMMAND);
|
|
}
|
|
break;
|
|
default:
|
|
CDialog::OnSysCommand(nID, lParam);
|
|
}
|
|
}
|
|
|
|
void CScreenSpyDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
|
|
{
|
|
RECT rectWindow, rectClient;
|
|
GetWindowRect(&rectWindow);
|
|
GetClientRect(&rectClient);
|
|
ClientToScreen(&rectClient);
|
|
|
|
int nBorderSize = rectClient.left - rectWindow.left; // 单边框的大小(宽度或高度)
|
|
int nTitleHeight = rectClient.top - rectWindow.top - nBorderSize; // 标题栏的高度
|
|
// int nMinWindowWidth = 400 + nBorderSize * 2;
|
|
// int nMinWindowHeight = 300 + nTitleHeight + nBorderSize * 2;
|
|
int nMaxWindowWidth = m_lpbmi_full->bmiHeader.biWidth + nBorderSize * 2;
|
|
int nMaxWindowHeight = m_lpbmi_full->bmiHeader.biHeight + nTitleHeight + nBorderSize * 2;
|
|
|
|
SCROLLBARINFO sbiv, sbih;
|
|
sbiv.cbSize = sizeof(SCROLLBARINFO);
|
|
sbih.cbSize = sizeof(SCROLLBARINFO);
|
|
GetScrollBarInfo(m_hWnd, OBJID_VSCROLL, &sbiv);
|
|
GetScrollBarInfo(m_hWnd, OBJID_HSCROLL, &sbih);
|
|
// nMinWindowWidth += sbiv.dxyLineButton;
|
|
// nMinWindowHeight += sbih.dxyLineButton;
|
|
nMaxWindowWidth += sbiv.rgstate[0] & STATE_SYSTEM_INVISIBLE ? 0 : sbiv.dxyLineButton;
|
|
nMaxWindowHeight += sbih.rgstate[0] & STATE_SYSTEM_INVISIBLE ? 0 : sbih.dxyLineButton;
|
|
|
|
// lpMMI->ptMinTrackSize.x = nMinWindowWidth;
|
|
// lpMMI->ptMinTrackSize.y = nMinWindowHeight;
|
|
lpMMI->ptMaxTrackSize.x = nMaxWindowWidth;
|
|
lpMMI->ptMaxTrackSize.y = nMaxWindowHeight;
|
|
|
|
// APPBARDATA abd;
|
|
// memset(&abd, 0, sizeof(abd));
|
|
// abd.cbSize = sizeof(abd);
|
|
// UINT_PTR uState = SHAppBarMessage(ABM_GETSTATE, &abd);
|
|
// SHAppBarMessage(ABM_GETTASKBARPOS, &abd);
|
|
// if (abd.uEdge == 0) // 任务栏在左
|
|
// {
|
|
// lpMMI->ptMaxPosition.x = uState == ABS_AUTOHIDE ? 0 : abd.rc.right;
|
|
// lpMMI->ptMaxPosition.y = 0;
|
|
// lpMMI->ptMaxSize.x = GetSystemMetrics(SM_CXSCREEN) - (uState == ABS_AUTOHIDE ? 0 : abd.rc.right);
|
|
// lpMMI->ptMaxSize.y = GetSystemMetrics(SM_CYSCREEN);
|
|
// }
|
|
// if (abd.uEdge == 1) // 任务栏在上
|
|
// {
|
|
// lpMMI->ptMaxPosition.x = 0;
|
|
// lpMMI->ptMaxPosition.y = uState == ABS_AUTOHIDE ? 0 : abd.rc.bottom;
|
|
// lpMMI->ptMaxSize.x = GetSystemMetrics(SM_CXSCREEN);
|
|
// lpMMI->ptMaxSize.y = GetSystemMetrics(SM_CYSCREEN) - (uState == ABS_AUTOHIDE ? 0 : abd.rc.bottom);
|
|
// }
|
|
// if (abd.uEdge == 2) // 任务栏在右
|
|
// {
|
|
// lpMMI->ptMaxPosition.x = 0;
|
|
// lpMMI->ptMaxPosition.y = 0;
|
|
// lpMMI->ptMaxSize.x = GetSystemMetrics(SM_CXSCREEN) - (uState == ABS_AUTOHIDE ? 0 : abd.rc.right - abd.rc.left);
|
|
// lpMMI->ptMaxSize.y = GetSystemMetrics(SM_CYSCREEN);
|
|
// }
|
|
// if (abd.uEdge == 3) // 任务栏在下
|
|
// {
|
|
// lpMMI->ptMaxPosition.x = 0;
|
|
// lpMMI->ptMaxPosition.y = 0;
|
|
// lpMMI->ptMaxSize.x = GetSystemMetrics(SM_CXSCREEN);
|
|
// lpMMI->ptMaxSize.y = GetSystemMetrics(SM_CYSCREEN) - (uState == ABS_AUTOHIDE ? 0 : abd.rc.bottom - abd.rc.top);
|
|
// }
|
|
}
|
|
|
|
void CScreenSpyDlg::DrawTipString(CString str)
|
|
{
|
|
RECT rect;
|
|
GetClientRect(&rect);
|
|
COLORREF bgcol = RGB(0x00, 0x00, 0x00);
|
|
COLORREF oldbgcol = SetBkColor(m_hCurrWndDC, bgcol);
|
|
COLORREF oldtxtcol = SetTextColor(m_hCurrWndDC, RGB(0xff,0x00,0x00));
|
|
ExtTextOut(m_hCurrWndDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
|
|
|
|
DrawText (m_hCurrWndDC, str, -1, &rect,
|
|
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
|
|
|
|
SetBkColor(m_hCurrWndDC, oldbgcol);
|
|
SetTextColor(m_hCurrWndDC, oldtxtcol);
|
|
/* InvalidateRect(NULL, FALSE);*/
|
|
}
|
|
|
|
BOOL CScreenSpyDlg::PreTranslateMessage(MSG* pMsg)
|
|
{
|
|
// TODO: Add your specialized code here and/or call the base class
|
|
|
|
switch (pMsg->message)
|
|
{
|
|
case WM_MOUSEMOVE:
|
|
if (GetKeyState(VK_SCROLL) & 0x0001) // Scroll灯点亮状态
|
|
{
|
|
CRect ClientRect;
|
|
GetClientRect(ClientRect);
|
|
|
|
int nHScrollPos = (float)m_lpbmi_full->bmiHeader.biWidth / ClientRect.Width() * LOWORD(pMsg->lParam);
|
|
int nVScrollPos = (float)m_lpbmi_full->bmiHeader.biHeight / ClientRect.Height() * HIWORD(pMsg->lParam);
|
|
SCROLLBARINFO sbi; int nMinPos, nMaxPos;
|
|
sbi.cbSize = sizeof(SCROLLBARINFO);
|
|
GetScrollBarInfo(m_hWnd, OBJID_HSCROLL, &sbi);
|
|
if (!(sbi.rgstate[0] & STATE_SYSTEM_INVISIBLE))
|
|
{
|
|
GetScrollRange(SB_HORZ, &nMinPos, &nMaxPos);
|
|
if (nHScrollPos > nMaxPos)
|
|
nHScrollPos = nMaxPos;
|
|
PostMessage(WM_HSCROLL, MAKEWPARAM(SB_THUMBTRACK, nHScrollPos), NULL);
|
|
}
|
|
GetScrollBarInfo(m_hWnd, OBJID_VSCROLL, &sbi);
|
|
if (!(sbi.rgstate[0] & STATE_SYSTEM_INVISIBLE))
|
|
{
|
|
GetScrollRange(SB_VERT, &nMinPos, &nMaxPos);
|
|
if (nVScrollPos > nMaxPos)
|
|
nVScrollPos = nMaxPos;
|
|
PostMessage(WM_VSCROLL, MAKEWPARAM(SB_THUMBTRACK, nVScrollPos), NULL);
|
|
}
|
|
|
|
ClientToScreen(ClientRect);
|
|
ClipCursor(ClientRect);
|
|
}
|
|
else
|
|
{
|
|
ClipCursor(NULL);
|
|
}
|
|
case WM_LBUTTONDOWN:
|
|
case WM_LBUTTONUP:
|
|
case WM_RBUTTONDOWN:
|
|
case WM_RBUTTONUP:
|
|
case WM_LBUTTONDBLCLK:
|
|
case WM_RBUTTONDBLCLK:
|
|
case WM_MBUTTONDOWN:
|
|
case WM_MBUTTONUP:
|
|
case WM_MBUTTONDBLCLK:
|
|
case WM_MOUSEWHEEL:
|
|
{
|
|
MSG msg;
|
|
memcpy(&msg, pMsg, sizeof(MSG));
|
|
int xPos = (int)(short)LOWORD(pMsg->lParam) + GetScrollPos(SB_HORZ);
|
|
int yPos = (int)(short)HIWORD(pMsg->lParam) + GetScrollPos(SB_VERT);
|
|
msg.lParam = MAKELPARAM(xPos, yPos);
|
|
msg.pt.x = xPos;
|
|
msg.pt.y = yPos;
|
|
SendCommand(&msg);
|
|
}
|
|
break;
|
|
case WM_KEYDOWN:
|
|
if (pMsg->wParam == VK_RETURN && GetKeyState(VK_CONTROL)&0x8000 && GetKeyState(VK_MENU)&0x8000)
|
|
{
|
|
FullScreen();
|
|
if (GetKeyState(VK_SCROLL) & 0x0001)
|
|
{
|
|
CRect ClientRect;
|
|
GetClientRect(ClientRect);
|
|
ClientToScreen(ClientRect);
|
|
ClipCursor(ClientRect);
|
|
}
|
|
return TRUE;
|
|
}
|
|
case WM_KEYUP:
|
|
if (pMsg->wParam == VK_RETURN && GetKeyState(VK_CONTROL)&0x8000 && GetKeyState(VK_MENU)&0x8000)
|
|
{
|
|
return TRUE;
|
|
}
|
|
case WM_SYSKEYUP:
|
|
case WM_SYSKEYDOWN:
|
|
if (pMsg->wParam != VK_SCROLL)
|
|
{
|
|
MSG msg;
|
|
memcpy(&msg, pMsg, sizeof(MSG));
|
|
ScreenToClient(&msg.pt);
|
|
msg.pt.x += GetScrollPos(SB_HORZ);
|
|
msg.pt.y += GetScrollPos(SB_VERT);
|
|
SendCommand(&msg);
|
|
if (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_F4)
|
|
return TRUE;
|
|
}
|
|
if (pMsg->wParam == VK_SCROLL)
|
|
{
|
|
if (GetKeyState(VK_SCROLL) & 0x0001)
|
|
{
|
|
CRect ClientRect;
|
|
GetClientRect(ClientRect);
|
|
ClientToScreen(ClientRect);
|
|
ClipCursor(ClientRect);
|
|
}
|
|
else ClipCursor(NULL);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return CDialog::PreTranslateMessage(pMsg);
|
|
}
|
|
|
|
void CScreenSpyDlg::PostNcDestroy()
|
|
{
|
|
// TODO: Add your specialized code here and/or call the base class
|
|
delete this;
|
|
CDialog::PostNcDestroy();
|
|
}
|
|
|
|
void CScreenSpyDlg::SendCommand(MSG* pMsg)
|
|
{
|
|
if (!m_bIsCtrl)
|
|
return;
|
|
|
|
LPBYTE lpData = new BYTE[sizeof(MSG) + 1];
|
|
lpData[0] = COMMAND_SCREEN_CONTROL;
|
|
memcpy(lpData + 1, pMsg, sizeof(MSG));
|
|
m_iocpServer->Send(m_pContext, lpData, sizeof(MSG) + 1);
|
|
|
|
delete[] lpData;
|
|
}
|
|
|
|
void CScreenSpyDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
|
|
{
|
|
// TODO: Add your message handler code here and/or call default
|
|
SCROLLINFO si;
|
|
si.cbSize = sizeof(SCROLLINFO);
|
|
si.fMask = SIF_ALL;
|
|
GetScrollInfo(SB_HORZ, &si);
|
|
|
|
int nPrevPos = si.nPos;
|
|
switch(nSBCode)
|
|
{
|
|
case SB_LEFT:
|
|
si.nPos = si.nMin;
|
|
break;
|
|
case SB_RIGHT:
|
|
si.nPos = si.nMax;
|
|
break;
|
|
case SB_LINELEFT:
|
|
if (si.nPos > si.nMin)
|
|
si.nPos--;
|
|
break;
|
|
case SB_LINERIGHT:
|
|
if (si.nPos < si.nMax)
|
|
si.nPos++;
|
|
break;
|
|
case SB_PAGELEFT:
|
|
if (si.nPos > si.nMin)
|
|
si.nPos = max(si.nMin, si.nPos - (int)si.nPage);
|
|
break;
|
|
case SB_PAGERIGHT:
|
|
if (si.nPos < si.nMax)
|
|
si.nPos = min(si.nMax, si.nPos + (int)si.nPage);
|
|
break;
|
|
case SB_THUMBPOSITION:
|
|
case SB_THUMBTRACK:
|
|
si.nPos = nPos;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
si.fMask = SIF_POS;
|
|
SetScrollInfo(SB_HORZ, &si, TRUE);
|
|
// ScrollWindow(nPrevPos - si.nPos, 0);
|
|
OnPaint();
|
|
|
|
CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
|
|
}
|
|
|
|
void CScreenSpyDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
|
|
{
|
|
// TODO: Add your message handler code here and/or call default
|
|
SCROLLINFO si;
|
|
si.cbSize = sizeof(SCROLLINFO);
|
|
si.fMask = SIF_ALL;
|
|
GetScrollInfo(SB_VERT, &si);
|
|
|
|
int nPrevPos = si.nPos;
|
|
switch(nSBCode)
|
|
{
|
|
case SB_TOP:
|
|
si.nPos = si.nMin;
|
|
break;
|
|
case SB_BOTTOM:
|
|
si.nPos = si.nMax;
|
|
break;
|
|
case SB_LINEUP:
|
|
if (si.nPos > si.nMin)
|
|
si.nPos--;
|
|
break;
|
|
case SB_LINEDOWN:
|
|
if (si.nPos < si.nMax)
|
|
si.nPos++;
|
|
break;
|
|
case SB_PAGEUP:
|
|
if (si.nPos > si.nMin)
|
|
si.nPos = max(si.nMin, si.nPos - (int)si.nPage);
|
|
break;
|
|
case SB_PAGEDOWN:
|
|
if (si.nPos < si.nMax)
|
|
si.nPos = min(si.nMax, si.nPos + (int)si.nPage);
|
|
break;
|
|
case SB_THUMBPOSITION:
|
|
case SB_THUMBTRACK:
|
|
si.nPos = nPos;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
si.fMask = SIF_POS;
|
|
SetScrollInfo(SB_VERT, &si, TRUE);
|
|
// ScrollWindow(0, nPrevPos - si.nPos);
|
|
OnPaint();
|
|
|
|
CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
|
|
}
|
|
|
|
void CScreenSpyDlg::UpdateLocalClipboard(char *buf, int len)
|
|
{
|
|
if (!::OpenClipboard(NULL))
|
|
return;
|
|
|
|
::EmptyClipboard();
|
|
HGLOBAL hglbCopy = GlobalAlloc(GPTR, 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 CScreenSpyDlg::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] = COMMAND_SCREEN_SET_CLIPBOARD;
|
|
memcpy(lpData + 1, lpstr, nPacketLen - 1);
|
|
::GlobalUnlock(hglb);
|
|
::CloseClipboard();
|
|
m_iocpServer->Send(m_pContext, lpData, nPacketLen);
|
|
delete[] lpData;
|
|
}
|
|
|
|
void CScreenSpyDlg::SendNext()
|
|
{
|
|
BYTE bBuff = COMMAND_NEXT;
|
|
m_iocpServer->Send(m_pContext, &bBuff, 1);
|
|
}
|
|
|
|
LRESULT CScreenSpyDlg::OnMoving(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
SystemParametersInfo(SPI_GETWINARRANGING, 0, (LPVOID)&m_bWinArrange, 0);
|
|
SystemParametersInfo(SPI_GETSNAPSIZING, 0, (LPVOID)&m_bSnapSizing, 0);
|
|
SystemParametersInfo(SPI_SETWINARRANGING, 0, (LPVOID)TRUE, 0);
|
|
SystemParametersInfo(SPI_SETSNAPSIZING, 0, (LPVOID)FALSE, 0);
|
|
return FALSE;
|
|
}
|
|
|
|
void CScreenSpyDlg::OnMove(int x, int y)
|
|
{
|
|
CDialog::OnMove(x, y);
|
|
|
|
// TODO: Add your message handler code here
|
|
SystemParametersInfo(SPI_SETSNAPSIZING, 0, (LPVOID)m_bSnapSizing, 0);
|
|
SystemParametersInfo(SPI_SETWINARRANGING, 0, (LPVOID)m_bWinArrange, 0);
|
|
}
|
|
|
|
LRESULT CScreenSpyDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
// TODO: Add your specialized code here and/or call the base class
|
|
if (message == WM_POWERBROADCAST && wParam == PBT_APMQUERYSUSPEND)
|
|
{
|
|
return BROADCAST_QUERY_DENY; // 拦截系统待机, 休眠的请求
|
|
}
|
|
if (message == WM_ACTIVATE && LOWORD(wParam) != WA_INACTIVE && !HIWORD(wParam) && m_bIsFullScreen)
|
|
{
|
|
SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
|
|
return TRUE;
|
|
}
|
|
if (message == WM_ACTIVATE && LOWORD(wParam) == WA_INACTIVE && m_bIsFullScreen)
|
|
{
|
|
SetWindowPos(&wndNoTopMost, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
|
|
return TRUE;
|
|
}
|
|
|
|
return CDialog::WindowProc(message, wParam, lParam);
|
|
}
|