tag:blogger.com,1999:blog-3683784668343545582024-03-04T12:23:34.236-08:00Minutesycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.comBlogger46125tag:blogger.com,1999:blog-368378466834354558.post-5386762409360767132011-09-07T15:25:00.000-07:002011-09-07T15:26:10.641-07:00Windows Security: Path InterpretationI've come across this MSDN article, which talks about how Windows interprets paths:<br />
<a href="http://msdn.microsoft.com/en-us/library/aa365247%28v=vs.85%29.aspx">http://msdn.microsoft.com/en-us/library/aa365247%28v=vs.85%29.aspx</a><br />
<br />
Why is this a security concern?<br />
Let's say you have an application that allows a user to write a file path as input, and to get the content of the file as output. You want to restrict access to a specific file, let's say:<br />
<div style="font-family: "Courier New",Courier,monospace;">
c:\secret location\passwords.txt</div>
<br />
This code is a possible way of writing such functionality:
<style type="text/css">
.csharpcode, .csharpcode pre
{
font-size: 13.3333px;
font-width: 400;
color: black;
font-family: "Courier New";
}
.csharpcode pre { margin: 0px; }
.csharpcode .comment { color: #008000; }
.csharpcode .comment2 { color: #808080; }
.csharpcode .type { color: #2B91AF; }
.csharpcode .keyword { color: #0000FF; }
.csharpcode .string { color: #A31515; }
.csharpcode .preproc { color: #0000FF; }
</style>
<br />
<div class="csharpcode">
Code:<br />
<pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; color: black; overflow-x: auto; overflow-y: hidden; padding: 0px; text-align: left; word-wrap: normal;"><span class="keyword">string</span> GetFile(<span class="keyword">string</span> path)
{
<span class="keyword">if</span> (isok(path))
{
<span class="keyword">return</span> System.IO.File.ReadAllText(path);
}
<span class="keyword">else</span>
{
<span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">Exception</span>(<span class="string">"Access denied"</span>);
}
}</pre>
</div>
Maybe the best option is limiting the permissions of the application so it can't access the file, but then what about a web server that needs to hide .htaccess from the user but must be able to read it?<br />
So maybe you choose another option - examining the file path.<br />
For example:<br />
<style type="text/css">
.csharpcode, .csharpcode pre
{
font-size: 13.3333px;
font-width: 400;
color: black;
font-family: "Courier New";
}
.csharpcode pre { margin: 0px; }
.csharpcode .comment { color: #008000; }
.csharpcode .comment2 { color: #808080; }
.csharpcode .type { color: #2B91AF; }
.csharpcode .keyword { color: #0000FF; }
.csharpcode .string { color: #A31515; }
.csharpcode .preproc { color: #0000FF; }
</style>
<br />
<div class="csharpcode">
Code:<br />
<pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; color: black; overflow-x: auto; overflow-y: hidden; padding: 0px; text-align: left; word-wrap: normal;"><span class="keyword">bool</span> isok(<span class="keyword">string</span> path)
{
<span class="keyword">return</span> path != <span class="string">@"c:\secret location\passwords.txt"</span>;
<span class="comment">// THIS CODE IS WRONG</span>
}</pre>
</div>
But then an attacker could use uppercase or mixed to represent the same file:
<style type="text/css">
.csharpcode, .csharpcode pre
{
font-size: 13.3333px;
font-width: 400;
color: black;
font-family: "Courier New";
}
.csharpcode pre { margin: 0px; }
.csharpcode .comment { color: #008000; }
.csharpcode .comment2 { color: #808080; }
.csharpcode .type { color: #2B91AF; }
.csharpcode .keyword { color: #0000FF; }
.csharpcode .string { color: #A31515; }
.csharpcode .preproc { color: #0000FF; }
</style>
<br />
<div class="csharpcode">
Code:<br />
<pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; color: black; overflow-x: auto; overflow-y: hidden; padding: 0px; text-align: left; word-wrap: normal;">GetFile(<span class="string">@"C:\SECRET LOCATION\PASSWORDS.TXT"</span>);
GetFile(<span class="string">@"C:\SeCrEt LoCaTiOn\PaSsWoRdS.TxT"</span>);</pre>
</div>
So maybe this might be a possible fix:
<style type="text/css">
.csharpcode, .csharpcode pre
{
font-size: 13.3333px;
font-width: 400;
color: black;
font-family: "Courier New";
}
.csharpcode pre { margin: 0px; }
.csharpcode .comment { color: #008000; }
.csharpcode .comment2 { color: #808080; }
.csharpcode .type { color: #2B91AF; }
.csharpcode .keyword { color: #0000FF; }
.csharpcode .string { color: #A31515; }
.csharpcode .preproc { color: #0000FF; }
</style>
<br />
<div class="csharpcode">
Code:<br />
<pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; color: black; overflow-x: auto; overflow-y: hidden; padding: 0px; text-align: left; word-wrap: normal;"><span class="keyword">bool</span> isok(<span class="keyword">string</span> path)
{
<span class="keyword">return</span> path.ToLower() != <span class="string">@"c:\secret location\passwords.txt"</span>;
<span class="comment">// THIS CODE IS WRONG</span>
}</pre>
</div>
Unfortunately this code isn't sufficient either, what about:
<style type="text/css">
.csharpcode, .csharpcode pre
{
font-size: 13.3333px;
font-width: 400;
color: black;
font-family: "Courier New";
}
.csharpcode pre { margin: 0px; }
.csharpcode .comment { color: #008000; }
.csharpcode .comment2 { color: #808080; }
.csharpcode .type { color: #2B91AF; }
.csharpcode .keyword { color: #0000FF; }
.csharpcode .string { color: #A31515; }
.csharpcode .preproc { color: #0000FF; }
</style>
<br />
<div class="csharpcode">
Code:<br />
<pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; color: black; overflow-x: auto; overflow-y: hidden; padding: 0px; text-align: left; word-wrap: normal;">GetFile(<span class="string">@"c:\aaaa\..\secret location\passwords.txt"</span>);</pre>
</div>
Note that it works even if aaaa doesn't exist. <br />
This can go on and on. I tried to put some of those "path features" in the following list.<br />
<br />
<ol>
<li>Normal: @"c:\secret location\passwords.txt"</li>
<li>Upper/lower case: @"<span style="color: red;">C</span>:\<span style="color: red;">S</span>ecret <span style="color: red;">L</span>ocation\<span style="color: red;">P</span>asswords.<span style="color: red;">T</span>x<span style="color: red;">T</span>"</li>
<li> Parent directory: @"c:\<span style="color: red;">aaa\..\</span>secret location\passwords.txt"</li>
<li>Current directory: @"c:\<span style="color: red;">.\</span>secret location\passwords.txt"</li>
<li>Current file: @"c:\secret location\passwords.txt<span style="color: red;">\.</span>"</li>
<li>Spaces: @"c:\secret location\passwords.txt<span style="color: red;"> "</span></li>
<li>Dots: @"c:\secret location\passwords.txt<span style="color: red;">....</span>"</li>
<li>Network share: @"<span style="color: red;">\\localhost\c$</span>\secret location\passwords.txt" <br />or <ip_address> or <computer_name> or 127.0.0.1</li>
<li>Long path prefix: @"<span style="color: red;">\\?\</span>c:\secret location\passwords.txt"</li>
<li>MS-DOS style: @"C:\SECRET<span style="color: red;">~1</span>\PASSWO<span style="color: red;">~1</span>.TXT"</li>
<li>Relative path: @"<span style="color: red;">c:</span>secret location\passwords.txt"<br />(Works if current directory is c:\, otherwise need to add ..)</li>
<li>Win32 device: @"<span style="color: red;">\\.\</span>c:\secret location\passwords.txt"</li>
<li>Long UNC: @"<span style="color: red;">\\?\UNC\localhost\c$\</span>secret location\passwords.txt"</li>
<li><a href="http://www.think-techie.com/2010/04/alternate-data-streams.html">ADS</a>: @"c:\secret location\passwords.txt<span style="color: red;">::$DATA</span>"</li>
<li>Unix style: @"<span style="color: red;">c:/</span>secret location\passwords.txt"</li>
</ol>
Go on, try some of them!<br />
There are probably many more ways that aren't on that list. <br />
For conclusion, restricting access to a file simply by examining the input path is probably a bad idea. An alternative better solution should be chosen depending on the project requirements.ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com0tag:blogger.com,1999:blog-368378466834354558.post-84885692329598812212010-12-07T14:51:00.000-08:002010-12-07T14:51:21.293-08:00OpenLayers map + markers + cool info boxI made a little project for my father (in return he pays for my piano lessons).<br />
My father is one of the managers of the folk dance society in Israel. They have a <a href="http://www.harokdim.org/">website</a>, where all dancing clubs are listed, including relevant information such as place, time, price, type of music, ...<br />
He wanted a map where someone could see all dancing places near his/her home.<br />
Google Maps would have been a natural choice hadn't they <a href="http://groups.google.com/group/google-maps-api-for-flash/browse_thread/thread/f6aebea55754b6b9?pli=1">forbidden</a> access to their API specifically for Israel.<br />
I found a great alternative: <a href="http://openlayers.org/">OpenLayes</a>, which uses data from <a href="http://www.openstreetmap.org/">OpenStreetMap</a>.<br />
I'm all excited because I know nothing about JavaScript and CSS but eventually it worked! <br />
Well, here it is:<br />
<iframe height="300" src="http://www.harokdim.com/map.php" width="100%">&amp;lt;p&amp;gt;&amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;br /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;Your browser does not support iframes.&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;gt;&amp;lt;/p&amp;gt;</iframe><br />
<br />
Things to notice:<br />
<ul><li>The info box is half transparent</li>
<li>It has round corners</li>
<li>When you click a place, the info box sticks, so you can follow the links</li>
</ul>ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com0tag:blogger.com,1999:blog-368378466834354558.post-66277978244751647162010-09-24T17:37:00.000-07:002010-09-24T17:37:31.837-07:00C#: How to bypass firewallFirewalls like ZoneAlarm are supposed to be able to block outgoing connections of unknown programs. So for example, if I was careless and installed a malware, then at least it won't be able to send my passwords list to someone over the internet.<br />
Couple of years ago I tried to think about how to bypass that, and after a while I came up with this simple trick that works regardless of the firewall software, i.e. it does not alter the firewall.<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEMilehIUefggZRkI9PcsD_7T7kWQ2l0B2QPIErY0NidFbP3oJb2fOoJ6_bGs_ZIJoVU11mzPiQiPMmJjO4c__ZBkpaDl6TKqNER0j8iqU2ZIbgLpGMbUdUAmStkvsfo9B8o6KeAVFomU/s1600/zonealarm2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="336" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEMilehIUefggZRkI9PcsD_7T7kWQ2l0B2QPIErY0NidFbP3oJb2fOoJ6_bGs_ZIJoVU11mzPiQiPMmJjO4c__ZBkpaDl6TKqNER0j8iqU2ZIbgLpGMbUdUAmStkvsfo9B8o6KeAVFomU/s400/zonealarm2.png" width="400" /></a></div>Many users use Internet Explorer, so usually it has access through the firewall by default. It only remains to take control over it from C#, and that's exactly what I did using this magical API function: <span style="font-family: "Courier New",Courier,monospace;">ObjectFromLresult</span>. It might be funny to see a trojan horse written entirely using GET requests, but on the other hand it scares me a little bit because for example ZoneAlarm and AVG couldn't detect it.<br />
I wrote a small C# application to prove my point. You can download it from here:<br />
<a href="http://www.megaupload.com/?d=9W17LLP4">http://www.megaupload.com/?d=9W17LLP4</a><br />
It has 2 buttons: the first button attempts to make a normal <span style="font-family: "Courier New",Courier,monospace;">HttpWebRequest</span>, and tells you whether it succeeded or failed. If it failed, then probably your firewall is blocking the application. In that case you may want to try the second button. <br />
<div class="separator" style="clear: both; text-align: center;"></div>This is the code that creates a new Internet Explorer instance and gets the DOM object from it:<br />
(I found it on the internet) <br />
<style type="text/css">
.csharpcode, .csharpcode pre
{
font-size: 13.3333px;
font-width: 400;
color: black;
font-family: "Courier New";
}
.csharpcode pre { margin: 0px; }
.csharpcode .comment { color: #008000; }
.csharpcode .comment2 { color: #808080; }
.csharpcode .type { color: #2B91AF; }
.csharpcode .keyword { color: #0000FF; }
.csharpcode .string { color: #A31515; }
.csharpcode .preproc { color: #0000FF; }
</style><br />
<div class="csharpcode">Code:<br />
<pre style="background: none repeat scroll 0% 0% rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); color: black; overflow-x: auto; overflow-y: hidden; padding: 0px; text-align: left; word-wrap: normal;">[<span class="type">DllImport</span>(<span class="string">"user32.dll"</span>, <span class="type">EntryPoint</span> = <span class="string">"GetClassNameA"</span>)]
<span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">extern</span> <span class="keyword">int</span> GetClassName(<span class="type">IntPtr</span> hwnd, <span class="type">StringBuilder</span> lpClassName, <span class="keyword">int</span> nMaxCount);
<span class="keyword">public</span> <span class="keyword">delegate</span> <span class="keyword">int</span> EnumProc(<span class="type">IntPtr</span> hWnd, <span class="keyword">ref</span> <span class="type">IntPtr</span> lParam);
[<span class="type">DllImport</span>(<span class="string">"user32.dll"</span>)]
<span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">extern</span> <span class="keyword">int</span> EnumChildWindows(<span class="type">IntPtr</span> hWndParent, <span class="type">EnumProc</span> lpEnumFunc, <span class="keyword">ref</span> <span class="type">IntPtr</span> lParam);
[<span class="type">DllImport</span>(<span class="string">"user32.dll"</span>, <span class="type">EntryPoint</span> = <span class="string">"RegisterWindowMessageA"</span>)]
<span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">extern</span> <span class="keyword">int</span> RegisterWindowMessage(<span class="keyword">string</span> lpString);
[<span class="type">DllImport</span>(<span class="string">"user32.dll"</span>, <span class="type">EntryPoint</span> = <span class="string">"SendMessageTimeoutA"</span>)]
<span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">extern</span> <span class="keyword">int</span> SendMessageTimeout(<span class="type">IntPtr</span> hwnd, <span class="keyword">int</span> msg, <span class="keyword">int</span> wParam, <span class="keyword">int</span> lParam, <span class="keyword">int</span> fuFlags, <span class="keyword">int</span> uTimeout, <span class="keyword">out</span> <span class="keyword">int</span> lpdwResult);
[<span class="type">DllImport</span>(<span class="string">"OLEACC.dll"</span>)]
<span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">extern</span> <span class="keyword">int</span> ObjectFromLresult(<span class="keyword">int</span> lResult, <span class="keyword">ref</span> <span class="type">Guid</span> riid, <span class="keyword">int</span> wParam, <span class="keyword">ref</span> <span class="type">IHTMLDocument2</span> ppvObject);
<span class="keyword">public</span> <span class="keyword">const</span> <span class="keyword">int</span> SMTO_ABORTIFHUNG = 0x2;
<span class="keyword">public</span> <span class="type">Guid</span> IID_IHTMLDocument = <span class="keyword">typeof</span>(mshtml.<span class="type">IHTMLDocument</span>).GUID;
<span class="keyword">public</span> <span class="type">Process</span> process = <span class="keyword">null</span>;
<span class="keyword">public</span> <span class="type">IHTMLDocument2</span> document;
<span class="keyword">public</span> <span class="type">IHTMLDocument2</span> documentFromDOM(<span class="keyword">string</span> url)
{
process = <span class="keyword">new</span> <span class="type">Process</span>();
process.StartInfo.FileName = <span class="string">"iexplore.exe"</span>;
process.StartInfo.WindowStyle = <span class="type">ProcessWindowStyle</span>.Minimized;
process.StartInfo.Arguments = url;
process.Start();
<span class="type">IntPtr</span> hWnd = <span class="type">IntPtr</span>.Zero;
<span class="keyword">do</span>
{
<span class="type">Thread</span>.Sleep(3000);
} <span class="keyword">while</span> ((hWnd = process.MainWindowHandle) == <span class="type">IntPtr</span>.Zero);
<span class="keyword">int</span> lngMsg = 0;
<span class="keyword">int</span> lRes;
<span class="type">IntPtr</span> document_hWnd;
<span class="type">EnumProc</span> proc = <span class="keyword">new</span> <span class="type">EnumProc</span>(EnumWindows);
EnumChildWindows(hWnd, proc, <span class="keyword">ref</span> hWnd);
<span class="keyword">if</span> (!hWnd.Equals(<span class="type">IntPtr</span>.Zero))
{
lngMsg = RegisterWindowMessage(<span class="string">"WM_HTML_GETOBJECT"</span>);
<span class="keyword">if</span> (lngMsg != 0)
{
SendMessageTimeout(hWnd, lngMsg, 0, 0, SMTO_ABORTIFHUNG, 1000, <span class="keyword">out</span> lRes);
<span class="keyword">if</span> (!(<span class="keyword">bool</span>)(lRes == 0))
{
document_hWnd = hWnd;
<span class="keyword">int</span> hr = ObjectFromLresult(lRes, <span class="keyword">ref</span> IID_IHTMLDocument, 0, <span class="keyword">ref</span> document);
<span class="keyword">if</span> (document == <span class="keyword">null</span>)
{
<span class="type">MessageBox</span>.Show(<span class="string">"No IHTMLDocument Found!"</span>);
}
}
}
}
<span class="keyword">return</span> document;
}
<span class="keyword">public</span> <span class="keyword">int</span> EnumWindows(<span class="type">IntPtr</span> hWnd, <span class="keyword">ref</span> <span class="type">IntPtr</span> lParam)
{
<span class="keyword">int</span> retVal = 1;
<span class="type">StringBuilder</span> classname = <span class="keyword">new</span> <span class="type">StringBuilder</span>(128);
GetClassName(hWnd, classname, classname.Capacity);
<span class="keyword">if</span> (classname.ToString() == <span class="string">"Internet Explorer_Server"</span>)
{
lParam = hWnd;
retVal = 0;
}
<span class="keyword">return</span> retVal;
}</pre></div><br />
<i><b>Notes:</b></i><br />
The user can see the Internet Explorer at the taskbar, and the Thread.Sleep is weird, but both can be fixed sometime.ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com0tag:blogger.com,1999:blog-368378466834354558.post-16379593460392721262010-08-28T04:22:00.000-07:002010-08-28T04:22:15.450-07:00C#: Camera MatrixI always wanted to know how a 3D engine works. I've used DirectX several times before, but I never quite understood what's going on behind the scene.<br />
So, I decided to write a small naive 3D engine of my own, just to understand how it works.<br />
I studied about the subject, and wrote this engine, which is basically a camera matrix: (no textures or anything)<br />
<a href="http://www.megaupload.com/?d=6YON627Z">http://www.megaupload.com/?d=6YON627Z</a> <br />
The only external graphics function I used is the Graphics.DrawLine() function. <br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD4cpo-bulu9LhoqVAgutyvXalMo1m6Fvs9yGsuN3KTEwyDNarvQiDb69HtIccaKGLWZte01xLnWXrVuumejCOBtQVlO-16dDxmcGSbhcwa_zW8ApyVebPZBNjDpF9F3A827zYcAkubcI/s1600/CameraMatrix.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD4cpo-bulu9LhoqVAgutyvXalMo1m6Fvs9yGsuN3KTEwyDNarvQiDb69HtIccaKGLWZte01xLnWXrVuumejCOBtQVlO-16dDxmcGSbhcwa_zW8ApyVebPZBNjDpF9F3A827zYcAkubcI/s320/CameraMatrix.png" /></a></div><br />
<i><b>What is a Camera Matrix anyway?</b></i><br />
It's something that can be used to display 3D objects on our 2D screen.<br />
Think about a real camera like in a 2D movie (not Avatar) - you place it somewhere in the room (translation), it looks towards the scene (rotation), it can zoom in and out (scaling), and it converts the 3D scene to 2D (projection).<br />
From now on we say "translation" instead of "position". Mathematicians are to blame for that.<br />
<br />
<i><b>It's easy to do operations on vectors, why complicate things with Matrices?</b></i><br />
One of the main reasons is that matrices can be easily <a href="http://en.wikipedia.org/wiki/Matrix_multiplication">concatenated</a>.<br />
<a href="http://msdn.microsoft.com/en-us/library/bb153310%28VS.85%29.aspx">From DirectX MSDN:</a><br />
<blockquote>One advantage of using matrices is that you can combine the effects of two or more matrices by multiplying them. This means that, to rotate a model and then translate it to some location, you do not need to apply two matrices. Instead, you multiply the rotation and translation matrices to produce a composite matrix that contains all of their effects.</blockquote>Let me put it this way:<br />
"Using" a 4x4 matrix requires 16 multiplications and 9 additions.<br />
So rotating, which is "using" a rotation matrix, requires 16 multiplications and 9 additions.<br />
And scaling also requires 16 multiplications and 9 additions.<br />
If we do rotating and then scaling it would take 32 multiplications and 18 additions. Translation would takes us up to 48 multiplications and 27 additions, and so on...<br />
<b>BUT</b>, if we <i>concatenate</i> the rotation and scaling matrices, we will get a third matrix that does both operations in half the time (16 multiplications and 9 additions).<br />
In fact, we could concatenate any number of matrices, so the resulting matrix will do all the operations we want in only 16 multiplications and 9 additions.<br />
You might have noticed that we still need to do the concatenation operation which takes a long time, but it's worth it when you design a 3D game with thousands and thousands of objects to scale rotate translate etc. but only a few matrices to concatenate.<br />
<br />
<i><b>Why a Camera Matrix is not 3x3?</b></i><br />
In short, because then we can't use it for translation (moving the vectors).<br />
For more details read this fantastic article:<br />
<a href="http://www.geometer.org/mathcircles/cghomogen.pdf">http://www.geometer.org/mathcircles/cghomogen.pdf</a>ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com3tag:blogger.com,1999:blog-368378466834354558.post-13884069008429761532010-08-28T02:09:00.000-07:002010-08-28T02:09:21.517-07:00C#: Matrix and Vector RepresentationIn C# there are built in representations of 2D points and 2x2 matrices.<br />
This is good enough for image processing, but I needed more than that for 3D graphics.<br />
<br />
I wrote classes for:<br />
<ul><li>3D vector</li>
<li>3x3 matrix</li>
<li>4x4 matrix</li>
<li>Any size matrix</li>
</ul>All the first three objects can be represented by "Any size matrix", but it is much more efficient to use the specific class you need.<br />
<style type="text/css">
.csharpcode, .csharpcode pre
{
font-size: 13.3333px;
font-width: 400;
color: black;
font-family: "Courier New";
}
.csharpcode pre { margin: 0px; }
.csharpcode .comment { color: #008000; }
.csharpcode .comment2 { color: #808080; }
.csharpcode .type { color: #2B91AF; }
.csharpcode .keyword { color: #0000FF; }
.csharpcode .string { color: #A31515; }
.csharpcode .preproc { color: #0000FF; }
</style><br />
<div class="csharpcode">Code:<br />
<pre style="background: none repeat scroll 0% 0% rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); color: black; overflow-x: auto; overflow-y: hidden; padding: 0px; text-align: left; word-wrap: normal;"><span class="keyword">class</span> <span class="type">Vector3</span>
{
<span class="keyword">public</span> <span class="keyword">static</span> <span class="type">Vector3</span> Zero = NewZero();
<span class="keyword">public</span> <span class="keyword">static</span> <span class="type">Vector3</span> One = NewOne();
<span class="keyword">public</span> <span class="keyword">float</span> x;
<span class="keyword">public</span> <span class="keyword">float</span> y;
<span class="keyword">public</span> <span class="keyword">float</span> z;
<span class="keyword">public</span> Vector3()
{
x = 0.0f;
y = 0.0f;
z = 0.0f;
}
<span class="keyword">public</span> Vector3(<span class="keyword">float</span> x, <span class="keyword">float</span> y, <span class="keyword">float</span> z)
{
<span class="keyword">this</span>.x = x;
<span class="keyword">this</span>.y = y;
<span class="keyword">this</span>.z = z;
}
<span class="keyword">public</span> Vector3(<span class="keyword">float</span> xyz)
{
<span class="keyword">this</span>.x = xyz;
<span class="keyword">this</span>.y = xyz;
<span class="keyword">this</span>.z = xyz;
}
<span class="keyword">public</span> Vector3(<span class="type">Vector3</span> v)
{
<span class="keyword">this</span>.x = v.x;
<span class="keyword">this</span>.y = v.y;
<span class="keyword">this</span>.z = v.z;
}
<span class="keyword">public</span> <span class="keyword">static</span> <span class="type">Vector3</span> NewZero()
{
<span class="keyword">return</span> <span class="keyword">new</span> <span class="type">Vector3</span>(0.0f);
}
<span class="keyword">public</span> <span class="keyword">static</span> <span class="type">Vector3</span> NewOne()
{
<span class="keyword">return</span> <span class="keyword">new</span> <span class="type">Vector3</span>(1.0f);
}
<span class="keyword">public</span> <span class="keyword">float</span> DotProduct(<span class="type">Vector3</span> other)
{
<span class="keyword">return</span> x * other.x + y * other.y + z * other.z;
}
<span class="keyword">public</span> <span class="keyword">static</span> Vector3 <span class="keyword">operator</span> +(<span class="type">Vector3</span> v1, <span class="type">Vector3</span> v2)
{
<span class="keyword">return</span> <span class="keyword">new</span> <span class="type">Vector3</span>(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
}
<span class="keyword">public</span> <span class="keyword">static</span> Vector3 <span class="keyword">operator</span> -(<span class="type">Vector3</span> v1, <span class="type">Vector3</span> v2)
{
<span class="keyword">return</span> <span class="keyword">new</span> <span class="type">Vector3</span>(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
}
<span class="keyword">public</span> <span class="keyword">static</span> Vector3 <span class="keyword">operator</span> -(<span class="type">Vector3</span> v)
{
<span class="keyword">return</span> <span class="keyword">new</span> <span class="type">Vector3</span>(-v.x, -v.y, -v.z);
}
<span class="keyword">public</span> <span class="keyword">static</span> Vector3 <span class="keyword">operator</span> *(<span class="type">Vector3</span> v, <span class="keyword">float</span> scalar)
{
<span class="keyword">return</span> <span class="keyword">new</span> <span class="type">Vector3</span>(v.x * scalar, v.y * scalar, v.z * scalar);
}
<span class="keyword">public</span> <span class="keyword">static</span> Vector3 <span class="keyword">operator</span> /(<span class="type">Vector3</span> v, <span class="keyword">float</span> scalar)
{
<span class="keyword">return</span> <span class="keyword">new</span> <span class="type">Vector3</span>(v.x / scalar, v.y / scalar, v.z / scalar);
}
<span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">bool</span> <span class="keyword">operator</span> ==(<span class="type">Vector3</span> v1, <span class="type">Vector3</span> v2)
{
<span class="keyword">return</span> v1.x == v2.x && v1.y == v2.y && v1.z == v2.z;
}
<span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">bool</span> <span class="keyword">operator</span> !=(<span class="type">Vector3</span> v1, <span class="type">Vector3</span> v2)
{
<span class="keyword">return</span> v1.x != v2.x || v1.y != v2.y || v1.z != v2.z;
}
<span class="keyword">public</span> <span class="keyword">static</span> <span class="type">Vector3</span> CrossProduct(<span class="type">Vector3</span> a, <span class="type">Vector3</span> b)
{
<span class="keyword">return</span> <span class="keyword">new</span> <span class="type">Vector3</span>(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
}
<span class="keyword">public</span> <span class="type">Vector3</span> Add(<span class="type">Vector3</span> v)
{
x += v.x;
y += v.y;
z += v.z;
<span class="keyword">return</span> <span class="keyword">this</span>;
}
<span class="keyword">public</span> <span class="keyword">float</span> DistanceTo(<span class="type">Vector3</span> v)
{
<span class="keyword">float</span> dx = <span class="keyword">this</span>.x - v.x;
<span class="keyword">float</span> dy = <span class="keyword">this</span>.y - v.y;
<span class="keyword">float</span> dz = <span class="keyword">this</span>.z - v.z;
<span class="keyword">return</span> (<span class="keyword">float</span>)<span class="type">Math</span>.Sqrt(dx * dx + dy * dy + dz * dz);
}
<span class="keyword">public</span> <span class="keyword">float</span> Size()
{
<span class="keyword">return</span> DistanceTo(<span class="type">Vector3</span>.Zero);
}
<span class="keyword">public</span> <span class="type">Vector3</span> Normalize()
{
<span class="keyword">float</span> size = <span class="type">Size</span>();
<span class="keyword">this</span>.x /= size;
<span class="keyword">this</span>.y /= size;
<span class="keyword">this</span>.z /= size;
<span class="keyword">return</span> <span class="keyword">this</span>;
}
<span class="keyword">public</span> <span class="type">Vector3</span> Clone()
{
<span class="keyword">return</span> <span class="keyword">new</span> <span class="type">Vector3</span>(<span class="keyword">this</span>);
}
<span class="keyword">public</span> <span class="keyword">override</span> <span class="keyword">string</span> ToString()
{
<span class="keyword">return</span> <span class="string">"("</span> + x + <span class="string">", "</span> + y + <span class="string">", "</span> + z + <span class="string">")"</span>;
}
}
<span class="keyword">class</span> <span class="type">Matrix</span>
{
<span class="keyword">public</span> <span class="keyword">float</span>[,] matrix;
<span class="keyword">public</span> <span class="keyword">int</span> rows;
<span class="keyword">public</span> <span class="keyword">int</span> cols;
<span class="keyword">public</span> Matrix(<span class="keyword">int</span> rows, <span class="keyword">int</span> cols)
{
<span class="keyword">this</span>.matrix = <span class="keyword">new</span> <span class="keyword">float</span>[rows, cols];
<span class="keyword">this</span>.rows = rows;
<span class="keyword">this</span>.cols = cols;
}
<span class="keyword">public</span> Matrix(<span class="keyword">float</span>[,] matrix)
{
<span class="keyword">this</span>.matrix = matrix;
<span class="keyword">this</span>.rows = matrix.GetLength(0);
<span class="keyword">this</span>.cols = matrix.GetLength(1);
}
<span class="keyword">protected</span> <span class="keyword">static</span> <span class="keyword">float</span>[,] Multiply(<span class="type">Matrix</span> matrix, <span class="keyword">float</span> scalar)
{
<span class="keyword">int</span> rows = matrix.rows;
<span class="keyword">int</span> cols = matrix.cols;
<span class="keyword">float</span>[,] m1 = matrix.matrix;
<span class="keyword">float</span>[,] m2 = <span class="keyword">new</span> <span class="keyword">float</span>[rows, cols];
<span class="keyword">for</span> (<span class="keyword">int</span> i = 0; i < rows; ++i)
{
<span class="keyword">for</span> (<span class="keyword">int</span> j = 0; j < cols; ++j)
{
m2[i, j] = m1[i, j] * scalar;
}
}
<span class="keyword">return</span> m2;
}
<span class="keyword">protected</span> <span class="keyword">static</span> <span class="keyword">float</span>[,] Multiply(<span class="type">Matrix</span> matrix1, <span class="type">Matrix</span> matrix2)
{
<span class="keyword">int</span> m1rows = matrix1.rows;
<span class="keyword">int</span> m1cols = matrix1.cols;
<span class="keyword">int</span> m2rows = matrix2.rows;
<span class="keyword">int</span> m2cols = matrix2.cols;
<span class="keyword">if</span> (m1cols != m2rows)
{
<span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">ArgumentException</span>();
}
<span class="keyword">float</span>[,] m1 = matrix1.matrix;
<span class="keyword">float</span>[,] m2 = matrix2.matrix;
<span class="keyword">float</span>[,] m3 = <span class="keyword">new</span> <span class="keyword">float</span>[m1rows, m2cols];
<span class="keyword">for</span> (<span class="keyword">int</span> i = 0; i < m1rows; ++i)
{
<span class="keyword">for</span> (<span class="keyword">int</span> j = 0; j < m2cols; ++j)
{
<span class="keyword">float</span> sum = 0;
<span class="keyword">for</span> (<span class="keyword">int</span> it = 0; it < m1cols; ++it)
{
sum += m1[i, it] * m2[it, j];
}
m3[i, j] = sum;
}
}
<span class="keyword">return</span> m3;
}
<span class="keyword">public</span> <span class="keyword">static</span> Matrix <span class="keyword">operator</span> *(<span class="type">Matrix</span> m, <span class="keyword">float</span> scalar)
{
<span class="keyword">return</span> <span class="keyword">new</span> <span class="type">Matrix</span>(Multiply(m, scalar));
}
<span class="keyword">public</span> <span class="keyword">static</span> Matrix <span class="keyword">operator</span> *(<span class="type">Matrix</span> m1, <span class="type">Matrix</span> m2)
{
<span class="keyword">return</span> <span class="keyword">new</span> <span class="type">Matrix</span>(Multiply(m1, m2));
}
<span class="keyword">public</span> <span class="keyword">override</span> <span class="keyword">string</span> ToString()
{
<span class="keyword">string</span> res = <span class="string">""</span>;
<span class="keyword">for</span> (<span class="keyword">int</span> i = 0; i < rows; ++i)
{
<span class="keyword">if</span> (i > 0)
{
res += <span class="string">"|"</span>;
}
<span class="keyword">for</span> (<span class="keyword">int</span> j = 0; j < cols; ++j)
{
<span class="keyword">if</span> (j > 0)
{
res += <span class="string">","</span>;
}
res += matrix[i, j];
}
}
<span class="keyword">return</span> <span class="string">"("</span> + res + <span class="string">")"</span>;
}
}
<span class="keyword">class</span> <span class="type">Matrix3</span> : <span class="type">Matrix</span>
{
<span class="keyword">public</span> Matrix3()
: <span class="keyword">base</span>(3, 3)
{
}
<span class="keyword">public</span> Matrix3(<span class="keyword">float</span>[,] matrix)
: <span class="keyword">base</span>(matrix)
{
<span class="keyword">if</span> (rows != 3 || cols != 3)
{
<span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">ArgumentException</span>();
}
}
<span class="keyword">public</span> <span class="keyword">static</span> <span class="type">Matrix3</span> I()
{
<span class="keyword">return</span> <span class="keyword">new</span> <span class="type">Matrix3</span>(<span class="keyword">new</span> <span class="keyword">float</span>[,] {
{ 1.0f, 0.0f, 0.0f },
{ 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f } });
}
<span class="keyword">public</span> <span class="keyword">static</span> Vector3 <span class="keyword">operator</span> *(<span class="type">Matrix3</span> matrix3, <span class="type">Vector3</span> v)
{
<span class="keyword">float</span>[,] m = matrix3.matrix;
<span class="keyword">return</span> <span class="keyword">new</span> <span class="type">Vector3</span>(
m[0, 0] * v.x + m[0, 1] * v.y + m[0, 2] * v.z,
m[1, 0] * v.x + m[1, 1] * v.y + m[1, 2] * v.z,
m[2, 0] * v.x + m[2, 1] * v.y + m[2, 2] * v.z);
}
<span class="keyword">public</span> <span class="keyword">static</span> Matrix3 <span class="keyword">operator</span> *(<span class="type">Matrix3</span> mat1, <span class="type">Matrix3</span> mat2)
{
<span class="keyword">float</span>[,] m1 = mat1.matrix;
<span class="keyword">float</span>[,] m2 = mat2.matrix;
<span class="keyword">float</span>[,] m3 = <span class="keyword">new</span> <span class="keyword">float</span>[3, 3];
m3[0, 0] = m1[0, 0] * m2[0, 0] + m1[0, 1] * m2[1, 0] + m1[0, 2] * m2[2, 0];
m3[0, 1] = m1[0, 0] * m2[0, 1] + m1[0, 1] * m2[1, 1] + m1[0, 2] * m2[2, 1];
m3[0, 2] = m1[0, 0] * m2[0, 2] + m1[0, 1] * m2[1, 2] + m1[0, 2] * m2[2, 2];
m3[1, 0] = m1[1, 0] * m2[0, 0] + m1[1, 1] * m2[1, 0] + m1[1, 2] * m2[2, 0];
m3[1, 1] = m1[1, 0] * m2[0, 1] + m1[1, 1] * m2[1, 1] + m1[1, 2] * m2[2, 1];
m3[1, 2] = m1[1, 0] * m2[0, 2] + m1[1, 1] * m2[1, 2] + m1[1, 2] * m2[2, 2];
m3[2, 0] = m1[2, 0] * m2[0, 0] + m1[2, 1] * m2[1, 0] + m1[2, 2] * m2[2, 0];
m3[2, 1] = m1[2, 0] * m2[0, 1] + m1[2, 1] * m2[1, 1] + m1[2, 2] * m2[2, 1];
m3[2, 2] = m1[2, 0] * m2[0, 2] + m1[2, 1] * m2[1, 2] + m1[2, 2] * m2[2, 2];
<span class="keyword">return</span> <span class="keyword">new</span> <span class="type">Matrix3</span>(m3);
}
<span class="keyword">public</span> <span class="keyword">static</span> Matrix3 <span class="keyword">operator</span> *(<span class="type">Matrix3</span> m, <span class="keyword">float</span> scalar)
{
<span class="keyword">return</span> <span class="keyword">new</span> <span class="type">Matrix3</span>(Multiply(m, scalar));
}
}
<span class="keyword">class</span> <span class="type">Matrix4</span> : <span class="type">Matrix</span>
{
<span class="keyword">public</span> <span class="keyword">static</span> <span class="type">Matrix4</span> I = NewI();
<span class="keyword">public</span> Matrix4()
: <span class="keyword">base</span>(4, 4)
{
}
<span class="keyword">public</span> Matrix4(<span class="keyword">float</span>[,] matrix)
: <span class="keyword">base</span>(matrix)
{
<span class="keyword">if</span> (rows != 4 || cols != 4)
{
<span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">ArgumentException</span>();
}
}
<span class="keyword">public</span> <span class="keyword">static</span> <span class="type">Matrix4</span> NewI()
{
<span class="keyword">return</span> <span class="keyword">new</span> <span class="type">Matrix4</span>(<span class="keyword">new</span> <span class="keyword">float</span>[,] {
{ 1.0f, 0.0f, 0.0f, 0.0f },
{ 0.0f, 1.0f, 0.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f } });
}
<span class="keyword">public</span> <span class="keyword">static</span> Vector3 <span class="keyword">operator</span> *(<span class="type">Matrix4</span> matrix4, <span class="type">Vector3</span> v)
{
<span class="keyword">float</span>[,] m = matrix4.matrix;
<span class="keyword">float</span> w = m[3, 0] * v.x + m[3, 1] * v.y + m[3, 2] * v.z + m[3, 3];
<span class="keyword">return</span> <span class="keyword">new</span> <span class="type">Vector3</span>(
(m[0, 0] * v.x + m[0, 1] * v.y + m[0, 2] * v.z + m[0, 3]) / w,
(m[1, 0] * v.x + m[1, 1] * v.y + m[1, 2] * v.z + m[1, 3]) / w,
(m[2, 0] * v.x + m[2, 1] * v.y + m[2, 2] * v.z + m[2, 3]) / w
);
}
<span class="keyword">public</span> <span class="keyword">static</span> Matrix4 <span class="keyword">operator</span> *(<span class="type">Matrix4</span> mat1, <span class="type">Matrix4</span> mat2)
{
<span class="keyword">float</span>[,] m1 = mat1.matrix;
<span class="keyword">float</span>[,] m2 = mat2.matrix;
<span class="keyword">float</span>[,] m3 = <span class="keyword">new</span> <span class="keyword">float</span>[4, 4];
m3[0, 0] = m1[0, 0] * m2[0, 0] + m1[0, 1] * m2[1, 0] + m1[0, 2] * m2[2, 0] + m1[0, 3] * m2[3, 0];
m3[0, 1] = m1[0, 0] * m2[0, 1] + m1[0, 1] * m2[1, 1] + m1[0, 2] * m2[2, 1] + m1[0, 3] * m2[3, 1];
m3[0, 2] = m1[0, 0] * m2[0, 2] + m1[0, 1] * m2[1, 2] + m1[0, 2] * m2[2, 2] + m1[0, 3] * m2[3, 2];
m3[0, 3] = m1[0, 0] * m2[0, 3] + m1[0, 1] * m2[1, 3] + m1[0, 2] * m2[2, 3] + m1[0, 3] * m2[3, 3];
m3[1, 0] = m1[1, 0] * m2[0, 0] + m1[1, 1] * m2[1, 0] + m1[1, 2] * m2[2, 0] + m1[1, 3] * m2[3, 0];
m3[1, 1] = m1[1, 0] * m2[0, 1] + m1[1, 1] * m2[1, 1] + m1[1, 2] * m2[2, 1] + m1[1, 3] * m2[3, 1];
m3[1, 2] = m1[1, 0] * m2[0, 2] + m1[1, 1] * m2[1, 2] + m1[1, 2] * m2[2, 2] + m1[1, 3] * m2[3, 2];
m3[1, 3] = m1[1, 0] * m2[0, 3] + m1[1, 1] * m2[1, 3] + m1[1, 2] * m2[2, 3] + m1[1, 3] * m2[3, 3];
m3[2, 0] = m1[2, 0] * m2[0, 0] + m1[2, 1] * m2[1, 0] + m1[2, 2] * m2[2, 0] + m1[2, 3] * m2[3, 0];
m3[2, 1] = m1[2, 0] * m2[0, 1] + m1[2, 1] * m2[1, 1] + m1[2, 2] * m2[2, 1] + m1[2, 3] * m2[3, 1];
m3[2, 2] = m1[2, 0] * m2[0, 2] + m1[2, 1] * m2[1, 2] + m1[2, 2] * m2[2, 2] + m1[2, 3] * m2[3, 2];
m3[2, 3] = m1[2, 0] * m2[0, 3] + m1[2, 1] * m2[1, 3] + m1[2, 2] * m2[2, 3] + m1[2, 3] * m2[3, 3];
m3[3, 0] = m1[3, 0] * m2[0, 0] + m1[3, 1] * m2[1, 0] + m1[3, 2] * m2[2, 0] + m1[3, 3] * m2[3, 0];
m3[3, 1] = m1[3, 0] * m2[0, 1] + m1[3, 1] * m2[1, 1] + m1[3, 2] * m2[2, 1] + m1[3, 3] * m2[3, 1];
m3[3, 2] = m1[3, 0] * m2[0, 2] + m1[3, 1] * m2[1, 2] + m1[3, 2] * m2[2, 2] + m1[3, 3] * m2[3, 2];
m3[3, 3] = m1[3, 0] * m2[0, 3] + m1[3, 1] * m2[1, 3] + m1[3, 2] * m2[2, 3] + m1[3, 3] * m2[3, 3];
<span class="keyword">return</span> <span class="keyword">new</span> <span class="type">Matrix4</span>(m3);
}
<span class="keyword">public</span> <span class="keyword">static</span> Matrix4 <span class="keyword">operator</span> *(<span class="type">Matrix4</span> m, <span class="keyword">float</span> scalar)
{
<span class="keyword">return</span> <span class="keyword">new</span> <span class="type">Matrix4</span>(Multiply(m, scalar));
}
}</pre></div>ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com6tag:blogger.com,1999:blog-368378466834354558.post-54764285285681236802010-08-28T01:49:00.000-07:002010-08-28T02:17:16.134-07:00C#: Rotation Matrix<a href="http://en.wikipedia.org/wiki/Rotation_matrix">Rotation matrices</a> are used in 3D graphics to rotate vectors.<br />
I use <a href="http://en.wikipedia.org/wiki/Homogeneous_coordinates">homogeneous coordinates</a>, so the matrices are 4x4. If you want 3x3, just remove the last column and last row.<br />
I wrote several functions:<br />
<ul><li>Rotation around X axis</li>
<li>Rotation around Y axis</li>
<li>Rotation around Z axis</li>
<li>Rotation around all axes</li>
<li>Rotation around any given axis</li>
<li>Rotation from normal vector to normal vector</li>
</ul><b>Apparently</b> the 5th function is enough, because for example "Rotation around X axis" can be replace by rotation around (1,0,0), and "Rotation around all axes" is merely the product of 3 matrices. <b>BUT</b>, one should use the specific function he or she needs, because it is more efficient.<br />
For matrix operations you can use <a href="http://ycouriel.blogspot.com/2010/08/c-matrix-and-vector-representation.html">this post</a>.<br />
<style type="text/css">
.csharpcode, .csharpcode pre
{
font-size: 13.3333px;
font-width: 400;
color: black;
font-family: "Courier New";
}
.csharpcode pre { margin: 0px; }
.csharpcode .comment { color: #008000; }
.csharpcode .comment2 { color: #808080; }
.csharpcode .type { color: #2B91AF; }
.csharpcode .keyword { color: #0000FF; }
.csharpcode .string { color: #A31515; }
.csharpcode .preproc { color: #0000FF; }
</style><br />
<div class="csharpcode">Code:<br />
<pre style="background: none repeat scroll 0% 0% rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); color: black; overflow-x: auto; overflow-y: hidden; padding: 0px; text-align: left; word-wrap: normal;"><span class="keyword">public</span> <span class="keyword">static</span> <span class="type">Matrix4</span> GetRotationMatrixX(<span class="keyword">double</span> angle)
{
<span class="keyword">if</span> (angle == 0.0)
{
<span class="keyword">return</span> <span class="type">Matrix4</span>.I;
}
<span class="keyword">float</span> sin = (<span class="keyword">float</span>)<span class="type">Math</span>.Sin(angle);
<span class="keyword">float</span> cos = (<span class="keyword">float</span>)<span class="type">Math</span>.Cos(angle);
<span class="keyword">return</span> <span class="keyword">new</span> <span class="type">Matrix4</span>(<span class="keyword">new</span> <span class="keyword">float</span>[4, 4] {
{ 1.0f, 0.0f, 0.0f, 0.0f },
{ 0.0f, cos, -sin, 0.0f },
{ 0.0f, sin, cos, 0.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f } });
}
<span class="keyword">public</span> <span class="keyword">static</span> <span class="type">Matrix4</span> GetRotationMatrixY(<span class="keyword">double</span> angle)
{
<span class="keyword">if</span> (angle == 0.0)
{
<span class="keyword">return</span> <span class="type">Matrix4</span>.I;
}
<span class="keyword">float</span> sin = (<span class="keyword">float</span>)<span class="type">Math</span>.Sin(angle);
<span class="keyword">float</span> cos = (<span class="keyword">float</span>)<span class="type">Math</span>.Cos(angle);
<span class="keyword">return</span> <span class="keyword">new</span> <span class="type">Matrix4</span>(<span class="keyword">new</span> <span class="keyword">float</span>[4, 4] {
{ cos, 0.0f, sin, 0.0f },
{ 0.0f, 1.0f, 0.0f, 0.0f },
{ -sin, 0.0f, cos, 0.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f } });
}
<span class="keyword">public</span> <span class="keyword">static</span> <span class="type">Matrix4</span> GetRotationMatrixZ(<span class="keyword">double</span> angle)
{
<span class="keyword">if</span> (angle == 0.0)
{
<span class="keyword">return</span> <span class="type">Matrix4</span>.I;
}
<span class="keyword">float</span> sin = (<span class="keyword">float</span>)<span class="type">Math</span>.Sin(angle);
<span class="keyword">float</span> cos = (<span class="keyword">float</span>)<span class="type">Math</span>.Cos(angle);
<span class="keyword">return</span> <span class="keyword">new</span> <span class="type">Matrix4</span>(<span class="keyword">new</span> <span class="keyword">float</span>[4, 4] {
{ cos, -sin, 0.0f, 0.0f },
{ sin, cos, 0.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f } });
}
<span class="keyword">public</span> <span class="keyword">static</span> <span class="type">Matrix4</span> GetRotationMatrix(<span class="keyword">double</span> ax, <span class="keyword">double</span> ay, <span class="keyword">double</span> az)
{
<span class="type">Matrix4</span> my = <span class="keyword">null</span>;
<span class="type">Matrix4</span> mz = <span class="keyword">null</span>;
<span class="type">Matrix4</span> result = <span class="keyword">null</span>;
<span class="keyword">if</span> (ax != 0.0)
{
result = GetRotationMatrixX(ax);
}
<span class="keyword">if</span> (ay != 0.0)
{
my = GetRotationMatrixY(ay);
}
<span class="keyword">if</span> (az != 0.0)
{
mz = GetRotationMatrixZ(az);
}
<span class="keyword">if</span> (my != <span class="keyword">null</span>)
{
<span class="keyword">if</span> (result != <span class="keyword">null</span>)
{
result *= my;
}
<span class="keyword">else</span>
{
result = my;
}
}
<span class="keyword">if</span> (mz != <span class="keyword">null</span>)
{
<span class="keyword">if</span> (result != <span class="keyword">null</span>)
{
result *= mz;
}
<span class="keyword">else</span>
{
result = mz;
}
}
<span class="keyword">if</span> (result != <span class="keyword">null</span>)
{
<span class="keyword">return</span> result;
}
<span class="keyword">else</span>
{
<span class="keyword">return</span> <span class="type">Matrix4</span>.I;
}
}
<span class="keyword">public</span> <span class="keyword">static</span> <span class="type">Matrix4</span> GetRotationMatrix(<span class="type">Vector3</span> axis, <span class="keyword">double</span> angle)
{
<span class="keyword">if</span> (angle == 0.0)
{
<span class="keyword">return</span> <span class="type">Matrix4</span>.I;
}
<span class="keyword">float</span> x = axis.x;
<span class="keyword">float</span> y = axis.y;
<span class="keyword">float</span> z = axis.z;
<span class="keyword">float</span> sin = (<span class="keyword">float</span>)<span class="type">Math</span>.Sin(angle);
<span class="keyword">float</span> cos = (<span class="keyword">float</span>)<span class="type">Math</span>.Cos(angle);
<span class="keyword">float</span> xx = x * x;
<span class="keyword">float</span> yy = y * y;
<span class="keyword">float</span> zz = z * z;
<span class="keyword">float</span> xy = x * y;
<span class="keyword">float</span> xz = x * z;
<span class="keyword">float</span> yz = y * z;
<span class="keyword">float</span>[,] matrix = <span class="keyword">new</span> <span class="keyword">float</span>[4, 4];
matrix[0, 0] = xx + (1 - xx) * cos;
matrix[1, 0] = xy * (1 - cos) + z * sin;
matrix[2, 0] = xz * (1 - cos) - y * sin;
matrix[3, 0] = 0.0f;
matrix[0, 1] = xy * (1 - cos) - z * sin;
matrix[1, 1] = yy + (1 - yy) * cos;
matrix[2, 1] = yz * (1 - cos) + x * sin;
matrix[3, 1] = 0.0f;
matrix[0, 2] = xz * (1 - cos) + y * sin;
matrix[1, 2] = yz * (1 - cos) - x * sin;
matrix[2, 2] = zz + (1 - zz) * cos;
matrix[3, 2] = 0.0f;
matrix[3, 0] = 0.0f;
matrix[3, 1] = 0.0f;
matrix[3, 2] = 0.0f;
matrix[3, 3] = 1.0f;
<span class="keyword">return</span> <span class="keyword">new</span> <span class="type">Matrix4</span>(matrix);
}
<span class="comment2">///</span><span class="comment"> </span><span class="comment2"><param name="source"></span><span class="comment">Should be normalized</span><span class="comment"></span><span class="comment2"></param></span><span class="comment"></span>
<span class="comment2">///</span><span class="comment"> </span><span class="comment2"><param name="destination"></span><span class="comment">Should be normalized</span><span class="comment"></span><span class="comment2"></param></span><span class="comment"></span>
<span class="keyword">public</span> <span class="keyword">static</span> <span class="type">Matrix4</span> GetRotationMatrix(<span class="type">Vector3</span> source, <span class="type">Vector3</span> destination)
{
<span class="type">Vector3</span> rotaxis = <span class="type">Vector3</span>.CrossProduct(source, destination);
<span class="keyword">if</span> (rotaxis != <span class="type">Vector3</span>.Zero)
{
rotaxis.Normalize();
<span class="keyword">float</span> cos = source.DotProduct(destination);
<span class="keyword">double</span> angle = <span class="type">Math</span>.Acos(cos);
<span class="keyword">return</span> GetRotationMatrix(rotaxis, angle);
}
<span class="keyword">else</span>
{
<span class="keyword">return</span> <span class="type">Matrix4</span>.I;
}
}</pre></div>ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com1tag:blogger.com,1999:blog-368378466834354558.post-42504541005555345242010-08-21T00:22:00.000-07:002010-08-21T00:22:50.075-07:00How to connect to a remote computer with a click (VNC Step By Step)<i><b>What:</b></i><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLHOA9LYSUTHNl5s6SWfkfCUuqi5ZPZZTnyfQBZ6-Z_ipNKjHiaPFcnFhWKDl5vP7KtiowK7AssojeiO5yGhjcr50tliIZ-AD4pp85clEg4BTS38WILmP5UFqlmaoKtYpWtJJ-2Uh0BMc/s1600/VNC+with+a+click.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="454" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLHOA9LYSUTHNl5s6SWfkfCUuqi5ZPZZTnyfQBZ6-Z_ipNKjHiaPFcnFhWKDl5vP7KtiowK7AssojeiO5yGhjcr50tliIZ-AD4pp85clEg4BTS38WILmP5UFqlmaoKtYpWtJJ-2Uh0BMc/s640/VNC+with+a+click.png" width="640" /></a></div><br />
<i><b>Why: </b></i><br />
A few years ago I sent some files to a client by email, and I spent 3 hours over the phone trying to explain to him how to copy those files to C:\Program Files. Eventually I gave up. It would be faster for me to drive all the way to his office, do it myself, and return all the way. That's exactly what I did, but I also installed a secured VNC server so next time I won't have to drive.<br />
After that I began to install a VNC server everywhere - my grandma who always asks for help, the media center in the living room, a virtual machine, my remote server, ...<br />
I use it very often so it must be comfortable to use.<br />
<br />
<i><b>How:</b></i><br />
There are a few things to do: installation, opening ports, configuring dns, creating vnc file<br />
<br />
<b>1. Download VNC</b><br />
You can get the free edition from here: <a href="http://www.realvnc.com/">http://www.realvnc.com</a><br />
Please note that this version has no encryption (it has a password though), so if security is really important you should get the full version.<br />
<br />
<b>2. Install</b><br />
Install the VNC Viewer on your computer, and the VNC Server on the remote computer.<br />
In the end of the Server installation, set a password:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVTMEQSAW7y76nzJgnE2cDLjfRLB3p6rQFWvboQ3PNBq2CCkPsKDebGvbsY_Z-BU0reZZUxm2H7hkKeDhoCqMwzjZsT76NLLPSf4orFjTdVAVnUKGdN3PtbS4ytvKgJLN_2Ra_IIQbJp4/s1600/VNC+Server+Password.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="342" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVTMEQSAW7y76nzJgnE2cDLjfRLB3p6rQFWvboQ3PNBq2CCkPsKDebGvbsY_Z-BU0reZZUxm2H7hkKeDhoCqMwzjZsT76NLLPSf4orFjTdVAVnUKGdN3PtbS4ytvKgJLN_2Ra_IIQbJp4/s400/VNC+Server+Password.png" width="400" /></a></div><br />
<b>3. Open port 5900 on the Server side</b><br />
Most people have routers that block incoming connections. You need to open port 5900 on the <b>Server </b>side (TCP if you were wondering).<br />
First, let's be smart and check whether it's already opened: <a href="http://www.yougetsignal.com/tools/open-ports/">http://www.yougetsignal.com/tools/open-ports/</a><br />
If the port is blocked, you may need to access your router and open it. This site has detailed explanation for doing this for every router in the world: <a href="http://portforward.com/">http://portforward.com/</a><br />
<b><i>Note: </i></b>If you are not allowed or can't open ports on the Server side then you can use the "Listening mode" viewer, but then the rest of this post doesn't help you.<br />
<br />
<br />
<b>4. Test it</b><br />
On the <b>Server </b>side find the IP address: <a href="http://www.whatismyip.com/">http://www.whatismyip.com/</a><br />
On the <b>Client </b>side open VNC Viewer, enter the Server's IP address, and click OK:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPqKWzC-YJJjwT1F1hPj6XMtA3gFT9UVnuXQ8uq04Ew3SQGZn4nMJtCnXSN7NGeLU7E00-qq39QK4-9Y7-KJydbccrNw9ThcNippIKrOcC3dMyH8nPt377TyEzyk6CPkvs8D2mleeC-NU/s1600/VNC+Viewer+Connect.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="140" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPqKWzC-YJJjwT1F1hPj6XMtA3gFT9UVnuXQ8uq04Ew3SQGZn4nMJtCnXSN7NGeLU7E00-qq39QK4-9Y7-KJydbccrNw9ThcNippIKrOcC3dMyH8nPt377TyEzyk6CPkvs8D2mleeC-NU/s320/VNC+Viewer+Connect.png" width="320" /></a></div><br />
You will be asked for a password. You should enter the password from Step 2 above. <br />
If everything went OK you should now see the Server's desktop inside a window on the Client side. If you get an error message, try googling it.<br />
<br />
<b>5. Create DNS</b><br />
<i>Why?</i> Because usually the Server's IP address can change. If it's static you can skip to Step 8.<br />
Go to: <a href="http://www.dyndns.com/">http://www.dyndns.com/</a> and create a new account.<br />
Add a new host; don't mind the IP for now:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhW1SEJEv3gvkTxa97xa3GIC65-38qgmg-aUnLSnCOxbMHA7C6fUndN9QdwvdSG07M_I4jevgte6lvf1aahXKISXk-DY30I0QqUEEOAR6m_sBy7yEh6TFhC9mx8ObNlP3tZAjoobdVJzOU/s1600/DynDNS+Add+New+Host1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="197" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhW1SEJEv3gvkTxa97xa3GIC65-38qgmg-aUnLSnCOxbMHA7C6fUndN9QdwvdSG07M_I4jevgte6lvf1aahXKISXk-DY30I0QqUEEOAR6m_sBy7yEh6TFhC9mx8ObNlP3tZAjoobdVJzOU/s200/DynDNS+Add+New+Host1.png" width="200" /></a></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRAy0M16ot_UFilUTKE8OzQo1OvXQKUqQ1PR3lnv90t9bguTV1qfl4wSNScabirowfA8TCD6OA3ae35-ygUAwjFL3rv_zeIsST0aMr6i76w5GhOSPd1rgs2QQBSuloCotpjrZb3N4BAsE/s1600/DynDNS+Add+New+Host2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRAy0M16ot_UFilUTKE8OzQo1OvXQKUqQ1PR3lnv90t9bguTV1qfl4wSNScabirowfA8TCD6OA3ae35-ygUAwjFL3rv_zeIsST0aMr6i76w5GhOSPd1rgs2QQBSuloCotpjrZb3N4BAsE/s400/DynDNS+Add+New+Host2.png" width="400" /></a></div><br />
<b>6. Update DNS</b><br />
Download and install <a href="http://cdn.dyndns.com/windows/DynUpSetup.exe">DynDNS Updater</a> on the <b>Server </b>side.<br />
During the installation I advise on DISABLING "Internet Guide":<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjml20zorcQy_CrL_B_qbSTt_HqsUfR_GoVs0Q8lprLx7ssjUc_SRnI81vSwY-55T7kgponmTMJxZLnI40K-vmW_QhCZxySp9KDe_FlCsyNSOcqV5tVr95ioA8E6t_HqG2mK_cBNJgVEro/s1600/DynDNS+Internet+Guide.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjml20zorcQy_CrL_B_qbSTt_HqsUfR_GoVs0Q8lprLx7ssjUc_SRnI81vSwY-55T7kgponmTMJxZLnI40K-vmW_QhCZxySp9KDe_FlCsyNSOcqV5tVr95ioA8E6t_HqG2mK_cBNJgVEro/s320/DynDNS+Internet+Guide.png" /></a></div>You will be asked for your account's username and password. Then select the host you added earlier and click OK:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBKZ8Lcv298mhjnUAwKTjTnC3D1VFLXBDW9KG6dnKrgQF5G5flXbOCmHrw9ng2yrrOm-UqmRxVPWWDCPcV-eddm_jHCVMjUHXXJ_NSmUPsSBLtErsjVlSqx6olIte3pYPyFxbLgdFWDPw/s1600/DynDNS+Updater+Configuration.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBKZ8Lcv298mhjnUAwKTjTnC3D1VFLXBDW9KG6dnKrgQF5G5flXbOCmHrw9ng2yrrOm-UqmRxVPWWDCPcV-eddm_jHCVMjUHXXJ_NSmUPsSBLtErsjVlSqx6olIte3pYPyFxbLgdFWDPw/s320/DynDNS+Updater+Configuration.png" /></a></div><br />
Note: Some routers have this feature built in. I know some of the D-Links have it for example. Use can use it <b>instead</b> of the DynDNS Updater, but you should do it only if you know what you are doing. Example of this feature on my D-Link router:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiADdhrCK46iX02pfXetxAx-rT6njawzyd5Ld09RHumQCPUIALYqA6O3vsVfNWlfDpmUKblNAQDeiEemC7MuBwv4AWcJ3itXfjg1qYwyjHe-eVQrollytfAEsD7nuNJpOMW8ZUA_PP0mik/s1600/D-Link+DynDNS.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiADdhrCK46iX02pfXetxAx-rT6njawzyd5Ld09RHumQCPUIALYqA6O3vsVfNWlfDpmUKblNAQDeiEemC7MuBwv4AWcJ3itXfjg1qYwyjHe-eVQrollytfAEsD7nuNJpOMW8ZUA_PP0mik/s320/D-Link+DynDNS.png" /></a></div><br />
<br />
<b>7. Test it</b><br />
On the <b>Client </b>side open VNC Viewer, enter the host address, and click OK:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8ll0AfcBMY_j7RodNUP9czbikZZ-JGJIf7MopQrZZV4SwnE4wLwM_Fn8AEvAshM5o4yqC32IpAV8bnD5aKFQMVOUjizkvqTvKzo7OobTZNvj7M08WjutpWvt7ADore99BRboIfxSIB6o/s1600/VNC+Viewer+Connect+DNS.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8ll0AfcBMY_j7RodNUP9czbikZZ-JGJIf7MopQrZZV4SwnE4wLwM_Fn8AEvAshM5o4yqC32IpAV8bnD5aKFQMVOUjizkvqTvKzo7OobTZNvj7M08WjutpWvt7ADore99BRboIfxSIB6o/s320/VNC+Viewer+Connect+DNS.png" /></a></div>Again, if you are asked for the password, enter it (the one from Step 2). You should get a window with the <b>Server</b>'s desktop. Don't close it, we need it for the next step.<br />
<br />
<b>8. Save Connection</b><br />
If you didn't connect to the <b>Server </b>do it now. Right-click the top of the window and click on "options":<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDjVlq9yM9WWtrxx5Yayf59-aoKR_tAR5IpiGcaI7V74JXgJZvZrafdoCURNtBaDnmzEZ_wkK6rfo6vX47sBtg7jMObyUJkRvXknroT5YdxvLdr9D3T2lFzBHxwICiTRcMGgZoZ2Fo1ew/s1600/VNC+Viewer+Options1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDjVlq9yM9WWtrxx5Yayf59-aoKR_tAR5IpiGcaI7V74JXgJZvZrafdoCURNtBaDnmzEZ_wkK6rfo6vX47sBtg7jMObyUJkRvXknroT5YdxvLdr9D3T2lFzBHxwICiTRcMGgZoZ2Fo1ew/s320/VNC+Viewer+Options1.png" /></a></div>In the new window click the "Load / Save" tab and then "Save As...":<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7fH_g4Kng-rfH9D90zsbS6I-A8eX3z0j9DroluCTmx06InNbvmfOyibXIKJYLxoXxuYCEzEhHKQJPcb6I7KzHmV-lPGvT6n6fEhWqT3YsO5UCrgS5R9t0Qj3eCKDwP-fDlKNShsLICC0/s1600/VNC+Viewer+Options2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7fH_g4Kng-rfH9D90zsbS6I-A8eX3z0j9DroluCTmx06InNbvmfOyibXIKJYLxoXxuYCEzEhHKQJPcb6I7KzHmV-lPGvT6n6fEhWqT3YsO5UCrgS5R9t0Qj3eCKDwP-fDlKNShsLICC0/s320/VNC+Viewer+Options2.png" /></a></div>Choose a location (e.g. your Desktop) and a name (e.g. "My Remote Server") and save it. You will probably get the following screen:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0agJDNdH7PfsKi7V4CgmYvu-wTY-58ShuR9KrPXK7OsEKRLTQ3pgLhzNJ-3IlxYNZl4DUklTcvX1-Busy43kjv27KG7gj0MkKYbQar8ned5uvU32IHtfRLm4KCxtcbasGhchtqZaLyZI/s1600/VNC+Viewer+Security+Risk.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0agJDNdH7PfsKi7V4CgmYvu-wTY-58ShuR9KrPXK7OsEKRLTQ3pgLhzNJ-3IlxYNZl4DUklTcvX1-Busy43kjv27KG7gj0MkKYbQar8ned5uvU32IHtfRLm4KCxtcbasGhchtqZaLyZI/s320/VNC+Viewer+Security+Risk.png" /></a></div>It's your choice whether to click Yes or No.<br />
If you click No you will have to type in the password each time you want to connect.<br />
If you click Yes, then everything is automatic (no need to type password). Well, the message is pretty accurate: "it's more convenient, but...".<br />
Explanation: If you click yes you will have automatic access to the remote computer. So if someone gains access to your computer, then he will have access to the remote computer as well.<br />
My advice is to click Yes for your Media Center, local server or grandma, but to click No for business computer or something important.<br />
<br />
<b>9. That's it!</b><br />
Go to the location of the file you saved earlier and open it:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeqzW1VuMs64m1SWeSe9sWUPskotuuRenNVOkb4eCCuFyGMGrQo1aq-WRRu27NUg5z-Og2SGGAag7mvzXhaFu6Bg7OZYf3SsYfJX3Jo_oK90MYA1pQdAAQdJ3PEGnWIIUz3VCaj68iWMA/s1600/My+Remote+Server.vnc.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeqzW1VuMs64m1SWeSe9sWUPskotuuRenNVOkb4eCCuFyGMGrQo1aq-WRRu27NUg5z-Og2SGGAag7mvzXhaFu6Bg7OZYf3SsYfJX3Jo_oK90MYA1pQdAAQdJ3PEGnWIIUz3VCaj68iWMA/s320/My+Remote+Server.vnc.png" /></a></div>ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com0tag:blogger.com,1999:blog-368378466834354558.post-69813292193234086002010-07-16T12:59:00.000-07:002010-07-16T13:00:41.861-07:00PRE Tag Internet Explorer Scrollbar Solution<span style="font-family: "Courier New",Courier,monospace;"><pre></span> tag is very useful for writing code. I use it all the time actually for <a href="http://formatmycsharpcode.blogspot.com/">posting C# code</a>.<br />
There is however a problem with Internet Explorer:<br />
If the text is too long, and a horizontal scroll bar appears, it overlaps the bottom line.<br />
You can find many solutions to this problem in <a href="http://perishablepress.com/press/2009/11/09/perfect-pre-tags/">this link</a>, including scanning the document with JavaScript fixing all the pre tags.<br />
My solution is a lot simpler.<br />
<br />
<u><b>Solution:</b></u><br />
If you know that the text is too long and a horizontal scroll bar will appear, then add the following code at the bottom, just before the <span style="font-family: "Courier New",Courier,monospace;"></pre></span> ending tag:<br />
<u><b> </b></u><style>
<!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;
mso-font-charset:0;
mso-generic-font-family:roman;
mso-font-pitch:variable;
mso-font-signature:-1610611985 1107304683 0 0 415 0;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:-520092929 1073786111 9 0 415 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-parent:"";
margin-top:0cm;
margin-right:0cm;
margin-bottom:10.0pt;
margin-left:0cm;
text-align:right;
line-height:115%;
mso-pagination:widow-orphan;
direction:rtl;
unicode-bidi:embed;
font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoChpDefault
{mso-style-type:export-only;
mso-default-props:yes;
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoPapDefault
{mso-style-type:export-only;
margin-bottom:10.0pt;
line-height:115%;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
mso-header-margin:36.0pt;
mso-footer-margin:36.0pt;
mso-paper-source:0;}
div.WordSection1
{page:WordSection1;}
-->
</style> <br />
<div class="MsoNormal" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: green; font-family: "Courier New"; font-size: 10pt;"><!--[if IE]><o:p></o:p></span></div><div class="MsoNormal" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><br />
</div><div class="MsoNormal" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: green; font-family: "Courier New"; font-size: 10pt;"><![endif]--></span><span style="font-family: "Times New Roman","serif"; font-size: 12pt;"><o:p></o:p></span></div><br />
<u><b>Explanation:</b></u><br />
If the user is using Internet Explorer, then there will be an extra (empty) line inside the pre tag, and the horizontal scroll bar will overlap the empty line and not the original content.<u><b><br />
</b></u>ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com0tag:blogger.com,1999:blog-368378466834354558.post-3565550914307375772010-07-15T18:15:00.000-07:002010-07-15T18:26:54.545-07:00איך יוצרים קישור למקום מסוים במפה של גוגל, ynet ווואלה<div dir="rtl" style="text-align: right;">אתם רוצים לשלוח לכל החברים קישור למקום מסויים שבו צריך להיפגש. אפשר לשלוח תמונה של המפה (Print Screen), ואפשר לשלוח להם לינק למפה אינטרקטיבית, ובה מסומן מקום המפגש, כך שהם יוכלו להוציא איזה מידע שהם צריכים ביותר קלות (למשל מגרשי חנייה).<br />
<u><b>דוגמה:</b></u> <a href="http://ymap.winwin.co.il/Navigate.aspx?tab=1&CityNmS=%u05D9%u05E8%u05D5%u05E9%u05DC%u05D9%u05DD&StreetNmS=%u05E9%u05D3%u05E8%u05D5%u05EA%20%u05D1%u05DF%20%u05DE%u05D9%u05D9%u05DE%u05D5%u05DF&HouseNbrS=1&Mode=1">אוהל המחאה של משפחת שליט</a><br />
<br />
<a href="http://maps.google.com/?hl=iw"><img src="http://maps.google.com/intl/iw_ALL/images/maps_small_horizontal_logo.png" style="border: medium none;" /></a><br />
הכי נוח. מחפשים את המקום ואז יש כפתור "קישור" בצד שמאל.<br />
<br />
<a href="http://ymap.winwin.co.il/"><img src="http://ymap.winwin.co.il/ymapimg/logosmall2.gif" style="border: medium none;" /></a><br />
<u><b>שיטה 1 קלה:</b></u><br />
הכניסו נתונים ולחצו על "צור קישור":<br />
<form>עיר: <input id="ymap_city" size="10" type="text" /> רחוב: <input id="ymap_street" size="10" type="text" /> מספר: <input id="ymap_number" size="10" type="text" /> <input onclick="var url='http://ymap.winwin.co.il/Navigate.aspx?tab=1&CityNmS='+escape(document.getElementById('ymap_city').value)+'&StreetNmS='+escape(document.getElementById('ymap_street').value)+'&HouseNbrS='+escape(document.getElementById('ymap_number').value);document.getElementById('ymap_result').innerHTML = unescape('%u05D4%u05E0%u05D4%20%u05D4%u05E7%u05D9%u05E9%u05D5%u05E8%20%u05E9%u05DC%u05DA%3A%3Cbr%3E%3Ca%20href%3D%27')+url+unescape('%27%3E')+url+unescape('%3C/a%3E');" type="button" value="צור קישור" /></form><div id="ymap_result"></div><br />
<u><b>שיטה 2:</b></u> נכנסים לאתר <a href="http://ymap.winwin.co.il/">המפות של ynet</a>, מחפשים את המקום שרוצים, ואז לוחצים על "הדפס" (למטה), בדף החדש מבטלים את ההדפסה, ומסתכלים על הכתובת:<br />
http://ymap.winwin.co.il/...&Mode=1<span style="color: red;">&forprint=y&displayMode=SMALLMAP</span><br />
מורידים את החלק שסימנתי באדום, ומה שנשאר זה הלינק שלכם.<br />
<br />
<a href="http://maps.walla.co.il/" style="text-decoration: none;"><img src="http://iscWBE.walla.co.il/w9/t/walla.gif" style="border: medium none;" /><span style="color: #7d7d7d; font-size: 41px;"><b>מפות</b></span></a><br />
הכניסו נתונים ולחצו על "צור קישור":<br />
<form>עיר: <input id="walla_city" size="10" type="text" /> רחוב: <input id="walla_street" size="10" type="text" /> מספר: <input id="walla_number" size="10" type="text" /> <input onclick="var url='http://mapsframe.walla.co.il/site/main.asp?cityS='+encodeHebrew(document.getElementById('walla_city').value)+'&streetS='+encodeHebrew(document.getElementById('walla_street').value)+'&houseS='+encodeHebrew(document.getElementById('walla_number').value);document.getElementById('walla_result').innerHTML = unescape('%u05D4%u05E0%u05D4%20%u05D4%u05E7%u05D9%u05E9%u05D5%u05E8%20%u05E9%u05DC%u05DA%3A%3Cbr%3E%3Ca%20href%3D%27')+url+unescape('%27%3E')+url+unescape('%3C/a%3E');" type="button" value="צור קישור" /></form><div id="walla_result"></div><script type="text/javascript">
translateHebrewMap = {'א' : '%E0', 'ב' : '%E1', 'ג' : '%E2', 'ד' : '%E3', 'ה' : '%E4', 'ו' : '%E5', 'ז' : '%E6', 'ח' : '%E7', 'ט' : '%E8', 'י' : '%E9', 'ך' : '%EA', 'כ' : '%EB', 'ל' : '%EC', 'ם' : '%ED', 'מ' : '%EE', 'ן' : '%EF', 'נ' : '%F0', 'ס' : '%F1', 'ע' : '%F2', 'ף' : '%F3', 'פ' : '%F4', 'ץ' : '%F5', 'צ' : '%F6', 'ק' : '%F7', 'ר' : '%F8', 'ש' : '%F9', 'ת' : '%FA'};
function encodeHebrew(text)
{
return text.replace(/([א-ת])/g, function(all, c) { return translateHebrewMap[c];});
}
</script></div>ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com0tag:blogger.com,1999:blog-368378466834354558.post-2537195173939070952010-07-11T16:19:00.000-07:002010-07-15T18:28:35.612-07:00איך לעקוף את ההודעה: "בחירת כסאות לא מאושרת, אין להשאיר כסא בודד" בסינמה סיטי<div style="text-align: right;">This post is intended for people from Israel.</div><div style="text-align: right;" dir="rtl"><br />
<div style="text-align: right;"><u><b>הערה חשובה: הפוסט הזה נועד כדי להראות בעיה שבנסיבות אחרות יכולה להיות בעיית אבטחה, ולא כדי להפציץ את סינמה סיטי בכיסאות בודדים!</b></u></div><div style="text-align: right;"><br />
</div><div style="text-align: right;"><u><b>בעיה</b></u>: אתם רוצים להזמין 4 מקומות לסרט בסינמה סיטי ויש 5 פנויים. אתם בוחרים ב-4 שקרובים לאמצע ואז מקבלים את ההודעה:</div><div class="separator" style="clear: both; text-align: right;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiC5yXVtUKDMTuTczflBdA4ZFUoAbThC-fdC3SmNj7PNEtnPSY2KgvEk0yj9jVM22X_OEYJCKxmmKReTP57uj0aAWLMj1I_pWh7KZk8HwkzR0MW1PEOPtqZDK5fdOXcXMnrRaQSIxl9AfA/s1600/cinema-city.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiC5yXVtUKDMTuTczflBdA4ZFUoAbThC-fdC3SmNj7PNEtnPSY2KgvEk0yj9jVM22X_OEYJCKxmmKReTP57uj0aAWLMj1I_pWh7KZk8HwkzR0MW1PEOPtqZDK5fdOXcXMnrRaQSIxl9AfA/s320/cinema-city.png" /></a></div><div style="text-align: right;"><u><b>פתרון 1</b></u>: נכנסים במחשב אחר, בוחרים את הכיסא שלא רוצים, לוחצים על "הבא", והמערכת שומרת לכם אותו למשך 6 דקות. ואז במחשב שלכם אתם יכולים להזמין את ה-4 שאתם כן רוצים.</div><div style="text-align: right;"><br />
</div><div style="text-align: right;">עד עכשיו זה היה החלק היותר מוכר.</div><div style="text-align: right;">וזה אמור לפתור את רוב הבעיות.</div><div style="text-align: right;"><br />
</div><div style="text-align: right;">אבל מה קורה אם הזמנתם את הכרטיסים שלכם בלי בעיה (למשל 4 מתוך 6), אבל אתם מפוזרים כמוני ושכחתם מישהו בטעות, ועכשיו אתם צריכים להזמין מקום 1 מתוך 2? מהירי המחשבה ישימו לב שלא ניתן להשתמש בשיטה הקודמת.</div><div style="text-align: right;"><u><b>פתרון 2</b></u>: נכנסים במחשב שלכם בוחרים את 2 הכיסאות ולוחצים על "הבא"; המערכת שומרת אותם ל-6 דקות. נכנסים במחשב אחר לאותו סרט באותו יום באותה שעה איפה שרואים ש-2 הכיסאות תפוסים, ולא עושים כלום. חוזרים למחשב שלכם, לוחצים על "הקודם", בוחרים את הכיסא שאתם רוצים ומזמינים אותו.</div><div style="text-align: right;">כמובן שזה עובד על כל מספר של כיסאות ולכן יותר חזק מפתרון 1. </div><div style="text-align: right;"><u><b>אז מה קרה פה?</b></u></div><div style="text-align: right;">ההשערה שלי: כנראה שהמערכת של סינמה סיטי שומרת סוג של מטמון ברגע שנכנסים מהמחשב השני, וכאשר חוזרים למחשב שלכם ומזמינים כיסא אחד במקום 2 המערכת משתמשת באותו מטמון שבו עדיין שמורים 2 הכיסאות, ולכן אין כיסא בודד.</div><div style="text-align: right;"><br />
</div><div style="text-align: right;"><u><b>הערות:</b></u></div><div style="text-align: right;">במקום להשתמש בשני מחשבים, ניתן להשתמש בשני דפדפנים, או בכל דרך שבה מפרידים את הסשן.</div><div style="text-align: right;">שני הפתרונות עובדים נכון ל-12 ביולי 2010.</div></div>ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com1tag:blogger.com,1999:blog-368378466834354558.post-10525370294190331672010-07-06T10:36:00.000-07:002010-07-16T12:38:07.027-07:00C# Sort Text and Numbers (like Explorer does)<i><b>For example:</b></i><br />
<div style="font-family: "Courier New",Courier,monospace;">myvideo.part2.rar</div>Should come <b>before</b>:<br />
<div style="font-family: "Courier New",Courier,monospace;">myvideo.part10.rar</div><br />
<br />
<pre formatcs="1">// Usage:
list.Sort(new StringLogicalComparer());
// Comparer:
public class StringLogicalComparer : IComparer, IComparer<string>
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
public static extern int StrCmpLogicalW(string x, string y);
public int Compare(object x, object y)
{
return StrCmpLogicalW(x.ToString(), y.ToString());
}
public int Compare(string x, string y)
{
return StrCmpLogicalW(x, y);
}
}
</pre>ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com1tag:blogger.com,1999:blog-368378466834354558.post-38329719549940571782010-07-01T18:26:00.000-07:002010-07-01T18:32:33.776-07:00WebBrowser and HttpWebRequest Cookies Problem and SolutionIf you are working with WebBrowser control and you want to make some WebRequest you need to synchronize the cookies.<br />
And that would be the naive way to do it:<br />
<pre formatcs="1">httpWebRequest.CookieContainer.SetCookies(
webBrowser.Document.Url,
webBrowser.Document.Cookie.Replace(';', ',')
); // THIS CODE IS WRONG!!
</pre><br />
The problem is the HttpOnly cookies that are missing from Document.Cookie for security reasons.<br />
The HttpOnly cookies are probably the most important ones that you need.<br />
This article explains how to get them:<br />
<a href="http://www.codeproject.com/KB/shell/RetrieveHttponlyCookies.aspx">http://www.codeproject.com/KB/shell/RetrieveHttponlyCookies.aspx</a><br />
<br />
Here is a more compact version of the function for C#:<br />
<pre formatcs=1>[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool InternetGetCookieEx(string pchURL, string pchCookieName, StringBuilder pchCookieData, ref uint pcchCookieData, int dwFlags, IntPtr lpReserved);
const int INTERNET_COOKIE_HTTPONLY = 0x00002000;
public static string GetGlobalCookies(string uri)
{
uint datasize = 1024;
StringBuilder cookieData = new StringBuilder((int)datasize);
if (InternetGetCookieEx(uri, null, cookieData, ref datasize, INTERNET_COOKIE_HTTPONLY, IntPtr.Zero)
&& cookieData.Length > 0)
{
return cookieData.ToString().Replace(';', ',');
}
else
{
return null;
}
}
</pre>And the usage would be:<br />
<pre formatcs="1">httpWebRequest.CookieContainer.SetCookies(
webBrowser.Document.Url,
GetGlobalCookies(webBrowser.Document.Url.AbsoluteUri)
);
</pre>ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com34tag:blogger.com,1999:blog-368378466834354558.post-72494136855543334292010-06-28T17:36:00.000-07:002010-06-28T17:36:47.643-07:00Blogger C# APISource: <a href="http://google-gdata.googlecode.com/svn/trunk/clients/cs/samples/blogger/ConsoleSample.cs">http://google-gdata.googlecode.com/svn/trunk/clients/cs/samples/blogger/ConsoleSample.cs</a><br />
<br />
<pre formatcs=1>using System;
using System.Text;
using Google.GData.Client;
using System.Net;
using System.Xml;
using System.Text.RegularExpressions;
namespace BloggerDevSample
{
class ConsoleSample
{
/** Lists the user's blogs. */
static void ListUserBlogs(Service service)
{
Console.WriteLine("\nRetrieving a list of blogs");
FeedQuery query = new FeedQuery();
// Retrieving a list of blogs
query.Uri = new Uri("http://www.blogger.com/feeds/default/blogs");
AtomFeed feed = null;
feed = service.Query(query);
foreach (AtomEntry entry in feed.Entries)
{
Console.WriteLine(" Blog title: " + entry.Title.Text);
}
}
/** Lists the user's blogs and returns the URI for posting new entries
* to the blog which the user selected.
*/
static Uri SelectUserBlog(Service service)
{
Console.WriteLine("\nPlease select a blog on which to post.");
FeedQuery query = new FeedQuery();
// Retrieving a list of blogs
query.Uri = new Uri("http://www.blogger.com/feeds/default/blogs");
AtomFeed feed = service.Query(query);
// Publishing a blog post
Uri blogPostUri = null;
if (feed != null)
{
foreach (AtomEntry entry in feed.Entries)
{
// Print out the title of the Blog
Console.WriteLine(" Blog name: " + entry.Title.Text);
Console.Write(" Post to this blog? (y/n): ");
if (Console.ReadLine().Equals("y"))
{
// find the href in the link with a rel pointing to the blog's feed
for (int i = 0; i < entry.Links.Count; i++)
{
if (entry.Links[i].Rel.Equals("http://schemas.google.com/g/2005#post"))
{
blogPostUri = new Uri(entry.Links[i].HRef.ToString());
Console.WriteLine(" Your new posts will be sent to " + blogPostUri.AbsoluteUri.ToString());
}
}
return blogPostUri;
}
}
}
return blogPostUri;
}
/** Creates a new blog entry and sends it to the specified Uri */
static AtomEntry PostNewEntry(Service service, Uri blogPostUri)
{
Console.WriteLine("\nPublishing a blog post");
AtomEntry createdEntry = null;
if (blogPostUri != null)
{
// construct the new entry
AtomEntry newPost = new AtomEntry();
newPost.Title.Text = "Marriage!";
newPost.Content = new AtomContent();
newPost.Content.Content = "<div xmlns='http://www.w3.org/1999/xhtml'>" +
"<p>Mr. Darcy has <em>proposed marriage</em> to me!</p>" +
"<p>He is the last man on earth I would ever desire to marry.</p>" +
"<p>Whatever shall I do?</p>" +
"</div>";
newPost.Content.Type = "xhtml";
newPost.Authors.Add(new AtomPerson());
newPost.Authors[0].Name = "Elizabeth Bennet";
newPost.Authors[0].Email = "liz@gmail.com";
createdEntry = service.Insert(blogPostUri, newPost);
if (createdEntry != null)
{
Console.WriteLine(" New blog post created with title: " + createdEntry.Title.Text);
}
}
return createdEntry;
}
/** Creates a new blog entry and sends it to the specified Uri */
static void PostAndDeleteNewDraftEntry(Service service, Uri blogPostUri)
{
Console.WriteLine("\nCreating a draft blog post");
AtomEntry draftEntry = null;
if (blogPostUri != null)
{
// construct the new entry
AtomEntry newPost = new AtomEntry();
newPost.Title.Text = "Marriage! (Draft)";
newPost.Content = new AtomContent();
newPost.Content.Content = "<div xmlns='http://www.w3.org/1999/xhtml'>" +
"<p>Mr. Darcy has <em>proposed marriage</em> to me!</p>" +
"<p>He is the last man on earth I would ever desire to marry.</p>" +
"<p>Whatever shall I do?</p>" +
"</div>";
newPost.Content.Type = "xhtml";
newPost.Authors.Add(new AtomPerson());
newPost.Authors[0].Name = "Elizabeth Bennet";
newPost.Authors[0].Email = "liz@gmail.com";
newPost.IsDraft = true;
draftEntry = service.Insert(blogPostUri, newPost);
if (draftEntry != null)
{
Console.WriteLine(" New draft post created with title: " + draftEntry.Title.Text);
// Delete the newly created draft entry
Console.WriteLine(" Press enter to delete the draft blog post");
Console.ReadLine();
draftEntry.Delete();
}
}
}
/** Display the titles for all entries in the previously selected blog. */
static void ListBlogEntries(Service service, Uri blogUri)
{
if (blogUri != null)
{
Console.WriteLine("\nRetrieving all blog posts");
// Retrieve all posts in a blog
FeedQuery query = new FeedQuery();
Console.WriteLine(" Query URI: " + blogUri.ToString());
query.Uri = blogUri;
AtomFeed feed = service.Query(query);
foreach (AtomEntry entry in feed.Entries)
{
Console.WriteLine(" Entry Title: " + entry.Title.Text);
}
}
}
/** Display title for entries in the blog in the hard coded date range. */
static void ListBlogEntriesInDateRange(Service service, Uri blogUri)
{
Console.WriteLine("\nRetrieving posts using query parameters");
// Retrieve all posts in a blog between Jan 1, 2006 and Apr 12, 2007
FeedQuery query = new FeedQuery();
query.Uri = blogUri;
query.MinPublication = new DateTime(2006, 1, 1);
query.MaxPublication = new DateTime(2007, 4, 12);
AtomFeed feed = service.Query(query);
foreach (AtomEntry entry in feed.Entries)
{
Console.WriteLine(" Entry Title: " + entry.Title.Text);
}
}
/** Change the contents of the newly created blog entry. */
static AtomEntry EditEntry(AtomEntry toEdit)
{
Console.WriteLine("\nUpdating post");
// Edit the new entry
if (toEdit != null)
{
toEdit.Title.Text = "Marriage Woes!";
Console.WriteLine(" Press enter to update");
Console.ReadLine();
toEdit = toEdit.Update();
}
return toEdit;
}
/** Delete the specified blog entry. */
static void DeleteEntry(AtomEntry toDelete)
{
Console.WriteLine("\nDeleting post");
// Delete the edited entry
if (toDelete != null)
{
Console.WriteLine(" Press enter to delete the new blog post");
Console.ReadLine();
toDelete.Delete();
}
}
/** Get the comments feed URI for the desired blog entry. */
static Uri SelectBlogEntry(Service service, Uri blogPostUri)
{
Console.WriteLine("\nPlease select a blog entry on which to comment.");
FeedQuery query = new FeedQuery();
query.Uri = blogPostUri;
AtomFeed feed = service.Query(query);
Uri commentPostUri = null;
if (feed != null)
{
foreach (AtomEntry entry in feed.Entries)
{
// Print out the title of the Blog
Console.WriteLine(" Blog entry title: " + entry.Title.Text);
Console.Write(" Post a comment on this entry? (y/n): ");
if (Console.ReadLine().Equals("y"))
{
// Create the Post URL for adding a comment by finding this entry's id number.
// Find the href in the link with a rel pointing to the blog's feed.
for (int i = 0; i < entry.Links.Count; i++)
{
if (entry.Links[i].Rel == "edit")
{
string commentUriStart = Regex.Replace(blogPostUri.ToString(), "/posts/default", "");
string selfLink = entry.Links[i].HRef.ToString();
string entryId = Regex.Replace(selfLink, blogPostUri.ToString() + "/", "");
// Build the comment URI from the blog id in and the entry id.
commentPostUri = new Uri(commentUriStart + "/" + entryId + "/comments/default");
Console.WriteLine(" Your new comments will be sent to " + commentPostUri.ToString());
return commentPostUri;
}
}
}
}
}
return commentPostUri;
}
static AtomEntry PostNewComment(Service service, Uri commentPostUri)
{
Console.WriteLine("\nCommenting on a blog post");
AtomEntry postedComment = null;
if (commentPostUri != null)
{
// Add a comment.
AtomEntry comment;
comment = new AtomEntry();
comment.Title.Text = "This is my first comment";
comment.Content.Content = "This is my first comment";
comment.Authors.Add(new AtomPerson());
comment.Authors[0].Name = "Blog Author Name";
postedComment = service.Insert(commentPostUri, comment);
Console.WriteLine(" Result's title: " + postedComment.Title.Text);
}
return postedComment;
}
static void ListEntryComments(Service service, Uri commentUri)
{
if (commentUri != null)
{
Console.WriteLine("\nRetrieving all blog post comments");
// Retrieve all comments on a blog entry
FeedQuery query = new FeedQuery();
Console.WriteLine(" Query URI: " + commentUri.ToString());
query.Uri = commentUri;
AtomFeed feed = service.Query(query);
foreach (AtomEntry entry in feed.Entries)
{
Console.WriteLine(" Comment Title: " + entry.Title.Text);
}
}
}
static void DeleteComment(AtomEntry commentEntry)
{
Console.WriteLine("\nDeleting the comment");
if (commentEntry != null)
{
// Delete the comment.
Console.WriteLine(" Press enter to delete the new comment post");
Console.ReadLine();
commentEntry.Delete();
}
}
static void Main(string[] args)
{
Service service = new Service("blogger", "blogger-example");
// ClientLogin using username/password authentication
string username;
string password;
if (args.Length != 2)
{
Console.WriteLine("Usage: BloggerDevSample.exe <username> <password>");
return;
}
else
{
username = args[0];
password = args[1];
}
service.Credentials = new GDataCredentials(username, password);
ListUserBlogs(service);
Uri blogPostUri = SelectUserBlog(service);
AtomEntry createdEntry = PostNewEntry(service, blogPostUri);
PostAndDeleteNewDraftEntry(service, blogPostUri);
ListBlogEntries(service, blogPostUri);
ListBlogEntriesInDateRange(service, blogPostUri);
AtomEntry editedEntry = EditEntry(createdEntry);
DeleteEntry(editedEntry);
Uri commentPostUri = SelectBlogEntry(service, blogPostUri);
AtomEntry commentEntry = PostNewComment(service, commentPostUri);
ListEntryComments(service, commentPostUri);
DeleteComment(commentEntry);
Console.WriteLine("Press enter to quit");
Console.ReadLine();
}
}
}
</pre>ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com15tag:blogger.com,1999:blog-368378466834354558.post-28152973508170588252010-06-26T10:27:00.000-07:002010-06-26T10:27:12.706-07:00Remoting Exception "[...] is not registered for activation"RemotingException "[...] is not registered for activation"<br />
<br />
I had to write something about it, because I was stuck for a whole hour and couldn't google anything useful.<br />
<br />
It happens when the Client is trying to create a new remoting class "X".<br />
The Server, by mistake, registered a remoting class "Y".<br />
<br />
The classes must have the same name. Fix the class name.<br />
That's it.ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com1tag:blogger.com,1999:blog-368378466834354558.post-50294256405886053772010-06-19T04:40:00.000-07:002010-06-19T04:40:14.447-07:00Google Command Line<span style="font-size: small;"></span><span style="font-size: small;">Project homepage: </span><br />
<span style="font-size: small;"><a href="http://code.google.com/p/googlecl/">http://code.google.com/p/googlecl/</a></span><br />
<br />
It is originally for *nix, but can also be used on Windows:<br />
<span style="font-size: small;"><a href="http://publicint.blogspot.com/2010/06/setup-googlecl-on-winxp.html">http://publicint.blogspot.com/2010/06/setup-googlecl-on-winxp.html</a></span><br />
<br />
<span style="font-size: small;"><b><u>From the usage examples:<br />
</u></b></span><br />
<span style="font-size: small;"><i><b>Blogger</b></i></span><br />
<ul style="font-family: "Courier New",Courier,monospace;"><li><span style="font-size: small;">google blogger post --tags "GoogleCL, awesome" --title "Test Post" "I'm posting from the command line"</span></li>
<li><span style="font-size: small;">google blogger post blogpost.txt</span></li>
<li><span style="font-size: small;">google blogger list title,url-site # List posts</span></li>
<li><span style="font-size: small;">google blogger delete --title "Test Post"</span></li>
<li><span style="font-size: small;">google delete --title "Silly post number [0-9]*" # Delete posts matching regex</span></li>
<li><span style="font-size: small;">google tag --title "Dev post" --tags "Python, software" # label an existing post </span></li>
</ul><span style="font-size: small;"><br />
<i><b>Calendar</b></i></span><br />
<ul style="font-family: "Courier New",Courier,monospace;"><li><span style="font-size: small;">google calendar add "Dinner party with George today at 6pm" # add event to calendar</span></li>
<li><span style="font-size: small;">google calendar today # List events for today only.</span></li>
<li><span style="font-size: small;">google calendar list --date 2010-06-01,2010-06-30 # List events.</span></li>
<li><span style="font-size: small;">google calendar delete --title "Dinner party with George" # Delete an event. </span></li>
</ul><span style="font-size: small;"><br />
<i><b>Contacts</b></i></span><br />
<ul style="font-family: "Courier New",Courier,monospace;"><li><span style="font-size: small;">google contacts add "J. Random Hacker, jrandom@example.com"</span></li>
<li><span style="font-size: small;">google contacts list name,email --title "J. Random Hacker"</span></li>
<li><span style="font-size: small;">google contacts delete --title "J. Random Hacker" </span></li>
</ul><span style="font-size: small;"><br />
<i><b>Docs</b></i></span><br />
<ul style="font-family: "Courier New",Courier,monospace;"><li><span style="font-size: small;">google docs delete --title "Evidence"</span></li>
<li><span style="font-size: small;">google docs edit --title "Shopping list" --editor vim</span></li>
<li><span style="font-size: small;">google docs get --title "Homework [0-9]*"</span></li>
<li><span style="font-size: small;">google docs list title,url-direct --delimiter ": " # list docs</span></li>
<li><span style="font-size: small;">google docs upload the_bobs.csv ~/work/docs_to_share/* </span></li>
</ul><span style="font-size: small;"><br />
<i><b>Picasa</b></i></span><br />
<ul style="font-family: "Courier New",Courier,monospace;"><li><span style="font-size: small;">google picasa create --title "Vermont Test" --tags Vermont vermont.jpg</span></li>
<li><span style="font-size: small;">google picasa get --title "Vermont Test" /path/to/download/folder</span></li>
<li><span style="font-size: small;">google picasa list title,url-direct --query "A tag"</span></li>
<li><span style="font-size: small;">google picasa post --title "Vermont Test" ~/old_photos/*.jpg # Add to an album</span></li>
<li><span style="font-size: small;">google picasa tag --title "Vermont Test" --tags "places"</span></li>
<li><span style="font-size: small;">google picasa delete --title "Vermont Test" # delete entire album </span></li>
</ul><span style="font-size: small;"><br />
<i><b>Youtube</b></i></span><br />
<ul style="font-family: "Courier New",Courier,monospace;"><li><span style="font-size: small;">google youtube post --category Education --devtags GoogleCL killer_robots.avi</span></li>
<li><span style="font-size: small;">google youtube delete --title "killer_robots.avi"</span></li>
<li><span style="font-size: small;">google youtube list # list my videos</span></li>
<li><span style="font-size: small;">google youtube tag -n ".*robot.*" --tags robot </span></li>
</ul><span style="font-size: small;"><br />
<i><b>Search, Buzz, Gmail, etc.</b></i><br />
</span>ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com0tag:blogger.com,1999:blog-368378466834354558.post-10393906756701261742010-06-07T09:20:00.000-07:002010-07-07T09:04:15.553-07:00Get IMDB movie rating using JavaScript (Cross domain AJAX solution)<b>UPDATE:</b> I modified my script to use <a href="https://imdbparser.appspot.com/">imdbparser.appspot.com</a> that I built, so the information is always accurate and it works fast.<br />
This query:<br />
<div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">https://imdbparser.appspot.com/?callback=<span style="color: red;">foo</span>&context=<span style="color: red;">bar</span>&action=rating&id=<span style="color: red;">tt0411008</span></span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-family: Arial,Helvetica,sans-serif;">Gives this result:</span><span style="font-size: x-small;"><span style="font-family: Arial,Helvetica,sans-serif;"> </span><span style="font-size: small;">foo('bar', '8.7')</span></span></div>So you can write something like that:<br />
<br />
<div style="font-family: "Courier New",Courier,monospace;"><script type="text/javascript"></div><div style="font-family: "Courier New",Courier,monospace;">function <span style="color: red;">foo</span>(<span style="color: red;">context</span>, <span style="color: red;">rating</span>)</div><div style="font-family: "Courier New",Courier,monospace;">{</div><div style="font-family: "Courier New",Courier,monospace;"> alert("The rating is: " + <span style="color: red;">rating</span>);</div><div style="font-family: "Courier New",Courier,monospace;">}<br />
</script></div><span style="font-family: "Courier New",Courier,monospace;"><script src="</span><span style="font-family: "Courier New",Courier,monospace; font-size: small;">https://imdbparser.appspot.com/?callback=<span style="color: red;">foo</span>&context=<span style="color: red;">bar</span>&action=rating&id=<span style="color: red;">tt0411008</span></span><span style="font-family: "Courier New",Courier,monospace;">" type="text/javascript"></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"></script></span><br />
<br />
<b>Original Post:</b><br />
<br />
<br />
<script src="http://www.thomasfrank.se/sessvars.js" type="text/javascript">
</script><br />
<script src="http://sites.google.com/site/ycouriel/files/imdbrating.js" type="text/javascript">
</script><style type="text/css">
.stars_yellow, .stars_gray {
display: block; width: 200px; height: 20px; background-image: url(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNJKb8Q5PbxWEHiOPK6XT7KMyYJLO4W3OZB4PhWFvDmHCQcuSThTQZUa-8kSwRd723b8HuZyZo6dXuSZ_Lr6XP4bASQyIQy4Le8_8PIjwLAcw1nK8xIF2HcpxfHv7ENWbPq9wTsm8oyvc/s320/stars.png); background-repeat: no-repeat;
}
.stars_gray {
background-position: 0px 0px;
}
.stars_yellow {
background-position: 0px -20px;
}
</style><i><b>Solution to what exactly?</b></i><br />
<br />
In JavaScript you aren't suppose to communicate with other sites, such as <a href="http://www.imdb.com/">IMDB</a>. As a result, you can't get the rating of a movie just like that.<br />
For more information:<br />
<a href="http://en.wikipedia.org/wiki/Same_origin_policy">http://en.wikipedia.org/wiki/Same_origin_policy</a><br />
<br />
<i><b>Example:</b></i> <a href="http://www.imdb.com/title/tt0497465/">Vicky Cristina Barcelona</a><br />
<script type="text/javascript">
IMDBRATING.registerTitle("tt0497465");
</script><br />
<i><b>How to use it in your website?</b></i><br />
<br />
Put this code in the top of the page:<br />
<div style="font-family: "Courier New",Courier,monospace;"><span class="sc1" style="font-size: x-small;"><script</span><span class="sc8" style="font-size: x-small;"> </span><span class="sc3" style="font-size: x-small;">src</span><span class="sc8" style="font-size: x-small;">=</span><span class="sc6" style="font-size: x-small;">"http://sites.google.com/site/ycouriel/files/imdbrating.js"</span><span class="sc8" style="font-size: x-small;"> </span><span class="sc3" style="font-size: x-small;">type</span><span class="sc8" style="font-size: x-small;">=</span><span class="sc6" style="font-size: x-small;">"text/javascript"</span><span class="sc1" style="font-size: x-small;">></span><span class="sc40" style="font-size: x-small;"> </span><span class="sc1" style="font-size: x-small;"></script></span></div>Put this code each time you want to get rating:<br />
<div style="font-family: "Courier New",Courier,monospace;"><span class="sc1" style="font-size: x-small;"><script</span><span class="sc8" style="font-size: x-small;"> </span><span class="sc3" style="font-size: x-small;">type</span><span class="sc8" style="font-size: x-small;">=</span><span class="sc6" style="font-size: x-small;">"text/javascript"</span><span class="sc1" style="font-size: x-small;">></span><span class="sc46" style="font-size: x-small;"> IMDBRATING.registerTitle</span><span class="sc50" style="font-size: x-small;">(</span><span class="sc48" style="font-size: x-small;">"tt0068646"</span><span class="sc50" style="font-size: x-small;">);</span><span class="sc1" style="font-size: x-small;"></script></span></div>Finally, put this code in the bottom of the page:<span class="sc1" style="font-size: x-small;"> </span><br />
<div style="font-family: "Courier New",Courier,monospace;"><span class="sc1" style="font-size: x-small;"><script</span><span class="sc8" style="font-size: x-small;"> </span><span class="sc3" style="font-size: x-small;">type</span><span class="sc8" style="font-size: x-small;">=</span><span class="sc6" style="font-size: x-small;">"text/javascript"</span><span class="sc1" style="font-size: x-small;">></span><span class="sc46" style="font-size: x-small;"> IMDBRATING.processTitles</span><span class="sc50" style="font-size: x-small;">();</span><span class="sc1" style="font-size: x-small;"></script></span><br />
<span style="font-size: small;"><span style="font-family: Arial,Helvetica,sans-serif;">You also need to put this CSS if you want the nice stars:</span></span><span style="font-size: x-small;"> <a href="https://sites.google.com/site/ycouriel/files/imdbrating.css">imdbrating.css</a></span></div><style type="text/css">
.sc1 {
color: #0000FF;
}
.sc3 {
color: #FF0000;
}
.sc6 {
font-weight: bold;
color: #8000FF;
}
.sc8 {
}
.sc46 {
background: #F2F4FF;
}
.sc50 {
font-weight: bold;
background: #F2F4FF;
}
</style> <br />
<br />
<i><b>How it's done?</b></i><br />
<br />
The trick is to use Google. Consider the following query:<br />
<div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: xx-small;"><a href="http://www.google.com/uds/GwebSearch?callback=IMDBRATING.ratingCallback&context=tt0497465&lstkp=0&rsz=small&hl=en&source=gsc&gss=.com&sig=d5fae37fdfdac0a0e1e1aa0c8bc4b04c&q=http%3A%2F%2Fwww.imdb.com%2Ftitle%2Ftt0497465%2F%20rating%2010%20site%3Aimdb.com&gl=www.google.com&key=notsupplied&v=1.0">http://www.google.com/uds/GwebSearch?<span style="color: red;">callback=IMDBRATING.ratingCallback</span>&context=tt0497465&lstkp=0&rsz=small&hl=en&source=gsc&gss=.com&sig=d5fae37fdfdac0a0e1e1aa0c8bc4b04c&<span style="color: red;">q=http%3A%2F%2Fwww.imdb.com%2Ftitle%2Ftt0497465%2F%20rating%2010%20site%3Aimdb.com</span>&gl=www.google.com&key=notsupplied&v=1.0</a></span></div>You get in return:<br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">IMDBRATING.ratingCallback( <search results here> );</span></span><br />
This wonderful feature of Google allows you to write a query as the source of JavaScript:<span class="sc1" style="font-size: x-small;"> </span><br />
<div style="font-family: "Courier New",Courier,monospace;"><span class="sc1" style="font-size: x-small;"><script</span><span class="sc8" style="font-size: x-small;"> </span><span class="sc3" style="font-size: x-small;">src</span><span class="sc8" style="font-size: x-small;">=</span><span class="sc6" style="font-size: x-small;">" <the query above here> "</span><span class="sc8" style="font-size: x-small;"> </span><span class="sc3" style="font-size: x-small;">type</span><span class="sc8" style="font-size: x-small;">=</span><span class="sc6" style="font-size: x-small;">"text/javascript"</span><span class="sc1" style="font-size: x-small;">></span><span class="sc40" style="font-size: x-small;"> </span><span class="sc1" style="font-size: x-small;"></script></span></div>By parsing the search results, you can easily find the rating.<br />
<br />
<i><b>Notes:</b></i><br />
<ul><li>This is a JavaScript solution; if you have a server running PHP or something you can put some page like Google's, only instead of search results you return the ratings. This could be wonderful, but all the websites on the Internet that do exactly that didn't work for me or were very slow.</li>
<li>The rating you get is sometimes not updated, it entirely depends on how often Google database is updated.</li>
</ul><br />
<script type="text/javascript">
IMDBRATING.processTitles();
</script>ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com6tag:blogger.com,1999:blog-368378466834354558.post-21978845565669737292010-06-06T10:04:00.000-07:002010-06-07T08:02:21.957-07:00Tabnapping - A New Type of Phishing AttackI admit that before I saw this video I could have been easily fooled by this attack...<br />
<br />
<a href="http://www.azarask.in/blog/post/a-new-type-of-phishing-attack/">http://www.azarask.in/blog/post/a-new-type-of-phishing-attack/</a><br />
<br />
<object height="267" width="400"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=12003099&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=12003099&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="267"></embed></object><br />
<a href="http://vimeo.com/12003099">A New Type of Phishing Attack</a> from <a href="http://vimeo.com/user532161">Aza Raskin</a> on <a href="http://vimeo.com/">Vimeo</a>.ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com0tag:blogger.com,1999:blog-368378466834354558.post-43129803029717964902010-02-21T03:34:00.000-08:002010-03-01T23:56:32.702-08:00Add C# Code Formatter Widget To Your Blog<div class="separator" style="clear: both; text-align: center;"><a href="http://jscsharpformatter.googlecode.com/svn/trunk/publish/logo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://jscsharpformatter.googlecode.com/svn/trunk/publish/logo.png" /></a></div>This widget formats all the C# code in your blog so it looks exactly like in Visual Studio.<br />
It supports all the cases of string literals, comments, keywords and preprocessors. It has a huge list of all commonly used types, and it has some capability of learning new types (classes, enums, interfaces, structs) from your code.<br />
<a href="http://formatmycsharpcode.blogspot.com/"><i>Try it now online!</i></a> <b> - OR - </b><i>Add it to your blog:</i><script src="http://jscsharpformatter.googlecode.com/svn/trunk/publish/addwidgetbutton.js" type="text/javascript"></script><br />
Note: the widget is for lazy people like me, if you want you can add the formatting script to your <b>HTML Layout</b> <a href="http://code.google.com/p/jscsharpformatter/wiki/GettingStarted#Method2:_Add_JS_code_to_layout">manually</a>.<br />
<br />
<i><b>Here is a simple example:</b></i><br />
<pre formatcs="1">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace exp1
{
class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello, world!");
}
}
}</pre><br />
<i><b>This is what the author sees when writing the post:</b></i><br />
<div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><pre formatcs="1">using System;</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">using System.Collections.Generic;</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">using System.Linq;</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">using System.Text;</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><br />
</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">namespace exp1</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">{</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> class Program</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> {</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> public static void Main(string[] args)</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> {</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> Console.WriteLine("Hello, world!");</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> }</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> }</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">}</pre></span></div><br />
<i><b>So how does it work?</b></i> <br />
The script scans the page looking for <span style="font-family: "Courier New",Courier,monospace;"><pre></span> elements with the attribute <span style="font-family: "Courier New",Courier,monospace;">formatcs=1</span>. Each element is then formatted as C# code.<br />
The <span style="font-family: "Courier New",Courier,monospace;"><pre></span> tag was chosen for a reason - if the user doesn't have JavaScript supported, then the <span style="font-family: "Courier New",Courier,monospace;"><pre></span> tag is the best way to show code in a blog.<br />
<br />
<i><b>Here is a more advanced example:</b></i><br />
<pre formatcs="1">[XmlRoot("Node")]
class MyNode<T> : MyBaseClass<T>
where T : Dictionary<List<T>, int>, ISerializable
{
MyNode MyNode = new SuperNode();
/// <summary> *
/// comment2... *
/// </summary> *
MyType1 foo(out MyType2 x)
{
x = MyType1.StaticFunction(@"c:\");
Console.WriteLine(" aaaa \" \\\" \\\\");
return new T();
}
}
</pre>Note that these classes are being deduced by reading the code: <span style="font-family: "Courier New",Courier,monospace;">MyNode</span>, <span style="font-family: "Courier New",Courier,monospace;">MyBaseClass</span>, <span style="font-family: "Courier New",Courier,monospace;">SuperNode</span>, <span style="font-family: "Courier New",Courier,monospace;">MyType1</span>, <span style="font-family: "Courier New",Courier,monospace;">MyType2</span>.<br />
Note that "<span style="font-family: "Courier New",Courier,monospace;">T</span>" is not styled as a type, exactly as in Visual Studio.<br />
<br />
<b><i>OK OK! I'm convinced! How do I add this widget to my blog?</i></b><br />
Simply by clicking here:<script src="http://jscsharpformatter.googlecode.com/svn/trunk/publish/addwidgetbutton.js" type="text/javascript">
</script><br />
<b><i>- Or - You can use the online version here:</i></b><br />
<a href="http://formatmycsharpcode.blogspot.com/">formatmycsharpcode.blogspot.com</a><br />
<br />
For more information refer to <a href="http://code.google.com/p/jscsharpformatter/wiki/GettingStarted" target="_blank">this wiki page</a>.ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com2tag:blogger.com,1999:blog-368378466834354558.post-46943971086411356132010-02-20T14:29:00.000-08:002010-02-23T00:12:27.802-08:00Use JavaScript to Format C# Code to HTMLTo format C# code online go <a href="http://formatmycsharpcode.blogspot.com/">here</a>. <br />
To add it as a widget go to <a href="http://ycouriel.blogspot.com/2010/02/add-c-code-formatter-widget-to-your.html">this post</a>.<br />
To get the most recent source code go <a href="http://code.google.com/p/jscsharpformatter/">here</a>. <br />
<br />
Example of how it looks:<br />
<pre formatcs="1">using System.Xml.Serialization;
namespace foo
{
public partial class Form1<AAA> : Form
{
void bar<T, R, L>(int k, Form1 f)
where T : ISerializable
where R : Dictionary<string, List<Form1>>, ISerializable
{
Form1 Form1 = new Form1();
}
}
}
</pre><br />
I wrote a script in JavaScript to format C# Code.<br />
I needed such a script because I didn't like the old way of copying the code to Microsoft Word, then to Blogger, and then looking for and removing all the <META> and <LINK> tags that Blogger doesn't accept.<br />
Before I did that, I looked on the Internet, and I found this wonderful site:<a href="http://www.manoli.net/csharpformat"> http://www.manoli.net/csharpformat</a> <br />
But it doesn't handle strings very well, and doesn't recognize types.<br />
<br />
For example, the expression 'string path = @"c:\";' returns:<br />
<div style="font-family: "Courier New",Courier,monospace;"><span class="kwrd">string</span> path = @"c:\";</div>Which means the string is black instead of red.<br />
About types, I think it's not supported at all.<br />
I downloaded their source code and I found some useful things for my code.<br />
<br />
I used more accurate regular expressions to identify strings:<br />
<pre formatcs="1">// backslash slash before the end using @
string path = @"c:\";
// even number of backslashes means no backslash
string x = " \" \\\" \\\\";
/* support for multi line
comments and strings
*/
string y = @" begin
end";
/// <summary> This kind is also supported
/// </summary>
</pre><br />
Formatting strings, comments and keywords is no big deal, but what about types?<br />
Sometimes you don't know if something is a type or a variable, for example:<br />
<pre formatcs="1">Something.DoIt();
</pre>(There is a way of telling the script that "Something" is a type, and it will be explained later)<br />
It could be a field or a property called "Something", or it could be a class called "Something" and in that case "DoIt" would be a static function.<br />
But sometimes you do know that something is a type, and it worth remembering it for the future:<br />
<pre formatcs="1">class Something { } // here the script identifies "Something" as a type
Something.DoIt(); // here it uses the information from earlier
</pre><br />
But what about "Application.DoEvents()" ?<br />
In that case the script has a list of common types:<br />
<pre formatcs="1">Application.DoEvents();
</pre><br />
I compiled this list using this code:<br />
<pre formatcs="1">static string GetAllTypes()
{
string regex = "";
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
{
foreach (Type type in asm.GetTypes())
{
string name = new Regex("(`.*)").Replace(type.Name, "");
if (new Regex("^[A-Za-z0-9]+$").IsMatch(name))
{
regex += name + "|";
Match match = new Regex("^(.+)Attribute$").Match(name);
if (match.Success){
regex += match.Groups[1].Value + "|";
}
}
}
}
return regex;
}
</pre><br />
Sometimes the long list affects the loading time of the blog, so I have another manually written list that has the most commonly used types like: List, EventArgs, ...<br />
Note that the shorter list doesn't necessarily mean the script wont recognize any types, that is because it learns the types from the code itself (as shown in the example above).<br />
<br />
In order to use the script you need to write the following code:<br />
<div style="font-family: "Courier New",Courier,monospace;"><pre formatcs=1></div><div style="font-family: "Courier New",Courier,monospace;">your code here</div><div style="font-family: "Courier New",Courier,monospace;"></pre></div><br />
If the script doesn't recognize a type from some reason, like in the in example of "Something.DoIt()" case, then you can instruct the script to recognize it by adding a new attribute called "types":<br />
<div style="font-family: "Courier New",Courier,monospace;"><pre formatcs=1 types="Something"></div><div style="font-family: "Courier New",Courier,monospace;">Something.DoIt();</div><div style="font-family: "Courier New",Courier,monospace;"></pre></div>And the result:<br />
<pre formatcs="1" types="Something">Something.DoIt();
</pre>The types attribute accepts a list of type names, and it can be separated by comma, white space, anything.<br />
<br />
The script can handle generics - means it doesn't paint it like in here:<br />
<pre formatcs="1">class MyClass<T>
{
List<T> x = new List<T>();
}
</pre><br />
However, there might be cases where the class definition is missing, and then T might be mistaken for type:<br />
<pre formatcs="1">x = new T();
</pre><br />
Another issue with generics and more specifically with the "<" sign is that you have to write "&lt;", otherwise Blogger is going crazy adding all sorts of strange ending tags to the posts. This behavior is not caused by the script, but it does keep it from working correctly. I don't know how it behaves on other blogging sites, but I tested the script offline on my computer it works with normal "<" too.<br />
<br />
I plan to make a gadget that adds this functionality to a blog. I will call it "C# Code Formatter". <br />
But in the meantime the script can be used from here:<br />
<a href="http://code.google.com/p/jscsharpformatter/">jscsharpformatter.googlecode.com</a><br />
<br />
I added a new "HTML/JavaScript" gadget on the bottom of the page with the following code:<br />
<span style="font-family: "Courier New",Courier,monospace;"><script type="text/javascript" src="http://sites.google.com/site/ycouriel/files/csharp_formatter_normal.js"></span><br />
<span style="font-family: "Courier New",Courier,monospace;"></script></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><script type="text/javascript"></span><br />
<span style="font-family: "Courier New",Courier,monospace;">var howmany = findAndFormatCSharp();</span><br />
<span style="font-family: "Courier New",Courier,monospace;">document.write(howmany + " c# code elements were formatted");</span><br />
<span style="font-family: "Courier New",Courier,monospace;"></script></span><br />
<br />
Feedback is very welcome!ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com2tag:blogger.com,1999:blog-368378466834354558.post-91856636126042443282010-02-18T17:43:00.000-08:002010-02-20T16:05:26.878-08:00Version SynchronizationI wrote a server for my MegaCollection software.<br />
Each member of the family can upload new movies and TV series, and edit, delete and rate existing items. The server is used to store this data and support versions synchronization.<br />
<br />
Each item has a quite complex data structure including names of actors, image, IMDB identifier, etc. TV series has Seasons, and they have Episodes, and the list is long...<br />
I'll ignore all of this and assume the following:<br />
<ul><li>The <span style="font-family: "Courier New",Courier,monospace;">Database </span>is a list of <span style="font-family: "Courier New",Courier,monospace;">Movies</span></li>
<li>Each <span style="font-family: "Courier New",Courier,monospace;">Movie </span>has a list of <span style="font-family: "Courier New",Courier,monospace;">DownloadVersions</span></li>
<li><span style="font-family: "Courier New",Courier,monospace;">Movies<span style="font-family: Arial,Helvetica,sans-serif;"> and </span>DownloadVersions<span style="font-family: Arial,Helvetica,sans-serif;"> have some data inside</span> </span></li>
</ul>Now we have the <span style="font-family: "Courier New",Courier,monospace;">serverDatabase </span>and the <span style="font-family: "Courier New",Courier,monospace;">userDatabase</span>.The user can edit his database offline. Other users can do this too.<br />
So we can't assume anything about the databases apart from their correctness.<br />
<br />
How do we produce a synchronized database?<br />
<br />
I decided to define an interface that all synchronized objects must implement:<br />
<style>
<!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;
mso-font-charset:0;
mso-generic-font-family:roman;
mso-font-pitch:variable;
mso-font-signature:-1610611985 1107304683 0 0 415 0;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:-520092929 1073786111 9 0 415 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-parent:"";
margin-top:0cm;
margin-right:0cm;
margin-bottom:10.0pt;
margin-left:0cm;
text-align:right;
line-height:115%;
mso-pagination:widow-orphan;
direction:rtl;
unicode-bidi:embed;
font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoChpDefault
{mso-style-type:export-only;
mso-default-props:yes;
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoPapDefault
{mso-style-type:export-only;
margin-bottom:10.0pt;
line-height:115%;}
@page Section1
{size:595.3pt 841.9pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
mso-header-margin:35.4pt;
mso-footer-margin:35.4pt;
mso-paper-source:0;
mso-gutter-direction:rtl;}
div.Section1
{page:Section1;}
-->
</style> <br />
<div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><br />
<span style="color: blue; font-family: "Courier New"; font-size: 10pt;">interface</span><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: #2b91af;">ISyncObject<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;">{<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">string</span> ID { <span style="color: blue;">get</span>; }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: #2b91af;">DateTime</span> Timestamp { <span style="color: blue;">get</span>; }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt; line-height: 115%;">}</span><br />
<br />
</div>We also need the following information:<br />
<br />
<style>
<!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;
mso-font-charset:0;
mso-generic-font-family:roman;
mso-font-pitch:variable;
mso-font-signature:-1610611985 1107304683 0 0 415 0;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:-520092929 1073786111 9 0 415 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-parent:"";
margin-top:0cm;
margin-right:0cm;
margin-bottom:10.0pt;
margin-left:0cm;
text-align:right;
line-height:115%;
mso-pagination:widow-orphan;
direction:rtl;
unicode-bidi:embed;
font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoChpDefault
{mso-style-type:export-only;
mso-default-props:yes;
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoPapDefault
{mso-style-type:export-only;
margin-bottom:10.0pt;
line-height:115%;}
@page Section1
{size:612.0pt 792.0pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
mso-header-margin:36.0pt;
mso-footer-margin:36.0pt;
mso-paper-source:0;}
div.Section1
{page:Section1;}
-->
</style><span style="color: #2b91af; font-family: "Courier New"; font-size: 10pt;">DateTime</span><span style="font-family: "Courier New"; font-size: 10pt;"> lastSuccessfulSynchronizationWithServer;</span><br />
<br />
This should be enough information to handle all of the following cases:<br />
<ol><li>User added a new <span style="font-family: "Courier New",Courier,monospace;">Movie</span></li>
<li>Other user added a new <span style="font-family: "Courier New",Courier,monospace;">Movie</span></li>
<li>User deleted a <span style="font-family: "Courier New",Courier,monospace;">Movie</span></li>
<li>Other user deleted a <span style="font-family: "Courier New",Courier,monospace;">Movie</span></li>
<li>User modified data inside a <span style="font-family: "Courier New",Courier,monospace;">Movie</span></li>
<li>Other user modified data inside a <span style="font-family: "Courier New",Courier,monospace;">Movie</span></li>
<li>User added a new <span style="font-family: "Courier New",Courier,monospace;">DownloadVersion</span></li>
<li>Other user added a new <span style="font-family: "Courier New",Courier,monospace;">DownloadVersion</span></li>
<li>User deleted a <span style="font-family: "Courier New",Courier,monospace;">DownloadVersion</span></li>
<li>Other user deleted a <span style="font-family: "Courier New",Courier,monospace;">DownloadVersion</span></li>
<li>User modified data inside a <span style="font-family: "Courier New",Courier,monospace;">DownloadVersion</span></li>
<li>Other user modified data inside a <span style="font-family: "Courier New",Courier,monospace;">DownloadVersion</span></li>
</ol>Note that cases 7 to 12 happen only if two <span style="font-family: "Courier New",Courier,monospace;">Movies </span>has the same <span style="font-family: "Courier New",Courier,monospace;">ID </span>and <span style="font-family: "Courier New",Courier,monospace;">Timestamp</span>. This case is referred to as "Merging" of the two <span style="font-family: "Courier New",Courier,monospace;">Movies</span>.<br />
<br />
I wrote a synchronization function that considers all the cases 1 to 6. When a merging is required, this function is called again on the <span style="font-family: "Courier New",Courier,monospace;">DownloadVersions</span>.<br />
<br />
Here is the function signature:<br />
<style>
<!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;
mso-font-charset:0;
mso-generic-font-family:roman;
mso-font-pitch:variable;
mso-font-signature:-1610611985 1107304683 0 0 415 0;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:-520092929 1073786111 9 0 415 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-parent:"";
margin-top:0cm;
margin-right:0cm;
margin-bottom:10.0pt;
margin-left:0cm;
text-align:right;
line-height:115%;
mso-pagination:widow-orphan;
direction:rtl;
unicode-bidi:embed;
font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoChpDefault
{mso-style-type:export-only;
mso-default-props:yes;
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoPapDefault
{mso-style-type:export-only;
margin-bottom:10.0pt;
line-height:115%;}
@page Section1
{size:612.0pt 792.0pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
mso-header-margin:36.0pt;
mso-footer-margin:36.0pt;
mso-paper-source:0;}
div.Section1
{page:Section1;}
-->
</style> <br />
<div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: blue; font-family: "Courier New"; font-size: 10pt;">static</span><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">class</span> <span style="color: #2b91af;">SyncHelper</span><T> <span style="color: blue;">where</span> T : <span style="color: blue;">class</span>, <span style="color: #2b91af;">ISyncObject<o:p></o:p></span></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;">{<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: blue; font-family: "Courier New"; font-size: 10pt;"> public</span><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">static</span> <span style="color: blue;">void</span> SynchronizeLists(<span style="color: #2b91af;"><o:p></o:p></span></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: #2b91af; font-family: "Courier New"; font-size: 10pt;"> List</span><span style="font-family: "Courier New"; font-size: 10pt;"><T> serverList, <span style="color: #2b91af;"><o:p></o:p></span></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: #2b91af; font-family: "Courier New"; font-size: 10pt;"> List</span><span style="font-family: "Courier New"; font-size: 10pt;"><T> userList, <span style="color: #2b91af;"><o:p></o:p></span></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: #2b91af; font-family: "Courier New"; font-size: 10pt;"> DateTime</span><span style="font-family: "Courier New"; font-size: 10pt;"> lastSuccessfulSynchronizationWithServer, <span style="color: #2b91af;"><o:p></o:p></span></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: #2b91af; font-family: "Courier New"; font-size: 10pt;"> MergeObjectsDelegate</span><span style="font-family: "Courier New"; font-size: 10pt;"> mergeObjectsMethod<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> )<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">// code</span><o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;">}<o:p></o:p></span></div><br />
Assuming this functions works, we can synchronize the database using the following code:<br />
<br />
<pre dir="ltr" style="overflow: auto; padding: 1px; text-align: left;"><style>
<!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;
mso-font-charset:0;
mso-generic-font-family:roman;
mso-font-pitch:variable;
mso-font-signature:-1610611985 1107304683 0 0 415 0;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:-520092929 1073786111 9 0 415 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-parent:"";
margin-top:0cm;
margin-right:0cm;
margin-bottom:10.0pt;
margin-left:0cm;
text-align:right;
line-height:115%;
mso-pagination:widow-orphan;
direction:rtl;
unicode-bidi:embed;
font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoChpDefault
{mso-style-type:export-only;
mso-default-props:yes;
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoPapDefault
{mso-style-type:export-only;
margin-bottom:10.0pt;
line-height:115%;}
@page Section1
{size:612.0pt 792.0pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
mso-header-margin:36.0pt;
mso-footer-margin:36.0pt;
mso-paper-source:0;}
div.Section1
{page:Section1;}
-->
</style>
<div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: blue; font-family: "Courier New"; font-size: 10pt;">static</span><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">void</span> SynchronizeDatabase(<span style="color: #2b91af;">Database</span> serverDatabase, <span style="color: #2b91af;">Database</span> userDatabase)<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;">{<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: #2b91af;">SyncHelper</span><<span style="color: #2b91af;">Movie</span>>.SynchronizeLists(<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> serverDatabase.movies, <o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> userDatabase.movies, <o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> userDatabase.lastSuccessfulSynchronizationWithServer,<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> MergeMovies<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> );<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> userDatabase.lastSuccessfulSynchronizationWithServer = <span style="color: #2b91af;">DateTime</span>.Now;<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;">}<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: blue; font-family: "Courier New"; font-size: 10pt;">static</span><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: #2b91af;">Movie</span> MergeMovies(<span style="color: #2b91af;">Movie</span> serverMovie, <span style="color: #2b91af;">Movie</span> userMovie, <span style="color: #2b91af;">DateTime</span> lastSuccessfulSynchronizationWithServer)<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;">{<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: #2b91af;">SyncHelper</span><<span style="color: #2b91af;">DownloadVersion</span>>.SynchronizeLists(<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> serverMovie.DownloadVersions, <o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> userMovie.DownloadVersions, <o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> lastSuccessfulSynchronizationWithServer,<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> MergeDownloadVersions<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> );<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">// add code to merge other movie data<o:p></o:p></span></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">return</span> serverMovie;<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;">}<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: blue; font-family: "Courier New"; font-size: 10pt;">static</span><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: #2b91af;">DownloadVersion</span> MergeDownloadVersions(<span style="color: #2b91af;">DownloadVersion</span> serverDownloadVersion, <span style="color: #2b91af;">DownloadVersion</span> userDownloadVersion, <span style="color: #2b91af;">DateTime</span> lastSuccessfulSynchronizationWithServer)<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;">{<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">// add code to merge download versions data<o:p></o:p></span></span></div><div class="MsoNormal" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">return</span> mergedDownloadVersion;<o:p></o:p></span></div><div class="MsoNormal" style="direction: ltr; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt; line-height: 115%;">}</span><span style="line-height: 115%;"><o:p></o:p></span></div></pre><br />
The purpose of this was to prove it is a quite handy function. I use it in my server to synchronize several types of classes and it works flawlessly.<br />
Here is the full class:<br />
<br />
<pre dir="ltr" style="overflow: auto; padding: 1px; text-align: left;"><style>
<!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;
mso-font-charset:0;
mso-generic-font-family:roman;
mso-font-pitch:variable;
mso-font-signature:-1610611985 1107304683 0 0 415 0;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:-520092929 1073786111 9 0 415 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-parent:"";
margin-top:0cm;
margin-right:0cm;
margin-bottom:10.0pt;
margin-left:0cm;
text-align:right;
line-height:115%;
mso-pagination:widow-orphan;
direction:rtl;
unicode-bidi:embed;
font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoChpDefault
{mso-style-type:export-only;
mso-default-props:yes;
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoPapDefault
{mso-style-type:export-only;
margin-bottom:10.0pt;
line-height:115%;}
@page Section1
{size:595.3pt 841.9pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
mso-header-margin:35.4pt;
mso-footer-margin:35.4pt;
mso-paper-source:0;
mso-gutter-direction:rtl;}
div.Section1
{page:Section1;}
-->
</style>
<div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: blue; font-family: "Courier New"; font-size: 10pt;">static</span><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">class</span> <span style="color: #2b91af;">SyncHelper</span><t> <span style="color: blue;">where</span> T : <span style="color: blue;">class</span>, <span style="color: #2b91af;">ISyncObject<o:p></o:p></span></t></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;">{<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">public</span> <span style="color: blue;">delegate</span> T <span style="color: #2b91af;">MergeObjectsDelegate</span>(T serverObject, T userObject, <span style="color: #2b91af;">DateTime</span> lastSuccessfulSynchronizationWithServer);<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">private</span> <span style="color: blue;">static</span> <span style="color: #2b91af;">Dictionary</span><<span style="color: blue;">string</span>, T> ListToDictionaryByID(<span style="color: #2b91af;">List</span><t> list)<o:p></o:p></t></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: #2b91af;">Dictionary</span><<span style="color: blue;">string</span>, T> dic = <span style="color: blue;">new</span> <span style="color: #2b91af;">Dictionary</span><<span style="color: blue;">string</span>, T>();<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">foreach</span> (T obj <span style="color: blue;">in</span> list)<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> dic[obj.ID] = obj;<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">return</span> dic;<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: blue;">void</span> SynchronizeLists(<span style="color: #2b91af;">List</span><t> serverList, <span style="color: #2b91af;">List</span><t> userList, <span style="color: #2b91af;">DateTime</span> lastSuccessfulSynchronizationWithServer)<o:p></o:p></t></t></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">// call original function, on merging always take server's object<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> SynchronizeLists(serverList, userList, lastSuccessfulSynchronizationWithServer, <span style="color: blue;">delegate</span>(T obj1, T obj2, <span style="color: #2b91af;">DateTime</span> timestamp) { <span style="color: blue;">return</span> <span style="color: blue;">null</span>; });<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: blue;">void</span> SynchronizeLists(<span style="color: #2b91af;">List</span><t> serverList, <span style="color: #2b91af;">List</span><t> userList, <span style="color: #2b91af;">DateTime</span> lastSuccessfulSynchronizationWithServer, <span style="color: #2b91af;">MergeObjectsDelegate</span> mergeObjectsMethod)<o:p></o:p></t></t></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">// note that objects that were added by other user will be<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">// updated at current user because we are sending him serverList<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">string</span> tname = <span style="color: blue;">typeof</span>(T).Name;<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: #2b91af;">Dictionary</span><<span style="color: blue;">string</span>, T> serverObjectByID = ListToDictionaryByID(serverList);<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: #2b91af;">Dictionary</span><<span style="color: blue;">string</span>, T> userObjectByID = ListToDictionaryByID(userList);<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">// look for objects that user deleted<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">for</span> (<span style="color: blue;">int</span> i = serverList.Count - 1; i >= 0; --i)<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> T serverObject = serverList[i];<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">//l.Debug("Checking server's", tname, serverObject);<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">if</span> (!userObjectByID.ContainsKey(serverObject.ID) &&<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> serverObject.Timestamp < lastSuccessfulSynchronizationWithServer)<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">// if user doesn't have this object, but he should have it<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">// then he deleted it after previous synchronization<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">//l.Debug("User deleted this", tname, ", removing from server:", serverObject);<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> serverList.RemoveAt(i);<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> serverObjectByID.Remove(serverObject.ID);<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">foreach</span> (T userObject <span style="color: blue;">in</span> userList)<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">//l.Debug("Checking user's", tname, userObject);<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">if</span> (!serverObjectByID.ContainsKey(userObject.ID))<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">// user has an object which doesn't exist at the server's list<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">// check timestamps<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">if</span> (userObject.Timestamp > lastSuccessfulSynchronizationWithServer)<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">// user added a new object after previous synchronization<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">//l.Debug("This", tname, "is new. Adding to server's list:", userObject);<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> serverList.Add(userObject);<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">else<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">// this movie was deleted by other user<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">// the current user will get the new list without this object<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">//l.Debug("This", tname, "was deleted by other user:", userObject);<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">else<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">// both server and user has this object<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> T serverObject = serverObjectByID[userObject.ID];<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">//l.Debug("This", tname, "already exists in server database:", serverObject);<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">if</span> (serverObject.Timestamp > userObject.Timestamp)<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">// the object was updated by other user<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">// ignore user's object, he will get the new version<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">//l.Debug("Server", tname, "is newer than user's:", serverObject);<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">if</span> (userObject.Timestamp > lastSuccessfulSynchronizationWithServer)<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: #2b91af;">l</span>.Warn(<span style="color: #a31515;">"Possible conflict between server and user objects: Server object is newer, but User object was modified after previous synchronization:"</span>, userObject);<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">else</span> <span style="color: blue;">if</span> (serverObject.Timestamp < userObject.Timestamp)<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">// user deleted the object and then added it again<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">// remove server's copy and replace it with user's<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">//l.Debug("User", tname, "is newer than server's:", userObject);<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> serverList.Remove(serverObject);<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> serverList.Add(userObject);<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">if</span> (serverObject.Timestamp > lastSuccessfulSynchronizationWithServer)<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: #2b91af;">l</span>.Warn(<span style="color: #a31515;">"Possible conflict between server and user objects: User object is newer, but Server object was modified after previous synchronization:"</span>, userObject);<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">else<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">// both server and user has this movie and:<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">// serverObject.Timestamp == userObject.Timestamp<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: green;">//l.Debug("Server and user have the same", tname, "and with equal timestamps, merging is required:", userObject);<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> T mergedObject = mergeObjectsMethod(serverObject, userObject, lastSuccessfulSynchronizationWithServer);<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">if</span> (mergedObject != <span style="color: blue;">null</span>)<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> serverList.Remove(serverObject);<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> serverList.Add(mergedObject);<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt; line-height: 115%;">}</span><span style="line-height: 115%;"><o:p></o:p></span></div></pre>ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com0tag:blogger.com,1999:blog-368378466834354558.post-6667632564012379522010-02-18T16:25:00.000-08:002010-02-20T16:05:42.820-08:00How to add a new Blogger post with labels from C#First download and install Google API from here:<br />
<a href="http://code.google.com/p/google-gdata/downloads/list">http://code.google.com/p/google-gdata/downloads/list</a><br />
<br />
Add a reference to "Google Data API Core Library",<br />
and use the following function:<br />
<br />
<style>
<!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;
mso-font-charset:1;
mso-generic-font-family:roman;
mso-font-format:other;
mso-font-pitch:variable;
mso-font-signature:0 0 0 0 0 0;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:-520092929 1073786111 9 0 415 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-parent:"";
margin-top:0cm;
margin-right:0cm;
margin-bottom:10.0pt;
margin-left:0cm;
text-align:right;
line-height:115%;
mso-pagination:widow-orphan;
direction:rtl;
unicode-bidi:embed;
font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoChpDefault
{mso-style-type:export-only;
mso-default-props:yes;
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoPapDefault
{mso-style-type:export-only;
margin-bottom:10.0pt;
line-height:115%;}
@page Section1
{size:595.3pt 841.9pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
mso-header-margin:35.4pt;
mso-footer-margin:35.4pt;
mso-paper-source:0;
mso-gutter-direction:rtl;}
div.Section1
{page:Section1;}
-->
</style> <br />
<div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: blue; font-family: "Courier New"; font-size: 10pt;">public</span><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">static</span> <span style="color: blue;">bool</span> AddPost(<span style="color: blue;">string</span> title, <span style="color: blue;">string</span> bodyHTML, <span style="color: blue;">string</span>[] labels)<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;">{<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: #2b91af;">Service</span> service = <span style="color: blue;">new</span> <span style="color: #2b91af;">Service</span>(<span style="color: #a31515;">"blogger"</span>, <span style="color: #a31515;">"<program name>"</span>);<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> service.Credentials = <span style="color: blue;">new</span> <span style="color: #2b91af;">GDataCredentials</span>(<span style="color: #a31515;">"<username>"</span>, <span style="color: #a31515;">"<password>"</span>);<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: #2b91af;">AtomEntry</span> newPost = <span style="color: blue;">new</span> <span style="color: #2b91af;">AtomEntry</span>();<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> newPost.Title.Text = title;<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> newPost.Content = <span style="color: blue;">new</span> <span style="color: #2b91af;">AtomContent</span>();<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> newPost.Content.Content = bodyHTML;<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> newPost.Content.Type = <span style="color: #a31515;">"html"</span>;<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">foreach</span> (<span style="color: blue;">string</span> label <span style="color: blue;">in</span> labels)<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: #2b91af;">AtomCategory</span> cat = <span style="color: blue;">new</span> <span style="color: #2b91af;">AtomCategory</span>();<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="background: none repeat scroll 0% 0% yellow;">cat.Scheme = <span style="color: blue;">new</span> <span style="color: #2b91af;">Uri</span>(<span style="color: #a31515;">"http://www.blogger.com/atom/ns#"</span>);</span><o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> cat.Term = label;<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> newPost.Categories.Add(cat);<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: #2b91af;">AtomEntry</span> response = <span style="color: blue;">null</span>;<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">try<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> response = service.Insert(<span style="color: blue;">new</span> <span style="color: #2b91af;">Uri</span>(<span style="color: #a31515;">"<uri>"</span>), newPost);<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">catch</span> (<span style="color: #2b91af;">GDataRequestException</span> exception)<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">if</span> (exception.ResponseString == <span style="color: #a31515;">"Blog has exceeded rate limit or otherwise requires word verification for new posts"</span>)<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">return</span> <span style="color: blue;">false</span>;<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">else<o:p></o:p></span></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">throw</span> exception;<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">if</span> (response == <span style="color: blue;">null</span>)<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> {<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">Exception</span>(<span style="color: #a31515;">"Something went wrong"</span>);<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> }<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">return</span> <span style="color: blue;">true</span>;<o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="direction: ltr; text-align: left; unicode-bidi: embed;"><span style="font-family: "Courier New"; font-size: 10pt; line-height: 115%;">}</span></div><br />
Note what you need to replace:<br />
<ul><li><program name> </li>
<li><username></li>
<li><password></li>
<li><uri> is for example: <a href="http://ycouriel.blogspot.com/feeds/posts/default">http://ycouriel.blogspot.com/feeds/posts/default</a></li>
</ul>Also note the marked yellow line. It took me some nasty googling time to find it. You must put it for the labels to work.ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com8tag:blogger.com,1999:blog-368378466834354558.post-24018492072259268762010-02-18T15:37:00.000-08:002010-02-20T16:06:33.567-08:00Blogger like search boxI copied the Blogger search box and added the following features:<br />
<ul><li>It shows the current search keywords after you invoked the search (by parsing the URL)</li>
<li>It has a border that becomes gray when mouse is on the box</li>
<li>It has a faded string when not in focus, and it disappears when in focus</li>
</ul>Take a look:<br />
<a href="http://ycouriel-archive.blogspot.com/">http://ycouriel-archive.blogspot.com/</a><br />
(It's on the sidebar)<br />
<br />
This is actually the first time I'm using HTML, JavaScript and CSS.<br />
So I hope the code won't be that embarrassing:<br />
<style>
<!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;
mso-font-charset:1;
mso-generic-font-family:roman;
mso-font-format:other;
mso-font-pitch:variable;
mso-font-signature:0 0 0 0 0 0;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:-520092929 1073786111 9 0 415 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-parent:"";
margin-top:0cm;
margin-right:0cm;
margin-bottom:10.0pt;
margin-left:0cm;
text-align:right;
line-height:115%;
mso-pagination:widow-orphan;
direction:rtl;
unicode-bidi:embed;
font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoChpDefault
{mso-style-type:export-only;
mso-default-props:yes;
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoPapDefault
{mso-style-type:export-only;
margin-bottom:10.0pt;
line-height:115%;}
@page Section1
{size:595.3pt 841.9pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
mso-header-margin:35.4pt;
mso-footer-margin:35.4pt;
mso-paper-source:0;
mso-gutter-direction:rtl;}
div.Section1
{page:Section1;}
-->
</style> <br />
<div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: blue; font-family: "Courier New"; font-size: 10pt;"><div</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">id</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"b-navbar2"</span></b><span style="color: blue; font-family: "Courier New"; font-size: 10pt;">></span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: blue; font-family: "Courier New"; font-size: 10pt;"><form</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">style</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"display: inline;"</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">method</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"get"</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">action</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"http://ycouriel-archive.blogspot.com/search"</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">id</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"searchthis"</span></b><span style="color: blue; font-family: "Courier New"; font-size: 10pt;">></span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: blue; font-family: "Courier New"; font-size: 10pt;"><div</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">id</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"b-query-box"</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">style</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"width: 193.7px;"</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: blue; font-family: "Courier New"; font-size: 10pt;">></span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: blue; font-family: "Courier New"; font-size: 10pt;"><table</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">cellspacing</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"0"</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">cellpadding</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"0"</span></b><span style="color: blue; font-family: "Courier New"; font-size: 10pt;">></span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: blue; font-family: "Courier New"; font-size: 10pt;"><tbody></span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: blue; font-family: "Courier New"; font-size: 10pt;"><tr></span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: blue; font-family: "Courier New"; font-size: 10pt;"><style</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">type</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"text/css"</span></b><span style="color: blue; font-family: "Courier New"; font-size: 10pt;">></span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">#b-navbar2{<o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">white-space:nowrap;color:#fff;height:29px;border-bottom:1px solid #024;background:transparent;font-size:13px;font-family:Arial,Sans-serif<o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">}<o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">#b-navbar2 #b-query-box{<o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">background-color:#fff;margin:0 .5em 0 0;border:1px solid transparent;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;padding:0 .3em<o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">}<o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">#b-navbar2 #b-query-box:hover{<o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">border:1px solid #999999;<o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">}<o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">#b-navbar2 #b-query-icon{<o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">display:block;width:13px;height:13px;cursor:pointer;cursor:hand;background:url(http://img1.blogblog.com/img/navbar/icons_orange.png) no-repeat 0 0<o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">}<o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">#b-navbar2 #b-query-icon:hover{<o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">background:url(http://img1.blogblog.com/img/navbar/icons_orange.png) no-repeat -13px 0<o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">}<o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">#b-navbar2 #b-query{<o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">font-size:13px;color:#000;background-color:transparent;border:none;margin:0<o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">}<o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: blue; font-family: "Courier New"; font-size: 10pt;"></style></span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: blue; font-family: "Courier New"; font-size: 10pt;"><td</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">valign</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"middle"</span></b><span style="color: blue; font-family: "Courier New"; font-size: 10pt;">></span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: blue; font-family: "Courier New"; font-size: 10pt;"><input</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">type</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"text"</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">title</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"Search"</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">style</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"width: 180px; color: #999999;"</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">tabindex</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"3"</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">name</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"q"</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">id</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"b-query"</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">onblur</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"if (this.value == '') {this.value = 'Search...'; this.style.color='#999999';}"</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">onfocus</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"if(this.value == 'Search...') {this.style.color='#000000';this.value = '';}"</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">value</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"Search..."</span></b><span style="color: blue; font-family: "Courier New"; font-size: 10pt;">></span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: blue; font-family: "Courier New"; font-size: 10pt;"></td></span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: blue; font-family: "Courier New"; font-size: 10pt;"><td</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">valign</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"right"</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">style</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"width: 15px;"</span></b><span style="color: blue; font-family: "Courier New"; font-size: 10pt;">></span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: blue; font-family: "Courier New"; font-size: 10pt;"><a</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">title</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"Search this blog"</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">onclick</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"document.getElementById(&quot;searchthis&quot;).submit();"</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">id</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"b-query-icon"</span></b><span style="color: blue; font-family: "Courier New"; font-size: 10pt;">></a></td></tr></tbody></table></div></form></span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: blue; font-family: "Courier New"; font-size: 10pt;"><script</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">language</span><span style="color: black; font-family: "Courier New"; font-size: 10pt;">=</span><b><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">"JavaScript"</span></b><span style="color: blue; font-family: "Courier New"; font-size: 10pt;">></span><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><i><span style="color: navy; font-family: "Courier New"; font-size: 10pt;">function</span></i></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> gup<b>(</b> name <b>)</b><o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">{</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> name <b>=</b> name.replace<b>(</b></span><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">/[\[]/</span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">,</span></b><span style="color: grey; font-family: "Courier New"; font-size: 10pt;">"\\\["</span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">).</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">replace<b>(</b></span><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">/[\]]/</span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">,</span></b><span style="color: grey; font-family: "Courier New"; font-size: 10pt;">"\\\]"</span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">);</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><b><i><span style="color: navy; font-family: "Courier New"; font-size: 10pt;">var</span></i></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> regexS <b>=</b> </span><span style="color: grey; font-family: "Courier New"; font-size: 10pt;">"[\\?&]"</span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">+</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">name<b>+</b></span><span style="color: grey; font-family: "Courier New"; font-size: 10pt;">"=([^&#]*)"</span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">;</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><b><i><span style="color: navy; font-family: "Courier New"; font-size: 10pt;">var</span></i></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> regex <b>=</b> </span><b><i><span style="color: navy; font-family: "Courier New"; font-size: 10pt;">new</span></i></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> RegExp<b>(</b> regexS <b>);</b><o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><b><i><span style="color: navy; font-family: "Courier New"; font-size: 10pt;">var</span></i></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> results <b>=</b> regex.exec<b>(</b> window.location.href <b>);</b><o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><b><i><span style="color: navy; font-family: "Courier New"; font-size: 10pt;">if</span></i></b><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">(</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> results <b>==</b> null <b>)</b><o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><b><i><span style="color: navy; font-family: "Courier New"; font-size: 10pt;">return</span></i></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: grey; font-family: "Courier New"; font-size: 10pt;">""</span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">;</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><b><i><span style="color: navy; font-family: "Courier New"; font-size: 10pt;">else</span></i></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><b><i><span style="color: navy; font-family: "Courier New"; font-size: 10pt;">return</span></i></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> results<b>[</b></span><span style="color: red; font-family: "Courier New"; font-size: 10pt;">1</span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">];</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">}</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><br />
</div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><i><span style="color: navy; font-family: "Courier New"; font-size: 10pt;">function</span></i></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> decode<b>(</b>encoded<b>)</b> <b>{</b><o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><b><i><span style="color: navy; font-family: "Courier New"; font-size: 10pt;">return</span></i></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> decodeURIComponent<b>(</b>encoded.replace<b>(</b></span><span style="color: #8000ff; font-family: "Courier New"; font-size: 10pt;">/\+/g</span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">,</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><span style="color: grey; font-family: "Courier New"; font-size: 10pt;">" "</span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">));</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">}</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> <o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><br />
</div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><i><span style="color: navy; font-family: "Courier New"; font-size: 10pt;">var</span></i></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> q <b>=</b> gup<b>(</b></span><span style="color: grey; font-family: "Courier New"; font-size: 10pt;">"q"</span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">);</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><i><span style="color: navy; font-family: "Courier New"; font-size: 10pt;">if</span></i></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> <b>(</b>q <b>!=</b> </span><span style="color: grey; font-family: "Courier New"; font-size: 10pt;">""</span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">)</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> <b>{</b><o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> </span><b><i><span style="color: navy; font-family: "Courier New"; font-size: 10pt;">var</span></i></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> lmnt <b>=</b> document.getElementById<b>(</b></span><span style="color: grey; font-family: "Courier New"; font-size: 10pt;">"b-query"</span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">);</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> lmnt.value <b>=</b> decode<b>(</b>q<b>);</b><o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: black; font-family: "Courier New"; font-size: 10pt;"> lmnt.style.color <b>=</b> </span><span style="color: grey; font-family: "Courier New"; font-size: 10pt;">"#000000"</span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">;</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;">}</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></div><div class="MsoNormal" dir="LTR" style="background: none repeat scroll 0% 0% white; direction: ltr; line-height: normal; margin-bottom: 0.0001pt; text-align: left; unicode-bidi: embed;"><span style="color: blue; font-family: "Courier New"; font-size: 10pt;"></script></span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt;"><o:p></o:p></span></b></div><div class="MsoNormal" dir="LTR" style="direction: ltr; text-align: left; unicode-bidi: embed;"><br />
</div>ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com3tag:blogger.com,1999:blog-368378466834354558.post-32653950724888388902010-01-21T19:33:00.000-08:002010-02-20T16:08:23.293-08:00My upgrades to XNA 2D beginners tutorialI used a XNA 2D beginners tutorial and changed it to a more generic and flexible code.<br />
I also added explosions and sound.<br />
The new classes I created can be used for any 2D XNA game.<br />
The tutorial is here: <a href="http://creators.xna.com/en-US/education/gettingstarted/bg2d/chapter1">http://creators.xna.com/en-US/education/gettingstarted/bg2d/chapter1</a>Explanations and demo of explosions: <a href="http://creators.xna.com/en-US/sample/particle">http://creators.xna.com/en-US/sample/particle</a><br />
The demo project with the new classes: <a href="http://www.megaupload.com/?d=NEMV4EF3">http://www.megaupload.com/?d=NEMV4EF3</a><br />
Screenshot:<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivxfaL4LY5TraWyAOYWMy1bQPqSKpyaYtABvs2nATg-AIbAqrYOIzoM8Qvixl-xi-q5Rhn7WGBw_3ltH0YUkbXJmP0UrIBSm-Um6J72VZqFZ8hrlypC2lcvL5egsGkX75C8DT9hXt2wiU/s1600-h/exp13xna1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivxfaL4LY5TraWyAOYWMy1bQPqSKpyaYtABvs2nATg-AIbAqrYOIzoM8Qvixl-xi-q5Rhn7WGBw_3ltH0YUkbXJmP0UrIBSm-Um6J72VZqFZ8hrlypC2lcvL5egsGkX75C8DT9hXt2wiU/s400/exp13xna1.jpg" /></a><br />
</div>Most of the code can't be figured from the screenshot.<br />
I created some generic classes to represent static objects, moving objects, particles, and particles systems. I wrote the most important things about some classes:<br />
<ul><li><span style="color: blue; font-family: "Courier New"; font-size: 10pt; line-height: 115%;">class</span><span style="font-family: "Courier New"; font-size: 10pt; line-height: 115%;"> <span style="color: #2b91af;">GameObject2</span> : <span style="color: #2b91af;">DrawableGameComponent</span></span><ul><li>Represents a static 2D object</li>
<li>Has the following additional properties:</li>
<ul style="font-family: "Courier New",Courier,monospace;"><li>Texture <br />
</li>
<li>Position</li>
<li>Center</li>
<li>Rotation</li>
<li>Scale</li>
<li>DestinationRectangle</li>
<li>CenterPosition</li>
<li>Active</li>
<li>SourceRectangle</li>
<li>Color</li>
<li>Effects</li>
<li>LayerDepth</li>
<li>SpriteBlendMode</li>
</ul><li>Has 8 different constructors for different purposes</li>
<li>Overrides <span style="font-family: "Courier New",Courier,monospace;">Draw()</span> method<br />
</li>
</ul><br />
<br />
</li>
<li><style>
<!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;
mso-font-charset:0;
mso-generic-font-family:roman;
mso-font-pitch:variable;
mso-font-signature:-1610611985 1107304683 0 0 415 0;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:-520092929 1073786111 9 0 415 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-parent:"";
margin-top:0cm;
margin-right:0cm;
margin-bottom:10.0pt;
margin-left:0cm;
text-align:right;
line-height:115%;
mso-pagination:widow-orphan;
direction:rtl;
unicode-bidi:embed;
font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoChpDefault
{mso-style-type:export-only;
mso-default-props:yes;
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoPapDefault
{mso-style-type:export-only;
margin-bottom:10.0pt;
line-height:115%;}
@page Section1
{size:612.0pt 792.0pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
mso-header-margin:36.0pt;
mso-footer-margin:36.0pt;
mso-paper-source:0;}
div.Section1
{page:Section1;}
-->
</style><span style="color: blue; font-family: "Courier New"; font-size: 10pt;">class</span><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: #2b91af;">MovingGameObject2</span> : <span style="color: #2b91af;">GameObject2</span></span></li>
<ul><li>Represents an 2D object that moves</li>
<li>Has the following additional properties:</li>
<ul style="font-family: "Courier New",Courier,monospace;"><li>Velocity</li>
<li>Acceleration</li>
<li>RotationSpeed</li>
<li>TimeSinceInit</li>
</ul><li>Overrides <span style="font-family: "Courier New",Courier,monospace;">Update()</span> method <br />
</li>
</ul></ul><ul><ul></ul><li><style>
<!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;
mso-font-charset:0;
mso-generic-font-family:roman;
mso-font-pitch:variable;
mso-font-signature:-1610611985 1107304683 0 0 415 0;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:-520092929 1073786111 9 0 415 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-parent:"";
margin-top:0cm;
margin-right:0cm;
margin-bottom:10.0pt;
margin-left:0cm;
text-align:right;
line-height:115%;
mso-pagination:widow-orphan;
direction:rtl;
unicode-bidi:embed;
font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoChpDefault
{mso-style-type:export-only;
mso-default-props:yes;
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoPapDefault
{mso-style-type:export-only;
margin-bottom:10.0pt;
line-height:115%;}
@page Section1
{size:612.0pt 792.0pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
mso-header-margin:36.0pt;
mso-footer-margin:36.0pt;
mso-paper-source:0;}
div.Section1
{page:Section1;}
-->
</style><span style="color: blue; font-family: "Courier New"; font-size: 10pt;">class</span><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: #2b91af;">Particle2</span> : <span style="color: #2b91af;">MovingGameObject2</span></span> </li>
<ul><li>Represents a 2D particle like in an explosion</li>
<li>Has a <span style="font-family: "Courier New",Courier,monospace;">Lifetime </span>property</li>
<li>Overrides <span style="font-family: "Courier New",Courier,monospace;">Update()</span> method <br />
</li>
</ul></ul><ul><li><style>
<!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;
mso-font-charset:0;
mso-generic-font-family:roman;
mso-font-pitch:variable;
mso-font-signature:-1610611985 1107304683 0 0 415 0;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:-520092929 1073786111 9 0 415 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-parent:"";
margin-top:0cm;
margin-right:0cm;
margin-bottom:10.0pt;
margin-left:0cm;
text-align:right;
line-height:115%;
mso-pagination:widow-orphan;
direction:rtl;
unicode-bidi:embed;
font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoChpDefault
{mso-style-type:export-only;
mso-default-props:yes;
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoPapDefault
{mso-style-type:export-only;
margin-bottom:10.0pt;
line-height:115%;}
@page Section1
{size:612.0pt 792.0pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
mso-header-margin:36.0pt;
mso-footer-margin:36.0pt;
mso-paper-source:0;}
div.Section1
{page:Section1;}
-->
</style><span style="color: blue; font-family: "Courier New"; font-size: 10pt;">abstract</span><span style="font-family: "Courier New"; font-size: 10pt;"> <span style="color: blue;">class</span> <span style="color: #2b91af;">ParticleSystem2</span> : <span style="color: #2b91af;">GameObject2</span></span> </li>
<ul><li>Represents a 2D particle system that can be used for explosions, smoke etc.</li>
<li>Has the following protected parameters:</li>
<ul style="font-family: "Courier New",Courier,monospace;"><li>rangeParticlesPerEffect</li>
<li>rangeVelocity</li>
<li>rangeAcceleration</li>
<li>rangeRotation</li>
<li>rangeRotationSpeed</li>
<li>rangeScale</li>
<li>rangeLifetime</li>
</ul><li>Each new particle gets a random value for each parameter from its range </li>
<li>Overrides <span style="font-family: "Courier New",Courier,monospace;">Draw()</span> and <span style="font-family: "Courier New",Courier,monospace;">Update()</span> methods<br />
</li>
</ul></ul><ul><ul></ul></ul>ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com1tag:blogger.com,1999:blog-368378466834354558.post-524417389603013112010-01-05T22:04:00.000-08:002010-02-20T16:09:06.371-08:00How to restore Visual Studio .sln file iconI merely tried to associate .sln file type with the IDE so Windows 7 taskbar will remember my recent projects and I could access them with right click. I ended up reinstalling Visual Studio. This was after I tried to fix it in registry, just to find out Windows 7 has a different mechanism for file types associations. The big frustration was I could not find the icons themselves to put them on the registry. Visual Studio has a "Restore File Associations" feature. It doesn't fix the icons! Reinstalling after deleting all related registry values didn't work either! After a couple of hours where I visited sites like <a href="http://toastytech.com/evil/killbill.html">Ways Bill Gates Should Die</a>, and Googling a lot I found the solution:<br />
<br />
<ol><li>Right click a .sln file</li>
<li>Click "Open with..."</li>
<li>Click "Browse..."</li>
<li>Go to "Program Files\Common Files\microsoft shared\MSEnv"</li>
<li>Choose "VSLauncher.exe"</li>
<li>Click "Open"</li>
<li>Check "Always use the selected program to open this kind of file"</li>
<li>Click "OK"<br />
</li>
</ol>ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com3tag:blogger.com,1999:blog-368378466834354558.post-60286545578297317822009-12-29T03:05:00.000-08:002010-09-06T09:37:08.471-07:00C# Clipboard in Console ApplicationIn C# accessing the Clipboard suppose to be easy, but you'll find out it doesn't work in the normal way.<br />
Here is a small note from <a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.clipboard.getdataobject.aspx">MSDN</a> that I missed at first:<br />
<style>
<!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;
mso-font-charset:0;
mso-generic-font-family:roman;
mso-font-pitch:variable;
mso-font-signature:-1610611985 1107304683 0 0 415 0;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:-520092929 1073786111 9 0 415 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-parent:"";
margin-top:0cm;
margin-right:0cm;
margin-bottom:10.0pt;
margin-left:0cm;
text-align:right;
line-height:115%;
mso-pagination:widow-orphan;
direction:rtl;
unicode-bidi:embed;
font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoChpDefault
{mso-style-type:export-only;
mso-default-props:yes;
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:Arial;
mso-bidi-theme-font:minor-bidi;}
.MsoPapDefault
{mso-style-type:export-only;
margin-bottom:10.0pt;
line-height:115%;}
@page Section1
{size:612.0pt 792.0pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
mso-header-margin:36.0pt;
mso-footer-margin:36.0pt;
mso-paper-source:0;}
div.Section1
{page:Section1;}
-->
</style> <br />
<blockquote><div class="MsoNormal" style="direction: ltr; line-height: normal; text-align: left; unicode-bidi: embed;"><span style="font-family: "Times New Roman","serif"; font-size: 12pt;">The <a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.clipboard.aspx"><span style="color: blue;">Clipboard</span></a> class can only be used in threads set to single thread apartment (STA) mode. To use this class, ensure that your Main method is marked with the <a href="http://msdn.microsoft.com/en-us/library/system.stathreadattribute.aspx"><span style="color: blue;">STAThreadAttribute</span></a> attribute. <o:p></o:p></span></div></blockquote>So, in a Console application, use this function:<br />
<style type="text/css">
.csharpcode, .csharpcode pre
{
font-size: 13.3333px;
font-width: 400;
color: black;
font-family: "Courier New";
}
.csharpcode pre { margin: 0px; }
.csharpcode .comment { color: #008000; }
.csharpcode .comment2 { color: #808080; }
.csharpcode .type { color: #2B91AF; }
.csharpcode .keyword { color: #0000FF; }
.csharpcode .string { color: #A31515; }
.csharpcode .preproc { color: #0000FF; }
</style><br />
<div class="csharpcode">Code:<br />
<pre style="background: none repeat scroll 0% 0% rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); color: black; overflow-x: auto; overflow-y: hidden; padding: 0px; text-align: left; word-wrap: normal;"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">object</span> GetClipboardData()
{
<span class="keyword">object</span> ret = <span class="keyword">null</span>;
<span class="type">ThreadStart</span> method = <span class="keyword">delegate</span>()
{
System.Windows.Forms.<span class="type">IDataObject</span> dataObject = <span class="type">Clipboard</span>.GetDataObject();
<span class="keyword">if</span> (dataObject != <span class="keyword">null</span> && dataObject.GetDataPresent(<span class="type">DataFormats</span>.<span class="type">Text</span>))
{
ret = dataObject.GetData(<span class="type">DataFormats</span>.<span class="type">Text</span>);
}
};
<span class="keyword">if</span> (<span class="type">Thread</span>.CurrentThread.GetApartmentState() != <span class="type">ApartmentState</span>.STA)
{
<span class="type">Thread</span> thread = <span class="keyword">new</span> <span class="type">Thread</span>(method);
thread.SetApartmentState(<span class="type">ApartmentState</span>.STA);
thread.Start();
thread.Join();
}
<span class="keyword">else</span>
{
method();
}
<span class="keyword">return</span> ret;
}</pre></div>ycourielhttp://www.blogger.com/profile/03611193432268156631noreply@blogger.com4