visual basic ile programlama

Document Sample
visual basic ile programlama Powered By Docstoc
					                                                     İÇİNDEKİLER
İÇİNDEKİLER ............................................................................................................................ 1
1. VISUAL BASIC 5 İLE PROGRAMLAMAYA GENEL BİR BAKIŞ ................................ 3
     1.1. Visual Basic 5 İle Yazılım Geliştirme ............................................................................ 3
2. DATA CONTROL NESNESİNİN KULLANIMI ............................................................... 20
     2.1. Visual Basic 5 İle Yazılım Geliştirme .......................................................................... 20
     2.2. Data Control Nesnesi Kullanarak Veritabanına Erişim. ............................................... 21
     2.3. Data Control Nesnesinin Olaylarını ve Metotlarını Kullanma ..................................... 24
     2.4. Activex Data Bound Kontrol Nesnelerini Kullanma .................................................... 27
3. VERİ ERİŞİM NESNELERİNİN KULLANIMI ................................................................ 38
     3.1. Giriş .............................................................................................................................. 38
     3.2. Recordset Yapısı İle Çalışmak ...................................................................................... 40
              3.2.1 Veritabanı Tasarımı ve Yaratılması .............................................................. 41
              3.2.2. Veritabanına Erişim ..................................................................................... 46
              3.2.3. Veritabanı Üzerinde Ekleme ve Silme İşlemleri ......................................... 50
              3.2.4. Veritabanı Üzerinde Arama İşlemleri .......................................................... 55
4. İLERİ DÜZEY VERİ TABANI GELİŞTİRME ................................................................. 60
     4.1. Veri Bütünlüğünü Sağlama. ......................................................................................... 60
     4.2. Çok Kullanıcılı Veritabanları ve Güvenlik ................................................................... 63
     4.3. Dış (External) Veritabanlarına Erişim .......................................................................... 70
     4.4. ODBC Veritabanlarına Erişim ...................................................................................... 75
              4.4.1. ODBC Verilerine Microsoft Jet Kullanarak Erişim..................................... 76
              4.4.2. ODBC Verilerine ODBCdirect Kullanarak Erişim ...................................... 79
     4.5. Veritabanı Performansını Eniyileştirme ....................................................................... 79
5. DLL (Dynamic Link Library-Devirgen Bağlı Kütüphane) KULLANIMI ....................... 82
     5.1. Bir DLL Yordamını Uygulamanın İçinde Kullanmak .................................................. 82
     5.2. Microsoft Windows API Yordamlarına Erişim ............................................................ 83
     5.3. DLL İçindeki Bir Yordamın Tanımlanması ................................................................. 84
     5.4. String Kullanan Windows API Yordamları .................................................................. 85
     5.5. Parametreleri Değer İle Veya Referans İle Gönderme ................................................. 85
     5.6. Alias Kullanımı ............................................................................................................ 85
     5.7. Esnek Parametre Türleri ............................................................................................... 86
     5.8. Parametre Olarak String Gönderme .............................................................................. 86
     5.9. Parametre Olarak Dizi Gönderme ................................................................................ 87
     5.10. Kullanıcı Tarafından Tanımlanmış Türlerin Kullanımı .............................................. 87
     5.11. DLL Yordamlarına Fonksiyon Göstergelerini Parametre Olarak Gönderme ............. 88
     5.12. Diğer Türlerin Parametre Olarak Gönderilmesi ......................................................... 88
     5.13. C Tanımlarını Visual Basic Tanımlarına Dönüştürme ............................................... 88
     5.14. C Veri Türü Visual Basic İçinde Tanımı .................................................................... 89
6. ACTIVEX İSTEMCİLERİ YARATMA ............................................................................. 91
     6.1. Bileşen Nesne Modeli (COM-Component Object Mofel) ............................................ 91
     6.2. Otomasyonun Gerçekleştirilmesi .................................................................................. 91
     6.3. Activex Bileşenlerinin Özellikleri ................................................................................ 92
     6.4. Activex Bileşenlerinin VB İçinde Kullanımı ................................................................ 94
     6.5. Activex Bileşenleri İle İletişim Kurma ......................................................................... 97
     6.6 Microsoft Excel’i Bileşen Olarak Kullanan Bir Program .............................................. 98
7. ACTIVEX KOD BİLEŞENLERİNİ YARATMA ............................................................. 101
     7.1. Giriş ............................................................................................................................ 101
     7.2. Visual Basic İle Nesne Yaratma ................................................................................. 102
     7.3 Activex Kod Bileşeni Projelerinin Tasarlanması ve Gerçekleştirimi .......................... 105
              7.3.1. Dış-Bileşenler ............................................................................................ 105
              7.3.2. İç-Bileşenler .............................................................................................. 109
     7.4. Activex Kod Bileşenlerinin Test Edilmesi ................................................................. 112

                                                                      1
       7.5. Bileşenlerin İçinde Olay Kullanımı. ........................................................................... 116
       7.5. Nesneler İçin Arayüz Tanımlama. .............................................................................. 116
       7.6. Kod Bileşenlerinin Diğer Özellikleri. ......................................................................... 118
8. ACTIVEX KONTROL NESNESİ YARATMA ................................................................ 119
     8.1. ActiveX Control Nesnesinin Yaratılması ................................................................... 119
     8.2. Bir UserControl Nesnesinin Temel Olayları .............................................................. 121
     8.3. Kontrol Nesnesine Bir Caption Özelliği Ekleme ........................................................ 123
     8.4. UserControl Nesnesinin Olayları ................................................................................ 124
     8.5. UserControl Nesnesi İçin Olay Tanımlama ................................................................ 125
     8.6. UserControl Nesnesine Property Page Ekleme........................................................... 126
     8.7. Control Interface Wizard Kullanarak Kontrol Yaratma ............................................. 128
     8.8. Kontrol Nesnesinin Derlenmesi ve Dağıtılması ......................................................... 134
     8.9. Veritabanı İle İlişkilendirilebilir Kontrol Nesneleri Yaratma ..................................... 134
9. ACTIVEX BILEŞENLERİNİN WEB SAYFALARINDA KULLANILMASI .............. 143
     9.1. Giriş ............................................................................................................................ 143
     9.2. Kontrol Nesnelerinin Yüklenmesi .............................................................................. 143
     9.3. Kontrol Nesneleri İçin Makro (Script) Hazırlama ...................................................... 146
     9.4. Güvenlik ..................................................................................................................... 147
10. ACTIVEX DOKÜMANLARININ KULLANILMASI ................................................... 148
     10.1. Giriş .......................................................................................................................... 148
     10.2. Activex Doküman Projesi ......................................................................................... 148
     10.3. Çoklu Doküman Kullanımı ...................................................................................... 149
     10.4. Kullanıcı Arayüzü..................................................................................................... 150
11. INTERNET UYGULAMALARI YARATMA ................................................................ 152
     11.1. Winsock Control Nesnesi Kullanımı ........................................................................ 152
     11.2. İnternet Transfer Control Nesnesi Kullanımı ........................................................... 154
     11.3. Web Browser Kontrol Nesnesi Kullanımı ................................................................ 158
     11.4. İnternet Explorer İle Otomasyonun Kullanılması ..................................................... 159
     11.5. Kişisel Web Sunumcuları ......................................................................................... 160
12.UYGULAMA PROGRAMLARI İÇİN SETUP HAZIRLAMA ..................................... 163
13. ÇEŞİTLİ VİSUAL BASİC BİLEŞENLERİ .................................................................... 166
     13.1. Takvim (Calendar.ZIP) ............................................................................................ 166
     13.2. MCDBCombo - Multi Column DB Combo (MCDBCombo.ZIP)............................ 167
     13.3. Editör (Editor.ZIP).................................................................................................... 168
     13.4. FORMATLI Tarih Girişi (f_date.ZIP)...................................................................... 169
     13.5. Formatlı Para Girişi (f_money.ZIP).......................................................................... 170
     13.6. Hesap Makinesi (Calc.ZIP) ...................................................................................... 171
     13.7. List of Value (LOV) (Lov.ZIP) ................................................................................ 172
     13.8. Resim Kutusu (Scrool.ZIP) ...................................................................................... 173
     13.9. Formatlı Tarih Girişi (Takvim ile birlikte) (datebox.ZIP) ........................................ 174
14.VISUAL BASIC İLE BİLEŞEN HAZIRLAMA .............................................................. 175




                                                                     2
1. VISUAL BASIC 5 İLE PROGRAMLAMAYA GENEL BİR BAKIŞ

1.1. Visual Basic 5 İle Yazılım Geliştirme

Visual Basic 5 ilk açıldığında görülen New Project penceresi Visual Basic 5 ile neler
yapılabileceğinin bir özeti gibidir.

   Standart EXE:
      Normal bir uygulama yazılımı geliştirmek için kullanılır. Buna örnek olarak, bir
      kütüphane otomasyonu sistemi, adres etiket programı gibi yazılımlar verilebilir.

   ActiveX EXE:
      Başka programların kendi verilerine erişebilmesine olanak tanıyan programlar
      geliştirmek için kullanılır. Bu programlar işlem dışı sunucular olarak da
      adlandırılırlar, çünkü bu programların kendi işlem kesimleri vardır. Activex EXE
      programlar kendi işlevlerinden yararlanan programlardan ayrı bir program olarak
      çalışırlar.

   ActiveX DLL:
      Başka programlar tarafından kullanılabilen fonksiyon ve yordam kümelerini
      içeren kütüphanelerdir. DLL dosyaları işlem içi sunucular olarak da
      adlandırılırlar. ActiveX DLL dosyalar kendi işlevlerinden yararlanan
      programlarla aynı bellek alanında işlem görürler. ActiveX EXE programlardaki
      gibi ayrı bir program olarak çalıştırılmazlar.

   ActiveX Control:
      Bir programa eklemek için kullanıcının ihtiyaç duyduğu kontrol nesnelerini
      kendisinin tasarlayıp gerçekleştirmesi için kullanılır. Visual Basic programlama
      sisteminde iki tür kontrol nesnesi bulunur. Bunlar içsel kontrol nesneleri ve
      ActiveX kontrol nesneleridir. İçsel kontrol nesneleri Visual Basic açıldığında araç
      kutusunda görülen nesnelerdir. ActiveX control nesneleri araç kutusuna
      eklenebilen kullanıcıya özel kontrol nesneleridir.

   ActiveX Document DLL:
      Web sayfalarında kullanılmak üzere doküman hazırlamak için kullanılır. Bu
      dokümanlar bir web browser kullanılarak gösterildiğinde içerdiği işlevlerin yer
      aldığı bir kütüphaneye ihtiyaç duyarlar. İhtiyaç duyulan bu işlevler ActiveX
      Document DLL kütüphanelerinde bulunur. Bu kütüphanelerdeki işlevler işlevi
      kullanan dokümanla aynı bellek alanında çalıştığı için bunlar işlem içi
      bileşenlerdir.

   ActiveX Document EXE:
      ActiveX Document DLL ile aynıdır. Farklı olan kesim, içerdiği işlevlerin işlem
      dışı olarak çalışmasıdır. İşlem içi bileşenler daha hızlı çalışma özelliğine sahiptir.

   ADD IN:
     Visual Basic ortamına bazı işlemlerin otomatikleştirilmesi için eklenebilen bir
     bileşen yaratmak için kullanılır.




                                                3
   VB Application Wizard:
     Programın bir kısmını otomatik olarak üretmek için kullanılan bir bileşendir. Bir
     çok seçeneği sayesinde programın kullanıcı arabiriminin çoğunu otomatik olarak
     üretir.

   Visual Basic ile yapılabilecekler kısaca yukarıda belirtildiği gibidir.

Bir uygulama geliştirirken önce geliştirilecek olan uygulamanın bunlardan hangisi ile
yapılabileceğine bakmak gerekir. Uygulama yazılımları genellikle Standart EXE türündedir.

Şimdi Visual Basic ile Uygulama Yazılımı geliştirmeyi, kullanıcı arayüzü tasarımını, kod
yazmayı, girilen verilerin doğruluğunu kontrol etmeyi ve hataları ele almayı tekrar gözden
geçirmek için bir örnek tanımlayalım.


Örnek: Wordpad programına benzeyen fakat çoklu doküman arayüzüne sahip bir metin
yazma programı gerçekleştirelim.


   1. Kullanıcı Arayüzü Gerçekleştirimi

      Yeni bir proje yaratın ve Project menüsünden bir MDI form ekleyin. MDI form
      kullanmak bize birden fazla dosyayı aynı anda açabilmeyi sağlayacak. MDI formu
      programın temel penceresi, diğer formlar da açılan dosyaların gösterildiği pencereler
      olacaktır. Burada dosyaların gösterildiği formlardan sadece biri yaratılacak, diğerleri
      kodun içinden gerektikçe yaratılacaktır. Formların isimlerini ve Caption özelliklerini şu
      şekilde değiştirin:

       Bileşen                    Özellik                        Değer
       MDIForm                    Name                           frmANA
                                  Caption                        MetinYaz
       Form1                      Name                           frmDok
                                  Caption                        isimsiz
                                  MDIChild                       True

      FrmDok üzerine bir metin kutusu yerleştirin:

       Bileşen                    Özellik                        Değer
       TextBox                    Name                           txtDok
                                  Text
                                  Multiline                      True
                                  ScrollBars                     2-vertical




                                                 4
Başlangıç olarak aşağıdaki kodu frmAna formunun kod kesimine ekleyin:

   Option Explicit

   Dim frmMetin As New frmDok

   Private Sub MDIForm_Load()
       frmMetin.Show
   End Sub

   Startup Object: frmAna
   Project Name: metinyaz

Programı çalıştırdığınızda aşağıdaki ekran görüntüsü çıkacaktır.




                 Şekil 1.1. Metinyaz-ilk çalıştırma

Formların icon özelliklerini aşağıdaki gibi düzeltin:

   frmAna: note03.ico
   frmDok note07.ico

Bir formun icon özelliği formun köşesinde yer alan simgeyi belirler.
Çalışma esnasında gerekli olabilecek form sayısı önceden belli olmadığı için yeni
dokümanlar için çalışma esnasında form yaratmak gerekir. Bunun için yukarıdaki kodu
frmAna formundan silip yerine aşağıdaki kodu ekleyin.

   Option Explicit

   Private Sub MDIForm_Load()
       FormEkle
   End Sub

   Private Function FormEkle() As Form
       Set FormEkle = New frmDok
       FormEkle.Show vbModeless
   End Function

Böylece istenilen sayıda form eklemek mümkün hale geldi. Bir form eklemek için
FormEkle fonksiyonunu çağırmak yeterlidir.


                                         5
   Program çalıştırılıp metin penceresi büyütüldüğünde içindeki metin kutusunun birlikte
   büyümediği görülür. Metin kutusunun da form ile beraber büyümesini sağlamak için
   formun Resize olayına aşağıdaki kodu yazmak gerekir.

      Private Sub Form_Resize()
          Me.txtDok.Top = 0
          Me.txtDok.Left = 0
          Me.txtDok.Width = Me.ScaleWidth
          Me.txtDok.Height = Me.ScaleHeight
      End Sub

   Program çalıştığında ekranı ortalaması ve belirli bir büyüklükte çıkması için aşağıdaki
   kodu MDIForm_Load olay yordamının başına ekleyin.

      Me.Height = Screen.Height * 0.75
      Me.Width = Screen.Width * 0.75
      Me.Move (Screen.Height - Me.Height) / 2, _(Screen.Width - Me.Width) / 2

   Şimdi program çalıştırıldığında daha güzel bir ekran görünümüne sahip olduğu
   görülecektir.


2. Menü Ekleme, Dosya Menüsü:

   Programın genel iskeletini oluşturduktan sonra, biraz işlerlik kazandıralım. Bunun için
   önce bir menü eklemek gerekir. Menüler kullanım kolaylığı açısından program
   geliştirirken sık başvurulan öğelerdir.

   Aşağıdaki menüyü frmAna formuna ekleyin.

      Eklenecek Menüler:

     Dosya                       (mnuDosya)
     &Yeni                       (mnuYeni)                  Ctrl+Y
     &Aç                         (mnuAc)                    Ctrl+A
     &Kapat                      (mnuKapat)                 Gri
     -                           (mnuDosyaCiz1)
     Kayde&t                     (mnuKaydet)                Gri
     Ye&ni Adla Kaydet           (mnuYeniAd)                Ctrl+N Gri
     -                           (mnuDosyaCiz2)
     Yazdirma Aya&ri             (mnuYAyar)
     Ya&zdir                     (mnuYazdir)                Ctrl+Z Gri
     -                           (mnuDosyaCiz3)
     Cikis                       (mnuDosyaCikis)
     Düzen                       (mnuDuzen)
     &Kes                        (mnuKes)                   Ctrl+X Gri
     K&opyala                    (mnuKopyala)               Ctrl+C Gri

                                           6
  &Yapistir                  (mnuYapistir)             Ctrl+V Gri
  &Sil                       (mnuSil)                  Del Gri
  -                          (mnuDuzenCiz1)
  &Tümünü Seç                (mnuTumunuSec)            Gri
  Zaman/&Tarih               (mnuTarih)                F5 Gri
  Yardim                     (mnuYardim)
  MetinYaz Hakkinda          (mnuMetinYazH)


Dosya menüsü için aşağıdaki kodu frmAna formuna ekleyin.

   Public Sub MenuGunle()
      Dim bulundu As Boolean
      Dim i As Integer
      For i = 0 To Forms.Count - 1
          If Forms(i).Name = "frmDok" Then
              If Forms(i).kapat = False Then
                  bulundu = True
                  Exit For
              End If
          End If
      Next i
      mnuKapat.Enabled = bulundu
      mnuKaydet.Enabled = bulundu
      mnuYeniAd.Enabled = bulundu
      mnuYazdir.Enabled = bulundu
   End Sub

   Private Sub mnuCikis_Click()
       Unload Me
   End Sub

   Private Sub mnuKapat_Click()
       Unload frmAna.ActiveForm
   End Sub

   Private Sub mnuYeni_Click()
       FormEkle
   End Sub

Burada MenuGunle yordamı menülerin gri yapılmasını veya aktif hale getirilmesini
sağlar. Bunun için önce açık döküman olup olmadığını kontrol eder. Eğer dokümanlardan
en az bir tane varsa ve kapatılmak üzere değilse açık dokümanların bulunduğunu menü
elemanlarını aktif hale getirerek belirler.

Menüyü geçerli kılmak ve dokümanların değişip değişmediğini kontrol etmek dolayısıyla
kapatma işleminin yapılabileceğine karar vermek için için aşağıdaki kodu frmDok
formuna ekleyin.


                                        7
      Dim degisti As Boolean
      Public kapat As Boolean

      Private Sub Form_Load()
          frmAna.MenuGunle
      End Sub

      Private Sub Form_Unload(Cancel As Integer)
          If degisti Then
              Select Case MsgBox(Me.Caption & " 'deki metin degisti" _
              & vbCr & vbCr & " degisiklikler kaydedilsin mi", _
              vbExclamation Or vbYesNoCancel, frmAna.Caption)
                  Case vbYes 'kaydetme işlemleri
                  Case vbNo 'kapatma işlemine devam et
                  Case vbCancel
                  Cancel = True
              End Select
          End If
          kapat = Not Cancel
          frmAna.MenuGunle
      End Sub

      Private Sub txtDok_Change()
          degisti = True
      End Sub

   Burada form kapatılırken dokümanın değişip değişmediği kontrol edilir. Eğer değişiklik
   varsa kapatılmasına izin vermek için onay istenir. Bu işlem bir mesaj kutusu aracılığıyla
   yapılır.


3. Düzen Menüsü, Yardım Menüsü ve Pencere Menüsü:

   Düzen menüsündeki öğeleri aktif hale getirmek veya gri yapmak için MenuGunle
   fonksiyonuna aşağıdaki kod eklenmelidir.

      mnuTumunuSec.Enabled = bulundu
      mnuTarih.Enabled = bulundu
      If bulundu = False Then
          mnuKopyala.Enabled = False
          mnuKes.Enabled = False
          mnuSil.Enabled = False
          mnuYapistir.Enabled = False
      Else
          If frmAna.ActiveForm.txtDok.SelLength > 0 Then
               mnuKopyala.Enabled = True
               mnuKes.Enabled = True
               mnuSil.Enabled = True
          Else
               mnuKopyala.Enabled = False
               mnuKes.Enabled = False
               mnuSil.Enabled = False
                                           8
      End If
      If Clipboard.GetFormat(vbCFText) Then
          mnuYapistir.Enabled = True
      Else
          mnuYapistir.Enabled = True
      End If
   End If

Daha sonra frmDok formunun aşağıdaki olay yordamlarından MenuGunle yordamı
çağrılmalıdır.

   Private Sub Form_Activate()
       FrmAna.MenuGunle
   End Sub

   Private Sub txtDok_KeyUp(KeyCode As Integer, Shift As Integer)
       FrmAna.MenuGunle
   End Sub

   Private Sub txtDok_MouseUp(Button As Integer, Shift As Integer, _
   X As Single, Y As Single)
       FrmAna.MenuGunle
   End Sub

FrmDok için menu gunleme işlemi Form_Load olay yordamından kaldırılmalıdır. Menü
elemanlarını işler hale getirmek için aşağıdaki kodu frmAna formuna ekleyin

   Private Sub mnuKes_Click()
       Clipboard.SetText frmAna.ActiveForm.txtDok.SelText
       Sil
       MenuGunle
   End Sub

   Private Sub mnuKopyala_Click()
       Clipboard.SetText frmAna.ActiveForm.txtDok.SelText
       MenuGunle
   End Sub

   Private Sub mnuYapistir_Click()
       Dim metin As String
       Dim clipboardMetni As String
       Dim selStart As Long
       If Clipboard.GetFormat(vbCFText) Then
           If frmAna.ActiveForm.txtDok.selLength > 0 Then Sil
           metin = frmAna.ActiveForm.txtDok.Text
           selStart = frmAna.ActiveForm.txtDok.selStart
           clipboardMetni = Clipboard.GetText
           frmAna.ActiveForm.txtDok.Text = Left(metin, selStart) & _
           clipboardMetni & Right(metin, Len(metin) - selStart)
           frmAna.ActiveForm.txtDok.selStart = selStart
       Else
           MenuGunle
                                      9
      End If
   End Sub

   Private Sub mnuSil_Click()
       Sil
       MenuGunle
   End Sub

   Private Sub mnuTumunuSec_Click()
       frmAna.ActiveForm.txtDok.selStart = 0
       frmAna.ActiveForm.txtDok.selLength = _
       Len(frmAna.ActiveForm.txtDok.Text)
       MenuGunle
   End Sub

   Private Sub mnuTarih_Click()
       Dim metin As String
       Dim selStart As Long
       If frmAna.ActiveForm.txtDok.selLength > 0 Then Sil
       metin = frmAna.ActiveForm.txtDok.Text
       selStart = frmAna.ActiveForm.txtDok.selStart
       frmAna.ActiveForm.txtDok.Text = Left(metin, selStart) & _
       Now & Right(metin, Len(metin) - selStart)
       frmAna.ActiveForm.txtDok.selStart = selStart
       MenuGunle
   End Sub

Yardım menüsündeki MetinYaz Hakkında seçeneği için de aşağıdaki formu yaratın.




Bu formu gostermek için ilgili menü seçeneğine aşağıdaki kodu ekleyin.

   Private Sub mnuMetinYazH_Click()
       frmMetinYazH.Show vbModal
   End Sub

Şimdi frmAna formuna aşağıda belirtildiği gibi bir pencere menüsü ekleyin.

Pencere                     (mnuPencere)              WindowList
Yer&lestir                  (mnuYerlestir)
&Yatay Yerlestir            (mnuYatay)
                                       10
   &Dikey Yerlestir            (mnuDikey)
   Dü&zenle                    (mnuDuzenle)

   Bu menü oğeleri için aşağıdaki kodu frmAna formuna ekleyin.

      Private Sub mnuYerlestir_Click()
          frmAna.Arrange vbCascade
      End Sub

      Private Sub mnuDikey_Click()
          frmAna.Arrange vbTileVertical
      End Sub

      Private Sub mnuYatay_Click()
          frmAna.Arrange vbTileHorizontal
      End Sub

      Private Sub mnuDuzenle_Click()
          frmAna.Arrange vbArrangeIcons
      End Sub


4. Nesneye Yönelik Yaklaşım:

   Bu noktaya kadar      MetinYazma       programının   kullanıcı   arayüzü   tamamlanmış
   bulunmaktadır.

   Programın etkinliğini artırmak için Nesneye Yönelik bir yaklaşım kullanmak daha doğru
   olacaktır. Programın şu andaki haline bakılırsa doküman pencerelerini birbirinden
   ayırmak mümkün değildir. Programı Nesneye Yönelik yaklaşımla yeniden yazacak
   olursak, önce bir döküman sınıfı yaratmak gerekecektir. Adımları sırayla yazacak
   olursak:

   4.1.Dokümanlar için dokKume adlı bir küme (Collection) yaratın. Bunun için frmAna
   formunun başına aşağıdaki kodu ekleyin.

      Public dokKume As New Collection
      Public kumeIndeksi As Integer

   Bu kümeyi yok etmek için ise frmAna formunun MDIForm_Terminate olay yordamına
   aşağodaki satırı ekleyin.

      Set dokKume = Nothing

   4.2. Programa yeni bir sınıf ekleyip adını clsDok olarak değiştirin. Bu sınıfın kod
   kesimine aşağıdaki kodu ekleyin

      Private mtndegisti As Boolean
      Public kapat As Boolean
      Public dokIsim As String
      Public dokForm As frmDok
                                          11
4.3. clsDok sınıfı için degisti adlı bir Property yaratıp aşağıdaki kodu ekleyin.

    Public Property Get degisti() As Variant
       degisti = mtndegisti
    End Property

    Public Property Let degisti(ByVal vNewValue As Variant)
       mtndegisti = vNewValue
       If mtndegisti Then
           If Right(dokForm.Caption, 2) <> " *" Then
               dokForm.Caption = dokIsim & " *"
           End If
       Else
           If Right(dokForm.Caption, 2) = " *" Then
               dokForm.Caption = dokIsim
           End If
       End If
    End Property

4.4. FrmDok formundaki degisti ve kapat değişken tanımlarını kaldırın ve yerine
aşağıdaki kodu yazın.

    Public objDok as new clsDok
    Dim kumeNo As Integer

    Private Sub Form_Load()
        frmAna.dokKume.Add objDok, CStr(frmAna.kumeIndeksi)
        kumeNo = frmAna.kumeIndeksi
        frmAna.kumeIndeksi = frmAna.kumeIndeksi + 1
        Me.Caption = Me.Caption & CStr(frmAna.kumeIndeksi)
        Set objDok.dokForm = Me
        objDok.dokIsim = Me.Caption
    End Sub

4.5. Daha sonra degisti ve kapat değişkenlerine yapılan tüm erişimleri objDok.degisti
veya objDok.kapat olarak değiştirin.

4.6. frmDok formunun Form_Unload olay yordamının sonuna aşağıdaki kodu ekleyin:

    If Cancel = False Then
        frmAna.dokKume.Remove CStr(kumeNo)
        Set objDok = Nothing
    End If

4.7. Doküman içinde bir metni aramak için frmAna formunda Duzen menüsüne aşağıdaki
menü seçeneğini ekleyin.

-                      (mnuDuzenCiz2)

&Bul                   (mnuBul)                        Ctrl+B Gri


                                         12
Daha sonra bu seçeneğin aktif veya gri yapılmasını denetlemek için frmAna formundaki
MenuGunle yordamının Düzen menüsü için yapılan işlemler kısmına aşağıdaki satırı
ekleyin.

   mnuBul = bulundu

Arama işlemi için aşağıdaki elemanları içeren ve görünüşü verilmiş olan formu
hazırlayın.


Bileşen             Özellik                      Değer
Form                Name                         frmBul
                    Borderstyle                  3-Fixed Dialog
                    ControlBox                   False
Label               Name                         lblBul
TextBox             Name                         txtBul
CommandButton       Name                         cmdBul
                    Default                      True
CommandButton       Name                         cmdIptal
                    Cancel                       True




Bu formu göstermek için frmAna formundaki mnuBul_Click olay yordamına aşağıdaki
satırı ekleyin.

   frmBul.Show vbModal

Ayrıca frmBul formuna aşağıdaki kodu ekleyin.

   Private Sub cmdBul_Click()
       Dim dokObj As clsDok
       Dim sonuc As Integer
       For Each dokObj In frmAna.dokKume
          sonuc = InStr(dokObj.dokForm.txtDok.Text, txtBul.Text)
          If sonuc > 0 Then
              dokObj.dokForm.ZOrder
              dokObj.dokForm.txtDok.selStart = sonuc - 1
              dokObj.dokForm.txtDok.selLength                =
              Len(txtBul.Text)
              Exit For
          End If
       Next dokObj
                                     13
          Unload Me
      End Sub
      Private Sub cmdIptal_Click()
          Unload Me
      End Sub


5. Microsoft Common Dialog Control nesnelerinin kullanılması, araç çubuğu ve geri
   kalan menü oğeleri.

   Bu kısımda Dosya menüsünde eksik kalmış olan doküman açma ve kaydetme işlemleri,
   Duzen menüsüne eklenecek olan Font ve Renk seçenekleri ile bir araç çubuğu MetinYaz
   programına dahil edilecektir.

   Şimdi yapılacak işlemleri adımlar halinde gerçekleştirelim.

   5.1. frmDok doküman formundaki metin kutusunu RICHTEXTBOX ile değiştirin. Bunu
   yapmaktaki amaç, metin kutusunun getirdiği kısıtlamaları ortadan kaldırmaktır. Eklenen
   RICHTEXTBOX metin kutusunun aşağıda belirtilen özelliklerini belirtildiği gibi
   değiştirin.

      Name txtDok
      Apperance 0-Flat
      BorderStyle 0-No Border

   5.2. frmAna formuna bir CommonDialog nesnesi yerleştirin.

   5.3. Dosya menüsünün Aç seçeneği için aşağıdaki kodu frmAna formuna ekleyin.

      Private Sub mnuAc_Click()
      Dim Cancel As Boolean
          On Error GoTo hata
          Cancel = False
          CommonDialog1.Filter = "Metin dosyalari|*.txt|" & _
          "Tum dosyalar|*.*|Rich Text dosyalari|*.rtf"
          CommonDialog1.CancelError = True
          CommonDialog1.Flags = cdlOFNHideReadOnly Or _
          cdlOFNFileMustExist
          CommonDialog1.ShowOpen
      If Not Cancel Then
          If UCase(Right(CommonDialog1.filename, 3) )= "RTF" Then
              frmAna.ActiveForm.txtDok.LoadFile _
              CommonDialog1.filename, rtfRTF
          Else
              frmAna.ActiveForm.txtDok.LoadFile _
              CommonDialog1.filename, rtfText
          End If
          frmAna.ActiveForm.txtDok.dokIsim = _
          CommonDialog1.filename
          frmAna.ActiveForm.txtDok.degisti = False
      End If
      Exit Sub
                                           14
hata:
   Select Case Err.Number
       Case cdlCancel: Cancel = True
       Case rtfInvalidFileFormat:
       Cancel = MsgBox("Dosya açma hatasi", vbExclamation _
       Or vbOKOnly, "Dosya Açma")
       Resume Next
   End Select
   End Sub

Burada önce windows’un dosya açma diyalog kutusu kullanılarak bir dosya adı belirleniyor,
belirlenen dosya türüne göre RICHTEXTBOX nesnesinin bir metodu olan LOADFILE
kullanılarak dosya içeriği metin kutusuna yazılır.

5.4. Dosya menüsünün Kaydet seçeneği için aşağıdaki kodu ekleyin.

   Private Sub mnuKaydet_Click()
      With frmAna.ActiveForm
          If .objDok.dokIsim = "isimsiz" Then
               mnuYeniAd_Click
          Else
               If UCase(Right(.objDok.dokIsim, 3)) = "RTF" Then
                   .txtDok.SaveFile .objDok.dokIsim, rtfRTF
               Else
                   .txtDok.SaveFile .objDok.dokIsim, rtfText
               End If
               .objDok.degisti = False
          End If
      End With
   End Sub

Burada eğer doküman yeni yazılmış bir doküman ise bir isim verileceğinden Yeni Adla
Kaydet menü seçeneği çağrılmaktadır.

5.5. Dosya menüsünün Yeni Adla Kaydet menü seçeneği için aşağıdaki kodu ekleyin.

   Private Sub mnuYeniAd_Click()
      Dim Cancel As Boolean
      On Error GoTo hata
      Cancel = False
      CommonDialog1.DefaultExt = ".rtf"
      CommonDialog1.Filter = "Metin dosyalari|*.txt|" & _
      "Tum dosyalar|*.*|Rich Text dosyalari|*.rtf"
      CommonDialog1.CancelError = True
      CommonDialog1.Flags = cdlOFNHideReadOnly Or _
      cdlOFNOverwritePrompt
      CommonDialog1.ShowSave
      If Not Cancel Then
          If UCase(Right(CommonDialog1.filename, 3)) = "RTF" Then
              frmAna.ActiveForm.txtDok.SaveFile _
              CommonDialog1.filename, rtfRTF
                                         15
           Else
               frmAna.ActiveForm.txtDok.SaveFile _
               CommonDialog1.filename, rtfText
           End If
           frmAna.ActiveForm.objDok.dokIsim = _
           CommonDialog1.filename
           frmAna.ActiveForm.objDok.degisti = False
       End If
       Exit Sub
       hata:
       If Err.Number = cdlCancel Then
           Cancel = True
           Resume Next
       End If
    End Sub

 5.6. Düzen menüsüne aşağıdaki menü seçeneklerini ekleyin.

-                                      (mnuDuzenCiz3)
&Font                                  (mnuFont)
&Renk                                  (mnuRenk)

 Daha sonra bu seçeneklerin aktif veya gri yapılmasını denetlemek için frmAna formundaki
 MenuGunle yordamının Düzen menüsü için yapılan işlemler kısmına aşağıdaki satırları
 ekleyin.

    mnuFont = bulundu
    mnuRenk = bulundu

 5.7. Düzen menüsü Font ve Renk seçenekleri için aşağıdaki kodu ekleyin.

    Private Sub mnuFont_Click()
       On Error GoTo fonthata
       CommonDialog1.Flags = cdlCFBoth Or cdlCFEffects
       CommonDialog1.ShowFont
       With frmAna.ActiveForm.txtDok
           .SelFontName = CommonDialog1.FontName
           .SelFontSize = CommonDialog1.FontSize
           .SelBold = CommonDialog1.FontBold
           .SelItalic = CommonDialog1.FontItalic
           .SelStrikeThru = CommonDialog1.FontStrikethru
           .SelUnderline = CommonDialog1.FontUnderline
           .SelColor = CommonDialog1.Color
       End With
       fonthata:
    End Sub
    Private Sub mnuRenk_Click()
       On Error GoTo renkhata
       CommonDialog1.Flags = cdlCCFullOpen
       CommonDialog1.ShowColor
       frmAna.ActiveForm.txtDok.SelColor = CommonDialog1.Color
       renkhata:
                                           16
   End Sub

  5.8. frmAna formuna bir araç çubuğu (ToolBar) ve bir ImageList ekleyin. ImageList resim
       listesine aşağıda görülen resimleri GRAPHICS\BITMAPS\TLBR_95 dizini içinden
       ekleyin ve sırasıyla araç çubuğuna yerleştirin.




Yukarıda belirtilen araç çubuğu düğmelerinin anahtar (Key) değerlerini sırasıyla “Yeni”,
“Ac” ve “Kaydet” olarak değiştirin.

Kaydet düğmesini aktif hale getirmek veya gri yapmak için aşağıdaki satırı MenuGunle
yordamının dosya menüsü ile ilgili kısmına ekleyin.

   Toolbar1.Buttons(“Kaydet”).Enabled = bulundu

Daha sonra aşağıdaki kodu frmAna formuna ekleyin.

   Private Sub Toolbar1_ButtonClick(ByVal Dugme As Button)
      Select Case Dugme.Key
          Case "Yeni": mnuYeni_Click
          Case "Ac": mnuAc_Click
          Case "Kaydet": mnuKaydet_Click
      End Select
   End Sub


  5.9. frmAna formuna bir Durum Çubuğu (StatusBar) ekleyin. Bu durum çubuğuna aşağıda
       belirtilen özelliklere sahip 7 tane kesim ekleyin.

 Inde   Key          Alignment     Style             Bevel         AutoSize
 x
 1      Metin        0 - Left      0 - Text          1 - Inset     1 - Spring
 2      Caps         1 - Center    1 - CAPS          1 - Inset     2 - Content
 3      NumLock      1 - Center    2 - NUM LOCK      1-Inset       2 - Content
 4      Ins          1 - Center    3 - INS           1 - Inset     2 - Content
 5      Scroll       1 - Center    4 - SCROLL        1 - Inset     2 - Content
 6      Time         1 - Center    5 - Time          1 - Inset     2 - Content
 7      Date         1 – Center    6 - Date          1 - Inset     2 - Content

Aşağıdaki kodu frmAna formuna ekleyin.

   Public Sub SatirNo()
      Dim sNo As Integer
      With frmAna.ActiveForm.txtDok
          If .selStart > 0 Then
               sNo = .GetLineFromChar(.selStart)
          End If
          frmAna.StatusBar1.Panels("Metin").Text = "SATIR: " _

                                           17
            & CStr(sNo + 1)
         End With
      End Sub

   Daha sonra bu yordamı frmDok formunun aşağıdaki yordamlarından çağırın.

      Private Sub Form_Activate()
         frmAna.MenuGunle
         frmAna.SatirNo
      End Sub
      Private Sub txtDok_SelChange()
         frmAna.SatirNo
      End Sub

   Bunlara ek olarak aşağıdaki satırı frmDok formunun Form_Unload yordamının sonundaki If
   koşul deyiminin içine de satır numarasını temizlemek için aşağıdaki satırı yazın.

      frmAna.StatusBar1.Panels("Metin").Text = ""


   6. Yazdırma ayarları ve Yazdırma:

Programın eksik kalan kısmı yazdığımız metnin yazıcıdan çıkarılmasıdır. Şimdi programın bu
kısmını adımlar halinde gerçekleştirelim.

     6.1. Dosya menüsü Yazdırma Ayarı seçeneği için aşağıdaki kodu frmAna formuna
          ekleyin.

      Private Sub mnuYAyar_Click()
         CommonDialog1.Flags = cdlPDPrintSetup
         CommonDialog1.PrinterDefault = True
         CommonDialog1.ShowPrinter
      End Sub

   6.2. Dosya Menüsünün Yazdır seçeneği için aşağıdaki kodu frmAna formuna ekleyin.

      Private Sub mnuYazdir_Click()
         Dim cancel As Boolean
         Dim kopya As Integer
         On Error GoTo yazhata
         cancel = False
         CommonDialog1.CancelError = True
         CommonDialog1.PrinterDefault = True
         CommonDialog1.Copies = 1
         CommonDialog1.ShowPrinter
         If cancel = False Then
             For kopya = 1 To CommonDialog1.Copies
                 Printer.Print frmAna.ActiveForm.txtDok.Text
                 Printer.EndDoc
             Next kopya
         End If
         Exit Sub
                                            18
          yazhata:
          If Err.Number = cdlCancel Then
              cancel = True
              Resume Next
          End If
       End Sub

Programın çalışır haldeki son durumu aşağıdaki gibi olacaktır.




                                               19
2. DATA CONTROL NESNESİNİN KULLANIMI


2.1. Visual Basic 5 İle Yazılım Geliştirme

Bütün uygulamalar, çok değişik türlerdeki yapısal bilgilere ihtiyaç duyar. Bu uygulamalar,
muhasebe uygulamaları, bilimsel hesaplamalar yapan programlar, müşteri bilgilerine erişen
programlar v.b. olabilir. Microsoft Visual Basic içindeki Data Access kullanıcılara uygulamada
kullanılan verileri yönetebilmek için kullanılması gereken yapısal veritabanı sistemlerini,
uygulamaların içinden yaratmak ve kullanmak için gerekli araçları sağlar.

Bu araçlar şunlardır:

   1. Microsoft Jet Database Engine (Jet veritabanı motoru)
   2. Data Control (Veri Tabanı kontrol nesnesi)
   3. Data Access Object (DAO) –veri erişim nesnesi- programlama arabirimi.

Veri erişim nesneleri kullanarak, veritabanı yaratan veya var olan bir veri tabanlarına değişik
biçimlerde erişimi sağlayan programlar yapmak mümkündür. Aşağıdaki veri tabanı biçimlerine
veri erişim nesneleriyle erişmek mümkündür;

   Microsoft Access
   Mtrieve
   dBASE
   Microsoft FoxPro
   Paradox
   Open Database Connectivity (ODBC) client/server veritabanları (örneğin Microsoft SQL server veritabanı)

Yapısal veri tabanı sistemlerini yaratabilme ve bunlara erişebilme olanağı kullanıcıya
programlama yaparken birçok kolaylık ve avantaj sağlar. Bu avantajlar şunlardır:

      Var olan veritabanı sistemlerine erişen programlar yazmak
      Uygulamanın verilerini diğer programlarla paylaşmasını sağlamak
      Programı basitleştirmek ( Alt düzey kütük işlemleriyle uğraşmak zorunda olmamak)

Visual Basic’de Jet veri tabanı motoruyla iletişim kurmak için iki tane yöntem vardır: Data
Control nesnesi ve veri irişim nesneleri. Data Control nesnesi veritabanına programlamaya gerek
duymadan sınırlı bir erişim sağlar. DAO modeli ise veri tabanı üzerinde tam bir kontrol
sağlamaya yardımcı olan bir programlama arabirimi sağlar. Bu iki yöntem birbirini dışlamaz.
Yani bir uygulamada her iki yöntemin de kullanılması gereken durumlar oluşabilir.

DAO modeli ilişkisel veri tabanı sistemlerinin yapısını modelleyen bir nesne kümesinden oluşur.
Bu nesneler, veritabanı yaratma, tablo tanımlama, alan ve indeks tanımlama, tablolar arasında
ilişki tanımlama ve veritabanını sorgulama vb. gibi işlemleri gerçekleştirmey, sağlayan birçok
özellik ve metot sağlar.

Jet veri tabanı motoru, yukarıda belirtilen işlemleri veri tabanı dosyaları üzerinde fiziksel
işlemlere dönüştürür ve ayrıca desteklenen veritabanları ile iletişimi sağlar.

Visual Basic ile veritabanı programlama yapılırken veri erişim nesnelerinin yaratılması ön plana
çıkar. Bu nesneler Database, TableDef, Fiels ve Index gibi nesneleridir. Bu nesnelerin özellik ve
metotları kullanılarak veritabanı üzerinde işlemler yapılır. İşlemlerin sonuçlarını Visual Basic
                                                     20
formları üzerinde görmek için de sınırlandırılmış (bound) ve sınırlandırılmamış(unbound)
kontrol nesneleri kullanılır.

Bu yaklaşım kod yazmayı basitleştirir ve uygulamayı veritabanının içsel yapısından ve verilerin
getirilme mekanizmalarından soyutlar. Böylece uygulamayı geliştiren kişiye büyük bir esneklik
sağlanmış olur. Ayrıca veritabanının türü değiştiğinde bile yazılan kodun bunu destelemesi için
çok küçük değişiklikler yapmak yeterli olacağından sağlanan esnekliğin boyutunun daha da
büyük olduğu görülmektedir. Veri erişim nesneleri kullanarak farklı türden veri tabanlarından
tabloların birleştirilmesi mümkündür.

Visual Basic tarafından DAO ve Jet veritabanı motoru kullanılarak erişim yapılabilen üç
veritabanı kategorisi vardır:

   1. Visual Basic veri tabanları: Bunlar Microsoft Access veritabanı ile aynı biçimi kullanır.
      Bu veritabanlarına erişim ve üzerinde yapılacak işlemler Jet veritabanı motoru
      aracılığıyla doğrudan yapılabilir. Jet veritabanı motoru bu veritabanları üzerinde önemli
      derecede bir esneklik sağlar.

   2. Dış veri tabanları (External Databases): ISAM (Indexed Sequential Access Method)
      biçiminde olan veri tabanları üzerinde Visual Basic ile işlem yapmak mümkündür. Bu
      veritabanı biçimleri şunlardır: Btrieve, dBASE III, dBASE IV, Microsoft FoxPro 2.0 ve
      2.5, Paradox 3.x ve 4.0, Microsoft Excel, Lotus 1-2-3.

   3. ODBC veritabanları: Bunlar ODBC standardına uyan client/server yapısındaki
      veritabanlarıdır. Bu tür veritabanlarına bir örnek olarak Microsoft SQL Server verilebilir.
      Visual Basic ile client/server uygulamaları yaratmak için veri erişim nesnesinin
      ODBCDirect modunu kullanmak gerekir. Böylece komutlar doğrudan dış sunucuya
      (server) iletilir ve orada çalıştırılır. Yani Jet veritabanı motoru devreden çıkarılır.



2.2. Data Control Nesnesi Kullanarak Veritabanına Erişim.

Data Control nesnesi kullanarak, değişik türdeki çoğu veritabanındaki bilgileri görüntülemek,
değiştirmek ve bu veritabanlarına yeni bilgiler eklemek mümkündür. Data Control nesnesi
kullanılarak üzerinde işlem yapılabilen veri tabanları şunlardır: Microsoft Access, Btrieve,
dBASE, Microsoft FoxPro®, ve Paradox. Bunların dışında Microsoft Excel, Lotus 1-2-3, ve
standart ASCII metin kütüklerine de Data Control nesnesi kullanılarak erişmek mümkündür.
Ayrıca Data Control nesnesi Microsoft SQL server veya Oracle gibi ODBC veritabanlarının
verilerine uzak (remote) erişimi de sağlamaktadır.

Data Control nesnesi veri erişimini Jet veritabanı motoru kullanarak gerçekleştirir. Bu veritabanı
motoru Microsoft Access ile eşdeğer bir veritabanı yönetimi sağlar. Data Control nesnesi
kullanarak fazladan bir kod yazmaya gerek duymaksızın veritabanı erişimi mümkündür. Şimdi
Data Control nesnesi kullanımını örneklerle açıklayalım.



Örnek: Data Control nesnesi kullanımı.

Bu örnekte hazır bir veri tabanına Data Control nesnesi kullanılarak nasıl erişim sağlandığı
gösterilecektir. Şimdi bu işlemi adımlar halinde gösterelim.
                                               21
ADIM 1:Visual Basic ile beraber gelen BIBLIO.MDB veritabanındaki Authors tablosunu
kullanalım. Authors tablosunun alanları aşağıdaki gibidir.


   Sütun                         Veri Türü                            Tanımı
   Au_ID                         Long Integer                         Asıl Anahtar
   Author                        Text                                 Yazarın Adı
   Year Born                     Integer                              Yazarın Doğum yıl


ADIM 2 : Standart EXE türünden yeni bir proje yaratın. Formun alt kısmına bir Data
Control nesnesi yerleştirin ve aşağıdaki özelliklere belirtilen değerleri verin.

   Nesne                         Özellik                               Değer
   Form                          Caption                               Yazarlar Tablosu
   Data Control                  Align                                 2-Align Bottom
                                 Name                                  datYazar

Data Control nesnesinin Connect özelliği data control nesnesinin kullanacağı veritabanının
türünü belirler. Properties penceresinden bu özellik değiştirilmeye çalışıldığında bir uyumlu
veritabanı listesi çıkar, bu listeden bağlanacak veritabanının türü seçilebilir. Bu örnek için
Connect değerini Access olarak değiştirin (zaten başlangıç değeri de budur).

Data Control nesnesinin DatabaseName özelliği kullanılacak veritabanının fiziksel dosya
ismini belirler. Bu özelliği değiştirmek için yanındaki düğmeye basın. Visual Basic ana
dizininden BIBLIO.MDB veritabanı dosyasını seçin.

Data Control nesnesinin RecordSet özelliği kullanılacak veritabanının kayıtları birarada ne
şekilde tuttuğunu belirler. Bu değer;

        -Table, sadece bir tabloya dayanan kayıt türü
        -Dynaset, birden fazla tabloyu kullanan sorgular
        -Snapshot, birden fazla tabloyu kullanan sorgular(kayıtlar değiştirilemez)

Bu örnek için RecordSet değerini 0-Table olarak değiştirin.
RecordSource özelliği : kullanılacak tabloyu belirler. Bu özelliği Authors olarak seçin.

BOFAction özelliği :      En baştaki tutanağa gelinmişse bundan sonra ne yapılacağını belirler. Alabileceği
değerler şunlardır:

MoveFirst :      Data Control nesnesinin en başta kalmasını sağlar.

BOF : Data Control nesnesinin en başta kalmasını, geri tuşunun kullanımını iptal etmesini ve Validation adlı
olay yordamının çağrılmasını sağlar. (Burada bu özelliğin değerini MoveFirst olarak değiştirin.)

EOFAction özelliği:       Eğer en sondaki tutanağa gelinmişse bundan sonra ne yapılacağını belirler.
Alabileceği değerler şunlardır.

MoveLast :       Data Control nesnesinin en sonda kalmasını sağlar.

EOF : Data Control nesnesinin en sonda kalmasını, ileri tuşunun kullanımını iptal etmesini ve Validation adlı
olay yordamının çağrılmasını sağlar.
                                                     22
AddNew :         Tabloya yeni bir tutanak ekler. Bu değer kullanılırken dikkatli olunmalıdır.Çünkü farkında
olmadan bir çok boş tutanak eklemeye neden olabilir.(Burada bu özelliği MoveLast olarak değiştirin.)

ReadOnly özelliği :       True olduğunda tabloda değişiklik yapılması engellenmiş olur. Eğer RecordType
özelliği Snapshot seçilmişse bu özellik değiştirilemez.



ADIM 3 : Data Control nesnesi tarafından yaratılan kayıt kümesi herhangi bir kod yazmaya
gerek duyulmadan dolaşılabilir. Bu işlem Data Control nesnesinin üzerindeki düğmelerle
gerçekleştirilir.

Program çalıştırıldığında belirtilen tutanak kümesi (RecordSet) üzerinde dolaşılabilir, fakat
sonuçları herhangi bir şekilde form üzerinde gösterilmediğinden bu kullanıcı tarafından fark
edilmez.

ADIM 4 : Herhangi bir anda aktif olan tutanağı form üzerinde göstermek için formun
üzerine verileri göstermek için kullanılacak olan nesnelerin konması gerekir. Form üzerinde
veritabanı ile ilişkilendirilebilecek standart Visual Basic nesneleri şunlardır.

                    TextBox
                    ListBok
                    CheckBox
                    ImageControl
                    Label
                    PictureBox

Formun üzerine aşağıdaki gibi üç tane TextBox ve üç tane de Label yerleştirin.




        Bu formdaki elemanların özelliklerini de aşağıdaki tabloya göre düzenleyin.

          Nesne                        Özellik                         Değer
          TextBox                      DataSource                      datYazar
                                       DataField                       Au_ID
                                       Name                            txtYNo
          TextBox                      DataSource                      datYazar

                                                      23
                                DataField                   Author
                                Name                        txtYAd
        TextBox                 DataSource                  datYazar
                                DataField                   Year Born
                                Name                        txtDYil
        Label                   Caption                     Yazar No
                                Name                        lblYNo
        Label                   Caption                     Yazar ADI
                                Name                        lblYAd
        Label                   Caption                     Dogum YILI
                                Name                        lblDyil

   ADIM 5: Programı çalıştırın. Ekranda Yukarıdaki form görüntüsü çıkacaktır. Formda
   Görüleceği gibi tablonun ilk tutanağı ekrana gelmiştir. Şimdi Data Control nesnesi
   üzerindeki düğmelerle veritabanı tablosu üzerinde dolaşmak mümkündür.



2.3. Data Control Nesnesinin Olaylarını ve Metotlarını Kullanma

   Data Control nesnesinin de tüm nesneler gibi olay yordamları, metotları ve özellikleri
   vardır. Bunlar veri tabanı üzerinde işlem yapan uygulama yazılımları geliştirmeyi
   kolaylaştırır. Data kontrol nesnesinin olay yordamlarının ve metotlarının kullanımı için
   aşağıdaki örneği gerçekleştirelim.

   Örnek: Data Control Nesnesi kullanarak veritabanı üzerinde ekleme, silme, arama ve
   değiştirme işlemlerinin yapılması.

   Bu örnekte önce VB Aplication Wizard (uygulama sihirbazı) kullanarak bir şablon
   uygulama yaratalım. Bunun için yine BIBLIO.MDB veritabanının bu sefer Publishers
   tablosunu kullanalım. İşlemler aşağıda adımlar halinde sıralanmıştır.

   1.  Add-Ins menüsünden Application Wizard seçeneğini seçerek sihirbazı çalıştırın.
   2.  SDI seçeneğini seçin.
   3.  Clear All düğmesine basarak menüleri kaldırın.
   4.  Resource File kullanılmadığını belirtin.
   5.  Internet erişimi istenmediğini belirtin.
   6.  Standart formların hiçbirini istemediğinizi belirtin.
   7.  Bu aşamada Yes, create forms from my database seçeneğini seçip veritabanı türünü ve
       kullanacağınız veritabanı türünü belirleyin. Bu örnekte, veritabanı biçimi, Access ve
       veritabanı dosyası ise Visual Basic dizinindeki BIBLIO.MDB olarak belirlenmelidir.
   8. Listelenen tablolardan Publishers tablosunu seçin.
   9. Projenin ismini de YAYINEVI olarak değiştirin.
   10. Şimdi yeni yaratılmış olan projeden frmPublishers formu dışındaki formları silin.
   11. FrmPublishers formundan Grid butonunu ve bu düğmeye ait cmdGrid_Click kodunu
       silin.
   12. Project menüsünden Properties seçeneğini seçip başlangıç formu olarak frmPublishers
       formunu seçin. Üretilen kodu inceleyelim.

   Ekleme:

                                             24
Private Sub cmdAdd_Click()
    Data1.Recordset.AddNew
End Sub

AddNew metodu veritabanına tüm alanları boş bir tutanak ekler. Veri eklemek için
kontrolün en baştaki metin kutusuna geçmesini sağlamak için aşağıdaki satır bu yordamın
sonuna eklenmelidir.

    txtFields(0).SetFocus

Silme:
Private Sub cmdDelete_Click()
    With Data1.Recordset
         .Delete
         .MoveNext
         If .EOF Then .MoveLast
    End With
End Sub

Delete metodu tutanağı tablodan siler. Eğer silinen tutanak tek tutanak ise bir hata oluşur.
Bu hata oluştuğunda Data1 nesnesinin Data1_Error olayı çağrılır. Bu olay aşağıdadır.

Private Sub Data1_Error(DataErr As Integer, Response As Integer)
    MsgBox "Data error event hit err:" & Error$(DataErr)
    Response = 0
End Sub

Veri erişimi sırasında bir hata oluştuğunda bu olay çağrılır.

Refresh:
Private Sub cmdRefresh_Click()
    'sadece çok kullanıcılı uygulamalarda gereklidir
    Data1.Refresh
End Sub

Bu metod da aktif olan tutanağın yeniden oluşturulmasını sağlar.

Değiştirme:
Private Sub cmdUpdate_Click()
    Data1.UpdateRecord
    Data1.Recordset.Bookmark = Data1.Recordset.LastModified
End Sub

UpdateRecord metodu aktif olan tutanağın bilgilerini kaydeder. Yukarıda görülen
koddaki ikinci satır aktif tutanağın değişen tutanak olmasını sağlar. Bu satır yazılmazsa
aktif tutanak tablonun ilk tutanağı olur.

Bulma:

Bulma işleminin yukarıdaki gibi hazır bir metodu yoktur. Bu yüzden bu kodu kendimiz
yazmalıyız. Önce formu aşağı doğru bir miktar uzatın ve forma aşağıdaki nesneleri
ekleyin.

                                                   25
TextBox Name txtFind
CommanButton Caption &Find
Name cmdFind

Bu nesnelerden txtFind, aranacak olan yayınevinin ismini girmek için kullanılacak ve
cmdFind butonu da arama işlemini gerçekleştirmek için kullanılacaktır. Arama işlemini
gerçekleştirmek için aşağıdaki kodu cmdFind_Click olayına girin.
Private Sub cmdFind_Click()
    Data1.Recordset.FindFirst "Name = '" & txtFind & "'"
End Sub

Burada Data1 nesnesinin metotlarından olan FindFirst arama için kullanılmıştır. Bu kod
bize tablodaki ilk tutanağı bulur. Aynı şekilde son tutanağı bulmak için FindLast,
birsonraki tutanağı bulmak için FindNext, bir önceki tutanağı bulmak için FindPrevious
metotlarını kullanmak mümkündür.

Yukarıdaki kodda FindFirst metoduna parametre olarak verilen kısmı arama kriterini
belirler. Eğer arama kriteri adının içinde “Microsoft” geçen yayınevini bul gibi olursa bu
aşağıdaki gibi belirtilmelidir.

    Data1.Recordset.FindFirst “Name LIKE '*" & txtFind & "*'

Aranan nitelikte bir tutanak bulunmadığı takdirde Data1.Recordset.NoMatch adlı
özellik True değerini alır.

Data Control Nesnesinin diğer olayları:

    Private Sub Data1_Reposition()
        Screen.MousePointer = vbDefault
        On Error Resume Next
        Data1.Caption = "Record: " & CInt( (Data1.Recordset.RecordCount       *   _
        (Data1.Recordset.PercentPosition * 0.01)) + 1)
    End Sub

Bu olay aktif olan tutanak değiştiğinde çağrılır. Bu yordamdaki son satır Data1
nesnesinin başlığını o andaki tutanağın numarasını gösterecek şekilde değiştirir.
Private Sub Data1_Validate(Action As Integer, Save As Integer)
    Select Case Action
         Case vbDataActionMoveFirst
         Case vbDataActionMovePrevious
         Case vbDataActionMoveNext
         Case vbDataActionMoveLast
         Case vbDataActionAddNew
         Case vbDataActionUpdate
         Case vbDataActionDelete
         Case vbDataActionFind
         Case vbDataActionBookmark
         Case vbDataActionClose
    Screen.MousePointer = vbDefault
    End Select
    Screen.MousePointer = vbHourglass
End Sub




                                                  26
   Bu olay kodun içindeki Select deyiminde belirtilen veritabanı işlemlerinden sonra
   çağrılır. Parametre olarak verilen Action değeri hangi işlemden sonra çağrıldığını belirtir.
   Save parametresi de verinin değişip değişmediğini belirtir.




   Programın çalışır haldeki son durumu aşağıdaki gibidir.


2.4. Activex Data Bound Kontrol Nesnelerini Kullanma
    Visual Basic içinde veritabanı ile bağlanabilen birçok kontrol nesnesi bulunmaktadır.
    Bunların yanısıra birçok ActiveX kontrol nesnesi de mevcuttur. Veritabanı ile
    ilişkilendirilebilen içsel kontroller daha önce de sözkonusu edilen;

                    Check box
                    Image
                    Label
                    Picture box
                    Text box
                    List box
                    Combo box

   kontrolleridir.



   ActiveX kontrol nesneleri ise

                    Data-bound list box
                    Data-bound combo box
                    MSFlexGrid
                    Apex Data-Bound Grid (DBGrid)
                    MaskedEdit

   kontrol nesneleridir.
                                               27
Karmaşık kullanıcı arabirimlerinde, bu ActiveX kontrol nesneleri veritabanı kullanımını
daha da fonksiyonelleştirir. Böylece kullanıcının, karmaşık bir veritabanı ile çalışırken
daha kolay ve hatasız işlem yapması sağlanır. Sağlanan kolaylıklar, tutanak kümelerinin
tümüne liste halinde erişim, verilerin gruplanması gibi veritabanının işlevselliğini arttırıcı
işlemlerdir.

ActiveX kontrollerini kullanmadan önce form üzerine Data Control nesnesinin
yerleştirilmiş ve Project menüsünün References seçeneği kullanılarak ihtiyaç duyulan
ActiveX kontrollerinin seçilmesi ve ayrıca Data Access Object (DAO) kütüphanesinin de
seçili olmasını sağlamak gerekir.

Bu genel açıklamalardan sonra, ActiveX kontrol nesnelerinin kullanımına örnekler
verelim.

Data Bound ListBox ve Data Bound ComboBox kullanımı basittir. Daha önce kullanılan
TextBox kullanımı ile benzerdir. ListBox ve ComboBox nesneleri ilişkilendirildikleri
tablo alanı ile otomatik olarak doldurulur.

Örnek: Bir Data Bound ComboBox nesnesinin sorgu sonuçlarıyla doldurulması.
Yeni bir proje yaratın, forma aşağıdaki nesneleri ekleyin.

  Form                      Caption                        YAYINEVLERI
                            Name                           frmYEvi
  DataControl               Name                           datYEvi
                            Connect                        Access
                            Databasename                   BIBLIO.MDB
                            RecordsetType                  2-Snopshot
                                                           Select     Name         from
                            Recordsource
                                                           Publishers
                            Visible                        False
  DBCombo                   Name                           dbcYEvi
                            Style                          2-Dropdown List
                            RowSource                      datYEvi
                            ListField                      Name



Yukarıda görüleceği gibi DataControl nesnesinin RecordSource özelliğine Select Name
from Publishers ifadesi yazılmıştır. Bu ifade bir SQL sorgusudur. Bu ifadeyle Publisher
Tablosundan Yayınevi adları alanı seçilir ve bir liste oluşturulur.

DBCombo kontrol nesnesinin RowSource özelliği ilişkilendirileceği Data Control
nesnesini belirler. ListField özelliği ise listelenecek olan alanı belirler.




                                             28
Program çalıştırıldığında aşağıdaki ekran görüntüsü belirecektir.




DBCombo nesnesinin üç farklı biçimi vardır. Bunlar;

Dropdown combo Metin kutusu ve listeden oluşur. Metin kutusuna listede olmayan
elemanlar girilebilir. Yandaki ok düğmesine basıldığında aşağı doğru bir liste açılır.

Simple combo Listesi aşağı doğru açılan türden değildir. Listede olmayan elemanlar
girilebilir.

Dropdown list Aşağı doğru açılan bir listesi vardır. Listede olmayan elemanlar metin
kutusuna girilemez.

Örnek : İki Data Control nesnesinin aynı anda kullanımı ve DBCombo kontrol
nesnesinin önemi.

DBCombo nesnesinin önemi birden fazla tablo ile işlem yapmak gerektiğinde daha da
açık bir şekilde kendisini gösterecektir. Bir veritabanında iki ayrı tablo olduğunu
düşünelim. Bunlardan 1. Tablodaki bir alan 2. Tablodaki bir alanı referans olarak
gösteriyorsa, 1. Tabloya veri girileceği zaman referans gösteren alana girilecek veri 2.
Tabloda olmak zorundadır. Bu bilginin var olup olmadığının kontrol edilmesi veya var
olan bir bilginin girilmesi için bir listeye ihtiyaç duyulur.

Bu durumu örneklemek için daha önce de kullandığımız BIBLIO.MDB veritabanındaki
iki tabloyu göz önüne alalım. Bu tablolar, Titles (kitaplar) ve Publishers (Yayıncılar)
tablolarıdır. Kitap bilgilerinin tutulduğu Titles tablosunda yayıncılar tablosu olan
Publishers tablosuna referans gösteren PubId (Yayıncı numarası) adlı bir alan
mevcuttur. Bu alana girilecek olan değer var olmayan bir yayıncının numarası
olamayacağından önce varlığı kontrol edilmelidir.

Bu durumu daha açık hale getirmek için yeni bir proje başlatın ve aşağıdaki nesneleri
projeye ekleyin. Formun genel görünümü ileride verilmiştir. Nesnelerin yerleşim planı
için ilerideki form görünümünü kullanın.

Form                      Caption                             Kitap Adları
                          Name                                frmKitaplar

                                            29
DataControl       Name                 datYEvi
                  Connect              Access
                  Databasename         BIBLIO.MDB
                  RecordsetType        2-Snopshot
                  Recordsource         Select PubID,Name
From Publishers   Visible              False
CommandButton     Name                 cmdKapat
                  Caption              &Kapat
CommandButton     Name                 cmdDegistir
                  Caption              &Değiştir
CommandButton     Name                 cmdYenile
                  Caption              &Yenile
CommandButton     Name                 cmdSil
                  Caption              &Sil
CommandButton     Name                 cmdEkle
                  Caption              &Ekle
DataControl       Name                 datKitap
                  Align                2- AlignBottom
                  Connect              Access
                  Databasename         BIBLIO.MDB
                  Readonly             False
                  RecordsetType        1-Dynaset
                  RecordSource         Titles
DBCombo           Name                 dbcYEvi
                  DataField            PubID
                  DataSource           datKitap
                  ListField            Name
                  BoundColumn          PubID
                  Text                 Yayinevleri
                  RowSource            datYEvi
                  Style                2- Dropdown list
TextBox           Name                 txtKAd
                  DataField            Title
                  DataSource           datKitap
TextBox           Name                 txtYil
                  DataField            Year Published
                  DataSource           datKitap
TextBox           Name                 txtISBN
                  DataField            ISBN
                  DataSource           datKitap
TextBox           Name                 txtTanim
                  DataField            Description
                  DataSource           datKitap
TextBox           Name                 txtNotlar
                  DataField            Notes
                                  30
                            DataSource                              datKitap
TextBox                     Name                                    txtKonu
                            DataField                               Subject
                            DataSource                              datKitap
TextBox                     Name                                    txtYorumlar
                            DataField                               Comments
                            DataSource                              datKitap
                            Multiline                               1-True
                            ScrollBar                               2-Vertical

Bunlardan başka 8 tane de Label yerleştirin ve başlıklarını ileride verilecek olan form
görüntüsünden yararlanarak değiştirin.

Şimdi aşağıdaki kodu frmKitaplar formuna ekleyin.

       Private Sub cmdDegistir_Click()
           datKitap.UpdateRecord
           datKitap.Recordset.Bookmark = datKitap.Recordset.LastModified
       End Sub

       Private Sub cmdEkle_Click()
           datKitap.Recordset.AddNew
       End Sub

       Private Sub cmdKapat_Click()
           Unload Me
       End Sub

       Private Sub cmdSil_Click()
           datKitap.Recordset.Delete
           datKitap.Recordset.MoveNext
       End Sub

       Private Sub cmdYenile_Click()
           datKitap.Refresh
       End Sub

       Private Sub datKitap_Error(DataErr As Integer, Response As Integer)
           MsgBox "Hata: " & Error$(DataErr)
           Response = 0
       End Sub

       Private Sub datKitap_Reposition()
           Screen.MousePointer = vbDefault
           On Error Resume Next
           datKitap.Caption = (datKitap.Recordset.AbsolutePosition + 1) _
           & ". TUTANAK"
       End Sub




                                                31
Programı çalıştırın. Aşağıdaki ekran görüntüsü çıkacaktır.




Şimdi, DBCombo kontrol nesnesinin özelliklerini tekrar inceleyelim

DBCombo                    Name                              dbcYEvi
                           DataField                         PubID
                           DataSource                        datKitap
                           ListField                         Name
                           BoundColumn                       PubID
                           Text                              Yayinevleri
                           RowSource                         datYEvi
                           Style                             2- Dropdown list

DataSource özelliği Varlığı kontrol edilecek verilerin alınacağı DataControl nesnesini
belirler. Burada Kitaplar tablosu.

RowSource özelliği Listeye konacak olan verilerin alınacağı DataControl nesnesini
belirler. Burada Yayıcılar tablosundan seçilen kısım.

ListField özelliği Listelenecek alanı belirler. Burada Yaınevinin adı.

BoundColumn özelliği Referans gösterilen tablo alanını belirler. Burada Yayıncılar
tablosundan Yayıncı numarası.

DataField özelliği Karşılaştırılacak olan alanı belirler. Burada Kitaplar tablosundan
Yayıncı numarası.

Tablolardan görüleceği gibi, Kitaplar tablosunda Yayıncı adı alanı bulunmamaktadır.
Yayıncı adına erişmek için buradaki, Yayıncı numarası (PubID) alanından
faydalanılmaktadır. Bu numaranın Yayıncılar tablosunda gösterdiği yayıncının adı alınıp
listeye konmaktadır. Yeni bir kayıt eklenirken Yayıncı adını listeden seçmek, eklenecek
                                            32
olan kayda yayıncı numarası vermekle eşdeğerdir. Yayıncı numarası otomatik olarak
kayda eklenecektir.

Örnek : Data Bound Grid kontrol nesnesinin kullanımı.

Data Bound Grid kontrol nesnesi, verilerin çizelgeler halinde gösterilebilmesini ve
değiştirilebilmesini sağlar. Data Control nesnesi ile doğrudan bağlanabilir. Bu özellik
tablo içeriğinin doğrudan çizelgeye aktarılmasını sağlar. Kullanımı en basit Data Bound
Control nesnelerinden biridir. Çalışır duruma gelmesi için sadece yapılması gereken
DataSource özelliğinin değiştirilmesi yeterlidir.

ADIM 1 : Yeni bir proje yaratın. Aşağıdaki nesneleri formun üzerine ekleyin.

Form                           Caption                         Data Bound Grid
                               Name                            frmGrid
DataControl                    Connect                         Access
                               Databasename                    BIBLIO.MDB
                               Name                            datKitap
                               RecordSetType                   1-Dynaset
                               RecordSource                    Titles
                               Visible                         False
Data Bound Grid                DataSource                      datKitap
                               Name                            dbgKitap



ADIM 2 : Bir önceki örnekte kullanılan CommandButton nesnelerinin aynısını tekrar
formun üzerine yerleştirin ve bunlara ait kodları da bir önceki örnekteki gibi yazın. Bu
kodun yanısıra aşağıdaki kodu da forma ekleyin.

   Private Sub datKitap_Error(DataErr As Integer, Response As Integer)
       MsgBox "Hata: " & Error$(DataErr)
       Response = 0
   End Sub

   Private Sub dbgKitap_HeadClick(ByVal ColIndex As Integer)
       datKitap.RecordSource = "Select * From Titles Order By [" & _
       dbgKitap.Columns(ColIndex).DataField & "]"
       datKitap.Refresh
   End Sub

Burada ilk yordam herhangi bir hata oluştuğunda hatanın pas geçilmesini, ikinci yordam
ise çizelgedeki sütunlardan birine basıldığında çizelge içeriğinin o sütuna göre sıralı
olmasını sağlar. Bunun için bir SQL sorgusu kullanılmaktadır. Sıralamayı sağlayan kısım
SQL sorgusundaki Order By ile başlayan kısımdır.

Programın çalışması aşağıdaki gibi olacaktır.




                                                33
Buradaki çizelge Kitap ismine göre sıralıdır. Bu Kitap adı(Title) yazan yere mouse ile
basılarak sağlanmıştır.

Örnek : MSFlexGrid Control nesnesinin kullanımı.

Bu kontrol nesnesi Data Bound Grid nesnesinin sağladığı özelliklerin hepsini sağlar.
Farklı bir özelliği, üzerinde değişiklik yapılamamasıdır. Bu nesne verilerin
gösterilmesinde, gruplanmasında ve yönetiminde çok büyük avantajlar sağlar. Bu örnekte
MsFlexGrid nesnesinin bazı özelliklerinin ve metotlarının kullanımı konu edilecektir.

Yeni bir proje çalıştırın. Aşağıdaki nesneleri bu projedeki formun üstüne yerleştirin.
Nesneleri yerleştirirken ileride verilecek olan form görüntüsünü referans olarak
kullanabilirsiniz.

Form                   Caption                       Flex Grid
                       Name                          frmFlexGrid
DataControl            Connect                       Access
                       Databasename                  BIBLIO.MDB
                       Name                          datYazar
                       RecordSource                  Authors
                       Visible                       False
MsFlexGrid             Name                          MsFlexGrid1
                       DataSource                    datAuthors
                       AllowBigSelection             False
                       GridLines                     0-flexGridNone
                       GridLinesFixed                0-flexGridNone
                       AllowUserResizing             1-flexResultsColumns

Bunlardan başka 5 tane de CommandButton yerleştirin ve Caption özelliklerini
sırasıyla; Grid Lines, Grid Lines Fixed, ForeColor, Font ve BackColor olarak
değiştirin. Aşağıdaki kodu frmFlexGrid formuna ekleyin.

   Private Sub Command1_Click()
                                           34
       If MSFlexGrid1.GridLines < flexGridRaised Then
            MSFlexGrid1.GridLines = MSFlexGrid1.GridLines + 1
       Else
            MSFlexGrid1.GridLines = flexGridFlat
       End If
   End Sub

   Private Sub Command2_Click()
       If MSFlexGrid1.GridLinesFixed < flexGridRaised Then
            MSFlexGrid1.GridLinesFixed = MSFlexGrid1.GridLinesFixed + 1
       Else
            MSFlexGrid1.GridLinesFixed = flexGridFlat
       End If
   End Sub

   Private Sub Command3_Click()
       Static iClicks As Integer
       Select Case iClicks
            Case 0: MSFlexGrid1.CellForeColor = &HFF&
            Case 1: MSFlexGrid1.CellForeColor = &HFF00&
            Case 2: MSFlexGrid1.CellForeColor = &HFF0000
            Case 3: MSFlexGrid1.CellForeColor = 1: iClicks = -1
       End Select
       iClicks = iClicks + 1
   End Sub

   Private Sub Command4_Click()
       Static iClicks As Integer
       Select Case iClicks
            Case 0: MSFlexGrid1.CellFontBold = 1
            Case 1: MSFlexGrid1.CellFontItalic = 1
            Case 2: MSFlexGrid1.CellFontBold = 0
            Case 3: MSFlexGrid1.CellFontItalic = 0: iClicks = -1
       End Select
       iClicks = iClicks + 1
   End Sub

   Private Sub Command5_Click()
       Static iClicks As Integer
       Select Case iClicks
            Case 0: MSFlexGrid1.CellBackColor = &HFF&
            Case 1: MSFlexGrid1.CellBackColor = &HFF00&
            Case 2: MSFlexGrid1.CellBackColor = &HFF0000
            Case 3: MSFlexGrid1.CellBackColor = &HFFFFFF: iClicks = -1
       End Select
       iClicks = iClicks + 1
   End Sub



Burada ilk iki yordam çizgi biçimini basıldıkça döngü halinde değiştirir. Diğer yordamlar
da sırasıyla aktif olan hücrenin yazı rengini, font biçimini ve geri plan rengini yine döngü
halinde değiştirir.

Programın çalışma sırasındaki görünüş örneği aşağıdadır.




                                                 35
Örnek: Şimdi yukarıdaki örnek üzerinde biraz değişiklik yapıp MSFlexGrid kontrol
nesnesinin bir özelliğini daha görelim.

ADIM 1 : Yukarıdaki formu sağa doğru biraz genişletip ileride gösterilen biçime getirin.
Bu forma bir CheckBox yerleştirin ve Caption özelliğini Merge Cells olarak değiştirin.
Bu hücreleri birleştirmek için kullanılacak olan işaret kutusudur.

ADIM 2 : datYazar Data Control nesnesinin aşağıdaki özelliklerini değiştirin.

         Name                 datTKitap

         RecordSource         All Titles

ADIM 3 : Aşağıdaki kodu frmFlexGrid formunun sonuna ekleyin.

       Private Sub Init()
           Dim i As Integer
           MSFlexGrid1.Row = 0
           For i = 0 To MSFlexGrid1.Cols - 1
                MSFlexGrid1.Col = i
                MSFlexGrid1.CellFontSize = 8
                MSFlexGrid1.CellAlignment = 1
                MSFlexGrid1.MergeCol(i) = True
           Next i
           MSFlexGrid1.MergeCells = 0
       End Sub

       Private Sub Check1_Click()
           MSFlexGrid1.MergeCells = Check1
       End Sub



Burada init diye adlandırılan yordam MSFlexGrid nesnesinin sütunlarının birleşmeye
uygun hale getirilmesini ve görünümünün düzgün olmasını sağlar. Bu yordam
Form_Load olay yordamında çağrılmalıdır.

                                                 36
Programın bu yeni haliyle çalışması aşağıdaki gibidir. Görüleceği gibi aynı olan değerler
birleştirilmiş ve tek bir hücre haline getirilmiştir.




Bu özelliklerinden başka MSFlexGrid yapısında hücrelere resim yerleştirmek de
mümkündür.

MSFlexGrid yapısı DataControl nesnesi kullanılmadan da kullanılabilir. Bu durumda
hücreleri doldurmak için AddItem metodu kullanılır.




                                           37
3. VERİ ERİŞİM NESNELERİNİN KULLANIMI


3.1. Giriş

Bu bölümde Microsoft Jet veritabanı motoru ve onun programlama modeli olan DAO (Data
Access Objects – Veri Erişim Nesneleri) konu edilecektir. Bunun için ilişkisel veritabanı
tasarımı, yaratılması, bakımı ve değiştirilmesi konu edilecektir.

Bu bölümde DAO metotları kullanılarak;

                Veritabanı tanımlama
                Alan tanımlama
                İndeks (Dizin) tanımlama
                Tablolar arasında ilişki tanımlama
                Veritabanlarının yapısında değişiklik yapma
                Var olan bir veritabanı üzerinde işlem yapma

konularına açıklık getirilecektir.

Microsoft Jet Veritabanı Motoru

Visual Basic programlama dilindeki veri erişim olanağı, Microsoft Access yazılımının da temel
olarak kullandığı Microsoft Jet veritabanı motoruna dayanmaktadır. Jet motoru, verilerin
saklanması, geri getirilmesi ve değiştirilmesi için bir mekanizmanın yanısıra güçlü DAO nesne
tabanlı arabirimini de kullanıcıya sağlar.

Bir veri tabanı uygulaması üç kesimden oluşur. Bunlar;

                Kullanıcı arabirimi
                Veritabanı motoru
                Verilerin tutulduğu fiziksel ortam kesimleridir.

Veritabanı motoru, yazılım ile fiziksel veritabanı dosyaları arasında iletişimi sağlar. Bu
kullanıcıyı veritabanı dosyalarından soyutlar ve hareket serbestliği sağlar. Kullanıcı artık
veritabanının türü ile ilgilenmek durumunda değildir. Bütün veritabanı biçimleri için aynı tür
erişimler veritabanı motoru tarafından sağlanmaktadır.

Kullanıcı arabirimi, kullanıcının karşı karşıya kaldığı programın dış yüzüdür. Bu kesim,
kullanıcının verileri görmesine, değiştirmesine ve veri eklemesine yardımcı olan, formlardan
oluşan kesimdir. Bu formların yaptığı işlerle ilgilenen kesim ise uygulama yazılımının kodudur.
Bu kod kullanıcının görsel olarak belirttiği işlemleri veritabanı motoruna iletmekle yükümlüdür.

Jet veritabanı motoru bir takım DLL kütüphaneleri halinde Visual Basic aracılığıyla kullanılır.
Jet motoru veritabanı üzerindeki işlemler dışında ayrıca bir sorgu işleyici de barındırır. Bu sorgu
işleyici SQL sorgularını veritabanı üzerinde çalıştırır ve sorgu sonuçlarını döndürür.

Veritabanı fiziksel ortamda dosyalar halinde tutulur. Bu dosyalar sadece verileri tutmakla
yükümlüdür. Uygulama yazılımları bu dosyaların sadece adı ile muhatap olur. Bu dosyalarda
verilerin nasıl tutulduğu veritabanı motorunu ilgilendirir.

                                                  38
Burada bahsedilen üç kesim değişik biçimlerde bölünebilir. Bu üç kesimin bir bilgisayar
üzerinde tek bir kullanıcı tarafından kullanılması sözkonusu olabileceği gibi, birbirine ağ yapısı
ile bağlı farklı bilgisayarlar üzerinde de bulunmaları mümkündür. Örneğin veritabanı bir ana
bilgisayarın üzerinde bulunabilir, kullanıcılar ise bu veritabanına bir ağ üzerinden ulaşabilirler.

Kullanıcının veritabanından uzak (farklı bir bilgisayarda) olduğu durumda iki ayrı yapı
sözkonusudur.

              Uzak veri tabanı sistemi (Remote Database)
              İstemci/Sunucu veritabanı sistemi (Client/Server Database)

Bunlardan birincisinde veritabanı motoru kullanıcı ile aynı bilgisayarda, ikincisinde ise
veritabanı motoru veritabanı ile aynı bilgisayar üzerinde bulunur. Veritabanı motoru aynı anda
birden fazla kullanıcıdan istek alır ve istedikleri kayıtları veritabanı üzerinde işlem yaparak geri
döndürür.

Jet veritabanı motoru Client/Server bir yapıya sahip değildir. Yerel bir veritabanı motorudur.
Uygulama ile aynı bilgisayarda bulunur. İşlevleri bir DLL halinde bulunur. Eğer bir uygulama
programının farklı bilgisayarlar üzerinde kopyaları varsa herbirinin kendi Jet veritabanı motoru
DLL dosyalarına sahip olması gerekir.

Visual Basic kullanarak Client/Server veritabanları ile çalışmak da mümkündür. Bunun için
ODBC standardı kullanılarak sorgular doğrudan ODBC server olarak adlandırılan veritabanı
sunucusuna gönderilebilir.

Veri erişim nesnesi modeli Jet veritabanı motorunun veritabanı motorudur. Bu model aşağıdaki
çizimdeki sıradüzensel yapı ile ifade edilmektedir.




Bu yapıdaki elemanların herbiri aslında bir sınıfı temsil etmektedir. Bu sınıfın bir nesnesini
yaratmak için ise, örneğin;

   Dim MyWs as Workspace

gibi bir komut kullanmak gerekir. Yukarıdaki şemada DBEngine dışındaki elemanlar hem
küme(Collection) hem de nesne olarak kullanılabilirler. Kümelerin elemanlarına sıfırdan
                                                39
başlayan bir dizinli yapı ile erişmek mümkündür. Bu erişim için aşağıdaki gösterim bir örnek
olarak verilebilir.

   DBEngine.Workspaces(0).Databases(0).TableDefs(0).Fields("MüşteriNo")
Şu ana kadar veritabanı kavramlarına genel bir giriş yapılmış oldu. Veritabanları üzerinde işlem
yapılırken iki tür dilden bahsedilir. Bunlar;

              DDL (Data Definition Language – Veri tanımlama dili)
              DML (Data Manipulation Language – Veri işleme dili)

Bu sözkonusu olan farklı iki dil olduğu anlamına gelmez. Bu sadece verilerle işlem yapılırken
kullanılırken yapılan bir gruplamadır.

Veri Tanımlama(DDL), bir veritabanının tanımlaması ve yaratılması için gerekli özellikleri ve
metotları içerir. Veritabanının yaratılması bir defaya mahsus yapılan bir işlemdir. Bir defa
veritabanı yaratıldıktan sonra, onu açmak tüm yapısına erişmek anlamına gelir.

Veri İşleme(DML), varolan veritabanlarına erişebilen ve onların üzerinde işlem yapabilen
uygulama yazılımları yazmak için gerekli özellikleri ve metotları içerir. Bu veritabanını
sorgulama, tabloları üzerinde dolaşma, tutanaklar üzerinde değişiklik, ekleme, silme gibi
işlemler yapmayı içerir.

Var olan veritabanlarını kullanmak için sadece DML yeterlidir. Fakat DDL metotlarını ve
özelliklerini anlamak veritabanının yapısını daha iyi kavrama ve veritabanı üzerinde daha rahat
işlem yapabilme olanağı sağlar.



3.2. Recordset Yapısı İle Çalışmak

Recordset yapısı veritabanına erişimi sağlayan bir nesne yapısıdır. Bir Recordset nesnesi, bir
tablodaki tutanakları veya bir sorgunun sonucunda döndürülen tutanak kümelerini temsil eder.
Beş farklı Recordset nesnesi vardır. Bunların herbiri farklı özellikler gösterir. Bunlar, Table ,
Dynaset , Snapshot , Dynamic ve Forward-only nesneleridir.

Table (Tablo) Kullanılan veritabanı üzerindeki bir tabloyu belirtir. Bu türden bir Recordset
yaratıldığında, veritabanı motoru veritabanındaki bir tabloyu açar ve işlemler onun üzerinde
gerçekleştirilir. Bir tablo türündeki Recordset ilişkilendirildiği veritabanı tablosunun indeks
yapısını kullanabilir. Bu durum, hızlı arama yapabilme olanağı sağlar.

Dynaset Kullanılan veritabanı üzerinde yerel olarak var olan veya bu veritabanına bağlı olan
tablolar ile bir sorgu sonucunda oluşturulan tabloları da temsil edebilir. Genelde bir veya birden
fazla tablonun tutanaklarına referans kümeleri içerir. Bu yapı veritabanı üzerinde çok esnek bir
erişim sağlar, farklı türden veritabanları üzerinde aynı Recordset yapısı kullanarak işlem
yapmaya olanak sağlar. Bu avantajının yanısıra birden fazla tabloya çok sayıda bağ içerdiğinden
dolayı çalışma esnasında yavaş olduğu görülür.

Snapshot Yaratıldığı anda ilişkilendirildiği verilerin sabit bir kopyasını barındırır. Jet veritabanı
motoru tarafından kullanılan snapshot yapısında değişiklik yapılamaz. Ancak ODBC
veritabanları sunucunun olanaklarına göre snapshot yapısı kullanarak değişiklik yapmaya izin
verebilir. Snapshot işlem miktarını azalttığı için daha hızlı bir yapıdır. Bir sorgu sonucu bu yapı
ile çok hızlı bir şekilde elde edilebilir.
                                                  40
Forward-only Forward-scrolling snapshot veya forward-only snapshot olarak adlandırıldığı da
olur. Snapshot yapısının sağladığı olanakların bir alt kümesini sunar. En az işlevselliği olan
Recordset yapısıdır, bu yüzden en hızlı işlem yapan yapıdır. Bu yapıda da snapshot yapısında
olduğu gibi değiştirme yapılamaz. Bunun yanısıra bir kısıtlama daha vardır, bu da sadece ileriye
doğru hareket edebilme özelliğidir.

Dynamic Bir veya birden fazla tabloyu içeren bir sorgu sonucunu tutmak için kullanılır. Bu
yapıda ekleme, silme değiştirme gibi özellikler de sağlanır. Kullanıldığı sırada tablolardaki
değişiklik de hemen bu yapıya yansır. Bu yapı ODBC veritabanılarındaki Dynamic Cursor
yapısını temsil eder.

Recordset türleri kullanılırken dikkat edilmesi gereken bir unsur, Snapshot yapısı kullanılırken
verilerin tümünün bir kopyasının alındığıdır. Bu haliyle bazen bir Dynaset yapısı, Snapshot
yapısından daha hızlı olabilir.

Genel olarak eğer Table türü bir Recordset kullanmak mümkünse öncelikli olarak bu yapı tercih
edilmelidir.

Veritabanına erişim için Recordset yapısının kullanımını örneklemeden önce veritabanının nasıl
tasarlandığını ve yaratıldığını bir örnekle açıklayalım.

3.2.1 Veritabanı Tasarımı ve Yaratılması

Veritabanı tasarlama ve yaratma konusu işlenirken bir veritabanının tasarlanması şarttır. Bunun
için aşağıdaki kısıtlı olarak tasarlanmış PERSONEL veritabanını kullanalım. Bu veritabanı bir
kurumda çalışan personel ile ilgili birtakım bilgileri saklamak için kullanılıyor varsayalım.

PERSONEL veritabanı

Bu veritabanında aşağıdaki tabloların bulunduğunu düşünelim.

       1. PERSONEL_BIL(SICNO, AD_SOYAD, DTAR, DYER)
           SICNO: Sicil numarası, anahtar
           AD_SOYAD: Personelin adı ve soyadı
           DTAR: Doğum tarihi
           DYER: Doğum yeri

       2. PERSONEL_GOREV(SICNO, CYIL, GNO, DERECE, MNO)
           SICNO: Sicil numarası, anahtar
           CYIL: Kurumda çalıştığı yıl sayısı
           GNO: Görev numarası
           DERECE: Personelin kadro derecesi
           MNO: Meslek numarası

       3. MESLEKLER(MNO, MADI, ACIKLAMA)
           MNO: Meslek numarası, anahtar
           MADI: Meslek adı
           ACIKLAMA: Meslekle ilgili açıklama

       4. GOREVLER(GNO, GADI)
           GNO: Görev numarası
                                               41
          GADI: Görev numarası


Bu veritabanını yaratmak için Standart EXE türünde bir proje yaratın. Üzerine iki tane
CommandButton yerleştirin. Caption özelliklerini sırasıyla Yarat ve CIKIŞ olarak değiştirin ve
aşağıdaki kodu forma ekleyin.

   Option Explicit
   Private Sub Command1_Click()
       Dim ws As Workspace
       Dim db As Database
       Dim tdf As TableDef
       Dim fld As Field
       Set ws = DBEngine.Workspaces(0)
       Set db = ws.CreateDatabase(App.Path & _
       "\PERSONEL.MDB", dbLangTurkish)
                      'PERSONEL_BIL tablosu
       Set tdf = db.CreateTableDef("personel_bil")
       Set fld = tdf.CreateField("sicno", dbText, 10)
       tdf.Fields.Append fld
       Set fld = tdf.CreateField("ad_soyad", dbText, 30)
       tdf.Fields.Append fld
       Set fld = tdf.CreateField("dtar", dbDate)
       tdf.Fields.Append fld
       Set fld = tdf.CreateField("dyer", dbText, 15)
       tdf.Fields.Append fld
       db.TableDefs.Append tdf
                      'PERSONEL_GOREV tablosu
       Set tdf = db.CreateTableDef("personel_gorev")
       Set fld = tdf.CreateField("sicno", dbText, 10)
       tdf.Fields.Append fld
       Set fld = tdf.CreateField("CYIL", dbInteger)
       tdf.Fields.Append fld
       Set fld = tdf.CreateField("gno", dbInteger)
       tdf.Fields.Append fld
       Set fld = tdf.CreateField("derece", dbInteger)
       tdf.Fields.Append fld
       Set fld = tdf.CreateField("mno", dbInteger)
       tdf.Fields.Append fld
       db.TableDefs.Append tdf
                      'MESLEKLER tablosu
       Set tdf = db.CreateTableDef("gorevler")
       Set fld = tdf.CreateField("mno", dbInteger)
       tdf.Fields.Append fld
       Set fld = tdf.CreateField("MADI", dbText, 40)
       tdf.Fields.Append fld
       db.TableDefs.Append tdf
                      'GOREVLER tablosu
       Set tdf = db.CreateTableDef("meslekler")
       Set fld = tdf.CreateField("gno", dbInteger)
       tdf.Fields.Append fld
       Set fld = tdf.CreateField("GADI", dbText, 40)
       tdf.Fields.Append fld
       db.TableDefs.Append tdf
       db.Close
       Label1.Caption = "PERSONEL VERİTABANI YARATILDI"
       Command1.Enabled = False
   End Sub
   Private Sub Command2_Click()
            End
   End Sub

                                              42
Program çalıştırıldıktan sonra aşağıdaki form görüntüsü ekrana çıkar, fakat üstteki yazı yoktur.
Yarat düğmesine basıldıktan sonra üstteki yazı belirir. Daha sonra yapılması gereken ÇIKIŞ
düğmesine basarak programdan çıkmaktır.




Programdan çıktıktan sonra programla aynı dizinde PERSONEL.MDB adlı bir veritabanı kütüğü
yaratılmış olur. Bu veritabanının alanlarını görmek için Visual Basic dizinindeki Visdata.exe
programı kullanılabilir.



İndeks Yaratma. Veritabanını yarattıktan sonra sıra indeks ekleme işlemine geldi.

İndeksler veritabanı üzerinde arama yapılırken hızlı ve kolay erişim sağlayan veritabanı
öğeleridir.

Yukarıdaki projenin Command1_Click olay yordamını kaldırın ve form üzerindeki Yarat
butonunun Caption özelliğini İndex Yarat olarak değiştirin ve aşağıdaki kodu
Command1_Click olayına ekleyin.


   Private Sub Command1_Click()
       Dim ws As Workspace
       Dim db As Database
       Dim tdf As TableDef
       Dim fld As Field
       Dim idx As Index
       Set ws = DBEngine.Workspaces(0)
       Set db = ws.OpenDatabase(App.Path & "\PERSONEL.MDB")
                 'PERSONEL_BIL tablosu için indeks yaratma
       Set tdf = db.TableDefs("personel_bil")
       Set idx = tdf.CreateIndex("ind_sicno")
       Set fld = idx.CreateField("sicno")
       idx.Fields.Append fld
       Set fld = Nothing
       idx.Primary = True
       idx.Unique = True
       tdf.Indexes.Append idx
                 'PERSONLE_GOREV tablosu için indeks yaratma
       Set tdf = db.TableDefs("personel_gorev")
       Set idx = tdf.CreateIndex("ind_sicno")
       Set fld = idx.CreateField("sicno")
       idx.Fields.Append fld
       Set fld = Nothing
       idx.Primary = True
       idx.Unique = True
                                                    43
       tdf.Indexes.Append idx
                 'MESLEKLER tablosu için indeks yaratma
       Set tdf = db.TableDefs("meslekler")
       Set idx = tdf.CreateIndex("ind_mno")
       Set fld = idx.CreateField("mno")
       idx.Fields.Append fld
       Set fld = Nothing
       idx.Primary = True
       idx.Unique = True
       tdf.Indexes.Append idx
                 'GOREVLER tablosu için indeks yaratma
       Set tdf = db.TableDefs("gorevler")
       Set idx = tdf.CreateIndex("ind_gno")
       Set fld = idx.CreateField("gno")
       idx.Fields.Append fld
       Set fld = Nothing
       idx.Primary = True
       idx.Unique = True
       tdf.Indexes.Append idx
       db.Close
       Label1.Caption = "TABLO İNDEKSLERİ YARATILDI"
       Command1.Enabled = False
   End Sub

Program çalıştırıldıktan sonra aşağıdaki form görüntüsü ekrana çıkar, fakat üstteki yazı yoktur.
İndeks yarat düğmesine basıldıktan sonra üstteki yazı belirir. Daha sonra yapılması gereken
ÇIKIŞ düğmesine basarak programdan çıkmaktır.




Programdan çıktıktan sonra Visual Basic dizinindeki Visdata.exe programı kullanılarak
indekslerin yaratılıp yaratılmadığı kontrol edilebilir.

İlişki Yaratma. İki farklı tabloda aynı olan alanların tutarlılığını denetlemek için bu tablolar
arasında bağ kurma işlemine ilişki yaratma denir.

Yukarıdaki veritabanı için konuşacak olursak, PERSONEL_BIL tablosunda olmayan bir
personel, PERSONEL_GOREV tablosunda da olmamalıdır. Bunu sağlamak için iki tablo
arasında bir ilişki tanımlamak şarttır.

Jet veritabanı motoru ilişki tanımlamak için Relation diye bir nesne sağlar.

Bir veritabanına ilişki eklemek için:

   1. Database nesnesinin CreateRelation metodunu kullanarak bir ilişki nesnesi yaratın.
   2. İlişkinin dayandığı alanları belirlemek için Relation nesnesinin CreateField metodunu
      kullanarak bir alan yaratın.

                                                44
    3. Yaratılan bu alanı yaratılmış 1. Adımda yaratılan ilişki nesnesine ekleyin. Sonra bu
       ilişkiyi veritabanına ekleyin.

Bu adımların uygulanmış hali olan aşağıdaki kodu, yukarıdaki formun Command1_Click olay
yordamını silerek yerine yazın.

    Private Sub Command1_Click()
        Dim ws As Workspace
        Dim db As Database
        Dim fld As Field
        Dim rel As Relation
        Set ws = DBEngine.Workspaces(0)
        Set db = ws.OpenDatabase(App.Path & "\PERSONEL.MDB")
             'PERSONEL_BIL ile PERSONEL_GOREV tablosu arasında
             'p_gorevi (personelin görevi) ilişkisi yaratma
        Set tdf = db.CreateRelation("p_gorevi")
        rel.Table = "personel_bil"
        rel.ForeignTable = "personel_gorev"
        Set fld = rel.CreateField("sicno")
        fld.ForeignName = "sicno"
        rel.Fields.Append fld
        db.Relations.Append rel
             'PERSONEL_GOREV ile GOREVLER tablosu arasında
             'g_ad (görev adı) ilişkisi yaratma
        Set tdf = db.CreateRelation("g_ad")
        rel.Table = "gorevler"
        rel.ForeignTable = "personel_gorev"
        Set fld = rel.CreateField("gno")
        fld.ForeignName = "gno"
        rel.Fields.Append fld
        db.Relations.Append rel
             'PERSONEL_GOREV ile MESLEKLER tablosu arasında
             'm_ad (meslek adı) ilişkisi yaratma
        Set tdf = db.CreateRelation("m_ad")
        rel.Table = "meslekler"
        rel.ForeignTable = "personel_gorev"
        Set fld = rel.CreateField("mno")
        fld.ForeignName = "mno"
        rel.Fields.Append fld
        db.Relations.Append rel
        db.Close
        Label1.Caption = "İLİŞKİLER YARATILDI"
        Command1.Enabled = False
    End Sub

Program yine yukarıdakilere benzer bir biçimde çalışacak ve belirtilen üç ilişkiyi yaratacaktır.
Bu ilişkilerin veritabanına eklendiği yine VISDATA programı kullanılarak test edilebilir. Bu
ilişkiler şunlardır.

            1.PERSONEL_GOREV ile GOREVLER tablosu arasında g_ad (görev adı) ilişkisi.
            2.PERSONEL_GOREV ile GOREVLER tablosu arasında 'g_ad (görev adı) ilişkisi.
            3.PERSONEL_GOREV ile MESLEKLER tablosu arasında m_ad (meslek adı)
ilişkisi.

VISDATA ile bakıldığında bu ilişkilerin PERSONEL_GOREV tablosuna birer indeks olarak
eklendiği görülecektir.
Bu ilişkiler veritabanının tutarlılığını devam ettirmesine yardımcı olur. Örneğin bir personelin
GOREVLER tablosunda olmayan bir görevi olamaz.

                                               45
3.2.2. Veritabanına Erişim

Veritabanı üzerinde DataControl nesnesi kullanmadan da dolaşmak mümkündür. Bunun için
veritabanı ile kontrol nesneleri arasındaki ilişki elle kurulmalıdır. Bunu örneklemek için
aşağıdaki proje verilebilir.

   1. Formun üstüne aşağıdaki nesneleri ileride verilecek olan form nesnesini referans alarak
      yerleştirin.

  Form          Name            frmDolas
                Caption         Veritabanini Dolasma
  CommandButton Name            Command1 (Control dizisi, 4 elemanlı, Caption özellikleri: |<, <, >, >|
  TextBox       Name            Text1 (Control dizisi, 4 elemanlı)
  CommandButton Name            cmdKaydet
                Caption         &Kaydet

   2. Projeye bir Class Module ekleyin ve clsDolas.bas olarak kaydedin. Daha sonra aşağıdaki
      kodu bu Class Module içine ekleyin.

   Private db As Database
   Private rs As Recordset
   Private degisti As Boolean
   Private mmad As String
   Private myil As String
   Private mISBN As String
   Private mbno As String
   Public Enum hareket
       ilk = 1
       son = 2
       birsonraki = 3
       bironceki = 4
   End Enum
   Public Enum hata
       yhareket = vbObjectError + 1000 + 11
       tutanakyok = vbObjectError + 1000 + 12
   End Enum
   Private Sub class_Initialize()
       Dim dosyaAdi As String
       dosyaAdi = "c:\devstudio\vb\biblio.mdb"
       Set db = DBEngine.Workspaces(0).OpenDatabase(dosyaAdi)
       Set rs = db.OpenRecordset("Title", dbOpenDynaset, _
       dbSeeChanges, dbOptimistic)
       If rs.BOF Then HataVer yhareket
       TutanakOku
   End Sub
   Private Sub Class_Terminate()
       rs.Close
       Set rs = Nothing
       db.Close
       Set db = Nothing
   End Sub
   Private Sub HataVer(hatano As hata)
       Dim tanim As String
       Dim aciklama As String
       Select Case hatano
             Case yhareket: tanim = "YANLIS HAREKET"
             Case tutanakyok: tanim = "TUTANAK kitaplar tablosunda yok"
             Case Else: tanim = "TANIMSIZ HATA"
                                                    46
    End Select
    aciklama = App.EXEName & ".clsDolas"
End Sub
Private Sub TutanakOku()
    mISBN = rs![ISBN] & " "
    mad = rs![Title] & " "
    myil = rs![Year Published] & " "
    mbno = rs![PubID] & " "
End Sub
Private Sub TutanakGunle()
    On Error GoTo pHata
    rs.Edit
    rs![ISBN] = mISBN
    rs![Title] = mad
    rs![Year Published] = myil
    rs![PubID] = mbno
    rs.Update
    degisti = False
    Exit Sub
pHata:
    rs.MovePrevious
    rs.MoveNext
    Err.Raise Err.Number, Err.Source, Err.Description, _
    Err.HelpFile, Err.HelpContext
End Sub
Public Property Get ad() As String
    ad = mad
End Property
Public Property Let ad(sad As String)
    mad = sad
    degisti = True
End Property
Public Property Get yil() As String
    yil = myil
End Property
Public Property Let yil(syil As String)
    myil = syil
    degisti = True
End Property
Public Property Get ISBN() As String
    ISBN = mISBN
    End Property
    Public Property Let ISBN(sISBN As String)
    mISBN = sISBN
    degisti = True
End Property
Public Property Get bno() As String
    bno = mbno
End Property
Public Property Let bno(sbno As String)
    mbno = sbno
    degisti = True
End Property
Public Property Get degistimi() As Boolean
    degistimi = degisti
End Property

Public Sub git(htur As hareket)
    On Error GoTo phata:
    Select Case htur
        Case ilk: rs.MoveFirst
        Case son: rs.MoveLast
        Case birsonraki: rs.MoveNext
                                                  47
             Case bironceki: rs.MovePrevious
             Case Else: HataVer yhareket
       End Select
       TutanakOku
   phata: If rs.EOF Or rs.BOF Then HataVer yhareket
   End Sub
   Public Sub kaydet()
       If degisti Then TutanakGunle
   End Sub

Bu kodu biraz inceleyecek olursak, Class_Initialize olayında veritabanı açılıyor,
Class_Terminate olayında ise veritabanı kapatılıyor. Daha sonra tutanak okuma, günleme
yordamları yer almaktadır. Burada kullanılan veritabanı BIBLIO.MDB veritabanıdır. Recordset
olarak da bu veritabanının Titles (Kitaplar) tablosu kullanılmaktadır.

Kodun geri kalan kesiminde Recordset yapısının her bir alanı için bir Property tanımlandığı
görülebilir. Property Let yordamlarında aktif tutanakta değişiklik yapıldığını belirten degisti adlı
bir değişkene True değeri aktarılmaktadır.
degistimi adlı Property aktif tutanakta değişiklik yapılıp yapılmadığı bilgisini döndüren sadece
okunabilir bir özeliktir.

Yukarıdaki kodda görülebileceği gibi veritabanına erişimi destekleyen yordamların yanısıra hata
durumlarını ele alan ve hatalı bir duruma girildiğinde hata veren yordamlar da bulunmaktadır.
Bu yordamlar kendi hata mesajlarımızı yazmak ve hatalı durumalara gelindiğinde bu mesajları
kullanmak amacıyla yazılmıştır.

Bu erişim sınıfını tanımladıktan sonra, şimdi de frmDolas formunda yapılması gereken işlemlere
dönelim. Aşağıdaki kodu frmDolas formuna ekleyin.

   Private Kitaplar As clsDolas
   Private okunuyor As Boolean
   Private Sub Form_Load()
       On Error GoTo phata
       Set Kitaplar = New clsDolas
       VeriAl
       pcik: Exit Sub
       phata:
       MsgBox Err.Description, vbExclamation
       Unload Me
       Resume pcik
   End Sub

   Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
       On Error GoTo phata
       Kitaplar.kaydet

   pcik: Exit Sub

   phata:
       If MsgBox("Olusan hata:" & vbCrLf & Err.Description & vbCrLf & _
       "devam ederseniz, yaptiginiz degisiklikler kaybolur" & vbCrLf & _
       "Devam etmek istiyor musunuz?", vbQuestion Or vbYesNo Or _
       vbDefaultButton2) = vbNo Then Cancel = True
       Resume pcik
   End Sub

   Private Sub cmdKaydet_Click()
       On Error GoTo phata

                                                      48
       Kitaplar.kaydet
       VeriAl

   pcik: Exit Sub

   phata:
       MsgBox Err.Description, vbExclamation
       Resume pcik
   End Sub

   Private Sub Command1_Click(Index As Integer)
       On Error GoTo phata
       Kitaplar.kaydet
       Select Case Index
            Case 0: Kitaplar.git ilk
            Case 1: Kitaplar.git bironceki
            Case 2: Kitaplar.git birsonraki
            Case 3: Kitaplar.git son
       End Select

   pcik: Exit Sub
   phata:
       MsgBox Err.Description, vbExclamation
       Resume pcik
   End Sub

   Private Sub Text1_Change(Index As Integer)
       On Error GoTo phata
       If Not okunuyor Then
            Select Case Index
                 Case 0: Kitaplar.ad = Text1(Index).Text
                 Case 1: Kitaplar.yil = Text1(Index).Text
                 Case 2: Kitaplar.bno = Text1(Index).Text
                 Case 3: Kitaplar.ISBN = Text1(Index).Text
            End Select
       End If
   pcik: Exit Sub
   phata:
       MsgBox Err.Description, vbExclamation
       Resume pcik
   End Sub

   Private Sub VeriAl()
       okunuyor = True
       Text1(0).Text = Kitaplar.ad
       Text1(1).Text = Kitaplar.yil
       Text1(2).Text = Kitaplar.bno
       Text1(3).Text = Kitaplar.ISBN
       okunuyor = False
   End Sub

Burada görüleceği gibi veritabanı üzerinde doğrudan hiç bir işlem yapılmamaktadır. Veritabanı
erişimleri formun kodu içinde yapmaktansa sınıfın içinde yapıp bunu formun kodundan
saklamak kod yazımında önemli bir kolaylık ve esneklik sağlamaktadır. Bu nesneye yönelik
yaklaşımın sağladığı avantajlara bir örnek olarak verilebilir. Formun kodunda yapılan işlemleri
sırayla açıklayacak olursak;
     Form yüklenirken clsDolas sınıfından bir nesne yaratılmakta ve içine veriler
        okunmaktadır.
     Daha sonra form bellekten silinirken değişiklikler kaydedilmekte ve hata durumunda ne
        yapılacağı bilgisi kullanıcıya bırakılmaktadır.
                                                      49
      Kaydet butonu ile değişiklikler kaydedilmektedir.
      Hareket tuşlarına basıldığında yapılması gerekenler yapılmaktadır.
      Metin kutuları üzerinde yapılan değişiklikler doğrudan kayıt nesnesinin özelliklerine
       aktarılır.
      VeriAl yordamında ise kayıt nesnesinin özellikleri metin kutularına aktarılmaktadır.

Programın çalışması aşağıdaki gibi olacaktır.




3.2.3. Veritabanı Üzerinde Ekleme ve Silme İşlemleri

Yukarıda hazır bir veritabanı olan BIBLIO.MDB üzerinde tanımladığımız sınıfı kendi
veritabanımız olan PERSONEL veritabanı üzerinde yeniden tanımlayalım. Bu sınıfı personel_bil
tablosu üzerinde yeniden tanımlamak için kod aşağıdaki gibi değiştirilmelidir.

   Private db As Database
   Private rs As Recordset
   Private degisti As Boolean
   Private myeni As Boolean

   Private msicno As String
   Private mad_soyad As String
   Private mdyer As String
   Private mdtar As String

   Public Enum hareket
       ilk = 1
       son = 2
       birsonraki = 3
       bironceki = 4
   End Enum

   Public Enum hata
       yhareket = vbObjectError + 1000 + 11
       tutanakyok = vbObjectError + 1000 + 12
   End Enum

   Private Sub class_Initialize()
       Dim dosyaAdi As String
       dosyaAdi = App.Path & "\personel.mdb"
       Set db = DBEngine.Workspaces(0).OpenDatabase(dosyaAdi)
                                                 50
    Set rs = db.OpenRecordset("personel_bil", dbOpenDynaset, _
    dbSeeChanges, dbOptimistic)
    If rs.BOF And rs.EOF Then
          Yeni
    Else
          TutanakOku
    End If
End Sub

Private Sub Class_Terminate()
    rs.Close
    Set rs = Nothing
    db.Close
    Set db = Nothing
End Sub

Private Sub HataVer(hatano As hata)
    Dim tanim As String
    Dim aciklama As String
    Select Case hatano
         Case yhareket: tanim = "YANLIS HAREKET"
         Case tutanakyok: tanim = "tutanak personel_bil tablosunda yok"
         Case Else: tanim = "TANIMSIZ HATA"
    End Select
    aciklama = App.EXEName & ".clsPBil"
End Sub


Private Sub TutanakOku()
    mdyer = rs![dyer] & " "
    msicno = rs![sicno] & " "
    mad_soyad = rs![ad_soyad] & " "
    mdtar = rs![dtar] & " "
    MsgBox aciklama & vbCrLf & tanim
End Sub

Private Sub TutanakGunle()
    On Error GoTo phata
    rs.Edit
    rs![dyer] = mdyer
    rs![sicno] = msicno
    rs![ad_soyad] = mad_soyad
    rs![dtar] = mdtar
    rs.Update
    degisti = False
    Exit Sub
phata:
    rs.MovePrevious
    rs.MoveNext
    Err.Raise Err.Number, Err.Source, Err.Description, _
    Err.HelpFile, Err.HelpContext
End Sub

Public Property Get sicno() As String
    sicno = msicno
End Property

Public Property Let sicno(ssicno As String)
    msicno = ssicno
    degisti = True
End Property
Public Property Get ad_soyad() As String

                                                  51
    ad_soyad = mad_soyad
End Property
Public Property Let ad_soyad(sad_soyad As String)
    mad_soyad = sad_soyad
    degisti = True
End Property
Public Property Get dyer() As String
    dyer = mdyer
End Property
Public Property Let dyer(sdyer As String)
    mdyer = sdyer
    degisti = True
End Property
Public Property Get dtar() As String
    dtar = mdtar
End Property

Public Property Let dtar(sdtar As String)
    mdtar = sdtar
    degisti = True
End Property
Public Property Get degistimi() As Boolean
    degistimi = degisti
End Property

Public Sub git(htur As hareket)
    On Error GoTo phata:
    Select Case htur
          Case ilk: rs.MoveFirst
          Case son: rs.MoveLast
          Case birsonraki: rs.MoveNext
          Case bironceki: rs.MovePrevious
          Case Else: HataVer yhareket
    End Select
    TutanakOku
phata:
    If rs.EOF Or rs.BOF Then HataVer yhareket
End Sub
Public Sub kaydet()
    If degisti Then
          If myeni Then
              YeniTutanak
          Else: TutanakGunle
          End If
    End If
End Sub
Private Sub YeniTutanak()
    rs.AddNew
    rs![dyer] = mdyer
    rs![sicno] = msicno
    rs![ad_soyad] = mad_soyad
    rs![dtar] = mdtar
    rs.Update
    rs.Bookmark = rs.LastModified
    myeni = False
    degisti = False
End Sub
Public Property Get yenimi() As Boolean
    yenimi = myeni
End Property
Public Sub Yeni()
    mdyer = " "

                                                    52
       msicno = " "
       mad_soyad = " "
       mdtar = " "
       myeni = True
   End Sub
   Public Sub sil()
       rs.Delete
       degisti = False
       myeni = False
       rs.MovePrevious
       If rs.BOF Then
             If Not rs.EOF Then
                  rs.MoveFirst
             Else: HataVer tutanakyok
             End If
       End If
       TutanakOku
   End Sub



Bu kod hemen hemen daha önceki sınıf tanımıyla aynıdır. Yapılan değişiklik tablo alanlarına
göre değişkenlerin ve yordamların yeniden adlandırılmasıdır. Bunun yanısıra sınıfın içine iki
yeni metot daha eklenmiştir. Bunlar Yeni tutanak ekleme ve tablodan tutanak silme
yordamlarıdır. Ayrıca Class_Initialize yordamında eğer tablo boşsa yeni tutanak ekleme yordamı
çağrılmaktadır.

Bu sınıftan yaratılmış bir nesne kullanarak tabloyu dolaşmayı ve tablo üzerinde ekleme, silme
işlemlerini yapan formun tasarımı daha önceki örnekte kullanılan form üzerinde aşağıdaki
değişiklikleri yaparak mümkündür.

    Form                                Name                 frmPBil
                                        Caption              Veritabanını İşleme
    CommandButton                       Name                 cmdKaydet
    CommandButton                       Name                 cmdEkle
    CommandButton                       Name                 cmdSil

Formun tasarımını yapmak için ileride verilecek olan form tasarımı referans alınabilir.

Forma eklenecek kod aşağıdaki gibi olabilir.

   Private PBil As clsPBil
   Private okunuyor As Boolean
   Private Sub cmdEkle_Click()
       On Error GoTo phata
       PBil.kaydet
       PBil.Yeni
       VeriAl
   pcik: Exit Sub
   phata:
       MsgBox Err.Description, vbExclamation
       Resume pcik
   End Sub
   Private Sub cmdSil_Click()
       On Error GoTo phata
       PBil.kaydet
       PBil.sil
       VeriAl

                                                  53
pcik: Exit Sub
phata:
    Select Case Err.Number
         Case tutanakyok
         PBil.Yeni
         Resume Next
         Case Else
              MsgBox Err.Description, vbExclamation
              Resume pcik
    End Select
End Sub
Private Sub Form_Load()
    On Error GoTo phata
    Set PBil = New clsPBil
    VeriAl
pcik: Exit Sub
phata:
    Select Case Err.Number
         Case tutanakyok
         PBil.Yeni
         Resume Next
         Case Else
              MsgBox Err.Description, vbExclamation
              Unload Me
              Resume pcik
    End Select
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
    On Error GoTo phata
    PBil.kaydet

pcik: Exit Sub

phata:
    If MsgBox("Olusan hata:" & vbCrLf & Err.Description & vbCrLf & _
    "devam ederseniz, yaptiginiz degisiklikler kaybolur" & vbCrLf & _
    "Çikmak istiyor musunuz?", vbQuestion Or vbYesNo Or _
    vbDefaultButton2) = vbNo Then Cancel = True
    Resume pcik
End Sub

Private Sub cmdKaydet_Click()
    On Error GoTo phata
    PBil.kaydet
    VeriAl
pcik: Exit Sub
phata:
    MsgBox Err.Description, vbExclamation
    Resume pcik
End Sub

Private Sub Command1_Click(Index As Integer)
    On Error GoTo phata
    PBil.kaydet
    Select Case Index
         Case 0: PBil.git ilk
         Case 1: PBil.git bironceki
         Case 2: PBil.git birsonraki
         Case 3: PBil.git son
    End Select
    VeriAl
pcik: Exit Sub
                                                 54
   phata:
       MsgBox Err.Description, vbExclamation
       Resume pcik
   End Sub

   Private Sub Text1_Change(Index As Integer)
       On Error GoTo phata
       If Not okunuyor Then
            Select Case Index
                 Case 0: PBil.sicno = Text1(Index).Text
                 Case 1: PBil.ad_soyad = Text1(Index).Text
                 Case 2: PBil.dyer = Text1(Index).Text
                 Case 3: PBil.dtar = Text1(Index).Text
            End Select
       End If
   pcik: Exit Sub
   phata:
       MsgBox Err.Description, vbExclamation
       Resume pcik
   End Sub

   Private Sub VeriAl()
       okunuyor = True
       Text1(0).Text = PBil.sicno
       Text1(1).Text = PBil.ad_soyad
       Text1(2).Text = PBil.dyer
       Text1(3).Text = PBil.dtar
       okunuyor = False
   End Sub

Bu form için yapılanlar da sınıf için yapılanların aynıdır. Yeni eklenen kısımlar Ekleme ve Silme
butonlarına basıldığında ilgili clsPBil sınıfının metotlarının çağırılmasıdır.

Formun çalışır haldeki görüntüsü aşağıdaki gibidir.




3.2.4. Veritabanı Üzerinde Arama İşlemleri

Arama işlemi kullanmak için bir önceki örnekte kullandiğımız clsPBil sınıfını olduğu gibi
kullanabiliriz. Gerekli olan frmPBil formuna bir buton daha eklemek ve bu butona işlev
kazandırmaktır. Bunu sağlamak için aşağıdaki kodu forma ekleyin.

   Private Sub cmdBul_Click()
       Dim ad As String
       Dim bulundu As Boolean
                                                     55
       On Error GoTo phata
       ad = InputBox("Aranacak Personelin Adini Girin", "ARAMA")
       PBil.git ilk
       bulundu = PBil.sontutanak
       While Not bulundu
       If InStr(1, PBil.ad_soyad, ad) > 0 Then
            bulundu = True
       Else
            PBil.git birsonraki
            If PBil.sontutanak Then
                 If InStr(1, PBil.ad_soyad, ad) = 0 Then _
                      MsgBox "Personel BULUNAMADI", vbExclamation
                      bulundu = True
                 End If
            End If
       Wend
       VeriAl
       Exit Sub
   phata:
       MsgBox Err.Description, vbExclamation
   End Sub

Bu kodda görüleceği gibi clsPBil sınıfından yaratılmış olan Pbil nesnesinin sontutanak adlı bir
özelliği kullanılmıştır. Bu özellik için clsPBil sınıfı içinde yapılan tanım aşağıdaki gibidir.

   Public Property Get sontutanak() As Boolean
       sontutanak = rs.EOF
       If Not rs.EOF Then
            rs.MoveNext
            sontutanak = rs.EOF
            rs.MovePrevious
       End If
   End Property

Bu özellik, sadece okunabilir bir özelliktir. Kullanım amacı, veritabanının son tutanağına
gelinmişse bunu çağrıldığı yere döndürmektir.

Program çalıştığında aşağıdaki gibi bir görüntü çıkacaktir.

Bu form görüntüsünden BUL butonuna basıldığında isim girmeyi sağlayan bir form görüntüsü
gelir. Bu form InputBox fonksiyonu kullanılarak çıkarılabilen hazır bir veri alma formudur.

Bu programdaki arama işlemi sadece AD_SOYAD alanı üzerinden yapılmıştır. Aynı işlemleri
diğer alanlar için de yapmak mümkündür.




                                                 56
Veritabanındaki tutanakların hepsine kod aracılığıyla bakmak yerine arama işlemi için SQL
sorgu dilini kullanmak daha basittir. Şimdi veritabanı üzerinde arama yapmak için SQL
kullanımını örnekleyelim. Bunun için yukarıdaki örnekte yapılması gereken değişiklikler adımlar
halinde aşağıda gösterilmiştir.

1. frmPBil formunun cmdBul_Click yordamını aşağıdaki gibi değiştirin.

   Private Sub cmdBul_Click()
       Dim ad As String
       Dim strSQL As String
       On Error GoTo phata
       ad = InputBox("Aranacak Personelin Adini Girin", "ARAMA")
       If ad <> "" Then _
            strSQL = "SELECT * from personel_bil WHERE ad_soyad LIKE '*" _
            & ad & "*';"
            frmAra.ara "ad_soyad", strSQL, Me
       Exit Sub
   phata:
       MsgBox Err.Description, vbExclamation
   End Sub

2. Burada kullanılan frmAra formu sadece ListView nesnesi içeren bir formdur. Projeye bir form
ekleyip bu formu aşağıda belirtildiği gibi yaratın.

   Form                       Name                     frmAra
                              Caption                  SORGU SONUÇLARI
   Listview                   Name                     lstSonuc
                              View                     3- lvwReport
                              LabelEdit                1-lvwManual

Bu formun içine aşağıdaki yordamı kodlayın.

   Public Sub ara(alan As String, _
   strSQL As String, frm As Form)
       Dim PBil As clsPBil
       Dim rs As Recordset
       Dim fld As Field
       Dim kno As Long
                                                 57
       Set PBil = New clsPBil
       Set rs = PBil.ara(strSQL)
       If Not rs.EOF Then
            lvwSonuc.ColumnHeaders.Add , "kno", _
            "TUTANAK", 700
            For Each fld In rs.Fields
                 lvwSonuc.ColumnHeaders.Add , fld.Name, _
                 fld.Name, 200 * Len(fld.Name)
            Next
            Do
                 kno = kno + 1
                 lvwSonuc.ListItems.Add kno, , CStr(kno)
                 For Each fld In rs.Fields
                      lvwSonuc.ListItems(kno). _
                      SubItems(fld.OrdinalPosition + 1) = _
                      fld.Value & " "
                 Next
                 rs.MoveNext
            Loop While Not rs.EOF
            rs.Close
            Set rs = Nothing
            Me.Show vbModal, frm
       Else
            MsgBox "TUTANAK BULUNAMADI", vbInformation
            Me.Hide
       End If
   End Sub

Bu yordamda önce Pbil adlı clsPBil sınıfından bir nesne üretiliyor. Daha sonra bu nesnenin ara
adlı fonksiyonu çağrılarak sorgu sonuçları bir RecordSet yapısı içine alınıyor.

3. clsPBil sınıfının yeni fonksiyonu ara için aşağıdaki kodu bu sınıfın koduna ekleyin.

   Public Function ara(sSQL As String) As Recordset
       Set ara = db.OpenRecordset(sSQL, dbOpenDynaset, _
       dbReadOnly)
   End Function

Bu kodda da görülebileceği gibi Class_Initialize yordamıyla açılan ve db veritabanı değişkeni
kullanılarak veritabanı üzerinde bir sorgu yapılıyor. Sorgu sonuçları bu fonksiyon yardımıyla
fonksiyonun çağrıldığı yerdeki bir RecordSet yapısı içine döndürülüyor. Sorgu sonuçları için
sadece okunabilir, Dynaset yapısında bir Recordset kullanılıyor.

Programın çalıştırılıp BUL butonuna basıldığında aşağıdaki ekran görüntüsü belirecektir.




Bu sonuç isminin içinde “i” harfi geçen kişilerin listesidir. Bunun SQL dilindeki ifadesi şu
şekilde olur.

   SELECT * FROM personel_bil WHERE ad_soyad LIKE '*i*'



                                                  58
Bu sorgu clsPBil sınıfının ara fonksiyonunda veritabanına OpenRecordset metodu aracılığıyla
verilmekte ve veritabanı da bu sorgu sonucunu bir Recordset yapısı içinde döndürmektedir.

Veritabanı üzerinde arama yapmanın başka bir yolu da indeks kullanmaktır. Indeks kullanmak
için Recordset yapısının Seek metodu kullanılır.

1. Seek metodu sadece tablo türü Recordset yapılarında kullanıldığı için ilk yapılması gereken
clsPBil sınıfının Class_Initialize yordamında OpenRecordset metodunun paramatrelerini
değiştirmektir. Bu metodun kullanılışını aşağıdaki gibi değiştirin.

   Set rs = db.OpenRecordset("personel_bil", dbOpenTable, _
   dbSeeChanges, dbOptimistic)

2. Bu Recordset yapısı için indeks belirlemek index özelliğine değer aktarmakla olur. Bu işlemi
gerçekleştirmek için aşağıdaki kodu da Class_Initialize yordamına ekleyin.

   rs.Index = "ind_sicno"

3. Aşağıdaki yordamı clsPBil sınıfına ekleyin

   Public Sub indeksAra(deger As String)
       Dim aktiftut As Variant
       aktiftut = rs.Bookmark
       rs.Seek "=", deger
       If Not rs.NoMatch Then
            TutanakOku
       Else
            rs.Bookmark = aktiftut
            HataVer tutanakyok
       End If
   End Sub

Burada önce aktif tutanağın konumu saklanmakta, Recordset yapısının Seek metodu çağrılıyor.
Eğer tutanak yoksa aktif tutanağa tekrar dönülüyor.

4. frmPBil formunun cmdBul_Click yordamını aşağıdaki gibi değiştirin

   Private Sub cmdBul_Click()
       Dim ad As String
       Dim strSQL As String
       On Error GoTo phata
       ad = InputBox("Aranacak Personelin Sicil " & _
       "Numarasını Girin", "ARAMA")
       If ad <> "" Then PBil.indeksAra ad
       VeriAl
       Exit Sub
   phata:
       MsgBox Err.Description, vbExclamation
   End Sub

Bu program sicil numarası verilen personelin bilgilerini formda görüntüler.




                                                    59
4. İLERİ DÜZEY VERİ TABANI GELİŞTİRME

4.1. Veri Bütünlüğünü Sağlama.

Visual Basic ile veritabanı geliştirirken sağlanan önemli bir özellik de veri bütünlüğünü koruma
özelliğidir. Bu ilişkisel veritabanı kullanımının temel bir gereğidir.

Visual Basic ile veritabanının veri bütünlüğünü korumak ve sağlamak için veritabanı tabloları
arasında tanımlanabilen ilişkiler kullanılır. İlişki tanımlama kavramına daha önce değinilmişti.
İlişki yukarıda da bahsedildiği gibi birbiriyle ilişkili alanlar barındıran iki farklı tabloya girilecek
verilerin tutarlılığını sağlar. Veritabanı üzerinde bir ilişki tanımlandıktan sonra, ilişkiyi ihlal eden
veri girişi DAO nesnesinin ele alınabilir hatalı bir duruma girmesini sağlar. Böylece hem veri
bütünlüğü ve tutarlılığı sağlanmış olur, hem de kullanıcı böyle bir ihlalin açığa çıktığından
haberdar edilir.

Veritabanı bütünlüğünü sağlamanın bir diğer yolu da bazı kurallar tanımlayarak kullanıcının
belirli alanlara yanlış veriler girmesine engel olmaktır.

Veritabanı üzerinde tablolara ve alanlara uygulanabilecek birçok kural vardır.

       Alanlara girilebilecek değerler bir liste ile sınırlanabilir.
       Alanlara veri girilmesi zorunlu hale getirilebilir.
       Alanlara girilen değerler başka alanlara girilen değerlere bağlı olabilir.

Kuralları uygulamanın iki yolu vardır.

       Ekleme, silme ve değiştirme yapmadan önce verilerin kurallara uyup uymadığını kontrol
        etmek.
       Veritabanı tablolarına kuralları ekleyerek veritabanı motorunun kuralları uygulamasını
        sağlamak.

Veritabanı üzerinde tanımlanabilecek kuralların hepsini veritabanı motoruna bırakmak pek
mümkün değildir, fakat amaç olabildiğince çok kuralı veritabanı tanımına eklemek ve kuralları
veritabanı motorunun uygulamasını sağlamak olmalıdır.

Şu ana kadar veritabanı üzerinde bütünlüğünü sağlamaya yönelik bir çok kural tanımladık
bunlar;

       Bir alanın veri türünü belirleme (Yanlış türden veri girişini engeller),
       Primary Key ve Uniqe indeks tanımlama (verilerin tekrarını engeller),
       Tablolar arasında ilişki tanımlama (tutarsız veri girişini engeller) kurallarıdır.

Bu kuralların yanısıra aşağıdaki kuralları da veritabanına eklemek mümkündür.

       Required özelliği bir alanın boş bırakılarak geçilmesini engeller.
       Bir alanın veya bir tablonun ValidationRule özelliği alana veya tabloya girilecek olan
        değerleri belirli bir koşulla sınırlar. Bu özellik kullanıldığında ValidationText özelliği de
        kullanılır. Bu özellik de bu kural ihlal edildiğinde verilecek hata mesajını belirtir.
       AllowZeroLength özelliği metin türünde tanımlanmış bir alanın boş bir değer
        alabilmesine izin verilmesini sağlar.
                                                  60
Yukarıda belirtilen özelliklerden Required ve AllowZeroLength özellikleri Boolean türünden
özelliklerdir.

ValidationRule özelliği geçerli bir Visual Basic ifadesini belirtir. Bu ifadede kullanıcının
tanımladığı fonksiyonlar, SQL kümeleme fonksiyonları, bir sorgu, başka bir tablonun alanı yer
alamaz.

Şimdi veritabanı bütünlüğünü korumak için kural tanımlarını örneklemek için daha önce
kullanmış olduğumuz PERSONEL veritabanı üzerinde bazı kurallar tanımlayalım ve bunları
veritabanı üzerine uygulayalım.

1. Önce kuralları bir tablo halinde gösterelim.

   Tablolar                Alanlar                Özellik          Değer
   Personel_bil            sicno                  Required         True
                           ad_soyad               Required         True
                           dtar                   Required         True
                           dtar                   ValidationRule   Koşul1*
                           dyer                   Required         True
   personel_gorev          sicno                  Required         True
                           CYIL                   Required         True
                           CYIL                   ValidationRule   Koşul2*
                           gno                    Required         True
                           mno                    Required         True
                           derece                 Required         True
   gorevler                gno                    Required         True
                           GADI                   Required         True
   meslekler               mno                    Required         True
                           MADI                   Required         True

Koşul1: IIf(Year(dtar)>1930, Year(dtar)<1976, False)
Koşul2: IIf(CYIL>=0, CYIL<68, False)

2. Yeni bir proje yaratın. Aşağıdaki nesneleri ekleyin.

 Form                   Name                        frmKurallar
                        Caption                     KURAL EKLEME PROGRAMI
                        BorderStyle                 3-FixedDialog
                        CommonDialog Name           dlg
 CommandButton          Name                        cmdKural
                        Caption                     &Kural Ekle
 CommandButton          Name                        cmdVT
                        Caption                     &Veritabanı aç
 Label                  Name                        lblSonuc
                        Autosize                    True

Forma aşağıdaki kodu girin.
                                                  61
   Private db As Database

   Private Sub cmdKural_Click()
       On Error GoTo phata:
       KuralEkle
       lblSonuc.Caption = "KURALLAR EKLENDİ"
       Exit Sub
   phata:
       MsgBox Err.Description, vbExclamation
   End Sub

   Private Sub cmdVT_Click()
       Dim dosya As String
       dlg.InitDir = App.Path
       dlg.DefaultExt = "mdb"
       dlg.DialogTitle = "Veri Tabani Aç"
       dlg.Filter = "VB Veritabani(*.mdb)|*.mdb"
       dlg.FilterIndex = 1
       dlg.Flags = cdlOFNHideReadOnly Or cdlOFNFileMustExist _
       Or cdlOFNPathMustExist
       dlg.CancelError = True
       dlg.ShowOpen
       dosya = dlg.filename
       Set db = DBEngine.Workspaces(0).OpenDatabase(dosya)
       cmdKural.Enabled = True
       cmdVT.Enabled = False
       Exit Sub
   phata:
       dosya = ""
   End Sub

   Private Sub KuralEkle()
       Dim td As TableDef
       Dim fld As Field
       For Each fld In db.TableDefs("personel_bil").Fields
            fld.Required = True
       Next
       For Each fld In db.TableDefs("personel_gorev").Fields
            fld.Required = True
       Next
       For Each fld In db.TableDefs("gorevler").Fields
            fld.Required = True
       Next
       For Each fld In db.TableDefs("meslekler").Fields
            fld.Required = True
       Next
       Set fld = db.TableDefs("personel_bil").Fields("dtar")
       fld.ValidationRule = "IIf(Year(dtar)>1930, Year(dtar)<1976, False)"
       fld.ValidationText = "Dogum tarihi 1930-1976 arasinda olmali"
       Set fld = Nothing
       Set fld = db.TableDefs("personel_gorev").Fields("CYIL")
       fld.ValidationRule = "IIf(CYIL>=0, CYIL<68, False)"
       fld.ValidationText = "Çalistigi yil 0-68 arasi olmali"
       Set fld = Nothing
       cmdKural.Enabled = False
   End Sub

Yukarıdaki kodda önemli olan KuralEkle fonksiyonudur. Burada, kural tanımlarımızın gereği
tabloların bütün alanlarının Required özellikleri True yapılmıştır. Bunun anlamı, ‘veritabanının
hiç bir tablosundaki hiç bir alan boş geçilemez’ dir.
                                                     62
Bu kuraldan başka iki tane de farklı kural tanımlanmıştır. Bu kurallar doğum tarihinin yılını ve
kişinin kurumda çalıştığı yıl sayısını sınırlayan kurallardır.

Program çalıştığında aşağıdaki form çıkar. Başlangıçta bu formun üstündeki “KURALLAR
EKLENDİ” yazısı yoktur ve sadece veritabanı aç butonu aktif haldedir. Bu butona basıldığı anda
standart Windows95 Open Dialog kutusu çıkar ve buradan veritabanının adının bulunmasına
olanak tanınır. Daha sonra veri tabanı açılır, veritabanı açma butonu gri hale getirilir, kural
ekleme butonu aktif hale gelir. Kurallar eklendikten sonra bu buton da gri hale gelir.




4.2. Çok Kullanıcılı Veritabanları ve Güvenlik

Eğer bir ağ üzerinde, birden fazla kullanıcıya hizmet veren uygulamalar geliştirilecekse, bu
uygulamanın verileri kullanıcılar arasında etkin bir biçimde paylaştırması gerekir. Bu bölümde,
çok kullanıcılı uygulamalar geliştirilirken dikkat edilmesi gereken konuları içermektedir. Çok
kullanıcılı sistemlerde verilere erişimin denetlenmesi için gerekli olan kilitleme stratejileri ve bu
kilitlemelerin çok kullanıcılı bir ortamda ele alınışına değinilecektir.

Bu bölümde Microsoft Jet veritabanı motoru bağlamında çok kullanıcılı veritabanı kavramı ele
elınacaktır, ODBCDirect bağlamında değil. ODBCDirect yöntemi ile uygulamalar doğrudan
ODBC veritabanlarına erişebilir. Bu erişim için Jet veritabanı motoruna ihtiyaç yoktur. Bu
konuya daha sonra değinilecektir.
Bir programın çok kullanıcılı olabilmesi için;

   1. Uygulamanın tamamını bir ağ sunucusu üzerine yerleştirmek
   2. Uygulamayı iki parçaya bölmek (geri uç kısmı, tabloları içeren kısım ve ön uç kısmı,
      nesneleri, makroları ve modülleri içeren kısım) ve daha sonra geri uç kısmını bir ağ
      sunucusuna yerleştirmek ve on uç kısmını da kullanıcılara dağıtmak

olmak üzere iki yaklaşım sözkonusudur.

Bu yaklaşımlardan ilki ağ trafiğinde bir artışa neden olur.

Ağ üzerinden erişim daha yavaş olduğu için uygulamanın bazı kısımlarını kullanıcı
bilgisayarında tutmak her zaman için hız avantajı sağlar. Bu bağlamda uygulamanın kesimleri iki
kategori altında toplanabilir.
                                                 63
Statik kesimler : Programın çalışmasını sağlayan .dll ve .exe dosyalarıdır. Uygulamadaki,
formlar, raporlar, program kodları da statik kesimlerdir.

Aktif kesimler : Çok kullanıcılı bir ortamda kullanıcıların erişeceği gerçek verilerin tutulduğu
dosyalardır. Bunlar Jet veritabanları veya dış veritabanları olabilir.

Statik kesimlerin özellikleri:
     Kullanıcı bilgisayarında kurulu ve çalışır halde olmalıdırlar.
     Uygulamanın tasarımı değiştiğinde bu kısımlar da değişmelidir.
     Uygulamanın nesne yapısındaki değişklikler anında kullanıcı bilgisayarına yansımak
        zorundadır. Jet veritabanı motoru bu özelliği sağlayacak bir kopyalama (replication)
        mekanizmasında sahiptir. Gerekiyorsa bu mekanizma da nesnelerin son biçimlerini elde
        etmek için kullanılabilir.

Aktif kesimlerin özellikleri:
     Veri erişimi etkin olmalı, indeks yapıları kullanılmalıdır. Aksi takdirde ağ trafiği
       artacağından uygulamaların performansı düşer.
     Sık değişmeyen verilerin kullanıcı bilgisayarlarında tutulması ağ trafiğini azaltacaktır.
İki düzeyli veritabanı yaklaşımı sözkonusu olduğunda, her kullanıcının kendi bilgisayarında;
     Bir wokgroup bilgi dosyası ve
     Her bir veritabanı için bir kilitleme bilgi dosyası(.ldb) olması gerekir.
Microsoft Jet veritabanının çok kullanıcılı modeli aşağıdaki gibidir.




Workgroup bilgi dosyası, kullanıcı, grup ve password bilgilerini ve kullanıcı ile ilgili başka
bilgileri tutan bir veritabanıdır. Bu dosya ağ sunucusunda veya her bir kullanıcı bilgisayarında
tutulabilir. Herbir kullanıcı bilgisayarında tutulduğunda güvenlik bilgileri değiştiğinde
değişiklikleri anında güncelleme gerekliliği vardır.

Kilitleme bilgi dosyası, kilitlenmiş olan tutanaklarla ilgili bilgileri tutar. Veri tabanı açıldığında
bu kütük yoksa jet veritabanı motoru bu dosyayı yaratır. Paylaşımlı olarak açılan herbir
veritabanı dosyası için bir kilitleme dosyası tutulur. Bu dosyaya verilen isim veritabanı
dosyasının ismiyle aynıdır. Bu dosya veritabanı dosyası ile aynı dizinde tutulur.

Microsoft Jet tarafından desteklenen ağ-sunucuları şunlardır:

       Microsoft Windows NT and Windows 95 networks
       Banyan VINES 5.52
                                                 64
       DECnet 4.1
       LANtastic 5.0
       Novell NetWare 3.x and 4.x
       OS/2 LAN Manager, 2.1 and 2.2

Tek kullanıcılı bir ortamda çalışırken veriler tamamen kullanıcıya ait olduğundan hiç bir sorun
yoktur. Fakat çok kullanıcılı ortama geçildiğinde çatışmalar sözkonusudur.

Bu çatışmalar kilitleme olanakları sayesinde engellenmektedir. Bu olanaklar birçok kullanıcının
aynı anda veritabanı üzerinde işlem yapmasına olanak tanır.

Paylaşımlı bir veritabanı üzerinde işlem yapılırken, değişiklik yapılacağı zaman veri kilitlenir.
Bu sırada başka kullanıcılar bu veriyi okuyabilir fakat değişiklikler yapamaz. Jet veritabanı
motoru üç düzeyde kilitleme olanağı sağlamaktadır.

Dışlayan mod : Tüm kullanıcıların veritabanına erişimlerini engeller. Bu en kısıtlayıcı moddur.

RecordSet kilitleme : Bir Recordset nesnesinin belirttiği bir tabloyu table-read veya table-write
kilitlerini kullanarak kilitler.

Sayfa kilitleme : Üzerinde değişiklik yapılmakta olan 2048 byte(2K) uzunluğundaki veriyi
kilitler.

Hangi tür kilitlemeyi kullanacağımızı belirlemek için, sağlanacak olan paralellik düzeyi dikkate
alınmalıdır. En yüksek paralellik için en düşük kısıtlamaya sahip kilitlenme kullanılmalıdır.
Bunun yanısıra tüm verilere çabuk bir şekilde erişim için ise dışlayan kilitleme tercih edilmelidir.

Veritabanı üzerinde büyük değişiklikler yapılacaksa dışlayan mod tercih edilmelidir.

Tek kullanıcılı bir ortamda veritabanı erişimleri dışlayan modda olur, çünkü veritabanını
kullanacak başka kimse zaten yoktur. Çok kullanıcılı sistemlerde veritabanı paylaşımlı modda
kullanılmak üzere düzenlenmelidir. Bu tür ortamlarda kullanıcıların veritabanını dışlayan modda
açmaları engellenmelidir. Bunun için kullanıcılara veritabanı üzerinde haklar tanımlanır. Bir
kullanıcı bu haklar çerçevesinde veritabanına erişir.

Tutanak bazında kilitleme sözkonusu ise, veritabanı paylaşımlı modda açılır. Veritabanı
paylaşımlı modda açıldığında Jet veritabanı motoru çatışmaları ele alır ve tutarsız durumlara
girilmesini engeller.

Aşağıdaki kod parçası, veritabanının paylaşımlı modda açılmasını örneklemektedir.

   Function VTac(vt As Database, dosya As String, dislayan as Boolean) As Integer
       On Error Resume Next
       Set vt = OpenDatabase(dosya, dislayan)
       Select Case Err
            Case 0: VTac = 0 'Başarılı
            Case 3033: VTac = 1 'Erişim Hakkı yok
            Case 3343: VTac = 2 'Hatalı Veritabanı
            Case 3044: VTac = 3 'Hatalı Dizin Adı
            Case 3024: VTac = 4 'Hatalı Dosya Adı
            Case Else: VTac = 5 'Başarısız
       End Select
       Err = 0
   End Function

                                                     65
Bu kod sayesinde veritabanı verilen parametreye göre paylaşımlı veya paylaşımsız açılmakta ve
bu açma işleminin sonucu çağrıldığı ortama 0-5 arasında bir sayı olarak döndürülmektedir. Bu
fonksiyonun kullanımı şu şekilde olabilir.

   Dim Sonuc As Integer
   Dim db as Database
   Sonuc = VTac(db,"PERSONEL.MDB", False)

Bazen bir veritabanını sadece okunabilir modda açmak gerekebilir. Bu mod paylaşımlı modun
değiştirilmiş biçimidir. Bir veritabanını sadece okunabilir modda açmak için şu kod kullanılır.

   Vt = OpenDatabase("PERSONEL.MDB", False, True)

Veritabanı sadece okunabilir modda açıldığı zaman hiç bir çatışmaya neden olunmadan
veritabanı dolaşılabilir.

Recordset kilitleme yöntemiyle, Recordset nesnesinin ilgili olduğu tutanakların kilitlenmesi
sağlanabilir. Bu tür kilitleme ancak Dynaset türü Recordset nesnelerinde mümkündür. Veritabanı
paylaşımlı modda açıldıktan sonra Recordset kilitlemeyi sağlamak için OpenRecordset metodu
birkaç parametre daha eklenerek çağrılır.
Kilitlemeyi sağlamak için,

   1. Veritabanı paylaşımlı modda açılır,
   2. OpenRecordset metodu, kilitleme biçimi parametre olarak verilerek çağrılır.
   3. Recordset nesnesi ile yapılacak işlemler bittiğinde Close metodu çağrılarak kilitlemenin
      iptal edilmesi sağlanır.


Aşağıdaki kod kesiminde bir Recordset Yapısının dışlayan modda nasıl açılabileceğini görmek
mümkündür.

   Function TabloAc(vt As Database, rs As Recordset, Tablo As String) As Integer
       Set rst = dbs.OpenRecordset(Tablo, _
       dbOpenTable, dbDenyRead + dbDenyWrite)
       Select Case Err
            Case 0: OpenTableExclusive = 0 'Başarılı
            Case Else: OpenTableExclusive = 1 'Başarısız
       End Select
       Err = 0
   End Function

Burada Recorset yapısı verilen 3. Parametre ile hem yazmaya hem okumaya karşı kilitlenmiştir.
Bu parametre belirtilmezse Sayfa Kilitleme yöntemi kullanılır. Bu yöntemle başka kullanıcıların
veriyi okumaları engellenmez.
Recordset açılırken eğer başka kullanıcılar tarafından kullanılan tutanaklara kilitleme yapılmaya
çalışılıyorsa aşağıdaki hata oluşur.

   error 3262:"Couldn't lock table <a>; currently in use by user <b> on machine <c>."

Bu hatada a, bir tablo ismi, b, bir kullanıcı ismi, c, ağdaki bir makinenin ismidir. Bu hatayı ele
almak için bir süre beklyip kilitlemeyi tekrar denemek gerekir.

Sayfa Kilitleme yöntemiyle, değiştirilecek tutanakların kilitlenmesi mümkündür. Bir seferde
2048 byte uzunluğundaki veri bu yöntemle kilitlenebilir. Bu yöntemle veriler kilitlendiğinde
                                                     66
diğer kullanıcılar veriyi okuyabilir fakat değiştiremez. Sayfa kilitlemeyi denetlemek için
Recordset nesnesinin LockEdits özelliği kullanılır. Sayfa kilitleme modları iki tanedir. Bunlar
Pesimistic ve Optimistic olarak adlandırılır.

Pessimistic Kilitleme ile, şu anda değiştirilecek olan tutanağın bulunduğu sayfa, Edit metodu
kullanıldığı anda kilitlenir. Bu kilitleme değişiklikler tamamlanıncaya kadar devam eder.

Bu kilitleme yönteminin temel avantajı, kilitleme işlemi yapıldıktan sonra kilitlenen sayfadaki
tutanaklarla yapılan işlemlerde çatışma olmayacağının garanti edilmesidir. Ayrıca, pessimistic
kilitleme veritabanındaki tutanakların en son durumunu elde etmenin en emin yoludur. Çünkü bir
kere kilitleme yapıldıktan sonra hiç bir kullanıcı bu verileri değiştiremez.

Dezavantajı ise, sayfanın uzun süre kilitli kalma riskidir. Örneğin bir kullanıcı sayfayı kilitler ve
uzun süre bilgisayarı boş bırakırsa bu sayfada uzun bir süre boyunca kimse değişiklik yapamaz.

Optimistic Kilitleme yöntemiyle, sayfa sadece değişiklikler kaydedileceği zaman kilitleme
yapılır. Böylece sayfanın kilitli kaldığı süre önemli ölçüde azalmış olur.

Bu kilitleme yönteminin dezavantajı da, yapılan değişikliklerin kaydedilebileceğinden emin
olamamaktır. Çünkü değişikliğe başlandığında gerçek bir kilitleme yapılmaz. Bu esnada başka
bir kullanıcı tutanağı pesimistic kilitleme yöntemiyle kilitlerse, yapılan değişiklikler
kaydedilmeye çalışıldığında erişim hakkı olmadığı için bu işlem başarısız olacaktır.

Optimistic Kilitlemeyi kullanmak için;

   1.   Tablo veya Dynaset türünde bir Recordset açın.
   2.   Belirli bir tutanağı aktif tutanak yapın.
   3.   Recordset nesnesinin LockEdits özelliğine False aktarın.
   4.   Edit metodunu kullanarak değişikliğe başlayın.
   5.   Update metodunu kullanarak değişiklikleri kaydedin
   6.   Başarısızlık durumunda tekrar deneyin.

Değişiklikler kaydedileceği zaman veritabanı üzerinde Pesimistic kilitleme otomatik olarak
yapılır.

Sayfa Kilitleme sırasında çıkan hatalar:

   3188. Daha önce kilitlenmiş sayfa, kaydetme yapılamaz.
   3197. Aynı anda değişiklik yapmaya kalkışma sonucu oluşan çatışma.
   3260. Daha önce kilitlenmiş sayfa, kilitleme yapılamaz.

Örnek : Sayfa kilitlemeyi örneklemek için daha önce kullanılan PERSONEL veritabanının
PERSONEL_BIL tablosunu kullanalım.

1. Yeni bir proje yaratın ve içindeki formu silin. Projeye frmPBil formunu ekleyin.

2. Formun kodunu tamamen silin.

3. Formun üzerindeki, SIL butonunu YENILE, EKLE butonunu DEGISTIR olarak değiştirin.
   İsimlerini de buna uygun hale getirin.

4. Form üzerindeki BUL butonunu silip yerine aşağıdaki nesneleri ekleyin.
                                                 67
  Frame Name Frame1
  OptionButton Name Option1
  Caption Pessimistic Kilitleme
  OptionButton Name Option2
  Caption Optimistic Kilitleme

5. Formun kod kısmına aşağıdaki kodu ekleyin.

   Option Explicit
   Private db As Database
   Private rs As Recordset
   Private degisiyor As Boolean
   Private Const PESSIMISTIC = True
   Private Const OPTIMISTIC = False

   Private Sub cmdDeg_Click()
       Dim i As Integer
       On Error GoTo phata
       If degisiyor Then TutanakGunle
       rs.Edit
       degisiyor = True
       cmdDeg.Enabled = False
       cmdKaydet.Enabled = True
       For i = 0 To 3
            Text1(i).Enabled = True
       Next i
       Exit Sub
   phata:
       Select Case Err.Number
            Case 3260: MsgBox "Tutanak Kilitli", vbExclamation, "degistirme"
            Case Else: MsgBox Err.Description, vbExclamation, "degistirme"
       End Select
   End Sub

   Private Sub cmdKaydet_Click()
       TutanakGunle
   End Sub

   Private Sub cmdYenile_Click()
       If degisiyor Then TutanakGunle
       rs.Requery
       rs.MoveNext
       rs.MovePrevious
       VeriAl
   End Sub

   Private Sub Form_Load()
       Dim dosya As String
       On Error GoTo phata
       dosya = App.Path & "\PERSONEL.MDB"
       Set db = DBEngine.Workspaces(0).OpenDatabase(dosya)
       Set rs = db.OpenRecordset("personel_bil", dbOpenDynaset)
       If rs.EOF And rs.BOF Then
             MsgBox "Bos Tablo", vbExclamation, "HATA"
             Unload Me
       Else
             rs.MoveFirst
             VeriAl
       End If
       Option1 = True
   pcik: Exit Sub

                                                     68
phata:
    MsgBox Err.Description, vbExclamation
    Unload Me
    Resume pcik
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Set db = Nothing
    Set rs = Nothing
End Sub

Private Sub Command1_Click(Index As Integer)
    On Error GoTo phata
    If degisiyor Then TutanakGunle
    Select Case Index
         Case 0: rs.MoveFirst
         Case 1:
              rs.MovePrevious
              If rs.BOF Then rs.MoveFirst
         Case 2:
              rs.MoveNext
              If rs.EOF Then rs.MoveLast
         Case 3: rs.MoveLast
    End Select
    VeriAl
pcik: Exit Sub
phata:
    MsgBox Err.Description, vbExclamation
    Resume pcik
End Sub

Private Sub Option1_Click()
    If degisiyor Then TutanakGunle
    rs.LockEdits = PESSIMISTIC
End Sub

Private Sub Option2_Click()
    If degisiyor Then TutanakGunle
    rs.LockEdits = OPTIMISTIC
End Sub

Private Sub VeriAl()
    Dim i As Integer
    Text1(0).Text = rs!sicno
    Text1(1).Text = rs!ad_soyad
    Text1(2).Text = rs!dyer
    Text1(3).Text = rs!dtar
    For i = 0 To 3
         Text1(i).Enabled = False
    Next i
    cmdDeg.Enabled = True
    cmdKaydet.Enabled = False
    degisiyor = False
End Sub
Private Sub TutanakGunle()
    On Error GoTo phata:
    rs!sicno = Text1(0)
    rs!ad_soyad = Text1(1)
    rs!dyer = Text1(2)
    rs!dtar = Text1(3)
    VeriAl
    Exit Sub
                                               69
   phata:
       Select Case Err.Number
           Case 3260: MsgBox "Tutanak Kilitli", vbExclamation, "Kaydetme"
           Case Else: MsgBox Err.Description, vbExclamation, "Kaydetme"
       End Select
   End Sub
Programın çalışması aşağıdaki gibi olacaktır.




Kodu açıklayacak olursak; form yüklenirken veritabanı Recordset yapısı açılıyor. Değiştir
butonuna basıldığında veritabanı üzerinde değişiklik yapma başlatılıyor. Bu durumda tutanak
kilitleme önem kazanmaktadır.

Yenile butonuyla aktif tutanak yeniden gösteriliyor. Böylece son yapılan değişikliklerin
görülmesi sağlanabilir.

VeriAl yordamında veriler metin kutularına alınıyor. TutanakGunle yordamında ise değiştirilmiş
olan veriler veritabanı üzerine kaydediliyor.

Şimdi yukarıda anlatılan kilitleme mekanizmasını denemek için bir program hazırlanmış oldu.
Bu program kullanılarak optimistic ve pesimistic kilitleme arasındaki fark görülebilir.

Bu programın başka kopyalarını çalıştırarak çok kullanıcı ortam benzetimi yapılabilir.

4.3. Dış (External) Veritabanlarına Erişim

Microsoft Jet veritabanı motoru Microsoft Access veritabanları üzerinde çalışır. Bunun
örneklerini şimdiye kadar gördük. Bu veritabanlarından başka bir çok veritabanının da Jet
veritabanı motoru tarafından desteklendiği daha önce belirtilmişti. Bu bölümde bunun
gerçekleştirimi örneklenecektir.

Microsoft Access veritabanı olmayan tüm veritabanları burada Dış(External) veritabanı olarak
adlandırılmaktadır. Bu veritabanları üzerinde işlem yapılırken bazı kısıtlamalar olmasına rağmen
yine de bir çok kullanışlı metot ve özellik sunulmaktadır.

Dış veritabanları iki sınıfta toplanır. Bunlar ISAM ve ODBC veritabanlarıdır.
                                                   70
ISAM veritabanlarına erişim için üç yol vardır.

   1. Bound Control ve Data Control nesnelerini kullanmak (bunun Access veritabanlarına
      erişmekten farkı yoktur, sadece Connect özelliğini belirtmek yeterlidir).
   2. DAO kullanmak
   3. Bir tabloyu Access veritabanına bağlayıp Recordset yapısıyla tabloya erişmek.

Örnek. DAO kullanarak Microsoft Excel veritabanlarına erişim.

Excel vritabanlarına DAO kullanarak erişim yapılırken bazı kısıtlamalar sözkonusudur. Bunlar;
                     Satırlar silinemez
                     Formül içeren hücreler silinemez ve değiştirilemez
                     Indeks yaratılamaz
                     Şifrelenmiş excel veritabanları kullanılamaz.
Bunların dışında Excel veritabanları tıpkı Access veritabanıymış gibi kullanılır. (Dış
veritabanları için var olan bazı temel kısıtlamalar dışında)

Örnek :
   1. Yeni bir proje yaratın ve ismini ExcelDAO olarak değiştirin. Bu proje için PERSONEL
      veritabanının PERSONEL_BIL tablosunun excelde yaratılmış hali kullanılacaktır.

   2. Aşağıdaki nesneleri bir formun üzerine ekleyin ve özelliklerini belirtildiği gibi değiştirin.

          Form                      Name                  frmPBil
                                    Caption               EXCEL VERITABANI
          ListView                  Name                  ListView1
                                    View                  3-lvwReport
          CommandButton             Name                  cmdEkle
                                    Caption               &Ekle
          CommandButton             Name                  cmdDeg
                                    Caption               &Değiştir
          CommandButton             Name                  cmdYenile
                                    Caption               &Yenile
          CommandButton             Name                  cmdBak
                                    Caption               E&xcel’de Bak
          CommandButton             Name                  cmdKapat
                                    Caption               &Kapat
          CommandButton             Name                  cmdTamam
                                    Caption               &Tamam
          CommandButton             Name                  cmdIptal
                                    Caption               İ&ptal


                                                  71
           Textbox                       Name                      Text1 (Control array)



Formun tasarım esnasındaki görünüşü aşağıdaki gibi olmalıdır.




Aşağıdaki kodu formun kod kesimine yazın.

   Option Explicit
   Private db As Database
   Private rs As Recordset
   Private durum As Integer
   Private Const EKLEME = 0
   Private Const DEGISTIRME = 1
   Private aktifHucre As ComctlLib.ListItem

   Private Sub cmdBak_Click()
       Set rs = Nothing
       Set db = Nothing
       Shell "d:\msoffice\office\excel.exe " & App.Path & "\personel.xls", _
       vbNormalFocus
   End Sub

   Private Sub cmdDeg_Click()
       Dim i As Integer
       rs.MoveFirst
       For i = 1 To ListView1.SelectedItem.Index - 1
            rs.MoveNext
       Next i
       Text1(0) = rs!sicno
       Text1(1) = rs!ad_soyad
       Text1(2) = rs!dtar
       Text1(3) = rs!dyer
       EkleGoster
       durum = DEGISTIRME
   End Sub

   Private Sub cmdEkle_Click()
       Dim i As Integer
       For i = 0 To 3
                                                       72
        Text1(i) = ""
    Next
    EkleGoster
    durum = EKLEME
End Sub

Private Sub cmdIptal_Click()
    EkleSakla
End Sub

Private Sub cmdKapat_Click()
    Unload Me
End Sub

Private Sub cmdTamam_Click()
    If durum = EKLEME Then rs.AddNew Else rs.Edit
    rs!sicno = Text1(0)
    rs!ad_soyad = Text1(1)
    rs!dtar = Text1(2)
    rs!dyer = Text1(3)
    rs.Update
    ListeDoldur
    EkleSakla
End Sub

Private Sub cmdYenile_Click()
    ListeDoldur
End Sub

Private Sub Form_Activate()
    DoEvents
    ListeDoldur
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Set db = Nothing
    Set rs = Nothing
End Sub

Private Sub EkleSakla()
    Me.Height = 3700
    NesneGunle True
End Sub

Private Sub EkleGoster()
    Me.Height = 5265
    NesneGunle False
End Sub

Private Sub NesneGunle(idurum As Boolean)
    Dim i As Integer
    cmdEkle.Enabled = idurum
    cmdDeg.Enabled = idurum
    cmdYenile.Enabled = idurum
    cmdBak.Enabled = idurum
    cmdKapat.Enabled = idurum
    For i = 0 To 3
         Text1(i).Enabled = Not idurum
    Next
    cmdTamam.Enabled = Not idurum
    cmdIptal.Enabled = Not idurum
                                              73
   End Sub

   Private Sub ListeDoldur()
       Dim fld As Field
       Dim alanSay As Integer
       Dim alanGen As Single
       Dim listeEl As ListItem
       EkleSakla
       Set db = OpenDatabase(App.Path & "\personel.xls", False, False, _
       "Excel 8.0;HDR=YES;")
       Set rs = db.OpenRecordset("personel_bil$")
       With ListView1
            .ColumnHeaders.Clear
            .ListItems.Clear
            For Each fld In db.TableDefs("personel_bil$").Fields
            alanGen = TextWidth(fld.Name) + 500
            .ColumnHeaders.Add , , fld.Name, alanGen, vbLeftJustify
            Next fld
            .ColumnHeaders.Item(4).Width = .ColumnHeaders.Item(4).Width + 400
            .ColumnHeaders.Item(2).Width = .ColumnHeaders.Item(2).Width + 400
       End With
       rs.MoveFirst
       While (Not rs.EOF)
            Set listeEl = ListView1.ListItems.Add(, , CStr(rs.Fields(0)))
            For alanSay = 1 To rs.Fields.Count - 1
                 listeEl.SubItems(alanSay) = rs.Fields(alanSay)
            Next alanSay
            rs.MoveNext
       Wend
       Set aktifHucre = listeEl
       Set listeEl = Nothing
   End Sub




Program biraz incelendiğinde görülecektir ki erişimin daha önceki veritabanı erişimlerden hiç
farkı yoktur. Tek fark veritabanını açma aşamasındadır. Excel için bir diğer fark da Tablo
isimlerinin sonuna “$” işaretinin konması gerekliliğidir.


Programın çalışması aşağıdaki gibi olacaktır.

Program ilk çalıştığında formun alt kısmı görülmez. Bu özellik formun Height özelliği çalışma
esnasında değiştirilerek sağlanmıştır. Ekle ve Değiştir butonlarına basıldığında alt taraf görünür.
Bu kısım veri girişi yapmaya yardımcı olur. Değişiklik veya ekleme yapıldıktan sonra alt taraf
tekrar görünmez hale getirilir.




                                                  74
4.4. ODBC Veritabanlarına Erişim

Microsoft Jet veritabanı motoru ve DAO kullanarak ODBC verilerine erişim için iki yol vardır.
Bunlar;

   1. Microsoft Jet veritabanı motoru
   2. ODBCDirect

Microsoft Jet önemli bir işlevselliğe sahiptir. Bağlantıların kurulması ve yönetilmesi, sorguların
Veritabanı Sunucusu tarafından kabul edilebilir biçimlere dönüştürülmesi ve geri döndürülen
verinin işlenmesi gibi önemli özellikler sağlar.

Bazı durumlarda Jet motorunu devreden çıkarıp DAO nesnelerinin doğrudan ODBC sürücüsüyle
ilişki kurması gerekebilir. Bu ODBCDirect aracılığıyla gerçekleştirilir.

Jet veritabanı motorunun ve ODBCDirect yöntemlerinden herbirinin kendi çapında sağladığı
avantajlar vardır. Aynı anda her ikisini birden kullanmak da mümkündür.

Microsoft Jet tarafından sağlanan ve ODBCDirect ile yapılamayacak olanlar:

      Değiştirilebilir birleştirme işlemleri. Birleştirme(Join) işlemi kullanılarak yaratılan
       Recordset nesneleri üzerinde değişiklik yapmak mümkündür.
      Bağlı tablo kullanabilme. Ağ üzerindeki bir tablo ile bağ kurmak bu tablonun genel
       bilgilerini bir yapı içinde tutmak demektir. Bu özellik sayesinde tabloya erişim daha hızlı
       sağlanabilir.
      FindFirst, FindNext, FindPrevious ve FindLast arama özelliklerini kullanabilme.
      Değiştirme sorguları için kısmı hata. Bu özellik hatanın oluştuğu yere kadar olan
       değişiklikleri kaydedebilme olanağı sağlar.
      Kullanıcı tarafından tanımlanabilen özellikler. Kullanıcı veritabanı nesnelerine yeni
       özellikler ekleyebilir.
      Veri özetleme için kullanılabilen SQL TRANSFORM sorgularını kullanabilme olanağı.
      Heterojen veri erişimi. Farklı veritabanlarından tabloları aynı anda kullanabilme.
      Program tabanlı DDL. ODBCDirect TableDef nesnesini sağlamadığı için tablo yaratmak
       mümkün değildir. Ancak SQL DDL kullanarak veritabanı yaratmak mümkündür.
      Bağlı kontrol nesneleri. ODBCDirect ile bağlı kontrol nesneleri kullanmak mümkün
       değildir. Jet motoru kullanarak bazı kontrol nesnelerini veritabanındaki alanlara
       bağlamak mümkündür.

Eğer bütün bu özelliklere ihtiyaç duyulmuyorsa ODBCDirect kullanılabilir. Ayrıca her iki
yöntemin aynı anda kullanılabileceği de unutulmamalıdır.

ODBCDirect, ODBC API kullanarak DAO nesneleri aracılığıyla veritabanına doğrudan erişimi
sağlar. ODBCDirect kullanarak kullanıcı bilgisayarında en az işlemler yapılarak veritabanı
erişimi yapmak mümkündür. Sağladığı avantajlar:

      Doğrudan erişim. Sorgular doğrudan ODBC sunucusuna gönderilir.
      Düşük kaynak gereksinimi. Jet motoru yüklenmediği için kullanıcı bilgisayarındaki
       kaynak gereksinimi çok azdır.

                                               75
      Sunucuya özel işlevselliği kullanabilme.
      Zamanuyumsuz sorgular. Bir sorgu bitmeden bir başkasını başlatabilmek mümkündür.
       Bu paralelliği arttırır.
      Toplu halde değişiklik yapma olanağı. Değişikliklerin biriktirilip bir anda sunucuya
       gönderilmesi mümkündür.
      Daha esnek yordam çalıştırma.


4.4.1. ODBC Verilerine Microsoft Jet Kullanarak Erişim

ODBC veritabanlarına erişim için kullanılan bu iki yöntemin Visual Basic ile nasıl
gerçekleştiğini görelim.

Sunucuya bağlanma.

ODBC sunucusuna bağlanmak için 3 yol vardır.
   Tablolara bağ oluşturma
   SQL sorgularını doğrudan sunucuya gönderme
   DAO kullanarak sunucuya doğrudan erişim.

Tablolara Bağ Oluşturma

Veritabanını açmaktan daha etkin bir yöntemdir. Böylece bu tablolar üzerinde Jet veritabanında
yapılıyormuş gibi sorgu yapmak mümkündür. Veri tabanını açmak ilk bakışta daha hızlı gibi
görünebilir, fakat tablolara her erişim için veritabanına tekrar erişim gerekir. Bu yöntem
tabloların genel bilgilerini bir yerde saklar ve veritabanına erişim miktarını azaltır.

Dikkat edilmesi gereken bir konu ise sunucu tarafından tablo yapısında yapılan değişikliklerin
tutarsızlığa neden olabileceğidir. Çünkü bu yöntemle tablo yapısının bir kopyası kullanıcı
bilgisayarında tutulur ve sorgularda tutulan bu yapı kullanılır. Değişiklik olduğunda tekrar bağ
oluşturmak gerekir.

SQL sorgu sonuclarına (view) bağ kurma ve yapay indeks oluşturma

Eğer sunucu SQL sorgu sonuclarını tutan tablo yapılarını destekliyorsa bu yapılara bağ kurmak
mümkündür. Bu tablo yapıları için yapılan işlemler sunucuya aittir. Eğer sunucu bu yapılarda
değişiklik yapmaya izin veriyorsa bu yapılar üzerinde indeks tanımlama da yapılabilir. Böylece
sorgu sonuçlarına, herhangi bir satırı belirleyici özelliğe sahip bir alan kullanarak kolayca erişim
sağlanır.

Örneğin PERSONEL veritabanı üzerinde “Yüksekokul mezunu personelin SicilNo, Ad ve
Soyad, Görevi bilgilerinin listesi” sorgusunun sonucu Yuksek adıyla bir tablo yapısında
tutulsun. Bu yapıya kurulan bağ ise Yuksek1 olsun. Burada SicilNo hala tutanağı belirleyen bir
alan olduğundan bunu bir indeks olarak kullanabiliriz. Bunun için aşağıdaki SQL deyimi
kullanılabilir.

   CREATE UNIQUE INDEX Index1 ON Yuksek1(sicno)

Bu sunucuya gönderilen bir sorgu olmadığı için indeks sadece yapay bir indeks olarak kullanılır.
Sunucu üzerinde böyle bir indeks yoktur.


                                                76
DAO kullanarak ODBC verilerine erişim

DAO kullanarak ODBC verilerine erişmek için;
  1. Windows Control Penel penceresinden 32bit ODBC seçeneğini kullanarak ODBC veri
  kaynağı ile ilgili ayarları yapın ve bir veri kaynağı ismi (DSN) atayın
  2. Veri kaynağını temsil eden bir bağlantı (connect) metnı tanımlayın.
  3. Yukarıda tanımlanan bağlantı metnini kullanarak TableDef nesnesi yaratın.
  4. Bu TableDef nesnesini TableDefs kümesine ekleyin.
  5. Bu bağlı tablo üzerinde bit Recorset açın. Bu Recorset yapısı ODBC veri kaynağının
  verilerini barındırır. Recordset nesnesinin özellikleri kullanılarak bu veriler üzerinde
  işlem yapmak mümkündür.

Şimdi bu adımları açıklayalım.
   1. ODBC Data Source Menager kullanımı:
                   Control panel penceresinden 32bit-ODBC seçeneğini seçin.
                   Add düğmesine basıp bir ODBC sürücüsü seçin.(Ms SQL
                      server)
                   Bir DSN adı yazın(Personel)
                   Veritabanı ile ilgili bir açıklama yazın.(abc kurumunun
                      personeli)
                   Sunucunun adını yazın.(vtSunucu)
                   Veritabanının ağ adresini yazın.

   2. Bağlantı metnini hazırlama

Bu metin birbirinden noktalı virgülle ayrılmış ODBC sürücüsünün bağlantıyı sağlaması için
kullanılan birtakım değerlerden oluşan bir satırdır. Ilk değer “ODBC;” şeklinde olmalıdır.
Örneğin;

   ODBC;UID=mustafa;pwd=mmtt12;DSN=Personel

Bu satırda bazı bilgiler eksik kalırsa ODBC sürücüsü eksik bilgilerin girişi için bir dialog kutusu
çıkarır.

    3,4,5. Bağlı tablo oluşturma.

Aşağıdaki fonksiyon bağlı tablo oluşturarak personel veritabanında “Ankara” doğumlu personel
sayısını döndürür.

   Public Function ankSay() As Long
       Dim db As Database, rs As Recordset
       Dim strBag As String, tdf As TableDef
       Dim say As Long
       strBag = "ODBC;DSN=Personel;UID=mustafa;" & _
       "PWD=mmtt12;DATABASE=Personel"
       Set db = OpenDatabase(App.Path & "\Personel.mdb")
       On Error Resume Next
       db.TableDefs.Delete "bPers"
       db.TableDefs.Refresh
       On Error GoTo phata
       Set tdf = db.CreateTableDef("bPers")
       tdf.Connect = strBag
       tdf.SourceTableName = "personel_bil"
       db.TableDefs.Append tdf
       db.TableDefs.Refresh
                                                 77
        Set rs = db.OpenRecordset("bPers", dbOpenForwardOnly)
        Do Until rs.EOF
             If Trim$(rs!dyer) = "Ankara" Then say = say + 1
             rs.MoveNext
        Loop
        rs.Close
        db.Close
        ankSay = say
        Exit Function
    phata:
        MsgBox "Error " & Err & ": " & Error
        Exit Function
    End Function

Bu örnekte PERSONEL_BIL tablosu forward-only bir Recordset yapısıyla açılmıştır. Bağlı
ODBC tablolarının kullanım açısından daha önce kullanılmış olan Jet veritabanı motoru
tablolarından bir farkı yoktur. Örneğin aşağıdaki sorgu bağlı bir tablo üzerinde çalıştırılabilir.

    Dim db As Database, qdf As QueryDef
    Set db = db1 'Kullanılmakta olan bir veritabanı
    Set qdf = db.CreateQueryDef("bPers")
    qdf.SQL = "DELETE FROM bPers WHERE dyer = ' Ankara'"
    qdf.Execute

Bu kod daha önce yaratmış olduğumuz bağlı tablodan “Ankara” doğumlu olan personeli siler.

SQL sorgularını doğrudan sunucuya gönderme
ODBC veritabanı üzerinde SQL sorguları Jet veritabanı motoru kullanılarak da
gerçekleştirilebilir fakat doğrudan sunucu üzerinde çalıştırılmaları işlemlerini daha hızlı
yapılmasını sağlar.
Bu sorgular herhangi bir yorumlama yapılmadan doğrudan sunucuya gönderilir. Sorgular iki
kesimden oluşur, SQL sorgu deyimi ve ODBC bağlantı metni. SQL deyimleri sunucunun kabul
ettiği türden olmalıdır, Visual Basic deyimleri içermemelidir.

Avantaj ve dezavantajları:
    Sunucunun işlem miktarı artar, ağ trafiği azalır.
    Sunucu tarafından sağlanan özel işlevleri kullanabilirler.
    Sunucudan gelen mesajların listesini tutarlar.
    Sunucu üzerindeki farklı veritabanlarını birleştirmenin tek yolu bu tür sorgular
      kullanmaktır.
    Çok sayıda silme ve değiştirme yapan bu tür sorgular normal sorgulardan çok daha
      hızlıdır.
    Geri döndürülen Recordset yapısı ancak Snaphot olabilir.
    Değişiklik yapan bir sorgunun başarısızlığı kısmi olamaz.

Bu tür sorgular aşağıdaki gibi bir kodla çalıştırılabilir.

    Dim db As Database, qdf As QueryDef
    strBag = "ODBC;DSN=Personel;UID=mustafa;" & _
    "PWD=mmtt12;DATABASE=Personel"
    Set db = db1 'Kullanılmakta olan bir veritabanı
    Set qdf = db.CreateQueryDef("")
    qdf.SQL = "DELETE FROM bPers WHERE dyer = ' Ankara'"
    qdf.Connect = strBag
    qdf.Execute


                                                   78
Burada verilen Connect özelliği sorgunun doğrudan ODBC sunucusuna gönderilmesini sağlar.

Doğrudan sunucuya gönderilen sorgular aşağıdaki şekilde de çalıştırılabilir.

   strBag = "ODBC;DSN=Personel;UID=mustafa;" & _
   "PWD=mmtt12;DATABASE=Personel"
   Set db = OpenDatabase(App.Path & "\Personel.mdb")
   db.Execute "DELETE FROM bPers WHERE dyer = ' Ankara'"
   db.Close

4.4.2. ODBC Verilerine ODBCdirect Kullanarak Erişim

ODBCDirect kullanmak için önce bir ODBC Workspace yaratmak gerekir.                          Bu
CreateWorkSpace metodu kullanılarak yapılabilir. Bu işlem aşağıdaki gibi yapılabilir.

   Dim wks As Workspace
   Set wks = DBEngine.CreateWorkspace("ODBCWks", "mustafa", "mmtt12", _
                  dbUseODBC)

ODBC Workspace yaratıldıktan sonra yapılması gereken ODBC veri kaynağıyla bağlantı
kurmaktır. Bağlantı OpenDatabase metodu ile yapılır. Parametre olarak uygun bir bağlantı metni
verilir. Veri kaynağına bağlanmak için iki yol vardır. Bunlar Database nesnesi yaratmak ve
Connection nesnesi yaratmaktır. Connection nesnesi ODBC verilerine erişimde sağladığı bazı
olanaklar sayesinde verimlilik sağlar. Bu olanaklar;

      Zamanuyumsuz bağlantı. Bir uygulama bağlantının kurulmasını beklemek zorunda
       değildir.
      Zamanuyumsuz sorgu işleme. Bir sorgunun bitmesini beklemeden başka bir sorgu
       işletebilme olanağı.
      QueryDef nesnesi. ODBC veri kaynağı üzerinde yapılan sorguları bir yapı içinde
       tutmayı sağlar. Böyle bir olanak Database nesnesi kullandığında yoktur.

Bu olanaklardan yararlanmak için kullanılan Connection nesnesi aşağıdaki gibi kullanılır.
   Set variable = workspace.OpenConnection (dsName, prompt, readonly, connect)

Bu metodun kullanışı şu şekilde örneklenebilir.
   Dim cnn As Connection, strCn as String
   strCn = "ODBC;dsn=Pubs;database=Pubs;uid=sa;pwd=;"
   Set cnn = OpenConnection("", dbDriverNoPrompt, False, strCn)

Connection nesnesi yaratıldıktan sonra bu nesne üzerinde Recordset yapısı tanımlamak ve
üzerinde sorgu yapmak mümkündür.

ODBCDirect yöntemiyle aynı ODBC veri kaynağı üzerinde hem Connection hem de Database
nesnesi tanımlamak mümkündür. Database nesnesi ancak Microsoft Jet veritabanı motorundan
yararlanılacaksa kullanılmalıdır.


4.5. Veritabanı Performansını Eniyileştirme

Yerel ve uzak veritabanı sistemleri arasında önemli farklar olduğundan dolayı performansları da
farklıdır. Yanlış tasarlanmış bir Client/Server veritabanı ihtiyaçlara cevap vermez. Bu sebepten
dolayı client/server yapısında veritabanı tasarlanırken çok dikkatli olunmalıdır.

                                                    79
Sorguların hızlandırılması

Uzak bir sistemdeki sorguların performansını artırmak için yapılabilecek en iyi şey sorguların
olabildiğince fazla kısmını sunucu üzerinde çalıştırmayı sağlamaktır.
Microsoft Jet veritabanı motoru verilen bir sorgu için ön işlemleri yaparak bunu ODBC veri
kaynağının desteklediği türden sorgular haline getirir. Eğer bir sorgu bir çok deyim içeriyorsa bir
ön işlemeye ihtiyaç vardır. Bu ön işleme yerel olarak yapılır. Sorguları iyileştirmek için
sorgularda genel olarak sağlanan işlevler kullanılmalıdır.

Genel olarak sağlanmayan işlevler şunlardır.

      Basit bir SQL deyimi ile açıklanamayan işlemler.
      Microsoft Jet motorunun sorgular için getirdiği ekler.
      Microsoft ürünlerine has fonksiyon ve işleçler.
      Kullanıcı tarafından tanımlanan fonksiyonlar.
      Farklı veri türlerini bir arada kullanan deyimler.
      Yerel ve uzak tablolar arasında birleştirme işlemleri.

Eğer işlem sunucu tarafından destekleniyorsa, doğrudan sunucuya gönderilir, desteklenmiyorsa
yerel olarak işlenir.

Daha az veri istemek

Ne kadar çok veri istenirse ağ trafiği o kadar artacağından erişim hızı gittikçe düşer. Artan ağ
trafiği sunucunun işlem yükünü de artırır. Bu istenmeyen durumlara engel olmak için;
     Olabildiğince az tutanak istenmelidir.
     Uzak tutanaklardaki alanlardan olabildiğince azı seçilmelidir.
     Olabildiğince az bağlı kontrol nesnesi kuıllanılmalıdır.

Alanları sadece istendiğinde gösterme

Form içinde veritabanı tablosunun alanları gösterilirken bazen sadec bir alanın tüm değerleri
kullanılırken, bazen de bir tutanağın tüm alanlarına ihtiyaç duyulur. Bu tür durumları ele almak
için şu yöntemler kullanılabilir.

      Form üzerinde sık kullanılmayan alanlara bağlı nesnelerin Visible özelliklerini
       gerekmediği zaman False yaparak kullanılmaz hale getirmek
      En önemli alanları bir forma yerleştirip daha az önemsiz alanları başka bir forma eklemek
       ve bu formu göstermek için asıl forma bir buton yerleştirmek.

Verileri birden fazla form için kullanılmak üzere istemek

Genellikle uygulamalar, birden fazla form kullanır ve bu formlar uzak sistemlerdeki aynı verilere
erişir. Bu tür durumlarda performans iyileştirmek için şunlar yapılabilir.

      Eğer bir tablo hiç değişmeyen birtakım bilgiler içeriyorsa bunlar yerel bir veritabanı
       üzerine kaydedilmelidir.
      Sık değişmeyen veriler için de yine yerel bir kopya tutulmalı, verilerde değişiklik
       olduğunda bu veriler güncellenmelidir.
      Sık değişen verilerin de bir kopyası yerel veritabanı üzerinde tutulmalı ancak verilerin
       güncellenmesi için otomatikleştirilmiş bir mekanizma kullanılmalıdır.

                                                80
İşlevselliği daha az kullanma

Veritabanının performansının iyileştirilmesi için, Microsoft Jet veritabanı motoru tarafından
sağlanan bazı işlevlerin kullanılmasından sakınmak gerekir.

      Eğer veriler değiştirilmeyecekse, Dynaset türü Recordset yerine Snapshot türü Recordset
       tercih edilmelidir. Doğrudan sunucuya gönderilen sorgular için forward-only türü
       Recordset yapılarını kullanmak hızı artırır. Tutanak boyları uzun olduğunda dynaset
       türünü kullanmak daha elverişlidir. Çünkü bu durumda dynaset yapısı sadece birincil
       anahtarları getirirken, diğerleri tüm tutanağı getirir.
      Birden fazla tablodan verileri içeren bilgileri form üzerinde göstermenin iki yolu vardır.
       Sonuçların hepsi tek bir form üzerinde gösterilir, veya başka formlar kullanılır. Birden
       çok tabloyu içeren bir sorgu için tek bir form kullanılırsa sorgu bir defada sunucuya
       gönderilir. Alt formlar kullanılırsa her bir alt form için başka bir sorgu gönderilir. Alt
       formlar veri günleme yapılırken avantaj sağlar. Veri günlemenin yapılmadığı durumlarda
       alt form kullanılmamalıdır.

Uzak verilerin geçici Recordset yapılarında tutulması

Gunleme ve silme işlemleri için performansını artırmanın en basit yolu, uzaktaki tabloya
tablonun ne zaman değiştiğini belirten bir alan yerleştirmektir. Bu alan sunucu tarafından
yönetilir ve tutanak günlendiği anda günlenir. Bu alanı doğrudan okumak mümkün olmasa
bileMicrosoft Jet bu alan sayesinde tutanağın değişip değişmediğini algılayabilir. Böyle bir
alanın olmadığı durumlarda bir tutanağın değişip değişmediğini anlamak için tüm tutanağın
karşılaştırılması gerekir. Bir tabloya böyle bir alan aşağıdaki SQL deyimiyle eklenebilir.

   ALTER TABLE UzakTablo ADD SonDegZ TIMESTAMP

Bu deyimle UzakTablo adlı tabloya SonDegZ adlı, tablonun son değiştiği zamanı belirten bir
alan eklenir.
Uygulama performansını artırmanın bir diğer yolu da uzaktaki veriyi geçici bellek alanlarında
tutmaktır.
Bir Recordset tanımlayıp bunu yerel bilgisayara kopyalamak için Recordset yapısının
CacheStart, CacheSize özellikleri ve FillCache metodu kullanılabilir. Verilerin bir kopyasını
yerel bilgisayara almak bu Recordset yapısı üzerinde yapılacak sorguların hızını artırır.




                                               81
5. DLL (Dynamic Link Library-Devirgen Bağlı Kütüphane) KULLANIMI

Visual Basic tarafından sağlanmayan bazı temel özellikleri kullanmak için DLL
kütüphanelerinde saklanan yordamları doğrudan çağırmak mümkündür. Bu yöntem sayesinde
Microsoft Windows işletim sisteminin belkemiği olan birçok yordamı ve hatta başka dillerde
yazılmış başka kütüphanelere erişmek ve bu yordamları Visual Basic kodu içinde kullanmak
mümkündür.

Adından da anlaşıldığı üzere DLL dosyaları birer kütüphanedir. Bu sebeple başka uygulamalar
tarafından da kullanılabilirler ve üzerine yapılan eklemelerden programların çalışması
etkilenmez. Microsoft Windows işletim sisteminin kendisi de DLL dosyalarından yararlanır ve
başka uygulamalar da bu DLL dosyalarını kullanarak grafiksel işlemleri, bellek yönetimini ve
daha bir çok değişik işlemi kolayca destekler. Sağlanan bu olanaklara Windows API
(Application programming interface- Uygulama programlama arabirimi) denir.

DLL kullanımından başka Visual Basic programları içinde kullanılabilecek bir özellik de
Otomasyon(Automation) olarak adlandırılan ve bir uygulamanın nesnelerini dışarıdan (başka bir
programın içinden) kullanabilme olanağını sağlayan mekanizmadır. Bu DLL kullanımından daha
basittir ve hatalı durumlara düşme riski daha azdır.


5.1. Bir DLL Yordamını Uygulamanın İçinde Kullanmak

DLL yordamları programın dışında olan öğeler olduğu için bunların program içinde
kullanılabilmesi için, içinde bulundukları dosyanın ve yordam parametrelerinin program içinde
tanımlanmaları şarttır. Bu işlem bir Declare komutu sayesinde yapılır. Herhangi bir DLL içinde
bulunan bir yordam Declare komutu ile tanımlandıktan sonra programın içindeki diğer
yordamlar gibi kullanılabilir.

DLL kullanırken dikkat edilmesi gereken en önemli nokta, hatalı durumlara düşme riskinin
büyük olduğudur. Bu sebeple parametrelerine ve veri türlerine dikkat etmek gerekir.

DLL kullanımına basit bir örnek olarak, USER32.DLL dosyasında bulunan ve bir pencerenin
başlığını (Caption) değiştiren SetWindowText yordamının kullanılışını örnekleyelim. Bunun
için önce aşağıdaki Declare deyimi kullanılarak yordam tanımlanmalıdır.

Bu örnek için yeni bir proje başlatın, formun üzerine bir CommandButton yerleştirin ve
aşağıdaki kodu yazın.

Private Declare Function SetWindowText Lib "user32" _
Alias "SetWindowTextA" (ByVal hwnd As Long, _
ByVal baslik As String) As Long

Private Sub Command1_Click()
       SetWindowText Form1.hwnd, "Degismis Baslik"
End Sub

Burada önce kullanılacak yordamın tanımı yapılmıştır. Tanım yapılırken parametrelerin türüne
dikkat edilmesi gerekir. Bu yordama yeni pencere başlığı ikinci parametre ile gönderilmektedir.
Tanımlanan bu yordamın kullanılışı tıpkı normal bir Visual Basic yordamının kullanılışına
benzemektedir.
                                               82
Microsoft Windows işletim sisteminin sağladığı yordamların ve sabitlerin tanımları Visual Basic
ile birlikte gelen API text Viewer programı ile görülebilir. Bu program sayesinde tanımlar Visual
Basic programlarının içine kopyalanabilir.

Bu programın yukarıda tanımlanan yordamın tanımını kopyalarken durumu aşağıdaki gibidir.




Bu program kullanılarak Visual Basic ile birlikte gelen;

           Apiload.txt
           Mapi32.txt
           Win32api.txt

Dosyaları içinde yer alan DLL yordamlarının tanımlarını programın içine kopyalamak
mümkündür.


5.2. Microsoft Windows API Yordamlarına Erişim

DLL dosyalarından programlar içinde en sık ihtiyaç duyulanları ve kullanılanları Windows API
olarak bilinen, Windows işletim sisteminin sağladığı fonksiyon ve yordamları içeren DLL
dosyalarıdır.

Windows API binlerce yordam, tür tanımı ve sabit tanımlarını içerir. Bu yordamlar C dilinde
yazılmıştır, bu yüzden Visual Basic içinde kullanılırken dikkatli bir biçimde yeniden
tanımlanmaları gerekir. Visual basic bu işlem için yukarıda da bahsedildiği gibi API Text
Viewer programını ve bu tanımların Visual Basic için yapılmış halini içeren bir metin dosyasını
kullanıcılara sunmaktadır.

API Text Viewer programı metin kütüklerini, daha hızlı erişim ve kolay aramayı sağlamak için
Jet Veritabanlarına çevirebilme özelliğine de sahiptir.



                                                83
Görüldüğü üzere Windows API yordamlarının tanımlanmasında herhangi bir sorun yoktur.
Çünkü zaten hazır tanımları bulunmaktadır ve tek yapılması gereken bu tanımları Visual Basic
kodunun içine almaktır.

Windows API dışındaki bir DLL dosyasından yordamlar kullanılacağı zaman uygun tanımı
yapmak çok önemlidir. Aksi takdirde istenmeyen durumlar oluşabilir.


5.3. DLL İçindeki Bir Yordamın Tanımlanması

Windows API dışındaki DLL dosyaları içinden yordam kullanmak veya win32api.txt dosyası
içinde yapılmış olan tanımları kendi gereksinimlerimize göre değiştirmek için DLL içindeki bir
yordamın nasıl tanımlanabileceğini öğrenmek gerekir.

Bir DLL yordamını tanımlamak için Declare deyimi kullanılır. Eğer yordam bir değer
döndürüyorsa Function, döndürmüyorsa Sub olarak tanımlanır. Declare deyiminin kullanışı
aşağıdaki biçimdedir.

         Declare Function publicname Lib "libname" [Alias "alias"]
         [([[ByVal] variable [As type] [,[ByVal] variable [As type]]...])] As Type

         Declare Sub publicname Lib "libname" [Alias "alias"]
         [([[ByVal] variable [As type] [,[ByVal] variable [As type]]...])]

Kütühane İsmi (libname)

Windows kütüphaneleri için (User32, Kernel32 veya GDI32) dosyanın tam adını ve yolunu
belirtmeye gerek yoktur. Örneğin;

   Declare Function GetTickCount Lib "kernel32" Alias "GetTickCount" () As Long

Diğer DLL dosyaları kullanılırken tam yol ve dosya adı verilmek zorundadır

    Declare Function Topla Lib "c:\hesap.dll" _
    (ByVal sayi1 As Integer, ByVal sayi2 As Integer) As Long

DLL dosyasının yolu verilmezse bu dosya için;

               Programın .EXE dosyasının bulunduğu yere,
               Aktif dizine,
               Windows’un System dizinine,
               Windows dizinine,
               PATH değişkeninde tanımlı dizinlere
bakar.

Parametre türlerini belirlemeden önce sık kullanılan bazı DLL dosyalarının tanımlarını verelim.

    Advapi32.dll       Advanced API services library supporting numerous APIs including many
                       security and Registry calls
    Comdlg32.dll       Common dialog API library
    Gdi32.dll          Graphics Device Interface API library
    Kernel32.dll       Core Windows 32-bit base API support
                                                 84
    Lz32.dll           32-bit compression routines
    Mpr.dll            Multiple Provider Router library
    Netapi32.dll       32-bit Network API library
    Shell32.dll        32-bit Shell API library
    User32.dll         Library for user interface routines
    Version.dll        Version library
    Winmm.dll          Windows multimedia library
    Winspool.drv       Print spooler interface that contains the print spooler API calls


5.4. String Kullanan Windows API Yordamları

String kullanan Windows API yordamlarını kullanmak için karakter kümesini belirtmek gerekir.
Bu karakter kümesi ANSI veya Unicode olabilir. Windows 95 için kullanılan karakter kümesi
ANSI karakter kümesidir. Windows API içinde bu durum için bir yordamın genelde iki tanımı
birden olur. Bunlardan biri ANSI kodunu destekler, diğer Unicode kodunu destekler. Yukarıda
verilen örnekteki SetWindowsText yordamı için USER32.DLL dosyasında, SetWindowsTestW
ve SetWindowsTextA olarak adlandırılmış iki ayrı tanım söz konusudur. Bu tanımlardan
hangisinin kullanılmak istendiği Alias kısmında verilen isim ile belirtilir.


5.5. Parametreleri Değer İle Veya Referans İle Gönderme

Visual Basic yordamlarında eğer belirtilmemişse parametre geçiş yöntemi referans ile
göndermedir. Bunun anlamı parametre olarak verilen değişkenin değeri yerine bellek adresinin
gönderilmesidir.

Çoğu DLL yordamı parametrelerinin değerle aktarılmasını öngörürler. Bu tür yordamlara
referans ile parametre gönderilirse hatalı bir veri gönderilmiş olur.

Örneğin yukarıda bir formun başlığını değiştiren örnekte ilk parametre olan HWND parametresi
tanımı yapılırken referans ile gönderme türünden tanımlanmış olsaydı bu bir hata olurdu. Çünkü
bu yordamın DLL kütüphanesi içindeki tanımında bu parametre değer ile gönderilen bir
parametredir.

Bir parametreyi değer ile göndermek için ByVal, referans ile göndermek için de ByRef
sözcükleri kullanılır.

Herhangi bir DLL kütüphanesinin C dilindeki tanımından yararlanarak bir tanım yapılırken,
diziler dışındaki değişkenlerin ByVal olarak gönderildiği dikkate alınmalıdır.


5.6. Alias Kullanımı

Tanımlanacak bir yordama DLL kütüphanesi içindeki tanımından farklı bir isim verilmek
istendiğinde yordamın DLL kütüphanesi içindeki adı Alias kısmında verilir.
Örnek olarak, önce bir proje yaratın ve formun üzerinde bir CommandButton ve bir Label
yerleştirin. Daha sonra aşağıdaki kodu ekleyin.



        Private Declare Function WindowsDiziniGoster Lib "kernel32" _
                                                 85
              Alias "GetWindowsDirectoryA" (ByVal lpBuffer As String, _
                     ByVal nSize As Long) As Long


        Private Sub Command1_Click()
             Dim n As Integer
             Dim str As String
             str = Space$(100)
             n = WindowsDiziniGoster(str, 100)
             Label1.Caption = Left$(str, n)
        End Sub


Bu program çalıştırılıp form üzerindeki butona basıldığında bilgisayardaki windows dizini
form üzerindeki Label nesnesine yazılır.


5.7. Esnek Parametre Türleri

Bazı DLL kütüphaneleri aynı parametre değişkeni için birden fazla türün kullanılmasına izin
verir. Eğer farklı türlerden veriler bu tür yordamlara gönderilecekse parametre tanımları Any
türü olarak tanımlanmalıdır.

Buna örnek olarak aşağıdaki tanım verilebilir.

       Declare Function MapWindowPoints Lib "user32" Alias _
             "MapWindowPoints" (ByVal hwndFrom As Long, _
             ByVal hwndTo As Long, lppt As Any, _
             ByVal cPoints As Long) As Long

Bu yordam bir nokta dizisinin bir penceredeki konumunu verilen bir başka pencere üzerindeki
bir konuma çevirir. Sonuç, yordamın 3. Parametresi içinde döndürülür. Bu parametre POINT
türünde veya RECT türünde olabilir. Bu türler sırasıyla 2 ve 4 Long türünde sayı içeren türlerdir.
As Any kullanımı her ne kadar esneklik sağlıyorsa da kullanılırken dikkatli olunmalıdır. Yanlış
veri türleriyle kullanılınca ancak çalışma esnasında bu fark edilebilir.


5.8. Parametre Olarak String Gönderme

Genelde string türü değişkenler ByVal olarak gönderilir. Visual Basic içinde string türü BSTR
olarak bilinen bir yapıyı belirtir. Bu yapı string uzunluğu ve içeriği hakkında bilgiler tutar. Bu
yapı parametre olarak bir yordama gönderildiğinde yordamın bu yapıdaki içerik bilgisini
değiştirmesine olanak verilir.

WinAPI yordamlarında genellikle LPSTR olarak adlandırılan C string yapıları kullanılır. Bu
parametrelere karşılık olarak Visul Basic içinde kullanılan BSTR verilebilir.

Bu kullanımı yukarıda Windows dizinini almak için kullanılan örnekten görmek mümkündür.
Windows dizini ByVal olarak tanımlanmış olan String türündeki bir değişken içinde
döndürülmektedir.



                                                 86
Genel olarak LPSTR türü string bekleyen yordamlara String türü değişkenler parametre olarak
verilebilir.

Bir DLL yordamına BINARY verilerden oluşan bir karakter dizisi parametre olarak verilecekse,
String yerine Byte dizisi gönderilmelidir.


5.9. Parametre Olarak Dizi Gönderme

Dizinin herhangi bir elemanını parametre olarak göndermek dizinin türü ile aynı türden olan bir
değişkeni göndermekten farksızdır. Ancak bazen tüm diziyi parametre olarak göndermek
gerekebilir. Bu durumda dizi tıpkı Visual Basic yordamlarında olduğu gibi boş parantezlerle
göderilir.

Sayı içeren bir dizinin ilk parametresini ByRef olarak göndermek, bütün diziyi göndermek
anlamına gelir. Bu yaklaşım string dizileri için de geçerlidir. C dilinde string dizileri gösterge
içeren diziler olarak algılanır ve Visual Basic ile aynı şekilde kullanılır.


5.10. Kullanıcı Tarafından Tanımlanmış Türlerin Kullanımı

Bunu örneklemek için aşağıdaki örneği inceleyin.

       Private Type RECT
          sol As Long
          ust As Long
          sag As Long
          alt As Long
       End Type
       Private Declare Function RenkleriTersCevir Lib "User32" Alias "InvertRect" _
       (ByVal hdc As Long, lpRect As RECT) As Long
       Dim rect1 As RECT
       Private Sub Form_Load()
          ScaleMode = 3
       End Sub

       Private Sub Form_MouseDown(Button As Integer, _
          Shift As Integer, X As Single, Y As Single)
          If Button And 1 Then
              rect1.sol = X
              rect1.ust = Y
              rect1.sag = X
              rect1.alt = Y
          End If
       End Sub

       Private Sub Form_MouseUp(Button As Integer, _
       Shift As Integer, X As Single, Y As Single)
           If Not (Button And 1) Then
               rect1.sag = X
               rect1.alt = Y
               RenkleriTersCevir hdc, rect1
                                               87
          End If
       End Sub

Bu program mouse basılı tutularak seçilen bir alandaki renkleri ters çevirir. InvertRect
yordamına parametre olarak program içinde tanımlanan RECT türü gönderilmiştir. Burada
dikkat edilmesi gereken önemli bir husus gönderilen türün yordamın ihtiyaç duyduğu tür ile
aynı yapıda olmasına dikkat edilmelidir.


5.11. DLL Yordamlarına Fonksiyon Göstergelerini Parametre Olarak Gönderme

Fonksiyon göstergesi, kullanıcı tarafından tanımlanmış fonksiyonların adreslerini belirtir. Bu
göstergeler, bir DLL yordamı kullanıcı tarafından tanımlanmış bir yordamı kullanacağı zaman
kullanılır. Fonksiyon göstergelerini kullanmak için Address of fonksiyon_adı deyimi kullanılır.


5.12. Diğer Türlerin Parametre Olarak Gönderilmesi

              String türü bir değişkene boş gösterge göndermek gerektiğinde vbNullString
               sabiti kullanılır.

       Örneğin FindWindow yordamı belli bir pencereyi başlığı sayesinde bulur ve bu
       pencereye bir gösterge döndürür.

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

       Bu yordamın kullanılışı aşağıdaki gibi olabilir.

       hWndExcel = FindWindow(vbNullString, "Microsoft Excel")

       Bu yordamda ilk parametre boş bir string olarak gönderilmektedir.

              Nesne özellikleri de yordamlara parametre olarak gönderilebilir. Özellikler
               parametre olarak gönderilirken ByVal olarak gönderilmelidir. ByRef olarak
               kullanmak için ara bir değişkene ihtiyaç duyulur.

              Nesne göstergelerini parametre olarak göndermek mümkündür. Örneğin bir
               formun hWnd ve hDC göstergelerini bir yordama parametre olarak göndermek
               mümkündür.

              Variant türündeki bir değişkeni Variant olmayan bir değişkenin yerini tutması için
               göndermek gerektiğinde ByVal olarak gönderilir.


5.13. C Tanımlarını Visual Basic Tanımlarına Dönüştürme

DLL dosyaları içindeki yordamlara ait dokümanlar genelde C diline uyumlu olarak yazılmıştır.
Bunları Visual Basic içinde kullanabilmek için tanımları çevirmek gerekir. Bu çevirinin bir
parçası da C dilindeki türler için uygun Visual Basic veri türlerini kullanmak ve parametre geçiş
yöntemini belirlemektir.
                                                88
Bu çeviri işlemi için aşağıdaki tablo kullanılabilir.


5.14. C Veri Türü Visual Basic İçinde Tanımı
Ne tür değerlerle çağrılabileceği

ATOM                      ByVal variable As Integer                 Integer
BOOL                      ByVal variableAs Long                     Long
BYTE                      ByVal variable As Byte                    Byte
CHAR                      ByVal variable As Byte                    Byte
COLORREF                  ByVal variable As Long                    Long
DWORD                     ByVal variable As Long                    Long
HWND, HDC,
HMENU, etc.               ByVal variable As Long                    Long
(Windows handles)
INT, UINT                 ByVal variable As Long                    Long
LONG                      ByVal variable As Long                    Long
LPARAM                    ByVal variable As Long                    Long
LPDWORD                   variable As Long                          Long
LPINT, LPUINT             variable As Long                          Long
                                                                    Kullanıcı tarafından
LPRECT                    variable As type
                                                                    tanımlanmış herhangi bir tür
LPSTR, LPCSTR             ByVal variable As String                  String
                                                                    Herhangi bir değişken (string
LPVOID                    variable As Any
                                                                    türü için ByVal)
LPWORD                    variable As Integer                       Integer
LRESULT                   ByVal variable As Long                    Long
                          As Any or ByVal Nothing, ByVal 0 &
NULL
                          ByVal variable As Long vbNullString
SHORT                     ByVal variable As Integer                 Integer
VOID                      Sub procedure                             Desteklenmez
WORD                      ByVal variable As Integer                 Integer
WPARAM                    ByVal variable As Long                    Long

Örnek: Windows’u kapatan program.

Bu örnek için yeni bir proje yaratın ve içindeki formu silip yerine bir module ekleyin. Bu
modülün içine aşağıdaki kodu ekleyin.

   Option Explicit
       Private Declare Function WindowsKapat Lib "user32" Alias _
           "ExitWindowsEx" (ByVal uFlags As Long, ByVal dwRes As Long) As Long

   Private Sub Main()
       If MsgBox("Windows'u kapatmak " & vbCrLf & "istiyor musunuz", _
       vbYesNo, "Windows Kapaniyor") = vbYes Then WindowsKapat &H41, 0
   End Sub

                                                  89
Bu programı çalıştırmadan önce projeyi kaydedin. Daha sonra File menüsünden proje için bir
.EXE dosyası oluşturun. Bu program çalıştırıldığında Windows kapanır.

Burada uFlags parametresi için gönderilen değer, tüm programların kapatılıp windows’un
kapatılması anlamına gelmektedir.




                                            90
6. ACTIVEX İSTEMCİLERİ YARATMA

ActiveX teknolojisi Windows’un eskiden beri dayandığı temeller üzerine kurulmuştur.

İlk ortaya çıktığı zaman bu teknoloji DDE (devingen veri değişimi) olarak adlandırılmıştır. Daha
sonra OLE (Nesne bağlama ve gömme) olarak adlandırılmış ve işlevselliği artırılmıştır. Bu
teknolojinin son durumu ise ActiveX olmuştur.

OLE ve ActiveX bağlamında nesne kavramından sözedilirken özel bir nesne modeli söz konusu
edilmektedir. Bu nesne modeline Bileşen Nesne Modeli (COM) denir. Bu nesne modelindeki
nesnelere aynı zamanda Window nesnesi adı da verilir.


6.1. Bileşen Nesne Modeli (COM-Component Object Mofel)

COM standardının tanımladıkları kısaca şunlardır:
   Uygulamaların nesnelere erişmesini ve onlar üzerinde işlem yapmasını sağlayan ortak bir
     yol sağlamak.
   Bir nesnenin kullanımda olup olmadığını anlayacak bir mekanizma sağlamak ve
     kullanımda değilse nesneyi silmek.
   Standart hata bildirim mekanizması, hata kodları ve değerleri sağlamak.
   Uygulamaların nesnelerini karşılıklı olarak kullanabilmelerine olanak tanımak.
   Nesnelerin tanımlanabilmeleri için bir yol sağlamak ve uygulamaların, bu nesnelerin
     gerçekleştirimlerini anlayabilmelerine olanak tanımak.

Bir COM nesnesinin özellikleri şunlardır:
     Bir COM nesnesi veri içerebilir.
     Verileri işlemek için gerekli olan ve arayüz adı verilen bir işlev kümesine sahiptir.
     İşlevleri uygulamanın içinde yer alabilir veya bir DLL aracılığıyla sağlanabilir. Bu
      işlevler nesnenin verilerine erişimin tek yoludur.
     COM nesneleri biricik olarak tanımlanabilir olmalarını sağlayacak bir kimliğe sahiptir.
     COM nesnesinin kimliği onu bir uygulama ile veya bir .DLL dosyası ile ilişkilendirmek
      için kullanılır.

COM nesnelerinin bir görsel arayüzünün olması şart değildir ama en az bir arayüzü olmak
zorundadır. Bu arayüz şu üç işlevi içermelidir.
    AddRef, nesneye yapılan referans sayısını artırır.
    Release, referans saysısını azaltır.
    QueryInterface, nesnenin işlevlerine ulaşmayı sağlar.

Bu üç işlev açık bir şekilde Visual Basic kodu içinde çağrılmasa bile nesneler üzerinde işlemler
yapılırken her zaman bu işlevler kullanılır.


6.2. Otomasyonun Gerçekleştirilmesi

Bir çok yeni yazılım bileşenlerinin yanısıra Visual Basic 5.0 artık Bileşen Nesne Modeli (COM)
ile yazılım bileşenleri oluşturmayı da desteklemektedir. Sınıf modülleri için artık bir çok arayüz
gerçekleştirmek mümkündür
Bu yeni yaklaşımla OLE sunucuları artık yerini bileşenlere bırakmıştır.
                                               91
Visual Basic ActiveX bileşenlerini yaratmak için çok kolay ve anlaşılır bir yol sunmaktadır.

Visual Basic ile otomasyon Activex bileşenleri kullanılarak sağlanır. ActiveX bileşenleri COM
nesnelerinden oluşan birer bütündür.

ActiveX teknolojisine bir giriş yaptıktan sonra, şimdi bileşenlerin nasıl kullanılabildiği üzerinde
duralım. Örneğin Visual Basic kodu içinde Microsoft Excel ile kolayca yapılabilecek bir işleme
ihtiyaç duyulmuş olsun. Bunu gerçekleştirmek için tüm işlemleri yeniden yapmaktansa hazır
olan Excel nesneleri kullanılarak işlemler daha basit bir şekilde gerçekleştirilebilir. Bu durumda
işlemleri yapmaya olanak tanıyan Microsoft Excel nesneleri ActiveX bileşeni olarak görev
yapar. Hazır var olanların dışında ActiveX bileşenleri ticari bir nesne olarak da satılmaktadır. Bu
tıpkı bir ev yaparken parçalarını ayrı ayrı satın alıp birleştirmeye benzemektedir.

Bir ActiveX bileşeni yeniden kullanılabilir nesnelerden ve verilerden oluşan bir programdır. Bir
uygulama içinde hazır ActiveX bileşenlerini kullanmak veya yeni bileşen yaratmak mümkündür.

OLE özelliklerini destekleyen bileşenleri herhangi bir kod yazmaya gerek duymadan kullanmak
mümkündür. Bu Araç kutusu üzerinde bulunan OLE Container Control kullanılarak veya
nesneyi içeren sınıfı Araç kutusu üstüne yerleştirerek yapılır.


6.3. Activex Bileşenlerinin Özellikleri

ActiveX bileşenleri karmaşık uygulamaları var olan parçaları kullanarak gerçekleştirmeyi sağlar.
ActiveX teknolojisini destekleyen programlar (örneğin Microsoft Excel, Microsoft Word ve
Microsoft Access) Visual Basic programları içinden kullanılabilecek nesneler sağlar. Örneğin
Microsoft Excel Tablolarının özellikleri, metotları ve olayları Visual Basic Programları içinden
kullanılabilir.

Kod bileşenleri, programlanabilir nesne kütüphaneleri sağlar. Bu kütüphaneler bileşenlerin
verimli bir şekilde kullanımını sağlar. Kod bileşenlerindeki bir nesne onu kullanan uygulama ile
aynı bellek alanında da çalışabilir. Bu durum nesneye erişimi hızlandırır.

ActiveX bileşenlerini iki grupta toplamak mümkündür. Bunlar iç-bileşenler ve dış-bileşenler dir.
İç bileşenler uygulama ile aynı bellek alanında çalışırken, dış-bileşenler kendi bellek alanlarında
ayrı bir uygulama gibi çalışırlar.

ActiveX bileşenleri ile uygulama arasında bir iletişim sözkonusudur. Bu iletişim
istemci/sunumcu (Client/Server) ilişkisi şeklindedir. İstemci, bileşenin özelliklerini kullanan
uygulama, sunumcu ise bileşen ve onun kullanılan nesnesidir.

Bir ActiveX bileşeninin iç veya dış olması gerçekleştirimine bağlıdır. İç-bileşenler .DLL
dosyaları şeklindedir ve içerdikleri yordamlar çağrıldıkları uygulama ile aynı bellek alanı
üzerinde işlem yaparlar. Dış bileşenler de .EXE dosyaları biçimindedir. İçerdikleri yordamlar
çağrıldığında önce bu .EXE dosyaları ayrı bir bellek alanında çalıştırılır ve daha sonra uygulama
ile bu bileşenler arasında belirli kurallara göre iletişim başlar.

Aşağıdaki tablo, farklı türden bileşenlerin nasıl gerçekleştirilebileceğini gösterir.

Bileşen                       Sunucu Türü
ActiveX-içeren                Uygulama Dış-bileşen
                                                  92
Kod Bileşenleri              İç veya Dış bileşen
ActiveX control              İç-bileşen
ActiveX document             İç veya Dış bileşen

İç bileşen kullanmak uygulama performansını artırmanın bir yoludur.

ActiveX bileşenleri tarafından sağlanan nesneleri kullanmanın Visual Basic tarafından sağlanan
nesneleri kullanmaktan farkı yoktur. Bir nesnenin referansının aktarılabileceği değişkenler
tanımlamak, bu değişkenler kullanılarak nesnenin özelliklerini, metotlarını ve olaylarını
kullanmak mümkündür.

ActiveX bileşenlerinin sağladığı nesneleri kullanırken dikkat edilmesi gerekenler:
     Nesne için bir referans değişkeni yaratılır. Bu referansın tanımlanması ve bir nesne ile
       ilişkilendirilmesi nesnenin özelliğine göre değişir.
     Nesnenin metotlarını, özelliklerini ve olaylarını kullanacak kod yazılır.
     Nesnenin kullanımı bittiğinde nesne bellekten atılır.
     Nesneler kullanımda iken oluşabilecek hataları ele almak için yordamlar düzenlenir.

ActiveX bileşenlerinin sağladığı nesnelere örnek olması açısından aşağıdaki örnek verilebilir.

Bu örnek için, yeni bir proje yaratın ve içine aşağıdaki nesneleri yerleştirin

   CommandButton Command1 ControlArray(0-1)
   TextBox Text1 ControlArray(0-2)

Bu nesneleri ileride verilecek olan form görüntüsüne göre form üzerine yerleştirin.

Aşağıdaki kodu forma ekleyin.

Option Explicit
   Dim xlApp As Excel.Application
   Dim xlBook As Excel.Workbook
   Dim xlSheet As Excel.Worksheet
   Private Sub Command1_Click(index As Integer)
       xlSheet.Cells(1, 1).Value = Text1(0).Text
       xlSheet.Cells(2, 1).Value = Text1(1).Text
       Select Case index
           Case 0: xlSheet.Cells(3, 1).Formula = "=R1C1 + R2C1"
           Case 1: xlSheet.Cells(3, 1).Formula = "=R1C1 * R2C1"
       End Select
       Text1(2).Text = xlSheet.Cells(3, 1)
   End Sub
   Private Sub Form_Load()
       Set xlApp = New Excel.Application
       Set xlBook = xlApp.Workbooks.Add
                                                   93
       Set xlSheet = xlBook.Worksheets.Add
   End Sub
   Private Sub Form_Unload(Cancel As Integer)
       xlSheet.SaveAs App.Path & "\Temp.xls"
       xlApp.Quit
       Set xlApp = Nothing
       Set xlBook = Nothing
       Set xlSheet = Nothing
End Sub

Program çalıştığında aşağıdaki ekran görüntüsü belirecektir.




Burada TOPLA butonuna basıldığında 1. ve 2. Sayının toplamı, ÇARP butonuna basıldığında ise
çarpımı SONUC yazan yere yazılır. Bu işlemler yapılırken Excel’deki toplama ve çarpma
fonksiyonları kullanılır.

Form yüklenirken bir Excel uygulama nesnesi yaratılır, bu nesneye bir Workbook ve Worksheet
nesnesi eklenir. Daha sonra metin kutularındaki değerler, Excel’deki tablolara aktarılır ve
işlemler yapılır. Sonuç 3. Metin kutusuna aktarılır.

Programdan çıkarken de Excel’in kaydetme fonksiyonu kullanılarak yaratılan Excel tablosu
kaydedilir.

Bu örnekte fazla karmaşıklığa neden olmamak için hata ele alma kısımları eklenmemiştir. Fakat
ActiveX bileşenleri kullanılırken hata ele alma, programın önemli bir kesimidir.


6.4. Activex Bileşenlerinin VB İçinde Kullanımı

Bir nesnenin metotlarını, özelliklerini ve olaylarını Visual Basic içinde kullanabilmek içim ilk
yapılması gereken nesnenin tanımlanmasıdır. Tanımladıktan sonra bu nesne tanımına bir referans
aktarmak gerekir. Bu referans herhangi bir sınıftan türetilen bir nesnenin göstergesidir. Bir
referansın nesne değişkenine aktarılması;

                                               94
      ActiveX bileşeninin bir tür kütüphanesi sağlamasına ve,
      Nesnenin başlı başına yaratılabilmesine göre değişir.

İlk durum için Project menüsünün Preferences seçeneği kullanılarak ilgili kütüphanenin
belirtilmesi zorunludur. İkinci durumda eğer nesne tek başına var olamıyorsa önce onu
barındırabilecek bir nesne yaratmak şarttır.

Eğer bir nesne tek başına türetilebiliyorsa Set deyimi ile, New, GetObject, veya CreateObject
komutlarından biri kullanılarak nesne değişkenine bir nesne referansı yaratıp aktarmak
mümkündür. Eğer nesne bağımlı bir nesne ise aktarma işlemi kendisini barındıran nesnenin bir
özelliği kullanılarak yine bir Set deyimi ile yapılır.

Yukarıdaki örnekte xlSheet değişkeni ile belirtilen Excel Tablosu nesnesi tek başına
varolamadığı için önce onu içerebilecek nesneler yaratılmış ve bu tablo değişkenine aktarım ise
onu içeren Worksheet nesnesinin Add metodu kullanılarak yapılmıştır.


Tür kütüphanelerinde tanımlı olan türden nesnelerin kullanımı
   1. Project menüsünden Preferences seçeneğini kullanarak nesne kütüphanesini aktif hale
      getirin
   2. View menüsünden Object Browser seçeneği kullanılarak belirli bir tür kütüphanesinde
      bulunan nesneleri görmek mümkündür.
   3. Nesnenin sınıfından bir değişken tanımı yapın. Örneğin
      Dim Cizelge as Excel.Chart
   4. Değişkene değer aktarmak için Set deyimi ile birlikte New deyimini, CreateObject ve
      GetObject yordamlarını kullanmak gerekir.

Tür kütüphanelerinde tanımlı olmayan türden nesnelerin kullanımı
   1. Object türünden bir nesne tanımlanır. Bu şekilde tanımlama yapıldığında kullanılacak
      nesnenin özellikleri, metodları ve olayları doğru bir biçimde kullanılmalıdır.
   2. CreateObject veya GetObject yordamlarıyla birlikte Set deyimi kullanılarak nesne
      değişkeninne bir referans aktarılır.


Tür kütüphanesinde tanımlı bir nesne için bir değişken tanımlama
   1. Project menüsünden Properties seçeneğini kullanarak ilgili nesne için refarans olacak tür
      kütüphanesini seçin.
   2. İlgili nesnenin sınıf tanımını kullanarak bir değişken tanımlayın. Bu tanım;
      Dim değişken-adı As [New] sınıf-adı

Bu ifadedeki sınıf-adı kısmı iki parçadan oluşabilir. Bu ifade bileşen.sınıf-adı şeklinde olur.
Burada bileşen nesneyi sağlayan bileşenin adı, Sınıf-adı nesnenin sınıf adını belirtir.

Örneğin Microsoft Excel Chart nesnesi aşağıdaki iki şekilde de tanımlanabilir.

   Dim xlChart As Chart
   Dim xlChart As Excel.Chart

Eğer bir nesne için değişken tanımlandığında New deyimi kullanılırsa Visual Basic otomatik
olarak bu değişkene bir nesne yaratır ve bu nesneye bir referans ataması gerçekleştirir.
Nesnelerin New deyimi kullanılarak tanımlanmaları için şöyle bir örnek verilebilir.

                                               95
   Dim tdfPersonelGorev as new TableDef
   TdfPersonelGorev.Name = "personel-gorev"

New deyimi kullanılırken dikkatli olunmalıdır. Çünkü bu tür kullanımlar programın çalışmasını
yavaşlatır.

Tür kütüphanesinde tanımlı olmayan bir nesne için bir değişken tanımlama

Önce Object türünden bir nesne değişkeni tanımlanır.
   Dim değiken-adı As Object
Bu şekilde tanımlanan değişkenlere herhangi bir sınıftan bir nesne referansının atanması
mümkündür.

Bir nesne değişkeninin tanımı yapıldıktan sonra bu değişkenin özellik, metot ve olaylarının
kullanılabilmesi için bir nesne yaratılıp referansının bu değişkene atanması gerekir. Yeni
yaratılan bir nesnenin referansı bir değişkene farklı biçimlerde aktarılabilir.

      Değişken New deyimi kullanılarak tanımlanmışsa, değişken ilk kullanıldığında bir nesne
       yaratılır ve referansı otomatik olarak bu değişkene atanır.
      Set deyimi kullanılarak, New deyimi ile veya CreateObject yordamı ile yaratılan bir
       nesnenin referansı değişkene atanabilir.
      GetObject yordamı kullanılarak var olan bir nesnenin referansı veya eğer nesne yoksa
       yeni yaratılacak bir nesnenin referansı Set deyimi kullanılarak değişkene atanabilir.

New deyimi:
  Dim tdfMeslekler As DAO.TableDef
  Set tdfMeslekler = New DAO.TableDef
  tdfMeslekler.Name = "meslekler"

CreateObject yordamı:
   Set değişken-adı = CreateObject("sınıf-adı")
   Dim xlApp As Excel.Application
   Set xlApp = CreateObject("Excel.Application")

GetObject yordamı:
   Set değişken-adı = GetObject([yol-adı] [, sınıf-adı]).

Burada yol-ismi parametresi, var olan bir dosyanın yolunu belirleyebilir(belirtilen dosya
kullanılarak yeni bir nesne yaratılır), boş olabilir(Bu durumda CreateObject olarak işlem görülür)
veya pas geçilebilir.


Eğer ActiveX Bileşeni çalışıyorsa,
   Set X = GetObject(, "Bileşen.Application")
          X varolan bir uygulama nesnesinin referansını alır.
   Set X = GetObject("", "Bileşen.Object")
          X tek başına varolabilecek yeni bir nesne referansını alır

Eğer ActiveX bileşeni çalışmıyorsa
   Set X = GetObject(, "Bileşen.Object") Hatalı durum.
   Set X = GetObject("", "Bileşen.Object")

                                                96
ActiveX bileşeni çalıştırılır, ve X yeni bir nesne referansını alır..

Örnekler:
   Dim wordApp As Word.Application
   Set wordApp = GetObject("", "Word.Application")

Var olan bir nesne döndürülür veya yeniden yaratılır.

    Dim xlBook As Excel.Workbook
    Set xlBook = GetObject("C:\temp.xls")

Excel çalıştırılır, “temp.xls” açılır, yeni nir nesne referansı döndürülür.


6.5. Activex Bileşenleri İle İletişim Kurma

Bir nesne referansı bir değişkene atandıktan sonra, bu nesnenin özelliklerini ve metotlarını
kullanmak mümkündür.

Nesne özelliklerini ve metotlarını kullanma
Bir nesnenin özellik ve metotlarını kullanmak için nesne özellik ve nesne/metot gösterimleri
kullanılır.

Nesne olaylarını ele alma
Visual Basic programlarının içinde ActiveX nesnelerinin olaylarını ele almak da mümkündür.
Örneğin, eğer Visual Basic içinde bir Excel uygulamasına referans yaratılmışsa, Excel’de oluşan
olayları ele almak mümkündür.

Bir nesne değişkeni tanımlanırken WithEvents deyimi kullanılırsa nesnenin olaylarını olay
yordamları kullanarak ele almak mümkündür.

Bunun için yukarıda gerçekleştirilen örneği aşağıdaki belirtilen yordamlarını belirtildiği gibi
değiştirin ve belirtilen olay yordamını ekleyin.

Dim xlApp As Excel.Application
   Dim WithEvents xlBook As Excel.Workbook
   Dim xlSheet As Excel.Worksheet
   Dim kapat As Boolean
   Private Sub Form_Load()
        Set xlApp = New Excel.Application
        Set xlBook = xlApp.Workbooks.Add
        Set xlSheet = xlBook.Worksheets.Add
        xlApp.Visible = True
        xlApp.WindowState = xlMinimized
        kapat = False
    End Sub
    Private Sub Form_Unload(Cancel As Integer)

                                                   97
       kapat = True
       If MsgBox("SONUCU KAYDETMEK ISTIYOR MUSUNUZ", _
       vbYesNo) = vbYes Then
           xlBook.SaveAs App.Path & "\temp.xls"
       End If
       xlBook.Close False
       xlApp.Quit
   End Sub
   Private Sub xlBook_BeforeClose(Cancel As Boolean)
       If Not kapat Then
           xlBook.Application.Visible = False
           MsgBox "BU UYGULAMA KAPATILAMAZ"
           xlBook.Application.Visible = True
           Cancel = True
       End If
End Sub

Bu koddaki yenilikler, tanımlamalar kısmındaki WithEvents deyimi ile başlamaktadır.
Form_Load olayında Excel programının görünür hale gelmesi ve küçültülmüş duruma geçmesi
sağlanıyor.

Excel Workbook nesnesi kapatılacağı zaman ortaya çıkan xlBook_BeforeClose olay yordamında
Excel’in kapatılması engellenmektedir.



6.6 Microsoft Excel’i Bileşen Olarak Kullanan Bir Program

Böyle bir program gerçekleştirmek için;

1. Yeni bir proje yaratın. Formun üzerine aşağıdaki nesneleri ileride verilecek olan form
görüntüsüne dayanarak yerleştirin.

ListView        Name       Listview1
                View       3-lvwReport
                Text1      (ControlArray)
Form            Name       Form1

Formun içine aşağıdaki kodu ekleyin.

Option Explicit
   Dim xlApp As Excel.Application
                                                98
   Dim WithEvents xlBook As Excel.Workbook
   Dim xlSheet As Excel.Worksheet
   Dim satirSay As Integer
   Private Sub Command1_Click()
       Dim i As Integer, j As Integer
       For j = 0 To ListView1.ListItems.Count - 1
            xlSheet.Cells(j + 1, 1).Value = ListView1.ListItems(j + 1).Text
            For i = 0 To 4
                xlSheet.Cells(j + 1, i + 1).Value = _
                ListView1.ListItems(j + 1).SubItems(i + 1)
            Next i
       Next j
   End Sub
   Private Sub Form_Load()
       Set xlApp = New Excel.Application
       Set xlBook = xlApp.Workbooks.Add
       Set xlSheet = xlBook.Worksheets.Add
       satirSay = 1
       ListView1.ColumnHeaders.Add , , "A", 600
       ListView1.ColumnHeaders.Add , , "B", 600
       ListView1.ColumnHeaders.Add , , "C", 600
       ListView1.ColumnHeaders.Add , , "D", 600
       ListView1.ColumnHeaders.Add , , "E", 600
       ListView1.ColumnHeaders.Add , , "F", 600
   End Sub
   Private Sub Form_Unload(Cancel As Integer)
       Dim dAd As String
       dAd = App.Path & "\Temp.xls"
       If Dir(dAd) <> "" Then Kill dAd
       xlSheet.SaveAs dAd
       xlApp.Quit
       Set xlSheet = Nothing
       Set xlBook = Nothing
       Set xlApp = Nothing
   End Sub
   Private Sub Text1_KeyPress(Index As Integer, KeyAscii As Integer)
       Dim i As Integer
       If Index = 5 And KeyAscii = 13 Then
            ListView1.ListItems.Add satirSay, , Text1(0)
            Text1(0) = ""
            For i = 1 To 5
                ListView1.ListItems(satirSay).SubItems(i) = Text1(i)
                Text1(i) = ""
            Next i
            satirSay = satirSay + 1
            Text1(0).SetFocus
       End If
End Sub
Burada, bir ListView nesnesinin içine metin kutularına girilen veriler aktarılmakta, kaydet
düğmesine basıldığında ise bu veriler bir Excel tablosu içine aktarılır. Bu tablo ise
programdan çıkışta kaydedilmektedir.

                                                99
Programın çalışması aşağıdaki gibidir.




                                         100
7. ACTIVEX KOD BİLEŞENLERİNİ YARATMA

7.1. Giriş

Bir ActiveX bileşeni, çalıştırılabilir bir kod birimidir. Bu bir .exe, .dll veya .ocx dosyası olabilir.
Bu dosyalar ActiveX nesnelerini ve bu nesnelerin belirtimlerini içerir.

ActiveX bileşenleri çok farklı amaçlar için kullanılabilir. Bu amaçlar sayısal analiz araçları,
kullanıcı arayüzü elemanları v.b. olabilir. ActiveX bileşeni geliştirme işlemi nesneye yönelik
programlamadan (OOP) yararlanarak yapılır. Nesneye yönelik programlama, nesne tabanlı
bileşen yaratmada kullanılırken, ActiveX ise bu farklı biçimlerde ve ortamlarda yaratılmış
nesnelerin birarada çalışmasını sağlar.

ActiveX bileşeni yaratmak için özellikler
    Bileşenler farklı türlerden nesneler sağlayabilir. Bunlar, ActiveX kontrol nesneleri,
       ActiveX dokümanları, ActiveX kod bileşenleri ve Nesne Sağlayan Uygulamalardır.
    Bileşenler tarafından sağlanan nesneler için olaylar yaratılabilir.
    Friend fonksiyonlar, bir bileşen tarafından sağlanan nesnelerin birbirleriyle içsel olarak
       iletişim kurmalarını sağlar. Bu fonksiyonların dışarıdan erişilebilir olması şart değildir.
    Implements deyimi, nesnelere standart arayüzler eklemeyi sağlar.
    Adlandırılmış sabitlerin bileşendeki tüm türler için geçerli olması için Enumeration
       işlemi yapılabilir.
    Öngörülen bir özellik veya metot tanımlanarak nesne adı kullanıldığında bu metodun
       veya özelliğin anlaşılması sağlanabilir.
    Bir nesne sınıfı için gerçek bir nesne üretmeden onun özelliklerini ve metotlarını
       kullanabilme özelliği sağlanabilir.

ActiveX kod bileşenleri
Kod bileşenleri, nesne kütüphaneleri gibidir. Herhangi bir uygulama, kod bileşeninde tanımlı bir
nesne sınıfından bir nesne tanımlayarak bu nesnenin özellik metot ve olaylarını kullanabilir.
Bunlar OLE Otomasyon sunucuları olarak da adlandırılırlar.

Visual Basic kullanılarak üretilen kod bileşenleri iki biçimde olabilir. Bunlar iç-bileşen ve dış
bileşen olarak adlandırılır. İç-bileşenler daha hızlıdır ve uygulama ile aynı bellek alanında işlem
yaparlar. Dış-bileşenlerin işlem yaptıkları kendi bellek alanları vardır.

Kod bileşenleri kullanılarak bir çok dialog kutusu sunan bir kütüphane yapılabilir.

Ancak genellikle kod bileşenlerinin ayrı bir kullanıcı arabirimi yoktur.

Kod bileşenleri yukarıda da belirtildiği gibi iki farklı şekilde olabilir. Bunlar iç-bileşen veya dış-
bileşenlerdir.

İç bileşenler
Bir iç bileşen, diğer bir deyişle ActiveX DLL, başka bir uygulamanın içinde, onun bir parçası
olarak çalışır.

Avantajları:
    Kod uygulamalar arasında kolayca paylaşılabilir.
    Uygulamanın içinde çalıştıkları için hızlıdırlar.

                                                 101
      DLL içinde bir değişiklik yapmak, var olan bir hatayı düzeltmek, dağıtıldığı anda onu
       kullanan bütün uygulamaları etkiler.
      Tüm OLE otomasyon istemcileri (örneğin Microsoft Office) tarafından kullanılabilirler.

Dezavantajları:
    Değiştirilmiş bir DLL eğer önceki sürümlerini desteklemiyorsa onu kullanan
      uygulamaların işlev dışı kalmalarına neden olur.
    Uygulamanın karmaşıklığını artırabilir

Dış bileşenler
Bir dış bileşen, diğer bir deyişle ActiveX EXE, tek başına kendi bellek alanında çalışır ve diğer
uygulamalrın kendi nesnelerini kullanmasına izin verir.

Avantajları:
    Nesneler kendi bellek alalarında çalışır
    Nesneler ya tek başına, ActiveX EXE dosyasının çalıştırılmasıyla veya bir uygulama
       tarafından ActiveX EXE dosyasının çalıştırılmasıyla yaratılırlar.

Dezavantajları:
    Performansları düşüktür.
    Sistemin yükünü artırır.


7.2. Visual Basic İle Nesne Yaratma

Visual Basic ile bir nesne yaratmak için önce bir Class Module yaratılır. Class Module yapısı
nesne sınıfları yaratmak için önemli kolaylıklar ve yollar sağlar. Şimdi bir nesnenin nasıl
yaratılabileceğini ve kullanılabileceğini aşamalar halinde görelim.

1. Standart EXE türünde yeni bir proje başlatın ve adını Kredi olarak değiştirin.
2. Form1 formunun ismini frmKredi ve başlığını da KREDI ODEMELERI olarak değiştirin.
3. Projeye bir Class Module ekleyin ve ismini clsKredi olarak değiştirin.
4. Bu sınıf modülünün içine aşağıdaki kodu ekleyin.

       Public Miktar As Currency
       Public YillikFaiz As Single
       Private Ay1 As Integer
       Private Ba() As Currency

       Property Let Aylar(ay)
          Ay1 = ay
       End Property

       Property Get Aylar()
          Aylar = Ay1
       End Property

       Property Let Yillar(Y)
          Ay1 = Y * 12
       End Property

       Property Get Yillar()
                                              102
          Yillar = Ay1 / 12
       End Property

       Property Get Odeme()
          Dim AylikFaiz As Single
              'Verify that all properties are loaded
          If Miktar = 0 Or YillikFaiz = 0 Or Ay1 = 0 Then
              Odeme = 0
          Else
              AylikFaiz = YillikFaiz / 1200
              Odeme = (-AylikFaiz * Miktar) / _
              ((AylikFaiz + 1) ^ (-Ay1) - 1)
          End If
       End Property

       Public Sub OdemeHesapla()
          Dim i
          Dim bakiye As Currency
          Dim Odenen As Currency
          ReDim Ba(0)
          Ba(0) = Miktar
          Odenen = CCur(Odeme / 100) * 100
          Do Until Ba(i) <= 0
              i=i+1
              ReDim Preserve Ba(i)
              Ba(i) = Ba(i - 1) * (1 + YillikFaiz / 1200)
              Ba(i) = Ba(i) - Odenen
              Ba(i) = CCur(Ba(i) / 100) * 100
          Loop
       End Sub

       Property Get bakiye(N)
          If N > UBound(Ba) Or N < 1 Then
              bakiye = 0
          Else
              bakiye = Ba(N)
          End If
       End Property


5. Bu sınıf tanımında kredi nesnesi için özellikler ve metotlar tanımlanmıştır. Bunu kullanmak
için frmKredi formunun Form_Click olayına aşağıdaki kodu ekleyin.

Private Sub Form_Click()
       Dim KrediTest As New clsKredi
       Dim ay As Integer
       Dim bakiye As Currency
           'Set loan parameters
       Me.Cls
       KrediTest.Miktar = 180000000
       KrediTest.Aylar = 12
       KrediTest.YillikFaiz = 100
                                               103
      'Display parameters used
      Print "Miktar: ", , Format(KrediTest.Miktar, "Currency")
      Print "Ay sayisi: ", , KrediTest.Aylar
      Print "Faiz: %", , Format(KrediTest.YillikFaiz _
      / 100, "Percent")
      Print "Aylik Odeme: ", Format(KrediTest.Odeme, "Currency")
      Print
      KrediTest.OdemeHesapla
      Do
          ay = ay + 1
          bakiye = KrediTest.bakiye(ay)
          If bakiye <= 0 Then Exit Do
          Print "Ay: "; ay,
          Print "Bakiye: "; Format(bakiye, "Currency")
      Loop
End Sub



6. Eklenen bu kod ile formun üstüne mouse ile tıklandığında kredi geri ödemlerinin bir liste
halinde form üzerinde gözükmesi sağlanır. Programın çalışması aşağıdaki gibidir.




Bu program alınan bir kredi için %100 faiz uygulayarak, 1 yıllık sabit ödeme miktarını ve bu
ödeme biçiyle devam ederken kalan borç miktarını hesapmaktadır. Bunun için bir Kredi nesnesi
kullanılmaktadır. Kredi nesnesinin OdemeHesapla metodu 12 aylık bakiye miktarlarını
hesaplayıp bir dizi içine atmaktadır. Daha sonra kredi nesnesinin bakiye özelliği kullanılarak
tüm aylar için bakiyeler hesaplanmakta ve form üzerine yazılmaktadır.

Bir nesne yaratılırken dikkat edilmesi gereken önemli bir nokta da sahip olacağı özellik ve
metotların belirlenmesidir. Çünkü nesneyi kolay kullanılır ve verimli hale getiren sahip olduğu
özellikler ve metotlardır.




                                              104
7.3 Activex Kod Bileşeni Projelerinin Tasarlanması ve Gerçekleştirimi

7.3.1. Dış-Bileşenler

ActiveX kod bileşenlerinden ayrı bir bellek alanında çalışan ve nesnelerini başka uygulamaların
kullanmasına izin veren bileşenlere dış-bileşen denir. Bir uygulama, bir dış-bileşen nesnesinden
bir iş yapmasını istediğinde ondan cevap beklemek zorunda değildir. İş bildirimi aktarılır ve
uygulama kendi işine devam eder. Bu işleme zamanuyumsuz bildirim denir.

Şimdi bir ActiveX EXE projesinin gerçekleştirilmesini adımlar halinde gerçekleştirelim. Bu
projede BIBLIO veritabanının PUBLISHERS tablosuna erişim için bir nesne oluşturulacak ve bu
nesneyi başka uygulamaların kullanmasına olanak tanınacak.
    1. File menüsünden yeni bir proje yaratma seçeneğini seçin.
    2. Beliren pencereden ActiveX EXE seçeneğini seçin. Bu yeni projeye Class1 adlı bir sınıf
       modülü otomatik olarak eklenir.
    3. Proje ismini yayinevi olarak değiştirin.
    4. Proje menüsünden Properties seçeneğini seçin. General sekmesini aşağıdaki gibi
       doldurun.




   5. Project menüsünden References seçeneğini seçin ve DAO 3.5 nesne kütüphanesi ile
      projeyi ilişkilendirin.
   6. Sınıf ismini clsYayinevi olarak değiştirin ve projeyi kaydedin.
   7. Aşağıdaki kodu clsYayinevi sınıfının içine ekleyin.

              Option Explicit
              Private db As Database
              Private rs As Recordset
              Private yno As Long
              Private yad As String
              Private sad As String
              Private adres As String
              Private sehir As String
                                              105
   Private eyalet As String
   Private pkodu As String
   Private tel As String
   Private faks As String
   Private yorum As String

   Public Enum hareket
      ilk = 1
      son = 2
      birsonraki = 3
      bironceki = 4
   End Enum

   Private Sub Class_Initialize()
       Dim dosyaAdi As String
       dosyaAdi = "d:\devstudio\vb\biblio.mdb"
       Set db =
       DBEngine.Workspaces(0).OpenDatabase(dosyaAdi)
       Set rs = db.OpenRecordset("select * from publishers" & _
       " where (PubId < 100)", dbOpenDynaset, _
       dbSeeChanges, dbOptimistic)
       TutanakOku
   End Sub

   Private Sub Class_Terminate()
       rs.Close
       Set rs = Nothing
       db.Close
       Set db = Nothing
   End Sub

Public Function AlanSay() As Integer
   AlanSay = 10
End Function

Public Function AlanOku(alan As Integer) As Variant
   Select Case alan
       Case 0: AlanOku = yno
       Case 1: AlanOku = yad
       Case 2: AlanOku = sad
       Case 3: AlanOku = adres
       Case 4: AlanOku = sehir
       Case 5: AlanOku = eyalet
       Case 6: AlanOku = pkodu
       Case 7: AlanOku = tel
       Case 8: AlanOku = faks
       Case 9: AlanOku = yorum
   End Select
End Function

Public Property Get KutukBasi() As Boolean
   KutukBasi = rs.BOF
                                   106
       End Property

       Public Property Get KutukSonu()
          KutukSonu = rs.EOF
       End Property

       Public Property Get TutanakSay() As Long
          Dim bm As Variant
          bm = rs.Bookmark
          rs.MoveLast
          TutanakSay = rs.RecordCount
          rs.Bookmark = bm
       End Property

       Private Sub TutanakOku()
           If Not IsNull(rs![PubId]) Then yno = rs![PubId]
           If Not IsNull(rs![Name]) Then yad = rs![Name]
           If Not IsNull(rs![Company Name]) Then sad = rs![CompanyName]
           If Not IsNull(rs![Address]) Then adres = rs![Address]
           If Not IsNull(rs![City]) Then sehir = rs![City]
           If Not IsNull(rs![State]) Then eyalet = rs![State]
           If Not IsNull(rs![Zip]) Then pkodu = rs![Zip]
           If Not IsNull(rs![Telephone]) Then tel = rs![Telephone]
           If Not IsNull(rs![Fax]) Then faks = rs![Fax]
           If Not IsNull(rs![Comments]) Then yorum = rs![Comments]
       End Sub

       Public Sub git(htur As hareket)
          Select Case htur
              Case ilk: rs.MoveFirst
              Case son: rs.MoveLast
              Case birsonraki: rs.MoveNext
              Case bironceki: rs.MovePrevious
          End Select
          If Not (rs.EOF Or rs.BOF) Then TutanakOku
       End Sub

       Sub Main()
       End Sub

8. Bu sınıf, BIBLIO.MDB veritabanının PUBLISHERS tablosunun ilk 100 tutanağını bir
    Recorset yapısına alıp, başka programların bu bilgilere erişmeleri için nesne tanımı
    yapmalarına olanak tanır.
9. Dosya menüsünden Make yayinevi.exe seçeneğini seçin ve proje için çalışır bir dosya
    yaratın.
10. Programı çalıştırın.
11. Microsoft Excel programını çalıştırın. Açık olan çalışma kitabını yayinevi.xls olarak
    kaydedin.
12. Bu çalışma kitabı içinde, Tools menüsünün Makro seçeneğini kullanarak yayinevi adında
    bir makro yaratın.
13. Yaratılan bu makronun içine aşağıdaki visual basic kodunu yazın.


                                         107
Sub yayinevi()
       Dim AlanSay As Long
       Dim objYayinevi As Object
       Set objYayinevi = CreateObject("yayinevi.clsYayinevi")
       Dim i As Integer
       Dim j As Integer
       AlanSay = objYayinevi.AlanSay
       Sheets.Add

       ActiveSheet.Cells(1, 1).Select
       Selection.FormulaR1C1 = "Yayinevi No"
       Selection.Font.FontStyle = "Bold"
       Selection.HorizontalAlignment = xlCenter
       Selection.ColumnWidth = 12

       ActiveSheet.Cells(1, 2).Select
       Selection.FormulaR1C1 = "Yayinevi Adi"
       Selection.Font.FontStyle = "Bold"
       Selection.HorizontalAlignment = xlCenter
       Selection.ColumnWidth = 30

       ActiveSheet.Cells(1, 3).Select
       Selection.FormulaR1C1 = "Sirketi"
       Selection.Font.FontStyle = "Bold"
       Selection.HorizontalAlignment = xlCenter
       Selection.ColumnWidth = 30

       ActiveSheet.Cells(1, 4).Select
       Selection.FormulaR1C1 = "Adresi"
       Selection.Font.FontStyle = "Bold"
       Selection.HorizontalAlignment = xlCenter
       Selection.ColumnWidth = 30

       ActiveSheet.Cells(1, 5).Select
       Selection.FormulaR1C1 = "Sehir"
       Selection.Font.FontStyle = "Bold"
       Selection.HorizontalAlignment = xlCenter
       Selection.ColumnWidth = 10

       ActiveSheet.Cells(1, 6).Select
       Selection.FormulaR1C1 = "Eyalet"
       Selection.Font.FontStyle = "Bold"
       Selection.HorizontalAlignment = xlCenter
       Selection.ColumnWidth = 7

       ActiveSheet.Cells(1, 7).Select
       Selection.FormulaR1C1 = "Posta Kodu"
       Selection.Font.FontStyle = "Bold"
       Selection.HorizontalAlignment = xlCenter
       Selection.ColumnWidth = 12

       ActiveSheet.Cells(1, 8).Select
                                             108
       Selection.FormulaR1C1 = "Telefon"
       Selection.Font.FontStyle = "Bold"
       Selection.HorizontalAlignment = xlCenter
       Selection.ColumnWidth = 12

       ActiveSheet.Cells(1, 9).Select
       Selection.FormulaR1C1 = "Faks"
       Selection.Font.FontStyle = "Bold"
       Selection.HorizontalAlignment = xlCenter
       Selection.ColumnWidth = 12

      i=0
      objYayinevi.git (1)
      Do While Not objYayinevi.KutukSonu
          i=i+1
          For j = 0 To AlanSay - 2
             ActiveSheet.Cells(i + 1, j + 1).Select
             ActiveCell.FormulaR1C1 = objYayinevi.AlanOku(j)
          Next j
          objYayinevi.git (3)
      Loop
      ActiveSheet.Cells(1, 1).Select
      Set objYayinevi = Nothing
End Sub


Bu makro içinde yapılan, bir kere çalıştırılıp windows için kaydı yapıldıktan sonra, ActiveX
otomasyonunu destekleyen herhangi bir uygulama içinde kullanılabilir duruma gelen Yayınevi
nesnesinin kullanımıdır.

Önce Alan isimleri Excel tablosunun birinci satırına yazılmaktadır.

Daha sonra bir döngü içinde yaratılan Yayınevi nesnesinin tüm tutanakları bu tablonun içine
alanlarına göre yazılmaktadır.

7.3.2. İç-Bileşenler
İç bileşenler, kullanıldıkları uygulama ile aynı bellek alanında çalışan nesneleri içeren
kütüphanelerdir. İç bileşenler ActiveX DLL olarak adlandırılır.

Yukarıda verilen örneği bir iç bileşen olarak da gerçekleştirmek mümkündür.

Visual Basic ile ActiveX DLL oluşturmak, değişken tanımlamak veya yordam yazmak kadar
kolaydır.

ActiveX DLL ile normal bir DLL arasındaki fark, ActiveX DLL kullanırken içindeki
fonksiyonların tanımını yapma yerine içerdiği nesneleri ve fonksiyonları doğrudan kullanabilme
olanağı sağlamasıdır.

Şimdi ActiveX DLL yaratma işlemini adımlar halinde bir örnek içinde açıklayalım.

Bu örnekte kesirli matematik işlemlerini yapan bir nesne sınıfının tanımı yapılacak ve bu
nesnenin kullanımı açıklanacaktır.
                                               109
   1. File menüsünden yeni bir proje yaratma seçeneğini seçin.
   2. Beliren pencereden ActiveX DLL seçeneğini seçin. Bu yeni projeye Class1 adlı bir sınıf
      modülü otomatik olarak eklenir.
   3. Proje ismini KesirIslem olarak değiştirin.
   4. Proje menüsünden Properties seçeneğini seçin. General sekmesini aşağıdaki gibi
      doldurun.




   5. Sınıf ismini clsKesir olarak değiştirin ve projeyi kaydedin.
   6. Aşağıdaki kodu sınıfın içine ekleyin.

Option Explicit
       Public pay
       Public payda
       Public Sub ekle(pay1, payda1)
          pay = pay * payda1 + payda * pay1
          payda = payda * payda1
          Indirge
       End Sub
       Public Sub Cikar(pay1, payda1)
          pay = pay * payda1 - payda * pay1
          payda = payda * payda1
          Indirge
       End Sub
       Public Sub Carp(pay1, payda1)
          pay = pay * pay1
          payda = payda * payda1
          Indirge
       End Sub
       Public Sub Carp(pay1, payda1)
          pay = pay * payda1
          payda = payda * pay1
          Indirge
       End Sub
                                              110
      Private Sub Indirge()
         Dim s, t, u
         s = Abs(pay)
         t = Abs(payda)
         If t = 0 Then Exit Sub
         Do
              u = (s \ t) * t
              u=s-u
              s=t
              t=u
         Loop While u > 0
         pay = pay \ s
         payda = payda \ s
         If payda < 0 Then
              pay = -pay
              payda = -payda
         End If
   End Sub

   7. File menüsünden Make KesirIslem.dll seçeneğini seçerek KesirIslem.dll dosyasının
      oluşturulmasını sağlayın.
   8. 7. Adımdaki işlem yaratılan ActiveX DLL dosyasının windows Registry dosyasına
      kaydının yapılmasını sağlar. Bu işlemin kayıt işlemini yapmadığı durumlarda Run
      menüsünden Start With Full Compile seçeneği ile proje çalıştırılırsa kayıt yapılabilir.

Bu örnek kesirli sayılarla dört işlem yapmak için bir nesne sınıfı tanımlamakta ve bu nesne sınıfı
ActiveX otomasyonunu destekleyen uygulamalar tarafından kullanılabilir.

Bu örneği test etmek için Standart EXE türünde yeni bir proje yaratın.
   1. Projenin formuna aşağıdaki nesneleri ileride verilecek form görüntüsüne uygun olarak
       yerleştirin.

       Form                    Name frmKesir
       TextBox                 Name Text1 ControlArray(0-5)
       CommandButton           Name Command1 ControlArray(0-3)

   2. Project menüsünün Preferences seçeneğini seçin. Çıkan dialog kutusundan Kesirli Sayilar
      seçeneğinin yanındaki kutucuğu işaretleyin ve projeyi kaydedin.
   3. Formun kod kesimine aşağıdaki kodu ekleyin

Option Explicit
   Public Kesir As New clsKesir
   Private Sub Command1_Click(Index As Integer)
       Cls
       CurrentX = 1300
       CurrentY = 350
       FontSize = 30
       Kesir.pay = Text1(0)
       Kesir.payda = Text1(1)
       Select Case Index

                                               111
         Case 0
             Kesir.ekle Text1(2), Text1(3)
             Print "+"
         Case 1
             Kesir.Cikar Text1(2), Text1(3)
             Print "-"
         Case 2
             Kesir.Carp Text1(2), Text1(3)
             CurrentY = CurrentY + 50
             CurrentX = CurrentX + 50
             FontSize = 25
             Print "x"
         Case 3
             Kesir.Bol Text1(2), Text1(3)
             CurrentY = CurrentY + 100
             CurrentX = CurrentX + 100
             FontSize = 25
             Print "/"
         Case Else
      End Select
      Text1(4) = Kesir.pay
      Text1(5) = Kesir.payda
End Sub


Program çalıştırıldığında aşağıdaki form görüntüsü belirecektir. Burada iki kesiri yazın ve
aşağıda sıralanmış işlem butonlarından birine basın. İşlem sonucu en sağdaki kesir içinde
gözükecektir.




7.4. Activex Kod Bileşenlerinin Test Edilmesi

ActiveX kod bileşenlerini test etmek için veya hatalarını ayıklamak için iki yol vardır.

   1. Projeyi çalışır durumda bırakıp, başka bir uygulama açmak ve nesneleri kullanmak. Bu
      başka uygulama Visual Basic programının kendisi de olabilir. Bunun için Visual Basic
      programının yeniden çalıştırılması gerekir.
   2. ActiveX bileşeni oluşturmak için kullanılan proje açık iken File menüsünden Add Project
      seçeneği kullanılarak yeni bir proje eklemek ve bir proje grubu oluşturmak.

Bu yollardan birincisi yukarıdaki ActiveX EXE ve ActiveX DLL örneklerinde yapılan işlemin
aynıdır. Yukarıdaki projeler test aşamasında iken, örneğin ActiveX EXE programı, bu projeler
                                                112
kapatılmadan ve çalışır durumda bırakılarak içindeki nesneleri kullanmak mümkündür. Bu işlem,
bileşenlerin windows için kaydı yapılmamışken yapılır. Böylece bileşenin doğru çalıştığından
emin olunduktan windows kaydı yapılır.

ActiveX bileşenlerinin çalışıp çalışmadığını test etmek için şu ana kadar kullanılan yöntem
birinci yöntemdir.

Şimdi yeni bir ActiveX bileşeni yaratalım ve ikinci yöntemi kullanarak bu bileşeni nasıl test
edeceğimizi görelim.

Örneğin başkalarının da kullanabileceği, herhangi bir sisteme giriş için veya bir uygulamayı
kullanan kullanıcıların denetlenmesi sırasında kullanılabilecek bir PASSWORD dialog kutusu
tasarlayalım. Bu dialog kutusunun Kullanıcı Adı ve Kullanıcı Password’u adlı iki tane metin
kutusu ve Tamam ve İptal adlı iki tane butonu olsun.


Şimdi bu projenin oluşturulmasını adımlar halinde gösterelim.

   1. ActiveX DLL türünden yeni bir proje yaratın. İsmini Pass olarak değiştirin.
   2. File menüsünden Pass Properties seçeneğini kullanarak çıkan dialog kutusundan Project
      Description kısmına Password Alma Formu yazın.
   3. Projenin içindeki Class1 sınıfının ismini passWord olarak değiştirin.
   4. Projeye aşağıdaki formu ekleyin.




   5. Buradaki nesnelerin özelliklerini aşağıdaki gibi değiştirin.

       Form              Name                  frmPass
       TextBox           Name                  txtKAd
       TextBox           Name                  txtPass
                         Passwordchar          *
       C.Button          Name                  cmdTamam
                         Default               True
       C.Button          Name                  cmdIptal
                         Cancel                True

    6. passWord sınıfına aşağıdaki kodu ekleyin.

           Property Get kullaniciAd()
              kullaniciAd = frmPass.txtKAd
           End Property

           Property Get passWord()

                                               113
         passWord = frmPass.txtPass
      End Property

      Sub Gizle()
         frmPass.Hide
      End Sub

      Sub Goster(sol As Long, ust As Long)
         frmPass.Move sol, ust
         frmPass.Show vbModal
      End Sub

      Private Sub Class_Initialize()
          Load frmPass
      End Sub

      Private Sub Class_Terminate()
          Unload frmPass
      End Sub

7. frmPass formuna aşağıdaki kodu ekleyin.

       Option Explicit

      Private Sub cmdTamam_Click()
          Hide Me
      End Sub

      Private Sub Iptal_Click()
          txtKAd=""
          txtPass=""
          Hide Me
      End Sub

8. Projeyi test etmek için projeye yeni bir proje ekleyin.
9. Yeni eklenen projenin ismini PassTest olarak değiştirin. İçindeki formun ismini
    frmPassTest, Caption özelliğini PASSWORD TEST olarak değiştirin.
10. Forma cmdPassWordAl adlı ve Caption özelliği Password Al olan bir Command Button
    yerleştirin ve aşağıdaki kodu forma ekleyin.

   Option Explicit
   Dim objPass As New pass.passWord

   Private Sub cmdPasswordAl_Click()
      Dim kAd As String
      Dim pass As String
      Cls
      CurrentX = 0
      CurrentY = 2000
      FontSize = 14
      objPass.Goster frmPassTest.Left, frmPassTest.Top
      kAd = "Kullanıcı Adı : " & objPass.kullaniciAd
                                        114
      Print kAd
      pass = "Password : " & objPass.passWord
      Print pass
End Sub

11. Project menüsünden References seçeneğini seçin. Çıkan dialog kutusundan ActiveX DLL
    projesinin ismi olan Pass satırının yanını işaretleyin. Bu işlem diğer projeden ActiveX
    DLL projesinin nesnelerinin görülmesine olanak verir.
12. Yukarıdaki kod yeni tanımladığımız ActiveX bileşeninin formunu kullanarak Kullanıcı
    Adı ve Password bilgilerini almaktadır. Bu bilgiler daha sonra formun üzerine
    yazılmaktadır. Şimdi programı çalıştırın. Password girilip TAMAM tuşuna basıldığında
    aşağıdaki gibi bir form görüntüsü oluşacaktır.




13. Password alma formu gösterilirken konumu da Goster metoduna parametre olarak
    verilmektedir.
14. Programın çalışmasını bu şekilde test edip doğru çalıştığından emin olduktan sonra, File
    menüsünden Open Project seçeneğini kullanarak Pass.vbp projesini açın.
15. Daha sonra File menüsünden Make Pass.dll seçeneğini kullanarak ActiveX bileşeni için
    nesne kütüphanesini oluşturun ve windows kaydını yapın.
16. Bu işlem yapıldıktan sonra Visual Basic programını kapatın ve yeniden açın. Daha sonra
    Project menüsünden References seçeneğini seçin. Aşağıdaki gibi bir dialog kutusu
    çıkacaktır.




                                          115
Bu dialog kutusundan da görüldüğü üzere yeni yaratılan ActiveX bileşeninin windows kaydı
yapılmıştır. Artık ActiveX otomasyonunu destekleyen herhangi bir uygulama içinde bu bileşeni
kullanmak mümkündür.


7.5. Bileşenlerin İçinde Olay Kullanımı.

ActiveX bileşenleri içinde tıpkı normal nesnelerde olduğu gibi olay tanımlamak mümkündür.
Bunu örneklemek için kesir işlemleri için kullanılan daha önceki örnek üzerinde bir kısmı
değişiklikler yapalım. KesirIslem.vbp projesini açın.

   1. clsKesir sınıfının başına olay tanımı için aşağıdaki satırı ekleyin.

      Public Event SIFIRABolme()

   2. clsKesir sınıfındaki Ekle, Cikar, Carp ve Bol yordamlarına Indirge yoramının
      çağrılmasından önce şu satırı ekleyin

      If payda = 0 Then RaiseEvent SIFIRABolme

   3. Project menüsünden Properties seçeneğini kullanarak Prject Description kısmına Kesirli
      Islemler 2 yazın.
   4. Dosya menüsünden Make KesirIslem seçeneğini kullanarak bileşen için nesne
      kütüphanesi yaratın. Visual Basic programını kapatıp tekrar açın.
   5. KesirDene projesini açın. Project menüsünden Preferences seçeneğini seçin ve Kesirli
      Islemler 2 satırının seçilmiş olduğunu kontrol edin.
   6. FrmKesir formunun başındaki Kesir nesnesinin tanımını aşağıdaki gibi değiştirin.

      Public WithEvents Kesir As clsKesir

   7. Bu tanım Kesir nesnesinin olaylarını kullanabilme olanağı sağlar. Olayın naıl
      kullanılabileceğini görmek için aşağıdaki kodu forma ekleyin.

      Private Sub Form_Load()
          Set Kesir = New clsKesir
      End Sub

      Private Sub Kesir_SIFIRABolme()
         MsgBox "SIFIRA BOLME GERCEKLESTI", vbExclamation
      End Sub

   8. Program çalıştığında, eğer kesirlerden herhangi birinin paydası sıfır ise (sonuç kesiri de
      dahil) bu SIFIRABolme olayı gerçekleşir ve bir mesaj kutusu belirir.


7.5. Nesneler İçin Arayüz Tanımlama.

Visual Basic ile genel amaçlı yordam kütüphaneleri, yordamları sınıfın metotları olarak
yazmakla gerçekleştirilebilir. Bunun için, Class Module özelliklerinden Instancing özelliği
Private veya PublicNotCreatable değerleri dışında bir değer almalıdır.



                                                116
Instancing özelliği için GlobalMultiUse değerini alırsa sınıf için bir nesne yaratmaya gerek
kalmadan metotlarını kullanmak mümkündür.

Bunu kod ile örneklersek:

Instancing=MultiUse
   Public Kesir As New clsKesir
   Private Sub Topla()
       Kesir.pay=10
       Kesir.payda=20
       Kesir.ekle(7,8)
End Sub

Bu kullanımda nesnenin yaratılması, metot ve özelliklerinin nesne değişkeni ile beraber
kullanılması şarttır.

Instancing=GlobalMultiUse
   Private Sub Topla()
       pay=10
       payda=20
       ekle(7,8)
End Sub

Bu kullanımda ise, nesne özellikleri ve metotları doğrudan kullanılabilmektedir. Nesne
özelliklerine ve metotlarına erişim olduğunda gizli bir nesne yaratılır. Bu nesne üzerinde işlemler
gerçekleştirilir.

Global Nesne Arayüzleri ile ilgili öneriler ve sınırlamalar
    Enum olarak belirtilen nesneler Long türündedir.
    İsimlerde çakışma olduğunda kütüphane isimleri de kullanılmalıdır.
    Yordam adları dikkatli seçilmelidir. Eğer sık kullanılan bir ad olduğu düşünülüyorsa
       değişik bir ad kullanma tercih edilmelidir.
    İçerilen nesneler için değişken tanımlamak ve nesneleri yaratmak da mümkündür.
    Gizli olan bir nesneyi yok etmek için ona Nothing değerini aktarmak mümkün değildir.
    Uygulamanın çalışmasında biraz yavaşlatmaya neden olabilir.
    VB kütüphanelerindeki yordamların veya nesnelerin yerine kullanılamazlar.

Nesneler için arayüz tanımlanırken dikkat edilmesi gereken bir nokta da veri gizleme olanağının
kullanılmasıdır. Nesne özelliklerini Public tanımlar kullanarak tanımlamaktansa Property Get ve
Property Let yordamları yapmak daha kullanışlıdır. Bu şekilde nesne özelliklerinin alabileceği
değerleri kontrol etmek, bazı özelliklerinin sadece yazılabilir olmasını sağlamak ve bazı
özelliklerin sadece okunabilir olmasını sağlamak mümkündür.

Nesnelerin içsel olarak kullandıkları yordamlar Private olarak tanımlanmalıdır.

Arayüzler için şu kurallara uyulmalıdır:
Bir sınıfın metotları, özellikleri ve olayları için seçilen adlar sınıftan yaratılacak nesne için
arayüz oluşturur. Bu arayüzler tanımlanırken aşağıdaki kurallara uyulmalıdır.
     Kullanılan sözcükler kısaltılmamalıdır.
     Bir kaç sözcükten oluşan deyimler kullanmak anlaşılırlığı artırır.
     Bir ifadeyi kısaltmak yerine bütün olarak kullanmak daha kolay kullanılır arayüzler
       sağlar.
                                               117
      Sabit tanımları için uygun ön ekler belirlenmelidir.


7.6. Kod Bileşenlerinin Diğer Özellikleri.

      ActiveX bileşenleri tarafından sağlanan nesneler için olay tanımlamak mümkündür.
       Olaylar, bazı özel durumlarda denetimi uygulamanın ele geçirmesine yardımcı olmaları
       açısından yararlıdır.
      Bir Visual Basic oturumunda aynı anda bir çok açık proje olmasını sağlayan proje grubu
       yaratma özelliği sayesinde ActiveX DLL ve ActiveX EXE bileşenlerin anında hata
       kontrolünün yapılmasına olanak tanınması ve test edilmesi mümkündür.
      Global Nesne tanımlama olanağı nesneleri açık olarak yaratmadan özelliklerini ve
       metotlarını kullanmak mümkündür. Bu özellik yordam kitaplıkları yaratmada kolaylık
       sağlar.
      ActiveX DLL bileşenleri içinde Modeless formlar göstermek mümkündür.
      Sınıf tanımları içinde öngörülen bir özellik veya metot tanımlamak mümkündür.
      For Each deyimi ile kullanılabilecek Collection sınıfları yaratmak mümkündür.
      İsimlendirilmiş sabit tanımları yaratılan tür kitaplıkları ile kullanılabilir.
      Sınıfların birden çok arayüze sahip olması sağlanabilir.
      Friend yordam kullanma olanağı sayesinde, bir bileşen içindeki farklı nesneler
       birbirlerinin yordamlarını kullanabilir. Bu tür yordamlların tanımı şu şekilde yapılır.

       Friend Property Let Demo(NewDemo As udtDemo)
           mDemo = NewDemo
       End Property

       Friend Sub SetDemoParts(ByVal A As Integer, _
       ByVal B As Long, ByVal C As String)
          mDemo.intA = A
          mDemo.lngB = B
          mDemo.strC = C
       End Sub

      Property yordamlarında parametreler için esneklikler sağlanmaktadır. Değişken
       parametreler ve seçimlik parametre kullanmak mümkündür.




                                               118
8. ACTIVEX KONTROL NESNESİ YARATMA

Bu bölümde adımlar halinde ActiveX koontrol nesnelerinin nasıl yaratıldığı işlenecektir.

ActiveX kontrol nesneleri Visual Basic araç kutusuna yerleştirilebilen ve Visual Basic
programının bir parçası olmayan, uygulama geliştirirken uygulamalar içinde kullanılabilen
nesnelerdir.

Bir ActiveX kontrol nesnesini diğer kontrol nesneleri gibi kullanmak mümkündür. Daha önce
kullanmış olduğumuz ActiveX Data Bound kontrol nesneleri buna bir örnek olarak verilebilir.

ActiveX Kontrol nesneleri programların daha kolay yapılabilmesini, daha esnek olmasını ve
daha işlevsel olmasını sağlar. Bu kontrol nesnelerinin özellikleri, metotları ve olayları kendi
belirlediğimiz durumları karşılayacak şekilde tasarlandığı için programın bize özgü yapı taşları
görevini görürler.

Bir ActiveX kontrol nesnesi UserControl nesnesi ve bunun içine konacak olan birtakım kontrol
nesnesinden oluşur.

Visual Basic kullanarak ActiveX kontrol nesnesi yaratmak için üç yol vardır.
    Bir kontrol nesnesini baştan yaratmak.
    Var olan bir kontrol nesnesini iyileştirmek.
    Var olan bir çok kontrol nesnesini birleştirerek yeni bir kontrol nesnesi yaratmak.

Bu yollardan ikincisi en basit olanıdır. Tek yapılması gereken var olan konrol nesnesini
UserControl üzerine yerleştirip buna bazı işlevsellikler eklemektir. İlkinde kontrol nesnesinin
çizimi de dahil, tasarımı, olayları, metotları kullanıcı tarafından gerçekleştirilir.


8.1. ActiveX Control Nesnesinin Yaratılması
Visual Basic Add-Ins menüsünden kullanılabilecek olan ActiveX Control Interface Wizard
sihirbazı var olan kontrol nesnelerine dayanan yeni kontrol nesneleri yaratmaya olanak tanır.
Fakat başlangıç için bu sihirbazın yarattığı kodu incelemek biraz zor ve karmaşık gelebilir. Bu
yüzden önce bir ActiveX kontrol nesnesinin nasıl yaratıldığını görelim.

ActiveX kontrol nesnesi yaratmanın adımları:
    ActiveX Control türünde bir proje yaratın.
    UserControl penceresinde kontrol nesnesinin görsel arayüzünü yaratın.
    Kod penceresinde, kontrol nesnesinin yeniden boyutlandırılması durumunda çalışacak
       olan Resize olayı için kod yazın.
    Kontrol nesnesine özellikler, metotlar ve olaylar ekleyin ve onları programlayın.
    Kontrol nesnesinin işlevselliğini gerçekleştirecek kodu yazın.
    Yeni, Standard EXE türünden bir proje ekleyin. Bu kontrol nesnesinin hatalarını bulma
       ve test etme olanağı sağlayacaktır.
    File menüsünden Make OCX seçeneğini seçerek kontrolün derlenmiş halini yaratın.

Örnek: ActiveX kontrol nesnesi yaratma.
Yukarıda genel olarak adımlar halinde belirtilen işlemi yine adımlar halinde gerçekleştirelim.
   1. File menüsünden New Project seçeneğini seçin. ActiveX Control türünden bir proje
      yaratın.
                                              119
   2. Project menüsünden Project Properties seçeneğini seçin. Project Name olarak YeniButon
      yazın. Project Description kısmına Yeni ActiveX Butonu yazın.
   3. Projedeki UserControl nesnesinin, Name özelliğini yButon, BackColor özelliğini
      &H00FF8080&, Height özelliğini 405, Width özelliğni 1605 olarak değiştirin.
   4. Projeyi kaydedin.
   5. Kontrol nesnesini test edebilmek için Standard EXE türünden yeni bir proje ekleyin.
      Üzerindeki formun Name özelliğini frmYBtn, Caption özelliğini Kontrol Nesnesinin
      Testi olarak değiştirin.
   6. Proje grubunu kaydedin.

Bir ActiveX nesnesinin tasarım aşamasında tetiklenen olayları, çalışan bir kesimi vardır. Bu
olaylardan biri de Resize olayıdır. Tasarım sırasında kontrol nesnesinin boyutları değiştiğinde bu
olay tetiklenir. Bunu denemek için:

   1. Aşağıdaki kodu UserControl nesnesinin kod kısmına ekleyin.

       Private Sub UserControl_Resize()
           Static i As Integer
           i=i+1
           Debug.Print "Boyutlandırma" & i
       End Sub

   2. UserControl tasarım pencerisini ekrana getirin ve bu pencereyi kapatın. FrmYBtn
      formunun tasarım penceresini açın. Araç kutusunun altında yeni kontrol nesnesi standart
      bir şekil ile görülmektedir.
   3. yButon kontrol nesnesini çift tıklayın. Bu işlem kontrol nesnesinin gerçek boyutunda
      formun tam ortasına yerleştirilmesini sağlar. Bu durumuyla Immediate Window
      penceresinde “Boyutlandırma1” yazısı yazılır. Bunun anlamı Resize olayının bir kere
      tetiklendiğidir. Kontrol nesnesi yeniden boyutlandırıldığında bu defa “Boyutlandırma2”
      yazısı çıkacak ve bu böyle devam edecektir.Kontrol nesnesinin Width özelliği
      değiştirildiğinde bu yazının tekrar yazıldığı görülür.
   4. yButton tasarım penceresini açın. Şimdi form penceresine dönün. Kontrol nesnesinin
      taralı olarak gözüktüğü görülecektir. Şimdi yine kontrol nesnesini boyutlandırın. Bu defa
      herhangi bir yazı yazılmadı. Çünkü kontrol nesnesinin tasarım penceresi açık iken
      kontrol nesnesi çalışmaz.

Şimdi yeni butonun üç boyutlu görünümünü gerçekleştirmek için aşağıdaki işlemleri
gerçekleştirin.

   1. Form üzerindek yButon nesnesini silin ve çift tıklayarak yeniden bir yButon yerleştirin.
      Bu işlem gerçek boyutu ile bir yButon yerleştirilmesini sağlar.
   2. Aşağıdaki Line nesnelerini belirtilen özellikleriyle UserControl üzerine yerleştirin.

         Line    Name                Line1
                 BorderColor         &H00808080&
                 BorderWidth         2
                 X1                  1560
                 X2                  1560
                 Y1                  60
                 Y2                  400
         Line    Name                Line2
                                               120
                 BorderColor        &H00E0E0E0&
                 BorderWidth        2
                 X1                 20
                 X2                 20
                 Y1                 0
                 Y2                 400
        Line     Name               Line2
                 BorderColor        &H00808080&
                 BorderWidth        2
                 X1                 40
                 X2                 1560
                 Y1                 405
                 Y2                 405
        Line     Name               Line4
                 BorderColor        &H00E0E0E0&
                 BorderWidth        2
                 X1                 0
                 X2                 1560
                 Y1                 20
                 Y2                 20

   3. Form penceresine geçin, sağ tuşa basın ve çıkan menüden Update UserControl seçeneğini
      seçin. Üç boyutlu görünümün sağlandığı görülür.
   4. Şimdi kontrol nesnesini yeniden boyutlandırın. Görüleceği gibi yeni çizilen çizgiler
      olduğu yerde durmaktadır.


8.2. Bir UserControl Nesnesinin Temel Olayları

Bir UserControl nesnesinin yaşamı bir form üzerine yerleştirlmesiyle başlar ve formdan silinince
yok olur. Bu yaşamı boyunca oluşan olayların ne zaman oluştuğunu bilmek önemlidir. Bu
olayları görmek için:

   1. Aşağıdaki kodu Ybuton kontrol nesnesinin kod kesimine yazın.

       Private Sub UserControl_Initialize()
           Debug.Print "Initialize"
       End Sub

       Private Sub UserControl_InitProperties()
          Debug.Print "Init properties"
       End Sub

       Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
          Debug.Print "Read Properties"
       End Sub


       Private Sub UserControl_Terminate()
                                              121
          Debug.Print "Terminate"
       End Sub

       Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
          Debug.Print "Write Properties"
       End Sub

   2. Formun tasarım penceresini açın, sağ tuşa basıp Update User Control seçeneğini seçin.
      Bu işlem gerçekleştiği anda aşağıdaki yazıların Immediate penceresine yazıldığı görülür.
   3. Initialize
           Read Properties
           Boyutlandırma1
      Update User Control seçeneği form üzerindeki kontrol nesnesini siler ve yerine aynı
      boyutlarda yeni bir tane yaratır. Bu yazılar kontrol nesnesinin yaratılması sırasında
      oluşan olayları belirtmektedir.
   4. Şimdi F5 tuşuna basarak projeyi çalıştırın. Bu defa aşağıdaki yazıların yazıldığı
      görülecektir. Bunlarda ilki tasarım zamanındaki nesnenin yok edildiğini belirtmektedir.
   5. Write Properties
      Terminate
      Initialize
      Read Properties
      Boyutlandırma1
   6. Şimdi ilk nesneyi yukarı doğru çekerek, çift tıklama ile yeni bir nesne formu üzerine
      yerleştirin. Şimdi F5 tuşuna basarak projeyi çalıştırın. Bu defa yukarıdaki mesajlardan
      ikişer tane oluştuğu görülecektir.

Şimdi bütün bu olayların ne zaman oluştuğunu özetleyelim.

Initialize: Kontrol nesnesi her yaratıldığında(tasarım veya çalışma zamanında) oluşan ilk
olaydır.

InitProperties: Bir kontrol nesnesi yaratıldığında, bazı özelliklerine ilk değer atamak için
kullanılır.

Read Properties: Kontrol nesnesinin bir olgusu yaratıldığında oluşur.

Resize: Kontrol nesnesi yeniden boyutlandırıldığında oluşur.

Paint: Kontrol nesnesi form üzerinde kendisini gösterdiğinde oluşur.

Write Properties: Tasarım zamanı nesnesi silindiğinde oluşur. Özelliklerdeki değişimleri
kaydetmek için kullanılır.

Yukarıda da belirtildiği gibi kontrol nesnesi yeniden boyutlandırıldığında çizgilerin ortada
kaldığı görünmektedir. Bunu önlemek için Resize olayının kodunu aşağıdaki gibi değiştirin.

    Private Sub UserControl_Resize()
        Line1.X1 = scalewidht - 20
        Line1.X2 = ScaleWidth - 20
        Line1.Y2 = ScaleHeight
        Line2.Y2 = ScaleHeight
        Line3.X2 = ScaleWidth - 40
                                              122
        Line3.Y1 = ScaleHeight - 20
        Line3.Y2 = ScaleHeight - 20
        Line4.X2 = ScaleWidth - 40
    End Sub

Yani durumuyla, yeniden boyutlandırma sırasında herhangi bir sorun olmadığı, üç boyutlu
görünüşün devam ettiği görülür.


8.3. Kontrol Nesnesine Bir Caption Özelliği Ekleme

Kontrol nesnesine Caption özelliği eklemek için bir etiket eklemek gerekir. Etiketin özellikleri
dikkatli belirlenmelidir. Çünkü tasarımın güzel olması bu özelliklerin uygun olarak seçilmesine
bağlıdır. Şimdi aşağıdaki adımları izleyerek bir Caption özelliğinin nasıl eklendiğini görelim.

   1. Kontrol nesnesi tasarım penceresini açın ve üzerine bir etiket yerleştirin. Etiketin
      aşağıdaki özelliklerini belirtildiği gibi değiştirin.

        Label     Name             lblCaption
                  Alignment        Center
                  Autosize         True
                  Font             Times New Roman-10-Tur.
                  ForeColor        White
                  BackStyle        Transparent
                  Caption
                  WordWrap         True

   2. UserControl kod penceresini açın. Tools menüsünden Add Procedure seçeneğini
      kullanarak, Caption adında, Public bir Property yaratın ve aşağıdaki kodu ekleyin.

           Public Property Get Caption() As String
              Caption = lblCaption.Caption
           End Property

           Public Property Let Caption(vNewValue As String)
              lblCaption.Caption = vNewValue
           End Property

   3. Kontrol nesnesi tasarım penceresini kapatın, formun üzerindeki kontrol nesnelerinden
      birini seçin. Properties penceresinden de görüleceği gibi nesnenin artık Caption adlı bir
      özelliği vardır. Bu özelliği değiştirip ENTER tuşuna basın. Yazılan Caption özelliğinin
      nesne üzerine yansıdığı görülecektir.
   4. Şimdi projeyi çalıştırın. Yazılan Caption değerinin yok olduğu görülecektir. Bunun
      sebebi, yok edilen tasarım zamanı nesnesinin özelliklerinin çalışma zamanı nesnesine
      aktarılmamasıdır. Şimdi bu aktarmanın nasıl yapılacağını görelim.

Tasarım zamanındaki özelliklerin çalışma zamanına aktarılması için UserControl nesnesinin iki
olayı kullanılır. Bunlar ReadProperties ve WriteProperties olaylarıdır. Kod penceresini açın ve
tüm Debug.Print deyimlerini kaldırın. Aşağıdaki kodu ekleyin.
    Private Sub UserControl_InitProperties()
       Caption = Extender.Name
                                              123
   End Sub

   Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
       Caption = PropBag.ReadProperty("Caption", Extender.Name)
   End Sub

   Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
       PropBag.WriteProperty "Caption", Caption, Extender.Name
   End Sub


Buradaki ilk yordamda Caption özelliğine ilkdeğer atama işlemi yapılmaktadır. Diğer yordamlar
ise özelliklerin PropBag adı verilen ve özelliklerin değerini tutan özel bir veri yapısı içine özellik
değerlerinin yazılması ve oradan özellik değerlerinin okunması için kullanılmaktadır.

UserControl nesnesine yapılması gereken bir diğer ek ise Caption değerinin nesne üzerinde ortalı
görünmesini sağlamak olmalıdır. Bunun için aşağıdaki satırı Resize olayına ekleyin.

       lblCaption.Move (ScaleWidth - lblCaption.Width) / 2, _
       (ScaleHeight - lblCaption.Height) / 2

Proje bu haliyle çalıştırıldığında Caption özelliğinin artık doğru çalıştığı görülecektir.

Burada kullanılan Extender nesnesi UserControl nesnesinin ilk yaratıldığı anda sahip olduğu
özellikleri, olayları ve metotları içerir. Bu nesne UserControl nesnesinin ilkel halidir. Tanımlı
olan bir başka nesne ise Ambient nesnesidir. Bu nesne ise kontrol nesnesinin içine konduğu
formu belirtir.


8.4. UserControl Nesnesinin Olayları
Usercontrol nesnesi için tanımlanmış bir çok olay vardır. Bu olayların yaratılacak kontrol nesnesi
için geçerli olabilmesi için bir biçimde dışarıya gönderilmesi gerekir. Bu işleme olay tanımlama
denir.

Şimdi UserControl nesnesinin olaylarının nasıl kullanılacağını görelim. Bunun için butona
basıldığını belirten içe göçme işlemini gerçekleştirelim.

Aşağıdaki kodu UserControl kod kesimine ekleyin.

Private ArkaRenk As Long
    Const ISIKLI = &HE0E0E0
    Const GOLGELI = &H808080
    Private Sub BASILI()
    ArkaRenk = BackColor
    Line1.BorderColor = ISIKLI
    Line2.BorderColor = GOLGELI
    Line3.BorderColor = ISIKLI
    Line4.BorderColor = GOLGELI
    BackColor = &HFFFFFF - BackColor
End Sub

Private Sub SERBEST()
                                                 124
   BackColor = ArkaRenk
   Line1.BorderColor = GOLGELI
   Line2.BorderColor = ISIKLI
   Line3.BorderColor = GOLGELI
   Line4.BorderColor = ISIKLI
End Sub

Private Sub UserControl_MouseDown(Button As Integer, _
Shift As Integer, X As Single, Y As Single)
    BASILI
End Sub

Private Sub UserControl_MouseUp(Button As Integer, _
Shift As Integer, X As Single, Y As Single)
    SERBEST
End Sub

Private Sub lblCaption_MouseDown(Button As Integer, _
Shift As Integer, X As Single, Y As Single)
    BASILI
End Sub

Private Sub lblCaption_MouseUp(Button As Integer, _
Shift As Integer, X As Single, Y As Single)
    SERBEST
End Sub


Burada dikkat edilmesi gereken BASILI ve SERBEST yordamlarının hem UserControl ve hem
de lblCaption için çağrıldığıdır.

Progragram çalıştırıldığında içe göçme olayının gerçekleştiği görülecektir.


8.5. UserControl Nesnesi İçin Olay Tanımlama
Bir UserControl nesnesine olay eklemek çok basittir. Daha önce ActiveX DLL nesnesi içindeki
olay tanımının aynıdır. Şimdi UserControl nesnesinin kod penceresini açın ve aşağıdaki tanımı
Declarations kesimine ekleyin.

   Public Event Click()

Şimdi yapılması gereken bu olayın ne zaman ortaya çıkacağına karar vermektir. Bu olay,
UserControl nesnesinin ve lblCaption nesnesinin Click olayları oluştuğunda ortaya çıkacaktır.
Bunun için aşağıdaki kodu UserControl nesnesine ekleyin.

       Private Sub lblCaption_Click()
          RaiseEvent Click
       End Sub

       Private Sub UserControl_Click()
          RaiseEvent Click
       End Sub
                                               125
Bu olayları test etmek için UserControl tasarım penceresini kapatın. Formun kod kesimine
aşağıdaki kodu ekleyin.

       Private Sub yButon1_Click()
          MsgBox "BASTIGINIZ IÇIN" & vbCrLf & " TESEKKURLER " & _
          yButon1.Caption
       End Sub

       Private Sub yButon2_Click()
          MsgBox "BASTIGINIZ IÇIN" & vbCrLf & " TESEKKURLER " & _
          yButon2.Caption
       End Sub


Program çalıştırılıp üzerine yerleştirilmiş olan butonlara basıldığında bir mesaj kutusu ile
basıldığı bilgisi kullanıcıya gösterilmektedir. Böylece kullanıcıya UserControl nesnesi için olay
tanımlama ve bu olayı kullanabilme olanağı tanınmış olduğu görülmektedir.


8.6. UserControl Nesnesine Property Page Ekleme
Property yordamları kullanarak tanımlanan özellikler, kontrol nesnesi bir form üzerine
yerleştirilip seçili duruma getirildiğine Properties penceresinde görünürler. Ayrıca kendi
yarattığımız kontrol nesnelerinde bu özellikleri toplu olarak, bir dialog kutusu yardımıyla
değiştirebilme olanağı da vardır. Bu dialog kutularına Property Page denir. Bunlara örnek
olarak, CommonDialog kontrol nesnesinin (Custom) adlı özelliğini kullanarak çıkan Property
Page verilebilir. Bu dialog kutusu incelendiğinde, içinde bir çok sekme bulunan bir dialog kutusu
olduğu görülür.

Kontrol nesnesine eklenen her Property Page, Property Page dilog kutusuna bir sekme olarak
eklenir. Bu dialog kutusundaki Ok, Cancel, Apply butonları ve sekmeli yapı Visual Basic
tarafından otomatik olarak sağlanır.

Bir kontrol nesnesine Property Page eklemek için aşağıdaki adımlar takip edilmelidir.
    1. UserControl nesnesinin tasarım pencersi açılır, Project menüsünden Add PropertyPage
       seçeneği seçilir.
    2. Property Page için bir isim ve Caption belirlenir.
    3. Projeyi kaydedin.
    4. Propety Page tasarım penceresi UserControl tasarım penceresine benzerdir. Buradan
       Property Page tasarımı yapılabilir.

Şimdi bu adımları örneğimiz üzerinde adımlar halinde uygulayalım.
   1. UserControl tasarım penceresini açın. Project menüsünden Add Property Page seçeneğini
       seçin.
   2. Aşağıdaki nesneleri ekleyin ve özelliklerini belirtildiği gibi değiştirin

         PropertyPage         Name         YBGenel
                              Caption      Genel
         TextBox              Name         txtCaption
         Label                Name         Label1
                              Caption      Caption

                                              126
   4. Projeyi kaydedin. Property Page kod penceresini açın ve aşağıdaki kodu ekleyin.

       Private Sub PropertyPage_ApplyChanges()
           Dim obj As Variant
           For Each obj In SelectedControls
              obj.Caption = txtCaption
           Next
       End Sub

       Private Sub PropertyPage_SelectionChanged()
          txtCaption = SelectedControls(0).Caption
       End Sub

       Private Sub txtCaption_Change()
          Changed = True
       End Sub

       Bu kodda, ilk yordam yapılan değişiklikleri uygular, ikinci yordam şu andaki
       Caption değerini metin kutusuna alır, son yordam isi Property Page üzerindeki
       Apply butonunun aktif hale gelmesini sağlar.

   5. Property Page tasarım penceresini kapatın, UserControl tasarım penceresini açın.
      Properties penceresinden Property Pages özelliğini kullanarak YBGenel Property Page
      dialog kutusunu kontrol nesnesine ekleyin.
   6. Kontrol nesnesini test etmek için kullanılan frmYBtn formunu açıp Update UserControl
      seçeneği ile kontrol nesnelerini günleyin.
   7. Kontrol nesnelerinden birini seçip, Properties penceresinden (Custom) özelliğini
      kullanarak Property Page dialog kutusunu açın. Caption özelliğini değiştirip OK
      butonuna basın. Kontrol nesnesinin Caption özelliğinin değiştiği görülecektir. Bu işlem
      birden fazla kontrol nesnesinin özelliklerini bir defada değiştirmek için de kullanılabilir.
      Property Page Özellik sayfası olarak türkçeye çevrilebilir.

4. Adımda Property Page (Özellik Sayfası) ilişkilendirme işlemi yapılırken görüldüğü üzere
standart bazı özellik sayfaları bulunmaktadır. Bunları eklemek için tek yapılması gereken
önlerine işaret koymaktır. Bu işlem yapılmadan önce yapılması gereken standart özellik
sayfalarının kullanacağı özelliklerin yaratılmasıdır.


Şimdi Arka Plan Rengini belirleyen bir özellik tanımlayıp bunun için Özellik Sayfası kullanma
işlemini adımlar halinde görelim.

   1. UserControl kod pencersini açın, ArkaRenk diye bir özellik ekleyin ve aşağıdaki kodu
      yazın.

       Public Property Get ARenk() As OLE_COLOR
          ARenk = UserControl.BackColor
       End Property

       Public Property Let ARenk(ByVal yRenk As OLE_COLOR)
          UserControl.BackColor = yRenk
          PropertyChanged "ARenk"
                                               127
       End Property

   2. Sırasıyla InitProperties, ReadProperties ve WriteProperties olaylarına aşağıdaki satırları
      ekleyin.

           * ARenk= RGB(192, 192, 192) (InitProperties)
           * ARenk = PropBag.ReadProperty("ARenk", RGB(192, 192, 192))
           * PropBag.WriteProperty "ARenk", ARenk, RGB(192, 192, 192)

   3. Properties penceresinden Property Pages özelliğini seçip Color standart özellik sayfasını
      seçin.
   4. Deneme formunu açın ve üzerindeki kontrol nesnelerini silin. Çift tıklama ile yeni bir
      kontrol nesnesi ekleyin.
   5. (Custom) özelliğini kullanarak kontrol nesnesinin özellik sayfalarını açın ve özelliklerde
      değişiklik yaparak deneyin.

Böylece artık iki tane yeni özellik ve iki tane Özellik sayfası eklenmiş oldu. Görüldüğü gibi
özellik sayfaları özelliklere değer ekleme sırasında çok kullanışlı bir ortam sunmaktadır.



8.7. Control Interface Wizard Kullanarak Kontrol Yaratma

Şu ana kadar kontrol nesnesi yaratmanın aşamaları adım adım anlatıldı. Kontrol nesnesi yaratma,
özellik, metot ve olay ekleme işlemleri fazla karmaşık olmayan fakat detaylı işlemlerdir. Bu
detaylardan biri unutulduğunda kontrol nesnesi doğru çalışmayabilir.

Kontrol yaratmak için kullanılan Control Interface Wizard, kontrol yaratımının herhangi bir
aşamasında devreye konabilir. Örneğin yukarıda yapıldığı gibi kontrol nesnesinin genel tasarımı
bittikten sonra bazı otomatikleşmiş işlemlerin yapılması için faydalı olabilir. Şimdi yukarıdaki
kontrol nesnesinin iyileştirilmesi, başka özellikler eklenmesi için Control Interface Wizard
kullanımı örneklenecektir.

   1. Önce kontrol nesnesi için tanımlanmış olan olayları silin.
   2. Add-Ins menüsünden Control Interface Wizard seçeneğini seçin.
   3. İlk çıkan dialog kutusunda Font özelliğini seçip yapmadan Next butonuna basın. Çıkan
      dialog kutusuna aşağıdaki nesne olaylarını ve özelliklerini ekleyin.




   4. Next butonuna basın. Çıkan dialog kutusunu kullanarak tanımlanan olay ve özellikleri
      belirli olay veya özelliklerle ilişkilendirin.

       Public Name         Control            Member
       Arenk               (none)

                                              128
   Caption           (none)
   CiftTIK           (none)
   Font              lblCaption         Font
   FontBoyu          lblCaption         FontSize
   ItalikFont        lblCaption         FontItalic
   KoyuFont          lblCaption         FontBold
   Orenk             lblCaption         ForeColor
   Resim             UserControl        Picture
   Secili            UserControl        Enabled
   TIK               (none)

   Burada Arenk, Caption, CiftTIK ve TIK isimleri hiç bir olayla veya özellikle
   ilişkilendirilmemiştir. Bunlar birden fazla kontrol nesnesini ilgilendirmektedir.

5. Next butonuna basın ve daha sonra Finish butonuna basarak işlemi tamamlayın.
6. Projeyi kaydedin. Yeni yaratılan kodda bazı değişiklikler ve yapılması gereken bazı
   eklemeler sözkonusudur. Kodu aşağıdaki gibi değiştirin.

      Option Explicit
      Private ArkaRenk As Long
      Const ISIKLI = &HE0E0E0
      Const GOLGELI = &H808080
      'Event Declarations:
      Event TIK()
      Event CiftTIK()

      Private Sub BASILI()
          ArkaRenk = BackColor
          Line1.BorderColor = ISIKLI
          Line2.BorderColor = GOLGELI
          Line3.BorderColor = ISIKLI
          Line4.BorderColor = GOLGELI
          BackColor = &HFFFFFF - BackColor
      End Sub

      Private Sub SERBEST()
          BackColor = ArkaRenk
          Line1.BorderColor = GOLGELI
          Line2.BorderColor = ISIKLI
          Line3.BorderColor = GOLGELI
          Line4.BorderColor = ISIKLI
      End Sub

      Private Sub UserControl_MouseDown(Button As Integer, Shift As Integer,
      X As Single, Y As Single)
          BASILI
      End Sub
      Private Sub UserControl_MouseUp(Button As Integer, Shift As Integer, X
      As Single, Y As Single)
          SERBEST

                                       129
End Sub

Private Sub lblCaption_MouseDown(Button As Integer, Shift As Integer,
X As Single, Y As Single)
    BASILI
End Sub

Private Sub lblCaption_MouseUp(Button As Integer, Shift As Integer, X
As Single, Y As Single)
    SERBEST
End Sub

Private Sub UserControl_InitProperties()
    Caption = Extender.Name
    ARenk = RGB(192, 192, 192)
End Sub

Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
    Caption = PropBag.ReadProperty("Caption", Extender.Name)
    ARenk = PropBag.ReadProperty("ARenk", RGB(192, 192, 192))
    Secili = PropBag.ReadProperty("Secili", True)
    KoyuFont = PropBag.ReadProperty("KoyuFont", 0)
    ItalikFont = PropBag.ReadProperty("ItalikFont", 0)
    FontADI = PropBag.ReadProperty("FontADI", "Times New
    Roman")
    FontBoyu = PropBag.ReadProperty("FontBoyu", 10)
    ORenk = PropBag.ReadProperty("ORenk", &H80000007)
    Set Resim = PropBag.ReadProperty("Resim", Nothing)
    Set Font = PropBag.ReadProperty("Font", lblCaption.Font)
End Sub

Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
    PropBag.WriteProperty "Caption", Caption, Extender.Name
    PropBag.WriteProperty "ARenk", ARenk, RGB(192, 192, 192)
    PropBag.WriteProperty "Secili", Secili, True
    PropBag.WriteProperty "KoyuFont", KoyuFont, 0
    PropBag.WriteProperty "ItalikFont", ItalikFont, 0
    PropBag.WriteProperty "FontADI", FontADI, "Times New
    Roman"
    PropBag.WriteProperty "FontBoyu", FontBoyu, 10
    PropBag.WriteProperty "ORenk", ORenk, &H80000007
    PropBag.WriteProperty "Resim", Resim, Nothing
    PropBag.WriteProperty "Font", Font, lblCaption.Font
End Sub

Private Sub UserControl_Resize()
    Line1.X1 = ScaleWidth - 20
    Line1.X2 = ScaleWidth - 20
    Line1.Y2 = ScaleHeight
    Line2.Y2 = ScaleHeight
    Line3.X2 = ScaleWidth - 40
    Line3.Y1 = ScaleHeight - 20
                                   130
   Line3.Y2 = ScaleHeight - 20
   Line4.X2 = ScaleWidth - 40
   lblCaption.Move (ScaleWidth - lblCaption.Width) / 2, _
   (ScaleHeight - lblCaption.Height) / 2
End Sub

'DİKKAT! AŞAĞIDAKİ SATIRLARI DEĞİŞTİRMEYİN VEYA
SİLMEYİN …

'MappingInfo=UserControl,UserControl,-1,Enabled
Public Property Get Secili() As Boolean
   Secili = UserControl.Enabled
End Property

Public Property Let Secili(ByVal New_Secili As Boolean)
   UserControl.Enabled() = New_Secili
   PropertyChanged "Secili"
End Property

'DİKKAT! AŞAĞIDAKİ SATIRLARI DEĞİŞTİRMEYİN VEYA
SİLMEYİN …

'MappingInfo=lblCaption,lblCaption,-1,FontBold
Public Property Get KoyuFont() As Boolean
   KoyuFont = lblCaption.FontBold
End Property

Public Property Let KoyuFont(ByVal New_KoyuFont As Boolean)
   lblCaption.FontBold() = New_KoyuFont
   PropertyChanged "KoyuFont"
End Property

'DİKKAT! AŞAĞIDAKİ SATIRLARI DEĞİŞTİRMEYİN VEYA
SİLMEYİN …

'MappingInfo=lblCaption,lblCaption,-1,FontItalic
Public Property Get ItalikFont() As Boolean
   ItalikFont = lblCaption.FontItalic
End Property

Public Property Let ItalikFont(ByVal New_ItalikFont As Boolean)
   lblCaption.FontItalic() = New_ItalikFont
   PropertyChanged "ItalikFont"
End Property

'DİKKAT! AŞAĞIDAKİ SATIRLARI DEĞİŞTİRMEYİN VEYA
SİLMEYİN …
'MappingInfo=lblCaption,lblCaption,-1,FontName
Public Property Get FontADI() As String
   FontADI = lblCaption.FontName
End Property


                                  131
Public Property Let FontADI(ByVal New_FontADI As String)
   lblCaption.FontName() = New_FontADI
   PropertyChanged "FontADI"
End Property

'DİKKAT! AŞAĞIDAKİ SATIRLARI DEĞİŞTİRMEYİN VEYA
SİLMEYİN …

'MappingInfo=lblCaption,lblCaption,-1,FontSize
Public Property Get FontBoyu() As Single
   FontBoyu = lblCaption.FontSize
End Property

Public Property Let FontBoyu(ByVal New_FontBoyu As Single)
   lblCaption.FontSize() = New_FontBoyu
   PropertyChanged "FontBoyu"
End Property

'DİKKAT! AŞAĞIDAKİ SATIRLARI DEĞİŞTİRMEYİN VEYA
SİLMEYİN …

'MappingInfo=lblCaption,lblCaption,-1,ForeColor
Public Property Get ORenk() As OLE_COLOR
   ORenk = lblCaption.ForeColor
End Property

Public Property Let ORenk(ByVal New_ORenk As OLE_COLOR)
   lblCaption.ForeColor() = New_ORenk
   PropertyChanged "ORenk"
End Property

'DİKKAT! AŞAĞIDAKİ SATIRLARI DEĞİŞTİRMEYİN VEYA
SİLMEYİN …
'MappingInfo=UserControl,UserControl,-1,Picture
Public Property Get Resim() As Picture
   Set Resim = UserControl.Picture
End Property

Public Property Set Resim(ByVal New_Resim As Picture)
   Set UserControl.Picture = New_Resim
PropertyChanged "Resim"
End Property

Private Sub lblCaption_Click()
   RaiseEvent TIK
End Sub

Private Sub lblCaption_DblClick()
    RaiseEvent CiftTIK
End Sub

Private Sub UserControl_Click()
                                    132
             RaiseEvent TIK
          End Sub

          Private Sub UserControl_DblClick()
              RaiseEvent CiftTIK
          End Sub

          Public Property Get ARenk() As OLE_COLOR
             ARenk = ArkaRenk
          End Property

          Public Property Let ARenk(ByVal New_ARenk As OLE_COLOR)
             ArkaRenk = New_ARenk
             PropertyChanged "ARenk"
          End Property

          Public Property Get Caption() As String
             Caption = lblCaption.Caption
          End Property

          Public Property Let Caption(ByVal New_Caption As String)
          lblCaption.Caption = New_Caption
              PropertyChanged "Caption"
          End Property

           'DİKKAT! AŞAĞIDAKİ SATIRLARI DEĞİŞTİRMEYİN VEYA
           SİLMEYİN …

          'MappingInfo=lblCaption,lblCaption,-1,Font
          Public Property Get Font() As Font
             Set Font = lblCaption.Font
          End Property

          Public Property Set Font(ByVal New_Font As Font)
             Set lblCaption.Font = New_Font
             PropertyChanged "Font"
          End Property


   Bu kodda yapılan değişiklikler, ReadProperties ve WriteProperties olay yordamları ile
   var olan özellik yordamlarında yapılmıştır. Koda yapılan eklemeler ise olayların
   yaratılması için eklenen kodlardır.

Kontrol nesnesini test etmeden önce Properties penceresinden Property Pages özelliğini
kullanarak var olan tüm standart özellik sayfalarını seçin.
FrmYBtn formunu seçin. Update User Controls seçeneğini kullanarak kontrol nesnelerini
günleyin. (Custom) özelliğini kullanarak özellik sayfalarını çıkarın ve özellikleri değiştirin.
Yeni butonun çalışmasının tam olduğu görülmektedir. Şimdi yapılması gereken bu butonun
başka yerlere taşınmasını sağlamaktır.




                                             133
8.8. Kontrol Nesnesinin Derlenmesi ve Dağıtılması

Kontrol nesnesini kullanıma hazır hale getirmeden önce bir kaç ekleme daha yapmak
gerekmektedir.

   1. Önce kontrol nesnesinin Araç kutusunda görünecek olan bitmap resmini belirleyelim.
      Bunun için yButon nesnesinin ToolBox Birmap özelliğini kullanarak bir resim seçmek
      yeterlidir. Burada;
   2. devstudio\vb\graphics\bitmap\assorted\DIAMONDS.BMP resmini seçin.
   3. File menüsünden Make YeniButon.ocx seçeneğini seçin. YButon nesnesi derlenecek ve
      bir .OCX dosyası oluşacaktır. Bu kontrol nesnesinin çalışır halidir.
   4. Derleme işlemi bittikten sonra YeniButon projesini kaldırın. Kalan btnTest projesini
      şimdi deneyin ve kontrol nesnesinin doğru bir şekilde çalıştığını görün.
   5. Standard EXE türünde yeni bir proje yaratın. Components dialog kutusunun en altında
      Yeni ActiveX Butonu yazısının yanına işaret koyun ve bu dialog kutusunu kapatın.
   6. Araç kutusunda görülen kırmızı, elmas biçimindeki yeni butonu seçin ve form üzerine
      yerleştirin. Sorunsuz bir şekilde yeni butonun çalıştığı gözlenecektir. Burada yButon
      kontrol nesnesinin olaylarını da kullanmak mümkündür.
   7. Bunu denemek için aşağıdaki kodu forma ekleyin.

       Option Explicit
       Private Sub yButon1_TIK()
          CurrentY = 3000
          Print "yButon1 nesnesi TIKLANDI"
       End Sub

       Kontrol nesnesi artık tam çalışır ve dağıtılmaya hazır durumdadır. Kontrol
       nesnesinin dağıtımını yapmak için Application Setup Wizard programı kullanılır.
       Bu sihirbazı kullanarak kontrolü ve gereksindiği dosyaları bir paket haline
       getirmek mümkündür.

Bir kontrol nesnesini Lisanslı yapmak için Project menüsünden Properties seçeneğini seçin.
Çıkan dialog kutusundan Require Licence Key seçeneğini seçin.

Lisans özelliği eklenmiş bir kontrol nesnesi için dağıtım paketi hazırlanırken, .VBL diye bir
dosya yaratılır. Bu dosya olmadan kontrol nesnesi çalışamaz duruma getirilir.



8.9. Veritabanı İle İlişkilendirilebilir Kontrol Nesneleri Yaratma

Bu örnek için daha önce kullandığımız PERSONEL veritabanının MESLEKLER tablosuna bir
kaç tane tutanak ekleyin.

Aşağıdaki adımları izleyin.

   1. Yeni bir ActiveX kontrol projesi yaratın. UserControl formu üzerine bir ComboBox
      yerleştirin aşağıdaki isimlendirmeyi kullanın.
   2. Project1 dbComboProj
      UserControl dbCombo
      ComboBox cmbDeger

                                             134
3. Control Interface Wizard sihirbazını başlatın. 1. Aşamada, Selected Names listesine
   Change, ListCount, ListIndex, Style ve Text adlarını sol taraftan aktarın.
4. 2. Aşamada yeni yaratılacak özelliklerin ve metotların tanımlaması yapılmalıdır. Bunlar
   aşağıda belirtilmiştir.

   Property objVT
   Property strAlan
   Property strTablo
   Method Yukle

5. 3. Aşamada seçilen kontrol nesnesi elemanlarının ilişkilendirilmesi yapılır. Listedeki
   isimlerden, BackStyle, BorderStyle, MouseDown, MouseMove, MouseUp isimlerini
   UserControl nesnesinin ilgili isimleri ile, yeni tanımlanmış olanların dışındaki tüm
   isimleri cmbDeger nesnesinin ilgili isimleri ile ilişkilendirin. Daha sonra Next butonuna
   basın.
6. 4. Aşamada yeni eklenen nesne elemanlarının özellikleri belirtilir. Bu özellikleri
   aşağıdaki gibi belirtin.

     Eleman        Veri Türü        Çalışma zamanı          Tasarım zamanı
     objVT         Object           Write Only              Not Available
     strAlan       String           Read/Write              Read/Write
     strTablo      String           Read/Write              Read/Write

7. Finish butonuna basın ve Control Interface Wizard sihirbazını kapatın. Yaratılmış koda
   aşağıdaki olay yordamını ekleyin.

   Private Sub UserControl_Resize()
          Height = cmbDeger.Height
          cmbDeger.Top = 0
          cmbDeger.Left = 0
          cmbDeger.Width = ScaleWidth
   End Sub

8. Kontrol nesnesini test etmek için TestProj adında ve içinde frmTestProj adlı bir formu
    olan bir proje ekleyin.
9. Projeyi test edin. Yeniden boyutlandırarak Resize olayının çalıştığını görün.
10. Kontrol nesnesinin Text özelliğini Data Bound yani veri ile ilişkili bir özellik haline
    getirelim. Bunun için, UserControl tasarım penceresini açın.
11. Tools menüsünden Procedure Attributes seçeneğini seçin. Çıkan dialog kutusundan
    Advanced butonuna basın. Çıkan dialog kutusunda Data Binding kısmındaki tüm
    seçenekleri işaretleyin.
12. Property Let Text özellik yordamını aşağıdaki gibi değiştirin.

     Public Property Let Text(ByVal New_Text As String)
           If CanPropertyChange("Text") Then
               cmbDeger.Text() = New_Text
               PropertyChanged "Text"
           End If
     End Property



                                          135
13. PropertyChanged "Text" kodunu cmbDeger_Change ve cmbDeger_Click olaylarına
    ekleyin.
14. Property Set objVT özellik yordamını aşağıdaki kodu yazın.

     Public Property Set objVT(ByVal New_objVT As Object)
           Set m_objVT = New_objVT
           PropertyChanged "objVT"
           If "" <> strAlan And "" <> strTablo Then Call Yukle
     End Property

   Bu kod eğer tablo ve alan adı belirtilmemişse yükleme işlemini yapmayı engeller.

15. Yukleme işlemi için Yukle metodunu aşağıdaki gibi değiştirin.

   Public Sub Yukle()
        Dim strSql As String
        Dim rs As Recordset
        cmbDeger.Clear
        strSql = "SELECT " & strAlan & " FROM " & strTablo & _
        " ORDER BY " & strAlan
        Set rs = objVT.OpenRecordset(strSql, _
        vbRSTypeSnapShot, dbForwardOnly)
        Do While Not rs.EOF
              cmbDeger.AddItem "" & rs(strAlan)
              rs.MoveNext
        Loop
        rs.Close
   End Sub

   Burada yazılan kod verilen alandaki tüm değerleri Combo Box içine ekler.

16. Şimdi TestProj projesindeki frmTestProj formuna bir Data Control nesnesi ekleyin.

17. Properties penceresinden form üzerindeki dbCombo1 nesnesinin strAlan özelliğine
    “MADI”, strTablo özelliğine “MESLEKLER” değerlerini atayın ve form içine aşağıdaki
    kodu ekleyin.

   Private Sub Form_Load()
          Data1.DatabaseName = App.Path & "\personel.mdb"
          Data1.Refresh
          Set dbCombo1.objVT = Data1.Database
   End Sub

   Bu kodda yapılan dbCombo1 nesnesinin objVT özelliğine Data1 nesnesinin
   Database özelliğini aktarmaktır. Bu yapıldığında dbCombo1 nesnesinin
   Property Set objVT özellik yordamı çalışacak ve tablodaki meslek isimleri
   Combo Box içine yerleştirilecektir.




                                          136
Programın çalışması aşağıdaki gibi olacaktır.




Control nesnesinin tam kodu aşağıdaki gibidir.

       Option Explicit
       'Default Property Values:
       Const m_def_strAlan = ""
       Const m_def_strTablo = ""
       'Property Variables:
       Dim m_objVT As Object
       Dim m_strAlan As String
       Dim m_strTablo As String
       'Event Declarations:
       Event Click() 'MappingInfo=cmbDeger,cmbDeger,-1,Click
       Event DblClick() 'MappingInfo=cmbDeger,cmbDeger,-1,DblClick
       Event KeyDown(KeyCode As Integer, Shift As Integer)
       'MappingInfo=cmbDeger,cmbDeger,-1,KeyDown
       Event KeyPress(KeyAscii As Integer) 'MappingInfo=cmbDeger,cmbDeger,-
       1,KeyPress
       Event KeyUp(KeyCode As Integer, Shift As Integer)
       'MappingInfo=cmbDeger,cmbDeger,-1,KeyUp
       Event MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
       'MappingInfo=UserControl,UserControl,-1,MouseDown
       Event MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
       'MappingInfo=UserControl,UserControl,-1,MouseMove
       Event MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
       'MappingInfo=UserControl,UserControl,-1,MouseUp
       Event Change() 'MappingInfo=cmbDeger,cmbDeger,-1,Change

              'DİKKAT! AŞAĞIDAKİ SATIRLARI DEĞİŞTİRMEYİN VEYA
              SİLMEYİN …
       'MappingInfo=cmbDeger,cmbDeger,-1,BackColor
       Public Property Get BackColor() As OLE_COLOR
          BackColor = cmbDeger.BackColor
       End Property

       Public Property Let BackColor(ByVal New_BackColor As OLE_COLOR)
          cmbDeger.BackColor() = New_BackColor
                                                 137
   PropertyChanged "BackColor"
End Property
      'DİKKAT! AŞAĞIDAKİ SATIRLARI DEĞİŞTİRMEYİN VEYA
      SİLMEYİN …
'MappingInfo=cmbDeger,cmbDeger,-1,ForeColor
   Public Property Get ForeColor() As OLE_COLOR
   ForeColor = cmbDeger.ForeColor
End Property

Public Property Let ForeColor(ByVal New_ForeColor As OLE_COLOR)
   cmbDeger.ForeColor() = New_ForeColor
   PropertyChanged "ForeColor"
End Property

       'DİKKAT! AŞAĞIDAKİ SATIRLARI DEĞİŞTİRMEYİN VEYA
       SİLMEYİN …
'MappingInfo=cmbDeger,cmbDeger,-1,Enabled
Public Property Get Enabled() As Boolean
   Enabled = cmbDeger.Enabled
End Property

Public Property Let Enabled(ByVal New_Enabled As Boolean)
   cmbDeger.Enabled() = New_Enabled
   PropertyChanged "Enabled"
End Property

       'DİKKAT! AŞAĞIDAKİ SATIRLARI DEĞİŞTİRMEYİN VEYA
       SİLMEYİN …
'MappingInfo=cmbDeger,cmbDeger,-1,Font
Public Property Get Font() As Font
   Set Font = cmbDeger.Font
End Property

Public Property Set Font(ByVal New_Font As Font)
   Set cmbDeger.Font = New_Font
   PropertyChanged "Font"
End Property

       'DİKKAT! AŞAĞIDAKİ SATIRLARI DEĞİŞTİRMEYİN VEYA
       SİLMEYİN …
'MappingInfo=UserControl,UserControl,-1,BackStyle
Public Property Get BackStyle() As Integer
   BackStyle = UserControl.BackStyle
End Property

Public Property Let BackStyle(ByVal New_BackStyle As Integer)
   UserControl.BackStyle() = New_BackStyle
   PropertyChanged "BackStyle"
End Property

       'DİKKAT! AŞAĞIDAKİ SATIRLARI DEĞİŞTİRMEYİN VEYA
       SİLMEYİN …
                                     138
'MappingInfo=UserControl,UserControl,-1,BorderStyle
Public Property Get BorderStyle() As Integer
   BorderStyle = UserControl.BorderStyle
End Property

Public Property Let BorderStyle(ByVal New_BorderStyle As Integer)
   UserControl.BorderStyle() = New_BorderStyle
   PropertyChanged "BorderStyle"
End Property

       'DİKKAT! AŞAĞIDAKİ SATIRLARI DEĞİŞTİRMEYİN VEYA
       SİLMEYİN …
'MappingInfo=cmbDeger,cmbDeger,-1,Refresh
Public Sub Refresh()
   cmbDeger.Refresh
End Sub

Private Sub cmbDeger_Click()
   RaiseEvent Click
   PropertyChanged "Text"
End Sub

Private Sub cmbDeger_DblClick()
   RaiseEvent DblClick
End Sub

Private Sub cmbDeger_KeyDown(KeyCode As Integer, Shift As Integer)
   RaiseEvent KeyDown(KeyCode, Shift)
End Sub

Private Sub cmbDeger_KeyPress(KeyAscii As Integer)
   RaiseEvent KeyPress(KeyAscii)
End Sub

Private Sub cmbDeger_KeyUp(KeyCode As Integer, Shift As Integer)
   RaiseEvent KeyUp(KeyCode, Shift)
End Sub

Private Sub UserControl_MouseDown(Button As Integer, Shift As Integer, X As
Single, Y As Single)
   RaiseEvent MouseDown(Button, Shift, X, Y)
End Sub

Private Sub UserControl_MouseMove(Button As Integer, Shift As Integer, X As
Single, Y As Single)
   RaiseEvent MouseMove(Button, Shift, X, Y)
End Sub

Private Sub UserControl_MouseUp(Button As Integer, Shift As Integer, X As
Single, Y As Single)
   RaiseEvent MouseUp(Button, Shift, X, Y)


                                     139
End Sub

Private Sub cmbDeger_Change()
   PropertyChanged "Text"
End Sub

       'DİKKAT! AŞAĞIDAKİ SATIRLARI DEĞİŞTİRMEYİN VEYA
       SİLMEYİN …
'MappingInfo=cmbDeger,cmbDeger,-1,ListCount
Public Property Get ListCount() As Integer
   ListCount = cmbDeger.ListCount
End Property

       'DİKKAT! AŞAĞIDAKİ SATIRLARI DEĞİŞTİRMEYİN VEYA
       SİLMEYİN …
'MappingInfo=cmbDeger,cmbDeger,-1,ListIndex
   Public Property Get ListIndex() As Integer
   ListIndex = cmbDeger.ListIndex
End Property

Public Property Let ListIndex(ByVal New_ListIndex As Integer)
   cmbDeger.ListIndex() = New_ListIndex
   PropertyChanged "ListIndex"
End Property

       'DİKKAT! AŞAĞIDAKİ SATIRLARI DEĞİŞTİRMEYİN VEYA
       SİLMEYİN …
'MappingInfo=cmbDeger,cmbDeger,-1,Style
Public Property Get Style() As Integer
   Style = cmbDeger.Style
End Property

       'DİKKAT! AŞAĞIDAKİ SATIRLARI DEĞİŞTİRMEYİN VEYA
       SİLMEYİN …
'MappingInfo=cmbDeger,cmbDeger,-1,Text
Public Property Get Text() As String
   Text = cmbDeger.Text
End Property

Public Property Let Text(ByVal New_Text As String)
   If CanPropertyChange("Text") Then
       cmbDeger.Text() = New_Text
       PropertyChanged "Text"
   End If
End Property

Public Property Get objVT() As Object
   Set objVT = m_objVT
End Property

Public Property Set objVT(ByVal New_objVT As Object)
   Set m_objVT = New_objVT
                                        140
   PropertyChanged "objVT"
   If "" <> strAlan And "" <> strTablo Then Call Yukle
End Property

Public Property Get strAlan() As String
   strAlan = m_strAlan
End Property

Public Property Let strAlan(ByVal New_strAlan As String)
   m_strAlan = New_strAlan
   PropertyChanged "strAlan"
End Property

Public Property Get strTablo() As String
   strTablo = m_strTablo
End Property

Public Property Let strTablo(ByVal New_strTablo As String)
   m_strTablo = New_strTablo
   PropertyChanged "strTablo"
End Property

Public Sub Yukle()
   Dim strSql As String
   Dim rs As Recordset
   cmbDeger.Clear
   strSql = "SELECT " & strAlan & " FROM " & strTablo & _
   " ORDER BY " & strAlan
   Set rs = objVT.OpenRecordset(strSql, _
   vbRSTypeSnapShot, dbForwardOnly)
   Do While Not rs.EOF
       cmbDeger.AddItem "" & rs(strAlan)
       rs.MoveNext
   Loop
   rs.Close
End Sub

'Initialize Properties for User Control
Private Sub UserControl_InitProperties()
     m_strAlan = m_def_strAlan
     m_strTablo = m_def_strTablo
End Sub

'Load property values from storage
Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
   cmbDeger.BackColor = PropBag.ReadProperty("BackColor",
   &H80000005)
   cmbDeger.ForeColor = PropBag.ReadProperty("ForeColor",
   &H80000008)
   cmbDeger.Enabled = PropBag.ReadProperty("Enabled", True)
   Set Font = PropBag.ReadProperty("Font", Ambient.Font)
   UserControl.BackStyle = PropBag.ReadProperty("BackStyle", 1)
                                      141
         UserControl.BorderStyle = PropBag.ReadProperty("BorderStyle", 0)
         cmbDeger.ListIndex = PropBag.ReadProperty("ListIndex", -1)
         cmbDeger.Text = PropBag.ReadProperty("Text", "Combo1")
         Set m_objVT = PropBag.ReadProperty("objVT", Nothing)
         m_strAlan = PropBag.ReadProperty("strAlan", m_def_strAlan)
      m_strTablo = PropBag.ReadProperty("strTablo", m_def_strTablo)
End Sub

Private Sub UserControl_Resize()
    Height = cmbDeger.Height
    cmbDeger.Top = 0
    cmbDeger.Left = 0
    cmbDeger.Width = ScaleWidth
End Sub

'Write property values to storage
Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
    Call PropBag.WriteProperty("BackColor", cmbDeger.BackColor, &H80000005)
    Call PropBag.WriteProperty("ForeColor", cmbDeger.ForeColor, &H80000008)
    Call PropBag.WriteProperty("Enabled", cmbDeger.Enabled, True)
    Call PropBag.WriteProperty("Font", Font, Ambient.Font)
    Call PropBag.WriteProperty("BackStyle", UserControl.BackStyle, 1)
    Call PropBag.WriteProperty("BorderStyle", UserControl.BorderStyle, 0)
    Call PropBag.WriteProperty("ListIndex", cmbDeger.ListIndex, -1)
    Call PropBag.WriteProperty("Text", cmbDeger.Text, "Combo1")
    Call PropBag.WriteProperty("objVT", m_objVT, Nothing)
    Call PropBag.WriteProperty("strAlan", m_strAlan, m_def_strAlan)
    Call PropBag.WriteProperty("strTablo", m_strTablo, m_def_strTablo)
End Sub




                                          142
9. ACTIVEX BILEŞENLERİNİN WEB SAYFALARINDA KULLANILMASI

9.1. Giriş
İnternet teknolojisi, artan derecede karmaşık ve programlama yeteneğini gösterme konusunda bir
çok farklı yol sunmaktadır. Visual Basic ile internet için programlar yapabilmenin yanısıra,
internet teknolojisini kullanan karmaşık uygulamalar gerçekleştirme olanağı vardır.

Uygulama geliştirme ortamı olarak İnternet
İnternet, global, merkezileşmemiş ve TCP/IP standardına dayanan bilgisayar ağıdır. İnternet
teknolojisini yerel ağlar için de kullanmak mümkündür. İnternet için ActiveX bileşeni
hazırlarken biraz farklılıklar vardır ama yine metotlar, özellikler ve olaylar sözkonusudur.

İnternet bize daha rahat bir çalışma ortamı içinde program yapabilme olanağı sağlar.

Örneğin,
    Gerektiğinde yüklenebilen bileşenler programın yenilenmesini otomatikleştirir.
    Kolay uyum sağlama olanağı ile internet veya intranet için aynı programlar yapabilme
      olanağı verir.

İnternet uygulama geliştirme ortamı olarak düşünüldüğünde bir istemci/sunumcu ilişkisi vardır.
Burada istemci/sunumcu kavramları aktif ve statik olarak vardır. Aktif kesimler sunumcu görevi
görür ve dinamik bir yapıya sahiptir. Statik kesim ise pasif olarak işler.

Bu iletişimin
            Statik-statik
            Statik-aktif
            Aktif-statik
            Aktif-Aktif
olmak üzere 4 farklı biçimi vardır.

İnternetin iki ucundaki programların iletişimi olan bu iletişim aradaki bilgi alışverişinin düzeyine
göre sınıflandırılmıştır.

ActiveX bileşenlerinin Web sayfalarında kullanılması
ActiveX bileşenleri kullanıldığında web sayfalarının özellikleri önemli ölçüde artar.

HTML ve VBScript kullanırken ActiveX kontrol nesnelerini HTML sayfalarına eklemek
mümkündür. ActiveX kontrol nesneleri HTML sayfalarının işlevlerini artırır.

Bir ActiveX kontrol nesnesinin işlevi HTML ve VBScript kullanarak da gerçekleştirilebilir.


9.2. Kontrol Nesnelerinin Yüklenmesi
Bu bölümde kontrol nesnelerine internet özelliklerinin eklenmesi ve kontrol nesnelerinin
yüklenmesi (downloading) konu edilecektir.

Visual Basic ile yaratılmış ActiveX kontrol nesneleri zamanuyumsuz özellik değeri yüklemeyi
destekler. Örneğin bitmap içerebilecek bir Resim özelliği, UserControl nesnesinin Hyperlink
özelliği, belirtilen bir URL adresine bir tarayıcı yardımıyla geçişi sağlar.


                                                143
Bu özellikler kontrol nesnesi, bu tür işlemleri destekleyen bir form içine konduğunda geçerli
olabilir.

Bir uygulama gerçekleştirirken kontrol nesnelerinin özelliklerini hem zamanuyumsuz, hem de
PropBag kullanarak yüklemek gerekebilir.

Zamanuyumsuz Yükleme
Bir kontrol nesnesinin bir özelliğini zamanuyumsuz olarak yüklemek için AsyncRead metodu
kullanılır. Bu metot, bir kontrol nesnesi bir form üzerine yerleştirildikten sonra herhangi bir
yordam içinden çağrılabilir.

Bu metot yordamdan dönüşün hemen, özellik değerinin yüklenmesinin ise geri planda olmasını
sağlar. Kontrol nesnesinin özelliğinin yüklenmesi bittiğinde AsyncReadComplete olayı meydana
gelir.

Şimdi zamanuyumsuz yükleme özelliğini kavramak için aşağıdaki örneği inceleyin.
   1. ActiveX Control türünden yeni bir proje yaratın. İsmini Resim olarak değiştirin.
   2. Araç kutusundaki PictureBox kontrol nesnesini çift tıklayıp UserControl nesnesi içine bir
       PictureBox kontrol nesnesi yerleştirin. Aşağıdaki isimlendirmeyi kullanın.
       Project Name Resim
       UserControl Name ctlRes
       PictureBox Name res
   3. Aşağıdaki kodu UserControl nesnesi içine yazın.

       Option Explicit
          Dim mKaynak As String
          Property Get resim() As Picture
              Set resim = res.Picture
          End Property

          Property Let resim(ByVal deger As Picture)
             Set res.Picture = deger
             PropertyChanged "resim"
          End Property

          Property Set resim(ByVal deger As Picture)
             Set res.Picture = deger
             PropertyChanged "resim"
          End Property

          Property Let uResim(strDeger As String)
             mKaynak = strDeger
             If UserControl.Ambient.UserMode And Len(strDeger) Then
                 AsyncRead strDeger, vbAsyncTypePicture, "uResim"
             End If
             PropertyChanged "uResim"
          End Property

          Property Get uResim() As String
             uResim = mKaynak
          End Property


                                             144
       Private Sub res_Resize()
           If res.Picture <> 0 Then
                UserControl.Width = res.Width
                UserControl.Height = res.Height
           End If
       End Sub

       Private Sub UserControl_AsyncReadComplete(AsyncProp As AsyncProperty)
           Select Case AsyncProp.PropertyName
               Case "uResim" Set resim = AsyncProp.Value
           End Select
       End Sub

       Private Sub UserControl_InitProperties()
           Set resim = Nothing
       End Sub

       Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
           Set resim = PropBag.ReadProperty("resim", Nothing)
       End Sub

       Private Sub UserControl_Resize()
           If res.Picture = 0 Then res.Move 0, 0, ScaleWidth, ScaleHeight
       End Sub

       Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
           PropBag.WriteProperty "resim", resim, Nothing
       End Sub

   Bu kod ile UserControl nesnesi için resim ve uResim adlı iki özellik eklenmiştir. Bu
   özellikler PictureBox kontrol nesnesinin göstereceği resim ve resim dosyasının adını
   belirlemeye yarar.

4. Projeyi test etmek için yeni bir proje ekleyin.
5. UserControl tasarım penceresini kapatın. Form üzerine araç kutusu üzerindek yeni
   kontrol nesnesine ait işareti çift tıklayarak bir ctlRes kontrol nesnesi yerleştirin.
6. Aşağıdaki kodu forma ekleyin

   Option Explicit
      Private Sub Form_Load()
          ctlRes1.uResim = "file://" & App.Path & "\clouds.bmp"
      End Sub

      Private Sub Form_Paint()
          ctlRes1.Left = 0
          ctlRes1.Top = 0
          Width = ctlRes1.Width + 100
          Height = ctlRes1.Height + 400
   End Sub

7. Projeyi kaydedin ve çalıştırın.


                                          145
HyperLink nesnesi
HyperLink nesnesi UserControl nesnesinin HyperLink özelliği aracılığıyla erişilen bir nesnedir.
Bu nesnenin üç tane metodu vardır. Bunlar GoBack, GoForward ve NavigateTo metotlarıdır. Bu
metotlar, ancak Web browser gibi görev yapan bir nesne içinde iken geçerli olur. Diğer
durumlarda bu metotlar ihmal edilir.

Örneğin bir form üzerine içine aşağıdaki kod olan bir UserControl nesnesi eklendiğinde Internet
Explorer kullanılarak belirtilen HTML dosyası açılır.

Private Sub UserControl_Click()
        Hyperlink.NavigateTo "c:\windows\desktop\faq.htm"
End Sub


9.3. Kontrol Nesneleri İçin Makro (Script) Hazırlama
Bir HTML sayfasında kontrol nesnesi <OBJECT> ve </OBJECT> yazıları arasında belirtilir.
HTML dosyası işlenirken, kontrol nesnesi yaratılır ve yeri belirlenir. Bu ifade eğer <PARAM
NAME> ile başlayan ifadeler içeriyorsa, burada belirtilen özellikler kontrol nesnesinin
ReadProperties olayına, standart PropBag nesnesi kullanılarak aktarılır.

HTML dosyası aktif hale geldikten sonra, nesne olayları ile ilişkilendirimiş olaylar kullanılarak
da nesne özelliklerinin değerleri değiştirilebilir.

Application Setup Wizard programı kontrol nesneleri için internet setup programları oluşturmayı
kolay hale getirir.

Visual Basic kontrolleri, sayısal imza, güvenli yaratma ve güvenli makro oluşturma özelliklerini
destekler.

Visual Basic makrosu kullanarak kontrol nesnesinin web sayfasında kullanılmasına örnek olarak
aşağıdaki HTML kodu verilebilir.

<title></title>
    </head>
    <body>
    <p><object id="ctlRes"
    classid="clsid:9FBCEE2D-03C7-11D2-A252-8CBC08C10000"
    codebase="Resim.CAB#version=1,0,0,0" align="baseline" border="0"
    width="193" height="150"><param name="uResim"
    value="c:\clouds.bmp"></object></p>
    <p><input type="button" name="cmdAc" value="AC"> <script
    language="VBScript"><!--
    Sub cmdAc_Click
    ctlRes.uResim="file://c:\clouds.bmp"
    End Sub
    --></script> </p>
    </body>
</html>




                                              146
9.4. Güvenlik
Kontrol nesneleri HTML sayfalarında kullanılırken, kontrol nesnelerinin bu sayfayı ziyaret
edenlerden saklanması, izinsiz olarak kontrol nesnelerinin kullanılması engellenmelidir. Bunun
için:
     Sayısal imzalar, kontrol nesnesi kullanıcının sisteminde zararlara yol açtığında kontrol
       nesnesini yaratan kişiye ulaşmak için bir yol sunar. Sayısal imzalar Setup Wizard
       kullanılarak yaratılabilir.
     Kontrol nesnesini makrolar için güvenli olarak işaretlemek, kullanıcı bilgisayarında
       herhangi bir zarara yol açmayacağını (makro içinde kullanılarak) garantilemek için
       kullanılır. Böylece kontrol nesnesini web sayfalarında kullanan bir kullanıcının web
       sayfasını görüntüleyen başka kullanıcıların bilgisayarlarına zarar vermesi engellenmiş
       olur.

Kontrol nesnesinin yaratıcısı olarak onun kötü amaçlarla kullanımını engellemek de bize
düşmektedir.
   Aşağıdaki işlemlere izin veren kontrol nesneleri makrolar için güvenli değildir:
              Bir makro tarafından sağlanan bir isimle bir kütük yaratma.
              Bir makro tarafından sağlanan bir isimdeki dosyayı kullanıcının hard diskinden
               okuma.
              Windows Registry dosyasına bilgi ekleme.
              Windows Registry dosyasından bilgi okuma.
              Makro tarafından sağlanan bilgilere dayanarak bir Windows API fonksiyonu
               çağırma.
              Makro tarafından sağlanan bir bilgiye dayanarak dış nesneler yaratma ve onları
               yönetme.

Onu başkalarının kullanmasına izin vermeden önce bir kontrol nesnesinin makrolar için güvenli
olup olmadığını test etmenin en iyi yolu, kontrol nesnesinin tüm özellik metot ve olayları ile
erişilen tüm dosyalar, Registry elemanları ve WinAPI fonksiyonlarını bir çizelge halinde
hazırlamaktır.

Daha sonra bu çizelge dikkatle incelenmelidir.

      Kontrol nesnesinin güvenli olarak yaratılabilmesi nesne yaratılırken kullanıcı
       bilgisayarına zarar gelmeyeceğinin garanti edilmesi demektir.
       Güvenli yaratılabilme özelliğine sahip olmayan kontrol nesneleri, kötü niyetli web
       tasarımcıları tarafından başkalarının sistemlerine zarar vermek amacıyla
       kullanılabilir.
       Bu tür işlemleri engellemenin en iyi yolu kontrol nesnesinin özelliklerinin alabileceği
       tüm değerlerin bir ön kontrolünün yapılması ve uygun olmayan değerlerin özelliklere
       atanmasının engellenmesidir.




                                                 147
10. ACTIVEX DOKÜMANLARININ KULLANILMASI

10.1. Giriş

Visual Basic UserDocument denilen ve başka nesneleri barındıran bir nesne türü sağlar. Bu
nesne Internet Explorer ile görülebilir web VBD uzantılı dökümanlar hazırlama olanağı sağlar.

UserDocument nesnesi tıpkı bir form gibidir. Kontrol nesnelerini içerebilir, mesaj kutuları
gösterebilir, verileri işleyebilir ve başka bileşenleri çağırabilir. Formlardan önemli bazı
özellikleriyle ayrılır.

      UserDocument nesnesinin verileri uygulamanın diğer kesimlerinden hazır olarak
       kullanılamazlar.
      UserDocument içeren uygulamalar Visual Basic ile test edilemezler, test etmek için
       Internet Explorer programına ihtiyaç duyarlar.
      Derlenmiş uygulamalar bir HTM dosyası aracılığıyla başlatılmalıdır. Bu dosya
       dokümanın içerdiği bileşenlerin yüklenmesini sağlar. Dokümanları bu dosya olmadan
       görmek mümkün değildir.

10.2. Activex Doküman Projesi

Bir ActiveX doküman projesi için ilk yapılması gereken bir UserDocument nesnesi çıkarmak ve
içine tıpkı normal uygulamalar için yapıldığı gibi kontrol nesneleri koyup bunlara işlev
kazandırmaktır.
Şimdi bir ActiveX dokümanı hazırlamayı adımlar halinde gösterelim.
    1. ActiveX Document EXE türünden bir proje yaratın. Proje ismini prjBilgi ve
        UserDocument nesnesinin ismini Bilgi olarak değiştirin.
    2. Aşağıdaki nesneleri form üzerine ekleyin. Görünümü aşağıda belirtilfiği gibi olsun.

       TextBox Text1 (controlarray 0-5)
       CommandButton Command1 “Kaydet”




   3. Yeni bir class modeule ekleyin ve aşağıdaki kodu ekleyin. İsmini clsBilgi yapın.

       Public adSoyad As String
       Public dyer As String
                                             148
       Public Adres As String
       Public semt As String
       Public Sehir As String
       Public pkod As String

   4. Yeni bir module ekleyin ve aşağıdaki kodu Ekleyin. İsmini mdlKisi yapın.

       Public kisi As New clsBilgi


10.3. Çoklu Doküman Kullanımı
    1. Yeni bir User Document ekleyin. Bu doküman girilen bilgilerin onaylanması için
       kullanılacaktır. İsmini Onay olarak değiştirin. İçine Label nesnelerinden oluşan bir
       controlarray ve iki tane de CommandButton yerleştirin. Görünümü aşağıdaki gibi olsun.




    2. Projeyi kaydedin.
    3. Bilgi adlı userdocument nesnesine aşağıdaki kodu ekleyin.

       Dim Onay As String
       Private Sub Command1_Click()
          kisi.adSoyad = Text1(0)
          kisi.dyer = Text1(1)
          kisi.Adres = Text1(2)
          kisi.semt = Text1(3)
          kisi.Sehir = Text1(4)
          kisi.pkod = Text1(5)
          Onay = "d:\devstudio\vb\onay.vbd"
          Hyperlink.NavigateTo Onay
       End Sub

      Bu kod Kaydet düğmesine basıldığında kisi bilgilerinin alınıp, Onay dokümanının
      gösterilmesini sağlar.
   5. Onay adlı userdocument nesnesine aşağıdaki kodu ekleyin.
      Private Sub Command1_Click()
         Dim i As Integer
         Open "kisi.txt" For Output As #1
         For i = 0 To 5
              Print #1, Label1(i).Caption
         Next i
                                              149
          Close #1
          MsgBox "Bilgiler kisi.txt adli dosyaya kaydedildi"
       End Sub

       Private Sub Command2_Click()
          Hyperlink.GoBack
       End Sub

       Private Sub UserDocument_Initialize()
          Label1(0).Caption = Label1(0).Caption & kisi.adSoyad
          Label1(1).Caption = Label1(1).Caption & kisi.dyer
          Label1(2).Caption = Label1(2).Caption & kisi.Adres
          Label1(3).Caption = Label1(3).Caption & kisi.semt
          Label1(4).Caption = Label1(4).Caption & kisi.Sehir
          Label1(5).Caption = Label1(5).Caption & kisi.pkod
       End Sub

Bu kod Devam butonuna basıldığında bilgileri kisi.txt adlı dosyaya kaydeder. Daha sonra bir
mesaj kutusu ile bunu bildirir.

Iptal butonu ise Veri Giriş Formuna geri dönüşü sağlar.

Programın test edilmesi ve varsa hatalarının bulunabilmesi için aşağıdaki aşamaları izleyin.
   1. Projeyi çalışır durumda bırakın.
   2. Internet Explorer programını açın.
   3. File menüsünden open seçeneğini seçerek “d:\devstudio\vb\bilgi.vbd” adlı dosyayı açın.
      Bu işlem bilgi formunun çıkmasını sağlar.
   4. Bu formun KAYDET düğmesine basıldığında ikinci doküman olan Onay formu çıkar.
   5. Onay formunda Kaydet butonuna basıldığında bir mesaj kutusu ile bilgilerin kaydedildiği
      belirtilir.
   6. Iptal butonuna basıldığında ise Bilgi formuna geri dönülür.

Bu projede dikkat edilmesi gereken bir nokta UserDocument nesnelerinin ortak olarak kullandığı
kisi nesnesinin bir module içinde tanımlanmasıdır.

UserDocument nesnesine kullanıcı arayüzü tanımlamak için kullanılan öğeler yerleştirmek
mümkündür.

Örneğin bir UserDocument projesinde başka bir form kullanmak ve bu formun gösterilmesini
sağlamak, bir menü eklemek mümkündür.

Ayrıca, UserDocument nesnesine tıpkı diğer nesne tanımlarında olduğu gibi, özellik, metot ve
olay eklemek ve eklenen bu öğeleri başka programların kullanmasına olanak vermek de
mümkündür.


10.4. Kullanıcı Arayüzü
Bir örnekle UserDocument nesnesine kullanıcı arayüzü eklemeyi gösterelim. Bunun için
aşağıdaki aşamaları takip edin.
    1. Project menüsünden Add Form seçeneğini seçin.
    2. Çıkan pencereden About Dialog türünden bir form ekleyin.

                                              150
   3. Formun üzerindeki etiketleri ileride verilecek olan form görünüşünü referans olarak alıp
      değiştirin. Formun Form_Load yordamını kaldırın. Projeyi kaydedin.
   4. Bilgi adlı userdocument tasarım penceresini açın.
   5. Tools menüsünden menü editor seçeneğini seçin.
   6. Menü editor penceresinden iki tane menü öğesi ekleyin. Bunlar aşağıdaki özelliklere
      sahip olsun.

       Caption Name Negotiate Position
       Yardim mnuYardim 3-Right
       Hakkinda mnuHakkinda (none)

   7. Aşağıdaki kodu Bilgi adlı usercontrol nesnesine ekleyin

       Private Sub mnuHakkinda_Click()
          frmAbout.Show
       End Sub

   8. Projeyi çalıştırın ve çalışır durumda bırakın.
   9. Internet Explorer programını açın ve File menüsünün Open seçeneğini kullanarak
      Bilgi.VBD dosyasını açın. Görüldüğü gibi Internet Explorer menülerinde bir değişiklik
      oldu ve Yardim adlı bir menü oğesi eklendi. Bu menüden Hakkinda seçeneği seçilirse
      aşağıdaki form görüntüsü belirecektir.




Şimdi ActiveX dokümanı yaratmanın aşamalarını özetleyelim.
   1. Dokümanın ön tasarımı yapılmalı ve nitelikleri belirlenmeli.
   2. Dokümanın görünüşü tasarlanmalıdır.
   3. Dokümanın arayüzü tanımlanmalı, başka uygulamalar tarafından kullanılabilecek özellik,
      metot ve olayları belirleyip programlamak
   4. Projenin içerebileceği fazladan formları tasarlayıp işlev kazandırmak.
   5. UserDocument nesnesine kod eklemek
   6. Dokümana işlevsellik kazandıracak kodu yazmak.
   7. .vbd dosya oluşturmak için projeyi derlemek ve projeyi test etmek.




                                             151
11. INTERNET UYGULAMALARI YARATMA
Internetten bahsederken insanların ne kastettiğini anlamak çok zordur. Çünkü ortada çok farklı
türden Internet uygulamaları vardır. Visual Basic farklı türden uygulamalar geliştirebilme
olanakları sağlamaktadır. Bu olanakları aşağıdaki tablo ile gösterebiliriz.

Internet Uygulaması Visual Basic Olanağı

     Bilgisayarlar arası doğrudan iletişim Winsock Kontrol nesnesi
     Dosya Transferi Internet Transfer Kontrol nesnesi
     Web sayfalarını dolaşma WebBrowser kontrol nesnesi
     Internette çalışan uygulamalar ActiveX dokümanları
     Uygulamaların internet üzerinden dağıtılması Setup Wizard
     HTML sayfalarında kullanılabilen bileşenler ActiveX kontrol nesneleri
     Veritabanı uygulamaları Veri erişimi olan içeren dokümanlar.
     Bu bölümde ActiveX Internet Control nesnelerinin kullanımı anlatılacaktır.

11.1. Winsock Control Nesnesi Kullanımı
WinSock kontrol nesnesi, TCP ve UDP protokollerini kullanarak uzaktaki bir makineye
bağlanmak, ve veri alışverişinde bulunmak için kullanılır.

Kullanımları:
    Sunumcu makinesine göndermeden önce kullanıcı bilgilerini toplayan bir istemci
      uygulama yaratmak
    Bir çok kullanıcıdan bilgi toplayan bir sunumcu uygulama yaratmak
    Bir sohbet uygulaması gerçekleştirmek

Protokol seçimi:
    TCP protokolü bağlantı tabanlı bir protokoldür ve telefon bağlantısı ile benzerlik gösterir.
      İletişimden önce bağlantının yapılması gerekir.
    UDP protokolü bağlantısız bir protokoldür, mesajlar bilgisayarlar arasında gönderilirken
      bağlantı ile ilgilenilmez. Yani uygulamalar bağlantıdan bağımsız davranır.

Bu protokollerden birini seçmeye karar vermek için aşağıdaki soruların cevaplanması gerekir.
    Gönderilen bir veri için alındı bilgisi gerekiyor mu? TCP
    Gönderilecek veri büyük mü? TCP. (UDP ile sınırlı miktarda veri gönderilebilir ve veri
       bütünlüğü bozulabilir.)
    Verilerin gönderileceği an belirsiz mi ? UDP. Örneğin bir uygulama bittiğinde başka bir
       uygulama bundan haberdar edilecekse UDP kullanılır.

Protokolün belirtilmesi Winsock kontrol nesnesinin Protocol özelliğine değer atamakla olur.

Örneğin
   Winsock1.Protocol = sckTCPProtocol

Örnek: TCP protokolünün kullanımı.

WinSock kontrol nesnesinin TCP protokolünü nasıl kullandığını görmek için aşağıdaki adımlar
halinde geliştirilen uygulamayı inceleyin.


                                              152
Öncelikle uygulamanın istemci veya sunumcu olmasına karar verilir. Sunumcu yaratılması
demek, uygulamanın belli bir girişi dinlemesi, eğer bir istemciden bağlantı yapılırsa bu
istemcinin isteğini alıp bağlantıyı gerçekleştirmek ve daha sonra istemci-sunumcu arasında veri
alışverişini sağlamak demektir. Şimdi bir sunumcunun nasıl gerçekleştirildiğini görelim.

   1. Standart EXE türünden bir proje yaratın.
   2. Formun ismini frmSunumcu olarak değiştirin. Caption özelliğini de “TCP Sunumcu”
      olarak değiştirin.
   3. Form üzerine bir WinSock kontrol nesnesi yerleştirin ve ismini tcpSunumcu olarak
      değiştirin.
   4. Form üzerine iki tane TextBox yerleştirin, isimlerini txtGonder ve txtAl olarak değiştirin.
   5. Aşağıdaki kodu formun içine ekleyin.

       Private Sub Form_Load()
          tcpSunumcu.LocalPort = 1001
          tcpSunumcu.Listen
          frmIstemci.Show
       End Sub

       Private Sub tcpSunumcu_ConnectionRequest _
          (ByVal requestID As Long)
          If tcpSunumcu.State <> sckClosed Then _
          tcpSunumcu.Close
          tcpSunumcu.Accept requestID
       End Sub

       Private Sub txtGonder_Change()
          tcpSunumcu.SendData txtGonder.Text
       End Sub

       Private Sub tcpSunumcu_DataArrival _
       (ByVal bytesTotal As Long)
          Dim strVeri As String
          tcpSunumcu.GetData strVeri
          txtAl.Text = strVeri
       End Sub


Bu Sunumcuyu test etmek için bir istemci yaratalım.
   1. frmIstemci adında ve Caption özelliği “TCP Istemci olan bir form ekleyin.
   2. Yukarıdaki forma yerleştirilmiş tüm kontrol nesnelerini bu form üzerine kopyalayın.
      WinSock kontrol nesnesinin ismini tcpIstemci olarak değiştirin.
   3. CmdBaglan adlı bir CommandButton yerleştirin. Caption özelliğini “BAGLAN” olarak
      değiştirin.
   4. Kullandığınız bilgisayarın ağ ismini bulun ve aşağıdaki kodu formun kod kesimine
      ekleyin.

       Private Sub Form_Load()
          tcpIstemci.RemoteHost = "ilker"
          tcpIstemci.RemotePort = 1001
       End Sub


                                              153
       Private Sub cmdBaglan_Click()
          tcpIstemci.Connect
       End Sub

       Private Sub txtGonder_Change()
          tcpIstemci.SendData txtGonder.Text
       End Sub

       Private Sub tcpistemci_DataArrival _
       (ByVal bytesTotal As Long)
          Dim strVeri As String
          tcpIstemci.GetData strVeri
          txtAl.Text = strVeri
       End Sub

Yukarıdaki proje basit bir istemci-sunumcu uygulamasıdır. Projeyi çalıştırın. Önce BAGLAN
butonuna basın. Daha sonra txtGonder metin kutusuna yazı yazın. Yazılan yazıların aynı
zamanda diğer formun txtAl metin kutusunda belirdiği görülecektir.

Bu projeyi farklı makineler üzerinde denemek de mümkündür. Tek yapılması gereken
RemoteHost özelliğine uygun bir değer aktarmaktır.


11.2. İnternet Transfer Control Nesnesi Kullanımı
Internet Transfer Control nesnesi HTTP ve FTP olarak bilinen ve geniş bir kullanım alanına
sahip olan internet protokollerini kullanma olanağı dağlar.

ITC kullanarak bu protokolleri destekleyen herhangi bir web sitesine bağlanmak ve dosya
transferi yapmak(OpenURL ve Execute metotlarını kullanarak) mümkündür.

Kullanımları:
    Bir uygulamanın içine bir FTP ve HTTP tarayıcısı yerleştirme.
    FTP sitesinden otomatik olarak dosya transferi sağlayan bir uygulama geliştirmek.
    Web sayfalarının referans gösterdiği grafikleri yüklemek için uygulama geliştirmek.
    Web sayfasından alınan dinamik verilerin istenen biçimlerde gösterilebilmesine olanak
      tanıyan uygulamalar geliştirmek.

Şimdi aşağıdaki FTP tarayıcısı örneğini gerçekleştirelim.
   1. Yeni bir proje yaratın, Proje adını prjFTP, form isimini frmFTP ve form Caption
       özelliğini “FTP BROWSER” OLARAK değiştirin.
   2. Projeyi kaydedin.
   3. Form üzerine txtAdres ve txtDir adında iki tane TextBox yerleştirin. Yerleşimlerini
       ileride verilecek form görüntüsüne göre yapın.
   4. Form üzerine bir ITC (Inet) nesnesi yerleştirin. İsmini inetBrowse olarak değiştirin.
   5. Aşağıdaki kodu forma ekleyin.

       Option Explicit
       Dim msTempDir As String
       Dim msDir As String
       Private Declare Function GetTempPath _
          Lib "kernel32" Alias "GetTempPathA" ( _
          ByVal nBufferLength As Long, _
                                              154
   ByVal lpBuffer As String _
   ) As Long
Private Sub Form_Load()
   Dim lLen As Long
   lLen = 144
   msTempDir = Space(lLen)
   lLen = GetTempPath(lLen, msTempDir)
   msTempDir = Left(msTempDir, lLen)
End Sub

Private Sub txtAdres_KeyPress(KeyAscii As Integer)
   If KeyAscii = Asc(vbCr) Then
       KeyAscii = 0
       txtAdres.SelStart = 0
       txtAdres.SelLength = Len(txtAdres)
       On Error GoTo errOpenURL
       inetBrowse.URL = txtAdres.Text
       inetBrowse.Execute , "Dir"
       Caption = inetBrowse.URL
   End If
   Exit Sub
   errOpenURL:
   Select Case Err.Number
       Case icBadUrl
           MsgBox " YANLIS ADRES, TEKRAR GIRIN"
       Case icConnectFailed, icConnectionAborted, _
       icCannotConnect
           MsgBox "AG BAGLANTISI YAPILAMIYOR."
       Case icInetTimeout
           MsgBox "BAGLANTI KAPANDI."
       Case icExecuting
           inetBrowse.Cancel
           If inetBrowse.StillExecuting Then
                Caption = "IPTAL EDILEMIYOR."
           Else
                Resume
           End If
       Case Else
       Debug.Print Err.Number, Err.Description
   End Select
End Sub

Private Sub txtDir_DblClick()
   If txtDir.SelLength Then
        If Right(txtDir.SelText, 1) = "/" Then
            txtAdres = txtAdres & "/" & Left(txtDir.SelText,
            txtDir.SelLength - 1)
            On Error GoTo errBrowse
            msDir = Right(txtAdres, Len(txtAdres) -
            Len(inetBrowse.URL))
            inetBrowse.Execute , "Dir " & msDir & "/*"
        Else
                                        155
            msDir = Right(txtAdres, Len(txtAdres) _
            - Len(inetBrowse.URL)) & "/" & txtDir.SelText
            msDir = Right(msDir, Len(msDir) - 1)
            inetBrowse.Execute , "Get " & msDir & _
            " " & msTempDir & txtDir.SelText
       End If
   End If
   Exit Sub
   errBrowse:
   If Err = icExecuting Then
       inetBrowse.Cancel
       If inetBrowse.StillExecuting Then
       Caption = "Iptal Edilemez."
   Else
       Resume
   End If
   Else
       Debug.Print Err & " " & Err.Description
   End If
End Sub

Private Sub inetBrowse_StateChanged(ByVal State As Integer)
   Select Case State
       Case icError
           Debug.Print inetBrowse.ResponseCode & " " & _
           inetBrowse.ResponseInfo
       Case icResolvingHost, icRequesting, icRequestSent
           Caption = "Araniyor..."
       Case icHostResolved
           Caption = "Bulundu."
       Case icReceivingResponse, icResponseReceived
           Caption = "Veriler aliniyor."
       Case icResponseCompleted
           Dim sBuffer As String
           sBuffer = inetBrowse.GetChunk(1024)
           If sBuffer <> "" Then
               Caption = "Tamamlandi."
               txtDir = sBuffer
           Else
               Caption = "Dosya " & msTempDir & ". dizinine
               kaydedildi."
           End If
       Case icConnecting, icConnected
           Caption = "Baglaniyor."
       Case icDisconnecting
       Case icDisconnected
       Case Else
           Debug.Print State
   End Select
End Sub



                                      156
Bu kod, belirtilen bir ftp adresinden dizin adlarını veya bir dosyayı alır. Eğer dizin adları
alınıyorsa bu altta bulunan metin kutusuna yansıtılır. Dosya alınıyorsa dosya Windows Temp
dizinine kaydedilir.

Programın çalışması aşağıdaki gibidir.




ITC nesnesinin işlevi kullanılan internet protokolüne göre değişir. Örneğin GetHeader metodu
sadece HTTP protokolü için geçerlidir.

Internet Transfer Control nesnesinin Execute metodu ile çalıştırılabilecek komutlar aşağıdaki
tablolarda gösterilmiştir.

FTP protokolü için:
  CD dosya1 Belirtilen dizine geçer.
  CDUP Bir üst dizine geçer.
  DELETE dosya1 Belirtilen dosyayı siler.
  DIR [dosya1] Belirtilen (veya aktif olan) dizini listeler.
  GET dosya1 dosya2 Uzaktaki dosya1 dosyasını dosya2 ile belirtilen dosyaya
  kaydeder.
  MKDIR dosya1 Belirtilen isimde bir dizin yaratır.
  PUT dosya1 dosya2 dosya1 adlı dosyayı uzaktaki bilgisayarda dosya2 olarak
  kaydeder.
  PWD Aktif olan dizinin adını döndürür.
  QUIT Bağlantıyı koparır.
  RECV dosya1 dosya2 GET komutu ile aynı işi yapar.
  RENAME d1 d2 Belirtilen d1 dosyasının ismini d2 olarak değiştirir.
  RMDIR dosya1 dosya1 ile belirtilen dizini siler.
  SEND dosya1 dosya1 adlı dosyayı aynı ad ile uzaktaki sisteme kaydeder.
  SIZE dosya1 Belirtilen dosyanın uzunluğunu döndürür.

HTTP protokolü için:
  GET URL özelliğiyle belirtilen dosyayı getirir.
  HEAD Sadece dosya başlıklarını getirir.
  POST Belirtilen bir veriyi gönderir.
  PUT 3. Parametre ile verilen veriyi uzaktaki veriyle değiştirir.



                                               157
11.3. Web Browser Kontrol Nesnesi Kullanımı
WebBrowser kontrol nesnesi, bir web sayfalarını dolaşabilmek için bir kontrol nesnesi sağlar. Bu
kontrol nesnesi form üzerine yerleştirilen bir pencere gibidir. Bu kontrol nesnesini kullanarak
kendi web tarayıcımızı yapmamız mümkündür.

Bu kontrol nesnesinin kullanımı aşağıda örneklenmiştir. Burada bir form kullanılarak web
sayfası görüntülenmektedir.

   1. Yeni bir proje yaratın. Formun üzerine bir WebBrowser kontrol nesnesi yerleştirin ve
      aşağıdaki isimlendirmeyi kullanın.

       Project prjWEB
       Form frmWEB
       WebBrowser web1

   2. Aşağıdaki kodu formun içine ekleyin.

           Private Sub Form_Load()
               web1.Navigate "file:\\" & App.Path & "\v-groups.htm"
           End Sub

           Private Sub Form_Paint()
               web1.Left = 0
               web1.Top = 0
               web1.Width = Me.Width
               web1.Height = Me.Height
           End Sub

   3. Programı çalıştırın. Çalışma sırasındaki görünüm aşağıdaki gibidir.




                                              158
11.4. İnternet Explorer İle Otomasyonun Kullanılması
Internet Explorer nesnesi SHDOCVW.DLL kitaplıği içinde tanımlıdır. Bu nesnenin otomasyon
çerçevesinde kullanımı aşağıda örneklenmiştir.

Örnek: Internet explorer kullanan bir form gerçekleştirimi.
   1. Yeni bir proje başlatın. Projeye aşağıdaki nesneleri ekleyin.

       Project               Name                    prjIE
       Form                  Name                    frmIE
                             MinButton               False
                             MaxButton               False
                             Caption                 “WEB TARAYICI”
       TextBox               Name                    txtAdres
       CommandButton         Name                    cmdIleri
                             Caption                 “>>”
       CommandButton         Name                    cmdGeri
                             Caption                 “<<”
       Label                 Caption                 “Adres:”

   2. Aşağıdaki formu koda ekleyin.

           Option Explicit
           Dim WithEvents ie As InternetExplorer
           Private Sub Form_Load()
               Set ie = GetObject("", "InternetExplorer.Application")
               ie.Visible = True
               txtAdres = "file:\\" & App.Path & "\v-groups.htm"
           End Sub

           Private Sub ie_NavigateComplete2(ByVal pDisp As Object, URL As
           Variant)
               txtAdres.Text = URL
               txtAdres.SelLength = Len(txtAdres)
               Caption = ie.LocationName
           End Sub

           Private Sub txtAdres_KeyPress(KeyAscii As Integer)
               If KeyAscii = Asc(vbCr) Then
                   KeyAscii = 0
                   txtAdres.SelLength = Len(txtAdres)
                   ie.Navigate txtAdres
               End If
           End Sub

           Private Sub ie_CommandStateChange(ByVal Command As Long, ByVal
           Enable As Boolean)
               Select Case Command
                   Case CSC_NAVIGATEBACK
                                               159
                     cmdGeri.Enabled = Enable
                 Case CSC_NAVIGATEFORWARD
                     cmdIleri.Enabled = Enable
                 Case CSC_UPDATECOMMANDS
              End Select
           End Sub

           Private Sub cmdGeri_Click()
               ie.GoBack
           End Sub

           Private Sub cmdIleri_Click()
               ie.GoForward
           End Sub

           Private Sub ie_OnQuit()
               End
           End Sub

    3. Projeyi çalıştırın. Aşağıdaki form görüntüsü çıkacaktır.




Şimdi burada yapılan işlemleri açıklayalım.

   Form_Load olayında önce bir Internet Explorer nesnesi yaratılmaktadır. Daha sonra form
    üzerindek adres metin kutusuna ilk değer atanmaktadır.

   Metin kutusu üzerinde ENTER tuşuna basıldığında metin kutusu içindeki adres Internet
    Explorer nesnesine iletilir ve belirtilen adresin açılması sağlanır.

   Internet Explorer nesnesi yukarıda kullanılan WebBrowser kontrol nesnesi ile aynı özellik
    metot ve olaylara sahiptir.


11.5. Kişisel Web Sunumcuları
Kişisel Web sunumcuları (Personal Web Server) .ASP uzantılı aktif sunumcu sayfalarını
kullanırlar. Bu sayfalar standart metin kütükleridir. İçinde HTML kodları ve makrolar yer alır.

Aktif sunumcu sayfaları bir sunumcu üzerinde çalışır ve sunumcunun Dosya Sistemi ile
sunumcu üzerinde yüklenmiş nesneleri kullanabilme özelliğine sahiptir. Bu sayfaların en büyük
yararlarından biri de yaratılmasının ve kullanılmasının çok kolay olmasıdır.

Kişisel web sunumcularının sağladığı olanaklar:
     Internet veya Intranet üzerinden kişisel web sayfalarının dağıtılmasını sağlama
     FTP servislerini kullanarak dosya transferini sağlama

ASP dosyaların tüm kodu sunumcu üzerinde çalışır. İstemciler sonuçları HTML formatında
görürler.
                                               160
ASP dosyalarında makrolar (script code) <% ve %> karakterleri arasında yazılır. Bu karakterler
arasına yazılmış kodlar sunumcuda çalışır ve bu kısımlar tarayıcıda gözükmez.

Bu tür bir web sayfasına örnek olarak aşağıdaki ASP dosyası verilebilir.

   BILGI.ASP
   <HTML>
   <HEAD><TITLE> BILGI FORMU</TITLE></HEAD>
   <BODY BGCOLOR = #FFFFFF>
   <HR>
   <%
   On Error Resume Next
   Dim kisi
   If Request.Form("adsoyad")=" " Then
   %>
   <FORM METHOD=POST ACTION="bilgi.asp">
   <P>
   AdSoyad: <INPUT TYPE=TEXT SIZE=20 MAXLENGTH=20
   NAME="adsoyad">
   <P>
   Dogum Yeri: <INPUT TYPE=TEXT SIZE=20 MAXLENGTH=20
   NAME="dyer">
   <P>
   Adres: <INPUT TYPE=TEXT SIZE=20 MAXLENGTH=20
   NAME="adres">
   <P>
   Semt/Ilce: <INPUT TYPE=TEXT SIZE=20 MAXLENGTH=20
   NAME="semt">
   <P>
   Sehir: <INPUT TYPE=TEXT SIZE=20 MAXLENGTH=20
   NAME="sehir">
   <P>
   Posta Kodu: <INPUT TYPE=TEXT SIZE=20 MAXLENGTH=20
   NAME="pkod">
   </FORM>
   <%
   Else
   set kisi = CreateObject("Bilgi.clsBilgi")
   kisi.Adsoyad=Request.Form("adsoyad")
   kisi.dyer=Request.Form("dyer")
   kisi.adres=Request.Form("adres")
   kisi.semt=Request.Form("semt")
   kisi.sehir=Request.Form("sehir")
   kisi.pkod=Request.Form("pkod")
   %>

   <P>
   Ad soyad: <%kisi.Adsoyad%>
   <P>
   Dogum yeri: <%kisi.dyer%>
   <P>
   Adres : <%kisi.adres%>
                                               161
<P>
Semt/Ilce: <%kisi.semt%>
<P>
Sehir: <%kisi.sehir%>
<P>
Posta kodu: <%kisi.pkod%>
<%
End If
%>
</BODY>
<HTML>




                            162
12.UYGULAMA PROGRAMLARI İÇİN SETUP HAZIRLAMA
Bu bölümde 10. Bölümde işlenen ActiveX doküman projesi için bir setup programının nasıl
yaratılabileceğini konu edineceğiz.

Visual Basic dokümanlarını test ettikten ve hatalarını ayıkladıktan sonra, internette kullanmaya
hazır duruma gelmişler demektir.

Test işlemi bittikten sonra yapılması gereken, (10. Bölümdeki örnek için) dokümanı derlemek ve
prjBilgi.exe dosyasını oluşturmaktır. Bu işlem yapılmadan dokümanın Internet Explorer ile
görülebilmesi mümkündür. PrjBilgi.exe dosyası oluşturulurken aynı zamanda dokümanın
windows için kaydı da yapılır.

Internet explorer kullanarak bir Visual Basic dokümanını çalıştırmak mümkün değildir.
Çalıştırabilmek için bir setup programı yapılması şarttır. Aşağıda adımlar halinde gösterilecek
olan kesimde Visual Basic dokümanları için bir setup programı hazırlanmaktadır.

   1. Application setup programını çalıştırın. Next butonuna basarak aşağıdaki proje seçme
      ekranının gelmesini sağlayın ve projeyi seçin.




   2. Buradan Create Internet Download Setup seçeneğini seçip Next butonuna basın.
      Aşağıdaki ekrandan setup programının yazılacağı dizini seçin.




                                              163
   3. Buradan bir dizin seçip Next butonuna basın. Çıkacak olan ekran projenin çalışma anında
      ihtiyaç duyabileceği .CAB dosyaların nereden sağlanacağını belirler. Bu projede Use
      Alternate Location seçeneğini seçip Safety butonuna basın. Aşağıdaki ekran çıkacaktır.




   4. Bu ekrandaki tüm bileşenler için güvenlik seçeneklerini işaretleyip OK butonuna basın.
      Bir önceki ekrana geri dönülecektir.
   5. Bu ekran projede kullanılan ActiveX bileşenlerini gösterir. Bu projede herhangi bir
      ActiveX bileşeni kullanılmadığı için boş bir liste çıkacaktır. Next butonuna basarak bir
      sonraki aşamaya geçilmesini ve aşağıdaki ekranın çıkmasını sağlayın.




   6. Bu ekran projenin gereksinim duyduğu dosyaları gösterir. Bu ekrandan projeye dahil
      edilmek istenen dosyalar eklenebilir. Herhangi bir dosya eklemeye gerek olmadığı için
      Next butonuna basın. Çıkan ekran sonuç ekranıdır. Finish butonuna basarak Internet
      setup dosyalarının yaratılmasını sağlayın.

Setp Wizard programı boyunca seçilen seçeneklere bağlı olarak aşağıdaki listede belirtilen dosya
türleri oluşabilir.

Dosya Türü Tanımı

   CAB     Uygulamanın çalışan veya bağlantılı dosyalarının sıkıştırılmış hali
           Kullanıcı bilgisayarında CAB dosyalarını otomatik olarak yükler ve VBD dosyalarının
   HTM
           çalıştırılmasını sağlar.
   VBD     Derlenmiş ActiveX dokümanları.
   DDF     Setup Wizard tarafından CAB dosyası oluşturmak için kullanılır.

                                              164
   DEP     Setup Wizard tarafından kullanılan bağımlılıkları belirtir dosya.
   INF     Uygulamanın yüklenmesinin istenilen biçimde olmasını sağlamak İçin kullanılan dosya.
           Setup Wizard programın geçici olarak oluşturduğu dosya. Bu dosya Uygulamanın yüklenmesinde
   SWT
           değişiklikler yapılacağı zaman Setup Wizard tarafından kullanılır.

Yaratılan dosyalar bir kere Internet sitesine taşındıktan sonra, uygulama HTM dosyasını Internet
Explorer ile açarak çalıştırılabilir.

Bu örnekteki HTM dosyası aşağıdaki gibi olacaktır.

   <HTML>
   <OBJECT ID="clsBilgi"
   CLASSID="CLSID:ABF86DA6-0369-11D2-A252-78BC08C10000"
   CODEBASE="prjBilgi.CAB#version=1,0,0,0">
   </OBJECT>
   <SCRIPT LANGUAGE="VBScript">
   Sub Window_OnLoad
   Document.Open
   Document.Write "<FRAMESET>"
   Document.Write "<FRAME SRC=""Bilgi.VBD"">"
   Document.Write "</FRAMESET>"
   Document.Close
   End Sub
   </SCRIPT>
   </HTML>

Uygulamayı çalıştırmak için aşağıdaki Internet Explorer programını çalıştırın. Address diye
adlandırılan metin kutusuna HTM dosyasının tam yolunu yazın.




                                                 165
13. ÇEŞİTLİ VİSUAL BASİC BİLEŞENLERİ

13.1. Takvim (Calendar.ZIP)

                                 Bu bilesen takvim işlevini yerine getirmektedir. Default olarak
                                 sistem tarihi gelmektedir. Ve ardından yıl, ay ve gün değerleri
                                 değiştirilebilmektedir. Ortada seçili olan ay görülmektedir.
                                 Ayrıca üstte ve altta bir önceki ve bir sonraki aylar
                                 bulunmaktadır.

                                 Bu bileşenin text, yıl, ay, gün özellikleri bulunmaktadır.

                                 Text : Bu alan bileşenin gösterdiği tarih değerini belirtir. Bu
                                 değer herhangi bir değişkene aktarılabileceği gibi bir
                                 değişkenden de bilesene aktarılabilmektedir.
                                 Text1.text = Calendar1.text
                                 Calendar1.text = Text1.text
                                 Yıl : Bu alan bileşenin gösterdiği yıl değerini belirtir. Bu değer
                                 herhangi bir değişkene aktarılabileceği gibi bir değişkenden de
                                 bilesene aktarılabilmektedir.
                                 Text1.text = Calendar1.yil
                                 Calendar1.yil = Text1.text
                                 Ay : Bu alan bileşenin gösterdiği ay değerini belirtir. Bu değer
                                 herhangi bir değişkene aktarılabileceği gibi bir değişkenden de
                                 bilesene aktarılabilmektedir.
                                 Text1.text = Calendar1.ay
   Calendar1.ay = Text1.text
Gün : Bu alan bileşenin gösterdiği gün değerini belirtir. Bu değer herhangi bir değişkene
aktarılabileceği gibi bir değişkenden de bilesene aktarılabilmektedir.
   Text1.text = Calendar1.gun
   Calendar1.gun = Text1.text
Bu bilesene ait Event'ler ise;

DayClick               Takvim üzerinde herhangi bir gün üzerine basılırsa tetiklenir
MonthClick             Takvim üzerinde ayları gösteren list item üzerine basılırsa tetiklenir
YearClick              Takvim üzerinde yılları gösteren list item üzerine basılırsa tetiklenir
MonthChange            Takvim üzerinde ayları gösteren list item değiştirilirse tetiklenir
YearChange             Takvim üzerinde yılları gösteren list item değiştirilirse tetiklenir




                                                166
13.2. MCDBCombo - Multi Column DB Combo (MCDBCombo.ZIP)




Bu bilesen bir sorgu sonucu gelen verilerden oluşan bir listedir. Sorgu sonucunda gelen bir çok
alan içinden bir tanesini göstermektedir.

Bu bileşenin öncelikle bir veri tabanına bağlı olması gerekmektedir. Bunun için bileşenin
DataBaseName özelliğine veri tabanının adı yazılacaktır. Form dizayn edilirken eğer veri tabanı
adı girilecekse disk üzerinde dosya explorer yardımı ile bulunup eklenebilmektedir. Geliştirilmiş
olan Property Page yardımı ile bu özellik sağlanmıştır.




Ardından record source alanı içine seçilen Veri Tabanı içindeki tablolardan biri yada herhangi
bir sorgu girilmelidir. Bu da dizayn timeda ya da run time da değiştirilebilmektedir. Bu girilen
sorgu sonucu listelenecektir.




                                              167
13.3. Editör (Editor.ZIP)




Basit bir editör olarak tasarlanan bu bilesen editörde olabilecek özellikleri içermektedir. Yukarda
görüldüğü gibi menüde bulunan seçeneklerden tek tek bahsedecek olursak.

New                                               Yeni bir dosya açmak için kullanılır
Open                                              Var olan bir dosyayı açmak için kullanılır
Save                                              Dosyayı kaydetmek için kullanılır
                                                  Dosyayı başka bir isimle kaydetmek için
Save As
                                                  kullanılır
                                                  Dosya içinde bir stringi bulmak değiştirmek
Find & Replace
                                                  için kullanılır

Find and replace seçilirse karsınıza aşağıdaki ekran gelecektir.




Bu bileşenin 'Text' özelliği (Property) bulunmaktadır. Bu özellik sayesinde ekranda bulunan
değer bir text kutusu içine alınabilmekte ya da bir değer editör içine aktarılabilmektedir.
       Text1.text = Editor1.text
       Editor1.text = Text1.text




                                                168
13.4. FORMATLI Tarih Girişi (f_date.ZIP)




Tarih girişlerinde kullanılacak olan bu bileşen 3 ayrı text box ve iki ayıraçtan oluşmaktadır.
Ayıraçlar sistemin o anda kullandığı ayıraçlardan alınmıştır. Windows standartları kullanılmıştır.
Bu bileşenin kullanılabilecek özellikleri;

Text : Bu alan bileşenin gösterdiği tarih değerini belirtir. Bu değer herhangi bir değişkene
aktarılabileceği gibi bir değişkenden de bilesene aktarılabilmektedir.

Text1.text = f_date1.text
f_date1.text = Text1.text

Yıl : Bu alan bileşenin gösterdiği yıl değerini belirtir. Bu değer herhangi bir değişkene
aktarılabileceği gibi bir değişkenden de bilesene aktarılabilmektedir.

Text1.text = f_date1.yil
f_date1.yil = Text1.text

Ay : Bu alan bileşenin gösterdiği ay değerini belirtir. Bu değer herhangi bir değişkene
aktarılabileceği gibi bir değişkenden de bilesene aktarılabilmektedir.

Text1.text = f_date1.ay
f_date1.ay = Text1.text

Gün : Bu alan bileşenin gösterdiği gun değerini belirtir. Bu değer herhangi bir değişkene
aktarılabileceği gibi bir değişkenden de bilesene aktarılabilmektedir.

Text1.text = f_date1.gun
f_date1.gun = Text1.text




                                               169
13.5. Formatlı Para Girişi (f_money.ZIP)




Tek bir text box'dan oluşan bilesen ayıraç olarak windows ayıraçlarını kullanmaktadır. Numara
girişi dışındaki her türlü karakter girişi yasaklanmıştır. Bu bileşenin kullanılabilecek özelliği;

Text : Bu alan bileşenin gösterdiği tarih değerini belirtir. Bu değer herhangi bir değişkene
aktarılabileceği gibi bir değişkenden de bilesene aktarılabilmektedir.

Text1.text = f_money1.text
f_money1.text = Text1.text




                                               170
13.6. Hesap Makinesi (Calc.ZIP)




Bu bilesen adından da çok kolaylıkla anlaşılacağı üzere hesap makinesi olarak tasarlanmış ve
gerçekleştirilmiştir. Tuşların işlevlerine değinecek olursak.

Backspace    Hesap makinesinin ekranında bulunan değerin en sağındaki karakteri siler.
CE           Ekranı temizler. Sadece en son girilen değer silinir.
C            O ana kadar girilen bütün değerleri 0' lar.
sqrt         Girilen değerin karekökünü alır.
Ln           Girilen değerin doğal tabanda logaritmasını hesaplamak için kullanılır.
1/x          Girilen değerin 1'e bölümünü hesaplar.

Bu bileşenin sadece 'Text' özelliği (Property) bulunmaktadır. Bu özellik sayesinde ekranda
bulunan değer bir text kutusu içine alınabilmektedir.
       Text1.text = Calculator1.text




                                              171
13.7. List of Value (LOV) (Lov.ZIP)




                                            Bu bileşenin öncelikle bir veri tabanına bağlı olması
                                            gerekmektedir. Bunun için bileşenin DataBaseName
                                            özelliğine veri tabanının adı yazılacaktır. Form
                                            dizayn edilirken eğer veri tabanı adı girilecekse disk
                                            üzerinde dosya explorer yardımı ile bulunup
                                            eklenebilmektedir. Geliştirilmiş olan Property Page
                                            yardımı ile bu özellik sağlanmıştır.


Ardından record source alanı içine seçilen Veri
Tabanı içindeki tablolardan biri yada herhangi
bir sorgu girilmelidir. Bu da dizayn timeda ya da
run timeda değiştirilebilmektedir. Bu girilen
sorgu sonucu listelenecektir. Ancak LOV
özelliğinin aktif olabilmesi için bileşenin
Accesskey özelliği içine girilen karakter
kullanılacaktır. Örneğin Access_Key özelliği
içine 'x' karakteri yazıldığını varsayalım. Bu
durumda LOV'un aktif olabilmesi için ALT+x
kullanılmalıdır.

Ekrana gelen veriler içinden herhangi birisi
üzerine çift tıklanarak aktarılacak olan veri seçilir. Nereye aktarılacağına ise aktar isimli event
içinde karar verilir.

Örnek olarak;
       Private Sub Lov1_aktar()
       Text1.Text = Lov1.Text
       End Sub
Bu bileşenin diger özellikleri de;

Lov_Height                                       LOV'un yüksekligini belirler
Lov_Title                                        LOV'un basligi
Lov_Top                                          LOV'un üst baslangis noktasi belirler
Lov_Widht                                        LOV'un genisligini belirler
Lov_Left                                         LOV'un baslangiç noktasini belirler




                                               172
13.8. Resim Kutusu (Scrool.ZIP)




Bu bilesen bir resmi, alanı içinde göstermeye yaramaktadır. Bunun için Scrool Bar'lar
kullanılmaktadır. Bu bilesen ile ilgili olarak gösterilecek resmin hangisi olduğunun belirtilmesi
gerekmektedir. Bu da user kontrolün , picture eventi ile olmaktadır.

Private Sub Form_Load()
UserControl11.Picture = "c:\windows\setup.bmp"
End Sub




                                              173
13.9. Formatlı Tarih Girişi (Takvim ile birlikte) (datebox.ZIP)




Tarih girişlerinde kullanılacak olan bu bilesen 3 ayrı text box
ve iki ayıraçtan oluşmaktadır. Ayıraçlar sistemin o anda
kullandığı ayıraçlardan alınmıştır. Windows standartları
kullanılmıştır. Bu bilesen üzerinde F9 tuşuna basıldığında
takvim açılmakta ve kullanıcı buradan tarihi seçebilmektedir
Bu bileşenin kullanılabilecek özellikleri;

Text : Bu alan bileşenin gösterdiği tarih değerini belirtir. Bu
değer herhangi bir değişkene aktarılabileceği gibi bir
değişkenden de bilesene aktarılabilmektedir.

Text1.text = f_date1.text
f_date1.text = Text1.text

Yıl : Bu alan bileşenin gösterdiği yil değerini belirtir. Bu
değer herhangi bir değişkene aktarılabileceği gibi bir
değişkenden de bilesene aktarılabilmektedir.

Text1.text = f_date1.yil
f_date1.yil = Text1.text

Ay : Bu alan bileşenin gösterdiği ay değerini belirtir. Bu değer herhangi bir değişkene
aktarılabileceği gibi bir değişkenden de bilesene aktarılabilmektedir.

Text1.text = f_date1.ay
f_date1.ay = Text1.text

Gün : Bu alan bileşenin gösterdiği gün değerini belirtir. Bu değer herhangi bir değişkene
aktarılabileceği gibi bir değişkenden de bilesene aktarılabilmektedir.

Text1.text = f_date1.gun
f_date1.gun = Text1.text




                                               174
14.VISUAL BASIC İLE BİLEŞEN HAZIRLAMA

File menüsünden New Project seçeneği ile açılan pencereden ActiveX Control seçeneği
kullanılarak ActiveX dosyası oluşturulabilir. ActiveX dosyaları CTL uzantılı dosyalar olarak
kaydedilir.

ActiveX projenizdeki kontrolü oluştururken VB'nin ToolBox penceresindeki kontrollerden
birçoğunu kullanabilirsiniz. Kendi kontrolünüzü bir form gibi rahatça oluşturabilirsiniz.ActiveX
projenizi tasarım anında direkt olarak çalıştıramazsınız. ActiveX projenizi çalıştırabilmek için
projenize Standart Exe eklemeniz gerekmektedir. ActiveX kontrolün bütün pencerelerini kapatıp
Standart Exe'nin formunu açarsanız Tollbox penceresinde kendi oluşturduğunuz kontrolünde
icon'ını görebilirsiniz. Böylece bu kontrolü formunuza yerleştirebilirsiniz ve kontrolünüzü
deneyebilirsiniz. File menüsünden Make OCX seçeneği ile kontrolünüzü OCX dosyası haline
dönüştürebilirsiniz.

Herhangi bir özellik,metod yada olay tanımı yapılmadan ActiveX kontrolünün bazı özelliklere
sahip olduğu görülür. Bu özellikler VB tarafından standart olarak verilmektedir. VB'nin ActiveX
kontrole verdiği standart öellik, olay ve metodlar şunlardır:

Properties(Özellikler): Container, DragIcon, DragMode, Heigth, HelpContextID,Index, Left,
Name, Object, Parent, TabIndex, TabStop, Tag, ToolTipText, Top, Visible, WhatsThisHelpID,
Width

Events(Olaylar): DragDrop, DragOver, GotFocus, LostFocus

Methods(Metodlar): Drag, Move, SetFocus, ShowWhatsThis, Zorder


ActiveX Controlün Property'lerini açıklayalım:

Public: Bu özellik True ise olşturduğunuz kontrolü diğer uygulamalardada kullanabilir, False ise
sadece projenizdeki formlarda kullanabilirsiniz. Örneğin Bir OCX dosyasındaki User
Controllerin dahil edildikleri projelerden kullanılabilmeleri için bu özelliğin True olması gerekir.

TollBoxBitmap: Oluşturulan kontrolün ToolBox pencerisinde temsil edileceği resimi belirler.
Buraya verilecek olan resim 16*15 pixel boyutlarında olmalı.

Alignable: Bu özellikle oluşturduğunuz kontrole ait Align Özelliğinin bulunup
bulunamayacağını belirleyebilrsiniz. Bu özelliğe True değeri verirseniz kontrolünüzün Align
özelliğide bulunur.

CanGetFocus : Kontrolün klavye kontrolünü alıp almayacağını bu özellikle belirlenir.
Normalde True'dur ve kontrol Focus alabilir.

ControlContainer : Bu özelliğe True değeri verirseniz oluşturduğunuz kontrol diğer kontrolleri
barındırabilir(Frame, PictureBox gibi). Yan gruplandırma elemanı gibi davranır ve içine konulan
kontroller bu kontrole bağımlı olurlar.

DefaultCancel : Komut düğmeleri gibi Defaul ve Cancel özelliklerinin kontrolde yer alması
isteniliyorsa bu özellik True yapılır.

                                                175
EditAtDesignTime: Bu özelliğe True değeri verilirse kontrol tasrım modunda Edit moduna
geçebilir. Bu özelliği True olan kontrollerde kullanıcı tasarım zamanında sağ fare tuşu ile açılan
menüdeki Edit komutunu seçerek tasarım zamanında kontrol üzerinde düzeltme yapabilir. Yani
kontrol tasarım zamanındada çalışma durumuna geçebilir. Örneğin kontrolünüzün üzerinde bir
text kutusu varsa kullanıcı tasarım zamanında iken farenin sağ tuşu ile açılan pencereden Edit
seçeneğini kullanarak bu kutuya bilgi girişi yapabilir.

InvisibleAtRunTime: Tasarlanan kontrolün çalışma zamanında görülüp görülmeyeceğini
belirler. Kontrolünüze bu özelliği verdiğinizde toolboxdaki birçok kontrolü kullanamazsınız.

AccessKeys: Tasarlanan kontrole bir kısayol tuşu bu özellik sayesinde verilebilir. Bu kısayol
tuşuna basıldığında AccessKeyPres olayı meydana gelir.

PropertyPages: Bazı kontrollerin properties penceresinde birden fazla özelliği
değiştirebileceğiniz pencereler bulunur. Tasarlanan kontroldede böyle bir pencere bulunması
isteniliyorsa bu özellikle açılan pencereden istediğiniz özellikleri properties penceresine
ekleyebilirsiniz. Bu işlemden sonra kontrolünüzde custom isimli yeni bir özellik daha
bulunacaktır. İsterseniz kendi property page'lerinizi hazırlayabir veya hazır olanlardan birini
kullanabilirsiniz.

Ambient: Bu özellikle User Control'ün içinde bulunacağı yerin bazı özellikleri öğrenilebilir.
Örneğin tasarladığınız kontrol bir form içinde ise formun, bir frame'in içinde ise framin
özellikleri öğrenilebilir. Ambient özelliğinin şu alt özellikleri vardı: BackColor, ForeColor, Font,
DisplayAsDefault, DisplayName, LocaleID, MessageReflect, Palette, RightToLeft, ScaleUnits,
ShowGrapHandles, ShowHatchings, SuppotrsMnemonics, TextAling, UserMode,UIDead.

Ambient.DisplayName: Bu özellik ile User contolün ismini öğrenebilirsiniz.

Ambient.ScaleUnits: Bu özellikle usercontrolün içinde bulunduğu yerin Scale Mode özelliğine
verilen değeri öğrenebilirsiniz.

Ambient.UserMode: Bu özellikle o anda içinde bulunan kontrolün tasarım zamanındamı
çalışma zamanında mı olduğunu öğrenebilirsiniz.Eğer bu özellik True değerini alıyorsa çalışma
zamanı False ise tasarım zamanıdır.

Ambient.UIDead : Bu özellikle o anda kontrolün içinde bulunduğu yerin break modunda olup
olmadığı öğrenilir.

Ambient.RigthToLeft : Bu özellik ile sistemin yazıları sağdan solamı yoksa soldan sağa
doğrumu olduğu öğrenilir

Ambient.TextAling: User Controlün içinde bulunduğu yerdeki yazı yerleşimi bu özellikle
öğrenilebilir.

Extender : Bu özellikle Usercontrolün aşağıdaki özellikleri öğrenilip değiştirilebilir.
Name, Visible, Parent, Cancel, Default, Container, DragIcon, DragMode, Enabled, Height,
HelpContextID, Index, Left, TabIndex, TabStop, Tag, ToolTipText, Top, WhatThis, HelpID,
Width




                                                176
Events(Olaylar)

Initialize: Usercontrol form üzerine veya başka bir yere konulduğunda kısacası yeni bir tanesi
üretildiğinde Initialize olayı meydana gelir.

InitProperties: Usercontrol oluşturulduğunda Initialize olyından sonra Initproperties olayı
meydana gelir. Bu olay daha çok özelliklere ilk değer atamak için kullanılır.

Terminate: Usercontrol bellekten atıldığı zaman bu olay meydana gelir.

AccesKeyPress: Kullanıcı AccessKeys özelliği ile belirlenen tuşa bastığında bu olay meydana
gelir. Eğer usercontrolün DefaultCancel özelliği True yapılmış ise Enter ve Esc tuşlarınada
basıldığı zaman bu olay meydana gelir.

Hide: Kontrolün Visible özelliği False yapıldığında bu olay meydana gelir.

Show: Kontrolün Visible özelliği True yapıldığında bu olay meydana gelir.

AmbientChanged: Ambient özelliklerinden biri değiştiğinde bu olay meydana gelir.Örneğin
Usercontrolün üzerine yerleştirildiği formun rengi değiştirildiğinde bu olay meydana gelir.

EnterFocus,ExitFocus: Klavye kontrolü usercontrol içinde bir nesneye geçtiğinde veya
kaybettiğinde o nesnenin GotFocu ve LostFocus özelliğinden önce UserControlün EnterFocus ve
ExitFocus olayları meydana gelir.

ReadProperties: Tasım anında bir properties'e aktarılan değeri properties form çalıştırılıp tekrar
tasım anına döndüğünde koruması gerekir. Bu işlemleri yapabilmek için bu olay geliştirilmiştir.
Bu olayda properties'e aktarılan deger okunur. Bu işlem ProgPag parametresinin ReadProperty
ve WriteProperty metodları ile yapılır.

Deger=ProgBag.ReadProperty("Properties Adı",VarsayılanDeğeri)

WriteProperties: Bu olaydada daha önce ReadProperties olayında okunup saklanan değer
properties'e aktarılır.
Call PropBag.WriteProperty("PropertiesAdı",Deger,VarsayılanDeğer)




                                               177
Yeni Event ve Property Ekleme

Property Ekleme:


                                    Tools Menüsündeki Add procedure menü seçeneği ile
                                    açılan yukardaki pencereden yeni bir property
                                    oluşturulabilir.Bu işlem sonunla Let ve Get isimli iki yeni
                                    procedure oluşur. Bunlarda Let property'e bir değer
                                    aktarıldığında çalışır Get ise Property'nin değeri
                                    öğrenilmeye çalışıldında çalışır.




Bu şekilde oluşturulan propert property
penceresinde gözükür.Bu property'nin özellikleri
Tools menüsündeki Procedure Attributes seçeneği
ile açılan aşağıdaki pencere ile belirlenebilir.



                                            Penceredeki Description kısmına property'nin ne
                                            yaptığına ilişkin şeyler yazılır.Advanced >>
                                            düğmesine basılırsa property'nin daha gelişmiş
                                            özellikleri belirlenebilir.

                                            Use this Page in Property Browser seçeneğiyle
                                            propertynin hangi Propert Page'e bağlı olacağı
                                            belirtilir.

                                            Property Category seçeneği ile propertynin hangi
                                            kategoriye ait olacağı belirtilir.

                                            Don't Show in Property Browser seçeneği
                                            işaretlenirse Property property penceresinde
                                            gözükmeyecektir.


Hide This Member seçeneği işaretlenirse propertynin kullanıcı tarafından kullanılmaması
sağlanır.

Property is databound ve alt özellikleri işaretlenirse propertynin veritabanındaki bir alanla
bağlantısı kurulabilir.

Bir property'e bir değer aktarıldığında bu değer geçerli bir değerse Property procedurunun Let
kısmında PropertyChanged "Property Adı" metodu ile bu değeri kabul ettiğimizi bildirmemiz
gerekir.




                                             178
Event Ekleme:




Tools Menüsündeki Add procedure menü seçeneği ile açılan yukardaki pencereden yeni bir
event oluşturulabilir.

Bu eventi oluşturduktan sonra bu eventin tetiklenmesini istediğimiz yere RaiseEvent EventAdı
yazarak Eventi tetikleriz.




                                            179

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:199
posted:9/18/2012
language:Unknown
pages:179