B4J Question Convert Java code to B4J and InitializeNewInstance.

zed

Well-Known Member
Licensed User
First of all, I found the JAVA code on the net, but I'm having a bit of trouble implementing it in B4J.
Following Cableguy message
I coded this.
[CODE lang="b4x" title="Recover HWND"]'This procedure works well to recover the HWND
Private Sub GetHWND
Dim user32 As JavaObject
user32 = user32.InitializeStatic("com.sun.jna.platform.win32.User32").GetField("INSTANCE")

Dim hwnd As JavaObject = user32.RunMethod("GetActiveWindow",Null)
Log("hwnd : "&hwnd)

' Access the pointer
Dim pointer As JavaObject = hwnd.RunMethod("getPointer", Null)

' Extract the value from the pointer with NativeValue()
Dim native As JavaObject
native.InitializeStatic("com.sun.jna.Pointer")

Dim hwndLong As Long = native.RunMethod("nativeValue", Array(pointer))

Log("HWND (Long) : " & hwndLong)

If hwndLong > 0 Then
HookWindowProcedure(hwndLong)
Else
Log("Error: Invalid HWND")
End If
End Sub[/CODE]

How to intercept WM_NCHITTEST message and return HTMAXBUTTON in B4J with JNA

I have a sample code in Java to adapt to B4J.
[CODE lang="b4x" title="Java"]import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.*;
import com.sun.jna.platform.win32.WinUser.*;
import com.sun.jna.Callback;

public class MonWndProc implements Callback {
public LRESULT callback(HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam) {
if (uMsg == WinUser.WM_NCHITTEST) {
return new LRESULT(WinUser.HTMAXBUTTON); // Indique que le bouton max est actif
}
return User32.INSTANCE.DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}[/CODE]

Adaptation in B4J.
[CODE lang="b4x" title="B4J"]Sub HookWindowProcedure(hwnd As Long)
Dim User32 As JavaObject
User32.InitializeStatic("com.sun.jna.platform.win32.User32")

Dim WndProc As JavaObject
WndProc.InitializeNewInstance("MonWndProc", Null) ' <-- What is the classname

User32.RunMethod("SetWindowLongPtr", Array(hwnd, -4, WndProc))
End Sub[/CODE]

MyWndProc is a class that implements Callback and intercepts WM_NCHITTEST.
SetWindowLongPtr overrides the window procedure to use MyWndProc.
HTMAXBUTTON tricks Windows into thinking the custom button is the native maximize button.
What is the classname ?

And finally.
[CODE lang="b4x" title="B4J"]Sub CustomWndProc(hwnd As String, uMsg As Int, wParam As Long, lParam As Long) As Long
If uMsg = 132 Then ' WM_NCHITTEST
Return 9 ' HTMAXBUTTON
End If

Dim User32 As JavaObject
User32.InitializeStatic("com.sun.jna.platform.win32.User32")
Return User32.RunMethod("DefWindowProc", Array(hwnd, uMsg, wParam, lParam))
End Sub[/CODE]

Here are the Logs
[CODE lang="b4x" title="Log"]WARNING: package com.sun.javafx.embed.swing.oldimpl not in javafx.swing
Waiting for debugger to connect...
Program started.
hwnd1 : (HWND) native@0xbc0568
HWND (Long) : 12322152
Error occurred on line: 50 (Main)
java.lang.ClassNotFoundException: java$lang$MonWndProc
at anywheresoftware.b4j.object.JavaObject.getCorrectClassName(JavaObject.java:289)
at anywheresoftware.b4j.object.JavaObject.InitializeNewInstance(JavaObject.java:84)
at b4j.example.main._hookwindowprocedure(main.java:144)
at b4j.example.main._appstart(main.java:114)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:629)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:237)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:167)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:111)
at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:100)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:98)
at b4j.example.main.start(main.java:38)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:847)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:484)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
at java.base/java.lang.Thread.run(Thread.java:1589)[/CODE]


Thank you for any help you can give me
 
Should I put the java block
#if java
----
#end if

Because in this case, there is a compilation error.
[CODE lang="b4x" title="Error compilation"]B4J Version : 10.00
Analyse du code. (0.00s)
Java Version : 19
Building folders structure. (0.02s)
Compilation du code. (0.00s)
Compilation du code des layouts. (0.00s)
Organiser les bibliothèques. (0.00s)
Compilation du code Java. Error
B4J line: 59
End Sub
src\b4j\example\main.java:198: error: cannot find symbol
if (uMsg == WinUser.WM_NCHITTEST) {
^
symbol: variable WinUser
location: class MonWndProc
1 error
only showing the first 1 errors, of 2 total; use -Xmaxerrs if you would like to see more[/CODE]

the error comes from line 8 of the java code
 
Upvote 0
Thanks for the link, but it doesn't really help me.
Why WinUser.WM_NCHITTEST is not working.
I will continue my investigation, but any help is appreciated.
 
Upvote 0
Back
Top