Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:

Soutěž

Sponzorem soutěže je:

IDIF

 

Kde se koná výstava fotografií Luďka Vojtěchovského?

V dnešní soutěži hrajeme o:



Ikony na ploše - nefunguje zjištění názvu

Seznam témat     Nová odpověď

Přihlásit se     Registrace     Zapomenuté heslo

Ikony na ploše - nefunguje zjištění názvu

Autor: Hols ♂

7:09:13 06.06.2012

Jelikož zmizely letošní diskuze a můj dotaz dosud nebyl zodpovězen, vkládám jej znovu z Google cache...



Vloženo uživatelem: Neregistrovaný uživatel: Hols (IP uloženo)
Datum: 23. 05. 2012 15:49

Jak se prosím zjistí jméno ikonek na ploše? Na internetu jsem našel mraky řešení, z nichž ale žádné nefunguje.

Postupnými pokusy jsem dospěl k následujícímu kódu (w3 ukazuje na ListView, pprcs je pointer na příslušný proces a mem i mem2 jsou pole alokovaná v paměti tohoto procesu - tyto proměnné jsou stoprocentně v pořádku a odladěné, neboť pomocí nich v jiné metodě úspěšně zjišťuji souřadnice ikonek):

==========

Citovat:

public String GetIconName(int iconIndex)
{
// Prepare data structure
dllUser32.LVITEM[] vItem = new dllUser32.LVITEM[1];
vItem[0].mask = dllUser32.LVIF_TEXT;
vItem[0].iItem = iconIndex;
vItem[0].iSubItem = 0;
vItem[0].cchTextMax = BUF_TXT_SIZE;
vItem[0].pszText = mem2; // This pointer may change after SendMessage call!

Int32 rd;

// Move data structure to the desktop-memory
if (!dllKernel32.WriteProcessMemory(pprcs,
mem,
Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0),
Marshal.SizeOf(typeof(dllUser32.LVITEM)),
out rd))
{
throw new Exception(Kms.Errors.MESS_ERR_WRITE_ERROR);
}

// Perform the action
if (dllUser32.SendMessage(w3,
(UInt32)dllUser32.LVM.GETITEM,
IntPtr.Zero,
mem) != IntPtr.Zero)
{
throw new Exception(Kms.Errors.MESS_ERR_READ_ERROR);
}

// Move desktop-memory back to the structure
if (!dllKernel32.ReadProcessMemory(pprcs,
mem,
Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0),
Marshal.SizeOf(typeof(dllUser32.LVITEM)),
out rd))
{
throw new Exception(Kms.Errors.MESS_ERR_READ_ERROR);
}

byte[] outBuf = new byte[BUF_TXT_SIZE];
IntPtr pOutBuf;

// Has the memory pointer changed?
if (vItem[0].pszText != mem2)
{
pOutBuf = vItem[0].pszText;
}
else
{
pOutBuf = mem2;
}

// Move data buffer to temporary array
if (!dllKernel32.ReadProcessMemory(pprcs,
pOutBuf,
Marshal.UnsafeAddrOfPinnedArrayElement(outBuf, 0),
BUF_TXT_SIZE,
out rd))
{
throw new Exception(Kms.Errors.MESS_ERR_READ_ERROR);
}

// Convert data buffer to string
String result = Encoding.Unicode.GetString(outBuf, 0, BUF_TXT_SIZE);

return (result);
}


==========

Tento kód se oproti desítkám ukázek v různých fórech liší v následujícím (nepočítám jiné názvy proměnných :-) ):

- wParam pro SendMessage je 0, protože to tak vyžaduje specifikace na stránkách Microsoftu, všechny ostatní ukázky tam mají index ikonky - kód však nefunguje ani s nulou, ani s indexem

- u výstupního bufferu testuji, zda se buffer nezměnil, což je v souladu se specifikací Microsoftu, všude jinde ve fórech se natvrdo předpokládá, že služba vyplní předem definovaný buffer, což nemusí platit vždy. Opět nefunguje ani moje verze, ani verze z diskuzí.

- já mem2 (buffer pro název) aloguji zvlášť, důvod je pouze snadnější debuggování, jiní autoři používají jediné pole (u mě mem) a text strkají za strukturu.
Na funkci by to nemělo mít vliv, každopádně nefunguje ani původní koncept s jedním polem.

- pro jistotu mám obě pole výrazně delší oproti jiným ukázkám (já 4096 bajtů, ostatní ukázky 256 nebo 512), asi je zbytečné znovu opakovat, že nefunguje ani 256, ani 512, ani 4096 buffer.


Během ladění jsem přišel na to, že po zavolání SendMessage se zcela poničí obsah bufferu mem (v jednotlivých položkách zůstanou zcela nesmyslné hodnoty). Po zkopírování zpět do struktury pak pszText obvykle ukazuje na NULL. I když se pokusím bez ohledu na strukturu a její pointer pszText přečíst jméno ikonky z mého bufferu mem2, ten není vyplněn (obsahuje samé nuly).
Též jsem testoval, zda náhodou není jméno ikonky vyplněno přímo do struktury (i když by to bylo v rozporu se specifikací, měnit se má jen několik málo položek struktury), jedná se o nesmyslný obsah, který je do mem uložen.

Co dělám špatně? Proč mi nefungují ani původní ukázky kódu?

Možnosti: Odpovědět•Citovat příspěvek•Nahlásit moderátorům
Re: Ikony na ploše - nefunguje zjištění názvu
Vloženo uživatelem: Kra - uživatel již zaslal 168 příspěvků (IP uloženo)
Datum: 25. 05. 2012 20:37

Nevím přesně na co se ptáš. Nevím o tom, že by ikonky měly jména. Jestli ti jde o to, jak se jmenují zástupci na ploše, tak to jsou normální soubory *.lnk, které si stačí vylistovat ze složky Plocha.

Možnosti: Odpovědět•Citovat příspěvek•Nahlásit moderátorům
Re: Ikony na ploše - nefunguje zjištění názvu
Vloženo uživatelem: Neregistrovaný uživatel: Hols (IP uloženo)
Datum: 28. 05. 2012 07:37

Ano, ptám se na jména zástupců na ploše. Mohu projít adresář "Desktop", ale v tom případě mám dva další dotazy:

1) kde jsou ikonky, které v adresářích Desktop chybí? Ve svém profilu mám 52 ikonek, dalších 14 je v profilu All users. Na ploše však mám 72 ikonek. Kde jsou zbylé? (Např. Tento počítač, Okolní počítače, atd.)? Pro mé účely potřebuji zpracovat úplně všechny ikonky.

2) jak k souboru .lnk přiřadit položku z ListView? Účel, proč chci zjišťovat název ikonky (neboli popis, co se zobrazuje na ploše), je ten, že potřebuji u ikonek uložit a později obnovit jejich souřadnice a potřebuji je správně identifikovat (index pro ListView se může změnit, proto ho nemůžu pro identifikaci delší než jednorázovou manipulaci použít). Manipulace se souřadnicemi se dělá (viz o něco starší diskuze) právě přes ListView. V souborech .lnk s největší pravděpodobností souřadnice uložené nejsou, a i kdyby byly, tak na ploše mohou ležet kromě .lnk souborů také jakékoliv binárky, v nichž souřadnice ikonek už nejsou stoprocentně.

Citovat příspěvek

 

 

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: