<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Shenturk.com &#187; source</title>
	<atom:link href="http://www.shenturk.com/tag/source/feed" rel="self" type="application/rss+xml" />
	<link>http://www.shenturk.com</link>
	<description>Hava Durumu, Hava Cıva!, ADSL Kota, Ey DSL!, Döviz, Mini Döviz, Radyo, RDK, Haber...</description>
	<lastBuildDate>Fri, 10 Feb 2012 07:30:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>C# ile Hava Durumu Programı</title>
		<link>http://www.shenturk.com/genel/c-ile-hava-durumu-programi</link>
		<comments>http://www.shenturk.com/genel/c-ile-hava-durumu-programi#comments</comments>
		<pubDate>Tue, 03 Jan 2012 10:50:36 +0000</pubDate>
		<dc:creator>freedelphi</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Genel]]></category>
		<category><![CDATA[Programlama]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[2008]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[ders]]></category>
		<category><![CDATA[ders notları]]></category>
		<category><![CDATA[diziler]]></category>
		<category><![CDATA[durumu]]></category>
		<category><![CDATA[forecast]]></category>
		<category><![CDATA[hava]]></category>
		<category><![CDATA[indir]]></category>
		<category><![CDATA[kaynak]]></category>
		<category><![CDATA[kod]]></category>
		<category><![CDATA[notlar]]></category>
		<category><![CDATA[örnek]]></category>
		<category><![CDATA[sample]]></category>
		<category><![CDATA[source]]></category>
		<category><![CDATA[Studio]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[Visual]]></category>
		<category><![CDATA[weather]]></category>

		<guid isPermaLink="false">http://www.shenturk.com/?p=1454</guid>
		<description><![CDATA[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. [...]]]></description>
			<content:encoded><![CDATA[<div class="wp-caption aligncenter" style="width: 460px"><img title="C# ile Hava Durumu Programı" src="http://www.shenturk.com/images/img0180.jpg" alt="C# ile Hava Durumu Programı" width="377" height="413" /><p class="wp-caption-text">C# ile Hava Durumu Programı</p></div>
<p>C# ile örnek programlarımıza devam ediyoruz. Bu kez bir <strong>Hava Durumu</strong> 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 <strong>Kış Uykusu</strong> 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...</p>
<p><strong>1. TASARIM</strong></p>
<div class="wp-caption aligncenter" style="width: 460px"><img title="C# ile Hava Durumu Programı Tasarım Aşaması" src="http://www.shenturk.com/images/img0181.jpg" alt="C# ile Hava Durumu Programı Tasarım Aşaması" width="378" height="459" /><p class="wp-caption-text">C# ile Hava Durumu Programı Tasarım Aşaması</p></div>
<p>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 <strong>FormBorderStyle</strong> özelliğini <strong>None</strong> 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...</p>
<p><strong>2. KOD</strong></p>
<p>Diğer örneklere nazaran biraz daha fazla kod yazdım. Özellikle <strong>Renklendirme</strong> ve <strong>Kış Uykusu</strong> için gerekliydi. Ama gözünüz korkmasın oldukça kolaydır. Hava durumu bilgilerini <strong>MSN Weather Service</strong>' ten alıyoruz. Kaynak kod içinde gerekli URL adresleri mevcut. <strong>GetWeatherData()</strong> isimli prosedür gerekli internet bağlantısını sağlıyor. Bildiğiniz gibi bu tip bağlantılar için <strong>WebClient</strong> 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 GetWaetherData() prosedürü aşağıdaki şekildedir. Detaylar kaynak kod içinde mevcut.</p>
<pre class="brush: c-sharp;">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));
}
</pre>
<p>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.</p>
<p><strong>RENKLENDİRME</strong><br />
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:</p>
<pre class="brush: c-sharp;">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 }
});
</pre>
<p>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ı <strong>gri tonlarından</strong> 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:</p>
<pre class="brush: c-sharp;">matrix.Matrix00 = (float)color.R / (float)255;
matrix.Matrix11 = (float)color.G / (float)255;
matrix.Matrix22 = (float)color.B / (float)255;
</pre>
<p>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.</p>
<pre class="brush: c-sharp;">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);
	}
}
</pre>
<p><strong>KIŞ UYKUSU</strong><br />
Bu ifade tamamen benim uydurduğum bir şeydir. Programlama dünyasında <strong>Prevent Dragging</strong> (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 <strong>WS_EX_TRANSPARENT</strong> ö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:</p>
<pre class="brush: c-sharp;">private void DoHibernate()
{
	long style = Win32.GetWindowLong(this.Handle, Win32.GWL_EXSTYLE).ToInt32();
	if ((style &#038; Win32.WS_EX_TRANSPARENT) == 0)
	{
		style |= Win32.WS_EX_TRANSPARENT;
		Win32.SetWindowLong(this.Handle, Win32.GWL_EXSTYLE, (IntPtr)style);
		opacity = 0x80;
	}
}
</pre>
<p>Uyandırma işlemi için gereken kod:</p>
<pre class="brush: c-sharp;">private void DoWakeup()
{
	long style = Win32.GetWindowLong(this.Handle, Win32.GWL_EXSTYLE).ToInt32();
	if ((style &#038; Win32.WS_EX_TRANSPARENT) != 0)
	{
		style &#038;= ~Win32.WS_EX_TRANSPARENT;
		Win32.SetWindowLong(this.Handle, Win32.GWL_EXSTYLE, (IntPtr)style);
		opacity = 0xff;
	}
}
</pre>
<p>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:</p>
<pre class="brush: c-sharp;">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 &#038; 0x8000) != 0)
		{
			hibernate = false;
			SetHibernateState(hibernate);
		}
	}
}
</pre>
<p>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.</p>
<table>
<tbody>
<tr>
<td><a href="http://www.shenturk.com/downloads/havadurumu-csharp-source.rar"><img src="http://www.shenturk.com/images/img0166.png" alt="" /></a></td>
<td><a href="http://www.shenturk.com/downloads/havadurumu-csharp-source.rar">havadurumu-csharp-source.rar [1.85 MB]</a></td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.shenturk.com/genel/c-ile-hava-durumu-programi/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Delphi ile Analog Clock</title>
		<link>http://www.shenturk.com/delphi/delphi-ile-analog-clock</link>
		<comments>http://www.shenturk.com/delphi/delphi-ile-analog-clock#comments</comments>
		<pubDate>Mon, 18 Jul 2011 11:37:56 +0000</pubDate>
		<dc:creator>freedelphi</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Genel]]></category>
		<category><![CDATA[Programlama]]></category>
		<category><![CDATA[analog]]></category>
		<category><![CDATA[clock]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[gadget]]></category>
		<category><![CDATA[kaynak]]></category>
		<category><![CDATA[kod]]></category>
		<category><![CDATA[layered]]></category>
		<category><![CDATA[layeredwindow]]></category>
		<category><![CDATA[örnek]]></category>
		<category><![CDATA[saat]]></category>
		<category><![CDATA[sample]]></category>
		<category><![CDATA[source]]></category>
		<category><![CDATA[updatelayeredwindow]]></category>
		<category><![CDATA[widget]]></category>
		<category><![CDATA[yazılım]]></category>

		<guid isPermaLink="false">http://www.shenturk.com/?p=1127</guid>
		<description><![CDATA[Delphi ile Generic Clock örneği işinizi görmüştür umarım. Generic Clock projesinde yapacağımız küçük bir değişiklikle yeni projeler üretebiliriz aslında. Bilgisayar kullanıcılarının en çok tercih ettiği masaüstü araçlarından biri olan "Analog Clock" bu yazmının konusunu oluşturuyor. Siz Delphi kullanıcıları için elimden geldiği kadar sadeleştirmeye çalıştım. Başlayalım... 1. TASARIM Form tasarımı aşamasında dikkat edilmesi gereken birkaç ufak [...]]]></description>
			<content:encoded><![CDATA[<div class="wp-caption aligncenter" style="width: 380px"><img title="Analog Clock Ekran Görüntüsü" src="http://www.shenturk.com/images/img0167.png" alt="Analog Clock Ekran Görüntüsü" width="370" height="237" /><p class="wp-caption-text">Delphi ile Analog Clock</p></div>
<p>Delphi ile <a title="Delphi, GDI+ ve UpdateLayeredWindow" href="http://www.shenturk.com/delphi/delphi-gdi-ve-updatelayeredwindow">Generic Clock</a> örneği işinizi görmüştür umarım. Generic Clock projesinde yapacağımız küçük bir değişiklikle yeni projeler üretebiliriz aslında. Bilgisayar kullanıcılarının en çok tercih ettiği masaüstü araçlarından biri olan <strong>"Analog Clock"</strong> bu yazmının konusunu oluşturuyor. Siz Delphi kullanıcıları için elimden geldiği kadar sadeleştirmeye çalıştım. Başlayalım...</p>
<h3>1. TASARIM</h3>
<div class="wp-caption aligncenter" style="width: 414px"><img title="Delphi ile Analog Clock Tasarımı" src="http://www.shenturk.com/images/img0168.png" alt="Delphi ile Analog Clock Tasarımı" width="404" height="246" /><p class="wp-caption-text">Delphi ile Analog Clock Tasarımı</p></div>
<p>Form tasarımı aşamasında dikkat edilmesi gereken birkaç ufak tefek ayrıntı var. Önceki örneklerde açıkladığım gibi öncelikle ana formun <strong>BorderStyle</strong> özelliğini <strong>bsNone</strong> olarak ayarlamalıyız. Diğer önemli kısım ise <strong>Sağ Tuş Menüsü</strong> eklemek. Programda görselliği bozmamak için "Kapat" düğmesi kullanmadım. Bu yüzden farenin sağ tuşuna bastığımızda içerik menüsüne ihtiyaç duyacağız. Burada programdan çıkış işlemini "Kapat Menüsü" yardımıyla yapacağız. Tasarım aşamasını şöyle özetliyebiliriz:</p>
<ul>
<li>Ama formun Client boyutları saat resminin boyutları ile aynı olacak (ClientWidth = 130, ClientHeight = 130)</li>
<li><strong>BorderStyle</strong> özelliği <strong>bsNone</strong> olarak ayarlanacak</li>
<li>Ana forma <strong>Timer</strong> ve <strong>PopupMenu</strong> bileşenleri eklenecek</li>
</ul>
<p>Tasarım kısmı bu kadar. Yukarıdaki ekran alıntısında örnek bir görüntü mevcut. Gelelim algoritma kısmına...</p>
<h3><strong>2. ALGORITMA</strong></h3>
<p>Algoritma kısmında temel çizim işlemlerinden bahsetmeyeceğim. Bu konulara daha önceki örnekte değinmiştim. Fakat açıklanması gereken önemli bir kısım var:  Akrep, yelkovan ve saniye gibi saati oluşturan parçaların çizilmesi... Temel olarak bu parçalar belli bir eksen etrafında belirli açılarla dönerler. Bu açılar saatin kaç olduğuna göre değişmektedir. Örnegin Akrep çizimi için saatin 03:00:00 olduğu durumda 45 derecelik açı ile çizilmesi gerekmektedir. Bu hesaplamalar basit matematik işlemlerinden başkası değildir. Bu projede açı hesaplamalarını <strong>PaintElements</strong> prosedürü içine yerleştirdim. Aşağıdaki kod parçasını incelemekte fayda var sanırım.</p>
<p><code>procedure TForm1.PaintElements;<br />
var<br />
Hour, Minute, Second, MSec: Word;<br />
State: GraphicsState;<br />
Dx, Dy, Ox, Oy: Single;<br />
AngleS, AngleM, AngleH: Single;<br />
begin<br />
{ Acilari su anki saate gore hesapla. }<br />
DecodeTime(SysUtils.Now, Hour, Minute, Second, MSec);<br />
AngleS := Second * 6;<br />
AngleM := Minute * 6 + AngleS / 60;<br />
AngleH := Hour * 30 + AngleM / 12;<br />
{ Orta noktayi ekran genisligine gore bul. }<br />
Dx := Self.Width / 2 - 1;<br />
Dy := Self.Height / 2 - 1;<br />
Ox := -6; // -13 div 2<br />
Oy := -64; // -129 div 2<br />
with FGraphics do<br />
begin<br />
{ Cizim alaninin durmunu sakla. }<br />
State := Save();<br />
{ Baslangic cizim noktasini formun ortasina konumlandir. }<br />
TranslateTransform(Dx, Dy);<br />
{ Saat parcasini ciz }<br />
RotateTransform(AngleH);<br />
DrawImage(FHour, Ox, Oy, 13, 129);<br />
RotateTransform(-AngleH);<br />
{ Dakika parcasini ciz }<br />
RotateTransform(AngleM);<br />
DrawImage(FMinute, Ox, Oy, 13, 129);<br />
RotateTransform(-AngleM);<br />
{ Saniye parcasini ciz }<br />
RotateTransform(AngleS);<br />
DrawImage(FSecond, Ox, Oy, 13, 129);<br />
RotateTransform(-AngleS);<br />
{ Nokta parcasini ciz }<br />
DrawImage(FDot, Ox, Oy, 13, 129);<br />
{ Cizim alaninin durumunu eski haline getir. }<br />
Restore(State);<br />
end;<br />
end;<br />
</code><br />
GDI+ ile belirli bir açıda resim çizme işlemi biraz karışıktır. Dikkat edilmesi gereken en önemli kısım çizim alanımızın başlangıç kooardinatlarının ayarlanması. Varsayılan olarak başlangış koordinatları (0, 0) sol üst köşe olarak seçilmiştir. Buradaki örnekte Dx, Dy değişkenleri formun orta noktasına işaret ediyor. GDI+ ile başlangış koordinatlarını değiştirmek için <strong>TranslateTransform</strong> fonksiyonunu kullanmamız gerekiyor. Başlangıç koordinatlarını (0, 0) noktasından (Dx, Dy) noktasına taşıyoruz. Açıklanması gereken önemli bir kısım ise resimlerin çizilirken başlangıç noktasına göre yeni koordinatlarının hesaplanması işlemi. Örneğimizde Ox ve Oy değişkenlerini bunun için kullanancağız. Akrep ve yelkovan resimlerimizin boyutları 13x129 piksel olduğundan bu resimlerin orta noktası tam sayı olarak (6,64) olacaktır. Fakat Transform işleminden dolayı resmin orta noktası (-6, -64) olacaktır. Açı hesaplamaları kaynak kod içinden anlaşılabilir durumda. Bu bölüme değinmeğe gerek yok sanırım. Eğer <strong>Transform</strong> ve <strong>Rotate</strong> işlemleri sırasında sorun yaşarsanız bana mail atabilirsiniz. Şimdilik bu proje hakkında söyleyeceklerim bu kadar. Analog Clock projesinin kaynak kodunu aşağıdaki linkten indirebilirsiniz.</p>
<table>
<tbody>
<tr>
<td><a href="http://www.shenturk.com/downloads/analog-clock-source.rar"><img src="http://www.shenturk.com/images/img0164.png" alt="Analog Clock Kaynak Kod İndir" /></a></td>
<td><a href="http://www.shenturk.com/downloads/analog-clock-source.rar">analog-clock-source.rar [366 KB]</a></td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.shenturk.com/delphi/delphi-ile-analog-clock/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Delphi, GDI+ ve UpdateLayeredWindow</title>
		<link>http://www.shenturk.com/delphi/delphi-gdi-ve-updatelayeredwindow</link>
		<comments>http://www.shenturk.com/delphi/delphi-gdi-ve-updatelayeredwindow#comments</comments>
		<pubDate>Mon, 11 Jul 2011 13:05:52 +0000</pubDate>
		<dc:creator>freedelphi</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Genel]]></category>
		<category><![CDATA[Programlama]]></category>
		<category><![CDATA[clock]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[gdi+]]></category>
		<category><![CDATA[generic]]></category>
		<category><![CDATA[katmanlı]]></category>
		<category><![CDATA[layered]]></category>
		<category><![CDATA[pencere]]></category>
		<category><![CDATA[saat]]></category>
		<category><![CDATA[source]]></category>
		<category><![CDATA[updatelayeredwindow]]></category>
		<category><![CDATA[window]]></category>

		<guid isPermaLink="false">http://www.shenturk.com/?p=1039</guid>
		<description><![CDATA[Son günlerde Delphi ve GDI+ ile ilgili oldukça mail almaktayım. Aslında uzun zamandır yazmak istediğim bir yazı bu. Yazının konusu Delphi bilen yazılımcı arkadaşları yakından ilgilendiriyor. Başlıktan da anlaşılacağı üzere Delphi ile GDI+ kullanımı hakkında. Geçen sene bir arkadaşımız bana mail göndermişti. Hava Cıva! kodunun karışık olduğunu söylüyodu. Hava Cıva! gibi bir arayüzün daha basit [...]]]></description>
			<content:encoded><![CDATA[<div class="wp-caption aligncenter" style="width: 382px"><img title="Delphi ile Generic Clock" src="http://www.shenturk.com/images/img0162.png" alt="Delphi ile Generic Clock" width="372" height="237" /><p class="wp-caption-text">Delphi ile Generic Clock</p></div>
<p>Son günlerde Delphi ve GDI+ ile ilgili oldukça mail almaktayım. Aslında uzun zamandır yazmak istediğim bir yazı bu. Yazının konusu Delphi bilen yazılımcı arkadaşları yakından ilgilendiriyor. Başlıktan da anlaşılacağı üzere Delphi ile GDI+ kullanımı hakkında. Geçen sene bir arkadaşımız bana mail göndermişti. Hava Cıva! kodunun karışık olduğunu söylüyodu. Hava Cıva! gibi bir arayüzün daha basit bir şekilde nasıl yapılacağını merak etmiş. Bende üşenmedim ona çok basit bir saat programı yazmıştım. Delphi ile temel GDI+ tekniklerinin nasıl kullanılacağını göstermiştim. İşte konumuz bu işlemin nasıl yapılacağını anlatıyor. Eğer Delphi biliyorsanız çok basit bir şekilde Hava Cıva! gibi bir arayüz tasarlayabileceksiniz. Hemen başlayalım...</p>
<p>Projenin adı <strong>Generic Clock</strong>. Adından da anlaşılacağı üzere temel bir saat projesi. Uygulama geliştirme ortamı olarak Delphi 7 kullandım. Ayrıca GDI+ kütüphanesi de gerekli bizim için. Gerçi projenin kaynak kodunda GDI+ kütüphanesi mevcut ama yine de orjinal kütüphaneyi indirmek isteyenler için adresi verelim: <a href="http://www.progdigy.com/" target="_blank">Delphi için GDI+ Kütüphanesi</a></p>
<p><strong>1. TASARIM</strong><br />
Doğal olarak ilk önce ekran tasarımını yapmamız gerekiyor. Bunun için projenin ana formunda bazı değişiklikler yapılmalı. Bunlardan en önemlisi ana formun <strong>BorderStyle</strong> özelliğinin <strong>bsNone</strong> olarak ayarlanması. Neden mi? Widget (yada Gadget) tarzı arayüze sahip uygulamalarda pencerelerin kenarlı olması pek işimize yaramaz. Hatta işimizi daha da zorlaştırır. Bu uygulamada olduğu gibi zemin için bir resim seçeceğiz ve formumuzun zeminini seçtiğimiz resim ile kaplayacağız. Başlıksız ve kenarlıksız bir pencereye resmi uydurmak çok daha kolay olacaktır. Formun başlık bölümü olmadığına göre doğal olarak <strong>Kapat</strong> düğmeside olamıyor. Bu sorunu gidermek için formumuza bir <strong>Kapat</strong> düğmesi eklememiz gerekiyor. Bu düğmeyi ekledikten sonra bir <strong>StaticText</strong> ve bir de <strong>Timer</strong> bileşenin ekliyoruz. Son olarak pek önemli olmayan detaylar var. Örneğin ben ana formun <strong>Position</strong> özelliğini <strong>poScreenCenter</strong> olarak ayarladım. Ekranın ortasından başlasın diye. Diğer bileşenlerin boyutları ve konumları sizin isteğinize bağlı aslında. Ama örneğe sadık kalırsanız karışıklık olmadan anlayabilirsiniz. Tasarım kısmında hepsi bu. Tasarım için örnek bir resim aşağıda görüntüleniyor.</p>
<div class="wp-caption aligncenter" style="width: 423px"><img title="Delphi ile Generic Clock Tasarımı" src="http://www.shenturk.com/images/img0163.png" alt="Delphi ile Generic Clock Tasarımı" width="413" height="305" /><p class="wp-caption-text">Delphi ile Generic Clock Tasarımı</p></div>
<p><strong>2. ALGORITMA</strong><br />
Bu bölümde GDI+ ile Delphi formlarının nasıl ilişkilendirileceğinden bahsedeceğim. İlk öğrenmemiz gereken kısım klasik GDI çizim tekniklerini formumuzda kullanamayacağımızdır. Eğer gölgeli, saydam ve şık bir arayüz istiyorsak GDI tarafından sağlanan araçlar işimizi görmez. En başta GDI' nin renk desteği zayıftır. Oysa GDI+ Alpha channel ile 32-bit renk desteği sağlar. Bu sayede saydam pencereler oluşturabiliriz.<br />
Şimdi aklımızdan kesinlikle çıkarmamız gereken çok önemli bir kısma geldik: <strong>LayeredWindows</strong>! Katmanlı Pencereler olarak çevireceğiz bu terimi. Windows 2000 ile birlikte gelen bir pencere özelliğidir bu. Widget tarzı programların temelini oluşturur. Eğer formumuza katmalı pencere özelliği eklemezsek boşa uğraşmış oluruz. Peki nasıl yapacağız? O kısım oldukça kolay aslında. Formumuzun <strong>FormCreate</strong> olayına aşağıdaki kodu ekleyeceğiz.<br />
<code>SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_LAYERED);</code>Bu kodu ekledikten sonra diğer önemli bir kısımdan bahsetmek gerek. Microsoft MSDN' de belirttiği üzere <strong>"eğer pencereniz katmanlı olarak ayarlandıysa WM_PAINT mesajı oluşturulmaz!"</strong> MSDN' de bu yazıyı okuduktan sonra ne yapacağımı şaşırmıştım açıkçası. Windows'ta WM_PAINT mesajı oluşmuyorsa Delphi' de <strong>OnPaint</strong> olayı da oluşmaz! Bu karmaşayı aşmak için yine Windows API' den faydalanmamız gerekecek. Çözüm için <strong>UpdateLayeredWindow</strong> fonksiyonunu kullanacağız. Bu fonksiyon oldukça karışıktır. Benden söylemesi. Detaylı açıklamayı MSDN' den mutlaka okuyunuz (<a href="http://msdn.microsoft.com/en-us/library/ms633556(VS.85).aspx" target="_blank">MSDN: UpdateLayeredWindow</a>). Ben bu fonksiyonun nasıl kullanılacağını kaynak kod içinde gösterdim. <strong>UpdateLayeredForm</strong> yordamına bakmanız yeterlidir.<br />
<code>procedure TForm1.UpdateLayeredForm;<br />
var<br />
SrcDC, DestDC: HDC;<br />
BitmapHandle, PrevBitmap: HBITMAP;<br />
BlendFunc: _BLENDFUNCTION;<br />
Size: TSize;<br />
P, S: TPoint;<br />
begin<br />
{ Desktop ile uyumlu bir DC olustur. (Yada 0 yerine GetDesktopWindow yazabiliriz) }<br />
SrcDC := CreateCompatibleDC(0);<br />
{ Olusturdugumuz DC ile uyumlu yeni bir DC daha olusturmaliyiz. Kopyalama icin. }<br />
DestDC := CreateCompatibleDC(SrcDC);<br />
{ Cizim yaptigimiz resmin Windows tarafidan anlasilan HBITMAP turunden degiskene ata. }<br />
{ Bu kisim onemli. Cizim yaptigimiz resmi gercek dunyaya getiriyoruz. }<br />
{ BitmapHandle degiskeni artik Windows tarafindan kullanilanilabilir duruma geldi. }<br />
FBitmap.GetHBITMAP(0, BitmapHandle); { 0 = Background transparent, out BitmapHandle }<br />
{ SrcDC de bitmap secilmeli }<br />
PrevBitmap := SelectObject(SrcDC, BitmapHandle);<br />
{ Boyutlar ve konum }<br />
Size.cx := Width;<br />
Size.cy := Height;<br />
P := Point(Left, Top);<br />
S := Point(0, 0);<br />
with BlendFunc do<br />
begin<br />
BlendOp := AC_SRC_OVER;<br />
BlendFlags := 0; { Sifir olmali }<br />
SourceConstantAlpha := FOpacity; { Ana formun donukluk degeri. 0 = tam saydam, 255 = tam donuk. }<br />
AlphaFormat := AC_SRC_ALPHA;<br />
end;<br />
{ Microsoft'un sihirli fonksiyonu! Oylesine onemli ki, aslinda butun kiyamet burada kopuyor. }<br />
{ Detayli aciklamayi MSDN' den mutlaka okuyunuz. http://msdn.microsoft.com/en-us/library/ms633556(VS.85).aspx }<br />
UpdateLayeredWindow(Handle, DestDC, @P, @Size, SrcDC, @S, 0, @BlendFunc, ULW_ALPHA);<br />
{ SrcDC yi eski haline getir. }<br />
SelectObject(SrcDC, PrevBitmap);<br />
{ ve Bitmap'i yok et. Yoksa hafiza sizmasi olur. }<br />
DeleteObject(BitmapHandle);<br />
{ DC leri yok et. }<br />
DeleteDC(DestDC);<br />
DeleteDC(SrcDC);<br />
end;</code>Karmaşa hala devam ediyor... Madem windows bizim için WM_PAINT olayını oluşturmuyor o zaman bizim elle bu olayı tetiklememiz gerekiyor! Kendinizi resim yapıyor gibi düşünün. Önce zemini çizeceğiz sonra diğer bileşenleri vs. Böylelikle oluşan resmi formumuzda göstereceğiz. Mantık basit: Resmi çiz (RepaintForm) ve ekranda güncelle (UpdateLayeredForm).<br />
Örneğin bu projede saati saniye saniye ekranda göstermemiz gerekiyor. Bu durumda her saniye form alanını güncellemeliyiz. Bunun için Timer bileşeninden faydalanacağız.<br />
<code>procedure TForm1.Timer1Timer(Sender: TObject);<br />
begin<br />
{ Her saniye form alanini yeniden cizmek zorundayiz. }<br />
RepaintForm;<br />
{ Ayrica cizdigimiz form alanini guncellemeliyiz. }<br />
UpdateLayeredForm;<br />
end;</code></p>
<p>Bu proje hakkında yazacaklarım şimdilik bu kadar. Widget tarzı programlarda can alıcı noktaları açıklamaya çalıştım. Projenin kaynak kodunu aşağıdaki linkten indirebilirsiniz.</p>
<table>
<tbody>
<tr>
<td><a href="http://www.shenturk.com/downloads/generic-clock-source.rar"><img src="http://www.shenturk.com/images/img0164.png" alt="" /></a></td>
<td><a href="http://www.shenturk.com/downloads/generic-clock-source.rar">generic-clock-source.rar [290 KB]</a></td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.shenturk.com/delphi/delphi-gdi-ve-updatelayeredwindow/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

