AutoHotkey Community

It is currently May 25th, 2012, 6:15 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 23 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: June 7th, 2007, 11:36 pm 
Offline

Joined: March 28th, 2004, 3:53 pm
Posts: 1870
The target control is TListView1 and the app is probably written in delphi.

This doesn't help:
ControlGet, ret, List,, TListView1, WindowName

The below cmd gives me the no. of rows:
SendMessage, 0x1004, 1, 0, TListView1, WindowName

I want to read the contents of that control as well.

I was looking into LVM_GETITEMTEXT but that probably gives the length of string.

any ideas?

Thanks!

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
PostPosted: June 8th, 2007, 10:02 am 
Rajat wrote:
This doesn't help:
ControlGet, ret, List,, TListView1, WindowName
I what sense? You get empty value?
Using SendMessage probably won't help, I suppose that's what Chris uses internally anyway.
And since the messages are above WM_USER, you have to use remote procedure access (RPA) methods to get the data.
But if ControlGet fails, it might be because user data is stored internally, not in the control. Is the list view owner drawn?


Report this post
Top
  
Reply with quote  
PostPosted: June 8th, 2007, 11:49 am 
Offline

Joined: March 28th, 2004, 3:53 pm
Posts: 1870
Helpy wrote:
I what sense? You get empty value?
Using SendMessage probably won't help, I suppose that's what Chris uses internally anyway.
And since the messages are above WM_USER, you have to use remote procedure access (RPA) methods to get the data.
But if ControlGet fails, it might be because user data is stored internally, not in the control. Is the list view owner drawn?

yes i get empty value.

though TextCatch from http://www.skesoft.com/ catches the contents of the same control.
does that help?

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 8th, 2007, 12:31 pm 
I meant "In what sense", of course...
TextCatch is interesting, but I see it has a Scan mode, which might be an OCR module: if it can't get data by classical means, perhaps it scan it.
Or perhaps it can handle more components than AHK, Delphi components are quite commonplace anyway. I don't how much they differ from standard Windows components (wrappers).


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: June 8th, 2007, 2:37 pm 
Offline

Joined: March 28th, 2004, 3:53 pm
Posts: 1870
another approach.. is there a way to make the control copy its contents to clipboard?
i read somewhere that for the apps that keep this in their own memory , its difficult to grab the control's contents... but the clipboard approach might work.
any ideas on this?

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 8th, 2007, 3:13 pm 
Only if the application allows this, there is no way to force it.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: June 8th, 2007, 3:50 pm 
Offline

Joined: March 28th, 2004, 3:53 pm
Posts: 1870
:(

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 23rd, 2007, 10:50 am 
Hey, I have some code to read the text from an item in a TListView, maybe it'll help?

Code:
    GetListViewItemText(item_index, sub_index, ctrl_id, win_id)
    {
        ;const
        MAX_TEXT = 260

        VarSetCapacity(szText, MAX_TEXT, 0)
        VarSetCapacity(szClass, MAX_TEXT, 0)
        ControlGet, hListView, Hwnd, , %ctrl_id%, ahk_id %win_id%
        DllCall("GetClassName", UInt,hListView, Str,szClass, Int,MAX_TEXT)
        if (DllCall("lstrcmpi", Str,szClass, Str,"SysListView32") == 0 || DllCall("lstrcmpi", Str,szClass, Str,"TListView") == 0)
        {
            GetListViewText(hListView, item_index, sub_index, szText, MAX_TEXT)
        }

        return %szText%
    }

    GetListViewText(hListView, iItem, iSubItem, ByRef lpString, nMaxCount)
    {
        ;const
        NULL = 0
        PROCESS_ALL_ACCESS = 0x001F0FFF
        INVALID_HANDLE_VALUE = 0xFFFFFFFF
        PAGE_READWRITE = 4
        FILE_MAP_WRITE = 2
        MEM_COMMIT = 0x1000
        MEM_RELEASE = 0x8000
        LV_ITEM_mask = 0
        LV_ITEM_iItem = 4
        LV_ITEM_iSubItem = 8
        LV_ITEM_state = 12
        LV_ITEM_stateMask = 16
        LV_ITEM_pszText = 20
        LV_ITEM_cchTextMax = 24
        LVIF_TEXT = 1
        LVM_GETITEM = 0x1005
        SIZEOF_LV_ITEM = 0x28
        SIZEOF_TEXT_BUF = 0x104
        SIZEOF_BUF = 0x120
        SIZEOF_INT = 4
        SIZEOF_POINTER = 4

        ;var
        result := 0
        hProcess := NULL
        dwProcessId := 0

        if lpString <> NULL && nMaxCount > 0
        {
            DllCall("lstrcpy", Str,lpString, Str,"")
            DllCall("GetWindowThreadProcessId", UInt,hListView, UIntP,dwProcessId)
            hProcess := DllCall("OpenProcess", UInt,PROCESS_ALL_ACCESS, Int,false, UInt,dwProcessId)
            if hProcess <> NULL
            {
                ;var
                lpProcessBuf := NULL
                hMap := NULL
                hKernel := DllCall("GetModuleHandle", Str,"kernel32.dll", UInt)
                pVirtualAllocEx := DllCall("GetProcAddress", UInt,hKernel, Str,"VirtualAllocEx", UInt)
   
                if pVirtualAllocEx == NULL
                {
                    hMap := DllCall("CreateFileMapping", UInt,INVALID_HANDLE_VALUE, Int,NULL, UInt,PAGE_READWRITE, UInt,0, UInt,SIZEOF_BUF, UInt)
                    if hMap <> NULL
                        lpProcessBuf := DllCall("MapViewOfFile", UInt,hMap, UInt,FILE_MAP_WRITE, UInt,0, UInt,0, UInt,0, UInt)
                }
                else
                {
                    lpProcessBuf := DllCall("VirtualAllocEx", UInt,hProcess, UInt,NULL, UInt,SIZEOF_BUF, UInt,MEM_COMMIT, UInt,PAGE_READWRITE)
                }

                if lpProcessBuf <> NULL
                {
                    ;var
                    VarSetCapacity(buf, SIZEOF_BUF, 0)

                    InsertIntegerSL(LVIF_TEXT, buf, LV_ITEM_mask, SIZEOF_INT)
                    InsertIntegerSL(iItem, buf, LV_ITEM_iItem, SIZEOF_INT)
                    InsertIntegerSL(iSubItem, buf, LV_ITEM_iSubItem, SIZEOF_INT)
                    InsertIntegerSL(lpProcessBuf + SIZEOF_LV_ITEM, buf, LV_ITEM_pszText, SIZEOF_POINTER)
                    InsertIntegerSL(SIZEOF_TEXT_BUF, buf, LV_ITEM_cchTextMax, SIZEOF_INT)
   
                    if DllCall("WriteProcessMemory", UInt,hProcess, UInt,lpProcessBuf, UInt,&buf, UInt,SIZEOF_BUF, UInt,NULL) <> 0
                        if DllCall("SendMessage", UInt,hListView, UInt,LVM_GETITEM, Int,0, Int,lpProcessBuf) <> 0
                            if DllCall("ReadProcessMemory", UInt,hProcess, UInt,lpProcessBuf, UInt,&buf, UInt,SIZEOF_BUF, UInt,NULL) <> 0
                            {
                                DllCall("lstrcpyn", Str,lpString, UInt,&buf + SIZEOF_LV_ITEM, Int,nMaxCount)
                                result := DllCall("lstrlen", Str,lpString)
                            }
                }

                if lpProcessBuf <> NULL
                    if pVirtualAllocEx <> NULL
                        DllCall("VirtualFreeEx", UInt,hProcess, UInt,lpProcessBuf, UInt,0, UInt,MEM_RELEASE)
                    else
                        DllCall("UnmapViewOfFile", UInt,lpProcessBuf)
   
                if hMap <> NULL
                    DllCall("CloseHandle", UInt,hMap)
   
                DllCall("CloseHandle", UInt,hProcess)
            }
        }
        return result
    }

; *********************************
; Required functions - ExtractInteger, InsertInteger
; - original versions from Version 1.0.44.06 of the AutoHotkey help file
; by Chris Mallett
; // Renamed in case someone is using a modified version of these functions
; // somewhere else in their code
; *********************************
ExtractIntegerSL(ByRef pSource, pOffset = 0, pIsSigned = false, pSize = 4)
; pSource is a string (buffer) whose memory area contains a raw/binary integer at pOffset.
; The caller should pass true for pSigned to interpret the result as signed vs. unsigned.
; pSize is the size of PSource's integer in bytes (e.g. 4 bytes for a DWORD or Int).
; pSource must be ByRef to avoid corruption during the formal-to-actual copying process
; (since pSource might contain valid data beyond its first binary zero).
{
   Loop %pSize%  ; Build the integer by adding up its bytes.
      result += *(&pSource + pOffset + A_Index-1) << 8*(A_Index-1)
   if (!pIsSigned OR pSize > 4 OR result < 0x80000000)
      return result  ; Signed vs. unsigned doesn't matter in these cases.
   ; Otherwise, convert the value (now known to be 32-bit) to its signed counterpart:
   return -(0xFFFFFFFF - result + 1)
}
; *********************************
InsertIntegerSL(pInteger, ByRef pDest, pOffset = 0, pSize = 4)
; The caller must ensure that pDest has sufficient capacity.  To preserve any existing contents in pDest,
; only pSize number of bytes starting at pOffset are altered in it.
{
   Loop %pSize%  ; Copy each byte in the integer into the structure as raw binary data.
      DllCall("RtlFillMemory", "UInt", &pDest + pOffset + A_Index-1, "UInt", 1, "UChar", pInteger >> 8*(A_Index-1) & 0xFF)
}
; *********************************




Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: August 28th, 2007, 10:16 am 
Offline

Joined: March 28th, 2004, 3:53 pm
Posts: 1870
thanks Tigerite for your help, but it doesn't work for me :(
(i was out of town for a few days hence the late reply)

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 29th, 2007, 4:53 pm 
Really, that's most odd, could you tell me which app you're trying to read the ListView of? I tried this with a pretty complicated one and it read it alright (although only the text, it didn't read checkboxes and the like within it)


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: August 31st, 2007, 5:56 am 
Offline

Joined: March 28th, 2004, 3:53 pm
Posts: 1870
Tigerite,
its a custom s/w designed for my workplace. its definitely delphi, and the control is TListView1.

plz let me know if i'm using the script correctly. for testing i just added the following at top of your script :

x := GetListViewItemText(1, 1, "0x402be", "0x20318")
msgbox %x%

the hwnd values i took from my win-spy just before filling them in... i'd have scripted the code if this'd worked for me.

Thanks

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 31st, 2007, 4:15 pm 
No, that's not quite how you use it; the ctrl_id should be the ClassNN, for example, TListView1.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: August 31st, 2007, 4:16 pm 
Or in other words, for your control:

x := GetListViewItemText(1, 1, "TListView1", "0x20318")


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: August 31st, 2007, 4:24 pm 
Oh, one more thing; the indexes are zero-based.

Sorry the code isn't clearer, it does need a little tidying up.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: August 31st, 2007, 6:18 pm 
Offline

Joined: March 28th, 2004, 3:53 pm
Posts: 1870
thanks a lot Tigerite, it works perfectly now!
that was great help! :)

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 23 posts ]  Go to page 1, 2  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: BrandonHotkey, dra, Ohnitiel, Pulover, rbrtryn, sarevok9, tomL, vsub and 68 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group