[RESOLVED]Width of a ListView control

Here you can talk about C++ And C# And Other languages programming.

[RESOLVED]Width of a ListView control

Postby nooob » Fri Aug 25, 2006 3:12 pm


hi all

Using an ApiSpy, i am able to get the handle to a ListView control whose class name is SysListView32...now i want to get its width (the no of rows), i tried the following but it alwasy returns 0:

Code: Select all
[DllImport("user32.dll", EntryPoint = "SendMessage")]
public static extern int SendMessageLong(IntPtr hWnd, uint Msg,
int wParam, StringBuilder lParam);

const int LVM_GETCOLUMNWIDTH = 0xF126;

int count = SendMessageLong(hListView, LVM_GETCOLUMNWIDTH, 0, null);//returns 0



i am not sure if LVM_GETCOLUMNWIDTH is declared correctly.

any tips plz?
nanomachine dude are u there! :D

nooob
Last edited by nooob on Fri Sep 01, 2006 10:06 am, edited 1 time in total.
Water can make holes in rocks!
nooob
imFiles Junior
imFiles Junior
 
Posts: 52
Joined: Sun Jul 23, 2006 10:23 am

Postby BattleStar-Galactica » Fri Aug 25, 2006 4:19 pm

hehehe I dont understand what you try to do, for what purpose you want to know width column of listview. btw I never try it, hope you can get help from other...
User avatar
BattleStar-Galactica
imFiles Master
imFiles Master
 
Posts: 565
Joined: Tue Sep 20, 2005 12:19 am
Location: safest place to hide

Postby nooob » Sat Aug 26, 2006 8:13 am

lol...i am not sure if i were correct in saying the "width" of a column...but to be clear i meant to get the number of entries or rows in a column.

dude...since i m trying to learn c# with a bit of api, i decided to write some simple pal programs :D

the listview that i am talking about is the name list of any pal room... :P
in fact...i would need e.g. to get a name from that list...etc. if you guys can tell me how to get e.g. the width of that list, i might be able to go further on myself

nanomachine..in fact i came across one of ur posts...where u get a nick in pal room in Delphi 5...from the topic of ur post..it seems that i am looking for the same thing only in c#...but unfortunately its no longer there...the post is here:
http://www.locohacker.net/paltalk/get-pal-nick-in-room-with-delphi5-vt1728.html

hoping for more tips :roll:

nooob
Water can make holes in rocks!
nooob
imFiles Junior
imFiles Junior
 
Posts: 52
Joined: Sun Jul 23, 2006 10:23 am

Postby BattleStar-Galactica » Sat Aug 26, 2006 12:15 pm

ah you want to get the nick list right? that post was removed cuz nobody said thanks to me so I decided to removed it but there a some code in vb6 you can convert to c# cuz it's the same, all u have to do is import api function


like this c++ code count how many item in list view


int count=(int)::SendMessage(listview, LVM_GETITEMCOUNT, 0, 0);



try to convert this code from vbnet to c# is not diffecult, just the way define api a little bit different





Code: Select all
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Integer, ByVal bInheritHandle As Integer, ByVal dwProcId As Integer) As Integer
    Private Declare Function VirtualAllocEx Lib "kernel32" (ByVal hProcess As Integer, ByVal lpAddress As Integer, ByVal dwSize As Integer, ByVal flAllocationType As Integer, ByVal flProtect As Integer) As Integer
    Private Declare Function VirtualFreeEx Lib "kernel32" (ByVal hProcess As Integer, ByVal lpAddress As Integer, ByVal dwSize As Integer, ByVal dwFreeType As Integer) As Integer
    Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByRef lpBuffer As LV_ITEMA, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer
    Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByRef lpBuffer As LV_ITEMA, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer
    Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByRef lpBuffer As Byte, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer
    Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Integer, ByRef lpdwProcessId As Integer) As Integer
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Integer) As Integer
    Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Short, ByVal lParam As Integer) As Integer
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
    Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Integer, ByVal hWnd2 As Integer, ByVal lpsz1 As String, ByVal lpsz2 As String) As Integer
    Private Const PROCESS_QUERY_INFORMATION As Short = 1024
    Private Const PROCESS_VM_OPERATION As Short = &H8S
    Private Const PROCESS_VM_READ As Short = &H10S
    Private Const PROCESS_VM_WRITE As Short = &H20S
    Private Const STANDARD_RIGHTS_REQUIRED As Integer = &HF0000
    Private Const MAX_LVMSTRING As Integer = 255
    Private Const MEM_COMMIT As Short = &H1000S
    Private Const PAGE_READWRITE As Short = &H4S
    Private Const LVIF_TEXT As Integer = &H1S
    Private Const MEM_RELEASE As Short = &H8000S
    Public Const LVM_GETITEMCOUNT = LVM_FIRST + 4
    Public Const LVM_FIRST = &H1000
    Private Const LVM_GETITEMTEXT As Integer = (LVM_FIRST + 45)
    Public Const WM_USER As Int32 = &H400

    Private Structure LV_ITEMA
        Dim mask As Integer
        Dim iItem As Integer
        Dim iSubItem As Integer
        Dim state As Integer
        Dim stateMask As Integer
        Dim pszText As Integer
        Dim cchTextMax As Integer
        Dim iImage As Integer
        Dim lParam As Integer
        Dim iIndent As Integer
    End Structure
    Public Function GetListviewItem(ByVal lstviewhwnd As Integer) As String
        Dim result As Integer
        Dim myItem As LV_ITEMA
        Dim pHandle As Integer
        Dim pStrBufferMemory As Integer
        Dim pMyItemMemory As Integer
        Dim strBuffer() As Byte
        Dim index As Integer
        Dim tmpString As String
        Dim strLength As Integer
        Dim ProcessID As Integer
        Dim usernum As Integer
        Dim i As Short
        usernum = SendMessage(lstviewhwnd, LVM_GETITEMCOUNT, 0, 0)
        '**********************
        'init the string buffer
        '**********************
        ReDim strBuffer(MAX_LVMSTRING)
        '***********************************************************
        'open a handle to the process and allocate the string buffer
        '***********************************************************
        Call GetWindowThreadProcessId(lstviewhwnd, ProcessID)
        pHandle = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, ProcessID)
        pStrBufferMemory = VirtualAllocEx(pHandle, 0, MAX_LVMSTRING, MEM_COMMIT, PAGE_READWRITE)
        '************************************************************************************
        'initialize the local LV_ITEM structure
        'The myItem.iSubItem member is set to the index of the column that is being retrieved
        '************************************************************************************
        myItem.mask = LVIF_TEXT
        myItem.iSubItem = 2
        myItem.pszText = pStrBufferMemory
        myItem.cchTextMax = MAX_LVMSTRING
        '**********************************************************
        'write the structure into the remote process's memory space
        '**********************************************************
        pMyItemMemory = VirtualAllocEx(pHandle, 0, Len(myItem), MEM_COMMIT, PAGE_READWRITE)
        result = WriteProcessMemory(pHandle, pMyItemMemory, myItem, Len(myItem), 0)
        For i = 0 To usernum - 1
            '*************************************************************
            'send the get the item message and write back the memory space
            '*************************************************************
            result = SendMessage(lstviewhwnd, LVM_GETITEMTEXT, i, pMyItemMemory)
            result = ReadProcessMemory(pHandle, pStrBufferMemory, strBuffer(0), MAX_LVMSTRING, 0)
            result = ReadProcessMemory(pHandle, pMyItemMemory, myItem, Len(myItem), 0)
            '**************************************************
            'turn the byte array into a string and send it back
            '**************************************************
            For index = LBound(strBuffer) To UBound(strBuffer)
                If Chr(strBuffer(index)) = vbNullChar Then Exit For
                tmpString = tmpString & Chr(strBuffer(index))
            Next index
            tmpString = Trim(tmpString) & ";"
            MessageBox.Show(tmpString)
        Next
        '**************************************************
        'deallocate the memory and close the process handle
        '**************************************************
        result = VirtualFreeEx(pHandle, pStrBufferMemory, 0, MEM_RELEASE)
        result = VirtualFreeEx(pHandle, pMyItemMemory, 0, MEM_RELEASE)
        result = CloseHandle(pHandle)
        If Len(tmpString) > 0 Then GetListviewItem = tmpString
    End Function
User avatar
BattleStar-Galactica
imFiles Master
imFiles Master
 
Posts: 565
Joined: Tue Sep 20, 2005 12:19 am
Location: safest place to hide

Postby BattleStar-Galactica » Sat Aug 26, 2006 12:24 pm

or c++ code


Code: Select all


int count=(int)::SendMessage(listview, LVM_GETITEMCOUNT, 0, 0);
   int i;

   LVITEM lvi, *_lvi;
   char item[512], subitem[512];
   char *_item, *_subitem;
   unsigned long pid;
   HANDLE process;

   GetWindowThreadProcessId(listview, &pid);
   process=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION, FALSE, pid);

   _lvi=(LVITEM*)VirtualAllocEx(process, NULL, sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE);
   
   _item=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT, PAGE_READWRITE);
   
   lvi.cchTextMax=512;
   
   
   for(i=0; i<count; i++) {
      lvi.iSubItem=2;
      lvi.pszText=_item;
      WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
      ::SendMessage(listview, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);

      

      
      ReadProcessMemory(process, _item, item, 512, NULL);
      

      c.Format("%s", item);
          ::AfxMessageBox(c);///display item here
   }



all these codes work correctly, cuz I do copy and past my old project
listview is handle of listview

have fun, I think you are busy for a couple of hour :wink:
User avatar
BattleStar-Galactica
imFiles Master
imFiles Master
 
Posts: 565
Joined: Tue Sep 20, 2005 12:19 am
Location: safest place to hide

Postby nooob » Sat Aug 26, 2006 3:52 pm

nice..buddy...THANX ALOT nanomachine
i am going to study ur code

lol..i am gonna be busy for quite some time to come... 8)

noob
Water can make holes in rocks!
nooob
imFiles Junior
imFiles Junior
 
Posts: 52
Joined: Sun Jul 23, 2006 10:23 am

Postby nooob » Sun Aug 27, 2006 1:55 pm

ok i made some progress but had a problem in getting a nick from room listview.

Code: Select all

//constants
const int LVM_FIRST = 0x1000;
const int LVM_GETITEMCOUNT = LVM_FIRST + 4;
const int LVM_GETITEMTEXT = (LVM_FIRST + 45);

private void button1_Click(object sender, EventArgs e)
        {
            IntPtr hRoom = FindWindow("My Window Class", null);
            IntPtr hSplitter = FindWindowEx(hRoom, IntPtr.Zero, "WTL_SplitterWindow", null);
            IntPtr hSplitter1 = FindWindowEx(hSplitter, IntPtr.Zero, "WTL_SplitterWindow", null);
            IntPtr hSplitter2 = FindWindowEx(hSplitter1, IntPtr.Zero, "WTL_SplitterWindow", null);
            IntPtr hSysList = FindWindowEx(hSplitter2, IntPtr.Zero, "ATL:0053C8D0", null);
            IntPtr hList = FindWindowEx(hSysList, IntPtr.Zero, "SysListView32", null);
            int count = SendMessageLong(hList, LVM_GETITEMCOUNT , 0, null);
            StringBuilder selectedNick = new StringBuilder(256);
            MessageBox.Show(count.ToString());
            SendMessageLong(hList, LVM_GETITEMTEXT, 0, selectedNick);
            MessageBox.Show(selectedNick.ToString());
        }


i was able to get the no of entries in the listview using this:
Code: Select all
int count = SendMessageLong(hList, LVM_GETITEMCOUNT , 0, null);


the following line should get the first nick from the listview...but it does not:
Code: Select all
SendMessageLong(hList, LVM_GETITEMTEXT, 0, selectedNick);



can see whats wrong??

ty nanomachine

nooob
Water can make holes in rocks!
nooob
imFiles Junior
imFiles Junior
 
Posts: 52
Joined: Sun Jul 23, 2006 10:23 am

Postby BattleStar-Galactica » Mon Aug 28, 2006 4:32 am

dealing with external listview to get item or select an item, you have to allocate virtual memory and not sendmessage direct like that. check the vbnet code. for counting item yes you can sendmessage normally like that but not get item or select an item with position.
Last edited by BattleStar-Galactica on Mon Aug 28, 2006 9:53 am, edited 1 time in total.
User avatar
BattleStar-Galactica
imFiles Master
imFiles Master
 
Posts: 565
Joined: Tue Sep 20, 2005 12:19 am
Location: safest place to hide

Postby BattleStar-Galactica » Mon Aug 28, 2006 4:42 am

c++ code is more clair cuz you dont have to declare api constants or import api functions but the way to allocate virtual is like c++. vbnet code look like forest...

open process
allocate memory
write process memory
read process memory
deallocate memory before exit function
close process


you have to follow those steps to get listview item
Last edited by BattleStar-Galactica on Mon Aug 28, 2006 9:54 am, edited 1 time in total.
User avatar
BattleStar-Galactica
imFiles Master
imFiles Master
 
Posts: 565
Joined: Tue Sep 20, 2005 12:19 am
Location: safest place to hide

Postby nooob » Mon Aug 28, 2006 9:06 am

nanomachine...any sites about this process in vc#?
or if u can elaborate on it....plz
coz...i could compile only half way...not sure if it work

nooob
Water can make holes in rocks!
nooob
imFiles Junior
imFiles Junior
 
Posts: 52
Joined: Sun Jul 23, 2006 10:23 am

Postby BattleStar-Galactica » Mon Aug 28, 2006 9:56 am

nope I can't cuz i'm busy with my project live cam streamming with c++. look around google or go to microsoft codezone, there are many forums for c#.net
User avatar
BattleStar-Galactica
imFiles Master
imFiles Master
 
Posts: 565
Joined: Tue Sep 20, 2005 12:19 am
Location: safest place to hide

Postby nooob » Wed Aug 30, 2006 6:37 pm

hi nanomachine
i know you are busy...but if you sometime get a bit free plz have a look at the following code and lets hope that you find out the problem:


Note: I have found this code at a site

Code: Select all


[StructLayout(LayoutKind.Sequential)]
          public struct LV_ITEM
          {
            public uint   mask;
            public int    iItem;
            public int    iSubItem;
            public uint   state;
            public uint   stateMask;
            public IntPtr pszText;
            public int    cchTextMax;
            public int    iImage;
          }


public static string ReadListViewItem( IntPtr hWnd, int item )
          {
            const int dwBufferSize = 1024;
               
            int         dwProcessID;
            LV_ITEM     lvItem;     
            string      retval;
            bool        bSuccess;
            IntPtr      hProcess        = IntPtr.Zero;
            IntPtr      lpRemoteBuffer  = IntPtr.Zero;
            IntPtr      lpLocalBuffer   = IntPtr.Zero;
            IntPtr      threadId        = IntPtr.Zero;
                 
            try
            {
              lvItem = new LV_ITEM();
              lpLocalBuffer = Marshal.AllocHGlobal(dwBufferSize);
              // Get the process id owning the window
              threadId = GetWindowThreadProcessId( hWnd, out dwProcessID );
              if ( (threadId == IntPtr.Zero) || (dwProcessID == 0) )
                throw new ArgumentException( "hWnd" );

              // Open the process with all access
              hProcess = OpenProcess( PROCESS_ALL_ACCESS, false, dwProcessID );
              if ( hProcess == IntPtr.Zero )
                throw new ApplicationException( "Failed to access process" );

              // Allocate a buffer in the remote process
              lpRemoteBuffer = VirtualAllocEx( hProcess, IntPtr.Zero, dwBufferSize, MEM_COMMIT,
                PAGE_READWRITE );
              if ( lpRemoteBuffer == IntPtr.Zero )
                throw new SystemException( "Failed to allocate memory in remote process" );
             
              // Fill in the LVITEM struct, this is in your own process
              // Set the pszText member to somewhere in the remote buffer,
              // For the example I used the address imediately following the LVITEM stuct
              lvItem.mask = LVIF_TEXT;
              lvItem.iItem = item;
              lvItem.pszText = (IntPtr)(lpRemoteBuffer.ToInt32() + Marshal.SizeOf(typeof(LV_ITEM)));
              lvItem.cchTextMax = 50;

              // Copy the local LVITEM to the remote buffer
              bSuccess = WriteProcessMemory( hProcess, lpRemoteBuffer, ref lvItem,
                Marshal.SizeOf(typeof(LV_ITEM)), IntPtr.Zero );
              if ( !bSuccess )
                throw new SystemException( "Failed to write to process memory" );

              // Send the message to the remote window with the address of the remote buffer
              SendMessage( hWnd, LVM_GETITEM, 0, lpRemoteBuffer);
             
              // Read the struct back from the remote process into local buffer
              bSuccess = ReadProcessMemory( hProcess, lpRemoteBuffer, lpLocalBuffer, dwBufferSize,
                IntPtr.Zero );
              if ( !bSuccess )
                throw new SystemException( "Failed to read from process memory" );
             
              // At this point the lpLocalBuffer contains the returned LV_ITEM structure
              // the next line extracts the text from the buffer into a managed string
   
              retval = Marshal.PtrToStringAnsi((IntPtr)(lpLocalBuffer.ToInt32() +
                Marshal.SizeOf(typeof(LV_ITEM))));

               
            }
            finally
            {
              if ( lpLocalBuffer != IntPtr.Zero )
                Marshal.FreeHGlobal( lpLocalBuffer );
              if ( lpRemoteBuffer != IntPtr.Zero )
                VirtualFreeEx( hProcess, lpRemoteBuffer, 0, MEM_RELEASE );
              if ( hProcess != IntPtr.Zero )
                CloseHandle( hProcess );
            }
            return retval;
          }


the problem is that it returns null?!

the author has used LVM_GETITEM...i also tried with LVM_GETITEMTEXT....but no luck

thnx for your time

nooob
Water can make holes in rocks!
nooob
imFiles Junior
imFiles Junior
 
Posts: 52
Joined: Sun Jul 23, 2006 10:23 am

Postby BattleStar-Galactica » Thu Aug 31, 2006 5:41 am

if you dont change anything it should work by adding this line after the line

lvItem.iItem = item;
add this line
lvItem.iSubItem=2;


that code is really nice :lol:

call that function by passing listview handle and the position of item you want to get like 0 is the first nick in paltalk room, 1 is second nick, 2 is third ect...

I copy that code to the project for testing and it works correctly with sending message LVM_GETITEM, author of that code get item by position and not all the item in listview

if you want get all item using that code
do like this
for int pos; pos<icount;pos++
{
nick=hisfunction (listviewhandle,pos);

}

or just change his code but the performance is after you undertand the code 8)

btw the iSubItem =2 is just for paltalk, item is the row of listview, iSubItem is like column.
User avatar
BattleStar-Galactica
imFiles Master
imFiles Master
 
Posts: 565
Joined: Tue Sep 20, 2005 12:19 am
Location: safest place to hide

Postby nooob » Thu Aug 31, 2006 3:14 pm

yesssssssssss....got it.... :D

thanx alot....for your time and effort nanomachine :P

i would not have made it without your quick replies...ty

i get most of the code..that i had pasted (from the site)...but still have problems with LV_ITEM struc....as how it works...

can you elaborate a little more on your this line:
btw the iSubItem =2 is just for paltalk, item is the row of listview, iSubItem is like column.


i tried iSubItem = 1...but it didn work...why is that?


thanx once again...nanomachine


nooob
Water can make holes in rocks!
nooob
imFiles Junior
imFiles Junior
 
Posts: 52
Joined: Sun Jul 23, 2006 10:23 am

Postby BattleStar-Galactica » Thu Aug 31, 2006 9:57 pm

iSubItem is the column of your listview. you can create a app that has a listview with some rows and some columns and try to get the item and subitem. dont do the test with pt listview, create your own listview and try change value of iItem and iSubItem, you will understand better what it is.

item1|subitem1|subitem2|subitem3
item2|subitem1|subitem2|subitem3
item3|subitem1|subitem2|subitem3


create a listview like that and do the test. dont try with pt listview :roll:
User avatar
BattleStar-Galactica
imFiles Master
imFiles Master
 
Posts: 565
Joined: Tue Sep 20, 2005 12:19 am
Location: safest place to hide

Next

Return to C++, C# And Others Programming

 


  • Related topics
    Replies
    Views
    Last post

Who is online

Users browsing this forum: No registered users and 0 guests