mirror of
https://github.com/yuanyuanxiang/SimpleRemoter.git
synced 2026-01-21 23:13:08 +08:00
Improve ToolbarDlg slide in / slide out performance
This commit is contained in:
Binary file not shown.
@@ -741,6 +741,9 @@ BOOL CScreenSpyDlg::PreTranslateMessage(MSG* pMsg)
|
|||||||
if (pMsg->wParam != VK_LWIN && pMsg->wParam != VK_RWIN) {
|
if (pMsg->wParam != VK_LWIN && pMsg->wParam != VK_RWIN) {
|
||||||
SendScaledMouseMessage(pMsg, true);
|
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)
|
if (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE)
|
||||||
return TRUE;// 屏蔽Enter和ESC关闭对话
|
return TRUE;// 屏蔽Enter和ESC关闭对话
|
||||||
break;
|
break;
|
||||||
@@ -987,7 +990,7 @@ void CScreenSpyDlg::EnterFullScreen()
|
|||||||
// 7. 标记全屏模式
|
// 7. 标记全屏模式
|
||||||
m_bFullScreen = true;
|
m_bFullScreen = true;
|
||||||
|
|
||||||
SetTimer(1, 100, NULL);
|
SetTimer(1, 50, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ void CToolbarDlg::DoDataExchange(CDataExchange* pDX)
|
|||||||
BEGIN_MESSAGE_MAP(CToolbarDlg, CDialogEx)
|
BEGIN_MESSAGE_MAP(CToolbarDlg, CDialogEx)
|
||||||
ON_BN_CLICKED(IDC_BTN_EXIT_FULLSCREEN, &CToolbarDlg::OnBnClickedExitFullscreen)
|
ON_BN_CLICKED(IDC_BTN_EXIT_FULLSCREEN, &CToolbarDlg::OnBnClickedExitFullscreen)
|
||||||
ON_BN_CLICKED(CONTROL_BTN_ID, &CToolbarDlg::OnBnClickedCtrl)
|
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_CLOSE, &CToolbarDlg::OnBnClickedClose)
|
||||||
|
ON_WM_ERASEBKGND()
|
||||||
END_MESSAGE_MAP()
|
END_MESSAGE_MAP()
|
||||||
|
|
||||||
void CToolbarDlg::CheckMousePosition()
|
void CToolbarDlg::CheckMousePosition()
|
||||||
@@ -30,24 +32,44 @@ void CToolbarDlg::CheckMousePosition()
|
|||||||
CPoint pt;
|
CPoint pt;
|
||||||
GetCursorPos(&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();
|
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();
|
if (m_bVisible) SlideOut();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CToolbarDlg::SlideIn()
|
void CToolbarDlg::SlideIn()
|
||||||
{
|
{
|
||||||
|
if (m_bVisible) return;
|
||||||
m_bVisible = true;
|
m_bVisible = true;
|
||||||
ShowWindow(SW_SHOWNOACTIVATE);
|
|
||||||
|
|
||||||
|
// 获取屏幕宽度,确保位置正确
|
||||||
int cx = GetSystemMetrics(SM_CXSCREEN);
|
int cx = GetSystemMetrics(SM_CXSCREEN);
|
||||||
for (int y = -m_nHeight; y <= 0; y += 8) {
|
|
||||||
SetWindowPos(&wndTopMost, 0, y, cx, m_nHeight, SWP_NOACTIVATE);
|
// 动画:从 -m_nHeight 移动到 0
|
||||||
Sleep(100);
|
// 步进加大(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);
|
SetWindowPos(&wndTopMost, 0, 0, cx, m_nHeight, SWP_NOACTIVATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +78,7 @@ void CToolbarDlg::SlideOut()
|
|||||||
int cx = GetSystemMetrics(SM_CXSCREEN);
|
int cx = GetSystemMetrics(SM_CXSCREEN);
|
||||||
for (int y = 0; y >= -m_nHeight; y -= 8) {
|
for (int y = 0; y >= -m_nHeight; y -= 8) {
|
||||||
SetWindowPos(&wndTopMost, 0, y, cx, m_nHeight, SWP_NOACTIVATE);
|
SetWindowPos(&wndTopMost, 0, y, cx, m_nHeight, SWP_NOACTIVATE);
|
||||||
Sleep(100);
|
Sleep(50);
|
||||||
}
|
}
|
||||||
ShowWindow(SW_HIDE);
|
ShowWindow(SW_HIDE);
|
||||||
m_bVisible = false;
|
m_bVisible = false;
|
||||||
@@ -85,30 +107,54 @@ BOOL CToolbarDlg::OnInitDialog()
|
|||||||
{
|
{
|
||||||
CDialogEx::OnInitDialog();
|
CDialogEx::OnInitDialog();
|
||||||
|
|
||||||
// 设置分层窗口样式
|
// 1. 设置分层窗口样式
|
||||||
ModifyStyleEx(0, WS_EX_LAYERED);
|
ModifyStyleEx(0, WS_EX_LAYERED);
|
||||||
|
|
||||||
// 设置透明度 (0-255)
|
// 2. 关键设置:使用 LWA_COLORKEY 和 LWA_ALPHA 混合
|
||||||
SetLayeredWindowAttributes(0, 100, 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 cx = GetSystemMetrics(SM_CXSCREEN);
|
||||||
int btnWidth = 80;
|
int btnWidth = 80;
|
||||||
int btnHeight = 28;
|
int btnHeight = 28;
|
||||||
int btnSpacing = 10;
|
int btnSpacing = 10;
|
||||||
int totalWidth = btnWidth * 3 + btnSpacing * 2;
|
int totalWidth = btnWidth * 4 + btnSpacing * 3;
|
||||||
int startX = (cx - totalWidth) / 2;
|
int startX = (cx - totalWidth) / 2;
|
||||||
int y = (m_nHeight - btnHeight) / 2;
|
int y = (m_nHeight - btnHeight) / 2;
|
||||||
|
|
||||||
GetDlgItem(IDC_BTN_EXIT_FULLSCREEN)->SetWindowPos(NULL,
|
GetDlgItem(IDC_BTN_EXIT_FULLSCREEN)->SetWindowPos(NULL, startX, y, btnWidth, btnHeight, SWP_NOZORDER);
|
||||||
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);
|
|
||||||
|
|
||||||
|
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();
|
CScreenSpyDlg* pParent = (CScreenSpyDlg*)GetParent();
|
||||||
GetDlgItem(CONTROL_BTN_ID)->SetWindowTextA(pParent->m_bIsCtrl ? "暂停控制" : "控制屏幕");
|
GetDlgItem(CONTROL_BTN_ID)->SetWindowTextA(pParent->m_bIsCtrl ? "暂停控制" : "控制屏幕");
|
||||||
|
|
||||||
return TRUE;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
class CToolbarDlg : public CDialogEx
|
class CToolbarDlg : public CDialogEx
|
||||||
{
|
{
|
||||||
DECLARE_DYNAMIC(CToolbarDlg)
|
DECLARE_DYNAMIC(CToolbarDlg)
|
||||||
|
private:
|
||||||
|
int m_lastY = 0; // 记录上一次的 Y 坐标
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CToolbarDlg(CWnd* pParent = nullptr);
|
CToolbarDlg(CWnd* pParent = nullptr);
|
||||||
@@ -25,6 +27,8 @@ protected:
|
|||||||
public:
|
public:
|
||||||
afx_msg void OnBnClickedExitFullscreen();
|
afx_msg void OnBnClickedExitFullscreen();
|
||||||
afx_msg void OnBnClickedCtrl();
|
afx_msg void OnBnClickedCtrl();
|
||||||
|
afx_msg void OnBnClickedMinimize();
|
||||||
afx_msg void OnBnClickedClose();
|
afx_msg void OnBnClickedClose();
|
||||||
|
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
|
||||||
virtual BOOL OnInitDialog();
|
virtual BOOL OnInitDialog();
|
||||||
};
|
};
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user