B4J Question Convert Java code to B4J and InitializeNewInstance.

zed

Active 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.
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

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

I have a sample code in Java to adapt to B4J.
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);
    }
}

Adaptation in B4J.
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

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.
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

Here are the Logs
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)


Thank you for any help you can give me
 

zed

Active Member
Licensed User
Should I put the java block
#if java
----
#end if

Because in this case, there is a compilation error.
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

the error comes from line 8 of the java code
 
Upvote 0

zed

Active Member
Licensed User
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
Top