#1
|
||||
|
||||
C# Projelerinde DLL Kullanımı
C# Projelerinde DLL Kullanımı
Photoshop'ta birçoğumuz görmüşüzdür "eyedropper" aracını. Ekranda herhangi bir noktaya tıkladığımızda o noktanın renk bilgilerini verir. İşte biz de buna benzer bir uygulama geliştireceğiz. İlk olarak yeni bir C# projesi oluşturup projemize "damlalik" ismini verelim. Formumuzun Size özelliğine 200;200 değerini verelim. Ardından projemize Timer nesnesi ekleyip Name özelliğini "timer" , Enabled özelliğini true ve Interval özelliğini ise 100 olarak değiştirelim. Timer nesnesi, belirli zaman aralıklarında bellirli bir işi yapmamıza olanak sağlar. İşte belirli zaman aralığını ise Interval özelliği sağlar. Milisaniye cinsinden değer alır (1 saniye = 1000 milisaniye). Biz de projemizde Interval değerine 100 vererek 1 saniyede 10 defa istediğimiz işi programıza yaptıracağız. Enabled özelliğinin true verilmesinin nedeni ise uygulamamızın çalışır çalışmaz Timer nesnesinin aktif hale gelmesidir. Programımıza yaptıracağımız işi Timer nesnemizin Tick olayına yazacağız. Timer nesnesine kısaca değindikten sonra şimdi projemizde Win32 API lerini nasıl kullanacağımıza bakalım. Kullanacağımız API ler : HDC CreateDC( LPCTSTR lpszDriver, // Ekranımızı belirtir. LPCTSTR lpszDevice, // Aygıtı belirtir. LPCTSTR lpszOutput, // Kullanılmaz. NULL değer verilebilir CONST DEVMODE* lpInitData // isteğe bağlıdır, yazıcıdaki veriler için kullanılır.); Çizim karmaşık ve çok bileşenli bir olaydır. Çizim bileşenleri bir alanda tutulur. Bu alana DC (Device Context) denir. Uygulamamızda işlemleri ekran için yapacağımızdan bir alan oluşturmamız gerekir ki bunu da CreateDC fonksiyonu ile yapacağız. Fonskiyonun geri dönüş değeri HDC türündendir.(Aslında void * ın typedef edilmiş halidir.) BOOL DeleteDC( HDC hdc // oluşturduğumuz DC alanı); CreateDC ile oluşturduğumuz alanın sisteme iade edilmesi için bu fonksiyonu kullanacağız. Fonksiyonun geri dönüş değeri BOOL yane boolean türündendir(true yada false). COLORREF GetPixel( HDC hdc, // oluşturduğumuz DC alanı int nXPos, // pixelin x koordinatı int nYPos // pixelin y koordinatı); Bu fonksiyon yardımı ile ekrandaki herhangi bir pixelin renk değerlerini alacağız. Fonksiyonun geri dönüş değeri COLORREF türündendir. Bu ise renkleri RGB formatında tutar. .NET te ise renk formatı farklıdır. Ama küçük matematik hesabı ile bu tür dönüşümünü yapacağız. Kullanacağımız API ler bunlardı. Bu üç fonksiyonumuz da gdi32.dll dosyasındadır. Şimdi nasıl kullanacağımıza değinelim. Bunun için projemize using System.Runtime.InteropServices; isim uzayını (namaspace) eklememiz gerekiyor. DLL leri kullanabilmemizi sağlayan çeşitli özellikleri bu isim uzayından yararlanarak vereceğiz. Bir DLL i projemizde kullanmak için [DllImport(…)] özelliğini (attribute) kullanmamız gerekli. Bu özellik ile çağırdığımız WIN32 API leri hakkında bilgi vermektir. Örneğin CreateDC fonksiyonumuzu çağıralım : [DllImport("gdi32.dll")] public static extern IntPtr CreateDC(string strDriver, string strDevice, string strOutput, IntPtr pData); İşte fonksiyonu çağırmış olduk. Şimdi diyeceksiniz ki, "bu Intptr string nerden çıktı". Hemen açıklayayım: WIN32 API deki veri türleri ile .NET Framework teki veri türleri farklı isimlendirilmiştir. Bizler LPCTSTR, HDC gibi API ye özgü veri türlerinin karşılığı C# ta string, IntPtr dir. Bu yüzden bu isimleri C# ın anlayacağı şekle getirdik.Şimdi diğer fonksiyonlarımızı da ekleyelim. [DllImport("gdi32.dll")] public static extern bool DeleteDC(IntPtr hdc);[DllImport("gdi32.dll")] public static extern int GetPixel(IntPtr hdc, int x, int y); Şimdi uygulamamıza adım adım devam edelim. Pixel deki renk bilgilerini tutmak için 2 tane Color yapısından değişken tanımlayalım Color clr, clrLast; clrLast bir önceki renk bilgilerini, clr ise o andaki renk bilgilerini tutmakta kullanacağız. Şimdi sıra geldi her 1/10 sn de ekrandaki pixel değerini alıp işlemeye. Bunun için timer nesnemizin Tick olayına aşağıdaki kodu yazıyoruz. Point pt = MousePosition; // faremizin koordinatlarını alıyoruz.IntPtr hdcScreen = CreateDC("Display", null, null, IntPtr.Zero); // "Display" ile ekran için bir alan oluşturuyoruz.int cr = GetPixel(hdcScreen, pt.X, pt.Y); // Ekrandaki pixelin renk değerini alıp, cr değişkenine atadık.DeleteDC(hdcScreen); //Alan ile işimiz bitti. Bilgilerimizi aldık şimdi bu alanı sisteme geri iade ettik.clr = Color.FromArgb((cr & 0x000000FF),(cr & 0x0000FF00) >> 8,(cr & 0x00FF0000) >> 16); // WIN32 renk formatından .NET renk nesnesine dönüşüm yapıldı.if (clr != clrLast){ Invalidate(); // eğer ilk renk bir önceki renge eşitse işlem yapmaya gerek yok.Invalidate(…) ise fonksiyonu belirli bir alanın yeniden boyanmasını sağlar. Yani // belirli bir alana paint mesajı göndererek sadece bizim belirlediğimiz alanın yenilenmesini sağlar. Burda eğer elimizdeki renk ile bir önceki renk //farklı ise formuzun yeni bilgileri göstermesi için OnPaint olayına ihtiyacı var ve Invalidate(…) bunu gerçekleştiriyor. } Sırada elde ettiğimiz bilgileri forma yazmaya geldi. Bunu için formun OnPaint olayına aşağıdaki kodu ekleyelim. if (clr != clrLast) // Eğer ilk renk bir önceki renge eşit ise bilgileri güncellemeye gerek yok.{ Graphics grfx = e.Graphics; // Graphics nesnemizi oluşturduk. clrLast = clr; //ilk rengimiz bir önceki renkten farklı olduğu için önceki rengimizi yeni renk ile değiştiriyoruz. StringFormat strfmt = new StringFormat(); // strfmt.Alignment = strfmt.LineAlignment = StringAlignment.Center; // formumuza yazacağımız yazının formatı için StringFormat(…) sınıfındabir nesne oluşturduk. // Center değeri ile yazılarımız formun merkezine yazılacak Color exTextColor = Color.FromArgb(255, (byte)(255^clr.R), (byte)(255^clr.G), (byte)(255^clr.B)); // formdaki yazı için yazı rengi belirliyoruz SolidBrush sBrush = new SolidBrush(exTextColor); // yazımız için força oluşturuyoruz SolidBrush fBrush = new SolidBrush(clr); //formumuzu boyamak için fırça oluşturuyoruz grfx.FillRectangle(fBrush,0,0,this.ClientRectangle .Width,this.ClientRectangle.Height); // formumuzu ekrandan elde ettiğimiz renkle boyuyoruz grfx.DrawString("\nKırmızı: " + clr.R.ToString("X00") + " - " + clr.R.ToString() + // Bilgileri forma yazdırıyoruz. "\nYeşil: " + clr.G.ToString("X00") + " - " + clr.G.ToString()+ "\nMavi: " + clr.B.ToString("X00") + " - " + clr.B.ToString()+ "\n\nYoğunluk: " + clr.GetHue().ToString()+ "\nDoygunluk: " + clr.GetSaturation().ToString("0.000f")+ "\nParlaklık: " + clr.GetBrightness().ToString("0.000f"), Font,sBrush,ClientRectangle, strfmt); fBrush.Dispose(); //Fırçalarımızı bellekten siliyoruz. sBrush.Dispose(); Invalidate(); // ve forma yazdığımız bilgilerin güncellenmesini sağlıyoruz..} Son olarak ise formumuzun zeminin onPaint olayından etkilenmemesi için OnPaintBackGround(…) olayini override edelim ve hiç bir şey yapmamasını sağlayalım |