【Unity知識分享】Unity實現全局監聽鍵鼠調用

1、實現該功能前,優先學習Unity接入dll調用Window系統接口教程

【Unity知識分享】Unity接入dll調用Window系統接口

2、初始化動態連接庫后,進行腳本功能實現

2.1 創建腳本KeyBoardHook.h和KeyBoardHook.cpp,實現功能如下

KeyBoardHook.h

#pragma once
#include <windows.h>#ifdef MYNATIVE_EXPORTS
#define MY_API __declspec(dllexport)
#else
#define MY_API __declspec(dllimport)
#endif // MYNATIVE_EXPORTSextern "C" {//定義一個回調的函數指針typedef void(__stdcall* KeyCallback)(int vkCode);MY_API bool InstallHook(HWND hWnd, KeyCallback callback);MY_API void UninstallHook();
}LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam);

KeyBoardHook.cpp

#include "KeyBoardHook.h"
//#include <Windows.h>HHOOK g_hHook = NULL;
HHOOK g_hMouseHook = NULL;
HWND g_hwnd = NULL;
KeyCallback g_callback = nullptr;extern "C" {MY_API bool InstallHook(HWND hwnd, KeyCallback callback){g_hwnd = hwnd;g_callback = callback;g_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, GetModuleHandle(NULL), 0);g_hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseProc, GetModuleHandle(NULL), 0);return g_hHook != NULL;}MY_API void UninstallHook() {if (g_hHook) {UnhookWindowsHookEx(g_hHook);UnhookWindowsHookEx(g_hMouseHook);g_hHook = NULL;g_hMouseHook = NULL;g_callback = nullptr;}}
}LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) 
{if (nCode == HC_ACTION && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)){KBDLLHOOKSTRUCT* kb = (KBDLLHOOKSTRUCT*)lParam;OutputDebugStringA("keyboardProc triggered\n");if (g_hwnd && g_callback){OutputDebugStringA("Calling Unity callback\n");g_callback((int)kb->vkCode);}else{OutputDebugStringA("g_callback is null\n");}}return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{if (nCode == HC_ACTION){int vkCode = 0;MSLLHOOKSTRUCT* ms = (MSLLHOOKSTRUCT*)lParam;switch (wParam){case WM_LBUTTONDOWN:vkCode = VK_LBUTTON;break;case WM_RBUTTONDOWN:vkCode = VK_RBUTTON;break;case WM_MBUTTONDOWN:vkCode = VK_MBUTTON;break;default:return CallNextHookEx(g_hMouseHook, nCode, wParam, lParam);}OutputDebugStringA("MouseProc triggered\n");if (g_hwnd && g_callback) {OutputDebugStringA("Calling Unity mouse callback\n");g_callback(vkCode);}else{OutputDebugStringA("g_callback is null\n");}}return CallNextHookEx(g_hMouseHook, nCode, wParam, lParam);
}

2.2 生成dll包

3、將dll包導入Unity,并實現dll包實現功能

3.1 創建Plugins文件夾,將dll包復制到該文件夾下面

3.2 將dll設置為PC的x64

3.3 創建腳本KeyboardHook,實現具體功能邏輯,代碼如下

KeyboardHook

using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.UI;public class KeyboardHook : MonoBehaviour
{[UnmanagedFunctionPointer(CallingConvention.StdCall)]public delegate void KeyCallback(int vkCode);[DllImport("UnityDll.dll")]private static extern bool InstallHook(IntPtr hwnd, KeyCallback callback);[DllImport("UnityDll.dll")]private static extern void UninstallHook();private static KeyCallback callbackDelegate;private IntPtr _hwnd;public Text txt_NumberText;public Text txt_vkText;private int num = 0;private Dictionary<int, string> keyCodeToStringDic = new Dictionary<int, string>{// 字母鍵 (A-Z){ 65, "A" }, { 66, "B" }, { 67, "C" }, { 68, "D" }, { 69, "E" },{ 70, "F" }, { 71, "G" }, { 72, "H" }, { 73, "I" }, { 74, "J" },{ 75, "K" }, { 76, "L" }, { 77, "M" }, { 78, "N" }, { 79, "O" },{ 80, "P" }, { 81, "Q" }, { 82, "R" }, { 83, "S" }, { 84, "T" },{ 85, "U" }, { 86, "V" }, { 87, "W" }, { 88, "X" }, { 89, "Y" },{ 90, "Z" },// 數字鍵 (0-9){ 48, "0" }, { 49, "1" }, { 50, "2" }, { 51, "3" }, { 52, "4" },{ 53, "5" }, { 54, "6" }, { 55, "7" }, { 56, "8" }, { 57, "9" },// 數字小鍵盤 (NumPad 0-9){ 96, "NumPad 0" }, { 97, "NumPad 1" }, { 98, "NumPad 2" },{ 99, "NumPad 3" }, { 100, "NumPad 4" }, { 101, "NumPad 5" },{ 102, "NumPad 6" }, { 103, "NumPad 7" }, { 104, "NumPad 8" },{ 105, "NumPad 9" },// 功能鍵 (F1-F12){ 112, "F1" }, { 113, "F2" }, { 114, "F3" }, { 115, "F4" },{ 116, "F5" }, { 117, "F6" }, { 118, "F7" }, { 119, "F8" },{ 120, "F9" }, { 121, "F10" }, { 122, "F11" }, { 123, "F12" },// 方向鍵{ 38, "Up Arrow" }, { 40, "Down Arrow" },{ 37, "Left Arrow" }, { 39, "Right Arrow" },// 特殊鍵{ 27, "Escape" }, { 9, "Tab" }, { 20, "Caps Lock" },{ 16, "Shift" }, { 17, "Control" }, { 18, "Alt" },{ 91, "Left Windows" }, { 92, "Right Windows" },{ 93, "Application" }, { 32, "Space" }, { 13, "Enter" },{ 8, "Backspace" }, { 46, "Delete" }, { 45, "Insert" },{ 36, "Home" }, { 35, "End" }, { 33, "Page Up" },{ 34, "Page Down" }, { 44, "Print Screen" }, { 145, "Scroll Lock" },{ 19, "Pause" }, { 144, "Num Lock" },// 小鍵盤操作符{ 107, "NumPad +" }, { 109, "NumPad -" }, { 106, "NumPad *" },{ 111, "NumPad /" }, { 110, "NumPad ." },// 標點符號(美式鍵盤){ 186, ";:" }, { 187, "=+" }, { 188, ",<" },{ 189, "-_" }, { 190, ".>" }, { 191, "/?" },{ 192, "~`" }, { 219, "[{" }, { 220, "\\|" },{ 221, "]}" }, { 222, "'\"" },//鼠標按鍵{1, "Left Mouse Key" },{2, "Right Mouse Key" },{4, "Middle Mouse Key" },};private void Awake(){_hwnd = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;callbackDelegate = OnKeyPressed;bool res = InstallHook(_hwnd, callbackDelegate);if(!res){Debug.LogError("鉤子安裝失敗!");}else{Debug.Log("鉤子安裝成功!");}}private void OnDestroy(){UninstallHook();}private string GetKeyName(int vkCode){if(keyCodeToStringDic.ContainsKey(vkCode))return keyCodeToStringDic[vkCode];return "Null";}private void OnKeyPressed(int vkCode){string keyName = GetKeyName(vkCode);Debug.Log(vkCode);Debug.Log(KeyCode.W);Debug.Log((int)KeyCode.W);//設置Text文字內容if (txt_NumberText){txt_NumberText.text = (num++).ToString();}if(txt_vkText){txt_vkText.text = keyName;}}}

3.4 創建兩個Text,一個記錄點擊鍵鼠次數,一個用于顯示當前按下鍵鼠鍵位,創建空物體拖拽腳本,并將Text拖拽到腳本中

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/97948.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/97948.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/97948.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

深度學習篇---MNIST:手寫數字數據集

下面我將詳細介紹使用 PyTorch 處理 MNIST 手寫數字數據集的完整流程&#xff0c;包括數據加載、模型定義、訓練和評估&#xff0c;并解釋每一行代碼的含義和注意事項。整個流程可以分為五個主要步驟&#xff1a;準備工作、數據加載與預處理、模型定義、模型訓練和模型評估。# …

k8s集群搭建(二)-------- 集群搭建

安裝 containerd 需要在集群內的每個節點上都安裝容器運行時&#xff08;containerd runtime&#xff09;&#xff0c;這個軟件是負責運行容器的軟件。 1. 啟動 ipv4 數據包轉發 # 設置所需的 sysctl 參數&#xff0c;參數在重新啟動后保持不變 cat <<EOF | sudo tee …

【Docker】P1 前言:容器化技術發展之路

目錄容器發展之路物理服務器時代&#xff1a;一機一應用的局限虛擬化時代&#xff1a;突破與局限并存容器化時代&#xff1a;輕量級的革新技術演進的價值體現各位&#xff0c;歡迎來到容器化時代。 容器發展之路 現代業務的核心是應用程序&#xff08;Application&#xff09;…

WPF依賴屬性和依賴屬性的包裝器:

依賴屬性是WPF&#xff08;Windows Presentation Foundation&#xff09;中的一種特殊類型的屬性&#xff0c;特別適用于內存使用優化和屬性值繼承。依賴屬性的定義包括以下幾個步驟&#xff1a; 使用 DependencyProperty.Register 方法注冊依賴屬性。 該方法需要四個參數&…

圖生圖算法

圖生圖算法研究細分&#xff1a;技術演進、應用與爭議 1. 基于GAN的傳統圖生圖方法 定義&#xff1a;利用生成對抗網絡&#xff08;GAN&#xff09;將輸入圖像轉換為目標域圖像&#xff08;如語義圖→照片、草圖→彩圖&#xff09;。關鍵發展與趨勢&#xff1a; Pix2Pix&#…

Go 自建庫的使用教程與測試

附加一個Go庫的實現&#xff0c;相較于Python&#xff0c;Go的實現更較為日常&#xff0c;不需要額外增加setup.py類的文件去額外定義,計算和并發的性能更加。 1. 創建 Go 模塊項目結構 首先創建完整的項目結構&#xff1a; gomathlib/ ├── go.mod ├── go.sum ├── cor…

What is a prototype network in few-shot learning?

A prototype network is a method used in few-shot learning to classify new data points when only a small number of labeled examples (the “shots”) are available per class. It works by creating a representative “prototype” for each class, which is typical…

Linux中用于線程/進程同步的核心函數——`sem_wait`函數

<摘要> sem_wait 是 POSIX 信號量操作函數&#xff0c;用于對信號量執行 P 操作&#xff08;等待、獲取&#xff09;。它的核心功能是原子地將信號量的值減 1。如果信號量的值大于 0&#xff0c;則減 1 并立即返回&#xff1b;如果信號量的值為 0&#xff0c;則調用線程&…

25高教社杯數模國賽【B題超高質量思路+問題分析】

注&#xff1a;本內容由”數模加油站“ 原創出品&#xff0c;雖無償分享&#xff0c;但創作不易。 歡迎參考teach&#xff0c;但請勿抄襲、盜賣或商用。 B 題 碳化硅外延層厚度的確定碳化硅作為一種新興的第三代半導體材料&#xff0c;以其優越的綜合性能表現正在受到越來越多…

【Linux篇章】再續傳輸層協議UDP :從低可靠到極速傳輸的協議重生之路,揭秘無連接通信的二次進化密碼!

&#x1f4cc;本篇摘要&#xff1a; 本篇將承接上次的UDP系列網絡編程&#xff0c;來深入認識下UDP協議的結構&#xff0c;特性&#xff0c;底層原理&#xff0c;注意事項及應用場景&#xff01; &#x1f3e0;歡迎拜訪&#x1f3e0;&#xff1a;點擊進入博主主頁 &#x1f4c…

《A Study of Probabilistic Password Models》(IEEE SP 2014)——論文閱讀

提出更高效的密碼評估工具&#xff0c;將統計語言建模技術引入密碼建模&#xff0c;系統評估各類概率密碼模型性能&#xff0c;打破PCFGw的 “最優模型” 認知。一、研究背景當前研究存在兩大關鍵問題&#xff1a;一是主流的 “猜測數圖” 計算成本極高&#xff0c;且難以覆蓋強…

校園外賣點餐系統(代碼+數據庫+LW)

摘要 隨著校園生活節奏的加快&#xff0c;學生對外賣的需求日益增長。然而&#xff0c;傳統的外賣服務存在諸多不便&#xff0c;如配送時間長、菜品選擇有限、信息更新不及時等。為解決這些問題&#xff0c;本研究開發了一款校園外賣點餐系統&#xff0c;采用前端 Vue、后端 S…

友思特案例 | 食品行業視覺檢測案例集錦(三)

食品制造質量檢測對保障消費者安全和產品質量穩定至關重要&#xff0c;覆蓋原材料至成品全階段&#xff0c;含過程中檢測與成品包裝檢測。近年人工智能深度學習及自動化系統正日益融入食品生產。本篇文章將介紹案例三&#xff1a;友思特Neuro-T深度學習平臺進行面餅質量檢測。在…

SQLynx 3.7 發布:數據庫管理工具的性能與交互雙重進化

目錄 &#x1f511; 核心功能更新 1. 單頁百萬級數據展示 2. 更安全的數據更新與刪除機制 3. 更智能的 SQL 代碼提示 4. 新增物化視圖與外表支持 5. 數據庫搜索與過濾功能重構 ? 總結與思考 在大數據與云原生應用快速發展的今天&#xff0c;數據庫管理工具不僅要“能用…

10G網速不是夢!5G-A如何“榨干”毫米波,跑出比5G快10倍的速度?

5G-A&#xff08;5G-Advanced&#xff09;網絡技術已經在中國福建省廈門市軟件園成功實現萬兆&#xff08;10Gbps&#xff09;速率驗證&#xff0c;標志著我國正式進入5G增強版商用階段。這一突破性成果不僅驗證了5G-A技術的可行性&#xff0c;也為6G網絡的發展奠定了堅實基礎。…

Linux筆記---UDP套接字實戰:簡易聊天室

1. 項目需求分析 我們要設計的是一個簡單的匿名聊天室&#xff0c;用戶的客戶端要求用戶輸入自己的昵稱之后即可在一個公共的群聊當中聊天。 為了簡單起見&#xff0c;我們設計用戶在終端當中與客戶端交互&#xff0c;而在一個文件當中顯式群聊信息&#xff1a; 當用戶輸入的…

RTP打包與解包全解析:從RFC規范到跨平臺輕量級RTSP服務和低延遲RTSP播放器實現

引言 在實時音視頻系統中&#xff0c;RTSP&#xff08;Real-Time Streaming Protocol&#xff09;負責會話與控制&#xff0c;而 RTP&#xff08;Real-time Transport Protocol&#xff09;負責媒體數據承載。開發者在實現跨平臺、低延遲的 RTSP 播放器或輕量級 RTSP 服務時&a…

Ubuntu 用戶和用戶組

一、 Linux 用戶linux 是一個多用戶操作系統&#xff0c;不同的用戶擁有不同的權限&#xff0c;可以查看和操作不同的文件。 Ubuntu 有三種用戶1、初次創建的用戶2、root 用戶---上帝3、普通用戶初次創建的用戶權限比普通用戶要多&#xff0c;但是沒有 root 用戶多。Linux 用戶…

FastGPT社區版大語言模型知識庫、Agent開源項目推薦

? FastGPT 項目說明 項目概述 FastGPT 是一個基于大語言模型&#xff08;LLM&#xff09;的知識庫問答系統&#xff0c;提供開箱即用的數據處理和模型調用能力&#xff0c;支持通過可視化工作流編排實現復雜問答場景。 技術架構 前端: Next.js TypeScript Chakra UI 后…

jsencrypt公鑰分段加密,支持后端解密

前端使用jsencryp實現分段加密。 解決長文本RSA加密報錯問題。 支持文本包含中文。 支持后端解密。前端加密代碼&#xff1a; // import { JSEncrypt } from jsencrypt const JSEncrypt require(jsencrypt) /*** 使用 JSEncrypt 實現分段 RSA 加密&#xff08;正確處理中文字符…