B4J Tutorial Floating ContextMenu using jNativeHookB4j

This is an example of using @Roycefer 's jNativeHook to monitor all mouse events, even outside of the current app. It uses a ContextMenu to replicate the right click functionality. Default behaviour is overridden by the jNativeHook library and returning false from the relevant event sub.

It uses a dummy form to enable the context menu to be placed anywhere on the screen.

It's not been comprehensively tested and I can't guarantee it will work on Mac or Linux, but would be interested to know if it does.

Get the jNativehook files from here: https://www.b4x.com/android/forum/threads/jnativehookb4j-for-intercepting-system-input-events.55826/

Hope you enjoy it.

V 0.2 Update for Mac - see post #3
V 0.6 implements Tags, css styling of menu, checkmenuitem, submenus and a menutitle
V 0.7 Close all menus correctly
V 0.8 Added :
  • Ignore clicks on window (allows window to operate normally)
  • Multiple Floating Menus (Only one can be active at a time)
This update contains breaking code, MainForm has to be passed to the NativeHook initialization.

No version increment update fixed menu resize issue.
Demo only update to V0.8
V0.8.5 Added
ThRuST's latest css styles
Pause and Restart Mouse Listener
cmenu.css.zip contains the latest css.file
Tags : B4j Native Hook Floating Context Menu
12
 

Attachments

  • FloatingContextMenu-0-7.zip
    7.1 KB · Views: 480
  • cmenu.css.zip
    1 KB · Views: 474
  • FloatingContextMenu-0-8-6.zip
    10.3 KB · Views: 526
  • Test - cmenu.css.zip
    1 KB · Views: 449
  • FCMTest1.zip
    10.3 KB · Views: 454
Last edited:

ThRuST

Well-Known Member
Licensed User
Longtime User
Steve, do you ever sleep?:eek: and I taught that I was working extremely hard. :D
Nice solution jmon, that will keep Steve busy while I enjoy a drink at Bahamas ;)
 

ThRuST

Well-Known Member
Licensed User
Longtime User
Steve, do you mind trying to apply my second theme and perhaps add some more complexity to the CSS style and then you right click quickly anywhere on the screen and you will see how the contextmenu refreshes on the screen. I'm using a slow Windows laptop (1.7 Ghz) so it might be that, or if your code can be optimized eventually the mousehook also needs to be optimized. I've notified the author of the library to look this up, so I also wanted to tell you. It might just be my slow computer, so you're code is probably perfect and the hook library too but just in case, try it out and tell me what happens.
 

stevel05

Expert
Licensed User
Longtime User
I think that as we are pushing Context menus to do something they weren't really designed for, it causes problems when a new menu is opened in a different location, the sub menus weren't closed. V0.7 explicitly closes them. Test it and let me know.

Note: If you are taking pieces from this code, there is an amendment to the Mouse_Clicked sub in NativeHook_Static as well as several in the Floating Menu Class.
 

ThRuST

Well-Known Member
Licensed User
Longtime User
I just tested it (v0.7) and it works great. It's good that we evaluated the contextmenu with CSS themes. Now we know that it's better to not load it too heavily with complex CSS so that the menu can be responsive. It's getting close to version 1.0 :) I like it alot and will update my code. There should be possible to access multiple menus Steve ;) so I guess you'll be busy for another night through haha. Actually there should be a new context menu for some buttons, possible 4 or 5, since it should support the new gaming mouse, in this case Logitech G300S and the more expensive versions. They are qual in quality but the G300S is abit lower in price which is the reason I bought that instead. If you don't mind you can add those unique menus. Only headlines and submenus in one depth is enough, and no markers.
After all when programming we want to access stuff quickly so that will be very convenient once it done. One menu should hold for example initialization stuff, form related code, another subs, one for various code and one for SQL, like queries and connections. I'm exploating my secret ideas in this forum, but that's only good :)
 

stevel05

Expert
Licensed User
Longtime User
How do you envisage deciding which menu should be displayed? Native hook listens for all clicks, which is why I set it as a static code module. If you want display menus for your app it would need to be done in the normal way i,e, through events in the app. It should be simple enough to get the Native Listener to ignore clicks on the app window.
 

ThRuST

Well-Known Member
Licensed User
Longtime User
in NativeHook_Static

B4X:
'Sub to handle Mouse Pressed call from the Native hook
Sub NH_NativeMousePressed(nme As NativeMouseEvent) As Boolean
  
    If nme.MouseButton = 4 Then
        'Mouse button 4 has been pressed
        TH.RunOnGuiThread("Mouse_Clicked",Array(nme,True))
              
        'Consume the event
        Return True
    End If

    If nme.MouseButton = 5 Then
        'Mouse button 5 has been pressed
        TH.RunOnGuiThread("Mouse_Clicked",Array(nme,True))
              
        'Consume the event
        Return True
    End If


    Return False
End Sub

'Sub to handle Mouse Released call from the Native hook
Sub NH_NativeMouseReleased(nme As NativeMouseEvent) As Boolean

    If nme.MouseButton = 4 Then
        'Mouse button 4 has been released
        TH.RunOnGuiThread("Mouse_Clicked",Array(nme,False))
    End if

    If nme.MouseButton = 5 Then
        'Mouse button 5 has been released
        TH.RunOnGuiThread("Mouse_Clicked",Array(nme,False))
    End if

        'Consume the event
        Return True
      
    End If

I guess a new array should be assigned to each button. So depending on which button that was clicked it just calls the strings that is needed.
At initialization I will probably load the stored data from a database. I think you understand what I mean :)

EDIT: Made some corrections to the above code to correspond to yours correct one.
 

ThRuST

Well-Known Member
Licensed User
Longtime User
I know how to access each button from jAWTRobot so I might add that in. Will that be a better solution?
 

stevel05

Expert
Licensed User
Longtime User
I need to know more about why different menus are needed and how they are going to be used to advise you.

It would be possible to enable a switch between different floating menus. But only one would be active at any given time, if you want to do what I think you want to do.

The switch would be immediate, so no reloading.
 

ThRuST

Well-Known Member
Licensed User
Longtime User
Steve, That's exactly what I want. I am now creating a Windows inspired CSS theme. I'll post it when I'm done.
Probably tomorrow because I won't stay up all night. You need some sleep too. Then we'll continue tomorrow :)
 

ThRuST

Well-Known Member
Licensed User
Longtime User
I couldn't let it go. Here's my 'Windows plus' CSS theme. It's officially works with FloatingContextMenu v07 with support for a title name :)

css3.png


CSS
// Windows Plus CSS Theme by Roger 'ThRuST' Lindfors 2017-01-10

.context-menu {

-fx-border-color: #BBC2CC;
-fx-background-insets: 0,1,4,5,6;
-fx-background-radius: 0,0,0,0,0;
-fx-padding: 1 1 1 1;
-fx-background-color: #c7c7c7;

}

.cmenu .title {

-fx-background-color: transparent;
-fx-pref-height: 20px;
-fx-font-weight: normal;
-fx-text-fill: transparent;

}

.cmenu .title .label {

-fx-background-color: transparent;
-fx-font-weight: bold;
-fx-text-fill: gray;

}

.cmenu .cmcheckbox .mark{

-fx-border-color: Black;

}

.menu-item .label {

-fx-font-family:verdana;
-fx-font-size: 12px;
-fx-font-weight: bold;

}

.menu-item: focused .label {
-fx-text-fill: white;
}

.menu-item{

-fx-border-color: #FFFFFF transparent #000000 transparent;
-fx-border-width:.20px;

}

.menu-item: focused {

-fx-background-color: #979797;
-fx-text-fill: -fx-selection-bar-text;

}

.menu-item: pressed {

-fx-background-color: #696969;
}

Goodnight!!
 

stevel05

Expert
Licensed User
Longtime User
V0.8 Implements Multiple Floating menus, IgnoreClicks on window (see post 1)
 

ThRuST

Well-Known Member
Licensed User
Longtime User
I'm on it again, designed a copy as close as I could get of the windows contextmenu image I posted earlier. However it's not allways drawing the full menu can you confirm how it works on your computers and if possible, make corrections to the CSS. I also could'nt change the color of the subitem arrows and markers so please post the corrections and I'll update the CSS script. Play around with it, and tell me what you think of it.

Windows classic theme
win2.png


CSS
// Windows classic CSS Theme by Roger 'ThRuST' Lindfors 2017-01-10

.context-menu {

-fx-background-color: #f0f0f0;
-fx-background-insets: 0,1,4,5,6;
-fx-background-radius: 0,0,0,0,0;
-fx-padding: 0,0,0,0;
-fx-border-color: #BBC2CC;
-fx-text-fill: white;
}

.cmenu .title {

-fx-background-color: white;
-fx-pref-height: 20px;
-fx-font-weight: normal;
-fx-text-fill: transparent;
}

.cmenu .title .label {

-fx-font-size: 12px;
-fx-background-color: transparent;
-fx-font-weight: bold;
-fx-text-fill: #4a4a4a;


}

.cmenu .cmcheckbox .mark{

-fx-border-color: black;

}

.menu-item .label {

-fx-font-family:verdana;
-fx-font-size: 12px;
-fx-font-weight: normal;

}

.menu-item: focused .label {
-fx-text-fill: #333333;
}

.menu-item: focused {

-fx-background-color: #e0edf3;


}

.menu-item: pressed {

-fx-background-color: #d5e0e5;
}
 

ThRuST

Well-Known Member
Licensed User
Longtime User
Finally, the new era in menuhandling has begun, so that gaming mouse devices will be used in desktop applications. We are pinoeers of the software industry.
I'll take a look at your 'masterful experimental software innovation' in just a moment Steve, well done :)
 

ThRuST

Well-Known Member
Licensed User
Longtime User
Steve, please check this line it won't trigger any CSS. Also check the subitem arrows, how their color can be changed.

.cmenu .cmcheckbox .mark{
-fx-border-color: black;
}
 

stevel05

Expert
Licensed User
Longtime User
Please download again, I've uploaded a new non increment version that fixes the menu sizing issue.
 

ThRuST

Well-Known Member
Licensed User
Longtime User
It kinda.. works :) No matter how fast I'm clicking allover the screen it's redrawing the contextmenu correctly, very nice with the new design also.
I have not had time to look closer into the code, but I assume there's some kind of switch value to assign the menu to each button. Also please add a submenu to FM2, and if there's a FM3 button that triggers another array of strings for a new menu (that replaces the one showing). What I mean is two array of strings that is showing depending on which button that was clicked. Now that the menu is properly redrawn I can update it with the previous designs. Please use the same template for the CSS menu as it's alot easier to work with the same template. The latest I posted (windows classic) seems to change mostly everything in the contextmenu except for subarrows and markers. But those markers is not important for my own use. Now I understand what you was thinking about showing one menu in each button, while I was thinking a submenu to each new menu. But a single menu on each button will make it faster to locate the code snippets (which is what we want) so I guess your idea to this is better since it must be smooth to use. Add one more button FM3 and assign a new menu to it which will make the multiple menu idea more complete.
 

ThRuST

Well-Known Member
Licensed User
Longtime User
FM3 can have a submenu to it, and F4 two submenus. It will provide a good example and freedom which ones to implement :)
 

stevel05

Expert
Licensed User
Longtime User
.cmenu .cmcheckbox .mark{
-fx-border-color: black;
}

works as :

B4X:
.cmenu .cmcheckbox .left-container{
-fx-border-color: black;

}
 
Top