Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Ogni classe finestra ha una routine finestra associata condivisa da tutte le finestre della stessa classe. La routine finestra 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 della 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 di finestre:
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 window 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 thread chiama una funzione GDI (User o Windows Graphics Device Interface).
Ogni applicazione riceve una propria copia delle classi di sistema. Tutte le applicazioni basate su Windows a 16 bit nello stesso VDM condividono le classi di sistema, proprio come accade 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 del pulsante. |
ComboBox | Classe per una casella combinata. |
Redigere | Classe per un controllo di modifica. |
Casella di elenco | Classe per una casella di riepilogo. |
MDIClient | Classe per una finestra client MDI. |
barra di scorrimento | Classe per una barra di scorrimento. |
Statico | 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 l'elenco contenuto in una casella combinata. |
DDEMLEvent | Classe per gli eventi DDEML (Dynamic Data Exchange Management Library). |
Messaggio | Classe per una finestra di soli messaggi. |
#32768 | Classe per un menu. |
#32769 | Classe per la finestra del desktop. |
#32770 | Classe per una finestra di dialogo. |
#32771 | Classe per la finestra di commutazione delle 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 window 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 window in un .dll e caricare il .dll in ogni processo. Per caricare il .dll in ogni processo, aggiungere il suo nome al valore AppInit_DLLs nella chiave del Registro di sistema seguente:
\ HKEY_LOCAL_MACHINESoftware\Microsoft\Windows NT\CurrentVersion\Windows
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 CS_GLOBALCLASS . Per altre informazioni, vedere Stili di classe.
Per rimuovere una classe globale dell'applicazione e liberare lo spazio di archiviazione associato, usare la funzione UnregisterClass .
Classi locali dell'applicazione
Una classe locale dell'applicazione è qualsiasi classe di finestra registrata da un eseguibile o .dll per l'uso esclusivo. Sebbene sia possibile registrare un numero qualsiasi di classi locali, è tipico registrare solo una classe. Questa classe di finestra supporta la procedura 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 l'archiviazione associata.
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 dell'istanza del modulo. Diversi moduli possono usare lo stesso nome per registrare le classi locali nello stesso processo.
- Se il nome non è presente nell'elenco delle classi locali dell'applicazione, cercare nell'elenco delle classi globali dell'applicazione.
- Se il nome non è presente nell'elenco di classi globali dell'applicazione, cercare nell'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. Questa operazione 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 Window
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 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 finestre.
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 di CS_GLOBALCLASS .
Se si registra la classe window 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.
L'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 .dll.
La classe non viene eliminata definitivamente quando il .dll proprietario viene scaricato. Pertanto, se il sistema chiama la routine della finestra per una finestra di tale classe, causerà una violazione di accesso, perché il .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 window definiscono il comportamento predefinito delle finestre appartenenti alla classe . L'applicazione che registra una classe window assegna elementi alla classe impostando i 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 finestra completa è costituita da molti elementi, il sistema richiede solo che un'applicazione fornisca un nome di classe, l'indirizzo della routine finestra e un handle di istanza. Utilizzare 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 finestra sono come illustrato nella tabella seguente.
Elemento | Scopo |
---|---|
Nome classe | Distingue la classe da altre classi registrate. |
Indirizzo della procedura finestra | Puntatore alla funzione che elabora tutti i messaggi inviati alle finestre nella classe e definisce il comportamento della finestra. |
Handle dell'istanza | Identifica l'applicazione o .dll che ha effettuato la registrazione della classe. |
Classe cursore | Definisce il cursore del mouse visualizzato dal sistema per una finestra della classe . |
icone delle classi | Definisce l'icona grande e l'icona piccola. |
Pennello di Sfondo della Classe | Definisce il colore e il motivo che riempiono l'area client quando la finestra viene aperta o dipinta. |
Menu della Classe | Specifica il menu predefinito per le finestre che non definiscono in modo esplicito un menu. |
Stili di classe | Definisce come aggiornare la finestra dopo lo spostamento o il ridimensionamento, come elaborare i doppio clic del mouse, come allocare spazio per il contesto di dispositivo e altri aspetti della finestra. |
Memoria di classe aggiuntiva | Specifica la quantità di memoria aggiuntiva, espressa 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 la 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 la memoria su zero. |
Nome della classe
Ogni classe della 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 finestre 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 dei nomi della classe il più breve possibile.
La funzione GetClassName recupera il nome della classe a cui appartiene una determinata finestra.
Indirizzo Procedura Finestra
Ogni classe richiede un indirizzo di routine finestra per definire il punto di ingresso della routine finestra utilizzata 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 finestra a una classe copiandone l'indirizzo nel membro lpfnWndProc della struttura WNDCLASSEX . Per altre informazioni, vedere Routine della finestra.
Handle dell'istanza
Ogni classe 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 attivo 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 l'handle di istanza alla classe copiandolo nel membro hInstance della struttura WNDCLASSEX.
Classe Cursore
Il cursore di 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 mantenga tale forma mentre rimane 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 di cursore restituito al membro hCursor della struttura WNDCLASSEX . In alternativa, fornire 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 imposti 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 classi
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 la grande icona di classe di una finestra nella finestra di cambio attività visualizzata quando l'utente preme ALT+TAB e nelle visualizzazioni a grandi icone della barra delle applicazioni e di Esplora risorse. L'icona della classe piccola viene visualizzata nella barra del titolo di una finestra e nelle piccole visualizzazioni icona della barra delle applicazioni e della finestra di esplorazione.
Per assegnare un'icona grande e un'icona piccola a una classe finestra, specificate gli handle delle icone nei membri hIcon e hIconSm della struttura WNDCLASSEX. Le dimensioni dell'icona devono essere conformi alle dimensioni necessarie per le icone di classi grandi e piccole. Per un'icona di classe di grandi dimensioni, è possibile determinare le dimensioni necessarie specificando i valori SM_CXICON e SM_CYICON in una chiamata alla funzione GetSystemMetrics . Per un'icona di classe di piccole dimensioni, specificare i valori 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 classi grandi e piccole per la classe window. 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 di grandi dimensioni, il sistema usa l'icona dell'applicazione predefinita come icona di classe grande e l'icona specificata come icona di classe piccola.
È possibile eseguire l'override dell'icona della classe grande o piccola per una determinata finestra usando il messaggio WM_SETICON . È possibile recuperare l'icona corrente della classe grande o piccola usando il messaggio WM_GETICON .
Pennello per sfondo di classe
Un pennello di sfondo della classe prepara l'area client di una finestra per il disegno successivo da parte dell'applicazione. Il sistema usa il pennello per riempire l'area client con un colore a tinta unita o un motivo, 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 disegnato inviando il messaggio di WM_ERASEBKGND alla finestra. Per altre informazioni, vedere Pennelli.
Per assegnare un pennello di sfondo a una classe, crea un pennello utilizzando le funzioni GDI appropriate e assegna l'handle del 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 dei colori di sistema standard, vedere SetSysColors.
Per usare un colore di sistema standard, l'applicazione deve aumentare di uno il valore del colore di sfondo. Ad esempio, COLOR_BACKGROUND + 1 è il colore di sfondo del sistema. In alternativa, è possibile usare la funzione GetSysColorBrush per recuperare un handle per 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 della classe. Se questo parametro è impostato su NULL, la finestra deve disegnare il proprio sfondo ogni volta che riceve il messaggio di WM_ERASEBKGND .
Classe Menu
Un menu classe definisce il menu predefinito da utilizzare nelle 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 le azioni da eseguire per l'applicazione.
È possibile assegnare un menu a una classe impostando il membro lpszMenuName della struttura WNDCLASSEX sull'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 di menu è 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 di 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 per una classe è specificato un menu e viene creata una finestra figlio di quella classe, il menu viene ignorato. Per altre informazioni, vedere Menu.
Stili di classe
Gli stili della classe definiscono elementi aggiuntivi della classe window. È 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 degli stili di classe, vedere Stili classe finestra.
Classi e contesti dei dispositivi
Un contesto di dispositivo è un set speciale di valori che le applicazioni usano per disegnare nell'area client delle finestre. Il sistema richiede un contesto di dispositivo per ogni finestra sullo schermo, ma consente una certa flessibilità nel modo in cui il sistema archivia e gestisce il contesto del dispositivo.
Se non viene specificato in modo esplicito uno stile di contesto del dispositivo, il sistema presuppone che ogni finestra usi un contesto di 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 di dispositivo ogni volta che deve disegnare all'interno di una finestra, un'applicazione può specificare lo stile CS_OWNDC per la classe window. Questo stile di classe indirizza il sistema a creare un contesto di dispositivo privato, ovvero allocare un contesto di dispositivo univoco per ogni finestra della classe. L'applicazione deve recuperare il contesto una sola volta e usarlo per tutti i dipinti successivi.
Memoria di classe aggiuntiva
Il sistema gestisce una struttura WNDCLASSEX internamente per ogni classe finestra nel sistema. Quando un'applicazione registra una classe window, può indirizzare il sistema ad allocare e accodare un numero di byte aggiuntivi di memoria alla fine della struttura WNDCLASSEX . Questa memoria è denominata 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 con moderazione la memoria di classe aggiuntiva. La funzione RegisterClassEx ha esito negativo se la quantità di memoria della classe aggiuntiva richiesta è maggiore di 40 byte. Se un'applicazione richiede più di 40 byte, deve allocare la propria memoria e memorizzare un puntatore alla memoria nella memoria della classe aggiuntiva.
Le funzioni SetClassWord e SetClassLong copiano un valore nella memoria della classe aggiuntiva. Per recuperare un valore dalla memoria della classe aggiuntiva, usare le funzioni GetClassWord e GetClassLong . Il membro cbClsExtra della struttura WNDCLASSEX specifica la quantità di memoria della 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 aggiuntiva della finestra. Quando si crea una finestra della classe, il sistema alloca e aggiunge la quantità specificata di memoria aggiuntiva della finestra 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 dovrebbe utilizzare con parsimonia la memoria extra della finestra. La funzione RegisterClassEx ha esito negativo se la quantità di memoria aggiuntiva della finestra 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 aggiuntiva della finestra da allocare. Un'applicazione che non usa la memoria deve inizializzare cbWndExtra su zero.