2009-04-16 9 views
5

Ogni volta che si aggiunge una nuova unità al progetto, Delphi ricostruisce il file .dpr e tutti gli IFDEF nella sezione usi sono scomparsi.Come si gestiscono gli IFDEF in .dpr utilizza la sezione

Per ovviare a ciò, in genere utilizzo NotePad per creare nuovi file .pas e aggiungerlo manualmente a .dpr. Se ho bisogno di un modulo, utilizzo File-> Nuovo-> Modulo e quindi ripristino il file .dpr alla versione precedente. Non molto RAD se me lo chiedi ;-)

Come ci si confronta? C'è un modo per aggiungere un'unità nell'IDE mantenendo le IFDEF?

+0

Potreste spiegare il motivo per cui si desidera solo _sometimes_ un'unità di essere un membro del vostro progetto? Non capisco lo scopo. –

+4

Nel nostro progetto utilizziamo il FastMM fornito con Delphi per le build di rilascio, ma il FastMM4.pas esterno per le build di debug. Quindi abbiamo un IFDEF intorno "usa FastMM4;" –

+0

@ Url: utilizzo FastMM4 sia per build DEBUG che RELEASE - perché no? Fa parte del repository SVN del progetto e ottengo lo stesso ambiente indipendentemente dalla versione del compilatore. Cosa non va? – mghie

risposta

2

È possibile aggiungerlo manualmente dall'interno dell'IDE. (Usa l'opzione "visualizza sorgente" sul progetto).

Normalmente il dpr è "nascosto". Non ci si aspetta che cambi nulla lì dentro. E se lo fai, è meglio assicurarsi che tutte le modifiche siano manuali altrimenti perdi alcune informazioni.

9

A volte creo un'unità in modo specifico come luogo per tutti gli IFDEF e altre cose che l'IDE potrebbe rovinare se fosse nel dpr. Questa unità generalmente va in cima alla clausola degli usi di dpr. Questo trucco non soddisfa tutti gli scenari, ma a volte consente di risparmiare un sacco di lavoro noioso.

+0

+1. Non ricordo di aver mai usato l'inclusione condizionale delle unità. Perché uno vorrebbe farlo? – mghie

+1

@mghie: portabilità tra versioni del compilatore e RTL. Portabilità tra compilatori (Delphi vs C++ Builder.) Evitando l'inclusione di unità a seconda della configurazione di build (ad esempio, potresti non volere il supporto per il dump dello stack in una build di rilascio poiché non ci sono simboli di debug.) E un centinaio di altri scenari. –

+0

prima di tutto ciò non comporterebbe la partecipazione delle unità condizionatamente incluse nel progetto (e quindi accessibile tramite il Project Manager) –

3

Ho passato un po 'di tempo cercando di lavorare che uno fuori,

ho finito per avere un file di progetto (.dpr) per ogni tipo di costruzione, con le condizioni in Progetto | Opzioni progetto | Directories/condizionali e solo le unità volevo aggiunto nel al progetto

questa dose hanno il lato verso il basso che, se si dispone di codice personalizzato nel .dpr, dovrà essere copiati manualmente agli altri file di progetto quando cambia.

come notato da Rob Kennedy, questo può essere gestito inserendo il codice personalizzato nella propria unità, che viene chiamata con un'unica procedura. riducendo così al minimo la dimensione del codice .dpr/modifiche da apportare

Inoltre, un altro bonus si ottiene è che se si aggiungono tutti i file .dpr ad un gruppo di progetto, è possibile costruire tutti vostre diverse versioni con un clic/linea cmd

+1

La maggior parte del codice DPR può essere ridotto al minimo spostandolo su un'unità diversa e quindi con una sola linea che lo chiama. In questo modo, è meno probabile che il codice DPR abbia bisogno di cambiare. –

+0

grazie per quello, ho aggiornato la mia risposta e sono libero di aggiornare il mio codice;) –

3

Non inserisco alcun ifdef in un file dpr. Se voglio usare diverse unità/moduli in un progetto, a seconda di alcune condizioni, ho diviso il progetto in due.

0

(Delphi 7)

Ho appena provato lo stesso. Date un'occhiata alla prima versione del codice e ai miei commenti qui sotto:

program Project1; 

{$IFDEF TESTIFDEF} 
uses 
    Forms, 
    Unit1 in 'Unit1.pas' {Form1}, 
    Unit2 in 'Unit2.pas' {Form2}; 

{$ELSE} 
uses 
    Forms, 
    Unit1 in 'Unit1.pas' {Form1}; 
{$ENDIF TESTIFDEF} 

{$R *.res} 

begin 
    Application.Initialize; 
    Application.CreateForm(TForm1, Form1); 
    Application.CreateForm(TForm2, Form2); 
    Application.Run; 
end. 

A quel punto, ho appena inserito il 2 ° modulo e ho notato che la relativa unità (Unit2.pas) è stato inserito all'interno del primo parte dell'IFDEF, cioè all'interno della parte etichettata "TESTIFDEF", quindi non sovrascrivere il secondo blocco (dopo {$ ELSE}).

Così la soluzione dovrebbe essere:

  1. definiscono una dichiarazione IFDEF come "{$ IFDEF DELPHIBASISCONFIGURATION}" in luogo del mio "{$ IFDEF TESTIFDEF}" appena verranno tutte le forme.
  2. definire tante ETICHETTE alternative per le diverse configurazioni con cui si desidera lavorare.
  3. ogni volta che hai aggiunto un modulo al progetto, copia la riga inserita del primo blocco nei blocchi corrispondenti sotto - a seconda delle tue esigenze ...
  4. attiva la configurazione richiesta usando l'istruzione define o l'opzione dialogo
  5. MAI Definire "DELPHIBASISCONFIGURATION";)

Quindi, dovrebbe assomigliare a questa:

program Project1; 

{$DEFINE MYCONFIG1} // THIS ONE IS NOW ACTIVE 


{$IFDEF DELPHIBASISCONFIGURATION} 
uses 
    Forms, 
    Unit1 in 'Unit1.pas' {Form1}, 
    Unit2 in 'Unit2.pas' {Form2}, 
    Unit3 in 'Unit3.pas' {Form3}; 

{$ELSE} 
    // THIS IS A "COMMON TO ALL CONFIG" PART 
    uses 
     Forms, 

     // FIRST CONFIGURATION 
     {$IFDEF MYCONFIG1} 
     Unit1 in 'Unit1.pas' {Form1}, 
     Unit3 in 'Unit3.pas' {Form3} 
     {$ENDIF MYCONFIG1} 

     // SECOND CONFIGURATION  
     {$IFDEF MYCONFIG2} 
     Unit1 in 'Unit1.pas' {Form1}, 
     Unit2 in 'Unit2.pas' {Form2} 
     {$ENDIF MYCONFIG2} 

    // THIS IS THE "COMMON TO ALL CONFIG" END :) 
    ; 

{$ENDIF TESTIFDEF} 

{$R *.res} 

begin 
    Application.Initialize; 
    Application.CreateForm(TForm1, Form1); 
    //Application.CreateForm(TForm3, Form3); 
    //Application.CreateForm(TForm2, Form2); 
    Application.Run; 
end. 

come potete vedere, ho scartato le chiamate a Appli cation.CreateForm (...) per Form2 e Form3.

IMHO, di solito è meglio per creare dinamicamente i moduli supplementari al momento in cui si ha realmente bisogno di loro cioè non tutte le forme all'avvio del programma ...

+1

Questa è un'idea molto intelligente. Sfortunatamente non funziona con D2007, che a quanto pare capisce la definizione e modifica la sezione 'reale' :-( – Giel

1

Per le forme, datamodules, e le altre unità che contengono un classe singola con cui verrà sostituita la funzione, la soluzione è piuttosto semplice. Basta NON aggiungere le unità personalizzate direttamente al prodotto, ma salvale in qualche posto nel percorso di ricerca (o modifica il percorso di ricerca del progetto per includere la loro posizione).

1) Creare un'unità NUOVA, che contiene il genitore per tutte le altre classi o le interfacce che tutti implementeranno (generalmente preferisco la versione successiva in quanto consente una più facile personalizzazione) [ad esempio, questo è chiamato uSpecialParent.pas]

2) Aggiungere una variabile di classe a cui verrà fatto riferimento quando è necessario creare la nuova funzionalità. per esempio se si stesse andando a mostrare modale un gruppo di forme, quindi non si preoccupano eventuali altri metodi, allora si potrebbe avere una variabile che sembrava il seguente:

TYPE 
    TMySpecialFormClass : class of TForm; 

VAR 
    TMySpecialForm : TMySpecialFormClass; 

3) Creare un'altra unità che sarà contiene tutti gli IFDEFS. Potrebbe essere simile a quanto segue:

Unit uRegisterSpecialForms; 

interface 

uses 
{$IFDF SPECIAL1} 
    uSpecial1, 
{$ENDIF} 
{$IFDEF SPECIAL2} 
    uSpecial2, 
{$ENDIF} 
    uSpecialParent; 

implementation 

// no code needed. 

initialization 

{$IFDEF SPECIAL1} 
    TMySpecialForm := uSpecial1.TSpecialForm1; 
{$ENDIF} 
{$IFDEF SPECIAL2} 
    TMySpecialForm := uSpecial2.TSPecialForm2; 
{$ENDIF} 

end. 

4) Per fare riferimento a questo nel codice è necessario solo l'uSpecialParent aggiunto al gruppo che sarà richiede una forma speciale e quindi creare in modo dinamico, ad esempio per mostrare questo modale si potrebbe richiamare il seguente:

var 
    frm : TForm; 
begin 
    frm := TMySpecialForm.Create(nil); 
    try 
    frm.showmodal; 
    finally 
    frm.free; 
    end; 
end; 
1

Ed ecco l'approccio lo-Tech per completezza amor:

Dopo l'IDE ha incasinato la tua clausola uses ancora:

  1. chiudere il progetto
  2. andare al tuo strumento di controllo versione di scelta e diff DPR contro l'ultimo check-in versione utilizzando uno strumento diff merge-enabled come WinMerge
  3. ripristinare l'IDE cambia
  4. Salva DPR
  5. andare avanti con lui
Problemi correlati