I am trying to get the current foreground window title using JNA and Jython. My code is just a translation of a Java code to accomplish the same. Code in Java works - I have tested it - and was taken from here: https://stackoverflow.com/a/10315344/1522521
When I call GetLastError()
I get 1400
code back, which is ERROR_INVALID_WINDOW_HANDLE
- stating that the window handle is invalid. I am sure that window handle is correct, because I can successfully call GetWindowTextLength();
ShowWindow(handle, WinUser.SW_MINIMIZE);
and ShowWindow(handle, WinUser.SW_MAXIMIZE);
to get the length of the title (seems correct) and manipulate the window.
I have a hunch, that the problem is with how I use variable text
as argument for GetWindowText()
. According to JNA's Javadoc it suppose to be char[]
buffer for JNA to copy the text. As I simply pass 'string' it may be incorrect. This is my code:
def get_current_window_text():
"""
Get current foreground window title.
"""
handle = User32.INSTANCE.GetForegroundWindow()
if User32.INSTANCE.IsWindowVisible(handle):
print "Text lenght:", User32.INSTANCE.GetWindowTextLength(handle)
max_length = 512
text = ''
result = User32.INSTANCE.GetWindowText(handle, text, max_length)
print "Copied text length:", result
if result:
print "Window text:", text
return result
else:
last_error_code = Kernel32.INSTANCE.GetLastError()
if last_error_code == Kernel32.ERROR_INVALID_WINDOW_HANDLE:
print "[ERROR] GetWindowText: Invalid Window handle!"
else:
print "[ERROR] Unknown error code:", last_error_code
else:
print "[ERROR] Current window is not visible"
My hunch was correct, the problems was with incorrect argument when calling GetWindowText(). It suppose to be char[]
- not a Jython variable. This lead me to research more and find something I wasn't aware before - Java arrays in Jython. As stated in Jython documentation http://www.jython.org/archive/21/docs/jarray.html :
Many Java methods require Java array objects as arguments. The way that these arguments are used means that they must correspond to fixed-length, mutable sequences, sometimes of primitive data types. The PyArray class is added to support these Java arrays and instances of this class will be automatically returned from any Java method call that produces an array. In addition, the "jarray" module is provided to allow users of Jython to create these arrays themselves, primarily for the purpose of passing them to a Java method.
The documentation has the mapping table as well. The working code would be something like this:
import jarray
text_length = User32.INSTANCE.GetWindowTextLength(handle)
max_length = 512
text = jarray.zeros(text_length, 'c')
result = User32.INSTANCE.GetWindowText(handle, text, max_length)
print 'Copied text:', result