<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Hüseyin Tüfekçilerli]]></title>
  <link href="http://huseyint.com/atom.xml" rel="self"/>
  <link href="http://huseyint.com/"/>
  <updated>2024-05-23T13:10:12+00:00</updated>
  <id>http://huseyint.com/</id>
  <author>
    <name><![CDATA[Hüseyin Tüfekçilerli]]></name>
    <email><![CDATA[huseyint@gmail.com]]></email>
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Bisiklet ile Selanik ve Atina yolculuğu]]></title>
    <link href="http://huseyint.com/2014/10/Bisiklet-ile-Selanik-ve-Atina-yolculugu/"/>
    <updated>2014-10-11T00:00:00+00:00</updated>
    <id>http://huseyint.com/2014/10/Bisiklet-ile-Selanik-ve-Atina-yolculugu</id>
    <content type="html"><![CDATA[<p>Bir arkadaşımın gaza getirmesi sonucu başladı bu girişim. Bisiklet ile uzun zamandır pek alakam yoktu, çocukluğumuzun bisiklet üzerinde geçmesindendir belki hevesimi almıştım. Bisikleti hep zevk için değil de okula işe gitmek gibi bir amaç uğruna kullanmayı mantıklı buluyordum. Öyle bisikletimi alayım şurada gezeyim olayını sevmiyordum yani. İstanbul’da yaşayan biri olarak da bu amaç doğrultusunda bisiklet kullanamayacağınız malum. O yüzden sırf bu tur için bir bisiklet aldım, belki dönüşte satarım diyordum.</p>

<p>İşin içine girince kaybolacağınız türden işlerden biriymiş bu da, bir sürü marka var bunların farklı türdeki ve kalitedeki bisikletleri var, bana ne lazım tam bir fikrim yok, yeni mi alsam yoksa ikinci el bir şey işimi görür mü sorunu… Velhasıl tercih yapma süreci kolay olmadı. Kadıköy’deki Velespit Bisiklet’teki satıcının övmesi üzerine Trek markasını tanıdım ve ertesi gün sahibinden.com’da bulduğumuz bir ilan ile çok az kullanılmış bir Trek FX 7.3 bisiklet satın aldım. Almakla bitmedi tabii iş, üzerindeki eksikleri tamamladık hemen: çamurluk, port bagaj, ayaklık, zil, vs. taktırdık. Bisiklet işi bisikleti donatmakla bitmiyor, sürücünün de giydiği kask, eldiven, vs. gibi aksesuarlar var, bunları da Decathlon’dan tamamladık. Eşyalarımızı koymak için bisiklete özel heybelerden aldık, su geçirmez olmalarına dikkat ettik.</p>

<p>Bisiklet ile son zamanlarda öyle pek ilgim yok dedim ama bisikleti alıp eve getirdiğim gün işler değişti, adeta bir çocuk gibi heyecanlandım ve gece şu şekilde uyudum: “Bu bisikleti ben yarın süreceğim, kaçarı yok!”. Sabah kalkar kalkmaz aldım bisikleti, fırladım İstanbul sokaklarına. Mecidiyeköy’den evden çıkıp Ortaköy’e indim oradan ver elini Bebek-Yeniköy-Tarabya. Biraz dinlendikten sonra Ortaköy’e döndüm, amacım Mecidiyeköy’e geri çıkmaktı ilk başta ama hem o yokuşu çıkmak pek yemedi hem de daha süresim vardı. Ben de devam ettim Beşiktaş-Fındıklı-Eminönü yönünde. Hala süresim var, devam… Sarayburnu’na gidip tekrar Eminönü’ne otobüs duraklarına döndüm. Burası Mecidiyeköy’e giden otobüslerin kalktığı durak, burada bisikleti otobüse koyup eve dönerim diyordum. Ancak hem otobüsün kalkmak bilmemesi hem de otobüs şoförünün mırın kırın etmesi üzerine eve kadar bisiklet ile dönmeye karar verdim. Unkapanı Köprüsü-Taksim Meydanı-Osmanbey yönünde sürüp eve vardım. Şaka maka ilk günden 55 km’lik bir tur yapmıştım ve bu kadar yapabileceğimi beklemiyordum. Bu biraz şevkimi artırdı, daha sonraki haftalarda da antrenman olsun mantığıyla Bahçeköy civarı ve Belgrad ormanında sürüşler yaptık, 50-60 km’leri rahat sürebiliyorduk.</p>

<p>Yunanistan için vize başvurularını tamamladık, beklediğimden çok hızlı bir şekilde hazırlandı vizeler. Süre olarak bir hafta izin alacaktık, diğer hafta da 2 gün Kurban Bayramı tatilinden gelince 11 günlük bir süremiz oldu. İlk planımızda Atina yoktu, İpsala sınır kapısından Selanik’e bisikletle gidip bisikletle dönecektik, böylece 350 + 350 = 700 km yol yapmış olacaktık. Ancak bu plandan iki sebepten ötürü vaz geçtik: bir, gitmişken bari Atina’yı da görsek iyi olurdu, iki, aynı yolu tekrar bisiklet ile tepmek ilki kadar zevkli olmayacaktı sanki. Bu yüzden planımızı Selanik’ten sonra Atina’ya doğru devam etmek ve dönüşte de tren ile dönmek şeklinde değiştirdik. Bu şekilde toplamda 850 km civarı yol yapmış olacaktık. Hedefimiz her gün 100 km civarı yol almak idi, daha önce hiç bu kadar yapmamıştık ve bunu her gün yapabileceğimiz konusunu da şansa bırakmıştık. Selanik’e bir şekilde gideriz diye düşünüyordum ben şahsen ama ondan sonra Atina’ya gidebilir miydik kafamda soru işaretiydi. Planımıza göre gündüz süreceğiz, geceleri ise vardığımız şehirlerde bir otelde kalacaktık. Selanik’e kadar olan gideceğimiz yerleri planlamış ve bunların otel rezervasyonlarını yapmıştık ama sonrası biraz kervan yolda düzülür mantığıyla ilerleyecekti ve zaten sonradan yaptığımız bir değişiklik olduğu için pek kafa da yormamıştık turun o kısmına.</p>

<p>Gün geldi çattı, sabah erkenden kalkıp bisikletleri arabaya attık, başlangıç noktamız olan İpsala sınır kapısına doğru yola çıktık. Yolda kahvaltı için Malkara civarında durduğumuz mekanda mekan sahibi ile geçirdiğimiz konuşma yöre insanından tam da beklenen bir diyalog idi:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Abi: Arabada bisikletler var, hayırdır?
Ben: Tura çıkıyoruz, önce Selanik'e sonra Atina'ya gideceğiz
Abi: Sebep?
</code></pre></div></div>

<p align="center">
  <img src="/img/p/yunanistan1.jpg" alt="Yolcudur Abbas" />
  <br /><em>Yolcudur Abbas</em>
</p>

<p>Hava pek de uygun değildi yola çıktığımızda, kara bulutlar ve hafif yağmur var, biraz da soğuk. Yaşadığımız ilk sorun arabayı bırakacak yer bulmaktı, İpsala’ya şehir merkezine girdik taksici bir abi burada bırakmayın girişteki petrol istasyonlarından birine bırakın önerisinde bulundu. O amaçla tekrar şehir dışına çıkarken emniyetin önündeki büyük alan gözümüze çarptı, izin istedik bir memurdan koyabilirsiniz dedi ama diğer bir memur burada durması doğru olmaz diyerek arabayı bırakmamıza izin vermedi, sınır kapısının orada bırakacağımız yer olduğunu ve oraya bırakmamızı tavsiye etti. Dediği gibi yaptık, kime ait olduğunu bilmediğimiz sınır kapısının hemen dibindeki oto parka arabayı dönüşte inşallah yerinde buluruz ümidiyle bıraktık. Bisikletleri çıkardık, heybeleri yerleştirdik, bisiklet aksesuarlarımızı kuşandık, gitmeye hazırdık! Ama benim lastikler biraz inmiş gibi göründü, şişirelim dedik, demez olaydık… Bir gün önce Decathlon’dan 10 lira civarı bir paraya aldığım dandik pompa çok kullanışsız çıktı, ne ucu tam oturdu ne de bastığı hava lastiği şişirebildi. Arkadaşımın pompa ile biraz şişirebildik, Allah’a emanet yola çıktık, daha ilk dakikadan çok zaman kaybetmiştik bu işle. Buradan çıkardığım iki ders şunlar: bir, aletini tanı, pompayı daha önceden denemem gerekiyordu, iki, ucuz etin yahnisi yavan olur.</p>

<p>Türkiye çıkışında 15’er liralık vergi harçlarımızı ödedik, şaşkın bakışlar içinde Yunanistan girişine geldik. Oradaki memurun “I admire your courage guys.” (“Cesaretinizi takdir ediyorum çocuklar.”) demesi biraz moral oldu :) Çanta vs. arama olaylarına girmeden işimiz hallettik ve yola koyulduk. Vardığımız ilk nokta Feres isminde küçük bir kasaba idi, şansımıza bir lastikçiye denk geldik benim lastiği ona şişirttik. Çat pat Türkçe bilen abi pek yakındı, borcumuz ne gibisinden soru sorduk, bizden olsun demek istedi hareketleriyle :) Karşılıksız kalmasın diye biz de yanımıza enerji için aldığımız cezeryeden ikram ettik :) İlk gün öğle molası vereceğimiz şehir Alexandroupoli (Dedeağaç’a) vardık. Fast food tarzı dükkanda tarzanca anlaşarak yiyecek bir şeyler aldık, gezi boyunca daha çok yiyeceğimiz pide (pita) ekmeği arasına bir şeyler koydurma olayını burada öğrendik. Turumuz gayet güzel gidiyordu, hava da biraz düzelmişti ta ki Makri denen bölgeye gelene kadar. Gelmez olaydık… sürekli rakım kazanıyoruz, etrafımızda sarp tepeler, deli gibi rüzgar esiyor (özellikle yolun etrafındaki tepelerden boğaz oluşan yerlerde). İndik bisikletlerden, yürüyerek devam edelim dedik. Tur boyunca “Biz ne yapıyoruz?” sorusunu kendimize ilk defa burada sorduk galiba. Çok yordu burası bizi, neyse bir noktada bitti. Yol düzgünleşti ama rüzgar hala devam ediyordu, bir taraftan da hafif hava kararmaya başladı. İlk gün hedefimiz olan Komotini (Gümülcine) şehrine 20-25 km kalmıştı ama bizde takat kalmamıştı sürecek, üstüne arkadaşımın dizi basamayacak noktaya gelmişti. Bir benzin istasyonunun orada durduk, dışardaki kamyoneti gözümüze kestirmiştik, bisikletleri buna atıp oradaki abiden bizi Komotini’ye kadar atmasını rica edecektik. Girdik, sordum abiye Türkçe biliyor musun diye, “biraz” dedi. Kafaya almış beni, adam şakır şakır Türkçe konuşuyor, Türk’müş :) Anlattık durumumuzu, yardımcı olmaya çalıştı, kendisi dükkanı bırakamayacağından bir kaç kişiye telefon etti ama bizi götürebilecek birisini bulamadı. Sonra bize yakında bir köye gitmemizi, oradaki Türk kahvesinden yardım istememizi söyledi. Dediğini yaptık, köy kahvesine gittik, çok iyi karşılandık hemen oturtup bize bir çay ikram ettiler, sallama mallama içtik. Nedense bu kahvede demleme çay içmiyorlar, daha ilginci ortamdaki bir amcanın köy kahvesinde Frappe siparişi vermesi baya garibimize gitti. Kahvenin garsonu genç arkadaş hemen bize bir taksi buldu, taksinin bagaja attık bisikletleri tuttuk yolumuzu Komotini’ye doğru. Otele vardık, yerleştik ama daha ilk günden bu şekilde başlamak biraz enerjimizi düşürdü, biraz fazla bir hedef mi koymuştuk kendimize?</p>

<p>İkinci gün Kavala’ya doğru yola çıktık. Arkadaşım merhem, sargı bir şekilde dizini sararak ağrıyı azaltmaya çalıştı, işe de yaradı. Bugünkü turda benim sol diz de ağrımaya başladı. Yol nispeten daha rahat idi ama yol üzerindeki Vistonida gölünün oradan geçerken yine hava çok rüzgarlı idi ve sürüşü etkiliyordu. Şehir girişindeki yokuş aşağılar sağ olsun Kavala şehrine vardık. Tam otele varmak üzereydik ki bir kaç tane yokuş çıkmak zorunda kaldık. Buralarda 3 kere falan vites düşürürken zincirim attı. Bizim gibi bisikletlerimiz de havlu mu atıyordu ne? O gün otele varınca ilk iş internetten bu zincir atma mevzusunu araştırdım, bu tarz dik yokuşlarda bisiklet yükteyken vites düşürmek zincir atmasına hatta kopmasına neden olabiliyormuş, geç de olsa öğrendim. Ayrıca yine bilmediğim ön ve arka viteslerin birbiriyle uyumlu kombinasyonlarının olduğunu öğrendim. Neyse ki tur boyunca bir daha bu sorunla karşılaşmadım. Akşam yemek için dışarı çıktığımızda Kavala Kurabiyesi satan yerlere rastladık, yarın yola çıkmadan alırız dedik ama almayı unuttuk. Yola çıkmadan şehirde açık bir eczane bulup dizlerimizdeki sorunu dilimiz döndüğünce anlatmaya çalıştık. Eczacı kadın bize bir sporcu jeli verdi bir kaç tane de sargı bezi aldık, bunları sarıp yola koyulduk.</p>

<p align="center">
  <img src="/img/p/yunanistan2.jpg" />
</p>

<p>Üçüncü gün Allah’ın unuttuğu, yaş ortalamasının 80 olduğu, Volvi gölünün kenarındaki Loutra Volvis denen bir yere vardık. Otel sahibinin zerre kadar İngilizcesi yoktu, o kadar ki bizi gördüğünde iki avcunu birleştirip kafasının sağına getirerek “Uyumak (kalmak) mı istiyorsunuz?” işareti yaptı. Evet, uyumak istiyorduk. O akşam yemeği kasabadaki tahminimizce tek restoran olan göl kenarındaki bir mekanda yedik. Bizim dışımızda 10-15 kişilik bir aile masası vardı, Yunan şarkıları çalıyor, uzolar içiliyor, ailenin genç erkek çocuğu sirtaki oynuyor, yaşlı teyzemiz şarkının sonunda önündeki tabağı alıp yere fırlatıyor. Tam bir Yunanistan deneyimi yaşadık diyebiliriz :)</p>

<p align="center">
  <img src="/img/p/yunanistan3.jpg" />
</p>

<p>Dördüncü gün ilk büyük hedefimiz olan Selanik’e doğru yola koyulduk. Bugün biraz daha az yolumuz vardı zira şehre öğlen gibi varıp öğleden sonra da şehri gezmeye zaman ayırmak istiyorduk. 50 km civarı bisiklet sürdük, şehrin girişinde kısa bir süre otobana girmek zorunda kaldık, bu sırada acayip bir yokuş tırmanıp afedersiniz neticemiz seleye yapıştı, ama bu yokuşun inişi ile süper hızlı bir şekilde şehre giriş yaptık. Şehirde trafik ve trafik ışıkları ile biraz zaman kaybettikten sonra otele vardık. Otel diyorum ama en fazla hostel diyebiliriz, bu kadar dandik bir yer olabilir, bir hastalık kapmadan buradan ayrılırız ümidiyle girdik. Haritadan Atatürk’ün Selanik’teki evini bulduk onu ziyaret ettik. Selanik Başkonsolosluğumuz’un bitişiğinde buluna ev 3 katlı, müzeye çevrilmiş. Ziyaret için isminize girişteki Türk görevliye yazdırıp bir ücret ödemeden giriyorsunuz. Buradan ayrıldıktan sonra bir şeyler yemek için sahile doğru yola çıktık. Yol boyunca sokak aralarında ve özellikle sahil şeridi boyunca gördüğümüz yiyecek mekanları çok dikkatimi çekti. O kadar çok mekan var ve hepsi de o kadar dolu ki, sanki burada yaşayanların evlerinde mutfak yok, herkes dışarda yiyip içiyor diye düşünüyor insan. Selanik’te zamanımızın bir kısmını ne yazık ki bir Internet Cafe’de geçirmek zorunda kaldık. Arkadaşımın iPhone’u daha ikinci günden bozulmuştu, ona yeniden yazılım yüklemeye çalıştık ama nafile, yapamadık. Ayrıca yolun kalan kısmını burada bilgisayar başında planladık, yine günde 100 km civarı gidebileceğimiz noktaları gözümüze kestirdik. Bu sefer otel rezervasyonu yapmamıştık zira hedeflerimize varabileceğimizden pek emin değildik.</p>

<p align="center">
  <img src="/img/p/yunanistan4.jpg" alt="Ata'nın huzurunda :)" />
  <br /><em>Ata'nın huzurunda :)</em>
</p>

<p>Selanik’ten ayrılıp Paralia Panteleimonos denen küçük kasabaya doğru yola koyulduk beşinci gün. Selanik çıkışı berbattı, bir sanayi bölgesinde geçtik, yollar kötü, yanımızdan geçen tırlar falan var. Bu civardan tam ayrılırken bisikletten bir şey düştü diye durduk, yerde bir metal parçası bulduk. Bir şeye benzetemediğimiz bu metal parçasını yolun kenarına fırlatıp devam ettik. Daha sonra anladık ki benim port bagajın bağlantı noktasında düşen bir parçaymış bu. Bir ders daha çıkardık bundan, bir parça düşürürsen bunu saklayacaksın. Neyse fazla kritik bir parça değilmiş ki turumuzu etkilemedi. Hedefimize varmak üzereyken benim sağ diz de alarm vermeye başladı. Sürüşümüzü ciddi şekilde etkiledi, güzelim düz yolları ağır ağır gitmek zorunda kaldık ve bu insana koyuyordu açıkçası. Paralia Panteleimonos’a vardığımızda bir gün önce gözümüze kestirdiğimiz “Fasoli Studios” isimli oteli bulmaya çalıştık. Tam bulamayacağımızı düşünmeye başlamıştık ki “ϕ” harfi ile başlayan tabelalı bir yere rastladık. Bir insan bir harfi gördüğüne bu kadar sevinebilir mi? (Seviniyor işte, ama bu harfi gördüğümüze bir daha sevineceğiz tur boyunca) Girişte hemen otel sahibi olan, hafif yaşını almış Polonyalı bir abla karşıladı. Gezi boyunca kaldığımız herhalde en sevecen yer burasıydı. Ablamız sağ olsun çok yardımcı oldu, kendi çamaşır makinesini kullanmamıza izin verdi, bize meyve sebze ve kendi yaptıkları şaraptan ikram etti. Daha sonra kocasıyla da tanıştık, karı koca burayı işletiyorlarmış, neredeyse bizim kadar oğulları varmış, Türkiye’ye yakın Yunan adalarının birinde çalışıyormuş. Ertesi sabah yolumuzu kısaltacak süper bir yol tarifi alıp vedalaştık.</p>

<p align="center">
  <img src="/img/p/yunanistan5.jpg" alt="Bu köprüden tır geçti!" />
  <br /><em>Bu köprüden tır geçti!</em>
</p>

<p>Altıncı gün hedefimiz önce Larissa’ya daha sonra Farsala’ya varmak idi. İki dizim de sakat olduğundan 1 km bile süremeyeceğim gibi şüphelerim vardı yola çıkmadan. Eski, kullanılmayan bir tren tünelinden geçerek yolumuzu kısaltmış, gereksiz yokuşları tırmanmaktan da kurtulmuştuk. Ama yine de dizlerimde ağrılar devam ediyordu, daha şöyle 1 saat falan sürmüşken “Yok, yapamayacağım” noktasına geldim ama sonra ne olduysa sürmeye devam edebildim. Maceralı geçen günlerden biriydi altıncı gün. Önce yolun bir kısmında otobana girmek zorunda kaldık. Gişelere geldiğimizde görevli burada sürmemizin yasak olduğunu, geçmemize izin vereceğini ama 1 km ötede Rapsani’de trene binmemiz gerektiğini söyledi. Tamam dedik, ama trene binmedik tabii ki, bastık devam ettik :) Etmez olay mıydık? Yolda emniyet şeridi çok dardı, çok fazla trafik vardı ve geçen araçların çoğu tırlar idi. Biraz gittikten sonra otoban devriyesinin aracı geldi bizi durdurdu, neden size dediğimiz şekilde trene binmediniz dedi, bir şey diyemedik. Polis geliyor falan dedi, dedik araca bizi alıp götürün. “Olmaz” dedi, “araçta kameralar var sizi alamam”. “Olabildiğince hızlı gidin, yolun bu kısmını bitirin.” dedi. O gaz ve adrenalin ile diz ağrısı falan kalmadı bende, bastık gittik, yolun o kısmını bitirdik. Larissa’ya vardığımızda hızlıca bir şeyler atıştırıp şehrin içine girmeden, çevreyolundan Farsala’ya doğru yola koyulduk. Tam şehirden çıkmıştık ki günün ikinci kabusuyla baş başa kaldık. Bisiklet sürerken başım dönmeye başlamıştı, ilk seferinde zor kaldırımda durabildim. İlk önce anlayamadım sorun bende mi yoksa bisiklete bir şey oldu da sağa mı çekiyor. Bisikleti kontrol ettik bir şey yok. Tekrar denedim, yok sorun bendeydi, gözlerim kararıyor gibi oluyor bisikleti kontrolü edemiyordum. Biraz daha dinlendik, şekerim falan düşmüştür belki diye bir elma falan yedim ama nafile. 50-100 metre sürebiliyordum anca. Sonra bir kafe bulup adam akıllı mola verelim dedik. Sert bir kahve içtim, arkadaşımın tavsiyesi üzerine biraz tuz yedim, tuzlu su falan içtim :) Yarım saat falan öyle dinlendik, ama işe de yaramıştı, bisiklet sürmeye devam edebiliyordum. Pamuk tarlalarının arasında geçtik, biraz yokuş tırmandık ama o yokuşun inişi her zamanki gibi çok güzeldi. Yakılan anız kokularının eşliğinde Farsala şehrine hava karardıktan sonra girebildik, “ϕ” harfini gördüğümüze bir kez daha çocuklar gibi sevindik. Şehirde gözümüze kestirdiğimiz bir tane otel vardı ama biraz şehrin ters tarafında, dışındaydı. Şehir merkezinde başka otel vardır ümidiyle merkeze gittik, orada birilerine otel sorduk ama şehirde tek otel olduğunu söylediler, çaresiz o otele kadar daha sürdük. Otele vardığımızda yorgunluktan ölüyorduk, yemek için şehir merkezine dönmeyi göze alamadık, otele yemek siparişi verdik.</p>

<p align="center">
  <img src="/img/p/yunanistan6.jpg" />
</p>

<p>Farsala’dan Lamia’ya doğru yola çıktık. Yedinci gün yolumuz nispeten kısa idi ama önce 500 metrelere tırmanacak daha sonra biraz inip bunu 700 küsur metrelere çıkaracaktık. Şehirden çıkmamızdan kısa bir süre sonra ilk ciddi köpek karşılaşmamızı yaşadık. 4-5 tane köpekten oluşan bir çete yanlarından geçerken havlıyor, lider ruhlu 2 tanesi de üzerimize doğru yaklaşıyordu. Bisikletlerden indik, kah köpek kovucuyu tutarak, kah bağırarak ya da taş atarak yavaşça bölgeyi geçtik. Tur boyunca 4-5 kere köpeklerle karşılaştık, genelde yavaşlayıp geçtik, basabileceğimiz yerde de basıp gittik. Yolun devamında ilk tırmanışa geldiğimizde olmadı bisikleti elime alır öyle çıkarım dedim ama gerek kalmadı, en düşük viteste dinlene dinlene çıktık burayı. Ama daha sonraki tırmanışa geldiğimizde hava da bozmuştu, bir taraftan yağmur yağıyor bir taraftan sis görüşümüzü çok kısıtlıyordu. Sürmeyi bırakıp bisikletler elimizde öyle devam ettik. En tepe noktada yol kenarında sebze, karpuz, vs. satan (kime sattığını çok merak ettiğim) bir abi bizi yanına davet etti. Oturduğu yerin yanına bir de ateş yakmıştı, ateşe yaklaşınca üzerimizden buharlar çıkıyordu. Abi tek kelime İngilizce bilmiyor ha bire Yunanca bir şeyler anlatıyor ve bizden anlamamızı bekliyordu. İki shot bardağı çıkartıp pet şişeden su gibi şeffaf bir şey koydu bizim için, için dedi. İçtik :) Daha sonra bu içkiden bir bardağa az bir şey koyup ateşin üstüne attı, ateşi baya bir harladı artık neyse bu. İçimiz de ısınmıştı birden :) Adama teşekkür ettik yola koyulduk. Tam 11 kilometre boyunca tek pedal çevirmeden adeta uçarcasına yağmur damlalarının arasından geçerek Lamia şehrine indik. Donumuza kadar da ıslanmıştık. Hava daha erkendi, biraz daha sürebilir miyiz diye düşündük ama sırılsıklam olmuştuk, Lamia’da kalmaya karar verdik.</p>

<p align="center">
  <img src="/img/p/yunanistan7.jpg" />
</p>

<p>Lamia’dan ana hedefimiz olan Atina’ya 220 km civarı kalmıştı, arada gidecek bir yer daha bulmamız gerekiyordu ama pek uygun bir yer yoktu. Bir günde gidebileceğimiz uzaklıktaki güzargahlar sürüş açısından yorucu olacaktı. Biz Thiva şehrini gözümüze kestirdik. 130 km gibi bir yol yapmamız gerekecekti ama yol en azından fazla yokuşlu değildi, yalnız yolun bir kısmında gidebileceğimiz yol bitecekti, orada bir karar veririz dedik. Biraz da erken yola koyularak sekizince gün sürüşümüze başladık. İlk 40 km çok iyi gitti, Kamena Vourla diye şirin bir tatil kasabasında kahve molası verdik, standart yol yiyeceğimiz olan muzdan aldık. Yolun kalan kısmında bir kez daha otobana girmek zorunda kaldık, yine otoban devriyesine yakalandık, bize ilk çıkışa kadar eskortluk ettiler. Bu sefer polis de geldi, uyardı bizi ve gitti. Otoban devriyesine o emin olmadığımız biten yolu sorduk, net bir şey söylemedi, sorun olursa tekrar otobana girin biz sizi buluruz dedi :) Yliki gölünün oraya geldiğimizde o biten yolun harbiden bittiğine tanık olduk. Yol ilk önce toprak yola dönüştü, sonra da bir noktada kesildi. Bisikletten inip keşif için yürüyerek ilerde gözüken ve sanki bir zamanlar bu yolun devamı olan yola kadar gittik. Bisikletleri elimize alıp buraya kadar getirip yola buradan devam edebilirdik ama bu yolun da tam olarak bizi nereye götüreceğine emin olamadık. Geri dönüp otobana girmeye karar verdik. Geri dönüşte giderken rastladığımız köpekler ile bir daha haşır neşir olmak zorunda kaldık. Şimdiye kadar hiç aynı yolu geri tepmediğimize seviniyordum, bu sefer şansımız yaver gitmedi. Otobana girdik, 100 metre sürdük sürmedik otoban devriyesi peşimize takıldı, dedik “Birader biz de meraklı değiliz otobana girmeye ama yol yok, ne yapalım?”. Yine bize eskortluk ederek Thiva çıkışına kadar götürdü. O gün en uzun mesafemiz olan 147 km’yi yapmıştık, akşam 9 civarı şehre vardık. Şehirde 3 tane otel vardı ama bizimki de şans, o hafta sonu şehirde bir drag racing aktivitesi varmış, tüm oteller dolu. Alternatif olarak ne yaparız planlarını yapıyoruz, şehirde tren istasyonu var onun bekleme salonunda yatarız falan. Otellerden birindeki görevli sağ olsun çok yardımcı oldu, “Bir odamın rezervasyonunu yaptıranlar daha gelmedi, 1 saat daha gelmezse size veririm, siz gidin yemeğinizi yiyin.” dedi. Şanslıymışız ki o odayı tutabildik ve geceyi sokakta geçirmekten kurtulduk :)</p>

<p align="center">
  <img src="/img/p/yunanistan8.jpg" />
</p>

<p>Artık Atina’ya varmak için bir günlük yolumuz kalmıştı, tek motivasyonum buydu :) Thiva’dan ayrılıp 90 km civarı sürerek Atina’ya vardık. Yolda öğle molasında yine çok fazla yememeyi planlamıştık ama yine çok fazla yedik, yemek sonrası sürüşler hele bir de yokuş çıkılacaksa çok zahmetli oluyor, son gün olmasının da verdiği rehavet ile fazla kasmadık. Atina’da şehir içinde azımsanmayacak kadar yol yapıp merkeze vardık, öğle molasında rezervasyon yaptırdığımız oteli bulup bisikletleri bıraktık. Akşam yemeği, dönüş tren biletini almak ve şehri turlamak için dışarı çıktık. Vakit biraz geç olduğu için Acropolis ziyaretini ertesi güne bıraktık, o akşam internetten Atina’da nereler gezilmeli not ettik. Ertesi gün ilk defa 10 gün sonra bisiklet sürmeyecektik :) Bir gün önceden planladığımız yerleri gezdik, turistik şehir turu yapan otobüslere binerek en az sürede en çok yeri görmeye çalıştık. Gece yarısı dönüş trenimiz vardı, otelden bisikletleri alıp istasyona gittik. Trene bisikleti koyma ile ilgili hep bir sorun çıkacak şeklinde şüphelerim vardı, yersizmiş, sorunsuz bir şekilde bisikletleri teslim ettik. 14 saat süren, pek de rahat olmayan bir yolculuk sonrası Alexandroupoli’ye vardık. Biletimiz aslında hemen yakınındaki Feres kasabasına idi, burada başka bir trene aktarma yapmayı bekliyorduk ama öyle olmadı. Aktarmayı otobüs ile yapacaktık. Otobüs şoförü her ne kadar olmaz dese de bisikletleri bagaja attık, Feres’e vardık. Burada son defa bir 15 km civarı yol alarak Türk sınırına vardık. Bayram dönüşünden dolayı olsa gerek girişte araç kuyruğu vardı, rica ettik, kuyruk beklemeden giriş işlemlerimizi tamamladık. Arabayı da koyduğumuz yerde bulunca derin bir nefes aldık, attık bisikletleri arabaya ve İstanbul’a doğru yola koyulduk.</p>

<p align="center">
  <img src="/img/p/yunanistan9.jpg" alt="Acropolis'teki Parthenon" />
  <br /><em>Acropolis'teki Parthenon</em>
</p>

<p>Zaman zaman “Biz ne yapıyoruz?” sorusunu sordurtsa da planladığın bir hedefe ulaşmanın verdiği tatmin insanı mutlu hissettiriyor. Bu yaptığımız ilk ciddi tur olduğu için çok şey öğrendik, ikincisinde muhtemelen çok daha rahat olacağızdır. Bu tarz bir gezide içime sinmeyen tek şey kısıtlı sürede zamanının büyük kısmı yol kat etmekle geçiyor ve yanından geçtiğiniz görülmeye değer yerlere sapmanız pek mümkün olmuyor.</p>

<p>Bisiklet ile aldığımız yollar kabaca şu şekilde:</p>

<ol>
  <li>Gün: İpsala-Alexandroupoli-Komotini, 90 km</li>
  <li>Gün: <a href="http://runkeeper.com/user/huseyint/activity/443484989">Komotini-Xanthi-Kavala, 110 km</a></li>
  <li>Gün: <a href="http://runkeeper.com/user/huseyint/activity/444116355">Kavala-Asprovalta-Loutra Volvis, 115 km</a></li>
  <li>Gün: <a href="http://runkeeper.com/user/huseyint/activity/444632137">Loutra Volvis-Selanik, 54 km</a></li>
  <li>Gün: <a href="http://runkeeper.com/user/huseyint/activity/445506832">Selanik-Katerini-Paralia Panteleimonos, 106 km</a></li>
  <li>Gün: <a href="http://runkeeper.com/user/huseyint/activity/446154234">Paralia Panteleimonos-Larissa-Farsala, 95 km</a></li>
  <li>Gün: <a href="http://runkeeper.com/user/huseyint/activity/446667714">Farsala-Lamia, 70 km</a></li>
  <li>Gün: <a href="http://runkeeper.com/user/huseyint/activity/447338556">Lamia-Thiva, 147 km</a></li>
  <li>Gün: <a href="http://runkeeper.com/user/huseyint/activity/447790059">Thiva-Atina, 93 km</a></li>
</ol>

<p>Yunanistan özelinde gözüme çarpan şu noktalar oldu:</p>

<ul>
  <li>Yemek porsiyonları çok büyük, yediğimiz her yemek sonrası kendimizi kötü hissettirecek kadar büyüktü porsiyonlar.</li>
  <li>Kızarmış patatesi çok seviyorlar, bir yerde yemeğe ulaşabilmek için yemeğin üzerini kaplayan patatesleri yemek zorunda kaldım.</li>
  <li>Çoğu yemeğin yanında bir iki dilim limon illa ki oluyor, pek anlam veremedim.</li>
  <li>Yemek veya içmek için gittiğin her mekanda eksiksiz masaya su geliyor ve devamlı tazeleniyor bu su. Bir çok yerde de kurabiye ikram edildiğini gördük.</li>
  <li>Çok fazla fiş kesiyorlar. Artık maliye korkusundan mıdır nedir, yemeğe eklettiğimiz her şey için ayrı bir fiş geliyor.</li>
  <li>Trafik ışık süreleri çok kısa, yaya geçidinin yarısında kırmızıya döndüğüne denk geldik birçok seferinde.</li>
</ul>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Setting UAC shield icon on buttons]]></title>
    <link href="http://huseyint.com/2014/01/Setting-UAC-shield-icon-on-buttons/"/>
    <updated>2014-01-19T00:00:00+00:00</updated>
    <id>http://huseyint.com/2014/01/Setting-UAC-shield-icon-on-buttons</id>
    <content type="html"><![CDATA[<p>Starting from Windows Vista, you should have noticed that actions which require administrative privileges and needs to elevate the current process, displays a shield icon right next to them. For example the <strong>Change date and time…</strong> button on Date and Time dialog requires admin rights to modify system date, hence displays a UAC shield right next to it:</p>

<p align="center">
  <img src="/img/p/DateAndTimeUAC.png" alt="Date and Time" />
</p>

<p>If your application has any buttons or menu items like this, to conform the Windows UX Guidelines, it is a good idea to display a UAC shield icon on your controls. <a href="http://www.codeproject.com/Articles/18509/Add-a-UAC-shield-to-a-button-when-elevation-is-req">This CodeProject article</a> has a good example that shows how to add shield icons to regular WinForms buttons. The gist is the following P/Invoke code:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">const</span> <span class="kt">int</span> <span class="n">BCM_FIRST</span> <span class="p">=</span> <span class="m">0x1600</span><span class="p">;</span> <span class="c1">//Normal button</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">BCM_SETSHIELD</span> <span class="p">=</span> <span class="n">BCM_FIRST</span> <span class="p">+</span> <span class="m">0x000C</span><span class="p">;</span> <span class="c1">//Elevated button</span>

<span class="k">static</span> <span class="k">void</span> <span class="nf">AddShieldToButton</span><span class="p">(</span><span class="n">Button</span> <span class="n">b</span><span class="p">)</span>
<span class="p">{</span>
  <span class="n">b</span><span class="p">.</span><span class="n">FlatStyle</span> <span class="p">=</span> <span class="n">FlatStyle</span><span class="p">.</span><span class="n">System</span><span class="p">;</span>
  <span class="nf">SendMessage</span><span class="p">(</span><span class="n">b</span><span class="p">.</span><span class="n">Handle</span><span class="p">,</span> <span class="n">BCM_SETSHIELD</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="m">0xFFFFFFFF</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Simply pass your <code class="language-plaintext highlighter-rouge">Button</code> instance reference to <code class="language-plaintext highlighter-rouge">AddShieldToButton</code> and you will have a nice UAC shield icon on your button on Windows Vista and above.</p>

<p>If you are using a third party library for your user interface controls (like <a href="https://www.devexpress.com/products/net/controls/winforms/">DevExpress WinForms</a>) or you need to add an icon to a menu item rather than a button, this method won’t work unfortunately. There is <a href="http://www.devexpress.com/Support/Center/Question/Details/S133322">a support ticket</a> on DevExpress Support Center about this issue and the suggested workaround is to use the <code class="language-plaintext highlighter-rouge">Image</code> property of <code class="language-plaintext highlighter-rouge">SimpleButton</code> class. So you can save a 16px * 16px version of this shield icon in your project resources and then use it. This has a minor issue though, if you want to strictly stick to the look and feel of the operating system, you may have problem while using a single hard-coded image. The reason is, this icon on Windows Vista was a shield icon with 4 colors (red, green, blue and yellow) but since Windows 7, it has only 2 colors (blue and yellow). Who knows what it will become on Windows 9 (do not get surprised if this icon becomes a flat metro-style icon). Not a big deal but if you really want to blend in with Windows desktop, these small things matter.</p>

<p align="center">
  <img src="/img/p/uac-shield-icons.png" alt="UAC Shield Icons on Windows Vista" />
</p>

<p>Windows stores these resources in its DLL files and it is a good idea to reuse them. This way, we will stick to what operating system has as the UAC shield icon and won’t need to maintain that image resource in our project. Even WinForms has a managed API to access these kind of icons like error, warning, information, shield, etc. You can get a shield <code class="language-plaintext highlighter-rouge">Icon</code> instance by accessing <a href="http://msdn.microsoft.com/en-us/library/system.drawing.systemicons.shield.aspx"><code class="language-plaintext highlighter-rouge">SystemIcons.Shield</code></a> property since .NET Framework 2.0 SP1. There are 2 issues with this approach:</p>

<ol>
  <li><code class="language-plaintext highlighter-rouge">SystemIcons.Shield</code> returns an <a href="http://msdn.microsoft.com/en-us/library/system.drawing.icon.aspx"><code class="language-plaintext highlighter-rouge">Icon</code></a> instance whereas <code class="language-plaintext highlighter-rouge">SimpleButton.Image</code> expects an <a href="http://msdn.microsoft.com/en-us/library/system.drawing.image.aspx"><code class="language-plaintext highlighter-rouge">Image</code></a> instance.</li>
  <li>The icon is in 32px * 32px size but a regular button on Windows should have a small 16px * 16px icon. (On 96 DPI desktops)</li>
</ol>

<p>To resolve these issues, I have come up with the following piece of code:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">static</span> <span class="k">void</span> <span class="nf">AddShieldToButton</span><span class="p">(</span><span class="n">SimpleButton</span> <span class="n">b</span><span class="p">)</span>
<span class="p">{</span>
  <span class="kt">var</span> <span class="n">icon</span> <span class="p">=</span> <span class="n">Icon</span><span class="p">.</span><span class="nf">FromHandle</span><span class="p">(</span><span class="n">SystemIcons</span><span class="p">.</span><span class="n">Shield</span><span class="p">.</span><span class="n">Handle</span><span class="p">);</span>

  <span class="kt">var</span> <span class="n">iconSize</span> <span class="p">=</span> <span class="n">SystemInformation</span><span class="p">.</span><span class="n">SmallIconSize</span><span class="p">;</span>
  <span class="kt">var</span> <span class="n">bitmap</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Bitmap</span><span class="p">(</span><span class="n">iconSize</span><span class="p">.</span><span class="n">Width</span><span class="p">,</span> <span class="n">iconSize</span><span class="p">.</span><span class="n">Height</span><span class="p">);</span>

  <span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">g</span> <span class="p">=</span> <span class="n">Graphics</span><span class="p">.</span><span class="nf">FromImage</span><span class="p">(</span><span class="n">bitmap</span><span class="p">))</span>
  <span class="p">{</span>
      <span class="n">g</span><span class="p">.</span><span class="n">InterpolationMode</span> <span class="p">=</span> <span class="n">InterpolationMode</span><span class="p">.</span><span class="n">HighQualityBicubic</span><span class="p">;</span>
      <span class="n">g</span><span class="p">.</span><span class="nf">DrawIcon</span><span class="p">(</span><span class="n">icon</span><span class="p">,</span> <span class="k">new</span> <span class="nf">Rectangle</span><span class="p">(</span><span class="m">0</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="n">iconSize</span><span class="p">.</span><span class="n">Width</span><span class="p">,</span> <span class="n">iconSize</span><span class="p">.</span><span class="n">Height</span><span class="p">));</span>
  <span class="p">}</span>

  <span class="n">b</span><span class="p">.</span><span class="n">Image</span> <span class="p">=</span> <span class="n">bitmap</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>This is what you get as a result with DevExpress controls using this method:</p>

<p align="center">
  <img src="/img/p/DevExpress-UAC1.png" alt="DevExpress UAC SimpleButton" />
</p>

<p>This is ugly, huh? The issues are:</p>

<ol>
  <li>
    <p>Even though I am on Windows 8.1, I am getting Windows Vista’s 4 color UAC shield icon. If you dig down the <code class="language-plaintext highlighter-rouge">SystemIcons.Shield</code> code with Reflector, you will see that the getter of this property first tries to load the system UAC shield icon using a P/Invoke code to <code class="language-plaintext highlighter-rouge">LoadIconWithScaleDown</code> function of <code class="language-plaintext highlighter-rouge">comctl32.dll</code>. This call fails, you can see that on your Visual Studio output pane reporting a first chance exception of type <code class="language-plaintext highlighter-rouge">EntryPointNotFoundException</code> thrown. The reason is, <code class="language-plaintext highlighter-rouge">LoadIconWithScaleDown</code> seems to be removed on a later version of <code class="language-plaintext highlighter-rouge">comctl32.dll</code>. Fortunately, the getter has a backup method which gets the icon loaded from the <code class="language-plaintext highlighter-rouge">System.Drawing.dll</code> embedded resources, which unfortunately is the old UAC shield icon:</p>

    <div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="k">new</span> <span class="nf">Icon</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">SystemIcons</span><span class="p">),</span> <span class="s">"ShieldIcon.ico"</span><span class="p">);</span>
</code></pre></div>    </div>
  </li>
  <li>
    <p>The resized icon looks rubbish. Even though we are using <code class="language-plaintext highlighter-rouge">InterpolationMode.HighQualityBicubic</code>, scaling down a 32px icon to 16px doesn’t end well.</p>
  </li>
</ol>

<p>Digging down a bit more, I have finally managed to get all these issues sorted with the following piece of code:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="nf">DllImport</span><span class="p">(</span><span class="s">"user32.dll"</span><span class="p">)]</span>
<span class="k">static</span> <span class="k">extern</span> <span class="n">IntPtr</span> <span class="nf">LoadImage</span><span class="p">(</span>
    <span class="n">IntPtr</span> <span class="n">hinst</span><span class="p">,</span> 
    <span class="kt">string</span> <span class="n">lpszName</span><span class="p">,</span> 
    <span class="kt">uint</span> <span class="n">uType</span><span class="p">,</span> 
    <span class="kt">int</span> <span class="n">cxDesired</span><span class="p">,</span> 
    <span class="kt">int</span> <span class="n">cyDesired</span><span class="p">,</span> 
    <span class="kt">uint</span> <span class="n">fuLoad</span><span class="p">);</span>

<span class="k">static</span> <span class="k">void</span> <span class="nf">AddShieldIcon</span><span class="p">(</span><span class="n">SimpleButton</span> <span class="n">button</span><span class="p">)</span>
<span class="p">{</span>
  <span class="kt">var</span> <span class="n">size</span> <span class="p">=</span> <span class="n">SystemInformation</span><span class="p">.</span><span class="n">SmallIconSize</span><span class="p">;</span>
  <span class="kt">var</span> <span class="n">image</span> <span class="p">=</span> <span class="nf">LoadImage</span><span class="p">(</span><span class="n">IntPtr</span><span class="p">.</span><span class="n">Zero</span><span class="p">,</span> <span class="s">"#106"</span><span class="p">,</span> <span class="m">1</span><span class="p">,</span> <span class="n">size</span><span class="p">.</span><span class="n">Width</span><span class="p">,</span> <span class="n">size</span><span class="p">.</span><span class="n">Height</span><span class="p">,</span> <span class="m">0</span><span class="p">);</span>

  <span class="k">if</span> <span class="p">(</span><span class="n">image</span> <span class="p">==</span> <span class="n">IntPtr</span><span class="p">.</span><span class="n">Zero</span><span class="p">)</span>
  <span class="p">{</span>
    <span class="k">return</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">icon</span> <span class="p">=</span> <span class="n">Icon</span><span class="p">.</span><span class="nf">FromHandle</span><span class="p">(</span><span class="n">image</span><span class="p">))</span>
  <span class="p">{</span>
    <span class="kt">var</span> <span class="n">bitmap</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Bitmap</span><span class="p">(</span><span class="n">size</span><span class="p">.</span><span class="n">Width</span><span class="p">,</span> <span class="n">size</span><span class="p">.</span><span class="n">Height</span><span class="p">);</span>

    <span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">g</span> <span class="p">=</span> <span class="n">Graphics</span><span class="p">.</span><span class="nf">FromImage</span><span class="p">(</span><span class="n">bitmap</span><span class="p">))</span>
    <span class="p">{</span>
      <span class="n">g</span><span class="p">.</span><span class="nf">DrawIcon</span><span class="p">(</span><span class="n">icon</span><span class="p">,</span> <span class="k">new</span> <span class="nf">Rectangle</span><span class="p">(</span><span class="m">0</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="n">size</span><span class="p">.</span><span class="n">Width</span><span class="p">,</span> <span class="n">size</span><span class="p">.</span><span class="n">Height</span><span class="p">));</span>
    <span class="p">}</span>

    <span class="n">button</span><span class="p">.</span><span class="n">Image</span> <span class="p">=</span> <span class="n">bitmap</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>And this is the result:</p>

<p align="center">
  <img src="/img/p/DevExpress-UAC2.png" alt="DevExpress UAC SimpleButton" />
</p>

<p>Much better, if I may say so myself. This one uses <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms648045.aspx"><code class="language-plaintext highlighter-rouge">LoadImage</code></a> P/Invoke call to get the correct size of the icon, so we don’t need to scale it down. Since this function returns an icon handle, we are just converting the icon to a bitmap. Using this method, you can even put UAC shield icons to your menu items:</p>

<p align="center">
  <img src="/img/p/WinForms-UAC-MenuItem.png" alt="WinForms UAC menu item" />
</p>

<p>Or you can get each and every size of the UAC shield icon, just because…you can:</p>

<p align="center">
  <img src="/img/p/UAC-Icons.png" alt="UAC icons" />
</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How to convert a .NET string to a Stream]]></title>
    <link href="http://huseyint.com/2013/12/How-to-convert-a-.NET-string-to-a-Stream/"/>
    <updated>2013-12-29T00:00:00+00:00</updated>
    <id>http://huseyint.com/2013/12/How-to-convert-a-.NET-string-to-a-Stream</id>
    <content type="html"><![CDATA[<p>If you ask this question on Google, you will find the following code snippet all over the web:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">text</span> <span class="p">=</span> <span class="s">"lorem ipsum dolor sit amet"</span><span class="p">;</span>
<span class="kt">var</span> <span class="n">bytes</span> <span class="p">=</span> <span class="n">Encoding</span><span class="p">.</span><span class="n">UTF8</span><span class="p">.</span><span class="nf">GetBytes</span><span class="p">(</span><span class="n">text</span><span class="p">);</span>
<span class="kt">var</span> <span class="n">stream</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">MemoryStream</span><span class="p">(</span><span class="n">bytes</span><span class="p">);</span>
</code></pre></div></div>

<p>This totally answers the question and works fine, but you should weigh your requirements while using this code. With short strings, that shouldn’t be much problem but if you are working with larger ones, the call to <code class="language-plaintext highlighter-rouge">GetBytes()</code> method will allocate a huge array at least the length of your string. And worse, if this byte array is larger than 85.000 bytes, it will go into the <a href="http://msdn.microsoft.com/en-us/magazine/cc534993.aspx">Large Object Heap (LOH)</a> which we should avoid as much as we can. Think also about this, if you need to pass that string to a consumer which expects a <code class="language-plaintext highlighter-rouge">Stream</code>, this should hint that this consumer won’t need that bulk of bytes at a single point of time, rather it will read those bytes batch by batch using regular streaming interface techniques.</p>

<p><a href="http://blogs.msdn.com/b/toub/">Stephen Toub</a>, on <a href="http://msdn.microsoft.com/en-us/magazine/cc163768.aspx">one of his MSDN Magazine blog posts</a> writes about this very issue and comes up with 3 solutions. The first two are very much like the code snippet above, only the second one is a bit refactored version of it but it has still the same semantics.</p>

<p>On the other hand, the third solution illustrates a quite nice approach as you can see on <em>Figure 1 Alternate StringStream Implementation</em> code listing. Possibly due to recent style changes on MSDN pages, the code is quite garbled but you can copy it over to Visual Studio and auto format it. This is a regular .NET <code class="language-plaintext highlighter-rouge">Stream</code> implementation code with the required overridden implementations. The interesting part is the <code class="language-plaintext highlighter-rouge">Read()</code> method which performs the real work:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">override</span> <span class="kt">int</span> <span class="nf">Read</span><span class="p">(</span><span class="kt">byte</span><span class="p">[]</span> <span class="n">buffer</span><span class="p">,</span> <span class="kt">int</span> <span class="n">offset</span><span class="p">,</span> <span class="kt">int</span> <span class="n">count</span><span class="p">)</span>
<span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">_position</span> <span class="p">&lt;</span> <span class="m">0</span><span class="p">)</span> <span class="k">throw</span> <span class="k">new</span> <span class="nf">InvalidOperationException</span><span class="p">();</span>

  <span class="kt">int</span> <span class="n">bytesRead</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>

  <span class="k">while</span> <span class="p">(</span><span class="n">bytesRead</span> <span class="p">&lt;</span> <span class="n">count</span><span class="p">)</span>
  <span class="p">{</span>
	<span class="k">if</span> <span class="p">(</span><span class="n">_position</span> <span class="p">&gt;=</span> <span class="n">_byteLength</span><span class="p">)</span> <span class="k">return</span> <span class="n">bytesRead</span><span class="p">;</span>
	<span class="kt">char</span> <span class="n">c</span> <span class="p">=</span> <span class="n">_str</span><span class="p">[</span><span class="n">_position</span> <span class="p">/</span> <span class="m">2</span><span class="p">];</span>
	<span class="kt">byte</span> <span class="n">b</span> <span class="p">=</span> <span class="p">(</span><span class="kt">byte</span><span class="p">)(</span><span class="n">_position</span> <span class="p">%</span> <span class="m">2</span> <span class="p">==</span> <span class="m">0</span> <span class="p">?</span> <span class="n">c</span> <span class="p">&amp;</span> <span class="m">0xFF</span> <span class="p">:</span> <span class="p">(</span><span class="n">c</span> <span class="p">&gt;&gt;</span> <span class="m">8</span><span class="p">)</span> <span class="p">&amp;</span> <span class="m">0xFF</span><span class="p">);</span>
	<span class="n">buffer</span><span class="p">[</span><span class="n">offset</span> <span class="p">+</span> <span class="n">bytesRead</span><span class="p">]</span> <span class="p">=</span> <span class="n">b</span><span class="p">;</span>
	<span class="n">Position</span><span class="p">++;</span>
	<span class="n">bytesRead</span><span class="p">++;</span>
  <span class="p">}</span>

  <span class="k">return</span> <span class="n">bytesRead</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>This method, on each call, tries to fill the given <code class="language-plaintext highlighter-rouge">buffer</code> with the byte representations of the remaining string until either the buffer is full or it reaches to the end of the underlying string. Since .NET strings are UTF-16 encoded, each char is represented with 2 bytes. The <code class="language-plaintext highlighter-rouge">while</code> loop in this method on each iteration writes a single byte, hence writing out a single char takes 2 iterations, one for lower byte and the other for upper byte. You can see this <code class="language-plaintext highlighter-rouge">StringStream</code> implementation in action with a code like this:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">text</span> <span class="p">=</span> <span class="s">"lorem ipsum dolor sit amet"</span><span class="p">;</span>

<span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">stream</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">StringStream</span><span class="p">(</span><span class="n">text</span><span class="p">))</span>
<span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">reader</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">StreamReader</span><span class="p">(</span><span class="n">stream</span><span class="p">,</span> <span class="n">Encoding</span><span class="p">.</span><span class="n">Unicode</span><span class="p">))</span>
<span class="p">{</span>
  <span class="kt">var</span> <span class="n">read</span> <span class="p">=</span> <span class="n">reader</span><span class="p">.</span><span class="nf">ReadToEnd</span><span class="p">();</span>

  <span class="n">Assert</span><span class="p">.</span><span class="nf">AreEqual</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="n">read</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Here I am providing a <code class="language-plaintext highlighter-rouge">text</code> to <code class="language-plaintext highlighter-rouge">StringStream</code> constructor, giving that stream to a <code class="language-plaintext highlighter-rouge">StreamReader</code>, reading to the end of the stream and what I <code class="language-plaintext highlighter-rouge">read</code> back is the exact same string I have provided in the first place. But notice that the second parameter of <code class="language-plaintext highlighter-rouge">StreamReader</code> constructor which is <code class="language-plaintext highlighter-rouge">Encoding.Unicode</code>, that is required in this case because <code class="language-plaintext highlighter-rouge">StreamReader</code> defaults to <code class="language-plaintext highlighter-rouge">Encoding.UTF8</code> in the absence of an <code class="language-plaintext highlighter-rouge">encoding</code> parameter. We need to explicitly specify the encoding because the underlying stream implementation will spit the bytes according to Unicode (UTF-16) encoding rules.</p>

<p>If the consumer of your stream instance doesn’t use Unicode encoding while decoding the bytes that come out of your <code class="language-plaintext highlighter-rouge">StringStream.Read()</code> method, it will fail to get the desired string decoded. In the previous code snippet, go either delete the second parameter of <code class="language-plaintext highlighter-rouge">StreamReader</code> constructor or replace it with <code class="language-plaintext highlighter-rouge">Encoding.UTF8</code>, you will <code class="language-plaintext highlighter-rouge">read</code> a string like this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"l\0o\0r\0e\0m\0 \0i\0p\0s\0u\0m\0 \0d\0o\0l\0o\0r\0 \0s\0i\0t\0 \0a\0m\0e\0t\0"
</code></pre></div></div>

<p>This string has a null char for every other char, this is because UTF-8 represents the characters in English alphabet (or any character in ASCII subset for that matter) with a single byte and secondary <code class="language-plaintext highlighter-rouge">0x00</code> bytes are represented as null chars in this string. The encoding assumption of <code class="language-plaintext highlighter-rouge">StringStream</code> class fails the consumer of this stream. To fix this issue, the <code class="language-plaintext highlighter-rouge">StringStream</code> class must know the desired encoding to use when spitting out bytes. I have modified this class to accept an encoding in its constructor and produce bytes according to the specified encoding rules. Here is what <code class="language-plaintext highlighter-rouge">Read()</code> method became with this implementation:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">override</span> <span class="kt">int</span> <span class="nf">Read</span><span class="p">(</span><span class="kt">byte</span><span class="p">[]</span> <span class="n">buffer</span><span class="p">,</span> <span class="kt">int</span> <span class="n">offset</span><span class="p">,</span> <span class="kt">int</span> <span class="n">count</span><span class="p">)</span>
<span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">_position</span> <span class="p">&lt;</span> <span class="m">0</span><span class="p">)</span>
  <span class="p">{</span>
    <span class="k">throw</span> <span class="k">new</span> <span class="nf">InvalidOperationException</span><span class="p">();</span>
  <span class="p">}</span>

  <span class="kt">var</span> <span class="n">bytesRead</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
  <span class="kt">var</span> <span class="n">chars</span> <span class="p">=</span> <span class="k">new</span> <span class="kt">char</span><span class="p">[</span><span class="m">1</span><span class="p">];</span>

  <span class="c1">// Loop until the buffer is full or the string has no more chars</span>
  <span class="k">while</span> <span class="p">(</span><span class="n">bytesRead</span> <span class="p">&lt;</span> <span class="n">count</span> <span class="p">&amp;&amp;</span> <span class="n">_position</span> <span class="p">&lt;</span> <span class="n">_str</span><span class="p">.</span><span class="n">Length</span><span class="p">)</span>
  <span class="p">{</span>
    <span class="c1">// Get the current char to encode</span>
    <span class="n">chars</span><span class="p">[</span><span class="m">0</span><span class="p">]</span> <span class="p">=</span> <span class="n">_str</span><span class="p">[</span><span class="n">_position</span><span class="p">];</span>

    <span class="c1">// Get the required byte count for current char</span>
    <span class="kt">var</span> <span class="n">byteCount</span> <span class="p">=</span> <span class="n">_encoding</span><span class="p">.</span><span class="nf">GetByteCount</span><span class="p">(</span><span class="n">chars</span><span class="p">);</span>

    <span class="c1">// If adding current char to buffer will exceed its length, do not add it</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">bytesRead</span> <span class="p">+</span> <span class="n">byteCount</span> <span class="p">&gt;</span> <span class="n">count</span><span class="p">)</span>
    <span class="p">{</span>
      <span class="k">return</span> <span class="n">bytesRead</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="c1">// Add the bytes of current char to byte buffer at next index</span>
    <span class="n">_encoding</span><span class="p">.</span><span class="nf">GetBytes</span><span class="p">(</span><span class="n">chars</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="m">1</span><span class="p">,</span> <span class="n">buffer</span><span class="p">,</span> <span class="n">offset</span> <span class="p">+</span> <span class="n">bytesRead</span><span class="p">);</span>

    <span class="c1">// Increment the string position and total bytes read so far</span>
    <span class="n">Position</span><span class="p">++;</span>
    <span class="n">bytesRead</span> <span class="p">+=</span> <span class="n">byteCount</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="k">return</span> <span class="n">bytesRead</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The key point in this implementation is that we are first making sure there is enough room to put the byte(s) of current char to <code class="language-plaintext highlighter-rouge">buffer</code>, to do that we are using <a href="http://msdn.microsoft.com/en-us/library/z2s2h516.aspx"><code class="language-plaintext highlighter-rouge">Encoding.GetByteCount()</code></a> method. If there are no rooms left to encode current char, the method simply returns with the total bytes read count so far, leaving the rest of reading to next <code class="language-plaintext highlighter-rouge">Read()</code> method call. If there is room, then the method uses <a href="http://msdn.microsoft.com/en-us/library/ms149355.aspx"><code class="language-plaintext highlighter-rouge">Encoding.GetBytes()</code></a> method to write current char byte(s) to buffer at next index.</p>

<p>You can find the <a href="https://github.com/huseyint/StringStream">source code of this class at my GitHub repository</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Have your JSON TreeView and unit test it too]]></title>
    <link href="http://huseyint.com/2013/12/Have-your-JSON-TreeView-and-unit-test-it-too/"/>
    <updated>2013-12-23T00:00:00+00:00</updated>
    <id>http://huseyint.com/2013/12/Have-your-JSON-TreeView-and-unit-test-it-too</id>
    <content type="html"><![CDATA[<p>The other day I was tasked to load XML and JSON documents to a WinForms <code class="language-plaintext highlighter-rouge">TreeView</code> control. Nothing fancy, obviously a recursive method will do the job but I thought this should be one of those already solved problems and I can easily find a snippet on the interwebs. For XML a <a href="https://www.google.com/search?q=load+xml+treeview+winforms">simple Google search</a> lead me to <a href="http://support.microsoft.com/kb/317597">the expected source code snippet</a> and after a few refactoring here and there, I was done.</p>

<p>But for the JSON, the first page of Google search results failed me and I couldn’t find that single method snippet, preferably using the great <a href="http://json.codeplex.com/">Newtonsoft.JSON</a> library. So I have given it a spin and get my hands dirty, after all it is good to refresh my rusty recursive coding skills :) I hope the next guy finds the following code useful and saves him a better half/one hour time.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">void</span> <span class="nf">LoadJsonToTreeView</span><span class="p">(</span><span class="n">TreeView</span> <span class="n">treeView</span><span class="p">,</span> <span class="kt">string</span> <span class="n">json</span><span class="p">)</span>
<span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="kt">string</span><span class="p">.</span><span class="nf">IsNullOrWhiteSpace</span><span class="p">(</span><span class="n">json</span><span class="p">))</span>
  <span class="p">{</span>
    <span class="k">return</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="kt">var</span> <span class="n">@object</span> <span class="p">=</span> <span class="n">JObject</span><span class="p">.</span><span class="nf">Parse</span><span class="p">(</span><span class="n">json</span><span class="p">);</span>
  <span class="nf">AddObjectNodes</span><span class="p">(</span><span class="n">@object</span><span class="p">,</span> <span class="s">"JSON"</span><span class="p">,</span> <span class="n">treeView</span><span class="p">.</span><span class="n">Nodes</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">void</span> <span class="nf">AddObjectNodes</span><span class="p">(</span><span class="n">JObject</span> <span class="n">@object</span><span class="p">,</span> <span class="kt">string</span> <span class="n">name</span><span class="p">,</span> <span class="n">TreeNodeCollection</span> <span class="n">parent</span><span class="p">)</span>
<span class="p">{</span>
  <span class="kt">var</span> <span class="n">node</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">TreeNode</span><span class="p">(</span><span class="n">name</span><span class="p">);</span>
  <span class="n">parent</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="n">node</span><span class="p">);</span>

  <span class="k">foreach</span> <span class="p">(</span><span class="kt">var</span> <span class="n">property</span> <span class="k">in</span> <span class="n">@object</span><span class="p">.</span><span class="nf">Properties</span><span class="p">())</span>
  <span class="p">{</span>
    <span class="nf">AddTokenNodes</span><span class="p">(</span><span class="n">property</span><span class="p">.</span><span class="n">Value</span><span class="p">,</span> <span class="n">property</span><span class="p">.</span><span class="n">Name</span><span class="p">,</span> <span class="n">node</span><span class="p">.</span><span class="n">Nodes</span><span class="p">);</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="k">void</span> <span class="nf">AddArrayNodes</span><span class="p">(</span><span class="n">JArray</span> <span class="n">array</span><span class="p">,</span> <span class="kt">string</span> <span class="n">name</span><span class="p">,</span> <span class="n">TreeNodeCollection</span> <span class="n">parent</span><span class="p">)</span>
<span class="p">{</span>
  <span class="kt">var</span> <span class="n">node</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">TreeNode</span><span class="p">(</span><span class="n">name</span><span class="p">);</span>
  <span class="n">parent</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="n">node</span><span class="p">);</span>

  <span class="k">for</span> <span class="p">(</span><span class="kt">var</span> <span class="n">i</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span> <span class="n">i</span> <span class="p">&lt;</span> <span class="n">array</span><span class="p">.</span><span class="n">Count</span><span class="p">;</span> <span class="n">i</span><span class="p">++)</span>
  <span class="p">{</span>
    <span class="nf">AddTokenNodes</span><span class="p">(</span><span class="n">array</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="kt">string</span><span class="p">.</span><span class="nf">Format</span><span class="p">(</span><span class="s">"[{0}]"</span><span class="p">,</span> <span class="n">i</span><span class="p">),</span> <span class="n">node</span><span class="p">.</span><span class="n">Nodes</span><span class="p">);</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="k">void</span> <span class="nf">AddTokenNodes</span><span class="p">(</span><span class="n">JToken</span> <span class="n">token</span><span class="p">,</span> <span class="kt">string</span> <span class="n">name</span><span class="p">,</span> <span class="n">TreeNodeCollection</span> <span class="n">parent</span><span class="p">)</span>
<span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">token</span> <span class="k">is</span> <span class="n">JValue</span><span class="p">)</span>
  <span class="p">{</span>
    <span class="n">parent</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="k">new</span> <span class="nf">TreeNode</span><span class="p">(</span><span class="kt">string</span><span class="p">.</span><span class="nf">Format</span><span class="p">(</span><span class="s">"{0}: {1}"</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="p">((</span><span class="n">JValue</span><span class="p">)</span><span class="n">token</span><span class="p">).</span><span class="n">Value</span><span class="p">)));</span>
  <span class="p">}</span>
  <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">token</span> <span class="k">is</span> <span class="n">JArray</span><span class="p">)</span>
  <span class="p">{</span>
    <span class="nf">AddArrayNodes</span><span class="p">((</span><span class="n">JArray</span><span class="p">)</span><span class="n">token</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">parent</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">token</span> <span class="k">is</span> <span class="n">JObject</span><span class="p">)</span>
  <span class="p">{</span>
    <span class="nf">AddObjectNodes</span><span class="p">((</span><span class="n">JObject</span><span class="p">)</span><span class="n">token</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">parent</span><span class="p">);</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>That’s fine and dandy, but how about adding some unit tests, there are quite lot of code execution paths over there, right? How would you test such a piece of code? The first thing comes to my mind is to not directly code against UI components like <code class="language-plaintext highlighter-rouge">TreeView</code> and <code class="language-plaintext highlighter-rouge">TreeNodeCollection</code>, but creating a generic view model and testing that model on your unit tests. This also decouples the design from the UI framework, so that you can easily port your code to another UI framework, say WPF. But still, I couldn’t think of an easy and maintainable way to write your assertions. This brings me to this great unit test helper library I have discovered recently, <a href="http://approvaltests.sourceforge.net/">Approval Tests</a>.</p>

<p>Simply put, Approval Tests diffs the results of your test code output with the output you have expected. The comparison can be made on either regular texts or on images if you are testing some UI code. You can watch <a href="https://www.youtube.com/watch?v=hKeKBjoSfJ8">Using ApprovalTests in .Net 16 WinForms</a> to get the idea. Here is a simple unit test that uses Approval Tests to perform assertion:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="n">Test</span><span class="p">]</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">Should_load_simple_json</span><span class="p">()</span>
<span class="p">{</span>
  <span class="kt">var</span> <span class="n">treeView</span> <span class="p">=</span> <span class="k">new</span> <span class="n">TreeView</span>
  <span class="p">{</span>
    <span class="n">BorderStyle</span> <span class="p">=</span> <span class="n">BorderStyle</span><span class="p">.</span><span class="n">None</span><span class="p">,</span>
    <span class="n">Width</span> <span class="p">=</span> <span class="m">400</span><span class="p">,</span>
    <span class="n">Height</span> <span class="p">=</span> <span class="m">400</span><span class="p">,</span>
  <span class="p">};</span>

  <span class="nf">LoadJsonToTreeView</span><span class="p">(</span><span class="n">treeView</span><span class="p">,</span> <span class="s">"{ 'foo': 'bar', 'baz': [ 42, 'quux' ] }"</span><span class="p">);</span>
  <span class="n">treeView</span><span class="p">.</span><span class="nf">ExpandAll</span><span class="p">();</span>

  <span class="n">WinFormsApprovals</span><span class="p">.</span><span class="nf">Verify</span><span class="p">(</span><span class="n">treeView</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The test first creates a WinForms <code class="language-plaintext highlighter-rouge">TreeView</code> control and calls the <code class="language-plaintext highlighter-rouge">LoadJsonToTreeView()</code> method (System Under Test) with a simple JSON string. Then <code class="language-plaintext highlighter-rouge">ExpandAll()</code> method is called on <code class="language-plaintext highlighter-rouge">TreeView</code> instance to get all nodes visible, since we are going to take a snapshot on the last line, all nodes better be visible. When you run this unit test for the first time, the test fails and you get the screen shot of the WinForms control that is produced:</p>

<p><img src="/img/p/ApprovalTestsReceived.png" alt="Received Image" title="Received Image" /></p>

<p>In Approval Tests terms, this is a <em>received</em> image which shows the actual output of current unit test code. What you do next is to simply approve this result if that looks correct. To approve a result, you need to create the image of the <em>expected</em> result. Approval Tests helps you here by providing the necessary move command on your unit test failure message, something along these lines:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>move /Y "Test_name.received.png" "Test_name.approved.png"
</code></pre></div></div>

<p>If you also prefer to use <code class="language-plaintext highlighter-rouge">ClipboardReporter</code> as another reporter for your unit tests, this command will automatically copied to your clipboard to be able to quickly run it, which is a great time saver.</p>

<p>Just run this command on your command prompt and the image you have just seen will be renamed and from now on, it will work as the expected result for this unit test. If you change the code and break the unit test, a nice side-by-side comparison view of the actual and expected images will show on a TortoiseDiff window. TortoiseDiff <a href="http://jake.ginnivan.net/getting-started-with-api-approver">seems to be a hard dependency of Approval Tests</a> and I am not sure how it is discovered on your system or any chance to change it to another diff viewer for that matter.</p>

<p>I have created a <a href="https://github.com/huseyint/JsonTreeView">sample project and unit tests project on GitHub</a>, send me a pull request if I am missing anything :)</p>

<p>PS: I am curious whether Approval Tests handle the different control styles across different operating systems, i.e. you create your approved images on a Windows 8 box but if your build server runs your tests on a Windows Server with classic Windows theme, you will end up having different images. Please let me know if you have any idea about this in comments.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Calling an overridden method on a JavaScript object]]></title>
    <link href="http://huseyint.com/2013/12/Calling-an-overridden-function-on-a-JavaScript-object/"/>
    <updated>2013-12-07T00:00:00+00:00</updated>
    <id>http://huseyint.com/2013/12/Calling-an-overridden-method-on-a-JavaScript-object</id>
    <content type="html"><![CDATA[<p>Suppose you have the following form on your HTML page:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;form</span> <span class="na">id=</span><span class="s">"MyForm"</span> <span class="na">action=</span><span class="s">"process.aspx"</span> <span class="na">method=</span><span class="s">"POST"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">name=</span><span class="s">"foo"</span> <span class="nt">/&gt;</span>
  <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"submit"</span> <span class="na">name=</span><span class="s">"submit"</span> <span class="na">value=</span><span class="s">"Send"</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/form&gt;</span>
</code></pre></div></div>
<p>Seems pretty innocent right? No. At least until you try to submit that form using JavaScript code. Try running the following JavaScript code on a page that contains this form inside developer tools console of your favorite browser:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">MyForm</span><span class="dl">'</span><span class="p">).</span><span class="nx">submit</span><span class="p">()</span>
</code></pre></div></div>

<p>You will get a lovely error, on Chrome:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>TypeError: Property 'submit' of object #&lt;HTMLFormElement&gt; is not a function
</code></pre></div></div>

<p>On Internet Explorer:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Member not found.
</code></pre></div></div>

<p>But how come? Is <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement.submit"><code class="language-plaintext highlighter-rouge">submit()</code></a> broken? Chrome’s error message hints that a property named <code class="language-plaintext highlighter-rouge">submit</code> exists but not a function. Let’s see what it is:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">MyForm</span><span class="dl">'</span><span class="p">).</span><span class="nx">submit</span>
</code></pre></div></div>

<p>This call will return a reference to submit button element in the form. Apparently you can access child form input elements as properties of parent form element, neat! But seriously, I need to call the <code class="language-plaintext highlighter-rouge">submit()</code> method. To do that I need to have a reference to the overridden function. If I had a reference to that function I know I can call it with the form reference I have in hand, thanks to <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call"><code class="language-plaintext highlighter-rouge">call()</code></a> method exists on all JavaScript functions. Using the <code class="language-plaintext highlighter-rouge">call()</code> method I can execute the <code class="language-plaintext highlighter-rouge">submit()</code> function with any instance I want. OK then, how about using another form reference’s non-overridden <code class="language-plaintext highlighter-rouge">submit()</code> method, let’s try this:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">form</span><span class="dl">'</span><span class="p">).</span><span class="nx">submit</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">MyForm</span><span class="dl">'</span><span class="p">))</span>
</code></pre></div></div>

<p>Bingo! It worked. But it doesn’t feel quite right, especially creating another form element to solely access one of its methods? There should be a better way. A little research took me to this: <a href="https://developer.mozilla.org/en/docs/Web/API/HTMLFormElement"><code class="language-plaintext highlighter-rouge">HTMLFormElement</code></a> which represents the base of all form elements and has references to all form functions accessible through its <code class="language-plaintext highlighter-rouge">prototype</code>, great! Let’s give the following revised code a chance:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">HTMLFormElement</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">submit</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">MyForm</span><span class="dl">'</span><span class="p">))</span>
</code></pre></div></div>

<p>This worked and is a reasonable solution for this problem.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Firefox adres çubuğunu daha da kullanışlı hale getirin]]></title>
    <link href="http://huseyint.com/2008/06/firefox-adres-cubugunu-daha-da-kullanisli-hale-getirin/"/>
    <updated>2008-06-29T00:00:00+00:00</updated>
    <id>http://huseyint.com/2008/06/firefox-adres-cubugunu-daha-da-kullanisli-hale-getirin</id>
    <content type="html"><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Semantic_Web">Semantic (anlamsal) webin</a> önemli unsurlarından biri de web sayfalarının <acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym>’lerinin (<a href="http://www.damnhandy.com/2007/11/19/uri-vs-url-whats-the-difference/">URI mi deseydik acaba?</a>) kısa, öz ve kullanıcı tarafından da anlaşılabilir olmasıdır. Bilgisayarlar açısından bir sorun yok, onlar kurallara uygun olduğu sürece bize doğru sayfayı gösterir ama bu adreslerin kullanıcılar tarafından da anlaşılabilir olması, sadece bir sitenin domain kısmının değil alt sayfalarının da akılda tutularak adres çubuğuna elle girilebilir olması hoş olmaz mı? Son zamanlarda biraz da Web 2.0 furyasının sayesinde web sitesi geliştiricileri sitelerinin <acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym> yapısına dikkat etmeye başladı. Böylelikle <acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym>’ler kısaldı, bir kaç kırılımdan oluşan bir şekil aldı ve en önemlisi sadece bilgisayarların anlam vereceği abidik gubidik karakter silsileleri olmaktan çıktı. Bununla beraber kendimden örnek vermem gerekirse bir sitede bir yerden başka yere geçerken sayfada gideceğim yeni sayfaya uygun link bulmaya çalışmaktansa, gider elle adres çubuğuna o alt sayfanın adresini girer oldum. Sanki bilgisayarımın sabit diskinde dolaşırmış gibi. Veya bulunduğum sayfa hiyerarşisine göre bir üst seviyeye geçmek istediğimde adres çubuğunda şu an bulunan adresin son segmentini silerek bu sayfaya gitmeye çalışır oldum, ve genelde de gidebildim. Hani nasıl derler, <acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym> hackerı oldum çıktım :)</p>

<p>Eğer siz de kendinize bu şekilde <acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym>’ler ile haşır neşir buluyorsanız ve Firefox web tarayıcısını kullanıyorsanız size süper bir eklenti tavsiye etmek istiyorum: <a href="http://en.design-noir.de/mozilla/locationbar2/">Locationbar²</a>. Bu eklenti yardımı ile adres çubuğunuzda bulunan <acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym> segmentlerini tıklanabilir linkler haline getirebilir ve bu segmentlerin görünümün daha anlaşılır bir hale sokabilirsiniz. Benim eklenti ayarlarım şu şekilde:</p>

<p align="center">
  <img src="http://huseyint.com/wp-content/uploads/2008/06/locationbar-options.png" alt="" title="Locationbar² seçenekleri" width="413" height="558" />
</p>

<p>Bu ayarlar ile fare imlecinizi adres çubuğunun alt kısmına yaklaştırdığınızda adres link şeklini alıyor ve o segmente kadar olan <acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym>’ye tıklamanız suretiyle gidebiliyorsunuz. Başta biraz kullanım zorluğu çekebilirsiniz ancak sonraları alışkanlık yapıyor ve kullandığınız her tarayıcıda arar oluyorsunuz.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Windows Forms ile kontrole Etched border eklemek]]></title>
    <link href="http://huseyint.com/2008/05/windows-forms-ile-kontrole-etched-border-eklemek/"/>
    <updated>2008-05-10T00:00:00+00:00</updated>
    <id>http://huseyint.com/2008/05/windows-forms-ile-kontrole-etched-border-eklemek</id>
    <content type="html"><![CDATA[<p>Genellikle programların About dialog pencerelerinde görürüz bu şekilde çizgileri. Etched (kazınmış demekmiş) 3 boyutlu görüntüsü ile kullanıldığı yere göre pencereye modern bir hava katıyor. Firefox’un About penceresi mesela:</p>

<p align="center">
  <img src="http://huseyint.com/wp-content/uploads/2008/05/firefox3-aboutdialog1.png" alt="Firefox 3 About dialog penceresi" title="Firefox 3 About dialog penceresi" width="316" height="467" />
</p>

<p>Butonların hemen üstündeki çizgi pencerenin beyaz arkaplanlı üst ve gri arkaplanlı alt kısımlarını ayırmada kullanılmış ve 3 boyutlu bir görünüm kazandırmış. Visual Basic 6 ile böyle bir şeyi yapmak için Line kontrollerini kullanırdık. Birer adet gri ve beyaz renkli Line kontrolünü aralık bırakmadan alt alta gelecek şekilde formumuza yerlerştirdiğimizde bu görünümü elde edebilirdik. Visual Studio’nun .NET sonrası versiyonlarında böyle bir kontrol gelmemekte. Bana kalırsa gerek de yok çünkü Form üzerine Line tarzı kontroller koymak gereksiz yere tasarım ortamını karıştırıyor. Bunun yerine Windows Forms’un nimetlerinden yararlanarak bu sorunu çok daha şık bir şekilde çözebiliriz.</p>

<p>Yapmamız gereken <a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.panel.aspx">Panel</a> kontrolünün <a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.control.onpaint.aspx">OnPaint</a> metodunu override edip bize sağlanan <a href="http://msdn.microsoft.com/en-us/library/system.drawing.graphics.aspx">Graphics</a> nesnesini kullanarak <a href="http://msdn.microsoft.com/en-us/library/b39h02xk.aspx">ControlPaint.DrawBorder3D</a> static metodu ile <a href="http://msdn.microsoft.com/en-us/library/ezxa8z32.aspx">istediğimiz kenara</a>, <a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.border3dstyle.aspx">istediğimiz tarzda</a> bir border ekleyebiliriz. C# ile anlatacak olursam:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">EtchedBorderedPanel</span> <span class="p">:</span> <span class="n">Panel</span>
<span class="p">{</span>
    <span class="k">protected</span> <span class="k">override</span> <span class="k">void</span> <span class="nf">OnPaint</span><span class="p">(</span><span class="n">PaintEventArgs</span> <span class="n">e</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">base</span><span class="p">.</span><span class="nf">OnPaint</span><span class="p">(</span><span class="n">e</span><span class="p">);</span>
 
        <span class="n">ControlPaint</span><span class="p">.</span><span class="nf">DrawBorder3D</span><span class="p">(</span><span class="n">e</span><span class="p">.</span><span class="n">Graphics</span><span class="p">,</span> 
            <span class="k">this</span><span class="p">.</span><span class="n">ClientRectangle</span><span class="p">,</span> 
            <span class="n">Border3DStyle</span><span class="p">.</span><span class="n">Etched</span><span class="p">,</span> 
            <span class="n">Border3DSide</span><span class="p">.</span><span class="n">Top</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu kontrolü daha sonra penceremizin alt kısmına <a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.control.dock.aspx">Dock</a> edebiliriz. En son hafta sonu projem <a href="http://huseyint.com/FxLibrarian/">FxLibrarian</a> için yaptığım About dialog penceresi:</p>

<p align="center">
  <img src="http://huseyint.com/wp-content/uploads/2008/05/fxlibrarian-aboutdialog.png" alt="FxLibrarian About dialog penceresi" title="FxLibrarian About dialog penceresi" width="385" height="170" />
</p>

<p><a href="http://www.codeproject.com/">CodeProject</a>‘teki <a href="http://www.codeproject.com/KB/miscctrl/DividerPanel.aspx">şu makale</a> de böyle bir kontrolü nasıl yapacağınızı anlatıyor. Biraz eski ama tekrar kullanılabilir bir kontrol yapma konusunda güzel bilgiler içeriyor.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Windows Vista&#8217;nın 3.1&#8242;den kalma mirasları]]></title>
    <link href="http://huseyint.com/2008/02/windows-vistanin-31den-kalma-miraslari/"/>
    <updated>2008-02-12T00:00:00+00:00</updated>
    <id>http://huseyint.com/2008/02/windows-vistanin-31den-kalma-miraslari</id>
    <content type="html"><![CDATA[<p>Dün akşam Windows Vista yüklü bilgisayarıma bir Font yüklemeye çalıştığımda aşağıdaki dialog karşıma çıktı:</p>

<p align="center">
  <img src="http://huseyint.com/wp-content/uploads/2008/02/add-fonts.png" alt="" />
</p>

<p>Gelmiş geçmiş Windows’ların içinde (<a href="http://en.wikipedia.org/wiki/Windows_Me">Millenium Edition</a> da dahil) en fiyakalısı olan Vista’da hala bu dialog neden bulunuyor? Atlamışlar heralde… Neyse bunu gördükten sonra bir başka tarihi eser olan moricons.dll de hala yerinde mi diye baktım. Yanlış hatırlamıyorsam C:\Windows klasöründe olması gerekiyordu ama yoktu. Klasör içinde arama yapınca System32 klasöründe olduğunu gördüm:</p>

<p align="center">
  <img src="http://huseyint.com/wp-content/uploads/2008/02/change-icon.png" alt="" />
</p>

<p>Eğer moricons.dll içindeki 32×32 büyüklüğünde ve tamı tamına 16 renk derinliğine sahip simgelere bağımlılığı bulunan uygulamalarınız varsa korkmayın, Windows Vista altında da uygulamalarınız sorunsuz bir şekilde çalışacaktır (<a href="http://en.wikipedia.org/wiki/User_Account_Control" class="ubernym uttInitialism"><acronym class="uttInitialism" title="User Account Control">UAC</acronym></a>’yi saymazsak). <a href="http://en.wikipedia.org/wiki/Backward_compatibility">Backward compatibility</a> bu olsa gerek.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Metin kutularına ipucu metni koyma &#8211; Cue Banner Text]]></title>
    <link href="http://huseyint.com/2008/01/metin-kutularina-ipucu-metni-koyma-cue-banner-text/"/>
    <updated>2008-01-28T00:00:00+00:00</updated>
    <id>http://huseyint.com/2008/01/metin-kutularina-ipucu-metni-koyma-cue-banner-text</id>
    <content type="html"><![CDATA[<p>Gerek Windows Forms ile gerekse de Web Forms ile bir kullanıcı arayüzü tasarlarken sıkça Label ve TextBox kontrol çiftlerini kullanırız. Bir TextBox koyarız ki kullanıcıdan bir değer alabilelim, soluna da bir Label koyarız ki kullanıcıdan ne bilgisi istediğimiz belli olsun. Ancak bazen ya yer darlığından ya da estetik kaygıdan dolayı TextBox kontrolünün işlevini belirleyen Label kontrolü gözümüze batar, kaldırmak isteriz. Böylelikle Label kontrolünden kurtuluruz kurtulmasına da bir şekilde kullanıcıya TextBox kontrolüne ne gireceği hakkında bilgi vermemiz gerekir. İşte bu noktada Cue Banner Text kullanmamız gereken fonksiyonalitedir. Peki nedir bu Cue Banner Text? Hani bazı web sitelerinin Login bölümlerinde kullanıcı adı ve parola gireceğiniz metin kutularının üstüne gelince <strong>Kullanıcı Adı</strong> ve <strong>Parola</strong> yazıları kayboluverir ki siz kendi kullanıcı adı ve parola değerlerini girebilirsiniz. İşte metin kutularının içine o kutulara ne girileceğini yazmak ve kutuya tıklayınca (veya bir şeyler yazmaya başlayınca) bu yazılara yok etme yöntemine Cue Banner Text deniyor. Eğer web ortamında bu yöntemi kullanarak erişilebilir formlar oluşturmak istiyorsanız A List Apart’taki <a href="http://www.alistapart.com/articles/makingcompactformsmoreaccessible/" title="Making Compact Forms More Accessible by Mike Brittain">Making Compact Forms More Accessible</a> makalesini okuyarabilirsiniz.</p>

<p align="center">
  <img src="http://huseyint.com/wp-content/uploads/2008/01/sample_form.gif" alt="Cue Banner Text yöntemi uygulanmış örnek bir web formu" />
</p>

<p>Masaüstü uygulamalarında da bu tarz TextBox kullanımını görmemiz münkün. Mesela Windows Vista’da her bir Explorer penceresinin sağ üst köşesinde ve Internet Explorer 7′de bulunan arama kutularında bu kullanım mevcut:</p>

<p align="center">
  <img src="http://huseyint.com/wp-content/uploads/2008/01/vistaexplorersearchbox.png" alt="Windows Vista Explorer arama kutusu" /><br /> <img src="http://huseyint.com/wp-content/uploads/2008/01/ie7searchbox.png" alt="IE7 arama kutusu" />
</p>

<p>Yine Windows Vista’da başlat menüsünün alt kısmında çıkan arama kutusunda da bunu görmekteyiz:</p>

<p align="center">
  <img src="http://huseyint.com/wp-content/uploads/2008/01/vistastartmenusearchbox.png" alt="Windows Vista başlat menüsü arama kutusu" />
</p>

<p>Sizin de bu yöntemi .NET ve Windows Forms kullanarak geliştirdiğiniz uygulamalarda kullanmanız mümkün. Ne yazık ki .NET ile gelen TextBox kontrolünün böyle bir özelliği yok, bir şekilde bunu kendimiz yapmamız gerek. İlk akla gelen yöntemlerden biri kullandığımız TextBox kontrolünün Enter ve Leave eventlerini yakalayıp yazıyı gösterme/göstermeme işlemini gerçekleştirebilirsiniz. Benzer bir yöntemle ama bu sefer biraz daha alt seviyede TextBox kontrolünü subclass ederek yeni bir kontrol oluşturabilir ve OnGotFocus/OnLostFocus metodlarını override ederek benzer işlevi yeni kontrole kazandırmanız da mümkün. Ama tahmin edebileceğiniz gibi bu yöntemler pek de temiz gibi görünmüyor. Hem yazacağımız kod gereğinden fazla karışık ve yönetilemez olacak, hem de kontrolün temiz/sorunsuz bir kullanımı olmayacak. Geçiniz…</p>

<p>Peki nasıl yapalım biz bu işi? Şöyle oluyor efendim; <a href="http://msdn2.microsoft.com/en-us/library/bb761639(VS.85).aspx">EM_SETCUEBANNER</a> mesajını TextBox kontrolümüze User32.dll kütüphanesindeki meşhur <a href="http://www.pinvoke.net/default.aspx/user32.SendMessage">SendMessage</a> fonksiyonu ile göndererek. Aynen yukarıda örnek verdiğim Windows uygulamalarının da yaptığı gibi. Eğer programınız Windows XP veya sonrası bir işletim sisteminde çalışıyorsa bu yöntemi kullanarak acısız ve ağrısız bir şekilde TextBox kontrollerinize Cue Banner Text özelliği kazandırabilirsiniz.</p>

<p>SendMessage User32 sistem kütüphanesinde export edilmiş bir fonksiyon olduğu için bu fonksiyonu .NET içerisinden Platform Invocation veya kısaltacak olursak <a href="http://msdn2.microsoft.com/en-us/library/aa719104.aspx" title="Using P/Invoke to Call Unmanaged APIs from Your Managed Classes">P/Invoke</a> ile çağırmamız mümkün. EM_SETCUEBANNER sabitinin değeri ve SendMessage fonksiyonunun kullanacağımız versiyonu şu şekilde:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">internal</span> <span class="k">const</span> <span class="kt">uint</span> <span class="n">ECM_FIRST</span> <span class="p">=</span> <span class="m">0x1500</span><span class="p">;</span>
<span class="k">internal</span> <span class="k">const</span> <span class="kt">uint</span> <span class="n">EM_SETCUEBANNER</span> <span class="p">=</span> <span class="n">ECM_FIRST</span> <span class="p">+</span> <span class="m">1</span><span class="p">;</span>

<span class="p">[</span><span class="nf">DllImport</span><span class="p">(</span><span class="s">"user32.dll"</span><span class="p">,</span> <span class="n">CharSet</span> <span class="p">=</span> <span class="n">CharSet</span><span class="p">.</span><span class="n">Auto</span><span class="p">)]</span>
<span class="k">internal</span> <span class="k">static</span> <span class="k">extern</span> <span class="n">IntPtr</span> <span class="nf">SendMessage</span><span class="p">(</span>
    <span class="n">HandleRef</span> <span class="n">hWnd</span><span class="p">,</span> 
    <span class="kt">uint</span> <span class="n">msg</span><span class="p">,</span> 
    <span class="kt">bool</span> <span class="n">wParam</span><span class="p">,</span> 
    <span class="kt">string</span> <span class="n">lParam</span><span class="p">);</span>
</code></pre></div></div>

<p>Fonksiyonun parametrelerinin ne işe yaradığınız özetlemek gerekirse; <a href="http://msdn2.microsoft.com/en-us/library/system.runtime.interopservices.handleref.aspx">HandleRef</a> tipindeki hWnd parametresi ile TextBox kontrolümüzün Handle değerini, msg parametresi ile EM_SETCUEBANNER sabitini, wParam ile Cue Banner metninin kontrol üzerinde iken de gösterilip gösterilmeyeceğini ve son olarak lParam ile de Cue Banner metnini göndereceğiz. Burada 3. parametre olan wParam için özel bir durum var. Windows Vista’ya kadar EM_SETCUEBANNER mesajını gönderirken bu parametre göz ardı ediliyordu. Ancak Vista ile beraber buraya true değeri göndermemiz durumunda Cue Banner metni kontrol üzerinde iken de görünüyor, ta ki kullanıcı ilk karakteri girene kadar. Eğer Windows Vista kullanıyorsanız bu özelliği başlat menüsündeki arama kutusunda deneyebilirsiniz. Aşağıdaki kod txtSearch isminde bir TextBox kontrolüne Cue Banner olarak “Search” metnini atıyor:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">SendMessage</span><span class="p">(</span>
    <span class="k">new</span> <span class="nf">HandleRef</span><span class="p">(</span><span class="n">txtSearch</span><span class="p">,</span> <span class="n">txtSearch</span><span class="p">.</span><span class="n">Handle</span><span class="p">),</span> 
    <span class="n">EM_SETCUEBANNER</span><span class="p">,</span> 
    <span class="k">false</span><span class="p">,</span> 
    <span class="s">"Search"</span><span class="p">);</span>
</code></pre></div></div>

<p>Kodu bu haliyle Windows Formunuzun constructoruna veya Form_Load eventine yerleştirmeniz mümkün. Ama bir kaç satır kod yazarak TextBox kontrolünden türeyen ve Cue Banner Text özelliği olan yeni bir TextBox kontrolü oluşturabiliriz. Böylelikle projenizin farklı yerlerinde böyle bir kontrol kullanacak olursanız sanki formunuza normal bir TextBox kontrolü yerleştirirmiş gibi bu kontrolü yerleştirip Properties penceresinden de Cue Banner metnini belirleyebilirsiniz.</p>

<p align="center">
  <img src="http://huseyint.com/wp-content/uploads/2008/01/cuebannertextboxdemo.png" alt="CueBannerTextBox kontrol demosu" />
</p>

<p>Fark ettiyseniz Windows Explorer, IE7 ve başlat menüsünde bulunan arama kutularındaki Cue Banner metinleri gri renkte ve italik yazı tipi ile yazılmış, bizim oluşturduğumuz ise gri olmasına rağmen italik değil. Channel 9 Forumlarında <a href="http://channel9.msdn.com/Niners/littleguru">littleguru</a> adındaki kullanıcının daha önceden <a href="http://channel9.msdn.com/ShowPost.aspx?PostID=208895">oluşturmuş olduğu</a> benzer bir kontrolde ek olarak Cue Banner fontunu belirleme seçeneği de koymuş. OnGotFocus/OnLostFocus metodlarını override ederek TextBox’un o anki font değerini değiştiriyor. Ancak program çalıştığı esnada bu değerlerin (Cue Banner metni ve fontu) değişmesi gibi bazı durumunda kontrol pek sağlıklı çalışmıyor. Ayrıca bahsettiğim Vista ile gelen yeni özellik de o kontrolde uygulanmış değil. O yüzden bu işi yapan kontrolü tekrar yazmaya karar verdim. Tekrar yazmak dediysem pek de bir şey yapmadım hani, littleguru’nun kodunu baz alarak bir kaç değişiklik yaptım. Vista ile gelen özellikten de <a href="http://weblogs.asp.net/kennykerr/">Kenny Kerr</a>‘in Ağustos ayında MSDN Magazine’de yayınlamış olduğu <a href="http://msdn.microsoft.com/msdnmag/issues/07/08/WindowsCPP/default.aspx#S2">Windows Vista Control Enhancements</a> yazısını okuyunca haberim oldu.</p>

<p>Kontrolü ve demosunu içeren <a href="http://huseyint.com/projeler/CueBannerTextBox_Control.zip">Visual Studio 2008 projesi</a> (12kb)</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[AirTies modem resetleme aracı]]></title>
    <link href="http://huseyint.com/2008/01/airties-modem-resetleme-araci/"/>
    <updated>2008-01-06T00:00:00+00:00</updated>
    <id>http://huseyint.com/2008/01/airties-modem-resetleme-araci</id>
    <content type="html"><![CDATA[<p><a href="http://www.rapidshare.com/">RapidShare</a> gibi sitelerden Premium hesap sahibi olmadan ücretsiz olarak dosya indiriyorsanız daha kısa zamanda daha fazla dosya indirebilmek için sık sık modeminize reset atmak zorunda kalıyorsunuzdur. Böylelikle modeminiz yeni bir IP alıyor ve sanki bambaşka biriymişçesine RapidShare&#8217;den dosyalarınızı indirmeye devam edebiliyorsunuz. Bir programcı olduğumu ve programcıların da tembel olduğunu göz önüne aldığımızda modemin elektrik kablosunu çıkarmak ve tekrar takmak oldukça zahmetli bir iş benim için. İşte bu yüzden bu sorunu tek tıkla çözen bir <a href="http://en.wikipedia.org/wiki/Command_line_interface" title="CLI - Command line interface">komut satırı uygulaması</a> geliştirdim. Eğer sizin de AirTies marka bir ADSL modeminiz varsa bu aracı kullanarak modeminize reset atabilir, yeni bir IP adresi alabilirsiniz. Modem arayüzüne 192.168.2.1 adresinden ve boş bir şifre ile ulaştığınızı varsayarsak programı hiçbir parametre göndermeden, çift tıklayarak, kullanabilirsiniz. Ancak modem arayüzüne eriştiğiniz IP adresiniz farklı ve/veya modeme erişmede bir şifre kullanıyorsanız ilgili <strong>/ip</strong> ve <strong>/password</strong> parametlerini kullanmanız gerekir. Programı çalıştırabilmeniz için <a href="http://go.microsoft.com/fwlink/?LinkId=37283">.NET Framework 2.0</a> veya üstü bilgisayarınızda yüklü olduğundan emin olun.</p>
<p><a href="http://huseyint.com/wp-content/uploads/2008/01/resetmodem.png" title="AirTies modem resetleme aracı ekran görüntüsü"><img src="http://huseyint.com/wp-content/uploads/2008/01/resetmodem.thumbnail.png" alt="AirTies modem resetleme aracı ekran görüntüsü" /></a></p>
<p><a href="/projeler/ResetModem/ResetModem.zip" title="AirTies ADSL modem resetleme aracını indirin">AirTies ADSL Modem Reset Utility 1.0.0.0</a> (3,40 KB)</p>
<p><strong>Not:</strong> Programı sadece kullanmakta olduğum AirTies RT-205 modeli ile test edebildim ancak diğer modeller ile de sorunsuz çalışacağını ümit ediyorum.</p>
<p><strong>Güncelleme:</strong> Programın <a href="/projeler/ResetModem/Program.cs.html" title="AirTies ADSL modem resetleme aracı kaynak kodu">C# kaynak kodunu</a> görebilirsiniz.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[XML Serializable Generic Dictionary tipi]]></title>
    <link href="http://huseyint.com/2007/12/xml-serializable-generic-dictionary-tipi/"/>
    <updated>2007-12-02T00:00:00+00:00</updated>
    <id>http://huseyint.com/2007/12/xml-serializable-generic-dictionary-tipi</id>
    <content type="html"><![CDATA[<p>.NET ile kod yazarken en çok kullandığım collection tiplerinden biri olan <a href="http://msdn2.microsoft.com/en-us/library/xfhwa508(VS.90).aspx">Dictionary</a> Generic yapısı ile de bizi bir çok casting işleminden kuratarıyor. Key olarak şu tipi, value olarak da şu tipi kullanacağız diyoruz ve key/value çiftlerini tiplerini de koruyarak tutabileceğimiz dört başı mamur bir listemiz olmuş oluyor. Bir de bu Dictionary tipimizi <acronym class="uttInitialism" title="eXtensible Markup Language">XML</acronym> olarak Serialize edebilsek tadından yenmeyecek ama nedendir bilinmez bunu yapamıyoruz. Yaparsak da şuna benzer bir Exception alıyoruz:</p>

<blockquote>
  <p>“The type System.Collections.Generic.Dictionary is not supported because it implements IDictionary.”</p>
</blockquote>

<p>İnternette bu işi yapabilecek bir şeyler araştırdım ve <a href="http://www.sitepoint.com/blogs/2006/07/09/generic-dictionaries-vs-the-xmlserializer/">hatrı sayılır</a> <a href="http://aspzone.com/blogs/john/articles/167.aspx">sitede</a> <a href="http://msdn.microsoft.com/msdnmag/issues/03/06/XMLFiles/default.aspx#QA7">bu sorunun</a> <a href="http://blogs.msdn.com/psheill/archive/2005/04/09/406823.aspx">farklı farklı</a> çözümlerine rastladım. Bunlardan en çok <a href="http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx">Pete Welter’in çözümü</a> hoşuma gitti. Bu çözümde Pete Welter, Dictionary generic tipini ve <a href="http://msdn2.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable.aspx">IXmlSerializable</a> tipini implement eden yeni bir tip yaratmış. Dictionary’den dolayı yeni tipimiz Dictionary ile beraber gelen tüm özelliklere sahip, oh ne güzel. IXmlSerializable tipinin gerektirdiği metodları da implement ederek <acronym class="uttInitialism" title="eXtensible Markup Language">XML</acronym> Serialization işlemi sırasında yeni tipimizin nasıl serialize edileceğini de bildirmiş sevgili Pete Welter. Sonuç olarak temiz ve çok rahat kullanılabilir yeni bir tip ortaya çıkmış. Kod şu şekilde:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="nf">XmlRoot</span><span class="p">(</span><span class="s">"dictionary"</span><span class="p">)]</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">SerializableDictionary</span><span class="p">&lt;</span><span class="n">TKey</span><span class="p">,</span> <span class="n">TValue</span><span class="p">&gt;</span>
    <span class="p">:</span> <span class="n">Dictionary</span><span class="p">&lt;</span><span class="n">TKey</span><span class="p">,</span> <span class="n">TValue</span><span class="p">&gt;,</span> <span class="n">IXmlSerializable</span>
<span class="p">{</span>
    <span class="err">#</span><span class="n">region</span> <span class="n">IXmlSerializable</span> <span class="n">Members</span>
    <span class="k">public</span> <span class="n">System</span><span class="p">.</span><span class="n">Xml</span><span class="p">.</span><span class="n">Schema</span><span class="p">.</span><span class="n">XmlSchema</span> <span class="nf">GetSchema</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="k">null</span><span class="p">;</span>
    <span class="p">}</span>
 
    <span class="k">public</span> <span class="k">void</span> <span class="nf">ReadXml</span><span class="p">(</span><span class="n">System</span><span class="p">.</span><span class="n">Xml</span><span class="p">.</span><span class="n">XmlReader</span> <span class="n">reader</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">XmlSerializer</span> <span class="n">keySerializer</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">XmlSerializer</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">TKey</span><span class="p">));</span>
        <span class="n">XmlSerializer</span> <span class="n">valueSerializer</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">XmlSerializer</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">TValue</span><span class="p">));</span>
 
        <span class="kt">bool</span> <span class="n">wasEmpty</span> <span class="p">=</span> <span class="n">reader</span><span class="p">.</span><span class="n">IsEmptyElement</span><span class="p">;</span>
        <span class="n">reader</span><span class="p">.</span><span class="nf">Read</span><span class="p">();</span>
 
        <span class="k">if</span> <span class="p">(</span><span class="n">wasEmpty</span><span class="p">)</span>
            <span class="k">return</span><span class="p">;</span>
 
        <span class="k">while</span> <span class="p">(</span><span class="n">reader</span><span class="p">.</span><span class="n">NodeType</span> <span class="p">!=</span> <span class="n">System</span><span class="p">.</span><span class="n">Xml</span><span class="p">.</span><span class="n">XmlNodeType</span><span class="p">.</span><span class="n">EndElement</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="n">reader</span><span class="p">.</span><span class="nf">ReadStartElement</span><span class="p">(</span><span class="s">"item"</span><span class="p">);</span>
 
            <span class="n">reader</span><span class="p">.</span><span class="nf">ReadStartElement</span><span class="p">(</span><span class="s">"key"</span><span class="p">);</span>
            <span class="n">TKey</span> <span class="n">key</span> <span class="p">=</span> <span class="p">(</span><span class="n">TKey</span><span class="p">)</span><span class="n">keySerializer</span><span class="p">.</span><span class="nf">Deserialize</span><span class="p">(</span><span class="n">reader</span><span class="p">);</span>
            <span class="n">reader</span><span class="p">.</span><span class="nf">ReadEndElement</span><span class="p">();</span>
 
            <span class="n">reader</span><span class="p">.</span><span class="nf">ReadStartElement</span><span class="p">(</span><span class="s">"value"</span><span class="p">);</span>
            <span class="n">TValue</span> <span class="k">value</span> <span class="p">=</span> <span class="p">(</span><span class="n">TValue</span><span class="p">)</span><span class="n">valueSerializer</span><span class="p">.</span><span class="nf">Deserialize</span><span class="p">(</span><span class="n">reader</span><span class="p">);</span>
            <span class="n">reader</span><span class="p">.</span><span class="nf">ReadEndElement</span><span class="p">();</span>
 
            <span class="k">this</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="k">value</span><span class="p">);</span>
 
            <span class="n">reader</span><span class="p">.</span><span class="nf">ReadEndElement</span><span class="p">();</span>
            <span class="n">reader</span><span class="p">.</span><span class="nf">MoveToContent</span><span class="p">();</span>
        <span class="p">}</span>
        <span class="n">reader</span><span class="p">.</span><span class="nf">ReadEndElement</span><span class="p">();</span>
    <span class="p">}</span>
 
    <span class="k">public</span> <span class="k">void</span> <span class="nf">WriteXml</span><span class="p">(</span><span class="n">System</span><span class="p">.</span><span class="n">Xml</span><span class="p">.</span><span class="n">XmlWriter</span> <span class="n">writer</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">XmlSerializer</span> <span class="n">keySerializer</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">XmlSerializer</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">TKey</span><span class="p">));</span>
        <span class="n">XmlSerializer</span> <span class="n">valueSerializer</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">XmlSerializer</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">TValue</span><span class="p">));</span>
 
        <span class="k">foreach</span> <span class="p">(</span><span class="n">TKey</span> <span class="n">key</span> <span class="k">in</span> <span class="k">this</span><span class="p">.</span><span class="n">Keys</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="n">writer</span><span class="p">.</span><span class="nf">WriteStartElement</span><span class="p">(</span><span class="s">"item"</span><span class="p">);</span>
 
            <span class="n">writer</span><span class="p">.</span><span class="nf">WriteStartElement</span><span class="p">(</span><span class="s">"key"</span><span class="p">);</span>
            <span class="n">keySerializer</span><span class="p">.</span><span class="nf">Serialize</span><span class="p">(</span><span class="n">writer</span><span class="p">,</span> <span class="n">key</span><span class="p">);</span>
            <span class="n">writer</span><span class="p">.</span><span class="nf">WriteEndElement</span><span class="p">();</span>
 
            <span class="n">writer</span><span class="p">.</span><span class="nf">WriteStartElement</span><span class="p">(</span><span class="s">"value"</span><span class="p">);</span>
            <span class="n">TValue</span> <span class="k">value</span> <span class="p">=</span> <span class="k">this</span><span class="p">[</span><span class="n">key</span><span class="p">];</span>
            <span class="n">valueSerializer</span><span class="p">.</span><span class="nf">Serialize</span><span class="p">(</span><span class="n">writer</span><span class="p">,</span> <span class="k">value</span><span class="p">);</span>
            <span class="n">writer</span><span class="p">.</span><span class="nf">WriteEndElement</span><span class="p">();</span>
 
            <span class="n">writer</span><span class="p">.</span><span class="nf">WriteEndElement</span><span class="p">();</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="err">#</span><span class="n">endregion</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Dictionary nesnemiz için serialize edilebilen key ve value tipleri seçtiğimiz sürece SerializableDictionary tipimiz de serialize edilebilir. Key/value tipleri olarak string kullandığımız bir SerializableDictionary nesnesini serialize ettiğimizde şöyle bir çıktıya sahip oluyor:</p>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;dictionary&gt;</span>
  <span class="nt">&lt;item&gt;</span>
    <span class="nt">&lt;key&gt;</span>
      <span class="nt">&lt;string&gt;</span>foo<span class="nt">&lt;/string&gt;</span>
    <span class="nt">&lt;/key&gt;</span>
    <span class="nt">&lt;value&gt;</span>
      <span class="nt">&lt;string&gt;</span>bar<span class="nt">&lt;/string&gt;</span>
    <span class="nt">&lt;/value&gt;</span>
  <span class="nt">&lt;/item&gt;</span>
<span class="nt">&lt;/dictionary&gt;</span>
</code></pre></div></div>

<p>Buraya kadar her şey güzel, Dictionary yerine bu yeni tipi kullanarak varolan Dictionary yapılarımızı <acronym class="uttInitialism" title="eXtensible Markup Language">XML</acronym> olarak da serialize edebiliriz artık. Ama bir şey içime sinmiyor hala, <acronym class="uttInitialism" title="eXtensible Markup Language">XML</acronym> çıktısındaki etiketlerin isimlerini SerializableDictionary üzerinde hard-coded olarak yazıyoruz. Kökteki etiket ismini XmlRootAttribute’e farklı bir parametre göndererek veya SerializableDictionary tipini extend eden yeni bir tip tanımlayarak değiştirebiliriz. Ama hala alt seviyelerdeki <strong>item</strong>, <strong>key</strong> ve <strong>value</strong> şeklindeki etiket isimlerini hard-code etmek dışında bir seçeneğimiz görünmüyor. Eğer bu sınıfı tek tipteki bir Dictionary verimiz için kullanacaksak pek bir sorun yok ama farklı farklı <acronym class="uttInitialism" title="eXtensible Markup Language">XML</acronym> çıktılarını beklediğimiz generic bir çözüm için bu tipi kullanmayı planlıyorsak bu etiket isimlerine müdahale etmenin daha generic bir yolunu bulmamız gerek (copy/paste yapmayı bir çözüm olarak aklımızdan bile geçirmiyoruz tabii ki). Bu amaçla SerializableDictionary tipini biraz değiştirerek şu kodu elde ettim:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">abstract</span> <span class="k">class</span> <span class="nc">SerializableDictionary</span><span class="p">&lt;</span><span class="n">TKey</span><span class="p">,</span> <span class="n">TValue</span><span class="p">&gt;</span> 
    <span class="p">:</span> <span class="n">Dictionary</span><span class="p">&lt;</span><span class="n">TKey</span><span class="p">,</span> <span class="n">TValue</span><span class="p">&gt;,</span> <span class="n">IXmlSerializable</span>
<span class="p">{</span>
    <span class="k">protected</span> <span class="k">abstract</span> <span class="kt">string</span> <span class="n">itemName</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
    <span class="k">protected</span> <span class="k">abstract</span> <span class="kt">string</span> <span class="n">keyName</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
    <span class="k">protected</span> <span class="k">abstract</span> <span class="kt">string</span> <span class="n">valueName</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
 
    <span class="err">#</span><span class="n">region</span> <span class="n">IXmlSerializable</span> <span class="n">Members</span>
    <span class="k">public</span> <span class="n">System</span><span class="p">.</span><span class="n">Xml</span><span class="p">.</span><span class="n">Schema</span><span class="p">.</span><span class="n">XmlSchema</span> <span class="nf">GetSchema</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="k">null</span><span class="p">;</span>
    <span class="p">}</span>
 
    <span class="k">public</span> <span class="k">void</span> <span class="nf">ReadXml</span><span class="p">(</span><span class="n">XmlReader</span> <span class="n">reader</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">XmlSerializer</span> <span class="n">keySerializer</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">XmlSerializer</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">TKey</span><span class="p">));</span>
        <span class="n">XmlSerializer</span> <span class="n">valueSerializer</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">XmlSerializer</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">TValue</span><span class="p">));</span>
 
        <span class="kt">bool</span> <span class="n">wasEmpty</span> <span class="p">=</span> <span class="n">reader</span><span class="p">.</span><span class="n">IsEmptyElement</span><span class="p">;</span>
        <span class="n">reader</span><span class="p">.</span><span class="nf">Read</span><span class="p">();</span>
 
        <span class="k">if</span> <span class="p">(</span><span class="n">wasEmpty</span><span class="p">)</span>
            <span class="k">return</span><span class="p">;</span>
 
        <span class="k">while</span> <span class="p">(</span><span class="n">reader</span><span class="p">.</span><span class="n">NodeType</span> <span class="p">!=</span> <span class="n">System</span><span class="p">.</span><span class="n">Xml</span><span class="p">.</span><span class="n">XmlNodeType</span><span class="p">.</span><span class="n">EndElement</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="n">reader</span><span class="p">.</span><span class="nf">ReadStartElement</span><span class="p">(</span><span class="n">itemName</span><span class="p">);</span>
 
            <span class="n">reader</span><span class="p">.</span><span class="nf">ReadStartElement</span><span class="p">(</span><span class="n">keyName</span><span class="p">);</span>
            <span class="n">TKey</span> <span class="n">key</span> <span class="p">=</span> <span class="p">(</span><span class="n">TKey</span><span class="p">)</span><span class="n">keySerializer</span><span class="p">.</span><span class="nf">Deserialize</span><span class="p">(</span><span class="n">reader</span><span class="p">);</span>
            <span class="n">reader</span><span class="p">.</span><span class="nf">ReadEndElement</span><span class="p">();</span>
 
            <span class="n">reader</span><span class="p">.</span><span class="nf">ReadStartElement</span><span class="p">(</span><span class="n">valueName</span><span class="p">);</span>
            <span class="n">TValue</span> <span class="k">value</span> <span class="p">=</span> <span class="p">(</span><span class="n">TValue</span><span class="p">)</span><span class="n">valueSerializer</span><span class="p">.</span><span class="nf">Deserialize</span><span class="p">(</span><span class="n">reader</span><span class="p">);</span>
            <span class="n">reader</span><span class="p">.</span><span class="nf">ReadEndElement</span><span class="p">();</span>
 
            <span class="k">this</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="k">value</span><span class="p">);</span>
 
            <span class="n">reader</span><span class="p">.</span><span class="nf">ReadEndElement</span><span class="p">();</span>
            <span class="n">reader</span><span class="p">.</span><span class="nf">MoveToContent</span><span class="p">();</span>
        <span class="p">}</span>
        <span class="n">reader</span><span class="p">.</span><span class="nf">ReadEndElement</span><span class="p">();</span>
    <span class="p">}</span>
 
    <span class="k">public</span> <span class="k">void</span> <span class="nf">WriteXml</span><span class="p">(</span><span class="n">System</span><span class="p">.</span><span class="n">Xml</span><span class="p">.</span><span class="n">XmlWriter</span> <span class="n">writer</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">XmlSerializer</span> <span class="n">keySerializer</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">XmlSerializer</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">TKey</span><span class="p">));</span>
        <span class="n">XmlSerializer</span> <span class="n">valueSerializer</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">XmlSerializer</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">TValue</span><span class="p">));</span>
 
        <span class="k">foreach</span> <span class="p">(</span><span class="n">TKey</span> <span class="n">key</span> <span class="k">in</span> <span class="k">this</span><span class="p">.</span><span class="n">Keys</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="n">writer</span><span class="p">.</span><span class="nf">WriteStartElement</span><span class="p">(</span><span class="n">itemName</span><span class="p">);</span>
 
 
            <span class="n">writer</span><span class="p">.</span><span class="nf">WriteStartElement</span><span class="p">(</span><span class="n">keyName</span><span class="p">);</span>
            <span class="n">keySerializer</span><span class="p">.</span><span class="nf">Serialize</span><span class="p">(</span><span class="n">writer</span><span class="p">,</span> <span class="n">key</span><span class="p">);</span>
            <span class="n">writer</span><span class="p">.</span><span class="nf">WriteEndElement</span><span class="p">();</span>
 
            <span class="n">writer</span><span class="p">.</span><span class="nf">WriteStartElement</span><span class="p">(</span><span class="n">valueName</span><span class="p">);</span>
            <span class="n">TValue</span> <span class="k">value</span> <span class="p">=</span> <span class="k">this</span><span class="p">[</span><span class="n">key</span><span class="p">];</span>
            <span class="n">valueSerializer</span><span class="p">.</span><span class="nf">Serialize</span><span class="p">(</span><span class="n">writer</span><span class="p">,</span> <span class="k">value</span><span class="p">);</span>
            <span class="n">writer</span><span class="p">.</span><span class="nf">WriteEndElement</span><span class="p">();</span>
 
            <span class="n">writer</span><span class="p">.</span><span class="nf">WriteEndElement</span><span class="p">();</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="err">#</span><span class="n">endregion</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Override edilmek üzere 3 tane abstract property ekleyerek hard-coded string değerlerinden kurtulmuş olduk. Tipimize abstract üyeler eklediğimiz için artık bu tipi direk olarak kullanılamaz hale getirdik ve bir abstract tipimiz oldu. Tipimizi kullanmak istediğimizde yamamız gereken kod artık şu şekilde olacak:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">Fields</span> <span class="p">:</span> <span class="n">SerializableDictionary</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">,</span> <span class="kt">string</span><span class="p">&gt;</span>
<span class="p">{</span>
    <span class="k">protected</span> <span class="k">override</span> <span class="kt">string</span> <span class="n">itemName</span>
    <span class="p">{</span>
        <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="s">"Field"</span><span class="p">;</span> <span class="p">}</span>
    <span class="p">}</span>
 
    <span class="k">protected</span> <span class="k">override</span> <span class="kt">string</span> <span class="n">keyName</span>
    <span class="p">{</span>
        <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="s">"Name"</span><span class="p">;</span> <span class="p">}</span>
    <span class="p">}</span>
 
    <span class="k">protected</span> <span class="k">override</span> <span class="kt">string</span> <span class="n">valueName</span>
    <span class="p">{</span>
        <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="s">"Value"</span><span class="p">;</span> <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Burada az önce değiştirdiğimiz SerializableDictionary tipini extend ederek kullanacağımız yeni tipi yaratıyoruz. Bu aşmada Key/Value tiplerimizi ve <acronym class="uttInitialism" title="eXtensible Markup Language">XML</acronym> çıktısında oluşacak etiketlerin isimlerini belirtiyoruz. Eğer kök <acronym class="uttInitialism" title="eXtensible Markup Language">XML</acronym> etiketi için kullanılacak ismin tipimizin isminden farklı olmasını istiyorsanız yeni tipin üzerinde XmlRootAttribute kullanarak bunu da belirtebilirsiniz. Bu tipimizi de artık şu şekilde kullanabiliriz:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 2 kayıt içeren bir Dictionary oluşturalım</span>
<span class="c1">// .NET 3.5/VS2008 ile gelen Collection Initializers özelliği</span>
<span class="c1">// bu gibi durumlarda daha temiz/kısa kod yazmamıza yarıyor</span>
<span class="n">Fields</span> <span class="n">fields</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Fields</span> <span class="p">{</span>
    <span class="p">{</span> <span class="s">"foo"</span><span class="p">,</span> <span class="s">"bar"</span> <span class="p">},</span>
    <span class="p">{</span> <span class="s">"hede"</span><span class="p">,</span> <span class="s">"hödö"</span><span class="p">}</span>
<span class="p">};</span>
 
<span class="c1">// XML Serialize işlemi için gerekli altyapıyı oluşturalım</span>
<span class="n">StringBuilder</span> <span class="n">sb</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">StringBuilder</span><span class="p">();</span>
 
<span class="c1">// Burada da bir başka yenilik olan Object Initializer özelliğini</span>
<span class="c1">// kullanarak nesneyi oluşturduğumuz satırda nesne üzerindeki</span>
<span class="c1">// bazı özelliklere de ilk değerlerini verebiliyoruz</span>
<span class="n">XmlTextWriter</span> <span class="n">xtw</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">XmlTextWriter</span><span class="p">(</span><span class="k">new</span> <span class="nf">StringWriter</span><span class="p">(</span><span class="n">sb</span><span class="p">))</span> 
    <span class="p">{</span> <span class="n">Formatting</span> <span class="p">=</span> <span class="n">Formatting</span><span class="p">.</span><span class="n">Indented</span> <span class="p">};</span>
<span class="n">xtw</span><span class="p">.</span><span class="nf">WriteRaw</span><span class="p">(</span><span class="s">""</span><span class="p">);</span>
 
<span class="c1">// Burada XML Serialize işlemi gerçekleşiyor</span>
<span class="n">XmlSerializer</span> <span class="n">xs</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">XmlSerializer</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">Fields</span><span class="p">));</span>
<span class="n">xs</span><span class="p">.</span><span class="nf">Serialize</span><span class="p">(</span><span class="n">xtw</span><span class="p">,</span> <span class="n">fields</span><span class="p">);</span>
 
<span class="kt">string</span> <span class="n">xmlFields</span> <span class="p">=</span> <span class="n">sb</span><span class="p">.</span><span class="nf">ToString</span><span class="p">();</span>
 
<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="n">xmlFields</span><span class="p">);</span>
 
<span class="c1">// Burada da daha önce serialize ettiğimiz nesneyi deserialize ederek</span>
<span class="c1">// tekrar hafızda bir nesne haline çeviriyoruz</span>
<span class="n">Fields</span> <span class="n">deserializedFields</span> <span class="p">=</span> <span class="n">xs</span><span class="p">.</span><span class="nf">Deserialize</span><span class="p">(</span><span class="k">new</span> <span class="nf">StringReader</span><span class="p">(</span><span class="n">xmlFields</span><span class="p">))</span> <span class="k">as</span> <span class="n">Fields</span><span class="p">;</span>
</code></pre></div></div>

<p>Bu kodun çıktısı da şu şekilde:</p>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;Fields&gt;</span>
  <span class="nt">&lt;Field&gt;</span>
    <span class="nt">&lt;Name&gt;</span>
      <span class="nt">&lt;string&gt;</span>foo<span class="nt">&lt;/string&gt;</span>
    <span class="nt">&lt;/Name&gt;</span>
    <span class="nt">&lt;Value&gt;</span>
      <span class="nt">&lt;string&gt;</span>bar<span class="nt">&lt;/string&gt;</span>
    <span class="nt">&lt;/Value&gt;</span>
  <span class="nt">&lt;/Field&gt;</span>
  <span class="nt">&lt;Field&gt;</span>
    <span class="nt">&lt;Name&gt;</span>
      <span class="nt">&lt;string&gt;</span>hede<span class="nt">&lt;/string&gt;</span>
    <span class="nt">&lt;/Name&gt;</span>
    <span class="nt">&lt;Value&gt;</span>
      <span class="nt">&lt;string&gt;</span>hödö<span class="nt">&lt;/string&gt;</span>
    <span class="nt">&lt;/Value&gt;</span>
  <span class="nt">&lt;/Field&gt;</span>
<span class="nt">&lt;/Fields&gt;</span>
</code></pre></div></div>

<p>SerializableDictionary tipini bir kere tanımlayarak projemiz içerisinde bunu baz alan farklı farklı Dictionary tiplerimizi oluşturabilir, bunların farklı farklı <acronym class="uttInitialism" title="eXtensible Markup Language">XML</acronym> çıktıları olmasını sağlayabiliriz.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Visual Studio 2008 ve .NET Framework 3.5 çıktı]]></title>
    <link href="http://huseyint.com/2007/11/visual-studio-2008-ve-net-framework-35-cikti/"/>
    <updated>2007-11-19T00:00:00+00:00</updated>
    <id>http://huseyint.com/2007/11/visual-studio-2008-ve-net-framework-35-cikti</id>
    <content type="html"><![CDATA[<p align="center">
  <img src="http://huseyint.com/wp-content/uploads/2007/11/aa700831vs08_ven-usmsdn10.png" alt="Visual Studio 2008" />
</p>

<p>Daha önce <a href="http://blogs.msdn.com/somasegar/archive/2007/11/05/teched-developer-in-europe.aspx">Kasım ayında çıkacağı duyurulan</a> <a href="http://msdn2.microsoft.com/en-us/vstudio/products/default.aspx">Visual Studio 2008</a> ve .NET Framework 3.5′in RTM sürümleri <a href="http://blogs.msdn.com/somasegar/archive/2007/11/19/visual-studio-2008-and-net-framework-3-5-shipped.aspx">bugün duyuruldu</a>. MSDN Subscription sahipleri bugün itibariyle bu ürünü <a href="http://msdn2.microsoft.com/en-us/subscriptions/bb608344.aspx">indirebilir</a>. Eğer 90 günlük deneme sürümünü indirmek istiyorsanız <a href="http://msdn2.microsoft.com/en-us/vstudio/products/aa700831.aspx">şu sayfaya</a> gidip Team System Edition’larını indirebilirsiniz. Burada daha “Visual Studio 2008 Professional Edition” için download linki hazır değil ama 1 haftaya kadar o da çıkacakmış. Tamamen ücretsiz olan Express sürümlerinin 2008 versiyonları da <a href="http://www.microsoft.com/express/download/">indirilebilir durumda</a>. .NET Framework’ün 3.5 <a href="http://go.microsoft.com/?linkid=7755937">internetten kurulan</a> versiyonunu (2.7 MB) ve <a href="http://download.microsoft.com/download/6/0/f/60fc5854-3cb8-4892-b6db-bd4f42510f28/dotnetfx35.exe">tekrar dağıtılabilen (offline)</a> versiyonunu (197.1 MB) da Microsoft Downloads’dan indirebilirsiniz. .NET Framework 3.5 ayrıca 2.0 ve 3.0 versiyonlarının SP1′lerini de içermekte.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[.NET Framework 3.5 çok kullanılan tipler ve namespaceler posteri]]></title>
    <link href="http://huseyint.com/2007/11/net-framework-35-cok-kullanilan-tipler-ve-namespaceler-posteri/"/>
    <updated>2007-11-05T00:00:00+00:00</updated>
    <id>http://huseyint.com/2007/11/net-framework-35-cok-kullanilan-tipler-ve-namespaceler-posteri</id>
    <content type="html"><![CDATA[<p>Frameworkun 3.0 ve 3.5 sürümleri ile beraber gelen tip ve namespaceleri de gösteren <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=7B645F3A-6D22-4548-A0D8-C2A27E1917F8&amp;displaylang=en">şöyle bir poster</a> hazırlamışlar:</p>

<p><a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=7B645F3A-6D22-4548-A0D8-C2A27E1917F8&amp;displaylang=en"><img src="/wp-content/uploads/2007/11/posterthumbnail.png" alt=".NET Framework 3.5 çok kullanılan tipler ve namespaceler posteri" /></a></p>

<p><a href="http://blogs.msdn.com/pandrew/archive/2007/11/02/announcing-the-net-framework-3-5-commonly-used-types-and-namespaces-poster.aspx">Kaynak</a></p>

<p><strong>Güncelleme:</strong> XPS formatında biri <a href="http://download.microsoft.com/download/4/a/3/4a3c7c55-84ab-4588-84a4-f96424a7d82d/dotnet_poster_xps_large.xps">tek parça</a> ve biri de <a href="http://download.microsoft.com/download/4/a/3/4a3c7c55-84ab-4588-84a4-f96424a7d82d/dotnet_poster_xps_split.xps">16 parçalık</a> halde olmak üzere iki yeni dosya daha eklenmiş. Tek parça halinde bastırmak biraz zor olacağı için, 16 tane A4 kağıda basıp birleştirmek mümkün.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Bunu biliyor muydunuz: C# Null Coalesce Operator ya da ?? operatörü]]></title>
    <link href="http://huseyint.com/2007/11/bunu-biliyor-muydunuz-c-null-coalesce-operator-ya-da-operatoru/"/>
    <updated>2007-11-02T00:00:00+00:00</updated>
    <id>http://huseyint.com/2007/11/bunu-biliyor-muydunuz-c-null-coalesce-operator-ya-da-operatoru</id>
    <content type="html"><![CDATA[<p>Geçenlerde bir videoda <strong>??</strong> şeklinde bir C# operatörünün kullanımına şahit oldum. Başta .NET 3.5 ile gelen yeni özelliklerden biri gibi gelse de bu operatör aslında .NET 2.0′dan beri varmış da haberimiz yokmuş. Videodaki kodun gelişinden operatörün ne amaçla kullanıldığı açıktı; operatörün solunda bulunan operandın (operandın Türkçe’si <strong>işlenen</strong>miş bu arada) değeri null değilse işlem sonucu bu (soldaki) operand, null ise de sağdaki operand dönüyor. Şu şekilde:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">string</span> <span class="n">a</span> <span class="p">=</span> <span class="k">null</span><span class="p">;</span>
<span class="kt">string</span> <span class="n">b</span> <span class="p">=</span> <span class="s">"foo"</span><span class="p">;</span>
<span class="kt">string</span> <span class="n">c</span> <span class="p">=</span> <span class="n">a</span> <span class="p">??</span> <span class="n">b</span><span class="p">;</span>
</code></pre></div></div>

<p>kodu çalıştırıldığında c değişkeni a null değerine sahip olduğu için b’nin değeri olan “foo” değerine sahip oluyor. İşimizi bir çok sefer kolaylaştıran diğer bir operatör <strong>?:</strong> <a href="http://msdn2.microsoft.com/en-us/library/ty67wk28(VS.80).aspx">Ternary operatöründen</a> bile daha okunabilir bir kod sağlıyor. Ternary ile bunu şu şekilde yazabilirdik:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">string</span> <span class="n">a</span> <span class="p">=</span> <span class="k">null</span><span class="p">;</span>
<span class="kt">string</span> <span class="n">b</span> <span class="p">=</span> <span class="s">"foo"</span><span class="p">;</span>
<span class="kt">string</span> <span class="n">c</span> <span class="p">=</span> <span class="n">a</span> <span class="p">!=</span> <span class="k">null</span> <span class="p">?</span> <span class="n">a</span> <span class="p">:</span> <span class="n">b</span><span class="p">;</span>
</code></pre></div></div>

<p>Hele bir de if kullansaydık bu işlem için bu kadar daha kod yazmamız gerekecekti:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">string</span> <span class="n">a</span> <span class="p">=</span> <span class="k">null</span><span class="p">;</span>
<span class="kt">string</span> <span class="n">b</span> <span class="p">=</span> <span class="s">"foo"</span><span class="p">;</span>
 
<span class="k">if</span> <span class="p">(</span><span class="n">a</span> <span class="p">!=</span> <span class="k">null</span><span class="p">)</span>
    <span class="n">c</span> <span class="p">=</span> <span class="n">a</span><span class="p">;</span>
<span class="k">else</span>
    <span class="n">c</span> <span class="p">=</span> <span class="n">b</span><span class="p">;</span>
</code></pre></div></div>

<p>Operatörü iç içe geçmiş bir şekilde kullanırsak bir kaç değişken arasından ilk null olmayanını bulabiliriz:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">string</span> <span class="n">a</span> <span class="p">=</span> <span class="k">null</span><span class="p">;</span>
<span class="kt">string</span> <span class="n">b</span> <span class="p">=</span> <span class="k">null</span><span class="p">;</span>
<span class="kt">string</span> <span class="n">c</span> <span class="p">=</span> <span class="s">"foo"</span><span class="p">;</span>
<span class="kt">string</span> <span class="n">d</span> <span class="p">=</span> <span class="n">a</span> <span class="p">??</span> <span class="n">b</span> <span class="p">??</span> <span class="n">c</span><span class="p">;</span> <span class="c1">// d = "foo"</span>
</code></pre></div></div>

<p>Operatörün MSDN sayfasına <a href="http://msdn2.microsoft.com/en-us/library/ms173224(VS.80).aspx">şuradan</a> ulaşabilirsiniz.</p>

<table>
  <tbody>
    <tr>
      <td>Bu operatör aslında JavaScript yazarken kullandığımız **</td>
      <td> </td>
      <td>** operatörü ile aynı işi yapıyor; ilk operand null değilse onu null ise sonrakini döndür.</td>
    </tr>
  </tbody>
</table>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">foo</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">bar</span><span class="dl">"</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">baz</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="nx">alert</span><span class="p">(</span><span class="nx">foo</span> <span class="o">||</span> <span class="nx">baz</span><span class="p">);</span>
</code></pre></div></div>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[ASP.NET ile MVC programlama, sonunda!]]></title>
    <link href="http://huseyint.com/2007/10/aspnet-ile-mvc-programlama-sonunda/"/>
    <updated>2007-10-27T00:00:00+00:00</updated>
    <id>http://huseyint.com/2007/10/aspnet-ile-mvc-programlama-sonunda</id>
    <content type="html"><![CDATA[<p>ASP.NET’in varsayılan programlama yaklaşımı <a href="http://msdn.microsoft.com/msdnmag/issues/01/05/webforms/" title="ASP .NET: Web Forms Let You Drag and Drop Your Way to Powerful Web Apps">Web Forms</a>‘a bir türlü ısınamıyorum, ısınamayacağım da. Oysa ki <a href="http://en.wikipedia.org/wiki/Active_Server_Pages">klasik ASP</a> (3.0) ne güzeldi, bir Request bir de Response nesnesi yetiyordu. Tamam, sayfanın yenilenmesi gibi durumlarda form değerlerini olması gereken yerlere doldurma hammalığı programcıya kalıyordu, ama ASP.NET’in &lt;form runat=”server”&gt; mantığı da pek hoş değildi. Binbir türlü yol (postback, viewstate, vs.) ile Microsoft mühendisleri web programcıların daha az kod ile hızlı bir şekilde nam-ı diğer Web Form Uygulamaları yazmalarını sağlıyordu. Bu çabaların hakkını vermek lazım, zira ASP.NET ile web programlama öyle bir duruma gelmişti ki Visual Studio ortamında masaüstü uygulama yazmaktan pek bir farkı kalmamıştı. Asıl amaç da bu değil miydi zaten, Visual Studio ile yıllardan beri aşina olan Microsoft teknolojileri odaklı programcıların bu yeni web programlama yaşam döngüsüne hızlı bir şekilde uyum sağlamaları. İyi güzel de bir şey unutuldu gibi geliyor bana, yazılan uygulamalar web uygulamaları olacaktı. Yani masaüstünden tamamen ayrı bir ortamda hayatlarını sürdüreceklerdi. Öyle bir ortam ki sunucu tarafını ayrı düşünmek, istemci (browser) tarafını ayrı düşünmek ve ona göre kod yazmak gerekiyordu. Web’in eti-kemiği olan <a href="http://www.w3.org/Protocols/rfc2616/rfc2616.html"><acronym class="uttInitialism" title="HyperText Transfer Protocol">HTTP</acronym> protokolünü</a> ve <acronym class="uttInitialism" title="HyperText Markup Language">HTML</acronym> dilini sular seller gibi bilmesek de bir formu <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3">GET</a> veya <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5">POST</a> ile göndermenin farkını, hangi etiketin nerede kullanıldığında <a href="http://huseyint.com/projeler/aptal-tablolar/" title="Aptal Tablolar">daha anlamlı</a> olacağını bilmek bir web programcısının boynunun borcu olsa gerek.</p>

<p>Oysa ki ASP.NET’in arkasında muazzam bir framework, <a href="http://msdn2.microsoft.com/en-us/library/aa388745.aspx">BCL</a> (Base Class Library) var. Klasik ASP’de olan Request, Response, Session, vs. nesneleri bunda yok mu; var tabii ki hem de çok daha zengin, çok daha kullanılabilir. Bana göre tek yanlış olan bunların üzerine kurulan ASP.NET Web Forms yapısı. <a href="http://www.castleproject.org/monorail/index.html">MonoRail</a> isimli proje ile <a href="http://www.rubyonrails.org/" class="ubernym uttInitialism"><acronym class="uttInitialism" title="Ruby on Rails">RoR</acronym></a>’daki web programlama mantığı .NET ortamına getirilmeye çalışılıyor. Bunun ile bir proje geliştirmeye fırsatım olmadı ancak muhtemelen Web Forms mantığından daha uygulanabilir olacağını tahmin ediyorum.</p>

<p>İşte bu noktada <a href="http://weblogs.asp.net/scottgu/">ScottGu</a> geçtiğimiz haftalarda <a href="http://www.altnetconf.com/">ALT.NET</a> konferansında Microsoft tarafından geliştirilmekte olan ASP.NET <acronym class="uttInitialism" title="Model View Controller">MVC</acronym> Framework’unu tanıttı. Daha üzerinde çalışmalar süren bu frameworkun bu yıl sonuna doğru genel önizleme (“public preview” demek istiyorum :) ) sürümü geliştiricilere bir <acronym class="uttInitialism" title="Community Technology Preview">CTP</acronym> olarak sunulacak. .NET 3.5′e dahil olmayacak bu framework, aynı ASP.NET <acronym class="uttAcronym" title="Asynchronous Javascript And XML">AJAX</acronym> (Asynchronous Javascript And <acronym class="uttInitialism" title="eXtensible Markup Language">XML</acronym>) (daha önce Atlas olarak da bilinen) gibi ASP.NET üzerine ek bir framework olarak dağıtılacak. 2008′in ilk yarısında da son halinin çıkması planlanıyor.</p>

<p style="text-align: center;">
  <img src="http://huseyint.com/wp-content/uploads/2007/10/aspnet-mvc.jpg" alt="ASP.NET MVC ile “Merhaba Dünya”" />
</p>

<p>Orjinal duyuruyu <a href="http://weblogs.asp.net/scottgu/archive/2007/10/14/asp-net-mvc-framework.aspx">ScottGu’nun blogunda</a>; ayrıntılı bilgiyi, blog camiasından konu ile ilgili linkleri ve ScottGu’nun tanıtım videosunu (izlemeniz şiddetle tavsiye olunur) <a href="http://www.hanselman.com/blog/ScottGuMVCPresentationAndScottHaScreencastFromALTNETConference.aspx">ScottHa’nın blogunda</a> bulabilirsiniz. Konu ile ilgili (blogunu yeni keşfettiğim) <a href="http://www.tahiroglu.com/post/aspnet-mvc-framework-ve-dusundurdukleri.aspx" title="ASP.NET MVC Framework ve Düşündürdükleri">Muhammed Tahiroğlu’nun yazısını</a> da okumanız tavsiye ederim.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Bir ikonun anatomisi]]></title>
    <link href="http://huseyint.com/2007/10/bir-ikonun-anatomisi/"/>
    <updated>2007-10-09T00:00:00+00:00</updated>
    <id>http://huseyint.com/2007/10/bir-ikonun-anatomisi</id>
    <content type="html"><![CDATA[<p style="text-align: center">
  <img src="http://huseyint.com/wp-content/uploads/2007/10/owl.png" alt="owl.png" />
</p>

<p>İkonların hastasıyım. O küçücük mini minnacık şeyler bazen binlerce kelimeye bedel. Ama tabi onların da kaliteli ve kalitesiz olanları var. Son zamanlarda keşfettiğim <a href="http://iconka.com/" title="Iconka.com (icons, illustrations, interfaces)">Iconka</a> isimli bir Rus ikon sitesinin <a href="http://iconka.com/works/" title="Iconka portföyü">portföyünde</a> gerçekten çok güzel şekilde hazırlanmış ikonlar bulunmakta. Asıl size bahsetmek istediğim site <a href="http://iconka.com/blog/lang/en/">blogunda</a> zaman zaman bazı ikonların nasıl yapıldığına dair videoları <a href="http://www.youtube.com/user/ikonkaru">YouTube’da yayınlıyor</a>:</p>

<p style="text-align: center">
</p>

<p style="text-align: center">
</p>

<p style="text-align: center">
</p>

<p>Not: Videolarda <a href="http://www.xara.com/products/xtreme/">Xara Xtreme</a> adında bir program kullanılıyor.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[MSDN Magazine&#8217;i Internet&#8217;te okuyun]]></title>
    <link href="http://huseyint.com/2007/09/msdn-magazinei-internette-okuyun/"/>
    <updated>2007-09-07T00:00:00+00:00</updated>
    <id>http://huseyint.com/2007/09/msdn-magazinei-internette-okuyun</id>
    <content type="html"><![CDATA[<p style="text-align: center">
  <img src="http://huseyint.com/wp-content/uploads/2007/09/msdnmagazine.gif" alt="MSDN Magazine" />
</p>

<p>Ne var bunda, zaten yıllardır bu böyle diyebilirsiniz. Evet <a href="http://msdn.microsoft.com/msdnmag/" title="MSDN Magazine ana sayfası">MSDN Magazine</a>‘i internet sitesinden okuyabiliyor hatta her ayın makalelerini <a href="http://msdn.microsoft.com/msdnmag/htmlhelp.aspx" title="MSDN Magazine HTML Help dosyaları"><acronym class="uttInitialism" title="Compiled HTML Help">CHM</acronym> formatında indirebiliyoruz</a>. Ancak <a href="http://www.nxtbookmedia.com/">NXTbook Media</a> adlı bir sitede derginin orjinal (basılı) halini web üzerinden sayfa çevirme efektleri, zoom in/out, belirli bir sayfa direk gitme, arama, vs. gibi özellikleri ile de okunabildiğini öğrendim<a href="http://labnol.blogspot.com/2007/09/get-dr-dobbs-journal-and-msdn-magazine.html" title="Get Dr. Dobbs Journal and MSDN Magazine (Digital Editions) for Free">*</a>. Flash kullanılarak yapılmış bu uygulamayı isterseniz EXE dosyası halinde de bilgisayarınıza indirip aynı şekilde okuyabilirsiniz. Hizmetin bir başka güzelliği ise dergiyi <acronym class="uttInitialism" title="Portable Document Format">PDF</acronym> formatında da indirmenize izin vermesi. Örnek vermek gerekirse Eylül ayının <acronym class="uttInitialism" title="Portable Document Format">PDF</acronym> dosyası 72,6MB boyutunda, yazdırma/yazı kopyalama koruması vs. gördüğüm kadarıyla yok.</p>

<p><a href="http://huseyint.com/wp-content/uploads/2007/09/msdnmagazinesample.png" title="MSDN Magazine örnek sayfa"></a></p>

<p style="text-align: center">
  <a href="http://huseyint.com/wp-content/uploads/2007/09/msdnmagazinesample.png" title="MSDN Magazine örnek sayfa"><img src="http://huseyint.com/wp-content/uploads/2007/09/msdnmagazinesample.thumbnail.png" alt="MSDN Magazine örnek sayfa" /></a>
</p>

<p>Eğer dosya boyutu çok fazla, hem içinde reklamlar var diyorsanız bir kaç MB’lık <acronym class="uttInitialism" title="Compiled HTML Help">CHM</acronym> dosyalarını indirebilir veya direk MSDN Magazine ana sayfasından makaleleri okuyabilirsiniz. Ancak böyle kaliteli bir kaynaktan okumak daha zevkli olacaktır diye düşünüyorum. Bu hizmet MSDN Magazine için Nisan 2007′de başlamış olacak ki daha öncesi ait bağlantılar çalışmadı. Nisan-Ekim (evet Ekim dahi çıkmış daha Eylül’e yeni girdiğimiz şu günlerde) ayları için MSDN Magazine bağlantıları şu şekilde: <a href="http://www.nxtbook.com/nxtbooks/cmp/msdnmag0407/index.php">Nisan</a> – <a href="http://www.nxtbook.com/nxtbooks/cmp/msdnmag0507/index.php">Mayıs</a> – <a href="http://www.nxtbook.com/nxtbooks/cmp/msdnmag0607/index.php">Haziran</a> – <a href="http://www.nxtbook.com/nxtbooks/cmp/msdnmag0707/index.php">Temmuz</a> – <a href="http://www.nxtbook.com/nxtbooks/cmp/msdnmag0807/index.php">Ağustos</a> – <a href="http://www.nxtbook.com/nxtbooks/cmp/msdnmag0907/index.php">Eylül</a> ve <a href="http://www.nxtbook.com/nxtbooks/cmp/msdnmag1007/index.php">Ekim</a>. Yayınlardan haberdar olmak için bir de <a href="http://www.nxtbook.com/rss/nxtbooks/cmp_msdn.xml" title="MSDN Magazine Digital Edition RSS"><acronym class="uttInitialism" title="Really Simple Syndication">RSS</acronym> bağlantısı</a> mevcut.</p>

<p>Not: <a href="http://www.ddj.com/">Dr. Dobb’s Journal</a> isimli bir başka yazılım geliştirme dergisine de benzer şekilde <a href="http://www.nxtbook.com/nxtbooks/cmp/ddj1007/" title="Dr. Dobb's Journal Digital Edition">ulaşabilirsiniz</a>.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ordan burdan #2]]></title>
    <link href="http://huseyint.com/2007/09/ordan-burdan-2/"/>
    <updated>2007-09-05T00:00:00+00:00</updated>
    <id>http://huseyint.com/2007/09/ordan-burdan-2</id>
    <content type="html"><![CDATA[<p align="center">
  <img src="http://huseyint.com/wp-content/uploads/2007/09/slpenguin-thumb.png" alt="Linux için Silverlight: Moonlight" />
</p>

<ul>
  <li><a href="http://weblogs.asp.net/scottgu/archive/2007/09/04/silverlight-1-0-released-and-silverlight-for-linux-announced.aspx" title=" Silverlight 1.0 Released and Silverlight for Linux Announced">Adobe Flash rakibi Microsoft Silverlight’ın 1.0 sürümü piyasada</a>: Novell ile yaptıkları anlaşma ile “Moonlight” isimli ürünle de Linux ortamında da çalışabilecekmiş.</li>
  <li><a href="http://baostuff.spaces.live.com/Blog/cns!F1D5A55E2D4C903A!330.entry">Başka bir Windows için Exposé – Switcher 2</a>: Mac OS X özelliği olan Exposé’yi Windows’a uyarlama çabalarından biri daha (<a href="http://lifehacker.com/software/featured-windows-download/manage-your-windows-with-switcher-2-296324.php">via</a>)</li>
  <li><a href="http://www.hanselman.com/blog/ScottHanselmans2007UltimateDeveloperAndPowerUsersToolListForWindows.aspx" title="Scott Hanselman's 2007 Ultimate Developer and Power Users Tool List for Windows">Scott Hanselman’ın Windows geliştirici ve ileri seviye (power user) kullanıcıları için 2007 yılı araç listesi</a>: Bir klasik haline gelen zaman kazandıran, saçınızı başınızı yolmaktan sizi kurtaran (çoğu mini minnacık) araçların bulunduğu listenin güncellenmş hali.</li>
  <li><a href="http://www.smashingmagazine.com/2007/09/04/40-books-for-professional-design-development/" title="40+ Books For Professional Design &amp; Development">Smashing Magazine’den profesyonel tasarım ve geliştirme için 40+ kitap</a>: “Mükemmel bir güne başlanılacak en güzel şey nedir?” sorusuna yazacağınız bir cevap (tek kelime de kabul) ve listeden seçeceğiniz bir kitap sonucu kurayla seçtiğiniz kitabı kazanabilirsiniz.</li>
  <li><a href="http://extjs.com/download/">Ext JS 1.1.1 çıktı</a>: Ufak tefek buglar giderilmiş, dokümantasyona eklentiler olmuş, ilk defa bir CHANGELOG da paket içine dahil edilmiş. Ayrıca <a href="http://www.crockford.com/javascript/jsmin.html" title="JSMin - The JavaScript Minifier">minification</a> işlemi için geçen yazımda da bahsettiğim <a href="http://www.julienlecomte.net/blog/2007/08/13/introducing-the-yui-compressor/">YUI Compressor</a> kullanılmış.</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[İpucu: .NET ile yazdığınız Windows servisinin çalıştığı dizini bulun]]></title>
    <link href="http://huseyint.com/2007/09/ipucu-net-ile-yazdiginiz-windows-servisinin-calistigi-dizini-bulun/"/>
    <updated>2007-09-03T00:00:00+00:00</updated>
    <id>http://huseyint.com/2007/09/ipucu-net-ile-yazdiginiz-windows-servisinin-calistigi-dizini-bulun</id>
    <content type="html"><![CDATA[<p>Bir Windows Forms uygulamasında <code class="language-plaintext highlighter-rouge">Application.StartupPath</code> ile eriştiğimiz çalışma dizinine Windows servisi şartları altında (<code class="language-plaintext highlighter-rouge">System.Windows.Forms.Application</code> sınıfına ulaşamadığımız bir durumda) şu şekilde erişebiliriz:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">System</span><span class="p">.</span><span class="n">IO</span><span class="p">.</span><span class="n">Path</span><span class="p">.</span><span class="nf">GetDirectoryName</span><span class="p">(</span><span class="n">System</span><span class="p">.</span><span class="n">Reflection</span><span class="p">.</span><span class="n">Assembly</span><span class="p">.</span><span class="nf">GetExecutingAssembly</span><span class="p">().</span><span class="n">Location</span><span class="p">)</span>
</code></pre></div></div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Adobe AIR]]></title>
    <link href="http://huseyint.com/2007/09/adobe-air/"/>
    <updated>2007-09-01T00:00:00+00:00</updated>
    <id>http://huseyint.com/2007/09/adobe-air</id>
    <content type="html"><![CDATA[<p>Yok yok Adobe’nin hava yolu işletmeciliğine falan girdiği yok :) Adobe Integrated Runtime’nin kısaltması olan AIR, Adobe tarafından geliştirilmekte olan ve web geliştiricilerinin var olan geliştirme yeteneklerini (Flash, Flex, <acronym class="uttInitialism" title="HyperText Markup Language">HTML</acronym>, JavaScript, <acronym class="uttInitialism" title="Cascading Style Sheets">CSS</acronym> (Cascading Style Sheets), vs.) kullanarak oluşturdukları masaüstü uygulamalarını farklı işletim sistemleri (Windows, Mac OS X, Linux) üzerinde çalıştırabilen bir çalıştırma ortamıdır. 10 Haziran’a kadar Apollo kod adı ile tanıtılan bu geliştirme ortamı, bu tarihte ilk kamuya açık betasının da yayınlanmasından sonra ismi de AIR olarak değiştirimiştir. Şu an hala Beta 1 aşamasında olan AIR’in, Adobe MAX 2007 esnasında Beta 2 sürümü yayınlanacak ve bu sene sonuna doğru da 1.0 kararlı sürümünün piyasaya çıkacak. Beta sürümlerinde sadece Windows ve Mac OS X desteklense de 1.0 ile beraber Linux desteği de bunlara eklenecek. Adobe’nin AIR ve tamamlayıcı diğer teknolojileri için duyurduğu yol haritası şu şekilde:</p>

<p style="text-align: center">
  <a href="http://huseyint.com/wp-content/uploads/2007/08/roadmap.png" title="Adobe AIR Yol Haritası"><img src="http://huseyint.com/wp-content/uploads/2007/08/roadmap.thumbnail.png" alt="Adobe AIR Yol Haritası" /></a>
</p>

<p>Adobe’nin bu teknoloji ile amaçladığı şeylerin en başında var olan Zengin Internet Uygulmalarını (RIA) web tarayıcılarından çıkartıp masaüstü ortamına getirme gelmektedir. Böylelikle geliştiricilerin yıllarca yaptıkları yatırımlar küçük değişiklikler ile korunucak, bunun yanı sıra web tarayıcılarının kısıtlamalarından (çevirim dışı depolama, domainler arası script istekleri, vs.) kurtulan uygulamalar daha etkili bir şekilde çalışmaya devam edeceklerdir. En basitinden <acronym class="uttAcronym" title="Asynchronous Javascript And XML">AJAX</acronym> (Asynchronous Javascript And <acronym class="uttInitialism" title="eXtensible Markup Language">XML</acronym>) uygulamalarının meşhur tarayıcı geri butonu (yenileme butonunun da aşağı kalır tarafı yok ya) problemini ele alalım. <acronym class="uttAcronym" title="Asynchronous Javascript And XML">AJAX</acronym> çağrılarıyla mutlu mesut çalışan web uygulamanız sadece tek bir sayfa üzerinde çalıştığı için adres çubuğunda hep aynı adres bulunmaktadır. Normal bir web sayfasında olması gibi uygulamanızda bir önceki ekrana geri gitmek isterseniz çok doğal olarak eliniz tarayıcınızın geri butonuna gidecektir. İşte bu noktada eğer (farklı tarayıcı aldatmacaları ile) önleminizi almadıysanız bir önceki ziyaret ettiğiniz siteye gidecek ve uygulamanız o sayfadan kaldırılacaktır. Benim düşünceme göre, adres çubuğu ve navigasyon butonlarının olmayışıyla Adobe AIR buna mükemmel bir çözüm getirmekte. AIR ile yaptığınız uygulama penceresi sadece size ait olacağı için bunun gibi dış etkenlerden etkilenmiş olmayacaksınız. Şu anda Adobe AIR’in desteklediği özellikler şu şekilde:</p>

<ul>
  <li>Mac desteği (OS X 10.4.8 ve üstü (Intel ve PPC))</li>
  <li>Windows desteği (Windows XP ve Windows Vista Home Premium Edition)</li>
  <li>Dosya I/O API’si</li>
  <li>Gömülü SQLite veritabanı</li>
  <li>Flash Player 9 dahilindeki tüm fonksiyonalite</li>
  <li>Pencereler ile ilgili API’ler</li>
  <li>Komut-satırı araçları (ADL ve ADT)</li>
  <li>Flash içerisinde <acronym class="uttInitialism" title="HyperText Markup Language">HTML</acronym> içerik</li>
  <li>Üst-seviye <acronym class="uttInitialism" title="HyperText Markup Language">HTML</acronym> uygulamaları</li>
  <li>ActionScript / JavaScript Script bağlantı desteği</li>
  <li>AIR uygulamaları geliştirmek için Flex Builder ve Flex Framework desteği</li>
  <li>Uygulamalarda komut-satırı argüman desteği</li>
  <li>Sürükler ve bırak desteği</li>
  <li>Zengin Pano (Clipboard) desteği</li>
  <li>Sistem Menu API’si (beta aşamasında sadece Mac için)</li>
  <li>İnternet bağlantısını tespit etmeyi sağlayan API</li>
  <li>Dosya türü ilişkilendirme desteği</li>
  <li>Uygulamalarınıza özel simge koyabilme</li>
  <li><acronym class="uttInitialism" title="Portable Document Format">PDF</acronym> desteği</li>
</ul>

<p>Çok basit bir mantığa sahip olan ve bir o kadar da etkili olabilecek bu teknolojiyi destekleyen kişi/kuruluşlar pek de yadsınacak bir nitelikte değil. Mesela <a href="http://adaptivepath.com/publications/essays/archives/000385.php" title="Ajax: A New Approach to Web Applications"><acronym class="uttAcronym" title="Asynchronous Javascript And XML">AJAX</acronym> terimini ortaya atan</a> Jesse James Garrett bir röportajında AIR’i web uygulamalarını arttıracak başka bir destekçi olarak gördüğünü <a href="http://blog.wired.com/monkeybites/2007/06/jesse_james_gar.html" title="Jesse James Garrett Sees Adobe AIR as Another Boost For Web Apps">belirtti</a>. Ayrıca daha beta aşamasında olmasına rağmen bir çok hatrı sayılır site/kuruluş AIR’e şans veriyor. Popüler sosyal imleme ağı olan Digg’in kamuya açık API’sini duyurmasının hemen ardından düzenlediği <a href="http://digg.com/contest" title="Digg API Visualization Contest">Visualization Contest</a> (Görselleştirme Yarışması) için Adobe AIR kullanımını teşvik etti. Yine Digg ile ilgili olarak, kurucusu Kevin Rose’un yeni sosyal ağ/mikro-blog projesi olan <a href="http://www.pownce.com/">Pownce</a> masaüstü istemcisi için de Adobe AIR tercih edildi. Popüler açık arttırma sitesi eBay de kullanıcılarının masaüstü ortamında daha rahat teklif vermelirini ve aradıkalrı ürünleri bulmalarını sağlayacak <a href="http://projectsandimas.com/" title="Project San Dimas">San Dimas Projesinde</a> de yine AIR’i tercih etti.</p>

<p align="center">
  <img src="http://huseyint.com/wp-content/uploads/2007/09/pownce.gif" alt="Pownce istemcisi" />
</p>

<p><a href="http://huseyint.com/wp-content/uploads/2007/09/san_dimas_prototype.jpg" title="Project San Dimas"></a></p>

<p style="text-align: center">
  <a href="http://huseyint.com/wp-content/uploads/2007/09/san_dimas_prototype.jpg" title="Project San Dimas"><img src="http://huseyint.com/wp-content/uploads/2007/09/san_dimas_prototype.thumbnail.jpg" alt="Project San Dimas" /></a>
</p>

<p style="text-align: center">
  <a href="http://huseyint.com/wp-content/uploads/2007/09/san_dimas_prototype.jpg" title="Project San Dimas"> </a>
</p>

<p align="left">
  <a href="http://huseyint.com/wp-content/uploads/2007/09/san_dimas_prototype.jpg" title="Project San Dimas"></a>
</p>

<p style="text-align: center">
  <a href="http://huseyint.com/wp-content/uploads/2007/09/san_dimas_prototype.jpg" title="Project San Dimas"> </a>
</p>

<p>Adobe bu teknolojiyi yaymak için bir çok girişimde bulunuyor. Bunlarda en sonuncusu <a href="http://onair.adobe.com/">on AIR Bus Tour</a>. Düzenlediği bu otobüs turuyla Amerika’daki 18 şehri dolaşarak orada seminerler/workshoplar düzenliyor. Bu etkinliklere katılamayanlar için ise bunların video kayıtlarını <a href="http://onair.adobe.com/blogs/videos/category/on-air-tour/">sitesinde yayınlıyor</a>. Bu seminerleri veren Adobe AIR geliştiricileri ayrıca bloglarında konuyla ilgili yazılar ile teknolojinin nasıl kullanılacağı hakkında bilgiler veriyor. Bunlardan bazıları: <a href="http://blog.kevinhoyt.org/">Kevin Hoyt</a>, <a href="http://madowney.com/blog/">Mike Downey</a>, <a href="http://www.danieldura.com/">Daniel Dura</a>, <a href="http://www.mikechambers.com/blog/">Mike Chambers</a>. Ayrıca yeni bir oluşum olan <a href="http://www.airapps.net/" title="The AIR Applications Network">AIRApps.net</a> AIR uygulama geliştiricilerini bir araya topluyarak bir komünite oluşturmaya çalışıyor.</p>

<p>Eğer Adobe AIR ilginizi çektiyse <a href="http://labs.adobe.com/technologies/air/" title="Adobe Integrated Runtime (AIR)">sitesine</a> gidip daha ayrıntılı bilgili alabilir, konuyla ilgili SSS’yi <a href="http://labs.adobe.com/wiki/index.php/AIR:Developer_FAQ" title=" AIR:Developer FAQ">okuyabilir</a> (tüm sorularıma cevap buldum diyebilirim), “Adobe Integrated Runtime (AIR) for JavaScript Developers Pocket Guide” kitabının ücretsiz elektronik versiyonunu <a href="http://ajaxian.com/downloads/books/AdobeAIR_for_javascript_developers.pdf">indirebilirsiniz</a> (<acronym class="uttInitialism" title="Portable Document Format">PDF</acronym>, 4.23MB).</p>

<p>Son bir link olarak favori JavaScript kütüphanem <a href="http://extjs.com/">Ext JS</a> ile nasıl bir Adobe AIR uygulaması geliştirileceği ile ilgili <a href="http://extjs.com/blog/2007/06/29/building-a-desktop-application-with-ext-air-aptana-and-red-bull/" title="Building a desktop application with Ext, AIR, Aptana and Red Bull ">şu yazıya</a> göz atmanızı tavsiye ederim.</p>

]]></content>
  </entry>
  
</feed>
