TN029: janelas separadoras

Esta nota descreve a Classe CSplitterWnd do MFC, que fornece divisões de janela e gerencia o redimensionamento de outras janelas do painel.

Estilos de divisor

Um CSplitterWnd dá suporte a dois estilos diferentes de janelas de divisão.

Em "divisores estáticos", a janela divisora cria os painéis ao ser criada. A ordem e o número de painéis nunca são alterados. As barras divisoras são usadas para redimensionar os diferentes painéis. Você pode usar esse estilo para exibir uma classe de exibição diferente em cada painel. O editor de gráficos do Visual C++ e o Gerenciador de Arquivos do Windows são exemplos de programas que usam esse estilo de divisor. Esse estilo de janela divisora não usa caixas divisoras.

Em "divisores dinâmicos", painéis adicionais são criados e destruídos à medida que o usuário divide e reúne novas exibições. Esse divisor começa com uma única exibição e fornece caixas divisoras para o usuário iniciar a divisão. A janela divisora cria dinamicamente um novo objeto de exibição quando a exibição é dividida em uma direção. Esse novo objeto de exibição representa o novo painel. Se a exibição for dividida em duas direções usando a interface do teclado, a janela divisora criará três novos objetos de exibição para os três novos painéis. Enquanto a divisão está ativa, o Windows exibe a caixa divisora como uma barra divisora entre os painéis. O Windows destrói objetos de exibição adicionais quando o usuário remove uma divisão, mas a exibição original permanece até que a própria janela divisora seja destruída. O Microsoft Excel e o Microsoft Word são exemplos de aplicativos que usam o estilo de divisor dinâmico.

Ao criar qualquer tipo de janela divisora, você deve especificar o número máximo de linhas e colunas que a divisora gerenciará. Um divisor estático criará painéis para preencher todas as linhas e colunas. Um divisor dinâmico criará apenas o primeiro painel quando o CSplitterWnd for criado.

O número máximo de painéis que você pode especificar para divisores estáticos é de 16 linhas por 16 colunas. As configurações recomendadas são:

  • 1 linha x 2 colunas: geralmente com painéis diferentes

  • 2 linhas x 1 coluna: geralmente com painéis diferentes

  • 2 linhas x 2 colunas: geralmente com painéis semelhantes

O número máximo de painéis que você pode especificar para divisores dinâmicos é de 2 linhas por 2 colunas. As configurações recomendadas são:

  • 1 linha x 2 colunas: para dados colunares

  • 2 linhas x 1 coluna: para textuais ou outros dados

  • 2 linhas x 2 colunas: para dados orientados por grade ou tabela

Exemplos de divisor

Muitos dos programas de exemplo do MFC usam janelas divisoras direta ou indiretamente. O exemplo geral do MFC VIEWEX ilustra vários usos de divisores estáticos, incluindo como colocar um divisor em um divisor.

Você também pode usar o ClassWizard para criar uma nova classe de janela de quadro filho de MDI (interface de documento múltiplo) que contém uma janela divisora. Para obter mais informações sobre janelas divisoras, consulte Diversos tipos de documentos, exibições e janelas de quadro.

Terminologia usada pela implementação

Aqui está uma lista de termos específicos para janelas divisoras:

CSplitterWnd: uma janela que fornece controles de divisão de painel e barras de rolagem que são compartilhadas entre todos os painéis em uma linha ou coluna. Especifique linhas e colunas com números baseados em zero (o primeiro painel é linha = 0 e coluna = 0).

Painel: uma janela específica do aplicativo que um CSplitterWnd gerencia. Um painel geralmente é um objeto derivado da Classe CView, mas pode ser qualquer objeto CWnd que tenha a ID da janela filho apropriada.

Para usar um objeto derivado de CWnd, passe a RUNTIME_CLASS do objeto para a função CreateView como faria se estivesse usando uma classe derivada de CView. Sua classe deve usar DECLARE_DYNCREATE e IMPLEMENT_DYNCREATE porque a estrutura usa a criação dinâmica no runtime. Embora haja muito código em CSplitterWnd que seja específico para a classe CView, CObject::IsKindOf sempre é usado antes que essas ações sejam executadas.

Barra Divisora: um controle que é colocado entre as linhas e colunas dos painéis. Ele pode ser usado para ajustar os tamanhos das linhas ou colunas dos painéis.

Caixa Divisora: um controle em uma dinâmica CSplitterWnd que você pode usar para criar novas linhas ou colunas de painéis. Ela está localizada na parte superior das barras de rolagem vertical ou à esquerda das barras de rolagem horizontal.

Interseção divisora: a interseção de uma barra divisora vertical e uma barra divisora horizontal. Você pode arrastá-la para ajustar o tamanho de uma linha e coluna dos painéis simultaneamente.

Barras de rolagem compartilhadas

A classe CSplitterWnd também dá suporte a barras de rolagem compartilhadas. Esses controles de barra de rolagem são filhos do CSplitterWnd e são compartilhados com os diferentes painéis no divisor.

Por exemplo, em uma janela de 1 linha x 2 colunas, você pode especificar WS_VSCROLL ao criar o CSplitterWnd. O Windows cria um controle de barra de rolagem especial compartilhado entre os dois painéis.

[      ][      ][^]
[pane00][pane01][|]
[      ][      ][v]

Quando o usuário mover a barra de rolagem, mensagens do WM_VSCROLL serão enviadas para ambas as exibições. Quando uma das exibições definir a posição da barra de rolagem, a barra de rolagem compartilhada será definida.

Observe que as barras de rolagem compartilhadas são mais úteis com objetos de exibição semelhantes. Se você misturar exibições de diferentes tipos em um divisor, talvez seja necessário escrever um código especial para coordenar suas posições de rolagem. Qualquer classe derivada de CView que usa as APIs da barra de rolagem CWnd delegará à barra de rolagem compartilhada se ela existir. A implementação CScrollView é um exemplo de uma classe CView que dá suporte a barras de rolagem compartilhadas. Classes que não são derivadas de CView, classes que dependem de barras de rolagem não controladas ou classes que usam implementações padrão do Windows (por exemplo, CEditView) não funcionarão com o recurso de barra de rolagem compartilhada de CSplitterWnd.

Tamanhos Mínimos

Para cada linha, há uma altura mínima de linha e, para cada coluna, há uma largura mínima da coluna. Esse mínimo garante que um painel não seja muito pequeno para ser mostrado em detalhes completos.

Para uma janela divisora estática, o mínimo inicial de altura da linha e a largura da coluna é 0. Para uma janela divisora dinâmica, o mínimo inicial de altura da linha e largura da coluna é definido pelo parâmetro sizeMin da função CSplitterWnd::Create.

Você pode alterar esses tamanhos mínimos usando as funções CSplitterWnd::SetRowInfo e CSplitterWnd::SetColumnInfo.

Tamanhos reais versus tamanhos ideais

O layout dos painéis na janela divisora depende do tamanho do quadro que os contém. Quando um usuário redimensiona o quadro que os contém, o CSplitterWnd reposiciona e redimensiona os painéis para que se ajustem da melhor maneira possível.

O usuário pode definir manualmente os tamanhos de altura da linha e largura da coluna ou o programa pode definir o tamanho ideal usando a classe CSplitterWnd. O tamanho real pode ser menor ou maior que o ideal. O Windows ajustará o tamanho real se não houver espaço suficiente para exibir o tamanho ideal ou se houver muito espaço vazio à direita ou na parte inferior da janela divisora.

Controles personalizados

Você pode substituir muitas funções para fornecer um comportamento e uma interface personalizados. Você pode substituir esse primeiro conjunto para fornecer imagens alternativas para os vários componentes gráficos de uma janela divisora.

  • virtual void OnDrawSpltter(CDC* pDC, ESplitType nType, const CRect& rect);

  • virtual void OnInvertTracker(const CRect& rect);

Você chama essa função para criar um controle de barra de rolagem compartilhado. Você pode substituí-la para criar controles extras ao lado da barra de rolagem.

  • virtual BOOL CreateScrollBarCtrl(DWORD dwStyle, UINT nID);

Essas funções implementam a lógica da janela divisora dinâmica. Você pode substituí-las para fornecer uma lógica de divisor mais avançada.

  • virtual void DeleteView(int row, int col);

  • virtual BOOL SplitRow(int cyBefore);

  • virtual BOOL SplitColumn(int cxBefore);

  • virtual void DeleteRow(int rowDelete);

  • virtual void DeleteColumn(int colDelete);

Funcionalidade CView

A classe CView usa os comandos de alto nível a seguir para delegar à implementação CSplitterWnd. Como esses comandos são virtuais, a implementação CView padrão não exigirá que toda a implementação CSplitterWnd seja vinculada. Para aplicativos que usam CView, mas não CSplitterWnd, a implementação CSplitterWnd não será vinculada ao aplicativo.

  • virtual BOOL CanActivateNext(BOOL bPrev = FALSE);

    Verifica se ID_NEXT_PANE ou ID_PREV_PANE atualmente é possível.

  • virtual void ActivateNext(BOOL bPrev = FALSE);

    Executa o comando "Próximo Painel" ou "Painel Anterior".

  • virtual BOOL DoKeyboardSplit();

    Executa o comando de divisão de teclado, geralmente "Divisão de Janela".

Confira também

Observações técnicas por número
Observações técnicas por categoria