2009-02-24 7 views
21

I componenti Delphi hanno CreateWnd e CreateWindowHandle (e DestroyWnd e DestroyWindowHandle). Entrambi sono destinati ad essere ignorati dai discendenti, giusto? E non è destinato ad essere chiamato tranne dall'implementazione VCL sottostante?Qual è la differenza tra CreateWnd e CreateWindowHandle?

Qual è la differenza tra loro; quando uno di essi deve essere sovrascritto?

risposta

36

Finora la maggior parte delle risposte qui sono più o meno nel segno e faresti bene a prestare attenzione ai loro consigli. Tuttavia, c'è un po 'di più in questa storia. Alla tua domanda specifica su quando avresti scavalcato l'uno o l'altro, cercherò un po 'di cose in poche parole.

CreateParams();

In generale, la maggior parte delle volte tutto ciò che devi fare è sovrascrivere CreateParams(). Se tutto ciò che si vuole fare è sottoclasse (ricorda lo stile Windows "sottoclassi?" Vedi il lavoro seminale di Petzold sulla programmazione Windows) una classe di controllo esistente e avvolgila in un controllo VCL, lo fai da CreateParams. È inoltre possibile controllare quali bit di stile sono impostati e altri vari parametri. Abbiamo reso molto facile il processo di creazione di una "sottoclasse". Basta chiamare CreateSubClass() dal metodo CreateParams(). Vedere i controlli principali VCL per un esempio come TCheckBox o TButton.

CreateWnd();

Si potrebbe ignorare questo uno se avete bisogno di fare un po 'di più con l'handle della finestra una volta che è stato creato. Ad esempio, se hai un controllo che è una sorta di elenco, albero o altro richiede la configurazione post-creazione, lo faresti qui. Chiama il CreateWnd ereditato e quando ritorna (sai che hai un handle valido se ritorni da CreateWnd perché genererà un'eccezione se qualcosa è andato storto), applica semplicemente la tua magia extra. Uno scenario comune consiste nel prendere i dati memorizzati nella cache in un elenco TStrings di istanza e spostarli effettivamente nel controllo della finestra sottostante. TListBox è un classico esempio di questo.

CreateWindowHandle();

Ho dovuto rinfrescare la memoria su questo, ma sembra che questo sia raramente, se non mai, sovrascritto. Nei pochi casi all'interno di VCL, sembra che sia usato per aggirare specifiche versioni di Windows e le stranezze locali con alcuni controlli, come TEdit e TMemo. L'altro caso più chiaro è in TCustomForm stesso. In questo caso è lì per supportare il vecchio modello MDI (interfaccia multi-documento). In questo caso i bambini MDI non possono essere creati utilizzando la normale API CreateWindowEx(), è necessario inviare un messaggio al frame padre MDI per creare effettivamente l'handle. Quindi l'unico motivo per sovrascrivere questo metodo è se l'effettivo processo di creazione dell'handle viene eseguito tramite un mezzo completamente diverso dal vecchio provato e vero CreateWindowEx().

Ho notato che la tua domanda stava semplicemente chiedendo del processo di creazione, ma ci sono metodi corrispondenti che sono sovrascritti in alcuni casi sia per la distruzione dell'handle sia per il "voodoo" che a volte circonda la ricreazione. Ma questi sono altri argomenti che dovrebbero essere trattati separatamente :-).

+0

Ottima risposta. Volevo solo aggiungere una bella risorsa web per completare la risposta dato che la domanda originale menziona il VCL: http://edn.embarcadero.com/article/20569 – Ampere

4

CreateWnd prima chiama CreateParams, quindi chiama CreateWindowHandle utilizzando i Params creati. Generalmente, sostituirai CreateWnd e CreateParams anziché CreateWindowHandle.

Spero che questo aiuti!

0

Sono sicuro che la risposta finale può venire solo dalle persone coinvolte nella creazione del VCL (Allen?), Ma IMHO il metodo virtuale con la minima responsabilità/che è il più basso nella catena di chiamate dovrebbe essere ignorato. È per questo che ho sempre sovrascritto CreateParams() e CreateWindowHandle(). Questo sembra un buon adattamento poiché entrambi sono chiamati da CreateWnd(), ed entrambi fanno solo una cosa speciale.

Alla fine è probabilmente una questione di preferenza.

2

Chi fa cosa:
CreateWnd è il general contractor che crea la finestra completamente formato per un WinControl.
Prima di tutto, deve impostare gli attributi richiesti per WindowClass chiamando CreateParams e assicurandosi che sia registrato correttamente.
Quindi viene effettivamente creata la finestra, chiamando CreateWindowHandle che restituisce l'handle risultante dal sistema operativo.
Dopo di che, abbiamo una finestra valida in grado di elaborare i messaggi, e CreateWnd non la toelettatura finale, regolando diversi aspetti visivi come la dimensione, font, ecc

C'è anche dopo scatto, fatto da CreateHandle, dopo che CreateWnd è finito, per aiutare il VCL nella gestione delle sue finestre (identificazione, parentela, ...).