2014-04-30 611 views
0

我正在製作一個程序(program1),它將讀取位於另一個程序中的報告樣式列表(SysListView32)中的標題列(SysHeader32)的名稱(程序2)。在另一個進程中從SysHeader32控件獲取列名

所以基本上我希望我的程序進入另一個程序,並閱讀我找到的所有頭文件(SysHeader32)的標題名稱。由於程序對每個列表都有很多不同的列表和標題,因此我決定使用EnumChildWindows函數和EnumChildProc回調函數來查看子窗口的所有句柄。使用這些句柄,我使用GetClassName()來查看類名是什麼,當我看到它是一個SysHeader32時,我知道我找到了一個包含各種標題名稱的標頭......但我不知道我可以使用哪些代碼來獲取從這些各種各樣的標題文字,我也不知道如何識別每個標題...

這裏是我的代碼到目前爲止是會發現找到的每個SysHeader32頭手柄:

BOOL CALLBACK EnumChildProc (HWND hWnd, LPARAM lParam) 
{ 
    char myBuffer [100];//buffer that will get the class name 
    GetClassName(hWnd, myBuffer, 100); 
    string myString (myBuffer);//converting myBuffer into a readable string 

    if (myString == "SysHeader32") 
    { 
    ///here is where I am currently lost 
    ///I just don't know how to get the text from the different titles/items 
    ///in the header found 
    } 
} 

問題1 ::如何檢查標題中有多少個不同的標題/項目?

問題2 ::如何獲取標題中找到的每個標題/項目的文本?

請提供一些示例代碼。

回答

0

不幸的是,訪問由另一個程序創建的窗口時,這是不容易的,因爲系統沒有對指針進行必要的窗口消息編組。您需要從共享的DLL文件(創建一些系統範圍的Windows Hook來將其加載到其他進程中)或使用其他黑客(如進程內存訪問)來完成此操作。


如果在同一個程序訪問SysHeader32窗口,這將是這樣簡單:

  1. 發送消息HDM_GETITEMCOUNT,它返回的項目數。

  2. 發送消息HDM_GETITEMwParam集到的項的索引來檢索和lParam集合的指針適當地設定HDITEM結構。特別設置maskHDI_TEXT併爲pszText準備緩衝區,並將其長度設置爲cchTextMax

例子:

int count = SendMessage(hWnd, HDM_GETITEMCOUNT, 0, 0); 
std::cout << "There are " << count << " items.\n"; 

for (int i = 0; i < count; i++) { 
    TCHAR name[260]; 
    HDITEM hdi; 
    hdi.mask = HDI_TEXT; 
    hdi.pszText = name; 
    hdi.cchTextMax = 260; 
    SendMessage(hWnd, HDM_GETITEM, i, reinterpret_cast<LPARAM>(&hdi)); 
    std::cout << " " << i << ") " << hdi.pszText << "\n"; 
} 

因爲我們需要存儲在另一個程序的空間輸入和輸出內存,這樣的事情是必要的(請根據自己的喜好添加錯誤檢查等。 ):

struct InterProcessData { 
    HDITEM hdi; 
    TCHAR buffer[260]; 
}; 

// Open the owning process and allocate a buffer big enough for 
// our inter-process communication 
DWORD dwProcessId; 
GetWindowThreadProcessId(hWnd, &dwProcessId); 
HANDLE hProcess = OpenProcess(
    PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, 
    FALSE, dwProcessId); 
InterProcessData* pRemoteData = reinterpret_cast<InterProcessData*>(
    VirtualAllocEx(hProcess, NULL, sizeof(InterProcessData), MEM_COMMIT, PAGE_READWRITE)); 

int count = SendMessage(hWnd, HDM_GETITEMCOUNT, 0, 0); 
std::cout << "There are " << count << " items.\n"; 

for (int i = 0; i < count; i++) { 
    InterProcessData data; 
    data.hdi.mask = HDI_TEXT; 
    data.hdi.pszText = pRemoteData->buffer; 
    data.hdi.cchTextMax = 260; 

    // Write the HDITEM structure to the space in the remote process 
    // (without the buffer, its contents are undefined anyway) 
    WriteProcessMemory(hProcess, pRemoteData, &data, sizeof(data.hdi), NULL); 

    // Send the message itself, passing the remote address in lParam 
    SendMessage(hWnd, HDM_GETITEM, i, reinterpret_cast<LPARAM>(&pRemoteData->hdi)); 

    // Read the data back, HDITEM and the buffer 
    ReadProcessMemory(hProcess, pRemoteData, &data, sizeof(data), NULL); 

    // The documentation says that the pszText can point elsewhere - 
    // copy it to our buffer in that case 
    if (data.hdi.pszText != pRemoteData->buffer) 
    ReadProcessMemory(hProcess, data.hdi.pszText, data.buffer, data.hdi.cchTextMax * sizeof(TCHAR), NULL); 

    std::cout << " " << i << ") " << data.buffer << "\n"; 
} 

// Cleanup 
VirtualFreeEx(hProcess, pRemoteData, 0, MEM_RELEASE); 
CloseHandle(hProcess); 
+0

當我使用代碼時,它編譯完美,但是當我運行該程序並且它搜索program2的項目時,它發現#項目(15),但是當它啓動SendMessage()以獲取項目文本時,program2關閉,並開始輸出類似於(pisymbole)TTw%的所有15個項目...任何想法爲什麼會發生這種情況? – computerWizard

+0

好的謝謝所有的信息兄弟。我確實調試過程序完全存在於代碼:SendMessage(hWnd,HDM_GETITEM,i,reinterpret_cast (&hdi));)。我猜測出於某種原因,msg發送給program2,導致program2中出現某種錯誤。想法? – computerWizard

+0

讓我們[在聊天中繼續討論](http://chat.stackoverflow.com/rooms/51761/discussion-between-yirkha-and-computerwizard) – Yirkha