C# ile Hava Durumu Programı
Kategori C#, Genel, Programlama, Oluşturulma Jan.03, 2012
C# ile örnek programlarımıza devam ediyoruz. Bu kez bir Hava Durumu programı tasarladım. Aslında amacım hava durumu takip programı yapmaktan öte birkaç teknik göstermek. Öncelikle göstermek istediğim şey resimlerin C# ve GDI+ ile nasıl renklendirileceği. Ayrıca Kış Uykusu konusunda çok mail aldım. Bende C# ile kış uykusu denilen şeyin nasıl yapılacağını göstermeye çalıştım. Başlıyoruz...
1. TASARIM
Son derece çirkin bir ekran görüntüsü değil mi? Tasarım aşamasında seçtiğim renklere takılmayın. Sadece ana form üzerinde çok fazla kontrol vardı ve ayırt etmek güç olduğundan farklı farklı renklerle boyadım. Hepsi bu. Programın çalışma zamanındaki ekran görüntüsü çok şık olacak inanın. Tasarım aşamasında önceki yazılarımda belirttiğim gibi ana formun FormBorderStyle özelliğini None olarak ayarlıyoruz. Form üzerindeki resimler için Picturebox ve yazılar için Label bileşenlerini kullanacağız. Siz, konumlar üzerinde değişikilik yaparak farklı ekran tasarımları elde edebilirsiniz. Denemenizde fayda var. Bu arada tasarım kısmında form üzerindeki birçok kontrol disable durumdadır. Bunun sebebi çalışma sırasındaki sürükleme işleminde kolaylık sağlaması. Sürükleme işlemini ana formun MouseMove olayına bağlamak en kolay yoldu benim için. Gelelim kod kısmına...
2. KOD
Diğer örneklere nazaran biraz daha fazla kod yazdım. Özellikle Renklendirme ve Kış Uykusu için gerekliydi. Ama gözünüz korkmasın oldukça kolaydır. Hava durumu bilgilerini MSN Weather Service' ten alıyoruz. Kaynak kod içinde gerekli URL adresleri mevcut. GetWeatherData() isimli prosedür gerekli internet bağlantısını sağlıyor. Bildiğiniz gibi bu tip bağlantılar için WebClient sınıfınından bir nesne kullanmak en kolay yoldur. Diğer projelerden farklı olarak WebClient ile oluşturduğumuz bağlantıyı asenkron (Async) yapacağız ki bağlantı sırasında diğer ekran işlemleri kesintiye uğramasın. Bağlantıyı sağlayan GetWeatherData() prosedürü aşağıdaki şekildedir. Detaylar kaynak kod içinde mevcut.
private void GetWeatherData() { locationLabel.Text = Properties.Resources.Connecting; RepaintLayeredForm(); UpdateLayeredForm(); string requestURL = String.Format(dataFormat, locationCode, degreeType, culture); WebClient webclient = new WebClient(); webclient.Encoding = Encoding.UTF8; webclient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(OnDownloadStringCompleted); webclient.DownloadStringAsync(new Uri(requestURL)); }
Bu yazıda İnternet bağlantısı ve veri çekme işlemlerinden bahsetmeyeceğim. Bizi asıl ilgilendiren konulara giriş yapalım. Yukarıda belirttiğim gibi Renklendirme ve Kış Uykusu temel hedefimiz.
RENKLENDİRME
GDI+ renklendirme işlemi için bir matris kullanır. Bu matris 5x5 şekilinde kare bir matristir. Sadece köşegenleri 1 olan ve diğer elemanları 0 olan bir matristir bu. C# içinde ColorMatrix adıyla tanımlanmıştır. Temel renklendirme matrisi C# için şu şekildedir:
ColorMatrix matrix = new ColorMatrix(new float[][] { new float[]{ 1f, 0f, 0f, 0f, 0f }, new float[]{ 0f, 1f, 0f, 0f, 0f }, new float[]{ 0f, 0f, 1f, 0f, 0f }, new float[]{ 0f, 0f, 0f, 1f, 0f }, new float[]{ 0f, 0f, 0f, 0f, 1f } });
Benim geliştirdiğim tüm projelerde bu matris kullanılmıştır. Fakat işin sırrı matriste değil kullandığım resimlerde gizlidir. Resimlerimin tamamı gri tonlarından oluşmuştur. Ancak bu tip bir resimde renklendirme istenilen sonucu verir. Hava durumu projesinde ekrandaki resimleri herhangi bir renge çevirmek istediğinizde matris içindeki ilk üç köşegeni değiştirmek yeterlidir. Kodu şu şekilde yazabiliriz:
matrix.Matrix00 = (float)color.R / (float)255; matrix.Matrix11 = (float)color.G / (float)255; matrix.Matrix22 = (float)color.B / (float)255;
Burada dikkat edilirse renk değerleri 255' e bölünmüştür. GDI+ renkler için normalize edilmiş değerler kullanır. Sebebi tamamen bu. Kaynak kod içinde DrawColorizedPicture adında bir prosedür mevcut. Burada PictureBox türünden bir nesne istenilen bir renkte çizilebiliyor.
private void DrawColorizedPicture(PictureBox picture, Color color) { ColorMatrix matrix = new ColorMatrix(new float[][] { new float[]{ 1f, 0f, 0f, 0f, 0f }, new float[]{ 0f, 1f, 0f, 0f, 0f }, new float[]{ 0f, 0f, 1f, 0f, 0f }, new float[]{ 0f, 0f, 0f, 1f, 0f }, new float[]{ 0f, 0f, 0f, 0f, 1f } }); matrix.Matrix00 = (float)color.R / (float)255; matrix.Matrix11 = (float)color.G / (float)255; matrix.Matrix22 = (float)color.B / (float)255; using (ImageAttributes attr = new ImageAttributes()) { attr.SetColorMatrix(matrix); graphics.DrawImage(picture.Image, picture.Bounds, 0f, 0f, picture.Image.Width, picture.Image.Height, GraphicsUnit.Pixel, attr); } }
KIŞ UYKUSU
Bu ifade tamamen benim uydurduğum bir şeydir. Programlama dünyasında Prevent Dragging (Sürükleme önlemi yada engeli) olarak bilinir. Bir de saydamlık ekledim. Daha şık olur diye düşündüm. Bu işlemi yapmak için penceremize WS_EX_TRANSPARENT özelliği eklememiz gerekiyor. Bu özellik pencerenizin fare ile yapılacak tüm olaylara geçirgen davranmasını sağlar. En basit olarak fare ile pencerenin hiçbir yerine tıklatamazsınız. C# ile bir pencereyi kış uykusu moduna geçirmek ve kış uykusundan çıkmasını sağlamak için şu kodları kullanabiliriz:
private void DoHibernate() { long style = Win32.GetWindowLong(this.Handle, Win32.GWL_EXSTYLE).ToInt32(); if ((style & Win32.WS_EX_TRANSPARENT) == 0) { style |= Win32.WS_EX_TRANSPARENT; Win32.SetWindowLong(this.Handle, Win32.GWL_EXSTYLE, (IntPtr)style); opacity = 0x80; } }
Uyandırma işlemi için gereken kod:
private void DoWakeup() { long style = Win32.GetWindowLong(this.Handle, Win32.GWL_EXSTYLE).ToInt32(); if ((style & Win32.WS_EX_TRANSPARENT) != 0) { style &= ~Win32.WS_EX_TRANSPARENT; Win32.SetWindowLong(this.Handle, Win32.GWL_EXSTYLE, (IntPtr)style); opacity = 0xff; } }
Kış uykusuna geçmiş bir pencereyi uyandırmak için yukarıdaki kodu nasıl kullanacağız? Bu işlem biraz daha kod gerektiriyor: Madem ki fare ile tıklatamıyorum o zaman klavyedeki tuşları takip ederim bende... Basit bir Timer bileşeni ile tuşları takip edebilirim aslında. Benim kullandığım teknik şu: Kış uykusuna geçtikten sonra ekranda farenin koordinatlarına bakıyorum ve klavyeden CTRL tuşuna basılıp basılmadığını kontrol ediyorum. Bu iki durum oluşmuşsa pencerenin uyanmasını istiyorum. Tabi bu işlemleri bir Timer' in OnTick olayı içinde yapmanız gerekiyor. Klavyeden CTRL tuşunu ve ekrandaki farenin pencere üzerinde olup olmadığını şu şekilde kontrol edebiliriz:
private void keyTimer_Tick(object sender, EventArgs e) { Win32.Rect rect = new Win32.Rect(); Win32.GetWindowRect(this.Handle, ref rect); Win32.Point p = new Win32.Point(); Win32.GetCursorPos(ref p); if (Win32.PtInRect(ref rect, p)) { short keyState = Win32.GetKeyState(Win32.VK_CONTROL); if ((keyState & 0x8000) != 0) { hibernate = false; SetHibernateState(hibernate); } } }
Evet. Kabaca anlatmaya çalıştım. Eğer kaynak kodu indirip incelerseniz çok daha kolay anlayacağınızı umuyorum. C# ile Hava Durumu programının kaynak kodunu aşağıdaki linkten indirebilirsiniz.
havadurumu-csharp-source.rar [1.85 MB] |
February 26th, 2012 on 10:46 am
WS_EX_TRANSPARENT nasıl eklenir bulamadım 🙁
February 27th, 2012 on 10:49 am
Kaynak kod içinde MainForm.cs dosyasında mevcut. Kaynak kodu indirdiniz mi?
February 28th, 2012 on 5:25 am
evet kaynak kodu indirdim ama o kadar çok kod var ki çorba oldu kafam 🙂 tekrar bi gözden geçirmekte fayda var
February 28th, 2012 on 9:03 am
Açıkçası bu tip programlar için yazdığım kod az bile sayılır 🙂
March 7th, 2012 on 8:55 pm
Görünce bile gözüm korktu indirdim bi baktm vazgeçtim 😀
March 7th, 2012 on 9:59 pm
Ne diyeyim Allah selamet versin o zaman…
March 9th, 2012 on 12:50 pm
Merhaba;
Yukarıda gösterilen 3 günlük rapor veren hava durumu görüntüsünü nereden indirebiliriz?
March 9th, 2012 on 3:59 pm
Tam anlayamadım, görüntü derken resmi mi kastediyorsunuz?
June 16th, 2012 on 4:57 am
teşekkürler faydalı bir paylasım 🙂
June 16th, 2012 on 1:08 pm
Güle güle kullanın…
July 31st, 2012 on 5:07 pm
Merhaba Uygulamamda .NET Framework 4.0 Kullanıyorum Uygulama çalışırken Webclient içini kontrol etiğim zaman
proxy’de bu mesajı veriyor ‘myWebClient.Proxy’ threw an exception of type ‘System.Configuration.ConfigurationErrorsException’
sonra veri çekmiyor hatta oluştu mesajı veriyor bu hata nasıl aşabilir ? teşekkürler
August 1st, 2012 on 12:16 am
Sorunumu çözdüm Derlemeyi any Cpu yapınca oldu ne alaka onu biraz araştırıcam.
January 24th, 2013 on 7:30 pm
Hocam eline sağlık senin programın xml okuma kodlarını kendime uyarladım ve harika çalışıyor. Ancak sana birşey soracağım. skytext yani msn weatherdan dönen değer,ılık,parçalı bulutlu,yağmurlu falan olarak geliyor ya ben orda kendi resimlerimi kullanacağım ancak bunun için tam listesine erişmem lazım bu mümkün mü aceba? kaç farklı durum var hepsi lazım bana yani.
Teşekkürler.
January 24th, 2013 on 11:28 pm
İşine yaradığına sevindim. Tam listeye açıkçası bende erişemedim. Daha önceki Hava Cıva projesinde Yahoo! dan bildiğim kadarıyla 47 adet durum var. Fakat Yahoo ile MSN aynı mı onu bilmiyorum.
January 25th, 2013 on 4:24 pm
Peki ben ulaşmaya çalışacağım.Yahoo’dakilerin listesini alabilme şansım var mı? Ancak bir isteğim daha olacak. Sunrise ve sunset değerlerini çekemedim. Onun için bana bir kod yollarmısın? http://local.msn.com/worldweather.aspx?q=ankara-tur&eid=1648
burdan çekiyorum senin gibi.
January 30th, 2013 on 1:41 pm
Yahoo listesi Hava Cıva projesinin kaynak kodunda mevcut.
July 18th, 2013 on 6:29 pm
öncelikle merhaba ben (c# hava durumu) programı 1 ay önce falan çalıştırdıgımda gayet güzel çalışıyordu fakat şimdi çalışmıyor hata veriyor “Özel durum bir çağırma hedefi tarafından oluşturuldu.” diye bir hata geliyor, acaba msn servisimi degişti lütfen yardım edebilirmidiniz
July 18th, 2013 on 8:00 pm
@ibrahim, dediğin gibi MSN servisinde bazı veriler değiştiği için hata veriyor. Bu tam teşekküllü bir hava durumu programı değil. Sadece geliştirilebilir bir örnek. Doğrudan kullanmamalısın.
May 3rd, 2014 on 7:00 pm
Hocam Programın Guncel Halını Yayınlamanız mumkunmu . Hava durumu cekmeyi bir turlu basaramadım . Projeye eklemem gerekiyor.Yardımcı olursanız çok makbule gecer.İyi çalışmalar
May 21st, 2014 on 6:59 pm
@Hakan, Kusura projeyle uzun zamandır ilgilenemiyorum.
May 7th, 2014 on 8:08 pm
peki bu programı yenileyemezmisiniz
May 21st, 2014 on 6:59 pm
@Dominic, Pek vakit ayıramıyorum. Kaynak kod açık siz yenileyebilirsiniz.
August 24th, 2014 on 8:42 pm
Merhaba,
öncelikle paylaşımınız için teşekkür ederim. Dosyayı indirip çalıştırmaya kalktığımda, program.cs dosyasında “Application.Run(new MainForm());” hatası veriyor. Bu hatayı neden verir ve çözümümü nedir?
November 1st, 2014 on 4:48 pm
@Cihang, anlayamadım. VS hangi sürüm?
August 24th, 2014 on 8:51 pm
Bu arada işletim sistemim win7 prof. ve vs 2010 prof. kullanıyorum
November 28th, 2015 on 8:23 pm
[…] sonucu geliyor fakat şehir ismi listelenmiyordu. Sorunu düzelttim. İlk sürümü merak edenler buradan […]
May 3rd, 2016 on 1:27 pm
Tasarima eklediginiz arka planin formati png ve saydam yerler de beyazlik gorunmuyo ben png ekledigimde saydam yerler jpg gibi beyaz gorunuyo neden olabilir