Problema ao obter o conteúdo de uma caixa de listagem com Python e Ctypes no Win32

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

  •  13-09-2019
  •  | 
  •  

Pergunta

Eu gostaria de obter o conteúdo de uma caixa de listagem graças ao Python e 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

O número de itens está correto, mas o texto está errado. Todos os text_len são 4 e os valores de texto são algo como '0 xd9 xee x02 x90'

Eu tentei usar um buffer Unicode com um resultado semelhante.

Eu não encontro meu erro. Qualquer ideia?

Foi útil?

Solução

Se a caixa de listagem em questão for desenhada, esta passagem do Lb_getText A documentação pode ser relevante:

Se você criar a caixa de listagem com um estilo proprietário, mas sem o estilo lbs_hasstrings, o buffer apontado pelo parâmetro LPARAM receberá o valor associado ao item (os dados do item).

Os quatro bytes que você recebeu certamente parecem ser um ponteiro, o que é um valor típico para armazenar nos dados por item.

Outras dicas

Parece que você precisa usar uma estrutura embalada para o resultado. Encontrei um exemplo online, talvez isso o ajude:

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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top