?? peeperwnd.cpp
字號:
///////////////////////////////////////////////////////////////////////////////
// 遠程控制軟件-偷窺者 開發庫 //
// 日期:2001/10/02 //
// 作者:劉東發 //
// Email:dongfa@yeah.net //
// http://dongfa.yeah.net //
// OICQ:5584173 阿東 //
// 作者聲明: //
// 此部分代碼全是作者所寫,或以隨便傳播,但要保持文件的完整性,有問題 //
// 或者意見請來信,謝謝! //
///////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "PeeperWnd.h"
#define USE_DOC // 如果不需要Doc類時,刪除此行
#ifdef USE_DOC
#include "PeeperClientDoc.h"
#endif
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// CGetDIBThread
IMPLEMENT_DYNCREATE(CPeeperThread, CWinThread)
CPeeperThread::CPeeperThread()
{
m_pPeeperWnd = NULL;
m_bAutoDelete = FALSE;
m_szScreen.cx = 1024;
m_szScreen.cx = 768;
}
CPeeperThread::~CPeeperThread()
{
}
BEGIN_MESSAGE_MAP(CPeeperThread, CWinThread)
//{{AFX_MSG_MAP(CGetDIBThread)
//}}AFX_MSG_MAP
ON_THREAD_MESSAGE(PL_GET_DIB_MESSAGE, OnMsgGetDIB)
ON_THREAD_MESSAGE(PL_CONNECT_MESSAGE, OnMsgConnect)
END_MESSAGE_MAP()
HRESULT CPeeperThread::OnMsgConnect(WPARAM, LPARAM)
{
BOOL bRet = FALSE;
do
{
bRet = ::PL_InitSocket();
if(!bRet)
{
break ;
}
if(!m_pPeeperWnd)
{
bRet = FALSE;
break ;
}
int nRet = 0;
sockaddr_in addr;
hostent* pEnt = NULL;
m_pPeeperWnd->m_sckClient[0] = ::socket(AF_INET, SOCK_STREAM, 0);
m_pPeeperWnd->m_sckClient[1] = ::socket(AF_INET, SOCK_STREAM, 0);
TRACE(_T("Client Socket 0 and 1:%d, %d.\n"),
m_pPeeperWnd->m_sckClient[0], m_pPeeperWnd->m_sckClient[1]);
if(m_pPeeperWnd->m_sckClient[0] == INVALID_SOCKET ||
m_pPeeperWnd->m_sckClient[1] == INVALID_SOCKET)
{
bRet = FALSE;
break ;
}
pEnt = ::gethostbyname(m_pPeeperWnd->m_strIP);
if(!pEnt)
{
bRet = FALSE;
break ;
}
addr.sin_family = AF_INET;
addr.sin_port = ::htons((u_short)(m_pPeeperWnd->m_uPort));
addr.sin_addr.S_un.S_un_b.s_b1 = pEnt->h_addr_list[0][0];
addr.sin_addr.S_un.S_un_b.s_b2 = pEnt->h_addr_list[0][1];
addr.sin_addr.S_un.S_un_b.s_b3 = pEnt->h_addr_list[0][2];
addr.sin_addr.S_un.S_un_b.s_b4 = pEnt->h_addr_list[0][3];
bRet = FALSE; // default
for(int i = 0; i < 3; i ++)
{
int nRet1 = ::connect(m_pPeeperWnd->m_sckClient[0],
(sockaddr*)&addr, sizeof(addr));
if(nRet1 != SOCKET_ERROR)
{
BYTE chData[5];
ZeroMemory(chData, 5);
::PL_ReadSocketData(m_pPeeperWnd->m_sckClient[0], chData, 5, NULL);
}
else
{
TRACE(_T("Socket Error Code = %d.\n"), ::WSAGetLastError());
}
TRACE(_T("Client[0] is: %s.\n"), (nRet1 == 0)?_T("Ok"):_T("Failed."));
int nRet2 = ::connect(m_pPeeperWnd->m_sckClient[1],
(sockaddr*)&addr, sizeof(addr));
if(nRet2 == SOCKET_ERROR)
{
TRACE(_T("Socket Error Code = %d.\n"), ::WSAGetLastError());
}
TRACE(_T("Client[1] is: %s.\n"), (nRet2 == 0)?_T("Ok"):_T("Failed."));
if(nRet1 == SOCKET_ERROR ||
nRet2 == SOCKET_ERROR)
{
Sleep(2000);
continue ;
}
char chConnectInfo[512];
ZeroMemory(chConnectInfo, 512);
int nRet = ::PL_ReadSocketData(m_pPeeperWnd->m_sckClient[0],
(BYTE *)chConnectInfo, 512, NULL);
m_pPeeperWnd->SetConnectInfo(chConnectInfo);
bRet = TRUE; // Connect Ok!
break ;
}
}while(0);
if(m_pPeeperWnd)
{
DWORD dwFlag = PL_PEEPER_NOTIFY_DISCONNECT;
if(bRet)
{
dwFlag = PL_PEEPER_NOTIFY_CONNECT;
}
::SendMessage(m_pPeeperWnd->GetSafeHwnd(),
PL_CONNECT_MESSAGE, (WPARAM)PL_CONNECT_MESSAGE, (LPARAM)dwFlag);
}
return bRet ? S_OK : E_FAIL;
}
HRESULT CPeeperThread::OnMsgGetDIB(WPARAM, LPARAM)
{
int nRet = INVALID_SOCKET;
DWORD d1 = ::GetTickCount();
if(m_pPeeperWnd && (m_pPeeperWnd->m_sckClient[1] != INVALID_SOCKET))
{
BYTE chData[20];
ZeroMemory(chData, 20);
//發送顏色位數和壓縮類型
PL_ColorType ctColor = m_pPeeperWnd->GetColorType();
memcpy(chData, &ctColor, sizeof(PL_ColorType));
PL_ZipType ztZip = m_pPeeperWnd->GetZipType();
memcpy(chData+sizeof(PL_ColorType), &ztZip, sizeof(PL_ZipType));
nRet = ::PL_SendSocketData(m_pPeeperWnd->m_sckClient[1],
chData, sizeof(PL_ColorType) + sizeof(PL_ZipType));
//讀取圖像大小
ZeroMemory(chData, 20);
nRet = ::PL_ReadSocketData(m_pPeeperWnd->m_sckClient[1], chData, 20, NULL);
if(nRet > 0)
{
int nSize = *((int*)(chData+1));
int cx = *((int*)(chData+1+sizeof(int)));
int cy = *((int*)(chData+1+sizeof(int)*2));
m_szScreen.cx = cx;
m_szScreen.cy = cy;
if(m_pPeeperWnd->m_hDib)
{
::GlobalFree(m_pPeeperWnd->m_hDib);
}
m_pPeeperWnd->m_hDib = (HDIB)::GlobalAlloc(GPTR, nSize);
LPBYTE lpData = (LPBYTE)::GlobalLock(m_pPeeperWnd->m_hDib);
int nRead = 0;
while(nRead < nSize)
{
int nBytes = ::PL_ReadSocketData(m_pPeeperWnd->m_sckClient[1],
(BYTE *)(lpData+nRead), PL_SOCKET_MAXBYTES, NULL);
nRead += (nBytes);
}
::GlobalUnlock(m_pPeeperWnd->m_hDib);
if(nRead == (int)::GlobalSize(m_pPeeperWnd->m_hDib))
{
::PostMessage(m_pPeeperWnd->GetSafeHwnd(),
PL_GET_DIB_MESSAGE, (WPARAM)PL_GET_DIB_MESSAGE, (LPARAM)ztZip);
}
}
}
TRACE(_T("Get data times:%d(ms).\nGet data sizes:%d(bytes).\n"),
::GetTickCount() - d1, ::GlobalSize(m_pPeeperWnd->m_hDib));
return nRet;
}
IMPLEMENT_DYNCREATE(CPeeperWnd, CScrollView)
CPeeperWnd::CPeeperWnd(CWnd *pNotifyWnd)
{
m_pNotifyWnd = pNotifyWnd;
m_strIP = _T("127.0.0.1");
m_uPort = 0;
m_hDib = NULL;
m_nBits = 4;
m_szScreen.cx = 1024;
m_szScreen.cy = 768;
m_nTimerID = PL_DIB_TIMERID;
m_nSpeed = PL_DIB_TIMER;
m_sckClient[0] = INVALID_SOCKET;
m_sckClient[1] = INVALID_SOCKET;
m_bIsDoing = FALSE;
ZeroMemory(m_chConnectInfo, 512);
strcpy(m_chConnectInfo, "Not Connected.");
m_nRetryTime = ::GetTickCount();
m_nLastUpdateTime = ::GetTickCount();
m_bIsPause = FALSE;
m_dwEnableFlag = PL_ENABLE_ALL;
m_ctColor = color_4;
m_ztZip = zip_none;
m_strState = _T("開始連接...");
m_nConnectTime = 0;
m_bIsConnect = FALSE;
}
CPeeperWnd::~CPeeperWnd()
{
ExitConnect();
::PL_TermSocket();
}
BEGIN_MESSAGE_MAP(CPeeperWnd, CScrollView)
//{{AFX_MSG_MAP(CPeeperWnd)
ON_WM_CREATE()
ON_WM_LBUTTONDBLCLK()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_RBUTTONDBLCLK()
ON_WM_RBUTTONDOWN()
ON_WM_RBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_TIMER()
ON_WM_DESTROY()
ON_WM_KEYDOWN()
ON_WM_KEYUP()
ON_WM_SYSKEYDOWN()
ON_WM_SYSKEYUP()
//}}AFX_MSG_MAP
ON_MESSAGE(PL_GET_DIB_MESSAGE, OnMsgPeeperThread)
ON_MESSAGE(PL_CONNECT_MESSAGE, OnMsgPeeperThread)
END_MESSAGE_MAP()
//返回偷窺者客戶端的版本
CString CPeeperWnd::GetClientVersion()
{
return PEEPER_SERVER_VER_15;
}
BOOL CPeeperWnd::Create(CString strIP, UINT uPort, CWnd * pParent, int nBits, UINT nTimer)
{
m_strIP = strIP;
m_uPort = uPort;
m_nBits = nBits;
m_nSpeed = nTimer;
LPCTSTR lpszPeeperClass = AfxRegisterWndClass(0);
BOOL bRet = CWnd::CreateEx(0, lpszPeeperClass, NULL,
WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
CRect(100, 100, 200, 150), pParent, NULL);
return bRet;
}
void CPeeperWnd::SetNotifyWnd(CWnd *pNotifyWnd)
{
m_pNotifyWnd = pNotifyWnd;
}
void CPeeperWnd::SetBits(int nBits)
{
m_nBits = nBits;
SendDIBBits();
}
void CPeeperWnd::SetUpdateSpeed(UINT nTimer)
{
m_nSpeed = nTimer;
KillTimer(m_nTimerID);
SetTimer(m_nTimerID, m_nSpeed, NULL);
}
int CPeeperWnd::SendData(BYTE *chData, int nLen, BYTE chFlag)
{
int nRet = INVALID_SOCKET;
if(m_sckClient[0] != INVALID_SOCKET)
{
nRet = ::PL_SendSocketData(m_sckClient[0], chData, nLen, chFlag);
}
return nRet;
}
int CPeeperWnd::ReadData(BYTE *chData, int nLen, BYTE *chFlag)
{
int nRet = INVALID_SOCKET;
if(m_sckClient[0] != INVALID_SOCKET)
{
nRet = ::PL_ReadSocketData(m_sckClient[0], chData, nLen, chFlag);
}
return nRet;
}
BOOL CPeeperWnd::CanSend()
{
return (m_sckClient[0] != INVALID_SOCKET) && (!m_bIsPause);
}
void CPeeperWnd::Pause()
{
m_bIsPause = TRUE;
}
BOOL CPeeperWnd::IsPause()
{
return m_bIsPause;
}
void CPeeperWnd::Resume()
{
m_bIsPause = FALSE;
}
DWORD CPeeperWnd::SetEnableFlag(DWORD dwFlag)
{
DWORD dwRet = m_dwEnableFlag;
m_dwEnableFlag = dwFlag;
return dwRet;
}
DWORD CPeeperWnd::SetEnableFlag(DWORD dwFlag, BOOL bSet)
{
DWORD dwRet = m_dwEnableFlag;
m_dwEnableFlag |= dwFlag;
if(!bSet)
{
m_dwEnableFlag ^= dwFlag;
}
return dwRet;
}
DWORD CPeeperWnd::GetEnableFlag()
{
return m_dwEnableFlag;
}
BOOL CPeeperWnd::GetEnableFlag(DWORD dwEvent)
{
return ((GetEnableFlag() & dwEvent) == dwEvent);
}
POINT CPeeperWnd::GetMousePoint(BYTE *chData)
{
POINT pt1, pt2, point;
::GetCursorPos(&pt1);
pt2 = GetOffsetPos();
pt1.x = pt1.x + pt2.x;
pt1.y = pt1.y + pt2.y;
CDC *pDC = GetDC();
GetDCOrgEx(pDC->GetSafeHdc(), &pt2);
point.x = pt1.x - pt2.x;
point.y = pt1.y - pt2.y;
if(AfxIsValidAddress(chData, 12))
{
int cx = point.x;
int cy = point.y;
ZeroMemory(chData, 12);
memcpy(chData, &cx, sizeof(int));
memcpy(chData+sizeof(int), &cy, sizeof(int));
}
return point;
}
CPoint CPeeperWnd::GetOffsetPos(BOOL bScroll)
{
CPoint pt = GetScrollPosition();
CPoint point = CPoint(0, 0);
CRect rect;
GetClientRect(&rect);
if(rect.Width() > m_szScreen.cx)
{
point.x = ((rect.Width() - m_szScreen.cx)/2);
}
if(rect.Height() > m_szScreen.cy)
{
point.y = ((rect.Height() - m_szScreen.cy)/2);
}
if(bScroll)
{
pt.x -= point.x;
pt.y -= point.y;
}
else
{
pt = point;
}
return pt;
}
int CPeeperWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CScrollView::OnCreate(lpCreateStruct) == -1)
return -1;
m_hPeeperThread.m_pPeeperWnd = this;
m_hPeeperThread.CreateThread();
ModifyStyleEx(WS_EX_CLIENTEDGE, 0);
return 0;
}
void CPeeperWnd::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
SetScrollSizes(MM_TEXT, CSize(0, 0));
#ifdef USE_DOC
if(m_pDocument)
{
m_strIP = ((CPeeperClientDoc *)m_pDocument)->m_strIP;
m_uPort = ((CPeeperClientDoc *)m_pDocument)->m_uPort;
m_nBits = ((CPeeperClientDoc *)m_pDocument)->m_nBits;
m_nSpeed = ((CPeeperClientDoc *)m_pDocument)->m_nSpeed;
CString str;
str.Format(_T("偷窺者窗口--[IP/Name:%s Port:%d]"), m_strIP, m_uPort);
m_pDocument->SetTitle(str);
}
#else
//不使用Doc類時,可以在這里增加參數的設置
#endif
if(!m_strIP.IsEmpty())
{
ConnectServer();
}
}
void CPeeperWnd::OnDraw(CDC* pDC)
{
CRect rect;
GetClientRect(&rect);
if((m_memDC.m_hDC == NULL) ||
(rect.right > m_szScreen.cx || rect.bottom > m_szScreen.cy))
{
rect.right = max(rect.right, m_szScreen.cx);
rect.bottom = max(rect.bottom, m_szScreen.cy);
pDC->FillSolidRect(rect, RGB(0, 100, 150));
}
if(m_memDC.m_hDC != NULL)
{
CPoint pt = GetOffsetPos(FALSE);
pDC->BitBlt(pt.x, pt.y, m_szScreen.cx, m_szScreen.cy, &m_memDC, 0, 0, SRCCOPY);
}
else
{
CFont font;
font.CreatePointFont(120, _T("宋體"));
CFont *old = pDC->SelectObject(&font);
CRect rc;
GetClientRect(&rc);
pDC->SetTextColor(RGB(255, 255, 255));
pDC->DrawText(m_strState, rc, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
pDC->SelectObject(old);
}
}
void CPeeperWnd::DrawDIB()
{
if(m_hDib && ::IsWindow(m_hWnd))
{
CClientDC dc(this);
if(m_hPeeperThread.m_szScreen.cx != m_szScreen.cx ||
m_hPeeperThread.m_szScreen.cy != m_szScreen.cy)
{
m_szScreen.cx = m_hPeeperThread.m_szScreen.cx;
m_szScreen.cy = m_hPeeperThread.m_szScreen.cy;
if(m_memDC.m_hDC)
{
m_memDC.DeleteDC();
}
m_memDC.CreateCompatibleDC(NULL);
CBitmap bmp;
bmp.CreateCompatibleBitmap(&dc, m_szScreen.cx, m_szScreen.cy);
m_memDC.SelectObject(&bmp);
SetScrollSizes(MM_TEXT, CSize(m_szScreen.cx, m_szScreen.cy));
Invalidate();
UpdateWindow();
}
else
{
if(!m_memDC.m_hDC)
{
m_memDC.CreateCompatibleDC(NULL);
CBitmap bmp;
CClientDC dc(this);
bmp.CreateCompatibleBitmap(&dc, m_szScreen.cx, m_szScreen.cy);
m_memDC.SelectObject(&bmp);
SetScrollSizes(MM_TEXT, CSize(m_szScreen.cx, m_szScreen.cy));
}
}
::PL_DrawDIB(m_memDC.m_hDC, NULL, m_hDib, NULL, NULL);
m_memDC.Draw3dRect(CRect(0, 0, m_szScreen.cx, m_szScreen.cy),
RGB(255, 255, 255), RGB(80, 80, 80));
#ifdef USE_DOC
//設置文件標題
CString str;
str.Format(_T("偷窺者窗口--[IP/Name:%s Port:%d, Refresh Time:%.3f(S/T)]"),
m_strIP, m_uPort, ((float)(::GetTickCount() - m_nLastUpdateTime))/1000.0f);
if(m_pDocument)
{
m_pDocument->SetTitle(str);
}
#endif
CPoint pt = GetOffsetPos();
dc.BitBlt(-pt.x, -pt.y, m_szScreen.cx, m_szScreen.cy, &m_memDC, 0, 0, SRCCOPY);
m_strState = _T("連接完畢");
}
m_bIsDoing = FALSE;
m_nLastUpdateTime = ::GetTickCount();
}
BOOL CPeeperWnd::PreTranslateMessage(MSG* pMsg)
{
return CScrollView::PreTranslateMessage(pMsg);
}
void CPeeperWnd::OnLButtonDblClk(UINT nFlags, CPoint point)
{
if(CanSend() && GetEnableFlag(PL_ENABLE_MOUSE_LDBLCLK))
{
BYTE chData[20];
GetMousePoint(chData);
BOOL bMouseMove = GetEnableFlag(PL_ENABLE_MOUSE_MOVE);
bMouseMove = !bMouseMove;
memcpy(chData+sizeof(int)*2, &bMouseMove, sizeof(BOOL));
int nRet = ::PL_SendSocketData(m_sckClient[0], chData,
sizeof(int)*2+sizeof(BOOL), PL_MOUSE_LDBLCLK);
if(nRet <= 0)
{
ExitConnect();
return ;
}
nRet = ::PL_ReadSocketData(m_sckClient[0], chData, 2, NULL);
return ;
}
CScrollView::OnLButtonDblClk(nFlags, point);
}
void CPeeperWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
if(CanSend() && GetEnableFlag(PL_ENABLE_MOUSE_LBUTTON))
{
BYTE chData[20];
GetMousePoint(chData);
BOOL bMouseMove = GetEnableFlag(PL_ENABLE_MOUSE_MOVE);
bMouseMove = !bMouseMove;
memcpy(chData+sizeof(int)*2, &bMouseMove, sizeof(BOOL));
int nRet = ::PL_SendSocketData(m_sckClient[0], chData,
sizeof(int)*2+sizeof(BOOL), PL_MOUSE_LBUTTONDOWN);
if(nRet <= 0)
{
ExitConnect();
return ;
}
nRet = ::PL_ReadSocketData(m_sckClient[0], chData, 2, NULL);
return ;
}
CScrollView::OnLButtonDown(nFlags, point);
}
void CPeeperWnd::OnLButtonUp(UINT nFlags, CPoint point)
{
if(CanSend() && GetEnableFlag(PL_ENABLE_MOUSE_LBUTTON))
{
BYTE chData[20];
GetMousePoint(chData);
BOOL bMouseMove = GetEnableFlag(PL_ENABLE_MOUSE_MOVE);
bMouseMove = !bMouseMove;
memcpy(chData+sizeof(int)*2, &bMouseMove, sizeof(BOOL));
int nRet = ::PL_SendSocketData(m_sckClient[0], chData,
sizeof(int)*2+sizeof(BOOL), PL_MOUSE_LBUTTONUP);
if(nRet <= 0)
{
ExitConnect();
return ;
}
nRet = ::PL_ReadSocketData(m_sckClient[0], chData, 2, NULL);
return ;
}
CScrollView::OnLButtonUp(nFlags, point);
}
void CPeeperWnd::OnRButtonDblClk(UINT nFlags, CPoint point)
{
if(CanSend() && GetEnableFlag(PL_ENABLE_MOUSE_RDBLCLK))
{
BYTE chData[20];
GetMousePoint(chData);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -