Ortak Öğe İletişim Kutusu

Windows Vista'den başlayarak, Ortak Öğe İletişim Kutusu bir dosyayı açmak veya kaydetmek için kullanıldığında eski Ortak Dosya İletişim Kutusunun yerini alır. Ortak Öğe İletişim Kutusu iki çeşitlemede kullanılır: iletişim kutusu ve Kaydet iletişim kutusu. Bu iki iletişim kutusu işlevlerinin çoğunu paylaşır, ancak her birinin kendi benzersiz yöntemleri vardır.

Important

IFileDialog, modern dosya iletişim kutusu API'sidir (Windows Vista ve üzeri). Eski GetOpenFileName ve GetSaveFileName işlevleri eskidir ve yeni uygulamalarda kullanılmamalıdır. Eski API'ler Kabuk ad alanını, modern iletişim kutusu özelleştirmesini veya dosya meta verileri özelliklerini desteklemez.

kullanırken IFileDialog:

  • İletişim kutusunu oluşturmak için CoCreateInstance'ı çağırmadan önce CoInitializeEx'i çağırmanız gerekir. COINIT_APARTMENTTHREADED öğesini kullanıcı arabirimi iş parçacıkları için kullanın.
  • CLSCTX_INPROC_SERVER ile CLSID_FileOpenDialog veya CLSID_FileSaveDialog kullanın.
  • Modern seçenekler: UWP/WinUI uygulamaları için Windows.Storage.Pickers kullanın. .NET masaüstü uygulamaları için WPF ve WinForms, dahili olarak IFileDialog kullanan OpenFileDialog/SaveFileDialog sarmalayıcıları sağlar.

Bu yeni sürüm Ortak Öğe İletişim Kutusu olarak adlandırılsa da, çoğu belgede Ortak Dosya İletişim Kutusu olarak adlandırılmaya devam eder. Özellikle eski bir Windows sürümüyle uğraşmıyorsanız, Common File Dialog ifadesine yapılan herhangi bir atfın bu Common Item Dialog’a işaret ettiğini varsaymalısınız.

Burada aşağıdaki konular ele alınıyor:

IFileDialog, IFileOpenDialog ve IFileSaveDialog

Windows Vista ve Kaydet iletişim kutularının uygulamalarını sağlar: CLSID_FileOpenDialog ve CLSID_FileSaveDialog. Bu iletişim kutuları burada gösterilir.

aç iletişim kutusunun ekran görüntüsü

Farklı kaydet iletişim kutusunun ekran görüntüsü

IFileOpenDialog ve IFileSaveDialog, IFileDialog'dan devralır ve işlevlerinin çoğunu paylaşır. Ayrıca, iletişim kutusu IFileOpenDialog'ı ve Kaydet iletişim kutusu da IFileSaveDialog'ı destekler.

Windows Vista'de bulunan Ortak Öğe İletişim Kutusu uygulaması, önceki sürümlerde sağlanan uygulamaya göre çeşitli avantajlar sağlar:

  • Dosya sistemi yollarını kullanmak yerine IShellItem aracılığıyla Shell ad alanının doğrudan kullanımını destekler.
  • OK düğmesinin etiketini ayarlamak gibi işlemlerle, bir hook yordamı gerektirmeden iletişim kutusunun kolayca özelleştirilmesini sağlar.
  • Win32 iletişim kutusu şablonu olmadan çalışan bir dizi veri temelli denetim eklenerek iletişim kutusunun daha kapsamlı bir şekilde özelleştirilmesini destekler. Bu özelleştirme düzeni, arama işlemini kullanıcı arabirimi düzeninden kaldırır. İletişim kutusu tasarımında yapılan değişiklikler bu veri modelini kullanmaya devam ettiğinden, iletişim kutusu uygulaması iletişim kutusunun belirli geçerli sürümüne bağlı değildir.
  • İletişim kutusundaki seçim değişikliği veya dosya türü değişikliği gibi olayların arayan bildirimini destekler. Ayrıca, arama işleminin ayrıştırma gibi iletişim kutusundaki belirli olayları bağlamasını sağlar.
  • Basamaklar çubuğuna arayan tarafından belirtilen yerleri ekleme gibi yeni iletişim kutusu özellikleri sunar.
  • Kaydet iletişim kutusunda, geliştiriciler Windows Vista Kabuğu'nun yeni meta veri özelliklerinden yararlanabilir.

Ayrıca, geliştiriciler aşağıdaki arabirimleri uygulamayı seçebilir:

veya Kaydet iletişim kutusu, çağırma işlemine bir IShellItem veya IShellItemArray nesnesi döndürür. Arayan daha sonra tek bir IShellItem nesnesini kullanarak bir dosya sistemi yolu alabilir veya öğede bilgi okumak veya yazmak için bir akış açabilir.

Yeni iletişim kutusu yöntemlerinde kullanılabilen bayraklar ve seçenekler, OPENFILENAME yapısında bulunan ve GetOpenFileName ve GetSaveFileName içinde kullanılan eski OFNbayraklarına çok benzer. Bunların çoğu, FOS ön eki ile başlamaları dışında tamamen aynıdır. Listenin tamamı IFileDialog::GetOptions ve IFileDialog::SetOptions konu başlıklarında bulunabilir. ve Kaydet iletişim kutuları varsayılan olarak en yaygın bayraklarla oluşturulur. iletişim kutusu için bunlar (FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST | FOS_NOCHANGEDIR), Kaydet iletişim kutusu içinse bunlar (FOS_OVERWRITEPROMPT | FOS_NOREADONLYRETURN | FOS_PATHMUSTEXIST | FOS_NOCHANGEDIR) şeklindedir.

IFileDialog ve alt arabirimleri IModalWindow'dan devralır ve genişletir. Göster , üst pencerenin tutamacını tek parametresi olarak alır. Göster başarıyla döndürürse geçerli bir sonuç vardır. HRESULT_FROM_WIN32(ERROR_CANCELLED) döndürürse, bu kullanıcının iletişim kutusunu iptal ettiği anlamına gelir. Ayrıca yasal olarak E_OUTOFMEMORY gibi başka bir hata kodu döndürebilir.

Örnek Kullanım

Aşağıdaki bölümlerde çeşitli iletişim kutusu görevleri için örnek kod gösterilmektedir.

Örnek kodun çoğu Windows SDK Ortak Dosya İletişim Kutusu Örneği'nde bulunabilir.

Temel Kullanım

Aşağıdaki örnekte iletişim kutusunun nasıl başlatıldığı gösterilmektedir. Bu örnekte, Microsoft Word belgelerle sınırlıdır.

Note

Bu konudaki birkaç örnek, CDialogEventHandler_CreateInstance uygulamasının bir örneğini oluşturmak için yardımcı işlevini kullanır. Bu işlevi kendi kodunuzda kullanmak için, bu konudaki CDialogEventHandler_CreateInstance tüm örneklerin alındığı Ortak Dosya İletişim Kutusu Örneği'nden işlevin kaynak kodunu kopyalayın.

 

HRESULT BasicFileOpen()
{
    // CoCreate the File Open Dialog object.
    IFileDialog *pfd = NULL;
    HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, 
                      NULL, 
                      CLSCTX_INPROC_SERVER, 
                      IID_PPV_ARGS(&pfd));
    if (SUCCEEDED(hr))
    {
        // Create an event handling object, and hook it up to the dialog.
        IFileDialogEvents *pfde = NULL;
        hr = CDialogEventHandler_CreateInstance(IID_PPV_ARGS(&pfde));
        if (SUCCEEDED(hr))
        {
            // Hook up the event handler.
            DWORD dwCookie;
            hr = pfd->Advise(pfde, &dwCookie);
            if (SUCCEEDED(hr))
            {
                // Set the options on the dialog.
                DWORD dwFlags;

                // Before setting, always get the options first in order 
                // not to override existing options.
                hr = pfd->GetOptions(&dwFlags);
                if (SUCCEEDED(hr))
                {
                    // In this case, get shell items only for file system items.
                    hr = pfd->SetOptions(dwFlags | FOS_FORCEFILESYSTEM);
                    if (SUCCEEDED(hr))
                    {
                        // Set the file types to display only. 
                        // Notice that this is a 1-based array.
                        hr = pfd->SetFileTypes(ARRAYSIZE(c_rgSaveTypes), c_rgSaveTypes);
                        if (SUCCEEDED(hr))
                        {
                            // Set the selected file type index to Word Docs for this example.
                            hr = pfd->SetFileTypeIndex(INDEX_WORDDOC);
                            if (SUCCEEDED(hr))
                            {
                                // Set the default extension to be ".doc" file.
                                hr = pfd->SetDefaultExtension(L"doc;docx");
                                if (SUCCEEDED(hr))
                                {
                                    // Show the dialog
                                    hr = pfd->Show(NULL);
                                    if (SUCCEEDED(hr))
                                    {
                                        // Obtain the result once the user clicks 
                                        // the 'Open' button.
                                        // The result is an IShellItem object.
                                        IShellItem *psiResult;
                                        hr = pfd->GetResult(&psiResult);
                                        if (SUCCEEDED(hr))
                                        {
                                            // We are just going to print out the 
                                            // name of the file for sample sake.
                                            PWSTR pszFilePath = NULL;
                                            hr = psiResult->GetDisplayName(SIGDN_FILESYSPATH, 
                                                               &pszFilePath);
                                            if (SUCCEEDED(hr))
                                            {
                                                TaskDialog(NULL,
                                                           NULL,
                                                           L"CommonFileDialogApp",
                                                           pszFilePath,
                                                           NULL,
                                                           TDCBF_OK_BUTTON,
                                                           TD_INFORMATION_ICON,
                                                           NULL);
                                                CoTaskMemFree(pszFilePath);
                                            }
                                            psiResult->Release();
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                // Unhook the event handler.
                pfd->Unadvise(dwCookie);
            }
            pfde->Release();
        }
        pfd->Release();
    }
    return hr;
}

Sonuçları Dosya Sistemi Öğeleriyle Sınırlama

Yukarıdan alınan aşağıdaki örnekte sonuçların dosya sistemi öğeleriyle nasıl kısıtlanması gösterilmektedir. IFileDialog::SetOptions'ın yeni bayrağını IFileDialog::GetOptions aracılığıyla alınan bir değere eklediğini unutmayın. Önerilen yöntem budur.

                // Set the options on the dialog.
                DWORD dwFlags;

                // Before setting, always get the options first in order 
                // not to override existing options.
                hr = pfd->GetOptions(&dwFlags);
                if (SUCCEEDED(hr))
                {
                    // In this case, get shell items only for file system items.
                    hr = pfd->SetOptions(dwFlags | FOS_FORCEFILESYSTEM);

İletişim Kutusu için Dosya Türlerini Belirtme

İletişim kutusunun işleyebileceği belirli dosya türlerini ayarlamak için IFileDialog::SetFileTypes yöntemini kullanın. Bu yöntem, her biri bir dosya türünü temsil eden bir COMDLG_FILTERSPEC yapı dizisi kabul eder.

İletişim kutusundaki varsayılan uzantı mekanizması GetOpenFileName ve GetSaveFileName ile değiştirilmez. Kullanıcının dosya adı düzenleme kutusuna yazdığınız metne eklenen dosya adı uzantısı, iletişim kutusu açıldığında başlatılır. Varsayılan dosya türüyle eşleşmelidir (iletişim kutusu açılırken seçilen dosya türü). Varsayılan dosya türü "*.*" (tüm dosyalar) ise, dosya seçtiğiniz bir uzantı olabilir. Kullanıcı farklı bir dosya türü seçerse, uzantı otomatik olarak bu dosya türüyle ilişkili ilk dosya adı uzantısına güncelleştirilir. Kullanıcı "*.*" (tüm dosyalar) seçeneğini belirlerse uzantı özgün değerine geri döner.

Aşağıdaki örnekte bunun yukarıda nasıl yapıldığı gösterilmektedir.

                        // Set the file types to display only. 
                        // Notice that this is a 1-based array.
                        hr = pfd->SetFileTypes(ARRAYSIZE(c_rgSaveTypes), c_rgSaveTypes);
                        if (SUCCEEDED(hr))
                        {
                            // Set the selected file type index to Word Docs for this example.
                            hr = pfd->SetFileTypeIndex(INDEX_WORDDOC);
                            if (SUCCEEDED(hr))
                            {
                                // Set the default extension to be ".doc" file.
                                hr = pfd->SetDefaultExtension(L"doc;docx");

Varsayılan Klasörü Denetleme

Kabuk ad alanı içindeki hemen her klasör, iletişim kutusunun varsayılan klasörü olarak kullanılabilir (kullanıcı bir dosyayı açmayı veya kaydetmeyi seçtiğinde sunulan klasör). Bunu yapmak için Show çağrısından önce IFileDialog::SetDefaultFolder çağrısı yapın.

Varsayılan klasör, bir kullanıcı uygulamanızdan ilk kez açtığında iletişim kutusunun başlatıldığı klasördür. Bundan sonra, iletişim kutusu kullanıcının açtığı son klasörde veya öğeyi kaydetmek için kullandığı son klasörde açılır. Daha fazla ayrıntı için bkz. Durum Kalıcılığı .

Önceki kullanıcı eyleminden bağımsız olarak, IFileDialog::SetFolder çağrısı yaparak iletişim kutusunu açıldığında her zaman aynı klasörü göstermeye zorlayabilirsiniz. Ancak, bunu yapmanız önerilmez. İletişim kutusunu görüntülemeden önce SetFolder'ı çağırırsanız, kullanıcının kaydettiği veya açtığı en son konum gösterilmez. Bu davranışın çok özel bir nedeni yoksa, iyi veya beklenen bir kullanıcı deneyimi değildir ve kaçınılmalıdır. Neredeyse tüm örneklerde IFileDialog::SetDefaultFolder daha iyi bir yöntemdir.

Kaydet iletişim kutusunda belgeyi ilk kez kaydederken, iletişim kutusunda yaptığınız ilk klasörü belirlerken de aynı yönergeleri izlemeniz gerekir. Kullanıcı daha önce var olan bir belgeyi düzenliyorsa, belgenin depolandığı klasörde iletişim kutusunu açın ve düzenleme kutusunu bu belgenin adıyla doldurun. Show çağrısından önce geçerli öğeyle IFileSaveDialog::SetSaveAsItem öğesini çağırın.

Yerler Çubuğuna Öğe Ekleme

Aşağıdaki örnek , Yerler çubuğuna öğe eklemeyi gösterir:

HRESULT AddItemsToCommonPlaces()
{
    // CoCreate the File Open Dialog object.
    IFileDialog *pfd = NULL;
    HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, 
                      NULL, 
                      CLSCTX_INPROC_SERVER, 
                      IID_PPV_ARGS(&pfd));
    if (SUCCEEDED(hr))
    {
        // Always use known folders instead of hard-coding physical file paths.
        // In this case we are using Public Music KnownFolder.
        IKnownFolderManager *pkfm = NULL;
        hr = CoCreateInstance(CLSID_KnownFolderManager, 
                      NULL, 
                      CLSCTX_INPROC_SERVER, 
                      IID_PPV_ARGS(&pkfm));
        if (SUCCEEDED(hr))
        {
            // Get the known folder.
            IKnownFolder *pKnownFolder = NULL;
            hr = pkfm->GetFolder(FOLDERID_PublicMusic, &pKnownFolder);
            if (SUCCEEDED(hr))
            {
                // File Dialog APIs need an IShellItem that represents the location.
                IShellItem *psi = NULL;
                hr = pKnownFolder->GetShellItem(0, IID_PPV_ARGS(&psi));
                if (SUCCEEDED(hr))
                {
                    // Add the place to the bottom of default list in Common File Dialog.
                    hr = pfd->AddPlace(psi, FDAP_BOTTOM);
                    if (SUCCEEDED(hr))
                    {
                        // Show the File Dialog.
                        hr = pfd->Show(NULL);
                        if (SUCCEEDED(hr))
                        {
                            //
                            // You can add your own code here to handle the results.
                            //
                        }
                    }
                    psi->Release();
                }
                pKnownFolder->Release();
            }
            pkfm->Release();
        }
        pfd->Release();
    }
    return hr;
}

Durum Sürekliliği

Windows Vista önce, son ziyaret edilen klasör gibi bir durum işlem başına kaydedilirdi. Ancak bu bilgiler, belirli bir eylemden bağımsız olarak kullanılmıştır. Örneğin, bir video düzenleme uygulaması, Medyayı İçeri Aktar iletişim kutusunda olduğu gibi Farklı İşle iletişim kutusunda aynı klasörü sunar. Windows Vista GUID'leri kullanarak daha belirgin olabilirsiniz. İletişim kutusuna GUID atamak için iFileDialog::SetClientGuid öğesini çağırın.

Çoklu Seçim Özellikleri

Burada gösterildiği gibi, iletişim kutusunda GetResults yöntemi kullanılarak çoklu seçim işlevi kullanılabilir.

HRESULT MultiselectInvoke()
{
    IFileOpenDialog *pfd;
    
    // CoCreate the dialog object.
    HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, 
                                  NULL, 
                                  CLSCTX_INPROC_SERVER, 
                                  IID_PPV_ARGS(&pfd));

    if (SUCCEEDED(hr))
    {
        DWORD dwOptions;
        // Specify multiselect.
        hr = pfd->GetOptions(&dwOptions);
        
        if (SUCCEEDED(hr))
        {
            hr = pfd->SetOptions(dwOptions | FOS_ALLOWMULTISELECT);
        }

        if (SUCCEEDED(hr))
        {
            // Show the Open dialog.
            hr = pfd->Show(NULL);

            if (SUCCEEDED(hr))
            {
                // Obtain the result of the user interaction.
                IShellItemArray *psiaResults;
                hr = pfd->GetResults(&psiaResults);
                
                if (SUCCEEDED(hr))
                {
                    //
                    // You can add your own code here to handle the results.
                    //
                    psiaResults->Release();
                }
            }
        }
        pfd->Release();
    }
    return hr;
}

İletişim Kutusundan Olayları Dinleme

Arama işlemi, burada gösterildiği gibi IFileDialog::Advise ve IFileDialog::Unadvise yöntemlerini kullanarak bir IFileDialogEvents arabirimini iletişim kutusuna kaydedebilir.

Bu, Temel Kullanım örneğinden alınır.

        // Create an event handling object, and hook it up to the dialog.
        IFileDialogEvents *pfde = NULL;
        hr = CDialogEventHandler_CreateInstance(IID_PPV_ARGS(&pfde));
        if (SUCCEEDED(hr))
        {
            // Hook up the event handler.
            DWORD dwCookie;
            hr = pfd->Advise(pfde, &dwCookie);

İletişim kutusunun işlenmesinin büyük bir kısmı burada yer alırdı.

                // Unhook the event handler.
                pfd->Unadvise(dwCookie);
            }
            pfde->Release();
        }
        pfd->Release();
    }
    return hr;
}

Arama işlemi, kullanıcı klasörü, dosya türünü veya seçimi değiştirdiğinde bildirim için olayları kullanabilir. Bu olaylar özellikle, arama işlemi iletişim kutusuna denetimler eklediğinde (bkz . İletişim Kutusunu Özelleştirme) ve bu olaylara tepki olarak bu denetimlerin durumunu değiştirmesi gerektiğinde yararlıdır. Her durumda yararlı olan, arama işleminin paylaşım ihlalleri, dosyaların üzerine yazma veya iletişim kutusu kapanmadan önce dosyanın geçerli olup olmadığını belirleme gibi durumlarla başa çıkmak için özel kod sağlama özelliğidir. Bu durumlardan bazıları bu bölümde açıklanmıştır.

OnFileOk

Bu yöntem, iletişim kutusu kapanmadan hemen önce kullanıcı bir öğe seçtikten sonra çağrılır. Uygulama daha sonra IFileDialog::GetResult veya IFileOpenDialog::GetResults çağrılarını iletişim kutusu kapatıldıktan sonra olduğu gibi çağırabilir. Seçilen öğe kabul edilebilirse S_OK döndürebilir. Aksi takdirde, S_FALSE döndürür ve kullanıcıya seçilen öğenin neden geçerli olmadığını söyleyen kullanıcı arabirimini görüntüler. S_FALSE döndürülürse iletişim kutusu kapatılmaz.

Arama işlemi, iletişim kutusunun pencere tutamacını kullanıcı arabiriminin üst öğesi olarak kullanabilir. Bu tanıtıcı, önce IOleWindow::QueryInterface ve ardından bu örnekte gösterildiği gibi tanıtıcıyla IOleWindow::GetWindow çağrılarak elde edilebilir.

HRESULT CDialogEventHandler::OnFileOk(IFileDialog *pfd) 
{ 
    IShellItem *psiResult;
    HRESULT hr = pfd->GetResult(&psiResult);
    
    if (SUCCEEDED(hr))
    {
        SFGAOF attributes;
        hr = psiResult->GetAttributes(SFGAO_COMPRESSED, &attributes);
    
        if (SUCCEEDED(hr))
        {
            if (attributes & SFGAO_COMPRESSED)
            {
                // Accept the file.
                hr = S_OK;
            }
            else
            {
                // Refuse the file.
                hr = S_FALSE;
                
                _DisplayMessage(pfd, L"Not a compressed file.");
            }
        }
        psiResult->Release();
    }
    return hr;
};

HRESULT CDialogEventHandler::_DisplayMessage(IFileDialog *pfd, PCWSTR pszMessage)
{
    IOleWindow *pWindow;
    HRESULT hr = pfd->QueryInterface(IID_PPV_ARGS(&pWindow));
    
    if (SUCCEEDED(hr))
    {
        HWND hwndDialog;
        hr = pWindow->GetWindow(&hwndDialog);
    
        if (SUCCEEDED(hr))
        {
            MessageBox(hwndDialog, pszMessage, L"An error has occurred", MB_OK);
        }
        pWindow->Release();
    }
    return hr;
}

OnShareViolation ve OnOverwrite

Kullanıcı Kaydet iletişim kutusundaki bir dosyanın üzerine yazmayı seçerse veya kaydedilen veya değiştirilen bir dosya kullanımdaysa ve üzerine yazılamazsa (paylaşım ihlali), uygulama iletişim kutusunun varsayılan davranışını geçersiz kılmak için özel işlevsellik sağlayabilir. Varsayılan olarak, bir dosyanın üzerine yazılırken iletişim kutusunda kullanıcının bu eylemi doğrulamasını sağlayan bir istem görüntülenir. Paylaşım ihlalleri için, iletişim kutusu varsayılan olarak bir hata iletisi görüntüler, kapatılmaz ve kullanıcının başka bir seçim yapması gerekir. Çağrı işlemi bu varsayılanları geçersiz kılabilir ve isterseniz kendi kullanıcı arabirimini görüntüleyebilir. İletişim kutusuna, dosyayı reddedip açık kalması veya dosyayı kabul edip başarıyla kapanması yönünde komut verilebilir.

İletişim Penceresini Özelleştirme

Win32 iletişim kutusu şablonu sağlanmadan iletişim kutusuna çeşitli denetimler eklenebilir. Bu denetimler Arasında PushButton, ComboBox, EditBox, CheckButton, RadioButton listeleri, Gruplar, Ayırıcılar ve Statik Metin denetimleri bulunur. IFileDialogCustomize işaretçisini almak için iletişim kutusu nesnesinde QueryInterface çağrısı yapın (IFileDialog, IFileOpenDialog veya IFileSaveDialog). Denetim eklemek için bu arabirimi kullanın. Her denetim, çağıran tarafından sağlanan ilişkili bir kimliğin yanı sıra çağrı işlemi tarafından ayarlanabilen görünür ve etkin bir duruma sahiptir. PushButton gibi bazı denetimlerin de bunlarla ilişkilendirilmiş metinleri vardır.

Birden çok denetim, iletişim kutusunun düzeni içinde tek bir birim olarak hareket eden bir "görsel gruba" eklenebilir. Grupların bunlarla ilişkilendirilmiş bir etiketi olabilir.

Denetimler yalnızca iletişim kutusu gösterilmeden önce eklenebilir. Ancak, iletişim kutusu görüntülendiğinde, denetimler gizlenebilir veya kullanıcı eylemine yanıt olarak istenildiği gibi gösterilebilir. Aşağıdaki örneklerde iletişim kutusuna radyo düğmesi listesinin nasıl ekleneceği gösterilmektedir.

// Controls
#define CONTROL_GROUP           2000
#define CONTROL_RADIOBUTTONLIST 2
#define CONTROL_RADIOBUTTON1    1
#define CONTROL_RADIOBUTTON2    2       // It is OK for this to have the same ID
                    // as CONTROL_RADIOBUTTONLIST, because it 
                    // is a child control under CONTROL_RADIOBUTTONLIST


// This code snippet demonstrates how to add custom controls in the Common File Dialog.
HRESULT AddCustomControls()
{
    // CoCreate the File Open Dialog object.
    IFileDialog *pfd = NULL;
    HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, 
                                  NULL, 
                                  CLSCTX_INPROC_SERVER, 
                                  IID_PPV_ARGS(&pfd));
    if (SUCCEEDED(hr))
    {
        // Create an event handling object, and hook it up to the dialog.
        IFileDialogEvents   *pfde       = NULL;
        DWORD               dwCookie    = 0;
        hr = CDialogEventHandler_CreateInstance(IID_PPV_ARGS(&pfde));
        if (SUCCEEDED(hr))
        {
            // Hook up the event handler.
            hr = pfd->Advise(pfde, &dwCookie);
            if (SUCCEEDED(hr))
            {
                // Set up a Customization.
                IFileDialogCustomize *pfdc = NULL;
                hr = pfd->QueryInterface(IID_PPV_ARGS(&pfdc));
                if (SUCCEEDED(hr))
                {
                    // Create a Visual Group.
                    hr = pfdc->StartVisualGroup(CONTROL_GROUP, L"Sample Group");
                    if (SUCCEEDED(hr))
                    {
                        // Add a radio-button list.
                        hr = pfdc->AddRadioButtonList(CONTROL_RADIOBUTTONLIST);
                        if (SUCCEEDED(hr))
                        {
                            // Set the state of the added radio-button list.
                            hr = pfdc->SetControlState(CONTROL_RADIOBUTTONLIST, 
                                               CDCS_VISIBLE | CDCS_ENABLED);
                            if (SUCCEEDED(hr))
                            {
                                // Add individual buttons to the radio-button list.
                                hr = pfdc->AddControlItem(CONTROL_RADIOBUTTONLIST,
                                                          CONTROL_RADIOBUTTON1,
                                                          L"Change Title to ABC");
                                if (SUCCEEDED(hr))
                                {
                                    hr = pfdc->AddControlItem(CONTROL_RADIOBUTTONLIST,
                                                              CONTROL_RADIOBUTTON2,
                                                              L"Change Title to XYZ");
                                    if (SUCCEEDED(hr))
                                    {
                                        // Set the default selection to option 1.
                                        hr = pfdc->SetSelectedControlItem(CONTROL_RADIOBUTTONLIST,
                                                                          CONTROL_RADIOBUTTON1);
                                    }
                                }
                            }
                        }
                        // End the visual group.
                        pfdc->EndVisualGroup();
                    }
                    pfdc->Release();
                }

                if (FAILED(hr))
                {
                    // Unadvise here in case we encounter failures 
                    // before we get a chance to show the dialog.
                    pfd->Unadvise(dwCookie);
                }
            }
            pfde->Release();
        }

        if (SUCCEEDED(hr))
        {
            // Now show the dialog.
            hr = pfd->Show(NULL);
            if (SUCCEEDED(hr))
            {
                //
                // You can add your own code here to handle the results.
                //
            }
            // Unhook the event handler.
            pfd->Unadvise(dwCookie);
        }
        pfd->Release();
    }
    return hr;
}

Tamam Düğmesine Seçenekler Ekleme

Benzer şekilde, ilgili iletişim kutusu türleri için Tamam düğmesi olan veya Kaydet düğmelerine seçenekler eklenebilir. Seçeneklere, düğmeye eklenmiş bir açılan liste kutusu aracılığıyla erişilebilir. Listedeki ilk öğe düğme metni olur. Aşağıdaki örnekte iki olasılık içeren bir düğmesinin nasıl sağlanıyor olduğu gösterilmektedir: "Aç" ve "Salt okunur olarak aç".

// OpenChoices options
#define OPENCHOICES 0
#define OPEN 0
#define OPEN_AS_READONLY 1


HRESULT AddOpenChoices()
{
    // CoCreate the File Open Dialog object.
    IFileDialog *pfd = NULL;
    HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, 
                      NULL, 
                      CLSCTX_INPROC_SERVER, 
                      IID_PPV_ARGS(&pfd));
    if (SUCCEEDED(hr))
    {
        // Create an event handling object, and hook it up to the dialog.
        IFileDialogEvents   *pfde       = NULL;
        DWORD               dwCookie    = 0;
        hr = CDialogEventHandler_CreateInstance(IID_PPV_ARGS(&pfde));
        if (SUCCEEDED(hr))
        {
            // Hook up the event handler.
            hr = pfd->Advise(pfde, &dwCookie);
            if (SUCCEEDED(hr))
            {
                // Set up a Customization.
                IFileDialogCustomize *pfdc = NULL;
                hr = pfd->QueryInterface(IID_PPV_ARGS(&pfdc));
                if (SUCCEEDED(hr))
                {
                    hr = pfdc->EnableOpenDropDown(OPENCHOICES);
                    if (SUCCEEDED(hr))
                    {
                        hr = pfdc->AddControlItem(OPENCHOICES, OPEN, L"&Open");
                    }                    
                    if (SUCCEEDED(hr))
                    {
                        hr = pfdc->AddControlItem(OPENCHOICES, 
                                                OPEN_AS_READONLY, 
                                                L"Open as &read-only");
                    }
                    if (SUCCEEDED(hr))
                    {
                        pfd->Show(NULL);
                    }
                }
                pfdc->Release();
            }
            pfd->Unadvise(dwCookie);
        }
        pfde->Release();
    }
    pfd->Release();
    return hr;
}

Kullanıcının seçimi, bir ComboBox için yaptığınız gibi, iletişim kutusu Show yönteminden döndükten sonra doğrulanabilir ya da IFileDialogEvents::OnFileOk işlenmesinin bir parçası olarak doğrulanabilir.

Eklenen Denetimlerde Olaylara Yanıt Verme

Çağırma işlemi tarafından sağlanan olay işleyicisi , IFileDialogEvents'e ek olarak IFileDialogControlEvents uygulayabilir. IFileDialogControlEvents , çağrı işleminin şu olaylara tepki vermesine olanak tanır:

  • Düğme tıklatıldı
  • CheckButton durumu değiştirildi
  • Menüden, ComboBox'tan veya RadioButton listesinden seçilen öğe
  • Etkinleştirmeyi denetleme. Bu, bir menü açılır listeyi görüntülemek üzereyken, çağıran işlemin listedeki öğeleri değiştirmek istemesi durumunda gönderilir.

Tam Örnekler

Ortak Öğe İletişim Kutusu'nun kullanımını ve etkileşimini gösteren Windows Yazılım Geliştirme Seti'nden (SDK) eksiksiz, indirilebilir C++ örnekleri aşağıdadır.

IID_PPV_ARGS