Recursos de janela

Essa visão geral discute recursos de janelas, como tipos de janela, estados, tamanho e posição.

Tipos de janela

Esta seção contém os tópicos a seguir que descrevem tipos de janela.

Windows sobreposto

Uma janela sobreposta é uma janela de nível superior (janela não filho) que tem uma barra de título, borda e área do cliente; ele serve como uma janela de main de um aplicativo. Ele também pode ter um menu de janela, minimizar e maximizar botões e barras de rolagem. Uma janela sobreposta usada como uma janela main normalmente inclui todos esses componentes.

Ao especificar o estilo WS_OVERLAPPED ou WS_OVERLAPPEDWINDOW na função CreateWindowEx , um aplicativo cria uma janela sobreposta. Se você usar o estilo WS_OVERLAPPED , a janela terá uma barra de título e uma borda. Se você usar o estilo WS_OVERLAPPEDWINDOW , a janela terá uma barra de título, borda de dimensionamento, menu de janela e minimizar e maximizar botões.

Pop-up Windows

Uma janela pop-up é um tipo especial de janela sobreposta usada para caixas de diálogo, caixas de mensagem e outras janelas temporárias que aparecem fora da janela main de um aplicativo. As barras de título são opcionais para janelas pop-up; caso contrário, as janelas pop-up são iguais às janelas sobrepostas do estilo WS_OVERLAPPED .

Você cria uma janela pop-up especificando o estilo WS_POPUP em CreateWindowEx. Para incluir uma barra de título, especifique o estilo WS_CAPTION. Use o estilo WS_POPUPWINDOW para criar uma janela pop-up que tenha uma borda e um menu de janela. O estilo WS_CAPTION deve ser combinado com o estilo WS_POPUPWINDOW para tornar o menu de janela visível.

Janelas filho

Uma janela filho tem o estilo WS_CHILD e está confinada à área do cliente de sua janela pai. Um aplicativo normalmente usa janelas filho para dividir a área do cliente de uma janela pai em áreas funcionais. Você cria uma janela filho especificando o estilo WS_CHILD na função CreateWindowEx .

Uma janela filho deve ter uma janela pai. A janela pai pode ser uma janela sobreposta, uma janela pop-up ou até mesmo outra janela filho. Especifique a janela pai ao chamar CreateWindowEx. Se você especificar o estilo WS_CHILD em CreateWindowEx , mas não especificar uma janela pai, o sistema não criará a janela.

Uma janela filho tem uma área de cliente, mas nenhum outro recurso, a menos que sejam solicitados explicitamente. Um aplicativo pode solicitar uma barra de título, um menu de janela, minimizar e maximizar botões, uma borda e barras de rolagem para uma janela filho, mas uma janela filho não pode ter um menu. Se o aplicativo especificar um identificador de menu, ao registrar a classe de janela filho ou criar a janela filho, o identificador de menu será ignorado. Se nenhum estilo de borda for especificado, o sistema criará uma janela sem bordas. Um aplicativo pode usar janelas filho sem borda para dividir a área do cliente de uma janela pai, mantendo as divisões invisíveis para o usuário.

Esta seção discute os seguintes aspectos das janelas filho:

Posicionamento

O sistema sempre posiciona uma janela filho em relação ao canto superior esquerdo da área de cliente da janela pai. Nenhuma parte de uma janela filho aparece fora das bordas de sua janela pai. Se um aplicativo criar uma janela filho maior que a janela pai ou posicionar uma janela filho para que parte ou toda a janela filho se estenda além das bordas do pai, o sistema cortará a janela filho; ou seja, a parte fora da área do cliente da janela pai não é exibida. As ações que afetam a janela pai também podem afetar a janela filho, da seguinte maneira.

Janela pai Janela Filho
Destruído Destruído antes que a janela pai seja destruída.
Hidden Oculto antes que a janela pai esteja oculta. Uma janela filho só fica visível quando a janela pai está visível.
Movido Movido com a área de cliente da janela pai. A janela filho é responsável por pintar sua área de cliente após a movimentação.
Mostrado Mostrado depois que a janela pai é mostrada.

 

Recortando

O sistema não recortar automaticamente uma janela filho da área do cliente da janela pai. Isso significa que a janela pai desenha sobre a janela filho se ela executar qualquer desenho no mesmo local que a janela filho. No entanto, o sistema cortará a janela filho da área do cliente da janela pai se a janela pai tiver o estilo WS_CLIPCHILDREN . Se a janela filho for recortada, a janela pai não poderá desenhar sobre ela.

Uma janela filho pode sobrepor outras janelas filho na mesma área do cliente. Uma janela filho que compartilha a mesma janela pai que uma ou mais janelas filho é chamada de janela de irmão. Janelas irmãos podem desenhar na área de cliente uma da outra, a menos que uma das janelas filho tenha o estilo WS_CLIPSIBLINGS . Se uma janela filho tiver esse estilo, qualquer parte de sua janela irmão que esteja dentro da janela filho será recortada.

Se uma janela tiver o estilo WS_CLIPCHILDREN ou WS_CLIPSIBLINGS , ocorrerá uma pequena perda de desempenho. Cada janela ocupa recursos do sistema, portanto, um aplicativo não deve usar janelas filho indiscriminadamente. Para obter o melhor desempenho, um aplicativo que precisa dividir logicamente sua janela main deve fazer isso no procedimento de janela da janela main em vez de usar janelas filho.

Relação com janela pai

Um aplicativo pode alterar a janela pai de uma janela filho existente chamando a função SetParent . Nesse caso, o sistema remove a janela filho da área do cliente da janela pai antiga e a move para a área do cliente da nova janela pai. Se SetParent especificar um identificador NULL , a janela da área de trabalho se tornará a nova janela pai. Nesse caso, a janela filho é desenhada na área de trabalho, fora das bordas de qualquer outra janela. A função GetParent recupera um identificador para a janela pai de uma janela filho.

A janela pai abre mão de uma parte de sua área de cliente para uma janela filho e a janela filho recebe toda a entrada dessa área. A classe de janela não precisa ser a mesma para cada uma das janelas filho da janela pai. Isso significa que um aplicativo pode preencher uma janela pai com janelas filho que parecem diferentes e realizar tarefas diferentes. Por exemplo, uma caixa de diálogo pode conter muitos tipos de controles, cada um uma janela filho que aceita diferentes tipos de dados do usuário.

Uma janela filho tem apenas uma janela pai, mas um pai pode ter qualquer número de janelas filho. Cada janela filho, por sua vez, pode ter janelas filho. Nessa cadeia de janelas, cada janela filho é chamada de janela descendente da janela pai original. Um aplicativo usa a função IsChild para descobrir se uma determinada janela é uma janela filho ou uma janela descendente de uma determinada janela pai.

A função EnumChildWindows enumera as janelas filho de uma janela pai. Em seguida, EnumChildWindows passa o identificador para cada janela filho para uma função de retorno de chamada definida pelo aplicativo. Janelas descendentes da janela pai fornecida também são enumeradas.

Mensagens

O sistema passa as mensagens de entrada de uma janela filho diretamente para a janela filho; as mensagens não são passadas pela janela pai. A única exceção será se a janela filho tiver sido desabilitada pela função EnableWindow . Nesse caso, o sistema passa todas as mensagens de entrada que teriam ido para a janela filho para a janela pai. Isso permite que a janela pai examine as mensagens de entrada e habilite a janela filho, se necessário.

Uma janela filho pode ter um identificador inteiro exclusivo. Identificadores de janela filho são importantes ao trabalhar com janelas de controle. Um aplicativo direciona a atividade de um controle enviando-lhe mensagens. O aplicativo usa o identificador de janela filho do controle para direcionar as mensagens para o controle. Além disso, um controle envia mensagens de notificação para sua janela pai. Uma mensagem de notificação inclui o identificador de janela filho do controle, que o pai usa para identificar qual controle enviou a mensagem. Um aplicativo especifica o identificador de janela filho para outros tipos de janelas filho definindo o parâmetro hMenu da função CreateWindowEx como um valor em vez de um identificador de menu.

Windows em camadas

O uso de uma janela em camadas pode melhorar significativamente o desempenho e os efeitos visuais de uma janela que tem uma forma complexa, anima sua forma ou deseja usar efeitos de combinação alfa. O sistema compõe e repinta automaticamente janelas em camadas e as janelas de aplicativos subjacentes. Como resultado, as janelas em camadas são renderizadas sem a cintilação típica de regiões de janela complexas. Além disso, as janelas em camadas podem ser parcialmente translúcidas, ou seja, combinadas em alfa.

Para criar uma janela em camadas, especifique o WS_EX_LAYERED estilo de janela estendido ao chamar a função CreateWindowEx ou chame a função SetWindowLong para definir WS_EX_LAYERED após a criação da janela. Após a chamada CreateWindowEx , a janela em camadas não ficará visível até que a função SetLayeredWindowAttributes ou UpdateLayeredWindow seja chamada para essa janela.

Observação

Começando com Windows 8, WS_EX_LAYERED podem ser usados com janelas filho e janelas de nível superior. As versões anteriores do Windows dão suporte apenas a WS_EX_LAYERED para janelas de nível superior.

 

Para definir o nível de opacidade ou a chave de cor de transparência para uma determinada janela em camadas, chame SetLayeredWindowAttributes. Após a chamada, o sistema ainda poderá solicitar que a janela seja pintada quando a janela for mostrada ou redimensionada. No entanto, como o sistema armazena a imagem de uma janela em camadas, o sistema não solicitará que a janela pinte se partes dela forem reveladas como resultado de movimentações relativas da janela na área de trabalho. Os aplicativos herdados não precisam reestruturar o código de pintura se quiserem adicionar efeitos de translucência ou transparência para uma janela, pois o sistema redireciona a pintura de janelas que chamaram SetLayeredWindowAttributes na memória fora da tela e a recompõe para obter o efeito desejado.

Para animação mais rápida e eficiente ou se for necessário alfa por pixel, chame UpdateLayeredWindow. UpdateLayeredWindow deve ser usado principalmente quando o aplicativo deve fornecer diretamente a forma e o conteúdo de uma janela em camadas, sem usar o mecanismo de redirecionamento que o sistema fornece por meio de SetLayeredWindowAttributes. Além disso, usar UpdateLayeredWindow usa diretamente a memória com mais eficiência, pois o sistema não precisa da memória adicional necessária para armazenar a imagem da janela redirecionada. Para obter a máxima eficiência na animação de janelas, chame UpdateLayeredWindow para alterar a posição e o tamanho de uma janela em camadas. Observe que, depois que SetLayeredWindowAttributes tiver sido chamado, as chamadas updateLayeredWindow subsequentes falharão até que o bit de estilo de camada seja limpo e definido novamente.

O teste de clique de uma janela em camadas baseia-se na forma e na transparência da janela. Isso significa que as áreas da janela com chave de cor ou cujo valor alfa é zero permitirão que as mensagens do mouse passem. No entanto, se a janela em camadas tiver o estilo WS_EX_TRANSPARENT janela estendida, a forma da janela em camadas será ignorada e os eventos do mouse serão passados para outras janelas sob a janela em camadas.

Message-Only Windows

Uma janela somente mensagem permite que você envie e receba mensagens. Ele não está visível, não tem ordem z, não pode ser enumerado e não recebe mensagens de transmissão. A janela simplesmente envia mensagens.

Para criar uma janela somente mensagem, especifique a constante HWND_MESSAGE ou um identificador para uma janela somente mensagem existente no parâmetro hWndParent da função CreateWindowEx . Você também pode alterar uma janela existente para uma janela somente mensagem especificando HWND_MESSAGE no parâmetro hWndNewParent da função SetParent .

Para localizar janelas somente mensagens, especifique HWND_MESSAGE no parâmetro hwndParent da função FindWindowEx . Além disso, FindWindowEx pesquisa janelas somente mensagens, bem como janelas de nível superior se os parâmetros hwndParent e hwndChildAfter forem NULL.

Relações de janela

Há muitas maneiras pelas quais uma janela pode se relacionar com o usuário ou outra janela. Uma janela pode ser uma janela de propriedade, uma janela em primeiro plano ou uma janela em segundo plano. Uma janela também tem uma ordem z em relação a outras janelas. Para obter mais informações, consulte estes tópicos:

Primeiro plano e Windows em segundo plano

Cada processo pode ter vários threads de execução e cada thread pode criar janelas. O thread que criou a janela com a qual o usuário está trabalhando atualmente é chamado de thread em primeiro plano e a janela é chamada de janela em primeiro plano. Todos os outros threads são threads em segundo plano e as janelas criadas por threads em segundo plano são chamadas de janelas em segundo plano.

Cada thread tem um nível de prioridade que determina a quantidade de tempo de CPU que o thread recebe. Embora um aplicativo possa definir o nível de prioridade de seus threads, normalmente o thread em primeiro plano tem um nível de prioridade ligeiramente maior do que os threads em segundo plano. Como ele tem uma prioridade mais alta, o thread em primeiro plano recebe mais tempo de CPU do que os threads em segundo plano. O thread em primeiro plano tem uma prioridade base normal de 9; um thread em segundo plano tem uma prioridade base normal de 7.

O usuário define a janela em primeiro plano clicando em uma janela ou usando a combinação de teclas ALT+TAB ou ALT+ESC. Para recuperar um identificador para a janela em primeiro plano, use a função GetForegroundWindow . Para marcar se a janela do aplicativo for a janela em primeiro plano, compare o identificador retornado por GetForegroundWindow com o da janela do aplicativo.

Um aplicativo define a janela em primeiro plano usando a função SetForegroundWindow .

O sistema restringe quais processos podem definir a janela em primeiro plano. Um processo só poderá definir a janela em primeiro plano se:

  • Todas as seguintes condições são verdadeiras:
    • O processo que chama SetForegroundWindow pertence a um aplicativo da área de trabalho, não a um aplicativo UWP ou a um aplicativo da Windows Store projetado para Windows 8 ou 8.1.
    • O processo em primeiro plano não desabilitou as chamadas para SetForegroundWindow por uma chamada anterior para a função LockSetForegroundWindow .
    • O tempo limite de bloqueio em primeiro plano expirou (consulte SPI_GETFOREGROUNDLOCKTIMEOUT em SystemParametersInfo).
    • Nenhum menu está ativo.
  • Além disso, pelo menos uma das seguintes condições é verdadeira:
    • O processo de chamada é o processo em primeiro plano.
    • O processo de chamada foi iniciado pelo processo em primeiro plano.
    • No momento, não há nenhuma janela em primeiro plano e, portanto, nenhum processo em primeiro plano.
    • O processo de chamada recebeu o último evento de entrada.
    • O processo em primeiro plano ou o processo de chamada está sendo depurado.

É possível que um processo seja negado o direito de definir a janela em primeiro plano, mesmo que ela atenda a essas condições.

Um processo que pode definir a janela de primeiro plano pode habilitar outro processo para definir a janela de primeiro plano chamando a função AllowSetForegroundWindow ou chamando a função BroadcastSystemMessage com o sinalizador BSF_ALLOWSFW . O processo em primeiro plano pode desabilitar chamadas para SetForegroundWindow chamando a função LockSetForegroundWindow .

Windows de propriedade

Uma janela pop-up ou sobreposta pode pertencer a outra janela pop-up ou sobreposta. Ser proprietário coloca várias restrições em uma janela.

  • Uma janela de propriedade está sempre acima de seu proprietário na ordem z.
  • O sistema destrói automaticamente uma janela própria quando seu proprietário é destruído.
  • Uma janela de propriedade fica oculta quando seu proprietário é minimizado.

Somente uma janela pop-up ou sobreposta pode ser uma janela de proprietário; uma janela filho não pode ser uma janela de proprietário. Um aplicativo cria uma janela de propriedade especificando o identificador de janela do proprietário como o parâmetro hwndParent de CreateWindowEx quando cria uma janela com o estilo WS_OVERLAPPED ou WS_POPUP . O parâmetro hwndParent deve identificar uma janela pop-up ou sobreposta. Se hwndParent identificar uma janela filho, o sistema atribuirá propriedade à janela pai de nível superior da janela filho. Depois de criar uma janela de propriedade, um aplicativo não pode transferir a propriedade da janela para outra janela.

Caixas de diálogo e caixas de mensagem são janelas de propriedade por padrão. Um aplicativo especifica a janela do proprietário ao chamar uma função que cria uma caixa de diálogo ou uma caixa de mensagem.

Um aplicativo pode usar a função GetWindow com o sinalizador GW_OWNER para recuperar um identificador para o proprietário de uma janela.

Ordem Z

A ordem z de uma janela indica a posição da janela em uma pilha de janelas sobrepostas. Essa pilha de janelas é orientada ao longo de um eixo imaginário, o eixo z, estendendo-se para fora da tela. A janela na parte superior da ordem z se sobrepõe a todas as outras janelas. A janela na parte inferior da ordem z é sobreposta por todas as outras janelas.

O sistema mantém a ordem z em uma única lista. Ele adiciona janelas à ordem z com base em se são janelas superiores, janelas de nível superior ou janelas filho. Uma janela superior sobrepõe todas as outras janelas não superiores, independentemente de ser a janela ativa ou em primeiro plano. Uma janela superior tem o estilo WS_EX_TOPMOST . Todas as janelas superiores aparecem na ordem z antes de qualquer janela não superior. Uma janela filho é agrupada com seu pai na ordem z.

Quando um aplicativo cria uma janela, o sistema a coloca na parte superior da ordem z para janelas do mesmo tipo. Você pode usar a função BringWindowToTop para trazer uma janela para a parte superior da ordem z para janelas do mesmo tipo. Você pode reorganizar a ordem z usando as funções SetWindowPos e DeferWindowPos .

O usuário altera a ordem z ativando uma janela diferente. O sistema posiciona a janela ativa na parte superior da ordem z para janelas do mesmo tipo. Quando uma janela chega à parte superior da ordem z, as janelas filho também. Você pode usar a função GetTopWindow para pesquisar todas as janelas filho de uma janela pai e retornar um identificador para a janela filho mais alta em ordem z. A função GetNextWindow recupera um identificador para a janela seguinte ou anterior na ordem z.

Estado de Exibição de Janela

A qualquer momento, uma janela pode estar ativa ou inativa; oculto ou visível; e minimizado, maximizado ou restaurado. Essas qualidades são referidas coletivamente como o estado de exibição de janela. Os tópicos a seguir discutem o estado de exibição da janela:

Janela Ativa

Uma janela ativa é a janela de nível superior do aplicativo com a qual o usuário está trabalhando no momento. Para permitir que o usuário identifique facilmente a janela ativa, o sistema a coloca na parte superior da ordem z e altera a cor de sua barra de título e borda para as cores da janela ativa definidas pelo sistema. Somente uma janela de nível superior pode ser uma janela ativa. Quando o usuário está trabalhando com uma janela filho, o sistema ativa a janela pai de nível superior associada à janela filho.

Apenas uma janela de nível superior no sistema está ativa por vez. O usuário ativa uma janela de nível superior clicando nela (ou em uma de suas janelas filho) ou usando a combinação de teclas ALT+ESC ou ALT+TAB. Um aplicativo ativa uma janela de nível superior chamando a função SetActiveWindow . Outras funções podem fazer com que o sistema ative uma janela de nível superior diferente, incluindo SetWindowPos, DeferWindowPos, SetWindowPlacement e DestroyWindow. Embora um aplicativo possa ativar uma janela de nível superior diferente a qualquer momento, para evitar confundir o usuário, ele deve fazê-lo apenas em resposta a uma ação do usuário. Um aplicativo usa a função GetActiveWindow para recuperar um identificador para a janela ativa.

Quando a ativação muda de uma janela de nível superior de um aplicativo para a janela de nível superior de outro, o sistema envia uma mensagem WM_ACTIVATEAPP para ambos os aplicativos, notificando-os sobre a alteração. Quando a ativação é alterada para uma janela de nível superior diferente no mesmo aplicativo, o sistema envia às duas janelas uma mensagem de WM_ACTIVATE .

Windows desabilitado

Uma janela pode ser desabilitada. Uma janela desabilitada não recebe nenhuma entrada de teclado ou mouse do usuário, mas pode receber mensagens de outras janelas, de outros aplicativos e do sistema. Um aplicativo normalmente desabilita uma janela para impedir que o usuário use a janela. Por exemplo, um aplicativo pode desabilitar um botão de push em uma caixa de diálogo para impedir que o usuário o escolha. Um aplicativo pode habilitar uma janela desabilitada a qualquer momento; habilitar uma janela restaura a entrada normal.

Por padrão, uma janela é habilitada quando criada. No entanto, um aplicativo pode especificar o estilo WS_DISABLED para desabilitar uma nova janela. Um aplicativo habilita ou desabilita uma janela existente usando a função EnableWindow . O sistema envia uma mensagem de WM_ENABLE para uma janela quando seu estado habilitado está prestes a ser alterado. Um aplicativo pode determinar se uma janela está habilitada usando a função IsWindowEnabled .

Quando uma janela filho é desabilitada, o sistema passa as mensagens de entrada do mouse do filho para a janela pai. O pai usa as mensagens para determinar se a janela filho deve ser habilitada. Para obter mais informações, consulte Entrada do mouse.

Somente uma janela de cada vez pode receber a entrada do teclado; diz-se que essa janela tem o foco do teclado. Se um aplicativo usar a função EnableWindow para desabilitar uma janela de foco do teclado, a janela perderá o foco do teclado além de ser desabilitada. EnableWindow define o foco do teclado como NULL, o que significa que nenhuma janela tem o foco. Se uma janela filho ou outra janela descendente tiver o foco do teclado, a janela descendente perderá o foco quando a janela pai estiver desabilitada. Para obter mais informações, consulte Entrada de teclado.

Visibilidade da janela

Uma janela pode ser visível ou oculta. O sistema exibe uma janela visível na tela. Ele oculta uma janela oculta não desenhando-a. Se uma janela estiver visível, o usuário poderá fornecer entradas a ela e exibir suas saídas. Se uma janela for oculta, ele estará efetivamente desabilitada. Uma janela oculta pode processar mensagens do sistema ou de outras janelas, mas não pode processar a entrada do usuário ou exibir a saída. Um aplicativo define o estado de visibilidade de uma janela ao criar a janela. Posteriormente, o aplicativo pode alterar o estado de visibilidade.

Uma janela fica visível quando o estilo de WS_VISIBLE é definido para a janela. Por padrão, a função CreateWindowEx cria uma janela oculta, a menos que o aplicativo especifique o estilo WS_VISIBLE . Normalmente, um aplicativo define o estilo de WS_VISIBLE depois de criar uma janela para manter os detalhes do processo de criação ocultos do usuário. Por exemplo, um aplicativo pode manter uma nova janela oculta enquanto personaliza a aparência da janela. Se o estilo de WS_VISIBLE for especificado em CreateWindowEx, o sistema enviará a mensagem WM_SHOWWINDOW para a janela depois de criar a janela, mas antes de exibi-la.

Um aplicativo pode determinar se uma janela está visível usando a função IsWindowVisible . Um aplicativo pode mostrar (tornar visível) ou ocultar uma janela usando a função ShowWindow, SetWindowPos, DeferWindowPos ou SetWindowPlacement ou SetWindowLong . Essas funções mostram ou ocultam uma janela definindo ou removendo o estilo de WS_VISIBLE da janela. Eles também enviam a mensagem WM_SHOWWINDOW para a janela antes de mostrá-la ou escondê-la.

Quando uma janela de proprietário é minimizada, o sistema oculta automaticamente as janelas associadas. Da mesma forma, quando uma janela de proprietário é restaurada, o sistema mostra automaticamente as janelas de propriedade associadas. Em ambos os casos, o sistema envia a mensagem WM_SHOWWINDOW para as janelas de propriedade antes de escondê-las ou mostrá-las. Ocasionalmente, um aplicativo pode precisar ocultar as janelas de propriedade sem precisar minimizar ou ocultar o proprietário. Nesse caso, o aplicativo usa a função ShowOwnedPopups . Essa função define ou remove o estilo de WS_VISIBLE para todas as janelas de propriedade e envia a mensagem WM_SHOWWINDOW para as janelas de propriedade antes de escondê-las ou mostrá-las. Ocultar uma janela de proprietário não tem efeito sobre o estado de visibilidade das janelas de propriedade.

Quando uma janela pai está visível, suas janelas filho associadas também ficam visíveis. Da mesma forma, quando a janela pai está oculta, suas janelas filho também ficam ocultas. Minimizar a janela pai não tem efeito sobre o estado de visibilidade das janelas filho; ou seja, as janelas filho são minimizadas junto com o pai, mas o estilo WS_VISIBLE não é alterado.

Mesmo que uma janela tenha o estilo WS_VISIBLE , talvez o usuário não consiga ver a janela na tela; outras janelas podem se sobrepor completamente ou podem ter sido movidas para além da borda da tela. Além disso, uma janela filho visível está sujeita às regras de recorte estabelecidas por sua relação pai-filho. Se a janela pai da janela não estiver visível, ela também não ficará visível. Se a janela pai for além da borda da tela, a janela filho também será movida porque uma janela filho é desenhada em relação ao canto superior esquerdo do pai. Por exemplo, um usuário pode mover a janela pai que contém a janela filho longe o suficiente da borda da tela que o usuário pode não conseguir ver a janela filho, mesmo que a janela filho e sua janela pai tenham o estilo WS_VISIBLE .

Windows minimizado, maximizado e restaurado

Uma janela maximizada é uma janela que tem o estilo WS_MAXIMIZE . Por padrão, o sistema aumenta uma janela maximizada para que ela ocupe a tela ou, no caso de uma janela filho, a área de cliente da janela pai. Embora o tamanho de uma janela possa ser definido com o mesmo tamanho de uma janela maximizada, uma janela maximizada é ligeiramente diferente. O sistema move automaticamente a barra de título da janela para a parte superior da tela ou para a parte superior da área do cliente da janela pai. Além disso, o sistema desabilita a borda de dimensionamento da janela e a capacidade de posicionamento da janela da barra de título (para que o usuário não possa mover a janela arrastando a barra de título).

Uma janela minimizada é uma janela que tem o estilo WS_MINIMIZE . Por padrão, o sistema reduz uma janela minimizada ao tamanho do seu botão da barra de tarefas e a move para a barra de tarefas. Uma janela restaurada é uma janela que foi retornada ao seu tamanho e posição anteriores, ou seja, o tamanho que era antes de ser minimizada ou maximizada.

Se um aplicativo especificar o estilo WS_MAXIMIZE ou WS_MINIMIZE na função CreateWindowEx , a janela será maximizada ou minimizada inicialmente. Depois de criar uma janela, um aplicativo pode usar a função CloseWindow para minimizar a janela. A função ArrangeIconicWindows organiza os ícones na área de trabalho ou organiza as janelas filho minimizadas de uma janela pai na janela pai. A função OpenIcon restaura uma janela minimizada para seu tamanho e posição anteriores.

A função ShowWindow pode minimizar, maximizar ou restaurar uma janela. Ele também pode definir os estados de visibilidade e ativação da janela. A função SetWindowPlacement inclui a mesma funcionalidade que ShowWindow, mas pode substituir as posições minimizadas, maximizadas e restauradas padrão da janela.

As funções IsZoomed e IsIconic determinam se uma determinada janela é maximizada ou minimizada, respectivamente. A função GetWindowPlacement recupera as posições minimizadas, maximizadas e restauradas da janela e também determina o estado de exibição da janela.

Quando o sistema recebe um comando para maximizar ou restaurar uma janela minimizada, ele envia à janela uma mensagem WM_QUERYOPEN . Se o procedimento de janela retornar FALSE, o sistema ignorará o comando maximizar ou restaurar.

O sistema define automaticamente o tamanho e a posição de uma janela maximizada para os padrões definidos pelo sistema para uma janela maximizada. Para substituir esses padrões, um aplicativo pode chamar a função SetWindowPlacement ou processar a mensagem WM_GETMINMAXINFO recebida por uma janela quando o sistema está prestes a maximizar a janela. WM_GETMINMAXINFO inclui um ponteiro para uma estrutura MINMAXINFO que contém valores que o sistema usa para definir o tamanho e a posição maximizados. Substituir esses valores substitui os padrões.

Tamanho e posição da janela

O tamanho e a posição de uma janela são expressos como um retângulo delimitador, fornecido em coordenadas relativas à tela ou à janela pai. As coordenadas de uma janela de nível superior são relativas ao canto superior esquerdo da tela; as coordenadas de uma janela filho são relativas ao canto superior esquerdo da janela pai. Um aplicativo especifica o tamanho e a posição iniciais de uma janela quando cria a janela, mas pode alterar o tamanho e a posição da janela a qualquer momento. Para obter mais informações, consulte Formas Preenchidas.

Esta seção contém os seguintes tópicos:

Tamanho e posição padrão

Um aplicativo pode permitir que o sistema calcule o tamanho ou a posição inicial de uma janela de nível superior especificando CW_USEDEFAULT em CreateWindowEx. Se o aplicativo definir as coordenadas da janela como CW_USEDEFAULT e não tiver criado nenhuma outra janela de nível superior, o sistema definirá a posição da nova janela em relação ao canto superior esquerdo da tela; caso contrário, ele define a posição relativa à posição da janela de nível superior que o aplicativo criou mais recentemente. Se os parâmetros de largura e altura forem definidos como CW_USEDEFAULT, o sistema calculará o tamanho da nova janela. Se o aplicativo tiver criado outras janelas de nível superior, o sistema baseá o tamanho da nova janela no tamanho da janela de nível superior criada mais recentemente pelo aplicativo. Especificar CW_USEDEFAULT ao criar uma janela pop-up ou filho faz com que o sistema defina o tamanho da janela como o tamanho mínimo da janela padrão.

Tamanho do rastreamento

O sistema mantém um tamanho de acompanhamento mínimo e máximo para uma janela do estilo WS_THICKFRAME ; uma janela com esse estilo tem uma borda de dimensionamento. O tamanho mínimo de rastreamento é o menor tamanho de janela que você pode produzir arrastando a borda de dimensionamento da janela. Da mesma forma, o tamanho máximo de rastreamento é o maior tamanho de janela que você pode produzir arrastando a borda de dimensionamento.

Os tamanhos de acompanhamento mínimo e máximo de uma janela são definidos como valores padrão definidos pelo sistema quando o sistema cria a janela. Um aplicativo pode descobrir os padrões e substituí-los processando a mensagem WM_GETMINMAXINFO . Para obter mais informações, consulte Dimensionar e posicionar mensagens.

Comandos do sistema

Um aplicativo que tem um menu de janela pode alterar o tamanho e a posição dessa janela enviando comandos do sistema. Os comandos do sistema são gerados quando o usuário escolhe comandos no menu da janela. Um aplicativo pode emular a ação do usuário enviando uma mensagem WM_SYSCOMMAND para a janela. Os comandos do sistema a seguir afetam o tamanho e a posição de uma janela.

Comando Descrição
SC_CLOSE Fecha a janela. Esse comando envia uma mensagem WM_CLOSE para a janela. A janela executa todas as etapas necessárias para limpo e se destruir.
SC_MAXIMIZE Maximiza a janela.
SC_MINIMIZE Minimiza a janela.
SC_MOVE Move a janela.
SC_RESTORE Restaura uma janela minimizada ou maximizada para seu tamanho e posição anteriores.
SC_SIZE Inicia um comando de tamanho. Para alterar o tamanho da janela, use o mouse ou o teclado.

 

Funções de tamanho e posição

Depois de criar uma janela, um aplicativo pode definir o tamanho ou a posição da janela chamando uma das várias funções diferentes, incluindo SetWindowPlacement, MoveWindow, SetWindowPos e DeferWindowPos. SetWindowPlacement define a posição minimizada de uma janela, a posição maximizada, o tamanho e a posição restaurados e o estado de exibição. As funções MoveWindow e SetWindowPos são semelhantes ; defina o tamanho ou a posição de uma única janela de aplicativo. A função SetWindowPos inclui um conjunto de sinalizadores que afetam o estado de exibição da janela; MoveWindow não inclui esses sinalizadores. Use as funções BeginDeferWindowPos, DeferWindowPos e EndDeferWindowPos para definir simultaneamente a posição de várias janelas, incluindo o tamanho, a posição, a posição na ordem z e o estado de exibição.

Um aplicativo pode recuperar as coordenadas do retângulo delimitador de uma janela usando a função GetWindowRect . GetWindowRect preenche uma estrutura RECT com as coordenadas dos cantos superior esquerdo e inferior direito da janela. As coordenadas são relativas ao canto superior esquerdo da tela, mesmo para uma janela filho. A função ScreenToClient ou MapWindowPoints mapeia as coordenadas de tela do retângulo delimitador de uma janela filho para coordenadas relativas à área do cliente da janela pai.

A função GetClientRect recupera as coordenadas da área de cliente de uma janela. GetClientRect preenche uma estrutura RECT com as coordenadas dos cantos superior esquerdo e inferior direito da área do cliente, mas as coordenadas são relativas à própria área do cliente. Isso significa que as coordenadas do canto superior esquerdo de uma área de cliente são sempre (0,0) e as coordenadas do canto inferior direito são a largura e a altura da área do cliente.

A função CascadeWindows coloca as janelas em cascata na área de trabalho ou coloca em cascata as janelas filho da janela pai especificada. A função TileWindows remenda as janelas na área de trabalho ou remenda as janelas filho da janela pai especificada.

Dimensionar e posicionar mensagens

O sistema envia a mensagem WM_GETMINMAXINFO para uma janela cujo tamanho ou posição está prestes a ser alterado. Por exemplo, a mensagem é enviada quando o usuário clica em Mover ou Tamanho no menu da janela ou clica na borda de dimensionamento ou na barra de título; a mensagem também é enviada quando um aplicativo chama SetWindowPos para mover ou dimensionar a janela. WM_GETMINMAXINFO inclui um ponteiro para uma estrutura MINMAXINFO que contém o tamanho e a posição maximizados padrão para a janela, bem como os tamanhos de acompanhamento mínimo e máximo padrão. Um aplicativo pode substituir os padrões processando WM_GETMINMAXINFO e definindo os membros apropriados do MINMAXINFO. Uma janela deve ter o estilo WS_THICKFRAME ou WS_CAPTION para receber WM_GETMINMAXINFO. Uma janela com o estilo WS_THICKFRAME recebe essa mensagem durante o processo de criação da janela, bem como quando ela está sendo movida ou dimensionada.

O sistema envia a mensagem WM_WINDOWPOSCHANGING para uma janela cujo tamanho, posição, posição na ordem z ou estado de exibição está prestes a ser alterado. Essa mensagem inclui um ponteiro para uma estrutura WINDOWPOS que especifica o novo tamanho, a posição, a posição da janela na ordem z e o estado de exibição. Ao definir os membros do WINDOWPOS, um aplicativo pode afetar o novo tamanho, a posição e a aparência da janela.

Depois de alterar o tamanho, a posição, a posição da janela na ordem z ou o estado de exibição, o sistema envia a mensagem WM_WINDOWPOSCHANGED para a janela. Essa mensagem inclui um ponteiro para WINDOWPOS que informa a janela de seu novo tamanho, posição, posição na ordem z e estado de exibição. Definir os membros da estrutura WINDOWPOS que é passada com WM_WINDOWPOSCHANGED não tem efeito na janela. Uma janela que deve processar mensagens de WM_SIZE e WM_MOVE deve passar WM_WINDOWPOSCHANGED para a função DefWindowProc ; caso contrário, o sistema não envia WM_SIZE e WM_MOVE mensagens para a janela.

O sistema envia a mensagem WM_NCCALCSIZE para uma janela quando a janela é criada ou dimensionada. O sistema usa a mensagem para calcular o tamanho da área do cliente de uma janela e a posição da área do cliente em relação ao canto superior esquerdo da janela. Normalmente, uma janela passa essa mensagem para o procedimento de janela padrão; no entanto, essa mensagem pode ser útil em aplicativos que personalizam a área não cliente de uma janela ou preservam partes da área do cliente quando a janela é dimensionada. Para obter mais informações, consulte Pintura e Desenho.

Animação de janela

Você pode produzir efeitos especiais ao mostrar ou ocultar janelas usando a função AnimateWindow . Quando a janela for animada dessa maneira, o sistema rolará, deslizará ou desaparecerá a janela, dependendo dos sinalizadores especificados em uma chamada para AnimateWindow.

Por padrão, o sistema usa animação roll. Com esse efeito, a janela parece rolar aberta (mostrando a janela) ou rolar fechada (ocultando a janela). Você pode usar o parâmetro dwFlags para especificar se a janela é rolada horizontalmente, verticalmente ou diagonalmente.

Quando você especifica o sinalizador AW_SLIDE , o sistema usa animação de slide. Com esse efeito, a janela parece deslizar para a exibição (mostrando a janela) ou deslizar para fora da exibição (ocultando a janela). Você pode usar o parâmetro dwFlags para especificar se a janela desliza horizontalmente, verticalmente ou diagonalmente.

Quando você especifica o sinalizador AW_BLEND , o sistema usa um fade combinado alfa.

Você também pode usar o sinalizador AW_CENTER para fazer com que uma janela pareça recolher para dentro ou expandir para fora.

Layout e espelhamento de janela

O layout da janela define como o texto e os objetos GDI (Interface do Dispositivo gráfico do Windows) são dispostos em uma janela ou contexto de dispositivo (DC). Alguns idiomas, como inglês, francês e alemão, exigem um layout da esquerda para a direita (LTR). Outras linguagens, como árabe e hebraico, exigem layout da direita para a esquerda (RTL). O layout da janela se aplica ao texto, mas também afeta os outros elementos GDI da janela, incluindo bitmaps, ícones, o local da origem, botões, controles de árvore em cascata e se a coordenada horizontal aumenta à medida que você vai para a esquerda ou para a direita. Por exemplo, depois que um aplicativo define o layout RTL, a origem é posicionada na borda direita da janela ou do dispositivo e o número que representa a coordenada horizontal aumenta à medida que você se move para a esquerda. No entanto, nem todos os objetos são afetados pelo layout de uma janela. Por exemplo, o layout para caixas de diálogo, caixas de mensagem e contextos de dispositivo que não estão associados a uma janela, como metafile e DCs de impressora, deve ser tratado separadamente. As especificações para elas são mencionadas posteriormente neste tópico.

As funções de janela permitem especificar ou alterar o layout da janela em versões em árabe e hebraico do Windows. Observe que não há suporte para alteração para um layout RTL (também conhecido como espelhamento) para janelas que têm o estilo CS_OWNDC ou para um DC com o modo gráfico GM_ADVANCED.

Por padrão, o layout da janela é da esquerda para a direita (LTR). Para definir o layout da janela RTL, chame CreateWindowEx com o estilo WS_EX_LAYOUTRTL. Também por padrão, uma janela filho (ou seja, criada com o estilo WS_CHILD e com um parâmetro hWnd pai válido na chamada para CreateWindow ou CreateWindowEx) tem o mesmo layout que seu pai. Para desabilitar a herança de espelhamento em todas as janelas filho, especifique WS_EX_NOINHERITLAYOUT na chamada para CreateWindowEx. Observe que o espelhamento não é herdado por janelas de propriedade (aquelas criadas sem o estilo WS_CHILD ) ou aquelas criadas com o parâmetro pai hWnd em CreateWindowEx definido como NULL. Para desabilitar a herança de espelhamento para uma janela individual, processe a mensagem WM_NCCREATE com GetWindowLong e SetWindowLong para desativar o sinalizador WS_EX_LAYOUTRTL . Esse processamento é além de qualquer outro processamento necessário. O fragmento de código a seguir mostra como isso é feito.

SetWindowLong (hWnd, 
               GWL_EXSTYLE, 
               GetWindowLong(hWnd,GWL_EXSTYLE) & ~WS_EX_LAYOUTRTL))

Você pode definir o layout padrão como RTL chamando SetProcessDefaultLayout(LAYOUT_RTL). Todas as janelas criadas após a chamada serão espelhadas, mas as janelas existentes não serão afetadas. Para desativar o espelhamento padrão, chame SetProcessDefaultLayout(0).

Observe que SetProcessDefaultLayout espelha os DCs somente de janelas espelhadas. Para espelho qualquer DC, chame SetLayout(hdc, LAYOUT_RTL). Para obter mais informações, consulte a discussão sobre espelhamento de contextos de dispositivo não associados ao windows, que vem posteriormente neste tópico.

Bitmaps e ícones em uma janela espelhada também são espelhados por padrão. No entanto, nem todos eles devem ser espelhados. Por exemplo, aqueles com texto, um logotipo de negócios ou um relógio analógico não devem ser espelhados. Para desabilitar o espelhamento de bitmaps, chame SetLayout com o LAYOUT_BITMAPORIENTATIONPRESERVED bit definido em dwLayout. Para desabilitar o espelhamento em um DC, chame SetLayout(hdc, 0).

Para consultar o layout padrão atual, chame GetProcessDefaultLayout. Após um retorno bem-sucedido, pdwDefaultLayout contém LAYOUT_RTL ou 0. Para consultar as configurações de layout do contexto do dispositivo, chame GetLayout. Após um retorno bem-sucedido, GetLayout retorna um DWORD que indica as configurações de layout pelas configurações do LAYOUT_RTL e dos bits LAYOUT_BITMAPORIENTATIONPRESERVED.

Depois que uma janela for criada, você alterará o layout usando a função SetWindowLong . Por exemplo, isso é necessário quando o usuário altera o idioma da interface do usuário de uma janela existente de árabe ou hebraico para alemão. No entanto, ao alterar o layout de uma janela existente, você deve invalidar e atualizar a janela para garantir que o conteúdo da janela seja todo desenhado no mesmo layout. O exemplo de código a seguir é do código de exemplo que altera o layout da janela conforme necessário:

// Using ANSI versions of GetWindowLong and SetWindowLong because Unicode
// is not needed for these calls

lExStyles = GetWindowLongA(hWnd, GWL_EXSTYLE);

// Check whether new layout is opposite the current layout
if (!!(pLState -> IsRTLLayout) != !!(lExStyles & WS_EX_LAYOUTRTL))
{
    // the following lines will update the window layout

    lExStyles ^= WS_EX_LAYOUTRTL;        // toggle layout
    SetWindowLongA(hWnd, GWL_EXSTYLE, lExStyles);
    InvalidateRect(hWnd, NULL, TRUE);    // to update layout in the client area
}

No espelhamento, você deve pensar em termos de "perto" e "longe" em vez de "esquerda" e "direita". Falha ao fazer isso pode causar problemas. Uma prática comum de codificação que causa problemas em uma janela espelhada ocorre ao mapear entre coordenadas de tela e coordenadas do cliente. Por exemplo, os aplicativos geralmente usam código semelhante ao seguinte para posicionar um controle em uma janela:

// DO NOT USE THIS IF APPLICATION MIRRORS THE WINDOW

// get coordinates of the window in screen coordinates
GetWindowRect(hControl, (LPRECT) &rControlRect);  

// map screen coordinates to client coordinates in dialog
ScreenToClient(hDialog, (LPPOINT) &rControlRect.left); 
ScreenToClient(hDialog, (LPPOINT) &rControlRect.right);

Isso causa problemas no espelhamento porque a borda esquerda do retângulo se torna a borda direita em uma janela espelhada e vice-versa. Para evitar esse problema, substitua as chamadas ScreenToClient por uma chamada para MapWindowPoints da seguinte maneira:

// USE THIS FOR MIRRORING

GetWindowRect(hControl, (LPRECT) &rControlRect);
MapWindowPoints(NULL, hDialog, (LPPOINT) &rControlRect, 2)

Esse código funciona porque, em plataformas que dão suporte ao espelhamento, MapWindowPoints é modificado para trocar as coordenadas do ponto esquerdo e direito quando a janela do cliente é espelhada. Para obter mais informações, consulte a seção Comentários de MapWindowPoints.

Outra prática comum que pode causar problemas em janelas espelhadas é posicionar objetos em uma janela do cliente usando deslocamentos em coordenadas de tela em vez de coordenadas do cliente. Por exemplo, o código a seguir usa a diferença nas coordenadas de tela como a posição x nas coordenadas do cliente para posicionar um controle em uma caixa de diálogo.

// OK if LTR layout and mapping mode of client is MM_TEXT,
// but WRONG for a mirrored dialog 

RECT rdDialog;
RECT rcControl;

HWND hControl = GetDlgItem(hDlg, IDD_CONTROL);
GetWindowRect(hDlg, &rcDialog);             // gets rect in screen coordinates
GetWindowRect(hControl, &rcControl);
MoveWindow(hControl,
           rcControl.left - rcDialog.left,  // uses x position in client coords
           rcControl.top - rcDialog.top,
           nWidth,
           nHeight,
           FALSE);

Esse código é bom quando a janela de diálogo tem o layout da esquerda para a direita (LTR) e o modo de mapeamento do cliente é MM_TEXT, pois a nova posição x nas coordenadas do cliente corresponde à diferença nas bordas esquerdas do controle e da caixa de diálogo nas coordenadas da tela. No entanto, em uma caixa de diálogo espelhada, esquerda e direita são invertidas, portanto, você deve usar MapWindowPoints da seguinte maneira:

RECT rcDialog;
RECT rcControl;

HWND hControl - GetDlgItem(hDlg, IDD_CONTROL);
GetWindowRect(hControl, &rcControl);

// MapWindowPoints works correctly in both mirrored and non-mirrored windows.
MapWindowPoints(NULL, hDlg, (LPPOINT) &rcControl, 2);

// Now rcControl is in client coordinates.
MoveWindow(hControl, rcControl.left, rcControl.top, nWidth, nHeight, FALSE)

Caixas de diálogo de espelhamento e caixas de mensagem

Caixas de diálogo e caixas de mensagem não herdam o layout, portanto, você deve definir o layout explicitamente. Para espelho uma caixa de mensagem, chame MessageBox ou MessageBoxEx com a opção MB_RTLREADING. Para layout de uma caixa de diálogo da direita para a esquerda, use o estilo estendido WS_EX_LAYOUTRTL na estrutura de modelo de caixa de diálogo DLGTEMPLATEEX. Folhas de propriedades são um caso especial de caixas de diálogo. Cada guia é tratada como uma caixa de diálogo separada, portanto, você precisa incluir o estilo WS_EX_LAYOUTRTL em cada guia que você deseja espelhar.

Espelhamento de contextos de dispositivo não associados a uma janela

Os DCs que não estão associados a uma janela, como metarquivo ou DCs de impressora, não herdam o layout, portanto, você deve definir o layout explicitamente. Para alterar o layout de contexto do dispositivo, use a função SetLayout .

A função SetLayout raramente é usada com janelas. Normalmente, as janelas recebem um DC associado somente no processamento de uma mensagem WM_PAINT . Ocasionalmente, um programa cria um DC para uma janela chamando GetDC. De qualquer forma, o layout inicial do DC é definido por BeginPaint ou GetDC de acordo com o sinalizador WS_EX_LAYOUTRTL da janela.

Os valores retornados por GetWindowOrgEx, GetWindowExtEx, GetViewportOrgEx e GetViewportExtExtEx não são afetados pela chamada de SetLayout.

Quando o layout for RTL, GetMapMode retornará MM_ANISOTROPIC em vez de MM_TEXT. Chamar SetMapMode com MM_TEXT funcionará corretamente; somente o valor retornado de GetMapMode é afetado. Da mesma forma, chamar SetLayout(hdc, LAYOUT_RTL) quando o modo de mapeamento é MM_TEXT faz com que o modo de mapeamento relatado seja alterado para MM_ANISOTROPIC.

Destruição de janela

Em geral, um aplicativo deve destruir todas as janelas que cria. Ele faz isso usando a função DestroyWindow . Quando uma janela é destruída, o sistema oculta a janela, se estiver visível, e remove todos os dados internos associados à janela. Isso invalida o identificador de janela, que não pode mais ser usado pelo aplicativo.

Um aplicativo destrói muitas das janelas que cria logo após criá-las. Por exemplo, um aplicativo geralmente destrói uma janela de caixa de diálogo assim que o aplicativo tem entrada suficiente do usuário para continuar sua tarefa. Um aplicativo eventualmente destrói a janela main do aplicativo (antes de encerrar).

Antes de destruir uma janela, um aplicativo deve salvar ou remover todos os dados associados à janela e deve liberar todos os recursos do sistema alocados para a janela. Se o aplicativo não liberar os recursos, o sistema liberará todos os recursos não liberados pelo aplicativo.

Destruir uma janela não afeta a classe de janela da qual a janela é criada. Novas janelas ainda podem ser criadas usando essa classe, e todas as janelas existentes dessa classe continuam operando. Destruir uma janela também destrói as janelas descendentes da janela. A função DestroyWindow envia uma mensagem WM_DESTROY primeiro para a janela e, em seguida, para suas janelas filho e janelas descendentes. Dessa forma, todas as janelas descendentes da janela que está sendo destruída também são destruídas.

Uma janela com um menu de janela recebe uma mensagem WM_CLOSE quando o usuário clica em Fechar. Ao processar essa mensagem, um aplicativo pode solicitar confirmação ao usuário antes de destruir a janela. Se o usuário confirmar que a janela deve ser destruída, o aplicativo poderá chamar a função DestroyWindow para destruir a janela.

Se a janela que está sendo destruída for a janela ativa, os estados ativos e de foco serão transferidos para outra janela. A janela que se torna a janela ativa é a próxima janela, conforme determinado pela combinação de teclas ALT+ESC. Em seguida, a nova janela ativa determina qual janela recebe o foco do teclado.