V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
natsukage
V2EX  ›  C#

[C#]WPF 中如何令窗体在按住某个键时临时解除鼠标穿透?

  •  
  •   natsukage · 2020-11-07 21:47:35 +08:00 · 3555 次点击
    这是一个创建于 1511 天前的主题,其中的信息可能已经有所发展或是发生改变。

    RT,基本需求是一个非透明悬浮窗,平时鼠标可以穿透窗体与其后方的其他应用窗体正常交互,但是在按下特定按键(例如 ctrl )时临时解除鼠标穿透状态,令悬浮窗可以被拖动或右键点击弹出 ContextMenu 。 感觉这个需求有些怪,搜了一圈没看到有类似的教程或提问。求各位大佬不吝赐教,谢谢!

    7 条回复    2020-11-11 12:30:30 +08:00
    geelaw
        1
    geelaw  
       2020-11-07 22:05:25 +08:00 via iPhone   ❤️ 1
    你需要 PInvoke 设置窗口的 extended style,同时具有 WS_EX_LAYERED 和 WS_EX_TRANSPARENT 可以让点击穿透,当窗口需要停止穿透时去掉 WS_EX_TRANSPARENT 即可。WS_EX_TRANSPARENT 不影响窗口绘制的透明度。

    https://stackoverflow.com/questions/1524035/topmost-form-clicking-through-possible/1524047#1524047
    natsukage
        2
    natsukage  
    OP
       2020-11-07 22:49:55 +08:00
    @geelaw #1 啊不好意思我应该是没说清楚题意…抱歉。

    我知道正常的方法是通过 SetWindowLong 为窗体设置 WS_EX_TRANSPARENT 来进行鼠标穿透。我的主要问题是在题目中的情况下应当如何实现“按住 ctrl 时临时解除穿透,让窗体可以被拖动、右键弹出菜单”的效果。

    我能想到的思路有 2 种,1 是在当前窗体被鼠标拖拽、右键点击等事件时判断当前 ctrl 是否按下,如果是则执行正常的拖拽、弹出右键菜单等操作,如果否则将鼠标点击、拖动的事件放行给后面的窗体。但是我不清楚 windows 与 wpf 是否支持这样的操作。

    另一种就是注册 ctrl 为全局快捷键,在按下时和解除时分别设置窗体的 WS_EX_TRANSPARENT 属性。但我同样不知道 windows 是否支持单独给 ctrl 注册全局快捷键而不影响其他程序正常响应 ctrl 键,也不知道是否可以捕获 ctrl 键被松开的事件。

    因为感觉 2 条路都走不通,因此才发帖求助的 OTL
    xenme
        3
    xenme  
       2020-11-07 22:52:07 +08:00 via iPhone
    顺着你的思路,直接 hook 按键消息肯定可以
    whwlsfb
        4
    whwlsfb  
       2020-11-07 22:53:58 +08:00 via Android
    hook 单个按键是可以的
    geelaw
        5
    geelaw  
       2020-11-07 23:06:36 +08:00
    @natsukage #2 第一种思路不能成立,因为输入一旦进入某个窗口,就不能再把它交给该窗口背后的窗口——由于 UIPI,如果当前窗口不能向背后的窗口发送消息,则输入会丢失。

    第二条路是可以的。
    lxilu
        6
    lxilu  
       2020-11-08 14:49:02 +08:00
    钩子 +1 ;要是自己写窗口拖拽别用 Move 事件,请用 SendMessage WM_SYSCOMMAND 或 WndProc WM_NCHITTEST
    natsukage
        7
    natsukage  
    OP
       2020-11-11 12:30:30 +08:00
    感谢各位大佬的指点。
    通过 hook 实现了,然后被吐槽:你还不如直接在托盘图标右键开关鼠标穿透
    我人傻了 OTL
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2559 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 01:36 · PVG 09:36 · LAX 17:36 · JFK 20:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.