Informazioni sulle procedure finestra

Ogni finestra è un membro di una determinata classe di finestra. La classe window determina la routine di finestra predefinita usata da una singola finestra per elaborare i messaggi. Tutte le finestre appartenenti alla stessa classe usano la stessa routine di finestra predefinita. Ad esempio, il sistema definisce una routine finestra per la classe casella combinata (COMBOBOX). Tutte le caselle combinate quindi usano tale routine finestra.

Un'applicazione registra in genere almeno una nuova classe finestra e la relativa routine finestra associata. Dopo la registrazione di una classe, l'applicazione può creare molte finestre di tale classe, che usano tutte la stessa routine della finestra. Poiché ciò significa che più origini possono chiamare contemporaneamente lo stesso frammento di codice, è necessario prestare attenzione quando si modificano le risorse condivise da una routine finestra. Per altre informazioni, vedere Classi di finestre.

Le procedure di finestra per le finestre di dialogo ,denominate routine della finestra di dialogo, hanno una struttura e una funzione simili a quella delle normali routine della finestra. Tutti i punti che fanno riferimento alle procedure della finestra in questa sezione si applicano anche alle procedure della finestra di dialogo. Per altre informazioni, vedere Finestre di dialogo.

In questa sezione vengono illustrati gli argomenti seguenti.

Struttura di una routine finestra

Una routine finestra è una funzione con quattro parametri e restituisce un valore con segno. I parametri sono costituiti da un handle di finestra, un identificatore di messaggio UINT e due parametri del messaggio dichiarati con i tipi di dati WPARAM e LPARAM . Per altre informazioni, vedere WindowProc.

I parametri del messaggio contengono spesso informazioni nelle parole di ordine basso e in ordine elevato. Esistono diverse macro che un'applicazione può usare per estrarre informazioni dai parametri del messaggio. La macro LOWORD , ad esempio, estrae la parola con ordine basso (bit da 0 a 15) da un parametro di messaggio. Altre macro includono HIWORD, LOBYTE e macro HIBYTE.

L'interpretazione del valore restituito dipende dal messaggio specifico. Consultare la descrizione di ogni messaggio per determinare il valore restituito appropriato.

Poiché è possibile chiamare una routine finestra in modo ricorsivo, è importante ridurre al minimo il numero di variabili locali usate. Quando si elaborano singoli messaggi, un'applicazione deve chiamare funzioni esterne alla routine della finestra per evitare un uso eccessivo di variabili locali, causando un overflow dello stack durante la ricorsione profonda.

Routine finestra predefinita

La funzione di routine della finestra predefinita DefWindowProc definisce determinati comportamenti fondamentali condivisi da tutte le finestre. La procedura predefinita della finestra fornisce la funzionalità minima per una finestra. Una routine della finestra definita dall'applicazione deve passare tutti i messaggi che non elabora alla funzione DefWindowProc per l'elaborazione predefinita.

Sottoclasse della routine window

Quando un'applicazione crea una finestra, il sistema alloca un blocco di memoria per l'archiviazione di informazioni specifiche della finestra, incluso l'indirizzo della routine finestra che elabora i messaggi per la finestra. Quando il sistema deve passare un messaggio alla finestra, cerca nelle informazioni specifiche della finestra l'indirizzo della routine della finestra e passa il messaggio a tale routine.

La sottoclasse è una tecnica che consente a un'applicazione di intercettare ed elaborare i messaggi inviati o inviati a una determinata finestra prima che la finestra abbia la possibilità di elaborarli. Sottoclassando una finestra, un'applicazione può aumentare, modificare o monitorare il comportamento della finestra. Un'applicazione può sottoclassare una finestra appartenente a una classe globale di sistema, ad esempio un controllo di modifica o una casella di riepilogo. Ad esempio, un'applicazione potrebbe sottoclassare un controllo di modifica per impedire al controllo di accettare determinati caratteri. Tuttavia, non è possibile sottoclassare una finestra o una classe appartenente a un'altra applicazione. Tutte le sottoclassi devono essere eseguite nello stesso processo.

Un'applicazione sottoclassa una finestra sostituendo l'indirizzo della routine della finestra originale della finestra con l'indirizzo di una nuova routine finestra, denominata routine della sottoclasse. Successivamente, la routine della sottoclasse riceve tutti i messaggi inviati o inviati alla finestra.

La routine della sottoclasse può eseguire tre azioni alla ricezione di un messaggio: può passare il messaggio alla routine della finestra originale, modificare il messaggio e passarlo alla routine della finestra originale oppure elaborare il messaggio e non passarlo alla routine della finestra originale. Se la routine della sottoclasse elabora un messaggio, può farlo prima, dopo o entrambi prima e dopo aver passato il messaggio alla routine della finestra originale.

Il sistema fornisce due tipi di sottoclasse: istanza e globale. Nella sottoclasse dell'istanza, un'applicazione sostituisce l'indirizzo della routine della finestra di una singola istanza di una finestra. Un'applicazione deve usare la sottoclasse dell'istanza per sottoclassare una finestra esistente. Nella sottoclasse globale, un'applicazione sostituisce l'indirizzo della routine della finestra nella struttura WNDCLAS edizione Standard X di una classe finestra. Tutte le finestre successive create con la classe hanno l'indirizzo della routine della sottoclasse, ma le finestre esistenti della classe non sono interessate.

Sottoclasse dell'istanza

Un'applicazione sottoclassa un'istanza di una finestra usando la funzione SetWindowLongPtr. L'applicazione passa il flag GWL_WNDPROC , l'handle alla finestra alla sottoclasse e l'indirizzo della routine della sottoclasse a SetWindowLongPtr. La routine della sottoclasse può risiedere nel file eseguibile dell'applicazione o in una DLL.

Quando viene passato il flag di GWL_WNDPROC , SetWindowLongPtr restituisce l'indirizzo della routine della finestra originale della finestra. L'applicazione deve salvare questo indirizzo, usandolo nelle chiamate successive alla funzione CallWindowProc , per passare messaggi intercettati alla routine della finestra originale. L'applicazione deve inoltre avere l'indirizzo della routine della finestra originale per rimuovere la sottoclasse dalla finestra. Per rimuovere la sottoclasse, l'applicazione chiama nuovamente SetWindowLongPtr , passando l'indirizzo della routine della finestra originale con il flag GWL_WNDPROC e l'handle alla finestra.

Il sistema possiede le classi globali di sistema e gli aspetti dei controlli possono cambiare da una versione del sistema a quella successiva. Se l'applicazione deve sottoclassare una finestra appartenente a una classe globale di sistema, lo sviluppatore potrebbe dover aggiornare l'applicazione quando viene rilasciata una nuova versione del sistema.

Poiché la sottoclasse dell'istanza si verifica dopo la creazione di una finestra, non è possibile aggiungere altri byte alla finestra. Le applicazioni che sottoclassino una finestra devono usare l'elenco delle proprietà della finestra per archiviare i dati necessari per un'istanza della finestra sottoclassata. Per altre informazioni, vedere Proprietà della finestra.

Quando un'applicazione sottoclassa una finestra sottoclassata, deve rimuovere le sottoclassi nell'ordine inverso in cui sono state eseguite. Se l'ordine di rimozione non viene invertito, potrebbe verificarsi un errore di sistema irreversibile.

Sottoclasse globale

Per sottoclasse globale una classe di finestra, l'applicazione deve avere un handle per una finestra della classe . L'applicazione richiede anche l'handle per rimuovere la sottoclasse. Per ottenere l'handle, un'applicazione crea in genere una finestra nascosta della classe da sottoclassare. Dopo aver ottenuto l'handle, l'applicazione chiama la funzione SetClassLongPtr, specificando l'handle, il flag GCL_WNDPROC e l'indirizzo della routine della sottoclasse. SetClassLongPtr restituisce l'indirizzo della routine della finestra originale per la classe .

L'indirizzo della routine della finestra originale viene usato nella sottoclasse globale nello stesso modo in cui viene usato nella sottoclasse dell'istanza. La routine della sottoclasse passa messaggi alla routine della finestra originale chiamando CallWindowProc. L'applicazione rimuove la sottoclasse dalla classe window chiamando di nuovo SetClassLongPtr, specificando l'indirizzo della routine della finestra originale, il flag GCL_WNDPROC e l'handle in una finestra della classe sottoclassata. Un'applicazione che sottoclassa globalmente una classe di controllo deve rimuovere la sottoclasse al termine dell'applicazione; in caso contrario, può verificarsi un errore di sistema irreversibile.

La sottoclasse globale presenta le stesse limitazioni della sottoclasse dell'istanza, oltre ad alcune restrizioni aggiuntive. Un'applicazione non deve usare i byte aggiuntivi per la classe o l'istanza della finestra senza sapere esattamente come viene utilizzata la routine della finestra originale. Se l'applicazione deve associare i dati a una finestra, deve usare le proprietà della finestra.

Superclassamento routine finestra

La superclassamento è una tecnica che consente a un'applicazione di creare una nuova classe finestra con la funzionalità di base della classe esistente, oltre ai miglioramenti forniti dall'applicazione. Una superclasse si basa su una classe finestra esistente denominata classe base. Spesso, la classe base è una classe finestra globale di sistema, ad esempio un controllo di modifica, ma può essere qualsiasi classe di finestra.

Una superclasse ha una propria routine finestra, denominata procedura superclasse. La procedura superclasse può eseguire tre azioni alla ricezione di un messaggio: può passare il messaggio alla routine della finestra originale, modificare il messaggio e passarlo alla routine della finestra originale oppure elaborare il messaggio e non passarlo alla routine della finestra originale. Se la routine superclasse elabora un messaggio, può farlo prima, dopo o dopo e dopo che passa il messaggio alla routine della finestra originale.

A differenza di una routine di sottoclasse, una routine superclasse può elaborare i messaggi di creazione della finestra (WM_NCCREATE, WM_CREATE e così via), ma deve anche passarli alla routine della finestra della classe base originale in modo che la routine della finestra della classe base possa eseguire la procedura di inizializzazione.

Per sovraclassare una classe window, un'applicazione chiama innanzitutto la funzione GetClassInfoEx per recuperare informazioni sulla classe base. GetClassInfoEx riempie una struttura WNDCLAS edizione Standard X con i valori della struttura WNDCLAS edizione Standard X della classe di base. Successivamente, l'applicazione copia il proprio handle di istanza nel membro hInstance della struttura WNDCLAS edizione Standard X e copia il nome della superclasse nel membro lpszClassName. Se la classe base ha un menu, l'applicazione deve fornire un nuovo menu con gli stessi identificatori di menu e copiare il nome del menu nel membro lpszMenuName . Se la routine superclasse elabora il messaggio WM_COMMAND e non la passa alla routine della finestra della classe base, il menu non deve avere identificatori corrispondenti. GetClassInfoEx non restituisce il membro lpszMenuName, lpszClassName o hInstance della struttura WNDCLAS edizione Standard X.

Un'applicazione deve anche impostare il membro lpfnWndProc della struttura WNDCLAS edizione Standard X. La funzione GetClassInfoEx riempie questo membro con l'indirizzo della routine della finestra originale per la classe . L'applicazione deve salvare questo indirizzo, per passare messaggi alla routine della finestra originale e quindi copiare l'indirizzo della routine superclasse nel membro lpfnWndProc . L'applicazione può, se necessario, modificare qualsiasi altro membro della struttura WNDCLAS edizione Standard X. Dopo aver riempito la struttura WNDCLAS edizione Standard X, l'applicazione registra la superclasse passando l'indirizzo della struttura alla funzione RegisterClassEx. La superclasse può quindi essere usata per creare finestre.

Poiché la superclasse registra una nuova classe di finestra, un'applicazione può aggiungere sia ai byte di classe aggiuntivi che ai byte di finestra aggiuntivi. La superclasse non deve utilizzare i byte aggiuntivi originali per la classe base o la finestra per gli stessi motivi per cui una sottoclasse di istanza o una sottoclasse globale non deve usarli. Inoltre, se l'applicazione aggiunge byte aggiuntivi per il relativo utilizzo alla classe o all'istanza della finestra, deve fare riferimento ai byte aggiuntivi relativi al numero di byte aggiuntivi utilizzati dalla classe di base originale. Poiché il numero di byte utilizzati dalla classe base può variare da una versione della classe di base alla successiva, l'offset iniziale per i propri byte aggiuntivi della superclasse può variare anche da una versione della classe base alla successiva.