Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Começando com Windows Vista, a Caixa de Diálogo de Item Comum substitui a caixa de diálogo de arquivo comum mais antiga quando usada para abrir ou salvar um arquivo. A caixa de diálogo Item Comum é usada em duas variações: a caixa de diálogo Abrir e a caixa de diálogo Salvar . Essas duas caixas de diálogo compartilham a maior parte de suas funcionalidades, mas cada uma tem seus próprios métodos exclusivos.
Importante
IFileDialog é a API de diálogo de arquivo moderna (Windows Vista e posterior). As funções GetOpenFileName e GetSaveFileName mais antigas são herdadas e não devem ser usadas em novos aplicativos. As APIs herdadas não dão suporte ao namespace do Shell, à personalização da caixa de diálogo moderna ou aos recursos de metadados de arquivo.
Ao usar IFileDialog:
- Você deve chamar CoInitializeEx antes de chamar CoCreateInstance para criar a caixa de diálogo. Use
COINIT_APARTMENTTHREADEDpara threads de interface do usuário. - Usar
CLSID_FileOpenDialogouCLSID_FileSaveDialogcomCLSCTX_INPROC_SERVER. -
Alternativas modernas: para aplicativos UWP/WinUI, use Windows. Storage.Pickers. Para aplicativos de desktop .NET, WPF e WinForms fornecem encapsulamentos
OpenFileDialog/SaveFileDialogque usamIFileDialoginternamente.
Embora essa versão mais recente seja chamada de Caixa de Diálogo de Item Comum, ela continua a ser chamada de Caixa de Diálogo de Arquivo Comum na maioria da documentação. A menos que você esteja lidando especificamente com uma versão mais antiga do Windows, você deve assumir que qualquer menção da caixa de diálogo Arquivo Comum se refere a esta caixa de diálogo Item Comum.
Os tópicos a seguir são discutidos aqui:
- IFileDialog, IFileOpenDialog e IFileSaveDialog
- Escuta de eventos da caixa de diálogo
- Personalizando a caixa de diálogo
- Exemplos completos
- Tópicos relacionados
IFileDialog, IFileOpenDialog e IFileSaveDialog
Windows Vista fornece implementações das caixas de diálogo Abrir e Salvar: CLSID_FileOpenDialog e CLSID_FileSaveDialog. Essas caixas de diálogo são mostradas aqui.
IFileOpenDialog e IFileSaveDialog herdam do IFileDialog e compartilham grande parte de suas funcionalidades. Além disso, a caixa de diálogo Abrir dá suporte a IFileOpenDialog e a caixa de diálogo Salvar dá suporte a IFileSaveDialog.
A implementação da caixa de diálogo comum de item presente no Windows Vista oferece várias vantagens em relação à implementação fornecida em versões anteriores:
- Dá suporte ao uso direto do namespace do Shell por meio do IShellItem em vez de usar caminhos do sistema de arquivos.
- Permite a personalização simples da caixa de diálogo, como definir o rótulo do botão OK, sem exigir um procedimento de hook.
- Dá suporte à personalização mais abrangente da caixa de diálogo pela adição de um conjunto de controles controlados por dados que operam sem um modelo de caixa de diálogo Win32. Esse esquema de personalização libera o processo de chamada do layout da interface do usuário. Como as alterações no design da caixa de diálogo continuam a usar esse modelo de dados, a implementação da caixa de diálogo não está vinculada à versão atual específica da caixa de diálogo.
- Oferece suporte à notificação do chamador sobre eventos na caixa de diálogo, como alteração de seleção ou alteração do tipo de arquivo. Também permite que o processo de chamada conecte determinados eventos na caixa de diálogo, como a análise.
- Apresenta novos recursos de caixa de diálogo, como a adição de locais especificados pelo chamador à barra Locais .
- Na caixa de diálogo Salvar, os desenvolvedores podem aproveitar os novos recursos de metadados do Windows Vista Shell.
Além disso, os desenvolvedores podem optar por implementar as seguintes interfaces:
- IFileDialogEvents para receber notificações de eventos na caixa de diálogo.
- IFileDialogCustomize para adicionar controles à caixa de diálogo.
- IFileDialogControlEvents para ser notificado sobre eventos nesses controles adicionados.
A caixa de diálogo Abrir ou Salvar retorna um objeto IShellItem ou IShellItemArray para o processo de chamada. Em seguida, o chamador pode usar um objeto IShellItem individual para obter um caminho do sistema de arquivos ou abrir um fluxo no item para ler ou gravar informações.
Sinalizadores e opções disponíveis para os novos métodos de diálogo são muito semelhantes aos sinalizadores OFN mais antigos encontrados na estrutura OPENFILENAME e usados em GetOpenFileName e GetSaveFileName. Muitos deles são exatamente iguais, exceto que começam com um prefixo FOS. A lista completa pode ser encontrada nos tópicos IFileDialog::GetOptions e IFileDialog::SetOptions . As caixas de diálogo Abrir e Salvar são criadas por padrão com os sinalizadores mais comuns. Para a caixa de diálogo Abrir, é (FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST | FOS_NOCHANGEDIR), e para a caixa de diálogo Salvar, é (FOS_OVERWRITEPROMPT | FOS_NOREADONLYRETURN | FOS_PATHMUSTEXIST | FOS_NOCHANGEDIR).
IFileDialog e suas interfaces descendentes herdam e estendem IModalWindow.
Show recebe como único parâmetro o handle da janela pai. Se Show retornar com êxito, haverá um resultado válido. Se retornar HRESULT_FROM_WIN32(ERROR_CANCELLED), significa que o usuário cancelou a caixa de diálogo. Ele também pode retornar legitimamente outro código de erro, como E_OUTOFMEMORY.
Exemplo de uso
As seções a seguir mostram o código de exemplo para uma variedade de tarefas de diálogo.
- Uso básico
- Limitando resultados a itens do sistema de arquivos
- Especificando tipos de arquivo para uma caixa de diálogo
- Controlando a pasta padrão
- Adicionar itens à barra de locais
- Persistência de Estado
- Funcionalidades de seleção múltipla
Grande parte do código de exemplo pode ser encontrada no Windows SDK Common File Dialog Sample.
Uso básico
O exemplo a seguir ilustra como iniciar uma caixa de diálogo Abrir . Neste exemplo, ele é restrito a documentos Microsoft Word.
Note
Vários exemplos neste tópico usam a CDialogEventHandler_CreateInstance função auxiliar para criar uma instância da implementação IFileDialogEvents . Para usar esta função no seu próprio código, copie o código-fonte da função CDialogEventHandler_CreateInstance do Exemplo da Caixa de Diálogo de Arquivo Comum, do qual foram extraídos todos os exemplos deste tópico.
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;
}
Limitando resultados a itens do sistema de arquivos
O exemplo a seguir, obtido acima, demonstra como restringir os resultados a itens do sistema de arquivos. Observe que IFileDialog::SetOptions adiciona o novo sinalizador a um valor obtido por meio de IFileDialog::GetOptions. Este e o método recomendado.
// 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);
Especificando tipos de arquivo para uma caixa de diálogo
Para definir tipos de arquivo específicos que a caixa de diálogo pode manipular, use o método IFileDialog::SetFileTypes . Esse método aceita uma matriz de estruturas de COMDLG_FILTERSPEC , cada uma delas representa um tipo de arquivo.
O mecanismo de extensão padrão em uma caixa de diálogo permanece inalterado em relação a GetOpenFileName e GetSaveFileName. A extensão de nome de arquivo que é acrescentada ao texto que o usuário digita na caixa de edição de nome de arquivo é inicializada quando a caixa de diálogo é aberta. Ele deve corresponder ao tipo de arquivo padrão (selecionado à medida que a caixa de diálogo é aberta). Se o tipo de arquivo padrão for "*.*" (todos os arquivos), o arquivo poderá ser uma extensão de sua escolha. Se o usuário escolher um tipo de arquivo diferente, a extensão será atualizada automaticamente para a primeira extensão de nome de arquivo associada a esse tipo de arquivo. Se o usuário escolher "*.*" (todos os arquivos), a extensão será revertida para seu valor original.
O exemplo a seguir ilustra como isso foi feito acima.
// 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");
Controlando a pasta padrão
Quase qualquer pasta no namespace shell pode ser usada como a pasta padrão para a caixa de diálogo (a pasta apresentada quando o usuário opta por abrir ou salvar um arquivo). Chame IFileDialog::SetDefaultFolder antes de chamar Show para fazer isso.
A pasta padrão é a pasta na qual a caixa de diálogo inicia na primeira vez que um usuário a abre do seu aplicativo. Depois disso, a caixa de diálogo será aberta na última pasta que um usuário abriu ou a última pasta usada para salvar um item. Consulte a Persistência de Estado para obter mais detalhes.
Você pode forçar a caixa de diálogo a sempre mostrar a mesma pasta quando ela for aberta, independentemente da ação anterior do usuário, chamando IFileDialog::SetFolder. No entanto, não recomendamos fazer isso. Se você chamar SetFolder antes de exibir a caixa de diálogo, o local mais recente no qual o usuário salvou ou abriu não será mostrado. A menos que haja um motivo muito específico para esse comportamento, não é uma experiência de usuário boa ou esperada e deve ser evitada. Em quase todas as instâncias, IFileDialog::SetDefaultFolder é o melhor método.
Ao salvar um documento pela primeira vez na caixa de diálogo Salvar , você deve seguir as mesmas diretrizes para determinar a pasta inicial como fez na caixa de diálogo Abrir . Se o usuário estiver editando um documento existente anteriormente, abra a caixa de diálogo na pasta em que o documento está armazenado e preencha a caixa de edição com o nome desse documento. Chame IFileSaveDialog::SetSaveAsItem com o item atual antes de chamar Show.
Adicionando itens à barra de lugares
O exemplo a seguir demonstra a adição de itens à barra Locais :
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;
}
Persistência de Estado
Antes de Windows Vista, um estado, como a última pasta visitada, era salvo por processo. No entanto, essas informações foram usadas independentemente da ação específica. Por exemplo, um aplicativo de edição de vídeo apresentaria a mesma pasta na caixa de diálogo Renderizar como que apresentaria na caixa de diálogo Importar mídia. Em Windows Vista você pode ser mais específico por meio do uso de GUIDs. Para atribuir um GUID à caixa de diálogo, chame iFileDialog::SetClientGuid.
Funcionalidades de seleção múltipla
A funcionalidade de seleção múltipla está disponível na caixa de diálogo Abrir usando o método GetResults, conforme mostrado a seguir.
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;
}
Escuta de eventos da caixa de diálogo
Um processo de chamada pode registrar uma interface IFileDialogEvents com a caixa de diálogo usando os métodos IFileDialog::Advise e IFileDialog::Unadvise , conforme mostrado aqui.
Isso é obtido do exemplo de Uso Básico .
// 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);
A maior parte do processamento da caixa de diálogo seria colocada aqui.
// Unhook the event handler.
pfd->Unadvise(dwCookie);
}
pfde->Release();
}
pfd->Release();
}
return hr;
}
O processo de chamada pode usar eventos para notificação quando o usuário altera a pasta, o tipo de arquivo ou a seleção. Esses eventos são particularmente úteis quando o processo de chamada adiciona controles à caixa de diálogo (consulte Personalizando a caixa de diálogo) e devem alterar o estado desses controles em reação a esses eventos. Útil em todos os casos é a capacidade do processo de chamada de fornecer código personalizado para lidar com situações como compartilhamento de violações, substituição de arquivos ou determinar se um arquivo é válido antes do fechamento da caixa de diálogo. Alguns desses casos são descritos nesta seção.
OnFileOk
Esse método é chamado depois que o usuário escolhe um item, logo antes do fechamento da caixa de diálogo. Em seguida, o aplicativo pode chamar IFileDialog::GetResult ou IFileOpenDialog::GetResults , como seria feito após o fechamento da caixa de diálogo. Se o item escolhido for aceitável, eles poderão retornar S_OK. Caso contrário, eles retornam S_FALSE e exibem a interface do usuário que informa ao usuário por que o item escolhido não é válido. Se S_FALSE for retornado, a caixa de diálogo não será fechada.
O processo de chamada pode usar o identificador de janela da própria caixa de diálogo como o pai da interface do usuário. Esse identificador pode ser obtido primeiro chamando IOleWindow::QueryInterface e, em seguida, chamando IOleWindow::GetWindow com o identificador, conforme mostrado neste exemplo.
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 e OnOverwrite
Se o usuário optar por substituir um arquivo na caixa de diálogo Salvar ou se um arquivo que está sendo salvo ou substituído estiver em uso e não puder ser gravado (uma violação de compartilhamento), o aplicativo poderá fornecer funcionalidade personalizada para substituir o comportamento padrão da caixa de diálogo. Por padrão, ao sobrescrever um arquivo, a caixa de diálogo exibe uma mensagem que permite ao usuário confirmar essa ação. Para violações de compartilhamento, por padrão, a caixa de diálogo exibe uma mensagem de erro, ela não fecha e o usuário é obrigado a fazer outra escolha. O processo de chamada pode substituir esses padrões e exibir sua própria interface do usuário, se desejado. A caixa de diálogo pode ser instruída a recusar o arquivo e permanecer aberta ou a aceitar o arquivo e ser fechada com sucesso.
Personalizando a caixa de diálogo
Uma variedade de controles pode ser adicionada à caixa de diálogo sem fornecer um modelo de caixa de diálogo Win32. Esses controles incluem PushButton, ComboBox, EditBox, CheckButton, listas RadioButton, Grupos, Separadores e controles de Texto Estático. Chame QueryInterface no objeto de diálogo (IFileDialog, IFileOpenDialog ou IFileSaveDialog) para obter um ponteiro IFileDialogCustomize . Use essa interface para adicionar controles. Cada controle tem uma ID fornecida pelo chamador associada, bem como um estado visível e habilitado que pode ser definido pelo processo de chamada. Alguns controles, como PushButton, também têm texto associado a eles.
Vários controles podem ser adicionados a um "grupo visual" que se move como uma única unidade no layout da caixa de diálogo. Os grupos podem ter um rótulo associado a eles.
Os controles só podem ser adicionados antes que a caixa de diálogo seja mostrada. No entanto, depois que a caixa de diálogo é exibida, os controles podem ser ocultos ou mostrados como desejado, talvez em resposta à ação do usuário. Os exemplos a seguir mostram como adicionar uma lista de botões de opção à caixa de diálogo.
// 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;
}
Adicionando opções ao botão OK
Da mesma forma, as opções podem ser adicionadas aos botões Abrir ou Salvar , que são o botão OK para seus respectivos tipos de caixa de diálogo. As opções são acessíveis por meio de uma caixa de listagem suspensa anexada ao botão. O primeiro item da lista se torna o texto do botão. O exemplo a seguir mostra como fornecer um botão Abrir com duas possibilidades: "Abrir" e "Abrir como somente leitura".
// 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;
}
A escolha do usuário pode ser verificada depois que a caixa de diálogo retorna do método Show, como você faria para um ComboBox, ou pode ser verificada como parte da manipulação de IFileDialogEvents::OnFileOk.
Respondendo a eventos em controles adicionados
O manipulador de eventos fornecido pelo processo de chamada pode implementar IFileDialogControlEvents além de IFileDialogEvents. IFileDialogControlEvents permite que o processo de chamada reaja a esses eventos:
- PushButton foi clicado
- Estado de checkButton alterado
- Item selecionado de um menu, ComboBox ou lista de RadioButton
- Ativação de controle. Isso é enviado quando um menu está prestes a exibir uma lista suspensa, caso o processo de chamada queira alterar os itens na lista.
Exemplos completos
A seguir estão exemplos completos em C++ que podem ser baixados, do Kit de Desenvolvimento de Software (SDK) do Windows, que demonstram o uso e a interação com a caixa de diálogo de item comum.
Tópicos relacionados: