Unity3d user32.dll 拖动窗口并重新获得焦点
Posted
技术标签:
【中文标题】Unity3d user32.dll 拖动窗口并重新获得焦点【英文标题】:Unity3d user32.dll drag window and take focus back 【发布时间】: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,我还有一个小问题 【参考方案1】:终于摆脱了这个错误,将 SendMessage() 替换为:
SendMessageCallback(window, WM_SYSCOMMAND, MOUSE_MOVE, 0, WindowDropCallback, 0);
【讨论】:
以上是关于Unity3d user32.dll 拖动窗口并重新获得焦点的主要内容,如果未能解决你的问题,请参考以下文章
尝试从 user32.dll 的 GetWindowText() 读取窗口时发生“System.ExecutionEngineException”类型的未处理异常