Skip to content
Home > Programming > my paltalk list > Reply To: my paltalk list

Reply To: my paltalk list

#187437
Chike
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);
}
}
}