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.
Esta seção explica como executar as seguintes tarefas associadas aos procedimentos de janela.
- Desenhando um procedimento de janela
- Associando um procedimento de janela a uma classe de janela
- Subclassificar uma janela
Projetando um procedimento de janela
O exemplo a seguir mostra a estrutura de um procedimento de janela típico. O procedimento de janela usa o argumento de mensagem numa instrução switch, em que mensagens individuais são tratadas em instruções case separadas. Observe que cada caso retorna um valor específico para cada mensagem. Para mensagens que não processa, o procedimento de janela chama a função DefWindowProc.
LRESULT CALLBACK MainWndProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam) // second message parameter
{
switch (uMsg)
{
case WM_CREATE:
// Initialize the window.
return 0;
case WM_PAINT:
// Paint the window's client area.
return 0;
case WM_SIZE:
// Set the size and position of the window.
return 0;
case WM_DESTROY:
// Clean up window-specific data objects.
return 0;
//
// Process other messages.
//
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
A mensagem WM_NCCREATE é enviada logo após a janela ser criada, mas, se um aplicativo responder a essa mensagem retornando FALSE, a função CreateWindowEx falhará. A mensagem WM_CREATE é enviada depois que a janela já foi criada.
A mensagem WM_DESTROY é enviada quando a janela está prestes a ser destruída. A função DestroyWindow encarrega-se de destruir todas as janelas infantis da janela que está a ser destruída. A mensagem WM_NCDESTROY é enviada pouco antes de uma janela ser destruída.
No mínimo, um procedimento de janela deve processar a mensagem WM_PAINT para desenhar a si mesma. Normalmente, ele deve lidar com mensagens de mouse e teclado também. Consulte as descrições das mensagens individuais para determinar se o procedimento da janela deve processá-las.
O seu aplicativo pode chamar a função DefWindowProc como parte do processamento de uma mensagem. Nesse caso, o aplicativo pode modificar os parâmetros da mensagem antes de passar a mensagem para DefWindowProc, ou pode continuar com o processamento padrão depois de executar suas próprias operações.
Um procedimento de caixa de diálogo recebe uma mensagem WM_INITDIALOG em vez de uma mensagem WM_CREATE e não passa mensagens não processadas para a funçãoDefDlgProc. Caso contrário, um procedimento de caixa de diálogo é exatamente o mesmo que um procedimento de janela.
Associar um processo de janela a uma classe de janela
Você associa um procedimento de janela a uma classe de janela ao registrar a classe. Você deve preencher uma estrutura de WNDCLASS com informações sobre a classe, e o membro do lpfnWndProc deve especificar o endereço do procedimento da janela. Para registar a classe, passe o endereço da estrutura WNDCLASS para a função RegisterClass. Depois que a classe window for registrada, o procedimento window será automaticamente associado a cada nova janela criada com essa classe.
O exemplo a seguir mostra como associar o procedimento window no exemplo anterior a uma classe window.
int APIENTRY WinMain(
HINSTANCE hinstance, // handle to current instance
HINSTANCE hinstPrev, // handle to previous instance
LPSTR lpCmdLine, // address of command-line string
int nCmdShow) // show-window type
{
WNDCLASS wc;
// Register the main window class.
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC) MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hinstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = "MainMenu";
wc.lpszClassName = "MainWindowClass";
if (!RegisterClass(&wc))
return FALSE;
//
// Process other messages.
//
}
Subclassificando uma janela
Para subclassificar uma instância de uma janela, chame a função SetWindowLong e especifique o identificador da janela que deve ser subclassificada, o sinalizador GWL_WNDPROC e um ponteiro para o procedimento de subclasse. SetWindowLong retorna um ponteiro para o procedimento da janela original; use este ponteiro para passar mensagens para o procedimento da janela original. O procedimento da janela de subclasse deve usar a função CallWindowProc para chamar o procedimento da janela original.
Observação
Para escrever código compatível com as versões de 32 bits e 64 bits do Windows, use a funçãoSetWindowLongPtr.
O exemplo a seguir mostra como subclassificar uma instância de um controle de edição em uma caixa de diálogo. O procedimento da janela de subclasse permite que o controle de edição receba todas as entradas do teclado, incluindo as teclas ENTER e TAB, sempre que o controle tiver o foco de entrada.
WNDPROC wpOrigEditProc;
LRESULT APIENTRY EditBoxProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
HWND hwndEdit;
switch(uMsg)
{
case WM_INITDIALOG:
// Retrieve the handle to the edit control.
hwndEdit = GetDlgItem(hwndDlg, ID_EDIT);
// Subclass the edit control.
wpOrigEditProc = (WNDPROC) SetWindowLong(hwndEdit,
GWL_WNDPROC, (LONG) EditSubclassProc);
//
// Continue the initialization procedure.
//
return TRUE;
case WM_DESTROY:
// Remove the subclass from the edit control.
SetWindowLong(hwndEdit, GWL_WNDPROC,
(LONG) wpOrigEditProc);
//
// Continue the cleanup procedure.
//
break;
}
return FALSE;
UNREFERENCED_PARAMETER(lParam);
}
// Subclass procedure
LRESULT APIENTRY EditSubclassProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
if (uMsg == WM_GETDLGCODE)
return DLGC_WANTALLKEYS;
return CallWindowProc(wpOrigEditProc, hwnd, uMsg,
wParam, lParam);
}