在win32上使用python和ctypes获取列表框的内容时出现问题

时间:2009-09-23 14:42:36

标签: python winapi ctypes

感谢python和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

项目数量正确但文字错误。所有text_len都是4,文本值类似于'0 \ xd9 \ xee \ x02 \ x90'

我尝试使用具有类似结果的unicode缓冲区。

我没有找到我的错误。任何的想法?

2 个答案:

答案 0 :(得分:1)

如果相关列表框是所有者绘制的,那么LB_GETTEXT文档中的这段内容可能是相关的:

  

如果使用所有者绘制的样式创建列表框但没有LBS_HASSTRINGS样式,则lParam参数指向的缓冲区将接收与项目关联的值(项目数据)。

您收到的四个字节看起来确实可能是一个指针,这是存储在每个项目数据中的典型值。

答案 1 :(得分:0)

看起来您需要使用打包结构来获得结果。我在网上找到了一个例子,也许这会对你有所帮助:

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)