Avatar of marcodalzotto
marcodalzottoFlag for Italy

asked on 

Get Desktop Icon Text and Position

Hi experts,
 I having some difficulties to acces to all the desktop icons info.
I've tried using a DLL, and it works fine. But I discovered a better solution by accessing to the ListCtrl memory with a OpenPocess and VirtualAllocEx functions.

The technique works for the item position, but I'm not able to get the item text.

Can some of you find a solution?

PS: I made a lot of tryings. Please try the code you are going to suggest if you are not secure.

Thanks
HANDLE hProcess = 0;
  POINT *ptVitual = 0;
  char  *ptTitle = 0;
  DWORD wndThreadID;
  DWORD pID;
  int i;
  char title[256];
 
  HWND main    = ::FindWindow("Progman", NULL);
  HWND defView = ::FindWindowEx(main, NULL, "SHELLDLL_DefView", NULL);
  HWND list    = ::FindWindowEx(defView, NULL, "SysListView32", NULL);
 
  wndThreadID = ::GetWindowThreadProcessId(list, &pID);
 
  hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, pID);
  ptTitle = (char  *)VirtualAllocEx(hProcess, NULL, 256, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
  ptVitual = (POINT *)VirtualAllocEx(hProcess, NULL, sizeof(POINT), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
 
  CListCtrl mydesktop;
  mydesktop.Attach(list);
 
  int count = mydesktop.GetItemCount();
  for(i = 0; i < count; i++) {
    // read the item position (this is working)
    mydesktop.GetItemPosition(x, ptVitual);
    ReadProcessMemory(hProcess, ptVitual, &DesktopIcon.pt, sizeof(POINT), NULL);
 
    // read the item text (not working)
    mydesktop.GetItemText(x, 0, ptTitle, 255);
    ReadProcessMemory(hProcess, ptTitle, &title, sizeof DesktopIcon.title, NULL);
 
    // here there is a break to check the title variable content
  }
  mydesktop.Detach();
 
  VirtualFreeEx(hProcess, ptTitle, 256, MEM_RELEASE);
  VirtualFreeEx(hProcess, ptVitual, sizeof(POINT), MEM_RELEASE);
  CloseHandle(hProcess);
  fclose(file);

Open in new window

System ProgrammingVisual C++.NETC++

Avatar of undefined
Last Comment
alb66
Avatar of Zoppo
Zoppo
Flag of Germany image

Hi marcodalzotto,

try to pass 'title' instead of '&title' to 'ReadProcessMemory' - a 'char title[256]' already is a pointer to a 256 byte buffer, &title is a pointer to this pointer, not to the buffer ...

If this doesn't help please show how DesktopIcon is declared.

Hope that helps,

ZOPPO
Avatar of marcodalzotto
marcodalzotto
Flag of Italy image

ASKER

Thanks ZOPPO, but it is not the solution.

You can try the code, you will see that exporer.exe crashes when the program execure mydesktop.GetItemText.
The thing is that ptPoint is red correctly.

I already tried to use SendMessage with LVM_GETITEMTEXT but doesn't return the title of the item.
typedef struct {
	char title[256];
	POINT	pt;
	RECT  rect;
} DESKTOPICON;
 
void CDskSaverDlg::OnBnClickedSave()
{
  CListCtrl mydesktop;
 
  DESKTOPICON DesktopIcon;
  HANDLE hProcess = 0;
  POINT *ptPoint = 0;
  char  *ptTitle = 0;
  DWORD wndThreadID;
  DWORD pID;
  int i, count;
 
  HWND main    = ::FindWindow("Progman", NULL);
  HWND defView = ::FindWindowEx(main, NULL, "SHELLDLL_DefView", NULL);
  HWND list    = ::FindWindowEx(defView, NULL, "SysListView32", NULL);
  wndThreadID = ::GetWindowThreadProcessId(main, &pID);
 
  // Alloc memory to the process of SysListView32 window
  hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, pID);
  ptTitle = (char  *)VirtualAllocEx(hProcess, NULL, sizeof(DesktopIcon.title), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  ptPoint = (POINT *)VirtualAllocEx(hProcess, NULL, sizeof(POINT), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 
//  FILE *file;
//	file = fopen("icone.bin", "w+");
//	if(file == NULL) ::MessageBox(main, "Impossibile aprire il file.", "DLL", MB_OK);
 
  // attach the list hwnd to the ListCtrl
  mydesktop.Attach(list);
 
  count = mydesktop.GetItemCount();
  for(i = 0; i < count; i++) {
    mydesktop.GetItemPosition(i, ptPoint);
    ReadProcessMemory(hProcess, ptPoint, &DesktopIcon.pt, sizeof(POINT), NULL);
 
    mydesktop.GetItemText(i, 0, ptTitle, sizeof(DesktopIcon.title)-1); // explorer crashes
    ReadProcessMemory(hProcess, ptTitle, DesktopIcon.title, sizeof(DesktopIcon.title), NULL);
 
//    fwrite(&DesktopIcon, sizeof(char), sizeof(DESKTOPICON), file);
  }
  mydesktop.Detach();
 
  // Free memory
  VirtualFreeEx(hProcess, ptTitle, sizeof(DesktopIcon.title), MEM_RELEASE);
  VirtualFreeEx(hProcess, ptPoint, sizeof(POINT), MEM_RELEASE);
  CloseHandle(hProcess);
//	fclose(file);
 
//	::MessageBox(main, "Icone salvate.", "DZIconSave", MB_OK);
}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Zoppo
Zoppo
Flag of Germany image

Blurred text
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
Avatar of marcodalzotto
marcodalzotto
Flag of Italy image

ASKER

Zoppo, thank you for trying. I made a similar try yesterday with the same resuts.

I made another project that use a Hook to a DLL function to achieve the same results... and i it works fine, except that I need to generate a keyboard event to the desktop so the Hook with WH_KEYBOARD can call my function. Right now to save the icons I have to focus manually the desktop and press a key.

Maybe you or somebody else can help me on that too:
https://www.experts-exchange.com/questions/23581079/Send-VK-to-desktop.html

PS: If the experts of experts-exchange cannot help me to solve this questions... I don't know who can!

marcodalzotto
Avatar of Zoppo
Zoppo
Flag of Germany image

Hi again,

sorry, no idea about the other question - maybe you should use another kind of hook, i.e. a WH_GETMESSAGE which should be called with every message that's handled by the process ...

ZOPPO
Avatar of alb66
alb66
Flag of Italy image

May be the desktop listcrl is a virtual list? In that case the icon text isn't stored in the control.
If it is the case, i think that the text should be sending an LVN_GETDISPINFO notification message to the control's parent window.
C++
C++

C++ is an intermediate-level general-purpose programming language, not to be confused with C or C#. It was developed as a set of extensions to the C programming language to improve type-safety and add support for automatic resource management, object-orientation, generic programming, and exception handling, among other features.

58K
Questions
--
Followers
--
Top Experts
Get a personalized solution from industry experts
Ask the experts
Read over 600 more reviews

TRUSTED BY

IBM logoIntel logoMicrosoft logoUbisoft logoSAP logo
Qualcomm logoCitrix Systems logoWorkday logoErnst & Young logo
High performer badgeUsers love us badge
LinkedIn logoFacebook logoX logoInstagram logoTikTok logoYouTube logo