使用AHK PostMessage / SendMessage或DllCall(“SendMessage”获取listview控件的内容

时间:2015-03-30 00:12:37

标签: autohotkey

我正在尝试使用AHK在另一个应用程序中获取listview控件的内容。我尝试使用

ControlGet, List, List,, ListViewWndClass1, WindowTitle
在AutoHotKey中

但这不起作用。有没有办法使用AHK PostMessage / SendMessage或DllCall获取listview控件内容(“SendMessage”?

1 个答案:

答案 0 :(得分:0)

试试这个:

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) 
} 
; *********************************

应该像这样工作:

WinGet, hWnd, ID, My WinTitle
GetListViewItemText(1, 1, "ListViewWndClass1", hWnd)

来源:http://www.autohotkey.com/board/topic/18299-reading-listview-of-another-app/