API FONKSİYONLARIBu yazı Delphi’nin .NET uyumlu versiyonunu konu ettiğim kitabımın Api fonksiyonları adlı bölümün bir kısmıdır.
Bu yazıda Windows’un API fonksiyonlarının bazıları hakkında bilgi verilecektir. API fonksiyonların çoğunluğu Delphi projelerine otomatik olarak dahil edilmeyen Namespace’lerde tanımlı oldukları için bu Namespace’lerin projeye dahil edilmesi gerekiyor.
Windows’un bazı API fonksiyonlarını kullanabilmek için Borland.Vcl.Windows, Borland.Vcl.Mapi, Borland.Vcl.ShellApi ve Borland.Vcl.SHFolder gibi namespace’lere gerek duyulmaktadır.
Konunun devamında anlatılacağı gibi Windows’a ait API fonksiyonları Windows ile gelen bazı DLL dosyaları içinde yer almaktadır. Bu nedenle kullanılmak istenen API fonksiyonun Windows’un hangi DLL dosyasında tanımlı olduğu öğrenilmelidir.
Windows’u Kapatmak – ExitWindowsEx() Fonksiyonu
Windows yeniden başlatılmak istendiğinde Windows’un ExitWindowsEx() fonksiyonu kullanılmaktadır. Ancak bu fonksiyon kullanılan Windows sürümünden ve Windows’un mevcut ayarlarından etkilenmektedir. Bu nedenle istenilen sonuçlar alınamayabilir.
Bildiğiniz gibi .NET Framework ile gelen MessageBox sınıfı System.Windows.Forms adlı Namespace’te tanımlıdır ve bu Namespace projelere otomatik olarak dahil edilmektedir. Ancak API fonksiyonlarını kullanmak üzere koda Borland.Vcl.Windows adlı Namespace’i projeye dahil ettiğinizde derleyici MessageBox sınıfını hangi Namespace’te arayacağına karar veremiyor. Bu nedenle kod dosyasına Borland.Vcl.Windows’u dahil ettiğinizde MessageBox sınıfının başına tanımlı olduğu Namespace’i yazmalısınız.
ExitWindowsEx() fonksiyonu 2 parametreye sahiptir. Bu fonksiyona ilk parametre olarak 0 veya EWX_LOGOFF değeri verildiği zaman o sırada programların çalışması sona erdirilir ve geçerli kullanıcının açmış olduğu oturum kapatılır. Aşağıda verilen ekran görüntüsünü ExitWindowsEx() fonksiyonunu anlatmak için hazırladığım projeyi çalıştırıp “Oturumu Kapat” başlıklı düğmeyi tıkladıktan sonra aldım.
İlk parametre olarak “1” veya EWX_SHUTDOWN verilirse bilgisayar kapatılır. Bu fonksiyona ilk parametre olarak EWX_REBOOT değeri verilirse bilgisayar kapatılıp yeniden açılır. Bu fonksiyon Windows sürümünden ve Windows’un mevcut ayarlarından etkilendiği için istediğiniz sonucu alamayabilirsiniz.
Kullanmak istediğiniz API fonksiyonu ile ilgili ve Borland tarafından geliştirilen Namespace’i koda dahil etmediyseniz fonksiyonu deklare edip tanımlı olduğu DLL dosyasını işaret etmelisiniz. Şimdi Borland.Vcl.Windows aldı Namespace’ten yararlanmadan bu fonksiyonu Visual Basic ve C’deki gibi deklare edip kullanacağım. Bu amaçla ilk olarak kod dosyasının Implementation bloğunda ExitWindowsEx() fonksiyonunu aşağıdaki gibi deklare ettim.
ExitWindowsEx() fonksiyonu bu şekilde deklare edildikten sonra Delphi projesi dahilinde kullanılabilir. Fonksiyonun deklare edildiği satırda görebileceğiniz gibi geriye Boolean bilgi gönderilmektedir. Burada Flags parametresinin yerine 0 yazdığım için oturum kapatılır.
Sonuc := ExitWindowsEx(0, 0);
Yukarıda hakkında bilgi verilen ExitWindowsEx() fonksiyonu Windows’un “users32.dll” adlı DLL dosyasında tanımlıdır. Bu fonksiyonu Visual Basic projesi dahilinde kullanmak istemiş olsaydım aşağıdaki gibi deklare ederdim.
Yukarıda hakkında bilgi verdiğim ExitWindowsEx() fonksiyonundan C# veya C++ projesi dahilinde yararlanmak istemiş olsaydım bu fonksiyonu aşağıdaki gibi deklare ederdim.
[DllImport("User32")] public static extern bool ExitWindowsEx( int uFlags, int dwReserved);
Delphi projeleri dahilinde API fonksiyonlarını C#’taki gibi kullanmak istiyorsanız DllImport deyimi ile fonksiyonun tanımlı olduğu DLL dosyasını işaret ettikten sonra C#’taki gibi deklare edip .NET Framework ile gelen System.Runtime.InteropServices adlı namespace’i koda dahil etmelisiniz. Bu namespace’i koda dahil ettikten sonra ExitWindowsEx() fonksiyonunu aşağıdaki gibi deklare edip kullandım.
Şimdiye kadar API fonksiyonları hakkında verilen bilgilere göre Delphi’nin daha önceki sürümlerini kullandıysanız API fonksiyonlarını kullanırken Borland tarafından geliştirilen Borland.Vcl.Windows ve Borland.Vcl.ShellApi gibi Namepsace’leri koda dahil edip fonksiyonu kullanmak kolayınıza gelecektir. Bu kitapta örnek olması için hakkında bilgi verilen API fonksiyonlarını kullanırken yukarıda söz edilen her 3 teknik te kullanıldı.
MesasageBox() Fonksiyonu
Windows’un MessageBox() fonksiyonundan yararlanıp mesaj verip kullanıcıdan onay almaya yarayan diyalog kutusunu ekrana getirebilirsiniz. Bu fonksiyonu yukarıda sözünü ettiğim her 3 teknik ile kullanmayı deneyeceğim. İlk olarak Borland.Vcl.Windows’u koda dahil edip aşağıda verdiğim kodu yazdım.
MessageBox() fonksiyonuna 1. parametre olarak ekrana getirilecek diyalog kutusunun handle numarası verilmektedir. 4. parametre olarak verilen 35, 32 ve 3 sayılarının toplamından meydana gelmektedir. 3 sayısı MessageBox tarafından ekrana getirilecek diyalog kutusunda Evet, Hayır ve İptal düğmelerinin olmasını sağlamaktadır. 32 ise diyalog kutusunda mesajdan önce soru(?) işaretinin olmasını sağlamaktadır.
Bu diyalog kutusunda tıklanan düğmeye göre MessageBox() fonksiyonu geriye sayısal bir değer göndermektedir. Bu değeri yakalamak için aşağıda verdiğim kodu hazırladım.
Var Secim : LongInt; Ptr : HWND; Yazi : Graphics; Yazi_tipi : System.Drawing.Font; Nokta : PointF; Firca : SolidBrush; Begin Secim := MessageBox(Ptr, 'Dosya Silinsin mi?','Silme Onayı', 35); Yazi := self.CreateGraphics; Nokta := PointF.Create(30, 40); Firca := SolidBrush.Create(Color.Blue); Yazi_tipi :=System.Drawing.Font.Create('Tahoma',14,FontStyle.Bold); If Secim = 6 Then Yazi.DrawString('Evet düğmesini tıkladınız', Yazi_tipi, Firca, Nokta) Else If Secim = 7 Then Yazi.DrawString('Hayır düğmesini tıkladınız', Yazi_tipi, Firca, Nokta) Else If Secim = 2 Then Yazi.DrawString('İptal düğmesini tıkladınız', Yazi_tipi, Firca, Nokta); end;
Bu kod işletilip diyalog kutusundaki düğmelerden birisi tıklandığında tıklanan düğmeye göre formun üzerine mesaj yazılır. Bu örnekte kullanılan System.Drawing’de tanımlı olan Graphics sınıfı hakkında daha önce bilgi verilmişti.
Şimdi ise Borland.Vcl.Windows’tan yararlanmadan bu API fonksiyonunu kullanacağım. Bu amaçla fonksiyonu formu temsil eden Unit’in Implementation bloğunda aşağıdaki gibi deklare ettim. Ekran görüntüsü verilen koda göre “user32.dll” dosyasında tanımlı olan MessageBox fonksiyonu 4 parametreye sahiptir ve geriye LongInt bilgi göndermektedir.
Fonksiyonu bu şekilde deklare ettikten sonra yukarıda verdiğim kodda küçük bir değişiklik yaptım. Yukarıda verdiğim kodda bu fonksiyonun 1. parametresi HWND tipindeydi. HWND tipi Borland.Vcl.Windows’de tanımlı olduğu için 1. parametrenin LongInt tipinde olmasını sağladım.
Şimdi ise bu fonksiyonu C#’taki gibi deklare edip System.Runtime.InteropServices’den yararlanıp kullanacağım. Bu Namespace’i koda dahil ettikten sonra deklarasyonu aşağıdaki gibi yaptım. Bu şekilde deklare edilen fonksiyon istenildiği gibi kullanılabilir.
Program Çalıştırmak ve Dosya Açmak
Delphi projeleri dahilinde bilgisayara kurulu olan herhangi bir programı çalıştırmak için WinExec() adlı API fonksiyonundan yararlanabilirsiniz. WinExec() fonksiyonu 2 parametreye sahiptir. İlk parametrede çalıştırılacak program dosyasının adı verilmekte ve 2. parametrede ise programa ait pencerenin ilk şekli belirtilmektedir.
Çalışma anında WinExec() fonksiyonu sayesinde Not Defteri programının(Notepad.exe) çalışmasını sağlamak için forma bir düğme yerleştirdim ve bu düğmenin Click() yordamını aşağıdaki gibi düzenledim. Deklarasyon yapmadan WinExec() fonksiyonunu bu şekilde kullanabilmek için Borland.Vcl.Windows’un koda dahil edilmesi gerekir.
Çalıştırılan programa ait pencere ilk ekrana getirildiği zaman ekranı kaplaması isteniyorsa WinExec() fonksiyonuna 2. parametre olarak 3 değeri verilmelidir. 2. parametre olarak 6 verilirse programa ait pencere simge durumuna küçültülür, 9 verilirse pencere orijinal boyutları ile ekrana getirilir.
WinExec() fonksiyonu kendisine 1. parametre olarak verilen program dosyası ile ilgili olarak geriye sayısal bir değer göndermektedir. Çalıştırılmak istenen program dosyası bulunamazsa geriye 2 gönderilmektedir.
Belirtilen sürücü veya klasör bulunmazsa WinExec() fonksiyonu geriye 3 değerini gönderir. Belirtilen programı çalıştırmak için yeterli bellek yoksa geriye 8 gönderilir. WinExec() fonksiyonun geriye gönderdiği değeri yakalamak için yukarıda verdiğim kodu aşağıdaki gibi değiştirdim.
Delphi projesi dahilinde çalıştırılacak programı çalışma anında belirleyebilmek için forma bir OpenFileDialog nesnesi yerleştirdim ve yukarıda verdiğim kodu aşağıdaki gibi düzenledim.
WinExec() fonksiyonunu aşağıdaki gibi kullanıp Denetim Masası penceresini ekrana getirebilirsiniz. WinExec() fonksiyonuna 2. parametre olarak 9 yerine “sw_ShowNormal” sabit bilgisini kullanabilirsiniz.
begin WinExec('C:\Windows\System32\Control.exe', sw_ShowNormal); end;
Bildiğiniz gibi Denetim Masası penceresinde sistemle ilgili programları temsil eden simge veya seçenekler bulunmaktadır. Denetim Masası penceresini ekrana getirmedeki amacınız Yazıcılar penceresini açıp yazıcılar ile ilgili ayarlama yapmaksa WinExec() fonksiyonunu aşağıdaki gibi kullanabilirsiniz. Bu şekilde düzenlenen WinExec() fonksiyonu sayesinde Denetim Masası penceresi ekrana getirilmeden direk Yazıcılar penceresi açılır.
begin WinExec('C:\Windows\System32\Control.exe PRINTERS', 9); end;
Denetim Masasındaki bazı uygulamalar CPL uzantılı dosyalar şeklinde gelmektedir. Örneğin “Tarih ve Saat Özellikleri” penceresini ekrana getirmek için TIMEDATE.CPL adlı dosyayı “Control.exe” programı ile açmak gerekmektedir. Bu işlemin nasıl yapıldığını aşağıda görebilirsiz.
begin WinExec('C:\Windows\System32\Control.exe TIMEDATE.CPL', 9); end;
Delphi projeleri dahilinde DOS penceresi açmak istiyorsanız WinExec() fonksiyonunu aşağıdaki gibi kullanabilirsiniz.
begin WinExec('Command.com', 9); end;
WinExec() fonksiyonunu System.Runtime.InteropServices’den yararlanarak çalıştırmak istemiş olsaydım bu fonksiyonu aşağıdaki gibi deklare ederdim. Fonksiyonları deklare ederken parametrelere istediğiniz adı verebilirsiniz.
ShellExecute() Fonksiyonu
Herhangi bir dosyayı ilgili program ile açmak veya yazıcıya göndermek istiyorsanız ShellExecute() fonksiyonunu kullanabilirsiniz. Bu fonksiyonun nasıl kullanıldığını aşağıda görebilirsiniz. ShellExecute() fonksiyonunu kullanabilmek için Borland.Vcl.ShellApi adlı Namespace koda dahil edilmelidir. Verilen kod incelenirse ShellExecute() fonksiyonun toplam 6 parametreye sahip olduğu görülür.
Bu şekilde düzenlenen yordam işletildiğinde ShellExecute() fonksiyonuna 3. parametre olarak verilen dosya ilgili program ile açılıp ekrana getirilir. Dosyayı yazıcıya göndermek istiyor olsaydım 2. parametrede “Open” yerine “Print” kullanırdım.
ShellExecute() fonksiyonuna 3. parametre olarak bir dosya adı yerine bir klasörün adını verir ve 2. parametre olarak “Explore” seçeneğini kullanırsanız söz konusu klasörün içeriği Windows Gezgini programı ile ekrana getirilir.
ShellExecute(0,'Explore', 'C:\', '', '',SW_SHOW);
ShellExecute() fonksiyonu ile yukarıda yapıldığı gibi istediğiniz dosyayı açabildiğiniz gibi web sitelerine bağlanabilirsiniz. ShellExecute() fonksiyonu aşağıdaki gibi düzenlendiğinde Internet Explorer programı çalıştırılır ve belirtilen web sitesine erişim sağlanır.
ShellExecute(0,'Open', 'http://www.borland.com', '', '',SW_SHOW);
Geçerli Mail programını çalıştırıp E-Mail göndermek istiyorsanız ShellExecute() fonksiyonuna ilgili mail adresini 3. parametre olarak vermelisiniz.
ShellExecute(0, 'Open', 'mailto:seckin@seckin.com.tr','','', SW_SHOW);
Yukarıda ShellExecute fonksiyonunu kullanırken Borland.Vcl.ShellApi’den yararlandım. Bu Namespace’i projeye dahil etmeden ShellExecute() fonksiyonundan yararlanmak istemiş olsaydım bu fonksiyonu aşağıdaki gibi deklare etmem gerekirdi. Yukarıda belirtildiği gibi API fonksiyonlarını deklare ederken parametrelere istediğiniz adı verebilirsiniz.
Bu şekilde deklare edilen fonksiyon kullanılırken ekrana gelen pencerenin ilk halini temsil eden 6. parametrede SW_SHOW gibi sabit değerlerin yerine bu sabit değerleri temsil eden sayıları kullanmalısınız. Çünkü bu sabitler Borland.Vcl.Windows.Pas dosyasında tanımlıdır. Bu sabitleri aşağıda tablo halinde verdim.
SW_HIDE = 0; SW_SHOWNORMAL = 1; SW_NORMAL = 1; SW_SHOWMINIMIZED = 2; SW_SHOWMAXIMIZED = 3; SW_MAXIMIZE = 3; SW_SHOWNOACTIVATE = 4; SW_SHOW = 5; SW_MINIMIZE = 6; SW_SHOWMINNOACTIVE = 7; SW_SHOWNA = 8; SW_RESTORE = 9; SW_SHOWDEFAULT = 10; SW_MAX = 10;
ShellExecute() fonksiyonunu System.Runtime. InteropServices’ten yararlanarak işletmek istemiş olsaydım bu fonksiyonun tanımlı olduğu DLL dosyasını aşağıdaki gibi kod dahil edip fonksiyonu deklare ederdim.
Windows’un Kurulu Olduğu Klasörü Öğrenmek
|
|
|
Söz konusu tuş devrede değilse dizi değişkenin o elemanı 0 değerini içerir. Yanda verilen ekran görüntüsünü hem Caps Lock hem Num Lock tuşları devrede değilken bu kodu işlettikten sonra aldım.
|
Bu sırada Caps Lock tuşuna basıp klavyeyi büyük harflere kilitleyip yukarıda verilen yordamı tekrar işletince aşağıdaki gibi bir sonuç elde ettim. Benzer mantıkla VK_SCROLL parametresi ile Scroll Lock tuşunu kontrol edebilirsiniz.

Delphi projelerinde tuşların durumunda değişiklik yapmak istiyorsanız SetKeyboardState() fonksiyonundan yararlanmalısınız. Bu fonksiyon ile tuşların durumlarının nasıl değiştirildiğini anlatmak için projenin formunu 2 düğme yerleştirdim ve “Caps_Lock_Tusu” adını verdiğim düğmenin Click yordamını aşağıdaki gibi düzenledim. SetKeyboardState() fonksiyonun da Borland.Vcl.ShellApi’de tanımlıdır.
Var
Durum : TKeyboardState;
begin
GetKeyboardState(Durum);
If Durum[20] = 0 Then
Durum[VK_CAPITAL] := 1;
Else
Durum[VK_CAPITAL] := 0;
SetKeyboardState(Durum);
end;
Delphi projesi dahilinde Windows’un görev çubuğunu gizlemek istiyorsanız ShowWindow() fonksiyonunu kullanabilirsiniz. 2 parametreye sahip olan bu fonksiyona ilk parametre olarak üzerinde işlem yapılmak istenen pencerenin Handle numarası verilmektedir.
Söz konusu pencerenin Handle numarası bulunurken FindWindow() fonksiyonundan yararlanılmaktadır. ShowWindow() fonksiyonun orijinal yapısı aşağıdaki gibidir. Yapıda görüldüğü gibi bu fonksiyon geriye Boolean tipinde bilgi göndermektedir.
BOOL ShowWindow
(
HWND hWnd,
int nCmdShow
);
ShowWindow() fonksiyonu aşağıdaki gibi kullanıldığında görev çubuğu gizlenir. Görev çubuğunu tekrar görüntülemek istiyorsanız ShowWindow() fonksiyonun 2. parametresini SW_SHOW yapmanız yeterlidir.
ShowWindow(FindWindow('Shell_TrayWnd', Nil), SW_HIDE);
ShowWindow() fonksiyonuna Handle numarası 1. parametre olarak verilen pencereyi simge durumuna küçültmek istiyorsanız 2. parametre olarak SW_MINIMIZE, ekranı kaplamasını istiyorsanız SW_MAXIMIZE seçeneğini vermelisiniz.
Masaüstündeki bütün simgeleri gizlemek istiyorsanız ShowWindow() fonksiyonunu aşağıdaki gibi kullanabilirsiniz. Gizlediğiniz simgelerin tekrar görünmesini sağlamak istiyorsanız SW_HIDE yerine SW_SHOW yazmanız yeterlidir.
ShowWindow(FindWindow(Nil, 'Program Manager'), SW_HIDE);
Bazen kullanıcı program çalıştırmaya yarayan kısayolun üzerinde çift tıklama yapar. Hemen tepki alamadığında sanki tıklama yapmamış gibi 2. kez tıklama yapabilir. Bu durumda aynı program 2 kez çalıştırılır. Bu gibi sorunların önüne geçmek veya Delphi ile hazırladığınız programın aynı oturumda 2. kez çalıştırılmasını önlemek istiyorsanız GlobalAddAtom() fonksiyonundan yararlanabilirsiniz. Projenin başlangıç formunun Load() yordamını aşağıdaki gibi düzenlemeniz halinde aynı program 2. kez çalıştırılamaz.

Bu kodda önce GlobalFindAtom() fonksiyonu ile söz konusu programın daha önce çalıştırılıp çalıştırılmadığı araştırılıyor. Program veya proje daha önce çalıştırılmadıysa GlobalFindAtom() geriye 0 değerini göndereceğinden programın çalışması engellenmez. Bu sırada GlobalAddAtom() metodu ile sistem programın çalıştırıldığı konusunda bilgilendirilir.
|
|
Program 2. kez çalıştırıldığında GlobalFindAtom() fonksiyonu geriye 0’dan farklı bir değer göndereceği için programın daha önce çalıştırıldığı mesajı verilip Halt deyimi ile programın çalışması sona erdirilir. |
Ancak bu durumda projenin ana formunun Destroy olayını temsil edene Procedure’nin aşağıdaki gibi düzenlenerek programın çalışması sona erdirildiğinde sistemin bundan haberdar edilmesi gerekir. Destroy() yordamında GlobalDeleteAtom() fonksiyonu kullanılmazsa bu şartlarda Windows tekrar başlatılana kadar aynı program tekrar çalıştırılamaz. Bu yordamda daha önce Load() yordamında tanımladığım “Sonuc” değişkenini kullanıldığım için bu değişkenin tanımlandığı satırı kod dosyasının üst kısmına aldım.
