下面列出了org.junit.jupiter.api.condition.EnabledOnOs#com.sun.jna.platform.win32.WinUser 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void doKeyRelease(int keyCode) {
logRobot(stdAutoDelay, "KeyRelease: WaitForIdle: %s - Delay: %d");
setAutoDelay(stdAutoDelay);
// on Windows we detect the current layout in KeyboardLayout.
// Since this layout is not compatible to AWT Robot, we have to use
// the User32 API to simulate the key release
if (Settings.AutoDetectKeyboardLayout && Settings.isWindows()) {
int scanCode = SXUser32.INSTANCE.MapVirtualKeyW(keyCode, 0);
SXUser32.INSTANCE.keybd_event((byte)keyCode, (byte)scanCode, new WinDef.DWORD(WinUser.KEYBDINPUT.KEYEVENTF_KEYUP), new BaseTSD.ULONG_PTR(0));
}else{
keyRelease(keyCode);
}
if (stdAutoDelay == 0) {
delay(stdDelay);
}
logRobot("KeyRelease: extended delay: %d", stdMaxElapsed);
}
private int switchAppWindow(WindowInfo window) {
HWND hwnd = window.getHwnd();
WinUser.WINDOWPLACEMENT lpwndpl = new WinUser.WINDOWPLACEMENT();
user32.GetWindowPlacement(hwnd, lpwndpl);
if (lpwndpl.showCmd == WinUser.SW_SHOWMINIMIZED || lpwndpl.showCmd == WinUser.SW_MINIMIZE) {
user32.ShowWindow(hwnd, WinUser.SW_RESTORE);
}
boolean success = user32.SetForegroundWindow(hwnd);
if (success) {
user32.SetFocus(hwnd);
IntByReference windowPid = new IntByReference();
user32.GetWindowThreadProcessId(hwnd, windowPid);
return windowPid.getValue();
} else {
return 0;
}
}
/**
* Forcibly set focus to the given component
*
*/
public static void requestForeground(Frame frame)
{
// SetForegroundWindow can't set iconified windows to foreground, so set the
// frame state to normal first
frame.setState(Frame.NORMAL);
User32 user32 = User32.INSTANCE;
// Windows does not allow any process to set the foreground window, but it will if
// the process received the last input event. So we send a F22 key event to the process.
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setforegroundwindow
WinUser.INPUT input = new WinUser.INPUT();
input.type = new WinDef.DWORD(WinUser.INPUT.INPUT_KEYBOARD);
input.input.ki.wVk = new WinDef.WORD(0x85); // VK_F22
user32.SendInput(new WinDef.DWORD(1), (WinUser.INPUT[]) input.toArray(1), input.size());
// Now we may set the foreground window
WinDef.HWND hwnd = new WinDef.HWND(Native.getComponentPointer(frame));
user32.SetForegroundWindow(hwnd);
}
public static void main(String[] args) {
final User32 user32 = User32.INSTANCE;
user32.EnumWindows(new WinUser.WNDENUMPROC() {
int count = 0;
@Override
public boolean callback(WinDef.HWND hwnd, Pointer pointer) {
byte[] windowText = new byte[512];
byte[] className = new byte[512];
user32.GetWindowTextA(hwnd, windowText, 512);
user32.GetClassNameA(hwnd, className, 512);
String title = Native.toString(windowText);
String classN = Native.toString(className);
// get rid of this if block if you want all windows regardless of whether
// or not they have text
if (title.isEmpty()) {
return true;
}
System.out.println("Title: " + title + " Class name: " + classN);
return true;
}
},null);
}
public void pressKeys(final List<KeyboardKey> keys) {
if (keys.isEmpty()) {
return;
}
final WinUser.INPUT input = new WinUser.INPUT();
final WinUser.INPUT[] inputs = (WinUser.INPUT[]) input.toArray(keys.size() * 2);
final ListIterator<KeyboardKey> iterator = keys.listIterator();
int index = 0;
while (iterator.hasNext()) {
setKeyDown(inputs[index], iterator.next());
index++;
}
while (iterator.hasPrevious()) {
setKeyUp(inputs[index], iterator.previous());
index++;
}
user32.SendInput(new WinDef.DWORD(inputs.length), inputs, inputs[0].size());
}
/**
* <p><b>Compatible only with windows!</b></p>
*/
protected void fetchEventWithUser32() {
final User32 lib = User32.INSTANCE;
final WinUser.MSG msg = new WinUser.MSG();
final boolean hasMessage = lib.PeekMessage(msg, null, 0, 0, 1);
if (hasMessage) {
lib.TranslateMessage(msg);
lib.DispatchMessage(msg);
}
}
@Test
@EnabledOnOs(OS.WINDOWS)
@Disabled("Only run manually")
void cameraConnectedIsSeenWithUser32() throws InterruptedException {
// This test demonstrate how to get events from library using User32 but better to use EdsGetEvent of library
final User32 lib = User32.INSTANCE;
final AtomicBoolean cameraEventCalled = new AtomicBoolean(false);
TestShortcutUtil.registerCameraAddedHandler(inContext -> {
log.warn("Camera added called {}", inContext);
cameraEventCalled.set(true);
return new NativeLong(0);
});
final WinUser.MSG msg = new WinUser.MSG();
for (int i = 0; i < 100; i++) {
Thread.sleep(50);
final boolean hasMessage = lib.PeekMessage(msg, null, 0, 0, 1);
if (hasMessage) {
log.warn("Had message");
lib.TranslateMessage(msg);
lib.DispatchMessage(msg);
}
}
Assertions.assertTrue(cameraEventCalled.get());
}
public static List<WindowInfo> allWindows() {
/* Initialize the empty window list. */
final List<WindowInfo> windows = new ArrayList<>();
/* Enumerate all of the windows and add all of the one for the
* given process id to our list. */
boolean result = user32.EnumWindows(
new WinUser.WNDENUMPROC() {
public boolean callback(
final HWND hwnd, final Pointer data) {
if (user32.IsWindowVisible(hwnd)) {
IntByReference windowPid = new IntByReference();
user32.GetWindowThreadProcessId(hwnd, windowPid);
String windowTitle = getWindowTitle(hwnd);
windows.add(new WindowInfo(hwnd, windowPid.getValue(), windowTitle));
}
return true;
}
},
null);
/* Handle errors. */
if (!result && Kernel32.INSTANCE.GetLastError() != 0) {
throw new RuntimeException("Couldn't enumerate windows.");
}
/* Return the window list. */
return windows;
}
public static void updateStageStyle(Stage stage) {
if (Platform.isWindows()) {
Pointer pointer = getWindowPointer(stage);
WinDef.HWND hwnd = new WinDef.HWND(pointer);
final User32 user32 = User32.INSTANCE;
int oldStyle = user32.GetWindowLong(hwnd, WinUser.GWL_STYLE);
int newStyle = oldStyle | 0x00020000; // WS_MINIMIZEBOX
user32.SetWindowLong(hwnd, WinUser.GWL_STYLE, newStyle);
}
}
private void setTransparent(Component w) {
this.componentHwnd = getHWnd(w);
this.settingWl = User32.INSTANCE.GetWindowLong(componentHwnd, WinUser.GWL_EXSTYLE);
int transparentWl = User32.INSTANCE.GetWindowLong(componentHwnd, WinUser.GWL_EXSTYLE) |
WinUser.WS_EX_LAYERED |
WinUser.WS_EX_TRANSPARENT;
User32.INSTANCE.SetWindowLong(componentHwnd, WinUser.GWL_EXSTYLE, transparentWl);
}
private static void setTransparent(Component w) {
WinDef.HWND hwnd = getHWnd(w);
int wl = User32.INSTANCE.GetWindowLong(hwnd, WinUser.GWL_EXSTYLE);
// wl = wl | WinUser.WS_EX_LAYERED | WinUser.WS_EX_TRANSPARENT;
wl = wl | WinUser.WS_EX_LAYERED | WinUser.WS_EX_TRANSPARENT;
User32.INSTANCE.SetWindowLong(hwnd, WinUser.GWL_EXSTYLE, wl);
}
/**
* Create keyboard input event.
*
* @param character character to print
* @param flags flags
* @return keyboard input event
*/
private static WinUser.INPUT createKeyboardInput(char character, long flags) {
WinUser.INPUT input = new WinUser.INPUT();
input.type = new WinDef.DWORD(WinUser.INPUT.INPUT_KEYBOARD);
input.input.setType("ki");
input.input.ki = new WinUser.KEYBDINPUT();
input.input.ki.wVk = new WinDef.WORD(0);
input.input.ki.wScan = new WinDef.WORD(character);
input.input.ki.time = new WinDef.DWORD(0);
input.input.ki.dwFlags = new WinDef.DWORD(flags);
input.input.ki.dwExtraInfo = new BaseTSD.ULONG_PTR();
return input;
}
public void setDisplaySleep(final boolean sleep) {
user32.DefWindowProc(
getForegroundWindow().get(),
WinUser.WM_SYSCOMMAND,
new WinDef.WPARAM(SC_MONITORPOWER),
new WinDef.LPARAM(sleep ? 2 : -1)
);
}
public void run(final String command, final String parameters, final String workingDirectory)
throws SystemException {
final WinDef.INT_PTR result = shell32.ShellExecute(
null,
"open",
Objects.requireNonNull(command),
Objects.requireNonNull(parameters),
workingDirectory,
WinUser.SW_SHOWNORMAL
);
if (result.intValue() <= 32) {
throw new SystemException("Could not run command: " + command + " " + parameters);
}
}
public void open(final String uri) throws SystemException {
final WinDef.INT_PTR result = shell32.ShellExecute(
null,
"open",
Objects.requireNonNull(uri),
null,
null,
WinUser.SW_SHOWNORMAL
);
if (result.intValue() <= 32) {
throw new SystemException("Cannot open URI: " + uri);
}
}
public void focus(HWND mainWindowHandle) {
if (PlatformSpecific.isOnWindows()) {
// Restores browser window if it is minimized / maximized
user32.ShowWindow(browserWindowHandle, WinUser.SW_SHOWNOACTIVATE);
// SWP_NOMOVE and SWP_NOSIZE prevents the 0,0,0,0 parameters from taking effect.
logger.info("Bringing bView to front");
boolean success = user32.SetWindowPos(browserWindowHandle, mainWindowHandle, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
if (!success) {
logger.info("Failed to bring bView to front.");
logger.info(Kernel32.INSTANCE.GetLastError());
}
user32.SetForegroundWindow(mainWindowHandle);
}
}
public MouseHookThread(MouseEventReceiver eventReceiver) {
super(eventReceiver, WinUser.WH_MOUSE_LL);
}
public KeyHookThread(KeyEventReceiver eventReceiver) {
super(eventReceiver, WinUser.WH_KEYBOARD_LL);
}
public void enableSettings() {
User32.INSTANCE.SetWindowLong(componentHwnd, WinUser.GWL_EXSTYLE, settingWl);
}
/**
* Enter a text by sending input events through the Windows API via JNA.
*
* @param text text to send through the Windows API
* @throws WindowsException if the User32 library is not available or no events were processed
* @see <a href="https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-sendinput">SendInput function</a>
* @see <a href="https://stackoverflow.com/a/22308727">Using SendInput to send unicode characters beyond U+FFFF</a>
*/
private static void sendTextViaUser32(String text) throws WindowsException {
if (StringUtils.isEmpty(text))
return;
if (USER32 == null)
throw new WindowsException("User32 library was not loaded.");
//final List<Long> pointers = new ArrayList<>();
//noinspection EmptyFinallyBlock
try {
final List<WinUser.INPUT> events = new ArrayList<>();
for (int i = 0; i < text.length(); i++) {
final char c = text.charAt(i);
//LOGGER.debug("printing " + c);
events.add(createKeyboardInput(c, WinUser.KEYBDINPUT.KEYEVENTF_UNICODE));
events.add(createKeyboardInput(c, WinUser.KEYBDINPUT.KEYEVENTF_KEYUP | WinUser.KEYBDINPUT.KEYEVENTF_UNICODE));
}
//for (WinUser.INPUT i : events) {
// long address = Pointer.nativeValue(i.getPointer());
// if (!pointers.contains(address)) pointers.add(address);
//}
WinUser.INPUT[] inputs = events.toArray(new WinUser.INPUT[0]);
inputs = (WinUser.INPUT[]) inputs[0].toArray(inputs);
//for (WinUser.INPUT i : inputs) {
// long address = Pointer.nativeValue(i.getPointer());
// if (!pointers.contains(address)) pointers.add(address);
//}
final WinDef.DWORD result = USER32.SendInput(
new WinDef.DWORD(inputs.length), inputs, inputs[0].size());
if (result.intValue() < 1) {
LOGGER.error("last error: {}", Kernel32Util.getLastErrorMessage());
throw new WindowsException("No events were executed.");
}
//LOGGER.debug("result: {}", result.intValue());
} finally {
//for (Long address : pointers) {
// Kernel32Util.freeLocalMemory(new Pointer(address));
//}
}
}
public void closeWindow(final WinDef.HWND window) {
user32.SendMessage(window, WinUser.WM_CLOSE, null, null);
}
private void setKeyDown(final WinUser.INPUT input, final KeyboardKey key) {
input.type.setValue(WinUser.INPUT.INPUT_KEYBOARD);
input.input.setType(WinUser.KEYBDINPUT.class);
input.input.ki.wVk = key.getVirtualKeyCode();
}
private void setKeyUp(final WinUser.INPUT input, final KeyboardKey key) {
input.type.setValue(WinUser.INPUT.INPUT_KEYBOARD);
input.input.setType(WinUser.KEYBDINPUT.class);
input.input.ki.dwFlags.setValue(WinUser.KEYBDINPUT.KEYEVENTF_KEYUP);
input.input.ki.wVk = key.getVirtualKeyCode();
}
private void bringToTop() {
if (PlatformSpecific.isOnWindows()) {
user32.ShowWindow(browserWindowHandle, WinUser.SW_RESTORE);
user32.SetForegroundWindow(browserWindowHandle);
}
}
public void minimizeWindow() {
if (PlatformSpecific.isOnWindows()) {
user32.ShowWindow(browserWindowHandle, WinUser.SW_MINIMIZE);
}
}
boolean EnumWindows(WinUser.WNDENUMPROC lpEnumFunc, Pointer arg);