Partilhar via


Usando caixas de diálogo comuns

Esta seção aborda tarefas que invocam caixas de diálogo comuns:

Escolher uma cor

Este tópico descreve o código de exemplo que exibe uma caixa de diálogo Cor para que um utilizador possa selecionar uma cor. O exemplo de código primeiro inicializa uma estrutura CHOOSECOLOR e, em seguida, chama a função ChooseColor para exibir a caixa de diálogo. Se a função retornar TRUE, indicando que o usuário selecionou uma cor, o código de exemplo usará a cor selecionada para criar um novo pincel sólido.

Este exemplo usa a estruturaCHOOSECOLOR para inicializar a caixa de diálogo da seguinte maneira:

  • Inicializa o lpCustColors membro com um ponteiro para uma matriz estática de valores. As cores na matriz são inicialmente pretas, mas a matriz estática preserva as cores personalizadas criadas pelo usuário para chamadas subsequentes de ChooseColor.
  • Configura o sinalizador CC_RGBINIT e inicializa o membro rgbResult para especificar a cor selecionada inicialmente quando a caixa de diálogo é aberta. Se não for especificado, a seleção inicial será preta. O exemplo usa a variável estática rgbCurrent para preservar o valor selecionado entre chamadas para a função ChooseColor.
  • Define o sinalizador CC_FULLOPEN para que a extensão de cores personalizadas da caixa de diálogo seja sempre exibida.
CHOOSECOLOR cc;                 // common dialog box structure 
static COLORREF acrCustClr[16]; // array of custom colors 
HWND hwnd;                      // owner window
HBRUSH hbrush;                  // brush handle
static DWORD rgbCurrent;        // initial color selection

// Initialize CHOOSECOLOR 
ZeroMemory(&cc, sizeof(cc));
cc.lStructSize = sizeof(cc);
cc.hwndOwner = hwnd;
cc.lpCustColors = (LPDWORD) acrCustClr;
cc.rgbResult = rgbCurrent;
cc.Flags = CC_FULLOPEN | CC_RGBINIT;
 
if (ChooseColor(&cc)==TRUE) 
{
    hbrush = CreateSolidBrush(cc.rgbResult);
    rgbCurrent = cc.rgbResult; 
}

Escolher um tipo de letra

Este tópico descreve o código de exemplo que exibe uma caixa de diálogo Fonte para que um usuário possa escolher os atributos de uma fonte. O código de exemplo primeiro inicializa uma estrutura de CHOOSEFONT e, em seguida, chama a função ChooseFont para exibir a caixa de diálogo.

Este exemplo define o sinalizador CF_SCREENFONTS para especificar que a caixa de diálogo deve exibir apenas fontes de tela. Ele define o sinalizador CF_EFFECTS para exibir controles que permitem ao usuário selecionar opções de riscado, sublinhado e cor.

Se ChooseFont retornar TRUE , indicando que o usuário clicou no botão OK, a estruturaCHOOSEFONT conterá informações que descrevem os atributos de fonte e fonte selecionados pelo usuário, incluindo os membros da estrutura deLOGFONTapontada pelo membro lpLogFont. O membro rgbColors contém a cor de texto selecionada. O código de exemplo usa essas informações para definir a fonte e a cor do texto para o contexto do dispositivo associado à janela do proprietário.

HWND hwnd;                // owner window
HDC hdc;                  // display device context of owner window

CHOOSEFONT cf;            // common dialog box structure
static LOGFONT lf;        // logical font structure
static DWORD rgbCurrent;  // current text color
HFONT hfont, hfontPrev;
DWORD rgbPrev;

// Initialize CHOOSEFONT
ZeroMemory(&cf, sizeof(cf));
cf.lStructSize = sizeof (cf);
cf.hwndOwner = hwnd;
cf.lpLogFont = &lf;
cf.rgbColors = rgbCurrent;
cf.Flags = CF_SCREENFONTS | CF_EFFECTS;

if (ChooseFont(&cf)==TRUE)
{
    hfont = CreateFontIndirect(cf.lpLogFont);
    hfontPrev = SelectObject(hdc, hfont);
    rgbCurrent= cf.rgbColors;
    rgbPrev = SetTextColor(hdc, rgbCurrent);
 .
 .
 .
}

Abrindo um arquivo

Observação

A partir do Windows Vista, a caixa de diálogo Arquivo comum foi substituída pela caixa de diálogo Item comum quando usada para abrir um arquivo. Recomendamos que você use a API Common Item Dialog em vez da Common File Dialog API. Para obter mais informações, consulte caixa de diálogo Item comum.

Este tópico descreve o código de exemplo que exibe uma caixa de diálogo Abrir para que um usuário possa especificar a unidade, o diretório e o nome de um arquivo a ser aberto. O código de exemplo primeiro inicializa uma estrutura deOPENFILENAME e, em seguida, chama a funçãoGetOpenFileName para exibir a caixa de diálogo.

Neste exemplo, o membro lpstrFilter é um ponteiro para um buffer que especifica dois filtros de nome de arquivo que o usuário pode selecionar para limitar os nomes de arquivo exibidos. O buffer contém uma matriz terminada duplamente nula de cadeias de caracteres na qual cada par de cadeias especifica um filtro. O membro nFilterIndex especifica que o primeiro padrão é usado quando a caixa de diálogo é criada.

Este exemplo define os sinalizadores OFN_PATHMUSTEXIST e OFN_FILEMUSTEXIST no membro Flags. Esses sinalizadores fazem com que a caixa de diálogo verifique, antes de retornar, se o caminho e o nome do arquivo especificados pelo usuário realmente existem.

A funçãoGetOpenFileName retornará TRUE se o usuário clicar no botão OK e o caminho especificado e o nome do arquivo existirem. Nesse caso, o buffer apontado pelo membro lpstrFile contém o caminho e o nome do arquivo. O código de exemplo usa essas informações em uma chamada para a função para abrir o arquivo.

Embora este exemplo não defina o sinalizador OFN_EXPLORER, ele ainda exibe a caixa de diálogo padrão estilo Explorer Abrir. No entanto, se pretender fornecer um procedimento de gancho ou um modelo personalizado e quiser a interface de utilizador do Explorer, deverá ativar o sinalizador OFN_EXPLORER.

Observação

Na linguagem de programação C, uma cadeia de caracteres entre aspas é terminada em nulo.

 

OPENFILENAME ofn;       // common dialog box structure
char szFile[260];       // buffer for file name
HWND hwnd;              // owner window
HANDLE hf;              // file handle

// Initialize OPENFILENAME
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwnd;
ofn.lpstrFile = szFile;
// Set lpstrFile[0] to '\0' so that GetOpenFileName does not 
// use the contents of szFile to initialize itself.
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = "All\0*.*\0Text\0*.TXT\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

// Display the Open dialog box. 

if (GetOpenFileName(&ofn)==TRUE) 
    hf = CreateFile(ofn.lpstrFile, 
                    GENERIC_READ,
                    0,
                    (LPSECURITY_ATTRIBUTES) NULL,
                    OPEN_EXISTING,
                    FILE_ATTRIBUTE_NORMAL,
                    (HANDLE) NULL);

Exibindo a caixa de diálogo de impressão

Este tópico descreve o código de exemplo que exibe uma caixa de diálogo Imprimir para que um usuário possa selecionar opções para imprimir um documento. O código de exemplo primeiro inicializa uma estrutura PRINTDLG e, em seguida, chama a função PrintDlg para exibir a caixa de diálogo.

Este exemplo define o sinalizador PD_RETURNDC no membro Flags da estrutura PRINTDLG. Isso faz com que PrintDlg retorne um identificador de contexto de dispositivo para a impressora selecionada no membro hDC. Você pode usar o identificador para renderizar a saída na impressora.

Na entrada, o código de exemplo define os membros hDevMode e hDevNames como NULL. Se a função retornar TRUE, esses membros retornarão identificadores para DEVNAMES estruturas que contêm a entrada do usuário e informações sobre a impressora. Você pode usar essas informações para preparar a saída a ser enviada para a impressora selecionada.

PRINTDLG pd;
HWND hwnd;

// Initialize PRINTDLG
ZeroMemory(&pd, sizeof(pd));
pd.lStructSize = sizeof(pd);
pd.hwndOwner   = hwnd;
pd.hDevMode    = NULL;     // Don't forget to free or store hDevMode.
pd.hDevNames   = NULL;     // Don't forget to free or store hDevNames.
pd.Flags       = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC; 
pd.nCopies     = 1;
pd.nFromPage   = 0xFFFF; 
pd.nToPage     = 0xFFFF; 
pd.nMinPage    = 1; 
pd.nMaxPage    = 0xFFFF; 

if (PrintDlg(&pd)==TRUE) 
{
    // GDI calls to render output. 

    // Delete DC when done.
    DeleteDC(pd.hDC);
}

Utilizando o painel de propriedades de impressão

Este tópico descreve o código de exemplo que exibe um Imprimir ficha de propriedades para que um utilizador possa selecionar opções para imprimir um documento. O código de exemplo primeiro inicializa uma estrutura de PRINTDLGEX e, em seguida, chama a função PrintDlgEx para exibir a folha de propriedades.

O código de exemplo define o sinalizador PD_RETURNDC no membro Flags da estrutura PRINTDLG. Isso faz com que a função PrintDlgEx retorne um identificador de contexto de dispositivo no membro hDC para a impressora selecionada.

Quando ocorre a entrada, o código de exemplo define os membros das estruturas hDevMode e hDevNames para NULL. Se a função retornar S_OK, esses membros retornarão identificadores para DEVNAMES estruturas contendo a entrada do usuário e informações sobre a impressora. Você pode usar essas informações para preparar a saída a ser enviada para a impressora selecionada.

Após a conclusão da operação de impressão, o código de exemplo libera o DEVMODE, DEVNAMESe PRINTPAGERANGE buffers e chama a função DeleteDC para excluir o contexto do dispositivo.

// hWnd is the window that owns the property sheet.
HRESULT DisplayPrintPropertySheet(HWND hWnd)
{
    HRESULT hResult;
    PRINTDLGEX pdx = {0};
    LPPRINTPAGERANGE pPageRanges = NULL;

    // Allocate an array of PRINTPAGERANGE structures.
    pPageRanges = (LPPRINTPAGERANGE) GlobalAlloc(GPTR, 10 * sizeof(PRINTPAGERANGE));
    if (!pPageRanges)
        return E_OUTOFMEMORY;

    //  Initialize the PRINTDLGEX structure.
    pdx.lStructSize = sizeof(PRINTDLGEX);
    pdx.hwndOwner = hWnd;
    pdx.hDevMode = NULL;
    pdx.hDevNames = NULL;
    pdx.hDC = NULL;
    pdx.Flags = PD_RETURNDC | PD_COLLATE;
    pdx.Flags2 = 0;
    pdx.ExclusionFlags = 0;
    pdx.nPageRanges = 0;
    pdx.nMaxPageRanges = 10;
    pdx.lpPageRanges = pPageRanges;
    pdx.nMinPage = 1;
    pdx.nMaxPage = 1000;
    pdx.nCopies = 1;
    pdx.hInstance = 0;
    pdx.lpPrintTemplateName = NULL;
    pdx.lpCallback = NULL;
    pdx.nPropertyPages = 0;
    pdx.lphPropertyPages = NULL;
    pdx.nStartPage = START_PAGE_GENERAL;
    pdx.dwResultAction = 0;
    
    //  Invoke the Print property sheet.
    
    hResult = PrintDlgEx(&pdx);

    if ((hResult == S_OK) && pdx.dwResultAction == PD_RESULT_PRINT) 
    {
        // User clicked the Print button, so use the DC and other information returned in the 
        // PRINTDLGEX structure to print the document.
    }

    if (pdx.hDevMode != NULL) 
        GlobalFree(pdx.hDevMode); 
    if (pdx.hDevNames != NULL) 
        GlobalFree(pdx.hDevNames); 
    if (pdx.lpPageRanges != NULL)
        GlobalFree(pPageRanges);

    if (pdx.hDC != NULL) 
        DeleteDC(pdx.hDC);

    return hResult;
}

Configurando a página impressa

Este tópico descreve o código de exemplo que exibe uma caixa de diálogo Configuração de Página para que um usuário possa selecionar os atributos da página impressa, como o tipo de papel, a fonte do papel, a orientação da página e as margens da página. O código de exemplo primeiro inicializa uma estrutura de PAGESETUPDLG e, em seguida, chama a funçãoPageSetupDlg para exibir a caixa de diálogo.

Este exemplo define a bandeira PSD_MARGINS no membro Flags e usa o membro rtMargin para especificar os valores iniciais de margem. Ele define o sinalizador PSD_INTHOUSANDTHSOFINCHES para garantir que a caixa de diálogo expresse as dimensões da margem em milésimos de polegada.

Na entrada, o código de exemplo define o hDevMode e hDevNames membros para NULL. Se a função retornar TRUE, ela usará esses membros para retornar identificadores para estruturas DEVNAMES que contêm a entrada do usuário e informações sobre a impressora. Você pode usar essas informações para preparar a saída a ser enviada para a impressora selecionada.

O exemplo a seguir também habilita um PagePaintHook procedimento de gancho para personalizar o desenho do conteúdo da página de exemplo.

PAGESETUPDLG psd;    // common dialog box structure
HWND hwnd;           // owner window

// Initialize PAGESETUPDLG
ZeroMemory(&psd, sizeof(psd));
psd.lStructSize = sizeof(psd);
psd.hwndOwner   = hwnd;
psd.hDevMode    = NULL; // Don't forget to free or store hDevMode.
psd.hDevNames   = NULL; // Don't forget to free or store hDevNames.
psd.Flags       = PSD_INTHOUSANDTHSOFINCHES | PSD_MARGINS | 
                  PSD_ENABLEPAGEPAINTHOOK; 
psd.rtMargin.top = 1000;
psd.rtMargin.left = 1250;
psd.rtMargin.right = 1250;
psd.rtMargin.bottom = 1000;
psd.lpfnPagePaintHook = PaintHook;

if (PageSetupDlg(&psd)==TRUE)
{
    // check paper size and margin values here.
}

O exemplo a seguir mostra um exemplo procedimento de gancho de PagePaintHook que desenha o retângulo de margem na área da página de exemplo:

BOOL CALLBACK PaintHook(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
    LPRECT lprc; 
    COLORREF crMargRect; 
    HDC hdc, hdcOld; 
 
    switch (uMsg) 
    { 
        // Draw the margin rectangle. 
        case WM_PSD_MARGINRECT: 
            hdc = (HDC) wParam; 
            lprc = (LPRECT) lParam; 
 
            // Get the system highlight color. 
            crMargRect = GetSysColor(COLOR_HIGHLIGHT); 
 
            // Create a dash-dot pen of the system highlight color and 
            // select it into the DC of the sample page. 
            hdcOld = SelectObject(hdc, CreatePen(PS_DASHDOT, .5, crMargRect)); 
 
            // Draw the margin rectangle. 
            Rectangle(hdc, lprc->left, lprc->top, lprc->right, lprc->bottom); 
 
            // Restore the previous pen to the DC. 
            SelectObject(hdc, hdcOld); 
            return TRUE; 
 
        default: 
            return FALSE; 
    } 
    return TRUE; 
}

Localizar Texto

Este tópico descreve o código de exemplo que exibe e gerencia uma caixa de diálogo Localizar para que o usuário possa especificar os parâmetros de uma operação de pesquisa. A caixa de diálogo envia mensagens para o procedimento da janela para que você possa executar a operação de pesquisa.

O código para exibir e gerenciar uma caixa de diálogo Substituir é semelhante, exceto que utiliza a função ReplaceText para exibir a caixa de diálogo. A caixa de diálogo Substituir também envia mensagens em resposta a cliques do utilizador nos botões Substituir e Substituir Tudo.

Para usar a caixa de diálogo Localizar ou Substituir, você deve executar três tarefas separadas:

  1. Obtenha um identificador de mensagem registada para a mensagem FINDMSGSTRING.
  2. Exiba a caixa de diálogo.
  3. Processem mensagens FINDMSGSTRING quando a caixa de diálogo estiver aberta.

Quando você inicializar seu aplicativo, chame a função RegisterWindowMessage para obter um identificador de mensagem para a mensagem registrada FINDMSGSTRING.

UINT uFindReplaceMsg;  // message identifier for FINDMSGSTRING 

uFindReplaceMsg = RegisterWindowMessage(FINDMSGSTRING);

Para exibir uma caixa de diálogo Localizar, primeiro inicialize uma estrutura FINDREPLACE e, em seguida, chame a função FindText. Observe que a estrutura FINDREPLACE e o buffer para a cadeia de caracteres de pesquisa devem ser uma variável global ou estática para que ela não saia do escopo antes que a caixa de diálogo seja fechada. Você deve definir o membro hwndOwner para especificar a janela que recebe as mensagens registadas. Depois de criar a caixa de diálogo, você pode movê-la ou manipulá-la usando a alça retornada.

FINDREPLACE fr;       // common dialog box structure
HWND hwnd;            // owner window
CHAR szFindWhat[80];  // buffer receiving string
HWND hdlg = NULL;     // handle to Find dialog box

// Initialize FINDREPLACE
ZeroMemory(&fr, sizeof(fr));
fr.lStructSize = sizeof(fr);
fr.hwndOwner = hwnd;
fr.lpstrFindWhat = szFindWhat;
fr.wFindWhatLen = 80;
fr.Flags = 0;

hdlg = FindText(&fr);

Quando a caixa de diálogo estiver aberta, o seu loop de mensagem principal deve incluir uma chamada para a função IsDialogMessage. Passe um identificador para a caixa de diálogo como um parâmetro na chamada IsDialogMessage. Isso garante que a caixa de diálogo processe corretamente as mensagens do teclado.

Para monitorizar mensagens enviadas da caixa de diálogo, o procedimento da janela deve verificar a mensagem registrada FINDMSGSTRING e processar os valores passados na estrutura FINDREPLACE como no exemplo a seguir.

LPFINDREPLACE lpfr;

if (message == uFindReplaceMsg)
{ 
    // Get pointer to FINDREPLACE structure from lParam.
    lpfr = (LPFINDREPLACE)lParam;

    // If the FR_DIALOGTERM flag is set, 
    // invalidate the handle that identifies the dialog box. 
    if (lpfr->Flags & FR_DIALOGTERM)
    { 
        hdlg = NULL; 
        return 0; 
    } 

    // If the FR_FINDNEXT flag is set, 
    // call the application-defined search routine
    // to search for the requested string. 
    if (lpfr->Flags & FR_FINDNEXT) 
    {
        SearchFile(lpfr->lpstrFindWhat,
                   (BOOL) (lpfr->Flags & FR_DOWN), 
                   (BOOL) (lpfr->Flags & FR_MATCHCASE)); 
    }

    return 0; 
}