Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Cada janela é um membro de uma classe de janela específica. A classe window determina o procedimento de janela padrão que uma janela individual usa para processar suas mensagens. Todas as janelas pertencentes à mesma classe usam o mesmo procedimento de janela padrão. For example, the system defines a window procedure for the combo box class (COMBOBOX); all combo boxes then use that window procedure.
Um aplicativo normalmente registra pelo menos uma nova classe de janela e seu procedimento de janela associado. Depois de registrar uma classe, o aplicativo pode criar muitas janelas dessa classe, todas usando o mesmo procedimento de janela. Como isso significa que várias fontes podem chamar simultaneamente a mesma parte do código, você deve ter cuidado ao modificar recursos compartilhados a partir de um procedimento de janela. Para obter mais informações, consulte Window Classes.
Os procedimentos de janela para caixas de diálogo (chamados procedimentos de caixa de diálogo) têm uma estrutura e função semelhantes aos procedimentos de janela regulares. Todos os pontos referentes aos procedimentos de janela nesta seção também se aplicam aos procedimentos da caixa de diálogo. Para obter mais informações, consulte Caixas de Diálogo.
Esta seção discute os seguintes tópicos.
- Structure of a Window Procedure
- Procedimento de janela padrão
- Window Procedure Subclassing
- Window Procedure Superclassing
Structure of a Window Procedure
Um procedimento de janela é uma função que tem quatro parâmetros e retorna um valor assinado. Os parâmetros consistem em um identificador de janela, um identificador de mensagem UINT e dois parâmetros de mensagem declarados com os tipos de dados WPARAM e LPARAM. Para obter mais informações, consulte WindowProc.
Os parâmetros de mensagem geralmente contêm informações em suas palavras de ordem baixa e alta. Há várias macros que um aplicativo pode usar para extrair informações dos parâmetros da mensagem. A macro LOWORD, por exemplo, extrai a palavra de ordem baixa (bits de 0 a 15) de um parâmetro de mensagem. Outras macros incluem HIWORD, LOBYTE e macro HIBYTE.
A interpretação do valor de retorno depende da mensagem específica. Consulte a descrição de cada mensagem para determinar o valor de retorno apropriado.
Como é possível chamar um procedimento de janela recursivamente, é importante minimizar o número de variáveis locais que ele usa. When processing individual messages, an application should call functions outside the window procedure to avoid excessive use of local variables, possibly causing the stack to overflow during deep recursion.
Procedimento de janela padrão
A função de procedimento de janela padrão, DefWindowProc define determinado comportamento fundamental compartilhado por todas as janelas. O procedimento de janela padrão fornece a funcionalidade mínima para uma janela. Um procedimento de janela definido pelo aplicativo deve passar todas as mensagens que ele não processa para a função DefWindowProc para processamento padrão.
Window Procedure Subclassing
Quando um aplicativo cria uma janela, o sistema aloca um bloco de memória para armazenar informações específicas da janela, incluindo o endereço do procedimento da janela que processa as mensagens para a janela. When the system needs to pass a message to the window, it searches the window-specific information for the address of the window procedure and passes the message to that procedure.
Subclassing é uma técnica que permite que um aplicativo intercepte e processe mensagens enviadas ou postadas numa janela específica antes que a janela tenha a chance de processá-las. Ao subclassificar uma janela, um aplicativo pode aumentar, modificar ou monitorar o comportamento da janela. Um aplicativo pode subclassificar uma janela pertencente a uma classe global do sistema, como um controle de edição ou uma caixa de listagem. Por exemplo, um aplicativo pode subclassificar um controle de edição para impedir que o controle aceite determinados caracteres. No entanto, você não pode subclassificar uma janela ou classe que pertence a outro aplicativo. Todas as subclassificações devem ser realizadas dentro do mesmo processo.
Um aplicativo subclassifica uma janela ao substituir o endereço do procedimento de janela original pelo endereço de um novo procedimento de janela, chamado procedimento de subclasse . Thereafter, the subclass procedure receives any messages sent or posted to the window.
O procedimento de subclasse pode executar três ações ao receber uma mensagem: pode passar a mensagem para o procedimento da janela original, modificar a mensagem e passá-la para o procedimento da janela original ou processar a mensagem e não passá-la para o procedimento da janela original. If the subclass procedure processes a message, it can do so before, after, or both before and after it passes the message to the original window procedure.
O sistema fornece dois tipos de subclassificação: instância e global. In instance subclassing, an application replaces the window procedure address of a single instance of a window. Um aplicativo deve usar a subclassificação de instância para subclassificar uma janela existente. In global subclassing, an application replaces the address of the window procedure in the WNDCLASSEX structure of a window class. Todas as janelas subsequentes criadas com a classe têm o endereço do procedimento de subclasse, mas as janelas existentes da classe não são afetadas.
Instance Subclassing
An application subclasses an instance of a window by using the SetWindowLongPtr function. The application passes the GWL_WNDPROC flag, the handle to the window to subclass, and the address of the subclass procedure to SetWindowLongPtr. O procedimento de subclasse pode residir no executável do aplicativo ou em uma DLL.
When passed the GWL_WNDPROC flag, SetWindowLongPtr returns the address of the window's original window procedure. A aplicação deve guardar este endereço, usando-o nas chamadas subsequentes para a função CallWindowProc, para passar mensagens intercetadas para o procedimento da janela original. O aplicativo também deve ter o endereço de procedimento da janela original para remover a subclasse da janela. To remove the subclass, the application calls SetWindowLongPtr again, passing the address of the original window procedure with the GWL_WNDPROC flag and the handle to the window.
O sistema possui as classes globais do sistema, e os aspetos dos controles podem mudar de uma versão do sistema para a próxima. Se o aplicativo deve subclassificar uma janela que pertence a uma classe global do sistema, o desenvolvedor pode precisar atualizar o aplicativo quando uma nova versão do sistema for lançada.
Como a subclassificação de instância ocorre depois que uma janela é criada, não é possível adicionar bytes extras à janela. Os aplicativos que subclassificam uma janela devem usar a lista de propriedades da janela para armazenar quaisquer dados necessários para uma instância da janela subclassificada. Para obter mais informações, consulte Propriedades da janela.
Quando um aplicativo subclassifica uma janela subclassificada, ele deve remover as subclasses na ordem inversa em que foram executadas. Se a ordem de remoção não for revertida, poderá ocorrer um erro de sistema irrecuperável.
Subclassificação Global
Para subclassificar globalmente uma classe de janela, o aplicativo deve ter um identificador para uma janela da classe. O aplicativo também precisa do identificador para remover a subclasse. To get the handle, an application typically creates a hidden window of the class to be subclassed. After obtaining the handle, the application calls the SetClassLongPtr function, specifying the handle, the GCL_WNDPROC flag, and the address of the subclass procedure. SetClassLongPtr retorna o endereço do procedimento de janela original associado à classe.
O endereço de procedimento da janela original é usado na subclassificação global da mesma forma que é usado na subclassificação de instância. O procedimento de subclasse passa mensagens para o procedimento de janela original chamando CallWindowProc. The application removes the subclass from the window class by calling SetClassLongPtr again, specifying the address of the original window procedure, the GCL_WNDPROC flag, and the handle to a window of the class being subclassed. Um aplicativo que globalmente subclassifica uma classe de controle deve remover a subclasse quando o aplicativo é encerrado; caso contrário, poderá ocorrer um erro de sistema irrecuperável.
A subclassificação global tem as mesmas limitações que a subclassificação de instância, além de algumas restrições adicionais. Um aplicativo não deve usar os bytes extras para a classe ou a instância da janela sem saber exatamente como o procedimento da janela original os usa. Se o aplicativo deve associar dados a uma janela, ele deve usar propriedades de janela.
Window Procedure Superclassing
Superclassificação é uma técnica que permite que um aplicativo crie uma nova classe de janela com a funcionalidade básica da classe existente, além de aprimoramentos fornecidos pelo aplicativo. Uma superclasse é baseada em uma classe de janela existente chamada classe base . Freqüentemente, a classe base é uma classe de janela global do sistema, como um controle de edição, mas pode ser qualquer classe de janela.
A superclass has its own window procedure, called the superclass procedure. O procedimento de superclasse pode executar três ações ao receber uma mensagem: Ele pode passar a mensagem para o procedimento da janela original, modificar a mensagem e passá-la para o procedimento da janela original ou processar a mensagem e não passá-la para o procedimento da janela original. If the superclass procedure processes a message, it can do so before, after, or both before and after it passes the message to the original window procedure.
Ao contrário de um procedimento de subclasse, um procedimento de superclasse pode processar mensagens de criação de janela (WM_NCCREATE, WM_CREATEe assim por diante), mas também deve passá-las para o procedimento de janela de classe base original para que o procedimento de janela de classe base possa executar seu procedimento de inicialização.
Para superclassificar uma classe de janela, um aplicativo primeiro chama a funçãoGetClassInfoEx para recuperar informações sobre a classe base. GetClassInfoEx preenche uma estrutura WNDCLASSEX com os valores da estrutura WNDCLASSEX da classe base. Em seguida, o aplicativo copia seu próprio identificador de instância para o membro hInstance da estrutura WNDCLASSEX e copia o nome da superclasse para o membro lpszClassName. Se a classe base tiver um menu, o aplicativo deve fornecer um novo menu com os mesmos identificadores de menu e copiar o nome do menu para o lpszMenuName membro. Se o procedimento de superclasse processar a mensagem WM_COMMAND e não passá-la para o procedimento de janela da classe base, o menu não precisará ter identificadores correspondentes. GetClassInfoEx não retorna o membro lpszMenuName, lpszClassNameou hInstance da estrutura WNDCLASSEX.
Uma aplicação também deve definir o membro lpfnWndProc da estrutura WNDCLASSEX. A funçãoGetClassInfoEx preenche esse membro com o endereço do procedimento de janela original para a classe. The application must save this address, to pass messages to the original window procedure, and then copy the address of the superclass procedure into the lpfnWndProc member. A aplicação pode, se necessário, modificar quaisquer outros membros da estrutura WNDCLASSEX. Depois de preencher a estrutura WNDCLASSEX, a aplicação registra a superclasse ao passar o endereço da estrutura para a função RegisterClassEx. A superclasse pode então ser usada para criar janelas.
Because superclassing registers a new window class, an application can add to both the extra class bytes and the extra window bytes. A superclasse não deve usar os bytes extras originais para a classe base ou a janela pelos mesmos motivos que uma subclasse de instância ou uma subclasse global não deve usá-los. Além disso, se o aplicativo adicionar bytes extras para seu uso à classe ou à instância da janela, ele deverá fazer referência aos bytes extras relativos ao número de bytes extras usados pela classe base original. Como o número de bytes usados pela classe base pode variar de uma versão da classe base para a próxima, o deslocamento inicial para os bytes extras da própria superclasse também pode variar de uma versão da classe base para a próxima.