提起 Deskflow(早年叫 Synergy),很多人第一反应是“把 A 机鼠标移到 B 机”的黑魔法。如果把这套魔法拆开,核心只有一句话:
本地截获输入事件 → 网络转发 → 远端还原输入事件。
下面,我们顺着 Windows 端源码,把这个过程讲成一篇“故事”,让你看明白鼠标是怎么“漂”到隔壁屏幕的。
- 舞台:Windows 桌面与世界
- 桌面
Windows 可以有多桌面(登录桌面、屏保桌面、UAC 桌面……)。Deskflow 启动后,会为 每一个可见桌面 各起一个线程,线程里再建一个几乎透明的 1×1 像素窗口——它就像“捕鼠笼”,用来吞掉本地鼠标事件。 - 钩子
线程装好钩子:- 低级鼠标钩子
WH_MOUSE_LL:任何鼠标移动、点击、滚轮先被 Deskflow 看到。 - 低级键盘钩子
WH_KEYBOARD_LL:同理,键盘事件先被截获。
钩子决定事件是“本地消化”还是“远端投递”。
- 低级鼠标钩子
- 鼠标怎样“消失”
当鼠标从屏幕右边缘离开(准备进入右侧那台电脑)时,Deskflow 做了三件事:
- 藏光标
连续调用ShowCursor(FALSE)直到系统内部计数器 < 0,本地光标彻底看不见。 - 铺隐形幕布
把刚才那个 1×1 小窗口瞬间放大到覆盖所有屏幕(或只留中心 1 像素),并SetCapture;从此本地鼠标事件全部被这扇“隐形门”吃掉,不会触发别的程序。 - 冻结加速度
用SystemParametersInfo把鼠标加速度关掉,确保后续远端还原时定位精准。
此刻,本地用户依旧移动物理鼠标,但 Windows 光标纹丝不动——它已“灵魂出窍”。
- 事件如何漂洋过海
钩子拿到数据后,把事件封装成一条轻量消息:
- 鼠标移动 →
DESKFLOW_MSG_FAKE_MOVE - 鼠标点击 →
DESKFLOW_MSG_FAKE_BUTTON - 滚轮 →
DESKFLOW_MSG_FAKE_WHEEL
消息被 PostThreadMessage 甩进网络线程 → TCP 发到远端 → 远端再 PostThreadMessage 给对应桌面线程。整个过程对系统而言,只是“普通消息”,延迟极低。
- 远端怎样“复现”光标
远端桌面线程收到消息后,立即调用 Win32 API 的 SendInput:
- 绝对坐标模式
MOUSEEVENTF_ABSOLUTE:把网络传来的 (x,y) 直接映射到远端屏幕分辨率。 - 相对模式
MOUSEEVENTF_MOVE:用于精细拖拽,不受系统加速干扰。 - 按钮/滚轮:同理,直接用
SendInput模拟。
于是,用户在 A 机移动鼠标,B 机光标同步滑行,肉眼几乎看不出时差。
- 鼠标怎样“回家”
当远端光标移动到屏幕边缘,准备回到 A 机:
- B 机 Deskflow 把光标瞬间移到屏幕中心,发消息“我要走了”;
- A 机收到后,
deskEnter():ShowCursor(TRUE)让本地光标重新出现;ReleaseCapture把隐形窗口缩回 1×1,本地系统重新接管鼠标;- 再把光标位置同步到屏幕边缘,用户无缝继续操作。
- 键盘、剪贴板、文件拖放
- 键盘 与鼠标完全同理:钩子截获 → 网络 → 远端
SendInput。 - 剪贴板 用本机剪贴板监听 + 网络同步,文字/图片跨机 Ctrl+C / Ctrl+V。
- 文件拖放 在鼠标“跨屏”瞬间把文件路径打包、通过 SFTP 直传。
905

被折叠的 条评论
为什么被折叠?



