ListView ColumnHeader caption via API?
|
|
Thread rating:  |
Markus Colorado - 08 Sep 2008 15:52 GMT 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
<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] ----------
MikeD - 09 Sep 2008 02:40 GMT > Hi, > [quoted text clipped - 8 lines] > Concerning WinAPI I think it's not relevant if it's written in (classic) > VB or in .NET. 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.
 Signature Mike Microsoft MVP Visual Basic
Markus Colorado - 09 Sep 2008 11:34 GMT 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
>> Hi, >> [quoted text clipped - 14 lines] > If you want a VB.NET solution, you need to ask in a newsgroup with dotnet or vsnet > in the name. Dean Earley - 09 Sep 2008 12:12 GMT >>> Hi, >>> [quoted text clipped - 16 lines] > 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. 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.
 Signature Dean Earley (dean.earley@icode.co.uk) i-Catcher Development Team
iCode Systems
expvb - 09 Sep 2008 14:48 GMT > 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. 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.
Markus Colorado - 09 Sep 2008 16:34 GMT 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
>> 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 [quoted text clipped - 7 lines] > a GPF. You have to use a function like ReadProcessMemory(). Search for that > function to see how it's used. Markus Colorado - 09 Sep 2008 20:16 GMT 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
>> 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 [quoted text clipped - 7 lines] > a GPF. You have to use a function like ReadProcessMemory(). Search for that > function to see how it's used. Ken Halter - 09 Sep 2008 21:16 GMT > Hi, > [quoted text clipped - 3 lines] > > 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?
 Signature Ken Halter Part time groupie
Markus Colorado - 09 Sep 2008 21:36 GMT 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
>> Hi, >> [quoted text clipped - 12 lines] > same process space as the code you're using, why not use the listview's built in > properties instead of mucking with API calls? Karl E. Peterson - 10 Sep 2008 00:15 GMT > a) it's a listview of a foreign app. 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?
 Signature .NET: It's About Trust! http://vfred.mvps.org
Markus Colorado - 10 Sep 2008 12:42 GMT Hi Karl,
>> 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] ----------
>> a) it's a listview of a foreign app. > [quoted text clipped - 7 lines] > The pszText is a *pointer* into the other process's address space. WTF good does > that do *your* process? Schmidt - 10 Sep 2008 21:00 GMT > 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
Markus Colorado - 10 Sep 2008 21:33 GMT 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
>> Below ist my code (VB6) for reading the items and >> the columns of an external listview. As said, I can read [quoted text clipped - 9 lines] > > Olaf Karl E. Peterson - 10 Sep 2008 21:31 GMT > Hi Karl, > [quoted text clipped - 3 lines] > ??? - sorry, I do not understand that statement. > WTF - "What the f..." ???? I may have misunderestimated you. If so, my apologies.
 Signature .NET: It's About Trust! http://vfred.mvps.org
Henri - 09 Sep 2008 18:48 GMT > There is no .NET ng dealing with WinAPI; so I took this ng. see Adv. Win32 api ng (news://194.177.96.26/comp.os.ms-windows.programmer.win32) where this has been answered... hundreds of times...
Markus Colorado - 09 Sep 2008 20:12 GMT 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
>> There is no .NET ng dealing with WinAPI; so I took this ng. > > see Adv. Win32 api ng (news://194.177.96.26/comp.os.ms-windows.programmer.win32) > where this has been answered... hundreds of times... Vinchenzo vinç - 09 Sep 2008 20:57 GMT > 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. Once again?, sorry, I think I missed something. Where did you said *before* external, foreign, o an other aplicacion's ListView?
 Signature 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Markus Colorado - 09 Sep 2008 21:05 GMT > Once again?, sorry, I think I missed something. Where did you said *before* > external, foreign, o an other aplicacion's ListView? Uuups, I'm sorry! - I really missed to write, that the ListView is in a foreign application. The only hint was the "processId"...
Markus
Vinchenzo vinç - 09 Sep 2008 21:23 GMT Hi Markus, see if some of the following results, in the newsgroup already suggested by Henri, helps you:
http://groups.google.com/group/comp.os.ms-windows.programmer.win32/search?group= comp.os.ms-windows.programmer.win32&q=OpenProcess+PROCESS_VM_READ+ReadProcessMem ory&qt_g=Buscar+en+este+grupo
 Signature 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Markus Colorado - 09 Sep 2008 15:50 GMT 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] ----------
>> Hi, >> [quoted text clipped - 14 lines] > If you want a VB.NET solution, you need to ask in a newsgroup with dotnet or vsnet > in the name. Vinchenzo vinç - 09 Sep 2008 18:03 GMT > 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. 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>
 Signature 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
expvb - 09 Sep 2008 19:09 GMT >> Hi MikeD, >> [quoted text clipped - 7 lines] > declarations for 'GetWindow' and GW_CHILD to obtain the handle to the > column header window associated with the ListView. 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.
Vinchenzo vinç - 09 Sep 2008 21:01 GMT Yes, but althought I agree with you, please read again what Markus said:
> 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...
 Signature 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|