Fix/Improve: fix #267 and scale 4K desktop screen to 1080P

This commit is contained in:
yuanyuanxiang
2025-12-24 09:24:15 +01:00
parent 47ac8fb0d2
commit 2ee61a760f
20 changed files with 109 additions and 51 deletions

View File

@@ -388,7 +388,7 @@ DWORD WINAPI IOCPClient::WorkThreadProc(LPVOID lParam)
}
}
}
CloseHandle(This->m_hWorkThread);
SAFE_CLOSE_HANDLE(This->m_hWorkThread);
This->m_hWorkThread = NULL;
This->m_bWorkThread = S_STOP;
This->m_bIsRunning = FALSE;
@@ -514,7 +514,7 @@ VOID IOCPClient::OnServerReceiving(CBuffer* m_CompressedBuffer, char* szBuffer,
// 关闭压缩开关时SendWithSplit比较耗时。
BOOL IOCPClient::OnServerSending(const char* szBuffer, ULONG ulOriginalLength, PkgMask* mask) //Hello
{
AUTO_TICK(40, "");
AUTO_TICK(100, std::to_string(ulOriginalLength));
assert (ulOriginalLength > 0);
{
int cmd = BYTE(szBuffer[0]);

View File

@@ -15,7 +15,7 @@
#include <future>
#include <emmintrin.h> // SSE2
#include "X264Encoder.h"
#include "common/file_upload.h"
class ThreadPool
{
@@ -120,6 +120,9 @@ public:
int m_SendQuality; // 发送质量
LPBITMAPINFO m_BitmapInfor_Full; // BMP信息
LPBITMAPINFO m_BitmapInfor_Send; // 发送的BMP信息
BYTE *m_BmpZoomFirst; // 第一个缩放帧
BYTE *m_BmpZoomBuffer; // 缩放缓存
BYTE m_bAlgorithm; // 屏幕差异算法
int m_iScreenX; // 起始x坐标
@@ -145,6 +148,9 @@ public:
m_FrameID(0), m_GOP(DEFAULT_GOP), m_iScreenX(0), m_iScreenY(0), m_biBitCount(n),
m_SendKeyFrame(false), m_encoder(nullptr)
{
m_BitmapInfor_Send = nullptr;
m_BmpZoomBuffer = nullptr;
m_BmpZoomFirst = nullptr;
m_BlockNum = 8;
m_ThreadPool = new ThreadPool(m_BlockNum);
static auto monitors = GetAllMonitors();
@@ -201,6 +207,9 @@ public:
m_BitmapInfor_Full = NULL;
}
SAFE_DELETE_ARRAY(m_RectBuffer);
SAFE_DELETE(m_BitmapInfor_Send);
SAFE_DELETE_ARRAY(m_BmpZoomBuffer);
SAFE_DELETE_ARRAY(m_BmpZoomFirst);
for (int blockY = 0; blockY < m_BlockNum; ++blockY) {
SAFE_DELETE_ARRAY(m_BlockBuffers[blockY]);
@@ -471,8 +480,8 @@ public:
virtual int GetBMPSize() const
{
assert(m_BitmapInfor_Full);
return m_BitmapInfor_Full->bmiHeader.biSizeImage;
assert(m_BitmapInfor_Send);
return m_BitmapInfor_Send->bmiHeader.biSizeImage;
}
// SSE2 优化BGRA 转单通道灰度,一次处理 4 个像素,输出 4 字节
@@ -521,7 +530,7 @@ public:
bmpInfo->bmiHeader.biWidth = biWidth;
bmpInfo->bmiHeader.biHeight = biHeight;
bmpInfo->bmiHeader.biPlanes = 1;
bmpInfo->bmiHeader.biBitCount = 32;
bmpInfo->bmiHeader.biBitCount = biBitCount;
bmpInfo->bmiHeader.biCompression = BI_RGB;
bmpInfo->bmiHeader.biSizeImage = biWidth * biHeight * 4;
return bmpInfo;
@@ -563,7 +572,7 @@ public:
memcpy(data + offset, &++m_FrameID, sizeof(int));
offset += sizeof(int);
#if SCREENSPY_WRITE
WriteBitmap(m_BitmapInfor_Full, nextData, "GHOST", m_FrameID);
WriteBitmap(m_BitmapInfor_Send, nextData, "GHOST", m_FrameID);
#endif
#else
m_FrameID++;
@@ -572,20 +581,20 @@ public:
if (keyFrame) {
switch (algo) {
case ALGORITHM_DIFF: {
*ulNextSendLength = 1 + offset + m_BitmapInfor_Full->bmiHeader.biSizeImage;
memcpy(data + offset, nextData, m_BitmapInfor_Full->bmiHeader.biSizeImage);
*ulNextSendLength = 1 + offset + m_BitmapInfor_Send->bmiHeader.biSizeImage;
memcpy(data + offset, nextData, m_BitmapInfor_Send->bmiHeader.biSizeImage);
break;
}
case ALGORITHM_GRAY: {
*ulNextSendLength = 1 + offset + m_BitmapInfor_Full->bmiHeader.biSizeImage;
ToGray(data + offset, nextData, m_BitmapInfor_Full->bmiHeader.biSizeImage);
*ulNextSendLength = 1 + offset + m_BitmapInfor_Send->bmiHeader.biSizeImage;
ToGray(data + offset, nextData, m_BitmapInfor_Send->bmiHeader.biSizeImage);
break;
}
case ALGORITHM_H264: {
uint8_t* encoded_data = nullptr;
uint32_t encoded_size = 0;
int err = m_encoder->encode(nextData, 32, 4*m_BitmapInfor_Full->bmiHeader.biWidth,
m_ulFullWidth, m_ulFullHeight, &encoded_data, &encoded_size);
int err = m_encoder->encode(nextData, 32, 4* m_BitmapInfor_Send->bmiHeader.biWidth,
m_BitmapInfor_Send->bmiHeader.biWidth, m_BitmapInfor_Send->bmiHeader.biHeight, &encoded_data, &encoded_size);
if (err) {
return nullptr;
}
@@ -596,7 +605,7 @@ public:
default:
break;
}
memcpy(GetFirstBuffer(), nextData, m_BitmapInfor_Full->bmiHeader.biSizeImage);
memcpy(GetFirstBuffer(), nextData, m_BitmapInfor_Send->bmiHeader.biSizeImage);
} else {
switch (algo) {
case ALGORITHM_DIFF:
@@ -607,8 +616,8 @@ public:
case ALGORITHM_H264: {
uint8_t* encoded_data = nullptr;
uint32_t encoded_size = 0;
int err = m_encoder->encode(nextData, 32, 4 * m_BitmapInfor_Full->bmiHeader.biWidth,
m_ulFullWidth, m_ulFullHeight, &encoded_data, &encoded_size);
int err = m_encoder->encode(nextData, 32, 4 * m_BitmapInfor_Send->bmiHeader.biWidth,
m_BitmapInfor_Send->bmiHeader.biWidth, m_BitmapInfor_Send->bmiHeader.biHeight, &encoded_data, &encoded_size);
if (err) {
return nullptr;
}
@@ -646,7 +655,7 @@ public:
// 获取位图结构信息
virtual const LPBITMAPINFO& GetBIData() const
{
return m_BitmapInfor_Full;
return m_BitmapInfor_Send;
}
public: // 纯虚接口
@@ -656,4 +665,11 @@ public: // 纯虚接口
// 获取下一帧屏幕
virtual LPBYTE ScanNextScreen() = 0;
virtual LPBYTE scaleBitmap(LPBYTE target, LPBYTE bitmap) {
if (m_ulFullWidth == m_BitmapInfor_Send->bmiHeader.biWidth && m_ulFullHeight == m_BitmapInfor_Send->bmiHeader.biHeight)
return bitmap;
return ScaleBitmap(target, (uint8_t*)bitmap, m_ulFullWidth, m_ulFullHeight, m_BitmapInfor_Send->bmiHeader.biWidth,
m_BitmapInfor_Send->bmiHeader.biHeight);
}
};

View File

@@ -107,20 +107,22 @@ public:
d3dDevice->CreateTexture2D(&desc, NULL, &cpuTexture);
// 9. <20><>ʼ<EFBFBD><CABC> BITMAPINFO
m_BitmapInfor_Full = (BITMAPINFO*)new char[sizeof(BITMAPINFO)];
memset(m_BitmapInfor_Full, 0, sizeof(BITMAPINFO));
m_BitmapInfor_Full->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
m_BitmapInfor_Full->bmiHeader.biWidth = m_ulFullWidth;
m_BitmapInfor_Full->bmiHeader.biHeight = m_ulFullHeight;
m_BitmapInfor_Full->bmiHeader.biPlanes = 1;
m_BitmapInfor_Full->bmiHeader.biBitCount = 32;
m_BitmapInfor_Full->bmiHeader.biCompression = BI_RGB;
m_BitmapInfor_Full->bmiHeader.biSizeImage = m_ulFullWidth * m_ulFullHeight * 4;
m_BitmapInfor_Full = ConstructBitmapInfo(32, m_ulFullWidth, m_ulFullHeight);
m_BitmapInfor_Send = new BITMAPINFO(*m_BitmapInfor_Full);
if (m_bAlgorithm != ALGORITHM_H264) {
m_BitmapInfor_Send->bmiHeader.biWidth = min(1920, m_BitmapInfor_Send->bmiHeader.biWidth);
m_BitmapInfor_Send->bmiHeader.biHeight = min(1080, m_BitmapInfor_Send->bmiHeader.biHeight);
m_BitmapInfor_Send->bmiHeader.biSizeImage =
((m_BitmapInfor_Send->bmiHeader.biWidth * m_BitmapInfor_Send->bmiHeader.biBitCount + 31) / 32) *
4 * m_BitmapInfor_Send->bmiHeader.biHeight;
}
// 10. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m_FirstBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage + 1];
m_NextBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage + 1];
m_RectBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage * 2 + 12];
m_BmpZoomBuffer = new BYTE[m_BitmapInfor_Send->bmiHeader.biSizeImage * 2 + 12];
m_BmpZoomFirst = nullptr;
break;
} while (true);
@@ -145,13 +147,24 @@ public:
if (d3dDevice) d3dDevice->Release();
}
virtual LPBYTE scaleBitmap(LPBYTE target, LPBYTE bitmap) override {
if (m_ulFullWidth == m_BitmapInfor_Send->bmiHeader.biWidth && m_ulFullHeight == m_BitmapInfor_Send->bmiHeader.biHeight) {
memcpy(target, bitmap, m_BitmapInfor_Send->bmiHeader.biSizeImage);
return bitmap;
}
return ScaleBitmap(target, (uint8_t*)bitmap, m_ulFullWidth, m_ulFullHeight, m_BitmapInfor_Send->bmiHeader.biWidth,
m_BitmapInfor_Send->bmiHeader.biHeight);
}
LPBYTE GetFirstScreenData(ULONG* ulFirstScreenLength) override
{
int ret = CaptureFrame(m_FirstBuffer, ulFirstScreenLength, 1);
scaleBitmap(m_BmpZoomBuffer, m_FirstBuffer);
memcpy(m_FirstBuffer, m_BmpZoomBuffer, m_BitmapInfor_Send->bmiHeader.biSizeImage);
if (ret)
return nullptr;
if (m_bAlgorithm == ALGORITHM_GRAY) {
ToGray(1 + m_RectBuffer, 1 + m_RectBuffer, m_BitmapInfor_Full->bmiHeader.biSizeImage);
ToGray(1 + m_RectBuffer, 1 + m_RectBuffer, m_BitmapInfor_Send->bmiHeader.biSizeImage);
}
m_FirstBuffer[0] = TOKEN_FIRSTSCREEN;
return m_FirstBuffer;
@@ -161,6 +174,8 @@ public:
{
ULONG ulNextScreenLength = 0;
int ret = CaptureFrame(m_NextBuffer, &ulNextScreenLength, 0);
scaleBitmap(m_BmpZoomBuffer, m_NextBuffer);
memcpy(m_NextBuffer, m_BmpZoomBuffer, m_BitmapInfor_Send->bmiHeader.biSizeImage);
if (ret)
return nullptr;

View File

@@ -349,7 +349,7 @@ DWORD WINAPI CScreenManager::WorkThreadProc(LPVOID lParam)
if (frames == ++c1) { // 连续一定次数耗时长
s0 = (s0 <= sleep*4) ? s0*alpha : s0;
c1 = 0;
#ifdef _DEBUG
#if _DEBUG
if (1000./s0>1.0)
Mprintf("[+]SendScreen Span= %dms, s0= %f, fps= %f\n", span, s0, 1000./s0);
#endif
@@ -359,7 +359,7 @@ DWORD WINAPI CScreenManager::WorkThreadProc(LPVOID lParam)
if (frames == ++c2) { // 连续一定次数耗时短
s0 = (s0 >= sleep/4) ? s0/alpha : s0;
c2 = 0;
#ifdef _DEBUG
#if _DEBUG
if (1000./s0<20.0)
Mprintf("[-]SendScreen Span= %dms, s0= %f, fps= %f\n", span, s0, 1000./s0);
#endif
@@ -457,7 +457,7 @@ VOID CScreenManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
{
switch(szBuffer[0]) {
case COMMAND_BYE: {
Mprintf("[CScreenManager] Received BYE\n");
Mprintf("[CScreenManager] Received BYE: %s\n", ToPekingTimeAsString(0).c_str());
m_bIsWorking = FALSE;
m_ClientObject->StopRunning();
break;
@@ -634,6 +634,7 @@ VOID CScreenManager::SendFirstScreen()
const char* CScreenManager::GetNextScreen(ULONG &ulNextSendLength)
{
AUTO_TICK(100, "GetNextScreen");
LPVOID NextScreenData = m_ScreenSpyObject->GetNextScreenData(&ulNextSendLength);
if (ulNextSendLength == 0 || NextScreenData == NULL) {
@@ -645,6 +646,7 @@ const char* CScreenManager::GetNextScreen(ULONG &ulNextSendLength)
VOID CScreenManager::SendNextScreen(const char* szBuffer, ULONG ulNextSendLength)
{
AUTO_TICK(100, std::to_string(ulNextSendLength));
m_ClientObject->Send2Server(szBuffer, ulNextSendLength);
}

View File

@@ -16,17 +16,16 @@ CScreenSpy::CScreenSpy(ULONG ulbiBitCount, BYTE algo, BOOL vDesk, int gop, BOOL
{
m_GOP = gop;
m_BitmapInfor_Full = new BITMAPINFO();
memset(m_BitmapInfor_Full, 0, sizeof(BITMAPINFO));
BITMAPINFOHEADER* BitmapInforHeader = &(m_BitmapInfor_Full->bmiHeader);
BitmapInforHeader->biSize = sizeof(BITMAPINFOHEADER);
BitmapInforHeader->biWidth = m_ulFullWidth; //1080
BitmapInforHeader->biHeight = m_ulFullHeight; //1920
BitmapInforHeader->biPlanes = 1;
BitmapInforHeader->biBitCount = ulbiBitCount; //ͨ<><CDA8>Ϊ32
BitmapInforHeader->biCompression = BI_RGB;
BitmapInforHeader->biSizeImage =
((BitmapInforHeader->biWidth * BitmapInforHeader->biBitCount + 31) / 32) * 4 * BitmapInforHeader->biHeight;
m_BitmapInfor_Full = ConstructBitmapInfo(ulbiBitCount, m_ulFullWidth, m_ulFullHeight);
m_BitmapInfor_Send = new BITMAPINFO(*m_BitmapInfor_Full);
if (m_bAlgorithm != ALGORITHM_H264) {
m_BitmapInfor_Send->bmiHeader.biWidth = min(1920, m_BitmapInfor_Send->bmiHeader.biWidth);
m_BitmapInfor_Send->bmiHeader.biHeight = min(1080, m_BitmapInfor_Send->bmiHeader.biHeight);
m_BitmapInfor_Send->bmiHeader.biSizeImage =
((m_BitmapInfor_Send->bmiHeader.biWidth * m_BitmapInfor_Send->bmiHeader.biBitCount + 31) / 32) *
4 * m_BitmapInfor_Send->bmiHeader.biHeight;
}
m_hDeskTopDC = GetDC(NULL);
@@ -42,6 +41,9 @@ CScreenSpy::CScreenSpy(ULONG ulbiBitCount, BYTE algo, BOOL vDesk, int gop, BOOL
::SelectObject(m_hDiffMemDC, m_DiffBitmapHandle);
m_RectBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage * 2 + 12];
m_BmpZoomBuffer = new BYTE[m_BitmapInfor_Send->bmiHeader.biSizeImage * 2 + 12];
m_BmpZoomFirst = new BYTE[m_BitmapInfor_Send->bmiHeader.biSizeImage * 2 + 12];
m_FirstBuffer = scaleBitmap(m_BmpZoomFirst, m_FirstBuffer);
m_bVirtualPaint = vDesk;
m_data.Create(m_hDeskTopDC, m_iScreenX, m_iScreenY, m_ulFullWidth, m_ulFullHeight);
@@ -87,11 +89,12 @@ LPBYTE CScreenSpy::GetFirstScreenData(ULONG* ulFirstScreenLength)
{
ScanScreen(m_hFullMemDC, m_hDeskTopDC, m_ulFullWidth, m_ulFullHeight);
m_RectBuffer[0] = TOKEN_FIRSTSCREEN;
memcpy(1 + m_RectBuffer, m_BitmapData_Full, m_BitmapInfor_Full->bmiHeader.biSizeImage);
LPBYTE bmp = scaleBitmap(m_BmpZoomBuffer, (LPBYTE)m_BitmapData_Full);
memcpy(1 + m_RectBuffer, bmp, m_BitmapInfor_Send->bmiHeader.biSizeImage);
if (m_bAlgorithm == ALGORITHM_GRAY) {
ToGray(1 + m_RectBuffer, 1 + m_RectBuffer, m_BitmapInfor_Full->bmiHeader.biSizeImage);
ToGray(1 + m_RectBuffer, 1 + m_RectBuffer, m_BitmapInfor_Send->bmiHeader.biSizeImage);
}
*ulFirstScreenLength = m_BitmapInfor_Full->bmiHeader.biSizeImage;
*ulFirstScreenLength = m_BitmapInfor_Send->bmiHeader.biSizeImage;
return m_RectBuffer; //<2F>ڴ<EFBFBD>
}

View File

@@ -126,12 +126,12 @@ public:
const LPBITMAPINFO& GetBIData() const
{
return m_BitmapInfor_Full;
return m_BitmapInfor_Send;
}
ULONG GetFirstScreenLength() const
{
return m_BitmapInfor_Full->bmiHeader.biSizeImage;
return m_BitmapInfor_Send->bmiHeader.biSizeImage;
}
static BOOL PaintWindow(HWND hWnd, EnumHwndsPrintData* data)
@@ -194,7 +194,8 @@ public:
virtual LPBYTE ScanNextScreen()
{
ScanScreen(m_hDiffMemDC, m_hDeskTopDC, m_ulFullWidth, m_ulFullHeight);
return (LPBYTE)m_DiffBitmapData_Full;
LPBYTE bmp = scaleBitmap(m_BmpZoomBuffer, (LPBYTE)m_DiffBitmapData_Full);
return (LPBYTE)bmp;
}
VOID ScanScreen(HDC hdcDest, HDC hdcSour, ULONG ulWidth, ULONG ulHeight);

View File

@@ -61,5 +61,7 @@
#define SAFE_DELETE_AR(p) if(NULL !=(p)){ delete[] (p);(p) = NULL;}
#endif
#define SAFE_CLOSE_HANDLE(h) do{if((h)!=NULL&&(h)!=INVALID_HANDLE_VALUE){CloseHandle(h);(h)=NULL;}}while(0)
#include "common/logger.h"
#include "common/locker.h"

View File

@@ -31,3 +31,5 @@ int FileBatchTransferWorker(const std::vector<std::string>& files, const std::st
void* user, OnTransform f, OnFinish finish, const std::string& hash, const std::string& hmac);
int RecvFileChunk(char* buf, size_t len, void* user, OnFinish f, const std::string& hash, const std::string& hmac);
uint8_t* ScaleBitmap(uint8_t* dst, const uint8_t* src, int srcW, int srcH, int dstW, int dstH);

View File

@@ -164,7 +164,7 @@ public:
#define Sleep_m(ms) { Sleep(ms); }
// 以步长n毫秒在条件C下等待T秒(n是步长必须能整除1000)
#define WAIT_n(C, T, n) { int s=(1000*(T))/(n); s=max(s,1); do{Sleep(n);}while((C)&&(--s)); }
#define WAIT_n(C, T, n) { int s=(1000*(T))/(n); s=max(s,1); while((C)&&(s--))Sleep(n); }
// 在条件C成立时等待T秒(步长10ms)
#define WAIT(C, T) { WAIT_n(C, T, 10); }

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -2079,7 +2079,9 @@ void CMy2015RemoteDlg::OnMainSet()
m_frpStatus = STATUS_RUN;
}
if (use && use_new && m_hFRPThread == NULL) {
#ifdef _WIN64
MessageBoxA("FRP代理服务异常需要重启当前应用程序进行重试。", "提示", MB_ICONINFORMATION);
#endif
}
int m = atoi(THIS_CFG.GetStr("settings", "ReportInterval", "5").c_str());
int n = THIS_CFG.GetInt("settings", "SoftwareDetect");
@@ -2679,6 +2681,7 @@ LRESULT CMy2015RemoteDlg::OnUserOfflineMsg(WPARAM wParam, LPARAM lParam)
}
DialogBase* p = (DialogBase*)wParam;
if (p && ::IsWindow(p->GetSafeHwnd()) && p->ShouldReconnect()) {
::PostMessageA(p->GetSafeHwnd(), WM_DISCONNECT, 0, 0);
return S_OK;
}

View File

@@ -120,18 +120,20 @@ public:
bool m_bIsClosed;
bool m_bIsProcessing;
HICON m_hIcon;
BOOL m_bConnected;
CDialogBase(UINT nIDTemplate, CWnd* pParent, Server* pIOCPServer, CONTEXT_OBJECT* pContext, int nIcon) :
m_bIsClosed(false), m_bIsProcessing(false),
m_ContextObject(pContext),
m_iocpServer(pIOCPServer),
CDialog(nIDTemplate, pParent)
{
m_bConnected = TRUE;
m_IPAddress = pContext->GetPeerName().c_str();
m_hIcon = nIcon > 0 ? LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(nIcon)) : NULL;
}
int UpdateContext(CONTEXT_OBJECT* pContext)
{
m_bConnected = TRUE;
m_ContextObject = pContext;
m_iocpServer = pContext->GetServer();
m_ContextObject->hDlg = this;
@@ -163,6 +165,7 @@ public:
}
void OnClose()
{
m_bConnected = FALSE;
m_bIsClosed = true;
while (m_bIsProcessing)
Sleep(200);
@@ -194,6 +197,9 @@ public:
}
BOOL SayByeBye()
{
if (!m_bConnected) return FALSE;
Mprintf("%s SayByeBye: %s\n", ToPekingTimeAsString(0).c_str(), m_ContextObject->GetPeerName().c_str());
BYTE bToken = COMMAND_BYE;
return m_ContextObject->Send2Client(&bToken, 1);
}

View File

@@ -166,6 +166,7 @@ BEGIN_MESSAGE_MAP(CScreenSpyDlg, CDialog)
ON_WM_ACTIVATE()
ON_WM_TIMER()
ON_COMMAND(ID_EXIT_FULLSCREEN, &CScreenSpyDlg::OnExitFullscreen)
ON_MESSAGE(WM_DISCONNECT, &CScreenSpyDlg::OnDisconnect)
END_MESSAGE_MAP()
@@ -272,7 +273,7 @@ VOID CScreenSpyDlg::OnClose()
m_aviFile = "";
m_aviStream.Close();
}
if (SayByeBye()) Sleep(500);
if (ShouldReconnect() && SayByeBye()) Sleep(500);
CancelIO();
// 恢复鼠标状态
SetClassLongPtr(m_hWnd, GCLP_HCURSOR, (LONG_PTR)LoadCursor(NULL, IDC_ARROW));
@@ -294,6 +295,11 @@ VOID CScreenSpyDlg::OnClose()
DialogBase::OnClose();
}
afx_msg LRESULT CScreenSpyDlg::OnDisconnect(WPARAM wParam, LPARAM lParam) {
m_bConnected = FALSE;
return S_OK;
}
VOID CScreenSpyDlg::OnReceiveComplete()
{
if (m_bIsClosed) return;
@@ -746,7 +752,7 @@ BOOL CScreenSpyDlg::PreTranslateMessage(MSG* pMsg)
void CScreenSpyDlg::SendScaledMouseMessage(MSG* pMsg, bool makeLP)
{
if (!m_bIsCtrl)
if (!m_bIsCtrl || !m_bConnected)
return;
MYMSG msg(*pMsg);

View File

@@ -123,6 +123,7 @@ public:
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
afx_msg LRESULT OnDisconnect(WPARAM wParam, LPARAM lParam);
afx_msg void OnExitFullscreen() {
LeaveFullScreen();
}

View File

@@ -92,6 +92,7 @@
#define WM_ANTI_BLACKSCREEN WM_USER+3029
#define WM_UPDATE_ACTIVEWND WM_USER+3030
#define WM_SHOWNOTIFY WM_USER+3031
#define WM_DISCONNECT WM_USER+3032
#ifdef _UNICODE
#if defined _M_IX86