diff --git a/server/2015Remote/HideScreenSpyDlg.cpp b/server/2015Remote/HideScreenSpyDlg.cpp index 688ceb3..12d1fab 100644 --- a/server/2015Remote/HideScreenSpyDlg.cpp +++ b/server/2015Remote/HideScreenSpyDlg.cpp @@ -90,11 +90,33 @@ BEGIN_MESSAGE_MAP(CHideScreenSpyDlg, CDialog) ON_WM_PAINT() ON_WM_TIMER() ON_WM_CLOSE() + ON_WM_SETCURSOR() END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CHideScreenSpyDlg message handlers +BOOL CHideScreenSpyDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) +{ + // 查看模式(未开启远程控制):客户区显示禁止图标;标题栏及系统按钮保持正常箭头, + // 便于拖动窗口或通过标题栏右键菜单开启远程控制。 + // 这里按窗口自身状态判断,避免用窗口类光标(GCLP_HCURSOR)时被同类的其他对话框实例 + // 共享串扰——第二个对话框切到查看模式后,第一个控制中的对话框也被误显示成禁止图标。 + if (!m_bIsCtrl && nHitTest == HTCLIENT) { + ::SetCursor(LoadCursor(NULL, IDC_NO)); + return TRUE; + } + if (!m_bIsCtrl && + (nHitTest == HTCAPTION || nHitTest == HTSYSMENU || nHitTest == HTMENU || + nHitTest == HTCLOSE || nHitTest == HTMINBUTTON || nHitTest == HTMAXBUTTON || + nHitTest == HTHELP)) { + ::SetCursor(LoadCursor(NULL, IDC_ARROW)); + return TRUE; + } + // 控制模式:交父类处理,显示窗口类光标(远程光标形状) + return __super::OnSetCursor(pWnd, nHitTest, message); +} + void CHideScreenSpyDlg::OnClose() { if (!m_aviFile.IsEmpty()) { @@ -165,7 +187,6 @@ BOOL CHideScreenSpyDlg::OnInitDialog() // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon - SetClassLongPtr(m_hWnd, GCLP_HCURSOR, (LONG_PTR)LoadCursor(NULL, IDC_NO)); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { pSysMenu->AppendMenuSeparator(MF_SEPARATOR); @@ -214,15 +235,7 @@ BOOL CHideScreenSpyDlg::OnInitDialog() } // TODO: Add extra initialization here - m_hRemoteCursor = LoadCursor(NULL, IDC_ARROW); - ICONINFO CursorInfo; - ::GetIconInfo(m_hRemoteCursor, &CursorInfo); pSysMenu->CheckMenuItem(IDM_CONTROL, m_bIsCtrl ? MF_CHECKED : MF_UNCHECKED); - SetClassLongPtr(m_hWnd, GCLP_HCURSOR, (LONG_PTR)m_hRemoteCursor); - if (CursorInfo.hbmMask != NULL) - ::DeleteObject(CursorInfo.hbmMask); - if (CursorInfo.hbmColor != NULL) - ::DeleteObject(CursorInfo.hbmColor); // 初始化窗口大小结构 m_hFullDC = ::GetDC(m_hWnd); m_hFullMemDC = CreateCompatibleDC(m_hFullDC); @@ -440,11 +453,6 @@ void CHideScreenSpyDlg::OnSysCommand(UINT nID, LPARAM lParam) case IDM_CONTROL: { m_bIsCtrl = !m_bIsCtrl; pSysMenu->CheckMenuItem(IDM_CONTROL, m_bIsCtrl ? MF_CHECKED : MF_UNCHECKED); - - if (m_bIsCtrl) { - SetClassLongPtr(m_hWnd, GCLP_HCURSOR, (LONG_PTR)m_hRemoteCursor); - } else - SetClassLongPtr(m_hWnd, GCLP_HCURSOR, (LONG_PTR)LoadCursor(NULL, IDC_NO)); } break; diff --git a/server/2015Remote/HideScreenSpyDlg.h b/server/2015Remote/HideScreenSpyDlg.h index 782bd23..92c5e2b 100644 --- a/server/2015Remote/HideScreenSpyDlg.h +++ b/server/2015Remote/HideScreenSpyDlg.h @@ -59,6 +59,7 @@ public: afx_msg void OnPaint(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam); @@ -75,7 +76,6 @@ protected: HBITMAP m_BitmapHandle; LPVOID m_BitmapData_Full; LPBITMAPINFO m_BitmapInfor_Full; - HCURSOR m_hRemoteCursor; CCursorInfo m_CursorInfo; BOOL m_bIsFirst; BOOL m_bIsCtrl; diff --git a/server/2015Remote/ScreenSpyDlg.cpp b/server/2015Remote/ScreenSpyDlg.cpp index c9c7515..1f67618 100644 --- a/server/2015Remote/ScreenSpyDlg.cpp +++ b/server/2015Remote/ScreenSpyDlg.cpp @@ -843,13 +843,9 @@ BOOL CScreenSpyDlg::OnInitDialog() m_ClientCursorPos.y = 0; m_bCursorIndex = 0; - m_hRemoteCursor = LoadCursor(NULL, IDC_ARROW); - ICONINFO CursorInfo; - ::GetIconInfo(m_hRemoteCursor, &CursorInfo); SysMenu->CheckMenuItem(IDM_CONTROL, m_bIsCtrl ? MF_CHECKED : MF_UNCHECKED); SysMenu->CheckMenuItem(IDM_ADAPTIVE_SIZE, m_bAdaptiveSize ? MF_CHECKED : MF_UNCHECKED); SysMenu->CheckMenuItem(IDM_TRACE_CURSOR, m_bIsTraceCursor ? MF_CHECKED : MF_UNCHECKED); - SetClassLongPtr(m_hWnd, GCLP_HCURSOR, m_bIsCtrl ? (LONG_PTR)m_hRemoteCursor : (LONG_PTR)LoadCursor(NULL, IDC_NO)); ShowScrollBar(SB_BOTH, !m_bAdaptiveSize); // 设置合理的"正常"窗口大小,显示在主程序所在的显示器上 @@ -1990,7 +1986,23 @@ void CScreenSpyDlg::OnPaint() BOOL CScreenSpyDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { - if ((m_bIsCtrl && m_Settings.RemoteCursor) && nHitTest == HTCLIENT) { + // 查看模式(未开启远程控制):客户区显示禁止图标;标题栏及系统按钮保持正常箭头, + // 便于拖动窗口或通过标题栏右键菜单开启远程控制。 + // 这里按窗口自身状态判断,避免用窗口类光标(GCLP_HCURSOR)时被同类的其他对话框实例 + // 共享串扰——打开第二个未控制的对话框后,第一个已控制的对话框也被误显示成禁止图标。 + if (!m_bIsCtrl && nHitTest == HTCLIENT) { + ::SetCursor(LoadCursor(NULL, IDC_NO)); + return TRUE; + } + if (!m_bIsCtrl && + (nHitTest == HTCAPTION || nHitTest == HTSYSMENU || nHitTest == HTMENU || + nHitTest == HTCLOSE || nHitTest == HTMINBUTTON || nHitTest == HTMAXBUTTON || + nHitTest == HTHELP)) { + ::SetCursor(LoadCursor(NULL, IDC_ARROW)); + return TRUE; + } + // 控制模式:保持原有逻辑——显示远程光标时客户区隐藏本地物理光标,否则交父类显示远程形状 + if (m_bIsCtrl && m_Settings.RemoteCursor && nHitTest == HTCLIENT) { ::SetCursor(NULL); // 只要在客户区,始终隐藏系统光标 return TRUE; // 告诉 Windows 我们处理过了 } @@ -2084,7 +2096,6 @@ void CScreenSpyDlg::OnSysCommand(UINT nID, LPARAM lParam) } SysMenu->CheckMenuItem(IDM_CONTROL, m_bIsCtrl ? MF_CHECKED : MF_UNCHECKED); SysMenu->CheckMenuItem(IDM_TRACE_CURSOR, m_bIsTraceCursor ? MF_CHECKED : MF_UNCHECKED); - SetClassLongPtr(m_hWnd, GCLP_HCURSOR, m_bIsCtrl ? (LONG_PTR)m_hRemoteCursor : (LONG_PTR)LoadCursor(NULL, IDC_NO)); // 控制模式:禁用本地 IME;查看模式:启用本地 IME ImmAssociateContext(m_hWnd, m_bIsCtrl ? NULL : m_hOldIMC); break; @@ -3473,9 +3484,6 @@ void CScreenSpyDlg::OnMouseMove(UINT nFlags, CPoint point) // 关键:在控制模式下,强制设置光标为空,隐藏本地物理箭头 ::SetCursor(NULL); } - } else if (!m_bMouseTracking) { - m_bMouseTracking = true; - SetClassLongPtr(m_hWnd, GCLP_HCURSOR, m_bIsCtrl ? (LONG_PTR)m_hRemoteCursor : (LONG_PTR)LoadCursor(NULL, IDC_NO)); } __super::OnMouseMove(nFlags, point); @@ -3484,9 +3492,6 @@ void CScreenSpyDlg::OnMouseMove(UINT nFlags, CPoint point) void CScreenSpyDlg::OnMouseLeave() { CWnd::OnMouseLeave(); - - m_bMouseTracking = false; - SetClassLongPtr(m_hWnd, GCLP_HCURSOR, m_bIsCtrl ? (LONG_PTR)m_hRemoteCursor : (LONG_PTR)LoadCursor(NULL, IDC_NO)); } void CScreenSpyDlg::OnKillFocus(CWnd* pNewWnd) @@ -3566,7 +3571,6 @@ void CScreenSpyDlg::UpdateCtrlStatus(BOOL ctrl) Invalidate(FALSE); } } - SetClassLongPtr(m_hWnd, GCLP_HCURSOR, m_bIsCtrl ? (LONG_PTR)m_hRemoteCursor : (LONG_PTR)LoadCursor(NULL, IDC_NO)); // 控制模式:禁用本地 IME;查看模式:启用本地 IME ImmAssociateContext(m_hWnd, m_bIsCtrl ? NULL : m_hOldIMC); CMenu* SysMenu = GetSystemMenu(FALSE); diff --git a/server/2015Remote/ScreenSpyDlg.h b/server/2015Remote/ScreenSpyDlg.h index f70e42e..3f9e2ba 100644 --- a/server/2015Remote/ScreenSpyDlg.h +++ b/server/2015Remote/ScreenSpyDlg.h @@ -274,13 +274,11 @@ public: clock_t m_lastMouseMove; // 鼠标移动时间 POINT m_lastMousePoint;// 上次鼠标位置 BOOL m_bAdaptiveSize = TRUE; - HCURSOR m_hRemoteCursor = NULL; HCURSOR m_hCustomCursor = NULL; // 缓存的自定义光标 DWORD m_dwCustomCursorHash = 0; // 当前自定义光标哈希 CRect m_CRect; double m_wZoom=1, m_hZoom=1; int m_offsetX=0, m_offsetY=0; // 自适应模式黑边偏移(像素) - bool m_bMouseTracking = false; // 自适应黑边合成缓冲(按窗口尺寸缓存,避免每帧分配 GDI 资源) HDC m_hComposeDC = NULL;