C#nedir?com
 
YAZAR HAKKINDA
Süleyman Payaslı
Süleyman Payaslı
http://www.csharpnedir.com/
İletişme geçmek için tıklayın.
7 Makalesi yayınlanmakta.
Yazar hakkında detaylı bilgi için tıklayın.
Yayınlanan diğer makaleleri için tıklayın.
İlgili etiketler: [flags] 0x00000002 basilinca hattin hizmet ilgili lineclass nesnesi saglayicisi string telefon telefonla uygulama verir. windows C# / VC#/.NET Süleyman Payaslı
 
YAZI HAKKINDA
Türü : Makale
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
Seviyesi : İleri
Kategori : C# / VC#/.NET
Yayınlanma Tarihi : 4.5.2007
Okunma Sayısı : 34425
Yorum Sayısı : 1     yorum yaz
Site İçi AramaSİTE İÇİ ARAMA
Üye Girişini AçÜye GİRİŞİ
Üye girişi için tıklayın.
Kullanıcı Adı
Şifre
 
Beni her zaman hatırla
Bir hafta boyunca kullanıcı bilgilerinizi kullanıcı çıkışı yapana kadar hatırlar. (Paylaşılan bilgisayarlarda önerilmez.)
 
Şifremi / Kullanıcı Adımı unuttum.
 
.net TV RSS Serbest KÖŞE (?)
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
emre TAŞ
XML - Deniz Kılınç
emre TAŞ
yazının devamı >
emre TAŞ
Decompiling and Reverse Engineering .Net Radyo
emre TAŞ
yazının devamı >
emre TAŞ
Masaüstü mü ? İnternet Mi? .Net Radyo
emre TAŞ
yazının devamı >
emre TAŞ
.Net Kavramları - .Net Radyo
emre TAŞ
yazının devamı >
emre TAŞ
Yeni Başlayanlar için - .Net Radyo
emre TAŞ
yazının devamı >
Makale Gönder Bende Yazmak İstiyorum
.net TV RSSBlogroll
Turhal Temizer
Conda install environment.yml Package 11.4.2021
Turhal Temizer
Mac OS/X Removing CUDA 11.4.2021
Burak Selim Şenyurt
Tie Fighter Değil, Project Tye! 11.4.2021
Burak Selim Şenyurt
Stackoverflow Sevgi Anketinde Yıllardır Bir Numara Çıkan Programlama Dili Rust Kimdir? 11.4.2021
  Diğer Herşey
Sponsorlar
BT Akademi
Medya Portakal
Video Hosting Sponsoru
Csharpnedir.com bir Ineta üyesidir
Uzman Abi
Her Yönüyle C# - Sefer Algan
TAPI Uygulaması: Ses Modemiyle Telefonu Kullanma
 
Kapat
Sayfayı Yazdır Sık Kullanılanlara Ekle Arkadaşıma Gönder MySpace Del.Ico.Us Digg Facebook Google Mixx Reddit StumbleUpon

1994 yılında Microsoft ve Intel’in ortak girişimiyle başlayan, Telefon Uygulama Programlama Arabirimi (TAPI), Windows için telefonla iletişim uygulamaları geliştirmeyi destekler. Sağladığı işlevsellikle telekomünikasyon ile bilgisayarı bütünleştirirken, tutarlı bir arayüz sunar. Desteklenen donanımlardan bazıları şunlardır: Sabit telefon, modemler, kameralar, IP telefonu, PBX, ISDN hatları ve ATM ağlarıdır. TAPI ile yapılabileck uygulamalar, sabit telefonla arama yapma veya arama yanıtlamanın ötesindedir. İnternet üzerinden sesli arama (VoIP), sesli posta, video konferans, sesli yanıt sistemleri (IVR), çağrı merkezi gibi gelişmiş iletişim uygulamalarını yapmaya olanak verir. İletişim programlarıyla telefonla arama yapma, yanıt verme, arayanın numarasını görme, arama bekletme, müzik dinletme, aktarma, yapılan görüşmenin kaydedilmesi, konferans, faks yollama, sesli ve görüntülü arama yapma olanakları sağlanabilir. TAPI, ayrıca ISDN, sayısal T1 gibi çeşitli hat tiplerini kontrol edebilir ve gözleyebilir.

Desteklenen Windows Sürümleri
Değişik Windows sürümleri için farklı TAPI sürümleri bulunmaktadır. Yeni sürümler, hizmet paketleri veya güncelleştirmeler bu tabloda aynen yer almayabilir. Bu duruma dikkat edilmesi gerekmektedir.

Windows sürümü
Varsayılan TAPI sürümü
Maksimum TAPI sürümü
Windows Server 2003
TAPI 2.2
TAPI 3.1
Windows XP
TAPI 2.2
TAPI 3.1
Windows 2000
TAPI 2.2
TAPI 3.0
Windows ME
TAPI 2.2
TAPI 2.2
Windows 98
TAPI 2.1
TAPI 2.2
Windows NT SP4
TAPI 2.1
TAPI 2.2
Windows 95
TAPI 1.4
TAPI 2.2

Tablo-1: Windows ve TAPI sürümleri.
Windows 95 ile ortaya çıkan TAPI 1.4 sürümü, 32-bit Windows ortamı için temel sürümdür. Windows NT 4.0 ile TAPI 2.0 sürümü 32-bit Windows için tam destek ve Unicode olanağını sundu. TAPI 2.1 sürümüne istemci/sunucu işlevselliği eklendi. TAPI 2.2 genel anahtarlı telefon ağı (PSTN) istemci-sunucu telefon işlevlerini ve çağrı merkezi yönetimi işlevlerini destekler. TAPI 3.0 ve TAPI 3.1 IP telefonunu destekler. TAPI 3.0, COM destekli API kullanarak geleneksel telefon ile IP telefonunu yönetimini birleştirmiştir. Böylece Java, Delphi, C/C++ ve Visual Basic gibi programla dilleriyle uygulama hazırlamayı kolaylaştırmıştır.

TAPI Hizmet Sağlayıcı (TSP)
Hizmet sağlayıcısı terimi, Windows için sağlanan TAPI sürücüsünü ifade eder. Bu sürücü bir DLL olup, TAPI uygulamalarının farklı donanımlarla iletişimini olanaklı kılar. Windows 95 ve NT ile beraber geliştirilen TSP, unimodem olarak bilinmektedir. Unimodem hizmet sağlayıcısı geniş bir şekilde farklı modem tiplerini destekler. Örneğin modem dışında PBX, değişik bir ses işleme kartı veya başka bir donanım kullanıldığında, üretici tarafından sağlanan TSP kullanılabilir. TAPI, veri/faks modemleri veya ses modemleriyle bağlantı kurmak istediğinde unimodem kullanır. Unimodem TAPI’den gelen komutları, modemin anlayabileceği AT komutlarına çevirir. Bunun anlamı şudur: Modemi kullanmak, modem ayarı yapmak veya bir telefon numarası çevirmek için kullanıcının modem komutlarını öğrenmesine gerek kalmaz. Windows içinde yer alan çevirmeli ağ bağlantısı, hyper terminal, telefon çeviricisi (phone dialer) gibi hizmetler TAPI ve unimodemle birlikte kullanılarak yapılır.

Buraya kadar anlatılanları özetleyecek olursak:
Aşağıdaki şekilde görüldüğü gibi telefon aygıtını kullanmamızı sağlayan üç yazılım katmanı vardır: Bir program, TAPI, bir telefon hizmet sağlayıcısı ve bir aygıt (telefon, fax/modem vb).

Şekil-1:TAPI genel çalışma şekli.

TAPI, Windows platformları üzerinden telefonla ilgili fonksiyonlara erişimi sağlamak için soyutlanmış bir katman sağlamaktadır. Bu fonksiyon dizisini kullanmak üzere çeşitli programlar yazabilme imkanını sunmaktadır. TAPI üzerine yazılan programlar, analog veya dijital telefon hatlarını kullanabilirler. Program, telefonla arama yapmanızı, faks alıp gönderme veya veri yollamanızı sağlar. TAPI, programlar için telefon hattını açma, çevir sesi kontrolü, meşgul tonu kontrolü, zil sesi algılama, konuşmayı sonlandırma gibi işlevleri sağlar. Telefon hizmet sağlayıcısı ise dinamik bir kütüphane olup, bir telefon aygıtı veya telefon protokolü ile ilgili komutların çevirisini gerçekleştirir. İçinde yer alan servis fonksiyonları sayesinde, aygıtla ilgili iletişim kontrolünü sağlar. Basit bir ifadeyle, program bir eylem gerçekleştirmek istediğinde, TAPI aygıtı destekleyen telefon hizmet sağlayıcısını belirler ve hizmet sağlayıcısı, gerekli komutları telefona veya aygıta gönderir.

Hatlar ve telefonlar
TAPI modeli, hatlar ve telefonlar olmak üzere iki alana ayrılmıştır. Bunların kendi API komutları bulunmaktadır. Hat, telefon hizmet sağlayıcısı tarafından desteklenen ses, veri veya video gibi bir ortam akışıdır. Hat bir modem için, gerçek bir telefon hattını temsil eder. Bilgisayara bağlı bir modem, faks veya ISDN kartı, hat aygıtlarına birer örnektir. Telefonla yapacağımız aramalar, telefon hizmet sağlayıcısının sunduğu bir hattın kullanılmasıyla yapılabilir. Bir hatla, aynı anda birden fazla arama yapma veya beklemeye alma gibi işlevleri destekleyebilir. Telefon hizmet sağlayıcısı, fiziksel aygıtların telefon hatları tarafından temsil edilme şeklini belirler.

TAPI’de bir "telefon", çoğunlukla fiziksel bir telefon anlamına gelir. Ancak gerçek bir donanım da olmayabilir. Hizmet sağlayıcısı tarafından desteklenen terminal donatımını temsil eder. Örneğin, bir TAPI programı yazarak, bilgisayar ortamında sanal telefon uygulaması yapılabilir. Burada sabit telefon veya cep telefonu öykünüm (emulation) programlarını hatırlamakta fayda vardır. Masaüstünde bir telefon modellemesi veya öykünmesi yapmak için bir ses kartı, bir mikrofon, kulaklık seti veya hoparlör yeterli olur. Burada fiziksel anlamda bir telefona gerek yoktur. Diğer taraftan bir arama yapmak istediğimizde bir modeme ihtiyacımız olacaktır. Tüm telefon hizmet sağlayıcıları hat desteği sunduğu halde, her telefon hizmet sağlayıcısının telefon desteği sağlamadığını hatırlamakta fayda vardır.

Bazı uygulamalarda TAPI, hatları ve telefonları biribirlerinden bağımsız olduğunu varsayabilir. Örneğin, bir telefon aygıtını kullanmadan, bir hattı kullanabiliriz. Daha açıkçası, hattın telefonla ilişkilendirilmeden kullanılabilmesidir. Bu durumun tersi de olabilir.

TAPI Programlaya Giriş
TAPI kütüphaneleri C/C++ ile yazılmış olduğundan, bunları .NET ortamında kullanabilmek ve özellikli uygulamalar geliştirebilmek için fazladan bir çaba harcamak gerekmektedir. TAPI fonksiyonlarını kullanmaya başlamadan önce bununla ilgili olark Platform SDK ve TAPI yardım dosyalarını çok iyi okumak ve anlamak gerekmektedir.

Buraya kadar yapılan genel açıklamalardan sonra, bazı tipik TAPI fonksiyonlarını ve yapıları incelemeye başlayalım:

TAPI fonksiyonları

TAPI Fonksiyonu
Açıklama
lineInitializeEx
Uygulamamız için TAPI kullanımını başlatır.
lineNegotiateAPIVersion
Uygulamanın bir TAPI versiyonu kullanması için anlaşmasına izin verir.
lineGetDevCaps
Belirtilen bir hattın kapasitesini sorgulayıp veren fonksiyon.
lineOpen
Bir hattı açar ve hatta ait bir handle verir.
lineMakeCall
Hat üzerinden telefon araması yapar.
lineDrop
Belirtilen çağrıyı keser veya hattan düşürür.
lineDeallocateCall
Çağrıya ait tutulan handle serbest bırakılır.
lineClose
Açık olan hattı kapatır.
lineShutdown
Uygulamanın hatla ilgili API’leri kullanmasını sonlandırır.
lineConfigDialog
Hatla ilgili parametreleri ayarlamaya izin veren diyalog.
lineTranslateDialog
Konum bilgileri, alan kodu, arama kuralları diyalogu.
tapiGetLocationInfo
Bilgisayarda kayıtlı ülke ve şehir kodunu verir.

Tablo-2: Kullanacağımız temel TAPI fonksiyonları. Hat yapıları (Line Structures)
TAPI ile istemci uygulamalar arasında bilgi geçirme amaçlı yapılar tanımlanmıştır. Bu yapıların bir kısmı değişken uzunluktadır. Buna dikkat etmekte fayda vardır. Yapının toplam uzunluğu ile kullanılan uzunluk farklı olabilmektedir.

Yapı (Struct)
Açıklama
LINEINITIALIZEEXPARAMS
lineInitializeEx çağrılırken verilmesi gereken parametreleri tanımlayan yapı.
LINEEXTENSIONID
Dahili hat tanıtıcı yapısı.
LINEDIALPARAMS
Numara çevrilmesiyle ilgili özellikleri belirleyen yapı.
LINEDEVCAPS
Hat kapasitesi ve yetenekleriyle ilgili yapı.
LINECALLPARAMS
lineMakeCall ile yapılan aramalarda kullanılacak parametreleri veren yapı.

Tablo-3:Kullanacağımız TAPI hat yapıları. Hat mesajları (Line Messages)
Hatla ilgili olan olaylar, uygulamaya TAPI mesajları kullanılarak yollanır. Uygulama başlangıç aşamasında lineInitialize veya lineInitializeEx fonksiyonunu kullanırken, olaylar için kullanılacak geri çağrılır (call back) fonksiyon adresini sağlamak zorundadır. Tüm mesajlar bu fonksiyona gönderilir. Bir mesaj hat, telefon veya çağrı nesnesiyle ilgili olarak bir handle tutar. Böylece uygulama bunu kullanarak mesaj tipini saptayabilir.

Mesaj
Açıklama
LINE_CALLSTATE
Arama-çağrı durumu değişikliklerinde yollanır.
LINE_CLOSE
Hat zorla kapatıldığında yollanır.
LINE_CALLINFO
Arama bilgisi değiştiğinde yollanır.
LINE_LINEDEVSTATE
Hat durumu değişikliklerinde yollanır.
LINE_REPLY
Tamamlanan asenkron fonksiyon çağrılarını rapor etmek için yollanır.
LINE_REQUEST
Diğer bir uygulamadan gelen isteğin ulaştığını rapor etmek için yollanır.

Tablo-4:TAPI hat mesajları. TAPI hat mesajları ve hat sabitleri hakkında daha fazla ayrıntılı bilgi için MSDN veya Platform SDK’ ya bakabilirsiniz. Örnek proje içinde bunları ayrı dosyalar içinde inceleme fırsatınızda olacaktır.

Buraya kadar anlatılanları daha iyi kavrayabilmek için bunları bir örnek projeyle uygularsak, konu daha iyi anlaşılacaktır. Yazacağımız basit bir projeyle yerel bilgisayar ve sabit telefon üzerinden, yapılabilecek bazı temel işlevleri inceleyeceğiz. Aynı anda konuşma ve dinleme için bilgisayarınıza, normal telefon hattı takılı bir ses modemi ve bir mikrofonun olması gerekir. Aksi halde telefonla konuşmayı tam olarak gerçekleştiremeyeceksiniz. TAPI iletişim fonksiyonlarını kullanarak hizmet sağlayıcısı özelliklerine erişim, arama, aramayı durdurma, yanıtlama, modem özelliklerini ekrana yazdırma gibi özellikleri olan bir uygulamayı, TAPI kütüphanesini kullanarak C# ile hazırlayacağız. Projemizde kodlamaya başlamadan önce, yapacaklarımızın kısa bir özetini çıkarmak, TAPI konusunu daha anlaşılır bir hale getirecektir. Yeni bir Windows uygulama projesi açalım ve yardımcı sınıflarımızı yazalım. Daha sonra formumuzu tasarlayacağız. Projedeki adımlar şunlardır:

İlk aşamada öncelikle TAPI sabitlerini ve mesaj değerlerini yazalım. TAPI enum sabitlerini kapsayan sınıfımızı kaynak kodlar içindeki Enums.cs dosyasında bulabilirsiniz. Siz de bu sabitleri ve enumları Tapi.h dosyasından derleyebilirsiniz. Enum sabitlerimiz içerisindeki değerlerin veyalanmış halleriyle kullanabileceğimizi varsayarsak, enum bildiriminden önce [Flags] niteliğini kullanmamız gerekir.

// TAPI hat sabitlerini kapsayan sınıfımız.
public class Enums
{
    // Hattı başlatma (lineInitializeEx) zamanında, seçilecek
    // olay bildirimi mekanizması enum sabitleri.
    public enum LineInitializeExOptions : uint
    {
        LINEINITIALIZEEXOPTION_USEHIDDENWINDOW = 0x00000001,
        LINEINITIALIZEEXOPTION_USEEVENT = 0x00000002,
        LINEINITIALIZEEXOPTION_USECOMPLETIONPORT = 0x00000003
    }
 
    // Hattın kullandığı string türü - ASCII, Unicode...
    public enum StringFormat : uint
    {
        STRINGFORMAT_ASCII = 0x00000001,
        STRINGFORMAT_DBCS = 0x00000002,
        STRINGFORMAT_UNICODE = 0x00000003,
        STRINGFORMAT_BINARY = 0x00000004
    }
 
    // Çağrıyla ilgili olarak, uygulamanın sahip olduğu ayrıcalıkların enum sabitleri.
    [Flags]
    public enum LineCallPrivilege : uint
    {
        // Uygulamaya ait özel bir hak yok.
        LINECALLPRIVILEGE_NONE = 0x00000001,
        // Uygulama çağrıyı sorgular ve durmunu takip eder.
        LINECALLPRIVILEGE_MONITOR = 0x00000002,
        // Uygulama çağrıyı kendi amacı doğrultusunda yönetebilir.
        LINECALLPRIVILEGE_OWNER = 0x00000004
    }
 
    // Hat durum olaylarıyla ilgili enum sabitleri.
    [Flags]
    public enum LineDevState : uint
    {
        LINEDEVSTATE_OTHER = 0x00000001,
        LINEDEVSTATE_RINGING = 0x00000002,
        LINEDEVSTATE_CONNECTED = 0x00000004,
        LINEDEVSTATE_DISCONNECTED = 0x00000008,
        LINEDEVSTATE_MSGWAITON = 0x00000010,
        LINEDEVSTATE_MSGWAITOFF = 0x00000020,
        LINEDEVSTATE_INSERVICE = 0x00000040,
        LINEDEVSTATE_OUTOFSERVICE = 0x00000080,
        LINEDEVSTATE_MAINTENANCE = 0x00000100,
        LINEDEVSTATE_OPEN = 0x00000200,
        LINEDEVSTATE_CLOSE = 0x00000400,
        LINEDEVSTATE_NUMCALLS = 0x00000800,
        LINEDEVSTATE_NUMCOMPLETIONS = 0x00001000,
        LINEDEVSTATE_TERMINALS = 0x00002000,
        LINEDEVSTATE_ROAMMODE = 0x00004000,
        LINEDEVSTATE_BATTERY = 0x00008000,
        LINEDEVSTATE_SIGNAL = 0x00010000,
        LINEDEVSTATE_DEVSPECIFIC = 0x00020000,
        LINEDEVSTATE_REINIT = 0x00040000,
        LINEDEVSTATE_LOCK = 0x00080000,
        LINEDEVSTATE_CAPSCHANGE = 0x00100000,           
        LINEDEVSTATE_CONFIGCHANGE = 0x00200000,         
        LINEDEVSTATE_TRANSLATECHANGE = 0x00400000,      
        LINEDEVSTATE_COMPLCANCEL = 0x00800000,          
        LINEDEVSTATE_REMOVED = 0x01000000               
    }
 
    // Adres durumu ögeleri enum sabitleri.
    [Flags]
    public enum LineAddressState : uint
    {
        LINEADDRESSSTATE_OTHER = 0x00000001,
        LINEADDRESSSTATE_DEVSPECIFIC = 0x00000002,
        LINEADDRESSSTATE_INUSEZERO = 0x00000004,
        LINEADDRESSSTATE_INUSEONE = 0x00000008,
        LINEADDRESSSTATE_INUSEMANY = 0x00000010,
        LINEADDRESSSTATE_NUMCALLS = 0x00000020,
        LINEADDRESSSTATE_FORWARD = 0x00000040,
        LINEADDRESSSTATE_TERMINALS = 0x00000080,
        LINEADDRESSSTATE_CAPSCHANGE = 0x00000100      
    }
 
    // Taşıyıcı biçimleri enum sabitleri
    [Flags]
    public enum LineBearerMode : uint
    {
        LINEBEARERMODE_VOICE = 0x00000001,
        LINEBEARERMODE_SPEECH = 0x00000002,
        LINEBEARERMODE_MULTIUSE = 0x00000004,
        LINEBEARERMODE_DATA = 0x00000008,
        LINEBEARERMODE_ALTSPEECHDATA = 0x00000010,
        LINEBEARERMODE_NONCALLSIGNALING = 0x00000020,
        LINEBEARERMODE_PASSTHROUGH = 0x00000040,       
        LINEBEARERMODE_RESTRICTEDDATA = 0x00000080     
    }
 
    // Kullanılabilir-uygun hat özellikleri enum sabitleri.
    [Flags]
    public enum LineFeature : uint
    {
        LINEFEATURE_DEVSPECIFIC = 0x00000001,
        LINEFEATURE_DEVSPECIFICFEAT = 0x00000002,
        LINEFEATURE_FORWARD = 0x00000004,
        LINEFEATURE_MAKECALL = 0x00000008,
        LINEFEATURE_SETMEDIACONTROL = 0x00000010,
        LINEFEATURE_SETTERMINAL = 0x00000020,
        LINEFEATURE_SETDEVSTATUS = 0x00000040,      
        LINEFEATURE_FORWARDFWD = 0x00000080,        
        LINEFEATURE_FORWARDDND = 0x00000100         
    }
 
    // Çağrı ortamı enum sabitleri - Ses modemi, fax, data modem, video v.b.
    [Flags]
    public enum LineMediaMode : uint
    {
        LINEMEDIAMODE_UNKNOWN = 0x00000002,
        LINEMEDIAMODE_INTERACTIVEVOICE = 0x00000004,
        LINEMEDIAMODE_AUTOMATEDVOICE = 0x00000008,
        LINEMEDIAMODE_DATAMODEM = 0x00000010,
        LINEMEDIAMODE_G3FAX = 0x00000020,
        LINEMEDIAMODE_TDD = 0x00000040,
        LINEMEDIAMODE_G4FAX = 0x00000080,
        LINEMEDIAMODE_DIGITALDATA = 0x00000100,
        LINEMEDIAMODE_TELETEX = 0x00000200,
        LINEMEDIAMODE_VIDEOTEX = 0x00000400,
        LINEMEDIAMODE_TELEX = 0x00000800,
        LINEMEDIAMODE_MIXED = 0x00001000,
        LINEMEDIAMODE_ADSI = 0x00002000,
        LINEMEDIAMODE_VOICEVIEW = 0x00004000,
        LINEMEDIAMODE_VIDEO = 0x00008000
    }
 
    // Arama-çağrı durumları enum sabitleri.
    [Flags]
    public enum LineCallState : uint
    {
        LINECALLSTATE_IDLE = 0x00000001,
        LINECALLSTATE_OFFERING = 0x00000002,
        LINECALLSTATE_ACCEPTED = 0x00000004,
        LINECALLSTATE_DIALTONE = 0x00000008,
        LINECALLSTATE_DIALING = 0x00000010,
        LINECALLSTATE_RINGBACK = 0x00000020,
        LINECALLSTATE_BUSY = 0x00000040,
        LINECALLSTATE_SPECIALINFO = 0x00000080,
        LINECALLSTATE_CONNECTED = 0x00000100,
        LINECALLSTATE_PROCEEDING = 0x00000200,
        LINECALLSTATE_ONHOLD = 0x00000400,
        LINECALLSTATE_CONFERENCED = 0x00000800,
        LINECALLSTATE_ONHOLDPENDCONF = 0x00001000,
        LINECALLSTATE_ONHOLDPENDTRANSFER = 0x00002000,
        LINECALLSTATE_DISCONNECTED = 0x00004000,
        LINECALLSTATE_UNKNOWN = 0x00008000
    }
 
    // Telefon - hat mesajları. Bkz. Tapi.h
    public enum LineDeviceMessages : int
    {
        LINE_ADDRESSSTATE = 0,
        LINE_CALLINFO,
        LINE_CALLSTATE,
        LINE_CLOSE,
        LINE_DEVSPECIFIC,
        LINE_DEVSPECIFICFEATURE,
        LINE_GATHERDIGITS,
        LINE_GENERATE,
        LINE_LINEDEVSTATE,
        LINE_MONITORDIGITS,
        LINE_MONITORMEDIA,
        LINE_MONITORTONE,
        LINE_REPLY,
        LINE_REQUEST,       
        PHONE_BUTTON,
        PHONE_CLOSE,
        PHONE_DEVSPECIFIC,
        PHONE_REPLY,
        PHONE_STATE,
        LINE_CREATE,
        PHONE_CREATE,
        LINE_AGENTSPECIFIC,
        LINE_AGENTSTATUS,
        LINE_APPNEWCALL,
        LINE_PROXYREQUEST,
        LINE_REMOVE,
        PHONE_REMOVE
    }
}//Enums

İkinci aşamada programınızın Windows’ taki handle değerini döndüren ve bazı pencere özellikleriyle ilgili Win32 API fonksiyonlarını kullanan diğer sınıfımızı tanımlıyoruz. Bu kodlar projemizdeki WindowsAPI.cs dosyasında yeralmaktadır.

public class WindowsAPI
{
    // SW_HIDE sabiti pencerenin saklanacağını bildirir. Bkz. winuser.h
    public const Int32 SW_HIDE = 0;
 
    // Kendi programınızın Windows’taki tanıtıcı değerini alan (handle) fonksiyon.
    // Fonksiyon çağrısı başarılıysa geriye modüle ait bir handle,
    // başarısız durumda ise null değer çevirir.
    [DllImport("kernel32.DLL", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr GetModuleHandle(
        // Exe vey DLL dosyasının adı veya null değer. 
        string lpModuleName);
 
    // Sınıf ismi ve adı verilen pencereyi bulan fonksiyon.
    // Fonksiyon çağrısı başarılıysa geriye pencereye ait bir handle,
    // başarısız durumda ise null değer çevirir.
    [DllImport("user32.DLL", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr FindWindow(
        // Pencere sınıfının adı
        string lpClassName,
        // Pencere başlığı
        string lpWindowName);
 
    // Pencerenin nasıl görüntüleneceğini belirten fonksiyon.
    [DllImport("user32", CharSet = CharSet.Auto)]
    public static extern Int32 ShowWindow(
        // Pencerinin tanıtıcısı (Windows’taki değeri veya handle)
        IntPtr hWnd,
        // Pencerenin nasıl görüntüleceğini bildiren sabit
        Int32 nCmdShow);
}//WindowsAPI

Üçüncü aşamada TAPI fonksiyonlarını, yapılarını ve sabitlerini sarmalayan bir sınıf yazalım. Bu sınıfı kullanarak telefonla bir arama yapmak istersek, şu adımları takip etmeliyiz:

  • TAPI sabitlerini tanımla.
  • TAPI yapılarını ve TAPI fonksiyonları tanımla.
  • TAPI oturumu başlatmak için lineInitializeEx fonksiyonunu çağır.
  • Uygun TAPI sürümü tespiti için lineNegotiateAPIVersion fonksiyonunu çağır.
  • LINEDEVCAPS yapısı ve lineGetDevCaps fonksiyon çağrısıyla hattının sahip olduğu kapasite ve özellikleri bul.
  • İsteğinize uygun bir hat (ses, faks, veri) açmak için lineOpen fonksiyonunu çağır.
  • Telefonla arama başlatmak için lineMakeCall fonksiyonunu çağır.
  • Aramayı sonlandırmak için lineDrop fonksiyonunu kullan.
  • Hattı kapatmak için lineClose kullan.
  • Uygulamanın hatla ilgili API’ leri kullanmasını sonlandırmak için lineShutdown fonksiyonu çağır.

Bu adımlar tamanlandıktan sonra, TAPI mesajlarını işlemek ve izlemek için temsilci, olay ve geri çağrılır metodumuzu yazmamız gerekir. Şimdi buraya kadar anlatılanları yapacak olan TAPIClass adlı sınıfımızı yazalım. Sınıfımıza IDisposable arayüzünü uygulayacağız. Sınıfla ilgili açıklamalar ve kavramlar, kodlar içerisinde yer alan yorum satırlarında açıklanmıştır.



 

Şekil-2:TAPIClass sınıf diyagramı. TAPIClass adlı sınıfımızda ilk önce kullanacağımız genel sabitleri, yapılarımızı, temsilcilerimizi, olaylar ve dış metod çağrılarımızı tanımlayalım. Bundan sonra değişken üyelerimizi ve özellikleri tanımlıyoruz. TAPI fonksiyonlarını ve yapılarını sarmalayan yardımcı sınıfımızı (TAPIClass.cs) aşağıdaki gibi kodlayalım:


(Bu kodlama makale içerisinde çok yer kapladığı düşüncesinde olduğum için buraya eklemedim. Makalenin en altında bulunan link ile kaynak kodları indirip inceleyebilirsiniz.

TAPI uygulamalarında hat sayısını almak için lineInitializeEx fonksiyonunu çağırırız. Bunu TAPIClass sınıfının yapıcı metodu içinde bulabilirsiniz. Bilgisayarımızda bir hattın bağlı olduğunu varsayıp kodlamaya devam edebiliriz ama diğer taraftan birden çok hat (gerçek veya sanal) bulunduğunda, diğer hatları göremeyeceğiz ve en önemlisi kapasitelerinden de faydalanamayacağız. Bu yüzden birden çok hatların kapasitelerini bir sınıf içinde tanımlayıp, bunları bir List<> nesnesi içine doldurmak üzere LineClass.cs sınıfımızı tanımlıyoruz.



Şekil-3:LineClass sınıf diyagramı. LineClass sınıfı List koleksiyonu ile kullanılacak olan, hat özelliklerini içeren yardımcı sınıfımız olacaktır. Sınıfımız IComparable arayüzü sayesinde, karşılaştırmalar gerçekleştirebilir.

public class LineClass : IComparable
{
    //*************************************
    // LineClass sınıfı değişken üyeleri  *
    //*************************************
 
    // Hat nosu  değişkeni.
    private UInt32 m_iLineDevID;
    // TAPI versiyonu değişkeni.
    private UInt32 m_TAPIVer;
    // Hat adı değişkeni.
    private string m_sLineName;
    // Hizmet sağlayıcısı adı değişkeni.
    private string m_sProviderInfo;
    // Taşıyıcı biçimi değişkeni.
    private Enums.LineBearerMode m_lineBearerModes;
    // Kullanılabilir-uygun hat özellikleri değişkeni.
    private Enums.LineFeature m_lineFeatures;
    // Çağrı ortamı değişkeni.
    private Enums.LineMediaMode m_lineMediaTypes;
    // Hattın kullandığı string format değişkeni.
    private Enums.StringFormat m_StringFormat;
    // m_bSupportVoiceCall:  Hattın sesli arama durumunu gösteren değişken.
    private bool m_bSupportVoiceCall;
 
 
    //*********************************
    // LineClass sınıfı özellikleri   *
    //*********************************
 
    // Hat ID’sini verir.
    public UInt32 LineDevID
    {
        get { return m_iLineDevID; }
    }
 
    // Hattın TAPI versiyonunu verir.
    public UInt32 TAPIVer
    {
        get { return m_TAPIVer; }
    }
 
    // Hattın adını verir.
    public string LineName
    {
        get { return m_sLineName; }
    }
 
    // Hattın hizmet sağlayıcısı adını verir.
    public string ProviderInfo
    {
        get { return m_sProviderInfo; }
    }
 
    // Hattın taşıyıcı biçimlerini verir.
    public Enums.LineBearerMode LineBearerModes
    {
        get { return m_lineBearerModes; }
    }
 
    // Hattın kullanılabilir-uygun özelliklerini verir.
    public Enums.LineFeature LineFeatures
    {
        get { return m_lineFeatures; }
    }
 
    // Hattın çağrı ortamı özelliğini verir.
    public Enums.LineMediaMode LineMediaTypes
    {
        get { return m_lineMediaTypes; }
    }
 
    // Hattın kullandığı string formatı verir. 
    public Enums.StringFormat StringFormat
    {
        get { return m_StringFormat; }
    }
 
    // Sesli aramanın yapılabilme durumunu gösterir.
    public bool SupportVoiceCall
    {
        get { return m_bSupportVoiceCall; }
    }
 
 
    // LineClass sınıfı yapıcı metodu
    public LineClass(UInt32 lineDevID, UInt32 iTapiVer)
    {
        this.m_iLineDevID = lineDevID;
        this.m_TAPIVer = iTapiVer;
    }
 
    //***************************
    // Public Metodlar          *
    //***************************
 
    // IComparable arayüzünü gerçekleştirebilmek için
    // LineClass nesnesinin CompareTo metodunu ortaya koyması gerekir.
    public int CompareTo(Object obj)
    {
        // LineClass nesnesi, parametreden gelen nesneyle kendini karşılaştırır.
        // Burada karşılaştırma hat adıyla delege edilmiştir.
        return this.LineName.CompareTo(((LineClass)obj).LineName);
    }
 
    // LINEDEVCAPS yapısından ve byte dizisi parametrelerin kullanarak,
    // bir hattın alanlarını dolduracağız.
    public bool PutLineProperties(TAPIClass.LINEDEVCAPS lineDevCaps,
        Byte[] buffer)
    {
        Decoder dec = null;     // Decoder nesnesi
 
        try
        {
            // Taşıyıcı biçimi değerini ata.
            this.m_lineBearerModes = (Enums.LineBearerMode)lineDevCaps.dwBearerModes;
            // Hat özellikleri değerini ata.
            this.m_lineFeatures = (Enums.LineFeature)lineDevCaps.dwLineFeatures;
            // Çağrı ortamı değerini ata.
            this.m_lineMediaTypes = (Enums.LineMediaMode)lineDevCaps.dwMediaModes;
            // LINEDEVCAPS yapısındaki dwStringFormat parametresi hattın
            // kullandığı string formatını verir.
            this.m_StringFormat = (Enums.StringFormat)lineDevCaps.dwStringFormat;
 
            // GetDecoder metoduyla Decoder tipinden bir nesne atanıyor.
            dec = TAPIClass.GetDecoder(this.m_StringFormat);
            // Decoder nesnesi null değerse?
            if (dec != null)
            {
                // GetStringFromByteArray tanımlı metodumuzu çağırarak
                // hat adını değişkene ata.
                this.m_sLineName = StrUtils.GetStringFromByteArray(buffer,
                    (int)lineDevCaps.dwLineNameOffset,
                    (int)lineDevCaps.dwLineNameSize,
                    dec);
                // GetStringFromByteArray tanımlı metodumuzu çağırarak
                // hizmet sağlayıcısı adını değişkene ata.
                this.m_sProviderInfo = StrUtils.GetStringFromByteArray(buffer,
                    (int)lineDevCaps.dwProviderInfoOffset,
                    (int)lineDevCaps.dwProviderInfoSize,
                    dec);
 
                // Hat sesli aramayı destekliyor mu?
                if (CanSupportVoiceCall())
                    this.m_bSupportVoiceCall = true;
            }//if
 
            return true;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            return false;
        }
    }//PutLineProperties
 
    // Hat hakkında kısa bilgi vermek için kullanılır.
    // Bir StringBuilder nesnesini doldurarak string tipine çevirir.
    public string GetLineInfo()
    {
        // StringBuilder nesnesi oluştur.
        StringBuilder sb = new StringBuilder();
 
        // LineClass sınıfı özelliklerinden bazıları okunurak ’sb’ değişkenine
        // ard arda eklenir.
        sb.Append("Hat ID:  " + this.LineDevID + "\r\n");
        sb.Append("Hat Adı:  " + this.LineName + "\r\n");
        sb.Append("Hizmet Sağlayıcısı:  " + this.ProviderInfo + "\r\n");
        sb.Append("Taşıyıcı Biçimi:  " + this.LineBearerModes + "\r\n");
        sb.Append("Hat Özellikleri:  " + this.LineFeatures + "\r\n");
        sb.Append("Çağrı Ortamı:  " + this.LineMediaTypes + "\r\n");
 
        if (this.CanSupportVoiceCall())
        {
            sb.Append("Sesli Arama:  Destekliyor");
        }
        else
        {
            sb.Append("Sesli Arama:  Desteklemiyor");
        }//if
 
        // ’sb’ nesnesi içindeki sonucu string tipine çevir.
        return sb.ToString();
    }//GetLineInfo
 
 
    //***************************
    // Private Metodlar         *
    //***************************
 
    // Hattın sesli aramayı destekleyip desteklemediğini veren metod.
    private bool CanSupportVoiceCall()
    {
        if (((this.LineBearerModes & Enums.LineBearerMode.LINEBEARERMODE_VOICE) != 0)
           && ((this.LineFeatures & Enums.LineFeature.LINEFEATURE_MAKECALL) != 0)
           && ((this.LineMediaTypes & Enums.LineMediaMode.LINEMEDIAMODE_INTERACTIVEVOICE) != 0))
        {
            // Sesli aramayı destekliyor
            return true;
        }
        else
        {
            // Sesli aramayı desteklemiyor
            return false;
        }//if
    }//CanSupportVoiceCall
 
}//LineClass

LineClass sınıfımızı hazırladıktan sonra, GetLineDeviceCaps metoduna geri dönebiliriz. LINEDEVCAPS yapısındaki alanları, hiçbir veri kaybı olmadan bir byte dizisine kopyalamıştık. Şimdi hatla ilgili değerleri tutacak olan bir LineClass nesne örneğini oluşturuyoruz. Bundan sonra LineClass içindeki PutLineProperties metodunu çağırıyoruz. Metoda LINEDEVCAPS yapısını ve byte dizisini parametre olarak geçiriyoruz. Böylece LineClass içindeki hat alanlarını doldurabileceğiz. Biz sadece sesli arama özelliği ile ilgilendiğimiz için bu özelliğe sahip olanları koleksiyonumuza ekliyoruz. PutLineProperties metodunda taşıyıcı biçimi, çağrı ortamı, hat string formatı, hat özellikleri gibi değerler değişkenlere aktarılır. Sayısal ve enum sabitleriyle ilgili içerikler kolayca elde edilirken, değişken uzunluk alanına sahip olanların string tipine çevrilmesi gerekmektedir. Örneğin, hizmet sağlayıcısı bilgisini ele alalım: Byte dizisindeki belli bir uzunluktaki parça alınıp string olarak çevrilmesi gerekmektedir. Bunun yapabilmek için GetStringFromByteArray metodunu kullanacağız. Elimizdeki byte dizisinden hizmet sağlayıcısı alanının başladığı konumunu, bu alanın uzunluğunu yapıdaki değerleri kullanarak alabiliriz. Bunları Decoder ile birlikte parametre olarak geçirirsek hizmet sağlayıcısını string olarak elde ederiz. Bu metodu StrUtils.cs içinde bulabilirsiniz.

// GetStringFromByteArray metodu byte dizisindeki belli uzunluktaki
// bir parçayı alarak, string olarak döndürür.
//
// bytes:  Byte dizisi.
// iStart: Byte dizisindeki başlangıç konumu.
// iLen:   Çevrilecek  byte parçasının uzunluğu.
// dec:    Çevirmede kullanılacak Decoder.
public static string GetStringFromByteArray(Byte[] bytes, int iStart,
    int iLen, Decoder dec)
{
    // Parametrelerin hata kontrolünü yap.
    if ((iStart + iLen <= bytes.Length) && (iStart >= 0) && (iLen > 0))
    {
        // Karakter dizisi nesnesi oluştur.
        Char[] chars;
        // StringBuilder nesnesi oluştur.
        StringBuilder sb = new StringBuilder();
 
        // GetCharCount metoduyla, byte dizisindeki kodlaması çözülecek
        // olan byte’lar için gerekli karakter sayısını hesapla.
        int iCharCount = dec.GetCharCount(bytes, iStart, iLen);
        // Karakter dizisini boyutlandır.
        chars = new Char[iCharCount];
        // GetChars metoduyla, belirtilen sayı kadar, byte dizisinden
        // alınan elemanların karakter dizisine çevrilmesi:
        dec.GetChars(bytes, iStart, iLen, chars, 0);
 
        // must skip null-termination of C++ string
        // Karakter dizisinin sonundaki null kontrolü için:
        for (int i = 0; i < iCharCount; ++i)
        {
            // Konrol karakteri var mı?
            if (Char.GetUnicodeCategory(chars[i]) != UnicodeCategory.Control)
            {
                // Karakter dizini doldur.
                sb.Append(chars[i].ToString());
            }
            else
            {
                break;      // Konrol karakteri yakalandı.
            }//if
        }//for
 
        return sb.ToString();
    }
    else
    {
        // Parametrelerde hata bulundu. Boş bir string çevir.
        return String.Empty;
    }
}//GetStringFromByteArray

Sınıflarımızı kodladıktan sonra şimdi formumuzu tasarlamaya başlayalım: Projemize frmTelephony adında yeni bir form ekleyelim. Kodumuz aşağıdaki gibi devam etmektedir:

using System;
using System.Windows.Forms;
 
namespace TapiInCS
{
    public partial class frmTelephony : Form
    {
        // TAPIClass nesnesi
        private TAPIClass TAPI;
        // Universal modem hizmet sağlayıcısı
        private string sUniModem = "Universal Modem Driver";
 
        public frmTelephony()
        {
            InitializeComponent();
 
            // Form üzerindeki kontrollerin bazılarını seçilemez konuma getir.
            btnDialProps.Enabled = false;
            btnLineConfigDlg.Enabled = false;
            btnLocationInfo.Enabled = false;
            btnDial.Enabled = false;
            btnHangup.Enabled = false;
            txbLineInfo.ReadOnly = true;
            txbCallStatus.ReadOnly = true;
 
            // TAPIClass nesnesini oluştur.
            TAPI = new TAPIClass("TAPISample");
 
        }//frmTelephony
 
        // TAPI olaylarından gelen mesajları txbCallStatus metin kutusuna yazar.
        public void ShowStatusMsg(string msg)
        {
            if (msg != String.Empty)
            {
                txbCallStatus.Text += msg;
            }
        }//ShowStatusMsg
 
        // TAPIClass sınıfındaki metodlarla doldurulan hat koleksiyonu<> kontrol
        // edilerek, bulunan hatlar cbxLines bileşenine aktarılıyor.
        private void frmTelephony_Load(object sender, EventArgs e)
        {
            // TAPIClass sınıfındaki frmMain değişkeni içine,
            // formumuz referans edilerek atanıyor.
            TAPIClass.frmMain = this;
 
            // ListLine koleksiyonu içindeki elemanların sayısı sıfırdan büyük mü?
            if (TAPI.ListLine.Count > 0)
            {
                // ListLine<> nesnesi içindeki hatlar arasında gezinmek
                // için foreach döngüsünü kullanıyoruz.
                foreach (LineClass cl in TAPI.ListLine)
                {
                    // Okunan hat adları içerisinde "sUniModem" string değişkeni varsa?
                    if (cl.ProviderInfo.IndexOf(sUniModem) >= 0)
                    {
                        // Hat adlarını combobox içine doldur.
                        cbxLines.Items.Add(cl.LineName);
                    }//if
                }//foreach
 
                // Combobox bileşenindeki ilk elemanı seç.
                cbxLines.SelectedIndex = 0;
            }//if
 
        }//Load
 
        // Form kapatılmadan önceki FormClosing olayı.
        private void frmTelephony_FormClosing(object sender, FormClosingEventArgs e)
        {
            // TAPI sınıfını sonlandır.
            TAPI.Dispose();
 
        }//FormClosing
 
        // "Telefon no. çevir" düğmesine basılınca, telefon numarası çevrilir.
        private void btnDial_Click(object sender, EventArgs e)
        {
            txbCallStatus.Clear();          // İçeriğini temizliyoruz
 
            // Metin kutusuna telefon numarası girilmiş mi?
            if (txbPhoneNumber.Text.Length != 0)
            {
                // Arama-çağrıya ait handle geçerli mi?
                if (TAPI.hCall == IntPtr.Zero)
                {
                    btnDial.Enabled = false;        // Kullanıma kapalı
 
                    // Telefonla arama yapan OpenLineDevice metodunu çağır ve
                    // metottan dönen değeri kontrol et. 
                    if (TAPI.OpenLineDevice(cbxLines.Text, txbPhoneNumber.Text))
                    {
                        // Telefonla arama başarılı. btnHangup kullanıma açık.
                        btnHangup.Enabled = true;
                    }
                    else
                    {
                        MessageBox.Show("Telefon araması yapılamadı.");
                    }//if
                }
                else
                {
                    MessageBox.Show("Yeni arama yapmadan önce telefonu kapatın.");
                }//if hCall
            }
            else
            {
                MessageBox.Show("Telefon numarasını giriniz.");
            }//if Text.Len
 
        }//btnDial_Click
 
        // "Telefonu kapat" düğmesine basılınca, yapılan aramayı iptal eder.
        private void btnHangup_Click(object sender, EventArgs e)
        {
            btnHangup.Enabled = false;      // Kullanıma kapalı
 
            // DropCall metodunu çağır ve dönen değeri kontrol et.
            if (TAPI.DropCall(TAPI.hCall))
            {
                // Telefonu kapatma başarılı.
                txbPhoneNumber_TextChanged(sender, e);
            }
            else
            {
                MessageBox.Show("Telefon kapatılamadı.");
            }//if
 
        }//btnHangup_Click
 
        // "Çevirme özellikleri" düğmesine basılınca, bir hatla ilgili
        // telefon ve modem seçenekleri penceresini açar.
        private void btnDialProps_Click(object sender, EventArgs e)
        {
            // Seçili bir hat için telefon ve modem seçenekleri penceresini açar.
            if (!TAPI.DialingPropertiesDialog(cbxLines.Text))
            {
                MessageBox.Show("Telefon ve modem seçenekleri diyalogu açılırken hata oluştu.");
            }//if
 
        }//btnDialProps_Click
 
        // "Hat ayarları" düğmesine basılınca, hattın ayarlar penceresini açar.
        private void btnLineConfigDlg_Click(object sender, EventArgs e)
        {
            // Seçili bir hat için ayarlar penceresini açar.
            if (!TAPI.LineDeviceConfigDialog(this.Handle, cbxLines.Text))
            {
                MessageBox.Show("Hat ayarları diyalogu açılırken hata oluştu.");
            }//if
 
        }//btnLineConfigDlg_Click
 
        // "Konum" düğmesine basılınca, yürürlükte olan kayıtlı ülke ve şehir kodunu verir.
        private void btnLocationInfo_Click(object sender, EventArgs e)
        {
            // Kayıtlı durumdaki ülke ve şehir kodunu verir.
            MessageBox.Show("Ülke - Şehir kodu: " +
                "+" + TAPI.CountryCode + " (" + TAPI.CityCode + ")");
        }//btnLocationInfo_Click
 
        // "Çıkış" düğmesine basılınca, uygulamadan çıkılır.
        private void btnClose_Click(object sender, EventArgs e)
        {
            Application.Exit();     // Uygulamayı sonlandır
        }//btnClose_Click
 
        private void cbxLines_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Hat adını alıyoruz.
            string sLineName = cbxLines.Text;
 
            // Hat adı  boşsa kontrol et.
            if (sLineName != String.Empty)
            {
                // Bir LineClass nesnesi oluşturuyoruz.
                // Hattın özelliklerine erişmek için GetLineByName metodunu çağırıyoruz.
                LineClass lnc = TAPI.GetLineByName(sLineName);
 
                // lnc nesnesinin özelliklerini kullanarak, hat bilgilerini
                // metin kutusuna yazdır.
                txbLineInfo.Text = lnc.GetLineInfo();
 
                // Form üzerindeki bazı buttonları kullanıma aç.
                btnDialProps.Enabled = true;
                btnLineConfigDlg.Enabled = true;
                btnLocationInfo.Enabled = true;
            }//if
 
        }//cbxLines_SelectedIndexChanged
 
        private void txbPhoneNumber_TextChanged(object sender, EventArgs e)
        {
            // txbPhoneNumber metin kutusuna giriş yapılırsa,
            // "Telefon no. çevir" düğmesini seçilir konuma getir.
            btnDial.Enabled = (0 < txbPhoneNumber.Text.Length) &&
                (txbPhoneNumber.Text.Trim() != String.Empty);
        }//txbPhoneNumber_TextChanged
 
    }//class frmTelephony
}

Uygulamayı çalıştırdığımda kendi bilgisayarımdaki ekran görüntüsü aşağıdaki gibidir:

"Çevirme özellikleri" düğmesine basılınca, denetim masasındaki telefon ve modem seçenekleri penceresini karşımıza getirir.

"Hat ayarları" düğmesine basılınca, seçili bir hat için ayarlarla ilgili pencereyi açar. Burada bazı ayarları değiştirebilirsiniz. Örneğin, arama tercihleri, veri bağlantı tercihleri, donanım ve uçbirim ayarları v.b. belirleyebilirsiniz.

"Konum" düğmesine basılınca, kayıtlı ülke ve şehir kodunu verir.

Sonuç:
Makalemizde çok bilinen bazı temel TAPI hat fonksiyonlarını, hat yapılarını ve hat mesajlarını bir sınıf içinde inceledik. Bir TAPI oturumu başlatmayı, TAPI sürümü sorgulayıp bulma, hat sayılarını ve özelliklerini bulma, hat açma, arama yapma, aramayı sonlandırma, hattı kapatma TAPI servisi isteklerinin nasıl yapılacağını öğrendik. Bunlarla beraber TAPI hat olaylarını izleme ve mesajları kullanıcıya aktarmayı gördük. Son olarak, modem ve hatla ilgili seçeneklerin ve ayarlarıyla ilgili diyaloglarının nasıl çağrılacağını gösterdik. Resimlerden görüldüğü gibi TAPI konusunu işleyebilmek için basit bir görsel uygulama hazırladık.

Makalemin sizlere yararlı olması dileklerimle, hoşçakalın...

Örnek kod için tıklayın.

Süleyman Payaslı
s_payasli@hotmail.com

Kaynaklar:
MSDN Library > Platform SDK: Telephony Application Programming Interfaces
Network Programming in .NET - Fiach Reid (Elsevier Digital Press-2004)
Burak Selim Şenyurt - Enum Sabitinin Bilinmeyen Yönleri
Sefer Algan - WinAPI Fonksiyonlarının C#’ta Kullanımı
Çiğdem Çavdaroğlu - Windows API - Pencerelerle İlgili İşlem Yapan API Fonksiyonları

Makale:
TAPI Uygulaması: Ses Modemiyle Telefonu Kullanma C#, Visual C# ve .NET Süleyman Payaslı
  • Yazılan Yorumlar
  • Yorum Yaz
Bu konu hakkında yayınlanan yorum bulunmamaktadır.
"Yorum Yaz" tabını kullanarak sizde yorumlarınızı yazabilirsiniz.
Yorum yazabilmek için üye girişi yapmalısınız. Üye girişi için tıklayın.
Üye değilseniz Üyel Ol linkine tıklayarak üyeliğinizi hemen başlatabilirisniz.
 
  • Bu Konuda Son 10
  • Eklenen Son 10
  • Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor