Mapping native C structure to JNA - jna

Very long post...
I have the following C structs that I've mapped into JNA.
These structures are used on Windows to get the raw input, from mouse, keyboard and other HID devices.
The problem is that I don't get anything in the RAWINPUT.data.keyboard (RAWKEYBAORD) structure. I haven't tested with mouse yet.
Regarding the RAWMOUSE structure, it's been modified after technomage's previous comments.
But I don't get any data in the field I expected, when debugging I can see there are data.
I think I might have mapped the structs incorrectly, or doing something wrong in the usage of them.
Can someone tell me if my mapping is correct or can use some corrections ?
I've written a DLL in C code previously, which I used in Java using JNI.
But I rather loose the DLL and use Java.
The two method below are mapped like this:
C code:
UINT WINAPI GetRawInputData(
_In_ HRAWINPUT hRawInput,
_In_ UINT uiCommand,
_Out_opt_ LPVOID pData,
_Inout_ PUINT pcbSize,
_In_ UINT cbSizeHeader
);
Java code:
int GetRawInputData(RawInputLibrary.HRAWINPUT hRawInput, int uiCommand, Memory pData, IntByReference pcbSize, int cbSizeHeader);
C code:
BOOL WINAPI RegisterRawInputDevices(
_In_ PCRAWINPUTDEVICE pRawInputDevices,
_In_ UINT uiNumDevices,
_In_ UINT cbSize
);
Java Code
boolean RegisterRawInputDevices(RawInputLibrary.RAWINPUTDEVICE pRawInputDevices, int uiNumDevices, int cbSize);
When I dump the buffer I can see the following the value for the key pressed.The 42, in memory block 6, is the letter b pressed on the keyboard, and that value changes according to the key I press. Here is the dump of the RAWINPUT structure:
RawInputLibrary$RAWINPUT(allocated#0x525ecb8 (44 bytes) (shared from allocated#0x525ecb8 (44 bytes))) {
RawInputLibrary$RAWINPUTHEADER header#0=RawInputLibrary$RAWINPUTHEADER(allocated#0x525ecb8 (16 bytes) (shared from allocated#0x525ecb8 (44 bytes) (shared from allocated#0x525ecb8 (44 bytes)))) {
int dwType#0=1
int dwSize#4=20
WinNT$HANDLE hDevice#8=native#0x3da0cb3 (com.sun.jna.platform.win32.WinNT$HANDLE#3da0cb3)
WinDef$WPARAM wParam#c=1
}
RawInputLibrary$RAWINPUT$DataUnion data#10=RawInputLibrary$RAWINPUT$DataUnion(allocated#0x525ecc8 (28 bytes) (shared from allocated#0x525ecb8 (44 bytes) (shared from allocated#0x525ecb8 (44 bytes)))) {
RawInputLibrary$RAWMOUSE mouse#0=RawInputLibrary$RAWMOUSE(auto-allocated#0x525ed48 (28 bytes)) {
short usFlags#0=0
NativeLong ulButtons#4=0
short usButtonFlags#8=0
short usButtonData#a=0
NativeLong ulRawButtons#c=0
NativeLong lLastX#10=0
NativeLong lLastY#14=0
NativeLong ulExtraInformation#18=0
}
RawInputLibrary$RAWKEYBOARD keyboard#0=RawInputLibrary$RAWKEYBOARD(auto-allocated#0x525ed70 (16 bytes)) {
short MakeCode#0=0
short Flags#2=0
short Reserved#4=0
short VKey#6=0
int Message#8=0
NativeLong ExtraInformation#c=0
}
RawInputLibrary$RAWHID hid#0=RawInputLibrary$RAWHID(auto-allocated#0x525ed88 (12 bytes)) {
int dwSizeHid#0=0
int dwCount#4=0
byte bRawData[1]#8=[B#50fe39
}
}
}
memory dump
[01000000]
[20000000]
[b30cda03]
[01000000]
[30000000]
[00004200]
[00010000]
[00000000]
[00000000]
[00000000]
[00000000]
These are the structs I've mapped. The C counter part can be seen here (not posting them in order to keep the post smaller): https://msdn.microsoft.com/en-us/library/windows/desktop/ff468899(v=vs.85).aspx
public static class HRAWINPUT extends PointerType {
public HRAWINPUT(Pointer address) {
super(address);
}
public HRAWINPUT() {
super();
}
}
public class RAWINPUT extends Structure {
public static class ByReference extends RAWINPUT implements Structure.ByReference {}
public static class ByValue extends RAWINPUT implements Structure.ByValue {}
public RawInputLibrary.RAWINPUTHEADER header;
public DataUnion data;
public static class DataUnion extends Union {
public static class ByReference extends DataUnion implements Structure.ByReference {}
public static class ByValue extends DataUnion implements Structure.ByValue {}
public RawInputLibrary.RAWMOUSE mouse;
public RawInputLibrary.RAWKEYBOARD keyboard;
public RawInputLibrary.RAWHID hid;
public DataUnion() {
super();
}
public DataUnion(RawInputLibrary.RAWMOUSE mouse) {
super();
this.mouse = mouse;
setType(RawInputLibrary.RAWMOUSE.class);
}
public DataUnion(RawInputLibrary.RAWKEYBOARD keyboard) {
super();
this.keyboard = keyboard;
setType(RawInputLibrary.RAWKEYBOARD.class);
}
public DataUnion(RawInputLibrary.RAWHID hid) {
super();
this.hid = hid;
setType(RawInputLibrary.RAWHID.class);
}
protected List<? > getFieldOrder() {
return Arrays.asList("mouse", "keyboard", "hid");
}
}
public RAWINPUT() {
super();
}
public RAWINPUT(Pointer p) {
super(p);
useMemory(p); //using this doesn't make any difference, but maybe I need to do something similar to this in the data struct ?
read();
}
public RAWINPUT(RawInputLibrary.RAWINPUTHEADER header, DataUnion data) {
super();
this.header = header;
this.data = data;
}
protected List<? > getFieldOrder() {
return Arrays.asList("header", "data");
}
}
public static class RAWINPUTHEADER extends Structure {
public static class ByReference extends RAWINPUTHEADER implements Structure.ByReference {}
public static class ByValue extends RAWINPUTHEADER implements Structure.ByValue {}
public int dwType;
public int dwSize;
public WinNT.HANDLE hDevice;
public WinDef.WPARAM wParam;
public RAWINPUTHEADER() {
super();
}
public RAWINPUTHEADER(int dwType, int dwSize, WinNT.HANDLE hDevice, WinDef.WPARAM wParam) {
super();
this.dwType = dwType;
this.dwSize = dwSize;
this.hDevice = hDevice;
this.wParam = wParam;
}
protected List<?> getFieldOrder() {
return Arrays.asList("dwType", "dwSize", "hDevice", "wParam");
}
}
public static class RAWHID extends Structure {
public static class ByReference extends RAWHID implements Structure.ByReference {}
public static class ByValue extends RAWHID implements Structure.ByValue {}
public int dwSizeHid;
public int dwCount;
public byte[] bRawData = new byte[1];
public RAWHID() {
super();
}
public RAWHID(int dwSizeHid, int dwCount, byte bRawData[]) {
super();
this.dwSizeHid = dwSizeHid;
this.dwCount = dwCount;
if ((bRawData.length != this.bRawData.length)) {
throw new IllegalArgumentException("Wrong array size !");
}
this.bRawData = bRawData;
}
protected List<? > getFieldOrder() {
return Arrays.asList("dwSizeHid", "dwCount", "bRawData");
}
}
public static class RAWKEYBOARD extends Structure {
public static class ByReference extends RAWKEYBOARD implements Structure.ByReference {}
public static class ByValue extends RAWKEYBOARD implements Structure.ByValue {}
public short MakeCode;
public short Flags;
public short Reserved;
public short VKey;
public int Message;
public NativeLong ExtraInformation;
public RAWKEYBOARD() {
super();
}
public RAWKEYBOARD(short MakeCode, short Flags, short Reserved, short VKey, int Message, NativeLong ExtraInformation) {
super();
this.MakeCode = MakeCode;
this.Flags = Flags;
this.Reserved = Reserved;
this.VKey = VKey;
this.Message = Message;
this.ExtraInformation = ExtraInformation;
}
protected List<?> getFieldOrder() {
return Arrays.asList("MakeCode", "Flags", "Reserved", "VKey", "Message", "ExtraInformation");
}
}
public static class RAWMOUSE extends Structure {
public static class ByReference extends RAWMOUSE implements Structure.ByReference {}
public static class ByValue extends RAWMOUSE implements Structure.ByValue {}
public short usFlags;
public NativeLong ulButtons;
public short usButtonFlags;
public short usButtonData;
public NativeLong ulRawButtons;
public NativeLong lLastX;
public NativeLong lLastY;
public NativeLong ulExtraInformation;
public RAWMOUSE() {
super();
}
public RAWMOUSE(short usFlags, NativeLong ulButtons, short usButtonFlags, short usButtonData, NativeLong ulRawButtons, NativeLong lLastX, NativeLong lLastY, NativeLong ulExtraInformation) {
super();
this.usFlags = usFlags;
this.ulButtons = ulButtons;
this.usButtonFlags = usButtonFlags;
this.usButtonData = usButtonData;
this.ulRawButtons = ulRawButtons;
this.lLastX = lLastX;
this.lLastY = lLastY;
this.ulExtraInformation = ulExtraInformation;
}
protected List<?> getFieldOrder() {
return Arrays.asList("usFlags", "ulButtons", "usButtonFlags", "usButtonData", "ulRawButtons", "lLastX", "lLastY", "ulExtraInformation");
}
}
The code below is an extract of thew code I'm using to test.
private class WndProc implements User32.WindowProc {
public WndProc() {
}
#Override
public LRESULT callback(HWND hwnd, int msg, WPARAM wparam, LPARAM lparam) {
switch (msg) {
case User32.WM_CREATE: {
if (hwnd != null) {
log.debug("Registering raw input device notifications...");
RawInputLibrary.RAWINPUTDEVICE.ByReference rawInputDevice = new RawInputLibrary.RAWINPUTDEVICE.ByReference();
//create an array of the struct in memory and fill it with data, and then parse the reference to the native call
RawInputLibrary.RAWINPUTDEVICE[] pRawInputDevice = (RawInputLibrary.RAWINPUTDEVICE[]) rawInputDevice.toArray(1);
pRawInputDevice[0].dwFlags = RawInputLibrary.RIDEV_INPUTSINK; // receive system wide keystrokes
pRawInputDevice[0].usUsagePage = 1; // generic desktop controls
pRawInputDevice[0].usUsage = 6; // keyboard
pRawInputDevice[0].hwndTarget = hwnd;
// register interest in raw data input
if (!rawInputLib.RegisterRawInputDevices(rawInputDevice, 1, rawInputDevice.size())) {
rawInputRegistrationSuccess = false;
log.error("Failed to register for raw input messages");
} else {
log.debug("Done registering raw input device notifications...");
}
} else {
log.debug("window handle is not defined");
}
break;
}
case RawInputLibrary.WM_INPUT: {
log.debug("Got raw input device message...");
IntByReference dwSize = new IntByReference();
int rawInputHeaderSize = new RawInputLibrary.RAWINPUTHEADER().size();
RawInputLibrary.HRAWINPUT hRawInput = new RawInputLibrary.HRAWINPUT(lparam.toPointer());
if (rawInputLib.GetRawInputData(hRawInput, RawInputLibrary.RID_INPUT, null, dwSize, rawInputHeaderSize) < 0) {
break;
}
if (dwSize.getValue() == 0) {
break;
}
IntByReference bufferSize = new IntByReference(Math.max(dwSize.getValue(), new RawInputLibrary.RAWINPUT().size()));
Memory buffer = new Memory(bufferSize.getValue());
if (rawInputLib.GetRawInputData(hRawInput, RawInputLibrary.RID_INPUT, buffer, bufferSize, rawInputHeaderSize) == -1) {
buffer.clear();
break;
}
RawInputLibrary.RAWINPUT rawinput = new RawInputLibrary.RAWINPUT(buffer);
int event = rawinput.data.keyboard.Message;
switch(event) {
case User32.WM_KEYDOWN:
case User32.WM_SYSKEYDOWN:
log.debug("Got raw input keyboard pressed");
switch(rawinput.data.keyboard.VKey){
//Shift
case 160:
case 161:
// inform listener about shift key pressed
break;
//Ignore special characters
case 144: //Numlock
break;
default:
// inform listener about key pressed
break;
}
break;
case User32.WM_KEYUP:
case User32.WM_SYSKEYUP:
if (rawinput.data.keyboard.VKey == 160 || rawinput.data.keyboard.VKey == 161) {
// inform listener about shift key released
}
break;
default:
break;
}
break;
}
default : {
return user32Lib.DefWindowProc(hwnd, msg, wparam, lparam);
}
}
return new LRESULT(0);
}
}

Related

Updating adapter of AutoCompleteTextView from LiveData

I have a AutoCompleteTextView that I give it 2 different adapters depending on the amount of text that is being present at the textview - if it has 0 characters I want it to display a list of "recently searched" strings adapter, while if it has more than 1 characters I want it to display auto completion list.
My getRecentlySearchedQueries method along with the RecentSearchedViewModel-
private List<String> recentlySearchedQueries = new ArrayList<>(); // pasted from the top of the class
#Override
public void getRecentlySearchedQueries() {
recentSearchViewModel.getAllQueries().observe(getActivity(), databaseRecentlySearchList -> {
if (databaseRecentlySearchList == null) {
return;
}
for (int i = 0; i < databaseRecentlySearchList.size(); i++) {
Log.d("localDBValue", "Added value - " + databaseRecentlySearchList.get(i).toString() + "\n");
String query = databaseRecentlySearchList.get(i).getQuery();
recentlySearchedQueries.add(query);
}
//Log.d("localDBValue", "recent search list value - " + recentlySearchedQueries);
});
}
public class RecentSearchViewModel extends AndroidViewModel {
private RecentSearchRepository recentSearchRepository;
private LiveData<List<RecentSearchModel>> allRecentlySearched;
public RecentSearchViewModel(#NonNull Application application) {
super(application);
recentSearchRepository = new RecentSearchRepository(application);
allRecentlySearched = recentSearchRepository.getAllRecentSearches();
}
public void insert(RecentSearchModel model) {
recentSearchRepository.insert(model);
}
public void update(RecentSearchModel model) {
// add implementation in the future if needed
}
public void delete(RecentSearchModel model) {
// add implementation in the future if needed
}
public LiveData<List<RecentSearchModel>> getAllQueries() {
return allRecentlySearched;
}
}
public class RecentSearchRepository {
private RecentSearchDao recentSearchDao;
private LiveData<List<RecentSearchModel>> allRecentSearches;
public RecentSearchRepository(Application application) {
MarketplaceDatabase database = MarketplaceDatabase.getRecentSearchInstance(application);
recentSearchDao = database.recentSearchDao();
allRecentSearches = recentSearchDao.getRecentSearchList();
}
public void insert(RecentSearchModel model) {
new RecentSearchRepository.InsertRecentSearchAsyncTask(recentSearchDao).execute(model);
}
public void update (RecentSearchModel model) {
//TODO - implement in future if needed
}
public void delete(RecentSearchModel model) {
//TODO - implement in future if needed
}
public LiveData<List<RecentSearchModel>> getAllRecentSearches() {
return allRecentSearches;
}
private static class InsertRecentSearchAsyncTask extends AsyncTask<RecentSearchModel, Void, Void> {
private RecentSearchDao recentSearchDao;
public InsertRecentSearchAsyncTask(RecentSearchDao recentSearchDao) {
this.recentSearchDao = recentSearchDao;
}
#Override
protected Void doInBackground(RecentSearchModel... recentSearchModels) {
recentSearchDao.insert(recentSearchModels[0]);
return null;
}
}
private static class UpdateRecentSearchAsyncTask extends AsyncTask<RecentSearchModel, Void, Void> {
private RecentSearchDao recentSearchDao;
public UpdateRecentSearchAsyncTask(RecentSearchDao recentSearchDao) {
this.recentSearchDao = recentSearchDao;
}
#Override
protected Void doInBackground(RecentSearchModel... recentSearchModels) {
recentSearchDao.update(recentSearchModels[0]);
return null;
}
}
}
#Dao
public interface RecentSearchDao {
#Insert()
void insert(RecentSearchModel model);
#Update
void update(RecentSearchModel model);
#Delete
void delete(RecentSearchModel model);
#Query("select * from recent_search_table")
LiveData<List<RecentSearchModel>> getRecentSearchList();
}
#Entity(tableName = "recent_search_table")
public class RecentSearchModel {
#PrimaryKey(autoGenerate = true)
private int ID;
private String query;
public RecentSearchModel(){
}
public RecentSearchModel(String query) {
this.query = query;
}
public void setID(int ID) {
this.ID = ID;
}
public int getID() {
return ID;
}
public String getQuery() {
return query;
}
public void setQuery(String query) {
this.query = query;
}
#Override
public String toString() {
return "RecentSearchModel{" +
"query='" + query + '\'' +
'}';
}
#Override
public boolean equals(#Nullable Object obj) {
if (obj instanceof RecentSearchModel)
return this.query.equalsIgnoreCase(((RecentSearchModel) obj).query);
return false;
}
}
So, what I am doing here is for start getting all values inside my local DB and adding them to my String list that is part of the adapter. So far so good.
The issue I am facing is that the adapter won't show the amount of strings available in the list that populates it. In fact, it sometimes shows a view half-cut with wierd information, sometimes does not show anything and sometimes shows part of the corrent information. What am I missing?
Another thing I am facing is that the "recently searched" adapter won't work when clicking on the AutoCompleteTextView - it only works when typing and deleting values so the char length is 0. How can I make it work from start of focus?
Here is the way I am populating the information to the ViewModel -
/**
* Shows the searched products following
*/
#Override
public void getSearchedProducts(String searchedQuery) {
MarketplaceUtils.getSearchedProducts(searchedQuery, marketApiCalls, false, initialSearchTake, initialMarketplacePage, new MarketplaceUtils.OnProductsFetchCompleteListener() {
#Override
public void onSuccess(List<MiniProductModel> list) {
if (!searchedQuery.equals(currentSearchedText))
return;
if (list == null) {
//reaching here means we do not have a result to show to the UI so we empty the list.
currentProductList.clear();
productsAdapter.notifyDataSetChanged();
return;
}
if (searchedQuery.length() > 3 && searchAutoCompleteStrings.contains(searchedQuery)) {
Log.d("localDBValue", "searchedValue - " + searchedQuery);
recentSearchViewModel.insert(new RecentSearchModel(searchedQuery));
}
mPresenter.setDiscoverProductsLayoutVisibility(View.GONE);
currentProductList.clear();
currentProductList.addAll(list);
productsAdapter.notifyDataSetChanged();
}
#Override
public void onError(Throwable throwable) {
Log.d("searchedProducts", throwable.getMessage());
}
});
}
The default behaviour for #Insert method of Room is OnConflictStrategy.ABORT - so what I did is to implement equals() method to verify that the RecentSearchModels that are being compared are compared by their string value. Still does seems to effect anything.

Class-based enums in Vala?

I'm wondering how to create class-based enums in Vala.
In Java you can do the following:
public class Main {
public static void main(String[] args) {
Action action = Action.COMPRESS;
System.out.printf("Action name: %s, index %d", action.getName(), action.getIndex());
}
}
class Action {
public static final Action COMPRESS = new Action("Compress", 60);
public static final Action DECOMPRESS = new Action("Decompress", 70);
private String name;
private int index;
private Action(String name, int index) {
this.name = name;
this.index = index;
}
public String getName() {
return name;
}
public int getIndex() {
return index;
}
}
But when I try the following in Vala, COMPRESS and DECOMPRESS are always null when accessing from outside the Action class.
public static int main(string[] args) {
stderr.printf("Action name: %s\n", UC.Action.COMPRESS.get_name());
}
public class UC.Action : GLib.Object {
public static UC.Action COMPRESS = new UC.Action("Compress");
public static UC.Action DECOMPRESS = new UC.Action("Decompress");
private string name;
[CCode (construct_function = null)]
private Action(string name) {
this.name = name;
}
public string get_name() {
return name;
}
}
That code outputs the following: Performing (null).
Any ideas how to accomplish this?
In Vala, static class members are initialized during the class_init GObject function, so they're not available until that has been called.
The easiest work-around is to just create an instance; you can throw it away immediately since all you're after is the side-effects.

How to collect data usage information from the internet to iPhone with Xamarin / monotouch

I'm needing to collect information from internet data usage on the iphone, the below code in C # I'm using only returns 0 values​​.
I'm using the right class?
have some reference I need to add in Xamarin?
appears in mono 3 types of classes, Coincidentally the "MacOsIPv4InterfaceStatistics" interface always returns the fixed value 0.
https://github.com/mono/mono/blob/master/mcs/class/System/System.Net.NetworkInformation/IPv4InterfaceStatistics.cs
Win32IPv4InterfaceStatistics
LinuxIPv4InterfaceStatistics
MacOsIPv4InterfaceStatistics
using System;
using System.Net;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using System.Threading;
using MonoTouch.ObjCRuntime;
namespace Taximetro { public delegate void Update();
public static class ControleUso
{
public static long controller;
public static long BytesReceivedWiFi;
public static long BytesSentWiFi;
public static long BytesReceived3G;
public static long BytesSent3G;
public static Update UpdateMethod;
public static void DoWork()
{
foreach (var netint in NetworkInterface.GetAllNetworkInterfaces()) {
var stats = netint.GetIPv4Statistics ();
//WiFi
//if (netint.Name.StartsWith ("en")) {
BytesReceivedWiFi += stats.BytesReceived;
BytesSentWiFi += stats.BytesSent;
//}
//3G
if (netint.Name.StartsWith ("pdp_ip")) {
BytesReceived3G += stats.BytesReceived;
BytesSent3G += stats.BytesSent;
}
}
controller++;
if (UpdateMethod != null) {
UpdateMethod ();
}
Thread.Sleep (1000);
}
}
}
Notice that data is uint and not long, which means it will overflow every 4GB of data.
Edit: After some Googling around I noticed that this data is reset on iOS reboot. Just some heads ups to anyone who might use this.
public enum InterfaceTypes
{
Wifi,
Cellular
}
public class DataUsage
{
[DllImport ("libc")]
static extern int getifaddrs (out IntPtr ifap);
[DllImport ("libc")]
static extern void freeifaddrs (IntPtr ifap);
const int AF_LINK = 18;
struct ifaddrs
{
public IntPtr ifa_next;
public string ifa_name;
public uint ifa_flags;
public IntPtr ifa_addr;
public IntPtr ifa_netmask;
public IntPtr ifa_dstaddr;
public IntPtr ifa_data;
}
public InterfaceTypes InterfaceType {
get;
private set;
}
public uint BytesSent {
get;
private set;
}
public uint BytesReceived {
get;
private set;
}
public static List<DataUsage> GetAllNetworkInterfacesUsage ()
{
IntPtr ifap;
if (getifaddrs (out ifap) != 0)
throw new SystemException ("getifaddrs() failed");
List<DataUsage> usages = new List<DataUsage> ();
try {
IntPtr next = ifap;
while (next != IntPtr.Zero) {
ifaddrs addr = (ifaddrs)Marshal.PtrToStructure (next, typeof(ifaddrs));
next = addr.ifa_next;
string name = addr.ifa_name;
if (addr.ifa_addr != IntPtr.Zero) {
if (Marshal.ReadByte (addr.ifa_addr, 1) == AF_LINK) {
if (!name.StartsWith ("en") && !name.StartsWith ("pdp_ip"))
continue;
usages.Add (new DataUsage () {
InterfaceType = name.StartsWith ("en") ? InterfaceTypes.Wifi : InterfaceTypes.Cellular,
BytesReceived = (uint)Marshal.ReadInt32 (addr.ifa_data, 40),
BytesSent = (uint)Marshal.ReadInt32 (addr.ifa_data, 44)
});
}
}
}
} finally {
freeifaddrs (ifap);
}
return usages;
}
}

PhoneStateListener causing problems in outgoin calls

Outgoing calls are ended automatically when phonestatelistener is used to monitor the calls.
This is my code and when this is executed it blocks the outgoing calls :
public class CallHelper {
public String number;
private Context ctx;
private TelephonyManager tm;
private CallStateListener callStateListener;
private OutgoingReceiver outgoingReceiver;
SharedPreferences trackMeData;
public CallHelper(Context ctx) {
this.ctx = ctx;
number ="";
callStateListener = new CallStateListener();
outgoingReceiver = new OutgoingReceiver();
trackMeData = ctx.getSharedPreferences("LockedSIM", 0);
}
private class CallStateListener extends PhoneStateListener {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
number = incomingNumber;
sendsmstoph(number);
System.out.println("Incomgin");
Toast.makeText(ctx, "Incoming: " + incomingNumber,Toast.LENGTH_LONG).show();
break;
}
}
}
public class OutgoingReceiver extends BroadcastReceiver {
public OutgoingReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Toast.makeText(ctx, "Outgoing: " + number, Toast.LENGTH_LONG).show();
sendsmstoph(number);
}
}

Working example of JNA mouse hook

Can any one provide me with a working example of JNA mouse hook, which would be able to track mouse movements/click outside my Java Swing application ?
Thanks in Advance
Yep, here is the code...
public class CWMouseHook {
public final User32 USER32INST;
public final Kernel32 KERNEL32INST;
public CWMouseHook()
{
if(!Platform.isWindows())
{
throw new UnsupportedOperationException("Not supported on this platform.");
}
USER32INST = User32.INSTANCE;
KERNEL32INST = Kernel32.INSTANCE;
mouseHook=hookTheMouse();
Native.setProtected(true);
}
public static LowLevelMouseProc mouseHook;
public HHOOK hhk;
public Thread thrd;
public boolean threadFinish = true;
public boolean isHooked = false;
public static final int WM_MOUSEMOVE = 512;
public static final int WM_LBUTTONDOWN = 513;
public static final int WM_LBUTTONUP = 514;
public static final int WM_RBUTTONDOWN = 516;
public static final int WM_RBUTTONUP = 517;
public static final int WM_MBUTTONDOWN = 519;
public static final int WM_MBUTTONUP = 520;
public void unsetMouseHook()
{
threadFinish = true;
if (thrd.isAlive())
{
thrd.interrupt();
thrd = null;
}
isHooked = false;
}
public boolean isIsHooked()
{
return isHooked;
}
public void setMouseHook()
{
thrd = new Thread(new Runnable() {
#Override
public void run()
{
try
{
if(!isHooked)
{
hhk = USER32INST.SetWindowsHookEx(14, mouseHook,KERNEL32INST.GetModuleHandle(null),0);
isHooked = true;
MSG msg = new MSG();
while ((USER32INST.GetMessage(msg, null, 0, 0)) != 0)
{
USER32INST.TranslateMessage(msg);
USER32INST.DispatchMessage(msg);
System.out.print(isHooked);
if (!isHooked)
break;
}
}
else
System.out.println("The Hook is already installed.");
}
catch (Exception e)
{ System.err.println(e.getMessage());
System.err.println("Caught exception in MouseHook!");
}
}
},"Named thread");
threadFinish = false;
thrd.start();
}
private interface LowLevelMouseProc extends HOOKPROC
{
LRESULT callback(int nCode, WPARAM wParam, MOUSEHOOKSTRUCT lParam);
}
public LowLevelMouseProc hookTheMouse() {
return new LowLevelMouseProc()
{
#Override
public LRESULT callback(int nCode, WPARAM wParam, MOUSEHOOKSTRUCT info) {
if (nCode >= 0)
{
switch(wParam.intValue())
{
case CWMouseHook.WM_LBUTTONDOWN:
// do stuff
break;
case CWMouseHook.WM_RBUTTONDOWN:
//do stuff
break;
case CWMouseHook.WM_MBUTTONDOWN:
//do other stuff
break;
case CWMouseHook.WM_LBUTTONUP:
//do even more stuff
break;
case CWMouseHook.WM_MOUSEMOVE:
break;
default:
break;
}
/****************************DO NOT CHANGE, this code unhooks mouse *********************************/
if (threadFinish == true)
{
USER32INST.PostQuitMessage(0);
}
/***************************END OF UNCHANGABLE *******************************************************/
}
return USER32INST.CallNextHookEx(hhk, nCode, wParam, info.getPointer());
}
};
}
public class Point extends Structure
{
public class ByReference extends Point implements Structure.ByReference {};
public NativeLong x;
public NativeLong y;
}
public static class MOUSEHOOKSTRUCT extends Structure
{
public static class ByReference extends MOUSEHOOKSTRUCT implements Structure.ByReference {};
public POINT pt;
public HWND hwnd;
public int wHitTestCode;
public ULONG_PTR dwExtraInfo;
}
That's all about there is to it. Cheers.
It's a basically a ripoff of the code of a guy in Sun forums...but also tested by me, and it works so cheers again.
Edit: I edited the code so it includes the LowLevelMouseProc but you can use your extension of HOOK which you can define elsewhere. It doesn't matter that much. Be wary that for some reason you have TO have the variable mouseHook as static otherwise hook just unhooks after a while.
movements:
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.mouse.NativeMouseWheelEvent;
import org.jnativehook.mouse.NativeMouseWheelListener;
public class GlobalMouseWheelListenerExample implements NativeMouseWheelListener {
public void nativeMouseWheelMoved(NativeMouseWheelEvent e) {
System.out.println("Mosue Wheel Moved: " + e.getWheelRotation());
}
public static void main(String[] args) {
try {
GlobalScreen.registerNativeHook();
} catch (NativeHookException ex) {
System.err.println("There was a problem registering the native hook.");
System.err.println(ex.getMessage());
ex.printStackTrace();
System.exit(1);
}
// Construct the example object and initialze native hook.
GlobalScreen.getInstance().addNativeMouseWheelListener(new GlobalMouseWheelListenerExample());
}
}
click:
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.mouse.NativeMouseEvent;
import org.jnativehook.mouse.NativeMouseInputListener;
public class GlobalMouseListenerExample implements NativeMouseInputListener {
public void nativeMouseClicked(NativeMouseEvent e) {
System.out.println("Mosue Clicked: " + e.getClickCount());
}
public void nativeMousePressed(NativeMouseEvent e) {
System.out.println("Mosue Pressed: " + e.getButton());
}
public void nativeMouseReleased(NativeMouseEvent e) {
System.out.println("Mosue Released: " + e.getButton());
}
public void nativeMouseMoved(NativeMouseEvent e) {
System.out.println("Mosue Moved: " + e.getX() + ", " + e.getY());
}
public void nativeMouseDragged(NativeMouseEvent e) {
System.out.println("Mosue Dragged: " + e.getX() + ", " + e.getY());
}
public static void main(String[] args) {
try {
GlobalScreen.registerNativeHook();
}
catch (NativeHookException ex) {
System.err.println("There was a problem registering the native hook.");
System.err.println(ex.getMessage());
System.exit(1);
}
//Construct the example object.
GlobalMouseListenerExample example = new GlobalMouseListenerExample();
//Add the appropriate listeners for the example object.
GlobalScreen.getInstance().addNativeMouseListener(example);
GlobalScreen.getInstance().addNativeMouseMotionListener(example);
}
}

Resources