How to get list of all window handles in Java (Using JNA)?

24,472

The latest version of JNA has had some changes that should fix this (as one of the authors of JNA, Luke Quinane, states here). If you use the latest version and check the JNA API, you'll see that the WinUser.WNDENUMPROC interface's method actually uses WinDef.HWND as its parameter, not long or int.

For example:

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinUser;
import com.sun.jna.platform.win32.WinUser.WNDENUMPROC;
import com.sun.jna.win32.StdCallLibrary;

public class TryWithHWND {
   public interface User32 extends StdCallLibrary {
      User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class);
      boolean EnumWindows(WinUser.WNDENUMPROC lpEnumFunc, Pointer arg);
      int GetWindowTextA(HWND hWnd, byte[] lpString, int nMaxCount);
   }

   public static void main(String[] args) {
      final User32 user32 = User32.INSTANCE;
      user32.EnumWindows(new WNDENUMPROC() {
         int count = 0;
         @Override
         public boolean callback(HWND hWnd, Pointer arg1) {
            byte[] windowText = new byte[512];
            user32.GetWindowTextA(hWnd, windowText, 512);
            String wText = Native.toString(windowText);

            // get rid of this if block if you want all windows regardless of whether
            // or not they have text
            if (wText.isEmpty()) {
               return true;
            }

            System.out.println("Found window with text " + hWnd + ", total " + ++count
                  + " Text: " + wText);
            return true;
         }
      }, null);
   }
}
Share:
24,472
Ahamed
Author by

Ahamed

J2EE & Android

Updated on January 04, 2020

Comments

  • Ahamed
    Ahamed over 4 years

    I am novice for JNA. I am trying to get handles for all the windows including minimised ones. I need HWND of all the windows. I have gone thro the question Windows: how to get a list of all visible windows? which helped me to get list of windows, but it has hWnd type as int. I can't use it with com.sun.jna.platform.win32.User32 functions which asks for hWnd of type com.sun.jna.platform.win32.WinDef.HWND. So, Is there any way to get all the window handles of type com.sun.jna.platform.win32.WinDef.HWND rather than int pointer? Finally, why is the difference int and HWND? How does it accept both? I am bit confused. Thanks.

    I have the following code(edited from Hovercreft's answer):

        import com.sun.jna.Native;
        import com.sun.jna.Pointer;
        import com.sun.jna.platform.win32.User32;
        import com.sun.jna.platform.win32.WinDef.HWND;
        import com.sun.jna.platform.win32.WinDef.RECT;
        import com.sun.jna.platform.win32.WinUser.WNDENUMPROC;
    
        public class TryWithHWND {
    
        public static void main(String[] args) {
            final User32 user32 = User32.INSTANCE;
            user32.EnumWindows(new WNDENUMPROC() {
                int count = 0;
                public boolean callback(HWND hWnd, Pointer arg1) {
                    char[] windowText = new char[512];
                    user32.GetWindowText(hWnd, windowText, 512);
                    String wText = Native.toString(windowText);
                    RECT rectangle = new RECT();
                    user32.GetWindowRect(hWnd, rectangle);
                    // get rid of this if block if you want all windows regardless
                    // of whether
                    // or not they have text
                    // second condition is for visible and non minimised windows
                    if (wText.isEmpty() || !(User32.INSTANCE.IsWindowVisible(hWnd)
                            && rectangle.left > -32000)) {
                        return true;
                    }
                    System.out.println("Found window with text " + hWnd
                            + ", total " + ++count + " Text: " + wText);
                    return true;
                }
            }, null);
        }
    }
    

    I tried to use only(not custom interface) the default User32 class. It is working fine. I have doubt, why we are using userdefined interface instead of already existing one? One more thing, There is always difference between userdefined method signature and already existing ones. For instance, the variable windowText is char[], whereas Hovercraft's variable is of type byte[]. Can anyone explain me? Thanks.

  • Ahamed
    Ahamed over 12 years
    Thanks a lot! I have added my code (edited from yours) in my question. Could you please help me understand more? Thanks again.
  • Ahamed
    Ahamed over 12 years
    HWND is cleared. Why default User32 has char[] as param but the one you have defined is having byte[]?
  • technomage
    technomage over 12 years
    If accessing the unicode version of a method (SomeFunctionW), you must use char[] for LPTCHAR parameters; if using the ascii version (SomeFunctionA), you must use byte[]. The MS headers automatically map "SomeFunction" to either "SomeFunctionW" or "SomeFunctionA" depending on whether UNICODE is defined; JNA accomplishes the same thing depending on the options passed to Native.loadLibrary. You may also explicitly use an "A" or "W" suffix as in the above example.