ChesTeRcs 5 ani în urmă
părinte
comite
7528185c7b

+ 0 - 14
.gitignore

@@ -1,14 +0,0 @@
-# ---> Java
-*.class
-
-# Mobile Tools for Java (J2ME)
-.mtj.tmp/
-
-# Package Files #
-*.jar
-*.war
-*.ear
-
-# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
-hs_err_pid*
-

+ 0 - 3
README.md

@@ -1,3 +0,0 @@
-# anti-afk
-
-Universal anti-afk solution

+ 22 - 0
build.gradle

@@ -0,0 +1,22 @@
+apply plugin: 'base'
+apply plugin: 'java'
+apply plugin: 'eclipse'
+apply plugin: 'idea'
+
+group 'chestercs'
+version '1.0-SNAPSHOT'
+sourceCompatibility = 1.8
+
+repositories {
+    mavenCentral()
+    jcenter()
+    maven {
+        url 'https://plugins.gradle.org/m2/'
+    }
+}
+
+dependencies {
+    compile group: 'net.java.dev.jna', name: 'jna-platform', version: '4.1.0'
+    compile group: 'org.jvnet.com4j', name: 'com4j', version: '2.1'
+    compile group: 'com.nativelibs4java', name: 'bridj', version: '0.7.0'
+}

+ 172 - 0
gradlew

@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+    echo "$*"
+}
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+  cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"

+ 84 - 0
gradlew.bat

@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

+ 4 - 0
settings.gradle

@@ -0,0 +1,4 @@
+rootProject.name = 'anti-afk'
+include 'java'
+findProject(':java')?.name = 'anti-afk'
+

+ 114 - 0
src/main/java/AntiAfk.java

@@ -0,0 +1,114 @@
+import com.sun.jna.Pointer;
+import timeUntil.TimeUntil;
+import user32util.User32Util;
+
+import java.awt.*;
+import java.awt.event.KeyEvent;
+import java.time.Instant;
+
+public class AntiAfk {
+    private Robot robot;
+    private final TimeUntil timeUntil = new TimeUntil();
+
+    // Config
+    private String windowTitle = "Sea of Thieves"; // Target process title.
+    private Integer afkTimerInMs = 5000; // AntiAfk repeat cycle in ms.
+    private int antiAfkKey = KeyEvent.VK_ENTER; // Key to antiAfk.
+
+    // Global
+    private Instant timeWhenAfkHappened = timeUntil.getNowInInstant().minusMillis(afkTimerInMs);
+    private Integer clock = 1000;
+
+
+    public static void main(String[] args) {
+        AntiAfk antiAfk = new AntiAfk();
+        antiAfk.start();
+    }
+
+
+    // Entry Point
+    public void start() {
+        try {
+            robot = new Robot();
+
+            do {
+                if (windowExists(windowTitle)) {
+
+                    if (timeUntil.calcBetween(timeWhenAfkHappened) >= afkTimerInMs) {
+                        if (getActiveWindow().equals(getWindowPointer(windowTitle))) {
+                            antiAfk(antiAfkKey);
+                        } else {
+                            System.out.println("Need to tab");
+                            Pointer lastWindow = getActiveWindow();
+                            setActivateWindow(windowTitle);
+                            Thread.sleep(100);
+                            antiAfk(antiAfkKey);
+                            Thread.sleep(300);
+                            System.out.println(setActivateWindow(lastWindow));
+                        }
+                    }
+
+                    System.out.println("Last AntiAfk: " + timeUntil.calcBetween(timeWhenAfkHappened));
+                    Thread.sleep(clock);
+                } else {
+                    System.out.println("Not running: " + windowTitle);
+                }
+                Thread.sleep(clock);
+            } while (true);
+        } catch (AWTException | InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public boolean windowExists(String windowTitle) {
+        return User32Util.windowExists(windowTitle);
+    }
+
+    public Pointer getWindowPointer(String windowTitle) {
+        return User32Util.getWinHwnd(windowTitle);
+    }
+
+    public Pointer getActiveWindow() {
+        return User32Util.getForegroundWindow();
+    }
+
+    public boolean setActivateWindow(String windowTitle) {
+        Pointer windowPointer = getWindowPointer(windowTitle);
+        User32Util.setForegroundWindow(windowPointer);
+        return winWaitActive(windowPointer);
+    }
+
+    public boolean setActivateWindow(Pointer windowPointer) {
+        return User32Util.setForegroundWindow(windowPointer);
+    }
+
+    public void antiAfk(int antiAfkKeyParam) {
+        sendKey(antiAfkKey, 100);
+        timeWhenAfkHappened = timeUntil.getNowInInstant();
+        System.out.println("AntiAfk sent.");
+    }
+
+    public void sendKey(int key, int keyDown) {
+        try {
+            robot.keyPress(key);
+            Thread.sleep(keyDown);
+            robot.keyRelease(key);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public boolean winWaitActive(Pointer winProcesstoBeActive) {
+        if (winProcesstoBeActive == null) return false;
+        try {
+            Instant whenSettingStarted = timeUntil.getNowInInstant();
+            while (!getActiveWindow().equals(winProcesstoBeActive)) {
+                Thread.sleep(20);
+                if (timeUntil.calcBetween(whenSettingStarted) >= 8000) return false;
+            }
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+        return true;
+    }
+}

+ 17 - 0
src/main/java/timeUntil/TimeUntil.java

@@ -0,0 +1,17 @@
+package timeUntil;
+
+import java.time.Duration;
+import java.time.Instant;
+
+public class TimeUntil {
+    public long calcBetween(Instant event) {
+        if (event == null) return 0;
+        Instant now = Instant.now();
+        Duration diff = Duration.between(event, now);
+        return diff.toMillis();
+    }
+
+    public Instant getNowInInstant() {
+        return Instant.now();
+    }
+}

+ 124 - 0
src/main/java/user32util/User32Ex.java

@@ -0,0 +1,124 @@
+package user32util;
+
+import com.sun.jna.Callback;
+import com.sun.jna.Native;
+import com.sun.jna.Pointer;
+import com.sun.jna.platform.win32.BaseTSD.LONG_PTR;
+import com.sun.jna.platform.win32.WinDef.*;
+import com.sun.jna.platform.win32.WinUser.WNDENUMPROC;
+import com.sun.jna.ptr.PointerByReference;
+import com.sun.jna.win32.W32APIOptions;
+
+public interface User32Ex extends W32APIOptions {
+    User32Ex instance = (User32Ex) Native.loadLibrary("user32", User32Ex.class, DEFAULT_OPTIONS);
+
+    int SetWindowLongPtr(HWND hWnd, int nIndex, Callback callback);
+
+    LRESULT CallWindowProc(LONG_PTR proc, HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam);
+
+    boolean ShowWindow(HWND hWnd, int nCmdShow);
+
+    boolean SetForegroundWindow(HWND hWnd);
+
+    void SwitchToThisWindow(HWND hWnd, boolean fAltTab);
+
+    HWND SetFocus(HWND hWnd);
+
+    HWND FindWindow(String winClass, String title);
+
+    LRESULT PostMessage(HWND hWnd, int Msg, WPARAM wParam, LPARAM lParam);
+
+    LRESULT SendMessage(HWND hWnd, int Msg, WPARAM wParam, LPARAM lParam);
+
+    LRESULT SendMessageA(HWND editHwnd, int wmGettext, long l, byte[] lParamStr);
+
+    boolean DestroyWindow(HWND hWnd);
+
+    boolean EnumWindows(WNDENUMPROC wndenumproc, int lParam);
+
+    boolean EnumChildWindows(HWND hWnd, WNDENUMPROC lpEnumFunc, Pointer data);
+
+    HWND GetParent(HWND hWnd);
+
+    boolean IsWindowVisible(HWND hWnd);
+
+    boolean IsWindow(HWND hWnd);
+
+    int GetWindowRect(HWND hWnd, RECT r);
+
+    int MapWindowPoints(HWND hWndFrom, HWND hWndTo, RECT r, int cPoints);
+
+    HWND GetDesktopWindow();
+
+    HDC GetWindowDC(HWND hWnd);
+
+    int ReleaseDC(HWND hWnd, HDC hDC);
+
+    boolean InvalidateRect(HWND hWnd, long lpRect, boolean bErase);
+
+    boolean UpdateWindow(HWND hWnd);
+
+    boolean RedrawWindow(HWND hWnd, long lprcUpdate, long hrgnUpdate, int flags);
+
+    void GetWindowTextA(HWND hWnd, byte[] buffer, int buflen);
+
+    int GetTopWindow(HWND hWnd);
+
+    int GetWindow(HWND hWnd, int flag);
+
+    final int GW_HWNDNEXT = 2;
+
+    int GetClassName(HWND hWnd, char[] buffer2, int i);
+
+    int GetWindowModuleFileName(HWND hWnd, char[] buffer2, int i);
+
+    int GetWindowThreadProcessId(HWND hWnd, PointerByReference pref);
+
+    // int GetWindowThreadProcessId(HWND hWnd, IntByReference
+    // lpdwProcessId);
+
+    boolean GetCursorPos(long[] lpPoint); // use macros POINT_X() and
+    // POINT_Y() on long lpPoint[0]
+
+    HWND WindowFromPoint(long point);
+
+    HWND ChildWindowFromPointEx(HWND hwndParent, long point, int uFlags);
+
+    boolean ClientToScreen(HWND hWnd, POINT lpPoint);// use macros
+    // POINT_X() and
+    // POINT_Y() on long
+    // lpPoint[0]
+
+    boolean ScreenToClient(HWND hWnd, long[] lpPoint);// use macros
+    // POINT_X() and
+    // POINT_Y() on long
+    // lpPoint[0]
+    // HWND WindowFromPoint(int xPoint, int yPoint);
+    // HWND WindowFromPoint(POINT point);
+
+    HMENU GetMenu(HWND hWnd);
+
+    HMENU GetSystemMenu(HWND hWnd, boolean bRevert);
+
+    boolean IsMenu(HMENU hMenu);
+
+    int GetMenuString(HMENU hMenu, int uIDItem, char[] buffer, int nMaxCount, int uFlag);
+
+    HMENU GetSubMenu(HMENU hMenu, int nPos);
+
+    int GetMenuItemCount(HMENU hMenu);
+
+    int GetMenuItemID(HMENU hMenu, int nPos);
+
+    boolean TrackPopupMenu(HMENU hMenu, int uFlags, int x, int y, int nReserved, HWND hWnd, long prcRect);
+
+    boolean GetMenuItemRect(HWND hWnd, HMENU hMenu, int uItem, RECT rect);
+
+    int GetDlgCtrlID(HWND hwndCtl);
+
+    int GetDlgItemText(HWND hDlg, int nIDDlgItem, byte[] buffer, int nMaxCount);
+
+    int GetMenuState(HMENU hMenuTopMenu, int uId, int uFlags);
+
+    HWND GetDlgItem(HWND hDlg, int nIDDlgItem);
+}

+ 55 - 0
src/main/java/user32util/User32Instance.java

@@ -0,0 +1,55 @@
+package user32util;
+
+import com.sun.jna.Native;
+import com.sun.jna.Pointer;
+import com.sun.jna.platform.win32.BaseTSD;
+import com.sun.jna.platform.win32.WinDef;
+import com.sun.jna.win32.StdCallLibrary;
+
+public interface User32Instance extends StdCallLibrary {
+    User32Instance INSTANCE = (User32Instance) Native.loadLibrary("user32", User32Instance.class);
+
+    interface WNDENUMPROC extends StdCallCallback {
+        boolean callback(Pointer hWnd, Pointer arg);
+    }
+
+    public static final int GW_OWNER = 4; // used with GetWindow to get win owner
+    public static final int GW_HWNDNEXT = 2; // used with GetNextWindow
+    public static final int GA_ROOT = 2; // used with GetAncestor
+    public static final int GWL_EXSTYLE = -20; // used with GetWindowLong
+    public static final long WS_EX_APPWINDOW = 0x00040000L;
+    public static final Pointer HWND_TOP = new Pointer(0L); // used with
+    // SetWindowPos
+
+    boolean EnumWindows(User32Instance.WNDENUMPROC lpEnumFunc, Pointer userData);
+
+    int GetWindowTextA(Pointer hWnd, byte[] lpString, int nMaxCount);
+
+    int SetForegroundWindow(Pointer hWnd);
+
+    Pointer GetForegroundWindow();
+
+    boolean GetWindowRect(Pointer hWnd, WinDef.RECT rect);
+    boolean GetClientRect(WinDef.HWND hWnd, WinDef.RECT rect);
+    boolean ClientToScreen(WinDef.HWND hWnd, WinDef.POINT pt);
+
+    boolean SetWindowPos(Pointer hWnd, Pointer hWndInsertAfter, int x, int y,
+                         int cx, int cy, int uFlags);
+
+    boolean MoveWindow(Pointer hWnd, int x, int y, int nWidth, int nHeight, boolean bRepaint);
+
+    boolean IsWindow(Pointer hWnd);
+
+    Pointer GetWindow(Pointer hWnd, int uCmd);
+
+    BaseTSD.LONG_PTR GetWindowLongPtr(WinDef.HWND hWnd, int nIndex);
+
+    Pointer GetParent(Pointer hWnd);
+
+    Pointer GetAncestor(Pointer hWnd, int gaFlags);
+
+    boolean IsWindowVisible(Pointer hWnd);
+
+    WinDef.HDC GetDC(WinDef.HWND hWnd);
+    WinDef.HDC GetWindowDC(WinDef.HWND hWnd);
+}

+ 232 - 0
src/main/java/user32util/User32Util.java

@@ -0,0 +1,232 @@
+package user32util;
+
+import com.sun.jna.Native;
+import com.sun.jna.Pointer;
+import com.sun.jna.platform.win32.BaseTSD;
+import com.sun.jna.platform.win32.User32;
+import com.sun.jna.platform.win32.WinDef;
+
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * static methods to allow Java to call Windows code. user32.dll code is as
+ * specified in the JNA interface User32.java
+ */
+
+public class User32Util {
+    private static final User32Instance USER_32_INSTANCE = User32Instance.INSTANCE;
+    private static Pointer callBackHwnd;
+
+    public static boolean windowExists(final String startOfWindowName) {
+        return !USER_32_INSTANCE.EnumWindows(new User32Instance.WNDENUMPROC() {
+            @Override
+            public boolean callback(Pointer hWnd, Pointer userData) {
+                byte[] windowText = new byte[512];
+                USER_32_INSTANCE.GetWindowTextA(hWnd, windowText, 512);
+                String wText = Native.toString(windowText).trim();
+
+                if (!wText.isEmpty() && wText.startsWith(startOfWindowName)) {
+                    return false;
+                }
+                return true;
+            }
+        }, null);
+    }
+
+    public static List<String> getAllWindowNames() {
+        final List<String> windowNames = new ArrayList<String>();
+        USER_32_INSTANCE.EnumWindows(new User32Instance.WNDENUMPROC() {
+
+            @Override
+            public boolean callback(Pointer hWnd, Pointer arg) {
+                byte[] windowText = new byte[512];
+                USER_32_INSTANCE.GetWindowTextA(hWnd, windowText, 512);
+                String wText = Native.toString(windowText).trim();
+                if (!wText.isEmpty()) {
+                    windowNames.add(wText);
+                }
+                return true;
+            }
+        }, null);
+
+        return windowNames;
+    }
+
+    public static boolean windowExists(Pointer hWnd) {
+        return USER_32_INSTANCE.IsWindow(hWnd);
+    }
+
+    public static Pointer getWinHwnd(final String startOfWindowName) {
+        callBackHwnd = null;
+
+        USER_32_INSTANCE.EnumWindows(new User32Instance.WNDENUMPROC() {
+            @Override
+            public boolean callback(Pointer hWnd, Pointer userData) {
+                byte[] windowText = new byte[512];
+                USER_32_INSTANCE.GetWindowTextA(hWnd, windowText, 512);
+                String wText = Native.toString(windowText).trim();
+
+                if (!wText.isEmpty() && wText.startsWith(startOfWindowName)) {
+                    callBackHwnd = hWnd;
+                    return false;
+                }
+                return true;
+            }
+        }, null);
+        return callBackHwnd;
+    }
+
+    public static boolean setForegroundWindow(Pointer hWnd) {
+        return USER_32_INSTANCE.SetForegroundWindow(hWnd) != 0;
+    }
+
+    public static Pointer getForegroundWindow() {
+        return USER_32_INSTANCE.GetForegroundWindow();
+    }
+
+    public static String getForegroundWindowText() {
+        Pointer hWnd = getForegroundWindow();
+        int nMaxCount = 512;
+        byte[] lpString = new byte[nMaxCount];
+        int getWindowTextResult = USER_32_INSTANCE
+                .GetWindowTextA(hWnd, lpString, nMaxCount);
+        if (getWindowTextResult == 0) {
+            return "";
+        }
+
+        return Native.toString(lpString);
+    }
+
+    public static boolean isForegroundWindow(Pointer hWnd) {
+        return USER_32_INSTANCE.GetForegroundWindow().equals(hWnd);
+    }
+
+    public static boolean setForegroundWindow(String startOfWindowName) {
+        Pointer hWnd = getWinHwnd(startOfWindowName);
+        return USER_32_INSTANCE.SetForegroundWindow(hWnd) != 0;
+    }
+
+    public static Rectangle getClientRect(WinDef.HWND hWnd) throws User32UtilException {
+        if (hWnd == null) {
+            throw new User32UtilException(
+                    "Failed to getWindowRect since Pointer hWnd is null");
+        }
+        Rectangle result = null;
+        WinDef.RECT rect = new WinDef.RECT();
+        boolean rectOK = USER_32_INSTANCE.GetClientRect(hWnd, rect);
+        if (rectOK) {
+            result = rect.toRectangle();
+        }
+
+        return result;
+    }
+
+    public static Rectangle getWindowRect(Pointer hWnd) throws User32UtilException {
+        if (hWnd == null) throw new User32UtilException("Failed to getWindowRect since Pointer hWnd is null");
+        WinDef.RECT rect = new WinDef.RECT();
+        if (USER_32_INSTANCE.GetWindowRect(hWnd, rect)) return rect.toRectangle();
+        return null;
+    }
+
+    /**
+     * set window at x and y position with w and h width. Set on top of z-order
+     *
+     * @param hWnd
+     * @param x
+     * @param y
+     * @param w
+     * @param h
+     * @return boolean -- did it work?
+     */
+    public static boolean setWindowPos(Pointer hWnd, int x, int y, int w, int h) {
+        int uFlags = 0;
+        return USER_32_INSTANCE.SetWindowPos(hWnd, User32Instance.HWND_TOP, x, y, w, h, uFlags);
+    }
+
+    public static boolean moveWindow(Pointer hWnd, int x, int y, int nWidth,
+                                     int nHeight) {
+        boolean bRepaint = true;
+        return USER_32_INSTANCE.MoveWindow(hWnd, x, y, nWidth, nHeight, bRepaint);
+    }
+
+    public static Rectangle getClientRect(String startOfWindowName) throws User32UtilException {
+        WinDef.HWND hWnd = User32.INSTANCE.FindWindow(null, startOfWindowName);
+        WinDef.POINT getPos = new WinDef.POINT();
+        WinDef.RECT rect = new WinDef.RECT();
+        User32Instance.INSTANCE.GetClientRect(hWnd, rect);
+        User32Ex.instance.ClientToScreen(hWnd, getPos);
+
+        return new Rectangle(getPos.x, getPos.y, rect.right, rect.bottom);
+    }
+
+    public static Rectangle getWindowRect(String startOfWindowName)
+            throws User32UtilException {
+        Pointer hWnd = getWinHwnd(startOfWindowName);
+        if (hWnd != null) {
+            return getWindowRect(hWnd);
+        } else {
+            throw new User32UtilException("Failed to getWindowRect for \""
+                    + startOfWindowName + "\"");
+        }
+    }
+
+    public static Pointer getWindow(Pointer hWnd, int uCmd) {
+        return USER_32_INSTANCE.GetWindow(hWnd, uCmd);
+    }
+
+    public static String getWindowText(Pointer hWnd) {
+        int nMaxCount = 512;
+        byte[] lpString = new byte[nMaxCount];
+        int result = USER_32_INSTANCE.GetWindowTextA(hWnd, lpString, nMaxCount);
+        if (result == 0) {
+            return "";
+        }
+        return Native.toString(lpString);
+    }
+
+    public static Pointer getOwnerWindow(Pointer hWnd) {
+        return USER_32_INSTANCE.GetWindow(hWnd, User32Instance.GW_OWNER);
+    }
+
+    public static String getOwnerWindow(String childTitle) {
+        Pointer hWnd = getWinHwnd(childTitle);
+        Pointer parentHWnd = getOwnerWindow(hWnd);
+        if (parentHWnd == null) {
+            return "";
+        }
+        return getWindowText(parentHWnd);
+
+    }
+
+    public static Pointer getNextWindow(Pointer hWnd) {
+        if (hWnd == null) {
+            return null;
+        }
+
+        return USER_32_INSTANCE.GetWindow(hWnd, User32Instance.GW_HWNDNEXT);
+    }
+
+    public static boolean isWindowVisible(Pointer hWnd) {
+        return USER_32_INSTANCE.IsWindowVisible(hWnd);
+    }
+
+    public static Pointer getParent(Pointer hWnd) {
+        return USER_32_INSTANCE.GetParent(hWnd);
+    }
+
+    public static Pointer getRoot(Pointer hWnd) {
+        return USER_32_INSTANCE.GetAncestor(hWnd, User32Instance.GA_ROOT);
+    }
+
+    public static BaseTSD.LONG_PTR getWindowLongPtr(Pointer hWndP, int nIndex) {
+        WinDef.HWND hwnd = new WinDef.HWND(hWndP);
+        return USER_32_INSTANCE.GetWindowLongPtr(hwnd, nIndex);
+    }
+
+    public static WinDef.HDC GetWindowDC(WinDef.HWND hWnd) {
+        return USER_32_INSTANCE.GetWindowDC(hWnd);
+    }
+}
+

+ 9 - 0
src/main/java/user32util/User32UtilException.java

@@ -0,0 +1,9 @@
+package user32util;
+
+public class User32UtilException extends Throwable {
+    private static final long serialVersionUID = 1L;
+
+    public User32UtilException(String text) {
+        super(text);
+    }
+}