Is there anything in electron BrowserWindow([options]) like always-on-bottom


#1

I want to stick my app to desktop. I know the option of alwaysOnTop but is there anything we can do to make the app at always on bottom ?


#2

I don’t think you can do this easily.
Seems like Chromium does not provide the API to set this z-order to make the window goes on the bottom apart from always on top.

as in the chromium code which Electron is built on top :

so i guess, the solution will be a bit complicated.

  1. from electron main process, you get window handle with this API - win.getNativeWindowHandle()
    https://github.com/electron/electron/blob/master/docs/api/browser-window.md#wingetnativewindowhandle

  2. you might need to call Windows/OS API directly to this Win32 API for Windows OS :
    ::SetWindowPos() with HWND_BOTTOM flag
    https://msdn.microsoft.com/en-us/library/windows/desktop/ms633545(v=vs.85).aspx

To call to system API, you have number of options:
A. using https://github.com/node-ffi/node-ffi
B. implement Node native module ( in C/C++ )


#3

Sure I will try to implement this functionality.
I have checked win.getNativeWindowHandle()
window.getNativeWindowHandle(function(e) {
console.log(e);
});
It doesn’t provide event when we window +D event triggered. I think calling native API is a good idea.
Let me check this and try to implement it.


#4

I got something
This code registers a low level keyboard hook and listens for D keypress while the windows key is held. If this is detected, the hook simply ignores the keypress. Otherwise, it forwards the keypress along.

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace KbHook
{
    public static class Program
    {
        const int HC_ACTION = 0;
        const int WH_KEYBOARD_LL = 13;
        const int WM_KEYDOWN = 0x0100;
        static IntPtr HookHandle = IntPtr.Zero;
        static Form1 Form1;

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern IntPtr SetWindowsHookEx(int idHook, KbHook lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern IntPtr GetModuleHandle(string lpModuleName);

        [STAThread]
        static void Main()
        {
            try
            {
                using (var proc = Process.GetCurrentProcess())
                    using (var curModule = proc.MainModule)
                    {
                        var moduleHandle = GetModuleHandle(curModule.ModuleName);
                        HookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, IgnoreWin_D, moduleHandle, 0);
                    }

                Form1 = new Form1();
                Application.Run(Form1);
            }
            finally
            {
                UnhookWindowsHookEx(HookHandle);
            }
        }

        [DllImport("user32.dll")]
        static extern short GetAsyncKeyState(Keys vKey);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        static IntPtr IgnoreWin_D(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode == HC_ACTION
                && IsWin_D(wParam, lParam))
                return (IntPtr) 1; //just ignore the key press

            return CallNextHookEx(HookHandle, nCode, wParam, lParam);
        }

        static bool IsWin_D(IntPtr wParam, IntPtr lParam)
        {
            if ((int) wParam != WM_KEYDOWN)
                return false;

            var keyInfo = (KbHookParam) Marshal.PtrToStructure(lParam, typeof (KbHookParam));
            if (keyInfo.VkCode != (int) Keys.D) return false;
            return GetAsyncKeyState(Keys.LWin) < 0
                   || GetAsyncKeyState(Keys.RWin) < 0;
        }

        delegate IntPtr KbHook(int nCode, IntPtr wParam, [In] IntPtr lParam);

        [StructLayout(LayoutKind.Sequential)]
        struct KbHookParam
        {
            public readonly int VkCode;
            public readonly int ScanCode;
            public readonly int Flags;
            public readonly int Time;
            public readonly IntPtr Extra;
        }
    }
}

Referred From :
https://stackoverflow.com/questions/31771464/catch-winkeyd-key-sequence-in-winforms
Will this help us?


#5

Hi @anurocha Thanks for replying but I am new to electron. Can you please show me how can I use win.getNativeWindowHandle()


#6

i think you can just

let hwnd = win.getNativeWindowHandle()

then you can use ‘hwnd’ for another task as you wish.


#7

@anurocha Thankyou buddy you save my day, Let me implement this.


#8

@anurocha I got value : <Buffer 86 05 06 00 00 00 00 00>


#9

basically, it is the value of HWND that you can use it to your Native (C++) API.