I stopped programming a few years ago for various reasons, but now I am trying to get an old program of mine working. It works on windows XP, but I cannot figure out how to get it to work on Windows 7, 64 bit.
The attached test code was extracted from the program I'm trying to fix. It finds the windows desktop listview, and prints out the position and caption of each item on the desktop. On Windows 7 64bit, it prints the correct handles as determined by winspy, and the correct number of icons, and their correct positions, so I'm fairly sure I'm finding the listview properly, but for some reason LVM_GETITEMTEXT always return zero.
This is a console program.
Any help with this will be greatly appreciated.
Update: See http://masm32.com/board/index.php?topic=1464.msg15440#msg15440 (http://masm32.com/board/index.php?topic=1464.msg15440#msg15440) for solution.
that'll teach ya to leave :P
the only thing that comes to mind is the difference in window hierarchy for controls under win7
but, if you've looked at it with spy++, i would think you have already noticed that
maybe take a snapshot of the windows in one os and do a side-by-side comparison
The order is strange in win7, here's how I find the listview
.const
workerw BYTE 'WorkerW',0
shellv BYTE 'SHELLDLL_DefView',0
lview BYTE 'SysListView32',0
.code
gethandle proc uses ebx esi ;returns EAX=handle else 0
sub esi,esi
@@: INVOKE FindWindowEx,0,esi,offset workerw,0
test eax,eax
jz @f
mov esi,eax
INVOKE FindWindowEx,eax,0,offset shellv,0
test eax,eax
jz @b
INVOKE FindWindowEx,eax,0,offset lview,0
@@: ret
gethandle endp
Unfortunately there is also something called "desktop isolation" (or similar) which means not all info is available.
I think I can get icon positions but not text - can't remember, just gave up :(
I didn't test it, but there's a bug in the code: you may not assume that member pszText in LV_ITEM keeps the initial value - it may be changed by Windows - and further calls with this changed value have a high risk to fail.
Quote from: japheth on February 11, 2013, 08:23:56 PM
I didn't test it, but there's a bug in the code: you may not assume that member pszText in LV_ITEM keeps the initial value - it may be changed by Windows - and further calls with this changed value have a high risk to fail.
I found that out the hard way, here's what I do, works in XP but not Vista+
gettext PROC USES EBX ESI EDI hwnd:DWORD,hprocess:DWORD,hprocessmem:DWORD,upto:DWORD,buff:DWORD
LOCAL item:LVITEM
INVOKE RtlZeroMemory,ADDR item,SIZEOF item
mov esi,hprocessmem
mov ebx,hprocess
lea eax,[esi+SIZEOF item]
push 1
pop item._mask
push upto
pop item.iItem
mov item.pszText,eax
push 260
pop item.cchTextMax
INVOKE WriteProcessMemory,ebx,esi,ADDR item,SIZEOF item,0
INVOKE SendMessage,hwnd,LVM_GETITEMTEXT,upto,esi
mov edi,eax
INVOKE ReadProcessMemory,ebx,item.pszText,buff,eax,0
mov eax,edi
ret
gettext endp
Even as admin I get a null string, same code worked OK in XP.
Quote from: sinsi on February 11, 2013, 08:42:54 PM
I found that out the hard way, here's what I do, works in XP but not Vista+
I see. However, in your code, shouldn't you first read the LV_ITEM structure back and THEN use the pszText member?
Btw, I found, at second glance, that Jimg does check in his code the "pszText has been changed"-case. Never mind.
Quote from: japheth on February 11, 2013, 10:19:23 PM
I see. However, in your code, shouldn't you first read the LV_ITEM structure back and THEN use the pszText member?
Thanks for spotting that. I guess I have been lucky in that Windows doesn't change it.
I've finally figured out what the problem is, but not the solution. Using Spy++ I found that the style of the desktop listview on windows 7 64 bit is LVS_OWNERDATA. Microsoft specifically says "LVM_GETITEMTEXT is not supported under the LVS_OWNERDATA style." This means it's a virtual listview, and doesn't keep the info around but asks the parent for it if it needs it. Microsoft doesn't say anything about what to use instead. I guess the only way would be to ask the parent ("SHELLDLL_DefView") for the info but have no idea how to get it to send to me instead of the listview.
Anyone have any ideas? Anyone heard from Donkey lately? He seems to be very proficient at figuring out this type of stuff.
you can determine the "worker" control window handles
but, that's probably not necessary
it seems to me that the window would be sent a notification message of some sort
a little different issue, but similar with regard to window hierarchy....
we wanted a GetOpenFileName dialog to appear in a specific position
because the hierarchy is different, i wrote some code to get the handles
as far as i know it works under win 7 - noone ever said that it didn't - lol
maybe you can get some ideas
http://www.masmforum.com/board/index.php?topic=16931.msg154917#msg154917 (http://www.masmforum.com/board/index.php?topic=16931.msg154917#msg154917)
Quote from: jimg on February 12, 2013, 12:50:11 PMhow to get it to send to me instead of the listview.
Subclassing & intercepting the appropriate message?
You might google for LVS_OWNERDATA LVM_GETITEMTEXT LVN_GETDISPINFO
... or check the NMLVDISPINFO structure (http://msdn.microsoft.com/en-us/library/windows/desktop/bb774780%28v=vs.85%29.aspx):
If the LVITEM structure is receiving item text, the pszText and cchTextMax members specify the address and size of a buffer.
Quote from: jimg on February 12, 2013, 12:50:11 PM
Anyone have any ideas?
The "official" way to talk with the Windows shell is surely not to use Read/WriteProcessMemory or SendMessage.
There's a bunch of COM interfaces that are supposed to be used. The problem is that not everything is well documented.
However, to get the text of folder items is simple:
;--- list the items on the desktop folder
.386
.model flat, stdcall
option casemap:none
.nolist
.nocref
include \wininc\include\windows.inc
include \wininc\include\shlobj.inc
include \wininc\include\shobjidl.inc
include \wininc\include\stdio.inc
.list
.cref
includelib kernel32.lib
includelib user32.lib
includelib gdi32.lib
includelib ole32.lib
includelib shell32.lib
includelib msvcrt.lib
CStr macro x:vararg
local xxx
.const
xxx db x,0
.code
exitm <offset xxx>
endm
.code
main proc
local sf:ptr IShellFolder
local il:ptr IEnumIDList
local iil:ptr ITEMIDLIST
local sr:STRRET
invoke SHGetDesktopFolder, addr sf
.if ( eax != S_OK )
invoke printf, CStr("SHGetDesktopFolder() failed [%X]",10), eax
ret
.endif
invoke vf( sf, IShellFolder, EnumObjects_ ), NULL, SHCONTF_FOLDERS or SHCONTF_NONFOLDERS, addr il
.if ( eax != S_OK )
invoke printf, CStr("IShellFolder:EnumObjects() failed [%X]",10), eax
invoke vf( sf, IUnknown, Release )
ret
.endif
.while 1
invoke vf( il, IEnumIDList, Next ), 1, addr iil, NULL
.break .if ( eax == S_FALSE )
.if ( eax != S_OK )
invoke printf, CStr("IEnumIDList:Next() failed [%X]",10), eax
.break
.endif
invoke vf( sf, IShellFolder, GetDisplayNameOf ), iil, SHGDN_NORMAL, addr sr
.if ( eax == S_OK )
.if ( sr.uType == STRRET_CSTR )
invoke printf, CStr("Item: %s",10), addr sr.cStr
.elseif ( sr.uType == STRRET_WSTR )
invoke printf, CStr("Item: %S",10), sr.pOleStr
invoke CoTaskMemFree, sr.pOleStr
.else
invoke printf, CStr("IShellFolder:GetDisplayNameOf() returned unexpected uType=%u",10), sr.uType
.endif
.else
invoke printf, CStr("IShellFolder:GetDisplayNameOf() failed [%X]",10), eax
.endif
invoke CoTaskMemFree, iil
.endw
invoke vf( il, IUnknown, Release )
invoke vf( sf, IUnknown, Release )
ret
align 4
main endp
start:
invoke main
invoke ExitProcess, eax
end start
It's more difficult to get "UI-related" things like icon positions, because you'll need UI-related interfaces like IShellBrowser ( which, AFAICS, is only accessible for shell extensions ) or IFolderView.
Please be aware that the sample code doesn't use Masm32!
I tried using SendMessage with LVM_EDITLABEL which is supposed to return the edit hwnd but got error 36B7 "The requested lookup key was not found in any active activation context."
Do I need a manifest or something? BTW, this is win8 but I had the same problem in win7.
Might play around with LVN_BEGINLABELEDIT, GetWindowText and LVN_ENDLABELEDIT.
Quote from: japheth on February 12, 2013, 06:24:02 PM
However, to get the text of folder items is simple:
Provided you add somewhere
includelib \WinInc\Lib\UUID.Lib
Quote from: jj2007 on February 12, 2013, 06:53:07 PM
Provided you add somewhere
includelib \WinInc\Lib\UUID.Lib
Actually, that's a Masm bug: sometimes, when 2 or more externdefs ( or prototypes ) of the very same symbol name are found in the source, it assumes that it's a true external - although it is not at all referenced in the source.
If you use jwasm, the link error should disappear.
Quote
IShellBrowser ( which, AFAICS, is only accessible for shell extensions ) or IFolderView.
I meant IShellView, not IFolderView.
Thank you Japheth, I appreciate the code.
After hours of digging through that deranged can of worms that is shell on the microsoft site, I've come to the conclusion that it is not actually what I need. When I compare the list your code gives me to the actual desktop, it gives me four items that are not on the desktop, and misses one that is. (It gives me two "control panel"s, a "J" (which is my user name), and a "Libraries". It misses desktop.ini)
Ultimately, with no way to actually tie the names to the desktop listview, it doesn't help much, but still I appreciate it.
My ultimate goal is to fix my desktop icon positioner program http://www.masmforum.com/board/index.php?topic=2704.msg21324#msg21324 (http://www.masmforum.com/board/index.php?topic=2704.msg21324#msg21324) to work with windows 7. It works, I can move icons around, but without the name or icon it really is not very useful.
Quote from: jimg on February 13, 2013, 08:59:58 AMMy ultimate goal is to fix my desktop icon positioner program http://www.masmforum.com/board/index.php?topic=2704.msg21324#msg21324 (http://www.masmforum.com/board/index.php?topic=2704.msg21324#msg21324) to work with windows 7. It works, I can move icons around, but without the name or icon it really is not very useful.
Jim,
Any chance hooking WM_NOTIFY and getting the text via the NMLVDISPINFO structure? Or is that a dead end street?
That's what I'm working on right now. I don't know that I need to hook WM_NOTIFY, but I need to be able to send a notify to the listviews parent with a NMLVDISPINFO message. I already have space alloted in the listviews memory, so I should be able to read the return if the parent responds properly. Have a few more things to check out before I try it.
Quote from: jimg on February 13, 2013, 08:59:58 AM
When I compare the list your code gives me to the actual desktop, it gives me four items that are not on the desktop, and misses one that is.
Well, it's a sample, to demonstrate the basics, not a "solution". One might have to adjust the code to get exactly what you want.
Yes, thank you. Didn't mean to seem ungrateful. Sorry. Reading about shell made me a little verrückt.
Just in case: on this site is a nice example about shell objects: http://wiki.winehq.org/Shell32 (http://wiki.winehq.org/Shell32)
if you study the items and their differences you should be able to see what flags have to be set to get the items you are interested in.
Status update:
I found out the while LVM_GETITEMTEXT is not supposed to work and indeed doesn't work on a virtual listview, LVM_GETITEM is supposed to work, but doesn't. In fact, it looks like all the straight functions work, but those that require LVITEM or another structure be passed don't work. I'm now thinking it has to be a 64 bit application to talk to the 64 bit desktop. I don't have any idea how to write 64 bit apps, so it will probably be awhile before I'm back with more info. Perhaps the LVITEM looks different for 64 bit apps? Qwords instead of Dwords?
Quote from: jimg on February 14, 2013, 01:41:52 PMPerhaps the LVITEM looks different for 64 bit apps? Qwords instead of Dwords?
Possible. By the way: Does GetLastError show anything interesting?
No errors, it thinks it worked.
I converted my code to 64-bit and Lo and Behold! it gets labels, and that's using LVM_GETITEMTEXT.
Quote from: sinsi on February 14, 2013, 06:33:14 PM
I converted my code to 64-bit and Lo and Behold! it gets labels, and that's using LVM_GETITEMTEXT.
Yes, it works in 64-bit.
option win64:3
option frame:auto
option casemap:none
include windows.inc
include commctrl.inc
include stdio.inc
includelib <kernel32.lib>
includelib <user32.lib>
includelib <comctl32.lib>
includelib <msvcrt.lib>
CStr macro x:vararg
local xxx
.const
xxx db x,0
.code
exitm <offset xxx>
endm
inv equ INVOKE
soff equ SADD
nl equ 13,10
.data?
hProgMan dq ?
hParent dq ? ; to get desktop listview handle
hListView dq ? ; desktop listview
.data
progman db "Progman",0
defview db "SHELLDLL_defVIEW", 0
syslistview db "SysListView32", 0
.code
Program proc frame
inv InitCommonControls
invoke printf, CStr("Desktop Icon Info Test",10,10)
mov rbx, offset progman
inv FindWindow,rbx,0 ; search for desktop listview
or rax,rax
jz ErrorExit
mov hProgMan,rax
invoke printf, CStr("hProgman=%p",10), hProgMan
mov rbx,offset defview
inv FindWindowEx, hProgMan, 0, rbx, 0
or rax,rax
jz ErrorExit
mov hParent,rax
invoke printf, CStr(" hParent=%p"), hParent
mov rbx,offset syslistview
inv FindWindowEx,hParent, 0, rbx, 0
or rax,rax
jz ErrorExit
mov hListView,rax
invoke printf, CStr(" hListView=%p",10), hListView
Call GetDesktopIconInfo ; go fill listview
jmp @f
ErrorExit:
inv MessageBox, 0, rbx, CStr("Unable to get"),0
@@:
; inkey "Press any key to exit..."
invoke ExitProcess, 0
; exit
Program endp
GetErrDescriptionconsole proc frame uses rbx rdi Routine:ptr BYTE
LOCAL hLocal:QWORD
.data
ErrMsgTmpl db 10,'%s failed, Error Code %Xh',10,'%s',0
Unknown db 'UnKnown Error',0
.code
invoke GetLastError
mov edi,eax
invoke FormatMessage,FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM,
0, ; GetItFromSystem
edi,0, ; ErrNum,Default language
addr hLocal, ; where to send the address of string from system
0,0 ; any size, no arguments
mov rbx,offset Unknown
.if eax!=0
invoke LocalLock,hLocal
mov rbx,rax
.endif
invoke printf, offset ErrMsgTmpl, Routine, edi, rbx
; invoke MessageBox,0,addr Bufferx,0,0
mov rax, offset Unknown
.if rbx!=rax
inv LocalFree,hLocal
.endif
ret
GetErrDescriptionconsole endp
GetDesktopIconInfo proc frame; get the names and positions of the desktop icons from the desktop listview
Local I:DWord,J:DWord
.data?
pid dd ?
IconCount dd ?
NumBytes dq ?
hProcess1 dq ?
SharedMem1 dq ? ; space for LV_ITEM and position data
SharedMem2 dq ? ; space for caption or title
SharedMem3 dq ? ; space for the position
PLen dd ?
vmemsize dq ?
LV_ITEMx STRUCT 8
imask DWORD ?
iItem DWORD ?
iSubItem DWORD ?
state DWORD ?
stateMask DWORD ?
pszText QWORD ?
cchTextMax DWORD ?
iImage DWORD ?
lParam QWORD ?
iIndent DWORD ?
iGroupId DWORD ?
puColumns DWORD ?
piColFmt DWORD ?
iGroup DWORD ?
LV_ITEMx ENDS
objItem LV_ITEMx <?>
objOut LV_ITEMx <?>
MaxName equ 225 ; maximum text description length for an icon (actually, its about 212)
IconTitle db MaxName dup (?)
TPos POINT <>
.code
inv SendMessage,hListView, LVM_GETITEMCOUNT, 0, 0 ; ask the desktop the number of icons present
mov IconCount,eax
or eax,eax
jz Done ; no icons???
sub eax,1
invoke printf, CStr("%u icons found",10), eax
mov vmemsize,sizeof LV_ITEMx + sizeof POINT + MaxName
mov PLen,sizeof TPos
inv GetWindowThreadProcessId,hListView, Addr pid
inv OpenProcess,PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, 0, pid ; common usage
mov hProcess1,rax
inv VirtualAllocEx, rax, 0, vmemsize, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE ; get memory within desktop process
mov SharedMem1,rax ; save location within Desktop Listview process to write LV_ITEM
add rax,sizeof POINT
mov SharedMem3,rax
add rax,sizeof LV_ITEMx
mov SharedMem2,rax ; save location of text output
mov I,0
Loop1: ; get length of all titles to reserve storage space
invoke printf, CStr("#%u "), I
mov eax, I
inv SendMessage, hListView, LVM_GETITEMPOSITION, rax, SharedMem1 ; ask for position of Item I (send msg to explorer listview (desktop))
mov ebx, PLen
inv ReadProcessMemory,hProcess1, SharedMem1, addr TPos, rbx, addr NumBytes ; read it into TPos
.if ( !eax )
invoke GetErrDescriptionconsole, CStr("ReadProcessMemory")
jmp Done3
.endif
invoke printf, CStr("x=%u y=%u "), TPos.x, TPos.y
mov objItem.imask, LVIF_TEXT
mov eax, I
mov objItem.iItem, eax
mov objItem.iSubItem, 0
mov rax, SharedMem2
mov objItem.pszText, rax
mov objItem.cchTextMax,MaxName
inv WriteProcessMemory, hProcess1, SharedMem1, ADDR objItem, sizeof LV_ITEMx, ADDR NumBytes ;copy LV_ITEM structure to memory
.if ( !eax )
invoke GetErrDescriptionconsole, CStr("WriteProcessMemory")
jmp Done3
.endif
;************************ this is the malfunctioning call
inv SendMessage, hListView, LVM_GETITEM, 0, SharedMem1 ; send msg to explorer listview (desktop), ask for title, returns length in eax
inv ReadProcessMemory, hProcess1, SharedMem1, addr objItem, sizeof LV_ITEMx, addr NumBytes
inv ReadProcessMemory, hProcess1, objItem.pszText, addr IconTitle, 40, addr NumBytes
mov byte ptr [IconTitle+40],0 ; **** truncate long names for test
invoke printf, CStr("Title %s",10), addr IconTitle
inc I
mov eax,IconCount
cmp I,eax
jb Loop1
;Loop1 ends
Done3:
inv VirtualFreeEx, hProcess1, SharedMem1, vmemsize, MEM_RELEASE
Done2:
inv CloseHandle,hProcess1
Done:
ret
GetDesktopIconInfo Endp
End Program
Since it works in Win 7 64-bit, the 32-bit version should work in Win 7 32-bit as well, shouldn't it?
Quote from: jimg on February 14, 2013, 05:54:27 PM
No errors, it thinks it worked.
I like that one :biggrin:
Have you tried LVM_GETITEMTEXTW? I know one case (with ToolTips) where only the Unicode version worked:
.if uMsg==WM_NOTIFY
mov ecx, lParam
.if [ecx.NMHDR.code]==TTN_GETDISPINFO
MsgBox 0, "Never seen!", "Hi", MB_OK
.endif
.if [ecx.NMHDR.code]==TTN_GETDISPINFOW
mov eax, [ecx.NMTTDISPINFOW.lpszText]
invoke MessageBoxW, 0, eax, 0, MB_OK
.endif
Thank guys, at least I have a direction to go now :) Is there an Idiots guide to 64 bit assembly programming anywhere? This is going to be painful to convert. I've become too dependent upon the masm32 macros. (Is there an msvcrt equivalent to inkey for pausing?)
Japheth-
I finally got JWasm 64 bit installed. I used these options and it seemed to work, but if you have better suggestions for options to use, I'd appreciate it.
@set INCLUDE=F:\JWasm\WinInc\Include
@set path=%path%;F:\jwasm\bin
@set lib=F:\JWasm\WinInc\Lib64
Jwasm -win64 -Cp -Fo=tst.obj %1
jwlink format win pe file tst.obj Libpath \WinInc\Lib64
also, I had to download polib to make the libraries using your batch file. Are you working on a jwlib?
Quote from: jimg on February 15, 2013, 04:06:38 AM
I finally got JWasm 64 bit installed. I used these options and it seemed to work, but if you have better suggestions for options to use, I'd appreciate it.
I used the standard 32-bit JWasm and the normal MS link to create the 64-bit sample - because I wanted to be able to use the 64-bit WinDbg.
Quote
also, I had to download polib to make the libraries using your batch file. Are you working on a jwlib?
There is a jwlib, but it doesn't understand .def files as of yet.
Just to avoid confusion, I used the standard JWasm, I didn't mean to imply that a 64 bit version of JWasm even existed, I just put -win64 in the options. But I did use the 64 bit libraries.
I just tried again using the 32bit libraries, and it assembled, but I got a lot of errors trying to link with jwlink. eg.
Error! E2028: __imp_LocalFree is an undefined reference
Error! E2028: __imp_VirtualAllocEx is an undefined reference
Error! E2028: InitCommonControls is an undefined reference
Error! E2028: printf is an undefined reference
creating a 64-bit PE executable
file tst.obj(F:\JWasm\Progs\dip64\ec.asm): undefined symbol InitCommonControls
file tst.obj(F:\JWasm\Progs\dip64\ec.asm): undefined symbol printf
file tst.obj(F:\JWasm\Progs\dip64\ec.asm): undefined
etc.
So I obviously have a lot of learning to do yet.
What version of MS link did you use? What were the options?
Quote from: jimg on February 15, 2013, 06:12:07 AM
What version of MS link did you use? What were the options?
I used the one included in VC++ 2003 Toolkit, but I assume any MS linker since 2001 should do.
used for debug build:
jwasm -win64 -Zi -Ic:\wininc\include ec.asm
link /debug /subsystem:console /libpath:c:\wininc\lib64 ec.obj
Thank you sir, I misread your previous post.
So, after screwing around for days, I learned I'm not ready for 64-bit assembly yet.
But, the solution did not have to be 64 bit, it only needed an LV_ITEM designed for a 64 bit listview, as Japheth did in his 64 bit program. I couldn't find any official Microsoft 64 bit layout, so I just fudged and added some extra space at the end in case some of the last five items are actually qwords.
Here is my 32-bit test program. It seems to work fine on both XP and 64 bit windows 7. I used the 64 bit layout as default, and if I needed the 32 bit instead, just converted it by copying the affected items.
update: fixed error: added cColumn to structure
Vey nice. Runs fine on my 64bit system. :t
Congrats, Jim - works like a charm on XP-32, too :t
And nearly as soon as I posted it I noticed that cColumns was missing from the structure. Shouldn't have had any serious effect on what I was doing, but I'll update it in a bit.
Windows 8 Pro x64 gives me: Unable to get SHELLDLL_defView
Ugh. If you look at the desktop with spy++, what is the name of the item between progman and the listview?
Progman is a sibling window to this window class - #32769 (Desktop window).
under xp sp3, also
SHELLDLL_DefView
Quote from: jimg on February 18, 2013, 04:36:04 AM
But, the solution did not have to be 64 bit, it only needed an LV_ITEM designed for a 64 bit listview, as Japheth did in his 64 bit program.
Nice find. Does that mean that the former assumption:
Quote
I found out the while LVM_GETITEMTEXT is not supposed to work and indeed doesn't work on a virtual listview,
was premature or that the Win7 64-bit explorer doesn't use virtual listviews?
If you can trust Spy++, it says that the listview has the property style LVS_OWNERDATA, which means it is a virtual listview.
Apparently, either it's not supposed to work, but does for some unknown reason and can't be trusted, or Microsoft screwed up the documentation. It clearly says "LVM_GETITEMTEXT is not supported under the LVS_OWNERDATA style" here http://msdn.microsoft.com/en-us/library/windows/desktop/bb761055%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/bb761055%28v=vs.85%29.aspx)
Perhaps "not supported" means... we meant for it to work, but sometimes it doesn't, so no guarantee, and we're not talking to you about it.
i have minimal experience with virtual listview controls, but....
if i understand the documentation, it is designed to allow you to manage the data
http://msdn.microsoft.com/en-us/library/windows/desktop/bb774735%28v=vs.85%29.aspx#Virtual_ListView_Style (http://msdn.microsoft.com/en-us/library/windows/desktop/bb774735%28v=vs.85%29.aspx#Virtual_ListView_Style)
so, i am having a hard time understanding why you are trying to use LVM_GETITEMTEXT :P
QuoteThe following messages are not supported under the LVS_OWNERDATA style:
LVM_ENABLEGROUPVIEW, LVM_GETITEMTEXT, LVM_SETTILEINFO, and LVM_MAPIDTOINDEX.
The text is the text that appears under the icon on your desktop. Why Microsoft switched to a virtual listview for the desktop is beyond me. But you do see why I wanted the text of the icon, right? Or did I misunderstand the question or intended humor of the question? I now use LVM_GETITEM to get the text purely because of the quote. It wasn't working either until we found the right layout for the structure, but at least it isn't specifically "not supported". (and I still think the word "supported" is really ambiguous in this case)
Using LVM_GETITEMTEXT I can get the text from 64-bit code and using the 64-bit LVITEM structure I can get the text from 32-bit code, again using LVM_GETITEMTEXT.
Looks like you can send a message to a 64-bit program from 32-bit land, assuming you use 64-bit parameters (which they would expect).
Two questions:
1) VirtualAllocEx returns a 32-bit pointer (in my 32-bit code) into a 64-bit process, luck? Or Windows?
2) Why does LVM_GETITEMTEXT work?
I also checked my old COMView source - written 10 years ago - which uses LVS_OWNERDATA. There's no problem with the LVM_GETITEMTEXT message. AFAICS, to support certain features of the standard listview, one may have to use ListView_SetCallbackMask(); but it's not necessary for LVM_GETITEM(TEXT).
So the MS documentation is probably wrong - surely not the first time.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa384203%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/aa384203%28v=vs.85%29.aspx)
Quote64-bit versions of Windows use 32-bit handles for interoperability. When sharing a handle between 32-bit and 64-bit applications, only the lower 32 bits are significant, so it is safe to truncate the handle (when passing it from 64-bit to 32-bit) or sign-extend the handle (when passing it from 32-bit to 64-bit).