Aracılığıyla paylaş


Kabuk Veri Transferi Senaryolarını İşleme

Shell Veri Nesnesi belgesi, sürükle ve bırak veya Pano ile Kabuk verilerini aktarmak için kullanılan genel yaklaşımı ele aldı. Bununla birlikte, uygulamanızda Shell veri aktarımını uygulamak için, bu genel ilkeleri ve teknikleri Shell verilerinin aktarılabildiği çeşitli yöntemlere nasıl uygulayabileceğinizi de anlamanız gerekir. Bu belgede yaygın olarak Shell veri aktarımı senaryoları gösterilir ve uygulamanızda her birinin nasıl uygulanacağı tartışılır.

Not

Bu senaryoların her biri belirli bir veri aktarımı işlemini ele alsa da, bunların çoğu çeşitli ilgili senaryolar için geçerlidir. Örneğin, çoğu Pano ile sürükle ve bırak aktarımları arasındaki birincil fark, veri nesnesinin hedefe nasıl ulaştığıdır. Hedef, veri nesnesinin IDataObject arabirimine yönelik bir işaretçiye sahip olduğunda, bilgi ayıklama yordamları her iki veri aktarımı türü için de büyük ölçüde aynıdır. Ancak bazı senaryolar belirli bir işlem türüyle sınırlıdır. Ayrıntılar için tek tek senaryoya bakın.

 

Genel Yönergeler

Aşağıdaki bölümlerin her biri tek, oldukça belirli bir veri aktarımı senaryolarını ele almaktadır. Ancak, veri aktarımları genellikle daha karmaşıktır ve çeşitli senaryoların yönlerini içerebilir. Genellikle hangi senaryoyla ilgilenmeniz gerektiğini önceden bilmezsiniz. Aklınızda bulundurmak için birkaç genel yönerge aşağıdadır.

Veri kaynakları için:

  • CF_HDROPdışında Kabuk Panosu biçimleri önceden tanımlı değildir. Kullanmak istediğiniz her biçim, RegisterClipboardFormatçağrılarak kaydedilmelidir.
  • Veri nesnelerindeki biçimler, kaynaktan tercih sırasına göre sağlanır. Veri nesnesini numaralandırın ve kullanabileceğiniz ilk nesneyi seçin.
  • Destekleyebileceğiniz kadar çok biçim ekleyin. Genellikle veri nesnesinin nereye bırakılacağını bilmezsiniz. Bu uygulama, veri nesnesinin bırakma hedefinin kabul edebileceği bir biçim içerme olasılığını artırır.
  • Mevcut dosyalar CF_HDROP biçiminde sunulmalıdır.
  • CFSTR_FILECONTENTS/CFSTR_FILEDESCRIPTOR biçimli dosya benzeri veriler sunar. Bu yaklaşım, hedefin temel alınan veri depolama hakkında hiçbir şey bilmesine gerek kalmadan bir veri nesnesinden dosya oluşturmasına olanak tanır. Normalde verileri IStream arabirimi olarak sunmalısınız. Bu veri aktarım mekanizması genel bellek nesnesine göre daha esnektir ve çok daha az bellek kullanır.
  • Sürükleme kaynakları, Kabuk öğelerini sürüklerken CFSTR_SHELLIDLIST biçimini sunmalıdır. Öğeler için veri nesneleri IShellFolder::GetUIObjectOf veya IShellItem::BindToHandler yöntemleri aracılığıyla edinilebilir. Veri kaynakları, SHCreateDataObjectkullanarak CFSTR_SHELLIDLIST biçimini destekleyen standart bir veri nesnesi uygulaması oluşturabilir.
  • Kabuk öğesi programlama modelini kullanarak sürüklenen öğeler hakkında anlamak isteyen bırakma hedefleri, bir IDataObject'i SHCreateShellItemArrayFromDataObjectkullanarak IShellItemArray'e dönüştürebilir.
  • Standart geri bildirim imleçlerini kullanın.
  • Sol ve sağ sürüklemeyi destekler.
  • Gömülü bir nesneden veri nesnesinin kendisini kullanın. Bu yaklaşım, uygulamanızın veri nesnesinin sunması gereken ek biçimleri almasını sağlar ve ek bir kapsama katmanı oluşturmaktan kaçınıyor. Örneğin, A sunucusundan katıştırılmış bir nesne sunucu/kapsayıcı B'den sürüklenip C kapsayıcısı üzerine bırakılır. C, A sunucusunun eklenmiş nesnesini içeren B sunucusunun katıştırılmış bir nesnesini değil, A sunucusunun katıştırılmış nesnesini oluşturmalıdır.
  • Kabuk'un dosyaları taşırken iyileştirilmiş taşıma veya yapıştırmayı silme işlemleri kullanabileceğini unutmayın. Uygulamanız bu işlemleri tanıyabilmeli ve uygun şekilde yanıt verebilmelidir.

Veri hedefleri için:

  • CF_HDROPdışında Kabuk Panosu biçimleri önceden tanımlı değildir. Kullanmak istediğiniz her biçim, RegisterClipboardFormatçağrılarak kaydedilmelidir.
  • OLE bırakma hedefine uygulayın ve kaydedin. Mümkünse Windows 3.1 hedeflerini veya WM_DROPFILES iletisini kullanmaktan kaçının.
  • Veri nesnesinin içerdiği biçimler, nesnenin nereden geldiğine bağlı olarak değişir. Genellikle bir veri nesnesinin nereden geldiğini önceden bilmediğinizden, belirli bir biçimin mevcut olacağını varsaymayın. Veri nesnesi, biçimleri en iyiden başlayarak kalite sırasına göre numaralandırmalıdır. Bu nedenle, kullanılabilir en iyi biçimi elde etmek için, uygulamalar normalde kullanılabilir biçimleri numaralandırır ve destekleyebilecekleri numaralandırmada ilk biçimi kullanır.
  • Sağ sürüklemeyi destekleyin. sürükleyip bırakma işleyicisi oluşturarak sürükleme kısayol menüsünü özelleştirebilirsiniz.
  • Uygulamanız mevcut dosyaları kabul edecekse, CF_HDROP biçimini işleyebilmelidir.
  • Genel olarak, dosyaları kabul eden uygulamalar da CFSTR_FILECONTENTS/CFSTR_FILEDESCRIPTOR biçimlerini işlemelidir. Dosya sistemindeki dosyalar CF_HDROP biçimine sahip olsa da, ad alanı uzantıları gibi sağlayıcılardan gelen dosyalar genellikle CFSTR_FILECONTENTS/CFSTR_FILEDESCRIPTORkullanır. Örnek olarak Windows CE klasörleri, Dosya Aktarım Protokolü (FTP) klasörleri, web klasörleri ve CAB klasörleri verilebilir. Kaynak normalde depolama alanından dosya olarak veri sunmak için bir IStream arabirimi uygular.
  • Kabuk'un dosyaları taşırken iyileştirilmiş taşıma veya yapıştırmayı silme işlemleri kullanabileceğini unutmayın. Uygulamanız bu işlemleri tanıyabilmeli ve uygun şekilde yanıt verebilmelidir.

Dosya Adlarını Panodan Uygulamaya Kopyalama

Senaryosu: Kullanıcı Windows Gezgini'nde bir veya daha fazla dosya seçer ve bunları Pano'ya kopyalar. Uygulamanız dosya adlarını ayıklar ve belgeye yapıştırır.

Bu senaryo, örneğin bir kullanıcının dosyayı kesip uygulamanıza yapıştırarak HTML bağlantısı oluşturmasına izin vermek için kullanılabilir. Uygulamanız daha sonra veri nesnesinden dosya adını ayıklayabilir ve bir tutturucu etiketi oluşturmak için işleyebilir.

Kullanıcı Windows Gezgini'nde bir dosya seçip Pano'ya kopyaladığında, Kabuk bir veri nesnesi oluşturur. Ardından OleSetClipboard çağırarak panoya veri nesnesinin IDataObject arabirimine bir işaretçi yerleştirir.

Kullanıcı uygulamanızın menüsünden veya araç çubuğundan Yapıştır komutunu seçtiğinde:

  1. Veri nesnesinin IDataObject arabirimini almak için OleGetClipboardçağırın.
  2. Numaralandırıcı nesnesi istemek için IDataObject::EnumFormatEtc çağrısı yapın.
  3. Veri nesnesinin içerdiği biçimleri numaralandırmak için numaralandırıcı nesnesinin IEnumFORMATETC arabirimini kullanın.

Not

Bu yordamdaki son iki adım, tamlık için eklenmiştir. Bunlar genellikle basit dosya aktarımları için gerekli değildir. Bu tür bir veri aktarımı için kullanılan tüm veri nesneleri, nesnenin içerdiği dosyaların adlarını belirlemek için kullanılabilecek CF_HDROP biçimini içermelidir. Ancak, daha genel veri aktarımları için biçimleri listelemeli ve uygulamanızın işleyebileceği en iyi olanı seçmelisiniz.

 

Veri Nesnesinden Dosya Adlarını Ayıklama

Sonraki adım, veri nesnesinden bir veya daha fazla dosya adı ayıklamak ve bunları uygulamanıza yapıştırmaktır. Veri nesnesinden dosya adı ayıklamak için bu bölümde açıklanan yordamın sürükle ve bırak aktarımlarına eşit derecede iyi uygulandığını unutmayın.

Veri nesnesinden dosya adlarını almanın en basit yolu CF_HDROP biçimidir:

  1. IDataObject::GetDataçağrısı. FORMATETC yapısının cfFormat üyesini CF_HDROP ve tymed üyesini TYMED_HGLOBALolarak ayarlayın. dwAspect üyesi normalde DVASPECT_CONTENT olarak ayarlanır. Ancak, dosyanın yolunun kısa (8,3) biçiminde olması gerekiyorsa dwAspect DVASPECT_SHORT olarak ayarlayın.

    IDataObject::GetData döndürdüğünde, STGMEDIUM yapısının hGlobal üyesi, verileri içeren bir genel bellek nesnesine işaret eder.

  2. Bir HDROP değişkeni oluşturun ve STGMEDIUM yapısının hGlobal üyesine ayarlayın. HDROP değişkeni artık DROPFILES yapısının tanıtıcısı ve ardından kopyalanan dosyaların tam dosya yollarını içeren çift null ile sonlandırılan bir dizedir.

  3. iFile parametresi 0xFFFFFFFF olarak ayarlanmış DragQueryFile çağırarak listede kaç dosya yolu olduğunu belirleyin. İşlev, listedeki dosya yollarının sayısını döndürür. Bu listedeki dosya yolunun sıfır tabanlı dizini, bir sonraki adımda belirli bir yolu tanımlamak için kullanılır.

  4. Her dosya için DragQueryFile bir kez çağırarak ve iFile dosyanın dizinine ayarlanmış olarak genel bellek nesnesinden dosya yollarını ayıklayın.

  5. Dosya yollarını gerektiği gibi işleyip uygulamanıza yapıştırın.

  6. ReleaseStgMedium çağırın ve işaretçiyi 1. adımda IDataObject::GetData geçirdiğiniz STGMEDIUM yapısına geçirin. Yapıyı serbest bıraktıktan sonra, 2. adımda oluşturduğunuz HDROP değeri artık geçerli olmaz ve kullanılmamalıdır.

Bırakılan Dosyanın İçeriğini Bir Uygulamaya Kopyalama

Senaryosu: Kullanıcı Windows Gezgini'nden bir veya daha fazla dosyayı sürükleyip uygulamanızın penceresine bırakır. Uygulamanız, dosya (lar) içeriğini ayıklar ve uygulamaya yapıştırır.

Bu senaryo, dosyaları Windows Gezgini'nden uygulamaya aktarmak için sürükle ve bırak işlevini kullanır. İşlemden önce uygulamanızın şunları yapması gerekir:

  1. Gerekli Kabuk Panosu biçimlerini kaydetmek için RegisterClipboardFormat çağrısını gerçekleştirin.
  2. Hedef pencereyi ve uygulamanızın IDropTarget arabirimini kaydetmek için RegisterDragDropçağırın.

Kullanıcı bir veya daha fazla dosya seçip sürüklemeye başlayarak işlemi başlattıktan sonra:

  1. Windows Gezgini bir veri nesnesi oluşturur ve desteklenen biçimleri buna yükler.
  2. Windows Gezgini, sürükleme döngüsünü başlatmak için DoDragDrop çağırır.
  3. Sürükleme görüntüsü hedef pencerenize ulaştığında, sistem IDropTarget::DragEnterçağırarak size bildirir.
  4. Veri nesnesinin ne içerdiğini belirlemek için veri nesnesinin IDataObject::EnumFormatEtc yöntemini çağırın. Veri nesnesinin içerdiği biçimleri numaralandırmak için yöntemi tarafından döndürülen numaralandırıcı nesnesini kullanın. Uygulamanız bu biçimlerden hiçbirini kabul etmek istemiyorsa DROPEFFECT_NONE döndürebilirsiniz. Bu senaryonun amaçları doğrultusunda, uygulamanız CF_HDROPgibi dosyaları aktarmak için kullanılan biçimleri içermeyen tüm veri nesnelerini yoksamalıdır.
  5. Kullanıcı verileri düşürdüğünde sistem IDropTarget::Dropçağırır.
  6. Dosyaların içeriğini ayıklamak için IDataObject arabirimini kullanın.

Kabuk nesnesinin içeriğini bir veri nesnesinden ayıklamanın birkaç farklı yolu vardır. Genel olarak aşağıdaki sırayı kullanın:

  • Dosya CF_TEXT bir biçim içeriyorsa veriler ANSI metnidir. Dosyanın kendisini açmak yerine verileri ayıklamak için CF_TEXT biçimini kullanabilirsiniz.
  • Dosya bağlı veya eklenmiş bir OLE nesnesi içeriyorsa, veri nesnesi CF_EMBEDDEDOBJECT biçimi içerir. Verileri ayıklamak için standart OLE tekniklerini kullanın. Hurda dosyaları her zaman CF_EMBEDDEDOBJECT biçimi içerir.
  • Shell nesnesi dosya sisteminden geliyorsa, veri nesnesi dosyaların adlarını içeren bir CF_HDROP biçimi içerir. Dosya adını CF_HDROP'den ayıklayın ve OleCreateFromFile çağrısını yaparak yeni bir bağlı veya eklenmiş nesne oluşturun. CF_HDROP formatından dosya adını nasıl alacağınızı tartışmak için bkz. Panodan Uygulamaya Dosya Adlarını Kopyalama.
  • Veri nesnesi CFSTR_FILEDESCRIPTOR bir biçim içeriyorsa, dosyanın içeriğini dosyanın CFSTR_FILECONTENTS biçiminden ayıklayabilirsiniz. Bu yordamın tartışması için bkz. CFSTR_FILECONTENTS Biçimini Kullanarak Dosyadan Veri Ayıklamak.
  • Shell sürüm 4.71'den önce bir uygulama, FILEDESCRIPTOR yapısının dwFlags üyesinde FD_LINKUI ayarlayarak bir kısayol dosya türünü aktardığını gösteriyordu. Kabuğun sonraki sürümlerinde kısayolların aktarıldığını belirtmenin tercih edilen yolu, DROPEFFECT_LINK olarak ayarlanmış CFSTR_PREFERREDDROPEFFECT biçimini kullanmaktır. Bu yaklaşım, yalnızca bayrağı denetlemek için FILEDESCRIPTOR yapısını ayıklamaktan çok daha verimlidir.

Veri ayıklama işlemi uzun olacaksa, işlemi arka plan iş parçacığında eşzamanlı olmayan şekilde yapmak isteyebilirsiniz. Ana iş parçacığınız gereksiz gecikmeler olmadan ilerleyebilir. Zaman uyumsuz veri ayıklamanın nasıl işleneceğinin tartışılması için bkz. Kabuk Nesnelerini Zaman Uyumsuz Olarak Sürükleme ve Bırakma.

Dosyadan Veri Ayıklamak için CFSTR_FILECONTENTS Biçimini Kullanma

CFSTR_FILECONTENTS biçimi, bir dosyanın içeriğini aktarmak için çok esnek ve güçlü bir yol sağlar. Verilerin tek bir dosya olarak depolanması bile gerekli değildir. Bu biçim için gereken tek şey, veri nesnesinin verileri bir dosyaymış gibi hedefe sunmasıdır. Örneğin, gerçek veriler metin belgesinin bir bölümü veya veritabanından ayıklanan veri bloğu olabilir. Hedef verileri bir dosya olarak değerlendirebilir ve temel alınan depolama mekanizması hakkında hiçbir şey bilmesi gerekmez.

Bu biçim belirli bir depolama mekanizmasını varsaymadığından, ad alanı uzantıları normalde verileri aktarmak için CFSTR_FILECONTENTS kullanır. Bir ad alanı uzantısı, uygun depolama mekanizmasını kullanabilir ve nesnelerini dosyalar gibi uygulamalara sunmak için bu biçimi kullanabilir.

CFSTR_FILECONTENTS için veri aktarım mekanizması genellikle TYMED_ISTREAM. IStream arabirim işaretçisinin aktarılması, verileri genel bir bellek nesnesine yüklemekten çok daha az bellek gerektirir ve IStream, IStorage'dan daha basit bir yöntemdir.

CFSTR_FILECONTENTS biçimine her zaman CFSTR_FILEDESCRIPTOR biçimi eşlik edilir. Önce bu biçimin içeriğini incelemeniz gerekir. Birden fazla dosya aktarılıyorsa, veri nesnesi aslında her dosya için bir tane olmak üzere birden çok CFSTR_FILECONTENTS biçimi içerir. CFSTR_FILEDESCRIPTOR biçimi, her dosyanın adını ve özniteliklerini içerir ve belirli bir dosyanın CFSTR_FILECONTENTS biçimini ayıklamak için gereken her dosya için bir dizin değeri sağlar.

CFSTR_FILECONTENTS biçimini ayıklamak için:

  1. CFSTR_FILEDESCRIPTOR biçimini TYMED_HGLOBAL değer olarak ayıklayın.
  2. Döndürülen STGMEDIUM yapısındaki hGlobal üyesi, bir genel bellek nesnesine işaret eder. hGlobal değerini üzerineGlobalLockgeçirerek bu nesneyi kilitleyin.
  3. GlobalLock tarafından döndürülen işaretçiyi bir FILEGROUPDESCRIPTOR işaretçisine dönüştürebilirsiniz. Bir FILEGROUPDESCRIPTOR yapısını ve ardından bir veya daha fazla FILEDESCRIPTOR yapısını gösterir. Her FILEDESCRIPTOR yapısı, eşlik eden CFSTR_FILECONTENTS biçimlerinden birinin içerdiği bir dosyanın açıklamasını içerir.
  4. FILEDESCRIPTOR yapılarını inceleyerek hangisinin ayıklamak istediğiniz dosyaya karşılık olduğunu belirleyin. Bu FILEDESCRIPTOR yapısının sıfır tabanlı dizini, dosyanın CFSTR_FILECONTENTS biçimini tanımlamak için kullanılır. Genel bellek bloğunun boyutu bayt açısından hassas olmadığından, genel bellek nesnesindeki dosyayı temsil eden bayt sayısını belirlemek için yapının nFileSizeLow ve nFileSizeHigh üyelerini kullanın.
  5. cfFormat üyesi CFSTR_FILECONTENTS değerine ve lIndex üyesi, önceki adımda belirlediğiniz dizine ayarlanmış olarak FORMATETC yapısının ayarlı olduğu durumda, IDataObject::GetData çağrısını yapın. tymed üyesi genellikle TYMED_HGLOBAL | olarak ayarlanır TYMED_ISTREAM | TYMED_ISTORAGE. Daha sonra veri nesnesi tercih ettiği veri aktarım mekanizmasını seçebilir.
  6. IDataObject::GetDataSTGMEDIUM yapısı, dosya verilerinin işaretçisini içerir. Veri aktarım mekanizmasını belirlemek için yapının tymed üyesini inceleyin.
  7. TYMED_ISTREAM veya TYMED_ISTORAGE olarak ayarlandıysa, verileri ayıklamak için arabirimini kullanın. TYMED_HGLOBAL olarak ayarlanırsa, veriler genel bellek nesnesinde yer alır. Genel bellek nesnesinden veri ayıklama yöntemleriyle ilgili olarak, Kabuk Veri Nesnesibölümündeki Veri nesnesinden genel bellek nesnesi ayıklama kısmına bakın.
  8. 2. adımda kilitlediğiniz genel bellek nesnesinin kilidini açmak için GlobalLock çağırın.

İyileştirilmiş Taşıma İşlemlerini İşleme

Senaryosu: Bir dosya, iyileştirilmiş bir taşıma kullanılarak dosya sisteminden bir ad alanı uzantısına taşınır.

Geleneksel taşıma işleminde hedef, verilerin bir kopyasını oluşturur ve kaynak özgün öğeyi siler. Bu yordam, verilerin iki kopyasını gerektirdiğinden verimsiz olabilir. Veritabanları gibi büyük nesnelerle, geleneksel taşıma işlemi pratik bile olmayabilir.

Optimize edilmiş bir taşıma ile hedef sistem, verilerin nasıl depolandığını anlama yeteneğini kullanarak taşıma işleminin tamamını işler. Verilerin ikinci bir kopyası asla yoktur ve kaynağın özgün verileri silmesine gerek yoktur. Hedef, Kabuk API'sini kullanarak tüm işlemi işleyebildiğinden, kabuk verileri iyileştirilmiş taşımalara uygundur. Tipik bir örnek dosyaları taşımaktır. Hedef taşınacak dosyanın yoluna sahip olduktan sonra, taşımak için SHFileOperation kullanabilir. Kaynağın özgün dosyayı silmesine gerek yoktur.

Not

Shell normalde dosyaları taşımak için iyileştirilmiş bir taşıma kullanır. Kabuk veri aktarımını düzgün bir şekilde işlemek için uygulamanızın iyileştirilmiş bir taşımayı algılayabilmesi ve işleyebilmesi gerekir.

 

Optimizasyonlu hareketler aşağıdaki şekilde yönetilir:

  1. Kaynak, dwEffect parametresini DROPEFFECT_MOVE olarak ayarlayarak kaynak nesnelerin taşınabileceğini belirtmek için DoDragDrop çağırır.

  2. Hedef, DROPEFFECT_MOVE değerini IDropTarget yöntemlerinden biri aracılığıyla alır ve bir taşımaya izin verildiğini gösterir.

  3. Hedef, nesneyi kopyalar (iyileştirilmemiş taşıma) veya nesneyi taşır (iyileştirilmiş taşıma).

  4. Hedef daha sonra kaynağa özgün verileri silmesi gerekip gerekmediğini söyler.

    Optimize edilmiş hareket, verilerin hedef tarafından silindiği varsayılan işlemdir. Kaynağa iyileştirilmiş bir taşıma gerçekleştirildiğini bildirmek için:

      • Hedef, IDropTarget::Drop yöntemi aracılığıyla aldığı pdwEffect değerini DROPEFFECT_MOVE dışında bir değere ayarlar. Genellikle DROPEFFECT_NONE veya DROPEFFECT_COPY olarak ayarlanır. Değer, DoDragDroptarafından kaynağa döndürülür.
      • Hedef ayrıca veri nesnesinin IDataObject::SetData yöntemini çağırır ve DROPEFFECT_NONE olarak ayarlanmış CFSTR_PERFORMEDDROPEFFECT biçim tanımlayıcısını geçirir. Bazı bırakma hedefleri DoDragDroppdwEffect parametresini düzgün ayarlamayabileceği için bu yöntem çağrısı gereklidir. CFSTR_PERFORMEDDROPEFFECT formatı, optimize edilmiş bir taşımanın gerçekleştiğini göstermek için güvenilir bir yoldur.

    Hedef optimize edilmemiş bir hareket yaptıysa, veri kaynak tarafından silinmelidir. Kaynağa optimize edilmemiş bir taşıma yapıldığını bildirmek için:

      • Hedef, IDropTarget::D rop yöntemi aracılığıyla aldığı pdwEffect değerini DROPEFFECT_MOVE olarak ayarlar. Değer, DoDragDroptarafından kaynağa döndürülür.
      • Hedef ayrıca veri nesnesinin IDataObject::SetData yöntemini çağırır ve DROPEFFECT_MOVE olarak ayarlanmış CFSTR_PERFORMEDDROPEFFECT biçim tanımlayıcısını geçirir. Bazı bırakma hedefleri DoDragDroppdwEffect parametresini düzgün ayarlamayabileceği için bu yöntem çağrısı gereklidir. CFSTR_PERFORMEDDROPEFFECT biçimi, optimize edilmemiş bir taşımanın gerçekleştiğini belirtmenin güvenilir bir yoludur.
  5. Kaynak, hedef tarafından döndürülebilecek iki değeri inceler. her ikisi de DROPEFFECT_MOVE olarak ayarlanırsa, özgün verileri silerek iyileştirilmemiş taşıma işlemini tamamlar. Aksi halde, hedef optimize edilmiş bir hareket yaptı ve orijinal veriler silindi.

Yapıştırma Anında Silme İşlemlerini İşleme

Senaryosu: Bir veya daha fazla dosya Windows Gezgini'ndeki bir klasörden kesilir ve ad alanı uzantısına yapıştırılır. Windows Gezgini, yapıştırma işleminin sonucu hakkında geri bildirim alıncaya kadar dosyaları vurgulanmış olarak bırakır.

Geleneksel olarak, bir kullanıcı verileri kestiğinde hemen görüntüden kaybolur. Bu verimli olmayabilir ve kullanıcının verilere ne olduğu konusunda endişelenmesi durumunda kullanılabilirlik sorunlarına yol açabilir. Alternatif bir yaklaşım, yapıştırmada silme işlemi kullanmaktır.

Yapıştırmada silme işlemiyle, seçili veriler görünümden hemen kaldırılmaz. Bunun yerine, kaynak uygulama yazı tipini veya arka plan rengini değiştirerek seçili olarak işaretler. Hedef uygulama verileri yapıştırdıktan sonra, işlemin sonucunu kaynağa bildirir. Hedef iyileştirilmiş taşımagerçekleştirdiyse, kaynak yalnızca ekranını güncelleştirebilir. Hedef normal bir taşıma gerçekleştirdiyse, kaynağın veri kopyasını da silmesi gerekir. Yapıştırma başarısız olursa, kaynak uygulama seçilen verileri özgün görünümüne geri yükler.

Not

Kabuk (Shell), dosyaları taşımak için kesme/yapıştırma işlemi kullanıldığında, yapıştırma sırasında otomatik silme işlemini genellikle kullanır. Shell nesneleriyle yapılan yapıştırma-silme işlemleri normalde dosyaları taşımak için iyileştirilmiş taşıma kullanır. Shell veri aktarımını düzgün bir şekilde işlemek için, uygulamanızın yapıştırma işlemleri sırasında silme komutlarını algılayabilmesi ve işleyebilmesi gerekir.

 

Yapıştırmada silme işleminin temel gereksinimi, hedefin işlemin sonucunu kaynağa raporlaması gerektiğidir. Ancak, standart Pano teknikleri hedefin kaynakla iletişim kurmasını sağlayamadığından yapıştırmada silme işlemi gerçekleştirmek için kullanılamaz. Bunun yerine hedef uygulama, sonucu veri nesnesine raporlamak için veri nesnesinin IDataObject::SetData yöntemini kullanır. Veri nesnesi daha sonra özel bir arabirim aracılığıyla kaynakla iletişim kurabilir.

Yapıştırma ile silme işleminin temel yordamı aşağıdaki gibidir:

  1. Kaynak, seçili verilerin ekran görüntüsünü işaretler.
  2. Kaynak bir veri nesnesi oluşturur. Bir kesme işlemini belirtir ve veri değeri DROPEFFECT_MOVE olan CFSTR_PREFERREDDROPEFFECT formatını ekler.
  3. Kaynak, OleSetClipboardkullanarak veri nesnesini Pano'ya yerleştirir.
  4. Hedef, OleGetClipboardkullanarak panodan veri nesnesini alır.
  5. Hedef, CFSTR_PREFERREDDROPEFFECT verilerini ayıklar. Yalnızca DROPEFFECT_MOVE olarak ayarlanırsa, hedef iyileştirilmiş bir taşıma yapabilir veya yalnızca verileri kopyalayabilir.
  6. Eğer hedef optimize edilmiş bir hareket yapmazsa, CFSTR_PERFORMEDDROPEFFECT formatı DROPEFFECT_MOVE olarak ayarlanmış IDataObject::SetData yöntemini çağırır.
  7. Yapıştırma işlemi tamamlandığında, hedef IDataObject::SetData yöntemini, DROPEFFECT_MOVE olarak ayarlanmış CFSTR_PASTESUCCEEDED biçimiyle çağırır.
  8. Kaynağın IDataObject::SetData yöntemi DROPEFFECT_MOVE olarak ayarlanmış CFSTR_PASTESUCCEEDED biçimiyle çağrıldığında, DROPEFFECT_MOVE olarak ayarlanmış CFSTR_PERFORMEDDROPEFFECT biçiminin de alınıp alınmadığını denetlemesi gerekir. Her iki biçim de hedef tarafından gönderilirse, kaynağın verileri silmesi gerekir. Yalnızca CFSTR_PASTESUCCEEDED biçimi alınırsa, kaynak verileri görüntüden kaldırabilir. Aktarım başarısız olursa, kaynak görüntüyü özgün görünümüne güncelleştirir.

Sanal Klasörlere ve Sanal Klasörlerden Veri Aktarma

Senaryosu: Kullanıcı bir nesneyi sanal klasörden sürükler veya bir sanal klasöre bırakır.

Sanal klasörler genellikle dosya sisteminin parçası olmayan nesneler içerir. Geri Dönüşüm Kutusu gibi bazı sanal klasörler, sabit diskte depolanan verileri temsil edebilir, ancak sıradan dosya sistemi nesneleri olarak gösterilmez. Bazıları, el bilgisayarı veya FTP sitesi gibi uzak bir sistemde depolanan verileri temsil edebilir. Yazıcılar klasörü gibi diğerleri, depolanan verileri hiç temsil etmeyen nesneler içerir. Bazı sanal klasörler sistemin bir parçası olsa da, geliştiriciler bir ad alanı uzantısı uygulayarak özel sanal klasörler oluşturabilir ve yükleyebilir.

Verilerin türüne veya nasıl depolandığına bakılmaksızın, sanal klasörün içerdiği klasör ve dosya nesneleri, Normal dosya ve klasörlermiş gibi Shell tarafından sunulur. Sanal klasörün içerdiği verileri alıp uygun şekilde Shell'e sunmak, sanal klasörün sorumluluğundadır. Bu gereksinim, sanal klasörlerin normalde sürükle ve bırak ve Pano veri aktarımlarını desteklediği anlamına gelir.

Bu nedenle, sanal klasörlere ve sanal klasörlerden veri aktarımıyla ilgilenmesi gereken iki geliştirici grubu vardır:

  • Uygulamaları sanal klasörden aktarılan verileri kabul etmek zorunda olan geliştiriciler.
  • Veri aktarımını düzgün bir şekilde desteklemesi gereken ad alanı uzantılarına ihtiyacı olan geliştiriciler.

Sanal Klasörden Veri Kabul Etme

Sanal klasörler neredeyse her tür veriyi temsil edebilir ve bu verileri istedikleri şekilde depolayabilir. Bazı sanal klasörler aslında normal dosya sistemi dosyaları ve klasörleri içerebilir. Örneğin, diğerleri tüm nesnelerini tek bir belgede veya veritabanında paketleyebilir.

Bir dosya sistemi nesnesi bir uygulamaya aktarıldığında, veri nesnesi normalde nesnenin tam yolunu içeren bir CF_HDROP biçimi içerir. Uygulamanız bu dizeyi ayıklayabilir ve normal dosya sistemi işlevlerini kullanarak dosyayı açabilir ve verilerini ayıklayabilir. Ancak, sanal klasörler normalde normal dosya sistemi nesneleri içermediğinden, genellikle CF_HDROPkullanmaz.

CF_HDROPyerine, veriler normalde CFSTR_FILEDESCRIPTOR/CFSTR_FILECONTENTS biçimleriyle sanal klasörlerden aktarılır. CFSTR_FILECONTENTS biçiminin CF_HDROPgöre iki avantajı vardır:

  • Herhangi bir veri depolama yöntemi varsayılmaz.
  • Biçim daha esnektir. Üç veri aktarım mekanizmasını destekler: genel bellek nesnesi, IStream arabirimi veya IStorage arabirimi.

Verilerin tamamen belleğe kopyalanması gerektiğinden, genel bellek nesneleri sanal nesnelere veya sanal nesnelerden veri aktarmak için nadiren kullanılır. Arabirim işaretçisini aktarmak neredeyse hiç bellek gerektirmez ve çok daha verimlidir. Çok büyük dosyalarda, tek pratik veri aktarım mekanizması arabirim işaretçisi olabilir. Veriler genellikle IStream işaretçisiyle temsil edilir, çünkü bu arabirim IStoragearabiriminden biraz daha esnektir. Hedef, işaretçiyi veri nesnesinden ayıklar ve verileri ayıklamak için arabirim yöntemlerini kullanır.

CFSTR_FILEDESCRIPTOR/CFSTR_FILECONTENTS formatlarını işleme hakkında daha fazla tartışma için bkz. Bir Dosyadan Veri Ayıklamak için CFSTR_FILECONTENTS Formatını Kullanma.

NameSpace Uzantısına ve Uzantıdan Veri Aktarma

Bir ad alanı uzantısı uyguladığınızda normalde sürükle ve bırak özelliklerini desteklemek istersiniz. Genel Yönergelerbölümünde açıklanan kaynak ve hedef noktalarını bırakma önerilerini izleyin. Özellikle bir ad alanı uzantısı şunları yapmalıdır:

  • CFSTR_FILEDESCRIPTOR/CFSTR_FILECONTENTS biçimlerini işleyebilme. Bu iki biçim normalde nesneleri ad alanı uzantılarına ve uzantılarından aktarmak için kullanılır.
  • iyileştirilmiştaşımaları işleyebilir. Shell, Shell nesnelerinin optimize edilmiş bir şekilde taşınmasını bekler.
  • yapıştırma silme işlemini işleyebilme. Shell, nesneler bir kesme/yapıştırma işlemiyle Shell'den taşındığında yapıştırmada silme işlemini kullanır.
  • IStream veya IStorage arabirimi aracılığıyla veri aktarımını işleyebilme. Bir sanal klasöre veya sanal klasörden veri aktarımı normalde bu iki arabirim işaretçisinden biri( genellikle bir IStream işaretçisi) aktarılarak işlenir. Hedef daha sonra verileri ayıklamak için arabirim yöntemlerini çağırır:
      • Bırakma kaynağı olarak, ad alanı uzantısının verileri depolama alanından ayıklaması ve bu arabirim aracılığıyla hedefe aktarması gerekir.
      • Bırakma hedefi olarak, ad alanı uzantısının bu arabirim aracılığıyla bir kaynaktan verileri kabul etmesi ve düzgün şekilde depolaması gerekir.

Dosyaları Geri Dönüşüm Kutusuna Bırakma

Senaryosu: Kullanıcı Geri Dönüşüm Kutusu'na bir dosya bırakır. Uygulamanız veya ad alanı uzantınız özgün dosyayı siler.

Geri Dönüşüm Kutusu, artık gerekli olmayan dosyalar için depo olarak kullanılan bir sanal klasördür. Geri Dönüşüm Kutusu boşaltılmadığı sürece, kullanıcı daha sonra dosyayı kurtarabilir ve dosya sistemine döndürebilir.

Çoğunlukla, Shell nesnelerini Geri Dönüşüm Kutusu'na aktarmak diğer tüm klasörlerde olduğu gibi çalışır. Ancak, kullanıcı Geri Dönüşüm Kutusu'nabir dosya bırakdığında, klasörden gelen geri bildirim kopyalama işlemini gösteriyor olsa bile kaynağın özgün dosyayı silmesi gerekir. Normalde, bırakma kaynağının veri nesnesinin hangi klasöre bırakıldığını bilmesi mümkün değildir. Ancak, Windows 2000 ve sonraki sistemlerde, bir veri nesnesi Geri Dönüşüm Kutusuüzerine bırakıldığında, Kabuk, veri nesnesinin IDataObject::SetData yöntemini, Geri Dönüşüm Kutusu'nun sınıf tanımlayıcısına (CLSID) (CLSID_RecycleBin) ayarlanmış CFSTR_TARGETCLSID formatı ile çağırır. Geri Dönüşüm Kutusu servis talebini düzgün bir şekilde işlemek için veri nesnenizin bu biçimi tanıyabilmesi ve bilgileri özel bir arabirim aracılığıyla kaynağa iletebilmesi gerekir.

Not

IDataObject::SetData CLSID_RecycleBin olarak ayarlanmış bir CFSTR_TARGETCLSID biçimiyle çağrıldığında, veri kaynağı yönteme geri dönmeden önce aktarılacak nesnelerin açık tutamaçlarını kapatmalıdır. Aksi takdirde paylaşım ihlalleri oluşturabilirsiniz.

 

İskarta Dosyalarını Oluşturma ve İçe Aktarma

Senaryosu: Kullanıcı ole uygulamasının veri dosyasından bazı verileri sürükleyip masaüstüne veya Windows Gezgini'ne bırakır.

Windows, kullanıcıların ole uygulamasının veri dosyasındaki bir nesneyi sürükleyip masaüstüne veya dosya sistemi klasörüne bırakmasına olanak tanır. Bu işlem, verileri veya verilere bağlantıyı içeren bir ıskarta dosyasıoluşturur. Dosya adı, nesnenin CLSID'sine ve CF_TEXT verilerine kayıtlı kısa addan alınır. Shell'in veri içeren bir ıskarta dosyası oluşturması için uygulamanın IDataObject arabiriminin CF_EMBEDSOURCE Pano biçimini desteklemesi gerekir. Bağlantı içeren bir dosya oluşturmak için IDataObject CF_LINKSOURCE biçimini desteklemelidir.

Ayrıca, bir uygulamanın hurda dosyalarını desteklemek için uygulayabileceği üç isteğe bağlı özellik de vardır:

  • Gidiş dönüş desteği
  • Önbelleğe alınan veri biçimleri
  • Gecikmeli işleme

Gidiş Dönüş Desteği

gidiş dönüş, bir veri nesnesini başka bir kapsayıcıya aktarmayı ve ardından özgün belgeye geri dönmeyi içerir. Örneğin, kullanıcı bir grup hücreyi elektronik tablodan masaüstüne aktararak verilerle birlikte bir atık dosyası oluşturabilir. Kullanıcı daha sonra hurdayı elektronik tabloya geri aktarırsa, verilerin özgün aktarımdan önceki gibi belgeyle tümleştirilmesi gerekir.

Kabuk, hurda dosyası oluşturduğunda, verileri bir gömme nesne olarak temsil eder. Hurda başka bir kapsayıcıya aktarıldığında, özgün belgeye döndürülse bile ekleme nesnesi olarak aktarılır. Uygulamanız, ıskartada yer alan veri biçimini belirlemek ve gerekirse verileri yerel biçimine geri koymakla sorumludur.

Katıştırılmış nesnenin biçimini oluşturmak için, nesnenin CF_OBJECTDESCRIPTOR biçimini alarak CLSID'sini belirleyin. CLSID uygulamaya ait bir veri biçimini gösteriyorsa olecreateFromDataçağırmak yerine yerel verileri aktarması gerekir.

Önbelleğe Alınan Veri Biçimleri

Shell ortamı bir geçici dosya oluşturduğunda, kullanılabilir formatların listesini almak için kayıt defterini denetler. Varsayılan olarak iki biçim vardır: CF_EMBEDSOURCE ve CF_LINKSOURCE. Ancak, uygulamaların farklı biçimlerde hurda dosyalarına sahip olması gerekebilecek çeşitli senaryolar vardır:

  • Artıkların, katıştırılmış nesne biçimlerini kabul edemeyen OLE dışı kapsayıcılara aktarılmasına olanak sağlamak için.
  • Uygulama paketlerinin özel biçimle iletişim kurmasına izin vermek için.
  • Gidiş dönüşleri daha kolay idare etmek için.

Uygulamalar, kayıt defterinde önbelleğe alarak ıskartaya biçim ekleyebilir. İki tür önbelleğe alınmış biçim vardır:

  • Öncelikli önbellek formatları. Bu biçimler için veriler tamamen veri nesnesinden ıskartaya kopyalanır.
  • Gecikmeli işleme tabii tutulan biçimler. Bu biçimler için veri nesnesi ıskartaya kopyalanmaz. Bunun yerine, hedef verileri isteyene kadar işlem ertelenir. Gecikmeli işleme, sonraki bölümde daha ayrıntılı olarak açıklanmıştır.

Öncelik önbelleği veya gecikmeli işlenen biçim eklemek için, verilerin kaynağı olan uygulamanın CLSID anahtarı altında DataFormat alt anahtarı oluşturun. Bu alt anahtar altında bir PriorityCacheFormats veya DelayRenderFormats alt anahtarı oluşturun. Her öncelik önbelleği veya gecikmeli işlenen biçim için sıfırdan başlayarak numaralandırılmış bir alt anahtar oluşturun. Bu anahtarın değerini, biçimin kayıtlı adına sahip bir dize veya #X değeri olarak ayarlayın; burada X, standart pano biçiminin biçim numarasını temsil eder.

Aşağıdaki örnekte iki uygulama için önbelleğe alınmış biçimler gösterilmektedir. MyProg1 uygulaması, öncelikli önbellek biçimi olarak zengin metin biçimini ve gecikmeli işlenmiş biçim olarak özel "Biçimim" biçimini kullanır. MyProg2 uygulaması, öncelik önbellek biçimi olarak CF_BITMAP biçimine (#8") sahiptir.

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

Ek numaralandırılmış alt anahtarlar oluşturularak ek biçimler eklenebilir.

Gecikmeli Oluşturma

Gecikmeli işleme biçimi, bir uygulamanın ıskarta dosyası oluşturmasına olanak tanır, ancak hedef tarafından istenene kadar verileri işleme masrafını geciktirir. Bir hurdanın IDataObject arabirimi, yerel ve önbelleğe alınmış verilerle birlikte hedefe gecikmeli oluşturma biçimlerini sunacaktır. Hedef gecikmeli işleme biçimi isterse Shell uygulamayı çalıştırır ve etkin nesneden hedefe veri sağlar.

Not

Gecikmeli işleme biraz riskli olduğundan dikkatli kullanılmalıdır. Sunucu kullanılamıyorsa veya OLE etkin olmayan uygulamalarda çalışmaz.

 

Kabuk Nesnelerini Eşzamansız Olarak Sürükleme ve Bırakma

Senaryosu: Kullanıcı büyük bir veri bloğunu kaynaktan hedefe aktarır. Her iki uygulamanın da uzun bir süre engellenmesini önlemek için hedef verileri eşzamanlı olmayan bir şekilde ayıklar.

Normalde sürükle ve bırak zaman uyumlu bir işlemdir. Kısaca:

  1. Bırakma kaynağı DoDragDrop çağırır ve işlev dönene kadar birincil iş parçacığını engeller. Birincil iş parçacığının engellenmesi normalde kullanıcı arabirimi işlemeyi engeller.
  2. Hedefin IDropTarget::D rop yöntemi çağrıldıktan sonra hedef, birincil iş parçacığındaki veri nesnesinden verileri ayıklar. Bu yordam normalde ayıklama işlemi boyunca hedefin kullanıcı arabirimi işlemesini engeller.
  3. Veriler ayıklandıktan sonra hedef, IDropTarget::Drop çağrısını geri döndürür, sistem DoDragDropgeri döndürür ve her iki iş parçacığı da devam edebilir.

Kısacası, zaman uyumlu veri aktarımı her iki uygulamanın birincil iş parçacıklarını önemli bir süre engelleyebilir. Özellikle, hedef verileri ayıklarken her iki iş parçacığının da beklemesi gerekir. Az miktarda veri için, verileri ayıklamak için gereken süre küçüktür ve zaman uyumlu veri aktarımı oldukça iyi çalışır. Ancak, büyük miktarda veriyi zaman uyumlu bir şekilde ayıklamak uzun gecikmelere neden olabilir ve hem hedef hem de kaynağın kullanıcı arabirimini etkileyebilir.

IAsyncOperation/IDataObjectAsyncCapability arabirimi, bir veri nesnesi tarafından uygulanabilen isteğe bağlı bir arabirimdir. Bırakma hedefine, veri nesnesinden veri ayıklamayı arka plan işlemi üzerinde zaman uyumsuz olarak gerçekleştirme yeteneği verir. Veri çıkarma işlemi arka plan iş parçacığına teslim edildikten sonra, her iki uygulamanın da birincil iş parçacıkları serbestçe çalışmaya devam edebilir.

IASyncOperation/IDataObjectAsyncCapability Kullanımı

Not

Arabirim ilk olarak IAsyncOperationolarak adlandırıldı, ancak bu daha sonra IDataObjectAsyncCapabilityolarak değiştirildi. Aksi takdirde, iki arabirim aynıdır.

 

IAsyncOperation/IDataObjectAsyncCapability amacı, bırakma kaynağı ve bırakma hedefinin verilerin zaman uyumsuz olarak ayıklanıp ayıklanamayacağını pazarlık yapmasına olanak sağlamaktır. Aşağıdaki yordam, sürükleme kaynağının arabirimini nasıl kullandığını özetler.

  1. IAsyncOperation/IDataObjectAsyncCapabilitykullanıma sunan bir veri nesnesi oluşturun.
  2. çağrısı, zaman uyumsuz bir işlemin desteklendiğini belirtmek için fDoOpAsync, VARIANT_TRUE olarak ayarlanmış SetAsyncMode ile yapılır.
  3. DoDragDrop döndürdükten sonra InOperationçağrısı yapın:
    • InOperation başarısız olursa veya VARIANT_FALSEdöndürürse, normal bir zaman uyumlu veri aktarımı gerçekleştirilir ve veri ayıklama işlemi tamamlanır. Kaynak, gerekli tüm temizlemeleri yapmalı ve devam etmelidir.
    • InOperationVARIANT_TRUEdöndürürse, veriler zaman uyumsuz şekilde ayıklanıyor. Temizleme işlemleri EndOperationtarafından işlenmelidir.
  4. Veri nesnesini serbest bırakın.
  5. Zaman uyumsuz veri aktarımı tamamlandığında, veri nesnesi normalde özel bir arabirim aracılığıyla kaynağa bildirir.

Aşağıdaki yordamda, bırakma hedefinin verileri zaman uyumsuz olarak ayıklamak için IDataObjectAsyncCapabilityarabirimini IAsyncOperation/nasıl kullandığı özetlenmiştir:

  1. Sistem IDropTarget::Dropçağırdığında, IDataObject::QueryInterface çağırın ve veri nesnesinden IAsyncOperation/IDataObjectAsyncCapability arabirimini (IID_IAsyncOperation/IID_IDataObjectAsyncCapability) isteyin.
  2. GetAsyncModeçağrısı. yöntemi VARIANT_TRUEdöndürürse, veri nesnesi zaman uyumsuz veri ayıklamayı destekler.
  3. Veri ayıklamayı ele almak ve StartOperationçağırmak için ayrı bir iş parçacığı oluşturun.
  4. Normal bir veri aktarımı işlemi için yaptığınız gibi IDropTarget::D rop çağrısını döndürebilirsiniz. DoDragDrop geri döner ve sürükleme kaynağının engelini kaldırır. İyileştirilmiş bir taşıma veya yapıştırmayı silme işleminin sonucunu belirtmek için IDataObject::SetDataçağırmayın. İşlem tamamlanana kadar bekleyin.
  5. Arka plan iş parçacığındaki verileri ayıklayın. Hedefin birincil iş parçacığının engeli kaldırılmıştır ve devam etmeye hazırdır.
  6. Veri aktarımı, iyileştirilmiş bir taşıma veya yapıştırma silme işlemiyse, sonucu belirtmek için IDataObject::SetDataçağırın.
  7. EndOperationçağırarak veri nesnesine ayıklamanın tamamlandığını bildirin.