Bagikan melalui


Menginisialisasi Handler Ekstensi Shell

Sebagian besar implementasi objek handler ekstensi Shell ditentukan oleh jenisnya. Namun, ada beberapa elemen umum. Topik ini membahas aspek implementasi yang dibagikan oleh semua penangan ekstensi Shell.

Semua penangan ekstensi Shell adalah objek Model Objek Komponen (COM) dalam proses. Mereka harus diberi GUID dan terdaftar seperti yang dijelaskan dalam Mendaftarkan Penangan Ekstensi Shell. Mereka diimplementasikan sebagai DLL dan harus mengekspor fungsi standar berikut:

  • DllMain. Titik masuk standar ke DLL.
  • DllGetClassObject. Mengekspos pabrik kelas objek.
  • DllCanUnloadNow. COM memanggil fungsi ini untuk menentukan apakah objek melayani klien mana pun. Jika tidak, sistem dapat membongkar DLL dan membebaskan memori terkait.

Seperti semua objek COM, handler ekstensi Shell harus mengimplementasikan antarmuka IUnknown dan pabrik kelas. Sebagian besar juga harus mengimplementasikan antarmuka IPersistFile atau IShellExtInit di Windows XP atau yang lebih lama. Ini digantikan oleh IInitializeWithStream, IInitializeWithItem dan IInitializeWithFile di Windows Vista. Shell menggunakan antarmuka ini untuk menginisialisasi handler.

Antarmuka IPersistFile harus diimplementasikan dengan cara berikut:

  • Penangan ikon
  • Penangan data
  • Jatuhkan handler

Antarmuka IShellExtInit harus diimplementasikan dengan cara berikut:

  • Penangan menu pintasan
  • Penangan seret dan letakkan
  • Penangan lembar properti

Subjek berikut dibahas di sisa topik ini:

Menerapkan IPersistFile

Antarmuka IPersistFile dirancang untuk memungkinkan objek dimuat dari atau disimpan ke file disk. Ini memiliki enam metode selain IUnknown, lima dari sendiri, dan metode GetClassID yang diwarisi dari IPersist. Dengan ekstensi Shell, IPersist hanya digunakan untuk menginisialisasi objek handler ekstensi Shell. Karena biasanya tidak perlu membaca dari atau menulis ke disk, hanya metode GetClassID dan Load yang memerlukan implementasi nontoken.

Shell memanggil GetClassID terlebih dahulu, dan fungsi mengembalikan pengidentifikasi kelas (CLSID) dari objek handler ekstensi. Shell kemudian memanggil Muat dan meneruskan dua nilai. Yang pertama, pszFile, adalah string Unicode dengan nama file atau folder yang akan dioperasikan Shell. Yang kedua adalah dwMode, yang menunjukkan mode akses file. Karena biasanya tidak perlu mengakses file, dwMode biasanya nol. Metode ini menyimpan nilai-nilai ini sesuai kebutuhan untuk referensi nanti.

Fragmen kode berikut menggambarkan bagaimana handler ekstensi Shell yang khas mengimplementasikan metode GetClassID dan Load . Ini dirancang untuk menangani ANSI atau Unicode. CLSID_SampleExtHandler adalah GUID objek handler ekstensi, dan CSampleShellExtension adalah nama kelas yang digunakan untuk mengimplementasikan antarmuka. Variabel m_szFileName dan m_dwMode adalah variabel privat yang digunakan untuk menyimpan nama file dan bendera akses.

class CSampleShellExtension : public IPersistFile
{
    // Method declarations not included

    private:
    WCHAR m_szFileName[MAX_PATH];    // The file name
    DWORD m_dwMode;                  // The file access mode
}

IFACEMETHODIMP CSampleShellExtension::GetClassID(__out CLSID *pCLSID)
{
    *pCLSID = CLSID_SampleExtHandler;
}

IFACEMETHODIMP CSampleShellExtension::Load(PCWSTR pszFile, DWORD dwMode)
{
    m_dwMode = dwMode;
    return StringCchCopy(m_szFileName, ARRAYSIZE(m_szFileName), pszFile); 
}

// The implementation sample is continued in the next section.

Menerapkan IShellExtInit

Antarmuka IShellExtInit hanya memiliki satu metode, IShellExtInit::Initialize, selain IUnknown. Metode ini memiliki tiga parameter yang dapat digunakan Shell untuk meneruskan berbagai jenis informasi. Nilai yang diteruskan bergantung pada jenis handler, dan beberapa dapat diatur ke NULL.

  • pidlFolder menyimpan penunjuk folder ke daftar pengidentifikasi item (PIDL). Ini adalah PIDL absolut. Untuk ekstensi lembar properti, nilai ini adalah NULL. Untuk ekstensi menu pintasan, ini adalah PIDL folder yang berisi item yang menu pintasannya sedang ditampilkan. Untuk penangan seret dan letakkan nondefault, ini adalah PIDL folder target.
  • pDataObject memegang penunjuk ke antarmuka IDataObject objek data. Objek data menyimpan satu atau beberapa nama file dalam format CF_HDROP .
  • hRegKey menyimpan kunci registri untuk objek file atau jenis folder.

Metode IShellExtInit::Initialize menyimpan nama file, penunjuk IDataObject , dan kunci registri sesuai kebutuhan untuk digunakan nanti. Fragmen kode berikut mengilustrasikan implementasi IShellExtInit::Initialize. Untuk kesederhanaan, contoh ini mengasumsikan bahwa objek data hanya berisi satu file. Secara umum, objek data mungkin berisi beberapa file, yang masing-masing perlu diekstraksi.

// This code continues the CSampleShellExtension sample shown in the
// "Implementing IPersistFile" section above.

class CSampleShellExtension : public IShellExtInit
{
    // Method declarations not included
    
    private:
    // IDList of the folder for extensions invoked on the folder, such as 
    // background context menu handlers or nondefault drag-and-drop handlers. 
    PIDLIST_ABSOLUTE m_pidlFolder;
    
    // The data object contains an expression of the items that the handler is 
    // being initialized for. Use SHCreateShellItemArrayFromDataObject to 
    // convert this object to an array of items. Use SHGetItemFromObject if you
    // are only interested in a single Shell item. If you need a file system
    // path, use IShellItem::GetDisplayName(SIGDN_FILESYSPATH, ...).
    IDataObject *m_pdtobj;
    
    // For context menu handlers, the registry key provides access to verb 
    // instance data that might be stored there. This is a rare feature to use 
    // so most extensions do not need this variable.
    HKEY m_hRegKey;             
}
    
// This method must be very efficient. Do not do any unnecessary work here.
// Use Initialize to acquire resources that will be used later.

IFACEMETHODIMP CSampleShellExtension::Initialize(__in_opt PCIDLIST_ABSOLUTE pidlFolder,
                                                 __in_opt IDataObject *pDataObject, 
                                                 __in_opt HKEY hRegKey) 
{ 
    // In some cases, handlers are initialized multiple times. Therefore, 
    // clear any previous state here.
    CoTaskMemFree(m_pidlFolder);
    m_pidlFolder = NULL;
    
    if (m_pdtobj)
    { 
        m_pdtobj->Release(); 
    }
    
    if (m_hRegKey)
    {
        RegCloseKey(m_hRegKey);
        m_hRegKey = NULL;
    }
    
    // Capture the inputs for use later.
    HRESULT hr = S_OK;
    
    if (pidlFolder)
    {
        m_pidlFolder = ILClone(pidlFolder);   // Make a copy to use later.
        hr = m_pidlFolder ? S_OK : E_OUTOFMEMORY;
    }
    
    if (SUCCEEDED(hr))
    {
        // If a data object pointer was passed into the method, save it and
        // extract the file name. 
        if (pDataObject) 
        { 
            m_pdtobj = pDataObject; 
            m_pdtobj->AddRef(); 
        }
    
        // It is uncommon to use the registry handle, but if you need it,
        // duplicate it now.
        if (hRegKey)
        {
            LSTATUS const result = RegOpenKeyEx(hRegKey, NULL, 0, KEY_READ, &m_hRegKey); 
            hr = HRESULT_FROM_WIN32(result);
        }
    }
    
    return hr;
}

Kustomisasi Infotip

Ada dua cara untuk menyesuaikan infotip. Salah satu caranya adalah dengan mengimplementasikan objek yang mendukung IQueryInfo dan kemudian mendaftarkan objek di bawah subkuntang yang tepat di registri (lihat di bawah). Atau, Anda dapat menentukan string tetap atau daftar properti file tertentu yang akan ditampilkan.

Untuk menampilkan string tetap untuk ekstensi namespace, buat subkunci yang disebut InfoTip di bawah kunci CLSID ekstensi namespace Anda. Atur data subkunci tersebut menjadi string yang ingin Anda tampilkan.

HKEY_CLASSES_ROOT
   CLSID
      {CLSID}
         InfoTip = InfoTip string for your namespace extension

Untuk menampilkan string tetap untuk jenis file, buat subkunci yang disebut InfoTip di bawah kunci ProgID dari jenis file yang ingin Anda berikan infotip. Atur data subkunci tersebut menjadi string yang ingin Anda tampilkan.

HKEY_CLASSES_ROOT
   ProgID
      InfoTip = InfoTip string for all files of this type

Jika Anda ingin Shell menampilkan properti file tertentu di infotip untuk jenis file tertentu, buat subkunci yang disebut InfoTip di bawah kunci ProgID dari jenis file tersebut. Atur data subkunci tersebut menjadi daftar nama properti kanonis yang digambarkan titik koma atau {fmtid}, pasangan pid di mana nama propname adalah nama properti kanonis dan {fmtid},pid adalah pasangan FMTID/PID.

HKEY_CLASSES_ROOT
   ProgID
      InfoTip = propname;propname;{fmtid},pid;{fmtid},pid

Nama properti berikut dapat digunakan.

Nama Properti Deskripsi Diambil Dari
Penulis Penulis dokumen PIDSI_AUTHOR
Judul Judul dokumen PIDSI_TITLE
Subjek Ringkasan subjek PIDSI_SUBJECT
Komentar Komentar dokumen PIDSI_COMMENT atau properti folder/drive
PageCount Jumlah halaman PIDSI_PAGECOUNT
Nama Nama yang mudah diingat Tampilan folder standar
OriginalLocation Lokasi file asli Folder tas kerja dan folder Keranjang Sampah
DateDeleted File tanggal dihapus Folder Keranjang Sampah
Jenis Jenis file Tampilan detail folder standar
Ukuran Ukuran file Tampilan detail folder standar
SyncCopyIn Sama seperti OriginalLocation Sama seperti OriginalLocation
Dimodifikasi Tanggal terakhir diubah Tampilan detail folder standar
Dibuat Tanggal dibuat Tampilan detail folder standar
Diakses Tanggal terakhir diakses Tampilan detail folder standar
InFolder Direktori yang berisi file Hasil pencarian dokumen
Pangkat Kualitas kecocokan pencarian Hasil pencarian dokumen
FreeSpace Ruang penyimpanan yang tersedia Disk drive
NumberOfVisits Jumlah kunjungan Folder favorit
Atribut Atribut File Tampilan detail folder standar
Perusahaan Nama perusahaan PIDDSI_COMPANY
Kategori Kategori dokumen PIDDSI_CATEGORY
Hak Cipta Hak cipta media PIDMSI_COPYRIGHT
HTMLInfoTipFile File InfoTip HTML Desktop.ini file untuk folder

 

Mendaftarkan Handler Ekstensi Shell