From dd5fe2cde197be2965917dade29a2a469b5be552 Mon Sep 17 00:00:00 2001 From: yuanyuanxiang <962914132@qq.com> Date: Mon, 12 Jan 2026 14:57:55 +0100 Subject: [PATCH] Improve: Add more features/buttons for remote desktop toolbar --- server/2015Remote/2015Remote.rc | Bin 107084 -> 104308 bytes server/2015Remote/CDlgFileSend.cpp | 9 ++ server/2015Remote/CDlgFileSend.h | 1 + server/2015Remote/IOCPServer.h | 3 + server/2015Remote/ScreenSpyDlg.cpp | 14 +- server/2015Remote/ToolbarDlg.cpp | 232 +++++++++++++++++++++++++---- server/2015Remote/ToolbarDlg.h | 12 ++ server/2015Remote/resource.h | 6 +- 8 files changed, 239 insertions(+), 38 deletions(-) diff --git a/server/2015Remote/2015Remote.rc b/server/2015Remote/2015Remote.rc index fa0539ce525f54c07d26170d9f4d9a7c67b9db68..e9b9c5ce984de619b2a561f398002175976ac90d 100644 GIT binary patch delta 12495 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 D7rF;t diff --git a/server/2015Remote/CDlgFileSend.cpp b/server/2015Remote/CDlgFileSend.cpp index c866a5f..b101330 100644 --- a/server/2015Remote/CDlgFileSend.cpp +++ b/server/2015Remote/CDlgFileSend.cpp @@ -27,6 +27,7 @@ void CDlgFileSend::DoDataExchange(CDataExchange* pDX) BEGIN_MESSAGE_MAP(CDlgFileSend, CDialog) ON_WM_CLOSE() + ON_WM_TIMER() ON_MESSAGE(WM_UPDATEFILEPROGRESS, &CDlgFileSend::OnUpdateFileProgress) ON_MESSAGE(WM_FINISHFILESEND, &CDlgFileSend::OnFinishFileSend) END_MESSAGE_MAP() @@ -83,6 +84,7 @@ LRESULT CDlgFileSend::OnUpdateFileProgress(WPARAM wParam, LPARAM lParam) ShowWindow(SW_SHOW); BringWindowToTop(); SetForegroundWindow(); + if (percent>=100.) SetTimer(1, 3000, NULL); delete pChunk; delete pFile; @@ -128,3 +130,10 @@ void CDlgFileSend::OnClose() DialogBase::OnClose(); } + +void CDlgFileSend::OnTimer(UINT_PTR nIDEvent) { + if (nIDEvent == 1) { + KillTimer(1); + PostMessageA(WM_CLOSE, 0, 0); + } +} diff --git a/server/2015Remote/CDlgFileSend.h b/server/2015Remote/CDlgFileSend.h index 14c7233..bf7fa7b 100644 --- a/server/2015Remote/CDlgFileSend.h +++ b/server/2015Remote/CDlgFileSend.h @@ -37,4 +37,5 @@ public: CProgressCtrl m_Progress; virtual BOOL OnInitDialog(); afx_msg void OnClose(); + afx_msg void OnTimer(UINT_PTR nIDEvent); }; diff --git a/server/2015Remote/IOCPServer.h b/server/2015Remote/IOCPServer.h index 6a4dde2..c451999 100644 --- a/server/2015Remote/IOCPServer.h +++ b/server/2015Remote/IOCPServer.h @@ -121,6 +121,7 @@ public: bool m_bIsProcessing; HICON m_hIcon; BOOL m_bConnected; + uint64_t m_nDisconnectTime = 0; CDialogBase(UINT nIDTemplate, CWnd* pParent, Server* pIOCPServer, CONTEXT_OBJECT* pContext, int nIcon) : m_bIsClosed(false), m_bIsProcessing(false), m_ContextObject(pContext), @@ -128,12 +129,14 @@ public: CDialog(nIDTemplate, pParent) { m_bConnected = TRUE; + m_nDisconnectTime = 0; m_IPAddress = pContext->GetPeerName().c_str(); m_hIcon = nIcon > 0 ? LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(nIcon)) : NULL; } int UpdateContext(CONTEXT_OBJECT* pContext) { m_bConnected = TRUE; + m_nDisconnectTime = 0; m_ContextObject = pContext; m_iocpServer = pContext->GetServer(); m_ContextObject->hDlg = this; diff --git a/server/2015Remote/ScreenSpyDlg.cpp b/server/2015Remote/ScreenSpyDlg.cpp index 52c4dcd..ac274ca 100644 --- a/server/2015Remote/ScreenSpyDlg.cpp +++ b/server/2015Remote/ScreenSpyDlg.cpp @@ -342,6 +342,7 @@ VOID CScreenSpyDlg::OnClose() afx_msg LRESULT CScreenSpyDlg::OnDisconnect(WPARAM wParam, LPARAM lParam) { m_bConnected = FALSE; + m_nDisconnectTime = GetTickCount64(); // Close the dialog if reconnect not succeed in 15 seconds SetTimer(2, 15000, NULL); PostMessage(WM_PAINT); @@ -594,7 +595,7 @@ void CScreenSpyDlg::OnPaint() NULL, DI_NORMAL | DI_COMPAT ); - if (!m_bConnected) { + if (!m_bConnected && GetTickCount64()-m_nDisconnectTime>2000) { DrawTipString("正在重连......", 2); } } @@ -1126,9 +1127,14 @@ void CScreenSpyDlg::EnterFullScreen() if (!m_pToolbar) { m_pToolbar = new CToolbarDlg(this); m_pToolbar->Create(IDD_TOOLBAR_DLG, this); - int cx = GetSystemMetrics(SM_CXSCREEN); - int cy = GetSystemMetrics(SM_CYSCREEN); - m_pToolbar->SetWindowPos(&wndTopMost, 0, -40, cx, 40, SWP_HIDEWINDOW); + // OnInitDialog() 会根据 m_bLocked 和 m_bOnTop 设置正确的位置和可见性 + // 如果未锁定,初始隐藏在屏幕外 + if (!m_pToolbar->m_bLocked) { + int cx = GetSystemMetrics(SM_CXSCREEN); + int cy = GetSystemMetrics(SM_CYSCREEN); + int y = m_pToolbar->m_bOnTop ? -40 : cy; // 根据位置设置隐藏在上方或下方 + m_pToolbar->SetWindowPos(&wndTopMost, 0, y, cx, 40, SWP_HIDEWINDOW); + } } // 7. 标记全屏模式 diff --git a/server/2015Remote/ToolbarDlg.cpp b/server/2015Remote/ToolbarDlg.cpp index 27aa0df..918b69f 100644 --- a/server/2015Remote/ToolbarDlg.cpp +++ b/server/2015Remote/ToolbarDlg.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "ToolbarDlg.h" +#include "2015Remote.h" #include "2015RemoteDlg.h" #include @@ -24,28 +25,62 @@ BEGIN_MESSAGE_MAP(CToolbarDlg, CDialogEx) 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_BN_CLICKED(IDC_BTN_LOCK, &CToolbarDlg::OnBnClickedLock) + ON_BN_CLICKED(IDC_BTN_POSITION, &CToolbarDlg::OnBnClickedPosition) + ON_BN_CLICKED(IDC_BTN_OPACITY, &CToolbarDlg::OnBnClickedOpacity) + ON_BN_CLICKED(IDC_BTN_SCREENSHOT, &CToolbarDlg::OnBnClickedScreenshot) ON_WM_ERASEBKGND() END_MESSAGE_MAP() void CToolbarDlg::CheckMousePosition() { + // 如果父窗口最小化,隐藏工具栏 + CWnd* pParent = GetParent(); + if (pParent && pParent->IsIconic()) { + if (m_bVisible) { + ShowWindow(SW_HIDE); + m_bVisible = false; + } + return; + } + + // 如果工具栏已锁定,确保它可见(处理最小化恢复等情况) + if (m_bLocked) { + if (!m_bVisible) { + SlideIn(); + } + return; + } + CPoint pt; GetCursorPos(&pt); int cxScreen = GetSystemMetrics(SM_CXSCREEN); + int cyScreen = GetSystemMetrics(SM_CYSCREEN); - // 计算按钮群的总宽度 (4个按钮 + 间距) - int totalWidth = 80 * 4 + 10 * 3; + // 计算按钮群的总宽度 (8个按钮 + 间距) + int totalWidth = 80 * 8 + 10 * 7; 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 + 10 || pt.x < leftBound - 50 || pt.x > rightBound + 50) { - if (m_bVisible) SlideOut(); + if (m_bOnTop) { + // 工具栏在上方: 鼠标移到顶端时弹出 + if (pt.y <= 2 && pt.x >= leftBound && pt.x <= rightBound) { + if (!m_bVisible) SlideIn(); + } + // 鼠标离开工具栏范围时隐藏 + else if (pt.y > m_nHeight + 10 || pt.x < leftBound - 50 || pt.x > rightBound + 50) { + if (m_bVisible) SlideOut(); + } + } else { + // 工具栏在下方: 鼠标移到底端时弹出 + if (pt.y >= cyScreen - 2 && pt.x >= leftBound && pt.x <= rightBound) { + if (!m_bVisible) SlideIn(); + } + // 鼠标离开工具栏范围时隐藏 + else if (pt.y < cyScreen - m_nHeight - 10 || pt.x < leftBound - 50 || pt.x > rightBound + 50) { + if (m_bVisible) SlideOut(); + } } } @@ -54,31 +89,46 @@ void CToolbarDlg::SlideIn() if (m_bVisible) return; m_bVisible = true; - // 获取屏幕宽度,确保位置正确 + // 获取屏幕尺寸 int cx = GetSystemMetrics(SM_CXSCREEN); + int cy = GetSystemMetrics(SM_CYSCREEN); - // 动画:从 -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 是人眼感知的流畅极限 + if (m_bOnTop) { + // 从上方滑入: 从 -m_nHeight 移动到 0 + for (int i = -m_nHeight; i <= 0; i += 10) { + SetWindowPos(&wndTopMost, 0, i, cx, m_nHeight, SWP_SHOWWINDOW | SWP_NOACTIVATE); + UpdateWindow(); + Sleep(10); + } + SetWindowPos(&wndTopMost, 0, 0, cx, m_nHeight, SWP_NOACTIVATE); + } else { + // 从下方滑入: 从 cy 移动到 cy - m_nHeight + for (int i = cy; i >= cy - m_nHeight; i -= 10) { + SetWindowPos(&wndTopMost, 0, i, cx, m_nHeight, SWP_SHOWWINDOW | SWP_NOACTIVATE); + UpdateWindow(); + Sleep(10); + } + SetWindowPos(&wndTopMost, 0, cy - m_nHeight, cx, m_nHeight, SWP_NOACTIVATE); } - - // 确保最终位置精准在 0 - SetWindowPos(&wndTopMost, 0, 0, cx, m_nHeight, SWP_NOACTIVATE); } 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(50); + int cy = GetSystemMetrics(SM_CYSCREEN); + + if (m_bOnTop) { + // 向上滑出 + for (int y = 0; y >= -m_nHeight; y -= 8) { + SetWindowPos(&wndTopMost, 0, y, cx, m_nHeight, SWP_NOACTIVATE); + Sleep(50); + } + } else { + // 向下滑出 + for (int y = cy - m_nHeight; y <= cy; y += 8) { + SetWindowPos(&wndTopMost, 0, y, cx, m_nHeight, SWP_NOACTIVATE); + Sleep(50); + } } ShowWindow(SW_HIDE); m_bVisible = false; @@ -107,20 +157,21 @@ BOOL CToolbarDlg::OnInitDialog() { CDialogEx::OnInitDialog(); + // 加载用户设置 + LoadSettings(); + // 1. 设置分层窗口样式 ModifyStyleEx(0, WS_EX_LAYERED); - // 2. 关键设置:使用 LWA_COLORKEY 和 LWA_ALPHA 混合 - // RGB(255, 0, 255) 是品红色,我们将它定义为“透明色” - // 255 代表按钮部分完全不透明(如果你想要按钮也半透明,可以改成 150-200) - SetLayeredWindowAttributes(RGB(255, 0, 255), 255, LWA_COLORKEY | LWA_ALPHA); + // 2. 应用透明度设置 + ApplyOpacity(); - // --- 按钮布局代码 (保持不变) --- + // --- 按钮布局代码 (8个按钮) --- int cx = GetSystemMetrics(SM_CXSCREEN); int btnWidth = 80; int btnHeight = 28; int btnSpacing = 10; - int totalWidth = btnWidth * 4 + btnSpacing * 3; + int totalWidth = btnWidth * 8 + btnSpacing * 7; int startX = (cx - totalWidth) / 2; int y = (m_nHeight - btnHeight) / 2; @@ -130,7 +181,19 @@ BOOL CToolbarDlg::OnInitDialog() 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); // 放置最小化按钮 + GetDlgItem(IDC_BTN_LOCK)->SetWindowPos(NULL, nextX, y, btnWidth, btnHeight, SWP_NOZORDER); + + nextX += btnWidth + btnSpacing; + GetDlgItem(IDC_BTN_POSITION)->SetWindowPos(NULL, nextX, y, btnWidth, btnHeight, SWP_NOZORDER); + + nextX += btnWidth + btnSpacing; + GetDlgItem(IDC_BTN_OPACITY)->SetWindowPos(NULL, nextX, y, btnWidth, btnHeight, SWP_NOZORDER); + + nextX += btnWidth + btnSpacing; + GetDlgItem(IDC_BTN_SCREENSHOT)->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); @@ -139,6 +202,29 @@ BOOL CToolbarDlg::OnInitDialog() CScreenSpyDlg* pParent = (CScreenSpyDlg*)GetParent(); GetDlgItem(CONTROL_BTN_ID)->SetWindowTextA(pParent->m_bIsCtrl ? "暂停控制" : "控制屏幕"); + // 设置锁定按钮文本 + GetDlgItem(IDC_BTN_LOCK)->SetWindowTextA(m_bLocked ? "解锁" : "锁定"); + + // 设置位置按钮文本 + GetDlgItem(IDC_BTN_POSITION)->SetWindowTextA(m_bOnTop ? "放下面" : "放上面"); + + // 设置透明度按钮文本 + GetDlgItem(IDC_BTN_OPACITY)->SetWindowTextA(GetOpacityText()); + + // 设置截图按钮文本 + GetDlgItem(IDC_BTN_SCREENSHOT)->SetWindowTextA("截图"); + + // 如果是锁定状态,立即显示工具栏(否则锁定时无法触发显示) + if (m_bLocked) { + m_bVisible = true; + int cy = GetSystemMetrics(SM_CYSCREEN); + if (m_bOnTop) { + SetWindowPos(&wndTopMost, 0, 0, cx, m_nHeight, SWP_SHOWWINDOW | SWP_NOACTIVATE); + } else { + SetWindowPos(&wndTopMost, 0, cy - m_nHeight, cx, m_nHeight, SWP_SHOWWINDOW | SWP_NOACTIVATE); + } + } + return TRUE; } @@ -158,3 +244,83 @@ BOOL CToolbarDlg::OnEraseBkgnd(CDC* pDC) pDC->FillSolidRect(rect, RGB(255, 0, 255)); return TRUE; } + +void CToolbarDlg::OnBnClickedLock() +{ + m_bLocked = !m_bLocked; + GetDlgItem(IDC_BTN_LOCK)->SetWindowTextA(m_bLocked ? "解锁" : "锁定"); + SaveSettings(); +} + +void CToolbarDlg::OnBnClickedPosition() +{ + m_bOnTop = !m_bOnTop; + GetDlgItem(IDC_BTN_POSITION)->SetWindowTextA(m_bOnTop ? "放下面" : "放上面"); + UpdatePosition(); + SaveSettings(); +} + +void CToolbarDlg::UpdatePosition() +{ + int cx = GetSystemMetrics(SM_CXSCREEN); + int cy = GetSystemMetrics(SM_CYSCREEN); + + if (m_bOnTop) { + // 移动到屏幕上方 + SetWindowPos(&wndTopMost, 0, 0, cx, m_nHeight, SWP_NOACTIVATE); + } else { + // 移动到屏幕下方 + SetWindowPos(&wndTopMost, 0, cy - m_nHeight, cx, m_nHeight, SWP_NOACTIVATE); + } +} + +void CToolbarDlg::LoadSettings() +{ + m_bLocked = THIS_CFG.GetInt("toolbar", "Locked", 0) != 0; + m_bOnTop = THIS_CFG.GetInt("toolbar", "OnTop", 1) != 0; + m_nOpacityLevel = THIS_CFG.GetInt("toolbar", "OpacityLevel", 0) % 3; +} + +void CToolbarDlg::SaveSettings() +{ + THIS_CFG.SetInt("toolbar", "Locked", m_bLocked ? 1 : 0); + THIS_CFG.SetInt("toolbar", "OnTop", m_bOnTop ? 1 : 0); + THIS_CFG.SetInt("toolbar", "OpacityLevel", m_nOpacityLevel); +} + +void CToolbarDlg::ApplyOpacity() +{ + // 透明度级别: 0=100%(255), 1=75%(191), 2=50%(128) + BYTE opacity; + switch (m_nOpacityLevel) { + case 1: opacity = 191; break; // 75% + case 2: opacity = 128; break; // 50% + default: opacity = 255; break; // 100% + } + SetLayeredWindowAttributes(RGB(255, 0, 255), opacity, LWA_COLORKEY | LWA_ALPHA); +} + +CString CToolbarDlg::GetOpacityText() +{ + switch (m_nOpacityLevel) { + case 1: return "透明75%"; + case 2: return "透明50%"; + default: return "透明度"; + } +} + +void CToolbarDlg::OnBnClickedOpacity() +{ + m_nOpacityLevel = (m_nOpacityLevel + 1) % 3; + ApplyOpacity(); + GetDlgItem(IDC_BTN_OPACITY)->SetWindowTextA(GetOpacityText()); + SaveSettings(); +} + +void CToolbarDlg::OnBnClickedScreenshot() +{ + CScreenSpyDlg* pParent = (CScreenSpyDlg*)GetParent(); + if (pParent) { + pParent->SaveSnapshot(); + } +} diff --git a/server/2015Remote/ToolbarDlg.h b/server/2015Remote/ToolbarDlg.h index 4732801..d5aa980 100644 --- a/server/2015Remote/ToolbarDlg.h +++ b/server/2015Remote/ToolbarDlg.h @@ -15,10 +15,18 @@ public: int m_nHeight = 40; bool m_bVisible = false; + bool m_bLocked = false; // 是否锁定工具栏 + bool m_bOnTop = true; // 是否在屏幕上方 (默认上方) + int m_nOpacityLevel = 0; // 透明度级别 (0=100%, 1=75%, 2=50%) void SlideIn(); void SlideOut(); void CheckMousePosition(); + void UpdatePosition(); // 更新工具栏位置 + void LoadSettings(); // 从注册表加载设置 + void SaveSettings(); // 保存设置到注册表 + void ApplyOpacity(); // 应用透明度 + CString GetOpacityText(); // 获取透明度按钮文本 protected: virtual void DoDataExchange(CDataExchange* pDX); @@ -29,6 +37,10 @@ public: afx_msg void OnBnClickedCtrl(); afx_msg void OnBnClickedMinimize(); afx_msg void OnBnClickedClose(); + afx_msg void OnBnClickedLock(); + afx_msg void OnBnClickedPosition(); + afx_msg void OnBnClickedOpacity(); + afx_msg void OnBnClickedScreenshot(); afx_msg BOOL OnEraseBkgnd(CDC* pDC); virtual BOOL OnInitDialog(); }; diff --git a/server/2015Remote/resource.h b/server/2015Remote/resource.h index 6585381..f6ee344 100644 --- a/server/2015Remote/resource.h +++ b/server/2015Remote/resource.h @@ -434,6 +434,10 @@ #define IDC_STATIC_CURRENTPERCENT 2216 #define IDC_EDIT_INSTALL_DIR 2216 #define IDC_EDIT_INSTALL_NAME 2217 +#define IDC_BTN_LOCK 2218 +#define IDC_BTN_POSITION 2219 +#define IDC_BTN_OPACITY 2220 +#define IDC_BTN_SCREENSHOT 2221 #define ID_ONLINE_UPDATE 32772 #define ID_ONLINE_MESSAGE 32773 #define ID_ONLINE_DELETE 32775 @@ -620,7 +624,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 322 #define _APS_NEXT_COMMAND_VALUE 32995 -#define _APS_NEXT_CONTROL_VALUE 2218 +#define _APS_NEXT_CONTROL_VALUE 2222 #define _APS_NEXT_SYMED_VALUE 105 #endif #endif