[C#] positie desktop icons en shared memory

Pagina: 1
Acties:

  • TangLeFuzZ
  • Registratie: Juni 2001
  • Laatst online: 15-10-2025
Hey,

Ik kwam vanmiddag het volgende artikel tegen:
http://www.codeguru.com/Cpp/misc/misc/article.php/c3807

Op die pagina staat uitgelegd wat je moet doen om de positie van je desktop icons wilt achterhalen.
Dit heb ik nodig voor een eigen programma, dus ik ben bezig gegaan het te bouwen in C# (het voorbeeld is in C++).

Het is me gelukt tot en met het achterhalen van het aantal icons op de desktop. Hierna is het de bedoeling om per icon de positie binnen te halen, maar dit schijnt niet zomaar te kunnen:
I did all of this, but the POINT structure never got filled. A very strange problem, indeed. The function returns TRUE, indicating success, but I get no info. After some thinking about the problem, it occurred to me. I'm sending the pointer to a place in the memory of my process, to another process. That pointer is not valid because each process has its own memory space. In other words, the pointer I send to the ListView isn't valid in its address space. So, now I need to have a pointer that is valid in the process space of the ListView, but I need to read it as well. So it's gonna need to be valid in both processes. To do this, you need to create shared memory.
In het voorbeeld gaat de auteur niet bezig met shared memory, dat leek hem te moeilijk. Hij doet het met VirtualAllocEx().

Dit laatste heb ik nog niet geprobeerd, want ik wil eigenlijk eerst aan de slag met shared memory, aangezien de VirtualAllocEx() oplossing alleen werkt op windows NT/XP bakken.

Als ik google naar shared memory kom ik wel van alles tegen, maar het is me nog steeds niet duidelijk, en al helemaal niet de manier waarop ik het zou kunnen toepassen om toch de positie van de icoontjes te kunnen achterhalen.

Heeft iemand hier ervaring mee, of heeft iemand een idee wat ik zou moeten doen?

  • TangLeFuzZ
  • Registratie: Juni 2001
  • Laatst online: 15-10-2025
Ik zal nog even een voorbeeld van mijn eigen code posten, misschien dat het dan duidelijker is.

Om de icon info binnen te halen heb ik (zoals in de uitleg op bovenstaande site vermeld staat) FindWindow en FindWindowEx uit de Kernell32 gebruikt:

C:
1
2
3
4
5
6
7
8
9
10
11
12
// Program Manager opzoeken
IntPtr iHandleProgMan = FindWindow(null, "Program Manager");

// SHELLDLL_DefView opzoeken
IntPtr iHandleShellDef = FindWindowEx(iHandleProgMan, IntPtr.Zero, "SHELLDLL_DefView", IntPtr.Zero);

// SysListView32 opzoeken
IntPtr iHandleSysList = FindWindowEx(iHandleShellDef, IntPtr.Zero, "SysListView32", IntPtr.Zero);

// aantal icons pakken
IntPtr tmpPointer = (IntPtr) 0;
int iIconsAmount = SendMessage(iHandleSysList, LVM_GETITEMCOUNT, 0, tmpPointer);


(let niet op die lelijke tmpPointer aub :D)

Na het uitvoeren van bovenstaande code zit de pointer naar de listview van de desktop in iHandleSysList en het aantal icons in iIconsAmount.

Je zou nu dus alle icons kunnen doorlopen en met het SendMessage commando een positie van elk icon opvragen, maar zoals ik al zei werkt dit dus niet goed zonder memory mapped te werken.

Memory Mapped

Ik kwam ergens een VB script tegen waarin de auteur een memory mapped file aanmaakt en daarna met behulp van movememory de x en y waardes van elk icon binnenhaalt.

Het stukje dat nuttig was voor mijn code heb ik omgezet naar c#:

C:
1
2
3
4
5
6
7
8
9
10
11
12
// memory-mapped file aanmaken
string sFileName = "tmpData.dat";

// file openen
IntPtr hFile = CreateFile(sFileName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);

// handle van memory map ophalen
IntPtr tmpPointer2 = (IntPtr) 0;
IntPtr hFileMap = CreateFileMapping(hFile, tmpPointer2, PageProtection.ReadWrite, 0, 16, "MyMapping");

// pointer ophalen van geheugenadres van de memory mapped file
IntPtr pFileMap = MapViewOfFile(hFileMap, FileMapEnum.FILE_MAP_WRITE, 0, 0, 0);


Nu loop ik alle icons door, en probeer ik met behulp van die memory mapped file handle, de positie op te vragen (de auteur van het vb scriptje deed het ook op deze manier):

C:
1
2
3
4
5
6
7
8
9
10
11
12
// alle icons doorlopen
for (int i = 0; i < iIconsAmount; i++)
{
    Point pIconPoint = new Point();

    SendMessage(iHandleSysList, LVM_GETITEMPOSITION, i, pFileMap);

    MoveMemory(ref pIconPoint, ref pFileMap, 8);

    // debug
    MessageBox.Show("x:" + pIconPoint.X + " y: " + pIconPoint.Y);
}


Ik krijg nu ineens wel iets terug, in tegenstelling tot eerst, maar het zijn nogal rare waardes en ze zijn voor elk icon gelijk, dus er gaat nog iets goed mis... ik heb alleen geen flauw idee wat.

De waardes die ik op dit moment terug krijg zijn:

x:18022400
y: 372

Ziet iemand misschien iets in die getallen?

  • NLChris
  • Registratie: Juli 2004
  • Laatst online: 06-04 13:34
Ik heb geen flauw idee maar bij de reacties op jou link staat dit:
(http://www.codeguru.com/c...s.php/c3807/?thread=47376)
Nice article :) I thought I'd add to it by indicating that
memory-mapped files are a good way to "share" memory
between processes on 9x boxes.

Here's a quick example of a function related to the
article, which removes the desktop icon's text, so that
they're left with just the icons themselves:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
void HideDTopIconText()
{
  HWND hWnd = FindDTopLView();
  if( hWnd ) {
    int nItems = ListView_GetItemCount(hWnd);
    if( nItems > 0 ) {
      char szText[40];
      HANDLE hFileMap =
        CreateFileMapping((HANDLE)0xFFFFFFFF, NULL,
          PAGE_READWRITE, 0, max(sizeof(szText), sizeof
          (LVITEM)), "MyMapping");
      if( hFileMap ) {
        LPVOID pFileMap = MapViewOfFile(hFileMap,
                            FILE_MAP_WRITE, 0, 0, 0);
        if( pFileMap ) {
          for( int i = 0; i < nItems; i++ ) {
            LVITEM *plvItem = (LVITEM *)pFileMap;
            ZeroMemory(plvItem, sizeof(LVITEM));
            plvItem->mask       = LVIF_TEXT;
            plvItem->iItem      = i;
            plvItem->pszText    = (char *)pFileMap;
            plvItem->cchTextMax = sizeof(szText);
            int nChars = SendMessage(hWnd, LVM_GETITEMTEXT,
                           (WPARAM)i, (LPARAM)pFileMap);
            if( nChars ) {
              CopyMemory(szText, pFileMap, nChars+1);
              ZeroMemory(plvItem, sizeof(LVITEM));
              plvItem->mask  = LVIF_TEXT;
              plvItem->iItem = i;
              SendMessage(hWnd, LVM_SETITEMTEXT, (WPARAM)i,
                         (LPARAM)pFileMap);
            }
          }
          UnmapViewOfFile(pFileMap);
        }
        CloseHandle(hFileMap);
      }
    }
  }
}


EDIT:
TangLeFuzZ schreef op woensdag 22 februari 2006 @ 22:50:
Ah mooi, ik wist niet eens dat er reacties bij die artikelen stonden... (wie zet die dan ook op een andere pagina :X )

Misschien zit er wat tussen, zal het 's uitzoeken...

Edit; ik hoop trouwens dat iemand die x en y waardes herkent, ik ben erg benieuwd waar die getallen vandaan komen, als ik dat zou weten dan weet ik of ik uberhaupt in de buurt zit / waar het mis gaat :)
offtopic:
Ze staan wel op dezelfde pagina helemaal onderaan op jou link :Y)

[ Voor 16% gewijzigd door NLChris op 23-02-2006 13:42 ]


  • TangLeFuzZ
  • Registratie: Juni 2001
  • Laatst online: 15-10-2025
Ah mooi, ik wist niet eens dat er reacties bij die artikelen stonden... (wie zet die dan ook op een andere pagina :X )

Misschien zit er wat tussen, zal het 's uitzoeken...

Edit; ik hoop trouwens dat iemand die x en y waardes herkent, ik ben erg benieuwd waar die getallen vandaan komen, als ik dat zou weten dan weet ik of ik uberhaupt in de buurt zit / waar het mis gaat :)

[ Voor 38% gewijzigd door TangLeFuzZ op 22-02-2006 22:55 ]