Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
In deze sectie wordt uitgelegd hoe u de volgende taken uitvoert die zijn gekoppeld aan vensterprocedures.
- Een vensterprocedure ontwerpen
- een vensterprocedure koppelen aan een vensterklasse
- Subklassen van een venster
Een vensterprocedure ontwerpen
In het volgende voorbeeld ziet u de structuur van een typische vensterprocedure. De vensterprocedure gebruikt het berichtargument in een switch instructie met afzonderlijke berichten die worden verwerkt door afzonderlijke case instructies. U ziet dat elke case een specifieke waarde retourneert voor elk bericht. Voor berichten die niet worden verwerkt, roept de vensterprocedure de functie DefWindowProc aan.
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;
}
Het WM_NCCREATE bericht wordt verzonden net nadat het venster is gemaakt, maar als een toepassing op dit bericht reageert door FALSE-te retourneren, mislukt functie CreateWindowEx. Het WM_CREATE bericht wordt verzonden nadat het venster al is gemaakt.
Het WM_DESTROY bericht wordt verzonden wanneer uw venster op het punt staat te worden vernietigd. De DestroyWindow functie zorgt ervoor dat alle onderliggende vensters van het venster dat wordt vernietigd, worden verwijderd. Het WM_NCDESTROY bericht wordt verzonden net voordat een venster wordt vernietigd.
In ieder geval moet een vensterprocedure het WM_PAINT bericht verwerken om zichzelf te tekenen. Normaal gesproken moet het ook muis- en toetsenbordberichten verwerken. Raadpleeg de beschrijvingen van afzonderlijke berichten om te bepalen of uw vensterprocedure deze moet verwerken.
Uw toepassing kan de functie DefWindowProc aanroepen als onderdeel van de verwerking van een bericht. In dat geval kan de toepassing de berichtparameters wijzigen voordat het bericht wordt doorgegeven aan DefWindowProc, of kan de toepassing doorgaan met de standaardverwerking nadat het zijn eigen bewerkingen heeft uitgevoerd.
Een dialoogvensterprocedure ontvangt een WM_INITDIALOG bericht in plaats van een WM_CREATE bericht en geeft geen niet-verwerkte berichten door aan de functie DefDlgProc-. Anders is een dialoogvensterprocedure precies hetzelfde als een vensterprocedure.
Een vensterprocedure koppelen aan een vensterklasse
U koppelt een vensterprocedure aan een vensterklasse bij het registreren van de klasse. U moet een WNDCLASS structuur vullen met informatie over de klasse en de lpfnWndProc lid moet het adres van de vensterprocedure opgeven. Als u de klasse wilt registreren, geeft u het adres van WNDCLASS- structuur door aan de functie RegisterClass. Nadat de vensterklasse is geregistreerd, wordt de vensterprocedure automatisch gekoppeld aan elk nieuw venster dat met die klasse is gemaakt.
In het volgende voorbeeld ziet u hoe u de vensterprocedure in het vorige voorbeeld koppelt aan een vensterklasse.
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.
//
}
Een venster subklasseren
Als u een vensterexemplaar wilt subklassen, roept u de functie SetWindowLong aan en specificeert u het handvat van het venster om de GWL_WNDPROC-vlag en een aanwijzer naar de subklasseprocedure op te geven. SetWindowLong retourneert een aanwijzer naar de oorspronkelijke vensterprocedure; gebruik deze aanwijzer om berichten door te geven aan de oorspronkelijke procedure. De subklassevensterprocedure moet de CallWindowProc--functie gebruiken om de oorspronkelijke vensterprocedure aan te roepen.
Notitie
Als u code wilt schrijven die compatibel is met zowel 32-bits als 64-bits versies van Windows, gebruikt u de functie SetWindowLongPtr.
In het volgende voorbeeld ziet u hoe u een instantie van een bewerkingsveld in een dialoogvenster kunt subclassen. Met de subklassen vensterprocedure kan het bewerkingsbesturingselement alle toetsenbordinvoer ontvangen, inclusief de ENTER- en TAB-toetsen, wanneer het besturingselement de invoerfocus heeft.
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);
}