Partilhar via


Sobre as classes de janela

Cada classe de janela tem um procedimento de janela associado compartilhado por todas as janelas da mesma classe. O procedimento de janela processa mensagens para todas as janelas dessa classe e, portanto, controla seu comportamento e aparência. Para obter mais informações, consulte Window Procedures.

Um processo deve registrar uma classe window antes de poder criar uma janela dessa classe. O registro de uma classe window associa um procedimento de janela, estilos de classe e outros atributos de classe a um nome de classe. Quando um processo especifica um nome de classe no CreateWindow ou função de CreateWindowEx, o sistema cria uma janela com o procedimento de janela, estilos e outros atributos associados a esse nome de classe.

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

Tipos de classes de janela

Existem três tipos de classes de janela:

Estes tipos diferem no âmbito e no momento e na forma como são registados e destruídos.

Classes de sistema

Uma classe de sistema é uma classe de janela registrada pelo sistema. Muitas classes de sistema estão disponíveis para todos os processos usarem, enquanto outras são usadas apenas internamente pelo sistema. Como o sistema registra essas classes, um processo não pode destruí-las.

O sistema registra as classes do sistema para um processo na primeira vez que um de seus threads chama um usuário ou uma função GDI (Graphics Device Interface) do Windows.

Cada aplicativo recebe sua própria cópia das classes do sistema. Todos os aplicativos baseados no Windows de 16 bits no mesmo VDM compartilham classes de sistema, assim como no Windows de 16 bits.

A tabela a seguir descreve as classes de sistema que estão disponíveis para uso por todos os processos.

Classe Descrição
Botão A classe para um botão.
Caixa de Combinação A classe para uma caixa de combinação.
Editar A classe para um controle de edição.
Caixa de listagem A classe de uma caixa de listagem.
MDIClient A classe para uma janela de cliente MDI.
Barra de rolagem A classe para uma barra de rolagem.
Estática A classe para um controle estático.

 

A tabela a seguir descreve as classes de sistema que estão disponíveis apenas para uso pelo sistema. Eles estão listados aqui por uma questão de completude.

Classe Descrição
ComboLBox A classe para a caixa de listagem contida em uma caixa de combinação.
DDEMLEvent A classe para eventos DDEML (Dynamic Data Exchange Management Library).
Mensagem A classe para uma janela somente mensagem.
#32768 A classe para um menu.
#32769 A classe para a janela da área de trabalho.
#32770 A classe de uma caixa de diálogo.
#32771 A classe para a janela de alternância de tarefas.
#32772 A classe para títulos de ícones.

 

Classes globais de aplicativos

Uma classe global de aplicativo é uma classe de janela registrada por um executável ou DLL que está disponível para todos os outros módulos no processo. Por exemplo, seu .dll pode chamar a função RegisterClassEx para registrar uma classe de janela que define um controle personalizado como uma classe global de aplicativo para que um processo que carrega o .dll possa criar instâncias do controle personalizado.

Para criar uma classe que possa ser usada em cada processo, crie a classe window em um .dll e carregue o .dll em cada processo. Para carregar o .dll em cada processo, adicione seu nome ao valor AppInit_DLLs na seguinte chave do Registro:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Windows

Sempre que um processo é iniciado, o sistema carrega o .dll especificado no contexto do processo recém-iniciado antes de chamar sua função de ponto de entrada. O .dll deve registrar a classe durante seu procedimento de inicialização e deve especificar o estilo CS_GLOBALCLASS. Para obter mais informações, consulte Estilos de classe.

Para remover uma classe global de aplicativo e liberar o armazenamento associado a ela, use a função UnregisterClass.

Classes locais do aplicativo

Um de classe local de aplicativo é qualquer classe de janela que um executável ou .dll registra para seu uso exclusivo. Embora você possa registrar qualquer número de classes locais, é típico registrar apenas uma. Esta classe de janela suporta o procedimento de janela da janela principal do aplicativo.

O sistema destrói uma classe local quando o módulo que a registrou é fechado. Um aplicativo também pode usar a funçãoUnregisterClass para remover uma classe local e liberar o armazenamento associado a ela.

Como o sistema localiza uma classe de janela

O sistema mantém uma lista de estruturas para cada um dos três tipos de classes de janela. Quando um aplicativo chama o CreateWindow ou função CreateWindowEx para criar uma janela com uma classe especificada, o sistema usa o procedimento a seguir para localizar a classe.

  1. Pesquise na lista de classes locais do aplicativo uma classe com o nome especificado cujo identificador de instância corresponde ao identificador de instância do módulo. (Vários módulos podem usar o mesmo nome para registrar classes locais no mesmo processo.)
  2. Se o nome não estiver na lista de classes locais do aplicativo, pesquise a lista de classes globais do aplicativo.
  3. Se o nome não estiver na lista de classes globais do aplicativo, pesquise a lista de classes do sistema.

Todas as janelas criadas pelo aplicativo usam este procedimento, incluindo janelas criadas pelo sistema em nome do aplicativo, como caixas de diálogo. É possível substituir classes do sistema sem afetar outros aplicativos. Ou seja, um aplicativo pode registrar uma classe local de aplicativo com o mesmo nome de uma classe de sistema. Isso substitui a classe de sistema no contexto do aplicativo, mas não impede que outros aplicativos usem a classe de sistema.

Registrando uma classe de janela

Uma classe window define os atributos de uma janela, como seu estilo, ícone, cursor, menu e procedimento de janela. A primeira etapa para registrar uma classe de janela é preencher uma estrutura deWNDCLASSEXcom as informações da classe de janela. Para obter mais informações, consulte elementos de uma classe de janela. Em seguida, passe a estrutura para a funçãoRegisterClassEx. Para obter mais informações, consulte Usando classes de janela.

Para registrar uma classe global de aplicativo, especifique o estilo CS_GLOBALCLASS no estilo membro da estruturaWNDCLASSEX. Ao registrar uma classe local do aplicativo, não especifique o estilo CS_GLOBALCLASS.

Se você registrar a classe window usando a versão ANSI do RegisterClassEx, RegisterClassExA, o aplicativo solicita que o sistema passe parâmetros de texto de mensagens para as janelas da classe criada usando o conjunto de caracteres ANSI; se você registrar a classe usando a versão Unicode do RegisterClassEx, RegisterClassExW, o aplicativo solicita que o sistema passe parâmetros de texto de mensagens para as janelas da classe criada usando o conjunto de caracteres Unicode. A funçãoIsWindowUnicode permite que os aplicativos consultem a natureza de cada janela. Para obter mais informações sobre as funções ANSI e Unicode, consulte Conventions for Function Prototypes.

O executável ou DLL que registrou a classe é o proprietário da classe. O sistema determina a propriedade da classe a partir do hInstance membro da estrutura deWNDCLASSEXpassada para a funçãoRegisterClassExquando a classe é registrada. Para DLLs, o membro hInstance deve ser o identificador da instância .dll.

A classe não é destruída quando o .dll que a possui é descarregado. Portanto, se o sistema chamar o procedimento de janela para uma janela dessa classe, isso causará uma violação de acesso, porque o .dll que contém o procedimento de janela não está mais na memória. O processo deve destruir todas as janelas usando a classe antes que o .dll seja descarregado e chame a funçãoUnregisterClass.

Elementos de uma classe de janela

Os elementos de uma classe window definem o comportamento padrão das janelas pertencentes à classe. O aplicativo que registra uma classe window atribui elementos à classe definindo membros apropriados em uma estrutura deWNDCLASSEXe passando a estrutura para a funçãoRegisterClassEx. O GetClassInfoEx e funções de GetClassLong recuperam informações sobre uma determinada classe de janela. A função SetClassLong altera elementos de uma classe local ou global que o aplicativo já registrou.

Embora uma classe de janela completa consista em muitos elementos, o sistema requer apenas que um aplicativo forneça um nome de classe, o endereço de procedimento de janela e um identificador de instância. Use os outros elementos para definir atributos padrão para janelas da classe, como a forma do cursor e o conteúdo do menu da janela. Você deve inicializar todos os membros não utilizados da estruturaWNDCLASSEXzero ou NULL. Os elementos da classe window são os mostrados na tabela a seguir.

Elemento Finalidade
Nome da classe Distingue a classe de outras classes registradas.
Janela Endereço do Procedimento Ponteiro para a função que processa todas as mensagens enviadas para janelas na classe e define o comportamento da janela.
identificador de instância Identifica o aplicativo ou .dll que registrou a classe.
Cursor de classe Define o cursor do mouse que o sistema exibe para uma janela da classe.
Ícones de classe Define o ícone grande e o ícone pequeno.
Pincel de fundo de classe Define a cor e o padrão que preenchem a área do cliente quando a janela é aberta ou pintada.
Menu Classe Especifica o menu padrão para janelas que não definem explicitamente um menu.
Estilos de classe Define como atualizar a janela depois de movê-la ou redimensioná-la, como processar cliques duplos do mouse, como alocar espaço para o contexto do dispositivo e outros aspetos da janela.
de memória extra de classe Especifica a quantidade de memória extra, em bytes, que o sistema deve reservar para a classe. Todas as janelas na classe compartilham a memória extra e podem usá-la para qualquer finalidade definida pelo aplicativo. O sistema inicializa essa memória a zero.
Memória de janela extra Especifica a quantidade de memória extra, em bytes, que o sistema deve reservar para cada janela pertencente à classe. A memória extra pode ser usada para qualquer finalidade definida pelo aplicativo. O sistema inicializa essa memória a zero.

 

Nome da classe

Cada classe de janela precisa de um Nome da Classe para distinguir uma classe da outra. Atribua um nome de classe definindo o lpszClassName membro da estruturaWNDCLASSEXpara o endereço de uma cadeia de caracteres terminada em nulo que especifica o nome. Como as classes de janela são específicas do processo, os nomes de classe de janela precisam ser exclusivos apenas dentro do mesmo processo. Além disso, como os nomes de classe ocupam espaço na tabela de átomos privados do sistema, você deve manter as cadeias de caracteres de nome de classe o mais curtas possível.

A funçãoGetClassNamerecupera o nome da classe à qual pertence uma determinada janela.

Endereço do procedimento da janela

Cada classe precisa de um endereço de procedimento de janela para definir o ponto de entrada do procedimento de janela usado para processar todas as mensagens para janelas na classe. O sistema passa mensagens para o procedimento quando requer que a janela realize tarefas, como pintar sua área de cliente ou responder à entrada do usuário. Um processo atribui um procedimento de janela a uma classe copiando seu endereço para o lpfnWndProc membro da estruturaWNDCLASSEX. Para obter mais informações, consulte Window Procedures.

Identificador de instância

Cada classe de janela requer um identificador de instância para identificar o aplicativo ou .dll que registrou a classe. O sistema requer identificadores de instância para acompanhar todos os módulos. O sistema atribui um identificador a cada cópia de um executável ou .dllem execução.

O sistema passa um identificador de instância para a função de ponto de entrada de cada executável (consulte WinMain) e .dll (consulte DllMain). O executável ou .dll atribui esse identificador de instância à classe copiando-o para o hInstance membro da estruturaWNDCLASSEX.

Cursor de classe

O cursor da classe define a forma do cursor quando ele está na área do cliente de uma janela na classe. O sistema define automaticamente o cursor para a forma dada quando o cursor entra na área do cliente da janela e garante que ele mantenha essa forma enquanto permanece na área do cliente. Para atribuir uma forma de cursor a uma classe de janela, carregue uma forma de cursor predefinida usando a função deLoadCursore atribua a alça de cursor retornada ao hCursor membro da estrutura deWNDCLASSEX. Como alternativa, forneça um recurso de cursor personalizado e use a função LoadCursor para carregá-lo a partir dos recursos do aplicativo.

O sistema não requer um cursor de classe. Se um aplicativo definir o hCursor membro da estruturaWNDCLASSEXcomo NULL , nenhum cursor de classe será definido. O sistema assume que a janela define a forma do cursor cada vez que o cursor se move para a janela. Uma janela pode definir a forma do cursor chamando o SetCursor função sempre que a janela recebe a mensagem WM_MOUSEMOVE. Para obter mais informações sobre cursores, consulte cursores.

Ícones de classe

Um ícone de classe é uma imagem que o sistema usa para representar uma janela de uma classe específica. Um aplicativo pode ter dois ícones de classe: um grande e outro pequeno. O sistema exibe o ícone de classe grande de uma janela na janela de alternância de tarefas que aparece quando o usuário pressiona ALT+TAB e nas visualizações de ícones grandes da barra de tarefas e do explorador. O ícone de classe pequena aparece na barra de título de uma janela e nas vistas de ícones pequenos da barra de tarefas e do explorador.

Para atribuir um ícone grande e pequeno a uma classe de janela, especifique as alças dos ícones no hIcon e hIconSm membros da estruturaWNDCLASSEX. As dimensões dos ícones devem estar em conformidade com as dimensões exigidas para ícones de classes grandes e pequenas. Para um ícone de classe grande, você pode determinar as dimensões necessárias especificando os valores SM_CXICON e SM_CYICON em uma chamada para a funçãoGetSystemMetrics. Para um ícone de classe pequena, especifique os valores SM_CXSMICON e SM_CYSMICON. Para obter informações, consulte Ícones.

Se um aplicativo definir o hIcon e hIconSm membros da estruturaWNDCLASSEXpara NULL, o sistema usará o ícone de aplicativo padrão como os ícones de classe grande e pequeno para a classe window. Se você especificar um ícone de classe grande, mas não um pequeno, o sistema criará um ícone de classe pequena com base no grande. No entanto, se você especificar um ícone de classe pequena, mas não grande, o sistema usará o ícone de aplicativo padrão como o ícone de classe grande e o ícone especificado como o ícone de classe pequena.

Você pode substituir o ícone de classe grande ou pequena de uma janela específica usando a mensagem WM_SETICON. Você pode recuperar o ícone de classe grande ou pequena atual usando a mensagem WM_GETICON.

Pincel de fundo de classe

Um pincel de fundo de classe prepara a área do cliente de uma janela para o desenho subsequente pelo aplicativo. O sistema usa o pincel para preencher a área do cliente com uma cor ou padrão sólido, removendo assim todas as imagens anteriores desse local, quer pertençam à janela ou não. O sistema notifica uma janela de que seu plano de fundo deve ser pintado enviando a mensagem WM_ERASEBKGND para a janela. Para obter mais informações, consulte Pincéis.

Para atribuir um pincel de plano de fundo a uma classe, crie um pincel usando as funções GDI apropriadas e atribua a alça de pincel retornada ao hbrBackground membro da estruturaWNDCLASSEX.

Em vez de criar um pincel, um aplicativo pode definir o membro hbrBackground para um dos valores de cor padrão do sistema. Para obter uma lista dos valores de cor padrão do sistema, consulte SetSysColors.

Para usar uma cor padrão do sistema, o aplicativo deve aumentar o valor da cor de plano de fundo em um. Por exemplo, COLOR_BACKGROUND + 1 é a cor de fundo do sistema. Como alternativa, você pode usar a função GetSysColorBrush para recuperar uma alça para um pincel que corresponde a uma cor padrão do sistema e, em seguida, especificar a alça no hbrBackground membro da estruturaWNDCLASSEX.

O sistema não requer que uma classe de janela tenha um pincel de plano de fundo de classe. Se esse parâmetro estiver definido como NULL , a janela deverá pintar seu próprio plano de fundo sempre que receber a mensagem WM_ERASEBKGND.

Menu Classe

Um menu de classe define o menu padrão a ser usado pelas janelas na classe se nenhum menu explícito for fornecido quando as janelas forem criadas. Um menu é uma lista de comandos a partir dos quais um usuário pode escolher ações para o aplicativo executar.

Você pode atribuir um menu a uma classe definindo o lpszMenuName membro da estruturaWNDCLASSEXpara o endereço de uma cadeia de caracteres terminada em nulo que especifica o nome do recurso do menu. O menu é assumido como um recurso na aplicação dada. O sistema carrega automaticamente o menu quando é necessário. Se o recurso de menu for identificado por um inteiro e não por um nome, o aplicativo poderá definir o lpszMenuName membro a esse inteiro aplicando o macro MAKEINTRESOURCE antes de atribuir o valor.

O sistema não requer um menu de classe. Se um aplicativo definir o lpszMenuName membro da estrutura deWNDCLASSEXpara NULL , as janelas na classe não têm barras de menu. Mesmo que nenhum menu de classe seja fornecido, um aplicativo ainda pode definir uma barra de menus para uma janela quando cria a janela.

Se um menu for fornecido para uma classe e uma janela filho dessa classe for criada, o menu será ignorado. Para obter mais informações, consulte Menus.

Estilos de classe

Os estilos de classe definem elementos adicionais da classe window. Dois ou mais estilos podem ser combinados usando o operador bit a bit OR (|). Para atribuir um estilo a uma classe de janela, atribua o estilo ao estilo membro da estruturaWNDCLASSEX. Para obter uma lista de estilos de classe, consulte Estilos de classe de janela.

Classes e contextos de dispositivo

Um de contexto de dispositivo é um conjunto especial de valores que os aplicativos usam para desenhar na área do cliente de suas janelas. O sistema requer um contexto de dispositivo para cada janela no visor, mas permite alguma flexibilidade na forma como o sistema armazena e trata esse contexto de dispositivo.

Se nenhum estilo de contexto de dispositivo for explicitamente fornecido, o sistema assumirá que cada janela usa um contexto de dispositivo recuperado de um pool de contextos mantidos pelo sistema. Nesses casos, cada janela deve recuperar e inicializar o contexto do dispositivo antes de pintar e liberá-lo após a pintura.

Para evitar recuperar um contexto de dispositivo cada vez que ele precisa pintar dentro de uma janela, um aplicativo pode especificar o estilo CS_OWNDC para a classe window. Esse estilo de classe direciona o sistema para criar um contexto de dispositivo privado, ou seja, alocar um contexto de dispositivo exclusivo para cada janela da classe. O aplicativo só precisa recuperar o contexto uma vez e, em seguida, usá-lo para toda a pintura subsequente.

Memória de classe extra

O sistema mantém uma estrutura deWNDCLASSEXinternamente para cada classe de janela no sistema. Quando um aplicativo registra uma classe de janela, ele pode direcionar o sistema para alocar e acrescentar um número de bytes adicionais de memória ao final da estrutura de WNDCLASSEX. Essa memória é chamada memória de classe extra e é compartilhada por todas as janelas pertencentes à classe. Use a memória de classe extra para armazenar todas as informações pertencentes à classe.

Como a memória extra é alocada a partir do heap local do sistema, um aplicativo deve usar memória de classe extra com moderação. A funçãoRegisterClassEx falhará se a quantidade de memória de classe extra solicitada for maior que 40 bytes. Se um aplicativo requer mais de 40 bytes, ele deve alocar sua própria memória e armazenar um ponteiro para a memória na memória de classe extra.

AsSetClassWorde funções de SetClassLong copiam um valor para a memória de classe extra. Para recuperar um valor da memória de classe extra, use o GetClassWord e funções GetClassLong. O membro do cbClsExtra da estruturaWNDCLASSEXespecifica a quantidade de memória de classe extra a alocar. Um aplicativo que não usa memória de classe extra deve inicializar o membro cbClsExtra para zero.

Memória de janela extra

O sistema mantém uma estrutura de dados interna para cada janela. Ao registrar uma classe de janela, um aplicativo pode especificar um número de bytes adicionais de memória, chamados memória de janela extra. Ao criar uma janela da classe, o sistema aloca e acrescenta a quantidade especificada de memória de janela extra ao final da estrutura da janela. Um aplicativo pode usar essa memória para armazenar dados específicos da janela.

Como a memória extra é alocada a partir do heap local do sistema, um aplicativo deve usar memória de janela extra com moderação. A funçãoRegisterClassEx falhará se a quantidade de memória de janela extra solicitada for maior que 40 bytes. Se um aplicativo requer mais de 40 bytes, ele deve alocar sua própria memória e armazenar um ponteiro para a memória na memória de janela extra.

A função SetWindowLong copia um valor para a memória extra. O função GetWindowLong recupera um valor da memória extra. O membro do cbWndExtra da estruturaWNDCLASSEXespecifica a quantidade de memória de janela extra a alocar. Um aplicativo que não usa a memória deve inicializar cbWndExtra para zero.