📄 screenview.cpp
字号:
// screenview.cpp: implementation of the CScreenView class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "resource.h"
#include "common.h"
#include "ntshell.h"
#include "sockmgr1.h"
#include "screenview.h"
extern ULONG ScreenCaptureMethod;
extern ULONG ScreenCaptureSpace;
extern BOOLEAN AutoZoom;
LRESULT CScreenView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
slave_sock = INVALID_SOCKET;
bScreenBuffer = NULL;
bSetCursor = false;
nLastPackSize = 0;
nScreenX = 0;
nScreenY = 0;
nLastPosX = 0;
nLastPosY = 0;
IPicture *pPic;
IStream *pStm;
HMODULE hModule = GetModuleHandle(NULL);
HRSRC hSrc = FindResource(hModule, MAKEINTRESOURCE(IDR_BACKGROUND), "BINARY");
HGLOBAL hRes = LoadResource(hModule, hSrc);
ULONG size = SizeofResource(hModule, hSrc);
UCHAR *p = (UCHAR *)LockResource(hRes);
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, size);
void *pData = GlobalLock(hGlobal);
memcpy(pData, p, size);
GlobalUnlock(hGlobal);
FreeResource(hRes);
if (CreateStreamOnHGlobal(hGlobal, TRUE, &pStm) == S_OK)
{
if (SUCCEEDED(OleLoadPicture(pStm, size, FALSE, IID_IPicture, (LPVOID *)&pPic)))
{
HBITMAP hB;
pPic->get_Handle((OLE_HANDLE *)&hB);
BITMAP bmpInfo;
GetObject(hB, sizeof(BITMAP), &bmpInfo);
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = bmpInfo.bmWidth;
bih.biHeight = -bmpInfo.bmHeight;
bih.biPlanes = 1;
bih.biBitCount = 16;
bih.biCompression = BI_RGB;
bih.biSizeImage = 0;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
bScreenBuffer = HeapAlloc(GetProcessHeap(), 0, bmpInfo.bmWidth * bmpInfo.bmHeight * 2);
HDC hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
GetDIBits(hScrDC, hB, 0, bmpInfo.bmHeight, bScreenBuffer, (BITMAPINFO *)&bih, DIB_RGB_COLORS);
DeleteDC(hScrDC);
pPic->Release();
}
}
GlobalFree(hGlobal);
return TRUE;
}
LRESULT CScreenView::OnTimer(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{/*
PVOID p1 = VirtualAlloc(NULL, 1024 * 768 * 2, MEM_COMMIT, PAGE_READWRITE);
PVOID p2 = VirtualAlloc(NULL, 1024 * 768 * 2, MEM_COMMIT, PAGE_READWRITE);
int n = DeCompress((PBYTE)p1, (PBYTE)p2, 200);
//memcpy(buffer2, buffer, n);
UpdateBuffer(p2, bScreenBuffer, n);
VirtualFree(p1, 0, MEM_RELEASE);
VirtualFree(p2, 0, MEM_RELEASE);//*/
updating = true;
int temp = SCREEN_FULL;
if (framecount & 15)
temp = ScreenCaptureMethod;//temp = SCREEN_DIFFERENCE;
send(slave_sock, (char *)&temp, sizeof(char), 0);
return TRUE;
}
LRESULT CScreenView::OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
SCROLLINFO si;
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_ALL;
GetScrollInfo(SB_HORZ, &si);
if (si.nMax <= LOWORD(lParam))
ShowScrollBar(SB_HORZ, FALSE);
else
ShowScrollBar(SB_HORZ, TRUE);
si.nPage = LOWORD(lParam);
SetScrollInfo(SB_HORZ, &si);
GetScrollInfo(SB_VERT, &si);
if (si.nMax <= HIWORD(lParam))
ShowScrollBar(SB_VERT, FALSE);
else
ShowScrollBar(SB_VERT, TRUE);
si.nPage = HIWORD(lParam);
SetScrollInfo(SB_VERT, &si);
return TRUE;
}
LRESULT CScreenView::OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
CPaintDC dc(m_hWnd);
RECT rc;
GetClientRect(&rc);
if (bScreenBuffer != NULL)
{
int nHeight = bih.biHeight < 0 ? -bih.biHeight : bih.biHeight;
HDC hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
HDC hMemDC = CreateCompatibleDC(hScrDC);
HBITMAP hBitmap = CreateCompatibleBitmap(hScrDC, bih.biWidth, nHeight);
SelectObject(hMemDC, hBitmap);
DeleteDC(hScrDC);
SetDIBits(hMemDC, hBitmap, 0, nHeight, bScreenBuffer, (BITMAPINFO *)&bih, DIB_RGB_COLORS);
if (AutoZoom)
{
dc.StretchBlt(rc.left, rc.top, rc.right, rc.bottom, hMemDC, 0, 0, bih.biWidth, nHeight, SRCCOPY);
ShowScrollBar(SB_VERT, FALSE);
ShowScrollBar(SB_HORZ, FALSE);
}
else
{
dc.BitBlt(0, 0, bih.biWidth, nHeight, hMemDC, nScreenX, nScreenY, SRCCOPY);/*
SCROLLINFO si;
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_ALL;
si.nMin = 0;
si.nMax = nHeight;
si.nPage = rc.right;
si.nPos = 0;
SetScrollInfo(SB_HORZ, &si);
si.nMax = bih.biWidth;
si.nPage = 16;
SetScrollInfo(SB_VERT, &si);//*/
}
CString msg;
msg.Format("收到:%dK", nLastPackSize / 1024);
SetTextColor(dc, RGB(255, 0, 0));
SetBkColor(dc, RGB(255, 255, 255));
SetBkMode(dc, TRANSPARENT);
dc.DrawText(msg, msg.GetLength(), &rc, DT_RIGHT);
DeleteDC(hMemDC);
DeleteObject(hBitmap);
}
if (slave_sock == INVALID_SOCKET)
{
HFONT hFont = CreateFont(84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "宋体");
HFONT hOldFont = (HFONT)SelectObject(dc, hFont);
SetTextColor(dc, RGB(0, 0, 0));
SetBkColor(dc, RGB(255, 255, 255));
SetBkMode(dc, TRANSPARENT);
dc.DrawText("未 连 接", 8, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
SelectObject(dc, hOldFont);
DeleteObject(hFont);
}
return TRUE;
}
LRESULT CScreenView::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
if (bScreenBuffer != NULL)
HeapFree(GetProcessHeap(), 0, bScreenBuffer);
return TRUE;
}
LRESULT CScreenView::OnSocketRead(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
SOCKET slave_sock = (SOCKET)wParam;
CSockMgr::RecvPack(slave_sock, ScreenUpdate, this);
return 0;
}
LRESULT CScreenView::OnHscroll(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
return 0;
}
LRESULT CScreenView::OnVscroll(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
SCROLLINFO si;
int i;
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_ALL;
GetScrollInfo(SB_VERT, &si);
switch (LOWORD(wParam))
{
case SB_LINEUP:
i = si.nPos - 1;
break;
case SB_LINEDOWN:
i = si.nPos + 1;
break;
case SB_THUMBPOSITION:
case SB_THUMBTRACK:
i = HIWORD(wParam);
break;
default:
return 0;
}
i = max(i, si.nMin);
i = min(i, (int)(si.nMax - si.nPage + 1));
SetScrollPos(SB_VERT, i);
return 0;
}
LRESULT CScreenView::OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
if (AutoZoom)
return 0;
nLastPosX = -1;
nLastPosY = -1;
if (!bSetCursor)
{
bSetCursor = true;
SetCursor(LoadCursor(NULL, IDC_SIZEALL));
SetCapture();
}
return 0;
}
LRESULT CScreenView::OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
if (AutoZoom)
return 0;
if (bSetCursor)
{
bSetCursor = false;
SetCursor(LoadCursor(NULL, IDC_ARROW));
ReleaseCapture();
}
return 0;
}
LRESULT CScreenView::OnMouseMove(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
if (AutoZoom)
return 0;
if (!(wParam & MK_LBUTTON))
{
if (bSetCursor)
{
bSetCursor = false;
SetCursor(LoadCursor(NULL, IDC_ARROW));
ReleaseCapture();
}
return 0;
}
bSetCursor = true;
SetCursor(LoadCursor(NULL, IDC_SIZEALL));
POINT point;
GetCursorPos(&point);
int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam);
xPos = point.x;
yPos = point.y;
if (nLastPosX == -1 || nLastPosY == -1)
{
nLastPosX = xPos;
nLastPosY = yPos;
return 0;
}
RECT rc;
GetClientRect(&rc);
if (xPos != nLastPosX)
{
nScreenX += nLastPosX - xPos;
nLastPosX = xPos;
}
if (yPos != nLastPosY)
{
nScreenY += nLastPosY - yPos;
nLastPosY = yPos;
}
if (bih.biWidth > rc.right)
{
if (nScreenX > (bih.biWidth - rc.right))
nScreenX = (bih.biWidth - rc.right);
if (nScreenX < 0)
nScreenX = 0;
}
else
{
nScreenX = 0;
}
if (-bih.biHeight > rc.bottom)
{
if (nScreenY > (-bih.biHeight - rc.bottom))
nScreenY = (-bih.biHeight - rc.bottom);
if (nScreenY < 0)
nScreenY = 0;
}
else
{
nScreenY = 0;
}
RedrawWindow(NULL, 0, RDW_INVALIDATE);
return 0;
}
LRESULT CScreenView::OnConnectCreated(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
{
slave_sock = (SOCKET)wParam;
updating = false;
framecount = 0;
InvalidateRect(NULL, FALSE);
SetTimer(WM_TIMER, 1000);
return 0;
}
LRESULT CScreenView::OnConnectClosed(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
CSockMgr::InterruptRecv(slave_sock);
slave_sock = INVALID_SOCKET;
KillTimer(WM_TIMER);
InvalidateRect(NULL, FALSE);
return 0;
}
void CScreenView::XorBuffer(PBYTE src, PBYTE dst, DWORD len)
{
for (DWORD i = 0; i < len / 4; i++)
{
((PDWORD)dst)[i] ^= ((PDWORD)src)[i];
}
}
void CScreenView::UpdateBuffer(PBYTE src, PBYTE dst, DWORD len, DWORD width)
{
PBYTE out = dst;
for (PBYTE p = src + len; src < p;)
{
DWORD temp = *src++;
if (temp >= 248)
{
DWORD y = ((temp & 0x07) << 8) | *src++;
out = dst + y * width * 2;
memcpy(out, src, width * 2);
src += width * 2;
}
else if (temp >= 240)
{
DWORD y = ((temp & 0x07) << 8) | *src++;
out = dst + y * width * 2;
}
else
{
DWORD offset = temp & 0x07;
if (temp >= 224)
offset = (offset << 8) | *src++;
DWORD length = *((PBYTE)src)++;
if (length >= 240)
length = ((length & 0x0f) << 8) | *src++;
memcpy(out + offset, src, length);
src += length;
out += offset + length;
}
}
}
int CScreenView::ScreenUpdate(CSockMgr::PPACK_INFO pack, LPVOID param)
{
PSCREENCAP_SCREENBITMAP psb = (PSCREENCAP_SCREENBITMAP)pack->pData;
CScreenView *scrview = (CScreenView *)param;
scrview->bih.biSize = sizeof(BITMAPINFOHEADER);
scrview->bih.biWidth = psb->Width;
scrview->bih.biHeight = -psb->Height;
scrview->bih.biPlanes = 1;
scrview->bih.biBitCount = psb->Depth;
scrview->bih.biCompression = BI_RGB;
scrview->bih.biSizeImage = 0;
scrview->bih.biXPelsPerMeter = 0;
scrview->bih.biYPelsPerMeter = 0;
scrview->bih.biClrUsed = 0;
scrview->bih.biClrImportant = 0;
if (psb->Method == SCREEN_DIFFERENCE)
{
if (psb->Size != 0)
scrview->UpdateBuffer((PBYTE)psb->Bits, (PBYTE)scrview->bScreenBuffer, psb->Size, psb->Width);
}
else if (psb->Method == SCREEN_FULL)
{
if (scrview->bScreenBuffer != NULL)
HeapFree(GetProcessHeap(), 0, scrview->bScreenBuffer);
scrview->bScreenBuffer = HeapAlloc(GetProcessHeap(), 0, psb->Size);
if (scrview->bScreenBuffer != NULL)
{
memcpy(scrview->bScreenBuffer, psb->Bits, psb->Size);
}
}
else if (psb->Method == SCREEN_XOR)
{
if (psb->Size != 0)
scrview->XorBuffer((PBYTE)psb->Bits, (PBYTE)scrview->bScreenBuffer, psb->Size);
}
scrview->nLastPackSize = pack->nPackSize;
scrview->InvalidateRect(NULL, FALSE);
scrview->framecount++;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -