Enumerating desktop icons with LVM_GETITEM, what am I doing wrong???

Enumerating desktop icons with LVM_GETITEM, what am I doing wrong???

Post by Fabian_D » Mon, 09 Apr 2007 18:03:45


I'm using the function below to get the names and positions of all
desktop icons, but it's not working.

After dome digging I found out that the LVITEM structure (for GETITEM)
and POINT (for GETITEMPOSITION) have to be in shared mem, that's that
the virtual file mapping stuff is for.

But no matter what I try, it's seems friggin' impossible to get the
info I want, and it's driving me nuts :(
Any help would be MUCH appreciated!

void EnumerateDesktopIcons()
{
// get the hwnd
HWND h = FindWindowEx(NULL, NULL, "Progman", "Program Manager");
if (h) h = FindWindowEx(h, NULL, "SHELLDLL_DefView", NULL);
if (h) h = FindWindowEx(h, NULL, "SysListView32", NULL);
if (!h) return; // couldn't get the hwnd we need

// get number of icons
int numItems = SendMessage(h, LVM_GETITEMCOUNT, 0, 0);

// get some shared mem
int memSize = sizeof(LVITEM) + sizeof(TCHAR) * MAX_PATH;
HANDLE fileMap = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL,
PAGE_READWRITE, 0, memSize, NULL);
char *buf = (char*) MapViewOfFile(fileMap, FILE_MAP_ALL_ACCESS, 0,
0, 0);

for (int i=0; i<numItems; i++)
{
// define LVITEM structure in shared mem
LVITEM *iconInfo = (LVITEM*) buf;

iconInfo->mask = LVIF_TEXT;
iconInfo->iItem = i;
iconInfo->iSubItem = 0;
iconInfo->pszText = buf + sizeof(LVITEM); // we put the text
buffer after the LVITEM struct
iconInfo->cchTextMax = MAX_PATH;
int result = SendMessage(h, LVM_GETITEM, 0, (LPARAM) buf);
// result is always 0 now :(

// define POINT structure in shared mem
POINT *p = (POINT*) buf;
p->x = p->y = 0;
SendMessage(h, LVM_GETITEMPOSITION, i, (LPARAM) p);
// p contains 0,0 now :( (or whataver I initialize it with)

// show results
char bla[500];
sprintf(bla,"%d: (%d,%d) '%s'", i, p->x, p->y, iconInfo-
MessageBox(NULL,bla,"Test",0);
}
UnmapViewOfFile(buf);
CloseHandle(fileMap);
}
 
 
 

Enumerating desktop icons with LVM_GETITEM, what am I doing wrong???

Post by Fabian_D » Mon, 09 Apr 2007 18:14:12

Followup: I just realized there's something wrong with the way I put
the POINT in mem. It didn't make any difference but for the sake of
good habits, here's the correct function:


#include <commctrl.h>

void EnumerateDesktopIcons()
{
// get the hwnd
HWND h = FindWindowEx(NULL, NULL, "Progman", "Program Manager");
if (h) h = FindWindowEx(h, NULL, "SHELLDLL_DefView", NULL);
if (h) h = FindWindowEx(h, NULL, "SysListView32", NULL);
if (!h) return; // couldn't get the hwnd we need

// get number of icons
int numItems = SendMessage(h, LVM_GETITEMCOUNT, 0, 0);

// get some shared mem
int memSize = sizeof(LVITEM) + MAX_PATH + sizeof(POINT);
HANDLE fileMap = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL,
PAGE_READWRITE, 0, memSize, NULL);
char *buf = (char*) MapViewOfFile(fileMap, FILE_MAP_ALL_ACCESS, 0,
0, 0);

for (int i=0; i<numItems; i++)
{
// define LVITEM structure in shared mem
LVITEM *iconInfo = (LVITEM*) buf;

iconInfo->mask = LVIF_TEXT;
iconInfo->iItem = i;
iconInfo->iSubItem = 0;
iconInfo->pszText = buf + sizeof(LVITEM); // we put the text
buffer after the LVITEM struct
iconInfo->cchTextMax = MAX_PATH;
int result = SendMessage(h, LVM_GETITEM, 0, (LPARAM) buf);
// result is always 0 now :(

// define POINT structure in shared mem
POINT *p = (POINT*) (buf+sizeof(LVITEM)+MAX_PATH); // we put the
point after the LVITEM + text
p->x = p->y = 0;
SendMessage(h, LVM_GETITEMPOSITION, i, (LPARAM) p);
// p contains 0,0 now :( (or whataver I initialize it with)

// show results
char bla[500];
sprintf(bla,"%d: (%d,%d) '%s'", i, p->x, p->y, iconInfo-
MessageBox(NULL,bla,"Test",0);
}
UnmapViewOfFile(buf);
CloseHandle(fileMap);
}

 
 
 

Enumerating desktop icons with LVM_GETITEM, what am I doing wrong???

Post by miche » Mon, 09 Apr 2007 19:36:07


see microsoft.public.win32.programmer.ui where it's a faq
 
 
 

Enumerating desktop icons with LVM_GETITEM, what am I doing wrong???

Post by Fabian_D » Tue, 10 Apr 2007 23:28:24


I found and read several topics on this (or closely related) subject
there, yet didn't find the answer I need.

I didn't find a specific FAQ about this though. So sorry in case I
missed something, but could you please post the link you referred to?
 
 
 

Enumerating desktop icons with LVM_GETITEM, what am I doing wrong???

Post by Michael K. » Wed, 11 Apr 2007 04:49:56


I think you need VirtualAllocEx, not file mapping, to allocate the memory in
the other process.

FWIW, here is a clever utility that copies the text of another process's
controls to the clipboard. The controls that are supported are Edit
(including obscured password edits), Static, Headers, Listview, ComboBox and
ListBox. Source code (GPL'd) is included: "Control Content Saver" by
Jacquelin Potier at http://www.yqcomputer.com/