Problema al obtener el contenido de un cuadro de lista con Python y Ctypes en Win32

StackOverflow https://stackoverflow.com/questions/1466453

  •  13-09-2019
  •  | 
  •  

Pregunta

Me gustaría obtener el contenido de un cuadro de lista gracias a Python y Ctypes.

item_count = ctypes.windll.user32.SendMessageA(hwnd, win32con.LB_GETCOUNT, 0, 0)
items = []
for i in xrange(item_count):
    text_len = ctypes.windll.user32.SendMessageA(hwnd, win32con.LB_GETTEXTLEN, i, 0)
    buffer = ctypes.create_string_buffer("", text_len+1)
    ctypes.windll.user32.SendMessageA(hwnd, win32con.LB_GETTEXT, i, buffer)
    items.append(buffer.value)
print items

El número de elementos es correcto pero el texto está mal. Todos los text_len son 4 y los valores de texto son algo así como '0 xd9 xee x02 x90'

He intentado usar un búfer Unicode con un resultado similar.

No encuentro mi error. ¿Alguna idea?

¿Fue útil?

Solución

Si el cuadro de lista en cuestión es dibujado por el propietario, este pasaje del Lb_gettext La documentación puede ser relevante:

Si crea el cuadro de lista con un estilo dibujado por el propietario pero sin el estilo lbs_hasstrings, el búfer apuntado por el parámetro LPARAM recibirá el valor asociado con el elemento (los datos del elemento).

Los cuatro bytes que recibió ciertamente parecen ser un puntero, que es un valor típico para almacenar en los datos por ítems.

Otros consejos

Parece que necesita usar una estructura empaquetada para el resultado. Encontré un ejemplo en línea, tal vez esto te ayudará:

http://www.brunningonline.net/simon/blog/archives/winguiauto.py.html

# Programmer : Simon Brunning - simon@brunningonline.net
# Date       : 25 June 2003
def _getMultipleWindowValues(hwnd, getCountMessage, getValueMessage):
    '''A common pattern in the Win32 API is that in order to retrieve a
    series of values, you use one message to get a count of available
    items, and another to retrieve them. This internal utility function
    performs the common processing for this pattern.

    Arguments:
    hwnd                Window handle for the window for which items should be
                        retrieved.
    getCountMessage     Item count message.
    getValueMessage     Value retrieval message.

    Returns:            Retrieved items.'''
    result = []

    VALUE_LENGTH = 256
    bufferlength_int  = struct.pack('i', VALUE_LENGTH) # This is a C style int.

    valuecount = win32gui.SendMessage(hwnd, getCountMessage, 0, 0)
    for itemIndex in range(valuecount):
        valuebuffer = array.array('c',
                                  bufferlength_int +
                                  " " * (VALUE_LENGTH - len(bufferlength_int)))
        valueLength = win32gui.SendMessage(hwnd,
                                           getValueMessage,
                                           itemIndex,
                                           valuebuffer)
        result.append(valuebuffer.tostring()[:valueLength])
    return result

def getListboxItems(hwnd):
    '''Returns the items in a list box control.

    Arguments:
    hwnd            Window handle for the list box.

    Returns:        List box items.

    Usage example:  TODO
    '''

    return _getMultipleWindowValues(hwnd,
                                     getCountMessage=win32con.LB_GETCOUNT,
                                     getValueMessage=win32con.LB_GETTEXT)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top