Move objects and interfaces to designated files
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -3,8 +3,7 @@
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski7@gmail.com
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
package org.synthuse;
|
||||
|
||||
@@ -21,314 +20,344 @@ import com.sun.jna.platform.win32.WinUser.*;
|
||||
import com.sun.jna.platform.win32.WinDef.*;
|
||||
import com.sun.jna.win32.W32APIOptions;
|
||||
|
||||
public class KeyboardHook implements Runnable{
|
||||
|
||||
|
||||
// Keyboard event class, interface, and array list
|
||||
public static class TargetKeyPress {
|
||||
int idNumber;
|
||||
int targetKeyCode;
|
||||
boolean withShift, withCtrl, withAlt;
|
||||
public TargetKeyPress (int targetKeyCode) {
|
||||
this.targetKeyCode = targetKeyCode;
|
||||
this.withShift = false;
|
||||
this.withCtrl = false;
|
||||
this.withAlt = false;
|
||||
}
|
||||
public TargetKeyPress (int idNumber, int targetKeyCode, boolean withShift, boolean withCtrl, boolean withAlt) {
|
||||
this.idNumber = idNumber;
|
||||
this.targetKeyCode = targetKeyCode;
|
||||
this.withShift = withShift;
|
||||
this.withCtrl = withCtrl;
|
||||
this.withAlt = withAlt;
|
||||
}
|
||||
public TargetKeyPress (int targetKeyCode, boolean withShift, boolean withCtrl, boolean withAlt) {
|
||||
this.targetKeyCode = targetKeyCode;
|
||||
this.withShift = withShift;
|
||||
this.withCtrl = withCtrl;
|
||||
this.withAlt = withAlt;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<TargetKeyPress> targetList = Collections.synchronizedList(new ArrayList<TargetKeyPress>());// all keys we want to throw events on
|
||||
|
||||
public static interface KeyboardEvents {
|
||||
void keyPressed(TargetKeyPress target);
|
||||
}
|
||||
public KeyboardEvents events = new KeyboardEvents() {
|
||||
public void keyPressed(TargetKeyPress target) {
|
||||
//System.out.println("target key pressed: " + target.targetKeyCode);
|
||||
}
|
||||
};
|
||||
|
||||
// JNA constants and functions
|
||||
public static final int WH_KEYBOARD_LL = 13;
|
||||
//Modifier key vkCode constants
|
||||
public static final int VK_SHIFT = 0x10;
|
||||
public static final int VK_CONTROL = 0x11;
|
||||
public static final int VK_MENU = 0x12;
|
||||
public static final int VK_CAPITAL = 0x14;
|
||||
|
||||
public static final int MOD_ALT = 0x0001;
|
||||
public static final int MOD_CONTROL = 0x0002;
|
||||
public static final int MOD_NOREPEAT = 0x4000;
|
||||
public static final int MOD_SHIFT = 0x0004;
|
||||
public static final int MOD_WIN = 0x0008;
|
||||
|
||||
public static final int QS_HOTKEY = 0x0080;
|
||||
public static final int INFINITE = 0xFFFFFFFF;
|
||||
|
||||
public static HHOOK hHook = null;
|
||||
public static LowLevelKeyboardProc lpfn;
|
||||
public static volatile boolean quit = false;
|
||||
public class KeyboardHook implements Runnable {
|
||||
|
||||
private static Thread khThread = null;
|
||||
|
||||
|
||||
public interface User32Ex extends W32APIOptions {
|
||||
User32Ex instance = (User32Ex) Native.loadLibrary("user32", User32Ex.class, DEFAULT_OPTIONS);
|
||||
|
||||
LRESULT LowLevelKeyboardProc(int nCode,WPARAM wParam,LPARAM lParam);
|
||||
HHOOK SetWindowsHookEx(int idHook, HOOKPROC lpfn, HMODULE hMod, int dwThreadId);
|
||||
LRESULT CallNextHookEx(HHOOK idHook, int nCode, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT CallNextHookEx(HHOOK idHook, int nCode, WPARAM wParam, Pointer lParam);
|
||||
boolean PeekMessage(MSG lpMsg, HWND hWnd, int wMsgFilterMin, int wMsgFilterMax, int wRemoveMsg);
|
||||
boolean UnhookWindowsHookEx(HHOOK idHook);
|
||||
short GetKeyState(int nVirtKey);
|
||||
short GetAsyncKeyState(int nVirtKey);
|
||||
|
||||
/*
|
||||
DWORD WINAPI MsgWaitForMultipleObjects(
|
||||
__in DWORD nCount, //The number of object handles in the array pointed to by pHandles.
|
||||
__in const HANDLE *pHandles, //An array of object handles.
|
||||
__in BOOL bWaitAll, //If this parameter is TRUE, the function returns when the states of all objects in the pHandles array have been set to signaled and an input event has been received.
|
||||
__in DWORD dwMilliseconds, //if dwMilliseconds is INFINITE, the function will return only when the specified objects are signaled.
|
||||
__in DWORD dwWakeMask //The input types for which an input event object handle will be added to the array of object handles.
|
||||
);*/
|
||||
int MsgWaitForMultipleObjects(int nCount, Pointer pHandles, boolean bWaitAll, int dwMilliSeconds, int dwWakeMask);
|
||||
boolean RegisterHotKey(Pointer hWnd, int id, int fsModifiers, int vk);
|
||||
// Keyboard event class, interface, and array list
|
||||
public static class TargetKeyPress {
|
||||
int idNumber;
|
||||
int targetKeyCode;
|
||||
boolean withShift, withCtrl, withAlt;
|
||||
|
||||
public TargetKeyPress(int targetKeyCode) {
|
||||
this.targetKeyCode = targetKeyCode;
|
||||
this.withShift = false;
|
||||
this.withCtrl = false;
|
||||
this.withAlt = false;
|
||||
}
|
||||
|
||||
public TargetKeyPress(int idNumber, int targetKeyCode, boolean withShift, boolean withCtrl, boolean withAlt) {
|
||||
this.idNumber = idNumber;
|
||||
this.targetKeyCode = targetKeyCode;
|
||||
this.withShift = withShift;
|
||||
this.withCtrl = withCtrl;
|
||||
this.withAlt = withAlt;
|
||||
}
|
||||
|
||||
public TargetKeyPress(int targetKeyCode, boolean withShift, boolean withCtrl, boolean withAlt) {
|
||||
this.targetKeyCode = targetKeyCode;
|
||||
this.withShift = withShift;
|
||||
this.withCtrl = withCtrl;
|
||||
this.withAlt = withAlt;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<TargetKeyPress> targetList = Collections.synchronizedList(new ArrayList<TargetKeyPress>());// all
|
||||
// keys
|
||||
// we
|
||||
// want
|
||||
// to
|
||||
// throw
|
||||
// events
|
||||
// on
|
||||
|
||||
public static interface KeyboardEvents {
|
||||
void keyPressed(TargetKeyPress target);
|
||||
}
|
||||
|
||||
public KeyboardEvents events = new KeyboardEvents() {
|
||||
public void keyPressed(TargetKeyPress target) {
|
||||
// System.out.println("target key pressed: " +
|
||||
// target.targetKeyCode);
|
||||
}
|
||||
};
|
||||
|
||||
// JNA constants and functions
|
||||
public static final int WH_KEYBOARD_LL = 13;
|
||||
// Modifier key vkCode constants
|
||||
public static final int VK_SHIFT = 0x10;
|
||||
public static final int VK_CONTROL = 0x11;
|
||||
public static final int VK_MENU = 0x12;
|
||||
public static final int VK_CAPITAL = 0x14;
|
||||
|
||||
public static final int MOD_ALT = 0x0001;
|
||||
public static final int MOD_CONTROL = 0x0002;
|
||||
public static final int MOD_NOREPEAT = 0x4000;
|
||||
public static final int MOD_SHIFT = 0x0004;
|
||||
public static final int MOD_WIN = 0x0008;
|
||||
|
||||
public static final int QS_HOTKEY = 0x0080;
|
||||
public static final int INFINITE = 0xFFFFFFFF;
|
||||
|
||||
public static HHOOK hHook = null;
|
||||
public static LowLevelKeyboardProc lpfn;
|
||||
public static volatile boolean quit = false;
|
||||
|
||||
private static Thread khThread = null;
|
||||
|
||||
public interface User32Ex extends W32APIOptions {
|
||||
User32Ex instance = (User32Ex) Native.loadLibrary("user32", User32Ex.class, DEFAULT_OPTIONS);
|
||||
|
||||
LRESULT LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
HHOOK SetWindowsHookEx(int idHook, HOOKPROC lpfn, HMODULE hMod, int dwThreadId);
|
||||
|
||||
LRESULT CallNextHookEx(HHOOK idHook, int nCode, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
LRESULT CallNextHookEx(HHOOK idHook, int nCode, WPARAM wParam, Pointer lParam);
|
||||
|
||||
boolean PeekMessage(MSG lpMsg, HWND hWnd, int wMsgFilterMin, int wMsgFilterMax, int wRemoveMsg);
|
||||
|
||||
boolean UnhookWindowsHookEx(HHOOK idHook);
|
||||
|
||||
short GetKeyState(int nVirtKey);
|
||||
|
||||
short GetAsyncKeyState(int nVirtKey);
|
||||
|
||||
/*
|
||||
* DWORD WINAPI MsgWaitForMultipleObjects( __in DWORD nCount, //The
|
||||
* number of object handles in the array pointed to by pHandles. __in
|
||||
* const HANDLE *pHandles, //An array of object handles. __in BOOL
|
||||
* bWaitAll, //If this parameter is TRUE, the function returns when the
|
||||
* states of all objects in the pHandles array have been set to signaled
|
||||
* and an input event has been received. __in DWORD dwMilliseconds, //if
|
||||
* dwMilliseconds is INFINITE, the function will return only when the
|
||||
* specified objects are signaled. __in DWORD dwWakeMask //The input
|
||||
* types for which an input event object handle will be added to the
|
||||
* array of object handles. );
|
||||
*/
|
||||
int MsgWaitForMultipleObjects(int nCount, Pointer pHandles, boolean bWaitAll, int dwMilliSeconds, int dwWakeMask);
|
||||
|
||||
boolean RegisterHotKey(Pointer hWnd, int id, int fsModifiers, int vk);
|
||||
|
||||
// public static interface HOOKPROC extends StdCallCallback {
|
||||
// LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT lParam);
|
||||
// }
|
||||
}
|
||||
|
||||
public interface Kernel32 extends W32APIOptions {
|
||||
Kernel32 instance = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class, DEFAULT_OPTIONS);
|
||||
|
||||
//public static interface HOOKPROC extends StdCallCallback {
|
||||
// LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT lParam);
|
||||
//}
|
||||
}
|
||||
|
||||
public interface Kernel32 extends W32APIOptions {
|
||||
Kernel32 instance = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class, DEFAULT_OPTIONS);
|
||||
|
||||
HMODULE GetModuleHandle(String name);
|
||||
}
|
||||
|
||||
// Create Global Windows Keyboard hook and wait until quit == true
|
||||
public void createGlobalKeyboardHook() {
|
||||
}
|
||||
|
||||
if (hHook != null)
|
||||
return; //hook already running don't add anymore
|
||||
System.out.println("starting global keyboard hook");
|
||||
HMODULE hMod = Kernel32.instance.GetModuleHandle(null);
|
||||
HOOKPROC lpfn = new HOOKPROC() {
|
||||
@SuppressWarnings("unused")
|
||||
public LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT lParam) {
|
||||
//System.out.println("here " + lParam.vkCode);
|
||||
TargetKeyPress target = getTargetKeyPressed(lParam.vkCode); //find if this is a target key pressed
|
||||
if (target != null)
|
||||
events.keyPressed(target);
|
||||
//if (lParam.vkCode == 87) //w
|
||||
// quit = true;
|
||||
return User32.INSTANCE.CallNextHookEx(hHook, nCode, wParam, lParam.getPointer());
|
||||
}
|
||||
};
|
||||
|
||||
hHook = User32.INSTANCE.SetWindowsHookEx(WH_KEYBOARD_LL, lpfn, hMod, 0);
|
||||
if (hHook == null)
|
||||
return;
|
||||
|
||||
//System.out.println("starting message loop");
|
||||
MSG msg = new MSG();
|
||||
try {
|
||||
|
||||
while (!quit) {
|
||||
User32.INSTANCE.PeekMessage(msg, null, 0, 0, 1);
|
||||
if (msg.message == User32.WM_HOTKEY){ // && msg.wParam.intValue() == 1
|
||||
//System.out.println("Hot key pressed!");
|
||||
msg = new MSG(); //must clear msg so it doesn't repeat
|
||||
}
|
||||
Thread.sleep(10);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
//System.out.println("message loop stopped");
|
||||
}
|
||||
|
||||
// Create HotKeys Windows hook and wait until quit == true
|
||||
public void createHotKeysHook() {
|
||||
registerAllHotKeys();
|
||||
//User32Ex.instance.MsgWaitForMultipleObjects(0, Pointer.NULL, true, INFINITE, QS_HOTKEY);
|
||||
// Create Global Windows Keyboard hook and wait until quit == true
|
||||
public void createGlobalKeyboardHook() {
|
||||
|
||||
//System.out.println("starting message loop");
|
||||
MSG msg = new MSG();
|
||||
try {
|
||||
|
||||
while (!quit) {
|
||||
User32.INSTANCE.PeekMessage(msg, null, 0, 0, 1);
|
||||
if (msg.message == User32.WM_HOTKEY){ // && msg.wParam.intValue() == 1
|
||||
//System.out.println("Hot key pressed " + msg.wParam);
|
||||
TargetKeyPress target = findTargetKeyPressById(msg.wParam.intValue());
|
||||
if (target != null)
|
||||
events.keyPressed(target);
|
||||
msg = new MSG(); //must clear msg so it doesn't repeat
|
||||
}
|
||||
Thread.sleep(10);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
unregisterAllHotKeys();
|
||||
//System.out.println("message loop stopped");
|
||||
}
|
||||
|
||||
//unhook the Global Windows Keyboard hook
|
||||
public void unhook() {
|
||||
if (hHook == null)
|
||||
return;
|
||||
if (!User32.INSTANCE.UnhookWindowsHookEx(hHook))
|
||||
System.out.println("Failed to unhook");
|
||||
//System.out.println("Unhooked");
|
||||
hHook = null;
|
||||
}
|
||||
|
||||
//stops Keyboard hook and causes the unhook command to be called
|
||||
public static void stopKeyboardHook() {
|
||||
quit = true;
|
||||
if (khThread != null)
|
||||
{
|
||||
try {
|
||||
khThread.join();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// search target keyboard event list for a match and return it otherwise return null if no match
|
||||
if (hHook != null)
|
||||
return; // hook already running don't add anymore
|
||||
System.out.println("starting global keyboard hook");
|
||||
HMODULE hMod = Kernel32.instance.GetModuleHandle(null);
|
||||
HOOKPROC lpfn = new HOOKPROC() {
|
||||
@SuppressWarnings("unused")
|
||||
public LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT lParam) {
|
||||
// System.out.println("here " + lParam.vkCode);
|
||||
TargetKeyPress target = getTargetKeyPressed(lParam.vkCode); // find
|
||||
// if
|
||||
// this
|
||||
// is
|
||||
// a
|
||||
// target
|
||||
// key
|
||||
// pressed
|
||||
if (target != null)
|
||||
events.keyPressed(target);
|
||||
// if (lParam.vkCode == 87) //w
|
||||
// quit = true;
|
||||
return User32.INSTANCE.CallNextHookEx(hHook, nCode, wParam, lParam.getPointer());
|
||||
}
|
||||
};
|
||||
|
||||
private TargetKeyPress getTargetKeyPressed(int keyCode) {
|
||||
TargetKeyPress target = null;
|
||||
for (TargetKeyPress tkp : KeyboardHook.targetList) {
|
||||
if (tkp.targetKeyCode != keyCode)
|
||||
continue;
|
||||
if (!tkp.withShift || ((User32Ex.instance.GetKeyState(VK_SHIFT) & 0x8000) != 0)) {
|
||||
if (!tkp.withCtrl || ((User32Ex.instance.GetKeyState(VK_CONTROL) & 0x8000) != 0)) {
|
||||
if (!tkp.withAlt || ((User32Ex.instance.GetKeyState(VK_MENU) & 0x8000) != 0)) {
|
||||
return tkp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
private TargetKeyPress findTargetKeyPressById(int idNumber)
|
||||
{
|
||||
TargetKeyPress target = null;
|
||||
for (TargetKeyPress tkp : KeyboardHook.targetList) {
|
||||
if (tkp.idNumber == idNumber)
|
||||
return tkp;
|
||||
}
|
||||
return target;
|
||||
}
|
||||
hHook = User32.INSTANCE.SetWindowsHookEx(WH_KEYBOARD_LL, lpfn, hMod, 0);
|
||||
if (hHook == null)
|
||||
return;
|
||||
|
||||
// clear all target keys to watch for
|
||||
public static void clearKeyEvent() {
|
||||
KeyboardHook.targetList.clear();
|
||||
}
|
||||
// System.out.println("starting message loop");
|
||||
MSG msg = new MSG();
|
||||
try {
|
||||
|
||||
|
||||
// add more target keys to watch for
|
||||
public static void addKeyEvent(int targetKeyCode, boolean withShift, boolean withCtrl, boolean withAlt) {
|
||||
KeyboardHook.targetList.add(new TargetKeyPress(KeyboardHook.targetList.size() + 1 , targetKeyCode, withShift, withCtrl, withAlt));
|
||||
}
|
||||
|
||||
// add more target keys to watch for
|
||||
public static void addKeyEvent(int targetKeyCode) {
|
||||
KeyboardHook.targetList.add(new TargetKeyPress(targetKeyCode));
|
||||
}
|
||||
while (!quit) {
|
||||
User32.INSTANCE.PeekMessage(msg, null, 0, 0, 1);
|
||||
if (msg.message == User32.WM_HOTKEY) { // &&
|
||||
// msg.wParam.intValue()
|
||||
// == 1
|
||||
// System.out.println("Hot key pressed!");
|
||||
msg = new MSG(); // must clear msg so it doesn't repeat
|
||||
}
|
||||
Thread.sleep(10);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// System.out.println("message loop stopped");
|
||||
}
|
||||
|
||||
|
||||
private void registerAllHotKeys() // must register hot keys in the same thread that is watching for hotkey messages
|
||||
{
|
||||
//System.out.println("registering hotkeys");
|
||||
for (TargetKeyPress tkp : KeyboardHook.targetList) {
|
||||
//BOOL WINAPI RegisterHotKey(HWND hWnd, int id, UINT fsModifiers, UINT vk);
|
||||
int modifiers = User32.MOD_NOREPEAT;
|
||||
if (tkp.withShift)
|
||||
modifiers = modifiers | User32.MOD_SHIFT;
|
||||
if (tkp.withCtrl)
|
||||
modifiers = modifiers | User32.MOD_CONTROL;
|
||||
if (tkp.withAlt)
|
||||
modifiers = modifiers | User32.MOD_ALT;
|
||||
//System.out.println("RegisterHotKey " + tkp.idNumber + "," + modifiers + ", " + tkp.targetKeyCode);
|
||||
|
||||
if (!User32.INSTANCE.RegisterHotKey(new WinDef.HWND(Pointer.NULL), tkp.idNumber, modifiers, tkp.targetKeyCode))
|
||||
{
|
||||
System.out.println("Couldn't register hotkey " + tkp.targetKeyCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void unregisterAllHotKeys() // must register hot keys in the same thread that is watching for hotkey messages
|
||||
{
|
||||
//System.out.println("unregistering hotkeys");
|
||||
for (TargetKeyPress tkp : KeyboardHook.targetList) {
|
||||
if (!User32.INSTANCE.UnregisterHotKey(Pointer.NULL, tkp.idNumber))
|
||||
{
|
||||
System.out.println("Couldn't unregister hotkey " + tkp.targetKeyCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
//createGlobalKeyboardHook();
|
||||
createHotKeysHook();
|
||||
//System.out.println("Unhooking Global Keyboard Hook");
|
||||
unhook();//wait for quit == true then unhook
|
||||
}
|
||||
|
||||
public KeyboardHook() {
|
||||
}
|
||||
// Create HotKeys Windows hook and wait until quit == true
|
||||
public void createHotKeysHook() {
|
||||
registerAllHotKeys();
|
||||
// User32Ex.instance.MsgWaitForMultipleObjects(0, Pointer.NULL, true,
|
||||
// INFINITE, QS_HOTKEY);
|
||||
|
||||
public KeyboardHook(KeyboardEvents events) {
|
||||
this.events = events;
|
||||
}
|
||||
|
||||
public static void StartKeyboardHookThreaded(KeyboardEvents events) {
|
||||
quit = false;
|
||||
khThread = new Thread(new KeyboardHook(events));
|
||||
khThread.start();
|
||||
}
|
||||
|
||||
/*
|
||||
// testing
|
||||
public static void main(String[] args) throws Exception {
|
||||
//add target keys
|
||||
KeyboardHook.addKeyEvent(KeyEvent.VK_3, true, true, false);
|
||||
KeyboardHook.addKeyEvent(KeyEvent.VK_5, false, true, false);
|
||||
KeyboardHook.addKeyEvent(KeyEvent.VK_Q);
|
||||
|
||||
//add global hook and event
|
||||
KeyboardHook.StartGlobalKeyboardHookThreaded(new KeyboardHook.KeyboardEvents() {
|
||||
@Override
|
||||
public void keyPressed(KeyboardHook.TargetKeyPress target) {
|
||||
System.out.println("target key pressed " + target.targetKeyCode);
|
||||
if (target.targetKeyCode == KeyEvent.VK_Q){ // if Q was pressed then unhook
|
||||
KeyboardHook.stopGlobalKeyboardHook();
|
||||
System.out.println("unhooking");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
*/
|
||||
// System.out.println("starting message loop");
|
||||
MSG msg = new MSG();
|
||||
try {
|
||||
|
||||
while (!quit) {
|
||||
User32.INSTANCE.PeekMessage(msg, null, 0, 0, 1);
|
||||
if (msg.message == User32.WM_HOTKEY) { // &&
|
||||
// msg.wParam.intValue()
|
||||
// == 1
|
||||
// System.out.println("Hot key pressed " + msg.wParam);
|
||||
TargetKeyPress target = findTargetKeyPressById(msg.wParam.intValue());
|
||||
if (target != null)
|
||||
events.keyPressed(target);
|
||||
msg = new MSG(); // must clear msg so it doesn't repeat
|
||||
}
|
||||
Thread.sleep(10);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
unregisterAllHotKeys();
|
||||
// System.out.println("message loop stopped");
|
||||
}
|
||||
|
||||
// unhook the Global Windows Keyboard hook
|
||||
public void unhook() {
|
||||
if (hHook == null)
|
||||
return;
|
||||
if (!User32.INSTANCE.UnhookWindowsHookEx(hHook))
|
||||
System.out.println("Failed to unhook");
|
||||
// System.out.println("Unhooked");
|
||||
hHook = null;
|
||||
}
|
||||
|
||||
// stops Keyboard hook and causes the unhook command to be called
|
||||
public static void stopKeyboardHook() {
|
||||
quit = true;
|
||||
if (khThread != null) {
|
||||
try {
|
||||
khThread.join();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// search target keyboard event list for a match and return it otherwise
|
||||
// return null if no match
|
||||
|
||||
private TargetKeyPress getTargetKeyPressed(int keyCode) {
|
||||
TargetKeyPress target = null;
|
||||
for (TargetKeyPress tkp : KeyboardHook.targetList) {
|
||||
if (tkp.targetKeyCode != keyCode)
|
||||
continue;
|
||||
if (!tkp.withShift || ((User32Ex.instance.GetKeyState(VK_SHIFT) & 0x8000) != 0)) {
|
||||
if (!tkp.withCtrl || ((User32Ex.instance.GetKeyState(VK_CONTROL) & 0x8000) != 0)) {
|
||||
if (!tkp.withAlt || ((User32Ex.instance.GetKeyState(VK_MENU) & 0x8000) != 0)) {
|
||||
return tkp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
private TargetKeyPress findTargetKeyPressById(int idNumber) {
|
||||
TargetKeyPress target = null;
|
||||
for (TargetKeyPress tkp : KeyboardHook.targetList) {
|
||||
if (tkp.idNumber == idNumber)
|
||||
return tkp;
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
// clear all target keys to watch for
|
||||
public static void clearKeyEvent() {
|
||||
KeyboardHook.targetList.clear();
|
||||
}
|
||||
|
||||
// add more target keys to watch for
|
||||
public static void addKeyEvent(int targetKeyCode, boolean withShift, boolean withCtrl, boolean withAlt) {
|
||||
KeyboardHook.targetList.add(new TargetKeyPress(KeyboardHook.targetList.size() + 1, targetKeyCode, withShift, withCtrl, withAlt));
|
||||
}
|
||||
|
||||
// add more target keys to watch for
|
||||
public static void addKeyEvent(int targetKeyCode) {
|
||||
KeyboardHook.targetList.add(new TargetKeyPress(targetKeyCode));
|
||||
}
|
||||
|
||||
private void registerAllHotKeys() // must register hot keys in the same
|
||||
// thread that is watching for hotkey
|
||||
// messages
|
||||
{
|
||||
// System.out.println("registering hotkeys");
|
||||
for (TargetKeyPress tkp : KeyboardHook.targetList) {
|
||||
// BOOL WINAPI RegisterHotKey(HWND hWnd, int id, UINT fsModifiers,
|
||||
// UINT vk);
|
||||
int modifiers = User32.MOD_NOREPEAT;
|
||||
if (tkp.withShift)
|
||||
modifiers = modifiers | User32.MOD_SHIFT;
|
||||
if (tkp.withCtrl)
|
||||
modifiers = modifiers | User32.MOD_CONTROL;
|
||||
if (tkp.withAlt)
|
||||
modifiers = modifiers | User32.MOD_ALT;
|
||||
// System.out.println("RegisterHotKey " + tkp.idNumber + "," +
|
||||
// modifiers + ", " + tkp.targetKeyCode);
|
||||
|
||||
if (!User32.INSTANCE.RegisterHotKey(new WinDef.HWND(Pointer.NULL), tkp.idNumber, modifiers, tkp.targetKeyCode)) {
|
||||
System.out.println("Couldn't register hotkey " + tkp.targetKeyCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void unregisterAllHotKeys() // must register hot keys in the same
|
||||
// thread that is watching for hotkey
|
||||
// messages
|
||||
{
|
||||
// System.out.println("unregistering hotkeys");
|
||||
for (TargetKeyPress tkp : KeyboardHook.targetList) {
|
||||
if (!User32.INSTANCE.UnregisterHotKey(Pointer.NULL, tkp.idNumber)) {
|
||||
System.out.println("Couldn't unregister hotkey " + tkp.targetKeyCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// createGlobalKeyboardHook();
|
||||
createHotKeysHook();
|
||||
// System.out.println("Unhooking Global Keyboard Hook");
|
||||
unhook();// wait for quit == true then unhook
|
||||
}
|
||||
|
||||
public KeyboardHook() {
|
||||
}
|
||||
|
||||
public KeyboardHook(KeyboardEvents events) {
|
||||
this.events = events;
|
||||
}
|
||||
|
||||
public static void StartKeyboardHookThreaded(KeyboardEvents events) {
|
||||
quit = false;
|
||||
khThread = new Thread(new KeyboardHook(events));
|
||||
khThread.start();
|
||||
}
|
||||
|
||||
/*
|
||||
* // testing public static void main(String[] args) throws Exception {
|
||||
* //add target keys KeyboardHook.addKeyEvent(KeyEvent.VK_3, true, true,
|
||||
* false); KeyboardHook.addKeyEvent(KeyEvent.VK_5, false, true, false);
|
||||
* KeyboardHook.addKeyEvent(KeyEvent.VK_Q);
|
||||
*
|
||||
* //add global hook and event
|
||||
* KeyboardHook.StartGlobalKeyboardHookThreaded(new
|
||||
* KeyboardHook.KeyboardEvents() {
|
||||
*
|
||||
* @Override public void keyPressed(KeyboardHook.TargetKeyPress target) {
|
||||
* System.out.println("target key pressed " + target.targetKeyCode); if
|
||||
* (target.targetKeyCode == KeyEvent.VK_Q){ // if Q was pressed then unhook
|
||||
* KeyboardHook.stopGlobalKeyboardHook(); System.out.println("unhooking"); }
|
||||
* } }); }
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski7@gmail.com
|
||||
*/
|
||||
|
||||
package org.synthuse;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.platform.win32.WinDef.*;
|
||||
|
||||
public class MenuInfo {
|
||||
public HMENU hmenu = null;
|
||||
public String hmenuStr = "";
|
||||
public String hwndStr = "";
|
||||
public int menuCount = 0;
|
||||
public String text = "";
|
||||
public String unaltered = "";
|
||||
public int id = 0;
|
||||
public int position = 0;
|
||||
public boolean hasSubMenu = false;
|
||||
public HMENU submenu = null;
|
||||
public String submenuStr = "";
|
||||
public int submenuCount = 0;
|
||||
public String center = "";
|
||||
|
||||
public MenuInfo(String hwndStr, HMENU hmenu) {
|
||||
this.hwndStr = hwndStr;
|
||||
loadMenuBase(hmenu);
|
||||
}
|
||||
|
||||
public MenuInfo(String hwndStr, HMENU hmenu, int position) {
|
||||
this.hwndStr = hwndStr;
|
||||
loadMenuBase(hmenu);
|
||||
if (this.menuCount > 0)
|
||||
loadMenuDetails(hmenu, position);
|
||||
}
|
||||
|
||||
public void loadMenuBase(HMENU hmenu) {
|
||||
Api api = new Api();
|
||||
this.hmenu = hmenu;
|
||||
this.hmenuStr = GetHandleMenuAsString(hmenu);
|
||||
this.menuCount = api.user32.GetMenuItemCount(hmenu);
|
||||
}
|
||||
|
||||
public void loadMenuDetails(HMENU hmenu, int position) {
|
||||
Api api = new Api();
|
||||
this.position = position;
|
||||
this.unaltered = api.GetMenuItemText(hmenu, position);
|
||||
this.text = unaltered;
|
||||
if (this.unaltered.contains("\t"))
|
||||
this.text = this.text.substring(0, this.text.indexOf("\t"));
|
||||
this.text = text.replaceAll("[^a-zA-Z0-9.,\\+ ]", "");
|
||||
this.id = api.user32.GetMenuItemID(hmenu, position);
|
||||
/*
|
||||
HWND hWnd = Api.GetHandleFromString(hwndStr);
|
||||
RECT rect = new RECT();
|
||||
api.user32.GetMenuItemRect(hWnd, hmenu, position, rect);
|
||||
int centerX = ((rect.right - rect.left) / 2) + rect.left;
|
||||
int centerY = ((rect.bottom - rect.top) / 2) + rect.top;
|
||||
this.center = centerX + "," + centerY;
|
||||
*/
|
||||
HMENU submenu = api.user32.GetSubMenu(hmenu, position);
|
||||
if (submenu != null) {
|
||||
int subCount = api.user32.GetMenuItemCount(submenu);
|
||||
if (subCount > 0) {
|
||||
this.hasSubMenu = true;
|
||||
this.submenu = submenu;
|
||||
this.submenuStr = GetHandleMenuAsString(submenu);
|
||||
this.submenuCount = subCount;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static String GetHandleMenuAsString(HMENU hmenu) {
|
||||
if (hmenu == null)
|
||||
return "0";
|
||||
//String longHexStr = hWnd.toString().substring("native@".length());
|
||||
//String longHexStr = hmenu.getPointer()
|
||||
String longHexStr = hmenu.getPointer().toString().substring("native@0x".length());
|
||||
long l = new BigInteger(longHexStr, 16).longValue();
|
||||
return l + "";
|
||||
}
|
||||
|
||||
public static HMENU GetHandleMenuFromString(String hmenu) {
|
||||
if (hmenu == null)
|
||||
return null;
|
||||
if (hmenu.isEmpty())
|
||||
return null;
|
||||
String cleanNumericHandle = hmenu.replaceAll("[^\\d.]", "");
|
||||
try {
|
||||
return (new HMENU(new Pointer(Long.parseLong(cleanNumericHandle))));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski7@gmail.com
|
||||
*/
|
||||
|
||||
package org.synthuse;
|
||||
|
||||
import com.sun.jna.platform.win32.WinDef.HWND;
|
||||
|
||||
public class WinPtr {
|
||||
|
||||
public HWND hWnd = null;
|
||||
public String hWndStr = "";
|
||||
public String runtimeId = "";
|
||||
|
||||
public String hmenuStr = "";//store menu handle
|
||||
public int hmenuPos = -1;//store menu position or id
|
||||
|
||||
public WinPtr() {
|
||||
}
|
||||
|
||||
public WinPtr(HWND hWnd) {
|
||||
this.hWnd = hWnd;
|
||||
this.hWndStr = Api.GetHandleAsString(hWnd);
|
||||
}
|
||||
|
||||
public WinPtr(String runtimeId) {
|
||||
this.runtimeId = runtimeId;
|
||||
}
|
||||
|
||||
public boolean isWin32() {
|
||||
return (hWnd != null || !hWndStr.equals(""));
|
||||
}
|
||||
|
||||
public boolean isWpf() {
|
||||
return (!runtimeId.equals(""));
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return (hWnd == null && hWndStr.equals("") && runtimeId.equals(""));
|
||||
}
|
||||
|
||||
public static boolean isWpfRuntimeIdFormat(String runtimeIdTest) {
|
||||
return (runtimeIdTest.contains("-"));
|
||||
}
|
||||
|
||||
public void convertToNativeHwnd()
|
||||
{
|
||||
if (isWpfRuntimeIdFormat(runtimeId)){
|
||||
hWndStr = runtimeId.split("-")[1];
|
||||
hWnd = Api.GetHandleFromString(hWndStr);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (isWin32() && !hWndStr.equals(""))
|
||||
return hWndStr;
|
||||
else if (isWin32() && hWnd != null)
|
||||
{
|
||||
hWndStr = Api.GetHandleAsString(hWnd);
|
||||
return hWndStr;
|
||||
}
|
||||
else if (isWpf())
|
||||
return runtimeId;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
54
src/main/java/org/synthuse/interfaces/Kernel32Ex.java
Normal file
54
src/main/java/org/synthuse/interfaces/Kernel32Ex.java
Normal file
@@ -0,0 +1,54 @@
|
||||
package org.synthuse.interfaces;
|
||||
|
||||
import org.synthuse.objects.LVITEM_VISTA;
|
||||
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.platform.win32.BaseTSD.SIZE_T;
|
||||
import com.sun.jna.platform.win32.WinBase.SYSTEM_INFO;
|
||||
import com.sun.jna.platform.win32.WinDef.DWORD;
|
||||
import com.sun.jna.platform.win32.WinNT.HANDLE;
|
||||
import com.sun.jna.platform.win32.WinNT.LARGE_INTEGER;
|
||||
import com.sun.jna.ptr.IntByReference;
|
||||
import com.sun.jna.win32.W32APIOptions;
|
||||
|
||||
public interface Kernel32Ex extends W32APIOptions {
|
||||
Kernel32Ex instance = (Kernel32Ex) Native.loadLibrary("kernel32", Kernel32Ex.class, DEFAULT_OPTIONS);
|
||||
|
||||
boolean GetDiskFreeSpaceEx(String lpDirectoryName, LARGE_INTEGER.ByReference lpFreeBytesAvailable, LARGE_INTEGER.ByReference lpTotalNumberOfBytes, LARGE_INTEGER.ByReference lpTotalNumberOfFreeBytes);
|
||||
|
||||
int GetLastError();
|
||||
|
||||
Pointer OpenProcess(int dwDesiredAccess, boolean bInheritHandle, Pointer pointer);
|
||||
|
||||
// int OpenProcess(int dwDesiredAccess, boolean bInheritHandle, Pointer
|
||||
// pointer);
|
||||
boolean CloseHandle(HANDLE hObject);
|
||||
|
||||
void GetNativeSystemInfo(SYSTEM_INFO lpSystemInfo);
|
||||
|
||||
boolean IsWow64Process(HANDLE hProcess, IntByReference Wow64Process);
|
||||
|
||||
// LPVOID VirtualAllocEx(HANDLE hProcess, LPVOID lpAddress, SIZE_T
|
||||
// dwSize, DWORD flAllocationType, DWORD flProtect);
|
||||
|
||||
// int VirtualAllocEx(HANDLE hProcess, int lpAddress, int dwSize, DWORD
|
||||
// flAllocationType, DWORD flProtect);
|
||||
IntByReference VirtualAllocEx(HANDLE hProc, IntByReference addr, SIZE_T size, int allocType, int prot);
|
||||
|
||||
Pointer VirtualAllocEx(HANDLE hProc, int i, int lngMemLen2, int allocType, int pAGE_READWRITE);
|
||||
|
||||
boolean VirtualFreeEx(HANDLE hProcess, IntByReference lpAddress, SIZE_T dwSize, DWORD dwFreeType);
|
||||
|
||||
boolean WriteProcessMemory(HANDLE hProcess, IntByReference lpBaseAddress, Pointer lpBuffer, int len, IntByReference bytesWritten);
|
||||
|
||||
// boolean WriteProcessMemory(Pointer p, long address, Pointer buffer,
|
||||
// int size, IntByReference written);
|
||||
boolean ReadProcessMemory(Pointer hProcess, long inBaseAddress, Pointer outputBuffer, int nSize, IntByReference outNumberOfBytesRead);
|
||||
|
||||
int WriteProcessMemory(HANDLE handle, Pointer lngMemVar2, LVITEM_VISTA lvi, int lngMemLen2, IntByReference byteIO);
|
||||
|
||||
int ReadProcessMemory(HANDLE handle, Pointer lngMemVar1, Pointer lngVarPtr1, int lngMemLen1, IntByReference byteIO);
|
||||
|
||||
int VirtualFreeEx(HANDLE hProcess, Pointer lngMemVar1, int i, int mEM_RELEASE);
|
||||
}
|
||||
11
src/main/java/org/synthuse/interfaces/PsapiEx.java
Normal file
11
src/main/java/org/synthuse/interfaces/PsapiEx.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package org.synthuse.interfaces;
|
||||
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.win32.W32APIOptions;
|
||||
|
||||
public interface PsapiEx extends W32APIOptions {
|
||||
PsapiEx instance = (PsapiEx) Native.loadLibrary("psapi", PsapiEx.class, DEFAULT_OPTIONS);
|
||||
|
||||
int GetModuleBaseNameW(Pointer hProcess, Pointer hmodule, char[] lpBaseName, int size);
|
||||
}
|
||||
138
src/main/java/org/synthuse/interfaces/User32Ex.java
Normal file
138
src/main/java/org/synthuse/interfaces/User32Ex.java
Normal file
@@ -0,0 +1,138 @@
|
||||
package org.synthuse.interfaces;
|
||||
|
||||
import org.synthuse.objects.LVITEM_VISTA;
|
||||
|
||||
import com.sun.jna.Callback;
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.platform.win32.BaseTSD.LONG_PTR;
|
||||
import com.sun.jna.platform.win32.WinDef.HDC;
|
||||
import com.sun.jna.platform.win32.WinDef.HMENU;
|
||||
import com.sun.jna.platform.win32.WinDef.HWND;
|
||||
import com.sun.jna.platform.win32.WinDef.LPARAM;
|
||||
import com.sun.jna.platform.win32.WinDef.LRESULT;
|
||||
import com.sun.jna.platform.win32.WinDef.RECT;
|
||||
import com.sun.jna.platform.win32.WinDef.WPARAM;
|
||||
import com.sun.jna.platform.win32.WinUser.WNDENUMPROC;
|
||||
import com.sun.jna.ptr.PointerByReference;
|
||||
import com.sun.jna.win32.W32APIOptions;
|
||||
|
||||
public interface User32Ex extends W32APIOptions {
|
||||
User32Ex instance = (User32Ex) Native.loadLibrary("user32", User32Ex.class, DEFAULT_OPTIONS);
|
||||
|
||||
int SetWindowLongPtr(HWND hWnd, int nIndex, Callback callback);
|
||||
|
||||
LRESULT CallWindowProc(LONG_PTR proc, HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam);
|
||||
|
||||
boolean ShowWindow(HWND hWnd, int nCmdShow);
|
||||
|
||||
boolean SetForegroundWindow(HWND hWnd);
|
||||
|
||||
void SwitchToThisWindow(HWND hWnd, boolean fAltTab);
|
||||
|
||||
HWND SetFocus(HWND hWnd);
|
||||
|
||||
HWND FindWindow(String winClass, String title);
|
||||
|
||||
LRESULT PostMessage(HWND hWnd, int Msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
LRESULT SendMessage(HWND hWnd, int Msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
LRESULT SendMessage(HWND hWnd, int Msg, WPARAM wParam, LVITEM_VISTA lParam);
|
||||
|
||||
LRESULT SendMessageA(HWND editHwnd, int wmGettext, long l, byte[] lParamStr);
|
||||
|
||||
boolean DestroyWindow(HWND hWnd);
|
||||
|
||||
boolean EnumWindows(WNDENUMPROC wndenumproc, int lParam);
|
||||
|
||||
boolean EnumChildWindows(HWND hWnd, WNDENUMPROC lpEnumFunc, Pointer data);
|
||||
|
||||
HWND GetParent(HWND hWnd);
|
||||
|
||||
boolean IsWindowVisible(HWND hWnd);
|
||||
|
||||
boolean IsWindow(HWND hWnd);
|
||||
|
||||
int GetWindowRect(HWND hWnd, RECT r);
|
||||
|
||||
int MapWindowPoints(HWND hWndFrom, HWND hWndTo, RECT r, int cPoints);
|
||||
|
||||
HWND GetDesktopWindow();
|
||||
|
||||
HDC GetWindowDC(HWND hWnd);
|
||||
|
||||
int ReleaseDC(HWND hWnd, HDC hDC);
|
||||
|
||||
boolean InvalidateRect(HWND hWnd, long lpRect, boolean bErase);
|
||||
|
||||
boolean UpdateWindow(HWND hWnd);
|
||||
|
||||
boolean RedrawWindow(HWND hWnd, long lprcUpdate, long hrgnUpdate, int flags);
|
||||
|
||||
void GetWindowTextA(HWND hWnd, byte[] buffer, int buflen);
|
||||
|
||||
int GetTopWindow(HWND hWnd);
|
||||
|
||||
int GetWindow(HWND hWnd, int flag);
|
||||
|
||||
final int GW_HWNDNEXT = 2;
|
||||
|
||||
int GetClassName(HWND hWnd, char[] buffer2, int i);
|
||||
|
||||
int GetWindowModuleFileName(HWND hWnd, char[] buffer2, int i);
|
||||
|
||||
int GetWindowThreadProcessId(HWND hWnd, PointerByReference pref);
|
||||
|
||||
// int GetWindowThreadProcessId(HWND hWnd, IntByReference
|
||||
// lpdwProcessId);
|
||||
|
||||
boolean GetCursorPos(long[] lpPoint); // use macros POINT_X() and
|
||||
// POINT_Y() on long lpPoint[0]
|
||||
|
||||
HWND WindowFromPoint(long point);
|
||||
|
||||
HWND ChildWindowFromPointEx(HWND hwndParent, long point, int uFlags);
|
||||
|
||||
boolean ClientToScreen(HWND hWnd, long[] lpPoint);// use macros
|
||||
// POINT_X() and
|
||||
// POINT_Y() on long
|
||||
// lpPoint[0]
|
||||
|
||||
boolean ScreenToClient(HWND hWnd, long[] lpPoint);// use macros
|
||||
// POINT_X() and
|
||||
// POINT_Y() on long
|
||||
// lpPoint[0]
|
||||
// HWND WindowFromPoint(int xPoint, int yPoint);
|
||||
// HWND WindowFromPoint(POINT point);
|
||||
|
||||
HMENU GetMenu(HWND hWnd);
|
||||
|
||||
HMENU GetSystemMenu(HWND hWnd, boolean bRevert);
|
||||
|
||||
boolean IsMenu(HMENU hMenu);
|
||||
|
||||
int GetMenuString(HMENU hMenu, int uIDItem, char[] buffer, int nMaxCount, int uFlag);
|
||||
|
||||
HMENU GetSubMenu(HMENU hMenu, int nPos);
|
||||
|
||||
int GetMenuItemCount(HMENU hMenu);
|
||||
|
||||
int GetMenuItemID(HMENU hMenu, int nPos);
|
||||
|
||||
// BOOL WINAPI GetMenuItemInfo(_In_ HMENU hMenu, _In_ UINT uItem, _In_
|
||||
// BOOL fByPosition, _Inout_ LPMENUITEMINFO lpmii);
|
||||
boolean GetMenuItemInfoA(HMENU hMenu, int uItem, boolean fByPosition, WinDefEx.MENUITEMINFO mii); // MENUITEMINFO
|
||||
|
||||
boolean TrackPopupMenu(HMENU hMenu, int uFlags, int x, int y, int nReserved, HWND hWnd, long prcRect);
|
||||
|
||||
boolean GetMenuItemRect(HWND hWnd, HMENU hMenu, int uItem, RECT rect);
|
||||
|
||||
int GetDlgCtrlID(HWND hwndCtl);
|
||||
|
||||
int GetDlgItemText(HWND hDlg, int nIDDlgItem, byte[] buffer, int nMaxCount);
|
||||
|
||||
int GetMenuState(HMENU hMenuTopMenu, int uId, int uFlags);
|
||||
|
||||
HWND GetDlgItem(HWND hDlg, int nIDDlgItem);
|
||||
}
|
||||
80
src/main/java/org/synthuse/interfaces/WinDefEx.java
Normal file
80
src/main/java/org/synthuse/interfaces/WinDefEx.java
Normal file
@@ -0,0 +1,80 @@
|
||||
package org.synthuse.interfaces;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.Structure;
|
||||
import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR;
|
||||
|
||||
public interface WinDefEx extends com.sun.jna.platform.win32.WinDef {
|
||||
// Structures
|
||||
public class MENUITEMINFO extends Structure {
|
||||
public static final int MFS_CHECKED = 0x00000008;
|
||||
public static final int MFS_DEFAULT = 0x00001000;
|
||||
public static final int MFS_DISABLED = 0x00000003;
|
||||
public static final int MFS_ENABLED = 0x00000000;
|
||||
public static final int MFS_GRAYED = 0x00000003;
|
||||
public static final int MFS_HILITE = 0x00000080;
|
||||
public static final int MFS_UNCHECKED = 0x00000000;
|
||||
public static final int MFS_UNHILITE = 0x00000000;
|
||||
public static final int MFT_STRING = 0x0000;
|
||||
public static final int MIIM_DATA = 0x00000020;
|
||||
public static final int MIIM_STRING = 0x0040;
|
||||
public static final int MIIM_SUBMENU = 0x0004;
|
||||
public static final int MIIM_TYPE = 0x0010;
|
||||
|
||||
public static class ByValue extends MENUITEMINFO implements Structure.ByValue {
|
||||
}
|
||||
|
||||
public static class ByReference extends MENUITEMINFO implements Structure.ByReference {
|
||||
}
|
||||
|
||||
public MENUITEMINFO() {
|
||||
cbSize = size();
|
||||
}
|
||||
|
||||
public MENUITEMINFO(Pointer p) {
|
||||
super(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<?> getFieldOrder() {
|
||||
return Arrays.asList(new String[] { "cbSize", "fMask", "fType", "fState", "wID", "hSubMenu", "hbmpChecked", "hbmpUnchecked", "dwItemData", "dwTypeData", "cch", "hbmpItem" });
|
||||
}
|
||||
|
||||
public int cbSize; // The size of the structure, in bytes. The
|
||||
// caller must set this member to
|
||||
// sizeof(MENUITEMINFO).
|
||||
public int fMask; // Indicates the members to be retrieved or set.
|
||||
// MIIM_STRING or MIIM_SUBMENU or ...
|
||||
public int fType; // The menu item type. fType is used only if fMask
|
||||
// has a value of MIIM_FTYPE.
|
||||
public int fState; // The menu item state. This member can be one or
|
||||
// more of these values. Set fMask to MIIM_STATE
|
||||
// to use fState.
|
||||
public int wID; // An application-defined value that identifies the
|
||||
// menu item. Set fMask to MIIM_ID to use wID.
|
||||
public HMENU hSubMenu; // A handle to the drop-down menu or submenu
|
||||
// associated with the menu item. Or NULL
|
||||
public HBITMAP hbmpChecked; // A handle to the bitmap to display
|
||||
// next to the item if it is selected.
|
||||
public HBITMAP hbmpUnchecked; // A handle to the bitmap to display
|
||||
// next to the item if it is not
|
||||
// selected.
|
||||
public ULONG_PTR dwItemData; // An application-defined value
|
||||
// associated with the menu item. Set
|
||||
// fMask to MIIM_DATA
|
||||
// public byte[] dwTypeData = new byte[256];
|
||||
public String dwTypeData; // The contents of the menu item, depends
|
||||
// on the value of fType and is used only
|
||||
// if the MIIM_TYPE flag is set in the
|
||||
// fMask member
|
||||
public int cch; // The length of the menu item text, in characters,
|
||||
// when information is received about a menu item of
|
||||
// the MFT_STRING type.
|
||||
public HBITMAP hbmpItem; // A handle to the bitmap to be displayed,
|
||||
// or it can be one of the values in the
|
||||
// following table.
|
||||
}
|
||||
}
|
||||
42
src/main/java/org/synthuse/objects/COPYDATASTRUCT.java
Normal file
42
src/main/java/org/synthuse/objects/COPYDATASTRUCT.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package org.synthuse.objects;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.Structure;
|
||||
import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR;
|
||||
|
||||
public class COPYDATASTRUCT extends Structure {
|
||||
// The by-reference version of this structure.
|
||||
public static class ByReference extends COPYDATASTRUCT implements Structure.ByReference {
|
||||
}
|
||||
|
||||
public COPYDATASTRUCT() {
|
||||
}
|
||||
|
||||
// Instantiates a new COPYDATASTRUCT with existing data given the
|
||||
// address of that data.
|
||||
public COPYDATASTRUCT(final long pointer) {
|
||||
this(new Pointer(pointer));
|
||||
}
|
||||
|
||||
// Instantiates a new COPYDATASTRUCT with existing data given a
|
||||
// pointer to that data.
|
||||
public COPYDATASTRUCT(final Pointer memory) {
|
||||
super(memory);
|
||||
read();
|
||||
}
|
||||
|
||||
public ULONG_PTR dwData; // The data to be passed to the receiving
|
||||
// application.
|
||||
public int cbData; // The size, in bytes, of the data pointed to by
|
||||
// the lpData
|
||||
public Pointer lpData;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
protected final List getFieldOrder() {
|
||||
return Arrays.asList(new String[] { "dwData", "cbData", "lpData" });
|
||||
}
|
||||
}
|
||||
34
src/main/java/org/synthuse/objects/LVITEM_VISTA.java
Normal file
34
src/main/java/org/synthuse/objects/LVITEM_VISTA.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package org.synthuse.objects;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.Structure;
|
||||
import com.sun.jna.platform.win32.WinDef.LPARAM;
|
||||
|
||||
// 64bit LVITEM size 88
|
||||
// 32bit LVITEM size 60
|
||||
public class LVITEM_VISTA extends Structure {
|
||||
public int mask;
|
||||
public int iItem;
|
||||
public int iSubItem;
|
||||
public int state;
|
||||
public int stateMask;
|
||||
public Pointer pszText;
|
||||
public int cchTextMax;
|
||||
public int iImage;
|
||||
public LPARAM lParam;
|
||||
public int iIndent;
|
||||
public int iGoupId;
|
||||
public int cColumns;
|
||||
public Pointer puColumns;
|
||||
// NTDDI_VERSION >= NTDDI_VISTA
|
||||
public Pointer piColFmt;
|
||||
public int iGroup;
|
||||
|
||||
@Override
|
||||
protected List<?> getFieldOrder() {
|
||||
return Arrays.asList(new String[] { "mask", "iItem", "iSubItem", "state", "stateMask", "pszText", "cchTextMax", "iImage", "lParam", "iIndent", "iGoupId", "cColumns", "puColumns", "piColFmt", "iGroup" });
|
||||
}
|
||||
}
|
||||
104
src/main/java/org/synthuse/objects/MenuInfo.java
Normal file
104
src/main/java/org/synthuse/objects/MenuInfo.java
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski7@gmail.com
|
||||
*/
|
||||
|
||||
package org.synthuse.objects;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import org.synthuse.Api;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.platform.win32.WinDef.*;
|
||||
|
||||
public class MenuInfo {
|
||||
public HMENU hmenu = null;
|
||||
public String hmenuStr = "";
|
||||
public String hwndStr = "";
|
||||
public int menuCount = 0;
|
||||
public String text = "";
|
||||
public String unaltered = "";
|
||||
public int id = 0;
|
||||
public int position = 0;
|
||||
public boolean hasSubMenu = false;
|
||||
public HMENU submenu = null;
|
||||
public String submenuStr = "";
|
||||
public int submenuCount = 0;
|
||||
public String center = "";
|
||||
|
||||
public MenuInfo(String hwndStr, HMENU hmenu) {
|
||||
this.hwndStr = hwndStr;
|
||||
loadMenuBase(hmenu);
|
||||
}
|
||||
|
||||
public MenuInfo(String hwndStr, HMENU hmenu, int position) {
|
||||
this.hwndStr = hwndStr;
|
||||
loadMenuBase(hmenu);
|
||||
if (this.menuCount > 0)
|
||||
loadMenuDetails(hmenu, position);
|
||||
}
|
||||
|
||||
public void loadMenuBase(HMENU hmenu) {
|
||||
Api api = new Api();
|
||||
this.hmenu = hmenu;
|
||||
this.hmenuStr = GetHandleMenuAsString(hmenu);
|
||||
this.menuCount = api.user32.GetMenuItemCount(hmenu);
|
||||
}
|
||||
|
||||
public void loadMenuDetails(HMENU hmenu, int position) {
|
||||
Api api = new Api();
|
||||
this.position = position;
|
||||
this.unaltered = api.GetMenuItemText(hmenu, position);
|
||||
this.text = unaltered;
|
||||
if (this.unaltered.contains("\t"))
|
||||
this.text = this.text.substring(0, this.text.indexOf("\t"));
|
||||
this.text = text.replaceAll("[^a-zA-Z0-9.,\\+ ]", "");
|
||||
this.id = api.user32.GetMenuItemID(hmenu, position);
|
||||
/*
|
||||
* HWND hWnd = Api.GetHandleFromString(hwndStr); RECT rect = new RECT();
|
||||
* api.user32.GetMenuItemRect(hWnd, hmenu, position, rect); int centerX
|
||||
* = ((rect.right - rect.left) / 2) + rect.left; int centerY =
|
||||
* ((rect.bottom - rect.top) / 2) + rect.top; this.center = centerX +
|
||||
* "," + centerY;
|
||||
*/
|
||||
HMENU submenu = api.user32.GetSubMenu(hmenu, position);
|
||||
if (submenu != null) {
|
||||
int subCount = api.user32.GetMenuItemCount(submenu);
|
||||
if (subCount > 0) {
|
||||
this.hasSubMenu = true;
|
||||
this.submenu = submenu;
|
||||
this.submenuStr = GetHandleMenuAsString(submenu);
|
||||
this.submenuCount = subCount;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static String GetHandleMenuAsString(HMENU hmenu) {
|
||||
if (hmenu == null)
|
||||
return "0";
|
||||
// String longHexStr = hWnd.toString().substring("native@".length());
|
||||
// String longHexStr = hmenu.getPointer()
|
||||
String longHexStr = hmenu.getPointer().toString().substring("native@0x".length());
|
||||
long l = new BigInteger(longHexStr, 16).longValue();
|
||||
return l + "";
|
||||
}
|
||||
|
||||
public static HMENU GetHandleMenuFromString(String hmenu) {
|
||||
if (hmenu == null)
|
||||
return null;
|
||||
if (hmenu.isEmpty())
|
||||
return null;
|
||||
String cleanNumericHandle = hmenu.replaceAll("[^\\d.]", "");
|
||||
try {
|
||||
return (new HMENU(new Pointer(Long.parseLong(cleanNumericHandle))));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
24
src/main/java/org/synthuse/objects/MenuItem.java
Normal file
24
src/main/java/org/synthuse/objects/MenuItem.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package org.synthuse.objects;
|
||||
|
||||
import com.sun.jna.platform.win32.WinDef.HMENU;
|
||||
import com.sun.jna.platform.win32.WinDef.HWND;
|
||||
|
||||
public class MenuItem {
|
||||
public static final boolean EXACT = false;
|
||||
|
||||
public HWND hWnd;
|
||||
public HMENU hMenu;
|
||||
public String[] path;
|
||||
public boolean exact;
|
||||
|
||||
public MenuItem(HWND hWnd, HMENU hMenu, String... path) {
|
||||
this(hWnd, hMenu, EXACT, path);
|
||||
}
|
||||
|
||||
public MenuItem(HWND hWnd, HMENU hMenu, boolean exact, String... path) {
|
||||
this.hWnd = hWnd;
|
||||
this.hMenu = hMenu;
|
||||
this.exact = exact;
|
||||
this.path = path;
|
||||
}
|
||||
}
|
||||
69
src/main/java/org/synthuse/objects/WinPtr.java
Normal file
69
src/main/java/org/synthuse/objects/WinPtr.java
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski7@gmail.com
|
||||
*/
|
||||
|
||||
package org.synthuse.objects;
|
||||
|
||||
import org.synthuse.Api;
|
||||
|
||||
import com.sun.jna.platform.win32.WinDef.HWND;
|
||||
|
||||
public class WinPtr {
|
||||
|
||||
public HWND hWnd = null;
|
||||
public String hWndStr = "";
|
||||
public String runtimeId = "";
|
||||
|
||||
public String hmenuStr = "";// store menu handle
|
||||
public int hmenuPos = -1;// store menu position or id
|
||||
|
||||
public WinPtr() {
|
||||
}
|
||||
|
||||
public WinPtr(HWND hWnd) {
|
||||
this.hWnd = hWnd;
|
||||
this.hWndStr = Api.GetHandleAsString(hWnd);
|
||||
}
|
||||
|
||||
public WinPtr(String runtimeId) {
|
||||
this.runtimeId = runtimeId;
|
||||
}
|
||||
|
||||
public boolean isWin32() {
|
||||
return (hWnd != null || !hWndStr.equals(""));
|
||||
}
|
||||
|
||||
public boolean isWpf() {
|
||||
return (!runtimeId.equals(""));
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return (hWnd == null && hWndStr.equals("") && runtimeId.equals(""));
|
||||
}
|
||||
|
||||
public static boolean isWpfRuntimeIdFormat(String runtimeIdTest) {
|
||||
return (runtimeIdTest.contains("-"));
|
||||
}
|
||||
|
||||
public void convertToNativeHwnd() {
|
||||
if (isWpfRuntimeIdFormat(runtimeId)) {
|
||||
hWndStr = runtimeId.split("-")[1];
|
||||
hWnd = Api.GetHandleFromString(hWndStr);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (isWin32() && !hWndStr.equals(""))
|
||||
return hWndStr;
|
||||
else if (isWin32() && hWnd != null) {
|
||||
hWndStr = Api.GetHandleAsString(hWnd);
|
||||
return hWndStr;
|
||||
} else if (isWpf())
|
||||
return runtimeId;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,13 @@ import java.util.HashMap;
|
||||
import java.util.Random;
|
||||
|
||||
import org.synthuse.Api;
|
||||
import org.synthuse.objects.MenuItem;
|
||||
|
||||
import com.sun.jna.platform.win32.WinDef.HMENU;
|
||||
import com.sun.jna.platform.win32.WinDef.HWND;
|
||||
import com.sun.jna.platform.win32.WinDef.WPARAM;
|
||||
|
||||
public class Test {
|
||||
|
||||
public class Test {
|
||||
protected Api api;
|
||||
protected HWND hWndFound;
|
||||
protected HashMap<HWND, HMENU> windowMap;
|
||||
@@ -17,26 +17,6 @@ public class Test {
|
||||
protected HashMap<Slider, HashMap<Amount, MenuItem>> sliderMap;
|
||||
protected HashMap<Slider, HWND> valueMap;
|
||||
|
||||
class MenuItem {
|
||||
public static final boolean EXACT = false;
|
||||
|
||||
public HWND hWnd;
|
||||
public HMENU hMenu;
|
||||
public String[] path;
|
||||
public boolean exact;
|
||||
|
||||
public MenuItem(HWND hWnd, HMENU hMenu, String... path) {
|
||||
this(hWnd, hMenu, EXACT, path);
|
||||
}
|
||||
|
||||
public MenuItem(HWND hWnd, HMENU hMenu, boolean exact, String... path) {
|
||||
this.hWnd = hWnd;
|
||||
this.hMenu = hMenu;
|
||||
this.exact = exact;
|
||||
this.path = path;
|
||||
}
|
||||
}
|
||||
|
||||
public Test() {
|
||||
api = new Api();
|
||||
windowMap = new HashMap<HWND, HMENU>();
|
||||
|
||||
Reference in New Issue
Block a user