8
votes

I made a borderless windowed application and a "fake" title bar to drag it.

I'm using user32.dll,

This to start the window drag (triggered by unity 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);

And this to stop dragging (not sure about this part):

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

It works well on editor and on build, but an error spawn on developpement build :

An abnormal situation has occurred: the PlayerLoop internal function has been called recursively. Please contact Customer Support with a sample project so that we can reproduce the problem and troubleshoot it. LauncherWindow:SendMessage(IntPtr, Int32, Int32, Int32) LauncherWindow:StartWindowDrag() (at E:\Unity Projects\Crime Club Launcher\Assets\Scripts\Lib\LauncherWindow.cs:115) WindowDragZone:UnityEngine.EventSystems.IBeginDragHandler.OnBeginDrag(PointerEventData) (at E:\Unity Projects\Crime Club Launcher\Assets\WindowDragZone.cs:9) UnityEngine.EventSystems.ExecuteEvents:Execute(IBeginDragHandler, BaseEventData) (at C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\EventSystem\ExecuteEvents.cs:64) UnityEngine.EventSystems.ExecuteEvents:Execute(GameObject, BaseEventData, EventFunction`1) (at C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\EventSystem\ExecuteEvents.cs:261) UnityEngine.EventSystems.PointerInputModule:ProcessDrag(PointerEventData) (at C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\EventSystem\InputModules\PointerInputModule.cs:261) UnityEngine.EventSystems.StandaloneInputModule:ProcessMouseEvent(Int32) (at C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\EventSystem\InputModules\StandaloneInputModule.cs:434) UnityEngine.EventSystems.StandaloneInputModule:ProcessMouseEvent() (at C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\EventSystem\InputModules\StandaloneInputModule.cs:412) UnityEngine.EventSystems.StandaloneInputModule:Process() (at C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\EventSystem\InputModules\StandaloneInputModule.cs:186) UnityEngine.EventSystems.EventSystem:Update() (at C:\buildslave\unity\build\Extensions\guisystem\UnityEngine.UI\EventSystem\EventSystem.cs:283)

What do you think about this ?

EDIT : Okay so I finally got rid of that error by replacing

SendMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, 0);

by :

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

Now I have a last little problem : The windows is dragged, dropped on mouse release, but I look like the window is loosing the focus on something like that : The first click always miss, I must click twice to be able to drag again or simply interact with the unity app.

I tried functions from User32 in OnEndDrag : ShowWindow, SetActiveWindow, SetFocus, etc... Everything I found related to that problem, but they all have no visible effect and I still must click twice.

1
Could you provide more context? What are you trying to achieve? Whats your deploy target?Smartis
Sure. I'm making a game launcher with unity, that will show latest news, manage files updates if necessary, and launch the game. For now this launcher is just for the windows version of my game. It will be runned in windowed mode (= not fullscreen), at a fixed resolution. I want to remove the windows title bar (-popupwindow argument) and use my own buttons to exit/minimize the launcher and drag&drop it's window. With some search I found User32.dll and was able to do exactly what I wanted, except that I still got this error at the end of the drop.FLX
and your code for start dragging?Smartis
The window is dragging fine, but when I release the mouse button I got that error and I must click twice on the drag zone to make it drag again. I'm not really sure that i'm using User32 the right wayFLX
@Smartis Ok I finally got it, can you have a look at my edit ? I have a last little question if you ever worked with user32.dllFLX

1 Answers

3
votes

Finally got rid of this error by replacing SendMessage() by :

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