All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.openfin.desktop.win32.WinMessageHelper Maven / Gradle / Ivy

There is a newer version: 11.0.2
Show newest version
package com.openfin.desktop.win32;

import com.openfin.desktop.*;
import com.sun.jna.Callback;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.*;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;
import org.json.JSONObject;

import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static com.sun.jna.platform.win32.WinReg.HKEY_CURRENT_USER;
import static com.sun.jna.platform.win32.WinReg.HKEY_LOCAL_MACHINE;

/**
 *
 * Helper class for hooking into Windows messages
 *
 * Created by wche on 3/11/15.
 *
 */
public class WinMessageHelper {
    private final static Logger logger = LoggerFactory.getLogger(WinMessageHelper.class.getName());

    public static CustomUser32 customUser32;
    private static Map callbackMap = Collections.synchronizedMap(new HashMap());

    static {
        try {
            customUser32 = (CustomUser32) Native.loadLibrary("user32", CustomUser32.class,
                    W32APIOptions.DEFAULT_OPTIONS);
        } catch (Exception e) {
            logger.error("Error initializing user32 lib", e);
        }
    }

    /**
     * Makes a connection between messages on a specified window handle
     * and the callback to be called when messages are received.
     *
     * @param hwnd HWND of the window
     * @param callback callback for each message
     *
     */
    public static void hookWndProc(WinDef.HWND hwnd, WindowProcCallback callback) {
        logger.debug("hookWndProc" + hwnd);
        CustomWindowProc customWindowProc = new CustomWindowProc() {
            @Override
            public WinDef.LRESULT callback(WinDef.HWND hwnd, int uMsg, WinDef.WPARAM wParam, Pointer lParam) {
                logger.debug("callback uMsg " + uMsg);
                HookProcInfo hpi = callbackMap.get(hwnd);
                if (hpi != null) {
                    boolean handled = hpi.winProcCallback.callback(hwnd, uMsg, wParam, lParam);
                    if (!handled) {
                        return customUser32.CallWindowProc(hpi.prevWndProc, hwnd, uMsg, wParam, lParam);
                    } else {
                        logger.debug("uMsg handled " + uMsg);
                        return new WinDef.LRESULT(1) ;
                    }
                } else {
                    logger.debug("custom windowproc missing. calling default");
                    return customUser32.DefWindowProc(hwnd, uMsg, wParam, lParam);
                }
            }
        };

        Pointer prev;
        if (Platform.is64Bit()) {
            logger.debug("installing 64b WNDPROC " + customWindowProc);
            prev = customUser32.SetWindowLongPtr(hwnd, User32.GWL_WNDPROC, customWindowProc);
        } else {
            logger.debug("installing WNDPROC " + customWindowProc);
            prev = customUser32.SetWindowLong(hwnd, User32.GWL_WNDPROC, customWindowProc);
        }
        logger.debug("saving WNDPROC " + prev);

        HookProcInfo info = new HookProcInfo();
        info.hwnd = hwnd;
        info.prevWndProc = prev;
        info.winProcCallback = callback;
        info.customWindowProc = customWindowProc;
        callbackMap.put(hwnd, info);
    }

    /**
     * Removes the WindowProc and restores previous one
     *
     * @param hwnd HWND of the window
     */
    public static void unhookWndProc(WinDef.HWND hwnd) {
        logger.debug("unhookWndProc" + hwnd);
        HookProcInfo hpi = callbackMap.get(hwnd);
        if (hpi != null) {
            if (Platform.is64Bit()) {
                logger.debug("installing 64b WNDPROC " + hpi.prevWndProc);
                User32.INSTANCE.SetWindowLongPtr(hwnd, User32.GWL_WNDPROC, hpi.prevWndProc);
            } else {
                logger.debug("installing WNDPROC " + hpi.prevWndProc);
                customUser32.SetWindowLong(hwnd, User32.GWL_WNDPROC, hpi.prevWndProc);
            }
            callbackMap.remove(hwnd);
        }
    }

    public static void embedInto(final long parentHwndId, final long childHwndId, final int width, final int height, final AckListener callback) {
        embedInto(parentHwndId, childHwndId, 0,0, width, height, callback);
    }

    /**
     * Embeds a window in a target hWin
     *
     * @param parentHwndId Parent window handle
     * @param childHwndId Child window handle
     * @param left The new position of the left side of the window.
     * @param top  The new position of the top of the window.
     * @param width The change in the width of the window
     * @param height The change in the height of the window
     * @param callback callback for each messag
     *                 e
     */
    public static void embedInto(final long parentHwndId, final long childHwndId, final int left, final int top,
                                 final int width, final int height, final AckListener callback) {
        logger.debug("embedInto" + parentHwndId);
        try {
            Pointer p = Pointer.createConstant(childHwndId);
            WinDef.HWND childHwnd = new WinDef.HWND(p);
            WinDef.HWND parentHwnd = new WinDef.HWND(new Pointer(parentHwndId));
            
            logger.debug("SetWindowLong " + childHwnd + " to " + parentHwnd);
            int style = User32.INSTANCE.GetWindowLong(childHwnd, User32.GWL_STYLE);
            style = style & ~(User32.WS_POPUP);
            style = style | User32.WS_CHILD;
            User32.INSTANCE.SetWindowLong(childHwnd, User32.GWL_STYLE,style);
            
            logger.debug("SetParent " + childHwnd + " to " + parentHwnd);
            final WinDef.HWND prevParent = User32.INSTANCE.SetParent(childHwnd, parentHwnd);

            logger.debug("MoveWindow " + " (" + width + "," + height + ")");
            User32.INSTANCE.MoveWindow(childHwnd, left, top, width, height, true);

            if (callback != null) {
                JSONObject msg = new JSONObject();
                msg.put("success", Boolean.TRUE);
                msg.put("hWndPreviousParent", Pointer.nativeValue(prevParent.getPointer()));
                DesktopUtils.successAck(callback, new Ack(msg, childHwnd));
            }
        } catch (Exception e) {
            logger.error("Error embedding window", e);
            if (callback != null) {
                JSONObject msg = new JSONObject();
                msg.put("success", Boolean.FALSE);
                DesktopUtils.errorAck(callback, new Ack(msg, childHwndId));
            }
        }
    }

    public static void embededViewSizeChange(final long parentHwndId, final long childHwndId, final int width, final int height) {
        embededViewSizeChange(parentHwndId, childHwndId, 0, 0, width, height);
    }
    public static void embededViewSizeChange(final long parentHwndId, final long childHwndId, final int left, final int top,
                                             final int width, final int height) {
        logger.debug("MoveWindow " + " (" + left + "," + top + "," + width + "," + height + ")");
        Pointer p = Pointer.createConstant(childHwndId);
        WinDef.HWND childHwnd = new WinDef.HWND(p);
        User32.INSTANCE.MoveWindow(childHwnd, left, top, width, height, true);
    }

    /**
     * Support different signature of callback in WinUser.WindowProc
     */
    private static interface CustomWindowProc extends Callback {
        WinDef.LRESULT callback(WinDef.HWND hwnd, int uMsg, WinDef.WPARAM wParam, Pointer lParam);
    }

    /**
     * Support different signature of User32
     */
    public static interface CustomUser32 extends StdCallLibrary {
        public int GWL_HWNDPARENT = -8;
        public Pointer SetWindowLong(WinDef.HWND hwnd, int index, CustomWindowProc newProc);
        public Pointer SetWindowLong(WinDef.HWND hWnd, int nIndex, Pointer dwNewPtr);
        public Pointer SetWindowLongPtr(WinDef.HWND hwnd, int index, CustomWindowProc newProc);
        public WinDef.LRESULT CallWindowProc(Pointer proc, WinDef.HWND hWnd, int uMsg, WinDef.WPARAM uParam, Pointer lParam);
        public WinDef.LRESULT DefWindowProc(WinDef.HWND hWnd, int Msg, WinDef.WPARAM wParam, Pointer lParam);

        public boolean GetCursorPos(WinDef.POINT point);

        public boolean ChangeWindowMessageFilterEx(WinDef.HWND hWnd, int Msg, WinDef.DWORD action, Pointer lParam);
    }

    /**
     *  This class remember old WindowProc so it can be restored
     */
    private static class HookProcInfo {
        public WinDef.HWND hwnd;
        public Pointer prevWndProc;
        public WindowProcCallback winProcCallback;
        public CustomWindowProc customWindowProc;
    }

    public static String registryUserGetStringValue(String key, String valueName) {
        String value = null;
        try {
            value = Advapi32Util.registryGetStringValue(WinReg.HKEY_CURRENT_USER, key, valueName);
        } catch (Exception ex) {
            logger.debug(String.format("Error reading registry %s %s", key, valueName), ex);
        }
        return value;
    }

    public static void main(String[] argv) {
        try {
//            java.lang.System.out.println(Advapi32Util.registryGetStringValue(HKEY_LOCAL_MACHINE, "SOFTWARE\\Policies\\OpenFin\\AutoSelectCertificateForUrls"));

//            WinReg.HKEYByReference phkKey = Advapi32Util.registryGetKey(WinReg.HKEY_CURRENT_USER, "SOFTWARE\\OpenFin\\RVM\\Settings", WinNT.KEY_READ | WinNT.KEY_WOW64_32KEY);
//            String[] value = Advapi32Util.registryGetKeys(phkKey.getValue(), "cleanUnusedRuntimes");
//            java.lang.System.out.println(value);
//            java.lang.System.out.println(Advapi32Util.registryGetStringValue(HKEY_CURRENT_USER, "SOFTWARE\\OpenFin\\RVM", "cleanUnusedRuntimes"));

            final String cpuRegistryRoot = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor";
            String[] processorIds = Advapi32Util.registryGetKeys(WinReg.HKEY_LOCAL_MACHINE, cpuRegistryRoot);
            String processorId = processorIds[0];
            String cpuRegistryPath = cpuRegistryRoot + "\\" + processorId;
            java.lang.System.out.println(Advapi32Util.registryGetStringValue(WinReg.HKEY_LOCAL_MACHINE, cpuRegistryPath, "ProcessorNameString").trim());

            String settings = "SOFTWARE\\OpenFin\\RVM\\Settings";
            java.lang.System.out.println(Advapi32Util.registryGetIntValue(WinReg.HKEY_CURRENT_USER, settings, "cleanUnusedRuntimes"));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy