You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Lua ffi中通过WM_LBUTTONDOWN监听鼠标左键点击获取布尔值

实现步骤(Windows平台+LuaJIT FFI示例,其他语言FFI逻辑通用)

1. ffi.cdef 类型与API声明

你需要先在cdef中声明用到的Windows系统类型、常量和API,示例如下:

local ffi = require("ffi")
ffi.cdef[[
// 基础Windows类型定义
typedef void* HWND;
typedef unsigned int UINT;
typedef uintptr_t WPARAM;
typedef intptr_t LPARAM;
typedef int BOOL;
typedef long LRESULT;

// 鼠标消息相关常量
static const int WM_LBUTTONDOWN = 0x0201;
static const int MK_LBUTTON = 0x0001;
static const int VK_LBUTTON = 0x01;

// 用到的系统API声明
LRESULT DefWindowProcA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL GetMessageA(void* lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax);
BOOL TranslateMessage(const void* lpMsg);
LRESULT DispatchMessageA(const void* lpMsg);
short GetAsyncKeyState(int vKey);
void Sleep(int dwMilliseconds);
]]

2. 功能实现

方案A:通过WM_LBUTTONDOWN消息获取状态(匹配你的调研需求)

适合有窗口程序、需要在消息回调中处理左键按下事件的场景:

local left_button_state = false
-- 窗口过程回调函数
local function window_proc(hwnd, msg, wparam, lparam)
    if msg == ffi.C.WM_LBUTTONDOWN then
        left_button_state = true -- 左键按下时更新布尔状态
        -- 可选:提取点击坐标,低16位为x,高16位为y
        local x = bit.band(lparam, 0xffff)
        local y = bit.rshift(bit.band(lparam, 0xffff0000), 16)
        print("左键按下,坐标:"..x..","..y)
        return 0
    end
    -- 其他消息交给系统默认处理
    return ffi.C.DefWindowProcA(hwnd, msg, wparam, lparam)
end

-- 消息循环示例(需要先完成窗口注册创建,省略窗口创建逻辑)
local msg = ffi.new("char[48]") -- 适配32/64位的MSG结构体缓冲区
while ffi.C.GetMessageA(msg, nil, 0, 0) > 0 do
    ffi.C.TranslateMessage(msg)
    ffi.C.DispatchMessageA(msg)
end

方案B:直接查询左键状态(更轻量,无窗口也可使用)

如果你不需要绑定窗口,只是要随时获取左键点击状态,用GetAsyncKeyState实现更简单:

local user32 = ffi.load("user32")
-- 调用该函数直接返回左键是否按下的布尔值
local function get_left_button_state()
    -- 返回值最高位为1代表按键处于按下状态
    return bit.band(user32.GetAsyncKeyState(ffi.C.VK_LBUTTON), 0x8000) ~= 0
end

-- 测试示例
while true do
    local state = get_left_button_state()
    print("左键当前状态:"..tostring(state))
    ffi.C.Sleep(100)
end

注意事项

  • 以上示例基于Windows平台,WM_LBUTTONDOWN是Windows专属消息常量,跨平台场景需要调整对应系统的接口
  • 如果你用的是其他语言的FFI(比如Python的cffi),cdef的声明语法基本一致,仅上层调用语法需要对应调整
  • 避免硬编码MSG结构体大小的话,可以在cdef中补充完整的MSG结构体定义即可

内容的提问来源于stack exchange,提问作者Alpha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 07:09:03