# RegisterWindowMessage and SendMessage

**URL:** <https://discourse.julialang.org/t/registerwindowmessage-and-sendmessage/64299>\
**Category:** New to Julia\
**Tags:** question, windows, ccall, c\
**Created:** [July 8, 2021, 6:59pm UTC](https://discourse.julialang.org/t/registerwindowmessage-and-sendmessage/64299 "2021-07-08T18:59:41Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![crivens](https://avatars.discourse-cdn.com/v4/letter/c/4bbf92/32.png) [@crivens](https://discourse.julialang.org/u/crivens)\
**Post date:** [July 8, 2021, 6:59pm UTC](https://discourse.julialang.org/t/registerwindowmessage-and-sendmessage/64299/1 "2021-07-08T18:59:41Z")

</div>

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.

```julia
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 ☹

---

<div class="post-metadata">

**Author:** ![LinasBa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/linasba/32/20957_2.png) [@LinasBa](https://discourse.julialang.org/u/LinasBa)\
**Post date:** [July 9, 2021, 12:10pm UTC](https://discourse.julialang.org/t/registerwindowmessage-and-sendmessage/64299/2 "2021-07-09T12:10:21Z")

</div>

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:

```julia
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
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.

---

<div class="post-metadata">

**Author:** ![crivens](https://avatars.discourse-cdn.com/v4/letter/c/4bbf92/32.png) [@crivens](https://discourse.julialang.org/u/crivens)\
**Post date:** [July 9, 2021, 12:41pm UTC](https://discourse.julialang.org/t/registerwindowmessage-and-sendmessage/64299/3 "2021-07-09T12:41:17Z")

</div>

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} )

```julia
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.

---

<div class="post-metadata">

**Author:** ![LinasBa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/linasba/32/20957_2.png) [@LinasBa](https://discourse.julialang.org/u/LinasBa)\
**Post date:** [July 9, 2021, 1:16pm UTC](https://discourse.julialang.org/t/registerwindowmessage-and-sendmessage/64299/4 "2021-07-09T13:16:52Z")

</div>

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:

```julia
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.
