Merhaba Arkadaşlar,
Bir kütüphanem var fakat bu kütüphanedeki kodlar piyasadaki bazı ticari bileşenlerin kurulu olup olmadığına bağlı olarak bazı kod bloklarını kapatıp açmamı gerektiriyor.
Sorunum şu;
Bir X bileşeninin kurulu olup olmadığını {$IFDEF} direktifleriyle nasıl anlarım?
ifdef ve component kurulmuş mu nasıl anlaşılır
Forum kuralları
Forum kurallarını okuyup, uyunuz!
Forum kurallarını okuyup, uyunuz!
Re: ifdef ve component kurulmuş mu nasıl anlaşılır
Şöyle bir üç kağıt uygulayabilirsin ama USES kısmına koyup koymadığını anlarsın. Kurulu olup olmadığını USES'a koyduğun halde görürse zaten Compile ederken hata alırsın. Hata vermeyek hali de mümkün ama pratik faydasını bilemedim, aşağıdaki ikinci kod bloğu USES'da varsa çalışır, yoksa çalışmaz..
Kod yazarken aslında sınırlarımızı biliriz ve bu şekilde çalışmamasını istediğimiz kodu zaten yazmayız ama konuyu anlamadığım için detay açıklama yaparsan şahsen cevaba ilişkin daha da rahatlarım.
Tam olarak pratikte yapmak istediğin ne ise onu biraz daha açar mısın ? Zaten bu bileşen kurulu değilse USES'da da yoksa hata alırsın. Nasıl bir bileşen için bu kontrol gerekli ?
Bahsettiğim olayı şöyle IdHttp ile örneklemek istersem :
Örnekte :USES satırındaki IdHttp'yi kaldırırsan FALSE döner, IdHttp'yi USES'a eklersen TRUE...
// Kod içerisinde nasıl kullanırsın..??
- Şöyle ki aşağıdaki kodu kullanırken bir USES'daki IdHttp'yi silip dene, bir de USES'da IdHttp varken..
- USES'da var olduğu zaman çalışacak, yoksa çalışmayacak. Hata da vermeyecek.
Kod yazarken aslında sınırlarımızı biliriz ve bu şekilde çalışmamasını istediğimiz kodu zaten yazmayız ama konuyu anlamadığım için detay açıklama yaparsan şahsen cevaba ilişkin daha da rahatlarım.

Tam olarak pratikte yapmak istediğin ne ise onu biraz daha açar mısın ? Zaten bu bileşen kurulu değilse USES'da da yoksa hata alırsın. Nasıl bir bileşen için bu kontrol gerekli ?
Bahsettiğim olayı şöyle IdHttp ile örneklemek istersem :
Örnekte :USES satırındaki IdHttp'yi kaldırırsan FALSE döner, IdHttp'yi USES'a eklersen TRUE...
Kod: Tümünü seç
USES IdHttp;
function VCL_IdHttp_Kontrol:Boolean;
begin
Result := {$IF DECLARED(TIdHttp)}True{$ELSE}False{$IFEND};
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
if VCL_IdHttp_Kontrol then showmessage('Kurulu')
else ShowMessage('Kurulu Değil...');
end;
- Şöyle ki aşağıdaki kodu kullanırken bir USES'daki IdHttp'yi silip dene, bir de USES'da IdHttp varken..
- USES'da var olduğu zaman çalışacak, yoksa çalışmayacak. Hata da vermeyecek.
Kod: Tümünü seç
USES IdHttp;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
{$IF DECLARED(TIdHttp)}
With TIdHttp.Create(nil) do
begin
// ...
Free;
end; MessageDlg('IdHttp Kurulu ve başarılı bir şekilde kullandık!!!', mtConfirmation, [mbOk], 0);
{$ELSE} MessageDlg('IdHttp Kurulu Değil...Kullanamadık !!!', mtError, [mbCancel], 0);
{$IFEND};
end;
Re: ifdef ve component kurulmuş mu nasıl anlaşılır
Aslında sorumun %90'ına cevap verdiniz fakat uses kısmı ile ilgili ne yapabiliriz henüz çözemedim.
Konuyu netleştirmek için soru biraz soyut kalmıştı somutlaştırmakta fayda var. Bu durumu aşağıdaki örnekten de görebiliriz; Örnek kodun içerisinde bazı açıklama satırları ekledim, sanırım sıkıntımı kodu incelerseniz daha net göreceksiniz;
Not: Bildiğiniz gibi ADO bileşenleri Delphi ile birlikte geliyor fakat UniDAC bileşenleri ise sonradan kurulan bir bileşen.
Konuyu netleştirmek için soru biraz soyut kalmıştı somutlaştırmakta fayda var. Bu durumu aşağıdaki örnekten de görebiliriz; Örnek kodun içerisinde bazı açıklama satırları ekledim, sanırım sıkıntımı kodu incelerseniz daha net göreceksiniz;
Not: Bildiğiniz gibi ADO bileşenleri Delphi ile birlikte geliyor fakat UniDAC bileşenleri ise sonradan kurulan bir bileşen.
Kod: Tümünü seç
// Aşağıdaki örnek kod, olguyu basite indirgemek için kırpılmıştır;
...
interface
uses ADOInt
, ADODB
, DB
, UNI {******* BU SATIRDA IFDEF DİREKTİFİNİ NASIL KULLANABİLİRİM? *******}
;
type
TADODataSetHelper = class helper for TADODataSet
public
procedure RunSQL(aSQL: String); overload;
procedure RunSQL(aSQL: String; const Args: array of const); overload;
end;
{******* AŞAĞIDAKİ HELPER TANIMININ TAMAMINA IFDEF DİREKTİFİ NASIL EKLEYEBİLİRİM? *******}
TUNIQuoeryHelper = class helper for TUniQuery
public
procedure RunSQL(aSQL: String; aFullFetch: Boolean = TRUE); overload;
procedure RunSQL(aSQL: String; const Args: array of const; aFullFetch: Boolean = TRUE); overload;
end;
implementation
{ TADODataSetHelper }
procedure TADODataSetHelper.RunSQL(aSQL: String);
var
aCursor: TBookmark;
begin
if (Trim(aSQL) = '') then Exit;
if (Assigned(Connection) = TRUE) then begin
try aCursor := GetBookmark; except end;
Close;
CommandType := cmdText;
CommandText := aSQL;
Open;
try if NOT IsEmpty AND Active then GotoBookmark(aCursor); except end;
end;
end;
procedure TADODataSetHelper.RunSQL(aSQL: String; const Args: array of const);
var
Temp: String;
begin
Temp := format(aSQL, Args);
RunSQL(Temp);
end;
{ TUNIQuoeryHelper }
{*******BU NOKTADAN SONRAKİ KISMA IFDEF NASIL EKLEYEBİLİRİM? *******}
procedure TUNIQuoeryHelper.RunSQL(aSQL: String; aFullFetch: Boolean = TRUE);
var
aCursor: TBookmark;
begin
if (Trim(aSQL) = '') then Exit;
if (Assigned(Self.Connection) = TRUE) then begin
try aCursor := Self.GetBookmark; except end;
Self.Close;
Self.SQL.Clear;
Self.SQL.Text := aSQL;
if (Self.Connection.ProviderName = 'SQL Server')
or (Self.Connection.ProviderName = 'MySQL') then begin
Self.Options.QueryRecCount := aFullFetch;
Self.SpecificOptions.Values['FetchAll'] := BitToStr(aFullFetch);
end;
Self.Open;
try Self.GotoBookmark(aCursor); except end;
end;
end;
procedure TUNIQuoeryHelper.RunSQL(aSQL: String; const Args: array of const; aFullFetch: Boolean = TRUE);
var
Temp: String;
begin
Temp := format(aSQL, Args);
RunSQL(Temp, aFullFetch);
end;
end.
Re: ifdef ve component kurulmuş mu nasıl anlaşılır
Uses kısmını serbest bırak, kullanıcı sadece bu kısmı devredışı bırakabilsin, alt tarafı da sana söylediğim şekilde kur. İşlem tamamdır.
USES sayırındaki unit bulunmazsa orada hata verir, kullanıcı onun başına // koyarak remark ettiğinde aşağoiıdakiler de ifdef ile kendi kendine devre dışı kalır.
Çünkü uses kısmı artık dpr kaynaktan dosya yolunu kontrol demek, oradan yürüyemeyeceğine göre zor bir durum diye değerlendiriyorum.
Ama path okuma diye birşey varsa ki compile öncesi nasıl olacak onu da bilemem, olsa olsa ide'ye bir eklenti gibi bir şey olurdu, bu seviyede erişim fikri için araştırmanın sonucunu merak da etmiyor değilim.
USES sayırındaki unit bulunmazsa orada hata verir, kullanıcı onun başına // koyarak remark ettiğinde aşağoiıdakiler de ifdef ile kendi kendine devre dışı kalır.
Çünkü uses kısmı artık dpr kaynaktan dosya yolunu kontrol demek, oradan yürüyemeyeceğine göre zor bir durum diye değerlendiriyorum.
Ama path okuma diye birşey varsa ki compile öncesi nasıl olacak onu da bilemem, olsa olsa ide'ye bir eklenti gibi bir şey olurdu, bu seviyede erişim fikri için araştırmanın sonucunu merak da etmiyor değilim.
Re: ifdef ve component kurulmuş mu nasıl anlaşılır
ifdef compiler directive ini şöyle Türkçeleştirirsen daha rahat kullanabilirsin. def -> define yada defined yani tanım yada tanımlanmış anlamında.
{$IFDEF uni_kullan} -> uni_kullan kullanılmışsa.... diye tercüme etmek pratiklik sağlıyabilir. ifdef in normal "if"ten farkı, compiler, sağlanmayan koşulu göz ardı eder, yok sayar. Dolayısıyla ne compile eder nede souce ların içine ekler.
son mesajında kullanmak istediğin şekli ile en pratik ve yaygın çözüm şudur.
bir "inc" uzantılı dosya oluşturulur, bu normal bir text dosyadır. inc uzantısı olmak zorunda değildir. INC->included yani eklenmiş demektir. Bu pascal dan kalma bir yöntemdir. pascal DOS ve xt makinlarda, pascal editor, büyük dosyalara hükmetmek zordu, bu ek dosyalar sayesinde kodları bölerdik. editör parça olarak görsede, compiler bu inc dosyaları kaynak kod içine ekleyip, tek dosya haline getirip öyle derler. Bir başka kullanım amacı, senin istediğin gibi kullanabilmek için, yani tek bir tanım yada code buloğu yapıp her yere aynı şeyi yazmak yerine {$I ekle.inc} şeklinde tek kelime yazmak daha pratik olabilir.
bu kaynak kod içinde yapılan bir işlemdir. Yani compile edilmek zorundadır, ve compile edilmiş bir kod içinde ifdef Muharrem beyin yazdıkları haricinde yönlendiremezsiniz.
bir desigtime packages yada plug in yazacaksanız, OTA (açılımını unuttum malesef) delphi IDE sine ait class lar bütünlüğü denebilir, bu OTA class ları ile delphi ye yüklenmiş olan component ve paketlere ulaşabilirsin. Unutulmaması gereken, kod içinde yapılan değişiklik compile edilmeden kullanılamaz. UNI eklenmediyse, kod içine eklenmesi onu kullanmanızı sağlamaz yada tersi. Yazdığınız kod için uni eklediniz, sonra uni yi delphi den kaldırdınız, kodunuz uni yi arayacağından bunu ifdef vs bir şey ile engelliyemezsiniz.
Kolay gele
{$IFDEF uni_kullan} -> uni_kullan kullanılmışsa.... diye tercüme etmek pratiklik sağlıyabilir. ifdef in normal "if"ten farkı, compiler, sağlanmayan koşulu göz ardı eder, yok sayar. Dolayısıyla ne compile eder nede souce ların içine ekler.
son mesajında kullanmak istediğin şekli ile en pratik ve yaygın çözüm şudur.
bir "inc" uzantılı dosya oluşturulur, bu normal bir text dosyadır. inc uzantısı olmak zorunda değildir. INC->included yani eklenmiş demektir. Bu pascal dan kalma bir yöntemdir. pascal DOS ve xt makinlarda, pascal editor, büyük dosyalara hükmetmek zordu, bu ek dosyalar sayesinde kodları bölerdik. editör parça olarak görsede, compiler bu inc dosyaları kaynak kod içine ekleyip, tek dosya haline getirip öyle derler. Bir başka kullanım amacı, senin istediğin gibi kullanabilmek için, yani tek bir tanım yada code buloğu yapıp her yere aynı şeyi yazmak yerine {$I ekle.inc} şeklinde tek kelime yazmak daha pratik olabilir.
Kod: Tümünü seç
interface
{$I ekle.inc}
{.$DEFINE uni_kullan} // bu ekle.inc dosyasının içeriği, başındaki nokta satırı remark haline çevirir.
uses ADOInt
, ADODB
, DB
{$IFDEF uni_kullan}
, UNI {******* BU SATIRDA IFDEF DİREKTİFİNİ NASIL KULLANABİLİRİM? *******}
{$ENDIF uni_kullan}
;
bir desigtime packages yada plug in yazacaksanız, OTA (açılımını unuttum malesef) delphi IDE sine ait class lar bütünlüğü denebilir, bu OTA class ları ile delphi ye yüklenmiş olan component ve paketlere ulaşabilirsin. Unutulmaması gereken, kod içinde yapılan değişiklik compile edilmeden kullanılamaz. UNI eklenmediyse, kod içine eklenmesi onu kullanmanızı sağlamaz yada tersi. Yazdığınız kod için uni eklediniz, sonra uni yi delphi den kaldırdınız, kodunuz uni yi arayacağından bunu ifdef vs bir şey ile engelliyemezsiniz.
Kolay gele
ZAGOR TENAY TÜRK'tür... TÜRK kalacak...
Zoru başarırım, İmkansız zaman alır
FreeMan 35.5
Soru sormaya üşenmiyorsan, sorunun çözümünü yazmaya da üşenme !!!
Zoru başarırım, İmkansız zaman alır
FreeMan 35.5
Soru sormaya üşenmiyorsan, sorunun çözümünü yazmaya da üşenme !!!