Bilgisayar Dünyası

 Genel Bilgiler :

Konu                       : API Programcılığı
 İçerik :

Api fonksiyonlarının kullanımıyla ilgili olarak anlatılan programın göçmesi, verilerin kaybedilmesi yada sistemin bozulması gibi hikayelere inanmayın. Visual Basic'te API kullanımı oldukça kolay ve VB projelerinizi geliştirmek için oldukça güçlü bir yoldur.
API'nin her türlü işte yararlı kullanıma hazır fonksiyonları vardır.
Çoğu durumda birkaç basit kurala dikkat ederseniz kullanımı çok kolaydır.
Yazdığınız programların çalışacağı her bilgisayarda zaten kurulu durumdadırlar.
Yapmanız gereken sadece birazcık program kodu yazmaktır.

Son satıra dikkatinizi çekmek istiyorum: Yapmanız gereken sadece biraz kod! Yeniler için VB'nin çekiciliği görsel ortamdır. Çabucak ve kolayca basit programları formlar üzerine kontrolleri yerleştirerek ve birkaç ufak tefek kod yazıp bu kontrolleri birbirine bağlayarak yaparsınız. Örnekler çok ancak size şu örneği vereyim: Form üzerine bir DBGrid ve bir Data nesnesi yerleştirip, Data'nın bağlantısını bir veritabanına, DBGrid'in bağlantısını da Data nesnesine yaparsanız, veritabanındaki kayıtların hemen DBGrid'te izlenebildiğini görürsünüz. İşte hiç bir kod yazmadan oldukça detaylı bir işlem. Bu; VB'nin nesnelerinin ve VB'nin bir görsel programlama ortamı olarak kolaylığının gücüdür. İşte bu görsel ortam nedeniyle bazı programcılar görsel olmayan kod yazmaktan korkarlar.

Ancak, API kullanımından korkmanın hiç bir gereği yoktur. Birazcık dikkat ve bir kaç satır kod ile yüzlerce satır kod ile yapılabilecek işlemleri başarabilirsiniz ve programcılık becerilerinizi arttırırsınız.


Giriş:
Win32 Application Programming Interface (API) VB'nin sahip olduğu en güçlü eklentidir. Yüzlerce fonksiyon çok geniş bir alanda görev yapmak için hazır beklemektedirler. Ancak maalesef, birçok VB programcısı, karışık yapılarından dolayı yada kullanımda hatalar meydana getirecekleri endişesiyle, bu güçlü araçları kullanmamayı yeğlemektedirler.

API nedir?
Adı üstünde hazır programlama arabirimidir. Windows için yazılan programlar yaygın Windows görevlerini API fonksiyonlarının çağırarak yaparlar. Örnek olarak: pencere, kontrol veya menü yaratmak yada yoketmek, görüntü, klavye, yazdırma yada fare girdisi gibi sistem araçlarını denetlemek ve daha niceleri... Api fonksiyonları DLL uzantılı Dynamic Link Libraries dosyalarından çağırılır.

Api Programlama Araçları:
Biraz bilgi ve Api referansları, bir kaç basit kural ile Win32 API fonksiyonlarını VB projelerinize yerleştirebilrsiniz. İşte ihtiyaçlarınız:

Win32 SDK (Software Development Kit) -- Yazılım Geliştirme Araçları --
SDK bilgisine VB Professional ve Enterprise içinden ulaşabilirsiniz. Ayrıca http://www.microsoft.com/msdn/ adresinden de ..

API İzleme Apleti
Bu aplet te VB ile birlikte gelir. Api fonksiyonlarını çağırmadan önce modüllerde nelerin deklere edilmesi gerektiğini listeler. Çalıştırmak için VB'de menüde Ad-on kısmında Api viewer'i seçin.
Size istediğiniz Api fonksiyonu için gereken tüm Declare ifadelerini verir.
Son olarak ta biraz cesaret...

Api Fonksiyonlarını Deklere Etmek:
Api içinden bir fonksiyon çağırmak iki aşama gerektirir. VB kodunu içinden fonksiyon çağrısını yapmadan önce VB'nin yapacağınız dış çağrıyı tanıyabilmesi için bir Declare ifadesi yazmalısınız. Declare ifadesi bazı kısımlardan oluşur ve bildiğiniz VB Sub (procesure) deklerasyonu gibidir. Declare ifadesinin söz dizimi şöyledir.
Sub prosedürleri için Declare kalıbı:

[Public | Private] Declare Sub ad Lib "kütüphane_adı" [Alias "aliasname"] [([argüman_listesi])]

Function prosedürleri için Declare tanımı:

[Public | Private] Declare Function ad Lib "kütüphane_adı" [Alias "aliasname"] [([argüman_listesi])] [As veri_türü]

Şimdi bu ifadeler içindeki bileşenlerin herbirine bakalım:

Public yada Private

Bu VB'nin standart etkin alan tanımlayıcısıdır. Declare ifadeleri modüllerin declarations kısmında yazılmalıdır (prosedür içinde yapılmaz!) ve Public deyimi yazılan ifadenin tüm program içinde geçerli olduğunu, Private deyimi ise sadece tanım yapılan modül içinde geçerli olduğunu bildirir. Değişkenlerin etkin alanları konusunda detaylı bilgi için değişkenler sayfasına bakınız.

Notlar:
API fonksiyonlarını Public olarak deklere etmektense, onları Private deklere edebilirsiniz ve API'yi çağırmak için bir public fonksiyon yazarsınız ve bu fonksiyon aracılığıyla API'yi public olarak çağırırsınız. Form yada class modüllerinde yazılan declare ifadeleri Public olamaz! Sadece private ifadelere izin verilir.

Declare Sub yada Declare Function

Bu prosedürün bir değer döndürüp döndürmeyeceğini gösterir. Fonksiyonlar değer döndürür.

Dikkat:
Bazı API fonksiyonlarının VB'de kullanılamayan illegal adları vardır, bu yüzden ikinci bir ad da (alias) standart olarak verilmiştir. Bazı nedenlerden dolayı bir ad ve bir ikinci adın kullanılması gereklidir. Ancak, (ileride açılanacak bazı nedenlerle) hem ad hem de ikinci adın TÜM API deklerasyonları için kullanılması önerilir.

Lib "kütüphane_adı"
Bu çağırılacak fonksiyonu içinde tutan DLL dosyasının adıdır.
Dikkat: Kütüphane adının verirken çift tırnak arsına almayı unutmayın.

Alias "ikinci_ad"
Çağırılacak fonksiyonun ikinci adıdır.
Dikkat: Kütüphane adı gibi, çift tırnak arasında yazılır

(argüman_listesi)
Standart VB argüman listesidir. Prosedür için hangi parametrelerin gerekli olduğunu, parametrelerin veri türünü ve parametrelerin ByVal olarak mı yoksa ByRef olarak mı geçeceğini gösterir.

Dikkat:
Bu kısmı yanlış yazmak bir sistem hatasına neden olabilir. Parantezler ve çift tırnaklar unutulmamalıdır.
API Argümanlarını deklere ederken, normal VB veri türlerine ek olarak AS ANY veri türünü de kullanabilirsiniz. Bazı durumlarda uygun olmakla birlikte; VB bu tür üzerinde hiçbir tür denetimi yapmadığı için bazen tehlikeli olabilir.

As veri_türü
Sadece fonksiyonlarda kullanılır ve dönüş veri türünü gösterir. Bunu bir örnekle açıklmak daha kolay olacaktır. Aşağıda FindWindow fonksiyonu için Declare ifadesi var.

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long


Bu declare'in tüm bileşenlerine bir göz atalım:

Private:
Bu fonk modüle private (özel) olarak tanımlandı, çünkü sonradan public olarak kullanılacak bir ara fonksiyon ile bu API değeri tüm program içinden çağırılabilecek. Bu şekilde sadece bu ara fonksiyonun API'yı direkt olarak çağırması kesinleştirilmiş olacaktır.

Function FindWindow:
Bu proc bir değer döndürür (pencerenin handle'i)

Lib "user32" Alias "FindWindowA":
Bu proc user32.dll dosyasını çağırmaktadır, ve çağırılan fonksiyon user32.dll dosyası içinde FindWindowA olarak tanıtılmıştır.

Dikkat:
Win32 API hem ANSI hemde Unicode fonksiyonlar kullanımına izin verir, ancak VB içinden bizler sadece ANSI versiyonları kullanırız, bu yüzden fonksiyon adı sonundaki A harfinin anlamı budur.

ByVal lpClassName As String, ByVal lpWindowName As String
Bu fonksiyon ki parametre alır, ikisi de ByVal stringtir.

As Long
Fonksiyon Long integer değer döndürür.

FindWindow fonksiyonu ayrıca API lerin bir başka özelliğini de göstermektedir. Parametrelerin her ikisi birden zorunlu değildir. Sadece bri parametre yeterlidir. İstersniz iki parametre de verebilirsiniz ancak biri yeterli iken ikincisini de yazma gereği niye ki? Boş bırakmak istediğiniz parametre için sadece ByVAl 0& yada vbNulString değişmezini yazınız.


API Viewer Kullanımı:
Yüzlerce fonksiyon, değişmez (constant), ve yapı (structure) arasından sadece gerekenleri bulmanız yeterlidir, bunları ezbere bilmeniz gerekmez. VB ile birlikte gelen API Viewer ile ihtiyacınız olanları kopyalayıp gerekli olan yerlere yapıştırırsınız (genelde VB modülleri declarations kısımları içine). O kadar kolay bir arabirim oluşturulmuş ki, yapmanız gereken tek şey win32api.txt yada win32api.mdbYi yüklemek ve bir combo box içine aradığınız fonksiyonu yazmak sonra herşey karşınızda...

Dikkat:
win32.txt'yi ilk kez kurduğunuzda, Api Viewer size bu dosyayı mdb formatına çevirmeyi isteyip istemediğinizi soracaktır. Yes cevabı verdikten sonra win32.mdb'yi yükleyin


API Fonksiyonlarını Çağırmak:

Bunu bir örnekle anlatalım:
Aşğıdaki kod GetComputerName fonksiyonunun declare ifadesidir. Bu fonksiyon bilgisayarın adını bir string parametre aracılığıyla döndürür.

Private Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA" ( _
ByVal lpBuffer As String, _
nSize As Long) As Long


GetComputerName iki parametre alır: lpBuffer ve nSize. lpBuffer parametresi API'den bilgisayar adını alacak ByVal stringdir. nSize parametresi ise lpBuffer string boyutunu fonksiyon çağırıldığında API'ye verir ve fonksiyonun lpBuffer içine yerleştirdiği sonucun boyutunu alır.
Fonksiyon başarılı olursa sıfır harici bir rakam, başarısız olursa sıfır üretir. Aşağıdaki kod bu fonksiyonun nasıl çağırılacağını gösteriyor:


Dim lResult As Long
Dim sBuffer As String
Dim lSize As Long
' sonuç için yer ayır
' 256 tüm platformlar için fazlasıyla yeter
lSize = 256
sBuffer = Space(lSize)
' çağrıyı yap
lResult = GetComputerName(sBuffer, nSize)
' sonucu test et
If lResult <> 0 Then
' sonuç sıfır değilse başarı
' sBuffer içinde artık bilgisyarın adı vardır
' nSize içinde null (satır sonu karakteri) hariç sonucun uzunluğu vardır
sBuffer = Left$(sBuffer, nSize)
Else
' sıfır değeri döndü, başarısızlık
End If

Fonksiyon çağırılmadan önce, nSize'a 256 değeri verildi ve sBuffer string'ine 256 boşluk (space) verildi. Parametreler belirlendikten sonra, fonksiyon çağırıldı ve sonuç test edildi. Sıfır değeri dönmediyse başarı sağlanmış ve bilgisayarın adı bulunmuştur ve iki şey oluşmuştur:
Bilgisayarın adı sBuffer string'i içine yerleştirilmiştir.
nSize değişkeni satırsonu karakteri hariç olmak üzere bilgisayara dının uzunluğunu tutmaktadır.
Bu aşamadan sonra yapılacak tek şey sBuffer içinden bilgisayar adını çekip almaktır. Bunun için null karakterinin solunda kalan herşey aradığımız kelime olacaktır. left$(sBuffer, vbNullChar) fonksiyonu ile yapılır.

Dikkat!! Dikkat!! Dikkat!! Dikkat!! Dikkat!! Dikkat!! Dikkat!! Dikkat!!

Gerçek buffer (tampon bellek) boyutuyla, parametre olarak verdiğiniz boyutu sakın karıştırmayın. API sizin ona söylediğinizi yapar ve ona belli boyutta buffer verirseniz, o da verdiğiniz boyutta
string'i sistemin sağladığı adrese yazar. aşağıdaki hatayı yaparsanız neler olabileceğine bakın:

Dim sBuffer As String
Dim nSize As Long
Dim lResult As Long

nSize = 2048
sBuffer = Space(248)
lResult = GetComputerName(sBuffer, nSize)


Fonksiyona nSize boyutunda string döndürebileceğini söylüyoruz (burada 2048 byte) ancak ona 248 byte buffer alan ayırıyoruz. Eğer fonksiyon (tesadüf bu ya) izin verdiğimiz boyutta veri döndürürse (2048), bunu buffer'e (tampon bellek) yazacaktır. Biz ona 248 byte ayırmıştık. Bizim ayırdığımız alanı bitirip, RAM'de önüne çıkan alanlara yazmaya devam edecektir. Sonuç, bize ait olmayan alanara da yazılacağı için şanslıysanız Windows genel koruma hatası vererek (mavi ekran) programınızı kapatacaktır. Daha da kötüsü, program çalışmaya devam ederse, hem kendi kodlarını hem de başka programları ve verileri yakıp yıkarak daha ileri hatalara neden olacaktır.

API Programlama Kuralları
API Programlama ile ilgili bir kitap almak bence birinci kural, diğer kurallar ise şöyle:

Çalışmalarınızı sık sık kaydedin
Herhangi bir fonksiyonu çağırmadan önce ne yapmakta olduğunuzdan emin olun
ByVal ve ByRef kelimelerini doğru yerlerde kullanın
String buffer'ların ve structure'ların boyutlarını ilgili parametreler ile eşleştirmeyi SAKIN unutmayın.
Uygulamalarınızın herhangi bir yerinden API fonksiyonlarını çağırmak için Global API deklerasyonu yerine kendi yazdığınız bir fonksiyon kullanın
Çalışmalarınızı devamlı kaydedin, VB'yi çökertip tüm kodlarınızı kaydedebilirsiniz.
VB String yapısını C String yapısı ile karıştırmayın
VB Null ile C Null'u karıştırmayın
Her parametrenin ne anlama geldiğine emin olmadan yola koyulmayın. Herşeyi anlayın ve sonra kullanın. Parametrelerin ByRef yada ByVAl dönüp dönmediğinden emin olun.

Özet

Bu sayfada VB programcılarına API programlamanın gerçekte görüldüğü kadar ürkütücü bir şey olmadığını göstermeye çalıştım. API programlama işi VB'ye henüz başlamış kişiler için biraz ağır olmakla beraber, ciddi ve düzenli çalışanlar için aşılamayacak bir engel değildir. Ancak eğer siz değişkenlerine "ayşe", "fatma" gibi rastgele adlar verenlerdenseniz, sürekli save yapmayan ve dönüş değerlerine dikkat etmeyenlerdenseniz, öncelikle bu huyunuzdan vazgeçmelisiniz.