diff --git a/server/2015Remote/2015Remote.rc b/server/2015Remote/2015Remote.rc index 8865c9f..b151db5 100644 Binary files a/server/2015Remote/2015Remote.rc and b/server/2015Remote/2015Remote.rc differ diff --git a/server/2015Remote/ScreenSpyDlg.cpp b/server/2015Remote/ScreenSpyDlg.cpp index f31f33d..0f4bb7f 100644 --- a/server/2015Remote/ScreenSpyDlg.cpp +++ b/server/2015Remote/ScreenSpyDlg.cpp @@ -741,6 +741,9 @@ BOOL CScreenSpyDlg::PreTranslateMessage(MSG* pMsg) if (pMsg->wParam != VK_LWIN && pMsg->wParam != VK_RWIN) { SendScaledMouseMessage(pMsg, true); } + if (pMsg->message == WM_SYSKEYDOWN && pMsg->wParam == VK_F4) { + return TRUE; // 屏蔽 Alt + F4 + } if (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE) return TRUE;// 屏蔽Enter和ESC关闭对话 break; @@ -987,7 +990,7 @@ void CScreenSpyDlg::EnterFullScreen() // 7. 标记全屏模式 m_bFullScreen = true; - SetTimer(1, 100, NULL); + SetTimer(1, 50, NULL); } } diff --git a/server/2015Remote/ToolbarDlg.cpp b/server/2015Remote/ToolbarDlg.cpp index 3baadde..55d33d9 100644 --- a/server/2015Remote/ToolbarDlg.cpp +++ b/server/2015Remote/ToolbarDlg.cpp @@ -22,7 +22,9 @@ void CToolbarDlg::DoDataExchange(CDataExchange* pDX) BEGIN_MESSAGE_MAP(CToolbarDlg, CDialogEx) ON_BN_CLICKED(IDC_BTN_EXIT_FULLSCREEN, &CToolbarDlg::OnBnClickedExitFullscreen) ON_BN_CLICKED(CONTROL_BTN_ID, &CToolbarDlg::OnBnClickedCtrl) + ON_BN_CLICKED(IDC_BTN_MINIMIZE, &CToolbarDlg::OnBnClickedMinimize) ON_BN_CLICKED(IDC_BTN_CLOSE, &CToolbarDlg::OnBnClickedClose) + ON_WM_ERASEBKGND() END_MESSAGE_MAP() void CToolbarDlg::CheckMousePosition() @@ -30,24 +32,44 @@ void CToolbarDlg::CheckMousePosition() CPoint pt; GetCursorPos(&pt); - if (pt.y <= 2) { + int cxScreen = GetSystemMetrics(SM_CXSCREEN); + + // 计算按钮群的总宽度 (4个按钮 + 间距) + int totalWidth = 80 * 4 + 10 * 3; + int leftBound = (cxScreen - totalWidth) / 2; + int rightBound = (cxScreen + totalWidth) / 2; + + // 只有在按钮对应的横向范围内从下往上扫到顶端才弹出 + if (pt.y <= 2 && pt.x >= leftBound && pt.x <= rightBound) { if (!m_bVisible) SlideIn(); } - else if (pt.y > m_nHeight + 20) { + // 鼠标离开工具栏范围(或者在工具栏左右两侧)时隐藏 + else if (pt.y > m_nHeight + 10 || pt.x < leftBound - 50 || pt.x > rightBound + 50) { if (m_bVisible) SlideOut(); } } void CToolbarDlg::SlideIn() { + if (m_bVisible) return; m_bVisible = true; - ShowWindow(SW_SHOWNOACTIVATE); + // 获取屏幕宽度,确保位置正确 int cx = GetSystemMetrics(SM_CXSCREEN); - for (int y = -m_nHeight; y <= 0; y += 8) { - SetWindowPos(&wndTopMost, 0, y, cx, m_nHeight, SWP_NOACTIVATE); - Sleep(100); + + // 动画:从 -m_nHeight 移动到 0 + // 步进加大(10像素),等待时间极短(10-15ms) + for (int i = -m_nHeight; i <= 0; i += 10) { + // 使用 SWP_NOACTIVATE 极其重要,防止夺取焦点导致的界面闪烁 + SetWindowPos(&wndTopMost, 0, i, cx, m_nHeight, SWP_SHOWWINDOW | SWP_NOACTIVATE); + + // 强制窗口立即重绘按钮,否则背景会是一片漆黑直到动画结束 + UpdateWindow(); + + Sleep(10); // 10ms 是人眼感知的流畅极限 } + + // 确保最终位置精准在 0 SetWindowPos(&wndTopMost, 0, 0, cx, m_nHeight, SWP_NOACTIVATE); } @@ -56,7 +78,7 @@ void CToolbarDlg::SlideOut() int cx = GetSystemMetrics(SM_CXSCREEN); for (int y = 0; y >= -m_nHeight; y -= 8) { SetWindowPos(&wndTopMost, 0, y, cx, m_nHeight, SWP_NOACTIVATE); - Sleep(100); + Sleep(50); } ShowWindow(SW_HIDE); m_bVisible = false; @@ -85,30 +107,54 @@ BOOL CToolbarDlg::OnInitDialog() { CDialogEx::OnInitDialog(); - // 设置分层窗口样式 + // 1. 设置分层窗口样式 ModifyStyleEx(0, WS_EX_LAYERED); - // 设置透明度 (0-255) - SetLayeredWindowAttributes(0, 100, LWA_ALPHA); + // 2. 关键设置:使用 LWA_COLORKEY 和 LWA_ALPHA 混合 + // RGB(255, 0, 255) 是品红色,我们将它定义为“透明色” + // 255 代表按钮部分完全不透明(如果你想要按钮也半透明,可以改成 150-200) + SetLayeredWindowAttributes(RGB(255, 0, 255), 255, LWA_COLORKEY | LWA_ALPHA); - // 按钮居中代码... + // --- 按钮布局代码 (保持不变) --- int cx = GetSystemMetrics(SM_CXSCREEN); int btnWidth = 80; int btnHeight = 28; int btnSpacing = 10; - int totalWidth = btnWidth * 3 + btnSpacing * 2; + int totalWidth = btnWidth * 4 + btnSpacing * 3; int startX = (cx - totalWidth) / 2; int y = (m_nHeight - btnHeight) / 2; - GetDlgItem(IDC_BTN_EXIT_FULLSCREEN)->SetWindowPos(NULL, - startX, y, btnWidth, btnHeight, SWP_NOZORDER); - GetDlgItem(CONTROL_BTN_ID)->SetWindowPos(NULL, - startX + btnWidth + btnSpacing, y, btnWidth, btnHeight, SWP_NOZORDER); - GetDlgItem(IDC_BTN_CLOSE)->SetWindowPos(NULL, - startX + (btnWidth + btnSpacing) * 2, y, btnWidth, btnHeight, SWP_NOZORDER); + GetDlgItem(IDC_BTN_EXIT_FULLSCREEN)->SetWindowPos(NULL, startX, y, btnWidth, btnHeight, SWP_NOZORDER); + int nextX = startX + btnWidth + btnSpacing; + GetDlgItem(CONTROL_BTN_ID)->SetWindowPos(NULL, nextX, y, btnWidth, btnHeight, SWP_NOZORDER); + + nextX += btnWidth + btnSpacing; + GetDlgItem(IDC_BTN_MINIMIZE)->SetWindowPos(NULL, nextX, y, btnWidth, btnHeight, SWP_NOZORDER); // 放置最小化按钮 + + nextX += btnWidth + btnSpacing; + GetDlgItem(IDC_BTN_CLOSE)->SetWindowPos(NULL, nextX, y, btnWidth, btnHeight, SWP_NOZORDER); + + // 设置控制按钮文本 CScreenSpyDlg* pParent = (CScreenSpyDlg*)GetParent(); GetDlgItem(CONTROL_BTN_ID)->SetWindowTextA(pParent->m_bIsCtrl ? "暂停控制" : "控制屏幕"); return TRUE; } + +void CToolbarDlg::OnBnClickedMinimize() +{ + // 隐藏工具栏自身并最小化父窗口 + ShowWindow(SW_HIDE); + m_bVisible = false; + GetParent()->ShowWindow(SW_MINIMIZE); +} + +BOOL CToolbarDlg::OnEraseBkgnd(CDC* pDC) +{ + CRect rect; + GetClientRect(&rect); + // 使用我们在 SetLayeredWindowAttributes 中定义的颜色填充背景 + pDC->FillSolidRect(rect, RGB(255, 0, 255)); + return TRUE; +} diff --git a/server/2015Remote/ToolbarDlg.h b/server/2015Remote/ToolbarDlg.h index 09b08fc..3788caf 100644 --- a/server/2015Remote/ToolbarDlg.h +++ b/server/2015Remote/ToolbarDlg.h @@ -4,6 +4,8 @@ class CToolbarDlg : public CDialogEx { DECLARE_DYNAMIC(CToolbarDlg) +private: + int m_lastY = 0; // 记录上一次的 Y 坐标 public: CToolbarDlg(CWnd* pParent = nullptr); @@ -25,6 +27,8 @@ protected: public: afx_msg void OnBnClickedExitFullscreen(); afx_msg void OnBnClickedCtrl(); + afx_msg void OnBnClickedMinimize(); afx_msg void OnBnClickedClose(); + afx_msg BOOL OnEraseBkgnd(CDC* pDC); virtual BOOL OnInitDialog(); }; diff --git a/server/2015Remote/resource.h b/server/2015Remote/resource.h index a2c8781..a7066a9 100644 Binary files a/server/2015Remote/resource.h and b/server/2015Remote/resource.h differ