本文介绍了您如何将击键发送到非活动窗口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

:有没有一种方法可以使用JNA将模拟按键发送到不活动的窗口(因为Java是我最强的语言)?当然,当有另一种语言可以实现此目标时,我会这么做.

as the title describes: Is there a way to send simulated keystrokes to an inactive window by using JNA ( ,because Java is my strongest language)? Of course when there is an alternative language, which can achieve this goal, I'd go for that.

除了JNA之外,我还在网上读了很多东西,但没有达到这个目标.

I read lots of stuff on the web, also besides JNA but with no succes for this goal.

现在,我能够使用JNA的sendInput()模拟击键,但是那不是想要的,因为它会影响活动窗口.您可以在此处阅读有关内容: https://docs.microsoft.com/zh-CN/windows/desktop/api/winuser/nf-winuser-sendinput

Right now I am able to simulate keystrokes with sendInput() with JNA but thats not what want, because it effects the active window.You can read about that here: https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-sendinput

我的理解是,您可以为该主题使用sendMessage(),但我无法使其正常运行. https://docs.microsoft.com/zh-cn/windows/desktop/api/winuser/nf-winuser-sendmessage

My understanding is that you can use sendMessage() for that topic, but I cant get it working.https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-sendmessage

LRESULT SendMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

LRESULT SendMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

还有SendMessageA和SendMessageW.有人说SendMessage对于某些操作系统来说太老了,但我无法验证.

There are also SendMessageA and SendMessageW. Some say SendMessage is too old for some os, but I could not verify that.

让我们以记事本为例.窗口标题为"new 2-Notepad ++"

Lets take Notepad as an example.The window title is 'new 2 - Notepad++'

Keydown: https://docs.microsoft.com/en-us/windows/desktop/inputdev/wm-keydown

关键字: https://docs.microsoft.com/en-us/windows/desktop/inputdev/wm-keyup

import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.LPARAM;
import com.sun.jna.platform.win32.WinDef.WPARAM;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

public interface User32 extends StdCallLibrary {
User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class, W32APIOptions.DEFAULT_OPTIONS);
LRESULT SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
}

public void winAPI() throws InterruptedException {
    HWND handler = User32.INSTANCE.FindWindow(null, "new 2 - Notepad++");
    // 0x0100 WM_KEYDOWN
    User32.INSTANCE.SendMessage(handler, 0x0100, new WinDef.WPARAM(0x31), new WinDef.LPARAM(0)}
    // recommended for dedection
    Thread.sleep(200);
    // 0x0101 WM_KEYUP
    User32.INSTANCE.SendMessage(handler, 0x0101, new WinDef.WPARAM(0x31), new WinDef.LPARAM(0)}
}

我对SendMessage(A?)(W?)()的正确实现感到困惑,因为它不是在JNA中实现的.

I struggle with the right implementation of SendMessage(A?)(W?)() since its not implemented in JNA.

您还如何创建WPARAM和LPARAM?MSDN说有特定的消息.因此,当将WM_KEYDOWN或WM_KEYUP作为消息参数传递时:

Also how do you create WPARAM and LPARAM?MSDN says there are message specific.So when pass WM_KEYDOWN or WM_KEYUP as message parameter:

WPARAM是虚拟的KeyCode:仅仅是一个整数?

WPARAM is the virual KeyCode: just an int?

LPARAM是字节数组(?).

LPARAM is a bytearray(?).

我想它不起作用,因为WPARAM和LPARAM的参数数据类型错误.

I guess it doesnt work because of wrong parameter datatypes of WPARAM and LPARAM.

推荐答案

我对JNA不熟悉,但是将从winapi方面给出以下信息.希望这可以帮助您找到解决方案.

I am not familiar with JNA but I'll give the following information from winapi aspect. Hope this helps you find the solution.

SendMessageA和SendMessageW代表SendMessage函数的Ascii和Unicode版本.它们具有相同的功能.请参阅Windows API中的 Unicode ".

The SendMessageA and SendMessageW represent Ascii and Unicode version of SendMessage function. They have the same capability. Refer to "Unicode in the Windows API".

因此,请随时在JNA中使用SendMessage.

So feel free use SendMessage in JNA.

对于不活动的窗口,由于您没有焦点,因此无法从系统收到诸如WM_KEYUP之类的按键消息.但是您可以模拟系统以将这种消息发送到非活动窗口.您可以参考以下代码. (初始线程)

For the inactive window, you can't receive a keystroke message like WM_KEYUP from the system because you have no focus. But you can simulate the system to send this kind of message to the inactive window. You can refer to the following code. (Initial thread)

#include <windows.h>
#include <iostream>
#include <string>


int main()
{
    LPCWSTR Target_window_Name = TEXT("Untitled - Notepad"); //<- Has to match window name
    HWND hWindowHandle = FindWindow(NULL, Target_window_Name);
    HWND EditClass = FindWindowEx(hWindowHandle, NULL, L"Edit", NULL);

    SendMessage(EditClass, WM_KEYDOWN, 0x5A, 0x002C0001);
    SendMessage(EditClass, WM_CHAR, 0x7A, 0x002C0001); //"z"
    SendMessage(EditClass, WM_KEYUP, 0x5A, 0xC02C0001);

    return(0);
}

您需要根据其他消息创建WPARAM和LPARAM.例如对于WM_KEYDOWN消息,wParam是非系统密钥的虚拟密钥代码.请参阅虚拟键代码.在上面的示例代码中,Z键的虚拟键代码为0x5A.因此,wParam为0x5A.与WM_KEYUP消息相同.在WM_CHAR消息中,wParam是密钥的字符代码.您可以在Ascii表中找到小写的"z"为0x7A.您还需要提供这些消息的扫描代码.您可以搜索键盘扫描代码规范-Microsoft". "Z"的扫描代码为0x2C. WM_KEYUP消息的lParam的最后一个比特30和31始终为1.因此它从0xC0开始.

You need create WPARAM and LPARAM based on a different message. For example, WM_KEYDOWN message, wParam is the virtual-key code of the nonsystem key. See Virtual-Key Codes. In sample code above, the virtual-key code of Z key is 0x5A. So wParam is 0x5A. Same with WM_KEYUP message. In WM_CHAR message, wParam is the character code of the key. You can find in the Ascii table, the lowercase "z" is 0x7A. You also need to provide the scan code for these messages. You can search "Keyboard Scan Code Specification - Microsoft". The scan code of "Z" is 0x2C. The last, bit 30 and 31 of lParam of WM_KEYUP message are always 1. So it starts as 0xC0.

更多参考资料:" WM_KEYDOWN消息" " WM_KEYUP消息"" WM_CHAR消息"

More references: "WM_KEYDOWN message" "WM_KEYUP message" "WM_CHAR message"

这篇关于您如何将击键发送到非活动窗口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 07:57