主頁 > 軟體工程 > vb利用SendMessage操作listview居然失敗,太怪異了!!

vb利用SendMessage操作listview居然失敗,太怪異了!!

2020-09-23 14:52:08 軟體工程

我參考網上的代碼,這段代碼我測驗了,對于“任務管理器”是有效的,但是對于我實際專案中的listview就無效了。。。
代碼如下:
...省略定義

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

Private Sub Command1_Click()
    Dim hWnd As Long

    hWnd = FindWindow(vbNullString, "GAINCNGTMGR - Sterling Trader(R) Manager")
    'hWnd = FindWindowEx(hWnd, 0, "#32770", vbNullString)
    hWnd = FindWindowEx(hWnd, 0, "SysListView32", vbNullString)
   
    Call ListView_SetItemText(hWnd, 5, 0, "12345667") '這句執行了無效
    Call ListView_DelItem(hWnd, 5)
    '這句執行了看到目標sylistview32 已經刪掉了第5行,但馬上sylistview32又自動出現剛才被刪掉的那行,出現在尾行,意思就是仍然無法洗掉
    
   
End Sub

'*************************************************************************
'**函 數 名:ListView_SetItemText
'**輸    入:ByVal hWnd(Long)       - ListView控制元件句柄
'**        :ByVal iItem(Long)      - 行
'**        :ByVal iSubItem(Long)   - 列
'**        :ByVal ItemText(String) - 更改的內容
'**輸    出:(Boolean) -
'**功能描述:更改其他程式ListView控制元件中某個Item的內容
'**全域變數:
'**呼叫模塊:
'**作    者:bbb620
'**日    期:2008-07-27 13:26:03
'**修 改 人:
'**日    期:
'**版    本:V1.0.0
'*************************************************************************
Public Function ListView_SetItemText(ByVal hWnd As Long, ByVal iItem As Long, ByVal iSubItem As Long, ByVal ItemText As String) As Boolean
    Dim PID As Long
    Dim hProcess As Long
    Dim nSize As Long
    Dim plvItem As Long
    Dim p_MyItemText As Long
    Dim myItem As LVITEM

    nSize = LenB(StrConv(ItemText, vbFromUnicode)) '獲取字串長度

    GetWindowThreadProcessId hWnd, PID '獲取與指定視窗關聯在一起的一個行程和執行緒識別符號
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, False, PID) '打開一個現有行程的句柄

    If hProcess <> 0 Then
        plvItem = VirtualAllocEx(hProcess, 0, Len(myItem), MEM_COMMIT, PAGE_READWRITE) '分配記憶體
        p_MyItemText = VirtualAllocEx(hProcess, 0, nSize, MEM_COMMIT, PAGE_READWRITE) '分配記憶體
        
        '初始化結構
        myItem.iSubItem = iSubItem
        myItem.pszText = p_MyItemText

        If plvItem And p_MyItemText Then
            Call WriteProcessMemory(hProcess, p_MyItemText, ByVal ItemText, nSize, 0)  '寫入記憶體
            Call WriteProcessMemory(hProcess, plvItem, myItem, Len(myItem), 0)  '寫入記憶體

            Call SendMessage(hWnd, LVM_SETITEMTEXT, iItem, ByVal plvItem)

            ListView_SetItemText = True

            '釋放記憶體
            CloseHandle (hWnd)
            CloseHandle (hProcess)
            Call VirtualFreeEx(hProcess, plvItem, 0, MEM_RELEASE)
            Call VirtualFreeEx(hProcess, p_MyItemText, 0, MEM_RELEASE)
        End If
    End If

End Function
'*************************************************************************
'**函 數 名:ListView_DelItem
'**輸    入:ByVal hwnd(Long) - ListView控制元件句柄
'**        :ByVal i(Long)    - 行
'**輸    出:無
'**功能描述:洗掉其他程式ListView控制元件中的某行Item
'*************************************************************************
Public Function ListView_DelItem(ByVal hWnd As Long, ByVal i As Long)
    SendMessage hWnd, LVM_DELETEITEM, i, 0
End Function


我本來是用c#的,在c#下也是無法取得listview的資料,后來參考vb代碼以為可以解決,誰知道仍然是一樣。
這段代碼vb中嘗試修改某個items的資料項,也是失敗,運行中我發現listview那個目標閃了一下,但原來的值不變。洗掉的時候,明明看到已經洗掉了,但一會馬上又出現了原來那一行。難道目標的listview是禁止了SendMessage 訊息,不可修改也不可取值的?
c#版我的帖子發了幾天了,無人解決,所以到這邊求教,希望遇到高手指點一下!
謝謝!!!!!!

uj5u.com熱心網友回復:

你的目標 ListView 可能是 OwnerDraw 風格的。
資料由程式管理而不是存放在 ListView 中的。
所以操作 ListView 是沒有效果的。

uj5u.com熱心網友回復:

參考 1 樓 Tiger_Zhao 的回復:
你的目標 ListView 可能是 OwnerDraw 風格的。
資料由程式管理而不是存放在 ListView 中的。
所以操作 ListView 是沒有效果的。


那么請問有什么辦法可以讀到listview的資料嗎?
我在c#下可以讀到listview的行數以及列數,而文本資料也是讀取不到。

謝謝!

uj5u.com熱心網友回復:

基本上是取不到的。
就像不帶現金帶信用卡一樣,花錢時直接劃賬,不怕搶。

uj5u.com熱心網友回復:

參考 1 樓 Tiger_Zhao 的回復:
你的目標 ListView 可能是 OwnerDraw 風格的。
資料由程式管理而不是存放在 ListView 中的。
所以操作 ListView 是沒有效果的。


我用spy查看了,
類名 SysListView32
視窗樣式是WS_CHILD|WS_HSCROLL|WS_VISIBLE
擴展樣式是WS_EX_CLIENTEDGE

這種也不行嗎

uj5u.com熱心網友回復:

參考 3 樓 Tiger_Zhao 的回復:
基本上是取不到的。
就像不帶現金帶信用卡一樣,花錢時直接劃賬,不怕搶。


請問怎么才能確定 ListView 是 OwnerDraw 風格的,我在spy下沒看到OwnerDraw ?
另外我在網上看到有人說,遠程子類化,再截取LVN_GETDISPINFO訊息可以取出文本資料?
另外還有個說法,“...注入目標行程,用經過改寫的FindControl來找到目標視窗的物件,然后再根據物件->屬性或方法的方式讀取內容”

請問如上思路是否可行?

難道真的沒有辦法取出listview的文本資料了嗎?
還請各位高手指點一二!
謝謝!!!

uj5u.com熱心網友回復:

MSDN 的 VC 樣例中有一個 VListVw,可以參考一下,如果是這樣的風格應該可以用 LVN_GETDISPINFO 取得資料。
但是也可能是通過子類化實作的自繪,資料完全自己控制,就取不到了。

uj5u.com熱心網友回復:

推薦使用spy4win軟體。

uj5u.com熱心網友回復:

參考 7 樓 zhao4zhong1 的回復:
推薦使用spy4win軟體。


我正是使用spy4win的,但一點用處沒有,他有個內容框,仍然取不到值,一片空白。
此外,我查看視窗風格,也沒有出現OwnerDraw之類的字樣。
我目前所知道的就是,目標程式的資料是來自對方服務器,且目標程式是vb寫的

謝謝!!

uj5u.com熱心網友回復:

求教還有什么辦法可以去到這個listview的資料,我那天看到一個人說可以子類化再攔截訊息,現在在研究子類化,過2天試試,不知道這條路行不行的通。
如果實在行不通,我只能對那個listview實作截圖,用學習影像分析處理,強行把上面的文字讀取出來。。。。。

uj5u.com熱心網友回復:

參考 8 樓 wwwww112233 的回復:
Quote: 參考 7 樓 zhao4zhong1 的回復:

推薦使用spy4win軟體。


我正是使用spy4win的,但一點用處沒有,他有個內容框,仍然取不到值,一片空白。
此外,我查看視窗風格,也沒有出現OwnerDraw之類的字樣。
我目前所知道的就是,目標程式的資料是來自對方服務器,且目標程式是vb寫的

謝謝!!

僅供參考
void MyGetListViewItem(HWND hWindow) {

    int          nLVItemCount;
    int          nColumns;
    DWORD        dwProcessID;
    HANDLE       hProcess;
    HWND         hHeaderCtrl;
    LVITEM       lvItemLocal;
    HDITEM       hdItemLocal;
    DWORD        dwBytesRead, dwBytesWrite;
    BOOL         bSuccess,bWriteOK;
    LPVOID       lpTextRemote;
    LPVOID       lpListItemRemote;
    LPVOID       lpHeadItemRemote;
    int i,j;

    GetWindowThreadProcessId(hWindow,&dwProcessID);
    hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessID);
    if (!hProcess) goto ABORT0;
    lpTextRemote=VirtualAllocEx(hProcess,NULL,nMaxLen+1,MEM_COMMIT,PAGE_READWRITE);
    if (!lpTextRemote) goto ABORT1;
    lpListItemRemote=VirtualAllocEx(hProcess,NULL,sizeof(LVITEM),MEM_COMMIT,PAGE_READWRITE);
    if (!lpListItemRemote) goto ABORT2;
    lpHeadItemRemote=VirtualAllocEx(hProcess,NULL,sizeof(HDITEM),MEM_COMMIT,PAGE_READWRITE);
    if (!lpHeadItemRemote) goto ABORT3;

    nLVItemCount=ListView_GetItemCount(hWindow);
    hHeaderCtrl =ListView_GetHeader(hWindow);
    nColumns    =Header_GetItemCount(hHeaderCtrl);

    init();
    if (nColumns<=0) {
        nColumns=1;
    } else {
        ln[0]=0;
        for (j=0;j<nColumns;j++) {
            ZeroMemory(szBuf,nMaxLen+1);
            bWriteOK= WriteProcessMemory(hProcess,lpTextRemote,(LPVOID)szBuf,nMaxLen+1,(LPDWORD)&dwBytesWrite);
            if (!bWriteOK) goto ABORT4;
            hdItemLocal.mask=HDI_TEXT;
            hdItemLocal.cchTextMax=nMaxLen;
            hdItemLocal.pszText=(LPTSTR)lpTextRemote;
            dwBytesWrite=0;
            bWriteOK=WriteProcessMemory(hProcess,lpHeadItemRemote,(LPVOID)&hdItemLocal,sizeof(HDITEM),(LPDWORD)&dwBytesWrite);
            if (!bWriteOK) goto ABORT4;
            SendMessage(hHeaderCtrl,HDM_GETITEM,(WPARAM)j,(LPARAM)lpHeadItemRemote);
            bSuccess=ReadProcessMemory(hProcess,lpTextRemote,szBuf,nMaxLen+1,&dwBytesRead);
            if (!bSuccess) goto ABORT4;
            if (j>0) strcat(ln,"|");
            strstrip(szBuf1,szBuf);
            strcat(ln,szBuf1);
        }
        add1(ln);
    }
//  printf("ListView的Columns數: %d\n",nColumns);
//  printf("---------------------------\n");
    for (i=0;i<nLVItemCount;i++) {
        ln[0]=0;
        for (j=0;j<nColumns;j++) {
            ZeroMemory(szBuf,nMaxLen+1);
            bWriteOK= WriteProcessMemory(hProcess,lpTextRemote,(LPVOID)szBuf,nMaxLen+1,(LPDWORD)&dwBytesWrite);
            if (!bWriteOK) goto ABORT4;
            lvItemLocal.iItem=i;
            lvItemLocal.iSubItem=j;
            lvItemLocal.mask=LVIF_TEXT;
            lvItemLocal.cchTextMax=nMaxLen;
            lvItemLocal.pszText=(LPTSTR)lpTextRemote;
            dwBytesWrite=0;
            bWriteOK=WriteProcessMemory(hProcess,lpListItemRemote,(LPVOID)&lvItemLocal,sizeof(LVITEM),(LPDWORD)&dwBytesWrite);
            if (!bWriteOK) goto ABORT4;
            SendMessage(hWindow,LVM_GETITEMTEXT,(WPARAM)i,(LPARAM)lpListItemRemote);
            bSuccess=ReadProcessMemory(hProcess,lpTextRemote,szBuf,nMaxLen+1,&dwBytesRead);
            //從指定行程存盤空間讀取文本
            if (!bSuccess) goto ABORT4;
            if (j>0) strcat(ln,"|");
            strstrip(szBuf1,szBuf);
            strcat(ln,szBuf1);
        }
        add1(ln);
    }
ABORT4:
    VirtualFreeEx(hProcess,lpHeadItemRemote,0,MEM_RELEASE);
ABORT3:
    VirtualFreeEx(hProcess,lpListItemRemote,0,MEM_RELEASE);
ABORT2:
    VirtualFreeEx(hProcess,lpTextRemote,0,MEM_RELEASE);
ABORT1:
    CloseHandle(hProcess);
ABORT0:
    over();
    return;
}
//---------------------------------------------------------------------------

uj5u.com熱心網友回復:

參考 8 樓 wwwww112233 的回復:
此外,我查看視窗風格,也沒有出現OwnerDraw之類的字樣。

ListView 提供的 OwnerDraw 風格只是一種可選方案,不是所有的自繪一定就是通過這種風格實作的。
就像購物付款,你可以刷卡,也可以付現金,后者明顯不利于商家追蹤你的購物習慣。

uj5u.com熱心網友回復:

參考 10 樓 zhao4zhong1 的回復:
Quote: 參考 8 樓 wwwww112233 的回復:

Quote: 參考 7 樓 zhao4zhong1 的回復:

推薦使用spy4win軟體。


僅供參考
void MyGetListViewItem(HWND hWindow) {

    int          nLVItemCount;
    int          nColumns;
    DWORD        dwProcessID;
    HANDLE       hProcess;
    HWND         hHeaderCtrl;
   ...
}
//---------------------------------------------------------------------------


謝謝!!
我對c++不是很熟悉,我這里有一段vb代碼,應該是和你給出的代碼是一樣的功能。即通過獲取目標行程,把行程資料寫入記憶體。代碼是這樣的,您看下是不是一樣的?

Public Function GetListviewItem(ByVal hWindow As Long, ByVal ProcessID As Long, ByVal pColumn As Long, ByVal pRow As Long) As String
    Dim Result As Long
    Dim myItem As LV_ITEMA
    Dim pHandle As Long
    Dim pStrBufferMemory As Long
    Dim pMyItemMemory As Long
    Dim strBuffer() As Byte
    Dim Index As Long
    Dim tmpString As String
    Dim strLength As Long

    '******************************
    '為動態陣列變數重新分配存盤空間
    '******************************
    ReDim strBuffer(MAX_LVMSTRING)

    '*****************************************************************************************************
    '打開一個現有行程的句柄,回傳值Long,如執行成功,回傳行程句柄;零表示失敗。會設定GetLastError
    'Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long
    '引數 型別及說明
    'dwDesiredAccess Long,指定這個句柄要求的訪問方法。指定API32.TXT檔案中以PROCESS_???開頭的一個或多個常數
    'bInheritHandle Long,如句柄能夠由子行程繼承,則為TRUE
    'dwProcessId Long,要打開那個行程的行程識別符號
    '*****************************************************************************************************
    pHandle = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, ProcessID)

    '*****************************************************************************************************
    'VirtualAllocEx(目標行程的句柄,0,記憶體區域的大小,分配型別,新分配記憶體的存取保護型別)回傳所分配頁面的基址
    '*****************************************************************************************************

If pStrBufferMemory = 0 Then
    pStrBufferMemory = VirtualAllocEx(pHandle, 0, MAX_LVMSTRING, MEM_COMMIT, PAGE_READWRITE)
End If
    '*************************************************
    '初始化LV_ITEM 結構
    'MyItem.iSubItem 列的索引號
    'myItem.pszText 資料內容(此處是一個分配的記憶體地址)
    '*************************************************
    myItem.mask = LVIF_TEXT
    myItem.iSubItem = pColumn
    myItem.pszText = pStrBufferMemory
    myItem.cchTextMax = MAX_LVMSTRING

    '***********************************************************
    '把這個結構寫入遠程行程process's 存盤量
    'WriteProcessMemory(目標行程的句柄,地址,寫入的資料,位元組數,0)
    '***********************************************************

If pMyItemMemory = 0 Then
    pMyItemMemory = VirtualAllocEx(pHandle, 0, Len(myItem), MEM_COMMIT, PAGE_READWRITE)

End If
    Result = WriteProcessMemory(pHandle, pMyItemMemory, myItem, Len(myItem), 0)

    '********************************
    '發送訊息,得到專案資訊和寫入記憶體
    '********************************
    Result = SendMessage(hWindow, LVM_GETITEMTEXT, pRow, ByVal pMyItemMemory)
    Result = ReadProcessMemory(pHandle, pStrBufferMemory, strBuffer(0), MAX_LVMSTRING, 0)
    Result = ReadProcessMemory(pHandle, pMyItemMemory, myItem, Len(myItem), 0)

    '************************
    '把位元組列陣變成串和送回它
    '************************

    tmpString = StrConv(strBuffer, vbUnicode)
    If InStr(tmpString, Chr$(0)) > 0 Then
        tmpString = Left$(tmpString, InStr(tmpString, Chr$(0)) - 1)
    End If

    tmpString = Trim$(tmpString)

    '****************************
    '釋放分配的記憶體和關閉行程句柄
    '****************************
    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


這些代碼在普通的listview都是可以取到值的,比如任務管理器,但我那個listview資料是動態實時更新的,取出都是空值。

uj5u.com熱心網友回復:

少Lock
不行就需要用WinDbg或WinHex了。

推薦使用WinHex軟體查看硬碟或檔案或記憶體中的原始位元組內容。

uj5u.com熱心網友回復:

請將你的VB代碼改成和我的C++代碼一樣檢查每個函式的回傳值再試試。
另外有99%的可能是你得到的hWnd不是你想抓取其內容的Listview的hWnd。
參考下面代碼:
HWND MyFindListViewWindow()
{
    const int MyMaxParentWinCount = 4;
    // 父視窗類名陣列
    char *A_szClassName[MyMaxParentWinCount] = {
        "ThunderRT6FormDC",
        "ThunderRT6Frame",
        "ThunderRT6Frame",
        "ListView20WndClass"
    };
    // 父視窗標題陣列
    char *A_szWinName[MyMaxParentWinCount] = {
        Title,
        "",
        "",
        ""
    };
    // 首先求得頂級父視窗
    HWND hMainWin = FindWindow(A_szClassName[0], A_szWinName[0]);
    if (NULL==hMainWin) {
        return NULL;
    }
    // 逐次用FindWindowEx函式求出各級子視窗
    HWND hNextChildWin=NULL;

    HWND hLastWin=NULL;
    for (int i=1; i<MyMaxParentWinCount; i++) {
        if (1==i) {
            hMainWin = FindWindowEx(hMainWin,NULL         ,A_szClassName[i],A_szWinName[i]);
        } else if (2==i) {
            hNextChildWin = FindWindowEx(hMainWin,hNextChildWin,A_szClassName[i],A_szWinName[i]);
            if (NULL==hNextChildWin) break;//
            hNextChildWin = FindWindowEx(hMainWin,hNextChildWin,A_szClassName[i],A_szWinName[i]);
            hLastWin=hNextChildWin;
        } else {
            hLastWin = FindWindowEx(hLastWin,NULL         ,A_szClassName[i],A_szWinName[i]);
        }
    }
    return hLastWin;
}
//---------------------------------------------------------------------------

uj5u.com熱心網友回復:

運行spy4win,將狗頭圖示拖動到主視窗,
選“附加工具、匯出視窗資訊”保存到檔案WinInfo.txt,
看里面的“子視窗串列:……”

uj5u.com熱心網友回復:

參考 15 樓 zhao4zhong1 的回復:
運行spy4win,將狗頭圖示拖動到主視窗,
選“附加工具、匯出視窗資訊”保存到檔案WinInfo.txt,
看里面的“子視窗串列:……”


謝謝。我按照你說的,查看資訊如下

子視窗串列:
TreeView的專案數: 8
-------------------------
|-Afx:00400000:b:00010003:00000006:00010482
|---SysListView32
|-----SysHeader32
|---ToolbarWindow32
|---ToolbarWindow32
|---#32770
|-----Static
|---msctls_statusbar32

這里面就一個syslistview32, hWnd應該沒錯啊

uj5u.com熱心網友回復:

參考 15 樓 zhao4zhong1 的回復:
運行spy4win,將狗頭圖示拖動到主視窗,
選“附加工具、匯出視窗資訊”保存到檔案WinInfo.txt,
看里面的“子視窗串列:……”

參考 11 樓 Tiger_Zhao 的回復:
Quote: 參考 8 樓 wwwww112233 的回復:
此外,我查看視窗風格,也沒有出現OwnerDraw之類的字樣。

ListView 提供的 OwnerDraw 風格只是一種可選方案,不是所有的自繪一定就是通過這種風格實作的。
就像購物付款,你可以刷卡,也可以付現金,后者明顯不利于商家追蹤你的購物習慣。


我最近一直在研究這個問題,我自己用c#在寫一個別的程式,里面放了2個listview,定時向listview發送資料顯示資料,用上述的代碼以及用spy4win7仍然無法獲取值,但可以成功獲取到listview的行數列數。我也沒有用own的風格。

c#下我都是用listview1.Items.AddRange()添加資料,外部仍然無法取得這些資料。

uj5u.com熱心網友回復:

參考10樓代碼,檢查每次函式呼叫的回傳值,如果不正常,輸出錯誤碼+錯誤資訊。

uj5u.com熱心網友回復:

當前登錄用戶的權限要夠高。殺毒或防火墻軟體暫時關掉。

uj5u.com熱心網友回復:

參考 18 樓 zhao4zhong1 的回復:
參考10樓代碼,檢查每次函式呼叫的回傳值,如果不正常,輸出錯誤碼+錯誤資訊。


參考 19 樓 zhao4zhong1 的回復:
當前登錄用戶的權限要夠高。殺毒或防火墻軟體暫時關掉。



我的c#程式里,有2個listview和一個listbox ,他們都是實時重繪資料,我用spy4win7 是可以獲取到listbox的內容的,但是就是listview 取不到資料,只能取到行數列數。
謝謝,因為我對c++不熟悉,要把那段翻譯成vb還要點時間。

uj5u.com熱心網友回復:

參考 17 樓 wwwww112233 的回復:
我最近一直在研究這個問題,我自己用c#在寫一個別的程式,里面放了2個listview,定時向listview發送資料顯示資料,用上述的代碼以及用spy4win7仍然無法獲取值,但可以成功獲取到listview的行數列數。我也沒有用own的風格。

c#下我都是用listview1.Items.AddRange()添加資料,外部仍然無法取得這些資料。

用 Reflector 看 .Net 的控制元件代碼,你會發現在沒有 hWnd 的情況下依舊可以操作控制元件。
.Net 控制元件的資料、狀態都是存放在物件中的。
不要再糾結這個問題了,不支持就是不支持,除非你能讓目標程式不用 .Net 框架。

再次強調,自繪控制元件不是一定有 OwnerDraw 風格標記的。

uj5u.com熱心網友回復:

參考 21 樓 Tiger_Zhao 的回復:
Quote: 參考 17 樓 wwwww112233 的回復:
我最近一直在研究這個問題,我自己用c#在寫一個別的程式,里面放了2個listview,定時向listview發送資料顯示資料,用上述的代碼以及用spy4win7仍然無法獲取值,但可以成功獲取到listview的行數列數。我也沒有用own的風格。

c#下我都是用listview1.Items.AddRange()添加資料,外部仍然無法取得這些資料。

用 Reflector 看 .Net 的控制元件代碼,你會發現在沒有 hWnd 的情況下依舊可以操作控制元件。
.Net 控制元件的資料、狀態都是存放在物件中的。
不要再糾結這個問題了,不支持就是不支持,除非你能讓目標程式不用 .Net 框架。

再次強調,自繪控制元件不是一定有 OwnerDraw 風格標記的。


謝謝,并不是我糾結這個問題,因為現在特別特別需要那個讀取外部listview的功能,如果這個無法實作,換一個思路,會十分麻煩而且費事費力。
如你所說,意思就是c#的listview是無法從外部讀取的?
但現在目標程式換成我自己的程式,listview 和listbox 都是我自己寫的,資料也是我自己添加的。但用最前面的vb代碼,可以獲取到listbox的資料,卻無法取得listview的資料。

另外你說的自繪控制元件意思我不大明白,例如我自己的listview,我并未對控制元件重繪,只是定時對控制元件用listview1.Items.AddRange()添加資料,這個應該是c#下listview的最基本的添加資料方式,不算重繪吧。

uj5u.com熱心網友回復:

不糾纏術語了。
反正改造利用控制元件的方法眾多,想用一種方法統一取數是不可能的。

uj5u.com熱心網友回復:

參考 23 樓 Tiger_Zhao 的回復:
不糾纏術語了。
反正改造利用控制元件的方法眾多,想用一種方法統一取數是不可能的。


謝謝,我1樓的代碼是刪去listview的某一項,其實我真正需要的功能是“獲取listview的文本資料”。只是一直不成功,所以就試著增刪listview。
我不明白的是,為什么listview的文本內容已經顯示在電腦螢屏上了,應該這些內容至少在電腦記憶體上把?即便如你所說這些資料是在控制元件的物件中,那這些物件不也是在記憶體中?當然這個是我的直觀猜測。我在10樓貼的vb代碼已經是在獲取目標行程讀取記憶體資料,為什么還是空值。。。

uj5u.com熱心網友回復:

存在≠可取
隨便拉個人到你面前,你能知道他/她腦袋里在想什么?

uj5u.com熱心網友回復:

你用spy4win獲取到的內容都為空的話  hWnd的獲取方法就不是你那樣獲取的了 有遮照視窗
除非你找到他真正的視窗  用spy++看看能找到不

修改了就變了的話  當然是在時刻的讀取資料了  所以改不到

uj5u.com熱心網友回復:

參考 12 樓 wwwww112233 的回復:
我那個listview資料是動態實時更新的,取出都是空值。

資料再怎么快速更新都得讀寫記憶體不是
所以任何資料都能在記憶體查到的
查不到只能說明查的地址不對
建議用CE之類的工具來查出資料基址

uj5u.com熱心網友回復:




參考 26 樓 webyuanli 的回復:
你用spy4win獲取到的內容都為空的話  hWnd的獲取方法就不是你那樣獲取的了 有遮照視窗
除非你找到他真正的視窗  用spy++看看能找到不

修改了就變了的話  當然是在時刻的讀取資料了  所以改不到


spy4win有個功能可以把所有子視窗列出來,我前面的回帖已經貼出來了,遮照視窗就不能找到hwnd么,spy++不行啊

uj5u.com熱心網友回復:

參考 27 樓 SongPixy 的回復:
Quote: 參考 12 樓 wwwww112233 的回復:

我那個listview資料是動態實時更新的,取出都是空值。

資料再怎么快速更新都得讀寫記憶體不是
所以任何資料都能在記憶體查到的
查不到只能說明查的地址不對
建議用CE之類的工具來查出資料基址


我之所以一直研究,正是有和你一樣的想法,認為資料在記憶體里總應該讀得出來。尤其行列數已經讀出來了,其實列數不同,遠遠大于我看到的實際列數,不知道為什么。

這個問題確實太難

uj5u.com熱心網友回復:

人人實測發現,相同的代碼在WIN7中無法成功,但在win2003,XP 中OK,不知道是什么原因

uj5u.com熱心網友回復:

繼續等待高人…

uj5u.com熱心網友回復:

參考 31 樓 wwwww112233 的回復:
繼續等待高人…


哇塞,這帖子一年前的,還挖出來說呀?
我之前遇到過你這情況, 發現是作業系統的問題,就是說那代碼在32位系統下運行良好,但是在64位(Win7)下就無法獲取了。
最終找到的根源好像是OpenProcess這個API在64位系統里一直無法打開行程!

uj5u.com熱心網友回復:

是啊,如果不是實在需要這個功能,也不會挖出一年前的帖子。
我上面的程式,讀取win 7的任務管理器的listview是完全正常,但是讀到我那個listview就只能讀出行數,內容全部為空。

uj5u.com熱心網友回復:

參考 33 樓 wwwww112233 的回復:
是啊,如果不是實在需要這個功能,也不會挖出一年前的帖子。
我上面的程式,讀取win 7的任務管理器的listview是完全正常,但是讀到我那個listview就只能讀出行數,內容全部為空。


我的系統是win7x64的,用你那代碼發現WriteProcessMemory回傳0,得不到任務管理器的內容

uj5u.com熱心網友回復:

建議用“記憶體耦合”法,獲取listview中的資料。

uj5u.com熱心網友回復:

參考 35 樓 u010302092 的回復:
建議用“記憶體耦合”法,獲取listview中的資料。


謝謝,您能說的詳細點嗎?何為記憶體耦合法,我百度也沒查出來……

uj5u.com熱心網友回復:

我也不會!請參考:http://www.55188.com/thread-4154233-1-1.html

uj5u.com熱心網友回復:

這個一般的原理 是,他用LISTVIEW顯示成一個表格樣式,只是抬頭欄位是真實的文字,下面表格只是一個框線,具體的單元格內容文字,他是用TEXTOUTA這型別的API繪制上去的,為的就是防止別人把資訊提取走或盜走。建議增加HOOK,對WINDOWS API進行攔截或修改其HOOK中攔到的文字 ,原理就是金山詞霸的螢屏取詞,你能做到這個,也就能解決了

uj5u.com熱心網友回復:

還有一種可能性是,他是用GDI函式進行內部繪圖,你所看到的文字可能只是一個圖片

uj5u.com熱心網友回復:

參考 34 樓 Carlven2012 的回復:
Quote: 參考 33 樓 wwwww112233 的回復:

是啊,如果不是實在需要這個功能,也不會挖出一年前的帖子。
我上面的程式,讀取win 7的任務管理器的listview是完全正常,但是讀到我那個listview就只能讀出行數,內容全部為空。


我的系統是win7x64的,用你那代碼發現WriteProcessMemory回傳0,得不到任務管理器的內容


謝謝,我重裝了xp的32位系統,讀取別的程式的listview都挺正常的,但是我實際中需要的syslistview32 還是空值.....

uj5u.com熱心網友回復:

參考 38 樓 xiaoyao961 的回復:
這個一般的原理 是,他用LISTVIEW顯示成一個表格樣式,只是抬頭欄位是真實的文字,下面表格只是一個框線,具體的單元格內容文字,他是用TEXTOUTA這型別的API繪制上去的,為的就是防止別人把資訊提取走或盜走。建議增加HOOK,對WINDOWS API進行攔截或修改其HOOK中攔到的文字 ,原理就是金山詞霸的螢屏取詞,你能做到這個,也就能解決了


參考 39 樓 xiaoyao961 的回復:
還有一種可能性是,他是用GDI函式進行內部繪圖,你所看到的文字可能只是一個圖片



謝謝,看到的應該不是圖片。因為我用上面的代碼可以正確獲取到listview里面的行列數,但就是內容無法讀取出來。
你說的hook 螢屏取詞,假如listview很長需要下拉框,也是沒有用啊。

uj5u.com熱心網友回復:

在spy4win下查出
SysListView32的控制元件樣式是 
lvs_report

不是
lvs_ownerdrawfixed
也不是
lvs_ownerdata

uj5u.com熱心網友回復:

參考 40 樓 wwwww112233 的回復:
Quote: 參考 34 樓 Carlven2012 的回復:

Quote: 參考 33 樓 wwwww112233 的回復:

是啊,如果不是實在需要這個功能,也不會挖出一年前的帖子。
我上面的程式,讀取win 7的任務管理器的listview是完全正常,但是讀到我那個listview就只能讀出行數,內容全部為空。


我的系統是win7x64的,用你那代碼發現WriteProcessMemory回傳0,得不到任務管理器的內容


謝謝,我重裝了xp的32位系統,讀取別的程式的listview都挺正常的,但是我實際中需要的syslistview32 還是空值.....


hWnd = FindWindowEx(hWnd, 0, "SysListView32", vbNullString)
你下斷點在這兒, 跟蹤看看syslistview32 的句柄正確獲取到了嗎? 我覺得應該是這兒沒得到句柄

uj5u.com熱心網友回復:

參考 43 樓 Carlven2012 的回復:
Quote: 參考 40 樓 wwwww112233 的回復:

Quote: 參考 34 樓 Carlven2012 的回復:

Quote: 參考 33 樓 wwwww112233 的回復:

是啊,如果不是實在需要這個功能,也不會挖出一年前的帖子。
我上面的程式,讀取win 7的任務管理器的listview是完全正常,但是讀到我那個listview就只能讀出行數,內容全部為空。


我的系統是win7x64的,用你那代碼發現WriteProcessMemory回傳0,得不到任務管理器的內容


謝謝,我重裝了xp的32位系統,讀取別的程式的listview都挺正常的,但是我實際中需要的syslistview32 還是空值.....


hWnd = FindWindowEx(hWnd, 0, "SysListView32", vbNullString)
你下斷點在這兒, 跟蹤看看syslistview32 的句柄正確獲取到了嗎? 我覺得應該是這兒沒得到句柄


這里是正常取得到值的,而且我后面有
rows = ListView_GetItemRows(hwnd);//總行數,即行程的數量
cols = ListView_GetItemCols(headerhwnd);//串列列數
行列數也可以正常取到,就是里面的內容取不到。

uj5u.com熱心網友回復:

你應該用spy++抓訊息 而不是看什么屬性

uj5u.com熱心網友回復:

參考 45 樓 startbin 的回復:
你應該用spy++抓訊息 而不是看什么屬性


我是使用spy4win。
我用任務管理器測驗過,listview里可以正常獲取到內容(我用的是網上有個修復spy4win的修復版本。)
我用別的listview,包括之前說到的owner型別的listview也可以讀取到其中的內容。
但是唯獨我的目標程式讀取不到,我測驗下,可以獲取到行列,以及標題,但就是正文讀取不到。
我使用spy4win捕獲視窗訊息,類似如下,不知該怎么用?

ID       Message Name          WParam        LParam             Result        Message Type         
---------------------------------------------------------------------------------------------------
4100     WM_USER + 3076        00000000      00000000           00000000      CALLWNDPROCRET       
4100     WM_USER + 3076        00000000      00000000           00000000      GETMESSAGE           
15       WM_PAINT              00000000      00000000           00000000      CALLWNDPROCRET       
15       WM_PAINT              00000000      00000000           00000000      GETMESSAGE
4191     WM_USER + 3167        00000012      0012DD78           00000001      GETMESSAGE           
4191     WM_USER + 3167        00000013      0012DD78           00000000      CALLWNDPROCRET       
4191     WM_USER + 3167        00000013      0012DD78           00000001      GETMESSAGE           
4191     WM_USER + 3167        00000014      0012DD78           00000000      CALLWNDPROCRET       
4191     WM_USER + 3167        00000014      0012DD78           00000001      GETMESSAGE           
4155     WM_USER + 3131        00000031      0012DDE0           00000000      CALLWNDPROCRET       
4155     WM_USER + 3131        00000031      0012DDE0           00000001      GETMESSAGE           
4191     WM_USER + 3167        00000000      0012DD78           00000000      CALLWNDPROCRET 

轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/112449.html

標籤:API

上一篇:用VB對CATIA進行二次開發的一個問題

下一篇:求教!實時錯誤 -2147417848(80010108)物件‘DO’的方法 ‘IKHCard’失敗

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • Git本地庫既關聯GitHub又關聯Gitee

    創建代碼倉庫 使用gitee舉例(github和gitee差不多) 1.在gitee右上角點擊+,選擇新建倉庫 ? 2.選擇填寫倉庫資訊,然后進行創建 ? 3.服務端已經準備好了,本地開始作準備 (1)Git 全域設定 git config --global user.name "成鈺" git c ......

    uj5u.com 2020-09-10 05:04:14 more
  • CODING DevOps 代碼質量實戰系列第二課,相約周三

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。**《DevOps 代碼質量實戰(PHP 版)》**為 CODING DevOps 代碼質量實戰系列的第二課,同時也是本系列的 PHP ......

    uj5u.com 2020-09-10 05:07:43 more
  • 推薦Scrum書籍

    推薦Scrum書籍 直接上干貨,推薦書籍清單如下(推薦有順序的哦) Scrum指南 Scrum精髓 Scrum敏捷軟體開發 Scrum捷徑 硝煙中的Scrum和XP : 我們如何實施Scrum 敏捷軟體開發:Scrum實戰指南 Scrum要素 大規模Scrum:大規模敏捷組織的設計 用戶故事地圖 用 ......

    uj5u.com 2020-09-10 05:07:45 more
  • CODING DevOps 代碼質量實戰系列最后一課,周四發車

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。 **《DevOps 代碼質量實戰(Java 版)》**為 CODING DevOps 代碼質量實戰系列的最后一課,同時也是本系列的 ......

    uj5u.com 2020-09-10 05:07:52 more
  • 敏捷軟體工程實踐書籍

    Scrum轉型想要做好,第一步先了解并真正落實Scrum,那么我推薦的Scrum書籍是要看懂并實踐的。第二步是團隊的工程實踐要做扎實。 下面推薦工程實踐書單: 重構:改善既有代碼的設計 決議極限編程 : 擁抱變化 代碼整潔代碼 程式員的職業素養 修改代碼的藝術 撰寫可讀代碼的藝術 測驗驅動開發 : ......

    uj5u.com 2020-09-10 05:07:55 more
  • Jenkins+svn+nginx實作windows環境自動部署vue前端專案

    前面文章介紹了Jenkins+svn+tomcat實作自動化部署,現在終于有空抽時間出來寫下Jenkins+svn+nginx實作自動部署vue前端專案。 jenkins的安裝和配置已經在前面文章進行介紹,下面介紹實作vue前端專案需要進行的哪些額外的步驟。 注意:在安裝jenkins和nginx的 ......

    uj5u.com 2020-09-10 05:08:49 more
  • CODING DevOps 微服務專案實戰系列第一課,明天等你

    CODING DevOps 微服務專案實戰系列第一課**《DevOps 微服務專案實戰:DevOps 初體驗》**將由 CODING DevOps 開發工程師 王寬老師 向大家介紹 DevOps 的基本理念,并探討為什么現代開發活動需要 DevOps,同時將以 eShopOnContainers 項 ......

    uj5u.com 2020-09-10 05:09:14 more
  • CODING DevOps 微服務專案實戰系列第二課來啦!

    近年來,工程專案的結構越來越復雜,需要接入合適的持續集成流水線形式,才能滿足更多變的需求,那么如何優雅地使用 CI 能力提升生產效率呢?CODING DevOps 微服務專案實戰系列第二課 《DevOps 微服務專案實戰:CI 進階用法》 將由 CODING DevOps 全堆疊工程師 何晨哲老師 向 ......

    uj5u.com 2020-09-10 05:09:33 more
  • CODING DevOps 微服務專案實戰系列最后一課,周四開講!

    隨著軟體工程越來越復雜化,如何在 Kubernetes 集群進行灰度發布成為了生產部署的”必修課“,而如何實作安全可控、自動化的灰度發布也成為了持續部署重點關注的問題。CODING DevOps 微服務專案實戰系列最后一課:**《DevOps 微服務專案實戰:基于 Nginx-ingress 的自動 ......

    uj5u.com 2020-09-10 05:10:00 more
  • CODING 儀表盤功能正式推出,實作作業資料可視化!

    CODING 儀表盤功能現已正式推出!該功能旨在用一張張統計卡片的形式,統計并展示使用 CODING 中所產生的資料。這意味著無需額外的設定,就可以收集歸納寶貴的作業資料并予之量化分析。這些海量的資料皆會以圖表或串列的方式躍然紙上,方便團隊成員隨時查看各專案的進度、狀態和指標,云端協作迎來真正意義上 ......

    uj5u.com 2020-09-10 05:11:01 more
最新发布
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:41:12 more
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:35:34 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:05:44 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:00:18 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:20:31 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:55 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:18:51 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:00 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:17:55 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:12:06 more