Windows Mobile Üzerinde Sms ve Email İşlemleri

Merhabalar,

Bu makalemde sizlerle birlikte mobil uygulamalarımızdan nasıl email veya sms mesajları gönderebileceğimizi ve sms veya email ile ilgili mobil cihazımızda meydana gelen değişiklikleri nasıl takip edebileceğimizi inceleyeceğiz.

Tüm bu işlemleri yapmak için uygulamaıza Microsoft.WindowsMobile.PocketOutlook referansını eklememiz gerekmektedir. Bu referansı ekleyerek uygulamamıza başlayabiliriz.

Makalemize öncelikle uygulamamızdan nasıl sms atacağımızı inceleyerek başlayalım. Sms göndermek için SmsMessage nesnesini kullanacağız. Sms alıcılarını tanımlamak için ise Recipient nesnesini kullanacağız. SmsMessage nesnesi sadece sms mesajları için kullanılırken Recipient nesnesi tüm mesaj tipleri (Email, sms) için kullanılan ortak bir nesnedir. Öncelikle bu nesnelerin özelliklerini ve metodlarını inceleyelim.

SmsMessage nesnesi özellikleri :

Body(String) Bu özellik sms mesajının içeriğini taşımaktadır.
From(Recipient) Bu özellik sms’in kimden geldiği bilgisini taşımaktadır ve readonly bir özelliktir. Sms gönderilirken değil gelen sms’lerin incelenmesinde kullanılan bir özelliktir.
ItemId(ItemId) Bu özellik sms’e ait unique bir değer taşımaktadır. Bu özellik read only’dir.
LastModified(DateTime) Mesajın gönderildiği tarih bilgisini taşıyan özelliktir. Bu özellik read only’dir.
Read(bool) Sms’in okunup okunmadığı bilgisini taşıyan özelliktir. Read only’dir.
Received(DateTime) Sms’in alındığı tarih bilgisini taşıyan özelliktir. Read only’dir. RequestDeliveryReport(bool) Gönderilen sms için delivery report istenip istenmediğinin tutulduğu özelliktir.
To(RecipientCollection) Sms’in alıcılarının bilgilerinin tutulduğu özelliktir. Her bir alıcı bir Recipient nesnesi ile temsil edilmektedir.

SmsMessage nesnesi metodları :

Send Sms’i göndermek için kullanacağımız metoddur. Sms’in aktif gsm şebekesi üzerinden gönderilmesini sağlar.

Recipient nesnesi özellikleri :

Address(string) Mesaj gönderilecek nokta bilgisini barındıran özelliktir. Sms mesajları için telefon numarası, Email mesajları için ise email adresidir.
Name(string) Mesaj gönderilecek kişiyi barındıran özelliktir.

Recipient nesnesi için bu değerlerin instance alırken tanımlanabileceği yapıcı metodlar mevcuttur. Bu nesnenin boş yapıcı metodu yoktur.

Şimdi isterseniz Sms göndermek için kullanabileceğimiz bir helper class’ını birlikte yazalım.

        public static void SendSms(string parBody, string parRecipient)
        {
            SmsMessage insSmsMessage = new SmsMessage();
            insSmsMessage.Body = parBody;
            AddRecipient(insSmsMessage, parRecipient);
            insSmsMessage.Send();
        }
        private static void AddRecipient(SmsMessage parSmsMessage, string parRecipient)
        {
            AddRecipient(parSmsMessage, new Recipient(parRecipient));
        }

Gördüğünüz gibi birkaç satırlık kod yazarak sms göndermek mümkün. Bu metodların farklı parametreler alan overload’larını yazdığım bir class’ı Download kısmından indirebilirsiniz.

Şimdi isterseniz sms göndermeye çok benzer bir şekilde çalışan Email gönderme işlemini inceleyelim. Bunun için kullanacağımız nesne EmailMessage nesnesidir.

EmailMessage nesnesi özellikleri :

Attachments(AttachmentCollection) Mail mesajının eklerini barındıran özelliktir.
Bcc(RecipientCollection) Email’in bcc alıcılarının bilgilerinin tutulduğu özelliktir. Her bir alıcı bir Recipient nesnesi ile temsil edilmektedir.
BodyText(string) Email’in içeriğinin tutulduğu özelliktir.
Cc(RecipientCollection) Email’in cc alıcılarının bilgilerinin tutulduğu özelliktir. Her bir alıcı bir Recipient nesnesi ile temsil edilmektedir.
From(Recipient) Mesaj alıcısında gösterilecek mesajı gönderen adres ve kişi bilgisinin tutulduğu özelliktir.
Importance(Importance) Email’in önem derecesinin tutulduğu özelliktir. Aynı isimdeki Importance enum’undan değerler alır.
ItemId(ItemId) Bu özellik email’e ait unique bir değer taşımaktadır. Bu özellik read only’dir.
LastModified(DateTime) Mesajın gönderildiği tarih bilgisini taşıyan özelliktir. Bu özellik read only’dir.
Read(bool) Email’in okunup okunmadığı bilgisini taşıyan özelliktir. Read only’dir.
Received(DateTime) Email’in alındığı tarih bilgisini taşıyan özelliktir. Read only’dir. Sensitivity(Sensitivity) Email’in kişisel mi confidential’mı olduğu gibi hassasiyet bilgilerinin tutulduğu özelliktir. Aynı isimdeki enum değerlerini taşır.
Subject(string) Email mesajının konusu’nun tutulduğu özelliktir.
To(RecipientCollection) Email’in alıcılarının bilgilerinin tutulduğu özelliktir. Her bir alıcı bir Recipient nesnesi ile temsil edilmektedir.

EmailMessage nesnesi metodları :

Send Email’i göndermek için kullanacağımız metoddur. Accountname veya EmailAccount nesnesini parametre alır ve parametre aldığı mail hesabı üzerinden gönderim yapar.

Şimdi isterseniz Email göndermek için kullanabileceğimiz bir helper class’ını birlikte yazalım.

        public static void SendEmail(string parBody, string parRecipient)
        {
            EmailMessage insEmailMessage = new EmailMessage();
            insEmailMessage.BodyText = parBody;
            AddRecipient(insEmailMessage, parRecipient);
            insEmailMessage.Send(GetAccountName());
        }        
        private static string GetAccountName()
        {
            OutlookSession insOutlookSession = new OutlookSession();
            return insOutlookSession.EmailAccounts[0].Name;
        }
        private static void AddRecipient(EmailMessage parEmailMessage, Recipient parRecipient)
        {
            parEmailMessage.To.Add(parRecipient);
        }

Gördüğünüz gibi mail gönderme işlemi Sms göndermeye çok benzemektedir. Tek farklı nokta send metodunda mail hesabının veya hesap adının verilmesi gerekmesidir. Gördüğünüz gibi bunun içinde Outlook Session nesnesinden tanımlı mail hesaplarını okuyabilmekteyiz.

Şimdi isterseniz mobil cihazımıza yeni bir mesaj geldiğinden nasıl haberdar olabileceğimizi inceleyelim. Bunun için MessageInterceptor nesnesini kullanacağız. Bu nesne overloadında sadece Notify mı edileceği veya Notify edildikten sonra mesajın silinip silinmeyeceğine dair bir aksiyon parametresi ve bu işlem için mevcut thread’in kullanılıp kullanılmayacağını belirleyen boolean tipinde bir parametre almaktadır. Sonrasında ise bu nesnenin MessageReceived event’ını handle ederek mesaj geldiğinden haberdar olabiliriz. Bu nesnenin kullanımına ait bir örnek aşağıda verilmiştir.

        MessageInterceptor msgInterceptor = new MessageInterceptor(InterceptionAction.Notify, true);

        public SmsAgent()
        {
            msgInterceptor.MessageReceived += new MessageInterceptorEventHandler(msgInterceptor_MessageReceived);
        }
        void msgInterceptor_MessageReceived(object sender, MessageInterceptorEventArgs e)
        {
        }

Gördüğünüz gibi mesaj geldiğinde MessageInterceptor nesnesinden fırlayan event sayesinde bir çok işlem yapabiliriz. Event’ta bulunan MessageInterceptorEventArgs parametresinin Message özelliği ile gelen mesaja ait özellikleri alabiliriz.

Burda önemli bir soru belirli özelliklere sahip mesajları nasıl yakalayacağımızdır. Örneğin bir kullanıcıdan gelen mesajları yakalamak istiyorsak ne yapmamız gerektiğidir. Birçoğunuzun aklına bu durumu MessageRecieved event’ı içinde kontrol etmek gelmiştir. Ancak bunun için MessageCondition nesnesi vardır. Tek yapmanız gereken bu nesnenin ilgili property’lerini doldurmak ve MessageInterceptor nesnesinin MessageCondition özelliğine bu nesneyi atamaktır. Aşağıda bununla ilgili bir örnek kod parçası veriyorum.

        MessageInterceptor msgInterceptor = new MessageInterceptor(InterceptionAction.Notify, true);
        public SmsAgent()
        {
            msgInterceptor.MessageCondition = new MessageCondition(MessageProperty.Body, MessagePropertyComparisonType.StartsWith, “Hello”);
            msgInterceptor.MessageReceived += new MessageInterceptorEventHandler(msgInterceptor_MessageReceived);
        }
        void msgInterceptor_MessageReceived(object sender, MessageInterceptorEventArgs e)
        {}

Umarım faydalı bir makale olmuştur.

Tamer Öz

Document Preview Application

DocExp temel anlamda Windows Vista ve Windows 7 de bulunan explorer içindeki preview özelliğini barındıran bir C# uygulamasıdır. Bu özelliği C# kullanarak nasıl geliştirebileceğimizi bu uygulama üzerinde göstermeye çalıştım. Bunun yanısıra Abstract Class’lar, Interface’ler, Attribute’lar, Linq gibi bazı gelişmiş konuları barındıran projede bu konular ile ilgili bilgi sahibi olabilecek ve bir projede nasıl kullanıldığını görebileceksiniz. Preview özelliğinin yanısıra uygulama klasör ve dosya kopyalama, taşıma, silme gibi özellikleri de barındırıyor. Bu konularda ise kod içinde recursive metod kullanımları ile ilgili örnekler bulabileceksiniz.

Önizleme için desteklenen dosya biçimleri

PDF Files
JPG Files
JPEG Files
TIFF Files
GIF Files
BMP Files
PNG Files
MP3 Files
Wav Files
Wma Files
Midi Files
Avi Files
Mpg Files
Wmv Files
Html Files
Htm Files
Txt Files
Rtf Files
Docx Files
Doc Files
Xlsx Files
Xls Files
Pptx Files
Ppt Files
Ppsx Files
Pps Files


Kaynağı İndir

Microsoft Tag API Kullanımı

         Merhabalar

         Bu makalemde sizlere Microsoft Tag’dan ve yeni çıkmış olan API’sinin nasıl kullanılabildiğinden bahsedeceğim.

         Microsoft tarafından geliştirilen ve henüz Beta olan Microsoft Tag, temelde bir barkod gibi çalışmaktadır. Ancak barkoddan farklı olarak renkli olduğundan daha fazla bilgi barındırabilmektedir. Bu bilgiler bir web sitesi adresi, bir contact kartı, bir metin veya bir telefon numarası olabilmektedir. Ayrıca bu bilgiler şifre ile korunabilmekte veya sadece bir geçerlilik tarihi kapsamında erişilebilir olmaktadır. Tüm bunların yanısıra Bir Tag’ı okuyabilmek için sadece bir cep telefonunuz olması yeterli olacaktır. Birçok cep telefonu modelinde başarıyla çalışan Tag’ın okuyucusu monitör gibi ortamlardan da etiketi kolaylıkla yakalayabilmektedir. Gelecekte kartvizitlerin üzerinde, marketteki fiyat etiketlerinin yanında, reklam borşürlerinde sıklıkla görüyor olmalız olasıdır.

         Microsoft Tag’ı internet üzerinden kullanmak için http://tag.microsoft.com adresine girmeniz ve üye olmanız gerekmektedir. Oldukça kolay ve kullanışlı bir arayüze sahip olduğundan bu makalemde daha çok biz programcıları ilgilendiren API’nin nasıl kullanıldığına değineceğim.

         Api’yi kullanabilmek için öncelikle http://tag.microsoft.com/ws/accessrequest.aspx?wa=wsignin1.0 adresine girip kullanım için aşağıdaki gibi bir form doldurmanız gerekiyor.



          Bu formu doldurarak başvurunuzu tamamladıktan sonra 1 veya 2 gün içerisinde size web servisinin adresini ve size özel token’ı içeren bir mail gelecektir. Bu mail geldikten sonra web servisi kullanmaya başlayabilirsiniz. Makalemin içinde verdiğim kod örneklerinde bana ait token’ı sizlerle paylaşamayacağım için token’ı “00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00″ olarak kullanacağım.

         İsterseniz uygulamamızı yazmaya başlayalım.






         Öncelikle uygulamamıza mail ile gelen web servisinin referansını ekliyoruz.


 


 













































         Yeni bir kategori oluşturma:


            try
            {
                TagService.MIBPContractClient insMIBPContractClient = new MicrosoftTagAPISample.TagService.MIBPContractClient();
                TagService.UserCredential insUserCredential = new MicrosoftTagAPISample.TagService.UserCredential();
                insUserCredential.AccessToken = “00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00″;
                TagService.Category insCategory = new MicrosoftTagAPISample.TagService.Category();
                insCategory.Name = “Dummy_Category”;
                insCategory.UTCStartDate = DateTime.Now;
                insCategory.UTCEndDate = DateTime.Now.AddDays(10);//Tarih atanmazsa bitiş tarihi olmayan bir kategori yaratmış olursunuz.
                bool result = insMIBPContractClient.CreateCategory(insUserCredential, insCategory);
                if (result)
                {
                    MessageBox.Show(“Category Successfully Created”);
                }
                else
                {
                    MessageBox.Show(“An Error Occured While Creating Category”);
                }
            }
            catch (Exception ex)
            {
 
                MessageBox.Show(ex.ToString());
            }
         Microsoft Tag’ın Api’lerini kullanarak işlem yapmak için öncelikle MIBPContractClient class’ının bir instance’ını almamız gerekmektedir. Sonrasında ise bize mail ile gelen token’ı UserCredential nesnesinin bir instance’ına atarayarak servise yaptığımız her istekte göndermemiz gerekmektedir.

         Bunun devamında yeni bir kategori oluşturmak için öncelikle Category nesnesinin bir instanece’ını almalı, bu instance üzerinde tüm değerlerini atamalıyız. Oluşturduğumuz kategorinin bir son geçerlilik tarihi olmasını istemiyorsak UTCEndDate property’sine değer atamamamız gerekiyor. Bunun hemen ardından ise MIBPContractClient nesnesinin örneğinin CreateCategory isimli metoduna Credential bilgisi ve oluşturmak istediğimiz kategoriyi temsil eden nesne örneğini geçirmeliyiz. Bu metod işlemimizin başarılı olup olmadığı bilgisini geri döndürmektedir.

         Bir kategoriyi düzenleme :


            try
            {
                TagService.MIBPContractClient insMIBPContractClient = new MicrosoftTagAPISample.TagService.MIBPContractClient();
                TagService.UserCredential insUserCredential = new MicrosoftTagAPISample.TagService.UserCredential();
                insUserCredential.AccessToken = “00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00″;
                TagService.Category insCategory = new MicrosoftTagAPISample.TagService.Category();
                insCategory.Name = “Dummy_Category_New”;
                insCategory.UTCStartDate = DateTime.Now;
                insCategory.UTCEndDate = DateTime.Now.AddDays(10);//Tarih atanmazsa bitiş tarihi olmayan bir kategori yaratmış olursunuz.
                bool result = insMIBPContractClient.UpdateCategory(insUserCredential,“Dummy_Category”, insCategory);
                if (result)
                {
                    MessageBox.Show(“Category Successfully Updated”);
                }
                else
                {
                    MessageBox.Show(“An Error Occured While Updating Category”);
                }
            }
            catch (Exception ex)
            {
 
                MessageBox.Show(ex.ToString());
            }
         Kategori düzenlemenin çalışma mantığı kategori eklemek ile aynıdır. Burada dikkat edilmesi gereken tek bir nokta var o da değiştirilmek istenen kategorinin adının UpdateCategory metoduna 2. parametre olarak geçilmesi ve 3. parametre olarak bu isimdeki kategorinin yeni bilgilerinin gönderilmesidir.

         Bir kategoriyi pasif etme:


            try
            {
                TagService.MIBPContractClient insMIBPContractClient = new MicrosoftTagAPISample.TagService.MIBPContractClient();
                TagService.UserCredential insUserCredential = new MicrosoftTagAPISample.TagService.UserCredential();
                insUserCredential.AccessToken = “00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00″;
                bool result = insMIBPContractClient.PauseCategory(insUserCredential,“Dummy_Category_New”);
                if (result)
                {
                    MessageBox.Show(“Category Successfully Paused”);
                }
                else
                {
                    MessageBox.Show(“An Error Occured While Pausing Category”);
                }
            }
            catch (Exception ex)
            {
 
                MessageBox.Show(ex.ToString());
            }
         Bir kategoriyi pasif etmek için MIBPContractClient nesnesinin PauseCategory metoduna kategorinin adını ve credential’ları göndermek yeterlidir.

         Bir kategoriyi aktive etme:


            try
            {
                TagService.MIBPContractClient insMIBPContractClient = new MicrosoftTagAPISample.TagService.MIBPContractClient();
                TagService.UserCredential insUserCredential = new MicrosoftTagAPISample.TagService.UserCredential();
                insUserCredential.AccessToken = “00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00″;
                bool result = insMIBPContractClient.ActivateCategory(insUserCredential,“Dummy_Category_New”);
                if (result)
                {
                    MessageBox.Show(“Category Successfully Activated”);
                }
                else
                {
                    MessageBox.Show(“An Error Occured While Activating Category”);
                }
            }
            catch (Exception ex)
            {
 
                MessageBox.Show(ex.ToString());
            }
         Aynı şekilde bir kategoriyi aktive etmek için MIBPContractClient nesnesininActıvateCategory metoduna kategorinin adını ve credential’ları göndermek yeterlidir.

         Yeni bir tag oluşturma:


            try
            {
                TagService.MIBPContractClient insMIBPContractClient = new MicrosoftTagAPISample.TagService.MIBPContractClient();
                TagService.UserCredential insUserCredential = new MicrosoftTagAPISample.TagService.UserCredential();
                insUserCredential.AccessToken = “00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00″;
                TagService.URITag insURITag = new MicrosoftTagAPISample.TagService.URITag();//DialerTag, FreeTextTag, VCardTag nesnelerinin örnekleri alınarak bu tiplerde de tag’lar aynı mantıkla oluşturulabilir
                insURITag.Title = “New_URI_Tag”;
                insURITag.MedFiUrl = “http://www.tameroz.com”;
                insURITag.UTCStartDate = DateTime.Now;
                insURITag.UTCEndDate = DateTime.Now.AddDays(10);//Tarih atanmazsa bitiş tarihi olmayan bir tag yaratmış olursunuz.
                bool result = insMIBPContractClient.CreateTag(insUserCredential,“Dummy_Category_New”, insURITag);
                if (result)
                {
                    MessageBox.Show(“Tag Successfully Created”);
                }
                else
                {
                    MessageBox.Show(“An Error Occured While Creating Tag”);
                }
            }
            catch (Exception ex)
            {
 
                MessageBox.Show(ex.ToString());
            }
         Yeni bir tag oluşturmak için öncelikle oluşturmak istediğimiz tag tipinden bir nesnenin örneğini almamız gerekmektedir. Bu tip DialerTag, FreeTextTag, VCardTag veya URITag tiplerinde olabilmektedir. Instance’ını aldığımız bu nesnenin ilgili property’lerinin doldurduktan sonra bu nesneyi MIBPContractClient nesnesinin CreateTag metoduna göndermemiz gerekmektedir. Bu metod ayrıca bizden oluşturulacak tag’ın hangi kategori altında oluşturulacağına dair bir parametre de almaktadır. Burada yine tag’ın geçerlilik bitiş tarihini belirlemek istemiyorsak bu özelliğe değer atamamamız gerekmektedir.

         Bir Tag’ı güncelleme:


            try
            {
                TagService.MIBPContractClient insMIBPContractClient = new MicrosoftTagAPISample.TagService.MIBPContractClient();
                TagService.UserCredential insUserCredential = new MicrosoftTagAPISample.TagService.UserCredential();
                insUserCredential.AccessToken = “00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00″;
                TagService.URITag insURITag = new MicrosoftTagAPISample.TagService.URITag();//DialerTag, FreeTextTag, VCardTag nesnelerinin örnekleri alınarak bu tiplerde de tag’lar aynı mantıkla oluşturulabilir
                insURITag.Title = “New_URI_Tag”;
                insURITag.MedFiUrl = “http://www.yazgelistir.com”;
                insURITag.UTCStartDate = DateTime.Now;
                insURITag.UTCEndDate = DateTime.Now.AddDays(10);//Tarih atanmazsa bitiş tarihi olmayan bir tag yaratmış olursunuz.
                bool result = insMIBPContractClient.UpdateTag(insUserCredential,“Dummy_Category_New”,“New_URI_Tag”, insURITag);
                if (result)
                {
                    MessageBox.Show(“Tag Successfully Updated”);
                }
                else
                {
                    MessageBox.Show(“An Error Occured While Updating Tag”);
                }
            }
            catch (Exception ex)
            {
 
                MessageBox.Show(ex.ToString());
            }
         Tag güncellemede ki mantık temelde bir kategorinin güncellenmesindeki mantık ile aynıdır. Güncellenmek istenen tag’ın adı, kategorisi ve yeni hali UpdateTag metoduna gönderilerek tag’ın sistemde güncellenmesi sağlanır.

         Bir Tag‘ı pasif etme : 


            try
            {
                TagService.MIBPContractClient insMIBPContractClient = new MicrosoftTagAPISample.TagService.MIBPContractClient();
                TagService.UserCredential insUserCredential = new MicrosoftTagAPISample.TagService.UserCredential();
                insUserCredential.AccessToken = “00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00″;
                bool result = insMIBPContractClient.PauseTag(insUserCredential, “Dummy_Category_New”, “New_URI_Tag”);
                if (result)
                {
                    MessageBox.Show(“Tag Successfully Paused”);
                }
                else
                {
                    MessageBox.Show(“An Error Occured While Pausing Tag”);
                }
            }
            catch (Exception ex)
            {
 
                MessageBox.Show(ex.ToString());
            }
         Bir tag’ı pasif etmek için MIBPContractClient nesnesinin PauseTag metodunun kullanılması gerekmektedir.

         Bir Tag’ı aktive etme :


            try
            {
                TagService.MIBPContractClient insMIBPContractClient = new MicrosoftTagAPISample.TagService.MIBPContractClient();
                TagService.UserCredential insUserCredential = new MicrosoftTagAPISample.TagService.UserCredential();
                insUserCredential.AccessToken = “00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00″;
                bool result = insMIBPContractClient.ActivateTag(insUserCredential, “Dummy_Category_New”, “New_URI_Tag”);
                if (result)
                {
                    MessageBox.Show(“Tag Successfully Activated”);
                }
                else
                {
                    MessageBox.Show(“An Error Occured While Activating Tag”);
                }
            }
            catch (Exception ex)
            {
 
                MessageBox.Show(ex.ToString());
            }
         Bir tag’ı aktive etmek için MIBPContractClient nesnesinin ActivateTag  metodunun kullanılması gerekmektedir.

         Bir Tag’ı Windows uygulamasında görüntüleme:


            try
            {
                TagService.MIBPContractClient insMIBPContractClient = new MicrosoftTagAPISample.TagService.MIBPContractClient();
                TagService.UserCredential insUserCredential = new MicrosoftTagAPISample.TagService.UserCredential();
                insUserCredential.AccessToken = “00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00″;
                byte[] b=insMIBPContractClient.GetBarcode(insUserCredential, “Main”, “Tamer Vcard”,MicrosoftTagAPISample.TagService.ImageTypes.jpeg, 2,
TagService.DecorationType.HCCBRP_DECORATION_FRAMEPLAIN, false);
                MemoryStream ms = new MemoryStream(b);
                Image i=Image.FromStream(ms);
                PictureBox pb = new PictureBox();
                pb.SizeMode = PictureBoxSizeMode.Zoom;
                this.Controls.Add(pb);
                pb.Dock = DockStyle.Fill;
                pb.Image = i;
            }
            catch (Exception ex)
            {
 
                MessageBox.Show(ex.ToString());
            }
         Bir tag’ı görüntülemek için MIBPContractClient nesnesinin GetBarcode metodunun kullanılması gerekmektedir. Bu metod bizden sırasıyla credential’ları, bastırmak istediğimiz barkodun kategori adını ve barkod adını, output olarak gelecek resmin biçimini(Jpg, gif, pdf, png vs vs.), inç olarak tag’ın boyutunu ve tag’ın gözükme şeklini alacaktır. Tag’ın gözükme şekli ile ilgili örnekleri makalemin en sonunda vereceğim.

         Bir Tag’ı Web uygulamasında görüntüleme :


        try
        {
            Response.Clear();
            TagService.MIBPContractClient insMIBPContractClient = new TagService.MIBPContractClient();
            TagService.UserCredential insUserCredential = new TagService.UserCredential();
            insUserCredential.AccessToken = “00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00″;
            byte[] b = insMIBPContractClient.GetBarcode(insUserCredential, “Main”, “Tamer Vcard”, TagService.ImageTypes.jpeg, 2, TagService.DecorationType.HCCBRP_DECORATION_DOWNLOAD, false);
            Response.BinaryWrite(b);
            Response.ContentType = “Image/JPEG”;
        }
        catch (Exception ex)
        {
 
            Response.Write(ex.ToString());
        }
 


            Şimdi isterseniz tag’ın görüntülenme şekli ile hangi parametre geçilirse nasıl bir değer çıkacağına dair örnekleri aşağıda verdim.



DecorationType.HCCBENCODEFLAG_STYLIZED


 


 DecorationType.HCCBRP_DECORATION_DOWNLOAD


 


 DecorationType.HCCBRP_DECORATION_FRAMEPLAIN


 


DecorationType.HCCBRP_DECORATION_NONE


 


 

C# ile Fax Göndermek

        Merhabalar,

         Bu makalemde bir windows uygulaması üzerinden nasıl fax gönderilebileceğini inceleyeceğiz.

         Uygulama alanlarına baktığımızda genellikle bayiler arası iletişimin sağlanması, farklı lokasyonlarda mail imkanı olmayan iş ortaklarıyla iletişimin sağlanması karşımıza çıkmaktadır. Gerçek hayattan bir örnek vermemiz gerekirse yemek sepetinden verilen bir sipariş ilgili restorana fax ile gönderilmektedir. Esasında fax göndermenin mantığı yazıcının çalışma mantığından çok farklılık taşımamaktadır. Biz bu fonsiyonaliteyi uygulamanıza katmak için bir com bileşeni olan FAXCOMLib kütüphanesini kullanacağız. Biraz sonra kodlarını paylaştığımda esasında çok kolay kullanımı olduğunu göreceksiniz.

         Öncelikle uygulamamıza FAXCOMLib kütüphanesini referans ekleyerek başlıyoruz.



        Uygulamamızda bu kütüphanenin bizlere sunduğu FaxServer ve FaxDoc interface’lerini kullanıyor olacağız. Bunun yanısıra FaxServerClass veya FaxDocClass nesnelerini de kullanmamız mümkündür.

         Şimdi kodumuzu yazmaya başlayalım.
















using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using FAXCOMLib;
 
namespace Fax
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 

 
         Gördüğünüz gibi kodumuza using FAXCOMLib tanımlamasını yapıyoruz. Şimdi ise esas işlemlerin yapılacağı kod bloğumuza gelelim.

        public void SendFax(string parFileName, string parFaxNumber, string parSenderName, string parDisplayName, string parRecipientName)
        {
            FaxServerClass insFaxServerClass = new FaxServerClass();
 
            FaxDoc insFaxDocClass = null;
            try
            {
                insFaxServerClass.Connect(Environment.MachineName);
            }
            catch (Exception ex)
            {
                MessageBox.Show(“Fax sunucusuna bağlanırken hata”);
                return;
            }
 
            try
            {
                insFaxDocClass = (FaxDoc)insFaxServerClass.CreateDocument(parFileName);
            }
            catch (Exception ex)
            {
                MessageBox.Show(“Fax oluşturulurken hata”);
                return;
            }
           
           
insFaxDocClass.FaxNumber = parFaxNumber;
            insFaxDocClass.SenderName = parSenderName;
            insFaxDocClass.DisplayName = parDisplayName;
            insFaxDocClass.RecipientName = parRecipientName;
 
            try
            {
                insFaxDocClass.Send();
            }
            catch (Exception)
            {
 
                MessageBox.Show(“Fax gönderilirken hata”);
                return;
            }
           
           
insFaxServerClass.Disconnect();
        }

         Yazmış olduğumuz metodu inceleyecek olursak öncelikle FaxServerClass tipindeki nesnenin bir instance’ını alıyoruz, bunun ardından kendi makinemiz üzerinden fax göndereceğimiz için bu nesnenin connect metoduna kendi makinemizin ismini veriyoruz. Bu kısımda başka bir fax sunucusunu kullanacak olsaydık onun ismini vermemiz gerekiyordu. Bu işlemin hemen ardından FaxServerClass nesnemizin örneğinin CreateDocument metoduna fax’ını oluşturmak istediğimiz dosyanın yolunu veriyoruz. Fax bir yazıcı gibi çalıştığından bu kısımda bir dosya tipi sınırlamamız yoktur. Hemen arkasından FaxDocument nesnemizin FaxNumber property’sine fax’ı göndermek istediğimiz numarayı atıyoruz. Bunun yanısıra SenderName, RecipientName, DisplayName, gibi bilgileri ve Coverpage gibi bilgileri de ekleyebiliyoruz. Bu nesnenin çok fazla property’si olduğundan burada bunları tek tek açıklamayacağım ancak hepsi isimlerinden anlaşılan property’ler. Bu işlemlerinden ardından son adımda FaxDocClass nesnemizin Send metodunu çağırarak fax’ımızı göndermiş oluyoruz. Son olarak da sunucudan bağlantımızı kesmemiz gerekiyor.


        private void Form1_Load(object sender, EventArgs e)
        {
 
            SendFax(@”C:\Users\Tamer\Desktop\a.docx”, “23423423″, “sdfsd”, “fsdfsd”, “fsdfsdf”);
        }
    }
}

 
Bu işlemlerin hemen ardından açağıdaki gibi bir fax penceresi karşımıza açılacaktır.


Umarım faydakı bir makale olmuştur.
Tamer Öz

System.IO.DriveInfo Class’ı

       Merhabalar,

         Bu makalemde sizlere bilgisayarınızda bulunan mantıksal sürücülerin bilgilerine nasıl ulaşılabileceğini, bu bilgiler ile neler yapılabileceğini bahsedeceğim.

          Böyle bir fonksiyonaliteyi uygulamanızda kullanmak istediğinizde eminim ilk aklınıza gelecek yöntem System.Management class’ı ile wmi sorgulayarak sonuca ulaşmaktır. Ancak .Net bu noktada bize wmi kadar çok bilgiye erişime olanak sağlamasa da birçok bilgiye erişim için çok daha kolay bir yöntem sunmaktadır. O da System.IO sınıfı altındaki DriveInfo class’ıdır. Bu class sayesinde sürücünüze ait birçok bilgiyi alabilmekte, bazılarını ise değiştirebilmektesiniz.

İsterseniz şimdi bu sınıf ile neler yapabildiğimizi inceleyelim.











































Metod GetDrives() Bu static aynen yukarıda kullanıldığı gibi çağrılabilmektedir. Bu metodun döndürdüğü değer bilgisayarımızda bulunan mantıksal sürücülerin bilgilerinin barındığı DriveInfo nesnesinin bir array’idir.
Özellik AvailableFreeSpace Belirttiğiniz mantıksal sürücüdeki kullanılabilir boş alandır. Dönüş değeri byte cinsinden boş alanı vermektedir.
Özellik DriveFormat Belirtilen mantıksal sürücünün dosya biçimini belirten özelliktir.Örneğin NTFS, FAT32 String tipinde dönüş değeri vardır.
Özellik DriveType Bu özellik belirttiğimiz mantıksal sürücünün ne tipte bir sürücü olduğunu belirtir. Dönüş tipi DriveType tipinden bir enum dur. BU enum’un değerleri CDRom, Fixed, Network, NoRootDirectory, Ram, Removable, Unknown değerlerinde olabilmektedir. Örneğin uygulamalarınızda usb bellek takılıyken uygulamayı çalıştırmak istemediğiniz durumlarda veya sürücülerin başlarına tiplerine göre icon’lar yerleştirmek istediğiniz durumlarda bu özellikten faydalanabilirsiniz.
Özellik IsReady Belirtilen mantıksal sürücünün hazır olup olmadığını belirten özelliktir. Bilhassa sürücüye erişmeye çalıştığınızda “Aygıt hazır değil” şeklinde bir hata alıyorsanız sürücüye erişmeye çalışmadan önce bu özelliği kontrol etmeniz gerekmektedir. Adından da anlaşılabileceği gibi dönüş değeri boolean’dır.
Özellik Name Sürücünün adını veren özelliktir. Örneğin C:\ d:\.
Özellik RootDirectory Sürücünün root klasörünü veren özelliktir. Bu özelliğin tipi DirectoryInfo tipindedir. DirectoryInfo nesnesi ile bir klasör altındaki diğer klasörleri, dosyaları görmek klasör özelliklerini değiştirmek gibi işlemler yapmak mümkündür.
Özellik TotalFreeSpace belirtilen sürücüdeki toplam boş alanı byte olarak vermektedir.
Özellik TotalSize Belirtilen mantıksal sürücünün toplam boyutunun belirtildiği özelliktir. Bu özellikteki değer de yine byte cinsindendir.
Özellik VolumeLabel Bu özellik mantıksal sürücünün etiket değerini bize geri döndürmektedir. Ayrıca bu özelliğe değer set edebilmekteyiz. Set ettiğimiz değer ise sürücünün etiket değeri olarak saklanacaktır.

Şimdi isterseniz bu özelliklerin kullanımı ile ilgili ufak bir örneği inceleyelim.




            foreach (DriveInfo insDriveInfo in DriveInfo.GetDrives())
            {
               
               
Console.WriteLine(“Sürücü : “ + insDriveInfo.Name);
                Console.WriteLine(“Hazır Mı : “ + insDriveInfo.IsReady.ToString());
                if (insDriveInfo.IsReady)
                {
                    Console.WriteLine(“Etiket : “ + insDriveInfo.VolumeLabel);
                    Console.WriteLine(“Biçim : “ + insDriveInfo.DriveFormat);
                    Console.WriteLine(“Tip : “ + insDriveInfo.DriveType.ToString());
                    Console.WriteLine(“Root : “ + insDriveInfo.RootDirectory.ToString());
                    Console.WriteLine(“Toplam Alan : “ + ConvertToGb(insDriveInfo.TotalSize).ToString() + ” GB”);
                    Console.WriteLine(“Kullanılabilir Boş Alan : “ + ConvertToGb(insDriveInfo.AvailableFreeSpace).ToString() + ” GB”);
                    Console.WriteLine(“Toplam Boş Alan : “ + ConvertToGb(insDriveInfo.TotalFreeSpace).ToString() + ” GB”);
                    Console.WriteLine();
                }
            }
            Console.ReadLine();
        }
        static decimal ConvertToGb(long l)
        {
            return Math.Round(Convert.ToDecimal(l) / 1024 / 1024 / 1024,2);
        }



Bu kodun çıktısı ise aşağıdaki gibi olmaktadır.

System.DirectoryServices.AccountManagement ile Kullanıcı Hesabı ve Grup İşlemleri

         Merhabalar

         Bu makalemde System.DirectoryServices.AccountManagement kullanarak gerek Active Directory’de gerek ise makine üzerinde kullanıcı hesaplarını nasıl oluşturacağımızı, sileceğimizi ve değiştireceğimizi inceleyeceğiz. Bu işlemi .Net Framework 2.0 da DirectorySearcher nesnesi ile dönen DirectoryEntry nesnesinin Invoke metodunu kullanarak yapıyorduk. Ancak .Net Framework 3.5 çıkmasıyla System.DirectoryServices.AccountManagement namespace’inin sunduğu özelliklerle yapabileceğiz.

         İsterseniz öncelikle bu makalemizde kullanacağımız nesneleri inceleyelim;


















PrincipalContext PrincipalContext nesnesi tüm bu işlemlerin yapılacağı dizin hizmetinin tanımlandığı class’tır.Örneğin AD, Machine SAM
Principal Principal nesnesi biraz sonra inceleyeceğimiz principal nesneleri için en temeldeki base class’tır.
GroupPrincipal GroupPrincipal nesnesi Principal class’ından türemektedir ve Grup işlemleri için gerekli metodları bizlere sunmaktadır.
AuthenticablePrincipal Bu principal Principal base class’ından türemektedir, Ancak bu class’ta farklı olarak bir kullanıcının bilgilerinin kontrol edilmesi gibi Authentication mekanizmalarına ait metodlar bulunmaktadır.
UserPrincipal Domain ve lokal bilgisayar üzerinde kullanıcı işlemleri yapmak için kullanacağımız ve kullanıcıları temsil eden nesnedir.


          Şimdi bu nesnelerin kullanımını en iyi inceleyebileceğimiz şekilde bir uygulama yazmaya başlayalım.

Öncelikle uygulamamıza System.DirectoryServices.AccountManagement referansını eklememiz gerekiyor.


 Groups sekmesinde;
Grupları listeleme,
Grupları belirli bir kritere göre listeleme,
Yeni grup oluşturma,
Grup düzenleme,
Grup silme,
Gruba ait kullanıcıları listeme işlemlerine dair örnekler yapılacaktır.


 


Users sekmesinde;
Kullanıcıları listeleme,
Kullanıcıları belirli bir kritere göre listeleme,
Yeni kullanıcı oluşturma,
Kullanıcı düzenleme,
Kullanıcı silme,
Şifre değiştirme,
Kullanıcının dahil olduğu grupları listeleme,
Kullanıcıyı bir gruba ekleme,
Kullanıcıyı bir gruptan çıkarma işlemlerine dair örnekler yapılacaktır.



 Ayrıca grup ve kullanıcı özelliklerini gerek düzenlemek gerek ise görüntülemek için uygulamamıza frmProperties adında bir form oluşturup içine PropertyGrid kontrolünü dock olacak şekilde ekliyoruz. Ayrıca seçili aksiyonu(Ekleme, düzenleme, filtreleme) gerçekleştirecek bir düğme ve formu kapayacak bir düğmeyi de bu forma ekliyoruz. Bu formun dizaynı aşağıdaki gibi olacaktır.Bu formun kodunu makalenin en sonunda ayrıca paylaşıyor olacağım.



Şimdi isterseniz uygulamamızın kodunu yazmaya başlayalım;




































































using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.DirectoryServices.AccountManagement;


namespace AccountManagementGUI
{
 
    public partial class frmMain : Form
    {
        internal class UserPassword
        {
            private string _Password;
 
            public string Password
            {
                get { return _Password; }
                set { _Password = value; }
            }
        }
        internal class UserGroup
        {
            private string _GroupName;
 
            public string GroupName
            {
                get { return _GroupName; }
                set { _GroupName = value; }
            }
        }
        public enum ActionTypes
        {
            Filter,
            Save,
            None,
        }
        public frmMain()
        {
            InitializeComponent();
        }

 
         Öncelikle uygulamamızın ilerleyen kısımlarında kullanacağımız bazı nesneleri oluşturuyoruz. Bu nesnelerden UserPassword şifre sıfırlama için propertygrid’e bind edilecek, UserGroup kullanıcı grubu silme veya ekleme için propertygrid’e bind edilecek nesnelerdir. Ayrıca ActionTypes enum’u ise frmProperties ekranında yapılacak aksiyonun ne olduğunu belirleyen enumeration olarak görev yapacaktır.


        PrincipalContext insPrincipalContext = new PrincipalContext(ContextType.Machine);

 
        Bu kısımda PrincipalContext nesnesi ile işlemleri gerçekleştireceğimiz yapıyı belirliyoruz. Yukarıdaki örnekte Lokal bilgisayara bağlanılmıştır. Bu nesnenin constructor’larını inceleyerek daha farklı yapılara nasıl bağlanılacağını anlamak basittir. Hemen aşağıda birkaç bağlantı örneğini sizlerler paylaşıyorum. 


        PrincipalContext insPrincipalContext = new PrincipalContext(ContextType.Domain, “MyDomain”, “DC=MyDomain,DC=com”); //domaine bağlanma


        PrincipalContext insPrincipalContext = new PrincipalContext(ContextType.Machine,“TAMERO”,“administrator”,“password”);//lokal bilgisayara bir kullanıcı ile bağlanma

 
        Gördüğünüz gibi bir domain controller’a bağlanmak ile local bilgisayara bağlanmak arasında fark yok. Burdan sonra yapacağımız tüm işlemler domain üzerinde de aynı şekilde yapılabilmektedir. Ayrıca makalemin sonunda PrincipalContext kullanılarak bir kullanıcının Authentication bilgilerinin nasıl doğrulanabileceğini de inceleyeceğiz.


        private void Form1_Load(object sender, EventArgs e)
        {
            ListGroups();
            ListUsers();
 
        }
        private void SearchGroups(GroupPrincipal parGroupPrincipal)
        {
            lbGroups.Items.Clear();
            PrincipalSearcher insPrincipalSearcher = new PrincipalSearcher();
            insPrincipalSearcher.QueryFilter = parGroupPrincipal;
            PrincipalSearchResult<Principal> results = insPrincipalSearcher.FindAll();
            foreach (Principal p in results)
            {
                lbGroups.Items.Add(p);
            }
        }
        private void SearchUsers(UserPrincipal parUserPrincipal)
        {
            lbUsers.Items.Clear();
            PrincipalSearcher insPrincipalSearcher = new PrincipalSearcher();
            insPrincipalSearcher.QueryFilter = parUserPrincipal;
            PrincipalSearchResult<Principal> results = insPrincipalSearcher.FindAll();
            foreach (Principal p in results)
            {
                lbUsers.Items.Add(p);
            }
        }
        private void ListGroups()
        {
            GroupPrincipal insGroupPrincipal = new GroupPrincipal(insPrincipalContext);
            insGroupPrincipal.Name = “*”;
            SearchGroups(insGroupPrincipal);
        }
        private void ListUsers()
        {
            UserPrincipal insUserPrincipal = new UserPrincipal(insPrincipalContext);
            insUserPrincipal.Name = “*”;
            SearchUsers(insUserPrincipal);
        }

 
        Form’un load eventinde ListUsers ve ListGroups isimli iki metodu çağırıyoruz. Uygulamanın bundan sonraki tüm aşamalarında kullanıcılarla ilgişi işlemlerimizi UserPrincipal, gruplarla ilgili işlemlerimizi yapmak içinse GroupPrincipal kullanacağız. Search işlemini yerine getirebilmek için öncelikle ilgili tipte(Kullanıcı aramak için UserPrincipal, Grup aramak için GroupPrincipal) principal nesnemizi tanımlamamız gerekiyor. Daha sonrasından bu nesnenin ilgili property’sine belirlediğimiz arama kriterini yazmamız gerekiyor. Tüm kayıtların gelmesini istiyorsak tüm kayıtlarda mevcut olan name property’sine * sorgusunu göndermemiz yeterlidir. Adı sadece Tamer olan kullanıcıları aramak için bu property’e Tamer, Tamer ile başlayan kullanıcılar için Tamer*, içinde a harfi geçen kullanıcılar için *a* değerlerini atayabiliriz.

      Daha sonrasında ise oluşturduğumuz bu nesneyi PrincipalSearcher nesnesinin yeni bir instance’ını aldıktan sonra QueryFilter property’sine atıyoruz. PrincipalSearcher nesnesinin FindAll() metodunu kullanarak belirlediğimiz kriterlere uyan tüm objeleri Principal nesnesinin taşıyan bir collection olarak alabiliyoruz. Ayrıca bu kısımda FindOne metodunu kullanarak tek bir kayıt döndürmemiz de mümkün olmaktadır.

      Makalemin sonunda ise tarih kriteri için küçüktür büyüktür gibi karşılaştırmaları nasıl yapabileceğimizden ayrıca bahsedeceğim.


        private void btnFilterUsers_Click(object sender, EventArgs e)
        {
            UserPrincipal insUserPrincipal = new UserPrincipal(insPrincipalContext);
            frmProperties insFrmProperties = new frmProperties(insUserPrincipal, ActionTypes.Filter);
            insFrmProperties.ShowDialog();
            if (insFrmProperties.DialogResult == DialogResult.OK)
            {
                SearchUsers(insUserPrincipal);
            }
        }
        private void btnFilterGroups_Click(object sender, EventArgs e)
        {
            GroupPrincipal insGroupPrincipal = new GroupPrincipal(insPrincipalContext);
            frmProperties insFrmProperties = new frmProperties(insGroupPrincipal, ActionTypes.Filter);
            insFrmProperties.ShowDialog();
            if (insFrmProperties.DialogResult == DialogResult.OK)
            {
                SearchGroups(insGroupPrincipal);
            }
        }

 
        Filtreleme işlemi için yine öncelikle ilgili Principal nesnesini oluşturarak, arama yapılacak property’lerinin kullanıcı tarafından doldurulması için frmProperties formuna geçiriyoruz. Bu form’un içinde bulunan PropertyGrid sayesinde kullanıcılar gerekli bilgileri kolaylıkla girebilmektedirler. Arama yapılmak için doldurulan özellikleri taşıyan nesneyi çalışma mantığından biraz önce bahsettiğimiz Search metoduna göndererek ilgili listbox’ların dolmasını sağlıyoruz.
 

        private void btnClearFilterUsers_Click(object sender, EventArgs e)
        {
            ListUsers();
        }
        private void btnClearFilterGroups_Click(object sender, EventArgs e)
        {
            ListGroups();
        }

 
        Filtrelemeyi temizlemek için kullandığımız metodlar Form’un load eventinde kullandığımız metodlar ile aynıdır.
 

        private void btnNewUser_Click(object sender, EventArgs e)
        {
            UserPrincipal insUserPrincipal = new UserPrincipal(insPrincipalContext);
            frmProperties insFrmProperties = new frmProperties(insUserPrincipal, ActionTypes.Save);
            insFrmProperties.ShowDialog();
            if (insFrmProperties.DialogResult == DialogResult.OK)
            {
                try
                {
                    insUserPrincipal.Save();
                    insUserPrincipal.Dispose();
                    MessageBox.Show(“User created.”);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
 
                ListUsers();
            }
        }
        private void btnNewGroup_Click(object sender, EventArgs e)
        {
            GroupPrincipal insGroupPrincipal = new GroupPrincipal(insPrincipalContext);
            frmProperties insFrmProperties = new frmProperties(insGroupPrincipal, ActionTypes.Save);
            insFrmProperties.ShowDialog();
            if (insFrmProperties.DialogResult == DialogResult.OK)
            {
                try
                {
                    insGroupPrincipal.Save();
                    insGroupPrincipal.Dispose();
                    MessageBox.Show(“Group created.”);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                } 
                ListGroups();
            }
        }

 
        Yeni bir kullanıcı veya grup oluşturmak için ilgili Principal nesnesinden oluşturup kullanıcının istediği özellikleri(Ad, PasswordNeverExpires, Enabled gibi) doldurması için frmProperties ekranına referans geçiriyoruz. Kullanıcı bu ekranda değerleri atadıktan ve Kaydet’e bastıktan sonra ilgili Principal nesnesinin Save metodunu kullanarak grubun veya kullanıcının kaydedilmesini sağlıyoruz. Vista ve Windows7 kullanan kullanıcılar için bu ksıımda AccessDenied veya ErişimEngellendi gibi bir hata almaları mümkün olabilmektedir. Bunun için uygulamayı Run As Administrator(Yönetici olarak çalıştır) seçeneğini kullanarak çalıştırmak gerekmektedir.


        private void btnEditUser_Click(object sender, EventArgs e)
        {
            if (lbUsers.SelectedItem == null)
            {
                MessageBox.Show(“Please select a user”);
                return;
            }
            UserPrincipal insUserPrincipal = (UserPrincipal)lbUsers.SelectedItem;
            frmProperties insFrmProperties = new frmProperties(insUserPrincipal, ActionTypes.Save);
            insFrmProperties.ShowDialog();
            if (insFrmProperties.DialogResult == DialogResult.OK)
            {
                try
                {
                    insUserPrincipal.Save();
                    insUserPrincipal.Dispose();
                    MessageBox.Show(“User updated.”);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
 
                ListUsers();
            }
        }
        private void btnEditGroup_Click(object sender, EventArgs e)
        {
            if (lbGroups.SelectedItem == null)
            {
                MessageBox.Show(“Please select a group”);
                return;
            }
            GroupPrincipal insGroupPrincipal = (GroupPrincipal)lbGroups.SelectedItem;
            frmProperties insFrmProperties = new frmProperties(insGroupPrincipal, ActionTypes.Save);
            insFrmProperties.ShowDialog();
            if (insFrmProperties.DialogResult == DialogResult.OK)
            {
                try
                {
                    insGroupPrincipal.Save();
                    insGroupPrincipal.Dispose();
                    MessageBox.Show(“Group updated.”);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
 
                ListGroups();
            }
        }

 
        Edit işlemi için kaydet metodundaki gibi Principal nesnesinin Save metodu kullanılmaktadır. Burda yaptığımız farklı tek iş yeni bir Principal nesnesi oluşturmaktansa listede seçili nesneyi alıp kullanıcının değiştirmek istediği özellikleri değiştirmesi için frmProperties formuna göndermektir.


        private void btnDeleteUser_Click(object sender, EventArgs e)
        {
            if (lbUsers.SelectedItem == null)
            {
                MessageBox.Show(“Please select a user”);
                return;
            }
            UserPrincipal insUserPrincipal = (UserPrincipal)lbUsers.SelectedItem;
            try
            {
                insUserPrincipal.Delete();
                insUserPrincipal.Dispose();
                MessageBox.Show(“User deleted.”);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
 
            ListUsers();
        }
        private void btnDeleteGroup_Click(object sender, EventArgs e)
        {
            if (lbGroups.SelectedItem == null)
            {
                MessageBox.Show(“Please select a group”);
                return;
            }
            GroupPrincipal insGroupPrincipal = (GroupPrincipal)lbGroups.SelectedItem;
            try
            {
                insGroupPrincipal.Delete();
                insGroupPrincipal.Dispose();
                MessageBox.Show(“Group deleted.”);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
 
            ListUsers();
        }

 
        Delete işlemi için ise yine listbox’ta seçili olan Principal nesnesinin Delete metodunu çağırmak yeterli olacaktır.
 

        private void btnChangePassword_Click(object sender, EventArgs e)
        {
            if (lbUsers.SelectedItem == null)
            {
                MessageBox.Show(“Please select a user”);
                return;
            }
            UserPrincipal insUserPrincipal = (UserPrincipal)lbUsers.SelectedItem;
 
            UserPassword password = new UserPassword();
            frmProperties insFrmProperties = new frmProperties(password, ActionTypes.Save);
            insFrmProperties.ShowDialog();
            if (insFrmProperties.DialogResult == DialogResult.OK)
            {
                try
                {
                    insUserPrincipal.SetPassword(password.Password);
                    MessageBox.Show(“Password changed.”);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
 
                ListUsers();
            }
        }

 
        Şifre değişikliği için ise kullanıcının listbox’ta seçmiş olduğu UserPrincipal nesnesini alıyoruz, bundan hemen sonra yeni bir password nesnesi oluşturup bunu frmProperties formuna geçirerek kullanıcının şifre girmesini sağlıyoruz. Kullanıcının şifreyi girmesinin hemen ardından UserPrincipal nesnesinin SetPassword metodunu kullanarak belirleiğimiz şifreyi hesaba atıyoruz. Burada şifrenin domain veya lokal bilgisayardaki policylere uymaması halinde exception ile durum hakkında bilgi verilmektedir.


        private void btnListGroupUser_Click(object sender, EventArgs e)
        {
            if (lbGroups.SelectedItem == null)
            {
                MessageBox.Show(“Please select a group”);
                return;
            }
            GroupPrincipal insGroupPrincipal = (GroupPrincipal)lbGroups.SelectedItem;
            List<Principal> insListPrincipal = new List<Principal>();
            foreach (Principal p in insGroupPrincipal.Members)
            {
                insListPrincipal.Add(p);
            }
            frmProperties insFrmProperties = new frmProperties(insListPrincipal, ActionTypes.None);
            insFrmProperties.ShowDialog();
        }

 
         Bir gruptaki kullanıcıları listelemek için GroupPrincipal nesnesinin Members property’sine erişmek yeterlidir. Bu property Principal nesnesinin bir collection’unu taşımaktadır. Uygulama üzerinde ise bu property’deki değerleri frmProperties ekranında gösterilmektedir.
 

        private void btnListUsersGroups_Click(object sender, EventArgs e)
        {
            if (lbUsers.SelectedItem == null)
            {
                MessageBox.Show(“Please select a user”);
                return;
            }
            UserPrincipal insUserPrincipal = (UserPrincipal)lbUsers.SelectedItem;
            List<Principal> insListPrincipal = new List<Principal>();
            foreach (Principal p in insUserPrincipal.GetGroups())
            {
                insListPrincipal.Add(p);
            }
            frmProperties insFrmProperties = new frmProperties(insListPrincipal, ActionTypes.None);
            insFrmProperties.ShowDialog();
        }

 
        Bir kullanıcının dahil olduğu grupları listelemek için ise öncelikle kullanıcının seçmiş olduğu UserPrincipal nesnesini alıyoruz. UserPrincipal nesnesinin GetGroups metodu bize istediğimiz bilgiyi bir collection olarak vermektedir. Bunun arkasından aldığımız bilgiyi ise yine frmProperties formunda gösteriyoruz.
 

        private void btnAddUserToAGroup_Click(object sender, EventArgs e)
        {
            if (lbUsers.SelectedItem == null)
            {
                MessageBox.Show(“Please select a user”);
                return;
            }
            UserPrincipal insUserPrincipal = (UserPrincipal)lbUsers.SelectedItem;
 
            UserGroup group = new UserGroup();
            frmProperties insFrmProperties = new frmProperties(group, ActionTypes.Save);
            insFrmProperties.ShowDialog();
            if (insFrmProperties.DialogResult == DialogResult.OK)
            {
                try
                {
                    GroupPrincipal groupPrincipal = GroupPrincipal.FindByIdentity(insPrincipalContext, group.GroupName);
                    if (groupPrincipal == null)
                    {
                        MessageBox.Show(“Group not found.”);
                        return;
                    }
                    if (groupPrincipal.Members.Contains(insPrincipalContext, IdentityType.SamAccountName, insUserPrincipal.SamAccountName))
                    {
                        MessageBox.Show(insUserPrincipal.Name + ” is already a member of group “ + group.GroupName);
                        return;
                    }
                    groupPrincipal.Members.Add(insUserPrincipal);
                    groupPrincipal.Save();
 
                    MessageBox.Show(“User added to group.”);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
 
                ListUsers();
            }
        }

 
        Bir kullanıcıyı gruba eklemek için öncelikle listede seçili UserPrincipal nesnesini alıyoruz. Bunun hmen ardından UserGroup nesnesinden bir instance alıp frmProperties formuna geçirerek kullanıcının bir grup ismi girmesini sağlıyoruz. Girilen grup adının geçerli olup olmadığına dair kontrolü GroupPrincipal nesnesinin static olan FindByIdentity metodu ile yapıyoruz. Grup nesnesi varsa bu ada sahip grup nesnesinin bir değişkene atıyoruz. Daha sonra ise kullanıcının zaten belirtilen grupta olup olmadığına dair kontrolü seçili grup nesnesinin Members property’sinin Contains metodu ile kontrol ediyoruz. Kullanıcı olmaması durumunda ise yine member property’sinin Add metodunu kullanarak kullanıcıyı ilgili gruba ekliyoruz. Burda yaptığımız değişikliğin geçerli olabilmesi için mutlaka GroupPrincipal nesnesinin Save metodunun çağrılmış olması gerekmektedir.


        private void btnRemoveUserFromAGroup_Click(object sender, EventArgs e)
        {
            if (lbUsers.SelectedItem == null)
            {
                MessageBox.Show(“Please select a user”);
                return;


            }
            UserPrincipal insUserPrincipal = (UserPrincipal)lbUsers.SelectedItem;
 
            UserGroup group = new UserGroup();
            frmProperties insFrmProperties = new frmProperties(group, ActionTypes.Save);
            insFrmProperties.ShowDialog();
            if (insFrmProperties.DialogResult == DialogResult.OK)
            {
                try
                {
                    GroupPrincipal groupPrincipal = GroupPrincipal.FindByIdentity(insPrincipalContext, group.GroupName);
                    if (groupPrincipal == null)
                    {
                        MessageBox.Show(“Group not found.”);
                        return;
                    }
                    if (!groupPrincipal.Members.Contains(insPrincipalContext, IdentityType.SamAccountName, insUserPrincipal.SamAccountName))
                    {
                        MessageBox.Show(insUserPrincipal.Name + ” is not a member of group “ + group.GroupName);
                        return;
                    }
                    groupPrincipal.Members.Remove(insUserPrincipal);
                    groupPrincipal.Save();
 
                    MessageBox.Show(“User removed from group.”);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
 
                ListUsers();
            }
        }
    }
}

 
        Kullanıcıyı belirli bir gruptan silmek için yaptığımız tüm işlemler eklemek ile aynı, tek fark GroupPrincipal nesnesinin Members property’sinin Add metodu yerine Remove metodu kullanmamız gerektiğidir.

        Böylece System.DirectoryServices.AccountManagement  namespace’ini kullanarak ActiveDirectory ve Local Machine üzerinde nasıl işlem yapabileceğimizi görmüş olduk. Şimdi isterseniz neredeyse uygulamamızdaki her metodda kullandığımız frmProperties nesnesinin koduna bakalım.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.DirectoryServices.AccountManagement;
 
namespace AccountManagementGUI
{
    public partial class frmProperties : Form
    {
        public frmProperties(object propertyItem, frmMain.ActionTypes actionType)
        {
            InitializeComponent();
            if (propertyItem is List<Principal>)
            {
                pgMain.SelectedObject = ((List<Principal>)propertyItem).ToArray();
            }
            else
            {
                pgMain.SelectedObject = propertyItem;
            }
            btnAction.Text = actionType.ToString();
            btnAction.Visible = (actionType != frmMain.ActionTypes.None);
 
        }
 
        private void btnAction_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.OK;
            this.Close();
        }
 
        private void btnClose_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }
    }
}

 
        Gördüğünüz gibi formun ana fikri Constructor’da geçen nesnenin PropertyGrid’e atanması ve kullanıcı tarafından değiştirilen property’lerinin ardından referans olarak geçen bir nesne olduğundan frmMain formundan erişilebilir olmasıdır.

         Şimdi ise daha önce bahsettiğim En sonra belirli bir tarihten önce giriş yapmış olan kullanıcıları nasıl listeleyebileceğimizi veya bir kullanıcının bilgilerini nasıl PrincipalContext ile kontrol edebileceğimizi inceleyelim.
 

insPrincipalContext.ValidateCredentials(“Tamer”, “12345678″);
parUserPrincipal.AdvancedSearchFilter.AccountExpirationDate(DateTime.Now.Date.AddDays(10), MatchType.Equals);
parUserPrincipal.AdvancedSearchFilter.BadLogonCount(5, MatchType/span>.GreaterThanOrEquals);

 
         Kullanıcı bilgilerini doğrulamak için PrincipalContext nesnesinin ValidateCredentials metodu kullanılabilmektedir. Bunun yarı sıra AccountExpirationDate, LastBadPasswordAttempt, BagLogonCount, AccountLockoutTime, LastPasswordSetTime gibi kriterlere göre arama yapmak için ise UserPrincipal nesnesinin AdvancedSearchFilter property’sini kullanmak gerekmektedir.

Umarım faydakı bir makale olmuştur.
Tamer Öz

Kodlar


 

C# ile TrackChanges

Merhabalar,

         Yazdığımız uygulamalarda bazı verilerde yapılan değişikliklerin geçmişinin tutulması gerekmektedir. Bu durumda kullanıcılar farklı iki versiyonu karşılaştırmada ‘Track Changes’ benzeri bir yöntemle farklılıkları kolay ayırt etmeyi isteyebileceklerdir veya bu özelliği siz projenizde bir artı değer olarak sunmak isteyebilirsiniz. Bir başka senaryo ise bazı bilgilerin değiştiğinde değişikliğin kabul edilebilmesi için yönetici onayına düşmesidir. Bu değişiklikleri onaylayacak yönetici yine değişiklikleri kolay ayırt edebilmek isteyecektir. Bu gibi durumlarda kullanıcılara Word’de bulunan ‘Track Changes’ benzeri bir gösterimi nasıl yapabileceğinizi bu makalede anlatacağım.

         Öncelikle bu işlemi yapabilmek için bize gerekli altyapıyı Menees Software (http://www.menees.com/) tarafından geliştirilmiş Diff.Net library’si sağlayacaktır. İndirmek için http://www.menees.com/Files/MeneesDiffUtils.zip adresini ziyaret edebilir veya bu makalenin Download’lar kısmına bakabilirsiniz. Şimdi isterseniz BinaryDiff, Copy, DiractoryDiff, TextDiff gibi gelişmiş karşılaştırmalar yapabilen bu kütüphanenin içindeki TextDiff özelliğinin kullanımını inceleyelim sonrasında ise bu kütüphanedeki metodları kullanarak ‘Track Changes’ işlemini yapacak class’ımızı yazalım;

Öncelikle TextDiff nesnesinin bir örneğini alabilmek için karşılaştırmanın hangi hash’e göre yapılacağını, boşluk karakterlerinin göz ardı edilip edilmeyeceğini ve büyük küçük harf duyarlı karşılaştırma yapılıp yapılmayacağını nesnenin bir instance’ını alırken constructor’da belirlememiz gerekiyor. Sonrasında ise yarattığımız bu nesnenin Execute metodunu kullanarak karşılaştırma işlemimizi yapabiliyoruz. Burada dikkat etmemiz gereken bir nokta Execute metodunun bizden parametre olarak iki tane string list alması. Bundan dolayı biz de iki metni karşılaştırıken öncelikle metinleri string list’e çevireceğiz. İsterseniz şimdide bu metodun döndürdüğü sonuçtan bahsedelim. Bu sonuçları yorumlayabilirsek metodumuz başarıyla çalışacaktır. Bu metod bize EditScript nesnesi döndürmektedir. Bu nesne Edit nesnelerini taşıyan bir collection’dır. Edit nesnesinin özelliklerini inceleyelim;















StartA Belirtilen değişikliğin Execute metoduna ilk parametre olarak verdiğimiz list’te hangi item’dan başladığını belirtir.
StartB Belirtilen değişikliğin Execute metoduna ikinci parametre olarak verdiğimiz list’te hangi item’dan başladığını belirtir.
Length Belirtilen değişikliğin kaç Item boyunca devam ettiğini belirtir.
Type Belirtilen değişikliğin tipinin ne olduğunu belirtir. Olası tipler;Change, Delete, Insert, None değerlerinin taşıyan EditType enum’undan gelmektedir.



Öncelikle bir tane Web Site projesi oluşturuyoruz. Sonraki adımda ise bu projenin referanslarına MeneesDiffUtils kütüphanesini ekliyoruz.




Sonraki adımda ise ismi StringDiff olan class’ımızı projeye ekliyoruz ve bu class’ın içine kodumuzu yazmaya başlıyoruz.







using System;
using System.Collections.Generic;
using System.Web;
using Menees.DiffUtils;
 
namespace StringDiffSample
{
    public class StringDiff
    {
Yukarıda gördüğünüz gibi öncelikle class’ımızı oluşturuyoruz. Bu işlemden sonra artık asıl işlemi yapacağımız metod olan GetDiffString metodunu yazmaya geçebiliriz.







        public string GetDiffString(string Astr, string Bstr)
        {
            List<string> A = new List<string>();
            List<string> B = new List<string>();
                foreach (string s in Astr.Split(” “.ToCharArray()))
                {
                    A.Add(s);
                }
                foreach (string s in Bstr.Split(” “.ToCharArray()))
                {
                    B.Add(s);
                }
Biz metodumuzda varsayılan olarak metinleri kelime kelime ayıracağız. Bunun için iki tane string değişken açık public bir metod ve bu metodun içinden çağıracağımız private metodumuzu yazıyoruz. Private metodumuzun ilk satırlarında gelen metni belirtilen split type’a göre split edip A ve B adındaki iki farklı string list’e atıyoruz.







            Menees.DiffUtils.TextDiff diff = new Menees.DiffUtils.TextDiff(Menees.DiffUtils.HashType.HashCode, false, false);
            EditScript es = diff.Execute(A, B);
Daha sonra oluşturduğumuz bu iki string list’i makalenin başında anlattığım MeneesDiff kütüphanesindeki TextDiff class’ının Execute metoduna geçiriyoruz ve EditScript tipinden sonucumuzu elde ediyoruz.







            int j = 0;
            foreach (Edit edit in es)
            {
Kuracağımız algoritmanın içinde işimize yarayacak bazı değişkenleri tanımlıyoruz ve EditScript nesnesinin içinde yer alan Edit nesneleri için bir for each iteration’ı yazıyoruz.







                for (int i = edit.StartA; i < edit.StartA + edit.Length; i++)
                {
                    if (i < A.Count)
                    {
                        if (edit.Type == EditType.Delete)
                        {
                            A[i] = “<font color=red><s>” + A[i] + “</s></font>”;
                            B.Insert(i, A[i]);
                            j++;
                        }
                    }
                }
Tüm değişiklikleri B string listimizde yapacağımızı düşünerek kodumuzu yazmaya başlıyoruz. Öncelikle döngümüzdeki ilk değişiklik kaydı için ilk geçirdiğimiz parametrede bulunan ve ikinci parametrede bulunmayan yani silinmiş kayıtları buluyoruz. Bu silinmiş kayıtları üstü çizgili ve kırmızı şekilde göstermek için metni gerekli html kodları arasına alıyoruz ve yine aynı listedeki değişkene atıyoruz. Bundan sonra aynı metni B değişkenindeki yerine yani eskiden olduğu ancak silindiği yere ekliyoruz. ve B’ye kaç ekleme yaptığımız daha ileride işimize yarayacağından j değişkenini bir arttırıyoruz.







                for (int i = edit.StartB; i < edit.StartB + edit.Length; i++)
                {
                    if (i < B.Count)
                    {
                        if (edit.Type == EditType.Change)
                        {
                            string s = “”;
                            s = “<font color=red><s>” + A[edit.StartA + i - edit.StartB] + “</s></font><font color=green><u>” + B[i + j] + “</u></font>”; 
                             B[i + j] = s;
                        }
                        else if (edit.Type == EditType.Insert)
                        {
                            B[i + j] = “<font color=green><u>” + B[i + j] + “</u></font>”;
                        }
                    }
                }
Bir sonraki adımda ise aynı değişikliğin ikinci parametre geçirdiğimiz metni nasıl etkilediğini inceliyoruz. İkinci parametre metnin yeni hali olduğu için bu kısımda bize silinme kaydı gelmeyecektir. Sadece ekleme ve değişiklikler gelecektir. Öncelikle değişiklikleri buluyoruz. Değişiklikler için öncelikle aynı metni ilk parametre geçirdiğimiz A listesinden silinmiş ikinci parametre geçirdiğimiz B dizisine eklenmiş gibi davranacağız. Bunun için aynı metnin A string listindeki değerini bulup font rengini kırmızı yapıyor, B string listindeki karşılığını bulup altı çizgili ve yeşil yapıyoruz. Bulduğumuz bu değeri B list stringindeki ilgili sıraya ekliyoruz. B list stringinde hangi sıraya ekleyeceğimize A metninden silinenlerden kaç tane araya eklediğimiz ile B metninden değişikliğin kaçıncı karakterden başladığını toplayarak yapıyoruz. Yeni eklenmiş metinler için ise metni direkt altı çizgili ve yeşil yapıyoruz.







                }
            }
            string retval = “”;
            foreach (string s in B)
            {
 
                 retval += s + ” “;
 
             }
            return retval;
        }
    }
}
Son işlem olarak B dizisindeki kelimeleri birleştirerek track changes yapılmış metnimizi ortaya çıkarıyoruz ve bu metni metodumuzdan geri döndürüyoruz. Şimdi isterseniz bunun ufak bir demosunu yapalım. Bunun için bir web sayfasına iki textbox ve bir button koyacağız ve button’un click olayına aşağıdaki kodu yazacağız.







            lblResult.Text = new StringDiff().GetDiffString(txtOld.Text, txtNew.Text);

Sonuç aşağıdaki gibi oluyor.




Umarım işinize yaramıştır. 


 

CodePlex

Merhabalar,

Codeplex Microsoft’un açık kaynak kodlu projeleri host etmek amacıya kurduğu bir sitedir. CodePlex’i başladığınız yeni bir projeyi tüm dünya ile paylaşmak için kullanabileceğiniz gibi daha önceden açılmış projelerin proje gruplarına dahil olabilir ve bu guruplarda projenin geliştirilmesine yardımcı olabilirsiniz. Ayrıca CodePlex’te bulunan uygulamaları sadece kullanmak amacıya indirip, günlük hayatta kullanırken sağladığınız geribildirimler ile sadece son kullanıcı olarak da rol alabilirsiniz.CodePlex’de bir proje açmanız için projenin yazılım projesi olması, devam eden(iptal edilmemiş) bir proje olması ve bir lisans tipinin seçilmiş olması yeterlidir.

C# ve Asp.Net 2.0 yazılarak geliştirilen ve Team Foundation Server ile entegrasyonu SDK ile yapılan Codeplex üzerinde Kaynak Kodu Kontrolü, Proje Tartışmaları, Wiki Sayfaları, Özellik ve Konu Takibi, Geliştirilmesi Bitmiş Sürümlerin Download Edilmesi ve Haber Feed’leri gibi özellikler bulunmaktadır. CodePlex’in kaynak kodu kontrolü için codeplex’te tanımlı proje üzerinde bir rolünüz yoksa TortoiseSVN veya CodePlex Client kullanabilirsiniz. Eğer projede bir rol sahibi iseniz bunların yanı sıra Teamprise, Team Explorer, TF.exe veya MSSCCI Provider kullanabilirsiniz.CodePlex’de bir projeyi aramak için her sayfanın üzerinde bulunan “Search Project” kısmını kullanabilirsiniz. Şimdi ise yeni bir projeyi nasıl oluşturabileceğinizi inceleyelim.

Yeni bir proje oluşturmak için öncelikle https://www.codeplex.com/Project/ProjectCreation.aspx adresini ziyaret etmeniz gerekmektedir. Bu sayfada size CodePlex kullanıcı adınız ve şifreniz sorulacaktır. Eğer daha önceden CodePlex’e üye olmadıysanız https://www.codeplex.com/site/register adresini ziyaret ederek basit bir formu doldurduktan sonra üyelik işleminizi tamamlayabilirsiniz.Giriş yaptığınızda karşınıza CodePlex’in ana sayfası gelecektir. Şimdi isterseniz bu sayfadan bahsedeyim. En yukarıda sağ kısımda giriş yaptığınız kullanıcı adını göreceksiniz. Bu linke tıklayarak profil bilgilerinizi güncelleyebilirsiniz.Hemen altında proje arama alanını, onun da hemen altında kendi projelerinizi görebilirsiniz. Orta kısımda En yeni ve en popüler projeler gibi bilgilere ulaşabilirken sol tarafta bulunan Create New Project linkinden yeni proje oluşturabilirsiniz.Şimdi bu linke tıklayalım.

Karşımıza aşağıdaki gibi bir ekran gelecektir.

Bu ekranda Title alanına projenizin başlığını, Url alanına projenizin ana sayfasının bulunacağı url’i Description alanına ise açıklamasını yazmanız ve next e basmanız gerekmektedir. Next’e bastığınızda karşınıza aşağıdaki gibi bir alan çıkacak ve güvenlik resmindeki resmi yazarak ve CodePlex kullanım koşullarını kabul ettiğinize dair kutucuğu işaretledikten sonra Finish’e basarak projenin oluşturulması işlemini tamamlayabilirsiniz.


        Bu işlemi tamamladıktan sonra karışınıza gelen onay sayfasındaki bilgilerin bir kopyası mail adresinize de gelmiş olacaktır. Oluşturduğunuz proje şu anda pending durumunda oluşturulmuştur ve 30 gün içerisinde yayınlanması gerekmektedir. Projenin yayınlanması bitirilmesi anlamına gelmemektedir. CodePlex kodlaması devam eden projeleride barındırmayı amaçlayan bir sitedir. Bu işlemden sonra yapmanız gereken ilk adımda url kısmına yazdığınız adrese giderek veya ana sayfadaki My Projects kısmından tıklayarak yeni oluşturmuş olduğunuz projenin ana sayfasına gitmek olacaktır.Şimdi ana sayfayı inceleyelim.

Proje ana sayfasında projenin publish edilmesi ile ilgili olarak bir uyarı göreceksiniz. Projeyi publish etmeden önce isterseniz proje ana sayfasında bulunan tab’ları inceleyelim.Sonrasında publish öncesi yapmamız gereken işlemlere bakalım.

         Home :
Projenin ana sayfasıdır. Proje açıklaması ve bu açıklama üzerindeki bilgilerin güncellenmesini bu ekrandan yapabilirsiniz. Edit buton’una tıklayarak mevcut proje açıklamasının altına projenin ana sayfasında gözükecek yeni metinler ekleyebilirsiniz. Bunun yanı sıra      proje ile ilgili yeni gelişmeleri kullanıcılara bu ekrandan duyurmak uygun olacaktır.

 Releases :

Releases projenizin geliştirmesi bitmiş hallerini versiyon versiyon bu kısıma ekleyebilirsiniz.Create New Release buton’una tıklayarak projenize yeni bir release yükleyebilirsiniz. Bunun için sizden “Create New Release” buton‘una bastıktan sonra karşımıza yukarıdaki gibi bir ekran gelecektir. Bu ekranda Name kısmına yayınlayacağınız release’in adını girebilirsiniz. Compose kısmından ise bu release ile ilgili açıklamaları girebilirsiniz. Sonrasında aşağıda bulunan “Add File” link’ine tıkladığınızda DosyaAdı, Dosya Tipi ve Dosya Yolu gibi parametreleri doldurduktan sonra Release’in durumu, public olup olmadığı, ana sayfada gözüküp gözükmeyeceği gibi bilgileri girebilirsiniz.

Discussions :
Projeniz üzerinde tartışılması gereken bir konu varsa bu konudaki tartışmaları bu ekran üzerinden forum mantığı ile yapabilirsiniz. Bu kısım forum mantığı ile çalıştığından daha fazla detaya girmeyeceğim.

Issue Tracker :
Proje üzerinde WorkItem’ların açılması ve bunların takip edilmesi için kullanılabilecek ekrandır. Kullanıcılar tarafından gelen bug bildirimleri veya feedbackler bu kısımdan bildirilecektir.Bu kısımda yüklenen bir bug’ın bir kişiye atanmasını yapabilir, geçmişini takip edebilir hatta hangi release de düzeltildiğine dair bilgiyi girebilirsiniz.

 Source Code :
Projenizin kaynak kodunun bulunacağı ekrandır. Birden fazla source control tool’una nasıl erişebileceğinize ait bilgileri bu ekranda bulabilirsiniz.

Stats :
Projenin download edilmesi, görüntülenmesi gibi istatistiki bilgileri alabileceğiniz ekrandır.

People :
Projenizde rol alacak kişileri ve rollerini seçebileceğiniz ekrandır. Bu roller ile ilgili detaylı bilgi aşağıdadır.
   Coordinator : Proje yöneticisi rolüdür, proje üzerinde tüm yetkiye sahiptir.
Developer : Site yönetimi hariç proje ile ilgili birçok işlemi yapabilen kullanıcı tipidir.
Signed-In Visitor : Bu kullanıcı CodePlex’e giriş yapmış ancak proje üzerinde yetki verilmemiş kullanıcıdır. Yorum yapma, bug bildirme tartışma grupları ve wiki de yer alma gibi işlemleri yapabilen bu kullanıcı tipi bir projenin kodunda değişiklik yapamaz. Bunun için biraz önce bahsettiğim iki rolden birinde olması gerekmektedir.
Anonymous Visitor : Sadece uygulamayı ve kaynak kodu indirebilir.

Bu roller ile ilgili bir tabloya bakacak olursak;

License :
Projenizin hangi opensource lisanslama modeli altında yer alacağını ayarlayabileceğiniz ekrandır.
Projenizi publish etmeden önce;
Projenin ana sayfasındaki bilgileri değiştirmemiz gerekmektedir.
Projemize bir opensource lisanslama modeli seçmemiz gerekmektedir.
Projemize ait bir public release i yayınlamamız veya kodları check-in yapmamız gerekmektedir.

Tüm bu işlemlersen donra Publish Diyerek projemizi tüm dünya ile paylaşıma açabilir, projemize katılmak isteyen diğer kişileri projeye dahil edebiliriz.

Kaynak : CodePlex(www.codeplex.com)

Kendi Bileşenimizle Code39 Barkod Oluşturalım

         Merhabalar,

         Bilhassa stok takip uygulamaları başta olmak üzere birçok uygulamada barkod bastırma ihtiyacımız olabilmektedir. Her ne kadar hazır barkod font’larını ekrana bastırmak ile bu özelliği sağlayabilsek de ben bu makalemde barkod’un .Net içerisinde bulunan classlar ile bir imaj olarak nasıl oluşturulabileceğimden bahsedeceğim. Bunun için en çok kullanılan ve her okuyucunun desteklediği Code39′u uygulamalarımızda kullanmamızı sağlayacak bir kontrol yazacağız.

         Öncelikle Code39 barkod mantığını inceleyelim.

         Bu barkod sistemine Code39(3 Of 9) denmesinin sebebi 9 tane çizginden 3′ünün kalın diğerlerinin ince olmasıdır. Bu barkod sisteminde her karakter 9 tane çizgi ile temsil edilir. Bu çizgiler siyah, beyaz renklerinde ve kalın, ince tiplerinde olabilirler. Renk sıralaması Siyah, Beyaz, Siyah, Beyaz şeklinde standart bir şekilde ilerlerken kalın, ince çizgi sıralaması barkod’a yazılacak karakterlere bağlıdır. Bu karakterlere ait listeyi i:İnce k:Kalın olmak üzere aşağıda bulabilirsiniz.

















































































































Karakter Barkod Karakter Barkod Karakter Barkod Karakter Barkod
1 kiikiiiik B iikiikiik M kikiiiiki X ikiikiiik
2 iikkiiiik C kikiikiii i iiiikiikk Y kkiikiiii
3 kikkiiiii D iiiikkiik O kiiikiiki Z ikkikiiii
4 iiikkiiik E kiiikkiii P iikikiiki - ikiiiikik
5 kiikkiiii F iikikkiii Q iiiiiikkk . kkiiiikii
6 iikkkiiii G iiiiikkik R kiiiiikki BOŞLUK ikkiiikii
7 iiikiikik H kiiiikkii S iikiiikki * ikiikikii
8 kiikiikii I iikiikkii T iiiikikki $ ikikikiii
9 iikkiikii J iiiikkkii U kkiiiiiik / ikikiiiki
0 iiikkikii K kiiiiiikk V ikkiiiiik + ikiiikiki
A kiiiikiik L iikiiiikk k kkkiiiiii % iiikikiki

         Her karakteri nasıl barkod çizgilerine çevireceğimizi inceledik. Dikkat etmemiz gereken bazı noktalar var;

         a)Kalın, ince çizgi arasındaki oran 1:2 veya 1:3 olmalıdır.
         b)Karakterler arasında ince bir beyaz çizgi olmalıdır.
         c)Barkod’un başlangıç ve bitişinde * karakterleri olmalıdır.

         Kontrolümüzde oluşturulan barkodun ekranda gösterilmesini, print alınabilmesini ve resim dosyasına export edilebilmesini sağlayacağız. Şimdi kontrolümüzü yazmaya başlayabiliriz.






using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Printing;
using System.Drawing.Imaging;
 
namespace Barcode
{
    public class Code39Control : Control
    {
        private ContextMenuStrip _ContextMenuStrip = new ContextMenuStrip();
        private int _WideNarrowRatio = 2;
        private Dictionary<string, byte[]> chars = new Dictionary<string, byte[]>();


         Öncelikle yazmış olduğumuz kontorlü Control class’ından inherit ediyoruz. Sonrasında ise kontrolümüzden kullanıcıların sağ tıklayarak resime veya printer’a çıktı alabilmeleri için bir ContextMenu oluşturuyoruz. Ayrıca belirttiğim gibi Kalın çizgilerle ince çizgiler arasındaki oranı bir property’e bağlıyoruz. Bu kısımda en önemli noktayı her bir karakterin ifade edileceği çizgiler gurubunu tutacağımız Dictionary nesnesi oluşturuyor. Bu nesne her bir string değer karşılığında bir byte dizisi tutmaktadır.
 






        public int WideNarrowRatio
        {
            get { return _WideNarrowRatio; }
            set { _WideNarrowRatio = value; }
        }
        public Code39Control()
        {
            _ContextMenuStrip.Items.Add(“Export”);
            _ContextMenuStrip.Items.Add(“Print”);
            this.ContextMenuStrip = _ContextMenuStrip;
            _ContextMenuStrip.ItemClicked += new ToolStripItemClickedEventHandler(_ContextMenuStrip_ItemClicked);
            this.BackColor = Color.White;
            this.TextChanged += new EventHandler(Code39Control_TextChanged);
            chars.Add(“1″, new byte[] { 1, 0, 0, 1, 0, 0, 0, 0, 1 });
            chars.Add(“2″, new byte[] { 0, 0, 1, 1, 0, 0, 0, 0, 1 });
            chars.Add(“3″, new byte[] { 1, 0, 1, 1, 0, 0, 0, 0, 0 });
            chars.Add(“4″, new byte[] { 0, 0, 0, 1, 1, 0, 0, 0, 1 });
            chars.Add(“5″, new byte[] { 1, 0, 0, 1, 1, 0, 0, 0, 0 });
            chars.Add(“6″, new byte[] { 0, 0, 1, 1, 1, 0, 0, 0, 0 });
            chars.Add(“7″, new byte[] { 0, 0, 0, 1, 0, 0, 1, 0, 1 });
            chars.Add(“8″, new byte[] { 1, 0, 0, 1, 0, 0, 1, 0, 0 });
            chars.Add(“9″, new byte[] { 0, 0, 1, 1, 0, 0, 1, 0, 0 });
            chars.Add(“0″, new byte[] { 0, 0, 0, 1, 1, 0, 1, 0, 0 });
            chars.Add(“A”, new byte[] { 1, 0, 0, 0, 0, 1, 0, 0, 1 });
            chars.Add(“B”, new byte[] { 0, 0, 1, 0, 0, 1, 0, 0, 1 });
            chars.Add(“C”, new byte[] { 1, 0, 1, 0, 0, 1, 0, 0, 0 });
            chars.Add(“D”, new byte[] { 0, 0, 0, 0, 1, 1, 0, 0, 1 });
            chars.Add(“E”, new byte[] { 1, 0, 0, 0, 1, 1, 0, 0, 0 });
            chars.Add(“F”, new byte[] { 0, 0, 1, 0, 1, 1, 0, 0, 0 });
            chars.Add(“G”, new byte[] { 0, 0, 0, 0, 0, 1, 1, 0, 1 });
            chars.Add(“H”, new byte[] { 1, 0, 0, 0, 0, 1, 1, 0, 0 });
            chars.Add(“I”, new byte[] { 0, 0, 1, 0, 0, 1, 1, 0, 0 });
            chars.Add(“J”, new byte[] { 0, 0, 0, 0, 1, 1, 1, 0, 0 });
            chars.Add(“K”, new byte[] { 1, 0, 0, 0, 0, 0, 0, 1, 1 });
            chars.Add(“L”, new byte[] { 0, 0, 1, 0, 0, 0, 0, 1, 1 });
            chars.Add(“M”, new byte[] { 1, 0, 1, 0, 0, 0, 0, 1, 0 });
            chars.Add(“N”, new byte[] { 0, 0, 0, 0, 1, 0, 0, 1, 1 });
            chars.Add(“O”, new byte[] { 1, 0, 0, 0, 1, 0, 0, 1, 0 });
            chars.Add(“P”, new byte[] { 0, 0, 1, 0, 1, 0, 0, 1, 0 });
            chars.Add(“Q”, new byte[] { 0, 0, 0, 0, 0, 0, 1, 1, 1 });
            chars.Add(“R”, new byte[] { 1, 0, 0, 0, 0, 0, 1, 1, 0 });
            chars.Add(“S”, new byte[] { 0, 0, 1, 0, 0, 0, 1, 1, 0 });
            chars.Add(“T”, new byte[] { 0, 0, 0, 0, 1, 0, 1, 1, 0 });
            chars.Add(“U”, new byte[] { 1, 1, 0, 0, 0, 0, 0, 0, 1 });
            chars.Add(“V”, new byte[] { 0, 1, 1, 0, 0, 0, 0, 0, 1 });
            chars.Add(“W”, new byte[] { 1, 1, 1, 0, 0, 0, 0, 0, 0 });
            chars.Add(“X”, new byte[] { 0, 1, 0, 0, 1, 0, 0, 0, 1 });
            chars.Add(“Y”, new byte[] { 1, 1, 0, 0, 1, 0, 0, 0, 0 });
            chars.Add(“Z”, new byte[] { 0, 1, 1, 0, 1, 0, 0, 0, 0 });
            chars.Add(“-”, new byte[] { 0, 1, 0, 0, 0, 0, 1, 0, 1 });
            chars.Add(“.”, new byte[] { 1, 1, 0, 0, 0, 0, 1, 0, 0 });
            chars.Add(” “, new byte[] { 0, 1, 1, 0, 0, 0, 1, 0, 0 });
            chars.Add(“*”, new byte[] { 0, 1, 0, 0, 1, 0, 1, 0, 0 });
            chars.Add(“$”, new byte[] { 0, 1, 0, 1, 0, 1, 0, 0, 0 });
            chars.Add(“/”, new byte[] { 0, 1, 0, 1, 0, 0, 0, 1, 0 });
            chars.Add(“+”, new byte[] { 0, 1, 0, 0, 0, 1, 0, 1, 0 });
            chars.Add(“%”, new byte[] { 0, 0, 0, 1, 0, 1, 0, 1, 0 });
 
        }


         Yazmış olduğumuz kontrolün Constructor’unda öncelikle biraz önce oluşturduğumuz ContextMenu kontrolümüze Export ve Print adı altında 2 tane yeni Item atıyoruz ve nesnemizi kontrolümüzün ContextMenu’su olarak belirliyoruz. Daha sonrasında ise kullanıcı bu Item’lardan herhangi birine tıkladığında bunu yakalayabilmek adına ContextMenu’nun ItemClicked event’ını handle ediyoruz. Varsayılan olarak arka planın beyaz gelmesi için BackColor property’sine değerimizi atadıktan sonra kontrolümüzün Text property’si her değiştiğinde barkodun tekrar tekrar çizilmesi için TextChanged event’ını handle ediyoruz. Son olarak ise biraz önce oluşturmuş olduğumuz char property’sine çizgilerin kalınlık ve incelik durumlarını 1,0 lardan oluşan bir byte array şeklinde atıyoruz.
 





        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            try
            {
                DrawBarcode(e.Graphics);
            }
            catch (Exception)
            {
                e.Graphics.DrawString(“COULD NOT DRAW BARCODE”, new Font(“Times New Roman”, 12), Brushes.Red, 0, 0);
            }
        }


         Bu kısımda ise kontrlümüzün OnPaint event’ını override ediyoruz ve bu event içerisinde biraz sonra yazacağımız DrawBarcode metodunun çalıştırılmasını, bu metod çalışırken oluşabilecek herhangi bir hatada ise ekrana Could Not Draw Barcode yazısının yazılmasını sağlıyoruz. Şimdi DrawBarcode metodunu inceleyelim.






        private void DrawBarcode(Graphics insGraphics)
        {
            string text = this.Text;
            if (!text.StartsWith(“*”)){text = “*” + text;}
            if (!text.EndsWith(“*”)){text = text + “*”;}
            insGraphics.FillRectangle(new SolidBrush(this.BackColor), 0, 0, this.Width, this.Height);
            int narrowCount = 0;
            int wideCount = 0;
            int blankCount = 0;
            for (int i = 0; i < text.Length; i++)
            {
                byte[] insByteArray = chars;
                foreach (byte insByte in insByteArray)
                {
                    if (insByte == 1){wideCount++;}else{narrowCount++;}
                }
                if (i + 1 != text.Length){blankCount++;}
            }
            decimal widthPerUnit = Math.Round(Convert.ToDecimal(this.Width) / Convert.ToDecimal(((wideCount * _WideNarrowRatio) + blankCount + narrowCount)), 2);
            decimal currentLeft = 0;
            for (int i = 0; i < text.Length; i++)
            {
                byte[] insByteArray = chars;
                int index = 0;
                foreach (byte insByte in insByteArray)
                {
                    if (index % 2 == 0)
                    {
                        insGraphics.FillRectangle(new SolidBrush(this.ForeColor), (float)currentLeft, 0, (float)(insByte == 1 ? widthPerUnit * _WideNarrowRatio : widthPerUnit), this.Height);
 
                    }
                    currentLeft += (insByte == 1 ? widthPerUnit * _WideNarrowRatio : widthPerUnit);
                    index++;
                }
                currentLeft += widthPerUnit;
            }
        }


          Bu metodda öncelikle gelen metnin başında ve sonunda * karakterleri yoksa bu karakterleri ekliyoruz. Sonrasında kontrolün tüm arka planına arka plan renginde bir dikdörtgen çiziyoruz. Şimdi öncelikle barkod çizgilerimizin genişliğini ayarlayabilmek için kaç tane ince kaç tane uzun çizgi olduğunu sayıyoruz ve ayrıca kelimeler arasındaki boşluğu da sayıyoruz. Sonraki adımda ise kalın çizgilerimizi kısa çizgilere olan oranları ile çarpıyoruz, kısa çizgilerimiz ve kelimeler arası boşlukların sayısıyla topluyoruz. Bu değeri genişliğe böldüğümüzde bir kısa çizgiyi ne genişlikte çizmemiz gerektiğini bulacağız. Daha sonra aynı döngüyü tekrarlayarak kalın ve ince çizgilerimizden sadece siyah olanları kontrolümüzün ForeColor property’sinde tanımlı renge göre dikdörtgen olarak çiziyoruz. Burada önemli bir nokta beyaz çizgileri çizmiyoruz ancak her beyaz çizgi için bir sonraki siyah çizginin başlayacağı noktayı öteliyoruz. Bu işlem sonunda ise tüm barkodumuzu çizmiş oluyoruz.






        void Code39Control_TextChanged(object sender, EventArgs e)
        {
            this.Refresh();
        }
        void _ContextMenuStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            if (e.ClickedItem.Text == “Print”)
            {
                PrintDocument p = new PrintDocument();
                p.PrintPage += new PrintPageEventHandler(p_PrintPage);
                p.Print();
            }
            else if (e.ClickedItem.Text == “Export”)
            {
                _ContextMenuStrip.Close();
                SaveFileDialog sfd = new SaveFileDialog();
                sfd.ShowDialog();
                if (sfd.FileName != “”)
                {
                    Bitmap b = new Bitmap(this.Width, this.Height);
                    this.DrawToBitmap(b, new Rectangle(0, 0, this.Width, this.Height));
                    Image i =  (Image)b;
                    i.Save(sfd.FileName, ImageFormat.Jpeg);
                }
            }
        }
        void p_PrintPage(object sender, PrintPageEventArgs e)
        {
            Bitmap b = new Bitmap(this.Width, this.Height);
            this.DrawToBitmap(b, new Rectangle(0, 0, this.Width, this.Height));
            Image i = (Image)b;
            e.Graphics.DrawImage(i, new Point(10, 10));
 
        }
    }
}


         TextChanged event’ında kontrolün tekrar çizilmesini sağlıyoruz. ContextMenu’nun ItemClicked event’ında ise Print’e tıklandıysa PrintDocument kullanarak resmi yazdırıyoruz. Bunu yaparken kontrolü bitmap’e çevirip daha sonrasında image’e çeviriyoruz. Ve bu Image’i PrintDocument nesnesinin Event argumanlarından e içerisinde bulunan Graphics.DrawImage metoduna parametre vererek Print metodunun çalıştırılmasından sonra basılmasını sağlıyoruz. Eğer kullanıcı Export’u seçmiş ise bunu da Yine kontrolümüzden Image nesnesini oluşturduktan sonra bu nesnenin Save metodunu kullanarak bir dosyaya kaydettiriyoruz.

         Örnek bir uygulamayı ve kodları Download’lar kısmında bulabilirsiniz.

         Umarım Faydalı olmuştur.

Resim Dosyasından Barkod Okumak

         Merhabalar,

         Barkodların uygulamalarda ne amaçlı kullanıldığına, ve bir Code39 barkodunun nasıl oluşturulacağına bir kontrol yazarak önceki makalemde değinmiştim. Bu makalemde hep beraber bize resim olarak gelen dosya içerisinden barkod bilgisinin nasıl okunacağı konusu üzerinde bir çalışma yapacağız. Öncelikle kullanım alanı olarak barkod okuyucusu olmayan el terminallerinden resim çekilerek barkodun okunmasını sağlayacağını düşündüğüm bu metod ile uygulamalarınıza ekstra özellikler katabilirsiniz.

         Code39 Barkod standardından çok kısa bahsetmek gerekirse


         Code39(3 Of 9) denmesinin sebebi 9 tane çizginden 3′ünün kalın diğerlerinin ince olmasıdır. Bu barkod sisteminde her karakter 9 tane çizgi ile temsil edilir. Bu çizgiler siyah, beyaz renklerinde ve kalın, ince tiplerinde olabilirler. Renk sıralaması Siyah, Beyaz, Siyah, Beyaz şeklinde standart bir şekilde ilerlerken kalın, ince çizgi sıralaması barkod’a yazılacak karakterlere bağlıdır. Bu karakterlere ait listeyi i:İnce k:Kalın olmak üzere aşağıda bulabilirsiniz.

















































































































Karakter Barkod Karakter Barkod Karakter Barkod Karakter Barkod
1 kiikiiiik B iikiikiik M kikiiiiki X ikiikiiik
2 iikkiiiik C kikiikiii i iiiikiikk Y kkiikiiii
3 kikkiiiii D iiiikkiik O kiiikiiki Z ikkikiiii
4 iiikkiiik E kiiikkiii P iikikiiki - ikiiiikik
5 kiikkiiii F iikikkiii Q iiiiiikkk . kkiiiikii
6 iikkkiiii G iiiiikkik R kiiiiikki BOŞLUK ikkiiikii
7 iiikiikik H kiiiikkii S iikiiikki * ikiikikii
8 kiikiikii I iikiikkii T iiiikikki $ ikikikiii
9 iikkiikii J iiiikkkii U kkiiiiiik / ikikiiiki
0 iiikkikii K kiiiiiikk V ikkiiiiik + ikiiikiki
A kiiiikiik L iikiiiikk k kkkiiiiii % iiikikiki

         Çalışma mantığı olarak gelen resimde bulunan siyah ve beyaz alanların kontrol edilerek barkod çubuklarının genişliği hakkında yorum yapabilen bir metod yazmamız gerekiyor. Bu noktada resimde oluşabilecek renk kaymaları, barkod dışında oluşabilecek beyaz boşluklar, ve resmin yamuk çekilmesi gibi bazı istisnai durumları düşünmeli ve burumlara göre kod yazmalıyız.

         Artık Class’ımızı oluşturmaya başlayabilir ancak yukarıda bahsettiğim tablodan karakterlere geri çevrim yapacağımızdan bu tablonun içeriğini tanımlamak zorundayız. Bu tablonun içeriğini tanımlarken kalın çizgileri 1 ince çizgileri ise 0 ile temsil edeceğiz. Ayrıca bu işlemi Class’In constructor’unda yapmamız gerekecektir.






using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
 
namespace BarcodeReader
{
    public class BarcodeDecoder
    {
        private Dictionary<string, string> chars = new Dictionary<string, string>();
        public BarcodeDecoder()
        {
            chars.Add(“100100001″, “1″);chars.Add(“001100001″, “2″);
            chars.Add(“101100000″, “3″);chars.Add(“000110001″, “4″);
            chars.Add(“100110000″, “5″);chars.Add(“001110000″, “6″);
            chars.Add(“000100101″, “7″);chars.Add(“100100100″, “8″);
            chars.Add(“001100100″, “9″);chars.Add(“000110100″, “0″);
            chars.Add(“100001001″, “A”);chars.Add(“001001001″, “B”);
            chars.Add(“101001000″, “C”);chars.Add(“000011001″, “D”);
            chars.Add(“100011000″, “E”);chars.Add(“001011000″, “F”);
            chars.Add(“000001101″, “G”);chars.Add(“100001100″, “H”);
            chars.Add(“001001100″, “I”);chars.Add(“000011100″, “J”);
            chars.Add(“100000011″, “K”);chars.Add(“001000011″, “L”);
            chars.Add(“101000010″, “M”);chars.Add(“000010011″, “N”);
            chars.Add(“100010010″, “O”);chars.Add(“001010010″, “P”);
            chars.Add(“000000111″, “Q”);chars.Add(“100000110″, “R”);
            chars.Add(“001000110″, “S”);chars.Add(“000010110″, “T”);
            chars.Add(“110000001″, “U”);chars.Add(“011000001″, “V”);
            chars.Add(“111000000″, “W”);chars.Add(“010010001″, “X”);
            chars.Add(“110010000″, “Y”);chars.Add(“011010000″, “Z”);
            chars.Add(“010000101″, “-”);chars.Add(“110000100″, “.”);
            chars.Add(“011000100″, “”);chars.Add(“010010100″, “*”);
            chars.Add(“010101000″, “$”);chars.Add(“010100010″, “/”);
            chars.Add(“010001010″, “+”);chars.Add(“000101010″, “%”);
       
}


         Bu tanımlamalarımızı yaptıktan sonra yapacağımız ilk işlem ise bu imaj dosyasında bulunan ilk siyah çizginin en küçük x koordinatını bulmak, sonrasında ise bu x koordinatı üzerinde siyah çizginin y koordinatına göre orta noktasını bulmak olacaktır. Bunun için yazılmış olan metodu inceleyelim. Daha sonrasında bu metodun çağrıldığı yeri de inceleyeceğiz.






        private Point FindFirstBlack(Bitmap b)
        {
            Point pFirstBlack = new Point();
            for (int i = 0; i < b.Width; i++)
            {
                int firstYBlack = 0;
                int lastYBlack = 0;
                for (int j = 0; j < b.Height; j++)
                {
                    Color c = b.GetPixel(i, j);
                    int average = (c.R + c.G + c.B) / 3;
                    if (average < 128)
                    {
                        if (firstYBlack == 0) { firstYBlack = j; }
                        lastYBlack = j;
                    }
                }
                if (firstYBlack != 0)
                {
                    pFirstBlack.Y = (firstYBlack + lastYBlack) / 2;
                    pFirstBlack.X = i;
                    break;
                }
            }
            return pFirstBlack;
        }


         Bu metodun yaptığı işi inceleyecek olursak, metod kendisine parametre olarak gelen Bitmap nesnesini en üst sol köşesinden başlamak üzere pixel pixel dolaşıyor. İlk siyah pixel’i bulduğunda artık sadece y eksenine bakıyor. Baktığı y ekseninde siyah pixel’lerin bittiği nokta ile başladığı noktanın orta noktasını alarak buradaki çizginin orta noktasını bulmuş oluyoruz. Burda dikkat edilmesi gereken önemli bir nokta bir pixel’in siyah’a mı beyaz’a mı yakın olduğuna karar vermek için kullanılan yöntemdir. Bu yöntemde pixelin R,G,B değerlerinin ortalamasına bakarak siyaha mı daya yakın yoksa beyaza mı daha yakın olduğuna karar verilebilmektedir. Bu metod daha sonra bize bahsettiğim noktanın koordinatlarını point cinsinden döndürüyor.






        public string DecodeCode39(Image img)
        {
            List<int> order = new List<int>();
            Bitmap b = (Bitmap)img;
            Point pFirstBlack = FindFirstBlack(b);
 
            int blackIndex = pFirstBlack.X;
            int whiteIndex = -1;
            for (int i = pFirstBlack.X + 1; i < img.Width; i++)
            {
                Color c = b.GetPixel(i, pFirstBlack.Y + 1);
                int average = (c.R + c.G + c.B) / 3;
 
                if (average < 128)
                {
                    if (whiteIndex > blackIndex)
                    {
                        order.Add(i – whiteIndex);blackIndex = i;
                    }
                }
                else
                {
                    if (blackIndex > whiteIndex)
                    {
                        order.Add(i – blackIndex);whiteIndex = i;
                    }
                }
            }
            order.Add(img.Width – blackIndex);
 
            int TotalLength = 0;
            foreach (int i in order)
            {
                TotalLength += i;
            }
            int avgLength = TotalLength / order.Count;
            string text = “”;
            for (int i = 0; i < order.Count; i = i + 9)
            {
                string s = “”;
                s += (order[i] > avgLength ? “1″ : “0″);s += (order[i + 1] > avgLength ? “1″ : “0″);
                s += (order[i + 2] > avgLength ? “1″ : “0″);s += (order[i + 3] > avgLength ? “1″ : “0″);
                s += (order[i + 4] > avgLength ? “1″ : “0″);s += (order[i + 5] > avgLength ? “1″ : “0″);
                s += (order[i + 6] > avgLength ? “1″ : “0″);s += (order[i + 7] > avgLength ? “1″ : “0″);
                s += (order[i + 8] > avgLength ? “1″ : “0″);
                text += chars[s];
                i++;
            }
            return text;
        }


         Gönderdiğimiz resmi decode edecek metodumuzu yazmaya başlıyoruz. Metodumuz bizden parametre olarak Image nesnesini alıyor ve bu nesneyi bitmap nesnesine çevirerek ilk siyah çizgiye ait noktanın bulunması için biraz önce bahsettiğim metoda gönderiyor ve buradan dönen point değerlerini alıyoruz.

         Bu kısımda tanımlamış olduğumuz blackIndex değişkeni yeni bir siyah çizgi bulunduğunda o siyah çizginin başladığı pixel’i temsil edecektir. Zaten bulduğumuz ilk nokta siyah çizgi olduğundan pointimizdeki değeri bu değişkene atayabiliyoruz. whiteIndex ise aynı şekilde en son bulduğumuz beyaz noktanın başlangıç pixel’ini tutacaktır. Henüz bir beyaz nokta bulmadığımızdan buraya değer atamıyor ve başlangıç değeri olan -1′i veriyoruz.

         Sonraki aşamada bulduğumuz ilk siyah noktadan sağa doğru pixel pixel geliyoruz ve her noktanın siyah mı beyaz mı olduğuna karar veriyoruz. Bu döngü içinde bir önceki noktamız siyah iken tekrar siyah bir noktaya gelirsek siyah çizgi devam ediyor demektir. Bunun için ancak renk değişimlerine siyah çizginin veya beyaz çizginin bittiğini anlayabiliriz. Zaten if sınamalarında bu açık bir şekilde gözükmektedir. En sonda bulunan çizgimiz siyah bir çizgi olacağından dolayı resmimizin bittiği yerden geri kalan noktayı ise tekrar collectionumuza ekliyoruz.

         Elimizde bulunan collectiondaki değerlerin siyah, beyaz, siyah, beyaz şeklinde ilerlediğinden bahsetmiştim. Zaten collectionda tuttuğumuz değerler bu çizgilerin uzunlukları. Örneğin Collectionda ilk sırada 10 ikinci sirada 5 değerleri var ise bu bizim için 10 pixel genişliğinde bir siyaz çizgi(kalın çizgi), 5 pixel genişliğinde bir beyaz çizgi(ince çizgi) var demektir. Daha sonra bu izgilerden hangilerinin uzun hangilerinin kısa olduğunu bulmak için collection’da bulunan tüm değerlerin ortalamasını alıyoruz. Bu ortalama değerden büyük olan değerler kalın, küçük olan değerler ise ince çizgileri temsil edeceklerdir.

          Barkod’daki karakterlerin 9 çizgi ile temsil edildiklerini sonrasında ise bir karakter boşluk bırakıldığını söylemiştirm. Bunun için bir döngüde değerleri 8er 8 er dolaşıyoruz ve kalın olanlar için 1 ince olanlar için 0 değerlerini ekleyerek bir string oluşturuyoruz. Bu 9 karakterden oluşan string bize, barkod içindeki 9 çubuğun hangi karakteri temsil ettiğini söyleyecek. Bu değeri bulmak için ise Class’ın constructor’unda tanımlamış olduğumuz List’i kullanıyoruz ve metni barkod içinden okuyoruz.

         Bu kodu örnek bir uygulama ile downloadlar kısmından indirerek inceleyebilirsiniz. Örnek uygulama içerisinde bulunan bu yazdığımız class’ın nasıl çağrılacağına ait örnek kodlar ve screenshotlar aşağıdadır.
 




            BarcodeDecoder dec = new BarcodeDecoder();
            Image img1 = Image.FromFile(“a.jpg”);
            Image img2 = Image.FromFile(“b.jpg”);
            pictureBox1.Image = img1;
            pictureBox2.Image = img2;
            label1.Text = dec.DecodeCode39(img1);
            label2.Text = dec.DecodeCode39(img2);