March 8, 2009 at 8:23 pm
#187437
Member
This is an update to the code I have posted in this C++ example.
It uses messages instead of the macros (that are commented out.)
#include #include #include #include void GetTVItem(HWND hwnd, HTREEITEM htvitem, char *buff, int buff_len); int main(int argc, char *argv[]) { HWND seinfeldsuperman, wtlsplitterwindow, atla, gradienttreeviewclass; seinfeldsuperman = FindWindow("seinfeld_superman", NULL); wtlsplitterwindow = FindWindowEx(seinfeldsuperman, 0, "wtl_splitterwindow", NULL); // Paltalk 9.5 atla = FindWindowEx(wtlsplitterwindow, 0, "ATL:0080DAA8", NULL); if (atla == NULL) // Paltalk 9.1 atla = FindWindowEx(wtlsplitterwindow, 0, "atl:006d06d0", NULL); if (atla == NULL) /// Paltalk Scene atla = FindWindowEx(wtlsplitterwindow, 0, "ATL:006FBF78", NULL); if (atla == NULL) // Paltalk 8.5 atla = FindWindowEx(wtlsplitterwindow, 0, "ATL:00547638", NULL); gradienttreeviewclass = FindWindowEx(atla, 0, "gradienttreeviewclass", NULL); /// get root item (Pals, Offline, and custome groups) HTREEITEM htvitem = (HTREEITEM) //TreeView_GetRoot(gradienttreeviewclass); SendMessage(gradienttreeviewclass, TVM_GETNEXTITEM, TVGN_ROOT, NULL); char text[256]; while (htvitem) { GetTVItem(gradienttreeviewclass, htvitem, text, 256); // un-comment the '|| true' to see onffine too if (_strnicmp("offline", text, 7) /*|| true*/) { printf("%sn", text); // get 1st buddy in this group HTREEITEM htvsubitem = (HTREEITEM) //TreeView_GetChild(gradienttreeviewclass, htvitem); SendMessage(gradienttreeviewclass, TVM_GETNEXTITEM, TVGN_CHILD, PtrToLong(htvitem)); while (htvsubitem) { GetTVItem(gradienttreeviewclass, htvsubitem, text, 256); printf(" %sn", text); // get next buddy htvsubitem = (HTREEITEM) //TreeView_GetNextSibling(gradienttreeviewclass, htvitem1); SendMessage(gradienttreeviewclass, TVM_GETNEXTITEM, TVGN_NEXT, PtrToLong(htvsubitem)); } } // get next group htvitem = (HTREEITEM)//TreeView_GetNextSibling (gradienttreeviewclass, htvitem); SendMessage(gradienttreeviewclass, TVM_GETNEXTITEM, TVGN_NEXT, PtrToLong(htvitem)); } system("PAUSE"); return EXIT_SUCCESS; } void GetTVItem(HWND hwnd, HTREEITEM htvitem, char *buff, int buff_len) { DWORD lProcID; // Get the process ID in which the TreeView is running GetWindowThreadProcessId(hwnd, &lProcID); if (lProcID != 0) { // make sure we have read write permissions in the process space HANDLE hProc = OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, FALSE, lProcID); if (hProc != 0) { // Grab enough memory in the other procedure's space to hold our TVITEM and the return text buffer void *xtvitem = VirtualAllocEx(hProc, 0, sizeof(TVITEM)+buff_len, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE); // Set up our local TVITEM TVITEM tv_item; tv_item.mask = TVIF_TEXT; tv_item.hItem = htvitem; tv_item.pszText = static_cast(xtvitem)+sizeof(TVITEM); tv_item.cchTextMax = buff_len; // Copy the local TVITEM into the space we reserved in the foreign process WriteProcessMemory(hProc, xtvitem, &tv_item, sizeof(TVITEM), NULL); // Now send the message, but pass the address of the copy of our TVITEM that now exists in the foreign process instead of our local versiony BOOL res = (BOOL) //TreeView_GetItem(hwnd, xtvitem); SendMessage(hwnd, TVM_GETITEM, 0, PtrToLong(xtvitem)); if (res) { // the return text buffer (address) may have changed so we need to copy it back ReadProcessMemory(hProc, xtvitem, &tv_item, sizeof(TVITEM), NULL); // Since we have no clue about it's length we have to copy it all ReadProcessMemory(hProc, tv_item.pszText, buff, buff_len, NULL); // Note: last line is a bit risky if buffer was actually changed // Because we could cross page boundary and hit a non-alloocated // page. } else { *buff = ''; } // Clean up VirtualFreeEx(hProc, xtvitem, 0, MEM_RELEASE); CloseHandle(hProc); } } }