Informazioni sulle classi finestra
Ogni classe finestra ha una routine finestra associata condivisa da tutte le finestre della stessa classe. La routine window elabora i messaggi per tutte le finestre di tale classe e controlla quindi il comportamento e l'aspetto. Per altre informazioni, vedere Routine della finestra.
Un processo deve registrare una classe finestra prima di poter creare una finestra di tale classe. La registrazione di una classe finestra associa una routine finestra, gli stili di classe e altri attributi di classe a un nome di classe. Quando un processo specifica un nome di classe nella funzione CreateWindow o CreateWindowEx , il sistema crea una finestra con la routine finestra, gli stili e altri attributi associati al nome della classe.
In questa sezione vengono illustrati gli argomenti seguenti.
- Tipi di classi di finestre
- Come il sistema individua una classe window
- Registrazione di una classe Window
- Elementi di una classe Window
Tipi di classi di finestre
Esistono tre tipi di classi finestra:
Questi tipi differiscono nell'ambito e in quando e in che modo vengono registrati e eliminati definitivamente.
Classi di sistema
Una classe di sistema è una classe finestra registrata dal sistema. Molte classi di sistema sono disponibili per tutti i processi da usare, mentre altre vengono usate solo internamente dal sistema. Poiché il sistema registra queste classi, un processo non può eliminarle.
Il sistema registra le classi di sistema per un processo la prima volta che uno dei relativi thread chiama una funzione User o Windows Graphics Device Interface (GDI).
Ogni applicazione riceve la propria copia delle classi di sistema. Tutte le applicazioni basate su Windows a 16 bit nella stessa classe di sistema di condivisione VDM, proprio come avviene in Windows a 16 bit.
Nella tabella seguente vengono descritte le classi di sistema disponibili per l'uso da parte di tutti i processi.
Classe | Descrizione |
---|---|
Pulsante | Classe per un pulsante. |
ComboBox | Classe per una casella combinata. |
Modifica | Classe per un controllo di modifica. |
ListBox | Classe per una casella di riepilogo. |
Mdiclient | Classe per una finestra client MDI. |
ScrollBar | Classe per una barra di scorrimento. |
Static | Classe per un controllo statico. |
Nella tabella seguente vengono descritte le classi di sistema disponibili solo per l'uso da parte del sistema. Sono elencati qui per motivi di completezza.
Classe | Descrizione |
---|---|
ComboLBox | Classe per la casella di riepilogo contenuta in una casella combinata. |
DDEMLEvent | Classe per gli eventi DDEML (Dynamic Data Exchange Management Library). |
Message | Classe per una finestra di sola messaggio. |
#32768 | Classe per un menu. |
#32769 | Classe per la finestra desktop. |
#32770 | Classe per una finestra di dialogo. |
#32771 | Classe per la finestra dell'opzione di attività. |
#32772 | Classe per i titoli delle icone. |
Classi globali dell'applicazione
Una classe globale dell'applicazione è una classe finestra registrata da un eseguibile o da una DLL disponibile per tutti gli altri moduli del processo. Ad esempio, il .dll può chiamare la funzione RegisterClassEx per registrare una classe finestra che definisce un controllo personalizzato come classe globale dell'applicazione in modo che un processo che carica il .dll possa creare istanze del controllo personalizzato.
Per creare una classe che può essere usata in ogni processo, creare la classe finestra in un .dll e caricare il .dll in ogni processo. Per caricare il .dll in ogni processo, aggiungere il nome al valore AppInit_DLLs nella chiave del Registro di sistema seguente:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\Currentversion\Finestre
Ogni volta che viene avviato un processo, il sistema carica il .dll specificato nel contesto del processo appena avviato prima di chiamare la funzione del punto di ingresso. Il .dll deve registrare la classe durante la procedura di inizializzazione e deve specificare lo stile di CS_GLOBALCLASS . Per altre informazioni, vedere Stili di classe.
Per rimuovere una classe globale dell'applicazione e liberare l'archiviazione associata, usare la funzione UnregisterClass .
Classi locali dell'applicazione
Una classe locale dell'applicazione è qualsiasi classe finestra registrata da un eseguibile o .dll per l'uso esclusivo. Sebbene sia possibile registrare un numero qualsiasi di classi locali, è in genere necessario registrare una sola classe. Questa classe di finestra supporta la routine della finestra principale dell'applicazione.
Il sistema elimina definitivamente una classe locale quando il modulo che lo ha registrato chiude. Un'applicazione può anche usare la funzione UnregisterClass per rimuovere una classe locale e liberare lo spazio di archiviazione associato.
Come il sistema individua una classe window
Il sistema gestisce un elenco di strutture per ognuno dei tre tipi di classi finestra. Quando un'applicazione chiama la funzione CreateWindow o CreateWindowEx per creare una finestra con una classe specificata, il sistema usa la procedura seguente per individuare la classe.
- Cercare nell'elenco delle classi locali dell'applicazione una classe con il nome specificato il cui handle di istanza corrisponde all'handle di istanza del modulo. Diversi moduli possono usare lo stesso nome per registrare le classi locali nello stesso processo.
- Se il nome non è incluso nell'elenco delle classi locali dell'applicazione, cercare nell'elenco delle classi globali dell'applicazione.
- Se il nome non è incluso nell'elenco di classi globali dell'applicazione, cercare l'elenco delle classi di sistema.
Tutte le finestre create dall'applicazione usano questa procedura, incluse le finestre create dal sistema per conto dell'applicazione, ad esempio le finestre di dialogo. È possibile eseguire l'override delle classi di sistema senza influire sulle altre applicazioni. Ovvero, un'applicazione può registrare una classe locale dell'applicazione con lo stesso nome di una classe di sistema. Ciò sostituisce la classe di sistema nel contesto dell'applicazione, ma non impedisce ad altre applicazioni di usare la classe di sistema.
Registrazione di una classe di finestra
Una classe finestra definisce gli attributi di una finestra, ad esempio lo stile, l'icona, il cursore, il menu e la routine della finestra. Il primo passaggio nella registrazione di una classe di finestra consiste nel compilare una struttura WNDCLASSEX con le informazioni sulla classe della finestra. Per altre informazioni, vedere Elementi di una classe window. Passare quindi la struttura alla funzione RegisterClassEx . Per altre informazioni, vedere Uso delle classi di finestra.
Per registrare una classe globale dell'applicazione, specificare lo stile CS_GLOBALCLASS nel membro di stile della struttura WNDCLASSEX . Quando si registra una classe locale dell'applicazione, non specificare lo stile CS_GLOBALCLASS .
Se si registra la classe di finestra usando la versione ANSI di RegisterClassEx, RegisterClassExA, l'applicazione richiede che il sistema passi i parametri di testo dei messaggi alle finestre della classe creata usando il set di caratteri ANSI; se si registra la classe usando la versione Unicode di RegisterClassEx, RegisterClassExW, l'applicazione richiede che il sistema passi i parametri di testo dei messaggi alle finestre della classe creata usando il set di caratteri Unicode. La funzione IsWindowUnicode consente alle applicazioni di eseguire query sulla natura di ogni finestra. Per altre informazioni sulle funzioni ANSI e Unicode, vedere Convenzioni per i prototipi di funzioni.
Il file eseguibile o la DLL che ha registrato la classe è il proprietario della classe. Il sistema determina la proprietà della classe dal membro hInstance della struttura WNDCLASSEX passata alla funzione RegisterClassEx quando la classe viene registrata. Per le DLL, il membro hInstance deve essere l'handle dell'istanza di .dll.
La classe non viene eliminata quando il .dll proprietario viene scaricato. Pertanto, se il sistema chiama la procedura della finestra per una finestra di tale classe, causerà una violazione di accesso, perché la .dll contenente la routine della finestra non è più in memoria. Il processo deve eliminare tutte le finestre usando la classe prima che il .dll venga scaricato e chiamare la funzione UnregisterClass .
Elementi di una classe Window
Gli elementi di una classe di finestra definiscono il comportamento predefinito delle finestre appartenenti alla classe . L'applicazione che registra una classe di finestra assegna elementi alla classe impostando membri appropriati in una struttura WNDCLASSEX e passando la struttura alla funzione RegisterClassEx . Le funzioni GetClassInfoEx e GetClassLong recuperano informazioni su una determinata classe di finestra. La funzione SetClassLong modifica gli elementi di una classe locale o globale già registrata dall'applicazione.
Anche se una classe di finestra completa è costituita da molti elementi, il sistema richiede solo che un'applicazione fornisca un nome di classe, l'indirizzo della routine della finestra e un handle di istanza. Usare gli altri elementi per definire gli attributi predefiniti per le finestre della classe, ad esempio la forma del cursore e il contenuto del menu per la finestra. È necessario inizializzare tutti i membri inutilizzati della struttura WNDCLASSEX su zero o NULL. Gli elementi della classe della finestra sono illustrati nella tabella seguente.
Elemento | Scopo |
---|---|
Nome della classe | Distingue la classe da altre classi registrate. |
Indirizzo della routine della finestra | Puntatore alla funzione che elabora tutti i messaggi inviati a finestre nella classe e definisce il comportamento della finestra. |
Handle istanza | Identifica l'applicazione o .dll che ha registrato la classe. |
Cursore classe | Definisce il cursore del mouse visualizzato dal sistema per una finestra della classe. |
Icone di classe | Definisce l'icona grande e l'icona piccola. |
Pennello sfondo classe | Definisce il colore e il modello che riempiono l'area client quando la finestra viene aperta o dipinta. |
Menu classi | Specifica il menu predefinito per le finestre che non definiscono in modo esplicito un menu. |
Stili classe | Definisce come aggiornare la finestra dopo lo spostamento o il ridimensionamento, come elaborare doppio clic del mouse, come allocare spazio per il contesto del dispositivo e altri aspetti della finestra. |
Memoria di classe aggiuntiva | Specifica la quantità di memoria aggiuntiva, in byte, che il sistema deve riservare per la classe. Tutte le finestre della classe condividono la memoria aggiuntiva e possono usarla per qualsiasi scopo definito dall'applicazione. Il sistema inizializza questa memoria su zero. |
Memoria finestra aggiuntiva | Specifica la quantità di memoria aggiuntiva, in byte, che il sistema deve riservare per ogni finestra appartenente alla classe. La memoria aggiuntiva può essere usata per qualsiasi scopo definito dall'applicazione. Il sistema inizializza questa memoria su zero. |
Nome della classe
Ogni classe di finestra richiede un nome di classe per distinguere una classe da un'altra. Assegnare un nome di classe impostando il membro lpszClassName della struttura WNDCLASSEX sull'indirizzo di una stringa con terminazione null che specifica il nome. Poiché le classi di finestra sono specifiche del processo, i nomi delle classi di finestra devono essere univoci solo all'interno dello stesso processo. Inoltre, poiché i nomi delle classi occupano spazio nella tabella atom privata del sistema, è consigliabile mantenere le stringhe di nome della classe più brevi possibile.
La funzione GetClassName recupera il nome della classe a cui appartiene una determinata finestra.
Indirizzo della routine della finestra
Ogni classe necessita di un indirizzo della routine finestra per definire il punto di ingresso della routine finestra usata per elaborare tutti i messaggi per le finestre nella classe. Il sistema passa messaggi alla procedura quando richiede la finestra di eseguire attività, ad esempio disegnare l'area client o rispondere all'input dell'utente. Un processo assegna una routine della finestra a una classe copiandone l'indirizzo nel membro lpfnWndProc della struttura WNDCLASSEX . Per altre informazioni, vedere Routine della finestra.
Handle istanza
Ogni classe di finestra richiede un handle di istanza per identificare l'applicazione o .dll che ha registrato la classe. Il sistema richiede handle di istanza per tenere traccia di tutti i moduli. Il sistema assegna un handle a ogni copia di un eseguibile in esecuzione o .dll.
Il sistema passa un handle di istanza alla funzione del punto di ingresso di ogni eseguibile (vedere WinMain) e .dll (vedere DllMain). Il file eseguibile o .dll assegna questo handle di istanza alla classe copiandolo nel membro hInstance della struttura WNDCLASSEX .
Cursore classe
Il cursore della classe definisce la forma del cursore quando si trova nell'area client di una finestra della classe. Il sistema imposta automaticamente il cursore sulla forma specificata quando il cursore entra nell'area client della finestra e garantisce che la forma rimanga nell'area client. Per assegnare una forma cursore a una classe finestra, caricare una forma di cursore predefinita usando la funzione LoadCursor e quindi assegnare l'handle cursore restituito al membro hCursor della struttura WNDCLASSEX . In alternativa, specificare una risorsa cursore personalizzata e usare la funzione LoadCursor per caricarla dalle risorse dell'applicazione.
Il sistema non richiede un cursore di classe. Se un'applicazione imposta il membro hCursor della struttura WNDCLASSEX su NULL, non viene definito alcun cursore di classe. Il sistema presuppone che la finestra imposta la forma del cursore ogni volta che il cursore si sposta nella finestra. Una finestra può impostare la forma del cursore chiamando la funzione SetCursor ogni volta che la finestra riceve il messaggio di WM_MOUSEMOVE . Per altre informazioni sui cursori, vedere Cursori.
Icone di classe
Un'icona di classe è un'immagine usata dal sistema per rappresentare una finestra di una determinata classe. Un'applicazione può avere due icone di classe, una grande e una piccola. Il sistema visualizza l'icona della classe grande di una finestra nella finestra del commutatore di attività visualizzata quando l'utente preme ALT+TAB e nelle visualizzazioni icona di grandi dimensioni della barra delle applicazioni e esplora risorse. L'icona della classe piccola viene visualizzata nella barra del titolo di una finestra e nelle visualizzazioni icona di piccole dimensioni della barra delle applicazioni e esplora risorse.
Per assegnare un'icona grande e piccola a una classe di finestra, specificare gli handle delle icone nei membri hIcon e hIconSm della struttura WNDCLASSEX. Le dimensioni dell'icona devono essere conformi alle dimensioni necessarie per icone di classe grandi e piccole. Per un'icona di classe di grandi dimensioni, è possibile determinare le dimensioni necessarie specificando i valori di SM_CXICON e SM_CYICON in una chiamata alla funzione GetSystemMetrics . Per un'icona di classe piccola, specificare i valori di SM_CXSMICON e SM_CYSMICON . Per informazioni, vedere Icone.
Se un'applicazione imposta i membri hIcon e hIconSm della struttura WNDCLASSEX su NULL, il sistema usa l'icona dell'applicazione predefinita come icone di classe grandi e piccole per la classe finestra. Se si specifica un'icona di classe di grandi dimensioni, ma non una piccola, il sistema crea un'icona di classe piccola in base a quella grande. Tuttavia, se si specifica un'icona di classe piccola, ma non una grande, il sistema usa l'icona dell'applicazione predefinita come icona di classe di grandi dimensioni e l'icona specificata come icona di classe piccola.
È possibile eseguire l'override dell'icona di classe grande o piccola per una finestra specifica usando il messaggio di WM_SETICON . È possibile recuperare l'icona di classe grande o piccola corrente usando il messaggio di WM_GETICON .
Pennello sfondo classe
Un pennello di sfondo della classe prepara l'area client di una finestra per il disegno successivo dall'applicazione. Il sistema usa il pennello per riempire l'area client con un colore o un modello a tinta unita, rimuovendo così tutte le immagini precedenti da tale posizione, indipendentemente dal fatto che appartengano alla finestra o meno. Il sistema notifica a una finestra che lo sfondo deve essere dipinto inviando il messaggio di WM_ERASEBKGND alla finestra. Per altre informazioni, vedere Pennelli.
Per assegnare un pennello di sfondo a una classe, creare un pennello usando le funzioni GDI appropriate e assegnare l'handle pennello restituito al membro hbrBackground della struttura WNDCLASSEX .
Anziché creare un pennello, un'applicazione può impostare il membro hbrBackground su uno dei valori di colore di sistema standard. Per un elenco dei valori di colore di sistema standard, vedere SetSysColors.
Per usare un colore di sistema standard, l'applicazione deve aumentare il valore di colore di sfondo per uno. Ad esempio, COLOR_BACKGROUND + 1 è il colore di sfondo del sistema. In alternativa, è possibile usare la funzione GetSysColorBrush per recuperare un handle in un pennello che corrisponde a un colore di sistema standard e quindi specificare l'handle nel membro hbrBackground della struttura WNDCLASSEX .
Il sistema non richiede che una classe finestra disponga di un pennello di sfondo di classe. Se questo parametro è impostato su NULL, la finestra deve disegnare il proprio sfondo ogni volta che riceve il messaggio di WM_ERASEBKGND .
Menu classi
Un menu di classe definisce il menu predefinito da utilizzare dalle finestre della classe se non viene specificato alcun menu esplicito quando vengono create le finestre. Un menu è un elenco di comandi da cui un utente può scegliere azioni per l'applicazione da eseguire.
È possibile assegnare un menu a una classe impostando il membro lpszMenuName della struttura WNDCLASSEX all'indirizzo di una stringa con terminazione null che specifica il nome della risorsa del menu. Si presuppone che il menu sia una risorsa nell'applicazione specificata. Il sistema carica automaticamente il menu quando è necessario. Se la risorsa del menu viene identificata da un numero intero e non da un nome, l'applicazione può impostare il membro lpszMenuName su tale intero applicando la macro MAKEINTRESOURCE prima di assegnare il valore.
Il sistema non richiede un menu di classe. Se un'applicazione imposta il membro lpszMenuName della struttura WNDCLASSEX su NULL, le finestre della classe non hanno barre dei menu. Anche se non viene specificato alcun menu di classe, un'applicazione può comunque definire una barra dei menu per una finestra quando crea la finestra.
Se viene specificato un menu per una classe e una finestra figlio di tale classe viene creata, il menu viene ignorato. Per altre informazioni, vedere Menu.
Stili classe
Gli stili della classe definiscono elementi aggiuntivi della classe finestra. È possibile combinare due o più stili usando l'operatore OR bit per bit (|). Per assegnare uno stile a una classe finestra, assegnare lo stile al membro di stile della struttura WNDCLASSEX . Per un elenco di stili di classe, vedere Stili di classe finestra.
Classi e contesti del dispositivo
Un contesto del dispositivo è un set speciale di valori che le applicazioni usano per il disegno nell'area client delle finestre. Il sistema richiede un contesto del dispositivo per ogni finestra sullo schermo, ma consente una certa flessibilità nel modo in cui il sistema archivia e tratta il contesto del dispositivo.
Se non viene specificato in modo esplicito lo stile del contesto del dispositivo, il sistema presuppone che ogni finestra usi un contesto del dispositivo recuperato da un pool di contesti gestiti dal sistema. In questi casi, ogni finestra deve recuperare e inizializzare il contesto del dispositivo prima di disegnare e liberarlo dopo la pittura.
Per evitare di recuperare un contesto del dispositivo ogni volta che deve disegnare all'interno di una finestra, un'applicazione può specificare lo stile CS_OWNDC per la classe finestra. Questo stile di classe indirizza il sistema per creare un contesto di dispositivo privato, ovvero allocare un contesto di dispositivo univoco per ogni finestra della classe. L'applicazione deve recuperare solo il contesto una volta e quindi usarla per tutti i dipinti successivi.
Memoria di classe aggiuntiva
Il sistema gestisce una struttura WNDCLASSEX internamente per ogni classe di finestra nel sistema. Quando un'applicazione registra una classe di finestra, può indirizzare il sistema ad allocare e aggiungere un numero di byte aggiuntivi di memoria alla fine della struttura WNDCLASSEX . Questa memoria viene chiamata memoria di classe aggiuntiva ed è condivisa da tutte le finestre appartenenti alla classe. Usare la memoria della classe aggiuntiva per archiviare tutte le informazioni relative alla classe.
Poiché la memoria aggiuntiva viene allocata dall'heap locale del sistema, un'applicazione deve usare memoria di classe aggiuntiva. La funzione RegisterClassEx ha esito negativo se la quantità di memoria di classe aggiuntiva richiesta è maggiore di 40 byte. Se un'applicazione richiede più di 40 byte, deve allocare la propria memoria e archiviare un puntatore alla memoria nella memoria aggiuntiva della classe.
Le funzioni SetClassWord e SetClassLong copiano un valore nella memoria della classe aggiuntiva. Per recuperare un valore dalla memoria di classe aggiuntiva, usare le funzioni GetClassWord e GetClassLong . Il membro cbClsExtra della struttura WNDCLASSEX specifica la quantità di memoria di classe aggiuntiva da allocare. Un'applicazione che non usa memoria di classe aggiuntiva deve inizializzare il membro cbClsExtra su zero.
Memoria finestra aggiuntiva
Il sistema gestisce una struttura di dati interna per ogni finestra. Quando si registra una classe di finestra, un'applicazione può specificare un numero di byte aggiuntivi di memoria, denominata memoria di finestra aggiuntiva. Quando si crea una finestra della classe, il sistema alloca e aggiunge la quantità di memoria finestra aggiuntiva alla fine della struttura della finestra. Un'applicazione può usare questa memoria per archiviare dati specifici della finestra.
Poiché la memoria aggiuntiva viene allocata dall'heap locale del sistema, un'applicazione deve usare memoria di finestra aggiuntiva. La funzione RegisterClassEx ha esito negativo se la quantità di memoria della finestra aggiuntiva richiesta è maggiore di 40 byte. Se un'applicazione richiede più di 40 byte, deve allocare la propria memoria e archiviare un puntatore alla memoria nella memoria aggiuntiva della finestra.
La funzione SetWindowLong copia un valore nella memoria aggiuntiva. La funzione GetWindowLong recupera un valore dalla memoria aggiuntiva. Il membro cbWndExtra della struttura WNDCLASSEX specifica la quantità di memoria di finestra aggiuntiva da allocare. Un'applicazione che non usa la memoria deve inizializzare cbWndExtra su zero.