<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CkMHQXY4fyp7ImA9WhRRFEk.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708</id><updated>2011-11-28T02:33:50.837+02:00</updated><category term="C#" /><category term="Personal" /><category term="Reflection" /><category term="Thougts" /><category term="Performance" /><category term="3D" /><category term="Backup" /><category term="Technology" /><category term="Linux" /><category term="Experiments" /><category term="Mozy" /><category term="Writing Quality Software" /><category term="Tutorial" /><category term="Ideas" /><category term="Blogger" /><category term="WPF" /><category term="Web" /><category term="Multitouch" /><title>Thoughts and Technology</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://itaibh.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>31</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/ThoughtsAndTechnology" /><feedburner:info uri="thoughtsandtechnology" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;A0YGQno_eCp7ImA9WhZUF0o.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-5745754419785765845</id><published>2011-06-11T10:18:00.011+03:00</published><updated>2011-06-11T10:58:43.440+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-11T10:58:43.440+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Web" /><category scheme="http://www.blogger.com/atom/ns#" term="Technology" /><category scheme="http://www.blogger.com/atom/ns#" term="Thougts" /><title>Web Development</title><content type="html">I recently started developing applications for the Chrome browser. This is as simple as developing any other web application, except I had no experience developing web application before.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;In this post I will share my impressions of web development and finally share my ideas of next generation web development.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
I had to learn JavaScript to a level that would allow me to write complex, object-oriented pieces of code. I didn't really bother with HTML5 and CSS3 - whenever I needed something I could easily find it somewhere on the web (mostly in &lt;a href="http://draft.blogger.com/www.w3schools.com"&gt;www.w3schools.com&lt;/a&gt;). But scripting is different. You can't just not remember the basics, so I had to learn it on the go.&lt;br /&gt;
&lt;br /&gt;
My impressions of JavaScript is that it is not as good as most compiled languages (like C, C++, C# and even Java). It is not type-safe, and it's object-oriented syntax is horrifying. In addition it lacks data structures like lists and hashtables (or dictionaries), so you need to use alternatives.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;By alternatives I don't mean creating your own data structures. You can achieve a mapping between a key to a value using an Object: add a member and give it the value. JSON is all about that... Except JSON comes to represent an object, not a list.&lt;br /&gt;
&lt;br /&gt;
And there is no such thing as a Class. There are only Functions. You want some function to behave as a class? Add sub-functions. You want to be able to override functions in an inherited "class"? Add prototype-level function.&lt;br /&gt;
&lt;br /&gt;
It's not that you can't get used to it. Well actually you can't, but still you write it automatically after a while. What I want to say is that there are so many options to write object oriented code even in scripted languages (see Ruby, for instance) that the way JavaScript is designed is simple horrible (especially with a name that suggests some relation to Java)&lt;br /&gt;
&lt;br /&gt;
Everybody's talking about web development as the next thing. All big software companies push HTML5, CSS3 and JavaScript, each company with its own unique reasons. Microsoft even said writing applets and gadgets to Windows 8 would be in JavaScript (they said that it is much lighter. I don't see how ANY script can be lighter than a compiled code).&lt;br /&gt;
&lt;br /&gt;
I understand the hype. I also starting to realize that web applications is the way to go for most of everyday's uses. But why JavaScript? or any other type-unsafe script for that matter? There are many applications written in Flash. While this is an improvement for the user who downloads compiled code, Flash was originally designed for web vector animation clips, so writing applications in it is really abusing it. Could be done much easier with, say, Silverlight (and C# is a much saner choice over ActionScript, which, AFAIK, is very similar to JavaScript).&lt;br /&gt;
&lt;br /&gt;
Why wouldn't new browsers support precompiled code that can access DOM elements? suppose I could write in C# some code that interacts with elements in a webpage, compile it to a DLL, and link to that DLL from an HTML file. Don't worry about security issues now, those can be taken care of in a variety of ways. Think of the result - faster download times, you don't get it as plain, readable text (I know most scripts are scrambled and their variables are shortened so it's not really readable, and I know you can easily decompile a .Net DLL into readable text), and the most important thing - the browser doesn't need to compile the script on the fly. It is ready to go!&lt;br /&gt;
&lt;br /&gt;
Thinking about it some more - there should be a way to compile an entire webpage. But for now perhaps the best way it to compact it (along with its resources) in a zip file (much like new document formats are doing today).&lt;br /&gt;
&lt;br /&gt;
To sum things up - from a developer point of view, moving to web applications is welcome, but browsers need to support nicer scripts, and perhaps even precompiled DLLs that can access DOM elements.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-5745754419785765845?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/2xucV2F86yhepzRaLhdVIEnXT7A/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2xucV2F86yhepzRaLhdVIEnXT7A/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/2xucV2F86yhepzRaLhdVIEnXT7A/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2xucV2F86yhepzRaLhdVIEnXT7A/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/-kTzqHK3SEw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/5745754419785765845/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2011/06/web-development.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/5745754419785765845?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/5745754419785765845?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/-kTzqHK3SEw/web-development.html" title="Web Development" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2011/06/web-development.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMDQ3syeSp7ImA9WhdTE0s.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-4884483363195400566</id><published>2011-06-10T09:00:00.163+03:00</published><updated>2011-07-11T08:34:32.591+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-11T08:34:32.591+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Linux" /><category scheme="http://www.blogger.com/atom/ns#" term="Thougts" /><title>Thinking of moving to Linux</title><content type="html">Well this thought has been around for a very long time now.&lt;br /&gt;
I started to learn to work with Linux a long while ago, in my first professional job. Then was also the time I got to know the world of open source software.&lt;br /&gt;
I've been following the development in the Linux world, and every now and then downloaded the latest ISO of some distributions for a test drive. In the end I never gave up Windows. I felt that Linux just could not give me all the tools I need for my everyday tasks.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-r_vdkHdgAUY/TfHmd1WE8xI/AAAAAAAABqA/lZmN5AbY-wA/s1600/xbmc.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-r_vdkHdgAUY/TfHmd1WE8xI/AAAAAAAABqA/lZmN5AbY-wA/s1600/xbmc.png" /&gt;&lt;/a&gt;&lt;/div&gt;When I started using a Media Center in the living room, I chose &lt;b&gt;&lt;a href="http://xbmc.org/"&gt;XBMC&lt;/a&gt;&amp;nbsp;&lt;/b&gt;over Ubuntu Linux. It did a pretty good job and was enough for what I needed.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-6kMTre7k_30/TfHmQwWCmhI/AAAAAAAABp8/0LcHNQFLJzs/s1600/ubuntu.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-6kMTre7k_30/TfHmQwWCmhI/AAAAAAAABp8/0LcHNQFLJzs/s1600/ubuntu.png" /&gt;&lt;/a&gt;&lt;/div&gt;The &lt;b&gt;&lt;a href="http://www.ubuntu.com/"&gt;Ubuntu&lt;/a&gt;&amp;nbsp;&lt;/b&gt;distribution was a good Linux choice for a long time, but only now, in version 11.04 it feels like there is nothing I want to do with it and can't.&lt;br /&gt;
&lt;br /&gt;
I always prefer open source software over closed source software and commercial software, with the exception of my Home Windows (Vista 64) which I bought with me PC almost 4 years ago, and Office 2007 Home and Student that I bought for my girlfriend while she was a student (in a great student discount).&lt;br /&gt;
Every now and then I review all of the installed programs I have and see which have a Linux version of a descent Linux alternative.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Currently, most of my program have a Linux version and the rest have Linux alternatives:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Image Manipulation:&lt;/li&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-b9_e3Zw9adQ/TfHmwZapiWI/AAAAAAAABqE/yE2xDtq24jA/s1600/gimp.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-b9_e3Zw9adQ/TfHmwZapiWI/AAAAAAAABqE/yE2xDtq24jA/s1600/gimp.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;&lt;a href="http://www.gimp.org/"&gt;Gimp &lt;/a&gt;&lt;/b&gt;- originally a native Linux program that was ported to Windows.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.getpaint.net/"&gt;&lt;b&gt;Paint.net&lt;/b&gt;&lt;/a&gt; - might run under &lt;b&gt;&lt;a href="http://www.mono-project.com/Main_Page"&gt;Mono&lt;/a&gt;&lt;/b&gt;, and if not there is &lt;b&gt;&lt;a href="http://pinta-project.com/"&gt;Pinta&lt;/a&gt;&lt;/b&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;Vector Editing:&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;&lt;a href="http://inkscape.org/"&gt;Inkscape&lt;/a&gt;&amp;nbsp;&lt;/b&gt;- originally a native Linux program that was ported to Windows.&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;Internet:&lt;/li&gt;
&lt;ul&gt;&lt;div style="float: right;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-lYQdi5VhzzE/ThoCIGY3-HI/AAAAAAAABsM/bMhCzlHo2cw/s1600/filezilla.png" /&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-p0e4ZHz6pKA/TfHlf5Ghx6I/AAAAAAAABp4/ee5j7MMhsN4/s1600/firefox.png" /&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-QElVw6U2zdU/TfHlfRzXeAI/AAAAAAAABp0/RV4S5pT_pTw/s1600/chrome.png" /&gt;&lt;/div&gt;&lt;li&gt;&lt;b&gt;&lt;a href="http://www.google.com/chrome/intl/en/make/download.html?brand=CHKZ&amp;amp;platform=linux"&gt;Chrome&lt;/a&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;a href="http://www.mozilla.com/en-US/firefox/new/"&gt;Firefox&lt;/a&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;a href="http://jdownloader.org/"&gt;JDownloader&lt;/a&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Plenty of Bittorernt clients&lt;/li&gt;
&lt;li&gt;FTP Client - &lt;a href="http://filezilla-project.org/"&gt;FileZilla&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;Programming:&lt;/li&gt;
&lt;ul&gt;&lt;a href="http://3.bp.blogspot.com/-kqEiK6h0I2o/TfHq31LMmgI/AAAAAAAABqs/Opd_UMz1ljM/s1600/monodevelop.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-kqEiK6h0I2o/TfHq31LMmgI/AAAAAAAABqs/Opd_UMz1ljM/s1600/monodevelop.png" /&gt;&lt;/a&gt;
&lt;li&gt;I'm developing mostly in C#, so &lt;b&gt;&lt;a href="http://monodevelop.com/"&gt;MonoDevelop&lt;/a&gt;&amp;nbsp;&lt;/b&gt;is my native choice. Used it quite a lot a long time ago. In my current job I'm using Visual Studio. While Mono and MonoDevelop lacks the features of WPF development, I don't think I'll be doing any WPF development at home. I'll try to focus on Internet related development.&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;Source Control:&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;&lt;a href="http://subversion.tigris.org/"&gt;Subversion&lt;/a&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;a href="http://git-scm.com/"&gt;GIT&lt;/a&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;Media Players:&lt;/li&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-qeol8VqnD1w/TfHpzyeVEXI/AAAAAAAABqk/xSh-a72Q4T0/s1600/banshee.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-qeol8VqnD1w/TfHpzyeVEXI/AAAAAAAABqk/xSh-a72Q4T0/s1600/banshee.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;&lt;a href="http://banshee.fm/"&gt;Banshee&lt;/a&gt;&amp;nbsp;&lt;/b&gt;- while there is a Windows version now, I never tried it. But it works fine on Linux.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;a href="http://projects.gnome.org/totem/"&gt;Totem&lt;/a&gt;&amp;nbsp;&lt;/b&gt;- another media player for Linux.&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;Text Editing:&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;I'm using notepad++ on Windows. There are plenty of alternatives on Linux. This is also my main development tool for Internet scripts (JS, HTML, PHP...)&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;Office Suites:&lt;/li&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-FnRw6-m9HfM/TfHqCdF4e-I/AAAAAAAABqo/tOZ26oLIcNo/s1600/libreoffice.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-FnRw6-m9HfM/TfHqCdF4e-I/AAAAAAAABqo/tOZ26oLIcNo/s1600/libreoffice.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;No real replacement for MS Office, but then again, I'm rarely using it. I'm using Google Docs to write most documents. If I really need an office suite, &lt;b&gt;&lt;a href="http://www.libreoffice.org/"&gt;Libre Office&lt;/a&gt;&lt;/b&gt; (a sane fork of Open Office) is available.&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;Video Editing: (I didn't edit video clips for a long while now, but want to make sure it is possible)&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;&lt;a href="http://www.kdenlive.org/"&gt;Kdenlive&lt;/a&gt;&amp;nbsp;&lt;/b&gt;- seems to have all the features one possibly wants.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;a href="http://cinelerra.org/"&gt;Cinelerra&lt;/a&gt;&amp;nbsp;&lt;/b&gt;- a more professional video editing software, in case Kdenlive won't suffice.&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;3D Modeling and Animation:&lt;/li&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-HBSSrSGCxpg/TfHokrZkXeI/AAAAAAAABqc/LUSkhri95BY/s1600/blender.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-HBSSrSGCxpg/TfHokrZkXeI/AAAAAAAABqc/LUSkhri95BY/s1600/blender.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;This is a sensitive issue. No free software that even compares to 3D Studio Max. I've started using Google Sketchup lately, but no Linux version for that either. There is &lt;b&gt;&lt;a href="http://www.blender.org/"&gt;Blender&lt;/a&gt;&lt;/b&gt;, which I've tried using several times, but it lacks the native, streaming UI that 3DSMax and Sketchup have (Although the latest version does present an improvement). There are some other alternatives but not as strong, and not as easy to use. I can always run Skethup with Wine, or start a new open source project that will mimic 3DSMax experience :-)&lt;/li&gt;
&lt;/ul&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-Lp9W-T17S60/TfHo23u2_lI/AAAAAAAABqg/3CSAHTica-g/s1600/sweethome3d.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-Lp9W-T17S60/TfHo23u2_lI/AAAAAAAABqg/3CSAHTica-g/s1600/sweethome3d.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;&lt;a href="http://www.sweethome3d.com/"&gt;Sweet Home 3D&lt;/a&gt;&lt;/b&gt; - I was using it to plan my&amp;nbsp;apartment. Written in Java it have a Linux version and also an online-in-browser version.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;a href="http://www.google.com/earth/"&gt;Google Earth&lt;/a&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;CAD&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;In the 3D CAD area there is almost nothing, as the market leaders AutoCAD and SolidWorks are for Windows only. Yet I was able to find &lt;a href="http://varicad.com/"&gt;VariCAD&lt;/a&gt;&amp;nbsp;that claims to have a Linux version and seems powerful. Never tried it, though, as the prices are quite high.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.linuxcad.com/"&gt;LinuxCAD&lt;/a&gt;&amp;nbsp;also promises to be AutoCAD compatible, but I just can't understand anything from their website and I actually had to search (using Ctrl+F) for the download link.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.opencascade.org/"&gt;Open CASCADE&lt;/a&gt; is a free, open source and cross platform CAD software that focuses on mathematical models, and allows you among other things to test the strength of structures.&lt;/li&gt;
&lt;li&gt;In the 2D CAD area there are several options, such as &lt;a href="http://www.ribbonsoft.com/qcad.html"&gt;QCAD&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;Audio Editing:&lt;/li&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-e3ARVYnLydE/TfHnEpGeYTI/AAAAAAAABqI/Y-423-EcjPc/s1600/audacity.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-e3ARVYnLydE/TfHnEpGeYTI/AAAAAAAABqI/Y-423-EcjPc/s1600/audacity.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;&lt;a href="http://audacity.sourceforge.net/"&gt;Audacity&lt;/a&gt;&amp;nbsp;&lt;/b&gt;- when ever I needed to record or edit audio this have been my natural choice.&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;Antivirus:&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;&lt;a href="http://free.avg.com/us-en/homepage"&gt;AVG&lt;/a&gt;&amp;nbsp;&lt;/b&gt;- it seems that they have a &lt;a href="http://free.avg.com/us-en/download.prd-alf.tpl-mcr8"&gt;Linux version&lt;/a&gt; too.&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;Backup:&lt;/li&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-xzwcTFNGjSA/TfHnVP_2MGI/AAAAAAAABqM/HFv5NdREeBg/s1600/crashplan.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-xzwcTFNGjSA/TfHnVP_2MGI/AAAAAAAABqM/HFv5NdREeBg/s1600/crashplan.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;I switch from &lt;b&gt;&lt;a href="http://mozy.com/"&gt;Mozy&lt;/a&gt;&amp;nbsp;&lt;/b&gt;to &lt;b&gt;&lt;a href="http://www.crashplan.com/"&gt;CrashPlan&lt;/a&gt;&amp;nbsp;&lt;/b&gt;due to Mozy's new pricing and service terms. Anyway, both have a Linux version.&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;Ability to Fallback:&lt;/li&gt;
&lt;ul&gt;&lt;a href="http://1.bp.blogspot.com/-ER6uzD5_Rxo/TfHoBNnzfQI/AAAAAAAABqU/vML1_vOiPq4/s1600/winehq.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-ER6uzD5_Rxo/TfHoBNnzfQI/AAAAAAAABqU/vML1_vOiPq4/s1600/winehq.png" /&gt;&lt;/a&gt;
&lt;li&gt;&lt;b&gt;&lt;a href="http://www.winehq.org/"&gt;Wine&lt;/a&gt;&amp;nbsp;&lt;/b&gt;- allows installing and running native Windows applications. Works quite well too, and with its graphics acceleration support (DirectX implemented over OpenGL, I believe) it can also run games.&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;a href="http://4.bp.blogspot.com/-Fe63hGGkydc/TfHnq2PraPI/AAAAAAAABqQ/PPyKMnPl15I/s1600/virtualbox.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-Fe63hGGkydc/TfHnq2PraPI/AAAAAAAABqQ/PPyKMnPl15I/s1600/virtualbox.png" /&gt;&lt;/a&gt;
&lt;li&gt;&lt;b&gt;&lt;a href="http://www.virtualbox.org/"&gt;VirtualBox&lt;/a&gt;&amp;nbsp;&lt;/b&gt;- currently I'm using VirtualBox on Windows to run Linux environments. This can also be done the other way...&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;a href="http://3.bp.blogspot.com/-XK9g_IPUmaA/TfHoOJfDYVI/AAAAAAAABqY/Bnv1-6Wrm0I/s1600/rdesktop.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-XK9g_IPUmaA/TfHoOJfDYVI/AAAAAAAABqY/Bnv1-6Wrm0I/s1600/rdesktop.png" /&gt;&lt;/a&gt;
&lt;li&gt;&lt;b&gt;&lt;a href="http://www.rdesktop.org/"&gt;RDesktop&lt;/a&gt;&amp;nbsp;&lt;/b&gt;- seems like the most used program that allows connecting to a Windows machine using the Remote Desktop feature from Linux. Good to know it is possible.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;a href="http://sourceforge.net/projects/gnome-rdp/"&gt;GnomeRDP&lt;/a&gt;&amp;nbsp;&lt;/b&gt;- another program that suppose to allow remote desktop connection to Windows. Could not find any screen shots that proves it, though.&lt;/li&gt;
&lt;/ul&gt;&lt;/ul&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;With such a long list, I think my switch is closer than ever :-)&lt;/div&gt;&lt;br /&gt;
&lt;script type="text/javascript"&gt;
slashdot_url="http://itaibh.blogspot.com/2011/06/thinking-of-moving-to-linux.html";
&lt;/script&gt;&lt;br /&gt;
&lt;script src="http://slashdot.org/slashdot-it.js" type="text/javascript"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-4884483363195400566?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/kmY8vqVikGWVumNGeQz6bqbE-zY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kmY8vqVikGWVumNGeQz6bqbE-zY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/kmY8vqVikGWVumNGeQz6bqbE-zY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kmY8vqVikGWVumNGeQz6bqbE-zY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/YQ9COEx0fZs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/4884483363195400566/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2011/06/thinking-of-moving-to-linux.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/4884483363195400566?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/4884483363195400566?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/YQ9COEx0fZs/thinking-of-moving-to-linux.html" title="Thinking of moving to Linux" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-r_vdkHdgAUY/TfHmd1WE8xI/AAAAAAAABqA/lZmN5AbY-wA/s72-c/xbmc.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2011/06/thinking-of-moving-to-linux.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEEBRHYzcSp7ImA9WhZUFE8.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-5655541152701918751</id><published>2011-06-06T08:30:00.003+03:00</published><updated>2011-06-07T07:57:35.889+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-07T07:57:35.889+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Mozy" /><category scheme="http://www.blogger.com/atom/ns#" term="Backup" /><title>Mozy’s underhanded opportunism</title><content type="html">I’m using Mozy as a backup service.&lt;br /&gt;&lt;br /&gt;To be more precise, I was using Mozy for a year before they raised their prices and downgraded their service. Except I’m still using it now even that I don’t want to.&lt;br /&gt;&lt;br /&gt;You see, Mozy has two renewal plans on their site once you paid. One – keep with the same plan you’ve paid for (or in my case – pay more and get less). Two – upgraded plan (still gives me less than what I originally signed) that gives you extra storage (I originally signed for unlimited. How it became limited is beyond me).&lt;br /&gt;&lt;br /&gt;Note that the is no “Three – no renewal”. There’s just no such thing. You don’t want to continue? That’s fine. You have the option to CANCEL your account (no refund,AFAIK).&lt;br /&gt;&lt;br /&gt;What happened the other day was that I got this email:&lt;br /&gt;&lt;blockquote&gt;Thanks for using MozyHome!&lt;br /&gt;&lt;br /&gt;Your credit card ending in **** was charged $65.89 today for a yearly subscription to MozyHome 50 GB.&lt;br /&gt;Your card will be automatically charged again on July 04, 2012 in order to keep your MozyHome 50 GB subscription current.&lt;br /&gt;&lt;br /&gt;Please visit your account page at&amp;nbsp;&lt;a avglsprocessed="1" href="https://mozy.com/login" target="_blank"&gt;https://mozy.com/login&lt;/a&gt;&amp;nbsp;to make changes to your MozyHome 50 GB subscription.&lt;br /&gt;&lt;br /&gt;Thank you!&lt;br /&gt;&lt;br /&gt;- The MozyHome Team&lt;/blockquote&gt;&lt;br /&gt;You see, not only they never notified me that my subscription is about to end, and never gave me the option not to renew it, they simply took my money without my permission.&lt;br /&gt;&lt;br /&gt;When I opened a support call regarding that issue, this was the response:&lt;br /&gt;&lt;blockquote&gt;When you signed up for service, the plan requires an auto renewal for the plan. ! After you sign up, we will automatically re-bill your credit card every year in order to keep your subscription current, unless you cancel.&lt;br /&gt;&lt;br /&gt;The only way to un-enroll is to cancel the account. If you wish to cancel your account I have provided step by step instructions to cancel [...clipped...]&lt;/blockquote&gt;&lt;br /&gt;Please do yourself a&amp;nbsp;favor&amp;nbsp;and keep away from Mozy as you would from fire. I was burnt already.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-5655541152701918751?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/rMjITuOiVWhlOXdQw7aRvjeshRM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rMjITuOiVWhlOXdQw7aRvjeshRM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/rMjITuOiVWhlOXdQw7aRvjeshRM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rMjITuOiVWhlOXdQw7aRvjeshRM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/_oMjeYJkl_4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/5655541152701918751/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2011/06/mozys-underhanded-opportunism.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/5655541152701918751?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/5655541152701918751?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/_oMjeYJkl_4/mozys-underhanded-opportunism.html" title="Mozy’s underhanded opportunism" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2011/06/mozys-underhanded-opportunism.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUENRX86eip7ImA9WhZUF0w.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-6714377085153536952</id><published>2011-02-01T21:45:00.005+02:00</published><updated>2011-06-10T16:48:14.112+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-10T16:48:14.112+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Performance" /><title>Performance – My biggest success so far</title><content type="html">&lt;p&gt;In my &lt;a href="http://itaibh.blogspot.com/2011/02/performance-using-net-and-com.html"&gt;last post&lt;/a&gt; I shared the story of improving performance while using .Net and COM.&lt;/p&gt;&lt;p&gt;While improving from a few minutes to a few seconds seems like a great success (if counting such great times ratios*), I haven’t yet beat myself.&lt;br /&gt;
The greatest time I’ve improved was from several &lt;strong&gt;hours&lt;/strong&gt; to a few seconds.&lt;/p&gt;&lt;h2&gt;Background&lt;/h2&gt;&lt;p&gt;In my first workplace there was a C4I application that showed a vector map. No standards where used as it was first develop 15 years ago, before any standards have evolved. In order for the map to run efficiently, its data was split into tiles. First the tiles in view were presented, and then, in background, the other tiles were loaded.&lt;/p&gt;&lt;p&gt;I want to talk about the tool that cut the one big map into tiles.&lt;br /&gt;
That tool was given a map, number of tiles along and across, output folder and several hours to run.&lt;/p&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;The Problem&lt;/h2&gt;&lt;p&gt;It was only used when the map was replaced, which was very rare, so no one took the time to improve it. However, this had changed, and I hated waiting those hours.&lt;br /&gt;
I looked at the code and found it was going in a simple XY loop over the map, slicing a tile at a time, saving it to a file. For every dead tile with nothing in it, it had to go over all the vector data in the map and testing it against the four walls of the tile.&lt;/p&gt;&lt;h2&gt;The Solution&lt;/h2&gt;&lt;p&gt;I decided to replace that mechanism with a smarter one. I figured that instead of running over all the data for every tile, I would slice the data recursively, leaving less and less work for next rounds until we get to a single tile size, and then store this tile to disk.&lt;/p&gt;&lt;p&gt;What do you know – it worked! &lt;img alt="Smile" class="wlEmoticon wlEmoticon-smile" src="http://lh4.ggpht.com/_skWDg2sd0Zc/TUhi8KWnYDI/AAAAAAAABmg/tJL9b7e1k0I/wlEmoticon-smile%5B2%5D.png?imgmax=800" style="border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;" /&gt; Only a few seconds after years of waiting for hours, leaving the tool running during launch or at night, hoping no mistake was made, and that no power loss will destroy the chance for result.&lt;/p&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;p&gt;This story shows that sometimes a replacement of the wrapping algorithm (in this case – from a simple XY loop to a bit more complicated recursion) is enough to gain major results.&lt;/p&gt;&lt;h3&gt;*endnote&lt;/h3&gt;&lt;p&gt;Optimizing code should be about reducing a method runtime from milliseconds to microseconds. Not from hours and minutes to seconds. If something takes that long, obviously something is very wrong with it that must be taken care of right away. Acceptable initial runtimes is the basis for real optimization.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-6714377085153536952?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/nC54pQf1Wxv6S7RJW2pXDzyd21U/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nC54pQf1Wxv6S7RJW2pXDzyd21U/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/nC54pQf1Wxv6S7RJW2pXDzyd21U/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nC54pQf1Wxv6S7RJW2pXDzyd21U/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/Rvx9qQfS2nM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/6714377085153536952/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2011/02/performance-my-biggest-success-so-far.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/6714377085153536952?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/6714377085153536952?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/Rvx9qQfS2nM/performance-my-biggest-success-so-far.html" title="Performance – My biggest success so far" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_skWDg2sd0Zc/TUhi8KWnYDI/AAAAAAAABmg/tJL9b7e1k0I/s72-c/wlEmoticon-smile%5B2%5D.png?imgmax=800" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2011/02/performance-my-biggest-success-so-far.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUAHQXw6eyp7ImA9WhZUF0w.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-3861116962831539326</id><published>2011-02-01T21:10:00.003+02:00</published><updated>2011-06-10T16:48:50.213+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-10T16:48:50.213+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="Performance" /><title>Performance - Using .Net and COM</title><content type="html">&lt;p&gt;Yesterday I was given a task to help improve the performance of a feature. I was told that the feature was written in a very straight forward way, nearly no optimizations taken. The problem was that it took several minutes (yes, minutes) to run, rather than a few seconds or better than that.&lt;/p&gt;&lt;p&gt;The story is quite long, so if you have time and patience read its whole. If not or you are just too lazy, skip to the summary at the end &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://lh6.ggpht.com/_skWDg2sd0Zc/TUhauPfpQgI/AAAAAAAABmc/7zCJ2juunLQ/wlEmoticon-smile%5B2%5D.png?imgmax=800" /&gt;&lt;/p&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;Identifying The Problem&lt;/h2&gt;&lt;p&gt;The code computed visible area from a given geographic point and &lt;a href="http://en.wikipedia.org/wiki/Digital_terrain_model"&gt;DTM&lt;/a&gt;. The &lt;a href="http://en.wikipedia.org/wiki/GIS"&gt;GIS&lt;/a&gt; package used was the one of &lt;a href="http://www.esri.com"&gt;ESRI&lt;/a&gt;. While ESRI tools must have that feature hidden somewhere, for several reasons, including performance, it was not used. However, the result - performance wise – was no better.&lt;/p&gt;&lt;p&gt;Using &lt;a href="http://technet.microsoft.com/en-us/sysinternals/default.aspx"&gt;Sysinternals Suite&lt;/a&gt; &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb896653"&gt;ProcExp&lt;/a&gt; I wanted to see just how much CPU the process is using. I saw that the process was using a total of about 70%. That’s a lot, but the interesting part was that about half of it was actually &lt;strong&gt;Kernel Time&lt;/strong&gt;. This usually means a lot of IO.&lt;/p&gt;&lt;p&gt;So I launched &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb896645"&gt;ProcMon&lt;/a&gt; to see what happens during the progress. It seemed that for every height sample of the DTM in a given coordinate, the ESRI package accessed the actual DTM file (DTM GeoTiff in that case). &lt;/p&gt;&lt;h2&gt;Solving The Problem – Phase 1&lt;/h2&gt;&lt;p&gt;I looked deep into the ESRI API to figure out how to prevent that from happening. Since I couldn’t find any descent way of getting ESRI to do it for me, I just used another ESRI API that reads all the data to the memory. While this requires me to build a big memory manager (I didn’t, by the way, just loaded everything to memory. The files are currently small enough to fit. But I’ll get to it…) it is better than accessing the disk for every request.&lt;/p&gt;&lt;p&gt;Joyful and happy that I’ve eliminated the constant file access, I ran the program again. A very minor improvement was shown, and still - too much kernel time.&lt;/p&gt;&lt;h2&gt;Solving The Problem – Phase 2&lt;/h2&gt;&lt;p&gt;Taking another look on ProcMon, showed a lot of registry access. By asking around (well, asking my supervisor…) I was told that this is due to COM object access. “Strange”, I thought, “I thought I got rid of all COM objects access…”&lt;/p&gt;&lt;p&gt;So the next step was to really get rid of all COM object access during that process. I tracked down several points that it was easy – the value never changes, so just put it in a primitive type member and we’re done. The hard part was to replace the calls to methods that computed something. However, those computations weren’t so hard to do after all. The converted map coordinates to pixel location value in the DTM. Using some linear algebra at its lowest level gave me a satisfying result. Now the program takes seconds instead of minutes.&lt;/p&gt;&lt;h2&gt;To sum things up:&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;If using COM objects, try to minimize or even eliminate calls to them when doing something that requires performance, especially if in a tight loop. &lt;/li&gt;
&lt;li&gt;Don’t be afraid to “re-invent the wheel” if your current package is too slow. Either find a faster package, or write simple tasks yourself. &lt;/li&gt;
&lt;li&gt;After doing this, make sure the results are satisfactory. Not only performance wise, but also in value. You don’t want to screw things up just to gain more speed. &lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;And in a more general note – improving performance (also true for efficiency) is all about getting the same effect with less work. In this case (and most of the other cases you would bump into), this can be done by a couple of simple replacements of one CPU killer method with another one, less costly. Only rarely the entire algorithm would need to be replaced. Knowing the common pitfalls (or hogs) is a good place to start. &lt;/p&gt;&lt;p&gt;Happy optimizing! &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://lh6.ggpht.com/_skWDg2sd0Zc/TUhauPfpQgI/AAAAAAAABmc/7zCJ2juunLQ/wlEmoticon-smile%5B2%5D.png?imgmax=800" /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-3861116962831539326?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/jXoHk5PokBjKaKE9yYW3ayiVMOQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/jXoHk5PokBjKaKE9yYW3ayiVMOQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/jXoHk5PokBjKaKE9yYW3ayiVMOQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/jXoHk5PokBjKaKE9yYW3ayiVMOQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/Ufe4ASanfag" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/3861116962831539326/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2011/02/performance-using-net-and-com.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/3861116962831539326?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/3861116962831539326?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/Ufe4ASanfag/performance-using-net-and-com.html" title="Performance - Using .Net and COM" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_skWDg2sd0Zc/TUhauPfpQgI/AAAAAAAABmc/7zCJ2juunLQ/s72-c/wlEmoticon-smile%5B2%5D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2011/02/performance-using-net-and-com.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUANRX8yfyp7ImA9WxBUF04.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-6406709344131627352</id><published>2010-03-04T23:22:00.001+02:00</published><updated>2010-03-04T23:23:14.197+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-04T23:23:14.197+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Thougts" /><title>Year 2048</title><content type="html">&lt;p&gt;In just less than 38 years from now, year 2048. I’ll be 65 years old. The world will be filled with slogans like “The real Y2K” spread by techies.&lt;/p&gt;  &lt;p&gt;This wasn’t possible on Y1K. Actually, it only became possible in the last several decades. A century, if considering some really old inventions.&lt;/p&gt;  &lt;p&gt;I said “the world will be filled with slogans”, because I’m not sure that saying “the internet will be filled with slogans” will be correct. The internet had evolved a lot in the last decade. From slow dial-up (yes, it was like that in late 90’s and early 2000) to 100mib constant connection, from home PCs to our cellular phones and PDAs. From simple websites with slowly loading GIFs, line by line, to advanced, interactive sites, filled with animation and streaming video.&lt;/p&gt;  &lt;p&gt;This all made me think what it would all look like in 38 years. I sometimes feel that when looking ahead in the short term, to the next year or two, it is very hard to think that great revolutions might occur. Thinking of bureaucracy of different authorities, things always seem to get delayed. But in the long term, things does happen very fast indeed. Dazzling fast.&lt;/p&gt;  &lt;p&gt;I know there are people working on shaping the next generation of the internet. I just wonder how far we can really imagine in such an exponential world.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-6406709344131627352?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/cgpUYmhGIcvBjK7LkBsqlqMS1Yc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cgpUYmhGIcvBjK7LkBsqlqMS1Yc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/cgpUYmhGIcvBjK7LkBsqlqMS1Yc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cgpUYmhGIcvBjK7LkBsqlqMS1Yc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/SJutzLePbJM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/6406709344131627352/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2010/03/year-2048.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/6406709344131627352?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/6406709344131627352?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/SJutzLePbJM/year-2048.html" title="Year 2048" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2010/03/year-2048.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk8GRHs7fyp7ImA9Wx9bFkk.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-4097921219918795383</id><published>2009-12-17T01:24:00.005+02:00</published><updated>2011-02-25T16:40:25.507+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-25T16:40:25.507+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="3D" /><category scheme="http://www.blogger.com/atom/ns#" term="WPF" /><category scheme="http://www.blogger.com/atom/ns#" term="Technology" /><title>XAML exporter for Sketchup - Round 2</title><content type="html">I just finished fixing some issues with the Google Sketchup Xaml Exporter.&lt;br /&gt;
The updated file can be downloaded here:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: #0000ee;"&gt;&lt;u&gt;&lt;a href="https://docs.google.com/leaf?id=0BxinGAr39Pd0ODQ2Y2IyZDUtZWNkYi00YTU2LTk3MmMtNDg4NmMzZDhlZjVh&amp;amp;hl=en"&gt;https://docs.google.com/leaf?id=0BxinGAr39Pd0ODQ2Y2IyZDUtZWNkYi00YTU2LTk3MmMtNDg4NmMzZDhlZjVh&amp;amp;hl=en&lt;/a&gt;&lt;/u&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #551a8b;"&gt;&lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;The new version fixes:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Different materials with the same base texture filename caused only one texture file to be created, thus wrong texture to appear.&lt;/li&gt;
&lt;li&gt;Group transformations were ignored.&lt;/li&gt;
&lt;li&gt;Back facing materials now supported.&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Enjoy!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;UPDATE&lt;/b&gt;:&lt;br /&gt;
I re-uploaded the file, this time under a bit different name. It seems that Vista shows me one version of the file, and even loads it correctly, while it shows a totally different file to the world.&lt;br /&gt;
I was told that the file I uploaded is not the correct file, and when checking locally, I saw that the size is really different. Strange, even rebooting didn't help. Oh well, saving as (and even copying!) to another local folder solved it, but I still don't understand why it happened.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-4097921219918795383?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/5qxc1xsZXuQ80BP3HbkkjqQGwpw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5qxc1xsZXuQ80BP3HbkkjqQGwpw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/5qxc1xsZXuQ80BP3HbkkjqQGwpw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5qxc1xsZXuQ80BP3HbkkjqQGwpw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/g3LNSymiGO8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/4097921219918795383/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2009/12/xaml-exporter-for-sketchup-round-2.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/4097921219918795383?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/4097921219918795383?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/g3LNSymiGO8/xaml-exporter-for-sketchup-round-2.html" title="XAML exporter for Sketchup - Round 2" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2009/12/xaml-exporter-for-sketchup-round-2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEAHSH0-fyp7ImA9WxBQEkU.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-336785735685903787</id><published>2009-09-27T16:07:00.006+02:00</published><updated>2010-01-12T10:58:59.357+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-12T10:58:59.357+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="3D" /><category scheme="http://www.blogger.com/atom/ns#" term="WPF" /><title>Google SketchUp Xaml exporter</title><content type="html">I wanted to build a WPF 3D application, that will present models. I didn't want to include code that loads different formats and creates WPF models at runtime, and I wanted an easy-to-use, free modeler.&lt;br /&gt;&lt;a href="http://www.blender.org/"&gt;Blender&lt;/a&gt; is free, but I find it very cumbersome. &lt;a href="http://sketchup.google.com/"&gt;Google SketchUp&lt;/a&gt; is very easy to use, but was lacking a way to export to XAML.&lt;br /&gt;Fortunately, SketchUp has a very easy-to-use &lt;a href="http://www.ruby-lang.org/en/"&gt;Ruby&lt;/a&gt; &lt;a href="http://code.google.com/apis/sketchup/"&gt;API&lt;/a&gt; that I could use to build an exporter.&lt;br /&gt;It currently exports the meshes separated by materials, and grouped together in geometry groups according to the same hierarchy structure of the model. Materials include front faces only (i.e. no BackMaterials) and support solid color and textures. If no material is given, a solid white material is used.&lt;br /&gt;While it's not perfect, it does a pretty good job. Feel free to use and please send feedback,&lt;br /&gt;&lt;a href="http://cid-8fbcae0caa96d592.skydrive.live.com/self.aspx/.Public/xamlExporter.rb"&gt;http://cid-8fbcae0caa96d592.skydrive.live.com/self.aspx/.Public/xamlExporter.rb&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;UPDATE:&lt;/b&gt;&lt;br /&gt;I updated the plugin. Check out the follow-up post: &lt;a href="http://itaibh.blogspot.com/2009/12/xaml-exporter-for-sketchup-round-2.html"&gt;XAML exporter for Sketchup - Round 2&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-336785735685903787?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/dl0LB7dibr_QIyBGzFPu6O1DKD8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dl0LB7dibr_QIyBGzFPu6O1DKD8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/dl0LB7dibr_QIyBGzFPu6O1DKD8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dl0LB7dibr_QIyBGzFPu6O1DKD8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/xMjBYvyzjKs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/336785735685903787/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2009/09/google-sketchup-xaml-exporter.html#comment-form" title="10 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/336785735685903787?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/336785735685903787?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/xMjBYvyzjKs/google-sketchup-xaml-exporter.html" title="Google SketchUp Xaml exporter" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><thr:total>10</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2009/09/google-sketchup-xaml-exporter.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0MHR30yeSp7ImA9WhZUF0w.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-7433432965552650576</id><published>2009-08-07T12:19:00.006+03:00</published><updated>2011-06-10T16:10:36.391+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-10T16:10:36.391+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="Writing Quality Software" /><title>Writing Quality Software - Code</title><content type="html">Coding is bringing the architecture and design to life. Making the idea work. Correct coding is more than just writing code that runs and do what it supposed to do. Correct coding is about making sure the architectural principles are applied, the code is readable and maintainable, self explanatory and self debuggable. Keep in mind that code is meant to be read much more than it is meant to be written.&lt;br /&gt;&lt;h2&gt;Debuggable Code&lt;/h2&gt;What exactly is “debuggable code”? Well, I would say a debuggable code is a code that helps you find where the errors are as you run into them. This can be done by:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Emitting enough logs where applicable. &lt;/li&gt;&lt;li&gt;Not “swallowing” exceptions. &lt;/li&gt;&lt;li&gt;Placing a method result in a local variable and returning it, rather than return a computation. &lt;/li&gt;&lt;li&gt;Preferring a full if/else when needed for populating a variable over the shorter form of x?a:b. &lt;/li&gt;&lt;li&gt;Breaking lines between different statements, such as      &lt;br /&gt;&lt;code&gt;if (something) return;&lt;/code&gt;       &lt;br /&gt;which is not debuggable, since you can’t place a breakpoint on the ‘return’. &lt;/li&gt;&lt;/ul&gt;Generally, if you try to debug a section in your code and think it is too hard to debug because the debugger is not enough feature rich, think again how you can change your code to fit the debugger limitations.&lt;br /&gt;&lt;h2&gt;Correct Casting&lt;/h2&gt;&lt;a href="http://themonkeysgrinder.blogspot.com/"&gt;Scott Peterson&lt;/a&gt; posted &lt;a href="http://themonkeysgrinder.blogspot.com/2009/07/casting-call.html"&gt;this post&lt;/a&gt; about casting best practices. There are several things I would like to add upon.&lt;br /&gt;First, when you expect a specific object type, prefer static cast, even in the case of a publicly visible method. The reason is that you would like the CLR to check the type for you and throw the relevant exception. Why? The alternative is you doing it yourself and responding correctly. Most people would simply “swallow” that error, which will yield bizarre errors elsewhere (most common ones are a null reference exception much deeper in the code, and it would be a very tedious work figuring out what went wrong).&lt;br /&gt;&lt;h2&gt;Readable Code&lt;/h2&gt;For each project, select a standard and stick with it. Keep in mind that in some cases you might need to read the code you’ve written outside the IDE. This means you won’t have all the cool features like tooltips specifying a member type, go to member, find member references, etc. You want to write code that will be easier to understand without jumping up and down the file.&lt;br /&gt;While it sounds like the &lt;a href="http://en.wikipedia.org/wiki/Hungarian_notation"&gt;Hungarian Notation&lt;/a&gt; might sound like a good idea (you can know the type and scope just by looking at the member name), it is a very unreadable notation. I like the naming that adds “m_” and “s_” prefixes to class members and static members respectively, but I hate the addition of “p_” prefix to parameters as I’ve seen in several places. So basically, it is all about readability. Whatever you choose, make sure it is easy to read outside an IDE (using notepad is a good test case), and stick with it.&lt;br /&gt;Another aspect of readable code relates to indentation. Indentation is not an option, my friends. It’s a must, and its better be done right. Select your favorite method of indentation (most common methods include 4 characters wide, 8 characters wide and “smart”), and make sure all indentations are using the same method (spaces or tabs). I personally believe that spaces are the best way to go (along with &lt;a href="http://en.wikipedia.org/wiki/Monospaced_font"&gt;monospaced font&lt;/a&gt;), since the overall code “design” is kept in all editors. &lt;a href="http://blogs.microsoft.co.il/blogs/liran_chen/"&gt;Liran Chen&lt;/a&gt; has a &lt;a href="http://beta.blogs.microsoft.co.il/blogs/liran_chen/archive/2009/08/01/wonders-with-visible-white-space.aspx"&gt;post&lt;/a&gt; about an indentation issue in Visual Studio (in Hebrew).&lt;br /&gt;&lt;h2&gt;Spelling&lt;/h2&gt;Don’t underestimate correct spelling. And prefer English in your code and comments over any other language. This will be used as a standard that will ease the process of joining new developers to the project. Minimize the use abbreviations and slang. It doesn’t come out nice, and tend to look unprofessional. &lt;br /&gt;&lt;br /&gt;These are my two cents of how to write better code, and there’s much more to write on that subject. Maybe in one of my next posts.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fitaibh.blogspot.com%2f2009%2f07%2fwriting-quality-software-code.html"&gt;&lt;img alt="kick it on DotNetKicks.com" border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fitaibh.blogspot.com%2f2009%2f07%2fwriting-quality-software-code.html" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;Update&lt;/h1&gt;&lt;br /&gt;Just found this post regarding programming:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://sites.google.com/site/yacoset/Home/signs-that-you-re-a-bad-programmer"&gt;http://sites.google.com/site/yacoset/Home/signs-that-you-re-a-bad-programmer&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I find it true, helpful and funny.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-7433432965552650576?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/NEEW3KUqQyHPpbbuQR8E_0PgXoo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NEEW3KUqQyHPpbbuQR8E_0PgXoo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/NEEW3KUqQyHPpbbuQR8E_0PgXoo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NEEW3KUqQyHPpbbuQR8E_0PgXoo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/FBAMtzH881s" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/7433432965552650576/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2009/07/writing-quality-software-code.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/7433432965552650576?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/7433432965552650576?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/FBAMtzH881s/writing-quality-software-code.html" title="Writing Quality Software - Code" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2009/07/writing-quality-software-code.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMCRXwzfSp7ImA9WxJaFEU.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-8582152077467453808</id><published>2009-08-05T19:07:00.001+03:00</published><updated>2009-08-05T19:07:44.285+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-05T19:07:44.285+03:00</app:edited><title>Installation Cancelled</title><content type="html">&lt;p&gt;&lt;a href="http://lh3.ggpht.com/_skWDg2sd0Zc/SnmuRBflxsI/AAAAAAAABgg/ZHdilT0wk5k/s1600-h/installation%20canceled%5B6%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="installation canceled" border="0" alt="installation canceled" src="http://lh6.ggpht.com/_skWDg2sd0Zc/SnmuTVyPXaI/AAAAAAAABgk/8TY0Gs-g9yY/installation%20canceled_thumb%5B4%5D.png?imgmax=800" width="396" height="306" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;The image speaks for itself.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-8582152077467453808?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/a6pTcdcT_LbVxxTeCkz9KzINInY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/a6pTcdcT_LbVxxTeCkz9KzINInY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/a6pTcdcT_LbVxxTeCkz9KzINInY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/a6pTcdcT_LbVxxTeCkz9KzINInY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/eCJwFspOWqU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/8582152077467453808/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2009/08/installation-cancelled.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/8582152077467453808?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/8582152077467453808?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/eCJwFspOWqU/installation-cancelled.html" title="Installation Cancelled" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_skWDg2sd0Zc/SnmuTVyPXaI/AAAAAAAABgk/8TY0Gs-g9yY/s72-c/installation%20canceled_thumb%5B4%5D.png?imgmax=800" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2009/08/installation-cancelled.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C04BSH87eyp7ImA9WhZUF0w.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-8399885371833709949</id><published>2009-07-26T23:09:00.006+03:00</published><updated>2011-06-10T16:19:19.103+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-10T16:19:19.103+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Writing Quality Software" /><category scheme="http://www.blogger.com/atom/ns#" term="Thougts" /><title>Writing Quality Software – Quality Assurance</title><content type="html">&lt;p&gt;One must not underestimate the necessity of the QA team.&lt;/p&gt;&lt;p&gt;Quality Assurance (QA), the guys that test the software designed by the engineers and written by the developers. Their mission is to make sure that the software does what it needs to do, and do it well. They are also the first users of the software so they have the best review and criticism about the visual design and usability.&lt;/p&gt;&lt;p&gt;A developer needs to learn to listen to the QA team notes. The QA team, on the other hand, must learn how to note.&lt;/p&gt;&lt;p&gt;In order to really understand this, lets check things more thoroughly:&lt;br /&gt;
First of all, the role of the QA team versus the role of the development team in terms of &lt;strong&gt;software operability&lt;/strong&gt;:&lt;/p&gt;&lt;p&gt;No QA team – Bad software; No development team – No software.&lt;/p&gt;&lt;p&gt;That said, we now need understand that the two teams must &lt;strong&gt;work together&lt;/strong&gt; in order to create &lt;strong&gt;good software&lt;/strong&gt;.&lt;/p&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;p&gt;Alas, those two teams are meant to work as rivals, as the QA must constantly critic the products of the developers, in order to find flaws, and the developers must fix the flaws and prevent new flaws from being introduced.&lt;/p&gt;&lt;p&gt;This is a real fight between the two teams, and not once you hear both sides places the blame on the other doing a bad job, wasting everybody’s else time, etc. While this is not true, this is often the feeling, especially if the organization isn’t done right.&lt;/p&gt;&lt;p?So, how can the two teams work together?&lt;/p&gt;&lt;p&gt;First, developers tend to fix problems presented to them when these are clear enough, and reject or ignore them when these are unclear. Also, a repeated claim, especially if not clear enough, rejects the average developer even more.   &lt;br /&gt;
This is why a tester must learn how to file a bug report. This is the key to good tester-developer relationship.&lt;/p&gt;&lt;p?A bug report must contain a very clear, short as possible list of steps that reproduce a bug. &lt;strong&gt;THE BUG MUST BE REPRODUCABLE UNDER ANY TERMS.&lt;/strong&gt; This means that a bug that could not be reproduced, actually does not exist.&lt;/p&gt;&lt;p&gt;Reproducing a bug is an art by itself. Finding the minimal set of operations that yields a bug to reveal. You think you had found it? Think again. Try to do things differently, see if it still happens. Omit steps. If you can’t make an educated guess, make some uneducated guesses. After that – call a developer who might know how things work on the inside, and direct you to a more simple way to reproduce it.&lt;/p&gt;&lt;p?Now, dear QA guys, please understand – The only people who have anything to do with your bug reports are us, the developers. Not your team leader, not your boss, not even the client. Only the developers. And it is very very frustrating for us not to understand what you have written, because, you see, we really do want to make the software we had written better. It is our reputation on the line.&lt;/p&gt;&lt;p&gt;Since developers are the only people who have anything to do with bug reports (the most important product of the QA team), I believe (and some would not agree, for some unclear reason) that the QA team should be placed next to the development team, under the development manager.&lt;/p&gt;&lt;p&gt;Yes, that’s right. There is no reason for a QA team to stand by itself, as the developers are those who need to use the QA products in order to fix their software. The managers can’t fix it. The client can’t fix it. Only the developers can fix it.&lt;/p&gt;&lt;p&gt;According to the size of the organization and the nature of the project, the QA-DEV relationship nature should be defined. Small company, with small development team and small QA team – consult each other a lot by speaking to each other. Don’t go and file bug reports just like that, and don’t go and write the same pieces of code after given a bad critic. Consult. For bigger companies – bug reports are the only way to go, but make sure everything is written correctly, everything can be understood by the relevant developer (or by anyone, for that matter), everything reproduces. Write the relevant version number in the bug report. Don’t attach error logs – these should be reproduced next time that bug occurs anyhow, so instead, make sure all the steps are clear, and that there are no redundant steps.&lt;/p&gt;&lt;p&gt;This is my two cents philosophy of quality assurance. Please try to put it to good use.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-8399885371833709949?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/qUdeLvK46I5c2d0ice8pgFyvrGY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/qUdeLvK46I5c2d0ice8pgFyvrGY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/qUdeLvK46I5c2d0ice8pgFyvrGY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/qUdeLvK46I5c2d0ice8pgFyvrGY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/SGppERQdpyQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/8399885371833709949/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2009/07/writing-quality-software-quality.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/8399885371833709949?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/8399885371833709949?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/SGppERQdpyQ/writing-quality-software-quality.html" title="Writing Quality Software – Quality Assurance" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2009/07/writing-quality-software-quality.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEYEQngzfyp7ImA9WhZUF0w.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-196178566385238407</id><published>2009-07-10T16:24:00.007+03:00</published><updated>2011-06-10T16:21:43.687+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-10T16:21:43.687+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Writing Quality Software" /><title>Writing Quality Software - Architecture</title><content type="html">&lt;p&gt;Designing the architecture of software is very important phase is the software lifecycle.&lt;/p&gt;&lt;h2&gt;Rules of thumb:&lt;/h2&gt;&lt;p&gt;A good piece of software would follow several rules of thumb:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Reusability&lt;/strong&gt; – The piece of software should be as reusable as possible (unless it is applicative), and reuse other components as much as possible.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Extensibility&lt;/strong&gt; – The piece of software should be as extensible as possible – i.e. have enough places which other developers (or the original developer in a later time) can use to add more functionality.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Functionality&lt;/strong&gt; – The piece of software should make the life of its user easier. The &lt;a href="http://en.wikipedia.org/wiki/Pareto_principle"&gt;80-20 rule&lt;/a&gt; would fit here (at least 80% of the time…)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Order &lt;/strong&gt;– The piece of software should be organized for easy finding of each piece of code, and easy thinking of a good place for a new piece of code.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Traceability&lt;/strong&gt; – The piece of software should log its actions in details, preferably in different levels of detail. Usage of extensible logging libraries (such as &lt;a href="http://logging.apache.org/log4net/index.html"&gt;log4net&lt;/a&gt;) are welcome.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Security&lt;/strong&gt; – The piece of software should not reveal security leaks, that would allow malicious code to abuse (I am talking about things like code injection, unauthorized privileges modification, system denial of service, etc.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Portability &lt;/strong&gt;– The piece of software should be as portable as possible. Not necessarily between operating systems, but generally between computers. Zero installation (aka -&lt;a href="http://en.wikipedia.org/wiki/XCOPY_deployment"&gt;xcopy deployment&lt;/a&gt;) is always welcome.&lt;/li&gt;
&lt;/ul&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;Reusability&lt;/h2&gt;&lt;p&gt;When writing software, the reusability factor is crucial, especially when you have deadlines. Splitting your code into several well-defined libraries, that each can be used in other projects, would usually yield lower cost factor in terms of time,effort and money when several projects are involved.&lt;/p&gt;&lt;p&gt;If you only have one project, you would still want to reuse. You should still split reusable code to a library of its own (or at least isolate it, so it could be split into a library at a later time). You might also would like to look for libraries that are already out there.&lt;/p&gt;&lt;h2&gt;When not to reuse&lt;/h2&gt;&lt;p&gt;One case where reuse is not welcome is a very specific case of the &lt;a href="http://en.wikipedia.org/wiki/Not_Invented_Here"&gt;NIH - “Not Invented Here” syndrome&lt;/a&gt;. This is the case where the potentially reusable code &lt;em&gt;&lt;strong&gt;from an external source&lt;/strong&gt;&lt;/em&gt; does what your business is all about. &lt;a href="http://www.joelonsoftware.com/"&gt;Joel Spolsky&lt;/a&gt; has a &lt;a href="http://www.joelonsoftware.com/articles/fog0000000007.html"&gt;blog post about it&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Another case, where reuse should be postponed, is the lack of understanding and/or foreseeing of the correct way to build the reusable code. This would usually be after the relevant code was only written once or twice. I’ll explain: You write a piece of software that does a certain task, and you feel this task might repeat itself in the future. You go and export it to a library. Then, after a while, you want to use it again, somewhere else, but you see that it is not extensible enough, portable enough, answer your functionality requirements, etc. You still have to write your own code. Or you have to fix the library to fit the two projects, then go and fix the old project that already uses it. Fixing the library at this point would be hard, since the new project’s requirements were not taken into consideration in the original design. When a 3rd project would need it, this might repeat itself again.&lt;/p&gt;&lt;p&gt;It is usually a good idea to wait until you have requirements from at least three different projects before you decide to make a piece of code a reusable library.&lt;/p&gt;&lt;h2&gt;Extensibility&lt;/h2&gt;&lt;p&gt;Extensibility allows adding new functionality in the future. There are several types of extensibility: External extensibility points, and internal extensibility points.&lt;/p&gt;&lt;p&gt;External extensibility points are the most important. The developer of a reusable piece of code should take into account the need of another developer to add functionality, or do things a little different from his own point of view.&lt;/p&gt;&lt;p&gt;For an example, suppose you have a class that contains a user control, and that user control is visible to the end-user. You could wrap it completely, only supplying the functionality you think relevant. But in some cases, a developer might want to tweak that control, and you might have not given him the option to do his little tweak (say, change the font or color). Exposing the wrapped control itself would allow the programmer to tweak it.&lt;/p&gt;&lt;h2&gt;Extensibility Best Practices&lt;/h2&gt;&lt;p&gt;Another extensibility rule of thumb would be to always expose functionality through interfaces, and if you want the user to be able to implement them in introduce the created objects to your library, use the factory pattern, and allow the user to register his own types. This allows you to replace the code behind the interface as much as you want without the user needs to wary about it, and also allows the user to introduce his own types.&lt;/p&gt;&lt;p&gt;Generally, prefer to introduce interfaces rather than base classes. If the user need to integrate your code into a current project, a base class might prevent him from doing so, as he might need to add functionality to a current class he already has, that already inherits another base class. With interfaces, this is always possible.&lt;/p&gt;&lt;p&gt;If you have a method that returns a result, prefer creating a specialized result class and fill it with the relevant data. If you’d like to add data in the future, this would be as easy as add fields to the already existing result class. In .Net this is also true for EventArgs – create your own even if they are empty. They might get filled later on.&lt;/p&gt;&lt;h2&gt;Functionality&lt;/h2&gt;&lt;p&gt;When writing software, make sure each portion of the software does what it needs to do, and does not do what it doesn’t need to do.&lt;/p&gt;&lt;p&gt;When thinking where to place each method that implement some of the functionality required, try to group together methods that have related functions. Try to avoid duplicating functionalities, just because of small differences. If you must, do it in smart way, reducing code duplication to the minimum necessary. Use helper class or helper methods as possible, and make them static, to reduce class state artifacts.&lt;/p&gt;&lt;p&gt;The exposed functionality should fit the user needs. In reusable code, don’t try to cover 100% of the cases. At least 10% of them are so rare you won’t even get to think about. Make a good, thorough research and find the 80% case that is relevant to you. Don’t look at other unrelated businesses research. They do things differently since they have different audience. Look inside your own market. Even in your own business. You’ll find plenty of information there. If you don’t – it only means this might be a functionality you don’t need to reuse. Make it applicative, and save others the burden of understanding why this is needed.&lt;/p&gt;&lt;p&gt;Don’t use intrusive technologies in your code, and if you do, document them and the reason you use them. For instance, don’t do communication for traceability. The containing project might be affected by it. If you must, make sure everything is configurable, including the traceability feature itself.&lt;/p&gt;&lt;h2&gt;Order&lt;/h2&gt;&lt;p&gt;When building your project tree structure (in terms of code files), make meaningful separation by logic, not by physical terms. Think where a new-comer would look for a certain file. If you can’t – ask a new-comer to find that file for you just by looking at the tree structure.&lt;/p&gt;&lt;p&gt;The same goes for using the “region” directives. I see endless “public methods” and “private properties” regions. Where would I find the method that performs the layout? or the methods that respond to user input events? I don’t know. In either of them. Better regions would be based on functionality groups. Region such as “User Interaction”, “Layout Logic”, “Construction and Initialization” are better.&lt;/p&gt;&lt;h2&gt;Traceability&lt;/h2&gt;&lt;p&gt;The software should log its actions and its errors. This logs are later used to analyze software usage for performance, errors, misbehavior, etc.&lt;/p&gt;&lt;p&gt;Use a common logging method for all parts of the application. A highly configurable and extensible logging method is preferred, because in the horrible case of mismatching with another logging facility used by some 3rd party component, it can be configured or extended to match it, so everything behaves like one logging method.&lt;/p&gt;&lt;h2&gt;Security&lt;/h2&gt;&lt;p&gt;Security is a very important issue, especially when the software is exposed to a large user base. You don’t know which of them might want to harm you, or your client.&lt;/p&gt;&lt;p&gt;When making database queries, make sure to sanitize the queries to prevent malicious SQL injection, that can result in loss of critical data.&lt;/p&gt;&lt;p&gt;When asking for input of any kind from any source (and this one is especially relevant in native environments, like C and C++), make sure you have enough room for it, to prevent code injection.&lt;/p&gt;&lt;h2&gt;Portability&lt;/h2&gt;&lt;p&gt;A portable software is much better that a software you need to install. Copying the files to place is the easiest thing to do, and it doesn’t mess up the registry. In .NET all you need to do is make sure all the required DLLs are there, near the main executable.&lt;/p&gt;&lt;p&gt;You might want to use tools like &lt;a href="http://research.microsoft.com/en-us/people/mbarnett/ilmerge.aspx"&gt;ILMerge&lt;/a&gt; to reduce the number of DLLs in your distribution.&lt;/p&gt;&lt;p&gt;When writing .NET software that should run on Linux, use &lt;a href="http://www.mono-project.com/MoMA"&gt;MoMA&lt;/a&gt; to make sure your application and dependencies are portable.&lt;/p&gt;&lt;p&gt;When writing a portable application that need to be run from a portable memory device (such as a disk-on-key), make sure to write the relevant data next to the application itself.&lt;/p&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;That’s it for now about writing quality software, a quick review of architectural design. I’ll try to add more about that subject later on, and write about other aspects of writing quality software, such as user interface design, testing your application and modules, etc.&lt;/p&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fitaibh.blogspot.com%2f2009%2f07%2fwriting-quality-software-architecture.html"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fitaibh.blogspot.com%2f2009%2f07%2fwriting-quality-software-architecture.html" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-196178566385238407?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/HNxnL3A9mOF7cwsnU-9vmIzZxhY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HNxnL3A9mOF7cwsnU-9vmIzZxhY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/HNxnL3A9mOF7cwsnU-9vmIzZxhY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HNxnL3A9mOF7cwsnU-9vmIzZxhY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/f2Hfvhv0bN0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/196178566385238407/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2009/07/writing-quality-software-architecture.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/196178566385238407?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/196178566385238407?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/f2Hfvhv0bN0/writing-quality-software-architecture.html" title="Writing Quality Software - Architecture" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2009/07/writing-quality-software-architecture.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D04DQns5fip7ImA9WxJQFU0.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-2776034648824687811</id><published>2009-05-28T13:01:00.001+03:00</published><updated>2009-05-28T13:19:33.526+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-28T13:19:33.526+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ideas" /><category scheme="http://www.blogger.com/atom/ns#" term="Thougts" /><title>How can Wikipedia improve its content reliability</title><content type="html">&lt;p&gt;&lt;a href="http://www.wikipedia.org/"&gt;Wikipedia&lt;/a&gt; is a very common online encyclopedia, built and managed in the form of a wiki, which means anyone can modify its values.&lt;/p&gt;&lt;p&gt;While this promises many writers, editors and critics, thus up-to-date content all the time, it also introduces great unreliability, as you can’t trust anyone who had written anything.&lt;/p&gt;&lt;p&gt;While even “&lt;a href="http://www.theregister.co.uk/2005/10/18/wikipedia_quality_problem/"&gt;Wikipedia founder admits there are serious quality problems&lt;/a&gt;”, I figured something can be done to improved the reliability and quality of the content.&lt;/p&gt;&lt;p&gt;So here is my idea: Wikipedia should introduce a “&lt;em&gt;Content Reliability Factor&lt;/em&gt;” that will be visible, sticking out on the top of each page. This factor will be on a scale (say, from 1 to 10), and will allow the reader to know how reliable the information on this page is.&lt;/p&gt;&lt;p&gt;In order to calculate the reliability factor, Wikipedia should introduce “&lt;em&gt;Fact Markup&lt;/em&gt;”, to specify “&lt;em&gt;Fact Fields&lt;/em&gt;”. Items that represent clear, hard facts, preferably numbers, will be marked using this markup.&lt;/p&gt;&lt;p&gt;There will be different types of fact fields: Absolute numeric fact fields (usually used for scientific articles), Usually climbing numeric fact fields (say, number of children of someone), Citations, etc.&lt;/p&gt;&lt;p&gt;Readers that come across&amp;#160; fact fields would then be able to rate the correctness of each fact field, and/or the entire article. Some users will be granted higher reliability factor for some values or categories, and their vote will have higher influence of the calculated result. (Of course, some articles will be blocked for such changes, for the same reasons some articles are blocked for public editing today).&lt;/p&gt;&lt;p&gt;Now to the really good part: When ever someone that is not trusted in a certain value or category, changes a fact field, the reliability factor for that fact field decreases. The amount of decrease depends on the type of that fact field – say, for usually climbing numbers, a decrease of that number would result in a very large decrease of that field’s reliability factor, while an increase would result in a smaller decrease of that reliability factor.&lt;/p&gt;&lt;p&gt;In the article history, the reliability factor will be stated next to each version. In addition, the highest ever reliability factor will be stated next to the current reliability factor on the top of the page, and will link to the relevant version of the article.&lt;/p&gt;&lt;p&gt;So all in all, while this idea does not solve the problem completely, and surely does not free us from the need of human approval for the content, it will allow to make better decisions regarding the given content.&lt;/p&gt;&lt;p&gt;P.S., There are many other methods that can be integrated into such a system that will assist with its automation. Maybe I will discuss those some other time.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-2776034648824687811?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/TUQg6tsK21O0bwaIkDomZ_h4d78/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TUQg6tsK21O0bwaIkDomZ_h4d78/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/TUQg6tsK21O0bwaIkDomZ_h4d78/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TUQg6tsK21O0bwaIkDomZ_h4d78/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/VI2c4d6zE-M" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/2776034648824687811/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2009/04/how-can-wikipedia-improve-its-content.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/2776034648824687811?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/2776034648824687811?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/VI2c4d6zE-M/how-can-wikipedia-improve-its-content.html" title="How can Wikipedia improve its content reliability" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2009/04/how-can-wikipedia-improve-its-content.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEQAQH4-fip7ImA9WhZUF0w.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-6995603994186286349</id><published>2009-04-28T17:20:00.008+03:00</published><updated>2011-06-10T16:25:41.056+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-10T16:25:41.056+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ideas" /><category scheme="http://www.blogger.com/atom/ns#" term="Thougts" /><title>What can the government of Israel do to solve the water crisis</title><content type="html">&lt;p&gt;Israel suffers greatly from lack of water.&lt;/p&gt;&lt;p&gt;This is the case for many years now, and from one year to another the government is doing more and more to solve it. By "doing more and more" I mean pass on the blame and the responsibility to the citizens.&lt;/p&gt;&lt;p&gt;Now they have a big campaign featuring all greatest Israeli celebrities, telling us to save water; telling that we must stop watering our gardens; asking to shower less. Before we'll know it they'll limit our tap water drinking.&lt;/p&gt;&lt;p&gt;This is, of course, useless and idiotic. It won't help even a tiny bit. This is the same as doing micro-optimization to a &lt;a href="http://en.wikipedia.org/wiki/Monkey_sort"&gt;monkey-sort&lt;/a&gt; algorithm. This is because the reason to this water crisis lies mainly on the fact that the population growing while the amount of water in our reservoirs stays the same (in the good case) or lowers (in the bad, current, case).&lt;/p&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Now, what can really be done to solve that crisis? Understanding the reasons, quite a few things:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;&lt;b&gt;Fixing Pipes&lt;/b&gt; - As what I've read, many of the main water pipes in Israel are leaking. In the announcements they tell us to close and fix leaking taps. A leaking tap costs us about three or four liter of water a day. A leaking main pipe costs us much more than that. I roughly assume between ten times more for a small pipe and a thousand times more for a big, central one.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Desalination&lt;/b&gt; - This is the most important one of all. Different versions of it will appear in some other suggestions. This one is the only action that can be taken that actually creates new drinking water out of bad water. Actually, there are some desalination devices used in Israel, but not enough. It seems like the bureaucracy is killing every new attempt to build new desalination devices. It is claimed that it takes about five years to build one, so the required authorizations are rarely granted, given the government is replaced every four years in the good case.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Recycling&lt;/b&gt; - Yes, water can be recycled. Actually, today, much of the water for agriculture are recycled water. The idea is that instead of sending all used water to the draining system, we clean them a bit (so they're not good for drinking) then re-use them to water fields. The same thing is also done in some water-smart buildings, where used water are re-used to fill toilet tanks. I say the government should demand that every new building would be built with such a system installed.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Mineral Water&lt;/b&gt; - There are three main companies that produce bottled mineral water in Israel. These are very good water, that most of the citizens can only buy for a great cost in bottles. I think the government should limit the amount of bottles produced every year, higher the cost of local production by taxing that companies per liter, and encourage importing of bottled water, by lowering import tax for water. In addition, state in law that every place that sells bottled water &lt;b&gt;must&lt;/b&gt; sell at least one brand of imported water. Oh, and forbid exporting of local water products.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Collecting Rain&lt;/b&gt; - Well, here we get a bit into micro-optimization, except this one is actually feasible. We can collect rain water not only in special reservoirs dug for that purpose, but using the roads and roofs draining system. Come to think about it, there is rarely anything bad in water dripping on roofs and roads. This is usually rain water, and there is always a special draining system built for each roof and on each road. Those draining system go usually to the sewer, but it is possible to collect it to reservoirs. Those doesn't have to be open reservoirs. They can be closed and underground. Still they are reservoirs, and they will get filled in the few rains we have each winter.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Well, these are my ideas for solving the water crisis. Not all are original, but I figured I'd put them all in one place, and maybe something will be done about it someday.&lt;/p&gt;&lt;p&gt;Please feel free to comment and to suggest new ideas.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-6995603994186286349?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/2TCE0t2oa5GB4KZfScY9maHZQbw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2TCE0t2oa5GB4KZfScY9maHZQbw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/2TCE0t2oa5GB4KZfScY9maHZQbw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2TCE0t2oa5GB4KZfScY9maHZQbw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/ahTIwQF2Jts" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/6995603994186286349/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2009/04/what-can-government-of-israel-do-to.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/6995603994186286349?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/6995603994186286349?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/ahTIwQF2Jts/what-can-government-of-israel-do-to.html" title="What can the government of Israel do to solve the water crisis" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2009/04/what-can-government-of-israel-do-to.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUHQn8_fip7ImA9WhZUF0w.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-6729539096705259718</id><published>2009-04-25T15:41:00.003+03:00</published><updated>2011-06-10T16:23:53.146+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-10T16:23:53.146+03:00</app:edited><title>BiDi – What is it, why we need it</title><content type="html">&lt;p&gt;BiDi stands for Bi-Directional text. Yes, specifically text. In some places (such as the Word text editor) this is referred to as Complex Scripts.&lt;/p&gt;&lt;p&gt;So what exactly is it? It is the case where several languages of different writing directions are mixed in a single sentence. More than that, in some cases, this is the case where a Right-To-Left language (Hebrew, Arabic and Persian) needs to be rendered to screen.&lt;/p&gt;&lt;p&gt;Why is this a problem? This is a problem because there is a dilemma of how to store textual data that contains both directions of writing; On the one hand, it can be stored visually, just like it appears on the screen. It will make it much easier to render, and save us from all the burden and improve performance of the rendering phase. On the other hand, however, it will make our writing phase much harder, and will require us to write some of the text reversed. Actually this is exactly what people where doing before the age of Logical Text and the BiDi algorithm.&lt;/p&gt;&lt;p&gt;The BiDi algorithm brought a new age of Logical Text, and by that we mean the way the text is stored in memory. Instead of storing it the way it is rendered, we store it the way it is being read and written. When we read text that contains several text directions (Hebrew and English mixed, for example), we change our reading direction every time the language is changed. When we write text that contains several directions, we still write the first letters first, and last letters last, even when the language changes. We don’t reverse the order of characters for that task.&lt;/p&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;p&gt;Storing the text logically makes much more sense, and makes it easier to develop software that handles text. The software behaves with text in the same way we think about it. However, in order to draw the characters on the screen in their correct position, we first need to reorder them.&lt;/p&gt;&lt;p&gt;Rendering text is not an easy task. Rendering each line requires all the letters (and other characters) to appear in their correct positions, since we usually want the renderer to make one pass due to efficiency reasons. Before that, if we want our break our lines to fit in a given width, we need to calculate the widths of the characters and select where to break the line &lt;strong&gt;logically&lt;/strong&gt;, as doing it visually might yield an unreadable result.&lt;/p&gt;&lt;p&gt;The reordering is done in the line level, after the text has been broken to lines. The BiDi algorithm takes each line and returns a new line with all the characters reordered, ready to be rendered.&lt;/p&gt;&lt;p&gt;The process of reordering can be controlled by inserting special Control Characters to the text. The most common ones define literally the direction of the text, even if the characters themselves implies differently. You can try it yourself: try to launch notepad, write some text, then click the right mouse button, in the context menu go to “Insert Unicode control character”, and select one of the control characters available. Experiment with it a little, see how it effects the text from that point on.&lt;/p&gt;&lt;p&gt;The BiDi algorithm is a one way algorithm. There is no reversed algorithm, and it is not guaranteed that running the same algorithm on visually ordered text would give the correct logically ordered text, since the visually ordered text could be the result of control characters usage, that might have been lost after the conversion. Thinking deeply about it, you don’t really need to convert back. If you do, think again, you’ve got something wrong in your overall design (this is always true, except for the case where you have &lt;strong&gt;INPUTS&lt;/strong&gt; from a legacy device that can’t be altered, and those inputs are ordered &lt;strong&gt;VISUALLY&lt;/strong&gt;. I will try to deal with this case in another post, if requested).&lt;/p&gt;&lt;p&gt;For further reading, the official &lt;a href="http://www.unicode.org/"&gt;Unicode&lt;/a&gt; website contains all Unicode information needed, including the &lt;a href="http://www.unicode.org/reports/tr9/"&gt;BiDi algorithm&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;You can find my implementation for that algorithm,called “&lt;a href="http://nbidi.sf.net"&gt;NBiDi&lt;/a&gt;”, written in C#, targeting .Net and currently being used to implement &lt;a href="http://www.codeplex.com/SilverlightRTL"&gt;Right-To-Left Silverlight controls&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fitaibh.blogspot.com%2f2009%2f04%2fbidi-what-is-it-why-we-need-it.html"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fitaibh.blogspot.com%2f2009%2f04%2fbidi-what-is-it-why-we-need-it.html" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-6729539096705259718?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/C6zhtixmUUyxo6f-YRhg3jJlUM4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/C6zhtixmUUyxo6f-YRhg3jJlUM4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/C6zhtixmUUyxo6f-YRhg3jJlUM4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/C6zhtixmUUyxo6f-YRhg3jJlUM4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/TWf9W3DpPJM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/6729539096705259718/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2009/04/bidi-what-is-it-why-we-need-it.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/6729539096705259718?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/6729539096705259718?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/TWf9W3DpPJM/bidi-what-is-it-why-we-need-it.html" title="BiDi – What is it, why we need it" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2009/04/bidi-what-is-it-why-we-need-it.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE8FRX4_cSp7ImA9WhZUF0w.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-5925063698152291624</id><published>2009-04-25T15:19:00.003+03:00</published><updated>2011-06-10T16:33:34.049+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-10T16:33:34.049+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Technology" /><title>A quick review of different UI frameworks</title><content type="html">&lt;p&gt;In this post I'll review several frameworks used for creating graphical user interfaces. I've decided to create such a review after noticing many programmers take a specific GUI framework for granted, as it is their automatic-choice-by-tool (i.e., they use what they're IDE let them, barely understanding the layers required to develop such a framework, and that there are alternatives they might have chosen if they had knew about).&lt;/p&gt;&lt;p&gt;I will review the following frameworks:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Windows.Forms&lt;/li&gt;
&lt;li&gt;WPF (+Silverlight)&lt;/li&gt;
&lt;li&gt;GTK&lt;/li&gt;
&lt;li&gt;QT&lt;/li&gt;
&lt;li&gt;wxWidgets&lt;/li&gt;
&lt;li&gt;AWT&lt;/li&gt;
&lt;li&gt;Swing&lt;/li&gt;
&lt;li&gt;SWT&lt;/li&gt;
&lt;li&gt;X/XT/Motif&lt;/li&gt;
&lt;/ul&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;Windows.Forms&lt;/h2&gt;&lt;p&gt;Naturally the automatic choice for anyone who builds a GUI in .Net. The first version was there from the very first .Net release, and supported by all versions of Visual Studio, the main IDE for .Net development.&lt;/p&gt;&lt;p&gt;When you ask most .Net developers what are they are using to build forms for their applications, they will most likely say &amp;quot;The default thing that comes with Visual Studio&amp;quot; or &amp;quot;... with .Net&amp;quot;. Most won't even know other UI frameworks exist.&lt;/p&gt;&lt;p&gt;And for some technicalities: Windows.Forms in its original implementation wraps the underlying Windows native controls. In its second version, some controls where added that doesn't wrap any base controls, but rather implemented the entire logic and graphics internally in C#.&lt;/p&gt;&lt;p&gt;As most .Net frameworks, their immediate audience is the Windows users (or in this case - developers). However, the &lt;a href="http://www.mono-project.com/"&gt;Mono&lt;/a&gt; project had implemented all the Windows.Forms controls entirely in C#, not wrapping anything at all, while maintaining complete API compatibility (including message loop interference). Due to the nature of .Net binaries, this allows migration of compiled applications from .Net to Mono, hence from Windows to Linux.&lt;/p&gt;&lt;h2&gt;WPF (+Silverlight)&lt;/h2&gt;&lt;p&gt;The newest technology reviewed in this list. Has not yet become a natural choice of any developer (mainly due to the lack of tools and IDE integration), but it is getting there. Unlike any other framework listed here, this framework does not base on the underlying windowing system at all. The only use it has for the windowing system is to open and register a top-level window. From now on it is all DirectX (at least in the WPF implementation).&lt;/p&gt;&lt;p&gt;Using XAML as the main form of defining UI, and tools that resemble artistic programs more than IDEs, WPF really allows developers and designers to work together, letting each one focus on what he can do best, providing better separation between the two worlds. Also, it allows to create applications that are much more appealing visually than most common applications.&lt;/p&gt;&lt;p&gt;WPF stands for “Windows Presentation Foundation” and was introduced with .Net framework 3.0.&lt;/p&gt;&lt;p&gt;&lt;a href="http://silverlight.net/"&gt;Silverlight&lt;/a&gt; is a subset of WPF, targeting the web. Allowing roughly the same features as WPF, in the same development model, using the same tools, it bridges the gap for developers and designers to move from desktop to web environment and vice-versa, allowing knowledge and components to be persisted and reused.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.go-mono.com/moonlight/"&gt;Moonlight&lt;/a&gt; is an open-source implementation of Silverlight, part of the &lt;a href="http://www.mono-project.com"&gt;Mono&lt;/a&gt; project, aims to bring Silverlight to the Linux world.&lt;/p&gt;&lt;h2&gt;&lt;a href="http://www.gtk.org/"&gt;GTK&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The automatic choice for anyone who develops applications for the &lt;a href="http://www.gnome.org/"&gt;Gnome&lt;/a&gt; Linux desktop. Written in C, and have many language bindings, including C#.&lt;/p&gt;&lt;p&gt;GTK was originally developed to support the development of &lt;a href="http://www.gimp.org"&gt;The GIMP&lt;/a&gt; (the GNU Image Manipulation Program), thus was named “GIMP Tool Kit” – or GTK for short. Later on it became the main toolkit for the entire &lt;a href="http://www.gnome.org"&gt;Gnome&lt;/a&gt; Linux desktop project.&lt;/p&gt;&lt;p&gt;This is an open-source (LGPL) library, developed and maintained by the community.    &lt;br /&gt;
GTK is a source-code-compatible, cross-platform toolkit, that has binary distributions for Linux, Windows, and Mac OS, and has some support for mobile devices as well (it runs on some Nokia smart phones, and used to build the &lt;a href="http://www.laptop.org/"&gt;OLPC&lt;/a&gt; project and the &lt;a href="http://www.openmoko.com/"&gt;OpenMoko&lt;/a&gt; project user interfaces).&lt;/p&gt;&lt;p&gt;It supports several levels of themes (Skins and Theme Engines), and has default themes for each operating system, especially for the Windows and Mac OS, that have very specific themes. This allows GTK applications to merge in the look and feel of those operating systems.&lt;/p&gt;&lt;h2&gt;&lt;a href="http://www.qtsoftware.com/"&gt;QT&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Originally developed by TrollTech, now owned by Nokia and supported by the community. Written in C++ and utilizing a Meta-Object-Compiler - a special precompiler that adds several features to the C++ language, mainly used for easier data binding. Some language bindings are available, including a community binding for C#, named &lt;a href="http://techbase.kde.org/Development/Languages/Qyoto"&gt;Qyoto&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;QT is a cross platform framework targeting both Desktop and Mobile applications.     &lt;br /&gt;
In its open-source license (GPL, LGPL) it is used to develop the &lt;a href="http://www.kde.org"&gt;KDE&lt;/a&gt; Linux desktop environment, while in its commercial license it is used by commercial software and hardware vendors to build the GUI of their products.&lt;/p&gt;&lt;p&gt;QT has a very good support for themes, allowing it to merge in the look and feel of just about any environment, including Windows, Mac OS, and even the Gnome Linux desktop (by reading the Gnome theme configuration file).&lt;/p&gt;&lt;h2&gt;&lt;a href="http://www.wxwidgets.org/"&gt;wxWidgets&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;wxWidgets is a cross-platform framework designed to use each system’s native controls to the max, while preserving common API and rich set of controls. Written in C++ and has several language bindings including C#.&lt;/p&gt;&lt;p&gt;There are no common tools that support visual design for it, but there are several visual designers for it out there, such as “&lt;a href="http://www.anthemion.co.uk/dialogblocks/"&gt;DialogBlocks&lt;/a&gt;”.&lt;/p&gt;&lt;h2&gt;AWT&lt;/h2&gt;&lt;p&gt;The Java most basic set of UI controls. AWT stands for “Abstract Windowing Toolkit”, and works in the same manner as .Net's Windows.Forms, but implemented differently on each JVM (i.e., wraps each system's native controls - The native Windows controls on Windows, usually GTK on Linux, and Cocoa on the Mac.)&lt;/p&gt;&lt;h2&gt;Swing&lt;/h2&gt;&lt;p&gt;Swing is Java’s themable UI framework, written completely in Java, using AWT’s most basic controls only, and built from scratch on top of than.&lt;/p&gt;&lt;p&gt;While this allows much nicer look and feels, Swing came too early and suffered from bad performance caused by the need to draw heavy graphics using a virtual machine on computers not strong enough at the time. This caused many developers to look for alternatives, and SWT was the most common one.&lt;/p&gt;&lt;h2&gt;SWT&lt;/h2&gt;&lt;p&gt;This one can be compared to the second version of Windows.Forms, or to wxWidgets, if you'd like. Based on each JVM implementation of AWT, makes a so called &amp;quot;Mix and Match&amp;quot; to create a better set of controls, that can run on each operating system and gains its native look and feel, while bringing large set of controls and maintaining performance by using the operating systems native controls.&lt;/p&gt;&lt;h2&gt;X/XT/Motif&lt;/h2&gt;&lt;p&gt;The 'X' Windowing System is the service that bring graphics and windowing operations to the Unix world. Like most windowing systems, this system is also based on a message loop and message dispatching, where each control is usually a window.&lt;/p&gt;&lt;p&gt;The X-Toolkit (XT) is a library helping to develop controls. It separates the control logic and design from the need to handle all the events passed to it from 'X', thus allowing vendors to focus on developing the controls themselves. Over time this approach has failed to persist, as no new control sets where created after Motif, and newer GUI frameworks (toolkits) had chosen to handle all events themselves, which also helped building cross-platform GUI frameworks.&lt;/p&gt;&lt;p&gt;Motif is the most commonly used set of controls that was build for the X-Toolkit framework, allowing large variety of controls for different aspects of GUI development.&lt;/p&gt;&lt;br /&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fitaibh.blogspot.com%2f2009%2f04%2fquick-review-of-different-ui-frameworks.html"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fitaibh.blogspot.com%2f2009%2f04%2fquick-review-of-different-ui-frameworks.html" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-5925063698152291624?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/H1pzNw6nrcHId-Ge0Qh_iT5rbjE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/H1pzNw6nrcHId-Ge0Qh_iT5rbjE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/H1pzNw6nrcHId-Ge0Qh_iT5rbjE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/H1pzNw6nrcHId-Ge0Qh_iT5rbjE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/2QZJsZpsMwQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/5925063698152291624/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2009/04/quick-review-of-different-ui-frameworks.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/5925063698152291624?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/5925063698152291624?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/2QZJsZpsMwQ/quick-review-of-different-ui-frameworks.html" title="A quick review of different UI frameworks" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2009/04/quick-review-of-different-ui-frameworks.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C08CRX4zeip7ImA9WhZUFE8.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-5072407676876696858</id><published>2009-04-15T16:29:00.011+03:00</published><updated>2011-06-07T07:44:24.082+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-07T07:44:24.082+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Technology" /><category scheme="http://www.blogger.com/atom/ns#" term="Reflection" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><title>Runtime testing and casting objects of generic types</title><content type="html">How can you tell, in runtime, if an object you have is of a specific generic type? For instance, if it implements the generic interface &lt;code&gt;ICollection&lt;T&gt;&lt;/code&gt; ?&lt;br /&gt;&lt;br /&gt;You might say, "lets get all interfaces implemented by that object, first by getting its type (using &lt;code&gt;GetType()&lt;/code&gt;), then by calling &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ayfa0fcd.aspx"&gt;GetInterface(string name)&lt;/a&gt;&lt;/code&gt;, passing in the type name in its mangled form".&lt;br /&gt;This will work, however, this yields to error prone, non-type-safe code, plus, making us required to know how to build the relevant mangled string.&lt;br /&gt;&lt;br /&gt;We would like something better. We would like to be able to get the generic type itself. Fortunately this can be easily done the following way:&lt;br /&gt;&lt;pre class="brush: csharp"&gt;Type genericCollectionInterfaceType = typeof(ICollection&amp;lt;&gt;);&lt;/pre&gt;&lt;br /&gt;This will return the generic collection interface type. Now, what can we do with it? We wanted to test if a certain object implements this interface. However, a list of, say, strings, will NOT implement that interface. It will implement the &lt;code&gt;ICollection&lt;String&gt;&lt;/code&gt; interface, which is not the same as &lt;code&gt;ICollection&lt;&gt;&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;What can we do? We need to build, in runtime, a generic interface type that corresponds to the interface signature of our object:&lt;br /&gt;&lt;pre class="brush: csharp"&gt;Type testedObjectType = testedObject.GetType();&lt;br /&gt;Type genericType = typeof(ICollection&amp;lt;&gt;).MakeGenericType(testedObjectType.GetGenericArguments());&lt;/pre&gt;&lt;br /&gt;Then we can use that type to test for assignability:&lt;br /&gt;&lt;pre class="brush: csharp"&gt;collectionType.IsAssignableFrom(testedObjectType);&lt;/pre&gt;&lt;br /&gt;Calling &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.type.makegenerictype.aspx"&gt;MakeGenericType&lt;/a&gt;&lt;/code&gt; creates a new &lt;code&gt;Type&lt;/code&gt; object that represents the type we are looking for. We pass it a list of types, in this case taken from the object itself (using &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.type.getgenericarguments.aspx"&gt;GetGenericArguments&lt;/a&gt;&lt;/code&gt;). Then we can check for assignability between the two.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fitaibh.blogspot.com%2f2009%2f04%2fruntime-testing-and-casting-objects-of.html"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fitaibh.blogspot.com%2f2009%2f04%2fruntime-testing-and-casting-objects-of.html" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-5072407676876696858?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/6dGleQtznuGqIi7tdRGmMB942J4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6dGleQtznuGqIi7tdRGmMB942J4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/6dGleQtznuGqIi7tdRGmMB942J4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6dGleQtznuGqIi7tdRGmMB942J4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/Q-E3rKoHFMs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/5072407676876696858/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2009/04/runtime-testing-and-casting-objects-of.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/5072407676876696858?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/5072407676876696858?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/Q-E3rKoHFMs/runtime-testing-and-casting-objects-of.html" title="Runtime testing and casting objects of generic types" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2009/04/runtime-testing-and-casting-objects-of.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4AQHo-fyp7ImA9WxVaFEo.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-1126836435635738846</id><published>2009-04-11T20:00:00.005+03:00</published><updated>2009-04-11T22:42:21.457+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-11T22:42:21.457+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Technology" /><category scheme="http://www.blogger.com/atom/ns#" term="Experiments" /><title>Lasers and experiments</title><content type="html">I tried to activate a laser diode today, that I disassembled from an old DVD player.&lt;br /&gt;I used a cellphone recharger (outputs 5V) and connected the wires.&lt;br /&gt;It worked for about half a second. I think it is now dead. R.I.P.&lt;br /&gt;Anyone got old DVD/Bluray players they don't need?&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_skWDg2sd0Zc/SeDQFnD5wII/AAAAAAAABcg/Dw8Rix5gJEo/s1600-h/Laser+Diode+Parts+2.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 239px;" src="http://2.bp.blogspot.com/_skWDg2sd0Zc/SeDQFnD5wII/AAAAAAAABcg/Dw8Rix5gJEo/s320/Laser+Diode+Parts+2.JPG" alt="" id="BLOGGER_PHOTO_ID_5323483554355200130" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;The dead laser diode (on the right), and its original housing and controller.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_skWDg2sd0Zc/SeDQFWJD5QI/AAAAAAAABcY/cbnZuFxmBWo/s1600-h/DVD+parts+4.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_skWDg2sd0Zc/SeDQFWJD5QI/AAAAAAAABcY/cbnZuFxmBWo/s320/DVD+parts+4.JPG" alt="" id="BLOGGER_PHOTO_ID_5323483549813433602" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;The disassembled DVD player.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-1126836435635738846?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Iw0u-65oh4nT06qw_kUCndnWmXU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Iw0u-65oh4nT06qw_kUCndnWmXU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Iw0u-65oh4nT06qw_kUCndnWmXU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Iw0u-65oh4nT06qw_kUCndnWmXU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/1hkI5S2IwIY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/1126836435635738846/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2009/04/lasers-and-experiments.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/1126836435635738846?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/1126836435635738846?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/1hkI5S2IwIY/lasers-and-experiments.html" title="Lasers and experiments" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_skWDg2sd0Zc/SeDQFnD5wII/AAAAAAAABcg/Dw8Rix5gJEo/s72-c/Laser+Diode+Parts+2.JPG" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2009/04/lasers-and-experiments.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4AQno-cSp7ImA9WhZUF0w.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-331031554530554128</id><published>2009-04-09T11:50:00.018+03:00</published><updated>2011-06-10T16:35:43.459+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-10T16:35:43.459+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="WPF" /><category scheme="http://www.blogger.com/atom/ns#" term="Tutorial" /><category scheme="http://www.blogger.com/atom/ns#" term="Technology" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><title>Creating customizable WPF drop-down menus (7)</title><content type="html">&lt;h1&gt;Step 7: Using the new binding correctly&lt;/h1&gt;&lt;br /&gt;
Remember that we overridden &lt;code&gt;OnDragEnter&lt;/code&gt; so the menu will open upon hovering? Well, we will have to make a slight change to that code, to (also) use our new property:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: csharp"&gt;protected override void OnDragEnter(DragEventArgs e)
{
    IsSubmenuOpen = true;
    IsSubmenuOpenInternal = true;
    e.Handled = true;
}&lt;/pre&gt;&lt;br /&gt;
Great! Except now the menu never closes. Well, the first occasion we want it to close is when we're done dropping. So we will add the following snippet to our &lt;code&gt;OnDrop&lt;/code&gt; code, just before the &lt;code&gt;e.Handle = true&lt;/code&gt; code:&lt;br /&gt;
&lt;pre class="brush: csharp"&gt;if (parentMenuItem != null)
    parentMenuItem.IsSubmenuOpenInternal = false;&lt;/pre&gt;&lt;br /&gt;
Another case when we want it to close is whenever a neighbor menu opens, or in case we stopped using the menu at all (like, clicking any other place). But the thing is, we really don't want to write such code, as it is already written. We need a way to find when the original property would change to &lt;code&gt;false&lt;/code&gt; and do the same.&lt;br /&gt;
Luckily, there is a routed event just for that: &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.menuitem.submenuclosed.aspx"&gt;SubmenuClosed&lt;/a&gt;&lt;/code&gt;.&lt;br /&gt;
We will register to that event, and change our new property to &lt;code&gt;false&lt;/code&gt; likewise. Except, we do it with a minor change: we need to make sure we are not in the middle of a drag operation, or right in the drop handling code. We will register to that event in the constructor, and implement it:&lt;br /&gt;
&lt;pre class="brush: csharp"&gt;public DraggableMenuItem()
{
    AllowDrop = true;
    SubmenuClosed += new RoutedEventHandler(DraggableMenuItem_SubmenuClosed);
}

void DraggableMenuItem_SubmenuClosed(object sender, RoutedEventArgs e)
{
    if (Mouse.LeftButton == MouseButtonState.Pressed || !IsDragging)
        IsSubmenuOpenInternal = false;
}&lt;/pre&gt;&lt;br /&gt;
And that's it! The menu is now Drag-and-Drop customizable! Note that the code brought here in this article is for explanatory purposes only, and is far from perfect. Its goal is to explain the main issues and problems encountered while developing such a control, so use it as a reference only.&lt;br /&gt;
&lt;br /&gt;
Hope you have found it useful, and please let me know if you did, and I'll be glad to hear about successful (preferably complete) implementations.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fitaibh.blogspot.com%2fsearch%2flabel%2fTutorial"&gt;&lt;img alt="kick it on DotNetKicks.com" border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fitaibh.blogspot.com%2fsearch%2flabel%2fTutorial" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-331031554530554128?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/50OLZugl7SpIbi_5EYwmK_xfiUU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/50OLZugl7SpIbi_5EYwmK_xfiUU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/50OLZugl7SpIbi_5EYwmK_xfiUU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/50OLZugl7SpIbi_5EYwmK_xfiUU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/AdGwkBBeeyg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/331031554530554128/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2009/04/creating-customizable-wpf-drop-down_3705.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/331031554530554128?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/331031554530554128?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/AdGwkBBeeyg/creating-customizable-wpf-drop-down_3705.html" title="Creating customizable WPF drop-down menus (7)" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2009/04/creating-customizable-wpf-drop-down_3705.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4DRHg-fSp7ImA9WhZUF0w.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-2297108475195496216</id><published>2009-04-09T10:57:00.019+03:00</published><updated>2011-06-10T16:36:15.655+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-10T16:36:15.655+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="WPF" /><category scheme="http://www.blogger.com/atom/ns#" term="Tutorial" /><category scheme="http://www.blogger.com/atom/ns#" term="Technology" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><title>Creating customizable WPF drop-down menus (6)</title><content type="html">&lt;h1&gt;Why dropping doesn't work on sub-menus?&lt;/h1&gt;&lt;br /&gt;
This question is actually the heart of the entire process. All we did until now was quite straight-forward.&lt;br /&gt;
So, why doesn't it work? To solve that I tried several debugging methods, but the one that really got me somewhere was to enable &lt;a href="http://referencesource.microsoft.com/"&gt;Reference Code Debugging&lt;/a&gt;.&lt;br /&gt;
So I found myself debugging deep into the WPF code, finding that during the drop operation, the result of the hit-test being performed is actually 'null'(!). More than that, it seemed like the native window holding the sub-menu wasn't even there (!!). How can that be?&lt;br /&gt;
Well, I couldn't debug much deeper than that, but thinking about how drop-down menus work, and how drag-and-drop mechanisms work, I figured that the problem must be that &lt;em&gt;the sub-menu popup was closing before the drop operation hit test takes place.&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
This means that if I want to be able to drop things on a sub-menu, I need to build a new mechanism that will keep it open until AFTER the drop.&lt;br /&gt;
&lt;br /&gt;
&lt;h1&gt;Step 6: Keeping the sub-menu open&lt;/h1&gt;&lt;br /&gt;
Now it is going to get clear why I insisted on inheriting &lt;code&gt;MenuItem&lt;/code&gt; (and be sure it will get worse, as we will need to change the default &lt;a href="http://msdn.microsoft.com/en-us/library/bb613570.aspx"&gt;control template&lt;/a&gt;).&lt;br /&gt;
&lt;br /&gt;
We will need to introduce a new &lt;a href="http://msdn.microsoft.com/en-us/library/ms752914.aspx"&gt;Dependency Property&lt;/a&gt; that will enable us to better control whenever the sub-menu is open. Let's call this property &lt;code&gt;IsSubmenuOpenInternal&lt;/code&gt;:&lt;br /&gt;
&lt;pre class="brush: csharp"&gt;public static readonly DependencyProperty IsSubmenuOpenInternalProperty =
   DependencyProperty.Register("IsSubmenuOpenInternal",
                               typeof(bool), typeof(DraggableMenuItem),
                               new FrameworkPropertyMetadata(false));

public bool IsSubmenuOpenInternal
{
   get { return(bool)GetValue(IsSubmenuOpenInternalProperty); }
   set { SetValue(IsSubmenuOpenInternalProperty, value); }
}&lt;/pre&gt;&lt;br /&gt;
In the XAML code, we will change the default style (this can be easily done using "Expression Blend") so the sub-menu opening state will now bind to our new property, rather than the default one.&lt;br /&gt;
&lt;br /&gt;
I will not place here the entire XAML for the new menu item class, since it is just too long.&lt;br /&gt;
What you will need to do is to use Expression Blend to copy the default MenuItem style, then make the following changes:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Change the &lt;code&gt;TargetType&lt;/code&gt; attribute to our new class type. Remember to add the relevant &lt;a href="http://msdn.microsoft.com/en-us/library/ms747086.aspx#Mapping_CLR_Namespaces_to_XML_Namespaces_in_an"&gt;namespace declaration in the XAML&lt;/a&gt; declaration.&lt;/li&gt;

&lt;li&gt;Locate the &lt;code&gt;Popup&lt;/code&gt; element block, and change its &lt;code&gt;IsOpen&lt;/code&gt; binding from &lt;code&gt;IsSubmenuOpen&lt;/code&gt; to our new &lt;code&gt;IsSubmenuOpenInternal&lt;/code&gt; dependency property.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;table class="note"&gt;&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Important Note:&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;If I could, I would of course rather override the default &lt;code&gt;IsSubmenuOpen&lt;/code&gt; property, leaving the XAML as it is. However, this is impossible (at least in accepted methods, without using reflection), so adding this property really seems like the only way to go.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
Now that the new bindings are in place, we can move on to the next post :-)&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fitaibh.blogspot.com%2fsearch%2flabel%2fTutorial"&gt;&lt;img alt="kick it on DotNetKicks.com" border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fitaibh.blogspot.com%2fsearch%2flabel%2fTutorial" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-2297108475195496216?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/XoWeHKH3YgWHOpyfcXe74eTKYSE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/XoWeHKH3YgWHOpyfcXe74eTKYSE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/XoWeHKH3YgWHOpyfcXe74eTKYSE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/XoWeHKH3YgWHOpyfcXe74eTKYSE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/4WhEr3cTKlg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/2297108475195496216/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2009/04/creating-customizable-wpf-drop-down_09.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/2297108475195496216?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/2297108475195496216?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/4WhEr3cTKlg/creating-customizable-wpf-drop-down_09.html" title="Creating customizable WPF drop-down menus (6)" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2009/04/creating-customizable-wpf-drop-down_09.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcGR3s8eip7ImA9WhZUF0w.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-2392942118877269330</id><published>2009-04-06T15:56:00.017+03:00</published><updated>2011-06-10T16:37:06.572+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-10T16:37:06.572+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="WPF" /><category scheme="http://www.blogger.com/atom/ns#" term="Tutorial" /><category scheme="http://www.blogger.com/atom/ns#" term="Technology" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><title>Creating customizable WPF drop-down menus (4,5)</title><content type="html">&lt;h1&gt;Step 4: Responding to drag hovering&lt;/h1&gt;&lt;br /&gt;
&lt;table class="note"&gt;&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Important Note:&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;In this part of the tutorial, we implement the draggable menu items that are static, and still in the menu, rather then the one being dragged. Keep that in mind, this is important.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
We want our menus open whenever an item is dragged over them. The simplest solution would be to override the &lt;code&gt;OnDragEnter&lt;/code&gt; method, and set the &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.menuitem.issubmenuopen.aspx"&gt;IsSubmenuOpen&lt;/a&gt;&lt;/code&gt; property to &lt;code&gt;true&lt;/code&gt;.&lt;br /&gt;
This will work for now, but we will have to change that later, when we get to the drop-handling part.&lt;br /&gt;
Anyway, for now:&lt;br /&gt;
&lt;pre class="brush: csharp"&gt;protected override void OnDragEnter(DragEventArgs e)
{
    IsSubmenuOpen = true;
    e.Handled = true;
}&lt;/pre&gt;&lt;br /&gt;
&lt;h1&gt;Step 5: Handling drops&lt;/h1&gt;&lt;br /&gt;
First we must accept drops. Lets implement the constructor:&lt;br /&gt;
&lt;pre class="brush: csharp"&gt;public DraggableMenuItem()
{
    AllowDrop = true;
}&lt;/pre&gt;&lt;br /&gt;
This code snippet set our draggable menu item to accept drops. Without this, it wouldn't be possible to drop anything on it, so we wouldn't be able to customize our menu.&lt;br /&gt;
Next we need to catch the drop operation, and perform the item movement logic. Of course we shall override and implement &lt;code&gt;OnDrop&lt;/code&gt;. Note that we will need to extract the item being dragged from the &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.drageventargs.aspx"&gt;DragEventArgs&lt;/a&gt;&lt;/code&gt;, and if it is a &lt;code&gt;DraggableMenuItem&lt;/code&gt;, remove it from its current position, and place it just before the drop target:&lt;br /&gt;
&lt;pre class="brush: csharp"&gt;protected override void OnDrop(DragEventArgs e)
{
    DraggableMenuItem draggedItem = (DraggableMenuItem)e.Data.GetData(typeof(DraggableMenuItem));
    DraggableMenuItem parentMenuItem = Parent as DraggableMenuItem;
    Menu parentMenu = Parent as Menu;
    ItemsControl itemsControl = Parent as ItemsControl;
    if (draggedItem != null &amp;amp;&amp;amp; (parentMenuItem != null || parentMenu != null)) 
    {
        int i = itemsControl.Items.IndexOf(this);
        ItemsControl draggedItemParent = draggedItem.Parent as ItemsControl;
        if (draggedItemParent != null) 
        {
            draggedItemParent.Items.Remove(draggedItem);
        }
        itemsControl.Items.Insert(i, draggedItem);
        e.Handled = true;
    }
    base.OnDrop(e);
}&lt;/pre&gt;&lt;br /&gt;
&lt;h1&gt;First attempt to test it all&lt;/h1&gt;&lt;br /&gt;
Generally, while things don't look as nice as they can be, and might still be somewhat buggy, it looks like things should work.&lt;br /&gt;
Testing it reveals that dropping items on the menu bar level does work. However, dropping things on open sub-menus doesn't!&lt;br /&gt;
I will review the reason for that on the next post.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fitaibh.blogspot.com%2fsearch%2flabel%2fTutorial"&gt;&lt;img alt="kick it on DotNetKicks.com" border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fitaibh.blogspot.com%2fsearch%2flabel%2fTutorial" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-2392942118877269330?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/i-EzKcLTjmRceDZsT_RTfcGMtFg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/i-EzKcLTjmRceDZsT_RTfcGMtFg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/i-EzKcLTjmRceDZsT_RTfcGMtFg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/i-EzKcLTjmRceDZsT_RTfcGMtFg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/2VjdXLbvuWM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/2392942118877269330/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2009/04/creating-customizable-wpf-drop-down_2044.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/2392942118877269330?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/2392942118877269330?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/2VjdXLbvuWM/creating-customizable-wpf-drop-down_2044.html" title="Creating customizable WPF drop-down menus (4,5)" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2009/04/creating-customizable-wpf-drop-down_2044.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcBRXc5fSp7ImA9WhZUF0w.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-8937216624394399551</id><published>2009-04-06T14:49:00.015+03:00</published><updated>2011-06-10T16:37:34.925+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-10T16:37:34.925+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="WPF" /><category scheme="http://www.blogger.com/atom/ns#" term="Tutorial" /><category scheme="http://www.blogger.com/atom/ns#" term="Technology" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><title>Creating customizable WPF drop-down menus (3)</title><content type="html">&lt;h1&gt;Step 3: Dragging items around&lt;/h1&gt;&lt;br /&gt;
Once we have figured out how to detect the drag, we need to perform the actual dragging. Moreover, we want the menu to respond while we move around - hovering over a menu should cause it sub menu (if any) to open.&lt;br /&gt;
&lt;br /&gt;
We will use the &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.dragdrop.aspx"&gt;System.Windows.DragDrop&lt;/a&gt;&lt;/code&gt; helper class to perform the actual dragging.&lt;br /&gt;
The main method in the &lt;code&gt;DragDrop&lt;/code&gt; class is &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.dragdrop.dodragdrop.aspx"&gt;DoDragDrop&lt;/a&gt;&lt;/code&gt;. This method is used to initialize a drag-and-drop session, perform the actual drag-and-drop operations, and returns the effect.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Initializing a drag-and-drop session&lt;/h2&gt;&lt;br /&gt;
The &lt;code&gt;DoDragDrop&lt;/code&gt; method takes 3 parameters:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;A drag source (which will be our draggable menu item), &lt;/li&gt;
&lt;li&gt;A data object, and&lt;/li&gt;
&lt;li&gt;The allowed effects.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
So as I mentioned, the drag source will be our draggable menu item. Since the code will be written as part of that menu item, we will just place there '&lt;code&gt;this&lt;/code&gt;'.&lt;br /&gt;
Our data source, while can be anything at all (as it is of type &lt;code&gt;object&lt;/code&gt;), should be of type &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.idataobject.aspx"&gt;System.Windows.IDataObject&lt;/a&gt;&lt;/code&gt;, since otherwise it will be wrapped with a &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.dataobject.aspx"&gt;DataObject&lt;/a&gt;&lt;/code&gt;.&lt;br /&gt;
The best thing to do in this case would be to create a &lt;code&gt;DataObject&lt;/code&gt;, and give it a unique name (or type), and the data itself. In our case, the data is the draggable menu item we'll be dragging, so the best unique id would be its type.&lt;br /&gt;
The only allowed effect, in our case, is the move effect, as this is what we want to do (at least for now) - move menu items from one place to another.&lt;br /&gt;
&lt;br /&gt;
So if we implement the &lt;code&gt;DoDragging&lt;/code&gt; method we left empty before:&lt;br /&gt;
&lt;pre class="brush: csharp"&gt;private void DoDragging()
{
IsDragging = true;
DataObject dataObj = new DataObject(typeof(DraggableMenuItem), this);
DragDrop.DoDragDrop(this, dataObj, DragDropEffects.Move);
IsDragging = false;
}&lt;/pre&gt;&lt;br /&gt;
Note that I raise the &lt;code&gt;IsDragging&lt;/code&gt; flag before the dragging process begins, and lower it immediately afterwards. One reason for that is to prevent dragging to begin on other draggable menu items. Other reasons will become clear in the following posts.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fitaibh.blogspot.com%2fsearch%2flabel%2fTutorial"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fitaibh.blogspot.com%2fsearch%2flabel%2fTutorial" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-8937216624394399551?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/SlN-k9NqvXgn3hgfCF2U7bc4kSM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SlN-k9NqvXgn3hgfCF2U7bc4kSM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/SlN-k9NqvXgn3hgfCF2U7bc4kSM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SlN-k9NqvXgn3hgfCF2U7bc4kSM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/hX7oKWBTxwk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/8937216624394399551/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2009/04/creating-customizable-wpf-drop-down_06.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/8937216624394399551?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/8937216624394399551?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/hX7oKWBTxwk/creating-customizable-wpf-drop-down_06.html" title="Creating customizable WPF drop-down menus (3)" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2009/04/creating-customizable-wpf-drop-down_06.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcCSXc_fip7ImA9WhZUF0w.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-520366681630953946</id><published>2009-04-06T14:43:00.007+03:00</published><updated>2011-06-10T16:37:48.946+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-10T16:37:48.946+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="WPF" /><category scheme="http://www.blogger.com/atom/ns#" term="Tutorial" /><category scheme="http://www.blogger.com/atom/ns#" term="Technology" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><title>Creating customizable WPF drop-down menus (2)</title><content type="html">&lt;h1&gt;Step 2: Detecting drag&lt;/h1&gt;&lt;br /&gt;
Drag will start when the user had pressed the mouse button on an item and moved it enough distance in pixels while being pressed.&lt;br /&gt;
So, we need to know where the mouse was pressed, then track it all time it is pressed until it moves far enough:&lt;br /&gt;
&lt;pre class="brush: csharp"&gt;public class DraggableMenuItem : MenuItem
{
private Point m_dragStartPoint;

public static  bool IsDragging { get; set; }

protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
m_dragStartPoint = e.GetPosition(this);
base.OnMouseLeftButtonDown(e);
}

protected override void OnMouseMove(MouseEventArgs e)
{
if (e.LeftButton != MouseButtonState.Pressed || IsDragging)
return;

Point p = e.GetPosition(this);
if (Point.Subtract(m_dragStartPoint, p).LengthSquared &lt; 16)
{
e.Handled = true;
return;
}

DoDragging();
}

protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
{
IsDragging = false;
base.OnMouseLeftButtonUp(e);
}

private void DoDragging()
{
}
}&lt;/pre&gt;

Note that the &lt;code&gt;IsDragging&lt;/code&gt; flag is a static flag, thus shared among all instances of the &lt;code&gt;DraggableMenuItem&lt;/code&gt;. In the code sample above we do not yet assign it. This will be done in the next steps, in addition to some other places we will need to use its value to achieve the correct behavior.

&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fitaibh.blogspot.com%2fsearch%2flabel%2fTutorial"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fitaibh.blogspot.com%2fsearch%2flabel%2fTutorial" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-520366681630953946?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/nPAGsNEZ34XoCWQvFtMNI-2KrG0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nPAGsNEZ34XoCWQvFtMNI-2KrG0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/nPAGsNEZ34XoCWQvFtMNI-2KrG0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nPAGsNEZ34XoCWQvFtMNI-2KrG0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/hxQMt8xh2QM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/520366681630953946/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2009/04/creating-customizable-wpf-drop-down.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/520366681630953946?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/520366681630953946?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/hxQMt8xh2QM/creating-customizable-wpf-drop-down.html" title="Creating customizable WPF drop-down menus (2)" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2009/04/creating-customizable-wpf-drop-down.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4AQHo-cCp7ImA9WxVaFEo.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-1749193499026610820</id><published>2009-04-02T22:43:00.004+03:00</published><updated>2009-04-11T22:42:21.458+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-11T22:42:21.458+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Technology" /><category scheme="http://www.blogger.com/atom/ns#" term="Blogger" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><title>Code Snippets (2)</title><content type="html">After I couldn't find a decent way to implement nice, colorful code snippets inside blogger (which holds me back from posing code related articles) as I mentioned in my &lt;a href="http://itaibh.blogspot.com/2009/03/code-snippets.html"&gt;last post&lt;/a&gt;, and after checking "CopySourceAsHtml" as suggested by Asher in his comment to my last post (and didn't like it - it creates HTML I really don't want to use), I decided to go on with writing my own converter.&lt;br /&gt;I used the &lt;a href="http://www.devincook.com/goldparser/"&gt;GOLD&lt;/a&gt; parsing system, along with the &lt;a href="http://www.calitha.com/goldparser.html"&gt;Calitha gold parser engine&lt;/a&gt; to parse source code of a given grammar (grammars for GOLD can be found &lt;a href="http://www.devincook.com/goldparser/grammars/index.htm"&gt;here&lt;/a&gt;), added some metadata to that grammar (currently I've only done a proof-of-concept, so everything is hard-coded) that defines how to indent and colorize (HTMLize) it, and wrote this application:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_skWDg2sd0Zc/SdUYT5CIgKI/AAAAAAAABcQ/gk7D4yvn4Co/s1600-h/html+code+snippet+maker+1.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 368px; height: 244px;" src="http://3.bp.blogspot.com/_skWDg2sd0Zc/SdUYT5CIgKI/AAAAAAAABcQ/gk7D4yvn4Co/s320/html+code+snippet+maker+1.png" alt="" id="BLOGGER_PHOTO_ID_5320185264814456994" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;(click to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Next will probably be adding another language (C# - currently only tried it with XML), extracting metadata to external files (should see if I can merge it with the GOLD parser grammar files, and read it from there somehow), and making things look nicer, for starters.&lt;br /&gt;&lt;br /&gt;The code is currently not available for download, but I'll probably start a project on &lt;a href="http://www.sourceforge.net"&gt;sourceforge&lt;/a&gt; for that soon. I'll post an update when I will.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-1749193499026610820?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/paGnAK0sh4kAiQec-wb1YISafAQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/paGnAK0sh4kAiQec-wb1YISafAQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/paGnAK0sh4kAiQec-wb1YISafAQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/paGnAK0sh4kAiQec-wb1YISafAQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/s_vR0V9nLSQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/1749193499026610820/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2009/04/code-snippets-2.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/1749193499026610820?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/1749193499026610820?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/s_vR0V9nLSQ/code-snippets-2.html" title="Code Snippets (2)" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_skWDg2sd0Zc/SdUYT5CIgKI/AAAAAAAABcQ/gk7D4yvn4Co/s72-c/html+code+snippet+maker+1.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2009/04/code-snippets-2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4AQHo-cCp7ImA9WxVaFEo.&quot;"><id>tag:blogger.com,1999:blog-3029714609596082708.post-6579494241524874247</id><published>2009-03-29T22:46:00.003+03:00</published><updated>2009-04-11T22:42:21.458+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-11T22:42:21.458+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Technology" /><category scheme="http://www.blogger.com/atom/ns#" term="Blogger" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><title>Code Snippets</title><content type="html">It seems like blogger does not support code snippets, and that its not as easy as I thought it will be to find some converters that will be able to convert my code into nice, colorful HTML syntax I can paste.&lt;br /&gt;&lt;br /&gt;Time to write something that does just that, I guess.&lt;br /&gt;&lt;br /&gt;Will probably build something generic, and base on the &lt;a href="http://www.devincook.com/goldparser/"&gt;GOLD&lt;/a&gt; parser. It have good base code generators for various languages, including C#, so it seems like a good place to start.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3029714609596082708-6579494241524874247?l=itaibh.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/X_IuUOhNLBLKoy4FnNVU-M8nD4E/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/X_IuUOhNLBLKoy4FnNVU-M8nD4E/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/X_IuUOhNLBLKoy4FnNVU-M8nD4E/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/X_IuUOhNLBLKoy4FnNVU-M8nD4E/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsAndTechnology/~4/EwSzNDiJtuA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://itaibh.blogspot.com/feeds/6579494241524874247/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://itaibh.blogspot.com/2009/03/code-snippets.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/6579494241524874247?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3029714609596082708/posts/default/6579494241524874247?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsAndTechnology/~3/EwSzNDiJtuA/code-snippets.html" title="Code Snippets" /><author><name>Itai Bar-Haim</name><uri>http://www.blogger.com/profile/09367004872480545744</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Nst9l8qja1k/TVPl8EPHNqI/AAAAAAAABmo/2k4HTPmi4vk/s220/itai3.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://itaibh.blogspot.com/2009/03/code-snippets.html</feedburner:origLink></entry></feed>

