Get status bar text (PythonScript)
-
I am trying to get the status bar text (any of the bar’s sections) via PythonScript but apparently I cannot do that because it only provides a setStatusBar function but not a getter one.
So I used the code from this post, however the text returned by the function is a bunch of
NUL
characters. The number of characters is correct though, which indicates that it does return the text. For example when a file is “UTF-8” (shown in section STATUSBARSECTION.UNICODETYPE of the status bar) the text I get isNULNULNULNULNUL
, five characters.I have no idea how to modify a Win32 API function to fix this, anyone can help?
The function used is copied from the linked post.
-
I get the same results using Scott’s 2018 script.
That old script made some assumptions that weren’t necessarily always true (I think it was written for just the 32-bit Notepad++, and might not have been tried with 64-bit Notepad++).
Even my old statusbar code doesn’t work anymore (which i’ll have to fix, if I ever want to use it again; bummer).
But I knew I had seen successful statusbar interaction at some point more recent than that, so grepped through some of my archives, and found that being explicit about the
SendMessage()
argument and return types (.restype
and.argtypes
), and by passing the address of the text_buffer instead of the text buffer itself, I was able to edit Scott’s 2018 script to work in v8.6.9 with either PythonScript 2 or PythonScript 3.import ctypes from ctypes.wintypes import BOOL, HWND, WPARAM, LPARAM, UINT def npp_get_statusbar(statusbar_item_number): LRESULT = LPARAM WNDENUMPROC = ctypes.WINFUNCTYPE(BOOL, HWND, LPARAM) FindWindow = ctypes.windll.user32.FindWindowW SendMessage = ctypes.windll.user32.SendMessageW SendMessage.restype = LRESULT SendMessage.argtypes = [ HWND, UINT, WPARAM, LPARAM ] EnumChildWindows = ctypes.windll.user32.EnumChildWindows GetClassName = ctypes.windll.user32.GetClassNameW create_unicode_buffer = ctypes.create_unicode_buffer WM_USER = 0x400; SB_GETTEXTLENGTHW = WM_USER + 12; SB_GETTEXTW = WM_USER + 13 npp_get_statusbar.STATUSBAR_HANDLE = None def get_data_from_statusbar(statusbar_item_number): retcode = SendMessage(npp_get_statusbar.STATUSBAR_HANDLE, SB_GETTEXTLENGTHW, statusbar_item_number, 0) length = retcode & 0xFFFF type = (retcode >> 16) & 0xFFFF text_buffer = create_unicode_buffer(length) retcode = SendMessage(npp_get_statusbar.STATUSBAR_HANDLE, SB_GETTEXTW, statusbar_item_number, ctypes.addressof(text_buffer)) retval = '{}'.format(text_buffer[:length]) return retval def EnumCallback(hwnd, lparam): curr_class = create_unicode_buffer(256) GetClassName(hwnd, curr_class, 256) if curr_class.value.lower() == "msctls_statusbar32": npp_get_statusbar.STATUSBAR_HANDLE = hwnd return False return True EnumChildWindows(FindWindow(u"Notepad++", None), WNDENUMPROC(EnumCallback), 0) return get_data_from_statusbar(statusbar_item_number) if npp_get_statusbar.STATUSBAR_HANDLE else None
With that, an interactive PythonScript console can get the active language correctly from the status bar:
>>> npp_get_statusbar(0) 'Python file'
-
Works perfectly, thank you.