使用WinAPI向记事本程序发送消息的Lua Alien
2017-5-23 12:19:44
收藏:0
阅读:194
评论:2
我已经收集了一些在线资源帮助我做到了这一步。希望我的代码已经接近正确。不幸的是我没有Windows编程经验,我来自Linux背景。我也是第一次使用Alien进行Lua编程,但我已经足够熟悉Lua。
我想要做的是从 Win32 API
发送一个简单的“Hello World”消息到运行中的 Notepad.exe
窗口,使用 SendMessage()
。
我使用以下命令从命令提示符中获得了进程ID:
tasklist /FI "IMAGENAME eq notepad.exe" /FI "USERNAME eq user"
我从这里获取要发送的消息代码为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 documents、msdn以及一些Google搜索中拼凑起来的(尤其是这个结果)。
有没有人能够成为英雄,向我解释我哪里出错了,我应该如何去做。最重要的是,为什么!
原文链接 https://stackoverflow.com/questions/16920492
点赞
stackoverflow用户1366973
我最终找到了一个更简单的方法来使用 Windows API 中的 FindWindow 和 FindWindowEX 来查找 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
评论区的留言会收到邮件通知哦~
推荐文章
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
你正在错误地使用 GetWindowThreadProcessId() 和 FindWindowEx()。它们的第一个参数都是所需窗口的 HWND 句柄,但是你正在将进程 ID 传递给 GetWindowThreadProcessId(),并将线程 ID 传递给 FindWindowEx(),这两种做法都是错误的。
从进程 ID 获取 HWND 的方法并不直接。你需要使用 EnumWindows() 循环遍历当前正在运行的窗口,在每个窗口上调用 GetWindowThreadProcessId(),直到找到与你已有的进程 ID 匹配的窗口为止。