Sobre as folhas de propriedades

Uma folha de propriedades é uma janela que permite ao usuário exibir e editar as propriedades de um item. Por exemplo, um aplicativo de planilha pode usar uma folha de propriedades para permitir que o usuário defina as propriedades de fonte e borda de uma célula ou para exibir e definir as propriedades de um dispositivo, como uma unidade de disco, impressora ou mouse.

Esta seção aborda os seguintes tópicos.

Noções básicas da folha de propriedades

Para implementar folhas de propriedades em seu aplicativo, inclua o arquivo de cabeçalho Prsht.h em seu projeto. Prsht.h contém todos os identificadores usados com folhas de propriedades.

Uma folha de propriedades contém uma ou mais janelas filhas sobrepostas chamadas páginas, cada uma contendo janelas de controle para definir um grupo de propriedades relacionadas. Por exemplo, uma página pode conter os controles para definir as propriedades de fonte de um item, incluindo o estilo do tipo, o tamanho do ponto, a cor e assim por diante. Cada página tem uma guia que o usuário pode selecionar para trazer a página para o primeiro plano da folha de propriedades. Por exemplo, o aplicativo do painel de controle Data-Hora exibe a seguinte folha de propriedades.

screen shot of a property sheet with two tabs, one of which shows a clock and a monthly calendar control

Uma folha de propriedades padrão com várias páginas com guias permite ao usuário acesso aleatório a todas as propriedades. Se for mais apropriado ter propriedades definidas em sequência, você poderá usar um assistente.

Caixas de diálogo da folha de propriedades

Uma folha de propriedades e as páginas que ela contém são, na verdade, caixas de diálogo. A folha de propriedades é uma caixa de diálogo definida pelo sistema que gerencia as páginas e fornece um contêiner comum para elas. Uma caixa de diálogo de folha de propriedades pode ser modal ou sem modo. Ele inclui um quadro, uma barra de título e quatro botões: OK, Cancelar, Aplicar e (opcionalmente) Ajuda. Os procedimentos da caixa de diálogo para as páginas recebem códigos de notificação na forma de mensagens de WM_NOTIFY quando o usuário clica nos botões.

Observação

Nem todas as informações nesta seção se aplicam aos assistentes, que têm uma aparência e um comportamento um pouco diferentes. Por exemplo, os assistentes têm um conjunto diferente de botões e nenhuma guia. Para obter mais informações, consulte Criando assistentes.

Cada página em uma folha de propriedades é uma caixa de diálogo sem janela restrita definida pelo aplicativo que gerencia as janelas de controle usadas para exibir e editar as propriedades de um item. Você fornece o modelo de caixa de diálogo usado para criar cada página, bem como o procedimento de caixa de diálogo que gerencia os controles e define as propriedades do item correspondente.

Uma folha de propriedades envia códigos de notificação para o procedimento de caixa de diálogo de uma página quando a página está ganhando ou perdendo a ativação e quando o usuário clica no botão OK, Cancelar, Aplicar ou Ajuda. As notificações são enviadas na forma de mensagens WM_NOTIFY. O parâmetro lParam é o endereço de uma estrutura NMHDR que inclui o identificador de janela para a caixa de diálogo da folha de propriedades.

Alguns códigos de notificação exigem que uma página retorne TRUE ou FALSE em resposta à mensagem WM_NOTIFY. Para fazer isso, a página deve usar a função SetWindowLong para definir o valor DWL_MSGRESULT da caixa de diálogo da página como TRUE ou FALSE.

Pages (Páginas)

Uma folha de propriedades deve conter pelo menos uma página, mas não pode conter mais do que o valor de MAXPROPPAGES, conforme definido nos arquivos de cabeçalho do Windows. Cada página tem um índice baseado em zero que a folha de propriedades atribui de acordo com a ordem em que a página é adicionada à folha de propriedades. Os índices são usados em mensagens que você envia para a folha de propriedades.

Uma página de propriedades pode conter uma caixa de diálogo aninhada. Se isso acontecer, você deverá incluir o estilo WS_EX_CONTROLPARENT para a caixa de diálogo de nível superior e chamar a função IsDialogMessage com o identificador para a caixa de diálogo pai. Isso garante que o usuário possa usar mnemônicos e as teclas de navegação da caixa de diálogo para mover o foco para controles na caixa de diálogo aninhada.

Cada página tem um ícone e um rótulo correspondentes. A folha de propriedades cria uma guia para cada página e exibe o ícone e o rótulo na guia. Espera-se que todas as páginas da folha de propriedades usem uma fonte sem negrito. Para garantir que a fonte não esteja em negrito, especifique o estilo DS_3DLOOK no modelo de caixa de diálogo.

O procedimento de caixa de diálogo para uma página não deve chamar a função EndDialog . Isso destruirá toda a folha de propriedades, não apenas a página.

O tamanho mínimo de uma página de folha de propriedades é de 212 unidades de diálogo horizontalmente e 114 unidades de diálogo verticalmente. Se uma caixa de diálogo de página for menor do que isso, a página será ampliada até atingir o tamanho mínimo. O arquivo de cabeçalho Prsht.h contém três conjuntos de tamanhos recomendados para páginas de folha de propriedades, conforme mostrado na tabela a seguir.

Tamanho Descrição
PROP_SM_CXDLG Largura, em unidades de diálogo, de uma pequena página de folha de propriedades.
PROP_SM_CYDLG Altura, em unidades de diálogo, de uma pequena página de folha de propriedades.
PROP_MED_CXDLG Largura, em unidades de diálogo, de uma página de folha de propriedades de tamanho médio.
PROP_MED_CYDLG Altura, em unidades de diálogo, de uma página de folha de propriedades de tamanho médio.
PROP_LG_CXDLG Largura, em unidades de diálogo, de uma página de folha de propriedades grande.
PROP_LG_CYDLG Altura, em unidades de diálogo, de uma página de folha de propriedades grande.

Usar esses tamanhos recomendados ajudará a garantir a consistência visual entre seu aplicativo e outros aplicativos do Microsoft Windows.

No editor de recursos do Microsoft Visual Studio, você pode criar uma página do tamanho apropriado na caixa de diálogo Adicionar Recurso . Expanda o nó Caixa de diálogo e selecione IDD_PROPPAGE_LARGE, IDD_PROPPAGE_MEDIUM ou IDD_PROPPAGE_SMALL.

A folha de propriedades é dimensionada automaticamente para acomodar a página maior.

Criação de folha de propriedades

Antes de criar uma folha de propriedades, você deve definir uma ou mais páginas. Isso envolve preencher uma estrutura PROPSHEETPAGE com informações sobre a página — seu ícone, rótulo, modelo de caixa de diálogo, procedimento de caixa de diálogo e assim por diante — e, em seguida, especificar o endereço da estrutura em uma chamada para a função CreatePropertySheetPage. A função retorna um identificador para o tipo HPROPSHEETPAGE que identifica exclusivamente a página.

Para criar uma folha de propriedades, especifique o endereço de uma estrutura PROPSHEETHEADER em uma chamada para a função PropertySheet. A estrutura define o ícone e o título da folha de propriedades e também inclui o endereço de uma matriz de identificadores HPROPSHEETPAGE que você obtém usando CreatePropertySheetPage. Quando PropertySheet cria a folha de propriedades, ele inclui as páginas identificadas na matriz. As páginas aparecem na folha de propriedades na mesma ordem em que estão contidas na matriz.

Outra maneira de atribuir páginas a uma folha de propriedades é especificar uma matriz de estruturas PROPSHEETPAGE em vez de uma matriz de identificadores HPROPSHEETPAGE. Nesse caso, PropertySheet cria identificadores para as páginas antes de adicioná-las à folha de propriedades.

Quando uma página é criada, seu procedimento de caixa de diálogo recebe uma mensagem WM_INITDIALOG. O parâmetro lParam da mensagem é um ponteiro para uma cópia da estrutura PROPSHEETPAGE que é definida quando a página é criada. Em particular, quando uma página é criada, o membro lParam da estrutura pode ser usado para passar informações definidas pelo aplicativo para o procedimento da caixa de diálogo. Com exceção do membro lParam , essa estrutura deve ser tratada como somente leitura. Modificar qualquer coisa que não seja lParam terá consequências imprevisíveis.

Quando o sistema passa subsequentemente uma cópia da estrutura PROPSHEETPAGE da página para seu aplicativo, ele usa o mesmo ponteiro. Quaisquer alterações na estrutura serão repassadas. Como o membro lParam é ignorado pelo sistema, ele pode ser modificado para enviar informações para outras partes do seu aplicativo. Você pode, por exemplo, usar lParam para passar informações para a função de retorno de chamada PropSheetPageProc da página.

PropertySheet define automaticamente o tamanho e a posição inicial de uma folha de propriedades. A posição é baseada na posição da janela do proprietário e o tamanho é baseado na maior página especificada na matriz de páginas quando a folha de propriedades foi criada. Se quiser que as páginas correspondam à largura dos quatro botões na parte inferior da folha de propriedades, defina a largura da página mais larga como 190 unidades de diálogo.

O tamanho de uma folha de propriedades é calculado a partir das propriedades width e height do modelo de diálogo no arquivo de recurso. Consulte Recurso DIALOG ou Recurso DIALOGEX para obter mais detalhes. Note, no entanto, que, por razões de compatibilidade, as dimensões são calculadas em relação à fonte MS Shell Dlg em vez da fonte usada pela página. Se você criar uma página que usa outra fonte, uma das sugestões a seguir pode ser usada.

  • Ajuste as dimensões do modelo de diálogo para compensar a diferença de tamanho entre a fonte MS Shell Dlg e a fonte que a página realmente usa. Por exemplo, se você escolher uma fonte que é duas vezes mais larga que o MS Shell Dlg, defina a propriedade width do modelo de diálogo para o dobro do uso normal.
  • Use um modelo DIALOGEX e defina o estilo de diálogo DS_SHELLFONT . Nesse caso, o gerenciador de folha de propriedades interpreta as dimensões do modelo de diálogo em relação à fonte usada pelo modelo de diálogo.

Adicionando e removendo páginas

Depois de criar uma folha de propriedades, um aplicativo pode adicionar uma página ao final do conjunto de páginas existente enviando uma mensagem de PSM_ADDPAGE . Para inserir uma página entre páginas existentes, envie uma mensagem PropSheet_InsertPage. Observe que o tamanho da folha de propriedades não pode ser alterado após sua criação. Todas as páginas adicionadas ou inseridas não devem ser maiores do que a maior página atualmente na folha de propriedades. Para remover uma página, envie uma mensagem de PSM_REMOVEPAGE .

Ao definir uma página, você pode especificar o endereço de uma função de retorno de chamada PropSheetPageProc que a folha de propriedades chama quando está criando ou removendo a página. O uso do PropSheetPageProc oferece a oportunidade de executar operações de inicialização e limpeza para páginas individuais.

Observação

Um número de mensagens e uma chamada de função ocorrem enquanto a folha de propriedades está manipulando a lista de páginas. Enquanto essa ação estiver ocorrendo, a tentativa de modificar a lista de páginas terá resultados imprevisíveis. Não adicione, insira ou remova páginas em sua implementação de PropSheetPageProc ou ao manipular as seguintes notificações e mensagens do Windows.

Se surgir a necessidade de modificar uma página de folha de propriedades enquanto você estiver manipulando uma dessas mensagens ou enquanto PropSheetPageProc estiver em operação, poste uma mensagem privada do Windows. Seu aplicativo não receberá essa mensagem até que o gerenciador da folha de propriedades tenha concluído suas tarefas, momento em que será seguro modificar a lista de páginas.

Quando uma folha de propriedades é destruída, ela destrói automaticamente todas as páginas que foram adicionadas a ela. As páginas são destruídas na ordem inversa daquela especificada na matriz usada para criar as páginas. Para destruir uma página que foi criada pela função CreatePropertySheetPage, mas não foi adicionada à folha de propriedades, use a função DestroyPropertySheetPage.

Rótulos de Título e Página da Folha de Propriedades

Você especifica o título de uma folha de propriedades na estrutura PROPSHEETHEADER usada para criar a folha de propriedades. Se o membro dwFlags incluir o valor PSH_PROPTITLE, a folha de propriedades adicionará o sufixo "Properties" ou o prefixo "Properties for", dependendo da versão. Você pode alterar o título depois que uma folha de propriedades é criada usando a mensagem PSM_SETTITLE. Em um Assistente Aero, essa mensagem pode ser usada para alterar o título de uma página interna dinamicamente.

Por padrão, uma folha de propriedades usa a cadeia de caracteres de nome especificada no modelo de caixa de diálogo como o rótulo de uma página. Você pode substituir a cadeia de caracteres de nome incluindo o valor PSP_USETITLE no membro dwFlags da estrutura PROPSHEETPAGE que define a página. Quando PSP_USETITLE é especificado, o membro pszTitle deve conter o endereço da cadeia de caracteres de rótulo para a página.

Ativação de página

Uma folha de propriedades pode ter apenas uma página ativa por vez. A página que tem a ativação está no primeiro plano da pilha sobreposta de páginas. O usuário ativa uma página selecionando sua guia; Um aplicativo ativa uma página usando a mensagem PSM_SETCURSEL.

A folha de propriedades envia o código de notificação PSN_KILLACTIVE para a página que está prestes a perder a ativação. Em resposta, a página deve validar quaisquer alterações que o usuário tenha feito na página. Se a página exigir entrada adicional do usuário antes de perder a ativação, use a função SetWindowLong para definir o valor DWL_MSGRESULT da página como TRUE. Além disso, a página deve exibir uma caixa de mensagem que descreve o problema e fornece a ação recomendada. Defina DWL_MSGRESULT como FALSE quando não houver problema em perder a ativação.

Antes que a página que está ganhando a ativação fique visível, a folha de propriedades envia o código de notificação PSN_SETACTIVE para a página. A página deve responder inicializando suas janelas de controle.

Botão Ajuda

As folhas de propriedades podem exibir dois botões da Ajuda: um botão Ajuda da folha de propriedades que é exibido na parte inferior do quadro, ao lado dos botões OK/Cancelar/Aplicação, e um botão padrão da barra de legenda que fornece Ajuda contextual.

O botão Ajuda da folha de propriedades é opcional e pode ser habilitado página por página. Para exibir o botão Ajuda da folha de propriedades para uma ou mais páginas:

  • Defina o sinalizador PSH_HASHELP no membro dwFlags da estrutura PROPSHEETHEADER da folha de propriedades.
  • Para cada página que exibirá um botão Ajuda, defina o sinalizador PSP_HASHELP no membro dwFlags da estrutura PROPSHEETPAGE da página.

Quando o usuário clica no botão Ajuda, a página ativa recebe um código de notificação PSN_HELP . A página deve responder exibindo informações da Ajuda, normalmente chamando a função WinHelp .

Removendo o botão Ajuda da barra de legendas

O botão Ajuda da barra de legenda é exibido por padrão, para que a Ajuda contextual esteja sempre disponível para os botões OK/Cancelar/Aplicar. No entanto, esse botão pode ser removido, se necessário. Para remover o botão Ajuda da barra de legendas de uma folha de propriedades:

  • Para versões dos controles comuns anteriores à versão 5.80, você deve implementar uma função de retorno de chamada de folha de propriedades.
  • Para a versão 5.80 e posterior dos controles comuns, você pode simplesmente definir o sinalizador PSH_NOCONTEXTHELP no membro dwFlags da estrutura PROPSHEETHEADER da folha de propriedades. No entanto, se você precisar de compatibilidade com versões anteriores do controle comum, deverá implementar a função de retorno de chamada.

Para implementar uma função de retorno de chamada da folha de propriedades que remove o botão Ajuda da barra de legendas:

  • Defina o sinalizador PSH_USECALLBACK no membro dwFlags da estrutura PROPSHEETHEADER da folha de propriedades.
  • Defina o membro pfnCallBack da estrutura PROPSHEETHEADER para apontar para a função de retorno de chamada.
  • Implemente a função de retorno de chamada. Quando essa função recebe a mensagem PSCB_PRECREATE, ela também receberá um ponteiro para o modelo de caixa de diálogo da folha de propriedades. Remova o estilo DS_CONTEXTHELP deste modelo.

O exemplo a seguir ilustra como implementar essa função de retorno de chamada:

int CALLBACK RemoveContextHelpProc(HWND hwnd, UINT message, LPARAM lParam)
{
    switch (message) 
    {
    case PSCB_PRECREATE:
        // Remove the DS_CONTEXTHELP style from the
        // dialog box template
        if (((LPDLGTEMPLATEEX)lParam)->signature ==    
           0xFFFF)
           {
            ((LPDLGTEMPLATEEX)lParam)->style 
            &= ~DS_CONTEXTHELP;
        }
        else {
            ((LPDLGTEMPLATE)lParam)->style 
            &= ~DS_CONTEXTHELP;
        }
        return TRUE;
    }
    return TRUE;
}

Se a estrutura DLGTEMPLATEEX não estiver definida, inclua a seguinte declaração:

#include <pshpack1.h>

typedef struct DLGTEMPLATEEX
{
    WORD dlgVer;
    WORD signature;
    DWORD helpID;
    DWORD exStyle;
    DWORD style;
    WORD cDlgItems;
    short x;
    short y;
    short cx;
    short cy;
} DLGTEMPLATEEX, *LPDLGTEMPLATEEX;

#include <poppack.h>

OK, Cancelar e Aplicar botões

Os botões OK e Aplicar são semelhantes, ambos direcionam as páginas de uma folha de propriedades para validar e aplicar as alterações de propriedade feitas pelo usuário. A única diferença é que clicar no botão OK faz com que a folha de propriedades seja destruída depois que as alterações forem aplicadas.

Quando o usuário clica no botão OK ou Aplicar , a folha de propriedades envia uma notificação PSN_KILLACTIVE para a página ativa, dando-lhe a oportunidade de validar as alterações do usuário. Se as alterações forem válidas, a página deverá chamar a função SetWindowLong com o valor DWL_MSGRESULT definido como FALSE. Se as alterações do usuário não forem válidas, a página deverá definir DWL_MSGRESULT como TRUE e exibir uma caixa de diálogo informando o usuário sobre o problema. A página permanece ativa até definir DWL_MSGRESULT como FALSE em resposta a uma mensagem PSN_KILLACTIVE.

Depois que uma página responder a uma notificação de PSN_KILLACTIVE definindo DWL_MSGRESULT como FALSE, a folha de propriedades enviará uma notificação PSN_APPLY para cada página. Quando uma página recebe essa notificação, ela deve aplicar as novas propriedades ao item correspondente. Para indicar à folha de propriedades que as alterações são válidas para a página, chame SetWindowLong com DWL_MSGRESULT definido como PSNRET_NOERROR. Se as alterações forem inválidas para a página, retorne um erro. Isso evita que a folha de propriedades seja destruída e retorna o foco para a página que recebeu a notificação PSN_APPLY ou para a página que tinha foco quando o botão Aplicar foi pressionado. Para retornar um erro e indicar qual página receberá foco, defina DWL_MSGRESULT para um dos seguintes valores.

  • PSNRET_INVALID. A folha de propriedades não será destruída e o foco será retornado a esta página.
  • PSNRET_INVALID_NOCHANGEPAGE. A folha de propriedades não será destruída e o foco será retornado à página que tinha foco quando o botão foi pressionado.

Um aplicativo pode usar a mensagem PSM_APPLY para simular a seleção do botão Aplicar.

O botão Aplicar é inicialmente desabilitado quando uma página se torna ativa, indicando que ainda não há alterações de propriedade a serem aplicadas. Quando a página recebe entrada por meio de um de seus controles indicando que o usuário editou uma propriedade, a página deve enviar a mensagem de PSM_CHANGED para a folha de propriedades. A mensagem faz com que a folha de propriedades habilite o botão Aplicar . Se, posteriormente, o usuário clicar no botão Aplicar ou Cancelar, a página deverá reinicializar seus controles e enviar a mensagem PSM_UNCHANGED para desabilitar novamente o botão Aplicar.

Às vezes, o botão Aplicar faz com que uma página faça uma alteração em uma folha de propriedades e a alteração não pode ser desfeita. Quando isso acontece, a página deve enviar a mensagem de PSM_CANCELTOCLOSE para a folha de propriedades. A mensagem faz com que a folha de propriedades altere o texto do botão OK para "Fechar", indicando que as alterações aplicadas não podem ser canceladas.

Às vezes, uma página faz uma alteração na configuração do sistema que requer que o Windows seja reiniciado ou o sistema reinicializado antes que a alteração possa entrar em vigor. Depois de fazer essa alteração, uma página deve enviar a mensagem PSM_RESTARTWINDOWS ou PSM_REBOOTSYSTEM para a folha de propriedades. Essas mensagens fazem com que a função PropertySheet retorne o valor ID_PSRESTARTWINDOWS ou ID_PSREBOOTSYSTEM depois que a folha de propriedades é destruída.

Quando um usuário clica no botão Cancelar, a folha de propriedades envia o código de notificação PSN_RESET para todas as páginas, indicando que a folha de propriedades está prestes a ser destruída. Uma página deve usar a notificação para executar operações de limpeza.

Assistentes

Um assistente é um tipo especial de folha de propriedades. Os assistentes são projetados para apresentar páginas uma de cada vez em uma sequência controlada pelo aplicativo. Em vez de selecionar em um grupo de páginas clicando em uma guia, os usuários navegam para frente e para trás pela sequência, uma página de cada vez, clicando em botões. Por exemplo, a captura de tela a seguir mostra a página de boas-vindas do assistente Adicionar Hardware:

screen shot of the welcome page of a wizard

A captura de tela a seguir mostra a primeira página de um Assistente Aero, o novo estilo introduzido no Windows Vista.

screen shot of the first page of an aero wizard

Consulte Criando assistentes para obter uma discussão completa sobre assistentes .