簡體   English   中英

如何將擊鍵發送到非活動窗口?

[英]How do you send keystrokes to an inactive window?

如標題所述:是否有一種方法可以通過使用JNA將模擬擊鍵發送到非活動窗口(因為Java是我最強的語言)? 當然,當有另一種語言可以實現此目標時,我會這么做。

除了JNA之外,我還在網絡上閱讀了很多東西,但沒有達到這個目標。

現在,我可以使用JNA的sendInput()模擬擊鍵,但這不是想要的,因為它會影響活動窗口。 您可以在此處閱讀有關內容: https : //docs.microsoft.com/zh-cn/windows/desktop/api/winuser/nf-winuser-sendinput

我的理解是您可以為該主題使用sendMessage(),但我無法使其正常工作。 https://docs.microsoft.com/zh-CN/windows/desktop/api/winuser/nf-winuser-sendmessage

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

也有SendMessageA和SendMessageW。 有人說SendMessage對於某些操作系統來說太舊了,但是我無法驗證這一點。

讓我們以記事本為例。 窗口標題為“新2-記事本++”

鍵盤輸入: https ://docs.microsoft.com/zh-cn/windows/desktop/inputdev/wm-keydown

鍵盤: https ://docs.microsoft.com/zh-cn/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中實現。

另外,如何創建WPARAM和LPARAM? MSDN說有特定的消息。 因此,當傳遞WM_KEYDOWN或WM_KEYUP作為消息參數時:

WPARAM是虛擬的KeyCode:僅僅是一個整數?

LPARAM是一個字節數組(?)。

我想這是行不通的,因為WPARAM和LPARAM的參數數據類型錯誤。

我不熟悉JNA,但將從winapi方面提供以下信息。 希望這可以幫助您找到解決方案。

也有SendMessageA和SendMessageW。 有人說SendMessage對於某些操作系統來說太舊了,但是我無法驗證這一點。

SendMessageA和SendMessageW代表SendMessage函數的Ascii和Unicode版本。 它們具有相同的功能。 請參閱“ Windows API中的Unicode ”。

我對SendMessage(A?)(W?)()的正確實現感到困惑,因為它沒有在JNA中實現。

因此,可以在JNA中隨意使用SendMessage。

對於不活動的窗口,由於您沒有焦點,因此無法從系統收到諸如WM_KEYUP之類的按鍵消息。 但是您可以模擬系統以將這種消息發送到非活動窗口。 您可以參考以下代碼。 初始線程

#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? MSDN說有特定的消息。

您需要根據其他消息創建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開始。

更多參考:“ WM_KEYDOWN消息 ”“ WM_KEYUP消息 ”“ WM_CHAR消息

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM