B4J Library Dark Title Bar (Windows only)

Another option for a Dark Title Bar

I found some code on StackOverflow which I got working in B4j:



1744803595570.png

It depends on JNA 5 + available on Github. Although it's probably easier to get them from Maven Central
B4X:
#AdditionalJar: jna-5.16.0
#AdditionalJar: jna-platform-5.16.0

I have tested on Win 11, apparently it may work on some versions of Win 10, but I can't test it.

There is not much code:

B4X:
'Static code module

Sub Process_Globals
    Private mDark As Boolean
End Sub

Public Sub SetDarkMode(Target As Form, Dark As Boolean)
    mDark = Dark
    Dim hwnd As JavaObject = Me.as(JavaObject).RunMethod("getActiveWindow",Null)
    Me.as(JavaObject).RunMethod("setDarkMode",Array(GetStage(Target),mDark,hwnd))
End Sub

Public Sub DarkMode As Boolean
    Return mDark
End Sub

Private Sub GetStage(tForm As Form) As JavaObject
    Return tForm.As(JavaObject).GetField("stage")
End Sub

'Does nothing.  For info
'Requires JNA jna 5 + available from <link>GitHub|https://github.com/java-native-access/jna</link>
'Based on code from <link>StackOverflow|https://stackoverflow.com/a/76543216/981223</link>
'<code>#AdditionalJar: jna-5.16.0
'#AdditionalJar: jna-platform-5.16.0</code>
Public Sub Info

End Sub



#if java
import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinDef;
import javafx.stage.Stage;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.PointerType;
import com.sun.jna.platform.win32.User32;


    public static void setDarkMode(Stage stage, boolean darkMode, WinDef.HWND hwnd) {

        Dwmapi dwmapi = Dwmapi.INSTANCE;
        WinDef.BOOLByReference darkModeRef = new WinDef.BOOLByReference(new WinDef.BOOL(darkMode));

       int hr = dwmapi.DwmSetWindowAttribute(hwnd, 20, darkModeRef, Native.getNativeSize(WinDef.BOOLByReference.class));
       if (hr != 0) { // S_OK is 0
            BA.Log("Mode not applied");
        }
    }

   
    public interface Dwmapi extends Library {
   
        Dwmapi INSTANCE = Native.load("dwmapi", Dwmapi.class);
   
        int DwmSetWindowAttribute(WinDef.HWND hwnd, int dwAttribute, PointerType pvAttribute, int cbAttribute);

    }
   
    public static WinDef.HWND getActiveWindow(){
        return User32.INSTANCE.GetActiveWindow();
    }
#End If

But I have created a B4xLib anyway.

You only need to add one line of code after the Form has been shown:
B4X:
    MainForm.Show
    DarkTitleBar.SetDarkMode(MainForm, True)

Updates V0.2
Updated to work with Packager


Let me know if it works for you.
 

Attachments

  • DarkWindowModeTest.zip
    4 KB · Views: 90
  • DarkWindowMode-b4xlib.b4xlib
    1.4 KB · Views: 88
Last edited:

zhangbao

Member
I tested normally in debug mode, but when building a standalone software package, it crashes and reports an error. The error content is as follows.
3f3b1cfa1ffbc2f3f835440d70cf78e.png
 

stevel05

Expert
Licensed User
Longtime User
Thanks for reporting that, I have amended the code so it works when packaged.
 

MikeH

Well-Known Member
Licensed User
Longtime User
Also tested and working here on Win 11 (packaged). Thank you Steve :)
 

zhangbao

Member
It runs normally on WIN11, but when running on WIN10 and using the software as shown in the first picture, the display becomes normal when clicking on other windows or resizing this window.

7387d2b4d66f2b5ce60bfe6f2d72c77.png
a856a8e04624e8579e57528aea755a2.png
 

stevel05

Expert
Licensed User
Longtime User
Hi zhangbao Yes, unfortunately not all versions of win 10 are compatible.
 

MikeH

Well-Known Member
Licensed User
Longtime User
Hi Steve,

Not sure what I've done to cause this, but I am unable to compile with DarkWindow and get this error:

B4X:
B4J Version: 10.20
Parsing code.    Error
Error parsing program.
Error description: Unknown type: javaobject
Are you missing a library reference?
Error occurred on line: 17 (DarkTitleBar)
Private Sub GetStage(tForm As Form) As JavaObject

I thought there may be a clash of Sub names since I added Net.lib to my project so I temporarily removed that but the error remains.

Using the code you kindly provided works, but the DarkWindow lib doesnt.

Hope you can shine some light :)
 

MikeH

Well-Known Member
Licensed User
Longtime User
Top