Bekerja dengan Galeri

Kerangka kerja Windows Ribbon memberi pengembang model yang kuat dan konsisten untuk mengelola konten dinamis di berbagai kontrol berbasis koleksi. Dengan mengadaptasi dan mengonfigurasi ulang UI Pita, kontrol dinamis ini memungkinkan kerangka kerja merespons interaksi pengguna di aplikasi host dan Pita itu sendiri, dan memberikan fleksibilitas untuk menangani berbagai lingkungan run time.

Pengantar

Kemampuan kerangka kerja Pita ini untuk beradaptasi secara dinamis dengan kondisi run-time, persyaratan aplikasi, dan input pengguna akhir menyoroti kemampuan UI yang kaya dari kerangka kerja, dan memberi pengembang fleksibilitas untuk memenuhi berbagai kebutuhan pelanggan.

Fokus dari panduan ini adalah untuk menggambarkan kontrol galeri dinamis yang didukung oleh kerangka kerja, menjelaskan perbedaannya, mendiskusikan kapan dan di mana mereka dapat digunakan dengan baik, dan menunjukkan bagaimana mereka dapat dimasukkan ke dalam aplikasi Pita.

Galeri

Galeri adalah kontrol kotak daftar yang kaya secara fungsional dan grafis. Koleksi item galeri dapat diatur berdasarkan kategori, ditampilkan dalam tata letak berbasis kolom dan baris yang fleksibel, diwakili dengan gambar dan teks, dan tergantung pada jenis galeri, mendukung pratinjau langsung.

Galeri secara fungsional berbeda dari kontrol Pita dinamis lainnya karena alasan berikut:

  • Galeri mengimplementasikan antarmuka IUICollection yang menentukan berbagai metode untuk memanipulasi koleksi item galeri.
  • Galeri dapat diperbarui pada durasi, berdasarkan aktivitas yang terjadi langsung di Pita, seperti saat pengguna menambahkan Perintah ke Toolbar Akses Cepat (QAT).
  • Galeri dapat diperbarui pada durasi, berdasarkan aktivitas yang terjadi secara tidak langsung dari lingkungan run-time, seperti ketika driver printer hanya mendukung tata letak halaman potret.
  • Galeri dapat diperbarui pada durasi, berdasarkan aktivitas yang terjadi secara tidak langsung di aplikasi host, seperti saat pengguna memilih item dalam dokumen.

Kerangka kerja Pita memaparkan dua jenis galeri: galeri item dan galeri Perintah.

Galeri Item

Galeri item berisi kumpulan item terkait berbasis indeks di mana setiap item diwakili oleh gambar, string, atau keduanya. Kontrol terikat ke satu handler Perintah yang bergantung pada nilai indeks yang diidentifikasi oleh properti UI_PKEY_SelectedItem .

Galeri item mendukung pratinjau langsung, yang berarti menampilkan hasil Perintah, berdasarkan mouseover atau fokus, tanpa berkomitmen atau benar-benar memanggil Perintah.

Penting

Kerangka kerja tidak mendukung galeri item hosting di Menu Aplikasi.

 

Galeri Perintah

Galeri perintah berisi kumpulan item yang berbeda dan tidak diindeks. Setiap item diwakili oleh satu kontrol yang terikat ke handler Perintah melalui ID Perintah. Seperti kontrol mandiri, setiap item di galeri Perintah merutekan peristiwa input ke penangan Perintah terkait—galeri Perintah itu sendiri tidak mendengarkan peristiwa.

Galeri perintah tidak mendukung pratinjau langsung.

Ada empat kontrol galeri dalam kerangka kerja Pita: DropDownGallery, SplitButtonGallery, InRibbonGallery, dan ComboBox. Semua kecuali ComboBox dapat diimplementasikan sebagai galeri item atau galeri Perintah.

DropDownGallery adalah tombol yang menampilkan daftar drop-down yang berisi kumpulan item atau Perintah yang saling eksklusif.

Cuplikan layar berikut mengilustrasikan kontrol Galeri Turun Bawah Pita di Microsoft Paint untuk Windows 7.

cuplikan layar kontrol galeri drop-down di microsoft paint untuk windows 7.

SplitButtonGallery

SplitButtonGallery adalah kontrol komposit yang mengekspos item default tunggal atau Perintah dari koleksinya pada tombol utama, dan menampilkan item atau perintah lain dalam daftar drop-down yang saling eksklusif yang ditampilkan saat tombol sekunder diklik.

Cuplikan layar berikut mengilustrasikan kontrol Galeri Tombol Pisahkan Pita di Microsoft Paint untuk Windows 7.

cuplikan layar kontrol galeri tombol terpisah di microsoft paint untuk windows 7.

InRibbonGallery

InRibbonGallery adalah galeri yang menampilkan kumpulan item atau Perintah terkait di Pita. Jika ada terlalu banyak item di galeri, panah perluas disediakan untuk menampilkan koleksi lainnya di panel yang diperluas.

Cuplikan layar berikut mengilustrasikan kontrol Galeri Pita Di Pita di Microsoft Paint untuk Windows 7.

cuplikan layar kontrol galeri di pita di pita cat microsoft.

ComboBox

ComboBox adalah kotak daftar kolom tunggal yang berisi kumpulan item dengan kontrol statis atau kontrol edit dan panah dropdown. Bagian kotak daftar kontrol ditampilkan saat pengguna mengklik panah turun bawah.

Cuplikan layar berikut mengilustrasikan kontrol Kotak Kombo Pita dari Windows Live Movie Maker.

cuplikan layar kontrol kombobox di pita cat microsoft.

Karena ComboBox secara eksklusif merupakan galeri item, itu tidak mendukung item Perintah. Ini juga merupakan satu-satunya kontrol galeri yang tidak mendukung Ruang Perintah. (Ruang Perintah adalah kumpulan Perintah yang dideklarasikan dalam markup dan tercantum di bagian bawah galeri item atau galeri Perintah.)

Contoh kode berikut menunjukkan markup yang diperlukan untuk mendeklarasikan Ruang Perintah tiga tombol di DropDownGallery.

<DropDownGallery 
  CommandName="cmdSizeAndColor" 
  TextPosition="Hide" 
  Type="Commands"
  ItemHeight="32"
  ItemWidth="32">
  <DropDownGallery.MenuLayout>
    <FlowMenuLayout Rows="2" Columns="3" Gripper="None"/>
  </DropDownGallery.MenuLayout>
  <Button CommandName="cmdCommandSpace1"/>
  <Button CommandName="cmdCommandSpace2"/>
  <Button CommandName="cmdCommandSpace3"/>
</DropDownGallery>

Cuplikan layar berikut mengilustrasikan Ruang Perintah tiga tombol dari contoh kode sebelumnya.

cuplikan layar ruang perintah tiga tombol di dropdowngallery.

Bagian ini membahas detail implementasi galeri Pita dan panduan cara menggabungkannya dalam aplikasi Pita.

Komponen Dasar

Bagian ini menjelaskan sekumpulan properti dan metode yang membentuk tulang punggung konten dinamis dalam kerangka kerja Pita dan mendukung penambahan, penghapusan, pembaruan, dan jika tidak memanipulasi konten dan tata letak visual galeri Pita pada durasi.

IUICollection

Galeri memerlukan serangkaian metode dasar untuk mengakses dan memanipulasi item individual dalam koleksi mereka.

Antarmuka IEnumUnknown mendefinisikan metode ini, dan kerangka kerja melengkapi fungsionalitasnya dengan metode tambahan yang ditentukan dalam antarmuka IUICollection . IUICollection diimplementasikan oleh kerangka kerja untuk setiap deklarasi galeri di markup Pita.

Jika fungsionalitas tambahan diperlukan yang tidak disediakan oleh antarmuka IUICollection , maka objek koleksi kustom yang diimplementasikan oleh aplikasi host dan berasal dari IEnumUnknown dapat digantikan untuk koleksi kerangka kerja.

IUICollectionChangedEvent

Agar aplikasi merespons perubahan dalam koleksi galeri, aplikasi harus mengimplementasikan antarmuka IUICollectionChangedEvent . Aplikasi dapat berlangganan pemberitahuan dari objek IUICollection melalui pendengar peristiwa IUICollectionChangedEvent::OnChanged .

Ketika aplikasi mengganti koleksi galeri yang disediakan oleh kerangka kerja dengan koleksi kustom, aplikasi harus mengimplementasikan antarmuka IConnectionPointContainer . Jika IConnectionPointContainer tidak diimplementasikan, maka aplikasi tidak dapat memberi tahu kerangka kerja perubahan dalam koleksi kustom yang memerlukan pembaruan dinamis pada kontrol galeri.

Dalam kasus di mana IConnectionPointContainer tidak diimplementasikan, kontrol galeri hanya dapat diperbarui dengan pembatalan melalui IUIFramework::InvalidateUICommand dan IUICommandHandler::UpdateProperty, atau dengan memanggil IUIFramework::SetUICommandProperty.

IUISimplePropertySet

Aplikasi harus menerapkan IUISimplePropertySet untuk setiap item atau Perintah dalam koleksi galeri. Namun, properti yang dapat diminta dengan IUISimplePropertySet::GetValue bervariasi.

Item ditentukan dan terikat ke galeri melalui kunci properti UI_PKEY_ItemsSource dan mengekspos properti dengan objek IUICollection .

Properti yang valid untuk item di galeri item (UI_COMMANDTYPE_COLLECTION) dijelaskan dalam tabel berikut.

Catatan

Beberapa properti item, seperti UI_PKEY_Label, dapat ditentukan dalam markup. Untuk detail selengkapnya, lihat dokumentasi referensi Kunci Properti .

 

Kontrol

Properti

ComboBox

UI_PKEY_Label, UI_PKEY_CategoryId

DropDownGallery

UI_PKEY_Label, UI_PKEY_ItemImage , UI_PKEY_CategoryId

InRibbonGallery

UI_PKEY_Label, UI_PKEY_ItemImage , UI_PKEY_CategoryId

SplitButtonGallery

UI_PKEY_Label, UI_PKEY_ItemImage, UI_PKEY_CategoryId

UI_PKEY_SelectedItem adalah properti galeri item.

 

Properti item yang valid untuk Galeri perintah (UI_COMMANDTYPE_COMMANDCOLLECTION) dijelaskan dalam tabel berikut ini.

Kontrol Properti
DropDownGallery UI_PKEY_CommandId, UI_PKEY_CommandType , UI_PKEY_CategoryId
InRibbonGallery UI_PKEY_CommandId, UI_PKEY_CommandType , UI_PKEY_CategoryId
SplitButtonGallery UI_PKEY_CommandId, UI_PKEY_CommandType, UI_PKEY_CategoryId

 

Kategori digunakan untuk menata item dan Perintah di galeri. Kategori ditentukan dan terikat ke galeri melalui kunci properti UI_PKEY_Categories dan mengekspos properti dengan objek IUICollection khusus kategori.

Kategori tidak memiliki CommandType dan tidak mendukung interaksi pengguna. Misalnya, kategori tidak dapat menjadi SelectedItem di galeri item, dan tidak terikat ke Perintah di galeri Perintah. Seperti properti item galeri lainnya, properti kategori seperti UI_PKEY_Label dan UI_PKEY_CategoryId dapat diambil dengan memanggil IUISimplePropertySet::GetValue.

Penting

IUISimplePropertySet::GetValue harus mengembalikan UI_COLLECTION_INVALIDINDEX ketika UI_PKEY_CategoryId diminta untuk item yang tidak memiliki kategori terkait.

 

Mendeklarasikan Kontrol dalam Markup

Galeri, seperti semua kontrol Pita, harus dideklarasikan dalam markup. Galeri diidentifikasi dalam markup sebagai galeri item atau galeri Perintah, dan berbagai detail presentasi dinyatakan. Tidak seperti kontrol lain, galeri hanya memerlukan kontrol dasar, atau kontainer koleksi, untuk dideklarasikan dalam markup. Koleksi aktual diisi pada durasi. Saat galeri dideklarasikan dalam markup, atribut Type digunakan untuk menentukan apakah galeri adalah galeri item galeri Command.

Ada sejumlah atribut tata letak opsional yang tersedia untuk setiap kontrol yang dibahas di sini. Atribut ini menyediakan preferensi pengembang untuk kerangka kerja untuk diikuti yang secara langsung memengaruhi bagaimana kontrol diisi dan ditampilkan dalam pita. Preferensi yang berlaku dalam markup terkait dengan templat tampilan dan tata letak dan perilaku yang dibahas dalam Menyesuaikan Pita Melalui Definisi Ukuran dan Kebijakan Penskalaan.

Jika kontrol tertentu tidak mengizinkan preferensi tata letak langsung dalam markup, atau preferensi tata letak tidak ditentukan, maka kerangka kerja menentukan konvensi tampilan khusus kontrol berdasarkan jumlah ruang layar yang tersedia.

Contoh berikut menunjukkan cara menggabungkan sekumpulan galeri ke dalam Pita.

Deklarasi Perintah

Perintah harus dideklarasikan dengan atribut CommandName yang digunakan untuk mengaitkan kontrol, atau sekumpulan kontrol, dengan Perintah.

Atribut CommandId yang digunakan untuk mengikat Perintah ke handler Perintah saat markup dikompilasi juga dapat ditentukan di sini. Jika tidak ada ID yang disediakan, maka id akan dihasilkan oleh kerangka kerja.

<!-- ComboBox -->
<Command Name="cmdComboBoxGroup"
         Symbol="cmdComboBoxGroup"
         Comment="ComboBox Group"
         LabelTitle="ComboBox"/>
<Command Name="cmdComboBox"
         Symbol="cmdComboBox"
         Comment="ComboBox"
         LabelTitle="ComboBox"/>

<!-- DropDownGallery -->
<Command Name="cmdDropDownGalleryGroup"
         Symbol="cmdDropDownGalleryGroup"
         Comment="DropDownGallery Group"
         LabelTitle="DropDownGallery"/>
<Command Name="cmdDropDownGallery"
         Symbol="cmdDropDownGallery"
         Comment="DropDownGallery"
         LabelTitle="DropDownGallery"/>

<!-- InRibbonGallery -->
<Command Name="cmdInRibbonGalleryGroup"
         Symbol="cmdInRibbonGalleryGroup"
         Comment="InRibbonGallery Group"
         LabelTitle="InRibbonGallery"/>
<Command Name="cmdInRibbonGallery"
         Symbol="cmdInRibbonGallery"
         Comment="InRibbonGallery"
         LabelTitle="InRibbonGallery"

<!-- SplitButtonGallery -->
<Command Name="cmdSplitButtonGalleryGroup"
         Symbol="cmdSplitButtonGalleryGroup"
         Comment="SplitButtonGallery Group"
         LabelTitle="SplitButtonGallery"/>
<Command Name="cmdSplitButtonGallery"
         Symbol="cmdSplitButtonGallery"
         Comment="SplitButtonGallery"
         LabelTitle="SplitButtonGallery"

Deklarasi Kontrol

Bagian ini berisi contoh yang menunjukkan markup kontrol dasar yang diperlukan untuk berbagai jenis galeri. Mereka menunjukkan cara mendeklarasikan kontrol galeri dan mengaitkannya dengan Perintah melalui atribut CommandName .

Contoh berikut menunjukkan deklarasi kontrol untuk DropDownGallery tempat atribut Type digunakan untuk menentukan bahwa ini adalah galeri Perintah.

<!-- DropDownGallery -->
<Group CommandName="cmdDropDownGalleryGroup">
  <DropDownGallery CommandName="cmdDropDownGallery"
                   TextPosition="Hide"
                   Type="Commands"
                   ItemHeight="32"
                   ItemWidth="32">
    <DropDownGallery.MenuLayout>
      <FlowMenuLayout Rows="2"
                      Columns="3"
                      Gripper="None"/>
    </DropDownGallery.MenuLayout>
    <DropDownGallery.MenuGroups>
      <MenuGroup>
        <Button CommandName="cmdButton1"></Button>
        <Button CommandName="cmdButton2"></Button>
       </MenuGroup>
       <MenuGroup>
        <Button CommandName="cmdButton3"></Button>
      </MenuGroup>
    </DropDownGallery.MenuGroups>
  </DropDownGallery>
</Group>

Contoh berikut menunjukkan deklarasi kontrol untuk SplitButtonGallery.

<!-- SplitButtonGallery -->
<Group CommandName="cmdSplitButtonGalleryGroup">
  <SplitButtonGallery CommandName="cmdSplitButtonGallery">
    <SplitButtonGallery.MenuLayout>
      <FlowMenuLayout Rows="2"
                      Columns="3"
                      Gripper="None"/>
    </SplitButtonGallery.MenuLayout>
    <SplitButtonGallery.MenuGroups>
      <MenuGroup>
        <Button CommandName="cmdButton1"></Button>
        <Button CommandName="cmdButton2"></Button>
      </MenuGroup>
      <MenuGroup>
        <Button CommandName="cmdButton3"></Button>
      </MenuGroup>
    </SplitButtonGallery.MenuGroups>
  </SplitButtonGallery>
</Group>

Contoh berikut menunjukkan deklarasi kontrol untuk InRibbonGallery.

Catatan

Karena InRibbonGallery dirancang untuk menampilkan subset kumpulan itemnya di Pita tanpa mengaktifkan menu drop-down, inRibbonGallery menyediakan sejumlah atribut opsional yang mengatur ukuran dan tata letak itemnya pada inisialisasi Pita. Atribut ini unik untuk InRibbonGallery dan tidak tersedia dari kontrol dinamis lainnya.

 

<!-- InRibbonGallery -->
<Group CommandName="cmdInRibbonGalleryGroup" SizeDefinition="OneInRibbonGallery">
  <InRibbonGallery CommandName="cmdInRibbonGallery"
                   MaxColumns="10"
                   MaxColumnsMedium="5"
                   MinColumnsLarge="5"
                   MinColumnsMedium="3"
                   Type="Items">
    <InRibbonGallery.MenuLayout>
      <VerticalMenuLayout Rows="2"
                          Gripper="Vertical"/>
    </InRibbonGallery.MenuLayout>
    <InRibbonGallery.MenuGroups>
      <MenuGroup>
        <Button CommandName="cmdButton1"></Button>
        <Button CommandName="cmdButton2"></Button>
      </MenuGroup>
      <MenuGroup>
        <Button CommandName="cmdButton3"></Button>
      </MenuGroup>
    </InRibbonGallery.MenuGroups>            
  </InRibbonGallery>
</Group>

Contoh berikut menunjukkan deklarasi kontrol untuk ComboBox.

<!-- ComboBox -->
<Group CommandName="cmdComboBoxGroup">
  <ComboBox CommandName="cmdComboBox">              
  </ComboBox>
</Group>

Membuat Handler Perintah

Untuk setiap Perintah, kerangka kerja Pita memerlukan penangan Perintah yang sesuai di aplikasi host. Penangan perintah diimplementasikan oleh aplikasi host Pita dan berasal dari antarmuka IUICommandHandler .

Catatan

Beberapa Perintah dapat terikat ke satu handler Perintah.

 

Handler Command melayani dua tujuan:

Contoh berikut menunjukkan handler perintah galeri.

/*
 * GALLERY COMMAND HANDLER IMPLEMENTATION
 */
class CGalleryCommandHandler
      : public CComObjectRootEx<CComMultiThreadModel>
      , public IUICommandHandler
{
public:
  BEGIN_COM_MAP(CGalleryCommandHandler)
    COM_INTERFACE_ENTRY(IUICommandHandler)
  END_COM_MAP()

  // Gallery command handler's Execute method
  STDMETHODIMP Execute(UINT nCmdID,
                       UI_EXECUTIONVERB verb, 
                       const PROPERTYKEY* key,
                       const PROPVARIANT* ppropvarValue,
                       IUISimplePropertySet* pCommandExecutionProperties)
  {
    HRESULT hr = S_OK;
        
    // Switch on manner of execution (Execute/Preview/CancelPreview)
    switch (verb)
    {
      case UI_EXECUTIONVERB_EXECUTE:
        if(nCmdID == cmdTextSizeGallery || 
           nCmdID == cmdTextSizeGallery2 || 
           nCmdID == cmdTextSizeGallery3)
        {
          if (pCommandExecutionProperties != NULL)
          {
            CItemProperties *pItem = 
              static_cast<CItemProperties *>(pCommandExecutionProperties);
            g_prevSelection = g_index = pItem->GetIndex();
            UpdateGallerySelectedItems();
            ::InvalidateRect(g_hWindowFrame, NULL, TRUE);
          }
          else
          {
            g_prevSelection = g_index = 0;
            UpdateGallerySelectedItems();
            ::InvalidateRect(g_hWindowFrame, NULL, TRUE);
          }
        }           
        break;
      case UI_EXECUTIONVERB_PREVIEW:
        CItemProperties *pItem = 
          static_cast<CItemProperties *>(pCommandExecutionProperties);
        g_index = pItem->GetIndex();
        ::InvalidateRect(g_hWindowFrame, NULL, TRUE);
        break;
      case UI_EXECUTIONVERB_CANCELPREVIEW:
        g_index = g_prevSelection;
        ::InvalidateRect(g_hWindowFrame, NULL, TRUE);
        break;
    }   
    return hr;
  }

  // Gallery command handler's UpdateProperty method
  STDMETHODIMP UpdateProperty(UINT nCmdID,
                              REFPROPERTYKEY key,
                              const PROPVARIANT* ppropvarCurrentValue,
                              PROPVARIANT* ppropvarNewValue)
  {
    UNREFERENCED_PARAMETER(ppropvarCurrentValue);

    HRESULT hr = E_NOTIMPL;         

    if (key == UI_PKEY_ItemsSource) // Gallery items requested
    {
      if (nCmdID == cmdTextSizeGallery || 
          nCmdID == cmdTextSizeGallery2 || 
          nCmdID == cmdTextSizeGallery3)
      {
        CComQIPtr<IUICollection> spCollection(ppropvarCurrentValue->punkVal);

        int count = _countof(g_labels);

        for (int i = 0; i < count; i++)
        {
          CComObject<CItemProperties> * pItem;
          CComObject<CItemProperties>::CreateInstance(&pItem);
                    
          pItem->AddRef();
          pItem->Initialize(i);

          spCollection->Add(pItem);
        }
        return S_OK;
      }
      if (nCmdID == cmdCommandGallery1)
      {
        CComQIPtr<IUICollection> spCollection(ppropvarCurrentValue->punkVal);

        int count = 12;
        int commands[] = {cmdButton1, 
                          cmdButton2, 
                          cmdBoolean1, 
                          cmdBoolean2, 
                          cmdButton1, 
                          cmdButton2, 
                          cmdBoolean1, 
                          cmdBoolean2, 
                          cmdButton1, 
                          cmdButton2, 
                          cmdBoolean1, 
                          cmdBoolean2};

        for (int i = 0; i < count; i++)
        {
          CComObject<CItemProperties> * pItem;
          CComObject<CItemProperties>::CreateInstance(&pItem);
                    
          pItem->AddRef();
          pItem->InitializeAsCommand(commands[i]);

          spCollection->Add(pItem);
        }
        return S_OK;
      }
    }        
    else if (key == UI_PKEY_SelectedItem) // Selected item requested
    {           
      hr = UIInitPropertyFromUInt32(UI_PKEY_SelectedItem, g_index, ppropvarNewValue);           
    }
    return hr;
  }
};

Mengikat Handler Perintah

Setelah Anda menentukan handler Perintah, Perintah harus terikat ke handler.

Contoh berikut menunjukkan cara mengikat galeri Perintah ke penangan Perintah tertentu. Dalam hal ini, kontrol ComboBox dan galeri terikat ke handler Command masing-masing.

// Called for each Command in markup. 
// Application will return a Command handler for each Command.
STDMETHOD(OnCreateUICommand)(UINT32 nCmdID,
                             UI_COMMANDTYPE typeID,
                             IUICommandHandler** ppCommandHandler) 
{   
  // CommandType for ComboBox and galleries
  if (typeID == UI_COMMANDTYPE_COLLECTION || typeID == UI_COMMANDTYPE_COMMANDCOLLECTION) 
  {
    switch (nCmdID)
    {
      case cmdComboBox:
        CComObject<CComboBoxCommandHandler> * pComboBoxCommandHandler;
        CComObject<CComboBoxCommandHandler>::CreateInstance(&pComboBoxCommandHandler);
        return pComboBoxCommandHandler->QueryInterface(IID_PPV_ARGS(ppCommandHandler));
      default:
        CComObject<CGalleryCommandHandler> * pGalleryCommandHandler;
        CComObject<CGalleryCommandHandler>::CreateInstance(&pGalleryCommandHandler);
        return pGalleryCommandHandler->QueryInterface(IID_PPV_ARGS(ppCommandHandler));
    }
    return E_NOTIMPL; // Command is not implemented, so do not pass a handler back.
  }
}

Menginisialisasi Koleksi

Contoh berikut menunjukkan implementasi kustom IUISimplePropertySet untuk galeri item dan Perintah.

Kelas CItemProperties dalam contoh ini berasal dari IUISimplePropertySet. Selain metode yang diperlukan IUISimplePropertySet::GetValue, kelas CItemProperties mengimplementasikan serangkaian fungsi pembantu untuk inisialisasi dan pelacakan indeks.

//
//  PURPOSE:    Implementation of IUISimplePropertySet.
//
//  COMMENTS:
//              Three gallery-specific helper functions included. 
//

class CItemProperties
  : public CComObjectRootEx<CComMultiThreadModel>
  , public IUISimplePropertySet
{
  public:

  // COM map for QueryInterface of IUISimplePropertySet.
  BEGIN_COM_MAP(CItemProperties)
    COM_INTERFACE_ENTRY(IUISimplePropertySet)
  END_COM_MAP()

  // Required method that enables property key values to be 
  // retrieved on gallery collection items.
  STDMETHOD(GetValue)(REFPROPERTYKEY key, PROPVARIANT *ppropvar)
  {
    HRESULT hr;

    // No category is associated with this item.
    if (key == UI_PKEY_CategoryId)
    {
      return UIInitiPropertyFromUInt32(UI_PKEY_CategoryId, 
                                       UI_COLLECTION_INVALIDINDEX, 
                                       pprovar);
    }

    // A Command gallery.
    // _isCommandGallery is set on initialization.
    if (_isCommandGallery)
    {           
      if(key == UI_PKEY_CommandId && _isCommandGallery)
      {
        // Return a pointer to the CommandId of the item.
        return InitPropVariantFromUInt32(_cmdID, ppropvar);
      }         
    }
    // An item gallery.
    else
    {
      if (key == UI_PKEY_Label)
      {
        // Return a pointer to the item label string.
        return UIInitPropertyFromString(UI_PKEY_Label, ppropvar);
      }
      else if(key == UI_PKEY_ItemImage)
      {
        // Return a pointer to the item image.
        return UIInitPropertyFromImage(UI_PKEY_ItemImage, ppropvar);
      }         
    }
    return E_NOTIMPL;
  }

  // Initialize an item in an item gallery collection at the specified index.
  void Initialize(int index)
  {
    _index = index;
    _cmdID = 0;
    _isCommandGallery = false;
  }

  // Initialize a Command in a Command gallery.
  void InitializeAsCommand(__in UINT cmdID)
  {
    _index = 0;
    _cmdID = cmdID;
    _isCommandGallery = true;
  }

  // Gets the index of the selected item in an item gallery.
  int GetIndex()
  {
    return _index;
  }

private:
  int _index;
  int _cmdID;
  bool _isCommandGallery;   
};

Menangani Peristiwa Pengumpulan

Contoh berikut menunjukkan implementasi IUICollectionChangedEvent.

class CQATChangedEvent
  : public CComObjectRootEx<CComSingleThreadModel>
  , public IUICollectionChangedEvent
{
  public:

  HRESULT FinalConstruct()
  {
    _pSite = NULL;
    return S_OK;
  }

  void Initialize(__in CQATSite* pSite)
  {
    if (pSite != NULL)
    {
      _pSite = pSite;
    }
  }

  void Uninitialize()
  {
    _pSite = NULL;
  }

  BEGIN_COM_MAP(CQATChangedEvent)
    COM_INTERFACE_ENTRY(IUICollectionChangedEvent)
  END_COM_MAP()

  // IUICollectionChangedEvent interface
  STDMETHOD(OnChanged)(UI_COLLECTIONCHANGE action, 
                       UINT32 oldIndex, 
                       IUnknown *pOldItem, 
                       UINT32 newIndex, 
                       IUnknown *pNewItem)
  {
    if (_pSite)
    {
      _pSite->OnCollectionChanged(action, oldIndex, pOldItem, newIndex, pNewItem);
    }
    return S_OK;
  }

  protected:
  virtual ~CQATChangedEvent(){}

  private:
  CQATSite* _pSite; // Weak ref to avoid circular refcounts
};

HRESULT CQATHandler::EnsureCollectionEventListener(__in IUICollection* pUICollection)
{
  // Check if listener already exists.
  if (_spQATChangedEvent)
  {
    return S_OK;
  }

  HRESULT hr = E_FAIL;

  // Create an IUICollectionChangedEvent listener.
  hr = CreateInstanceWithRefCountOne(&_spQATChangedEvent);
    
  if (SUCCEEDED(hr))
  {
    CComPtr<IUnknown> spUnknown;
    _spQATChangedEvent->QueryInterface(IID_PPV_ARGS(&spUnknown));

    // Create a connection between the collection connection point and the sink.
    AtlAdvise(pUICollection, spUnknown, __uuidof(IUICollectionChangedEvent), &_dwCookie);
    _spQATChangedEvent->Initialize(this);
  }
  return hr;
}

HRESULT CQATHandler::OnCollectionChanged(
             UI_COLLECTIONCHANGE action, 
          UINT32 oldIndex, 
             IUnknown *pOldItem, 
          UINT32 newIndex, 
          IUnknown *pNewItem)
{
    UNREFERENCED_PARAMETER(oldIndex);
    UNREFERENCED_PARAMETER(newIndex);

    switch (action)
    {
      case UI_COLLECTIONCHANGE_INSERT:
      {
        CComQIPtr<IUISimplePropertySet> spProperties(pNewItem);
                
        PROPVARIANT var;
        if (SUCCEEDED(spProperties->GetValue(UI_PKEY_CommandId, &var)))
        {
          UINT tcid;
          if (SUCCEEDED(UIPropertyToUInt32(UI_PKEY_CommandId, var, &tcid)))
          {
            FireETWEvent(tcid, L"Added to QAT");
            PropVariantClear(&var);
          }
        }
      }
      break;
      case UI_COLLECTIONCHANGE_REMOVE:
      {
        CComQIPtr<IUISimplePropertySet> spProperties(pOldItem);
                
        PROPVARIANT var;
        if (SUCCEEDED(spProperties->GetValue(UI_PKEY_CommandId, &var)))
        {
          UINT tcid;
          if (SUCCEEDED(UIPropertyToUInt32(UI_PKEY_CommandId, var, &tcid)))
          {
            FireETWEvent(tcid, L"Removed from QAT");
            PropVariantClear(&var);
          }
        }
      }
      break;
    default:
  }
  return S_OK;
}

Properti Koleksi

Membuat Aplikasi Pita

Memahami Perintah dan Kontrol

Panduan Pengalaman Pengguna Pita

Proses Desain Pita

Sampel Galeri