Not
Åtkomst till denna sida kräver auktorisation. Du kan prova att logga in eller byta katalog.
Åtkomst till denna sida kräver auktorisation. Du kan prova att byta katalog.
I det här avsnittet beskrivs hur du utför följande uppgifter som är associerade med fönsterprocedurer.
- Utforma en fönsterprocedur
- Associera en fönsterprocedur med en fönsterklass
- underklassning av ett fönster
Utforma en fönsterprocedur
I följande exempel visas strukturen för en typisk fönsterprocedur. Fönsterproceduren använder meddelandeargumentet i en växla-instruktion med enskilda meddelanden som hanteras av separata fall-instruktioner. Observera att varje ärende returnerar ett specifikt värde för varje meddelande. För meddelanden som inte bearbetas anropar fönsterproceduren funktionen 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;
}
Det WM_NCCREATE meddelandet skickas precis efter att fönstret har skapats, men om ett program svarar på det här meddelandet genom att returnera FALSE, funktionen CreateWindowEx misslyckas. Meddelandet WM_CREATE skickas när fönstret redan har skapats.
Meddelandet WM_DESTROY skickas när fönstret håller på att förstöras. Funktionen DestroyWindow ansvarar för att förstöra eventuella barnfönster till det fönster som förstörs. Meddelandet WM_NCDESTROY skickas precis innan ett fönster förstörs.
En fönsterprocedur bör åtminstone bearbeta WM_PAINT meddelande för att rita sig själv. Normalt bör den även hantera mus- och tangentbordsmeddelanden. Läs beskrivningarna av enskilda meddelanden för att avgöra om fönsterproceduren ska hantera dem.
Ditt program kan anropa funktionen DefWindowProc som en del av bearbetningen av ett meddelande. I sådana fall kan programmet ändra meddelandeparametrarna innan det skickar meddelandet till DefWindowProc, eller så kan det fortsätta med standardbearbetningen efter att ha utfört sina egna åtgärder.
En dialogruteprocedur tar emot ett WM_INITDIALOG meddelande i stället för ett WM_CREATE meddelande och skickar inte obearbetade meddelanden till funktionen DefDlgProc. Annars är en dialogruteprocedur exakt densamma som en fönsterprocedur.
Associera en fönsterprocedur med en fönsterklass
Du associerar en fönsterprocedur med en fönsterklass när du registrerar klassen. Du måste fylla i en WNDCLASS- struktur med information om klassen, och lpfnWndProc medlem måste ange adressen till fönsterproceduren. Om du vill registrera klassen skickar du adressen till WNDCLASS- struktur till funktionen RegisterClass. När fönsterklassen har registrerats associeras fönsterproceduren automatiskt med varje nytt fönster som skapas med den klassen.
I följande exempel visas hur du associerar fönsterproceduren i föregående exempel med en fönsterklass.
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.
//
}
Underklassning av ett fönster
Om du vill subklassa en instans av ett fönster anropar du funktionen SetWindowLong och anger handtaget till fönstret, flaggan GWL_WNDPROC och en pekare till subklassningsproceduren. SetWindowLong returnerar en pekare till den ursprungliga fönsterproceduren. använd den här pekaren för att skicka meddelanden till den ursprungliga proceduren. Underklassfönsterproceduren måste använda funktionen CallWindowProc för att anropa den ursprungliga fönsterproceduren.
Notis
Om du vill skriva kod som är kompatibel med både 32-bitars och 64-bitars versioner av Windows använder du funktionen SetWindowLongPtr.
I följande exempel visas hur du underklassar en instans av en redigeringskontroll i en dialogruta. Med underklassfönstret kan redigeringskontrollen ta emot alla tangentbordsindata, inklusive tangenterna RETUR och TABB, när kontrollen har indatafokus.
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);
}