[program-l] Re: Use Windows Message to get info från Python

  • From: Karl-Otto Rosenqvist <karl-otto@xxxxxxxxxx>
  • To: program-l@xxxxxxxxxxxxx, travis@xxxxxxxxxxxxxx
  • Date: Sat, 29 Jan 2022 00:01:19 +0100

Thanks!
The first call was successful because it didn't need any params and it just returned an int.

the second one requires a struct to be passed and that struct needs to contain a string pointer so the text on the tab can be written to it.
I haven't been able to do this successfully.

The struct to be passed:

class TCITEMAStruct(Structure):
    _fields_=[
        ("mask", c_uint),
        ('state', wintypes.DWORD),
        ('stateMask', wintypes.DWORD),
        ('text', c_char_p),
        ('textMax', c_int),
        ('image', c_int),
        ('lParam', wintypes.LPARAM),
    ]

If I do the following the host application crashes:
                bufLen = 100
                tcitemstruct = TCITEMAStruct()
                tcitemstruct.mask = TCIF_TEXT
                tcitemstruct.textMax = bufLen

                buf = create_string_buffer(bufLen)
                tcitemstruct.text = cast(buf, c_char_p)

got_it = winUser.sendMessage(obj.windowHandle, TCM_GETITEMA, tabidx , tcitemstruct)



In scintilla.py I found a way to do it by allocating memory for the process and it almost works:

                bufLen = 100
                tcitemstruct = TCITEMAStruct()
                tcitemstruct.mask = TCIF_TEXT
                tcitemstruct.textMax = bufLen
                processHandle = obj.processHandle
internalBuf = winKernel.virtualAllocEx(processHandle, None, bufLen, winKernel.MEM_COMMIT, winKernel.PAGE_READWRITE)
                try:
                    tcitemstruct.text = internalBuf
internalTCItem = winKernel.virtualAllocEx(processHandle, None, sizeof(tcitemstruct), winKernel.MEM_COMMIT, winKernel.PAGE_READWRITE)
                    try:
winKernel.writeProcessMemory(processHandle, internalTCItem, byref(tcitemstruct), sizeof(tcitemstruct), None)
got_it = winUser.sendMessage(obj.windowHandle, TCM_GETITEMW, tabidx , internalTCItem)
                    finally:
winKernel.virtualFreeEx(processHandle, internalTCItem, 0, winKernel.MEM_RELEASE)
                    buf = create_string_buffer(bufLen)
winKernel.readProcessMemory(processHandle, internalBuf, buf, bufLen, None)
                finally:
winKernel.virtualFreeEx(processHandle, internalBuf, 0, winKernel.MEM_RELEASE)
                if got_it:
                    ui.message("Got it!")
                    ui.message(buf)

The call is successful, i e got_it is true, but the buffer seems to be empty because NVDA doesn't say anything.

Does anyone have any idea on what's wrong here?


Kind regards

Karl-Otto

Karl-Otto Rosenqvist
MAWINGU
Orgnr: 750804-3937
0701- 75 98 56
karl-otto@xxxxxxxxxx
https://mawingu.se

Den 2022-01-28 kl. 18:00, skrev travis@xxxxxxxxxxxxxx:

In the case of NVDA, import winUser module. (You may also want to review it in 
the nvda \source folder.)
I'm not sure which method you need, perhaps getMessage() or sendMessage() will 
work.
NVDA has a lot of Windows helper function in winUser.py and something in there 
should do what you need.
-Travis


-----Original Message-----
From: program-l-bounce@xxxxxxxxxxxxx <program-l-bounce@xxxxxxxxxxxxx> On Behalf 
Of Karl-Otto Rosenqvist
Sent: Friday, January 28, 2022 10:48 AM
To: program-l@xxxxxxxxxxxxx
Subject: [program-l] Use Windows Message to get info från Python

Hi!
I'd like to enhance an add on I've created for NVDA and in order to get info 
about the selected tab and the text on that tab I need to send Windows Messages 
but I have no idea on how to do this in Python.

It is TCM_GETCURSEL and TCM_GETITEM I should use.


Thanks in advance

Karl-Otto

--
Karl-Otto Rosenqvist
MAWINGU
Orgnr: 750804-3937
0701- 75 98 56
karl-otto@xxxxxxxxxx
https://mawingu.se
** To leave the list, click on the immediately-following link:-
** [mailto:program-l-request@xxxxxxxxxxxxx?subject=unsubscribe]
** If this link doesn't work then send a message to:
** program-l-request@xxxxxxxxxxxxx
** and in the Subject line type
** unsubscribe
** For other list commands such as vacation mode, click on the
** immediately-following link:-
** [mailto:program-l-request@xxxxxxxxxxxxx?subject=faq]
** or send a message, to
** program-l-request@xxxxxxxxxxxxx with the Subject:- faq

** To leave the list, click on the immediately-following link:-
** [mailto:program-l-request@xxxxxxxxxxxxx?subject=unsubscribe]
** If this link doesn't work then send a message to:
** program-l-request@xxxxxxxxxxxxx
** and in the Subject line type
** unsubscribe
** For other list commands such as vacation mode, click on the
** immediately-following link:-
** [mailto:program-l-request@xxxxxxxxxxxxx?subject=faq]
** or send a message, to
** program-l-request@xxxxxxxxxxxxx with the Subject:- faq
** To leave the list, click on the immediately-following link:-
** [mailto:program-l-request@xxxxxxxxxxxxx?subject=unsubscribe]
** If this link doesn't work then send a message to:
** program-l-request@xxxxxxxxxxxxx
** and in the Subject line type
** unsubscribe
** For other list commands such as vacation mode, click on the
** immediately-following link:-
** [mailto:program-l-request@xxxxxxxxxxxxx?subject=faq]
** or send a message, to
** program-l-request@xxxxxxxxxxxxx with the Subject:- faq

Other related posts: