Reply To: my paltalk list


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.)


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));
void GetTVItem(HWND hwnd, HTREEITEM htvitem, char *buff, int buff_len)
// 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
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);