GridView'den Excele export işlemi

Table excelTable = new Table(); excelTable.GridLines = GridLines.Both; foreach (GridViewRow gvRow in GridView1.Rows) { excelTable.Rows.Add(gvRow); } StringWriter yaz = newStringWriter(); HtmlTextWriter htw = new HtmlTextWriter(yaz); excelTable.RenderControl(htw); Response.Clear(); Response.AddHeader("content-disposition", "attachment;filename=dosyaismi_+ DateTime.Today + ".xls"); Response.ContentType = "application/ms-excel"; Response.Write(yaz.ToString()); Response.End(); Dosya isminin önün tarih eklenmesinin sebebi dinamik dosyalama ve her seferinde aynı dosyanın oluşmasını engellemek amacıyla yapılmıştır.  

C++ ile Nesne Yönelimli Programlamaya Giriş

Bir programlama dilinin nesneye yönelik programlama dili olması için 3 kavramı içermesi gerekmektedir. Bütün nesne yönelimli programla dilleri bu 3 özelliği kapsamaktadır. Bunlar ; -          Encapsulation (Kapsülleme) -          Polimorfizm (Çok Biçimlilik) -          Inheritence (Kalıtım) Şeklinde olup kısaca kapsülleme; private,public gibi anahtar kelimeleri ile veriye nasıl erişebildiğini özetler. Kalıtım; bir sınıfın diğer bir sınıf tarafından kalıtım işleçlerini kullanarak izin veriler üye değişkenlerine ve fonksiyonlarına erişebilmesini sağlar. Türeyen sınıf ise bambaşka bir iş yapabilir. Polimorfizm; Çok biçimlilik diyede kaynaklarda geçmekte olup virtual ve override anahtar kelimelerinin sıkça kullanılabildiği anahtar kelimeleridir. Adında da anlaşılacağı gibi kalıtım ile aldığınız bir sınıfın bir metodu virtual ise türemiş sınıfta bunu override ederek fonksiyonun içeriğini değiştirebilmektesiniz. Başlangıç için basit bir C++ programı; #include <iostream> using namespace std; int main(){ cout<<”Volkan Atasever”  } Bu program ekrana Volkan Atasever yazacaktır. C dilinde de aynı programı sadece cout ifadesini değiştirerek yazabiliyorduk. SINIFLAR            Sınıflar class anahtar kelimesini kullanara deklare edilir. İleride tanıtacağımız struct yapısıda bir class’ın fonksiyon içermeyen hali olarak düşünebilirsiniz. Şimdilik bu kadarını bilmeniz yeterli. class deneme{  public:                     int a; private:                     int b; }; Şeklinde 2 integer üyesi olan bir sınıf tanımlamış olduk bu değişkenlerin arasındaki tek fark public ve private olarak tanımlanmış olması. Nedir bu public ve private ?  public değişkenler sınıfmızın üstünden her zaman erişilebilir üyyelerdir. Private değişkenler ise kalıtım ile alınmış olsalar dahi sınıfın haricinde hiç bir yerde kullanılamazlar.deneme sınıfımızı biraz daha geliştirelim.  class deneme{             string ad;             public:             string beni_oku();             void beni_yaz(string isim); }; Gördüğünüz gibi sınıfımızı yazmamıza rağmen fonksiyonlara hiçbir şey yazmadık. Sınıfımız içinde tanımladığımız bu fonksiyonlar sadece birer prototipdir. Sınıf dışında bu fonksiyonları tanımlayabiliriz. string deneme::beni_oku(){             cout<<”bir isim girin ve ardından enter tuşuna basınız”;             cin>>ad;             return ad; } void deneme::beni_yaz(string isim){             cout<<isim; } Şeklinde tasarladığımız fonksiyonları ana yordamımızdan çağırmak gerekirse; int main(){             deneme obj;             obj.beni_yaz(obj.beni_oku); } Şeklinde çalıştırdığımızda bizden bri isim girmemizi isteyecek ardından girdiğimiz ismi tekrar yazdıracaktır. Burada dikkat edilmesi gereken komple bir sınıf tasarladığımız ve fonksiyonlarıyla işe yarayan bir program yapmış olmamızdır.Bu programda değinmediğimiz konulara sırasıyla değinmemiz gerekirse; string bir veri tipidir. İnteger veri tipi gibi ilkel bir tiptir. Void geriye hiçbirşey döndürmeye ve bir anlamı olmayan bir anahtar kelimedir. Fonksiyonları yazış kuralımız C++ dilinin kurallarındandır. Fonksiyonlarda sınıfın içindeki veri tiplerine ismiyle erişebilirsiniz. Sınıf ismi ve kendi verdiğimiz bir isim şeklinde yazdığımız deneme obj; de ise obj rasgele verilmiş bir isimdir bu verdiğimiz isimle beraber RAM’de yer ayrılır ve sınıfımız artık bir nesne olmuştur. Bu sınıfın içindeki metodlara ise ‘.’ İşleci ile erişebiliyoruz.             Obj.beni_yaz(obj.beni_oku); kısmındaki dikkat edilecek kısım beni_oku fonksiyonu bir string değer döndürüyor ve beni_yaz fonksiyonuda parantezler arasındada gördüğünü gibi bir string veri bekliyor. Bu kullanım tarzı ile fonksiyonlarımızn ihtiyaçlarını karşılayabildik.

C# ile Oyun Yapımı Tekniklerine Giriş

Yıllardır programcılar C,C++ veya java gibi oldukça dezavantajları olan programlama dilleri ile oyun kodlamaya çalışmaktadırlar. Bunlar arasında C yapısal bir programlama dili olduğu için programcıyı en zorlayan ve karmaşık kodlar arasında programcının kaybolmasını sağlayan bir yapıya sahiptir. C++ ve Java için aynı şeyi söylemek mümkün değilken yinede bazı dezavantajları bulunmaktadır.             C# için ise aynı şeyi söyleyemeyeceğim. Çok kullanışlı bir dil olmasına rağmen programcılar daha çok database programlamada bu dile rağbet etmektedir. Bizim üstünde duracağımız konu ise C# ile C++ veya Java’ya nazaran daha kolay bir şekilde oyun programlama yapabileceğimizdir. Bu kolaylıklar getiren ve durmadan gelişmekte olan dilin sadece Database programlamada kullanılması biraz saçma olurdu zaten. Şu anda DirectX veya diğer SDK lar ile kolayca programlama yapabilmekteyiz. Fakat oyun programlamaya yeni başlayan biri için DirectX biraz karmaşık gelebilir. En azından hiç oyun yazmamış birinin bu mantığı programa oturtmasında zorluklarla karşılaşılabilir. Bunun içinde temel bir oyun programlama mantığı ile “oyunları nasıl programlayabiliriz ? “ soru cümlesinin üstünde durmak isterim.            Sıradan bir Jackpot düşünün kolu çekiyorsunu ve simgeler sırayla dönüyor ve rasgele bir şekilde 3 sıralama karşımıza çıkıyor. Bu sayının 3 olması standart bir işlem olmayıp 3,4 veya 5 li kombinasyonlara görede sıralama yapabiliyoruz.           3 sıralı bir jackpotun karmaşıklığını ele alırsak ve her bir sırada da 4 adet simgenin ardarda döndüğünü düşünürsek toplamda elimizde 4 adet simge olacaktır ve biz bu 4 simgenin 3 lü sıralanışlarını ele alacağız. Olasılığımız ise 64 olacaktır.           Jackpot gerçek hayatta mekanik bir yapıyla hareket etmekteyken biz yazılımsal bir yöntemle yaklaşacağımız için bu mekanişk yapının mantığını kağıda aktarmamız gerekecek. Olasıklarımız 64 adet olduğuna göre ve bu 64 olasılığı tutacağımız bir dizi işimizi görecektir. Mekanik yapıda şans devredeyken yazılımsal yapıda da aynı metodu ve rasgeleliği programımıza uygulamak için randomize ifadeler işimize yarayacaktır.          Oyun tekniğimiz bu kadar basitken görselliğimizde oyun yapımcısının ellerindedir. İster çok kötü bir kullanıcı arayüzü ile bu işi halledelim, ister Las Vegas’dan alınmış bir jackpot görünümü verelim Arka planda en iyi teknikleri kullanmış olsanızda çok kötü gözüken bir oyun hiç tutmayacaktır. . Oyunun kullanıcı arayüzü de oyun programlamada geniş bir yer tutmakta olup bu yazımız da bunu gözardı etmek durumunda kalacağız. Oyunun görünümü kullanıcının oyunun başında ne kadar kalacağı ve oynama sıklığı ile doğru orantılıdır.        Basit bir Jackpot programlamaya kalktığımızda öncelikle ortaya koyduğumuz kombinasyonları basit bir ifade ile diziye aktarmak olacaktır. Bu olasılıklar dizisini basit bir kod parçasıyla yazmamız mantıklıyken kombinasyonları görmemiz açısından tek tek elle yazmak bizim için daha yararlı olacaktır.         Her bir resmimize bir rakam verelim bunlar sırasıyla 0,1,2,3 olsun. Birinci resmimiz 0, ikinci resmimiz 1 , üçüncü resmimiz 2 ve son resmimiz ise 3 numaralı sayı ile temsil edilmektedir. Toplam olasılığımızı ve resimlerin değişik kombinasyonlarını 3 lü sırada yazalım; 0,2,0  0,2,1  0,2,1  0,2,3 1,0,0  1,0,1 1,0,2 1,0,3 2,0,0  2,0,1  2,0,2  2,0,3  3,0,0 3,0,1 3,0,2 3,0,3 0,1,0 0,1,1 0,1,2 0,1,3 1,1,0 1,1,1 1,1,2 1,1,3 2,1,0 2,1,1 2,1,2 2,1,3 1,2,0  1,2,1 1,2,2 1,2,3 0,3,0 0,3,1 0,3,2  0,3,3  3,3,0 3,3,1 3,3,2 3,3,3 3,1,0  3,1,1 3,1,2 3,1,3 2,2,0 2,2,1 2,2,2 2,2,3 1,3,0 1,3,1 1,3,2 1,3,3 0,2,0  0,2,1  0,2,2  0,2,3 3,2,0 3,2,1 3,2,2 3,2,3 2,3,0 2,3,1 2,3,2 2,3,3     Bu 4’lü gruplarımızdan toplamda 16 adet bulunmaktadır. Önemli olan ise bizim için 64 sayısıdır çünkü jackpotun kolunu çevirdiğimizde bunlardan herhangi biri karşımıza gelmektedir. Randomize bir sayı oluşturup ardından 1 ile 64 arasında bize bir rakam verirse karşımızda rasgele koluna başılmış ve gerçek hayatta jackpotun işini yani içerdiği simgelerin rasgele sırlanışını elde etmiş oluruz.          Artık temel oyun mantığımız hazır ve sırada sadece bu mantığı kodlamak kaldı bu mantığıda kod becerimize göre bir kabiliyetle kodlayabiliriz. Oyunda 4. Resim 3 tane çıkarsa oyuncu kazanır şeklinde bir mantık eklememiz çok kolay 64 sayısını randomize komutuyla elde ettiğimiz de oyuncu kazanacaktır veya birinci resim ilk iki karede çıkarsa 3. Nolursa olsun parasının iki katını kazanması için [1,1,0][1,1,1][1,1,2][1,1,3] kombinasyonlarından birisinin gelmesi yeterlidir.          Aslında bunun Jackpot uygulaması için zor bir yol olduğunu ve C# programlama dili ile daha basit bir yolunun olduğunuda söylemek isterim. Klasik olarak yolumuz bu şekildeyken bir Timer nesnesi işimizi dahada kolaylaştırabilir. Peki, “bu timer nesnesi nedir ve nasıl bu işi daha kolay bir şekilde yapabiliriz ? ” sorusunu C# kodumuzun üstünde açıklamak isterim.         Öncelikle Windows projesi oluşturup basit bir kullanıcı arayüzü yapalım burada para atacağımız bir kısım, bir kol, 3 adet imagelerimizi barındıracağımız bir picturebox, 4 veya daha fazla jetonlarımız ve birde kasamızda ne kadar bulunduğunu gösteren label veya textbox ile bu işe başlayalım. Yaptığım örnek uygulamanın görüntüsü aşağıdaki gibidir;   Öncelikle oyunumuzu hazırlamak için alanlarımızı ve metodlarımızı belirleyelim ve windows uygulamasına ekleyeceğimiz bileşenleri inceleyelim;       4 adet timer kontrolü ekleyelim ve bir tanede imagelist kontrolü. Bu imageliste göstereceğiniz 4 adet resim ekleyin.       Alanlarımız;       int[] tut;       int para = 0;       int oyun = 0;       Çekeceğimiz kolun ters bir görünümünü alıp form load’un da bu picturebox’ın visible özelliğini false yapmamız gerekmektedir. Böylece kolu çekteğimizde oyuncu kolun aşağıya indiğini görecektir.       Ardından bir baslangic metodu tasarlayalım;      private void baslangic()     {         int[] timrand = new int[3];         tut = new int[3];        for (int i = 0; i < 3; ++i)        {               tut[i] = 0;        }         Random rast = new Random();       timrand[0] = rast.Next(100, 250);       timrand[1] = rast.Next(100, 250);       timrand[2] = rast.Next(100, 250);       timer1.Interval = timrand[0];       timer2.Interval = timrand[1];       timer3.Interval = timrand[2];       timer4.Interval = 1000;    }              Timer1,timer2,timer3 ve timer4 eklediğimiz timerların isimleri. Timrand isimli integer dizimiz ve tut isimli dizimiz 3 boyutludur. Bir döngü ile tut dizimizin bütün indislerini sıfır yapıyoruz. Rast isminde bir Random nesne nesne oluşturup 100 ile 250 arasında bir değer tutmasını istiyoruz. Randomize rakamları timrand dizilerinin indislerine sırayla atıyoruz. Timerlarımızın interval özelliğini bu rakamlarla belirliyoruz. Böylece yaşam döngüsü birbirinden farklı timerlarımız oluyor.            Bu arada cash sistemini yapmak amacıyla Sürükle-Bırak işlemlerini pictureboxlarımızla ve textbox için yapılandırıyoruz.          private void pictureBox5_MouseDown(object sender, MouseEventArgs e)          {                   if (e.Button == MouseButtons.Left)                {                       pictureBox5.DoDragDrop("10", DragDropEffects.All);                       para += 10;                 } }            Yukarıdaki sarı,kırmızı,mavi ve yeşil para görünümde kutucuklar için bu işlemi yapıyoruz. Farklı olan değerimiz sadece para+=10 işaretindeki 10 sayısı olacaktır çünkü her paranın farklı değeri olacaktır.           DragDrop işleminde textbox için ekleyeceğimiz kod ise aşağıdaki gibidir; private void textBox2_DragDrop(object sender, DragEventArgs e) {           int t;           textBox2.Text = e.Data.GetData(DataFormats.Text).ToString();           t = (Convert.ToInt32(textBox1.Text) - Convert.ToInt32(textBox2.Text));           if (t =< 0)           {                 MessageBox.Show("Not Enough Coin");           }          else               textBox1.Text=t.ToString();   }          Kasamızda para kalmamışsa “Not Enough Coin” hatası alacağız. Textboxın dragover event’ine ise şu kodu ekleyelim; private void textBox2_DragOver(object sender, DragEventArgs e) {         if (e.KeyState == 1)        {                e.Effect = DragDropEffects.Copy;          } }          Randomize seçtiğimiz ilk 3 timer’ın tick event’ine ise aşağıdaki kodları ekleyelim; private void timer1_Tick(object sender, EventArgs e) {             pictureBox1.Image = ımageList1.Images[tut[0]];           tut[0]++;           if (tut[0] == 3)            tut[0] = 0; }   private void timer2_Tick(object sender, EventArgs e) {            pictureBox2.Image = ımageList1.Images[tut[1]];            tut[1]++;             if (tut[1] == 3)             tut[1] = 0; }   private void timer3_Tick(object sender, EventArgs e) {          pictureBox3.Image = ımageList1.Images[tut[2]];          tut[2]++;         if (tut[2] == 3)                tut[2] = 0; }                Ardından çekeceğimiz kolun yani picturebox’ın üstüne çift tıklayıp aşağıdaki kodu yazalım; private void pictureBox4_Click(object sender, EventArgs e) {             if (para != 0 & textBox2.Text!="")           {                  baslangic();                  pictureBox10.Visible = true;                  pictureBox4.Visible = false;                     timer1.Start();                     timer2.Start();                     timer3.Start();                     timer4.Start();          }          else          {                 MessageBox.Show("Please Take Coin.");           } }               Dikkat ederseniz ilk 3 timer’ın tick event’leri için belirli bir kod yazmıştık fakat aynısını 4. ve en önemli olan timer4 ün click evet’i için yapmadık. Çok önemli bir event ve oyunu sağlayan en önemli eventlerden biri. Kod aşağıda; private void timer4_Tick(object sender, EventArgs e) {          oyun++;           if (oyun == 8)           {                   timer1.Stop();                   timer2.Stop();                   timer3.Stop();                   timer4.Stop();                  if (tut[0] == 0 & tut[1] == 0 & tut[2] == 0)                  {                               MessageBox.Show("You WIN");                               int temp1 = Convert.ToInt32(textBox1.Text) + (para * 10);                               textBox1.Text = temp1.ToString();                   }                  else                  {                          MessageBox.Show("You Loose");                   }                 pictureBox4.Visible = true;                  pictureBox10.Visible = false;                oyun = 0;                para = 0;               if (Convert.ToInt32(textBox1.Text) <= 0)               {                            MessageBox.Show("game over");                           Application.Exit();                }           } }             Bundan sonra kazanca ve kayba göre her kolu çektiğimizde oyunumuzu oynayabiliyoruz. Her birisi farklı hızda dönüp farklı zamanlarda duruyorlar. Timer kontrolümüzünde önemli bir kullanımı göstermiş olduk.             Başlangıç kısmında anlatmış olduğum olasılık ile ilgili probleminde kullanım alanları vardır mesela bu mantığı aynısını bulma oyunu için uyarlayabilirsiniz.

VB.NET ile PDF Yaratma ve İşleme

VB.NET ile 3. Parti yazılımlar kullanarak PDF yaratma, işleme ve çeşitli özelliklerle PDF dosyaları üzerinde yapılan işlemleri örnek kodlar eşliğinde anlatmaya çalışıyoruz. --------------------------------------------------------------------------------------------------- Makalemde, sizlere VB.NET ile PDF yaratma ve PDF işleme ile ilgili bilgiler sunacağım. Projemize 3. Parti bir DLL ekleme zorunluluğumuz var bu dll’i http://www.tallcomponents.com/default.aspx?id=tallpdf3-download adresinden de çekebilirsiniz. Piyasada sınırsız bu işi yapan DLL ler varken bu firmanın dll’ini seçmemdeki amaç tamamen sınırsız kullanıma açık olmasıdır. Belli bir zaman kısıtlaması olmamasına rağmen deneme sürümü olduğunu uygulamamızda belirtiyor.          Buna ek olarak tamamen ücretsiz zLib’i de önerebilirim bu dll ise tamamen ücretsiz TallComponents’e göre doküman eksikliği biraz var ama source’ları açık olduğu için istediğiniz atraksiyonu yapabilirsiniz. zLib içinde http://www.componentace.com/zlib_.NET.htm adresini kullanabilirsiniz. Bu makalemde zLib örneklerine değinmeyeceğim. Projemize referans olarak: TallComponents.PDF.Layout.DLL dosyasını eklemeniz gerekli. Ardından çeşitli atraksiyonları PDF üzerinde gerçekleştirebiliriz. Bir PDF dosyası yaratmak için aşağıdaki kodu kullanabilirsiniz: Imports System Imports System.IO Imports TallComponents.PDF.Layout Imports TallComponents.PDF.Layout.Paragraphs Namespace TallComponents.Samples.TallPDF Public Class HelloWorld Shared Sub Main()   ' Using    Dim file As FileStream = New FileStream("..\..\HelloWorld.pdf", FileMode.Create, FileAccess.Write)    Try                     Dim document As Document = New Document                     Dim section As Section = document.Sections.Add                     Dim textParagraph As TextParagraph = New TextParagraph                     section.Paragraphs.Add(textParagraph)                    Dim fragment As Fragment = New Fragment                     fragment.Text = "Hello world!"                     textParagraph.Fragments.Add(fragment)                    document.Write(file)        Finally                   CType(file, IDisposable).Dispose()        End Try End Sub End Class End Namespace Hazır bulunan bir text dosyası veya text üzerinde biçimsel işlemler yaparak PDF olarak kaydetmek çok basit metodlarla mümkün kodun açıklaması kodun içinde yapılmıştır. Imports System Imports System.IO Imports TallComponents.PDF.Layout Imports TallComponents.PDF.Layout.Paragraphs Namespace TallComponents.Samples.TallPDF Public Class TextFormatting                 Const text As String = "With TallPDF.NET you can create PDF documents " + "by building an instance of the TallPDF.NET Document " + "Object Model. The TallComponents team has produced " + "a DOM that is extremely intuitive and yet powerful. " + "This allows you to create both simple and complex " + "documents fast." Shared Sub Main()                 ' Using                  Dim file As FileStream = New FileStream("..\..\TextFormatting.pdf", FileMode.Create, FileAccess.Write)                            Try                                  Dim document As Document = New Document                                  Dim section As Section = document.Sections.Add                                  section.PageSize = PageSize.A4                                  Dim textParagraph As TextParagraph                                   section.Paragraphs.Add(CreateTextParagraph("TextParagraph with default properties:"))                                   section.Paragraphs.Add(CreateTextParagraph(text, System.Drawing.Color.Blue))                                  section.Paragraphs.Add(CreateTextParagraph("textParagraph.HorizontalAlignment = HorizontalAlignment.Right"))                                 textParagraph = CreateTextParagraph(text, System.Drawing.Color.Blue)                                 textParagraph.HorizontalAlignment = HorizontalAlignment.Right                                 section.Paragraphs.Add(textParagraph)                                 section.Paragraphs.Add(CreateTextParagraph("textParagraph.HorizontalAlignment = HorizontalAlignment.Center"))                                 textParagraph = CreateTextParagraph(text, System.Drawing.Color.Blue)                                 textParagraph.HorizontalAlignment = HorizontalAlignment.Center                                 section.Paragraphs.Add(textParagraph)                                 section.Paragraphs.Add(CreateTextParagraph("textParagraph.Justified = true"))                                 textParagraph = CreateTextParagraph(text, System.Drawing.Color.Blue)                                 textParagraph.Justified = True                                 section.Paragraphs.Add(textParagraph)                                 section.Paragraphs.Add(CreateTextParagraph("textParagraph.LineSpacing = 5"))                                 textParagraph = CreateTextParagraph(text, System.Drawing.Color.Blue)                                  textParagraph.LineSpacing = 5                                  section.Paragraphs.Add(textParagraph)                                 section.Paragraphs.Add(CreateTextParagraph("textParagraph.FirstLineIndentation = 20"))                                 textParagraph = CreateTextParagraph(text, System.Drawing.Color.Blue)                                 textParagraph.FirstLineIndentation = 20                                 section.Paragraphs.Add(textParagraph)                                 section.Paragraphs.Add(CreateTextParagraph("textParagraph.HangIndentation = 20"))                                  textParagraph = CreateTextParagraph(text, System.Drawing.Color.Blue)                                 textParagraph.HangIndentation = 20                                 section.Paragraphs.Add(textParagraph)                                 document.Write(file)                      Finally                                 CType(file, IDisposable).Dispose()                      End Try End Sub Private Shared Function CreateTextParagraph(ByVal text As String) As TextParagraph                       Return CreateTextParagraph(text, System.Drawing.Color.Black) End Function Private Shared Function CreateTextParagraph(ByVal text As String, ByVal textcolor As System.Drawing.Color) As TextParagraph                             Dim paragraph As TextParagraph = New TextParagraph                             Dim textFragment As Fragment = New Fragment(text)                             textFragment.TextColor = textcolor                             paragraph.Fragments.Add(textFragment)                             paragraph.SpacingAfter = 10                             Return paragraph End Function End Class End Namespace Aynı zamanda XML dosyalarınıda PDF formatına çevirebiliyoruz. Örnek XML: '<'document author="Volkan"'>' '<'section pagesize="Letter"'>' '<'!-- İçerik... --'>' '<'/section'>' '<'/document'>' XML dosyamızı PDF çeviren kod bloğu, Dim xml As XmlDocument = New XmlDocument xml.Load("topdf.xml") Dim document As Document = New Document document.Read(xml.DocumentElement) Dim file As FileStream = New FileStream("out.pdf", FileMode.Create) document.Write(file) Burada sayamayacağımız kadar çeşitli örneklerle kütüphane kullanımımızı ve yapacaklarımızı genişletebiliriz. Makalemin başında verdiğim linkten çektiğiniz zLib ile ilgili bir örnek yapmanın önemliliğini vurgulamak isterim her componenet değişik arayüzlerle gelmekte. Yine zLib’i referans olarak eklememiz gerekiyor. Volkan Atasever

Kural Dışı Durum Yönetimi

         Bu makalemde sizlere kural dışı durumlardan bahsedeceğim. Gerçekten kolaylıkla her projenizde ve uygulamanızda kullanabileceğiniz çok önemli bir kavram. İstisnai durumlarda olayları kontrol etmenize kontrol altına almamız açısından göz ardı edilmeyecek , edilemeyecek bir konu. Örneğin, Drag Drop işlemi yapıyorsunuz ve bir listbox’ınızdan diğer listbox’ınıza elemanlardan birini sürükleyip bırakacaksınız. Listbox’ımızın boş bir yerine tıkladığımızda orada bir hata oluşacaktır peki bunu nasıl yok edebiliriz ? (İlerleyen kısımlarda ve uygulamamızda bu istisnai duruma değindik) Cevap aslında çok basit işlemlerimize bir try ve catch anahtar kelimelerinden oluşan standart kullanımımızı eklediğimiz zaman bu istisnai ve olası tek hatayı kontrol altına almış bulunuyoruz. Try , catch dediğimiz zaman artık kural dışı durumlarımızın anahtar kelimelerine girmiş bulunuyoruz. Kural dışı durumlarda toplam 4 anahtar kelimemiz bulunuyor ve bunların incelikleriyle her istisnai durumu yakalayabiliyoruz. Anahtar Kelimeler: Try, Catch, Finally, Throw .       Try Catch kullanımın temel örneğini verecek olursak,                    try{                  //Hata oluşan veya duruma göre oluşabilecek kod bloğu           }         catch{                //Hataların yakalandığı yer         }                 try bloğundaki her türlü hatayı catch ifadesi kısmında yakalanacaktır. Burada her türlü hatayı yakalayabilmektedir fakat biz 2 hata çıkma olasılığı görüyoruz ve bu hata ihtimallerine göre farklı işlemler yaptırmak istersek tek catch ifadesi yetersiz kalacaktır. İki catch ifadesi kullanabilmeliyiz yine de iki ayrı durumu ele almalıyız işte burada devreye Exception sınıfı diye bir kavram giriyor ve bahsetmeden geçmek silahımızı kuşanmadan düello yapmaya benzemektedir. O zaman Exception sınıfımız ve standart türetilmiş exception’larımıza(kural dışı durum) değinelim. C# taki her kural dışı durum Exception sınıfından türetilmektedir. Her kral dışı durum Exception sınıfının bir alt üyesidir. C# ta Exceptionlar iki kategoriye ayrılmıştır uygulama programı(ApplicationException) üzerinde oluşan istisnai durumlar ve sistem istisnai durumları(SystemException). System uzay alanında (Namespace) tanımlı Derleyiciyle birlikte gelen Exception’ların bir kısmına göz atacak olursak: DivideByZeroException: Sıfıra bölme hatasında oluşan exception IndexOutOfRangeException: Dizinin sınırı dışına çıkılmıştır ( C’ deki deyimiyle dizi taşmıştır) NullReferenceException: Null referans üzerinde işlem yapılmaktadır. Başka bir nesneyi göstermemektedir. İsterseniz bu kullanımları bir Windows uygulaması üstünde inceleyelim ve böylece teoride kalmaz ve işlemlerimizi pratiğe dökeriz.           Tasarımımız aşağıdaki gibi olsun:    Visual Studio.NET imizi açıp Windows application’ı seçtikten sonra Formumuza standart gelen namespace’lere şunları da ekleyelim: using System.Data.SqlClient; using System.Data.SqlTypes; using Microsoft.SqlServer.Server; Bu isim alanlarımız SqlException denememiz için gerekli. Sqlserver’a bağlanmayı deneyeceğiz. Ardından sınıfımızın içine şu alanları ekleyelim:             public partial class Form1 : Form            {                    int[] iAdizi = new int[10];                    int iTut = 0;                    public Form1()                    {                          InitializeComponent();                     }             }          Bu iki alan Dizi Taşması örneğimiz için eklenmiştir.          DivideByZero denemesi isimli groupbox’ımızdaki butona çift tıklayalım ve şu kodları yazalım sırasıyla studio.NET le standart gelen isimleri kullandık. Kodlarımız:             int iSayi1,iSayi2;             try              {                          iSayi1 = Convert.ToInt32(textBox1.Text);                          iSayi2 = Convert.ToInt32(textBox2.Text);                           iSayi1 /= iSayi2;                           MessageBox.Show("Herhangi Bir Hata Meydana Gelmedi ve Buraya Kadar Geldi Sonuç= " + iSayi1);               }              catch (DivideByZeroException)            {                          MessageBox.Show("Sıfıra bölme hatası Catch'e Düştü");             }            catch            {                          MessageBox.Show("İkinci catch: herhangi bir hata meydana geldi");             }                  Bu deneme amaçlı ve istediğiniz herşeyi deneyebilirsiniz bölüme sıfır girdiğinizde DivideByZeroException’a düşecektir. Diğer hata durumlarında ikinci catch’e yakalanacaktır. Tabiki de burada ardıardına iki catch kullandığımızı unutmamalıyız ikinci catch bütün hataları yakalamaktadır eüer ilk catch’den önce ikincisini yazsaydık yani DivideByZeroException lı catch’imizi ikinci catch olarak ele alsaydık oraya asla düşmezdi çünkü her hatayı yakalayan catch { } ifademiz hatayı yakalayıp çıkacaktı. Fakat DivideByZeroException kontrolümüz gerçekleşemeyecekti. Dizi Taşması örneği adlı groupbox’ımızdaki butona tıklayıp şu kodları yazalım:             try            {                            iAdizi[iTut] = Convert.ToInt32(textBox3.Text);                             iTut++;                            listBox1.Items.Add("" + iTut + " indise " + iAdizi[iTut-1] + " Eklendi");              }            catch (IndexOutOfRangeException)            {                            MessageBox.Show("Dizinin indeksini aştın 10 elemandan fazla Girdin ve catch'e yakalandım aslıdna istediğimizde buydu");                            listBox1.Items.Add("Hata");             }             catch          {                           MessageBox.Show("Diğer hata meydana geldi Sadece Sayı girmeliydin bu gerçekten beklenmedik bir hata");                           listBox1.Items.Add("Diğer bir Hata");          }           Gördüğünüz gibi dizimizin sınırları dışına çıkarsak IndexOutOfRangeException tarafından bu hata yakalanmaktadır. Burada her tıkladığımızda ilk indisten başlayarak dizimize bizim girdiğimiz rakamları yerleştirmektedir. Dizimizi ve iTut alanımızı sınıfımızın başında tanımlamıştık. Diğer hatalar mesela textboxın boş bırakılması veya karakter girilmesi durumunda ikinci genel catchimiz tarafından yakalanacaktır. Üçüncü olarak throw groupboxımızın butonuna çift tıklayıp şu kodlarıda yazalım (Fırlat butonu) :     try     {         kuraldisi();     }     catch     {         MessageBox.Show("İkinci Kez Yakalandı");     }             Örneğimizi ve throw’u anlamak için de kuraldisi adında bir metot yazmamız gerekli. kuraldisi() metodumuz:     private void kuraldisi()     {         try         {                 MessageBox.Show("Kural Dışı Durum Fırlatılıyor");                throw new IndexOutOfRangeException();        }         catch         {                MessageBox.Show("İstisnai Durum Yakalandı");                throw;         }     }           Fırlat butonumuza tıkladığımızda try bloğumuzuun içindeki kuraldisi(); metodumuz çalıaşcaktır ardından kuraldisi metodumuzda yeni bir exception new lenmekte yani oluşturulmaktadır. Ardından catch ifademize düşmekte ve oluşturduğumuz IndexOutOfRangeException istisnai durumumuz tekrar fırlatılmaktadır ve metodumuzun işleyişi bittiği için butonumuzun Click event’ında kod işleyişi yoluna devam etmektedir. Tekrar “throw;” anahtar kelimesi ile fırlattığımız istisnai durum bu sefer ikinci kez catch’e yakalanacaktır.           Checked Uncheck denemesi adlı dene adlı butonuzumuzun click event’inede şunları yazalım: int iCSayi1=2000000000,iCSayi2=2000000000; int iSonuc; if (radioButton1.Checked == true) {     try     {         checked         {         iSonuc = checked((int)(iCSayi1 * iCSayi2));         }     }     catch (OverflowException)     {         MessageBox.Show("OverflowException meydana geldi");     } } else {     try     {         unchecked         {         iSonuc = unchecked((int)(iCSayi1 * iCSayi2));        MessageBox.Show("OverflowException a Düşmedi");     }     }     catch (OverflowException)     {     MessageBox.Show("Buraya Düşmeyecek");     } }             Bu örneğimizde eğer radiobutton1’i seçtiğimiz zaman check özelliği eklenerek çalışılmış, radiobuton2 yi seçersek ise uncheckd özelliği ile çalışılmış. Nedir bu checked ve unchecked ? Açıklayacak olursak her dilde her değişkenin belli bir sayı tutma kapasitesi var atıyorum C dilinde integer(tam sayılar) veri tipimiz 2 byte yer kaplıyor ve 32000 i geçemiyor diyelim eğer ikinci değilkenimiz de 32000 olur ve çarpma işlemine tabi tutulursa hesap makinelerinde gördüğüüz kapasite farklılıklarında çık 32323e+2 gibi yazılar yani overflow meydana gelir bunlar artimetik işlemlerde meydana gelme olasılığı olan durumlardır ve bir çok hataya sebebiyet verir. İşte checked özelliği bu kontrolü sağlamamızı unchecked ise gözardı etmemizi sağlar. Checked ve uncheck anahtar kelimelirimiz bu gibi durumlarda büyük bir kurtarıcı rolü oyanamaktadır. Genel kullanımını taslak olarak yazacak olursak:           try{                     checked{                           //Meydana gelecek overflow lara sahip aritmetik işlem                      }            }          catch(OverflowException)          {                       //Overflow durumunda vereceğimiz mesaj            }              Not: Aritmerik işlemimizin önüne yukarıda gördüğünüz gibi checkd veya unchecked ardından da veri tipini yazmamız gereklidir.                 SqlException istisnai durumunu ve database işlemlerinde meydana gelebilecek durumlar içinde SqlException istisnai durumunu kullanabiliriz. Butonumuzun click evventına yine şunları yazalım ( Bu cümleyi çok kullandığımın farkındayım ama hep click eventına yazmak zorundayız ne yapalım ) Kod:         string con = "Data Source=(local);Initial Catalog=benneredeyim;Integrated Security=True";          SqlCommand InsertCurrencyCommand = new SqlCommand();         SqlConnection conn = new SqlConnection(con);         InsertCurrencyCommand.CommandText =         "INSERT tablom(deger)" +         " VALUES('selamlar')";        InsertCurrencyCommand.Connection = conn;        try       {                   conn.Open();                   InsertCurrencyCommand.ExecuteNonQuery();                   MessageBox.Show("Hata Olmadı Burayı Görmen biraz Zor :)");        }         catch (SqlException hata)       {                   MessageBox.Show(hata.Message.ToString());                   MessageBox.Show(" >Hata< !");       }        finally       {                    conn.Close();        }                  Diğer database connectionları SqlCommand üzerinde fazla durmayacağım burada şunu bilmeniz yeterli, büyük ihtimalle sizin Sql Server’ınızda benneredeyim isimli bir database olmadığı ve bir ihtimal olsa bile, içinde tablom isimli ve deger adlı kolona sahip bir tablo olamdığı için hata meydana gelecektir. Buradaki her türlü hatayı SqlException ile yakalayabiliriz. Mesaj kutumuzun içinde hata.Message.ToString() yapmamızın nedeni ise gelen hatayı MessageBox içinde yazdırmak içindir en azından karşınıza Continu veya Quit gibi programın büyük bir hataya sebebiyet verdiği gibi kaba bir kutucuk yerine güzel bir messagebox ile bu işi çözümleyebiliriz. Finally anahtar kelimesindende söz etmek gerekirse hata çıksada çıkmasada o kod bloğu işleyecektir sanırım kolay ama etkileyici bir özelliğe sahip.                   Uygulamamızdaki son örneğimiz ise sürükle bırak işlemleri ile ilgili iki listbox arasında veya bir listbox’dan herhangi bir yere sürükle bırak yaparken başıma gelen ve beni çıldırtan listbox’ın boş bir yerine tıkladığımızda meydana gelen bir hata bunuda kolayca try-catch bloğuyla bertaraf edebiliriz. Sürükle bırak örneğimiz için hazırlanmış olan kodlarımız:          private void listBox2_MouseDown(object sender, MouseEventArgs e)         {                    try                     {                             Point pTut = new Point(e.X, e.Y);                              int iIndeksNo = listBox2.IndexFromPoint(pTut);                               if (e.Button == MouseButtons.Left)                               {                                   listBox2.DoDragDrop(listBox2.Items[iIndeksNo].ToString(), DragDropEffects.All);                                }                     }                    catch                   {                              MessageBox.Show("Lütfen Boş Bir Yere Tıklamayınız");                    }        }         private void listBox3_DragOver(object sender, DragEventArgs e)       {                      if (e.KeyState == 1)                     {                                      e.Effect = DragDropEffects.Copy;                      }       }       private void listBox3_DragDrop(object sender, DragEventArgs e)      {                    listBox3.Items.Add(e.Data.GetData(DataFormats.Text).ToString());       }           Yukarıdada belirtilen her event a altında yazan kodlarımızı yazalım ve örneğimizi tamamlayalım. Sürükleme işlemi mouse’un sol tuşuna basmamızla gerçekleşecektir. Boş bir yere tıkladığımızda ise artık messagebox’ımızla belirttiğimiz uyarıyı kendimiz verebileceğiz isterseniz orayı boş bırakıp hiç bir şey olmamış gibi yolunuza devam edebilirsiniz. Böylece makalemizde kural dışı durumları ve onları yönetmeyi irdelemiş olduk. Eğer makale hakkında soru, görüş veya önerileriniz olursa inhoftec@gmail.com adresine mail atabilirsiniz elimden geldiğince cevaplamaya çalışacağım. Programın çalışan versiyonunu ise örnek kodlar kısmından  indirebilirsiniz. Yazan: Volkan Atasever

Metotların,Kurucuların ve Operatörlerin Aşırı Yüklenmesi

Metotların,Kurucuların ve Operatörlerin aşırı yüklenmesi dair açıklama ve bir windows uygulaması üzerinde açıklaması Yazan: Volkan Atasever            Kurucuların ve operatörlerin aşırı yüklenmesi konusunun daha iyi anlaşabilmesi için öncelikle, metotların aşırı yüklenmesinin izahı daha faydalı olacağı kanaatindeyim. Şöyle ki: Araştırmalarımda ; a)- metotların aşırı yüklenmesi, b)- Kurucuların aşırı yüklenmesi, c)- operatörlerin aşırı yüklenmesi'nin ayrı ayrı ele alındığını tespit ettim. Bu makalemde yukarıda belirttiğim üç hususu bir Windows uygulamasın da ne şekilde tatbik edilebileceğini izaha çalışmak istiyorum.           Bir metodu aşırı yüklemek, aynı isimli birden fazla metodun çalışabilir olması manasına gelmektedir. Tabii bunun içinde bazı kurallarımız vardır. Bunlardan biri, metodumuzun parametrelerinin tiplerinin farklı olmasıdır. Eğer bu koşul sağlanamıyorsa; parametre sayıları farklı olmak zorundadır. Bu koşulu sağladığımızda metodumuza aşırı yüklenmiş diyebiliriz. Dikkat edilmesi gereken diğer bir husus, metodun sadece geri dönüş değerinin farklı bir tipte olması yeterli değildir.           Öncelikle sınıfımızı tasarlayalım ve bu sınıfımızın içinde aşırı yüklenmiş metotlar bulunsun. Bu metotları nesnemiz üzerinden çağıralım.           Sınıfımız: class asiriyukleme {            public string yuklenmis(int iYerel)            {                       return iYerel.ToString();            }            public string yuklenmis(int iYerel1, string sYerel2)            {                       return (iYerel1.ToString() + " " + sYerel2);            }            public string yuklenmis(bool bYerel)            {                       return (bYerel.ToString());            }       }           Yukarıda ki örnekte dikkat etmeniz gereken husus, geri dönüş değerinin sabit olmasına rağmen parametrelerinin farklı tipte olmasıdır.           Kurucuları aşırı yüklemeye gelince sizden şöyle bir mantık yürütmenizi tavsiye edeceğim. Kurucularıda bir süreliğine metot gibi görmelisiniz. Bu bakış açısının ardından çok daha kolay kavranacağı kanısındayım. Geri dönüşü olmayan metotlar!           Kurucularımız içinde farklı bir sınıf tasarlayalım:       class kurucular       {            int iSayi; string sKelime;            bool bMantıksal;            public kurucular()            {                       iSayi = 123;                      sKelime = "Sıfırlandım";                       bMantıksal = true;            }            public kurucular(int a, string b)            {                       iSayi = a;                       sKelime = b;                       bMantıksal = true;            }            public kurucular(bool a)            {                       bMantıksal = a;                       sKelime = "Sıfırlandım";                      iSayi=123;            }            public kurucular(bool a, string b)            {                       bMantıksal = a;                      sKelime = b;                       iSayi = 123;            }            public kurucular(int a)            {                       iSayi = 123;                       bMantıksal = true;                      sKelime = "Sıfırlandım";            } }           Diğer kurucuları yazdığımız için varsayılan kurucuyu da bizim tanımlamamız lazım. Aksi takdir de kurucumuza parametre yollamadığımız zaman, sandığımız gibi varsayılan kurucu çalışmayacak. Hatayla karşılaşmak kaçınılmaz olacaktır. Yukarıda ki kurucular sınıfında farklı parametrelerle çalışabileceğinizi formumuzu da tasarladıktan sonra görebileceğiz.           Operatörlerin aşırı yüklenmesi ise + operatörünün bir metot ismiymiş gibi her atraksiyonu yaptırmamıza yarar ve kod yazarken inanın çok işimize yarayacaktır. Doğru yazılmış bir sınıfla iki nesneyi toplayabiliriz veya nesnenin önüne + ifadesi getirip o nesnedeki alanların pozitif değerlerini alabiliriz. Aynı mantıkla – operandınıda aşırı yükleyebiliriz. Operatörleri aşırı yüklerken;            public static geri_döndürdüğü_sınıf_ismi operator kıstaslarına dikkat etme zorunluluğumuz var.           Operatorler sınıfımız:       class operatorler       {            public int iSayi=0;            public operatorler(int a)            {                       iSayi = a;            }            public static operatorler operator +(operatorler sinif1,operatorler sinif2){                       operatorler don=new operatorler(0);                       don.iSayi=sinif1.iSayi+sinif2.iSayi;                      return don;            }            public static operatorler operator -(operatorler sinif1,operatorler sinif2){                       operatorler don = new operatorler(0);                      don.iSayi = sinif1.iSayi - sinif2.iSayi;                       return don;            }            public static operatorler operator +(operatorler sinif1)            {                       sinif1.iSayi = +sinif1.iSayi;                      return sinif1;            }            public static operatorler operator -(operatorler sinif1)            {                       sinif1.iSayi = -sinif1.iSayi;                       return sinif1;            }      }            Operatörler sınıfımızın kurucusu integer tipinde iSayi isimli bir parametre alıyor. İlk metodumuz iki operatorler tipinden parametresi olan + operandı.           Bir adet geri dönüş değeri için bir nesne daya yaratıyoruz ve geri dönüş tipi yine operatorler sınıfından unutulmaması gereken geri dönüş değeri olarak operatorler nesnesi yerine void tipide kabul edilebilirdi ama tasarımımız da + operantı ile iki nesne toplayacağımız için böyle bir geri dönüş yararlı olamazdı. Metodumuzun içinde ise don adında bir sınıfı 0 değeri ile canlandırıyoruz. Ardından don isimli nesnemize ilk gelen operatorler sınıfından sinif1 adlı nesnenin iSayi isimli alanına ulaşıp, sinif2 adlı nesnemizdeki iSayi ile toplayıp don adlı nesnemizin iSayi isimli alanına atıyoruz. 2 parametre alan – operatörü de aynı şekilde çalışırken aynı sınıftaki tek parametreli + ve – metotları ise daha farklı çalışmaktadır buradada ikinci bir aşırı yüklenme mevcut. Ve gelen nesnenin içindeki iSayi isimli alanın pozitifini veya negatifini yine aynı nesneye atarak geri döndürebiliyoruz.            Windows uygulamamızın tasarımı ise aşağıdaki şekilde:  public partial class Form1 : Form       {            operatorler oDeneme1;            operatorler oDeneme2;            operatorler oDeneme=new operatorler(0);           Formumuza öncelikle operatorler sınıfından oDeneme1 ve oDeneme2 yi deklare etmemiz ardından oDeneme sınıfımızı 0 parametresini kurucuya yollayarak canlandırmamız gerekmektedir.           Kuruculara ait groupboxımızın içinde bulunan comboboxın selectedindexchanged event’ine ise aşağıdaki kodları yazalım:       private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)       {            int i = comboBox2.SelectedIndex;            kurucular kDeneme;            switch (i)            {                       case 0:                                 kDeneme = new kurucular();                                 listBox1.Items.Add("ilk Kurucu Metot Çalıştı");                      break;                      case 1:                                 kDeneme = new kurucular(2, "deneme");                                listBox1.Items.Add("ikinci Kurucu Metot Çalıştı");                      break;                      case 2:                                kDeneme = new kurucular(true);                                listBox1.Items.Add("ucuncu Kurucu Metot Çalıştı");                      break;                      case 3:                                kDeneme = new kurucular(true, "deneme");                                listBox1.Items.Add("dorduncu Kurucu Metot Çalıştı");                      break;                      case 4:                                kDeneme = new kurucular(3);                                listBox1.Items.Add("besinci Kurucu Metot Çalıştı");                      break;            }       }            Üstte ki kodumuzda sabit değerlerle comboboxda seçtiğimiz kurucu varyasyonlarını çalıştırıyoruz.           Metotların aşırı yüklenme örneği içinse, ait olduğu groupbox’a çift tıklayalım ve şu kodları ekleyelim:       int i = comboBox1.SelectedIndex;            asiriyukleme aDeneme = new asiriyukleme();            switch (i)            {                       case 0:                                 try                                 {                                           listBox1.Items.Add(aDeneme.yuklenmis(Convert.ToInt32(textBox1.Text)));                                 }                                  catch                                  {                                            listBox1.Items.Add("Hata");                                             return;                                  }                       break;                       case 1:                                 try                                 {                                           listBox1.Items.Add(aDeneme.yuklenmis(Convert.ToInt32(textBox1.Text),textBox2.Text.Trim()));                                 }                                 catch                                  {                                           listBox1.Items.Add("Hata");                                            return;                                 }                      break;                       case 2:                                 if (textBox1.Text.ToLower() == "true")                                 listBox1.Items.Add(aDeneme.yuklenmis(true));                                  else if (textBox1.Text.ToLower() == "false")                                  listBox1.Items.Add(aDeneme.yuklenmis(false));                                 else                                  listBox1.Items.Add("Hata Lütfen true veya false yazınız");                       break;                      default:                                 listBox1.Items.Add("Lütfen aşırı yükleyeceğiniz metodu seçiniz");                       break;       }           Bu kod parçamızdada textboxlarımızın içindeki değerleri integer tipine çevirip ardından aDeneme nesnesinin üzerinden yuklenmis metoduna parametre olarak gönderiyoruz.aDeneme nesnesinin üzerinde aşırı yüklenmiş yuklenmis metodlarını basit bir switch mantığıyla işliyoruz.           Son olarakta operatorler sınıfımızın kullanımına değinecek olursak:            oDeneme = -oDeneme1;            listBox1.Items.Add("1. Nesnenin Negatifi :"+oDeneme.iSayi);           oDeneme1 nesnesinin üzerinde – operatörünü kullanarak oDeneme nesnesine atıyoruz çünkü geri dönüş değerimizde bir nesne.            oDeneme = oDeneme1 - oDeneme2;            listBox1.Items.Add("1. Nesneden 2. Nesne Çıkarıldı Sonuç:" + oDeneme.iSayi);           Burada ise diğer – operatörümüz çalışmaktadır – operatörünün iki parametre alan hali ile çalışmaktadır.           Operatörler groupboxımızdaki 1. + 2. butonumuzu aşağıda ki gibi:            oDeneme = oDeneme1 + oDeneme2;            listBox1.Items.Add("2. Nesne ile 1. Nesne Toplandı Sonuç:" + oDeneme.iSayi);           ve 2. – 1. metodumuzuda aşağıdaki gibi kodlayalım:            oDeneme = oDeneme2 - oDeneme1;            listBox1.Items.Add("2. Nesneden 1. Nesne Çıkarıldı Sonuç:" + oDeneme.iSayi);           Uygulamamıza görsellik açısından zenginlik katmak için ise uygulamamıza şu kodları ekleyelim. Formumuzun Load event’ine:            private void Form1_Load(object sender, EventArgs e)            {                       groupBox1.Enabled = false;                       groupBox2.Enabled = false;                       groupBox3.Enabled = false;            } Sırasıyla da her radiobutton kontrolümüzün CheckedChanged event’ine de gerekli şekilde true false değerleriyle işleyebilirsiniz.           Gördüğünüz gibi metotların aşırı yüklenmesinden sonra kurucu metotların ve operatörlerin aşırı yüklenmesini daha kolay izah edebildik. Makalemizde oluşturduğumuz uygulamanın tam kodlarını ve çalıştırılabilir dosyasına örnek kodlar kısmından ulaşabilirsiniz. Yorum ve görüşlerinizi volkan@volkanatasever.com adresine gönderebilirsiniz.  

Multithreading Programlama

       Multithreading programlamaya ve kodlara girmeden önce bu makalemde multitasking ve multithreading’in ne anlama geldiğini ve prensiplerini anlatmaya çalışacağım.          PC’ler ilk çıktığında multitasking işletim sistemlerine sahip değildiler. Bu bir programı çalıştırmak için ilk önce çalışan programı kapatıp, çalıştırmak istediğiniz programı açmak anlamına geliyordu. Zaman kaybı olduğu gibi verimde de büyük düşüşler yaşanıyordu.          Multitasking Türkçe ifadesiyle çok işlemli anlamına gelmektedir. İşlemler zamanı paylaşır ve bir işlemin bittiği yerde diğeri başlar bunun için 20ms gibi bir süreçte bu işler olur. Diğer işlemde 20ms çalışır ve tekrar yine diğer işleme geçilir. Win32 sistemlerde 20ms belirlenmiştir bu süre quanta süresi olarak adlandırılmıştır. Bu çok işlemli sisteme(Multi Processing) Multitasking sistemler denir.          Bizim inceleceğimiz konu ise bir işlemdeki parçacıklardır.Burada da aynı işlemlerin zaman paylaşımında olduğu gibi işlemdeki parçacıklar kendi aralarında bir zaman paylaşımı oluştururlar.          Multi Thread sayesinde aynı anda bir uygulamada birden fazla işlem yapabilmekteyiz. Multi Processing’in, process seviyesine indirilmiş bir özeliği gibi düşünebilirsiniz. Böylece uygulamalarımız daha stabil, kararlı ve bazı durumlarda performans da artış da getirmektedir.          VB.NET ile multi thread yapmamız için bize gereken sadece System.Threading namespace’idir.          Dim parcacik as Thread          parcacik = new Thread(new ThreadStart(AddressOf fonksiyon))          Thread sınıfından parcacik isimli bir nesne oluştuyor ardından bir alt satırda ThreadStart isminde delegate türünden nesnemizi parametre olarak veriyoruz. Bu delegeyede parametre olarak fonksiyon isimli fonksiyonumuzun başlangıç adresini gönderiyoruz.          Kanalımızı çalıştırmak için ise;          Dim instance As Thread          instance.Start()          Start metodunu kullanmalıyız.          Çalışan kanalı sonlandırmak için;          Dim instance As Thread          instance.Abort()          Abort Metodunu kullanmalıyız.          Diğer önemli metodlar ise Suspend() , Resume() ve Sleep() metodlarıdır.          Public Sub Suspend()          Public Sub Resume()          Sleep metodu ise kanalımızı belirlenen süre içerisinde çalışmasını yarıda keser.Metod, integer tipinde parametre alır ve bu tamsayıyı milisaniye cinsinden değerlendirir.          Public Shared Sub Sleep ( _                    millisecondsTimeout As Integer _          )          Bazı önemli özellikler ise şunlardır:          IsAlive:          Dim instance As Thread          Dim value As Boolean          value = instance.IsAlive          IsBackGround:          Dim instance As Thread          Dim value As Boolean          value = instance.IsBackground          instance.IsBackground = value          IsAlive propertys’i üzerinde çalıştırılan kanal halen çalışıyorsa true değerini aksi halde false değerini döndürür bu da bize avantajlar sağlamaktadır.          IsBackGround özelliği ise kanalın arka planda çalışmasını gerçekleştirir kanalın arkaplanda çalışmasını istiyorsanız IsBackground’a true değerini atamalısınız.          Her uygulamada varsayılan olarak bir thread ile çalışır ve zaten programımızın çalışmasını sağlayan bu ana thread’dir. Bu thread’e ulaşmak içinde CurrentThread özelliğini kullanabiliriz.          Deklarasyonu aşağıdaki gibidir:          Public Shared ReadOnly Property CurrentThread As Thread          Teorik olarak öğrendiğimiz multithreading programlamayı basit bir örnekle irdeleyelim; Imports System.Threading Public Class Form1           Dim thr As Thread           Private Sub arkaplan()                    Dim i As Integer = 1                    Do While True                             ListBox1.Items.Add("Tekrarlama: " + i.ToString())                             i += 1                    Loop           End Sub           Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click                    thr = New Thread(AddressOf Me.arkaplan)                    thr.Start()           End Sub           Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click                    thr.Abort()           End Sub           Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click                    thr.Sleep(2000)           End Sub End Class          Bu örneğimizdede göreceğiniz gibi thr isimli thread’imizi buton 1’e basmamızla birlikte canlandırıyoruz ve thread’i başlatıyoruz. İkinci butona basmamızla thread sonlanmış oluyor.          Kanallardan bahsederken unutmamız gereken kanalların önceliğidir. Bir kanalın önceliğini CPU belirler. Düşük öncelikli kanallar az CPU zamanı, yüksek öncelikli kanallar ise daha fazla CPU zamanı gerektirirler. Kullandığımız kanallar varsayılan bir öncelik atarlar. Tabiki bu önceliği bizim atamamızda mümkün ve böylece daha fazla performans elde edebiliriz. Bunun içinde Thread sınıfının üyesi olan priority özelliğini kullanabiliriz.          Public Property Priority As ThreadPriority          5 adet öncelik ataması mevcuttur. Bunlar sırasıyla;          Highest          AboveNormal          Normal          BelowNormal          Lowest          Oluşturduğumuz kanala biz bir öncelik atamassak varsayılan olarak Normal atanacaktır. Öncelik ataması ile ilgili açıkca önceliklerin ve CPU zamanını test eden bir örnek yapalım ve bu zamanlamayı görelim.          Konsoldan çalışan örneğimiz: Imports System Imports System.Threading Module Module1           Sub Main()                    Dim priorityTest As New PriorityTest()                    Dim threadOne As Thread = _                    New Thread(AddressOf priorityTest.ThreadMethod)                    threadOne.Name = "ThreadOne"                    Dim threadTwo As Thread = _                    New Thread(AddressOf priorityTest.ThreadMethod)                    threadTwo.Name = "ThreadTwo"                    threadTwo.Priority = ThreadPriority.BelowNormal                    threadOne.Start()                    threadTwo.Start()                    ' 10 Saniye                    Thread.Sleep(10000)                    priorityTest.LoopSwitch = False           End Sub End Module Public Class PriorityTest           Dim loopSwitchValue As Boolean           Sub New()                    loopSwitchValue = True           End Sub           WriteOnly Property LoopSwitch() As Boolean           Set(ByVal value As Boolean)           loopSwitchValue = value           End Set           End Property           Sub ThreadMethod()                    Dim threadCount As Long = 0                    While loopSwitchValue                             threadCount += 1 End While                                       Console.WriteLine("{0} with {1,11} priority " & _                    "has a count = {2,13}", Thread.CurrentThread.Name, _                    Thread.CurrentThread.Priority.ToString(), _                    threadCount.ToString("N0"))           End Sub End Class          Çıktı:    Multithreading programlamayı anlatırken Thread’lerin çalışma mantığı içerisindeki bazı çelişkileri engellemek için senkronizasyon sağlamak için bazı yöntemlere başvurmamız gerekmektedir. Aksi halde programımız istenmeyen sonuçlar doğuracaktır. Senkronizasyonu kullanma nedenimiz çoğunlukla aynı veriye erişimin söz konusu olduğu durumlarda meydana gelebilecek karışıklıkdır. Eğer ben integer bir değere bir thread’de 5 atayıp diğer thread’de aynı anda 7 atıyorsam ve ilk thread’de atadığım 5 sayısına göre işlem yapmam gerekirken 7 değerine göre işlem yapıyorsam ortada bir karışıklık olacaktır.          Synclock ifadesi bu senkronizasyonu sağlayan kurallardan bir tanesidir.          Synclock(“locking”)                    ‘Kodlar          End Synclock          Monitor sınıfıda senkronizasyonu sağlamanın yollarından bir tanesidir. 11 adet metoda sahiptir. Bunlardan ikisi en önemlileridir. Bunlar Enter() ve Exit metodlarıdır.          Dim obj As Object          Monitor.Enter(obj)          Ve          Dim obj As Object          Monitor.Exit(obj)           Monitor sınıfı, Synclock ile aynı işi yapmaktadır.Microsoft bir Synclock bloğunun monitor sınıfı ile ilk önce Enter() metodunu ardından Exit() metodunu çağırmanın eşdeğer olduğunu bildirmiştir.           Bu iki yöntem ile küçük bir uygulama yapacak olursak;          Synclock Örneğimiz: Imports System.Threading Public Class Form1           Public Sub fonk()                    Dim i As Integer                    SyncLock ("locking")                             For i = 1 To 10                             ListBox1.Items.Add("Sayı: " + i.ToString())                             Next                    End SyncLock           End Sub           Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click                    Dim thr1 As New Thread(AddressOf Me.fonk)                    Dim thr2 As New Thread(AddressOf Me.fonk)                    Dim thr3 As New Thread(AddressOf Me.fonk)                    thr1.Start()                    thr2.Start()                    thr3.Start()           End Sub End Class          Monitor Sınıfı Örneğimiz: Imports System.Threading Public Class Form1           Public Sub fonk()                    Dim i As Integer                    Monitor.Enter(Me)                    For i = 1 To 10                    ListBox1.Items.Add("Sayı: " + i.ToString())                    Next                    Monitor.Exit(Me)           End Sub           Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click                    Dim thr1 As New Thread(AddressOf Me.fonk)                    Dim thr2 As New Thread(AddressOf Me.fonk)                    Dim thr3 As New Thread(AddressOf Me.fonk)                    thr1.Start()                    thr2.Start()                    thr3.Start()           End Sub End Class          Gördüğünüz gibi kodumuzda fazla bir değişiklik olmadı. Sadece Synclock bloğunun yerine Monitor.Enter(object) ve Monitor.Exit(object) metodlarının geldiğine dikkat edin.           Çok kanallı programlama yapabildiğimiz gibi makalemizin başındada belirttiğim gibi çok işlemli programlama da yapabilirsiniz. Bunun için tek gerekli olan Process sınıfını kullanmak oalcaktır. Bir işlemi başlatmak için Start() metodunu kullanmamız yeterli olacaktır.          Process başlatmak için:           Dim prsc As New Process           prsc.Start(“wordpad.exe”)          Process sınıfı ile ilgili bir örenk yapmak gerekirse:           Dim prsc As New Process           prsc.Start(“wordpad.exe”)          prsc.WaitForExit()          prsc.Close()          Bu kod bloğunu projenizde çalıştırdığınız zaman wordpad başlayacaktır. Siz wordpad’i kapatana kadar programınız beklemede kalacaktır. Siz programı kapattığınız zaman Close() metodu ile ilgili işleme ayrılan bellek serbest bırakılacaktır.           Sorularınızı,yorumlarınızı ve görüşlerinizi volkan@volkanatasever.com adresine mail olarak atabilirsiniz.

BitArray sınıfı, indeksleyiciler ve özellikler

Bu yazımda sizlere BitArray sınıfının kullanımı ve tanımı hakkında bilgiler vereceğim. Bunu yaparken de C# a yeni başlayanlar için indeksleyiciler ve özellikler kavramına da bir göz kırpacağız. BitArray sınıfı, adından da anlaşıldığı gibi bitlerden oluşan bir koleksiyondur. Bitler bilgisayar dünyasının temelini oluşturduğu ve bu bağlamda hayati bir önem taşıdığı için bir çok uygulamamızda kullanabileceğimiz çok faydalı bir sınıftır. Birden fazla kurucusu mevcuttur isterseniz önce bunlara değinelim. Constructors (Kurucular) Açıklama public BitArray(bool[] bims) Burada boolean türündeki dizimiz aynen BitArray koleksiyonumuzun elemanları olur. public BitArray(byte[] bims) Byte türünden dizimizin uzunluğunun 4 olduğunu varsayarsak bims[0] ilk 8 biti bims[1],bims[2] ve bims[3] sırasıyla diğer 8 bitleri temsil eder. Sonuç olarak 32 biti koleksiyonumuzda barındırmış oluruz. public BitArray(int[] bims) Aynen byte türünden dizi kabul eden kurucumuzdaki gibi aynı mantıkla çalışır bims[0] ilk 32 biti ve sırasıyla diğer 32 bitlik gruplar koleksiyonumuzun elemanı olarak karşımıza çıkar. public BitArray(int boyut) Burada direkt olarak sınıfımız içindeki bitlerin sayısını belirleyebiliriz. Not: Ilk değer olarak false atandığını unutmamız gerekir. public BitArray(int boyut,bool xyz) Burada ise direkt olarak boyutunu verdiğimiz gibi ikinci parametre oalrak verdiğimiz bool türünden değişken sayesinde sınıfımıza ilk değeri otomatik değil bizim kontrolümüz altında istediğimiz seçenek atanır. True veya False. public BitArray(BitArray bims) bims sınıfımızdaki bitler aynen yeni oluşturduğumuz sınıfta da kullanılacaktır. Unutulmaması gereken bir değer kopyalanması olduğu ve referanslarının aynı olmadığıdır. Kurucularımızı irdeledikten sonra bir uygulama için gerekli olan diğer silahlarımızı kuşanalım ve bunlarda bu sınıfa ait olan üyelerden metotlarımız olsun. Bildiğiniz gibi metotlar, kurucular, özellikler ve indeksleyiciler bir sınıfın vazgeçilmez araçlarıdır. Yeni başlayanlar ve dah önceden C ile upraşanlar için Not: Metotların C deki karşılığının Fonksiyon olduğunu belirtmeden geçemeyeceğim aşağıdaki metotları eğer C biliyorsanız fonksiyon mantığıyla düşünmeniz işlerinizi eminim çok rahatlatacak. Yeni bir kavram ve C nin NYP(Nesne Yönelimli Programlama (Ingilizce deyimiyle OOP)) eklenmiş hali olarak görmeniz bir adım daha ileri gitmemiz için bir avantaj kazandırır. Metodlar Kısa Örnek Açıklama public BitArray And(BitArray isim) BitArray sınıfında kadir1 kadir2 kadir3 olsun. kadir3=kadir2.And(kadir3); kadir2 ile kadir3 bitsel ve ye sokulup kadir3 e atanıyor. BitArray sınıfından isim adlı nesnenin bitlerine ve bu metodun üstünden kullanılan nesnenin bitlerine bitsel ve uygular ardından tekrar geri dönüş değeri olarak kullanır. public BitArray Not() kadir3=kadir2.Not(); Fazla üstünde durmaya gerek yok sanırım. Üzerinden çağrılan BitArray sınıfını bitlerinin değilini alır ve geri dönüş değeri de bu sonuç içeren BitArray nesnesidir. public BitArray Or(BitArray isim)   BitArray And() ten tek farkı bitsel ve yerine bitsel or yapmasıdır. public BitArray Xor(BitArray isim)   Bu da bitsel Xor yapmaktadır kullanımı BitArray Or() veya And() ile aynıdır. public bool Get(int indeks) public void Set(int indeks,bool abc)   Indeksleyicilerden ve özelliklerde kullanılan get ve set den pek de bir farkı olduğu söylenemez. Get metotumuz BitArray sınıfındaki belirttiğimiz indeks deki biti döndürür. Set ise aynen dediğim gibi indeksini belirttiğimiz bite abc değerini koyar. Yeni Başlayanlara Için: Makalemizde bahsedilen indeksleyicilerde veya özelliklerdeki Get ve Set in tanımı şöyleydi; en basit tanımıyla get değer döndürür ve set değer atar. Tabi ki çok daha kullanışlı olduğunu belirtmek isterim kısa bir indeksleyici örneği verirsek: dizi adında bir dizi tanımlandığı farzedilmiştir. value atanan değerdir.   public int this[indeks] {     get{ return dizi[indeks]; };     set{ dizi[indeks]=value; }; } Özellikleri gösteren küçük bir örnek: (deger isminde bir int tipinde alanımız olduğu farzedilmiştir.) public int isim {     get{ return deger; }     set{ deger=value; } } Indeksleyicilere ve özelliklere dair böyle bir noktada ufak bir örnek vermemenin tuzsuz bir çorba yapmaktan pek bir farkı olduğunu sanmıyorum. Indeksleyiciler ve özellikler nesne yönelimli programlama mantığının temellerinden biridir öyle ki nesne üzerinden en azından bir diziye bizim verdiğimiz kurallara göre değer atamak ve değer okumak işi kolaylaştıran bir unsurdur en iyisi örneğimizi verelim. Bu aşamada eminim indeksleyicilerin kullanımı size bir çok şey katacaktır. Örneğimiz: using System; using System.Text; namespace indeksleyiciler {     class Program     {         static void Main(string[] args)         {             indexersinifi ind=new indexersinifi(10);             Console.WriteLine("Özelliğimiz çalışıyor...");             Console.WriteLine("Dizinin Boyu"+ind.boyut);             Console.WriteLine("indeksleyici sayesinde sınıfımızın içindeki dizimiz doluyor...");             for(int i=0;i<10;++i)                 ind[i]=(i+1)*2;             Console.WriteLine("Get Eden Bölüm Çalışıyor ve sonuçlar...");             for(int i=9;i>=0;--i)                 Console.WriteLine("Dizinin "+i+". elemanı "+ind[i]);         }     }     class indexersinifi     {         int[] dizi;             public indexersinifi(int aa)         {             dizi = new int[aa];         }         public int this[int index]         {             get{                 return dizi[index];             }             set{                 dizi[index]=value;             }         }         public int boyut{             get{                 return dizi.Length;             }         }     } } Programımızın Çıktısı:     Metodlar Açıklama public void SetAll(bool abc) BitArray sınıfının içerdiği bütün bitlere abc değerini atar. Yukarıda anlatılan set mantığının tek bir bite değil sahip olduğu bütün bitlerine uygulanmış bir varyasyonudur. Bu sınıf içinde ayrıca bir indeksleyici ve bir özellik tanımlıdır (Ingilizce karşılıkları indexer ve properties dir). object this[int indeks] { get; set; } ve public int Length { get; set; } Not: BitArray, ICollection IEnumerable uygular ve IClonable’ı destekler. Arayüzlere bu makalemde değinmiyorum. Kısaca teknik özelliklerinden bahsedersek interface anahtar kelimesi ile belirtilir. Metot imzalarını taşır ve sınıflar kalıtım yoluyla bir yada birden fazla arayüz alabilir. C# da eksik olan çoklu kalıtımın bir nevi değişik şekillerden gerçekleştirilmesidir. Bu bilgiler ışığında oluşturulmuş olan C# örneğimiz: using System; using System.Collections; class Program {     static void Main(string[] args)     {         byte[] bKadir ={ 67 };         bool[] bKadir2={true,false,false,true,true,false,true,false};         BitArray BBitler1 = new BitArray(bKadir2);         BitArray BBitler2 = new BitArray(8, false);         BitArray BBitler3 = new BitArray(bKadir);         BBitler2 = BBitler2.Xor(BBitler3);         BBitler3=BBitler3.Or(BBitler1);         BitArray BBitler = new BitArray(BBitler2.Not());         //indeksleyicinin kullanımı         BBitler3[1] = false;         BBitler2.SetAll(true);         Console.WriteLine("BBitler in son degeri");         foreach (bool xyz in BBitler)             Console.Write(xyz + " ");         Console.WriteLine();         Console.WriteLine("BBitler1 in son degeri");         foreach (bool xyz in BBitler1)             Console.Write(xyz + " ");         Console.WriteLine();         Console.WriteLine("BBitler2 in son degeri");         foreach (bool xyz in BBitler2)             Console.Write(xyz + " ");         Console.WriteLine();         Console.WriteLine("BBitler3 in son degeri");         foreach (bool xyz in BBitler3)             Console.Write(xyz + " ");         Console.WriteLine();         Console.WriteLine("BBitler in uzunluğu "+BBitler.Length);         Console.WriteLine("BBitler1 in uzunluğu "+BBitler1.Length);         Console.WriteLine("BBitler2 in uzunluğu "+BBitler2.Length);         Console.WriteLine("BBitler3 in uzunluğu "+BBitler3.Length);         } } Çıktımız ise şöyledir:  Başka bir uygulama olarak int[] dizisi ile bir BitArray sınıfı canlandıralım: using System; using System.Collections; class Program {     static void Main(string[] args)     {         int[] bKadir ={ 960167 };         BitArray BBitler1 = new BitArray(bKadir);         BitArray BBitler2=new BitArray(bKadir);         BBitler1.Not();         BBitler2.SetAll(true);         Console.WriteLine("BBitler1 in son degeri");         foreach (bool xyz in BBitler1)             Console.Write(xyz + " ");         Console.WriteLine();         Console.WriteLine("BBitler2 in son degeri");         foreach (bool xyz in BBitler2)             Console.Write(xyz + " ");         Console.WriteLine();         Console.WriteLine("BBitler1 in uzunluğu "+BBitler1.Length);         Console.WriteLine("BBitler2 in uzunluğu "+BBitler2.Length);     } } Çıktımız ise şöyle:  Gördüğünüz gibi hemen hemen bütün metotları, indeksleyicileri ve özellikleri kullanarak kompleks bir BitArray sınıfı uygulaması yaptık. Kurucu metotların değişik varyasyonlarını da rahatlıkla deneyebilirsiniz. C# ın ve Visual Studio.NET in .Net Framework gibi bir bileşenler yumağıyla oluşturduğu çıkış ve desteklediği geniş çaplı ve yapılabilir hemen hemen her şey sayesinde uygulayabileceğiniz her türlü alt seviyeli programlama içinde uygun bir sınıf. Bana kalırsa robotik deneylerinin de bir nevi vazgeçilmezi. Değişik kalıplar bulup BitArray dizisinin metotlarını kullanarak ilginç sonuçlar elde edebilirsiniz. C# ın hissettiğine inanmıyorum yani şu intellisense olayına çünkü asıl hisseden sizlersiniz ve bu kalıpları bulup kullanırsanız yapacağınız işlemler o kadar kompleks olacaktır. Unutmayın programlama dilleri ve bu yazıyı okuduğunuza göre C# sizin için ana diliniz gibi olmalıdır. 1 ve 0 mantığı her zaman işe yaramaktadır düşünsenize programcı mantığıyla bir 0 dan 1 elde etmek isteseniz yapacağınız şey bir 0’ın içinde kaç tane 0 olduğunu saymaktır. O halde bu BitArray sınıfının önemini kavramak da bizim için zor olmasa gerek. Siz bir adım öne gidin ve çeşitli atraksiyonlarını uygulayın. Yaptığınız programları da mail adresime yollayabilirsiniz. Herhangi bir soru ve yorum için inhoftec@gmail.com adresinden bana ulaşabilirsiniz. Yazan: Volkan Atasever

VB.NET ile Ses İşlemleri

  VB.NET’in biz programcılar için yapabilecekleri gerçekten neredeyse sınırsıza yakın. .NET ortamını, Visual Basic’in kolaylığıyla ve .NET’in kompleks içeriğiyle birleştirdiğimiz zaman inanılmaz özelliklere imza atan bir ortam görüyoruz.         Programlarımızı zenginleştirmek için görsel öğeleri bolca kullanmaktayız. Ses unsuru da unutulmaması gereken başlıca özelliklerden. Ses bildiğimiz gibi kulağımıza gelen ve beynimizin uyarılmasını sağlayan dış unsurlarla duyumsamamızı etkileyen bir titreşim topluluğudur.         Biz ise sıradan ses den değil ses sinyallerinden bahsedeceğiz İngilizce terimi ile ifade edersek: “audio”.         Fazla derinlemesine girmeden standart ve standart dışı olarak VB.NET projelerimizde bu sesi nasıl kullanabileceğimizi örneklendireceğiz. Gerek Directx Sound gerekse apilerle veya directx audioplayback ile bunları nasıl elde edeceğimizi inceleyeceğiz.         Bir oyun yazıyorsanız sizin için çok yararlı olacaktır veya kullanıcı ile etkileşime giren bir program.         Başlangıç olarak makalemin teknik kısmına directx sound ile başlamak istiyorum. Başlamadan önce directx sdk nın bilgisayarınıza yüklü olduğuna emin olmalısınız ben şubat 2006 dağıtımını kullandım.         http://www.microsoft.com/windows/directx/default.mspx         Yukarıdaki bağlantının download kısmında sdk yı indirebilirsiniz.         Projenize ileriki adımlarda da kullanmak için bazı referanslar eklemek zorundayız. Aşağıdaki resimde görebilirsiniz.  Projemize sağ tıklayıp add reference kısmına basıyoruz.         Ardından;  Microsoft.DirectX.DirectSound , Microsoft.DirectX.AudioVideoPlayBack ve Microsoft.DirectX referanslarını projenize ekleyin.         Not: Burada projenin bütün kodlarını değil de can alıcı noktalarını açıklayacağım. Uygulamanın tam kodlarını örnek kodlar bölümünden indirebilirsiniz.         Imports Microsoft.DirectX.DirectSound         Imports Microsoft.DirectX         ile namespacelerimizi projemize dahil ediyoruz.         İlk başta bize gereken bilgisayarımızdaki herhangi bir yoldan ses dosyamızı çağırmaktır. Bunun için bir textbox ve bir browse butonuna ihtiyacımız var. Textbox bileşenimizde de ses dosyamızın yolunu görebileceğiz bunun için gerekli olan toolbox’ımızdan OpenFileDİalog isimli bileşinimizi projememize eklememizdir.  OpenFileDialog1.ShowDialog()          filename = OpenFileDialog1.FileName          TextBox1.Text = filename         Filename ise bir string olarak tanımlanmıştır.         Temel kodumuz ise aşağıdaki gibidir:                   Dim dev As New Device()                   dev.SetCooperativeLevel(Me, CooperativeLevel.Normal)                   Dim dsc As New BufferDescription()                   dsc.ControlVolume = True                   dsc.ControlFrequency = True                   Dim snd As New SecondaryBuffer(filenamedxsound, dev)                   snd.Volume = volume                   snd.Frequency = frekans                   snd.Play(0, BufferPlayFlags.Default)           Device nesnemizi ses kartınız olarak düşenebilirsiniz sesimizi çalmamız için gereken en temel bileşendir. Yani ilk önce ses aygıtımızı oluşturduk. Ardından aygıtımızın üzerinden setcooperativelevel’i çağırmamız gerekir. Burada Normal’i kullandık çoğunluklada bu seçenek yeterli olacaktır. Ayrıca bir BufferDescription nesnesini canlandırdık bunun sebebi bu nesne üzerinde dahil olan ses yüksekliğini ve ses frekansının değerlerini aktif hale getirmek için kullanılmıştır. Ardından SecondaryBuffer’ımızı oluşturup filenamdxsound adını verdiğimiz dosya ismimizi çağırıyor ve ikinci parametre olarakda aygıtımızız gösteriyoruz. Snd.Volume e ses yüksekliği değerimizi Frequency’e ise bizim seçtiğimiz frekansı aktarıp . snd.Play’e 0 değerini veriyoruz ve varsayılan değer olarak çalmasını yani bir kere çalıp durmasını söylüyoruz.           Örnek uygulamamızda kullandığımız gibi bir trackbar kullanmak isterseniz maximum ve minimum değerlerini doğru seçmeniz gerekecektir. Bunun içinde volume trackbar’ımızın maximumunu 0 ve minimumunu ise -3000 olarak ayarlamalısınız.           Frekans’ımızın minimumumu ise 100 maksimumuda 10000’dir.           Sesi ve frekansı trackbarla ayarlamamıza yarayacak örnek kodumuz:            If TrackBar1.Value = TrackBar1.Minimum Then                       volume = -3000            Else                      volume = TrackBar1.Value            End If            If TrackBar2.Value = TrackBar2.Minimum Then                       frekans = 100            Else                       frekans = TrackBar2.Value            End If           Directx sound ile ses çaldırırken daha bir çok özellik yer almaktadır. Bunlardan bazıları,           Sağ ve sol balansı kontrol etmek için gereken özellik:           Yukarıdaki kodumuzda aşağıdaki modifikasyonları yapabilirsiniz.                      Dim dev As New Device()                       dev.SetCooperativeLevel(Me, CooperativeLevel.Normal)                      Dim dsc As New BufferDescription()                      dsc.ControlVolume = True                       dsc.ControlPan = True                      Dim snd As New SecondaryBuffer(filenamedxsound, dev)                      snd.Volume = volume                       snd.Pan = 3000                      snd.Play(0, BufferPlayFlags.Default)           Speaker seçiminide kolay bir şekilde projenize ekelmeniz olası:           ‘ Yeni Speaker Nesnesi yarat           Dim spk As New Speakers();           ‘ Properties’ler           spk.Mono = false ‘ mono speaker           spk.Headphone = false ‘ headphones           spk.Stereo = false ‘ stereo speakers           spk.Quad = true ‘ quad system (iki ön, iki arka)           spk.FiveDotOne = false ‘ 5.1 surround system           spk.SevenDotOne = false ‘ 7.1 surround system           spk.Surround = false ‘ surround system           dev.SpeakerConfig = spk;           Directx.AudioVideoPlayback ile ses çaldırmak ise Directxsound’dan daha kolay ve birkaç kod satırı ile sesi çaldırabiliyoruz.           Bunun içinde           Imports Microsoft.DirectX.AudioVideoPlayback           Namespace’imizi import etmemiz gerekecek.           Kodumuz ise:                      Dim audio As New Audio(filenameaudiopb)                      audio.Volume = volume                      audio.Play()                     Burada filenameaudiopb ses dosyamızın ismi ve Audio nesnemizde ses dosyasını çalmamızı yarayan nesnemiz. audio.Volume ve audio.Play() ile default olarak sesimizi çaldırabiliriz.           Ses dosyalarını çaldırmak için diğer bir yöntemimiz ise DLL import ile API’ler kullanılarak eskiden kalma yöntemlerle oluşturacağımız bir sistemdir.                     Imports System.Runtime.InteropServices           Projemize yukarıdaki namespace’i ekleyelim.           Ardından;                       Declare Auto Function PlaySound Lib "winmm.dll" (ByVal name _                      As String, ByVal hmod As Integer, ByVal flags As Integer) As Integer                       Public Const SND_SYNC = &H0 ' Senkron                       Public Const SND_ASYNC = &H1 ' Asenkron                      Public Const SND_FILENAME = &H20000           ile DLL dosyamızı import edelim ve sabitlerimizi belirleyelim SND_SYNC müzik dosyamızı Senkron bir şekilde çalmamızı SND_ASYNC ise asenkron şekilde çalmamızı gerçekleyecektir. SND_FILENAME ise adından anlayacağınız gibi dosyamızın ismi.           Tanımlamalarımız biraz karmaşık olmasına rağmen çalma işlemimiz çok daha basittir. Bunun için yapacağınız tek şey PlaySound metodunu kullanmanız olacaktır.           PlaySound(filename,0,SND_FILENAME)           Senkron veya asenkron çaldırmak için ise           PlaySound(filename,0,SND_FILENAME or SND_SYNC)           Veya           PlaySound(filename,0,SND_FILENAME or SND_ASYNC)           Şeklinde kodumuza ekleme yapabiliriz.           Diğer sabitlerimiz ise aşağıdaki gibidir:                      Public Const SND_SYNC = &H0                      Public Const SND_ASYNC = &H1                      Public Const SND_MEMORY = &H4                      Public Const SND_ALIAS = &H10000                      Public Const SND_NODEFAULT = &H2                      Public Const SND_FILENAME = &H20000                      Public Const SND_RESOURCE = &H40004            Not: Directx Sound ve API’lerle wav dosyalarını çalıp üstünde işlem yapabilirken Directx audio playback ile mp3 dosyalarını da çaldırabilirsiniz.

Yapılar, Birlikler ve Bit Alanları

Özet: Yapı tanımı ,örnekleri ve yapı işaretçileri. Yapı’ların fonksiyonlara parametre olarak gönderilmesi ve yapı döndüren fonksiyonlar. Birlik tanımı ve örnekleri. Yapı ile Birlik’ların iç içe kullanımı. Bit Alanları’nın açıklanması ve örnekleri. Bu makalemde yapı, birlik ve bit alanları ile ilgili tanım,tanımlamalar ve örnek uygulamalar üzerinde duracağım. C dilinde int, float, char vb. ilkel veri tiplerimiz olduğu gibi bir çeşit kendi veri tipimizi tanımlama olanağımız da vardır. Bu tanımlamayı da struct anahtar sözcüğümüz ile gerçekleştirebiliyoruz. Küçük bir örnek vermek gerekirse: struct ornek{      int a;     char b;     float c; }; Şeklinde olacaktır. Yapımızın yapısını incelersek struct anahtar sözcüğü ve örnek adında bir yapı etiketi kullandık. Her yapı ‘;’ ile bitmek zorundadır. Yapıların boyutu ise içindeki veri tiplerinin toplam boyu kadardır. int,float ve char veri tiplerimizin sırayla 2,4 ve 1 byte büyüklüğünde bellekte yer kapladıklarını düşünelim (Farklı derleyiciler de farklı temel veri tipi boyutuna rastlamak mümkün), o zaman struct örnek adındaki veri tipimizin toplam boyutu 7 byte olacaktır. Not: Alignment kavramı göz ardı edilerek 7 byte olacağı farzedilmiştir. Eğer alignment parametresi ile programımızı derlersek bir hizalama olacağı için göz önüne aldığımız sistemde 7byte yerine 8 byte yer kaplayacaktır. Alignment gerçekten programımızı hızlandıran bir seçenek olarak karşımıza çıkar ve CPU nun daha az yorulmasını sağlar. Eğer yapımızı bir veri tipi olarak düşünürsek fonksiyonlara parametre olarak göndermek ve geri dönüş değeri kullanmak bizim için daha da kolay bir hal alacaktır. Yapıların fonksiyonlarla kullanılmasına ve genel kullanımına ilişkin bir senaryo oluşturalım. Senaryomuz, iki tane farklı yapının farklı bellek bölgelerine kopyalanması olacaktır ve bunu bir fonksiyon yardmıyla gerçekleyecektir. İlk önce yapı tasarımımızı oluşturalım: typedef struct{     char ad[15],     soyad[15];     int borc; }kadir; Burada typedef anahtar kelimesi sayesinde uygulamamızda veri tipimizi kadir adında kullanabilmekteyiz. Yapımızın boyu 32 byte’dır. Kullandığımız uygulamalarda direk hesaplamak yerine sizeof(kadir) veya sizeof(struct etiket_ismi) şeklinde de öğrenebilriz. Fonksiyonumuz ise: kadir *kopy(kadir *al){     rewind(stdin);     puts("String gir");     gets(al->ad);     puts("2. String gir");     gets(al->soyad);     puts("rakam gir");     scanf("%d",&al->borc);     return al; } Şeklinde olsun.Burada kopy adındaki fonksiyonumu parametre olarak kadir tipinden bir adres beklemektedir. kadir isimli veri tipimizi de typedef ile yapımız üzerinde tanımladık. Fonksiyonumuzun geri dönüş değeri ise yine kadir tipinden bir adres olacaktır. rewind(stdin) ile standart input’umuzu geriye sardık. Ve puts fonksiyonları ile bir adres yazdırdık. Dikkat edilmesi gereken yer ise gets fonksiyonumuz parametre olarak yolladığımız kadir tipinden al adında değişkenin elemanlarına ‘->’ işaretiyle ulaşıyoruz. Eğer işaretçi üstünden değil de direkt değer türünden oluşturmuş olsaydık ‘.’ İşaretiyle elemanlarımıza ulaşabilirdik(Örnek: gets(al.ad); ) . scanf fonksiyonumuzun ise geleneksel olarak okuttuğumuz temel veri tiplerinden farklı bir yazım olarak sadece &borc olması gereken yerde &al->borc şeklinde yazılmıştır. Son olarak da kadir tipinden al adresini döndürüyoruz. main fonksiyonumuz ise şöyle olmalıdır: int main(void) {     kadir *x1;     kadir *x2;     clrscr();     x1=(kadir *)calloc(sizeof(kadir),5);     x2=(kadir *)calloc(sizeof(kadir),5);     for(int j=0;j<5;++j) {          *(x2+j)=*(kopy(x1+j));     }     for(int r=0;r<5;++r){         puts((x2+r)->ad);         puts((x2+r)->soyad);         printf("%d",(x2+r)->borc);     }     getch();     return 0; } kadir tipinden iki adet işaretçi tanımladık ve bunlara calloc fonksiyonu ile sizeof(kadir)*5 kadar yer aldık yani toplamda 5’er adet yapımız için yer açtık. Eğer sizeof() işlecini kullanmasaydık ‘(kadir *)calloc(32,5);’ da diyebilirdik. Ardından for döngümüzü 5 kere dönecek şekilde kurduk ve içinde kopy fonksiyonumuzu çalıştırdık. x1+j adresini fonksiyona parametre olarak verdik(x1+0,x1+1,…x1+4 olarak parametreler gidecektir) ve geri dönüş değerimizi işaretçi olduğu için onun * operandıyla değerini *(x2+j) nin gösterdiği adresinin değerine yerleştirmiş olduk. Not: Yapı işaretçilerinin 1 adres ileri gitmesi yapının boyu kadar olur. Diyelim yapımız 64 byte biz adresimizi bir arttırdığımızda 64 byte ileri gider. Veya 4 adres ileri gidersek 64*4 kadar yani 256 byte kadar ilerlemiş olur. Bu şekilde x1 adresimize bilgileri kopy fonksiyonuyla okuyup yine sırasıyla x2 ye yerleştirmiş olduk. Adresler hakkında ki bilgi ve RAM’lerdeki yerleşimleri için alttaki resmi inceleyebilrisiniz. İkinci for döngümüzde ise x2+r diyerek sırasıyla 5 adet yapımızın içinde olan bilgileri konsola yazdırdık. union yani birliklerin tanımları ve kullanılması da struct’larla benzerlik gösterirler. union’ların bize getirmiş olduğu en büyük kazanç aynı bellek adresini değişik veri tipleri için kullanabilmemizdir. Basit bir union tanımlamak gerekirse: union deneme{     int a;     char b;     int dizi[3]; }; Birliğimizde bir tam sayı değişkeni, bir karakter değişkeni ve bir de tam sayı dizisi bulunmaktadır. union deneme isimli birliğimizin boyu en büyük elemanının boyu kadardır burada da 3 elemanlı tam sayı dizimiz 6 byte olduğu için toplam boyut da 6 byte dır. Yapı ve birliklerin iç içe kullanımı ile ilgili bir örnek düşünürsek: struct AYIR{     char cIlk,     cSon; }; typedef union kisa{     short int shSayi;     struct AYIR AKrktr; }sayim; Öncelikle birliğimizi inceleyecek olursak içinde kısa bir tam sayı ve struct AYIR tipinden AKrktr isimli bir değişken tanımlanmış bulunuyor. Yapımızda ise cIlk ve cSon adında iki karakter değişkeni barındırmaktadır. İsterseniz bu tasarımımızın pratikte nasıl kullanılabileceğini düşünebiliriz. main() fonksiyonumuzu oluşturalım: int main(){     sayim saTest;     saTest.shSayi=19527;     printf("shSayi:%d cIlk: %c\n     cSon:%c\n",saTest.shSayi,     saTest.AKrktr.cIlk,     saTest.AKrktr.cSon);     printf("int: %d short int: %d char: %d",     sizeof(int),sizeof(short int),sizeof(char));     getch();     return 0; } Burada typedef ile ile belirttiğimiz kendi oluşturduğumuz türden bir değişken tanımlıyoruz aynı zamanda bu birliğimizi barındırmaktadır. Ardından değişken üzerinden birliğimizin elemanlarından olan shSayi adlı değişkene 19527 sayısını atıyoruz. Çalıştırdığımızda ise çıktımız: Kısa tamsayının 2 byte, karakterin ise 1 byte yer kapladığını çıktıdan görebiliyoruz. Birliklerin aynı bölgeyi kullandığını ve bu bölgeninde bizim yapımıza tekabül ettiğini unutmamız lazım. Yapımızda ise kendi içindeki 1 byte lık değişkenler sayesinde 19527 sayısının ilk 8 bitini cIlk ikinci 8 bitini ise cSon karşılamaktadır. İlk 8 bitin karşılığı G ve ikinci 8 bitin karşılığı ise L’dir. En basit tanımıyla herhangi bir karakterin bitlerini elde etmek için kullanacağımız ve bit düzeyinde işlem yapacağımız silahımız bit alanlarıdır. Alt seviyeli programlamada vazgeçilmezler arasında yer almaktadır düşünüyorum da sıradan bir com port’u programlamak ve bir protokol meydana getirip bit bit ele alınmadada faydalı olabilir. Biz şu anda temelini irdelemek için basit bir bitlere ayrıştırma programı tasarlayalım. struct bitler {     int iIlkBit: 1;     int iIknci: 1;     int iUcncu: 1;     int iDrdncu: 1;     int iBsnci: 1;     int iAltnci: 1;     int iYednci: 1;     int iSonBit: 1; };union ikili {     char ch;     struct bitler test; }ayir; Bir önceki verdiğimiz örnek ile yapımızın ve birliğimizin uyumu aynıdır. Tek fark ise yapımızın artık sıradan bir yapı olmayıp bit alanı diye isimlendirilmesidir. Basit manada : işlecinin hemen ardından o değişkene kaç bit yer ayırdığımızı belirleyebiliriz. Şu anda bit alanımız 8 bitlik veriyi saklayabilme kapasitesine sahiptir. Eğer birliğimizde bir 4 byte’lık tam sayı tanımlamış olsaydık, ilk iki bitine ve son bitine ulaşmak bizim için önemli olsaydı bit alanımızda şöyle bir oynama yapabilirdik. Not: 4 byte 32 bittir. struct tamsayı{     int birinci:1;     int ikinci:1;     :29;     int son:1; }; ‘:’ işlecinden sonra yazdığımız 29 ilk iki bitten sonraki 29 biti önemsememiz gerektiğini belirtmektedir. Son olarak örneğimize dönecek olursak bitlerine ayırmak için kullanacağımız main() fonksiyonumuz şöyle olacaktır:   int main(void) {     printf("Bir Karakter Giriniz\n");     scanf("%d",&ayir.ch);     printf("\nKarakterin Bitlerine Ayrilmis Sekli:\n");     if(ayir.test.iSonBit)          printf("1");     else         printf("0");     if(ayir.test.iYednci)         printf("1");     else         printf("0");     if(ayir.test.iAltnci)         printf("1");     else         printf("0");     if(ayir.test.iBsnci)         printf("1");     else         printf("0");     if(ayir.test.iDrdncu)         printf("1");     else         printf("0");     if(ayir.test.iUcncu)         printf("1");     else         printf("0");     if(ayir.test.iIknci)         printf("1");     else         printf("0");     if(ayir.test.iIlkBit)         printf("1");     else          printf("0");      getch();     return 0; }   Gördüğünüz gibi 99 sayısının bitlerine ayrılmış şekli çıktıda verilmiştir basit bir if else mantığıyla çok kolay bir şekilde elde edebildik. Unutmamanız gereken bit alanları alt seviyeli programlarda gerçekten çok faydalı işlere imza atmaktadır. Sorularınızı ve yorumlarınızı volkan@volkanatasever.com adresine yollayabilirsiniz. Yazan: Volkan Atasever