I'm trying to read the column header (SysHeader32) captions of an ListView. So far
I'm sure to have the right processID and handle (hWnd) , beacause I can successfully
read the right number of columns, but I do not get any text (caption) for each
column. I always get back an empty string for each column-text, although SendMessage
returns "1" as result. I would really need the captions of the listview...
Below are the relevant code-snipplets (vb.net).
Concerning WinAPI I think it's not relevant if it's written in (classic) VB or in
.NET.
Has anybody a hint - or even better a solution ;-)) - for me how to read the
captions of each column-header.
Thnaks for any help in advance.
Regards,
Markus
---------- [code begin] ----------
Public Enum HDM As Integer
HDM_FIRST = &H1200
HDM_GETITEMCOUNT = (HDM_FIRST + 0)
HDM_GETITEMA = (HDM_FIRST + 3)
HDM_GETITEM = HDM_GETITEMA
HDM_SETITEM = (HDM_FIRST + 4)
HDM_SETIMAGELIST = (HDM_FIRST + 8)
HDM_GETIMAGELIST = (HDM_FIRST + 9)
End Enum
<StructLayout(LayoutKind.Sequential)> _
Public Structure HDITEM
Public mask As Integer
Public cxy As Integer
Public pszText As String
Public hbm As IntPtr
Public cchTextMax As Integer
Public fmt As Integer
Public lParam As Integer
Public iImage As Integer
Public iOrder As Integer
Public type As UInteger
Public pvFilter As IntPtr
End Structure
<DllImport("user32.dll")> _
Private Overloads Shared Function SendMessage( _
ByVal hWnd As IntPtr, _
ByVal msg As Integer, _
ByVal wParam As IntPtr, _
ByVal lParam As IntPtr) As IntPtr
End Function
<DllImport("user32.dll")> _
Public Overloads Shared Function SendMessage( _
ByVal hWnd As IntPtr, _
ByVal msg As Integer, _
ByVal wParam As Integer, _
ByRef hdi As HDITEM) As Integer
End Function
Public Shared Sub ListView_GetColumnNames(ByVal hWnd As IntPtr)
Dim iCols As Integer = SendMessage(hWnd, HDM.HDM_GETITEMCOUNT, 0, 0)
Utilities.Debug(">> iCols: " & iCols.ToString)
For i As Integer = 0 To iCols - 1
Dim hditm As HDITEM = New HDITEM
hditm.cchTextMax = 32
hditm.pszText = New String(Chr(0), hditm.cchTextMax) ''Space$(32)
hditm.mask = CType(HDI.HDI_WIDTH, Integer) Or _
CType(HDI.HDI_FORMAT, Integer)
hditm.fmt = CType(HDF.HDF_STRING, Integer) Or _
CType(HDF.HDF_BITMAP_ON_RIGHT, Integer)
If SendMessage(hWnd, HDM.HDM_GETITEM, i, hditm) = 1 Then
Dim sText As String = StripNulls(hditm.pszText) & _
" {" & (hditm.pszText).Length & "}"
Utilities.Debug("[" & i.ToString & "]: iRes=1 | sText = " & sText)
Else
Utilities.Debug("[" & i.ToString & "]: iRes<>1 | sText = #####")
End If
Next
End Function
Private Shared Function StripNulls(ByVal OriginalStr As String) As String
' This removes the extra Nulls so String comparisons will work
If (InStr(OriginalStr, Chr(0)) > 0) Then
OriginalStr = Left(OriginalStr, InStr(OriginalStr, Chr(0)) - 1)
End If
Return OriginalStr
End Function
---------- [code end] ----------
No, it IS relevant. That code's quite different from what you'd write in
VB6...for one, data types are not the same.
If you want a VB.NET solution, you need to ask in a newsgroup with dotnet or
vsnet in the name.
--
Mike
Microsoft MVP Visual Basic
Markus
"MikeD" <nob...@nowhere.edu> schrieb im Newsbeitrag
news:uLjEY0h...@TK2MSFTNGP06.phx.gbl...
As long as you confirm it is broken in exactly the same way.
You may also want to try cross posting to
microsoft.public.win32.programmer.ui and microsoft.public.platformsdk.ui
if the problem is not language specific.
--
Dean Earley (dean....@icode.co.uk)
i-Catcher Development Team
iCode Systems
The only messages that copy string to another process is WM_GETTEXT,
WM_SETTEXT, and WM_COPYDATA. All other messages don't work as far as I know.
In some cases you get a pointer, but since each process has its own address
space, you won't see the data. If you use that pointer, you get garbage
data, sometimes 0 so you see an empty string, but sometimes points to an
invalid block in your process and you get a GPF. You have to use a function
like ReadProcessMemory(). Search for that function to see how it's used.
I've rewritten the posted VB.NET code in VB6 (see below).
In VB6 it's exactly the same; I do net get the needed column captions of my ListView
header.
Any idea how to solve my problem??
regards
Markus
---------- [code begin] ----------
Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _
ByVal hWnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
Private Const HDM_FIRST = &H1200
Private Const HDM_GETITEMCOUNT = (HDM_FIRST + 0)
Private Const HDM_GETITEMA = (HDM_FIRST + 3)
Private Const HDM_GETITEM = HDM_GETITEMA
Private Const HDM_SETITEM = (HDM_FIRST + 4)
Private Const HDM_SETIMAGELIST = (HDM_FIRST + 8)
Private Const HDM_GETIMAGELIST = (HDM_FIRST + 9)
Private Const HDI_WIDTH = &H1
Private Const HDI_HEIGHT = HDI_WIDTH
Private Const HDI_TEXT = &H2
Private Const HDI_FORMAT = &H4
Private Const HDI_LPARAM = &H8
Private Const HDI_BITMAP = &H10
Private Const HDF_LEFT = 0
Private Const HDF_RIGHT = 1
Private Const HDF_CENTER = 2
Private Const HDF_JUSTIFYMASK = &H3
Private Const HDF_RTLREADING = 4
Private Const HDF_BITMAP_ON_RIGHT = &H1000
Private Const HDF_IMAGE = &H800
Private Const HDF_OWNERDRAW = &H8000
Private Const HDF_STRING = &H4000
Private Const HDF_BITMAP = &H2000
Private Type HDITEM
mask As Long
cxy As Long
pszText As String
hbm As Long
cchTextMax As Long
fmt As Long
lParam As Long
iImage As Long
iOrder As Long
End Type
Public Sub ListView_GetColumnNames(ByVal hWnd As Long)
'// hWnd ist the handle of our 'SysHeader32'
Dim iCols As Integer
Dim i As Integer
iCols = SendMessage(hWnd, HDM_GETITEMCOUNT, 0, 0)
Utilities.DebugPrint (" >> iCols: " & iCols)
' iterate through columns
For i = 0 To iCols - 1
Dim hditm As HDITEM
Dim iRes As Integer
Dim sText As String
hditm.cchTextMax = 32
hditm.pszText = String$(hditm.cchTextMax, Chr$(0))
hditm.mask = HDI_FORMAT Or HDI_TEXT
hditm.fmt = HDF_STRING
If SendMessage(hWnd, HDM_GETITEM, i, hditm) = 1 Then
sText = StripNulls(hditm.pszText) & " {" & Len(hditm.pszText) & "}"
Utilities.DebugPrint ("[" & i & "]: iRes=1 | sText = " & sText)
Else
Utilities.DebugPrint ("[" & i & "]: iRes<>1 | sText = #####")
End If
Next
End Sub
Private Function StripNulls(OriginalStr As String) As String
' This removes the extra Nulls so String comparisons will work
If (InStr(OriginalStr, Chr(0)) > 0) Then
OriginalStr = Left(OriginalStr, InStr(OriginalStr, Chr(0)) - 1)
End If
StripNulls = OriginalStr
End Function
---------- [code end] ----------
"MikeD" <nob...@nowhere.edu> schrieb im Newsbeitrag
news:uLjEY0h...@TK2MSFTNGP06.phx.gbl...
>
Thanks so far.
Markus
"expvb" <nob...@cox.net> schrieb im Newsbeitrag
news:%23m1EiLo...@TK2MSFTNGP05.phx.gbl...
Hi Markus,
your code works perfectly (the only required change to work in Visual
Basic is replace "Utilities.DebugPrint" with "Debug.Print"), and add the
declarations for 'GetWindow' and GW_CHILD to obtain the handle to the column
header window associated with the ListView.
> Any idea how to solve my problem??
Of course:
<MODE MideD ON>
If you want a VB.NET solution, you need to ask in a newsgroup with dotnet or
vsnet in the name.
<MODE MideD OFF>
--
Regards
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
( ! ) Preceding answers in Google:
http://groups.google.com/group/microsoft.public.vb.winapi
( i ) Temperance in the forum:
http://www.microsoft.com/communities/conduct/default.mspx
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
see Adv. Win32 api ng
(news://194.177.96.26/comp.os.ms-windows.programmer.win32)
where this has been answered... hundreds of times...
This works if the control belongs to your own process. If it's another
process, you get empty string, garbage string, or GPF, depending on what
happens to be in the same location in your process. You can use
IsBadStringPtr() or IsBadReadPtr() to avoid a GPF, but you still get
incorrect data.
excuse my ignorance, but in the given ng I could not find one single post/message
concerning my problem.
Once aganin: I'd like to get the caption of each column of an EXTERNAL (foreign)
application ui.
Markus
"Henri" <he...@helios.com> schrieb im Newsbeitrag
news:ga6cto$q7h$1...@news.albasani.net...
thanks to yr suggestion I'm able to read the ITEMS (rows) oa a foreign ListView, but
I still can't get the column-captions of my lv.
Why is it so hard to get the column-captions...?
Markus
"expvb" <nob...@cox.net> schrieb im Newsbeitrag
news:%23m1EiLo...@TK2MSFTNGP05.phx.gbl...
Once again?, sorry, I think I missed something. Where did you said
*before* external, foreign, o an other aplicacion's ListView?
> Hi MikeD,
> I've rewritten the posted VB.NET code in VB6 (see below).
> In VB6 it's exactly the same; I do net get the needed column captions
> ****of my ListView header****.
And a later:
> I still can't get the column-captions **of my lv**.
So, well, his VB6 code works very well...
Uuups, I'm sorry! - I really missed to write, that the ListView is in a foreign
application.
The only hint was the "processId"...
Markus
If you're getting rows, it sounds like you're not using the correct window
handle.... the ListView hWnd and ColumnHeaders hWnd are different. The
listview is a container for the headers. Use the FindWindow functionality in
Spy++ to check it out....
btw, if this is "my listview" as in a listview running in your own app and
in the same process space as the code you're using, why not use the
listview's built in properties instead of mucking with API calls?
--
Ken Halter
Part time groupie
a) it's a listview of a foreign app.
b) I have solved to get the items of a foreign listview using SendMessge() with
LV_ITEMGETTEXT, allocating the memeory of the foreign app. But I'm not able to get
the 'pszText' from an ITEM (neither LV_ITEM or HD_ITEM).
Markus
"Ken Halter" <Ken_Halter@Use_Sparingly_Hotmail.com> schrieb im Newsbeitrag
news:%23V736jr...@TK2MSFTNGP02.phx.gbl...
Exactly.
> b) I have solved to get the items of a foreign listview using SendMessge() with
> LV_ITEMGETTEXT, allocating the memeory of the foreign app. But I'm not able to get
> the 'pszText' from an ITEM (neither LV_ITEM or HD_ITEM).
So which part of the explanation you got XX messages ago didn't you understand? The
pszText is a *pointer* into the other process's address space. WTF good does that
do *your* process?
--
.NET: It's About Trust!
http://vfred.mvps.org
>> So which part of the explanation you got XX messages ago didn't you understand?
>> The pszText is a *pointer* into the other process's address space.
>> WTF good does that do *your* process?
??? - sorry, I do not understand that statement.
WTF - "What the f..." ????
I've done a step forward. I'm able to get the items of the external ListView now via
LVM_GETITEM and read the item text, but I can't do that with the column captions of
the ListView heder (via HDM_GETITEM).
Below ist my code (VB6) for reading the items and the columns of an external
listview. As said, I can read the items (rows) without any problems, but I never get
any text (caption) for the column header; sometimes I run into a AccessViolation
inside the foreign process. - Does anybody see any failure in
ListViewColumnGetText()??
Thanks in advance,
Markus
---------- [code begin] ----------
'//
'// Utilities.DebugPrint() is a wrapped method for
'// OutputDebugString() in a module called Utilities.
'//
'// ListView item
Private Type LVITEM
mask As Long
iItem As Long
iSubitem As Long
state As Long
stateMask As Long
pszText As Long
cchTextMax As Long
iImage As Long
lParam As Long
iIndent As Long
End Type
'// ListView header item
Private Type HDITEM
mask As Long
cxy As Long
pszText As String
hbm As Long
cchTextMax As Long
fmt As Long
lParam As Long
iImage As Long
iOrder As Long
End Type
Declare Function CloseHandle Lib "kernel32" ( _
ByVal hObject As Long) As Long
Declare Function GetWindowThreadProcessId Lib "user32" ( _
ByVal hWnd As Long, _
lpdwProcessId As Long) As Long
Declare Function OpenProcess Lib "kernel32" ( _
ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, _
ByVal dwProcessId As Long) As Long
Declare Function ReadProcessMemory Lib "kernel32" ( _
ByVal hProcess As Long, _
lpBaseAddress As Any, _
lpBuffer As Any, _
ByVal nSize As Long, _
lpNumberOfBytesWritten As Long) As Long
Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _
ByVal hWnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
Declare Function VirtualAllocEx Lib "kernel32" ( _
ByVal hProcess As Long, _
ByVal lpAddress As Long, _
ByVal dwSize As Long, _
ByVal flAllocationType As Long, _
ByVal flProtect As Long) As Long
Declare Function VirtualFreeEx Lib "kernel32" ( _
ByVal hProcess As Long, _
lpAddress As Any, _
ByVal dwSize As Long, _
ByVal dwFreeType As Long) As Long
Declare Function WriteProcessMemory Lib "kernel32" ( _
ByVal hProcess As Long, _
lpBaseAddress As Any, _
lpBuffer As Any, _
ByVal nSize As Long, _
lpNumberOfBytesWritten As Long) As Long
Private Const HDM_FIRST = &H1200
Private Const HDM_GETITEMCOUNT = (HDM_FIRST + 0)
Private Const HDM_GETITEMA = (HDM_FIRST + 3)
Private Const HDM_GETITEM = HDM_GETITEMA
Private Const HDI_TEXT = &H2
Private Const LVIF_TEXT = &H1
Private Const LVM_FIRST As Long = &H1000
Private Const LVM_GETITEM As Long = (LVM_FIRST + 5)
Private Const LVM_GETITEMCOUNT = (LVM_FIRST + 4)
Private Const LVM_GETHEADER = (LVM_FIRST + 31)
Private Const PAGE_READWRITE = &H4&
Private Const MEM_RESERVE = &H2000
Private Const MEM_COMMIT = &H1000
Private Const MEM_RELEASE = &H8000
Private Const PROCESS_VM_OPERATION = &H8
Private Const PROCESS_VM_READ = &H10
Private Const PROCESS_VM_WRITE = &H20
Private Sub ListView_GetItems(ByVal hWnd As Long)
'// get number of rows and columns
'// hWnd = handle of ListView (SysListView32)
Dim hWnd_hd As Long ' handle of 'SysHeader32'
Dim iCols As Integer ' number of columns in ListView
Dim iRows As Integer ' number of rows in ListView
Dim iColCurr As Integer ' current column index
Dim iRowCurr As Integer ' current row index
hWnd_hd = SendMessage(hWnd, LVM_GETHEADER, 0, 0)
iCols = SendMessage(hWnd_hd, HDM_GETITEMCOUNT, 0, 0)
iRows = SendMessage(hWnd, LVM_GETITEMCOUNT, 0, 0)
Utilities.DebugPrint (" >> hWnd_hd: " & hWnd_hd)
Utilities.DebugPrint (" >> iCols: " & iCols)
Utilities.DebugPrint (" >> iRows: " & iRows)
For iRowCurr = 0 To iRows - 1
For iColCurr = 0 To iCols - 1
Utilities.DebugPrint ("[" & iRowCurr & "][" & iColCurr & "] " & _
ListViewGetText(hWnd, iColCurr, iRowCurr))
Next
Utilities.DebugPrint ("------------------------------")
Next
End Sub
Sub ListViewHeader_GetItems(ByVal hWnd As Long)
'// get number of columns
'// hWnd = handle of Header (SysHeader32)
Dim iCols As Integer ' number of columns in ListView
Dim iColCurr As Integer ' current column index
iCols = SendMessage(hWnd, HDM_GETITEMCOUNT, 0, 0)
Utilities.DebugPrint (" >> iCols: " & iCols)
For iColCurr = 0 To iCols - 1
Utilities.DebugPrint ("[" & iColCurr & "] " & _
ListViewColumnGetText(hWnd, iColCurr))
Next
End Sub
Function ListViewGetText(ByVal hWnd As Long, _
ByVal iSubitem As Integer, _
ByVal iItem As Integer) As String
Dim lngProcID As Long, lngProcHandle As Long
Dim typLvItem As LVITEM
Dim strLvItem As String
Dim lngVarPtr1 As Long, lngVarPtr2 As Long
Dim lngMemVar1 As Long, lngMemVar2 As Long
Dim lngMemLen1 As Long, lngMemLen2 As Long
Call GetWindowThreadProcessId(hWnd, lngProcID)
If lngProcID <> 0 Then
lngProcHandle = OpenProcess(PROCESS_VM_OPERATION Or _
PROCESS_VM_READ Or _
PROCESS_VM_WRITE, False, lngProcID)
If lngProcHandle <> 0 Then
strLvItem = String(255, vbNullChar)
lngVarPtr1 = StrPtr(strLvItem)
lngVarPtr2 = VarPtr(typLvItem)
lngMemLen1 = LenB(strLvItem)
lngMemLen2 = LenB(typLvItem)
lngMemVar1 = VirtualAllocEx(lngProcHandle, 0, lngMemLen1, _
MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
lngMemVar2 = VirtualAllocEx(lngProcHandle, 0, lngMemLen2, _
MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
With typLvItem
.cchTextMax = 255
.iItem = iItem
.iSubitem = iSubitem
.mask = LVIF_TEXT
.pszText = lngMemVar1
End With
Call WriteProcessMemory(lngProcHandle, ByVal lngMemVar1, _
ByVal lngVarPtr1, lngMemLen1, 0)
Call WriteProcessMemory(lngProcHandle, ByVal lngMemVar2, _
ByVal lngVarPtr2, lngMemLen2, 0)
Call SendMessage(hWnd, LVM_GETITEM, ByVal 0, ByVal lngMemVar2)
Call ReadProcessMemory(lngProcHandle, ByVal lngMemVar1, _
ByVal lngVarPtr1, lngMemLen1, 0)
strLvItem = StrConv(strLvItem, vbUnicode)
strLvItem = Left(strLvItem, InStr(1, strLvItem, vbNullChar) - 1)
ListViewGetText = strLvItem
Call VirtualFreeEx(lngProcHandle, ByVal lngMemVar1, _
lngMemLen1, MEM_RELEASE)
Call VirtualFreeEx(lngProcHandle, ByVal lngMemVar2, _
lngMemLen2, MEM_RELEASE)
Call CloseHandle(lngProcHandle)
End If
End If
End Function
Function ListViewColumnGetText(ByVal hWnd, iColumn As Integer) As String
Dim lngProcID As Long, lngProcHandle As Long
Dim typHdItem As HDITEM
Dim strHdItem As String
Dim lngVarPtr1 As Long, lngVarPtr2 As Long
Dim lngMemVar1 As Long, lngMemVar2 As Long
Dim lngMemLen1 As Long, lngMemLen2 As Long
Dim iMaxLen As Integer
iMaxLen = 64
Call GetWindowThreadProcessId(hWnd, lngProcID)
If lngProcID <> 0 Then
lngProcHandle = OpenProcess(PROCESS_VM_OPERATION Or _
PROCESS_VM_READ Or PROCESS_VM_WRITE, _
False, lngProcID)
If lngProcHandle <> 0 Then
strHdItem = String(iMaxLen, vbNullChar)
lngVarPtr1 = StrPtr(strHdItem)
lngVarPtr2 = VarPtr(typHdItem)
lngMemLen1 = LenB(strHdItem)
lngMemLen2 = LenB(typHdItem)
lngMemVar1 = VirtualAllocEx(lngProcHandle, 0, lngMemLen1, _
MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
lngMemVar2 = VirtualAllocEx(lngProcHandle, 0, lngMemLen2, _
MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
With typHdItem
.cchTextMax = iMaxLen
.mask = HDI_TEXT
.pszText = lngMemVar1
End With
Call WriteProcessMemory(lngProcHandle, ByVal lngMemVar1, _
ByVal lngVarPtr1, lngMemLen1, 0)
Call WriteProcessMemory(lngProcHandle, ByVal lngMemVar2, _
ByVal lngVarPtr2, lngMemLen2, 0)
Call SendMessage(hWnd, HDM_GETITEM, CLng(iColumn), _
ByVal lngMemVar2)
Call ReadProcessMemory(lngProcHandle, ByVal lngMemVar1, _
ByVal lngVarPtr1, lngMemLen1, 0)
strHdItem = StrConv(strHdItem, vbUnicode)
strHdItem = Left(strHdItem, InStr(1, strHdItem, vbNullChar) - 1)
ListViewColumnGetText = strHdItem
Call VirtualFreeEx(lngProcHandle, ByVal lngMemVar1, _
lngMemLen1, MEM_RELEASE)
Call VirtualFreeEx(lngProcHandle, ByVal lngMemVar2, _
lngMemLen2, MEM_RELEASE)
Call CloseHandle(lngProcHandle)
End If
End If
End Function
---------- [code end] ----------
"Karl E. Peterson" <ka...@mvps.org> schrieb im Newsbeitrag
news:OeFUAItE...@TK2MSFTNGP05.phx.gbl...
> Below ist my code (VB6) for reading the items and
> the columns of an external listview. As said, I can read
> the items (rows) without any problems, but I never get
> any text (caption) for the column header;
> Private Type HDITEM
> mask As Long
> cxy As Long
> pszText As String '<----- !!!
Change that to a Long and it will work.
Olaf
I may have misunderestimated you. If so, my apologies.
Thank you so much for that 'last missing link' and 'expvb' for guiding me to the
right direction concerning memory allocation.
Markus
"Schmidt" <s...@online.de> schrieb im Newsbeitrag
news:eJannC4...@TK2MSFTNGP06.phx.gbl...
Please help me out !
Markus Colorado wrote:
Hi Olaf, that's it!!
10-Sep-08
Hi Olaf, that's it!! - You are my hero ;-))
Thank you so much for that 'last missing link' and 'expvb' for guiding me to the
right direction concerning memory allocation.
Markus
"Schmidt" <s...@online.de> schrieb im Newsbeitrag
news:eJannC4...@TK2MSFTNGP06.phx.gbl...
Previous Posts In This Thread:
On Monday, September 08, 2008 10:52 AM
Markus Colorado wrote:
ListView ColumnHeader caption via API?
Hi,
I'm trying to read the column header (SysHeader32) captions of an ListView. So far
I'm sure to have the right processID and handle (hWnd) , beacause I can successfully
read the right number of columns, but I do not get any text (caption) for each
column. I always get back an empty string for each column-text, although SendMessage
returns "1" as result. I would really need the captions of the listview...
Below are the relevant code-snipplets (vb.net).
Concerning WinAPI I think it's not relevant if it's written in (classic) VB or in
..NET.
Has anybody a hint - or even better a solution ;-)) - for me how to read the
captions of each column-header.
Thnaks for any help in advance.
Regards,
Markus
---------- [code begin] ----------
Public Enum HDM As Integer
HDM_FIRST = &H1200
HDM_GETITEMCOUNT = (HDM_FIRST + 0)
HDM_GETITEMA = (HDM_FIRST + 3)
HDM_GETITEM = HDM_GETITEMA
HDM_SETITEM = (HDM_FIRST + 4)
HDM_SETIMAGELIST = (HDM_FIRST + 8)
HDM_GETIMAGELIST = (HDM_FIRST + 9)
End Enum
hditm.cchTextMax = 32
hditm.pszText = New String(Chr(0), hditm.cchTextMax) ''Space$(32)
hditm.mask = CType(HDI.HDI_WIDTH, Integer) Or _
CType(HDI.HDI_FORMAT, Integer)
hditm.fmt = CType(HDF.HDF_STRING, Integer) Or _
CType(HDF.HDF_BITMAP_ON_RIGHT, Integer)
If SendMessage(hWnd, HDM.HDM_GETITEM, i, hditm) = 1 Then
Dim sText As String = StripNulls(hditm.pszText) & _
" {" & (hditm.pszText).Length & "}"
Utilities.Debug("[" & i.ToString & "]: iRes=1 | sText = " & sText)
Else
Utilities.Debug("[" & i.ToString & "]: iRes<>1 | sText = #####")
End If
Next
End Function
Private Shared Function StripNulls(ByVal OriginalStr As String) As String
' This removes the extra Nulls so String comparisons will work
If (InStr(OriginalStr, Chr(0)) > 0) Then
OriginalStr = Left(OriginalStr, InStr(OriginalStr, Chr(0)) - 1)
End If
Return OriginalStr
End Function
---------- [code end] ----------
On Monday, September 08, 2008 9:40 PM
MikeD wrote:
Re: ListView ColumnHeader caption via API?
"Markus Colorado" <colo...@aon.at> wrote in message
news:OARJBKcE...@TK2MSFTNGP03.phx.gbl...
No, it IS relevant. That code's quite different from what you'd write in
VB6...for one, data types are not the same.
If you want a VB.NET solution, you need to ask in a newsgroup with dotnet or
vsnet in the name.
--
Mike
Microsoft MVP Visual Basic
On Tuesday, September 09, 2008 6:34 AM
Markus Colorado wrote:
There is no .NET ng dealing with WinAPI; so I took this ng.
There is no .NET ng dealing with WinAPI; so I took this ng.
I will rewrite my code-snip in VB6....hoping anybody will give a helpful reply then.
Markus
"MikeD" <nob...@nowhere.edu> schrieb im Newsbeitrag
news:uLjEY0h...@TK2MSFTNGP06.phx.gbl...
On Tuesday, September 09, 2008 7:12 AM
Dean Earley wrote:
Re: ListView ColumnHeader caption via API?
Markus Colorado wrote:
As long as you confirm it is broken in exactly the same way.
You may also want to try cross posting to
microsoft.public.win32.programmer.ui and microsoft.public.platformsdk.ui
if the problem is not language specific.
--
Dean Earley (dean....@icode.co.uk)
i-Catcher Development Team
iCode Systems
On Tuesday, September 09, 2008 9:48 AM
expvb wrote:
Re: ListView ColumnHeader caption via API?
"Markus Colorado" <colo...@aon.at> wrote in message
news:uoEgtem...@TK2MSFTNGP06.phx.gbl...
The only messages that copy string to another process is WM_GETTEXT,
WM_SETTEXT, and WM_COPYDATA. All other messages don't work as far as I know.
In some cases you get a pointer, but since each process has its own address
space, you won't see the data. If you use that pointer, you get garbage
data, sometimes 0 so you see an empty string, but sometimes points to an
invalid block in your process and you get a GPF. You have to use a function
like ReadProcessMemory(). Search for that function to see how it's used.
On Tuesday, September 09, 2008 10:50 AM
Markus Colorado wrote:
Hi MikeD,I've rewritten the posted VB.NET code in VB6 (see below).
Hi MikeD,
I've rewritten the posted VB.NET code in VB6 (see below).
In VB6 it's exactly the same; I do net get the needed column captions of my ListView
header.
Any idea how to solve my problem??
regards
Markus
---------- [code begin] ----------
Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _
ByVal hWnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
Private Const HDM_FIRST = &H1200
Private Const HDM_GETITEMCOUNT = (HDM_FIRST + 0)
Private Const HDM_GETITEMA = (HDM_FIRST + 3)
Private Const HDM_GETITEM = HDM_GETITEMA
Private Const HDM_SETITEM = (HDM_FIRST + 4)
Private Const HDM_SETIMAGELIST = (HDM_FIRST + 8)
Private Const HDM_GETIMAGELIST = (HDM_FIRST + 9)
Private Const HDI_WIDTH = &H1
Private Const HDI_HEIGHT = HDI_WIDTH
Private Const HDI_TEXT = &H2
Private Const HDI_FORMAT = &H4
Private Const HDI_LPARAM = &H8
Private Const HDI_BITMAP = &H10
Private Const HDF_LEFT = 0
Private Const HDF_RIGHT = 1
Private Const HDF_CENTER = 2
Private Const HDF_JUSTIFYMASK = &H3
Private Const HDF_RTLREADING = 4
Private Const HDF_BITMAP_ON_RIGHT = &H1000
Private Const HDF_IMAGE = &H800
Private Const HDF_OWNERDRAW = &H8000
Private Const HDF_STRING = &H4000
Private Const HDF_BITMAP = &H2000
Private Type HDITEM
mask As Long
cxy As Long
pszText As String
hbm As Long
cchTextMax As Long
fmt As Long
lParam As Long
iImage As Long
iOrder As Long
End Type
Public Sub ListView_GetColumnNames(ByVal hWnd As Long)
'// hWnd ist the handle of our 'SysHeader32'
Dim iCols As Integer
Dim i As Integer
iCols = SendMessage(hWnd, HDM_GETITEMCOUNT, 0, 0)
Utilities.DebugPrint (" >> iCols: " & iCols)
' iterate through columns
For i = 0 To iCols - 1
Dim hditm As HDITEM
Dim iRes As Integer
Dim sText As String
hditm.cchTextMax = 32
hditm.pszText = String$(hditm.cchTextMax, Chr$(0))
hditm.mask = HDI_FORMAT Or HDI_TEXT
hditm.fmt = HDF_STRING
If SendMessage(hWnd, HDM_GETITEM, i, hditm) = 1 Then
sText = StripNulls(hditm.pszText) & " {" & Len(hditm.pszText) & "}"
Utilities.DebugPrint ("[" & i & "]: iRes=1 | sText = " & sText)
Else
Utilities.DebugPrint ("[" & i & "]: iRes<>1 | sText = #####")
End If
Next
End Sub
Private Function StripNulls(OriginalStr As String) As String
' This removes the extra Nulls so String comparisons will work
If (InStr(OriginalStr, Chr(0)) > 0) Then
OriginalStr = Left(OriginalStr, InStr(OriginalStr, Chr(0)) - 1)
End If
StripNulls = OriginalStr
End Function
---------- [code end] ----------
"MikeD" <nob...@nowhere.edu> schrieb im Newsbeitrag
news:uLjEY0h...@TK2MSFTNGP06.phx.gbl...
On Tuesday, September 09, 2008 11:34 AM
Markus Colorado wrote:
Hi,that explains, why I can successfully read the number of items/columns, but
Hi,
that explains, why I can successfully read the number of items/columns, but don't get
any strings.
I'll try your suggestion and let y know.
Thanks so far.
Markus
"expvb" <nob...@cox.net> schrieb im Newsbeitrag
news:%23m1EiLo...@TK2MSFTNGP05.phx.gbl...
On Tuesday, September 09, 2008 1:03 PM
Vinchenzo vin? wrote:
Re: ListView ColumnHeader caption via API?
"Markus Colorado" <colo...@aon.at> escribi? en el mensaje de noticias
news:%23GyB4to...@TK2MSFTNGP06.phx.gbl...
Hi Markus,
your code works perfectly (the only required change to work in Visual
Basic is replace "Utilities.DebugPrint" with "Debug.Print"), and add the
declarations for 'GetWindow' and GW_CHILD to obtain the handle to the column
header window associated with the ListView.
Of course:
<MODE MideD ON>
If you want a VB.NET solution, you need to ask in a newsgroup with dotnet or
vsnet in the name.
<MODE MideD OFF>
--
Regards
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
( ! ) Preceding answers in Google:
http://groups.google.com/group/microsoft.public.vb.winapi
( i ) Temperance in the forum:
http://www.microsoft.com/communities/conduct/default.mspx
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
On Tuesday, September 09, 2008 1:48 PM
Henri wrote:
Re: ListView ColumnHeader caption via API?
Markus Colorado wrote:
see Adv. Win32 api ng
where this has been answered... hundreds of times...
On Tuesday, September 09, 2008 2:09 PM
expvb wrote:
Re: ListView ColumnHeader caption via API?
"Vinchenzo vin?" <Vin?@newsgroup.nospam> wrote in message
news:uLHJX4pE...@TK2MSFTNGP02.phx.gbl...
This works if the control belongs to your own process. If it's another
process, you get empty string, garbage string, or GPF, depending on what
happens to be in the same location in your process. You can use
IsBadStringPtr() or IsBadReadPtr() to avoid a GPF, but you still get
incorrect data.
On Tuesday, September 09, 2008 3:12 PM
Markus Colorado wrote:
Hi Henri,excuse my ignorance, but in the given ng I could not find one single
Hi Henri,
excuse my ignorance, but in the given ng I could not find one single post/message
concerning my problem.
Once aganin: I'd like to get the caption of each column of an EXTERNAL (foreign)
application ui.
Markus
"Henri" <he...@helios.com> schrieb im Newsbeitrag
news:ga6cto$q7h$1...@news.albasani.net...
On Tuesday, September 09, 2008 3:16 PM
Markus Colorado wrote:
Hi,thanks to yr suggestion I'm able to read the ITEMS (rows) oa a foreign
Hi,
thanks to yr suggestion I'm able to read the ITEMS (rows) oa a foreign ListView, but
I still can't get the column-captions of my lv.
Why is it so hard to get the column-captions...?
Markus
"expvb" <nob...@cox.net> schrieb im Newsbeitrag
news:%23m1EiLo...@TK2MSFTNGP05.phx.gbl...
On Tuesday, September 09, 2008 3:57 PM
Vinchenzo vin? wrote:
Re: ListView ColumnHeader caption via API?
"Markus Colorado" <colo...@aon.at> escribi? en el mensaje de noticias
news:e2lVGArE...@TK2MSFTNGP05.phx.gbl...
Once again?, sorry, I think I missed something. Where did you said
*before* external, foreign, o an other aplicacion's ListView?
--
Regards
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
( ! ) Preceding answers in Google:
http://groups.google.com/group/microsoft.public.vb.winapi
( i ) Temperance in the forum:
http://www.microsoft.com/communities/conduct/default.mspx
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
On Tuesday, September 09, 2008 4:01 PM
Vinchenzo vin? wrote:
Re: ListView ColumnHeader caption via API?
Yes, but althought I agree with you, please read again what Markus said:
And a later:
So, well, his VB6 code works very well...
--
Regards
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
( ! ) Preceding answers in Google:
http://groups.google.com/group/microsoft.public.vb.winapi
( i ) Temperance in the forum:
http://www.microsoft.com/communities/conduct/default.mspx
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
On Tuesday, September 09, 2008 4:05 PM
Markus Colorado wrote:
Uuups, I'm sorry!
Uuups, I am sorry! - I really missed to write, that the ListView is in a foreign
application.
The only hint was the "processId"...
Markus
On Tuesday, September 09, 2008 4:16 PM
Ken Halter wrote:
Re: ListView ColumnHeader caption via API?
"Markus Colorado" <colo...@aon.at> wrote in message
news:Ofd4ECrE...@TK2MSFTNGP05.phx.gbl...
If you're getting rows, it sounds like you're not using the correct window
handle.... the ListView hWnd and ColumnHeaders hWnd are different. The
listview is a container for the headers. Use the FindWindow functionality in
Spy++ to check it out....
btw, if this is "my listview" as in a listview running in your own app and
in the same process space as the code you're using, why not use the
listview's built in properties instead of mucking with API calls?
--
Ken Halter
Part time groupie
On Tuesday, September 09, 2008 4:23 PM
Vinchenzo vin? wrote:
On Tuesday, September 09, 2008 4:36 PM
Markus Colorado wrote:
Hi Ken,a) it's a listview of a foreign app.
Hi Ken,
a) it's a listview of a foreign app.
b) I have solved to get the items of a foreign listview using SendMessge() with
LV_ITEMGETTEXT, allocating the memeory of the foreign app. But I'm not able to get
the 'pszText' from an ITEM (neither LV_ITEM or HD_ITEM).
Markus
"Ken Halter" <Ken_Halter@Use_Sparingly_Hotmail.com> schrieb im Newsbeitrag
news:%23V736jr...@TK2MSFTNGP02.phx.gbl...
On Tuesday, September 09, 2008 7:15 PM
Karl E. Peterson wrote:
Re: ListView ColumnHeader caption via API?
Markus Colorado wrote:
Exactly.
So which part of the explanation you got XX messages ago didn't you understand? The
pszText is a *pointer* into the other process's address space. WTF good does that
do *your* process?
--
..NET: It's About Trust!
http://vfred.mvps.org
On Wednesday, September 10, 2008 7:42 AM
Markus Colorado wrote:
Hi Karl,??? - sorry, I do not understand that statement.WTF - "What the f..." ?
Hi Karl,
??? - sorry, I do not understand that statement.
WTF - "What the f..." ????
I've done a step forward. I'm able to get the items of the external ListView now via
LVM_GETITEM and read the item text, but I can't do that with the column captions of
the ListView heder (via HDM_GETITEM).
Below ist my code (VB6) for reading the items and the columns of an external
listview. As said, I can read the items (rows) without any problems, but I never get
any text (caption) for the column header; sometimes I run into a AccessViolation
inside the foreign process. - Does anybody see any failure in
ListViewColumnGetText()??
Thanks in advance,
Markus
---------- [code begin] ----------
'//
'// Utilities.DebugPrint() is a wrapped method for
'// OutputDebugString() in a module called Utilities.
'//
'// ListView item
Private Type LVITEM
mask As Long
iItem As Long
iSubitem As Long
state As Long
stateMask As Long
pszText As Long
cchTextMax As Long
iImage As Long
lParam As Long
iIndent As Long
End Type
'// ListView header item
Private Type HDITEM
mask As Long
cxy As Long
pszText As String
End Sub
End Sub
Call GetWindowThreadProcessId(hWnd, lngProcID)
If lngProcID <> 0 Then
If lngProcHandle <> 0 Then
Call CloseHandle(lngProcHandle)
End If
End If
End Function
iMaxLen = 64
Call GetWindowThreadProcessId(hWnd, lngProcID)
If lngProcID <> 0 Then
If lngProcHandle <> 0 Then
Call CloseHandle(lngProcHandle)
End If
End If
On Wednesday, September 10, 2008 4:00 PM
Schmidt wrote:
Re: ListView ColumnHeader caption via API?
"Markus Colorado" <colo...@aon.at> schrieb im Newsbeitrag
Change that to a Long and it will work.
Olaf
On Wednesday, September 10, 2008 4:31 PM
Karl E. Peterson wrote:
Re: ListView ColumnHeader caption via API?
Markus Colorado wrote:
I may have misunderestimated you. If so, my apologies.
--
..NET: it is About Trust!
http://vfred.mvps.org
On Wednesday, September 10, 2008 4:33 PM
Markus Colorado wrote:
Hi Olaf, that's it!!
Hi Olaf, that's it!! - You are my hero ;-))
Thank you so much for that 'last missing link' and 'expvb' for guiding me to the
right direction concerning memory allocation.
Markus
"Schmidt" <s...@online.de> schrieb im Newsbeitrag
news:eJannC4...@TK2MSFTNGP06.phx.gbl...
EggHeadCafe - Software Developer Portal of Choice
Build a Multi-Provider Async Methods Search Page
http://www.eggheadcafe.com/tutorials/aspnet/10697ee3-bc13-4ca4-9443-988bfcbaaacc/build-a-multiprovider-as.aspx
If so, have you tried the Shell object? With
Shell you can return all open Explorer windows.
Each of those is returned as an "Internet
Explorer" object. It's not actually an IE object.
That's something left over from Active Desktop.
Nevertheless, you can access the ShellFolderView
as the document object of the IE object. SFV
is the COM object that represents the folder
contents.
With "pre Chicago" (win3x) controls, you could get information by
using send message. This feature was carried over into win95,
and beyond for compatibility with win3x apps.
With the then-new "Chicago" (win95) controls, microsoft did not
allow for transfer of info across process boundaries. However,
there was/is a work-around. What you do is set up some "shared
memory" which can be used by your app and the external app.
You then use your send message calls, but with an address in
shared memory for the other app to send info to. You then
read the info out of shared memory and into your own app.
If you go looking for shared memory code, be sure to use the
"NT" version of the code, if you are using XP, Vista or 7.
cheers, jw
Regards,
Marilou
>>>>>> Private Type HDITEM
>>>>>> mask As Long
>>>>>> cxy As Long
>>>>>> pszText As String
>>>>>>>>>>>>>>>>> Hi Markus,
>>>>>>>>>>>>>>>>>>>> Below ist my code (VB6) for reading the items and the columns of an external
>>>>>>>>>>>>>>>>>>>> listview. As said, I can read the items (rows) without any problems, but I never get
>>>>>>>>>>>>>>>>>>>> any text (caption) for the column header; sometimes I run into a AccessViolation
>>>>>>>>>>>>>>>>>>>> inside the foreign process. - Does anybody see any failure in
>>>>>>>>>>>>>>>>>>>> ListViewColumnGetText()??
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Thanks in advance,
>>>>>>>>>>>>>>>>>>>> Markus
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> ---------- [code begin] ----------
>>>>>>>>>>>>>>>>>>>> '//
>>>>>>>>>>>>>>>>>>>> '// Utilities.DebugPrint() is a wrapped method for
>>>>>>>>>>>>>>>>>>>> '// OutputDebugString() in a module called Utilities.
>>>>>>>>>>>>>>>>>>>> '//
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> '// ListView item
>>>>>>>>>>>>>>>>>>>> Private Type LVITEM
>>>>>>>>>>>>>>>>>>>> mask As Long
>>>>>>>>>>>>>>>>>>>> iItem As Long
>>>>>>>>>>>>>>>>>>>> iSubitem As Long
>>>>>>>>>>>>>>>>>>>> state As Long
>>>>>>>>>>>>>>>>>>>> stateMask As Long
>>>>>>>>>>>>>>>>>>>> pszText As Long
>>>>>>>>>>>>>>>>>>>> cchTextMax As Long
>>>>>>>>>>>>>>>>>>>> iImage As Long
>>>>>>>>>>>>>>>>>>>> lParam As Long
>>>>>>>>>>>>>>>>>>>> iIndent As Long
>>>>>>>>>>>>>>>>>>>> End Type
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> '// ListView header item
>>>>>>>>>>>>>>>>>>>> Private Type HDITEM
>>>>>>>>>>>>>>>>>>>> mask As Long
>>>>>>>>>>>>>>>>>>>> cxy As Long
>>>>>>>>>>>>>>>>>>>> pszText As String
>>>>>>>>>>>>>>>>>>>>> "Markus Colorado" <colo...@aon.at> schrieb im Newsbeitrag
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Change that to a Long and it will work.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Olaf
>>>>>>>>>>>>>>>>>>>>>> On Wednesday, September 10, 2008 4:31 PM Karl E. Peterson wrote:
>>>>>>>>>>>>>>>>>>>>>> Markus Colorado wrote:
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> I may have misunderestimated you. If so, my apologies.
>>>>>>>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>>>>>>>> .NET: it is About Trust!
>>>>>>>>>>>>>>>>>>>>>> http://vfred.mvps.org
>>>>>>>>>>>>>>>>>>>>>>> On Wednesday, September 10, 2008 4:33 PM Markus Colorado wrote:
>>>>>>>>>>>>>>>>>>>>>>> Hi Olaf, that's it!! - You are my hero ;-))
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Thank you so much for that 'last missing link' and 'expvb' for guiding me to the
>>>>>>>>>>>>>>>>>>>>>>> right direction concerning memory allocation.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Markus
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> "Schmidt" <s...@online.de> schrieb im Newsbeitrag
>>>>>>>>>>>>>>>>>>>>>>> news:eJannC4...@TK2MSFTNGP06.phx.gbl...
>>>>>>>>>>>>>>>>>>>>>>>> On Friday, October 30, 2009 9:49 AM Ganesh babu wrote:
>>>>>>>>>>>>>>>>>>>>>>>> I saw ur forum of getting text from external listview using sendmessage. It works on normal listview i want to get data from SysListView32
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> But the code is working on ListView20WndClass
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Please help me out !
>>>>>>>>>>>>>>>>>>>>>>>> Submitted via EggHeadCafe - Software Developer Portal of Choice
>>>>>>>>>>>>>>>>>>>>>>>> Book Review: Google Analytics
>>>>>>>>>>>>>>>>>>>>>>>> http://www.eggheadcafe.com/tutorials/aspnet/a855a620-50a8-487c-9fac-b85f8fda2442/book-review-google-analytics.aspx