Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

User32.dll SetFocus() not working in standalone build

Discussion in 'Windows' started by _FLX, May 5, 2017.

  1. _FLX

    _FLX

    Joined:
    Nov 10, 2015
    Posts:
    85
    Hi,

    I managed to make a little borderless launcher with a custom title bar and a drag&drop function using user32.dll.

    I'm dragging the window using :
    Code (CSharp):
    1.  
    2.  
    3.   // Window drag&drop messages
    4.  
    5.  [DllImport("User32.dll")] public static extern bool ReleaseCapture(); // Used for window drag&drop
    6.     delegate void SendMessageDelegate(IntPtr hWnd, uint uMsg, UIntPtr dwData, IntPtr lResult);
    7.  [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern bool SendMessageCallback(IntPtr hWnd, int Msg, int wParam, int lParam, SendMessageDelegate lpCallBack, int dwData);
    8.  [DllImport("user32.dll", EntryPoint = "SetForegroundWindow")] static extern bool SetForegroundWindow(IntPtr hWnd);
    9.  [DllImport("user32.dll", SetLastError = true)] static extern IntPtr SetFocus(IntPtr hWnd);
    10. [DllImport("user32.dll", EntryPoint = "FindWindow")] public static extern System.IntPtr FindWindow(string className, string windowName);
    11.  
    12. // Drag Start
    13. window = GetActiveWindow();
    14. ReleaseCapture();
    15. SendMessageCallback(window, WM_SYSCOMMAND, MOUSE_MOVE, 0, WindowDropCallback, 0);
    16.  
    It works well, except that I have to click twice after the drop, because of the loss of focus.

    So i added this in the WindowDropCallback :
    Code (CSharp):
    1.  
    2. SetForegroundWindow(window);
    3.  SetFocus(window);
    4.  
    And it works exactly how I want, but ONLY in the editor !
    When I build, the focus is still lost on drop and I still have to click twice.

    Do you have an idea ?

    Thanks for reading :D
     
    Last edited: May 5, 2017
    lyuleon likes this.
  2. _FLX

    _FLX

    Joined:
    Nov 10, 2015
    Posts:
    85
    Found a workaround :
    I simulate a left click on the window using SendInput.
    Works very well
     
  3. Ciryus

    Ciryus

    Joined:
    Sep 17, 2012
    Posts:
    38
    Thank you for the workaround. I saw your post on StackOverFlow and was asking what you did in the callback. Very sad to read that a workaround is the only solution for the moment. But thank you because I was facing the exact same issue.
     
  4. lyuleon

    lyuleon

    Joined:
    Aug 10, 2017
    Posts:
    1
    Thank you very much for your help _FLX!!
    I followed your instructions and solved the problem of twice clicking issue!!
    For those who are unclear about how to simulate an input, here is my trick:

    void DragEvent(){
    SendMessageCallback(window, WM_SYSCOMMAND, MOUSE_MOVE, 0, DropCallBack, 0);
    }


    [DllImport("user32.dll")]
    public static extern bool SetForegroundWindow(IntPtr hwnd);
    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr SetFocus(IntPtr hWnd);
    [DllImport("user32.dll")]
    public static extern Boolean SendMessage(IntPtr hwnd, Int32 wMsg, Int32 wParam, Int32 lParam);
    public const int WM_LBUTTONDOWN = 0x201;
    public const int WM_LBUTTONUP = 0x0202;
    private static void DropCallBack(IntPtr hwnd, uint uMsg, int dwData, int lResult)
    {
    SetForegroundWindow(hwnd);
    SetFocus(hwnd);
    SendMessage(hwnd, WM_LBUTTONDOWN, 0, 0);
    SendMessage(hwnd, WM_LBUTTONUP, 0, 0);
    }
     
    Hertz likes this.