Megosztás a következőn keresztül:


Shell-adatátviteli forgatókönyvek kezelése

A Shell-adatobjektum dokumentum a Shell-adatok húzással vagy vágólapon történő átvitelére használt általános megközelítést ismerteti. A Shell-adatátvitel alkalmazásbeli implementálásához azonban tisztában kell lennie azzal is, hogyan alkalmazhatja ezeket az általános elveket és technikákat a Shell-adatok átvitelének különböző módjaira. Ez a dokumentum bemutatja a Shell gyakori adatátviteli forgatókönyveit, és ismerteti, hogyan implementálhatja az egyeseket az alkalmazásban.

Jegyzet

Bár ezek a forgatókönyvek egy adott adatátviteli műveletet tárgyalnak, ezek közül sok különböző kapcsolódó forgatókönyvre vonatkozik. A vágólap és a húzással végzett átvitelek között például az elsődleges különbség az, hogy az adatobjektum hogyan érkezik a célhoz. Miután a cél mutatóval rendelkezik az adatobjektum IDataObject felületére, az adatok kinyerésének eljárásai nagyrészt megegyeznek mindkét adatátviteli típus esetében. A forgatókönyvek némelyike azonban egy adott művelettípusra korlátozódik. Részletekért tekintse meg az egyes forgatókönyveket.

 

Általános irányelvek

A következő szakaszok mindegyike egyetlen, meglehetősen specifikus adatátviteli forgatókönyvet tárgyal. Az adatátvitel azonban gyakran összetettebb, és több forgatókönyv aspektusait is érintheti. Általában nem tudja előre, hogy melyik forgatókönyvet kell kezelnie. Íme néhány általános irányelv, amelyeket szem előtt kell tartani.

Adatforrások esetén:

  • A Rendszerhéj vágólap formátumai a CF_HDROPkivételével nincsenek előre definiálva. Minden használni kívánt formátumot regisztrálni kell RegisterClipboardFormatmeghívásával.
  • Az adatobjektumok formátumai a forrástól származó beállítások sorrendjében vannak megadva. Számba veheti az adatobjektumot, és kiválaszthatja az első használható objektumot.
  • Adjon meg annyi formátumot, amennyit csak tud. Általában nem tudja, hogy hová kerül az adatobjektum. Ez a gyakorlat növeli annak esélyét, hogy az adatobjektum olyan formátumot tartalmazzon, amelyet a cél elfogadhat.
  • A meglévő fájlokat CF_HDROP formátumban kell felajánlani.
  • Fájlszerű adatokat kínál CFSTR_FILECONTENTS/CFSTR_FILEDESCRIPTOR formátumokkal. Ez a megközelítés lehetővé teszi a cél számára, hogy egy adatobjektumból hozzon létre egy fájlt anélkül, hogy bármit is tudnia kellene az alapul szolgáló adattárról. Az adatokat általában IStream felületként kell bemutatnia. Ez az adatátviteli mechanizmus rugalmasabb, mint egy globális memóriaobjektum, és sokkal kevesebb memóriát használ.
  • Az húzási forrásoknak CFSTR_SHELLIDLIST formátumot kell biztosítaniuk a Shell-elemek húzásakor. Az elemek adatobjektumai az IShellFolder::GetUIObjectOf vagy IShellItem::BindToHandler metódusokkal szerezhetők be. Az adatforrások olyan szabványos adatobjektum-implementációt hozhatnak létre, amely támogatja a CFSTR_SHELLIDLIST formátumot SHCreateDataObjecthasználatával.
  • A célhelyek, amelyek a húzott elemeket szeretnék megérteni a rendszerhéjelem-programozási modell használatával, átalakíthatják az IDataObject-et IShellItemArraySHCreateShellItemArrayFromDataObjectsegítségével.
  • Használjon szabványos visszajelzési kurzorokat.
  • Támogatja a balra és jobbra húzást.
  • Használja magát az adatobjektumot egy beágyazott objektumból. Ez a módszer lehetővé teszi, hogy az alkalmazás lekérje az adatobjektum által kínált további formátumokat, és ne hozzon létre további elszigetelési réteget. Az A kiszolgálóról származó beágyazott objektumot például a rendszer a B kiszolgálóról vagy a B tárolóból húzza, és a C tárolóba vonta. A C tárolóban létre kell hoznia az A kiszolgáló beágyazott objektumát, nem pedig a B kiszolgáló beágyazott objektumát, amely az A kiszolgáló beágyazott objektumát tartalmazza.
  • Ne feledje, hogy a Shell optimalizált áthelyezési vagy beillesztés utáni törlési műveleteket használhat a fájlok áthelyezésekor. Az alkalmazásnak képesnek kell lennie felismerni ezeket a műveleteket, és megfelelően kell válaszolnia.

Adatcélok esetén:

  • A Shell vágólap formátumai a CF_HDROPkivételével nincsenek előre definiálva. Minden használni kívánt formátumot regisztrálni kell RegisterClipboardFormatmeghívásával.
  • Hajtsa végre és regisztrálja az OLE ejtési célpontot. Ha lehetséges, kerülje a Windows 3.1 célpontok vagy a WM_DROPFILES üzenet használatát.
  • Az adatobjektumok formátuma attól függően változik, hogy honnan származik az objektum. Mivel általában nem tudja előre, hogy honnan származik egy adatobjektum, ne feltételezze, hogy egy adott formátum jelen lesz. Az adatobjektumnak minőségi sorrendben kell számbavétele a formátumokat, a legjobbtól kezdve. Így a legjobb elérhető formátum eléréséhez az alkalmazások általában számba fogják a rendelkezésre álló formátumokat, és az első formátumot használják az enumerálásban, amelyet támogathatnak.
  • Támogatja a jobb gombbal történő húzást. A húzási helyi menüt testre szabhatja egy húzási kezelőlétrehozásával.
  • Ha az alkalmazás elfogadja a meglévő fájlokat, képesnek kell lennie a CF_HDROP formátum kezelésére.
  • Általában a fájlokat elfogadó alkalmazásoknak is kezelnie kell a CFSTR_FILECONTENTS/CFSTR_FILEDESCRIPTOR formátumokat. Bár a fájlrendszerből származó fájlok formátuma CF_HDROP, az olyan szolgáltatóktól, mint például a névtérbővítmények, származó fájlok általában CFSTR_FILECONTENTS/CFSTR_FILEDESCRIPTOR. Ilyenek például a Windows CE-mappák, az FTP-mappák, a webmappák és a CAB-mappák. A forrás általában egy IStream felületet implementál a tárolóból származó adatok fájlként való bemutatásához.
  • Ne feledje, hogy a Rendszerhéj optimalizált áthelyezési vagy törlési műveleteket használhat a fájlok áthelyezésekor. Az alkalmazásnak képesnek kell lennie felismerni ezeket a műveleteket, és megfelelően kell válaszolnia.

Fájlnevek másolása a vágólapról egy alkalmazásba

forgatókönyv: A felhasználó kiválaszt egy vagy több fájlt a Windows Intézőben, és átmásolja őket a vágólapra. Az alkalmazás kinyeri a fájlneveket, és beilleszti őket a dokumentumba.

Ez a forgatókönyv például arra használható, hogy a felhasználó HTML-hivatkozást hozzon létre a fájl kivágásával és az alkalmazásba való beillesztésével. Az alkalmazás ezután kinyerheti a fájlnevet az adatobjektumból, és feldolgozhatja egy horgonycímke létrehozásához.

Amikor egy felhasználó kiválaszt egy fájlt a Windows Intézőben, és átmásolja a vágólapra, a Rendszerhéj létrehoz egy adatobjektumot. Ezután meghívja OleSetClipboard, hogy mutasson az adatobjektum IDataObject felületére a vágólapon.

Amikor a felhasználó kiválasztja a Beillesztés parancsot az alkalmazás menüjéből vagy eszköztárából:

  1. Hívja meg OleGetClipboard az adatobjektum IDataObject felületének lekéréséhez.
  2. Hívja meg IDataObject::EnumFormatEtc enumerátorobjektum kéréséhez.
  3. Az enumerátorobjektum IEnumFORMATETC felületével számbavételt alkalmazhat az adatobjektum által tartalmazott formátumok számbavételéhez.

Jegyzet

Az eljárás utolsó két lépése a teljesség érdekében szerepel. Ezek általában nem szükségesek az egyszerű fájlátvitelekhez. Az ilyen típusú adatátvitelhez használt összes adatobjektumnak tartalmaznia kell a CF_HDROP formátumot, amely az objektum által tárolt fájlok nevének meghatározására használható. Az általánosabb adatátvitelhez azonban számba kell adnia a formátumokat, és ki kell választania az alkalmazás által kezelhető legjobbat.

 

A fájlnevek kinyerése az adatobjektumból

A következő lépés egy vagy több fájlnév kinyerése az adatobjektumból, majd beillesztése az alkalmazásba. Vegye figyelembe, hogy az ebben a szakaszban ismertetett eljárás, amely egy fájlnév adatobjektumból való kinyerésére vonatkozik, ugyanolyan jól alkalmazható az áthúzásos átvitelekre.

A fájlnevek adatobjektumból való lekérésének legegyszerűbb módja a CF_HDROP formátum:

  1. Hívás IDataObject::GetData. Állítsa a FORMATETC struktúrájának cfFormat tagját CF_HDROP, a tagot pedig TYMED_HGLOBAL. A dwAspect tag általában a DVASPECT_CONTENT beállításra van konfigurálva. Ha azonban rövid (8.3) formátumban kell megadnia a fájl elérési útját, állítsa dwAspect DVASPECT_SHORT értékre.

    Amikor IDataObject::GetData ad vissza, a STGMEDIUM struktúrájának hGlobal tagja az adatokat tartalmazó globális memóriaobjektumra mutat.

  2. Hozzon létre egy HDROP-változót, és állítsa be a STGMEDIUM struktúrájának hGlobal tagjára. A HDROP változó mostantól egy DROPFILES szerkezet leírója, amelyet a másolt fájlok teljes mértékben megadott fájlelérési útvonalait tartalmazó dupla nullával lezárt sztring követ.

  3. A DragQueryFile meghívásával, az iFile paramétert 0xFFFFFFFF értékre állítva, meghatározhatja, hogy hány fájlútvonal szerepel a listában. A függvény a listában szereplő fájlelérési utak számát adja vissza. A fájl elérési útjának nulla alapú indexe a listában a következő lépésben egy adott elérési út azonosítására szolgál.

  4. Nyissa ki a fájlok elérési útvonalait a globális memóriaobjektumból úgy, hogy minden fájlhoz egyszer meghívja a DragQueryFile függvényt, és a iFile a fájl indexére van állítva.

  5. Szükség szerint dolgozza fel a fájl elérési útját, és illessze be őket az alkalmazásba.

  6. Hívja meg ReleaseStgMedium, és adja meg az egérmutatót az STGMEDIUM struktúrának, amelyet IDataObject::GetData az 1. lépésben adott át. Miután kiadta a struktúrát, a 2. lépésben létrehozott HDROP-érték már nem érvényes, ezért nem használható.

Elvetett fájl tartalmának másolása egy alkalmazásba

forgatókönyv: Egy felhasználó húz egy vagy több fájlt a Windows Intézőből, és az alkalmazás ablakára dobja őket. Az alkalmazás kinyeri a fájl (ok) tartalmát, és beilleszti az alkalmazásba.

Ez a forgatókönyv húzással továbbítja a fájlokat a Windows Intézőből az alkalmazásba. A művelet előtt az alkalmazásnak a következőnek kell lennie:

  1. Hívja meg RegisterClipboardFormat a szükséges Shell-vágólapformátumok regisztrálásához.
  2. A RegisterDragDrop hívásával regisztrálhat egy célablakot és az alkalmazás IDropTarget felületét.

Miután a felhasználó elindította a műveletet, válasszon ki egy vagy több fájlt, és kezdje el húzni őket:

  1. A Windows Explorer létrehoz egy adatobjektumot, és betölti a támogatott formátumokat.
  2. A Windows Intéző meghívja a DoDragDrop -t a húzási ciklus elindítására.
  3. Amikor a húzási kép eléri a célablakot, a rendszer értesíti Önt IDropTarget::D ragEntermeghívásával.
  4. Az adatobjektum tartalma meghatározásához hívja meg az adatobjektum IDataObject::EnumFormatEtc metódust. A metódus által visszaadott enumerátor objektummal számba lehet adni az adatobjektum formátumát. Ha az alkalmazás nem szeretné elfogadni ezeket a formátumokat, adja vissza DROPEFFECT_NONE. Ebben a forgatókönyvben az alkalmazásnak figyelmen kívül kell hagynia minden olyan adatobjektumot, amely nem tartalmaz fájlátvitelhez használt formátumokat, például CF_HDROP.
  5. Amikor a felhasználó eldobja az adatokat, a rendszer meghívja IDropTarget::Drop.
  6. A fájlok tartalmának kinyeréséhez használja az IDataObject felületet.

Egy Shell-objektum tartalmát többféleképpen is kinyerheti egy adatobjektumból. Általában használja a következő sorrendet:

  • Ha a fájl CF_TEXT formátumot tartalmaz, az adatok ANSI-szövegek. A CF_TEXT formátummal kinyerheti az adatokat a fájl megnyitása helyett.
  • Ha a fájl csatolt vagy beágyazott OLE-objektumot tartalmaz, az adatobjektum CF_EMBEDDEDOBJECT formátumot tartalmaz. Az adatok kinyeréséhez használjon standard OLE-technikákat. fájlok mindig CF_EMBEDDEDOBJECT formátumot tartalmaznak.
  • Ha a Shell-objektum a fájlrendszerből származik, az adatobjektum CF_HDROP formátumot tartalmaz a fájlok nevével. Nyerd ki a fájlnevet a CF_HDROP, és használd a OleCreateFromFile-t egy új csatolt vagy beágyazott objektum létrehozásához. A fájlnevek CF_HDROP formátumból való lekéréséről a Fájlnevek másolása a vágólapról alkalmazáscímű témakörben olvashat.
  • Ha az adatobjektum CFSTR_FILEDESCRIPTOR formátumot tartalmaz, kinyerheti a fájl tartalmát a fájl CFSTR_FILECONTENTS formátumából. Az eljárás ismertetését a A CFSTR_FILECONTENTS formátum használata fájlbóladatok kinyeréséhez című témakörben talál.
  • A Shell 4.71-es-es verziója előtt egy alkalmazás azt jelezte, hogy egy parancsikonfájltípust adott át a dwFlagsFILEDESCRIPTOR struktúrájának FD_LINKUI beállításával. A Shell későbbi verziói esetében a parancsikonok átvitelének elsődleges módja a CFSTR_PREFERREDDROPEFFECT DROPEFFECT_LINK formátum beállítása. Ez a megközelítés sokkal hatékonyabb, mint a FILEDESCRIPTOR struktúra kinyerése csupán egy jelölő ellenőrzéséhez.

Ha az adatkinyerési folyamat hosszadalmas lesz, érdemes lehet a műveletet aszinkron módon elvégezni egy háttérszálon. Az elsődleges szál ezután szükségtelen késések nélkül folytathatja a műveletet. Az aszinkron adatkinyerés kezeléséről a Shell-objektumok aszinkron húzása és elvetésecímű témakörben olvashat.

Adatok kinyerése fájlból a CFSTR_FILECONTENTS formátum használatával

A CFSTR_FILECONTENTS formátum nagyon rugalmas és hatékony módot kínál a fájl tartalmának átvitelére. Még csak nem is szükséges, hogy az adatok egyetlen fájlként legyenek tárolva. Ehhez a formátumhoz mindössze annyit kell tenni, hogy az adatobjektum úgy jeleníti meg az adatokat a célnak, mintha fájl lenne. A tényleges adatok lehetnek például egy szöveges dokumentum egy szakasza vagy egy adatbázisból kinyert adatblokk. A cél fájlként kezelheti az adatokat, és nem kell semmit tudnia a mögöttes tárolási mechanizmusról.

A névtérbővítmények általában CFSTR_FILECONTENTS használnak az adatok átvitelére, mivel ez a formátum nem feltételez semmilyen konkrét tárolási mechanizmust. A névtérbővítmény bármilyen tárolási mechanizmust használhat, és ezzel a formátummal úgy jelenítheti meg objektumait az alkalmazásoknak, mintha fájlok lennének.

A CFSTR_FILECONTENTS adatátviteli mechanizmusa általában TYMED_ISTREAM. Az IStream interfészmutatójának átvitele sokkal kevesebb memóriát igényel, mint az adatok globális memóriaobjektumba való betöltése, és IStream egyszerűbb módja az adatok megjelenítésének, mint IStorage.

A CFSTR_FILECONTENTS formátumot mindig CFSTR_FILEDESCRIPTOR formátum kíséri. Először meg kell vizsgálnia ennek a formátumnak a tartalmát. Ha egynél több fájlt továbbít, az adatobjektum valójában több CFSTR_FILECONTENTS formátumot fog tartalmazni, egy-egy fájlt minden fájlhoz. A CFSTR_FILEDESCRIPTOR formátum tartalmazza az egyes fájlok nevét és attribútumait, és indexértéket biztosít minden fájlhoz, amely egy adott fájl CFSTR_FILECONTENTS formátumának kinyeréséhez szükséges.

CFSTR_FILECONTENTS formátum kinyeréséhez:

  1. Bontsa ki a CFSTR_FILEDESCRIPTOR formátumot TYMED_HGLOBAL értékként.
  2. A visszaadott STGMEDIUM struktúrájának hGlobal tagja egy globális memóriaobjektumra mutat. Az objektum zárolásához adja át a hGlobal értéket a GlobalLockfüggvénynek.
  3. Az GlobalLock által visszaadott mutatót egy FILEGROUPDESCRIPTOR mutatóvá alakítva. Egy FILEGROUPDESCRIPTOR struktúrára mutat, amelyet egy vagy több FILEDESCRIPTOR szerkezet követ. Minden FILEDESCRIPTOR-struktúra egy fájl leírását tartalmazza, amelyet az egyik mellékelt CFSTR_FILECONTENTS formátum tartalmaz.
  4. Vizsgálja meg a FILEDESCRIPTOR struktúrákat annak meghatározásához, hogy melyik felel meg a kinyerni kívánt fájlnak. A FILEDESCRIPTOR struktúrájának nulla alapú indexe a fájl CFSTR_FILECONTENTS formátumának azonosítására szolgál. Mivel a globális memóriablokkok mérete nem bájtpontos, használja a struktúra nFileSizeLow és nFileSizeHigh tagokat annak meghatározásához, hogy hány bájt képviseli a fájlt a globális memóriaobjektumban.
  5. Hívja meg a IDataObject::GetData függvényt úgy, hogy a FORMATETC szerkezet cfFormat tagja a CFSTR_FILECONTENTS értékére van állítva, és a lIndex tag az előző lépésben meghatározott indexre van beállítva. A tag általában TYMED_HGLOBAL | TYMED_ISTREAM | TYMED_ISTORAGE. Az adatobjektum ezután kiválaszthatja a kívánt adatátviteli mechanizmust.
  6. A STGMEDIUM struktúra, amelyet az IDataObject::GetData visszaad, tartalmazni fog egy mutatót a fájl adataira. Vizsgálja meg a időzített tagját az adatátviteli mechanizmus meghatározásához.
  7. Ha a tymed értéke TYMED_ISTREAM vagy TYMED_ISTORAGE, használja az interfészt az adatok kinyeréséhez. Ha tymed TYMED_HGLOBAL van beállítva, az adatokat egy globális memóriaobjektum tartalmazza. Az adatok globális memóriaobjektumokból való kinyerésének módjáról a Globális memóriaobjektum kinyerése adatobjektumbólShell-adatobjektumszakaszában olvashat.
  8. A 2. lépésben zárolt globális memóriaobjektum zárolásának feloldásához hívja meg GlobalLock.

Optimalizált áthelyezési műveletek kezelése

forgatókönyv: Egy fájl áthelyezése a fájlrendszerből egy névtérbővítménybe optimalizált áthelyezéssel történik.

Egy hagyományos áthelyezési műveletben a cél másolatot készít az adatokról, és a forrás törli az eredetit. Ez az eljárás nem lehet hatékony, mert két másolatot igényel az adatokról. Nagy méretű objektumok, például adatbázisok esetében előfordulhat, hogy a hagyományos áthelyezési művelet nem is praktikus.

Az optimalizált áthelyezéssel a cél az adatok tárolási módjának megértését használja a teljes áthelyezési művelet kezeléséhez. Az adatoknak soha nincs második példánya, és nincs szükség arra, hogy a forrás törölje az eredeti adatokat. A Shell-adatok jól használhatók az optimalizált áthelyezésekhez, mivel a cél képes kezelni a teljes műveletet a Shell API használatával. Tipikus példa a fájlok áthelyezése. Miután a célnak megvan az áthelyezendő fájl elérési útja, SHFileOperation használatával helyezheti át. Nincs szükség arra, hogy a forrás törölje az eredeti fájlt.

Jegyzet

A Shell általában optimalizált módszert használ a fájlok mozgatására. A Shell-adatátvitel megfelelő kezeléséhez az alkalmazásnak képesnek kell lennie az optimalizált áthelyezés észlelésére és kezelésére.

 

Az optimalizált áthelyezéseket a következő módon kezeli a rendszer:

  1. A forrás meghívja DoDragDrop a dwEffect paraméterrel, hogy a DROPEFFECT_MOVE jelezze, hogy a forrásobjektumok áthelyezhetők.

  2. A cél az DROPEFFECT_MOVE értéket az egyik IDropTarget metódusán keresztül kapja meg, ami azt jelzi, hogy az áthelyezés engedélyezett.

  3. A cél vagy átmásolja az objektumot (nem optimális áthelyezés), vagy áthelyezi az objektumot (optimalizált áthelyezés).

  4. Azután a cél megmondja a forrásnak, hogy törölje-e az eredeti adatokat.

    Az optimalizált áthelyezés az alapértelmezett művelet, amely során az adatokat a cél törli. A forrás tájékoztatása az optimalizált áthelyezésről:

      • A cél a pdwEffect értéket, amelyet a IDropTarget::Drop metóduson keresztül kapott, valamilyen DROPEFFECT_MOVE-en kívüli értékre állítja. Általában DROPEFFECT_NONE vagy DROPEFFECT_COPY értékre van állítva. Az értéket DoDragDropadja vissza a forrásnak.
      • A cél meghívja az adatobjektum IDataObject::SetData metódusát is, és átad neki egy CFSTR_PERFORMEDDROPEFFECT formátumazonosítót, amely DROPEFFECT_NONE értékre van állítva. Ez a metódushívás azért szükséges, mert egyes célobjektumok nem biztos, hogy megfelelően állítják be a DoDragDrop metódus pdwEffect paraméterét. A CFSTR_PERFORMEDDROPEFFECT formátum a megbízható módja annak, hogy egy optimalizált áthelyezés történt.

    Ha a cél optimalizálatlan mozgást végzett, az adatokat a forrásnak törölnie kell. A forrás tájékoztatása a nem optimális lépésről:

      • A cél a IDropTarget::D rop metóduson keresztül kapott pdwEffect értéket állítja be DROPEFFECT_MOVE. Az értéket DoDragDropadja vissza a forrásnak.
      • A cél meghívja az adatobjektum IDataObject::SetData metódusát is, és átad neki egy CFSTR_PERFORMEDDROPEFFECT formátumazonosítót, amelynek értéke DROPEFFECT_MOVE. Ez a metódushívás azért szükséges, mert egyes dobási célok nem biztos, hogy megfelelően állítják be DoDragDroppdwEffect paraméterét. A CFSTR_PERFORMEDDROPEFFECT formátum jelzi, hogy nem optimális lépés történt.
  5. A forrás a cél által visszaadható két értéket vizsgálja. Ha mindkettő DROPEFFECT_MOVE van beállítva, az eredeti adatok törlésével befejezi a nem optimális áthelyezést. Ellenkező esetben a cél optimalizált áthelyezést végzett, és az eredeti adatokat törölték.

Beillesztés utáni törlési műveletek kezelése

Forgatókönyv: Egy vagy több fájl ki van vágva a Windows Intéző egyik mappájából, és be van illesztve egy névtér kiterjesztésébe. A Windows Intéző addig hagyja kiemelve a fájlokat, amíg visszajelzést nem kap a beillesztési művelet eredményéről.

Hagyományosan, ha egy felhasználó adatokat vág le, az azonnal eltűnik a nézetből. Ez lehet, hogy nem hatékony, és használhatósági problémákhoz vezethet, ha a felhasználó aggódik amiatt, hogy mi történt az adatokkal. Az egyik alternatív módszer a beillesztéssel egyidejű törlési művelet használata.

A beillesztéskori törlési művelet során a kijelölt adatok nem tűnnek el azonnal a képernyőről. Ehelyett a forrásalkalmazás kijelöli azt, például a betűtípus vagy a háttérszín módosításával. Miután a célalkalmazás beillesztette az adatokat, értesíti a forrást a művelet eredményéről. Ha a cél egy optimalizált mozgást hajtott végre, a forrás egyszerűen frissítheti a megjelenítést. Ha a cél normál áthelyezést hajtott végre, a forrásnak törölnie kell az adatok másolatát is. Ha a beillesztés sikertelen, a forrásalkalmazás visszaállítja a kijelölt adatokat az eredeti megjelenésére.

Jegyzet

A Shell rendszerint törli a kivágott fájlokat beillesztéskor, amikor kivágási/beillesztési műveletet használ a fájlok áthelyezésére. A Shell-objektumok törlési műveletei általában optimalizált áthelyezést használnak a fájlok áthelyezéséhez. A Shell-adatátvitel megfelelő kezeléséhez az alkalmazásnak képesnek kell lennie a beillesztés utáni törlési műveletek észlelésére és kezelésére.

 

A beillesztés törlésének alapvető követelménye, hogy a célnak jelentenie kell a művelet eredményét a forrásnak. A szokásos vágólap-technikák azonban nem használhatók a törlés-beillesztés mechanizmus implementálásához, mert nem biztosítanak módot a cél számára a forrással való kommunikációra. Ehelyett a célalkalmazás az adatobjektum IDataObject::SetData metódussal jelenti az eredményt az adatobjektumnak. Az adatobjektum ezután egy privát felületen keresztül kommunikálhat a forrással.

A beillesztés utáni törlési művelet alapvető eljárása a következő:

  1. A forrás jelöli a kijelölt adatok képernyőmegjelenítését.
  2. A forrás létrehoz egy adatobjektumot. A vágási műveletet a CFSTR_PREFERREDDROPEFFECT formátum DROPEFFECT_MOVE adatértékkel történő hozzáadásával jelzi.
  3. A forrás az adatobjektumot a vágólapra helyezi OleSetClipboardhasználatával.
  4. A cél lekéri az adatobjektumot a vágólapról OleGetClipboardhasználatával.
  5. A cél a CFSTR_PREFERREDDROPEFFECT adatot nyeri ki. Ha csak DROPEFFECT_MOVE értékre van beállítva, a cél optimalizált áthelyezést végezhet, vagy egyszerűen átmásolhatja az adatokat.
  6. Ha a cél nem hajt végre optimalizált mozgatást, akkor meghívja a IDataObject::SetData metódust a CFSTR_PERFORMEDDROPEFFECT formátum beállításával DROPEFFECT_MOVE értékre.
  7. Amikor a beillesztés befejeződik, a cél meghívja a IDataObject::SetData metódust, a CFSTR_PASTESUCCEEDED formátummal, ami be van állítva DROPEFFECT_MOVE értékre.
  8. Amikor a forrás IDataObject::SetData metódust hívják meg a CFSTR_PASTESUCCEEDED formátumot DROPEFFECT_MOVE-ként beállítva, akkor ellenőriznie kell, hogy megkapta-e a CFSTR_PERFORMEDDROPEFFECT formátumot is DROPEFFECT_MOVE-ként beállítva. Ha a cél mindkét formátumot elküldi, a forrásnak törölnie kell az adatokat. Ha csak a CFSTR_PASTESUCCEEDED formátumot kapja meg, a forrás egyszerűen eltávolíthatja az adatokat a megjelenítésből. Ha az átvitel sikertelen, a forrás frissíti a megjelenítést az eredeti megjelenésére.

Adatok átvitele virtuális mappákba és onnan

forgatókönyv: Egy felhasználó húz egy objektumot egy virtuális mappából, vagy azt egy virtuális mappába helyezi.

A virtuális mappák olyan objektumokat tartalmaznak, amelyek általában nem részei a fájlrendszernek. Egyes virtuális mappák, például a Lomtár, a merevlemezen tárolt adatokat jelölhetik, de nem szokásos fájlrendszer-objektumokként. Egyes adatok távoli rendszeren, például kézi számítógépen vagy FTP-helyen tárolt adatokat jelölhetnek. Mások, például a Nyomtatók mappa, olyan objektumokat tartalmaznak, amelyek egyáltalán nem jelölik a tárolt adatokat. Bár egyes virtuális mappák a rendszer részét képezik, a fejlesztők névtérbővítmény implementálásával egyéni virtuális mappákat is létrehozhatnak és telepíthetnek.

Az adatok típusától vagy tárolási módjától függetlenül a rendszerhéj úgy jeleníti meg a virtuális mappa által tartalmazott mappát és fájlobjektumokat, mintha normál fájlok és mappák lennének. A virtuális mappa feladata, hogy a benne tárolt adatokat megfelelően átvegye és a Rendszerhéjnak bemutassa. Ez a követelmény azt jelenti, hogy a virtuális mappák általában támogatják a húzással és a vágólapon végzett adatátvitelt.

Ezért két fejlesztőcsoportot kell érintenie a virtuális mappákba való és onnan történő adatátvitelnek:

  • Azok a fejlesztők, akiknek az alkalmazásainak el kell fogadniuk a virtuális mappából átvitt adatokat.
  • Azok a fejlesztők, akiknek a névtérbővítményeinek megfelelően támogatniuk kell az adatátvitelt.

Adatok elfogadása virtuális mappából

A virtuális mappák gyakorlatilag bármilyen típusú adatot képviselhetnek, és tetszőleges módon tárolhatják az adatokat. Egyes virtuális mappák valójában normál fájlrendszerfájlokat és mappákat tartalmazhatnak. Mások például egyetlen dokumentumba vagy adatbázisba csomagolhatják az összes objektumukat.

Amikor egy fájlrendszer-objektumot átad egy alkalmazásnak, az adatobjektum általában CF_HDROP formátumot tartalmaz az objektum teljes elérési útjával. Az alkalmazás kinyerheti ezt a sztringet, és a normál fájlrendszer-függvényekkel megnyithatja a fájlt, és kinyerheti az adatait. Mivel azonban a virtuális mappák általában nem tartalmaznak normál fájlrendszerobjektumokat, általában nem használják a CF_HDROP.

A CF_HDROPhelyett az adatok általában a CFSTR_FILEDESCRIPTOR/CFSTR_FILECONTENTS formátummal rendelkező virtuális mappákból kerülnek át. A CFSTR_FILECONTENTS formátumnak két előnye van CF_HDROP:

  • Az adattárolásnak nincs konkrét módszere.
  • A formátum rugalmasabb. Három adatátviteli mechanizmust támogat: egy globális memóriaobjektumot, egy IStream felületet vagy egy IStorage felületet.

A globális memóriaobjektumokat ritkán használják virtuális objektumokba vagy onnan érkező adatok átvitelére, mert az adatokat teljes egészében a memóriába kell másolni. Az interfészmutató átvitele szinte nem igényel memóriát, és sokkal hatékonyabb. Nagyon nagy fájlok esetén az interfészmutató lehet az egyetlen gyakorlati adatátviteli mechanizmus. Az adatokat általában egy IStream mutató jelöli, mivel ez a felület valamivel rugalmasabb, mint IStorage. A cél kinyeri a mutatót az adatobjektumból, és a felületi metódusokkal nyeri ki az adatokat.

A CFSTR_FILEDESCRIPTOR/CFSTR_FILECONTENTS formátumok kezeléséről további információt A CFSTR_FILECONTENTS formátum használata fájlbóladatok kinyeréséhez című témakörben talál.

Adatok átvitele névtérbővítménybe és onnan

Névtérbővítmény megvalósításakor általában támogatnia kell a húzási képességeket. Kövesse az Általános irányelvekcímű témakörben ismertetett elvetési forrásokra és célokra vonatkozó javaslatokat. A névtérkiterjesztésnek különösen a következőkre kell kiterjednie:

  • Képesnek kell lennie a CFSTR_FILEDESCRIPTOR/CFSTR_FILECONTENTS formátumok kezelésére. Ez a két formátum általában az objektumok névtérbővítményekbe és -bővítményekből való átvitelére szolgál.
  • Képesnek kell lennie optimalizált áthelyezések kezelésére. A Shell arra számít, hogy a Shell objektumok optimalizáltan lesznek áthelyezve.
  • Képesnek kell lennie egy törlés beillesztéskor típusú művelet kezelésére. A Shell a beillesztéskor törlést alkalmaz, amikor az objektumokat kivágási/beillesztési művelettel áthelyezik a Shellből.
  • Képesnek kell lennie az adatátvitel kezelésére egy IStream vagy IStorage felületen keresztül. A virtuális mappába vagy onnan történő adatátvitelt általában a két felületmutató egyikének, általában egy IStream- mutatónak az átvitelével kezelik. A cél ezután meghívja az interfész metódusait az adatok kinyeréséhez:
      • Cseppforrásként a névtér bővítményének ki kell nyernie az adatokat a tárolóból, majd ezen az interfészen keresztül át kell adnia őket a célnak.
      • Dobási célként a névtérbővítménynek fogadnia kell a forrásból származó adatokat ezen a felületen keresztül, és megfelelően kell tárolnia azokat.

Fájlok elvetése a Lomtárba

forgatókönyv: A felhasználó fájlokat helyez el a Lomtár. Az alkalmazás- vagy névtérkiterjesztés törli az eredeti fájlt.

A Lomtár egy virtuális mappa, amely már nem szükséges fájlok adattáraként szolgál. Ha a Lomtár nincs kiürítve, a felhasználó később helyreállíthatja a fájlt, és visszaadhatja a fájlrendszerbe.

A Shell-objektumok lomtárba való átvitele többnyire ugyanúgy működik, mint bármely más mappa. Ha azonban egy felhasználó eldob egy fájlt a Lomtár, a forrásnak törölnie kell az eredetit még akkor is, ha a mappa visszajelzése másolási műveletet jelez. A drop source általában nem tudja, hogy melyik mappába esett az adatobjektum. Windows 2000-es és újabb rendszerek esetén azonban, amikor egy adatobjektumot a Lomtárbaledobnak, a Shell meghívja az adatobjektum IDataObject::SetData metódust, amelynek formátuma CFSTR_TARGETCLSID a Lomtár osztályazonosítója (CLSID) (CLSID_RecycleBin). A Lomtár-eset megfelelő kezeléséhez az adatobjektumnak képesnek kell lennie felismerni ezt a formátumot, és egy privát felületen keresztül továbbítani az információkat a forrásnak.

Jegyzet

Ha az IDataObject::SetData metódus CFSTR_TARGETCLSID formátummal, amely CLSID_RecycleBin-re van állítva, van meghívva, akkor az adatforrásnak a metódusból való visszatérés előtt be kell zárnia az átvitt objektumok nyitott leíróit. Ellenkező esetben megosztási szabálysértéseket hozhat létre.

 

Hulladékfájlok létrehozása és importálása

forgatókönyv: Egy felhasználó húz néhány adatot egy OLE-alkalmazás adatfájljából, és az asztalra vagy a Windows Intézőbe dobja.

A Windows lehetővé teszi, hogy a felhasználók áthúznak egy objektumot egy OLE-alkalmazás adatfájljából, és az asztalra vagy a fájlrendszer mappájába dobják. Ez a művelet létrehoz egy hulladékfájlt, amely tartalmazza az adatokat vagy az adatokra mutató hivatkozást. A fájlnév az objektum CLSID-éhez regisztrált rövid névből és a CF_TEXT adatokból származik. Ahhoz, hogy a Shell adatokat tartalmazó hulladékfájlt hozzon létre, az alkalmazás IDataObject felületének támogatnia kell a CF_EMBEDSOURCE vágólap formátumát. Hivatkozásokat tartalmazó fájl létrehozásához IDataObject támogatnia kell a CF_LINKSOURCE formátumot.

Az alkalmazások három választható funkciót is megvalósíthatnak a hulladékfájlok támogatásához:

  • Oda-vissza támogatás
  • Gyorsítótárazott adatformátumok
  • Késleltetett renderelés

Körutazás támogatás

A oda-vissza egy adatobjektum egy másik tárolóba való átvitelét, majd az eredeti dokumentumba való visszavezetését foglalja magában. Egy felhasználó például átvihet egy cellacsoportot egy számolótáblából az asztalra, és létrehozhat egy hulladékfájlt az adatokkal. Ha a felhasználó ezután visszaviszi a nyers adatokat a számolótáblába, az adatokat úgy kell integrálni a dokumentumba, ahogy az eredeti átvitel előtt voltak.

Amikor a Shell létrehozza a hulladékfájlt, az adatokat beágyazási objektumként jelöli. Amikor a hulladékot egy másik tárolóba helyezi át, beágyazási objektumként továbbítja, még akkor is, ha az eredeti dokumentumba kerül vissza. Az alkalmazás felelős a hulladékban található adatformátum meghatározásáért és az adatok natív formátumba helyezéséért, ha szükséges.

A beágyazott objektum formátumának meghatározásához határozza meg annak CLSID-azonosítóját az objektum CF_OBJECTDESCRIPTOR formátumának beolvasásával. Ha a CLSID az alkalmazáshoz tartozó adatformátumot jelez, a natív adatokat kell továbbítania az OleCreateFromDatahívása helyett.

Gyorsítótárazott adatformátumok

Amikor a Shell létrehoz egy hulladékfájlt, ellenőrzi a beállításjegyzékben az elérhető formátumok listáját. Alapértelmezés szerint két formátum érhető el: CF_EMBEDSOURCE és CF_LINKSOURCE. Vannak azonban olyan esetek, amikor az alkalmazásoknak különböző formátumú hulladékfájlokkal kell rendelkezniük:

  • A törmelékek nem OLE tárolókba való átvitelének engedélyezése, amelyek nem fogadhatók el beágyazott objektumformátumokként.
  • Annak érdekében, hogy az alkalmazáscsomagok privát formátummal kommunikálhassanak.
  • Hogy könnyebben kezelhetők legyenek a körutazások.

Az alkalmazások a regisztrációs adatbázisban való gyorsítótárazással adhatnak hozzá formátumokat a hulladékhoz. A gyorsítótárazott formátumok kétféleképpen használhatók:

  • Prioritási gyorsítótár-formátumok. Ezekben a formátumokban az adatok teljes egészében át lesznek másolva az adatobjektumból származó törmelékbe.
  • Késleltetett formátumok. Ezekben a formátumokban az adatobjektum nem lesz átmásolva a hulladékba. Ehelyett a renderelés késleltetve lesz, amíg valamilyen cél nem igényli az adatokat. A késleltetett megjelenítésről a következő szakaszban részletesebben olvashat.

Prioritási gyorsítótár vagy késleltetett formátum hozzáadásához hozzon létre egy DataFormat alkulcsot az alkalmazás CLSID kulcsa alatt, amely az adatok forrása. Az adott alkulcs alá hozzon létre egy PriorityCacheFormats vagy DelayRenderFormats alkulcsot. Minden prioritási gyorsítótárhoz vagy késleltetett megjelenítésű formátumhoz hozzon létre egy nullától kezdődő számozott alkulcsot. Állítsa a kulcs értékét egy karakterláncra a formátum regisztrált nevével vagy egy #X értékre, ahol az X egy szabványos vágólap formátumszámát jelöli.

Az alábbi minta két alkalmazás gyorsítótárazott formátumát mutatja be. A MyProg1 alkalmazás a rich-text formátumot prioritási gyorsítótár formátumként, a privát "Saját formátum" formátumot pedig késleltetett formátumként tartalmazza. A MyProg2 alkalmazás prioritási gyorsítótár-formátumként CF_BITMAP formátumot (#8") használ.

HKEY_CLASSES_ROOT
   CLSID
      {GUID}
         (Default) = MyProg1
         DataFormats
            PriorityCacheFormats
               0
                  (Default) = Rich Text Format
            DelayRenderFormats
               0
                  (Default) = My Format
      {GUID}
         (Default) = MyProg2
         DataFormats
            PriorityCacheFormats
               0
                  (Default) = #8

További formátumok is hozzáadhatók további számozott alkulcsok létrehozásával.

Késleltetett renderelés

A késleltetett renderelési formátum lehetővé teszi, hogy az alkalmazás létrehozhasson egy hulladékfájlt, de késleltetheti az adatok megjelenítésének költségeit, amíg a cél kéri. Az IDataObject felület késleltetett renderelési formátumokat kínál a célhoz, a natív és gyorsítótárazott adatokkal együtt. Ha a cél késleltetett renderelési formátumot kér, a Rendszerhéj futtatja az alkalmazást, és az aktív objektumból adja meg a célnak az adatokat.

Jegyzet

Mivel a késleltetett renderelés kissé kockázatos, körültekintően kell használni. Nem fog működni, ha a kiszolgáló nem érhető el, vagy az OLE-kompatibilisnek nem minősülő alkalmazások esetében.

 

Shell-objektumok aszinkron húzása és elvetése

forgatókönyv: A felhasználó nagy mennyiségű adatot továbbít a forrásból a célba. A cél aszinkron módon nyeri ki az adatokat, hogy elkerülje mindkét alkalmazás jelentős ideig történő blokkolását.

Általában a húzd és ejtsd szinkron művelet. Röviden:

  1. A drop source meghívja DoDragDrop, és blokkolja az elsődleges szálat, amíg a függvény vissza nem tér. Az elsődleges szál blokkolása általában blokkolja a felhasználói felület feldolgozását.
  2. A cél IDropTarget::Drop metódus meghívása után a cél kinyeri az adatokat az elsődleges szálon lévő adatobjektumból. Ez az eljárás általában letiltja a cél felhasználói felületének feldolgozását a kinyerési folyamat időtartamára.
  3. Az adatok kinyerése után a cél visszaadja a IDropTarget::D rop hívást, a rendszer DoDragDropad vissza, és mindkét szál továbbléphet.

Röviden, a szinkron adatátvitel jelentős ideig blokkolhatja mindkét alkalmazás elsődleges szálait. Különösen mindkét szálnak várnia kell, amíg a célrendszer kinyeri az adatokat. Kis mennyiségű adat esetén az adatok kinyeréséhez szükséges idő kicsi, és a szinkron adatátvitel elég jól működik. A nagy mennyiségű adat szinkron kinyerése azonban hosszadalmas késést okozhat, és megzavarhatja a cél és a forrás felhasználói felületét.

Az IAsyncOperation/IDataObjectAsyncCapability interfész egy opcionális felület, amelyet egy adatobjektum implementálhat. Lehetővé teszi, hogy a drop cél aszinkron módon nyerjen ki adatokat az adatobjektumból egy háttérszálon. Ha az adatkinyerés a háttérszálra kerül, mindkét alkalmazás elsődleges szálai szabadon folytathatóak.

Az IASyncOperation/IDataObjectAsyncCapability használata

Jegyzet

A felületet eredetileg IAsyncOperationnevezték el, de ezt később IDataObjectAsyncCapability- ra módosították. Ellenkező esetben a két felület azonos.

 

A IAsyncOperation/IDataObjectAsyncCapability célja, hogy lehetővé tegye a forrás és a cél helyének egyeztetését arról, hogy az adatok kinyerhetők-e aszinkron módon. Az alábbi eljárás azt ismerteti, hogyan használja a drop source az interfészt:

  1. Hozzon létre egy adatobjektumot, amely elérhetővé teszi IAsyncOperation/IDataObjectAsyncCapability.
  2. Hívja meg a SetAsyncMode függvényt, ahol a fDoOpAsyncVARIANT_TRUE értékre van állítva, jelezve, hogy az aszinkron művelet támogatott.
  3. Miután DoDragDrop visszatér, hívja meg InOperation:
    • Ha InOperation meghiúsul, vagy VARIANT_FALSEad vissza, normál szinkron adatátvitel történt, és az adatkinyerési folyamat befejeződött. A forrásnak minden szükséges tisztítást végre kell hajtania, és folytatnia kell a műveletet.
    • Ha InOperationVARIANT_TRUEad vissza, a rendszer aszinkron módon nyeri ki az adatokat. A törlési műveleteket a(z) EndOperationvégzi el.
  4. Engedje fel az adatobjektumot.
  5. Ha az aszinkron adatátvitel befejeződött, az adatobjektum általában egy privát felületen értesíti a forrást.

Az alábbi eljárás azt ismerteti, hogy a drop target hogyan használja az IAsyncOperation/IDataObjectAsyncCapability interfészt az adatok aszinkron kinyeréséhez:

  1. Amikor a rendszer meghívja IDropTarget::D rop, hívja meg IDataObject::QueryInterface, és kérjen egy IAsyncOperation/IDataObjectAsyncCapability interfészt (IID_IAsyncOperation/IID_IDataObjectAsyncCapability) az adatobjektumból.
  2. GetAsyncModehívása. Ha a metódus VARIANT_TRUEad vissza, az adatobjektum támogatja az aszinkron adatkinyeréseket.
  3. Hozzon létre egy külön szálat az adatkinyerés kezeléséhez és StartOperationmeghívásához.
  4. Adja vissza a IDropTarget::D rop hívást, ahogyan egy normál adatátviteli művelet esetében tenné. DoDragDrop visszatér, és feloldja a ledobási forrás letiltását. Ne hívja meg IDataObject::SetData parancsot az optimalizált áthelyezési vagy törlési beillesztési művelet eredményének jelzéséhez. Várjon, amíg a művelet befejeződik.
  5. Bontsa ki az adatokat a háttérszálon. A cél elsődleges szála le van tiltva, és szabadon folytatható.
  6. Ha az adatátvitel optimalizált áthelyezési vagy törlési művelet volt, hívja meg IDataObject::SetData az eredmény jelzéséhez.
  7. A EndOperationmeghívásával értesítse az adatobjektumot arról, hogy a kinyerés befejeződött.