In Windows I'm trying to get the title of the active window. I want to send keystrokes to an app, but can only do that if it has the focus, or the keyboard entry will end up in the wrong application. So I need to check first. However, I get an empty string with this code :
import winim/lean
var
handle: HWND
hasFocus = GetActiveWindow()
windowTitle: cstring # wstring
echo "Active window handle : "
echo repr(GetActiveWindow())
echo repr(GetWindowTextA(GetActiveWindow(), windowTitle, 128))
echo windowTitle
Thank you ! I also found wAuto with which I can :
getTitle(getActiveWindow())
Technically, I suggest to use unicode API (GetWindowTextU, or just GetWindowText by default) instead of ansi one (GetWindowTextA). So what you need is a unicode buffer, or better, one buffer can be unicode or ansi depend on conditional symbol. winstr module can help you.
template T(x: Natural): untyped
## Generate wstring or mstring buffer depend on conditional symbol: useWinAnsi.
## Use & to get the buffer address and then pass to Windows API.
Moreover, after GetWindowText returning the title, the buffer is still full of '0' in the end. You can set the correct length (returned by GetWindowText), or just use nullTerminated.
So here is some example to do the same thing.
import winim/lean
let handle = GetForegroundWindow()
var
windowTitle1 = T(128)
windowTitle2 = T(128)
# Use GetWindowTextLength should be the best way
windowTitle3 = T(int GetWindowTextLength(handle))
echo "Active window handle : "
GetWindowText(handle, &windowTitle1, 128)
windowTitle1.nullTerminate() # you can comment this line to see what different
windowTitle2.setLen(GetWindowText(handle, &windowTitle2, 128))
# GetWindowText need the length including the null character
GetWindowText(handle, &windowTitle3, cint(windowTitle3.len + sizeof(TChar)))
echo repr windowTitle1
echo repr windowTitle2
echo repr windowTitle3
BTW, I am glad that you found wAuto is useful. Your code is ok, but following code is more nimish.
echo activeWindow().title