www.pudn.com > ntshell.rar > 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; 
}