使用WinAPI向记事本程序发送消息的Lua Alien

我已经收集了一些在线资源帮助我做到了这一步。希望我的代码已经接近正确。不幸的是我没有Windows编程经验,我来自Linux背景。我也是第一次使用Alien进行Lua编程,但我已经足够熟悉Lua。

我想要做的是从 Win32 API 发送一个简单的“Hello World”消息到运行中的 Notepad.exe 窗口,使用 SendMessage()

我使用以下命令从命令提示符中获得了进程ID:

tasklist /FI "IMAGENAME eq notepad.exe" /FI "USERNAME eq user"

notepad PID

我从这里获取要发送的消息代码为0x000C

到目前为止,这就是我所拥有的:

require "luarocks.require"
require "alien"

myTestMessage = 0x000C -- Notepad "Set text" id
notepadPID = 2316      -- Notepad Process ID

-- 函数 SendMessage 的原型是从 User32.dll 中导入
local SendMessage= alien.User32.SendMessageA
SendMessage:types{ret ='long', abi = 'stdcall','long','long','string','string'}

-- 函数 FindWindowExA 的原型是从 User32.dll 中导入
local FindWindowEx = alien.User32.FindWindowExA
FindWindowEx:types{ret = 'long', abi = 'stdcall', 'long', 'long', 'string', 'string'}

-- 函数 GetWindowThreadProcessID 的原型是从 User32.dll 中导入
local GetWindowThreadProcessId = alien.User32.GetWindowThreadProcessId
GetWindowThreadProcessId:types{ret = 'long', abi = 'stdcall', 'long', 'pointer'}

local buffer = alien.buffer(4) -- 创建一个4字节的缓冲区

local threadID = GetWindowThreadProcessId(notepadPID, buffer) -- 填充threadID和我们的4字节缓冲区

local longFromBuffer = buffer:get(1, 'long') -- 告诉缓冲区从第一个字节开始,由x字节组成一个long值'longFromBuffer'(long类型)

local handle = FindWindowEx(threadID, "0", "Edit", nil); -- 获得要发送消息的句柄

local x = SendMessage(handle, myTestMessage, "0", "Hello World!") -- 发送消息

其中很多这些代码都是从Lua alien documentsmsdn以及一些Google搜索中拼凑起来的(尤其是这个结果)。

有没有人能够成为英雄,向我解释我哪里出错了,我应该如何去做。最重要的是,为什么!

原文链接 https://stackoverflow.com/questions/16920492

点赞
stackoverflow用户65863
stackoverflow用户65863

你正在错误地使用 GetWindowThreadProcessId() 和 FindWindowEx()。它们的第一个参数都是所需窗口的 HWND 句柄,但是你正在将进程 ID 传递给 GetWindowThreadProcessId(),并将线程 ID 传递给 FindWindowEx(),这两种做法都是错误的。

从进程 ID 获取 HWND 的方法并不直接。你需要使用 EnumWindows() 循环遍历当前正在运行的窗口,在每个窗口上调用 GetWindowThreadProcessId(),直到找到与你已有的进程 ID 匹配的窗口为止。

2013-06-04 14:51:16
stackoverflow用户1366973
stackoverflow用户1366973

我最终找到了一个更简单的方法来使用 Windows API 中的 FindWindowFindWindowEX 来查找 Notepad 的父进程和子进程的正确句柄。

-- 引入必要的 luarocks 和 alien 类库
require "luarocks.require"
require "alien"

-- 声明调用 Windows 函数时需要使用的类型
local SendMessage= alien.User32.SendMessageA
SendMessage:types{ret ='long', abi = 'stdcall','long','long','string','string'}

local FindWindowEx = alien.User32.FindWindowExA
FindWindowEx:types{ret = 'long', abi = 'stdcall', 'long', 'long', 'string', 'string'}

local FindWindow = alien.User32.FindWindowA
FindWindow:types{ret = 'long', abi = 'stdcall', 'string', 'string'}

-- 查找 Notepad 的窗口句柄
local notepadHandle = FindWindow("Notepad", NULL )

-- 查找 Notepad 子进程的句柄
local childHandle = FindWindowEx(notepadHandle, "0", "Edit", nil)

-- 发送消息
local x = SendMessage(childHandle, "0x000C", "0", "Hello World!") -- 实际发送消息
2014-03-05 14:56:15