【问题标题】:Unity3d user32.dll drag window and take focus backUnity3d user32.dll 拖动窗口并重新获得焦点
【发布时间】:2017-09-27 11:26:46
【问题描述】:

我制作了一个无边框的窗口应用程序和一个“假”标题栏来拖动它。

我正在使用 user32.dll,

这个启动窗口拖动(由统一IBeginDragHandler触发):

public const int WM_NCLBUTTONDOWN = 0xA1;
public const int WM_NCLBUTTONUP = 0x00A2;
public const int WM_LBUTTONUP = 0x0202;

[DllImport("User32.dll")]
public static extern bool ReleaseCapture();

[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);

IntPtr window = GetActiveWindow();
...
...
ReleaseCapture();
SendMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, 0);

这个停止拖动(不确定这部分):

    ReleaseCapture();
    SendMessage(window, WM_NCLBUTTONUP, HTCAPTION, 0);
    SendMessage(window, WM_LBUTTONUP, HTCAPTION, 0);

它在编辑器和构建时运行良好,但在开发构建时产生错误:

出现异常情况:PlayerLoop内部函数 已被递归调用。请联系客户支持 示例项目,以便我们可以重现问题并进行故障排除 它。 LauncherWindow:SendMessage(IntPtr, Int32, Int32, Int32) LauncherWindow:StartWindowDrag()(位于 E:\Unity Projects\Crime Club Launcher\Assets\Scripts\Lib\LauncherWindow.cs:115) WindowDragZone:UnityEngine.EventSystems.IBeginDragHandler.OnBeginDrag(PointerEventData) (在 E:\Unity Projects\Crime Club Launcher\Assets\WindowDragZone.cs:9) UnityEngine.EventSystems.ExecuteEvents:执行(IBeginDragHandler, BaseEventData) (在 C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\EventSystem\ExecuteEvents.cs:64) UnityEngine.EventSystems.ExecuteEvents:执行(游戏对象, BaseEventData, EventFunction`1) (在 C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\EventSystem\ExecuteEvents.cs:261) UnityEngine.EventSystems.PointerInputModule:ProcessDrag(PointerEventData) (在 C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\EventSystem\InputModules\PointerInputModule.cs:261) UnityEngine.EventSystems.StandaloneInputModule:ProcessMouseEvent(Int32) (在 C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\EventSystem\InputModules\StandaloneInputModule.cs:434) UnityEngine.EventSystems.StandaloneInputModule:ProcessMouseEvent()(在 C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\EventSystem\InputModules\StandaloneInputModule.cs:412) UnityEngine.EventSystems.StandaloneInputModule:Process()(在 C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\EventSystem\InputModules\StandaloneInputModule.cs:186) UnityEngine.EventSystems.EventSystem:Update()(在 C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\EventSystem\EventSystem.cs:283)

您对此有何看法?

编辑: 好的,所以我终于通过替换摆脱了那个错误

SendMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, 0);

作者:

private const int WM_SYSCOMMAND = 0x112;
private const int MOUSE_MOVE = 0xF012;
SendMessage(window, WM_SYSCOMMAND, MOUSE_MOVE, 0);

现在我有最后一个小问题: 窗口在鼠标释放时被拖放,但我看起来窗口正在失去对类似内容的关注: 第一次点击总是错过,我必须点击两次才能再次拖动或简单地与统一应用程序交互。

我在 OnEndDrag 中尝试了 User32 的函数: ShowWindow、SetActiveWindow、SetFocus 等... 我发现的所有内容都与该问题有关,但它们都没有明显的效果,我仍然必须单击两次。

【问题讨论】:

  • 您能提供更多上下文吗?你想达到什么目的?你的部署目标是什么?
  • 当然。我正在制作一个统一的游戏启动器,它将显示最新消息,必要时管理文件更新,并启动游戏。现在这个启动器只适用于我的游戏的 windows 版本。它将以固定分辨率以窗口模式(= 非全屏)运行。我想删除窗口标题栏(-popupwindow 参数)并使用我自己的按钮退出/最小化启动器并拖放它的窗口。通过一些搜索,我找到了 User32.dll 并且能够完全按照我的意愿进行操作,只是在删除结束时我仍然收到此错误。
  • 和你的开始拖动代码?
  • 窗口拖动正常,但是当我释放鼠标按钮时,我得到了那个错误,我必须在拖动区域上单击两次才能让它再次拖动。我不确定我是否以正确的方式使用 User32
  • @Smartis 好的,我终于明白了,你能看看我的编辑吗?如果您曾经使用过 user32.dll,我还有一个小问题

标签: c# unity3d user32


【解决方案1】:

终于摆脱了这个错误,将 SendMessage() 替换为:

SendMessageCallback(window, WM_SYSCOMMAND, MOUSE_MOVE, 0, WindowDropCallback, 0);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    • 2011-12-06
    • 1970-01-01
    • 2011-08-04
    • 2011-03-10
    • 1970-01-01
    相关资源
    最近更新 更多