B4J Question Getting Foreground Window Position, Size and others, all methods (jna-user32)

Magma

Expert
Licensed User
Longtime User
Well.. in my searching trying to do more with Windows app's and B4X - i want to get the Foreground Window's Position, Size (for start)

And because it is not good start over and over new thread for the same thing - let's make it as default place for all methods have relationship if needed... :)

B4X:
Sub Process_Globals
    Type rect(Bottom As Int,Left As Int,Right As Int,Top As Int)

...
    Dim user32 As JavaObject
    user32 = user32.InitializeStatic("com.sun.jna.platform.win32.User32").GetField("INSTANCE")
   
    Dim hwnd1 As JavaObject = user32.RunMethod("GetForegroundWindow",Null)

    Dim arect As rect
    user32.runmethod("GetWindowRect",Array(hwnd1,arect))
   
    Dim title(512) As Char
    user32.RunMethod("GetWindowText", Array(hwnd1,title,512))
    Dim native As JavaObject
    Dim activewindowtitle As String = native.InitializeStatic("com.sun.jna.Native").RunMethod("toString", Array(title))
    activewindowtitle = activewindowtitle.Trim
    Log(activewindowtitle)

    Log(arect.Left)

Where am i wrong ?

I am getting that:
java.lang.RuntimeException: Method: GetWindowRect not matched.

SOLVED specific that - at this post by stevel05

Have in mind trying to do all that with OpenJDK.. Thanks for help !
 
Last edited:

stevel05

Expert
Licensed User
Longtime User
Try this:

B4X:
#Region Project Attributes
    #MainFormWidth: 600
    #MainFormHeight: 600
#End Region

' or whichever version you are using
#AdditionalJar: jna-5.5.0 
#AdditionalJar: jna-platform-5.5.0 

Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Private xui As XUI
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.RootPane.LoadLayout("Layout1")
    MainForm.Show
    MainForm.WindowLeft = 1000
 
    Sleep(0) 'Just gives the window time to reposition before reading
    Dim user32 As JavaObject
    user32 = user32.InitializeStatic("com.sun.jna.platform.win32.User32").GetField("INSTANCE")
 
    Dim hwnd1 As JavaObject = user32.RunMethod("GetForegroundWindow",Null)

    Dim Rect As JavaObject
    Rect.InitializeNewInstance("com.sun.jna.platform.win32.WinDef.RECT",Null)
    user32.runmethod("GetWindowRect",Array(hwnd1,Rect))
 
    Dim title(512) As Char
    user32.RunMethod("GetWindowText", Array(hwnd1,title,512))
    Dim native As JavaObject
    Dim activewindowtitle As String = native.InitializeStatic("com.sun.jna.Native").RunMethod("toString", Array(title))
    activewindowtitle = activewindowtitle.Trim
    Log(activewindowtitle)

    Log("Left " & Rect.GetField("left"))
End Sub
 
Last edited:
Upvote 0

Magma

Expert
Licensed User
Longtime User
Well i ve been working for a better solution... found some java snippets... that may be help me for end it faster...

so if i want to work with injava - the same thing...

B4X:
...
    Dim jo As JavaObject

    jo.InitializeNewInstance("b4j.example.main$GetForeWinRect", Null)

    Dim gRect As JavaObject
    gRect.InitializeNewInstance("com.sun.jna.platform.win32.WinDef.RECT",Null) 'LETs make a jna-user32 rect

    jo.RunMethod("RECT111", gRect)  'full the readable gRect with values of foreground window or null :-(
    Log(gRect.GetField("left"))

...
#If JAVA
import com.sun.jna.Native;
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;
import com.sun.jna.win32.StdCallLibrary;

public class GetForeWinRect{

    public RECT RECT111() {
        try {
            HWND hwnd = User32.INSTANCE.GetForegroundWindow();
            RECT rect = new RECT();
            User32.INSTANCE.GetWindowRect(hwnd, rect);
               return rect;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
   
}
#End If


Why am I getting error... ?
java.lang.InstantiationException: b4j.example.main$GetForeWinRect
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
The code in my post 4 is working, why do you want to complicate it?

that may be help me for end it faster
I would be surprised if there is a meaningful speed improvement running the inline java over using javaobject.

There are a few errors in your java code.

1) You are creating a class, but not a constructor for the class, therefore the new instance method fails.
2) you don't need the class in the first place, you can use a static method.
3) you are trying to pass a variable to a method that does not accept a parameter.

I am not a Java expert, but this code runs:

In the calling sub:

B4X:
Dim Jo As JavaObject = Me

Dim gRect As JavaObject = Jo.RunMethod("RECT111",Null)  'full the readable gRect with values of foreground window or null :-(
Log("Left1 " & gRect.GetField("left"))


Java Block
B4X:
#If JAVA
import com.sun.jna.Native;
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;
import com.sun.jna.win32.StdCallLibrary;

    public static RECT RECT111() {
        try {
            HWND hwnd = User32.INSTANCE.GetForegroundWindow();
            RECT rect = new RECT();
            User32.INSTANCE.GetWindowRect(hwnd, rect);
               return rect;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

}
#End If

I use javaobject 99% of the time when dealing with Java code because:
  • I understand the syntax better than I understand the Java Syntax as I don't use it much.
  • I find it easier to debug.
  • As I said above, I would not expect a great improvement in speed using in-line Java over java object, especially for just a few calls.
 
Last edited:
Upvote 0
Top