0

Alright, to give you a bit of background, I have a JFrame that I've manipulated to be a full screen transparent overlay when the user types a keystroke on the keyboard.

The goal is I want the user to select any previously opened window (so could be the web browser you're using now) to then further manipulate with my program. I have the overlay working with a global keystroke managed with JIntellitype and Swing's nifty extended state method for full screen...ness.

The problem I have is that even with the really nice-looking overlay that appears the way I want, you cannot select any of your windows because the JFrame is over them. I need it to be like what ScreenCloud has with their screenshot selection (look at 0:19 on their video), but the user just needs to click on a window when the overlay/message appears.

I'm looking into JNA for getting the window sizes and other info for later use in my application. I'm open for any ideas on how to go about this. Worst case scenario would be that I do something that you would see on your CTRL-ALT-Tab window switcher for selecting a window.

Note: If it helps at all, I'm using a TrayIcon for my application to be centered around, which then calls and creates JFrames and such.

Kevin Thorne
  • 435
  • 5
  • 19

1 Answers1

0

For the future, if anyone (which I doubt anyone) runs into this problem, have JNA grab the rectangle for each window and in the order in which they're layered (e.g. "File Manager" - (0,0)(250,250) , "Eclipse" - (0,0)(1920,1080) -- this saying the window "File Manager" is on top). Then have the JFrame listen for a mouse click event on its frame; Use those coordinates to find any collisions with the rectangles you generated with JNA. Code example for those who would like it (the JNA side of it):

public static List<WindowInfo> getWindows() {
    final List<WindowInfo> inflList = new ArrayList<WindowInfo>();
    final List<Integer> order = new ArrayList<Integer>();
    int top = User32.instance.GetTopWindow(0);
    while (top!=0) {
        order.add(top);
        top = User32.instance.GetWindow(top, User32.GW_HWNDNEXT);
    }
    User32.instance.EnumWindows(new WndEnumProc()
    {
        @Override
        public boolean callback(int hWnd, int lParam)
        {
            if (User32.instance.IsWindowVisible(hWnd)) {
                RECT r = new RECT();
                User32.instance.GetWindowRect(hWnd, r);
                if (r.left>-32000) {     // minimized
                    byte[] buffer = new byte[1024];
                    User32.instance.GetWindowTextA(hWnd, buffer, buffer.length);
                    String title = Native.toString(buffer);
                    inflList.add(new WindowInfo(hWnd, r, title));
                }
            }
            return true;
        }
    }, 0);
    Collections.sort(inflList, new Comparator<WindowInfo>()
            {
        @Override
        public int compare(WindowInfo o1, WindowInfo o2) {
            return order.indexOf(o1.hwnd)-order.indexOf(o2.hwnd);
        }
            });
    return inflList;
}
public static interface WndEnumProc extends StdCallLibrary.StdCallCallback {
    boolean callback (int hWnd, int lParam);
}

public static interface User32 extends StdCallLibrary
{
    final User32 instance = (User32) Native.loadLibrary ("user32", User32.class);
    User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class,
               W32APIOptions.DEFAULT_OPTIONS);
    boolean EnumWindows (WndEnumProc wndenumproc, int lParam);
    boolean IsWindowVisible(int hWnd);
    int GetWindowRect(int hWnd, RECT r);
    void GetWindowTextA(int hWnd, byte[] buffer, int buflen);
    int GetTopWindow(int hWnd);
    int GetWindow(int hWnd, int flag);

    HWND FindWindow(String lpClassName, String lpWindowName);

    final int GW_HWNDNEXT = 2;
}

Note as this is for Windows (as seen by the User32 class). The class WindowInfo holds the rectangle, title, and handle for each window. This is then thrown back to the MouseListener.

EDIT: Found it here https://stackoverflow.com/a/3238193/3502776

Community
  • 1
  • 1
Kevin Thorne
  • 435
  • 5
  • 19