}     //DropCall

        // Burada, bir hattın çevirme özelliklerini belirleyebilirsiniz.
        // Örneğin, alan kodu, şehir ve ülke adı, dış hat alabilmek için numara,
        // uzak aramalar için çevrilecek numara, alan kodu düzenleme v.b. belirleyebilirsiniz.
        public bool DialingPropertiesDialog(string sLineName)
        {
            // Bir LineClass nesnesi oluşturuyoruz ve
            // içini GetLineByName metoduyla dolduruyoruz.
            LineClass lnc = GetLineByName(sLineName);

            // LineClass nesnesi null mu?
            if (lnc != null)
            {
                // lnc objesinden LineDevID ve TAPIVer özelliklerini parametre
                // olarak alıp, lineTranslateDialog fonksiyonunu çağırıyoruz.
                Int32 iRet = lineTranslateDialog(this.hLineApp,
                                                 lnc.LineDevID,
                                                 lnc.TAPIVer,
                                                 IntPtr.Zero,
                                                 String.Empty);

                // lineTranslateDialog çağrısı başarılıysa, true döndür.
                if (iRet == TAPI_SUCCESS)
                {
                    return(true);
                }
            }

            return(false);
        }//DialingPropertiesDialog
        }//constructor

        #endregion

        #region Public Methods
        //***************************
        // Public Metodlar          *
        //***************************

        // Bir hattın, LineClass özelliklerine erişmek için GetLineByName metodunu kullanıyoruz.
        // sLineName: Hat adı
        // Bu metod, LineClass sınıfından bir nesne çevirir.
        public LineClass GetLineByName(string sLineName)
        {
            // Find metodunun amacı koleksiyondan istediğimiz koşulları sağlayan
            // ilk kümeyi bulmak ve geriye döndürmektir. Burada isimsiz metod kullanılmıştır.
            LineClass myLineClass = ListLine.Find(
                // LineClass sınıfını kullanan adsız temsilciyi parametre
                // olarak geçiriyoruz. Daha sonra, istenilen hat adına eşit olan
                // kümeyi bulup geriye döndüreceğiz.
                delegate(LineClass lineObj)
            {
                return(lineObj.LineName.Equals(sLineName));
            });

            return(myLineClass);
        }//GetLineByName
        }//DialingPropertiesDialog

        // Burada, hizmet sağlayıcısının hat için verdiği ayarları değiştirebilirsiniz.
        // Örneğin, arama tercihleri, veri bağlantı tercihleri,
        // donanım ve uçbirim ayarları v.b. belirleyebilirsiniz.
        public bool LineDeviceConfigDialog(IntPtr hOwner, string sLineName)
        {
            // Bir LineClass nesnesi oluşturuyoruz ve
            // içini GetLineByName metoduyla dolduruyoruz.
            LineClass lnc = GetLineByName(sLineName);

            // LineClass nesnesi null mu?
            if (lnc != null)
            {
                // lineConfigDialog fonksiyonunu çağırıyoruz.
                Int32 iRet = lineConfigDialog(lnc.LineDevID, hOwner, String.Empty);
                // lineConfigDialog çağrısı başarılıysa, true döndür.
                if (iRet == TAPI_SUCCESS)
                {
                    return(true);
                }
            }

            return(false);
        }//LineDeviceConfigDialog
        // Verilen bir telefon hattının sahip olduğu kapasite ve özelliklerini bulur.
        // Bunun için LINEDEVCAPS yapısı ve lineGetDevCaps fonksiyonunu kullanacağız.
        // devID:    Hat ID
        // iTapiVer: TAPI sürümü
        private bool GetLineDeviceCaps(UInt32 devID, UInt32 iTapiVer)
        {
            Int32 iSize       = 0;     // LINEDEVCAPS yapısının ilk uzunluğu
            Int32 iTotalSize  = 0;     // Yapının toplam uzunluğu
            Int32 iNeededSize = 0;     // Gereksinim duyulan uzunluk

            Byte[] totalBuffer = null; // Yapıyı kopyalayacağımız byte dizisi
            bool   bUseMemory  = true; // Bellek gereksinimini kontrol edecek

            // LINEDEVCAPS yapı nesnesi tanımlıyoruz.
            // Bu yapı, değişken bir uzunluğa sahiptir.
            LINEDEVCAPS lineDevCaps = new LINEDEVCAPS();

            // Yapının ilk uzunluğunu değişkenlere aynen atıyoruz.
            iSize       = Marshal.SizeOf(lineDevCaps);
            iTotalSize  = iSize;
            iNeededSize = iSize;

            while (bUseMemory)
            {
                // Gereksinim duyulan uzunluk, verilen toplam uzunluktan büyük mü?
                if (iNeededSize > iTotalSize)
                {
                    // Yapı için tutulacak olan toplam uzunluğu yeniden atıyoruz.
                    lineDevCaps.dwTotalSize = iNeededSize;
                }
                else
                {
                    // Yapı için tutulacak olan toplam uzunluğa, ilk uzunluğu atıyoruz.
                    lineDevCaps.dwTotalSize = iSize;
                }//if

                // Tampon için bellekte, iNeededSize dönen uzunluk değeri kadar yer ayır.
                IntPtr buffer = Marshal.AllocHGlobal(iNeededSize);
                // LINEDEVCAPS yapısındaki değerleri tampona kopyala.
                Marshal.StructureToPtr(lineDevCaps, buffer, true);

                try
                {
                    // LINEDEVCAPS yapısına verdiğimiz uzunluğun yeterli olup olmadığına
                    // bakmak için, lineGetDevCaps fonksiyonunu çağırıyoruz.
                    // Bundan sonra, yapıdaki dwTotalSize, dwNeededSize alanlarını
                    // kıyaslama için kontrol edebileceğiz.
                    Int32 iRetVal = lineGetDevCaps(this.m_hLineApp,
                                                   (UInt32)devID,
                                                   iTapiVer,
                                                   0,
                                                   buffer);

                    // Fonksiyondan dönen değer başarılı mı?
                    if (iRetVal == TAPI_SUCCESS)
                    {
                        // Burada, yönetilmeyen bellek öbeğindeki veriler,
                        // yönetimli yapıya marshall ediliyor.
                        Marshal.PtrToStructure(buffer, lineDevCaps);
                        // Ölçü karşılaştırmasında kullanılacak olan, yapıdaki dwTotalSize
                        // ve dwNeededSize alanlarını değişkenlere atıyoruz.
                        iTotalSize  = (Int32)lineDevCaps.dwTotalSize;
                        iNeededSize = (Int32)lineDevCaps.dwNeededSize;

                        // Gereksinim duyulan uzunluk, verilen toplam uzunluktan büyükse,
                        // tampon için bellekte daha büyük bir yer ayırmak zorundayız.
                        // buffer parametresini yeniden lineGetDevCaps fonksiyonuna göndermeliyiz.

                        // Döngüdeki bUseMemory şartını yeni duruma göre eşitliyoruz.
                        bUseMemory = (iNeededSize > iTotalSize);

                        // Bellekte tampon için daha fazla yer ayrılacak mı?
                        if (!bUseMemory)
                        {
                            // Yapıyı kopyalayacağımız byte dizisinin uzunluğunu iTotalSize ile geçir.
                            totalBuffer = new byte[iTotalSize];
                            // Yönetilmeyen bellekte bulunan veri içeriği
                            // yönetilen bir dizi içine kopyalanıyor.
                            Marshal.Copy(buffer, totalBuffer, 0, iTotalSize);
                        }//if
                    }
                    else
                    {
                        //MessageBox.Show("lineGetDevCaps fonksiyonu çağrısı başarısız.");

                        return(false);
                    }
                }
                finally
                {
                    // AllocHGlobal ile bellekte ayrılan yeri serbest bırak.
                    Marshal.FreeHGlobal(buffer);
                }
            }//while

            // LineClass nesne örneğini yarat.
            LineClass myLines = new LineClass(devID, iTapiVer);

            // LineClass içindeki hat alanlarını doldurmak için PutLineProperties metodunu çağır.
            if (myLines.PutLineProperties(lineDevCaps, totalBuffer))
            {
                // Hattın sesli arama özelliğini kontrol et.
                if (myLines.SupportVoiceCall)
                {
                    this.m_ListLine.Add(myLines); // Koleksiyona ekle.
                }
            }
            else
            {
                //MessageBox.Show("Hat özellikleri sınıf üyelerine doldurulurken hata oluştu.");

                return(false);
            }//if

            return(true);
        }
        }//GetDecoder

        // İlk önce bir hat açan ve daha sonra bir telefon araması yapan metodumuz.
        // sLineName:    hat adı
        // sPhoneNumber: telefon numarası
        public bool OpenLineDevice(string sLineName, string sPhoneNumber)
        {
            // Hat açıksa, CloseLine metodu çağrılarak hat kaptılıyor.
            if (CloseLine() == TAPI_SUCCESS)
            {
                // Bir LineClass nesnesi tanımlıyoruz ve
                // hattın sınıf değişkenlerine - özelliklerine erişmek için
                // GetLineByName metodunu çağırıyoruz.
                LineClass lnc = GetLineByName(sLineName);

                // LineClass nesnesi null mu?
                if ((lnc == null))
                {
                    return(false);
                }

                // LINECALLPARAMS yapı nesnesi tanımlıyoruz.
                LINECALLPARAMS callParams = new LINECALLPARAMS();

                // Hat açmak için lineOpen fonksiyonunu çağırıyoruz.
                // Fonksiyondan dönen değer, iRetVal değişkenine atanır.
                Int32 iRetVal = lineOpen(this.m_hLineApp,
                                         lnc.LineDevID,
                                         ref this.m_hLine,
                                         lnc.TAPIVer,
                                         0,
                                         this.m_CallBack,
                                         Enums.LineCallPrivilege.LINECALLPRIVILEGE_NONE,
                                         Enums.LineMediaMode.LINEMEDIAMODE_INTERACTIVEVOICE,
                                         callParams);

                // Fonksiyon çağrısı başarılı mı?
                if (iRetVal == TAPI_SUCCESS)
                {
                    // CallStatusDialogEvent nesnesine OnCallStatusDialogEvent metodu adresi atanıyor.
                    CallStatusDialogEvent += new
                                             CallStatusDialogEventHandler(OnCallStatusDialogEvent);

                    //frmMain.ShowStatusMsg("Hat açıldı." + "\r\n");

                    // sPhoneNumber değişkeni boşsa sadece çevir sesi alınır.
                    // Boş değilse, bir telefon numarasını çevirerek arama yapar.
                    iRetVal = lineMakeCall(m_hLine, ref m_hCall, sPhoneNumber, 0, null);

                    if (iRetVal > 0)
                    {
                        // Telefonla arama başlatma başarılı olursa, bu LINE_REPLY olayı ile bildirilir.
                        // Geriye dönen pozitif tanıtıcı değer, LineCallbackEventHandler metodu içinde kullanılması için
                        // m_iPlaceCallIdt değişkenine atanır.
                        this.m_iPlaceCallIdt = iRetVal;

                        return(true);
                    }
                    else
                    {
                        return(false);
                    }//if
                }
                else
                {
                    // lineOpen fonksiyonu çağrısı başarısız.
                    //MessageBox.Show("Hat daha önce başka bir uygulama veya servis sağlayıcısı tarafından açılmış.");

                    return(false);
                }//if lineOpen
            }
            else
            {
                return(false);
            } //if
        }     //OpenLineDevice