Hey there! Some background so you can better answer my question:
I’m a beginner in Julia (with a long background in hobbyist coding in various languages).
I set myself to learn the language by creating an automation module, instead of the usual helloworld/AOC way.
How ever, I ran in some problems in a couple of very basic API call’s and I’m too green to realise why.
Here are the snippets, SendMessage times out on every handle I try (Error 258). Which in my basic understanding means that some of the arguments are wrong, but I can’t see which and why.
const HANDLE = Ptr{Cvoid}
const LPSTR = Vector{UInt8}
function RegisterWindowMessage(message::String)
msg = Vector{UInt8}(message)
return ccall((:RegisterWindowMessageA, "user32"), stdcall, Cint, (Ptr{Vector{UInt8}},), Ref(msg) )
end
function SendWindowMessage(handle::HANDLE, msg::Cint)
buffer = LPSTR(undef, 512)
retval = ccall((:SendMessageA, "user32"), stdcall, Cint, (HANDLE, Cint, Cint, Ptr{UInt8}), handle, msg, sizeof(buffer), buffer)
if retval == 0
return "NA"
else
buffer[end] = 0
return String(unsafe_string(pointer(buffer),retval))
end
end
msg = RegisterWindowMessage("WM_GETCONTROLNAME")
SendWindowMessage(HANDLE(app.HWND), msg))
Sorry if the snippets are formatted wrong, couldn’t find codeblock option 
Hello, I’m not exactly sure what your code should achieve and what desired output is, but I can help your from Julia side.
The code you provided isn’t self contained so I modified it a bit:
const HANDLE = Ptr{Cvoid}
const LPSTR = Vector{UInt8}
function RegisterWindowMessage(message::String)
msg = Vector{UInt8}(message)
return ccall((:RegisterWindowMessageA, "user32"), stdcall, Cint, (Ptr{Vector{UInt8}},), Ref(msg) )
end
function SendWindowMessage(handle::HANDLE, msg::Cint)
buffer = LPSTR(undef, 512)
retval = ccall((:SendMessageA, "user32"), stdcall, Cint, (HANDLE, Cint, Cint, Ptr{UInt8}), handle, msg, sizeof(buffer), buffer)
if retval == 0
return "NA"
else
buffer[end] = 0
return String(unsafe_string(pointer(buffer),retval))
end
end
function main()
hwnd = Ptr{Int32}(Int64(0xffff))
msg = RegisterWindowMessage("WM_GETCONTROLNAME")
@show msg
SendWindowMessage(HANDLE(hwnd), msg)
end
This is the output I get:
julia> main()
msg = 49822
"\0"
I can give you working example with SendMessageA, but I haven’t used RegisterWindowMessageA before, so I don’t know about that.
Sorry about that, I really can’t give a working example without being able to pick a process from your computer.
I’m also a bit uncertain about which part of the code you need clarification on, so I’m going to explain the full process.
I pick a running process (ie. calculator.exe) and list all the childwindows it has, then I’ll select on of them (ie. “+”-button) and save the handle of that window.
I register WM_CONTROLNAME message, and receive the message id from the API call, which I use with “SendMessageA” as the msg.
The “SendMessageA” call should cause WinAPI to write the child window’s name to the provided buffer.
The same way this snippet works ( You need to provide a hwnd of type PTR{Cvoid} )
function GetWindowText(handle::HANDLE)
name = LPSTR(undef, 256)
length = ccall((:GetWindowTextA, "user32"), stdcall, Cint, (HANDLE, Ptr{UInt8}, Cint), handle, name, sizeof(name))
if length == 0
return ""
else
name[end] = 0
name_str = String(unsafe_string(pointer(name),length))
end
return name_str
end
I’d love to have a look at your working SendMessageA example, even if it’s about a different message.
Sorry, I still can’t figure out how to fix your code. Have you tried implementing this in another language?
Anyway, I extracted an example from my code:
const WM_CLOSE = 0x000010
function findwindowex(class::AbstractString, child::Ptr{Int32})
hwnd = ccall((:FindWindowExA, "user32"), Ptr{Int32},
(Ptr{Int32}, Ptr{Int32}, Cstring, Cstring),
Ptr{Int32}(), child, class, C_NULL)
return hwnd
end
function sendmessage(hwnd::Ptr{Int32}, msg::UInt32, wparam::Ptr{Int32}, lparam::Ptr{Int32})
ccall((:SendMessageA, "user32"), Int32,
(Ptr{Int32}, UInt32, Ptr{Int32}, Ptr{Int32}),
hwnd, msg, wparam, lparam)
end
function main()
hwnd = findwindowex("Notepad", Ptr{Int32}())
sendmessage(hwnd, WM_CLOSE, Ptr{Int32}(), Ptr{Int32}())
end
This should close Notepad.