锁机与解锁功能的实现

        这篇文章的主要目的实现了一个锁机和解锁的功能,首先是实现锁机,锁机主要通过三方面实现:启动一个新的窗口,将其覆盖整个屏幕实现屏幕的锁定;隐藏任务栏,防止用户切换到其他应用;限制鼠标移动范围,阻止鼠标操作。同时留下解锁按键A,实现解锁功能。

详细分析:

1. LockMachine()

该函数用于启动 threadLockDlg 线程,并发送一个数据包。

2. threadLockDlg(void* arg)

该函数是 LockMachine() 启动的线程入口点,主要执行锁屏操作。

3. UnlockMachine()

该函数用于解锁屏幕。

        为什么使用线程函数?

        在 LockMachine() 中,我们使用了 _beginthreadex() 来创建一个新的线程运行 threadLockDlg(),原因如下:

1. 避免 UI 线程阻塞

如果 threadLockDlg() 在主线程(UI 线程)中运行,它会创建一个模态对话框 dlg,并进入 while (GetMessage(&msg, NULL, 0, 0)) 消息循环,导致主线程无法处理其他任务。

2. 让 LockMachine() 迅速返回

如果 threadLockDlg() 在主线程执行:

  • LockMachine() 会卡在 dlg.Create() 之后,直到窗口销毁。
  • 这样,LockMachine() 无法立即返回,程序执行效率降低。

通过子线程运行 threadLockDlg()

  • LockMachine() 不会等待 窗口运行完毕,而是立刻返回,让程序继续执行其他任务。

3.兼容多线程架构

在实际开发中:

  • LockMachine() 可能由其他线程调用(例如:网络接收线程)。
  • 使用线程封装 dlg,使其成为独立的可控组件,不会影响主程序逻辑。

此外,如果需要在多个地方调用 LockMachine(),独立线程方式更易维护,且不会干扰主线程。

具体操作如下:

1. threadLockDlg(void* arg)

创建并显示对话框

dlg.Create(IDD_DIALOG_INFO,NULL);
dlg.ShowWindow(SW_SHOW);
  • IDD_DIALOG_INFO 是一个对话框资源,dlg 作为 CLockDialog 实例被创建并显示.

  • 全屏遮盖后台窗口

CRect rect;
rect.left = 0;
rect.top = 0;
rect.right = GetSystemMetrics(SM_CXFULLSCREEN);
rect.bottom = GetSystemMetrics(SM_CYFULLSCREEN);
rect.bottom *= 1.03;
dlg.MoveWindow(rect);
  • 这段代码获取全屏分辨率,并设置窗口大小比屏幕稍大(1.03 倍)。

  • 鼠标控制

ShowCursor(false);  // 隐藏鼠标
rect.left = 0;
rect.top = 0;
rect.right = 1;
rect.bottom = 1;
ClipCursor(rect);  // 限制鼠标活动范围

这里将鼠标位置限制在 (0,0) 到 (1,1),相当于禁用鼠标。

隐藏任务栏

::ShowWindow(::FindWindow(_T("Shell_TrayWnd"), NULL), SW_HIDE);
  • 这行代码隐藏了 Windows 任务栏。

  • 消息循环

MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    if (msg.message == WM_KEYDOWN) {
        TRACE("msg:%08X wparam:%08X lparam:%08X\r\n", msg.message, msg.wParam, msg.lParam);
        if (msg.wParam == 0x41) { // 'A' 键退出
            break;
        }
    }
}
  • 监听键盘输入,按下 A (0x41) 退出。
  • 恢复鼠标、任务栏,并销毁窗口

ShowCursor(true);
::ShowWindow(::FindWindow(_T("Shell_TrayWnd"), NULL), SW_SHOW);
dlg.DestroyWindow();

恢复鼠标指针。

  • 显示任务栏。
  • 关闭 dlg 窗口,解除锁屏。
2. LockMachine()

该函数用于启动 threadLockDlg 线程,并发送一个数据包。

if ((dlg.m_hWnd == NULL) || (dlg.m_hWnd == INVALID_HANDLE_VALUE)) {
    _beginthreadex(NULL, 0, threadLockDlg, NULL, 0, &threadid);
    TRACE("THREADID=%d\r\n", threadid);
}
  • dlg.m_hWnd == NULL 表示窗口未创建,INVALID_HANDLE_VALUE 额外检查句柄无效。
  • 使用 _beginthreadex() 启动 threadLockDlg 线程,并存储线程 ID 到 threadid
CPacket pack(7, NULL, 0);
CServerSocket::getInstance()->Send(pack);
  • CPacket 是一个数据包类,构造函数参数 (7, NULL, 0)表示发送一个类型为 7 的消息。
  • CServerSocket::getInstance()->Send(pack); 发送数据。
3. UnlockMachine()

该函数用于解锁屏幕。

PostThreadMessage(threadid, WM_KEYDOWN, 0x41, 0);

PostThreadMessage(threadid, WM_KEYDOWN, 0x41, 0);

  • threadid 线程发送 WM_KEYDOWN 消息,模拟按下 A 键,使 threadLockDlg 退出。
CPacket pack(7, NULL, 0);
CServerSocket::getInstance()->Send(pack);
  • 再次发送数据包,可能是通知服务器解锁完成。
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值