[英]LVITEM for windows 64 bit
For a long time I tried to use the LVM_GETITEMW
message with LVIF_TEXT
mask to get the text of a ListView. 很长时间以来,我尝试将
LVM_GETITEMW
消息与LVIF_TEXT
掩码一起使用以获取ListView的文本。 My program worked in 32 bit but not in 64 bit architecture. 我的程序在32位上工作,但在64位体系结构上工作。
I discovered that the problem was at the LVITEM
struct. 我发现问题出在
LVITEM
结构上。 Shortly, my question is which struct is the appropriate one for 64 bit and why. 不久,我的问题是哪种结构适合64位,为什么呢?
The struct I used as the LVITEMW
struct had the following fields: 我用作
LVITEMW
结构的结构具有以下字段:
('mask', c_uint32),
('iItem', c_int32),
('iSubItem', c_int32),
('state', c_uint32),
('stateMask', c_uint32),
('pszText', c_uint32),
('cchTextMax', c_int32),
('iImage', c_int32),
('lParam', c_uint64),
('iIndent', c_int32),
('iGroupId', c_int32),
('cColumns', c_uint32),
('puColumns', c_uint32),
('piColFmt', c_int32),
('iGroup', c_int32)
(Written with python 2.7 ctypes, but this is just a form of writing - the language is really irrelevant). (使用python 2.7 ctypes编写,但这只是一种书写形式-语言确实无关紧要)。
These fields are just as documented . 这些字段已记录 。
After a lot of googling, I found this forum which had exactly what I needed - the 64 bit solution! 经过大量的搜寻,我发现这个论坛正是我所需要的-64位解决方案!
So in 64 bit the struct should have more "spaces", and should look something like this (the pointers are now 64 bit and also the stateMask
is 64 bit. That's a little bit different from what the forum suggested but works too): 因此,在64位中,该结构应该具有更多的“空间”,并且应该看起来像这样(指针现在为64位,
stateMask
也为64位。这与论坛建议的内容略有不同,但也可以使用):
('mask', c_uint32),
('iItem', c_int32),
('iSubItem', c_int32),
('state', c_uint32),
('stateMask', c_uint64), <-- Now 64 bit
('pszText', c_uint64), <-- Now 64 bit which makes sense since this is a pointer
('cchTextMax', c_int32),
('iImage', c_int32),
('lParam', c_uint64),
('iIndent', c_int32),
('iGroupId', c_int32),
('cColumns', c_uint32),
('puColumns', c_uint64), <-- Now 64 bit which makes sense since this is a pointer
('piColFmt', c_int64), <-- Now 64 bit which makes sense since this is a pointer
('iGroup', c_int32)
The forum suggested having: 该论坛建议:
('mask', c_uint32),
('iItem', c_int32),
('iSubItem', c_int32),
('state', c_uint32),
('stateMask', c_uint64),
('pszText', c_uint64),
('cchTextMax', c_int32),
('iImage', c_int64), <-- Now 64 bit
('lParam', c_uint32),
('iIndent', c_int32),
('iGroupId', c_int32),
('cColumns', c_uint32),
('puColumns', c_uint32),
('piColFmt', c_int32),
('iGroup', c_int64), <-- Now 128 bit all together
('iGroup2', c_int64) <-- continuation
Which also works, at list for my need which is the text pointed by pszText. pszText指向的文本也可以用,在我需要的列表中。
And my questions are: 我的问题是:
stateMask
be c_uint64
- shouldn't it always be the same size as the state
? stateMask
是c_uint64
-它不应该永远是大小相同的state
? Thank you! 谢谢!
Thanks to the comment by Raymond Chen I was able to figure out the answer! 感谢Raymond Chen的评论,我得以弄清楚答案!
It's about data alignment . 这与数据对齐有关 。 Every pointer should be 8 bytes and should also be aligned to an address that can be divided by 8, so sometimes there should be a padding before the pointer.
每个指针应为8个字节,并且还应对齐可除以8的地址,因此有时指针前应有填充。 Also, the size of the struct should be dividable by
min(max(sizeof(each field in the struct)), 8)
which is 8 in our case since the size of a pointer is 8. 另外,该结构的大小应可除以
min(max(sizeof(each field in the struct)), 8)
,在本例中为8,因为指针的大小为8。
class LVITEMW_explicit(ctypes.Structure):
_pack_ = 1
_fields_ = [
('mask', c_uint32), # 0
('iItem', c_int32), # 4
('iSubItem', c_int32), # 8
('state', c_uint32), # 12
('stateMask', c_uint32), # 16
('padding1', c_int),
('pszText', c_uint64), # 20 --> 24 after padding (A pointer)
('cchTextMax', c_int32), # 32
('iImage', c_int32), # 36
('lParam', c_uint64), # 40 (On 32 bit should be c_long which is 32 bits)
('iIndent', c_int32), # 48
('iGroupId', c_int32), # 52
('cColumns', c_uint32), # 56
('padding2', c_int),
('puColumns', c_uint64), # 60 --> 64 after padding (A pointer)
('piColFmt', c_int64), # 72 (A pointer)
('iGroup', c_int32), # 80
('padding3', c_int32), # The total length was 84 before padding3 was added, which is not dividable by 8
]
Or as this should really be written - without the _pack_ = 1
: 还是应该这样写-没有
_pack_ = 1
:
class LVITEMW(ctypes.Structure):
_fields_ = [
('mask', c_uint32),
('iItem', c_int32),
('iSubItem', c_int32),
('state', c_uint32),
('stateMask', c_uint32),
('pszText', c_uint64),
('cchTextMax', c_int32),
('iImage', c_int32),
('lParam', c_uint64), # On 32 bit should be c_long
('iIndent', c_int32),
('iGroupId', c_int32),
('cColumns', c_uint32),
('puColumns', c_uint64),
('piColFmt', c_int64),
('iGroup', c_int32),
]
And indeed ctypes.sizeof(LVITEMW)
returns 88, same as ctypes.sizeof(LVITEMW_explicit)
. 实际上,
ctypes.sizeof(LVITEMW)
返回88,与ctypes.sizeof(LVITEMW_explicit)
相同。
Thanks again for the helpful comments! 再次感谢您的有用评论!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.