Dialogruta för gemensamt objekt

Från och med Windows Vista ersätter dialogrutan Vanligt objekt den äldre gemensamma fildialogrutan när den används för att öppna eller spara en fil. Dialogrutan Gemensamt objekt används i två varianter: dialogrutan Öppna och dialogrutan Spara . De här två dialogrutorna delar de flesta av deras funktioner, men var och en har sina egna unika metoder.

Important

IFileDialog är det moderna fildialog-API:et (Windows Vista och senare). De äldre funktionerna GetOpenFileName och GetSaveFileName är äldre och bör inte användas i nya program. De äldre API:erna stöder inte shell-namnområdet, modern dialoganpassning eller filmetadatafunktioner.

När du använder IFileDialog:

  • Du måste anropa CoInitializeEx innan du anropar CoCreateInstance för att skapa dialogrutan. Använd COINIT_APARTMENTTHREADED för UI-trådar.
  • Använd CLSID_FileOpenDialog eller CLSID_FileSaveDialog med CLSCTX_INPROC_SERVER.
  • Moderna alternativ: För UWP/WinUI-appar använder du Windows.Storage.Pickers. För .NET-skrivbordsappar tillhandahåller WPF och WinForms OpenFileDialog/SaveFileDialog omslutande klasser som internt använder IFileDialog.

Även om den här nyare versionen heter Dialogrutan För gemensamt objekt, fortsätter den att kallas för dialogrutan Gemensam fil i de flesta dokumentationen. Om du inte specifikt hanterar en äldre version av Windows bör du anta att varje omnämnande av dialogrutan Gemensam fil refererar till den här dialogrutan för gemensamt objekt.

Följande ämnen beskrivs här:

IFileDialog, IFileOpenDialog och IFileSaveDialog

Windows Vista innehåller implementeringar av dialogrutorna Öppna och Spara: CLSID_FileOpenDialog och CLSID_FileSaveDialog. Dessa dialogrutor visas här.

skärmbild av den öppna dialogrutan

skärmbild av dialogrutan Spara som

IFileOpenDialog och IFileSaveDialog ärver från IFileDialog och delar mycket av deras funktioner. Dialogrutan Öppna stöder dessutom IFileOpenDialog, och dialogrutan Spara stöder IFileSaveDialog.

Implementeringen av common item-dialogrutan som finns i Windows Vista ger flera fördelar jämfört med implementeringen i tidigare versioner:

  • Stöder direkt användning av Shell-namnområdet via IShellItem i stället för att använda filsystemsökvägar.
  • Möjliggör enkel anpassning av dialogrutan, till exempel att ange etiketten på OK-knappen , utan att det krävs någon hook-procedur.
  • Stöder mer omfattande anpassning av dialogrutan genom att lägga till en uppsättning datadrivna kontroller som fungerar utan en Win32-dialogmall. Det här anpassningsschemat frigör samtalsprocessen från användargränssnittslayouten. Eftersom alla ändringar i dialogrutans design fortsätter att använda den här datamodellen är dialogimplementeringen inte kopplad till den specifika aktuella versionen av dialogrutan.
  • Stöder uppringarmeddelande om händelser i dialogrutan, till exempel ändring av val eller ändring av filtyp. Gör också att anropsprocessen kan koppla vissa händelser i dialogrutan, till exempel parsning.
  • Introducerar nya dialogfunktioner som att lägga till uppringarens angivna platser i fältet Platser .
  • I dialogrutan Spara kan utvecklare dra nytta av nya metadatafunktioner i Windows Vista Shell.

Dessutom kan utvecklare välja att implementera följande gränssnitt:

Dialogrutan Öppna eller Spara returnerar ett IShellItem - eller IShellItemArray-objekt till anropsprocessen. Anroparen kan sedan använda ett enskilt IShellItem-objekt för att hämta en filsystemsökväg eller för att öppna en ström på objektet för att läsa eller skriva information.

Flaggor och alternativ som är tillgängliga för de nya dialogmetoderna liknar de äldre OFN-flaggorna som finns i OPENFILENAME-strukturen och används i GetOpenFileName och GetSaveFileName. Många av dem är exakt likadana, förutom att de börjar med ett FOS-prefix. Den fullständiga listan finns i ämnena IFileDialog::GetOptions och IFileDialog::SetOptions . Dialogrutorna Öppna och Spara skapas som standard med de vanligaste flaggorna. För dialogrutan Öppna är detta (FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST | FOS_NOCHANGEDIR) och för dialogrutan Spara är detta (FOS_OVERWRITEPROMPT | FOS_NOREADONLYRETURN | FOS_PATHMUSTEXIST | FOS_NOCHANGEDIR).

IFileDialog och dess underordnade gränssnitt ärver från och utökar IModalWindow. Visa tar som enda parameter handtaget för det överordnade fönstret. Om Visa returnerar korrekt, finns det ett giltigt resultat. Om den returnerar HRESULT_FROM_WIN32(ERROR_CANCELLED)innebär det att användaren avbröt dialogrutan. Det kan också legitimt returnera en annan felkod, till exempel E_OUTOFMEMORY.

Exempel på användning

I följande avsnitt visas exempelkod för en mängd olika dialogaktiviteter.

Det mesta av exempelkoden finns i Windows SDK Common File Dialog Sample.

Grundläggande användning

I följande exempel visas hur du startar en öppen dialogruta. I det här exemplet är det begränsat till Microsoft Word dokument.

Note

Flera exempel i det här avsnittet använder CDialogEventHandler_CreateInstance hjälpfunktionen för att skapa en instans av IFileDialogEvents-implementeringen . Om du vill använda den här funktionen i din egen kod kopierar du källkoden CDialogEventHandler_CreateInstance för funktionen från dialogrutan Exempel på gemensam fil, från vilken alla exempel i det här avsnittet tas.

 

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;
}

Begränsa resultat till filsystemobjekt

I följande exempel, som tas ovanifrån, visas hur du begränsar resultatet till filsystemobjekt. Observera att IFileDialog::SetOptions lägger till den nya flaggan till ett värde som hämtas via IFileDialog::GetOptions. Det är den rekommenderade metoden.

                // 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);

Ange filtyper för en dialogruta

Om du vill ange specifika filtyper som dialogrutan kan hantera använder du metoden IFileDialog::SetFileTypes . Den metoden accepterar en matris med COMDLG_FILTERSPEC strukturer, som var och en representerar en filtyp.

Standardtilläggsmekanismen i en dialogruta är oförändrad från GetOpenFileName och GetSaveFileName. Filnamnstillägget som läggs till i texten som användaren skriver i redigeringsrutan för filnamn initieras när dialogrutan öppnas. Den ska matcha standardfiltypen (som valts när dialogrutan öppnas). Om standardfiltypen är "*.*" (alla filer) kan filen vara ett valfritt tillägg. Om användaren väljer en annan filtyp uppdateras tillägget automatiskt till det första filnamnstillägget som är associerat med den filtypen. Om användaren väljer "*.*" (alla filer) återgår tillägget till sitt ursprungliga värde.

I följande exempel visas hur detta gjordes ovan.

                        // 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");

Hantera standardmappen

Nästan vilken mapp som helst i Shell-namnområdet kan användas som standardmapp för dialogrutan (mappen som visas när användaren väljer att öppna eller spara en fil). Anropa IFileDialog::SetDefaultFolder innan du anroparVisa för att göra det.

Standardmappen är den mapp där dialogrutan startar första gången en användare öppnar den från ditt program. Därefter öppnas dialogrutan i den senaste mappen som en användare öppnade eller den sista mappen som de använde för att spara ett objekt. Mer information finns i Tillståndsbeständighet .

Du kan tvinga dialogrutan att alltid visa samma mapp när den öppnas, oavsett föregående användaråtgärd, genom att anropa IFileDialog::SetFolder. Vi rekommenderar dock inte att du gör detta. Om du anropar SetFolder innan du visar dialogrutan visas inte den senaste platsen som användaren sparade till eller öppnade från. Om det inte finns en mycket specifik orsak till det här beteendet är det inte en bra eller förväntad användarupplevelse och bör undvikas. I nästan alla instanser är IFileDialog::SetDefaultFolder den bättre metoden.

När du sparar ett dokument för första gången i dialogrutan Spara bör du följa samma riktlinjer för att fastställa den första mappen som du gjorde i dialogrutan Öppna . Om användaren redigerar ett tidigare befintligt dokument öppnar du dialogrutan i mappen där dokumentet lagras och fyller i redigeringsrutan med dokumentets namn. Anropa IFileSaveDialog::SetSaveAsItem med det aktuella objektet innan du anropar Visa.

Lägga till objekt i platsfältet

I följande exempel visas hur objekt läggs till i fältet Platser :

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;
}

Tillståndsbeständighet

Innan Windows Vista sparades ett tillstånd, till exempel den senast besökta mappen, per process. Den informationen användes dock oavsett vilken åtgärd det gäller. Ett videoredigeringsprogram skulle till exempel visa samma mapp i dialogrutan Rendera som i dialogrutan Importera media . I Windows Vista kan du vara mer specifik genom att använda GUID. Om du vill tilldela en GUID till dialogrutan anropar du iFileDialog::SetClientGuid.

Funktioner för flera val

Multiselect-funktioner är tillgängliga i dialogrutan Öppna med metoden GetResults som du ser här.

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;
}

Lyssna på händelser från dialogrutan

En anropsprocess kan registrera ett IFileDialogEvents-gränssnitt med dialogrutan med hjälp av IFileDialog::Advise and IFileDialog::Unadvise methods som visas här.

Detta hämtas från exempel på grundläggande användning .

        // 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);

Huvuddelen av dialogbearbetningen placeras här.

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

Anropsprocessen kan använda händelser för avisering när användaren ändrar mappen, filtypen eller markeringen. Dessa händelser är särskilt användbara när anropsprocessen har lagt till kontroller i dialogrutan (se Anpassa dialogrutan) och måste ändra tillståndet för dessa kontroller som en reaktion på dessa händelser. Användbar i alla fall är möjligheten för anropsprocessen att tillhandahålla anpassad kod för att hantera situationer som delningsöverträdelser, skriva över filer eller avgöra om en fil är giltig innan dialogrutan stängs. Några av dessa fall beskrivs i det här avsnittet.

OnFileOk

Den här metoden anropas när användaren har valt ett objekt, precis innan dialogrutan stängs. Programmet kan sedan anropa IFileDialog::GetResult eller IFileOpenDialog::GetResults som skulle göras när dialogrutan hade stängts. Om det valda objektet är acceptabelt kan de returnera S_OK. Annars returnerar de S_FALSE och visar användargränssnittet som talar om för användaren varför det valda objektet inte är giltigt. Om S_FALSE returneras stängs inte dialogrutan.

Den anropande processen kan använda själva dialogrutans fönsterhandtag som överordnat fönster för användargränssnittet. Det här handtaget kan hämtas genom att först anropa IOleWindow::QueryInterface och sedan anropa IOleWindow::GetWindow med handtaget som det visas i det här exemplet.

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 och OnOverwrite

Om användaren väljer att skriva över en fil i dialogrutan Spara , eller om en fil som sparas eller ersätts används och inte kan skrivas till (en delningsöverträdelse), kan programmet tillhandahålla anpassade funktioner för att åsidosätta standardbeteendet för dialogrutan. När du skriver över en fil visas som standard en uppmaning där användaren kan verifiera den här åtgärden. För delningsöverträdelser visas som standard ett felmeddelande i dialogrutan, den stängs inte och användaren måste göra ett annat val. Anropsprocessen kan åsidosätta dessa standardvärden och visa ett eget användargränssnitt om så önskas. Dialogrutan kan instrueras att neka filen och förbli öppen eller acceptera filen och stänga den.

Anpassa dialogrutan

Du kan lägga till en mängd olika kontroller i dialogrutan utan att ange en Win32-dialogmall. Dessa kontroller omfattar PushButton, ComboBox, EditBox, CheckButton, RadioButton-listor, grupper, avgränsare och Static Text-kontroller. Anropa QueryInterface på dialogobjektet (IFileDialog, IFileOpenDialog eller IFileSaveDialog) för att hämta en IFileDialogCustomize-pekare . Använd gränssnittet för att lägga till kontroller. Varje kontroll har ett associerat ID som tillhandahålls av anroparen samt ett synligt och aktiverat tillstånd som kan anges av den anropande processen. Vissa kontroller, till exempel PushButton, har också text associerad med dem.

Flera kontroller kan läggas till i en "visuell grupp" som flyttas som en enda enhet i dialogrutans layout. Grupper kan ha en etikett associerad med dem.

Kontroller kan bara läggas till innan dialogrutan visas. Men när dialogrutan visas kan kontroller döljas eller visas som önskat, kanske som svar på användaråtgärder. I följande exempel visas hur du lägger till en alternativknapplista i dialogrutan.

// 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;
}

Lägga till alternativ på OK-knappen

På samma sätt kan du lägga till alternativ i knapparna Öppna eller Spara , som är OK-knappen för respektive dialogtyp. Alternativen är tillgängliga via en listruta som är kopplad till knappen. Det första objektet i listan blir texten för knappen. I följande exempel visas hur du tillhandahåller en Öppna-knapp med två möjligheter: "Öppna" och "Öppna som skrivskyddad".

// 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;
}

Användarens val kan verifieras när dialogrutan har returnerats från metoden Visa som för en Kombinationsruta, eller så kan den verifieras som en del av hanteringen av IFileDialogEvents::OnFileOk.

Svara på händelser i tillagda kontroller

Händelsehanteraren som tillhandahålls av anropsprocessen kan implementera IFileDialogControlEvents utöver IFileDialogEvents. Med IFileDialogControlEvents kan anropsprocessen reagera på dessa händelser:

  • PushButton klickade
  • CheckButton-tillståndet har ändrats
  • Objekt som valts från en meny, Kombinationsruta eller RadioButton-lista
  • Kontroll aktiveras. Detta skickas när en meny är på väg att visa en listruta, om anropsprocessen vill ändra objekten i listan.

Fullständiga exempel

Följande är fullständiga, nedladdningsbara C++-exempel från Windows Software Development Kit (SDK) som visar användningen av och interaktionen med dialogrutan Common Item.

IID_PPV_ARGS