<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:georss="http://www.georss.org/georss"><id>tag:blogger.com,1999:blog-35928092</id><updated>2010-03-02T07:12:31.738-05:00</updated><title type="text">The Macadamian Files</title><subtitle type="html">Discussing the nuts and bolts of software development</subtitle><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/" /><link rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default?start-index=26&amp;max-results=25" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://thefiles.macadamian.com/atom.xml" /><author><name>Sargsyan Tigran</name><uri>http://www.blogger.com/profile/17269775074544232074</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>51</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/macadamian/thefiles" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="macadamian/thefiles" /><entry><id>tag:blogger.com,1999:blog-35928092.post-8255893885955056836</id><published>2010-03-02T06:50:00.010-05:00</published><updated>2010-03-02T07:12:26.648-05:00</updated><title type="text">RIATest: Automating Custom Components</title><content type="html">&lt;a href="http://www.riatest.com/"&gt;RIATest&lt;/a&gt; is a GUI test automation tool for &lt;a href="http://www.adobe.com/products/flex/"&gt;Adobe Flex&lt;/a&gt; applications. RIATest does for your GUI what FlexUnit does for your code, and it is available on Windows and Mac OS X. RIATest has number of useful features which can be very helpful, such as component inspector, script debugger, and synchronization capabilities. You can find the full list of features &lt;a href="http://www.riatest.com/products/features.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;When you specify actions that must be performed on your application the first thing you specify is what component you want to be located by RIATest so that an action can be performed on it. RIATest has few ways of locating components. One of the ways is locating component by label e.g. button with "Save" label can be located following way:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;FlexButton("Save")&lt;/pre&gt;&lt;br /&gt;Component can be located in a same manner using components automatationName. You can also locate component using its automationIndex:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;FlexButton("index:0")&lt;/pre&gt;&lt;br /&gt;&lt;blockquote&gt;In most of the cases you are getting every component which you need in the inspector, so you can easily locate those components. In case you derive a custom class from built-in container-type classes you usually do not need to do anything special to make children of your custom component available for automation since this is done by the automation delegate of base class.&lt;br /&gt;&lt;br /&gt;However sometimes you implement a custom component that contains other components but your custom component is not derived from Container built-in class. If that is the case you need to expose components contained in your custom class. You will need  to perform some additional steps to access them.&lt;/blockquote&gt;&lt;br /&gt;Let's discuss one exact example. Here we have a CustomPanel with a button added in its title bar. You will notice that the button which you just added is not visible in the inspector:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_HTeaIVjhZ04/S2qTlh50tJI/AAAAAAAAACk/o6ReDJMOcuA/s1600-h/noSwitch.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="256" src="http://1.bp.blogspot.com/_HTeaIVjhZ04/S2qTlh50tJI/AAAAAAAAACk/o6ReDJMOcuA/s320/noSwitch.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;So what we can do? We need to implement automation delegate class for our custom component. Exposing child components is done by implementing numAutomationChildren/getAutomationChildAt pair of functions. numAutomationChildren function must return the number of children component for your custom class, getAutomationChildAt must return the child at the specified index. This means we need to implement automatation delegate class for our custom component to make Switch button accessible from RIATest.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;numAutomationChildren&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In our case we will need to return the number of children which are implementing IAutomationObject plus Switch button:&lt;br /&gt;&lt;pre class="code"&gt;override public function get numAutomationChildren() : int {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var count:int = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for(var i:int=0; i &amp;lt; comp.numChildren; i++) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (comp.getChildAt(i) is IAutomationObject)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;count++;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return ++count;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;getAutomationChildAt&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;getAutomationChildAt will need to return the child with a given index in case of index &amp;lt; numChildren and return Switch button in case of index == numChildren&lt;br /&gt;&lt;pre class="code"&gt;override public function getAutomationChildAt( index : int ) : IAutomationObject {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (index &amp;gt;= 0 &amp;amp;&amp;amp; index &amp;lt; comp.numChildren )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return comp.getChildAt(index) as IAutomationObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(index == comp.numChildren)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return comp.button;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return null;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;We will also need to implement init method in order to register our delegate class:&lt;br /&gt;&lt;pre class="code"&gt;public static function init( root : DisplayObject ) : void {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Automation.registerDelegateClass( CustomPanel, CustomPanelAutomationImpl);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;The only thing left to do is to include our delegate into build, include your delegate class using additional compiler arguments:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;-includes CustomPanelAutomationImpl&lt;/pre&gt;&lt;br /&gt;As you can see from the screenshot now Switch button is getting displayed in the inspector, so you can easily locate it:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_HTeaIVjhZ04/S2qT1P8wjlI/AAAAAAAAACo/zdQc2oFuCK8/s1600-h/Switch.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="256" src="http://2.bp.blogspot.com/_HTeaIVjhZ04/S2qT1P8wjlI/AAAAAAAAACo/zdQc2oFuCK8/s320/Switch.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;pre class="code"&gt;FlexPanel("index:0")-&amp;gt;FlexButton("Switch")=&amp;gt;click();&lt;/pre&gt;&lt;br /&gt;You can download source code of this project from &lt;a href="http://vini1987.yolasite.com/resources/TestPanel.zip"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-8255893885955056836?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/Q3MhxE4ORDc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/8255893885955056836/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=8255893885955056836" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/8255893885955056836" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/8255893885955056836" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2010/03/riatest-automating-custom-components.html" title="RIATest: Automating Custom Components" /><author><name>Sargsyan Tigran</name><uri>http://www.blogger.com/profile/17269775074544232074</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="06043168613356651551" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_HTeaIVjhZ04/S2qTlh50tJI/AAAAAAAAACk/o6ReDJMOcuA/s72-c/noSwitch.PNG" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-838774620973074139</id><published>2009-09-18T10:44:00.005-04:00</published><updated>2009-09-18T12:25:34.855-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Maven" /><category scheme="http://www.blogger.com/atom/ns#" term="compiler" /><title type="text">Maven Compiler Tips and Tricks</title><content type="html">&lt;style&gt; &lt;!--  /* Font Definitions */  @font-face  {font-family:"Cambria Math";  panose-1:0 0 0 0 0 0 0 0 0 0;  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:-1610611985 1073750139 0 0 159 0;}  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal  {mso-style-unhide:no;  mso-style-qformat:yes;  mso-style-parent:"";  margin-top:0in;  margin-right:0in;  margin-bottom:10.0pt;  margin-left:0in;  line-height:115%;  mso-pagination:widow-orphan;  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:"Times New Roman";  mso-bidi-theme-font:minor-bidi;} p.MsoFootnoteText, li.MsoFootnoteText, div.MsoFootnoteText  {mso-style-noshow:yes;  mso-style-priority:99;  mso-style-link:"Footnote Text Char";  margin:0in;  margin-bottom:.0001pt;  mso-pagination:widow-orphan;  font-size:10.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:"Times New Roman";  mso-bidi-theme-font:minor-bidi;} span.MsoFootnoteReference  {mso-style-noshow:yes;  mso-style-priority:99;  vertical-align:super;} p.MsoNoSpacing, li.MsoNoSpacing, div.MsoNoSpacing  {mso-style-priority:1;  mso-style-unhide:no;  mso-style-qformat:yes;  mso-style-parent:"";  margin:0in;  margin-bottom:.0001pt;  mso-pagination:widow-orphan;  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:"Times New Roman";  mso-bidi-theme-font:minor-bidi;} span.FootnoteTextChar  {mso-style-name:"Footnote Text Char";  mso-style-noshow:yes;  mso-style-priority:99;  mso-style-unhide:no;  mso-style-locked:yes;  mso-style-link:"Footnote Text";  mso-ansi-font-size:10.0pt;  mso-bidi-font-size:10.0pt;} .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:"Times New Roman";  mso-bidi-theme-font:minor-bidi;} .MsoPapDefault  {mso-style-type:export-only;  margin-bottom:10.0pt;  line-height:115%;}  /* Page Definitions */  @page  {mso-footnote-separator:url("file:///C:/DOCUME~1/dmenard/LOCALS~1/Temp/msohtmlclip1/01/clip_header.htm") fs;  mso-footnote-continuation-separator:url("file:///C:/DOCUME~1/dmenard/LOCALS~1/Temp/msohtmlclip1/01/clip_header.htm") fcs;  mso-endnote-separator:url("file:///C:/DOCUME~1/dmenard/LOCALS~1/Temp/msohtmlclip1/01/clip_header.htm") es;  mso-endnote-continuation-separator:url("file:///C:/DOCUME~1/dmenard/LOCALS~1/Temp/msohtmlclip1/01/clip_header.htm") ecs;} @page Section1  {size:8.5in 11.0in;  margin:1.0in 1.0in 1.0in 1.0in;  mso-header-margin:.5in;  mso-footer-margin:.5in;  mso-paper-source:0;} div.Section1  {page:Section1;} --&gt; &lt;/style&gt;&lt;!--[if gte mso 10]&gt; &lt;style&gt;  /* Style Definitions */  table.MsoNormalTable  {mso-style-name:"Table Normal";  mso-tstyle-rowband-size:0;  mso-tstyle-colband-size:0;  mso-style-noshow:yes;  mso-style-priority:99;  mso-style-qformat:yes;  mso-style-parent:"";  mso-padding-alt:0in 5.4pt 0in 5.4pt;  mso-para-margin-top:0in;  mso-para-margin-right:0in;  mso-para-margin-bottom:10.0pt;  mso-para-margin-left:0in;  line-height:115%;  mso-pagination:widow-orphan;  font-size:11.0pt;  font-family:"Calibri","sans-serif";  mso-ascii-font-family:Calibri;  mso-ascii-theme-font:minor-latin;  mso-fareast-font-family:"Times New Roman";  mso-fareast-theme-font:minor-fareast;  mso-hansi-font-family:Calibri;  mso-hansi-theme-font:minor-latin;} &lt;/style&gt; &lt;![endif]--&gt;    &lt;p class="MsoNormal"&gt;Apache’s &lt;a href="http://maven.apache.org/"&gt;Maven&lt;/a&gt; is a great tool for managing a build environment: it keeps track of all project dependencies and provides a number of configurable build phases which can add depth to the build process. Building a project from the ground-up with Maven is a sure-fire way to keep it well organized and easy to maintain – but what about adding Maven on to an existing project, or worse, merging a non-Maven project into a project that already relies on Maven?&lt;/p&gt;  &lt;p class="MsoNormal"&gt;What follows is a look at some of the lessons I’ve learned from tweaking compiler plug-ins and digging through search results to debug various Maven-related issues. Hopefully it will be useful to the next developer who happens to hit similar issues, and if you have tips of your own be sure to leave a comment.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span style="line-height: 115%;font-size:14pt;" &gt;The &lt;i style=""&gt;maven-compiler-plugin&lt;/i&gt; &amp;lt;include&amp;gt; property&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;When overriding the default maven-compiler-plugin, the &amp;lt;include&amp;gt; tag may be used to force the compiler to include extra files into the build. There are a couple of interesting points to note here:&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 0.5in;"&gt;&lt;b style=""&gt;It is a filter&lt;/b&gt;. Many things in Maven expect a path to a directory, but not the &amp;lt;include&amp;gt; tag. If you have some extra java classes in src/main/java and you pass that to &amp;lt;include&amp;gt; it will fail silently – what you actually want is src/main/java/**/*.java.&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 0.5in;"&gt;&lt;b style=""&gt;It is for the compile-phase only&lt;/b&gt;. By default, in addition to using the maven-compiler-plugin during the compile phase, Maven will also use it during the test-compile phase. Most properties will apply to both, but &amp;lt;include&amp;gt; is not one of them; the test-compile phase requires a separate property, &amp;lt;testIncludes&amp;gt;, for any includables it requires&lt;a style="" href="http://www.blogger.com/post-edit.do#_ftn1" name="_ftnref1" title=""&gt;&lt;span class="MsoFootnoteReference"&gt;&lt;span style=""&gt;&lt;!--[if !supportFootnotes]--&gt;&lt;span class="MsoFootnoteReference"&gt;&lt;span style="line-height: 115%;font-family:&amp;quot;;font-size:11pt;"  &gt;[1]&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span style="line-height: 115%;font-size:14pt;" &gt;The generate-sources and generate-resources phases&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;These phases are great for adding source (.java) and resource (.class) files to the compiler before the compile phase occurs. The snippet below shows how to use &lt;a href="http://mojo.codehaus.org/build-helper-maven-plugin/usage.html"&gt;mojo's build-helper-plugin&lt;/a&gt; to add some obscure .class files to the classpath:&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;/p&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&amp;lt;plugin&amp;gt;&lt;br /&gt;  &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;&lt;br /&gt;  &amp;lt;artifactId&amp;gt;build-helper-maven-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;  &amp;lt;executions&amp;gt;&lt;br /&gt;      &amp;lt;execution&amp;gt;&lt;br /&gt;          &amp;lt;phase&amp;gt;generate-resources&amp;lt;/phase&amp;gt;&lt;br /&gt;          &amp;lt;goals&amp;gt;&lt;br /&gt;              &amp;lt;goal&amp;gt;add-resource&amp;lt;/goal&amp;gt;&lt;br /&gt;          &amp;lt;/goals&amp;gt;&lt;br /&gt;          &amp;lt;configuration&amp;gt;&lt;br /&gt;              &amp;lt;resources&amp;gt;&lt;br /&gt;                  &amp;lt;resource&amp;gt;&lt;br /&gt;                      &amp;lt;directory&amp;gt;../obscure/classes&amp;lt;/directory&amp;gt;&lt;br /&gt;                  &amp;lt;/resource&amp;gt;&lt;br /&gt;          &amp;lt;/configuration&amp;gt;&lt;br /&gt;      &amp;lt;/execution&amp;gt;&lt;br /&gt;  &amp;lt;/executions&amp;gt;&lt;br /&gt;&amp;lt;/plugin&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;Now any .class files in ../obscure/classes (or any subdirectories) will be added to the classpath.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;The same plug-in is used for adding .java files, simply tweak the generate-resources and add-resource values to generate-sources and add-source, and the &amp;lt;resources&amp;gt; and &amp;lt;resource&amp;gt; properties to &amp;lt;sources&amp;gt; and &amp;lt;source&amp;gt;.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span style="line-height: 115%;font-size:14pt;" &gt;The &lt;i style=""&gt;maven-compiler-plugin&lt;/i&gt; &amp;lt;compilerArgument&amp;gt; property&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;The &amp;lt;complierArgument&amp;gt; tag may be used to pass command-line arguments directly to the java compiler. Two examples:&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 0.5in;"&gt;&lt;b style=""&gt;&amp;lt;classpath&amp;gt;&lt;/b&gt; seems like it would let you add resources to the classpath, but near as I can tell, these aren’t actually used. Maven seems to prefer managing its own classpath, though we can still add/remove entries by overriding the default generate-resources phase (as explained above).&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 0.5in;"&gt;&lt;b style=""&gt;&amp;lt;sourcepath&amp;gt;&lt;/b&gt; is a great way to specify multiple source directories for compilation. It takes a semicolon-delimited list of top-level directories containing java files to compile. Alternately, an override of the generate-sources phase may be used here as well.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;One gotcha with regards to sourcepath: to get this to work, I had to manually set &amp;lt;fork&amp;gt; to true on the maven-compiler-plugin. In fact, this gets even worse: when &amp;lt;fork&amp;gt; is true, Maven will use the %PATH% environment variable to determine which JRE to use, and this will fail with a totally non-descript error if the path to your JRE contains any spaces – very annoying to track down. This is actually a bug in Maven, logged here (http://jira.codehaus.org/browse/MCOMPILER-30).&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span style="line-height: 115%;font-size:14pt;" &gt;The &amp;lt;sourceDirectory&amp;gt; property&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;A minor but important tag when playing around with various sources and resources, the &amp;lt;sourceDirectory&amp;gt; tag may be used to set the base directory for including java source files.&lt;span style=""&gt;  &lt;/span&gt;It defaults to src/main/java, but I found when playing around with a lot of sources spread around various directories, it was easiest to set it to the current directory as follows:&lt;/p&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&amp;lt;build&amp;gt;&lt;br /&gt;  &amp;lt;sourceDirectory&amp;gt;.&amp;lt;/sourceDirectory&amp;gt;&lt;br /&gt;  {...}&lt;br /&gt;&amp;lt;/build&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span style="line-height: 115%;font-size:14pt;" &gt;Other useful debugging hints&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;When running into problems, it’s always good to have a few debug flags around to get a little more information out of Maven, which is generally not great at telling you what might be wrong.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Specifying the &lt;b style=""&gt;-e&lt;/b&gt; flag while running Maven will print out any exceptions Maven encounters, with the corresponding stack trace.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;The &lt;b style=""&gt;&amp;lt;verbose&amp;gt; &lt;/b&gt;tag may be added inside any plug-in’s &amp;lt;configuration&amp;gt; property and when toggled to true (default is false) it will print some extra information, including the sourcepath and classpath being used by Maven’s compiler.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Specifying the &lt;b style=""&gt;-X&lt;/b&gt; flag while running Maven will document all kinds of intermediate steps Maven takes during the build – much more than -e and &amp;lt;verbose&amp;gt;.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;div style=""&gt;&lt;!--[if !supportFootnotes]--&gt;&lt;br /&gt;&lt;hr align="left" size="1" width="33%"&gt;  &lt;!--[endif]--&gt;  &lt;div style="" id="ftn1"&gt;  &lt;p class="MsoFootnoteText"&gt;&lt;a style="" href="http://www.blogger.com/post-edit.do#_ftnref1" name="_ftn1" title=""&gt;&lt;span class="MsoFootnoteReference"&gt;&lt;span style=""&gt;&lt;!--[if !supportFootnotes]--&gt;&lt;span class="MsoFootnoteReference"&gt;&lt;span style="line-height: 115%;font-family:&amp;quot;;font-size:10pt;"  &gt;[1]&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; This makes perfect sense, of course: it’s unlikely that you’ll want the same includables for both the normal compiler and the testing compiler. It’s just counter-intuitive compared to the rest of the &amp;lt;configuration&amp;gt; properties.&lt;/p&gt;  &lt;/div&gt;  &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-838774620973074139?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/PFyBKwZl-2o" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/838774620973074139/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=838774620973074139" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/838774620973074139" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/838774620973074139" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2009/09/maven-compiler-tips-and-tricks.html" title="Maven Compiler Tips and Tricks" /><author><name>Dan M</name><uri>http://www.blogger.com/profile/07261008052647160453</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03229345788419499251" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-330840305863602493</id><published>2009-07-17T09:08:00.010-04:00</published><updated>2009-07-18T02:39:28.719-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="GPS" /><category scheme="http://www.blogger.com/atom/ns#" term="SMS" /><category scheme="http://www.blogger.com/atom/ns#" term="Android" /><title type="text">Here I am!</title><content type="html">This application allows you to send URL link with your location through SMS message. Receiver will be able to see your location on the map(Google Maps) by simply clicking on the link.  First thing we need to do is to get our location using GPS. Android SDK has set of classes and interfaces which makes dealing with location services quite easy. Another positive thing is that SDK is well documented.  We need to get an instance of LocationManager:  &lt;br /&gt;&lt;pre style="-moz-background-clip: border; -moz-background-inline-policy: continuous; -moz-background-origin: padding; background: rgb(239, 239, 239) none repeat scroll 0% 0%; border: thin solid rgb(166, 176, 191); color: black; padding: 10px; width: 100%;"&gt;&lt;span style="color: black;"&gt;LocationManager lm = &lt;/span&gt;&lt;span style="color: black;"&gt;(&lt;/span&gt;&lt;span style="color: black;"&gt;LocationManager&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;/span&gt;&lt;span style="color: white;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;getSystemService&lt;/span&gt;&lt;span style="color: black;"&gt;(&lt;/span&gt;&lt;span style="color: black;"&gt;Context.LOCATION_SERVICE&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;/span&gt;&lt;/pre&gt;Now that we have location manager we need to request location updates from it. The location is requested using requestLocationUpdates method, it registers the current activity to be notified periodically by the named provider. In our case provider is GPS. For tracking location changes we are using LocationListener which is for receiving notifications from the LocationManager when the location has changed.  &lt;br /&gt;&lt;br /&gt;&lt;pre style="-moz-background-clip: border; -moz-background-inline-policy: continuous; -moz-background-origin: padding; background: rgb(239, 239, 239) none repeat scroll 0% 0%; border: thin solid rgb(166, 176, 191); color: black; padding: 10px; width: 100%;"&gt;&lt;span style="color: black;"&gt;lm.requestLocationUpdates&lt;/span&gt;&lt;span style="color: black;"&gt;(&lt;/span&gt;&lt;span style="color: black;"&gt;LocationManager.GPS_PROVIDER, &lt;/span&gt;&lt;span style="color: #990000;"&gt;1000&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: #990000;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;br /&gt;&lt;span style="color: white;"&gt;                &lt;/span&gt;&lt;span style="color: #7f0055;"&gt;&lt;b&gt;new &lt;/b&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;LocationListener&lt;/span&gt;&lt;span style="color: black;"&gt;() {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: white;"&gt;                    &lt;/span&gt;&lt;span style="color: #7f0055;"&gt;&lt;b&gt;public &lt;/b&gt;&lt;/span&gt;&lt;span style="color: #7f0055;"&gt;&lt;b&gt;void &lt;/b&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;onLocationChanged&lt;/span&gt;&lt;span style="color: black;"&gt;(&lt;/span&gt;&lt;span style="color: black;"&gt;Location location&lt;/span&gt;&lt;span style="color: black;"&gt;) &lt;/span&gt;&lt;br /&gt;&lt;span style="color: white;"&gt;                    &lt;/span&gt;&lt;span style="color: black;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="color: white;"&gt;                        &lt;/span&gt;&lt;span style="color: #7f0055;"&gt;&lt;b&gt;double &lt;/b&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;lat = location.getLatitude&lt;/span&gt;&lt;span style="color: black;"&gt;()&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: white;"&gt;                        &lt;/span&gt;&lt;span style="color: #7f0055;"&gt;&lt;b&gt;double &lt;/b&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;lng = location.getLongitude&lt;/span&gt;&lt;span style="color: black;"&gt;()&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;/span&gt;&lt;span style="color: white;"&gt;                        &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: white;"&gt;                        &lt;/span&gt;&lt;span style="color: black;"&gt;latitude.setText&lt;/span&gt;&lt;span style="color: black;"&gt;( &lt;/span&gt;&lt;span style="color: black;"&gt;Double.toString&lt;/span&gt;&lt;span style="color: black;"&gt;( &lt;/span&gt;&lt;span style="color: black;"&gt;lat &lt;/span&gt;&lt;span style="color: black;"&gt;) )&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: white;"&gt;                        &lt;/span&gt;&lt;span style="color: black;"&gt;longitude.setText&lt;/span&gt;&lt;span style="color: black;"&gt;( &lt;/span&gt;&lt;span style="color: black;"&gt;Double.toString&lt;/span&gt;&lt;span style="color: black;"&gt;( &lt;/span&gt;&lt;span style="color: black;"&gt;lng &lt;/span&gt;&lt;span style="color: black;"&gt;) )&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: white;"&gt;                    &lt;/span&gt;&lt;span style="color: black;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: white;"&gt;                    &lt;/span&gt;&lt;span style="color: #7f0055;"&gt;&lt;b&gt;public &lt;/b&gt;&lt;/span&gt;&lt;span style="color: #7f0055;"&gt;&lt;b&gt;void &lt;/b&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;onProviderDisabled&lt;/span&gt;&lt;span style="color: black;"&gt;(&lt;/span&gt;&lt;span style="color: black;"&gt;String provider&lt;/span&gt;&lt;span style="color: black;"&gt;){}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: white;"&gt;                    &lt;/span&gt;&lt;span style="color: #7f0055;"&gt;&lt;b&gt;public &lt;/b&gt;&lt;/span&gt;&lt;span style="color: #7f0055;"&gt;&lt;b&gt;void &lt;/b&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;onProviderEnabled&lt;/span&gt;&lt;span style="color: black;"&gt;(&lt;/span&gt;&lt;span style="color: black;"&gt;String provider&lt;/span&gt;&lt;span style="color: black;"&gt;){}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: white;"&gt;                    &lt;/span&gt;&lt;span style="color: #7f0055;"&gt;&lt;b&gt;public &lt;/b&gt;&lt;/span&gt;&lt;span style="color: #7f0055;"&gt;&lt;b&gt;void &lt;/b&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;onStatusChanged&lt;/span&gt;&lt;span style="color: black;"&gt;(&lt;/span&gt;&lt;span style="color: black;"&gt;String provider, &lt;/span&gt;&lt;span style="color: #7f0055;"&gt;&lt;b&gt;int &lt;/b&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;status,Bundle extras&lt;/span&gt;&lt;span style="color: black;"&gt;){}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: white;"&gt;        &lt;/span&gt;&lt;span style="color: black;"&gt;})&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Just getting last known location... &lt;br /&gt;&lt;pre style="-moz-background-clip: border; -moz-background-inline-policy: continuous; -moz-background-origin: padding; background: rgb(239, 239, 239) none repeat scroll 0% 0%; border: thin solid rgb(166, 176, 191); color: black; padding: 10px; width: 100%;"&gt;&lt;span style="color: black;"&gt;Location location = lm.getLastKnownLocation&lt;/span&gt;&lt;span style="color: black;"&gt;(&lt;/span&gt;&lt;span style="color: black;"&gt;LocationManager.GPS_PROVIDER&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;/span&gt;&lt;/pre&gt;Good! We got the location. Now we just need to generate the URL and send SMS. Android offers full access to SMS functionality from within your applications with the SMSManager.  We are geeting a reference to the SMS Manager using the static method SmsManger.getDefault. For sending SMS message use sendTextMessage, which allows you to send SMS message by specifying text message and receiver's phone number.  &lt;br /&gt;&lt;pre style="-moz-background-clip: border; -moz-background-inline-policy: continuous; -moz-background-origin: padding; background: rgb(239, 239, 239) none repeat scroll 0% 0%; border: thin solid rgb(166, 176, 191); color: black; padding: 10px; width: 100%;"&gt;&lt;span style="color: #000099;"&gt;final&amp;nbsp;SmsManager&amp;nbsp;sm&amp;nbsp;&lt;/span&gt;=&amp;nbsp;SmsManager.getDefault();&lt;br /&gt;&lt;span style="color: #000099;"&gt;String&amp;nbsp;phoneNumber&amp;nbsp;&lt;/span&gt;=&amp;nbsp;number.getText().toString();&lt;br /&gt;&lt;span style="color: #000099;"&gt;String&amp;nbsp;URL&amp;nbsp;&lt;/span&gt;=&amp;nbsp;"http://maps.google.com/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=";&lt;br /&gt;&lt;span style="color: #000099;"&gt;URL&amp;nbsp;+&lt;/span&gt;=&amp;nbsp;latitude.getText()&amp;nbsp;+&amp;nbsp;","&amp;nbsp;+&amp;nbsp;longitude.getText();&amp;nbsp;&lt;br /&gt;sm.sendTextMessage(phoneNumber,&amp;nbsp;null,&amp;nbsp;URL,&amp;nbsp;null,&amp;nbsp;null);&lt;br /&gt;&lt;/pre&gt;That's it! Just one note -  in order to send SMS message and request GPS location application require following two permissions:  &lt;br /&gt;&lt;pre style="-moz-background-clip: border; -moz-background-inline-policy: continuous; -moz-background-origin: padding; background: rgb(239, 239, 239) none repeat scroll 0% 0%; border: thin solid rgb(166, 176, 191); color: black; padding: 10px; width: 100%;"&gt;&lt;span style="color: black;"&gt;&amp;lt;uses-permission android:name=&lt;/span&gt;&lt;span style="color: #2a00ff;"&gt;"android.permission.ACCESS_FINE_LOCATION" &lt;/span&gt;&lt;span style="color: black;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: white;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: black;"&gt;&amp;lt;uses-permission android:name=&lt;/span&gt;&lt;span style="color: #2a00ff;"&gt;"android.permission.SEND_SMS"&lt;/span&gt;&lt;span style="color: black;"&gt;/&amp;gt; &lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Thanks to my friend Aaron Olson from &lt;a href="http://www.macadamian.com/"&gt;Macadamian&lt;/a&gt; for the help in testing this code.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ucesco.googlepages.com/GPSLocation.zip"&gt;Source&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-330840305863602493?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/E9iAIwAU9_o" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/330840305863602493/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=330840305863602493" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/330840305863602493" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/330840305863602493" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2009/07/here-i-am.html" title="Here I am!" /><author><name>Sargsyan Tigran</name><uri>http://www.blogger.com/profile/17269775074544232074</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="06043168613356651551" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-6956278635283207679</id><published>2009-06-04T10:14:00.002-04:00</published><updated>2009-06-04T10:42:33.880-04:00</updated><title type="text">Using Mate to Dispatch Events with a Callback in ActionScript</title><content type="html">&lt;a href="http://mate.asfusion.com/"&gt;Mate&lt;/a&gt; is a powerful event framework for Adobe Flex which provides advanced functionality for dispatching, listening for and handling events. The framework is tag-based, so the typical use case is to add tags provided by Mate to your MXML. This works very well in most situations, and Mate's documentation is generally very thorough and great for resolving any questions or issues that come up - until you have to do things without MXML.&lt;br /&gt;&lt;br /&gt;I ran into a situation not too long ago where I had to dispatch an event with a callback from a service-like class. Since this wasn't a UI component, there was no corresponding MXML. I needed a pure-ActionScript solution, but still wanted to use Mate. In a matter of minutes, I had no problem dispatching my event*:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class TestClass&lt;br /&gt;{&lt;br /&gt;    public function generateEvent():void&lt;br /&gt;    {&lt;br /&gt;        var event:TestEvent= new TestEvent();&lt;br /&gt;        event.type = TestEvent.TYPE;&lt;br /&gt;        &lt;br /&gt;        var dispatcher:Dispatcher = new Dispatcher();&lt;br /&gt;        dispatcher.generator = TestEvent;&lt;br /&gt;        dispatcher.dispatchEvent( event );&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This was a good start, but I wanted to specify a method within the same service-like class to be called if the event returned successfully. Mate's dispatcher tag makes this very easy, but without any MXML, it was not an option. All the handler for the event does is generate a result or fault using Mate's ServiceResponseAnnouncer, so I needed a way to specify the callback from my dispatcher: just like the MXML tag allows, but using only ActionScript.&lt;br /&gt;&lt;br /&gt;Looking through the docs didn't get me very far. The section on the &lt;a href="http://mate.asfusion.com/page/documentation/tags/dispatcher"&gt;Dispatcher&lt;/a&gt; provides information on using a dispatcher in ActionScript, but without a callback, and there is a section on using callbacks, but specific to the MXML implementation. I checked the ResponseHandler classes as well, and poked around a bit on Google without much luck.&lt;br /&gt;&lt;br /&gt;Knowing that these properties exist, I attempted to piece it together myself (and eventually succeeded). In case anyone else ever runs into the same issue, and because I'd rather not go through all that searching/trial-and-error again, here is a working solution:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class TestClass&lt;br /&gt;{&lt;br /&gt;    public function generateEvent():void&lt;br /&gt;    {&lt;br /&gt;        var event:TestEvent= new TestEvent();&lt;br /&gt;        event.type = TestEvent.TYPE;&lt;br /&gt;        &lt;br /&gt;        var handler:ResponseHandler = new ResponseHandler();&lt;br /&gt;        handler.type = ResponseEvent.RESULT;&lt;br /&gt;        handler.method = myCallback;&lt;br /&gt;        &lt;br /&gt;        var dispatcher:Dispatcher = new Dispatcher();&lt;br /&gt;        dispatcher.generator = TestEvent;&lt;br /&gt;        dispatcher.responseHandlers = [handler];&lt;br /&gt;        dispatcher.dispatchEvent( event );&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    private function myCallback(event:ResponseEvent):void&lt;br /&gt;    {&lt;br /&gt;        trace( "callback reached!" );&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;One of the hardest parts to figure out was what method signature was required for the callback function. I found my answer in a comment in the ResponseHandler class - one more reason why open source frameworks and well commented code are the way to go!&lt;br /&gt;&lt;br /&gt;&lt;small&gt;*Aside: if a callback is not necessary, there's no need to use Mate. In fact, Mate's &lt;a href="http://mate.asfusion.com/page/documentation/best-practices"&gt;best practices&lt;/a&gt; specifically encourage using Flex's built-in dispatchEvent() method. Had I not needed a callback here, I could have called dispatchEvent() on the parent application (or any other DisplayObject within the scope of my service class).&lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-6956278635283207679?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/ajdOzJBHeNc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/6956278635283207679/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=6956278635283207679" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/6956278635283207679" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/6956278635283207679" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2009/06/using-mate-to-dispatch-events-with.html" title="Using Mate to Dispatch Events with a Callback in ActionScript" /><author><name>Dan M</name><uri>http://www.blogger.com/profile/07261008052647160453</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03229345788419499251" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-7602282096744388604</id><published>2009-05-11T22:36:00.001-04:00</published><updated>2009-05-11T22:49:26.225-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="XBAP" /><category scheme="http://www.blogger.com/atom/ns#" term="WPF" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="popup" /><category scheme="http://www.blogger.com/atom/ns#" term="c#" /><category scheme="http://www.blogger.com/atom/ns#" term="code sample" /><title type="text">XBAP - Using the Popup Control as a Dialog Box</title><content type="html">&lt;p&gt;How many people have experienced the modal pop up in desktop applications? They are commonly used across a wide variety of applications, one could say, too commonly used. While not appropriate for all situations, sometimes you need to use a pop up.  &lt;p&gt;In XBAP applications the ability to open a pop-up is very limited; in many cases you will use navigation and multiple pages instead of separate windows. In most cases this is sufficient, but sometimes you really need to use a pop-up, and when you do a simple work around is to use the Popup control offered by WPF.  &lt;p align="justify"&gt;First, you define the Popup in the markup, making sure to set its StaysOpen property to true so it will remain open until you close it. (There’s no point in using the PopupAnimation or AllowsTransparency properties, because they won’t have any effect in a web page.) Include suitable buttons, such as OK and Cancel, and set the Placement property to Center so the popup will appear in the middle of the browser window.&lt;/p&gt; &lt;p&gt;Code sample:&lt;/p&gt; &lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt; &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Popup&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="dialogPopUp"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StaysOpen&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="True"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Placement&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Center"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;MaxWidth&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="200"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Border&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Border.Background&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;LinearGradientBrush&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;                &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="AliceBlue"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="1"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;GradientStop&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;                &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="LightBlue"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;GradientStop&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;LinearGradientBrush&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Border.Background&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;StackPanel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="5"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Background&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="White"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBlock&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;TextWrapping&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Wrap"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Please enter your name.&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBlock&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBox&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="txtName"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="10"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBox&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;StackPanel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Orientation&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Horizontal"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="10"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;                &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Click&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="dialog_boxOK_Click"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Padding&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="3"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0,0,5,0"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;OK&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;                &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Click&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="dialog_boxCancel_Click"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Padding&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="3"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Cancel&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;StackPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;StackPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Border&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Popup&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;At the appropriate time (for example, when a button is clicked), disable the rest of your user interface and show the Popup. To disable your user interface, you can set the IsEnabled property of some top-level container, such as a StackPanel or a Grid, to false. (You can also set the Background property of the page to gray, which will draw the user’s attention to Popup.) To show the Popup, simply set its IsVisible property to true. &lt;br&gt;&lt;br&gt;Here’s an event handler that shows the previously defined Popup:&lt;br /&gt;&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;&lt;br /&gt;&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; popupTriggerButton_Click(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, RoutedEventArgs e)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    DisableMainPage();&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;nbsp;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; DisableMainPage()&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    mainPage.IsEnabled = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Background = Brushes.LightGray;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    dialogPopUp.IsOpen = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;When the user clicks the OK or Cancel button, close the Popup by setting its IsVisible property to false, and re-enable the rest of the user interface:&lt;br /&gt;&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;&lt;br /&gt;&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; dialog_boxOK_Click(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, RoutedEventArgs e)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// Copy name from the Popup into the main page.&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    lblName.Content = &lt;span style="color: #006080"&gt;"You entered: "&lt;/span&gt; + txtName.Text;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    EnableMainPage();&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;} &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;nbsp;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; dialog_boxCancel_Click(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, RoutedEventArgs e)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    EnableMainPage();&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;nbsp;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; EnableMainPage()&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    mainPage.IsEnabled = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Background = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    dialogPopUp.IsOpen = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;Using the Popup control to create this workaround has one significant limitation. To ensure that the Popup control can’t be used to spoof legitimate system dialog boxes, the Popup window is constrained to the size of the browser window. If you have a large Popup window and a small browser window, this could chop off some of your content. One solution is to wrap the full content of the Popup control in a ScrollViewer with the VerticalScrollBarVisibility property set to Auto.&lt;br&gt;&lt;br&gt;If a Popup isn’t suitable for you, you can try another more “interesting” approach for showing a dialog box. Using the Windows Form library from .NET 2.0 you can safely create and host any WinForm control in your WPF application. In this case, you can create and show an instance of the System.Windows.Forms.Form class (or any custom form that derives from Form), because it doesn’t require unmanaged code permission. In fact, you can even show the form modelessly, so the page remains responsive. The only drawback is that a security balloon automatically appears superimposed over the form and remains until the user clicks the warning message. You’re also limited in what you can show in the form. Windows Forms controls are acceptable, but WPF content isn’t allowed.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-7602282096744388604?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/ZE_lf5WQS2M" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/7602282096744388604/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=7602282096744388604" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/7602282096744388604" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/7602282096744388604" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2009/05/xbap-using-popup-control-as-dialog-box.html" title="XBAP - Using the Popup Control as a Dialog Box" /><author><name>Romeo Dumitrescu</name><uri>http://www.blogger.com/profile/12048678127751485032</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17144581606452115795" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-943195283157539482</id><published>2009-04-27T16:26:00.000-04:00</published><updated>2009-04-27T16:26:50.627-04:00</updated><title type="text">FlexDock</title><content type="html">FlexDock is a custom component which allows to have a number of "expandable boxes" placed in horizontal direction. It is not possible to have more than one box expanded at the same. Click on the box expanding the clicked box and shrinking previously expanded box. Shift + Click shrinking the expanded box.&lt;br /&gt;&lt;br /&gt;The component which is actually our "box" is called CanvasBox. For expanding the boxes I prefer to use &lt;a href="http://code.google.com/p/tweener/"&gt;Caurina Tweener&lt;/a&gt;, it is also possible to use built-in mx.effects.Resize, but I prefer Caurina Tweener's one:&lt;br /&gt;&lt;br /&gt;&lt;pre style="color: #ffffff;background: #444444;overflow: scroll;width: 100%;height: 70px;border: 1px solid #A6B0BF;font-size: 100%;text-align: left;margin: 0;padding: 0;"&gt;private var _rollOverTween:Object = {width:200, height:200, time:0.45, transition:"easeOutBack", onComplete:onRollOver};&lt;br /&gt;private var _rollOutTween:Object = {width:90, height:90, time:0.2, transition:"linear", onComplete:onRollOut};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;When the user clicks on the button the Tweener.addTween( this, _rollOverTween); method is called, it is possible to change the content of the box in the click handler, but if you want your UI not to be broken it is better to do those changes in the onComplete handler of the tween.&lt;br /&gt;&lt;br /&gt;Besides the CanvasBox component we also need to have a component which will hold the boxes. It is called BoxHolder and it is template component. It has _content field which is storing the boxes, pay attention at [ArrayElementType("CanvasBox")]:&lt;br /&gt;&lt;br /&gt;&lt;pre style="color: #ffffff;background: #444444;overflow: scroll;width: 100%;height: 110px;border: 1px solid #A6B0BF;font-size: 100%;text-align: left;margin: 0;padding: 0;"&gt;// An array which stores the UI components&lt;br /&gt;// of our content&lt;br /&gt;[ArrayElementType("CanvasBox")]&lt;br /&gt;private var _content:Array;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Every time you click on a box, the closeOthers method is called which is shrinking previously expanded box.&lt;br /&gt;&lt;br /&gt;&lt;pre style="color: #ffffff;background: #444444;overflow: scroll;width: 100%;height: 220px;border: 1px solid #A6B0BF;font-size: 100%;text-align: left;margin: 0;padding: 0;"&gt;private function closeOthers(event:MouseEvent):void&lt;br /&gt;{&lt;br /&gt;   for each(var component:CanvasBox in _content)&lt;br /&gt;   {&lt;br /&gt;      if(component != event.currentTarget)&lt;br /&gt;      {&lt;br /&gt;         component.roolOut();&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://ucesco.googlepages.com/mockup5.html"&gt;DEMO&lt;/a&gt; | &lt;a href="http://ucesco.googlepages.com/ExpandableBoxes.zip"&gt;SOURCE&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-943195283157539482?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/sXRGZuShsN4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/943195283157539482/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=943195283157539482" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/943195283157539482" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/943195283157539482" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2009/04/flexdock.html" title="FlexDock" /><author><name>Sargsyan Tigran</name><uri>http://www.blogger.com/profile/17269775074544232074</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="06043168613356651551" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-7977650832252050331</id><published>2009-03-31T15:16:00.003-04:00</published><updated>2009-04-20T09:43:21.566-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="specification" /><title type="text">HTML4 and XHTML</title><content type="html">&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; "&gt;&lt;div style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; width: auto; font: normal normal normal 100%/normal Georgia, serif; text-align: left; "&gt;&lt;div&gt;This one hurts, Jason suggested to me to post this, and since Macadamian is an "egoless" programming shop - that I do adhere to - I do it even though I might be laughed at!&lt;br /&gt;&lt;br /&gt;More seriously, when dealing with HTML, remember that each version of the specification has specific characteristics. And the application you are using (in my case Atlassian's Confluence), is validating against some version of the specification. Somehow I known this for years, having spent countless hours in the SOAP and WSDL specifications back in my Cognos days. Yet somehow I forgot, its easy to overlook these sorts of things sometimes.&lt;br /&gt;&lt;br /&gt;Now the problem I encountered was around the closing tags. In XHTML you can do things like this but not in HTML4:&lt;br /&gt;&lt;span class="Apple-style-span" style="font-weight: bold; "&gt;&lt;br /&gt;&lt;/span&gt;&amp;lt;iframe src=.../&amp;gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;instead, in HTML4 you have to explicitely use the closing tag as shown below:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;lt;iframe src=...&amp;gt; &amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;The consequence of this mistake was that all the code following the first form was not rendered by the Browser (I tested this in Firefox and Chrome). I could see the content driven by the iframe though.&lt;br /&gt;&lt;br /&gt;So the morale of the story, read the manual and remember the specification! :)&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-7977650832252050331?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/SIH90XoPOQY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/7977650832252050331/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=7977650832252050331" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/7977650832252050331" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/7977650832252050331" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2009/03/html4-and-xhtml.html" title="HTML4 and XHTML" /><author><name>Sylvain St-Germain</name><uri>http://www.blogger.com/profile/17462626811937327974</uri><email>sylvain@macadamian.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="01328014249653960231" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-2758540179152804115</id><published>2009-03-09T11:49:00.001-04:00</published><updated>2009-03-09T11:51:44.853-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="WPF" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Win32" /><category scheme="http://www.blogger.com/atom/ns#" term="embedded" /><category scheme="http://www.blogger.com/atom/ns#" term="Visual Basic" /><category scheme="http://www.blogger.com/atom/ns#" term="c#" /><title type="text">Single Instance Applications in WPF</title><content type="html">&lt;p align="justify"&gt;In some design scenarios launching multiple copies of the same WPF application is a problem, especially for document-based applications or server applications. &lt;/p&gt; &lt;p align="justify"&gt;WPF does not provide a native solution for single instance applications; however there are several workarounds for this issue. &lt;/p&gt; &lt;p align="justify"&gt;The most commonly used solution is to check whether another instance of the application is already running when the Application.Startup event fires. This is easily done using a system wide mutex (provided by the operating system to allow interprocess communication). While this is easily done, it limits the developer’s options by not providing a way for the new instance to communicate with the already running instance. Mainly this will provide only a simple way of limiting the number of running instances to one, while a separate system will be required to handle the new calls (usually through remoting or Windows Communication Foundation). &lt;/p&gt; &lt;p align="justify"&gt;The recommended and more useful approach is to use the built-in support that’s provided in Windows Forms and originally intended for Visual Basic applications. This approach handles the messy plumbing behind the scenes. This means using an old style application class as wrapper for the WPF application. The wrapper will handle the instance management and will communicate the request to the already running instance of the WPF application. &lt;/p&gt; &lt;p align="justify"&gt;&lt;strong&gt;Solution steps&lt;/strong&gt;: &lt;/p&gt; &lt;p align="left"&gt;1) Add a reference to the &lt;strong&gt;Microsoft.VisualBasic.dll&lt;/strong&gt; assembly. &lt;/p&gt; &lt;p align="left"&gt;2) Add a new custom class derived from the &lt;strong&gt;Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase&lt;/strong&gt; class. &lt;/p&gt; &lt;p align="left"&gt;3) The &lt;strong&gt;IsSingleInstance&lt;/strong&gt; must be set to true in the constructor. This enables a single instance application. &lt;/p&gt; &lt;p align="left"&gt;4) Override the &lt;strong&gt;OnStartup()&lt;/strong&gt; method to create the WPF application object. (Note: The &lt;strong&gt;OnStartup()&lt;/strong&gt; method is triggered when the application starts) &lt;/p&gt; &lt;p align="left"&gt;5) Overide the &lt;strong&gt;OnStartupNextInstance()&lt;/strong&gt; method to handle future instances. (Note: The &lt;strong&gt;OnStartupNextInstance()&lt;/strong&gt; method is triggered in when another instance of the application starts up) &lt;/p&gt; &lt;p align="left"&gt;6) Define a Main entry point for the application and create the wrapper object&lt;/p&gt; &lt;p align="left"&gt;7) Create the WPF application class &lt;/p&gt; &lt;p align="justify"&gt;&lt;strong&gt;Sample of the application wrapper&lt;/strong&gt;:&amp;nbsp; &lt;/p&gt; &lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;&lt;/style&gt;  &lt;div align="justify"&gt; &lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt; &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Linq;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Text;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; Microsoft.VisualBasic.ApplicationServices;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Windows;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; SingleInstanceApplication&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;{&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    &lt;span style="color: #008000"&gt;//The Main entry point class&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Startup&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        [STAThread]&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[] args)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            SingleInstanceAppWrapper wrapper = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SingleInstanceAppWrapper();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            wrapper.Run(args);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    &lt;span style="color: #008000"&gt;//The old-style application wrapper&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; SingleInstanceAppWrapper : WindowsFormsApplicationBase&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; SingleInstanceAppWrapper()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            &lt;span style="color: #008000"&gt;// Enable single-instance mode.&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.IsSingleInstance = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;// Create the WPF application class.&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; WPFApplication _app;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;//Override OnStartup() method to create the WPF application object&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; OnStartup(&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;             Microsoft.VisualBasic.ApplicationServices.StartupEventArgs e)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            _app = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; WPFApplication();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            _app.Run();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;// Override OnStartupNextInstance() to handle multiple application instances.&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnStartupNextInstance(&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;             Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs e)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;span style="color: #008000"&gt;//In case of command line arguments, send them to the WPF application object    &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (e.CommandLine.Count &amp;gt; 0)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                _app.HandleCommandLine(e.CommandLine);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;As you can see, the sample above contains the Main entry point for the application. This is required because the wrapper must be created first. &lt;br&gt;If Visual Studio is used, by default the App.xaml application definition style is used. This will not work with the wrapper because the App.xaml approach already has a Main entry point. &lt;br&gt;Remove App.xaml and App.xaml.cs from the project and create a new class for the entry point.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;The only thing left to do is to create the WPF application definition:&lt;/p&gt;&lt;br /&gt;&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;br /&gt;&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; WPFApplication : System.Windows.Application&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;{&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    &lt;span style="color: #008000"&gt;//Override the OnStartup() method&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnStartup(System.Windows.StartupEventArgs e)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.OnStartup(e);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;//Load the main window&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        Window _MainWindow = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Window();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        _MainWindow.Show();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;//Set the MainWindow property for the WPF application object&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.MainWindow = _MainWindow;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    &lt;span style="color: #008000"&gt;//Method used to handle command line arguments&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; HandleCommandLine (System.Collections.ObjectModel.ReadOnlyCollection&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt; e)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;//Code to handle command line arguments from other instances goes here&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;    }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;Because the wrapper approach does not contain a XAML application definition (App.xaml), if you need to load application level resources, the following code can be placed the OnStartup() of the WPF application definition to load the resources from a resource dictionary:&lt;/p&gt;&lt;br /&gt;&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;br /&gt;&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        Application.Current.Resources.MergedDictionaries.Add(&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            Application.LoadComponent(&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Uri(&lt;span style="color: #006080"&gt;"AssemblyName;component/ApplicationResourceDictionary.xaml"&lt;/span&gt;,&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                UriKind.Relative)) &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; ResourceDictionary);&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;The above code will work for dynamic resource definitions. The static resource lookup process will fail because the source for the application resources dictionary need to be specified. In that case the code to load the resources will be replaced with the following:&lt;/p&gt;&lt;br /&gt;&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;br /&gt;&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;Application.Current.Resources.Source = &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Uri(&lt;span style="color: #006080"&gt;"/AssemblyName;component/ApplicationResourceDictionary.xaml"&lt;/span&gt;, UriKind.Relative);&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align="justify"&gt;Note: AssemblyName is a placeholder for the actual assembly name. The Uri for the resource dictionary location can be changed as required.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-2758540179152804115?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/E-L0nuVbotU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/2758540179152804115/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=2758540179152804115" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/2758540179152804115" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/2758540179152804115" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2009/03/single-instance-applications-in-wpf.html" title="Single Instance Applications in WPF" /><author><name>Romeo Dumitrescu</name><uri>http://www.blogger.com/profile/12048678127751485032</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17144581606452115795" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-7803744594165699629</id><published>2008-11-12T11:25:00.006-05:00</published><updated>2008-11-12T11:40:11.875-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="rest" /><category scheme="http://www.blogger.com/atom/ns#" term="twitter" /><title type="text">The Anti-social web - Twitter for the socially inept</title><content type="html">Twitter was mentioned during Macadamian's corporate blogging presentation. "Useless! Bah! Humbug!" were the first thoughts to enter my head. Then the speaker pointed out that corporate bloggers should strive to see the positive side of any situation, and I figured making Twitter useful to a neo-Luddite was a good challenge; there must be an itch to scratch here, right?&lt;br /&gt;&lt;br /&gt;All I knew about Twitter was that people think it's slow, and it's written in Ruby (on Rails.) After exploring a little more, I found out that it can provide private Atom feeds of your messages, and exposes a REST API (ooh, new, shiny!) That was enough to get me coding.&lt;br /&gt;&lt;br /&gt;To keep things simple I decided to be boring and test out Twitter using Ruby (normally, I plan epic posts with 5 different languages, communicating through at least 2 protocols... and a database for no good reason.) The process I followed was:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Install Ruby (one-click installer)&lt;/li&gt;&lt;li&gt;In the Gems package manager: gem install &lt;a href="http://rest-client.heroku.com/rdoc/"&gt;rest-client&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Install the &lt;a href="http://rubyeclipse.sourceforge.net/"&gt;Ruby Development Tools&lt;/a&gt; for Eclipse&lt;/li&gt;&lt;li&gt;Read the &lt;a href="http://apiwiki.twitter.com/REST+API+Documentation#DirectMessageMethods"&gt;Twitter API&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;require 'date'&lt;br /&gt;require 'rest_client'&lt;br /&gt;require 'rexml/document'&lt;br /&gt;&lt;br /&gt;username = "your_twitter_id_here"&lt;br /&gt;password = "your_twitter_password_here"&lt;br /&gt;&lt;br /&gt;twitter = RestClient::Resource.new 'http://%s:%s@twitter.com' % [ username, password ]&lt;br /&gt;&lt;br /&gt;# Send a message to twitter&lt;br /&gt;result = twitter['statuses/update.xml'].post(&lt;br /&gt;   :status =&gt; "This is your computer.  You have no life as of %s" % DateTime.now()&lt;br /&gt;)&lt;br /&gt;# print result&lt;br /&gt;&lt;br /&gt;timelineXML = twitter['statuses/user_timeline.xml'].get({ :count =&gt; 5 });&lt;br /&gt;&lt;br /&gt;# Make the XML usable&lt;br /&gt;# (Use XmlSimple for even easier handling)&lt;br /&gt;timeline = REXML::Document.new(timelineXML)&lt;br /&gt;&lt;br /&gt;# Display the text element of every status returned by the service&lt;br /&gt;# (print timelineXML to learn more about the structure of the result.)&lt;br /&gt;puts "%s's timeline:" % username&lt;br /&gt;timeline.elements.each('statuses/status/text') { |message|&lt;br /&gt;   puts message.text&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As Twitter &lt;a href="http://apiwiki.twitter.com/REST+API+Documentation#RateLimiting"&gt;restricts you to 70 calls per hour&lt;/a&gt;, it's a good job Ruby (on REST) made this so easy.  REST is a nice change from the usual URL gobbledygook that frameworks throw up - I can't wait to try it out in &lt;a href="http://struts.apache.org/2.x/docs/rest-plugin.html"&gt;Struts2&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So, what can people with no interest in socializing do with Twitter?&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Free yourself from your desk by monitoring that 45 minute long J2EE build from &lt;a href="http://twitterforiphone.com/"&gt;your iPhone&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Monitor your computers by receiving disk capacity warnings, CPU performance reports, and IP address changes&lt;/li&gt;&lt;li&gt;Find out when &lt;a href="http://tech.shantanugoel.com/2008/05/14/keep-tab-on-home-security-with-a-webcam-and-twitter.html"&gt;someone is breaking into your home&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Know when &lt;a href="http://www.engadget.com/2008/02/25/diy-kit-lets-houseplants-twitter-when-they-need-water/"&gt;your plants need to be watered&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Search for signs of life in the &lt;a href="http://www.p2pnet.net/story/16101"&gt;Mars lander&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;One final note, until &lt;a href="http://apiwiki.twitter.com/REST+API+Documentation#Authentication"&gt;the authentication framework is more robust&lt;/a&gt;, don’t rely on anything you twit staying private.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-7803744594165699629?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/AUMZTSGyV9E" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/7803744594165699629/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=7803744594165699629" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/7803744594165699629" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/7803744594165699629" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2008/11/anti-social-web-twitter-for-socially.html" title="The Anti-social web - Twitter for the socially inept" /><author><name>Gord. P</name><uri>http://www.blogger.com/profile/10684846302006538110</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="05573681110765124582" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-5878686279857402690</id><published>2008-10-29T00:41:00.005-04:00</published><updated>2008-10-29T10:02:44.011-04:00</updated><title type="text">Breadth-First Coding</title><content type="html">&lt;span style="font-size:130%;"&gt;&lt;span style="font-style: italic;"&gt;"Look Ma! I'm inventing my own buzzwords!"&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt;The problem&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A little while ago, some of us at &lt;a href="http://www.macadamian.com/"&gt;Macadamian&lt;/a&gt; held discussions on behaviors we would like to encourage among younger developers. One thing we agreed was that "stubbing" (coming up with methods containing as little code as possible, in order to stabilize the API interactions faster) was becoming a "lost art". And so we resolved to start encouraging "top-down development", as we were used to call it.&lt;br /&gt;&lt;br /&gt;So far, we've met with little success. Despite our explicit encouragements, it seems hard for people to adopt a "top-down" approach.&lt;br /&gt;&lt;br /&gt;And lately, I've been wondering: what if we're not communicating right? After all, "top-down" is a pretty generic term. After all, it's even used to describe &lt;a href="http://en.wikipedia.org/wiki/Top_down"&gt;an entire programming methodology&lt;/a&gt; which predates Object-Oriented Design. So perhaps some of the people in our teams are thinking: "&lt;span style="font-style: italic;"&gt;Of cours&lt;/span&gt;e I'm going from top to bottom, what are they complaining about!?"&lt;br /&gt;&lt;br /&gt;That's when I thought of something...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt;Mandatory flashback to the author's younger days&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Back at school, I followed this neat AI course which taught me some general problem-solving heuristics. Overall, it showed two ways to attack a problem by brute force: &lt;span style="font-style: italic;"&gt;breadth-first&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;depth-first&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Let's say we're looking for a file within a directory structure. A &lt;span style="font-style: italic;"&gt;depth-first&lt;/span&gt; approach will recursively explore each solution by first going to the lowest node possible. Only then will it work its way back up, before going down again.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://thefiles.macadamian.com/uploaded_images/DF-Tree-741487.png"&gt;&lt;img style="cursor: pointer; width: 320px; height: 200px;" src="http://thefiles.macadamian.com/uploaded_images/DF-Tree-741467.png" alt="Depth-First Search" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A &lt;span style="font-style: italic;"&gt;breadth-first&lt;/span&gt; approach, on the other hand, would attempt to fully explore one level of nodes before jumping to the next one.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://thefiles.macadamian.com/uploaded_images/BF-Tree-756275.png"&gt;&lt;img style="cursor: pointer; width: 320px; height: 210px;" src="http://thefiles.macadamian.com/uploaded_images/BF-Tree-756269.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For additional details, you check out &lt;a href="http://en.wikipedia.org/wiki/Breadth-first_search"&gt;breadth-first search&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Depth-first"&gt;depth-first search&lt;/a&gt; on Wikipedia (where I borrowed these graphs from).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt;And so...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I'm beginning to think that younger developers show a natural tendency to code &lt;span style="font-style:italic;"&gt;depth-first&lt;/span&gt;. They pick a single feature/functionality/API call, then implement it down to the lowest level, at which point they consider to have a "valid iteration". Then they go back up a few levels, and start again. Doing things that way can make you feel good because you've added a lot of code, but it makes things harder to test, and might complicate future integration.&lt;br /&gt;&lt;br /&gt;We'd like people to try out &lt;span style="font-style:italic;"&gt;breadth-first coding&lt;/span&gt;, which would mean getting a wider range of partly-implemented methods in the early stages.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://upload.wikimedia.org/wikipedia/commons/4/46/Animated_BFS.gif"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 187px; height: 175px;" src="http://upload.wikimedia.org/wikipedia/commons/4/46/Animated_BFS.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;First, you'd define the APIs of the first layer, providing a "bare-bone" implementation of each method. Then you'd define the second layer, once again with a minimal implementation, at which point you'd be able to properly implement the first layer. Repeat for each layer of implementation.&lt;br /&gt;&lt;br /&gt;So, as my first step, I'll start using the term "breadth-first" when talking about this approach. I'm hoping that by using this term instead of "top-down", I'll get a few "Huh? WTF?" responses, which may be just what we need in order to break some old habits...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-5878686279857402690?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/UPqt2XQRjgM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/5878686279857402690/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=5878686279857402690" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/5878686279857402690" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/5878686279857402690" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2008/10/breadth-first-coding.html" title="Breadth-First Coding" /><author><name>Gilles Duchesne</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-8080723372392435717</id><published>2008-09-12T09:28:00.004-04:00</published><updated>2008-09-12T09:59:03.465-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="web development" /><category scheme="http://www.blogger.com/atom/ns#" term="Win32" /><category scheme="http://www.blogger.com/atom/ns#" term="SharePoint" /><category scheme="http://www.blogger.com/atom/ns#" term="code quality" /><category scheme="http://www.blogger.com/atom/ns#" term="c#" /><category scheme="http://www.blogger.com/atom/ns#" term="string conversion" /><title type="text">Bridge SharePoint - User Profiles and User Profile Properties (part 2 of 2)</title><content type="html">&lt;p&gt;As we have found out in part 1, SharePoint can manipulate data using the user profile management objects and can accept data from external sources. Using these two features apart we have two limited tools with limited usage, but using them together gives us a powerful, flexible and efficient method of storing and using data from any internal or external resource.&lt;br /&gt;&lt;br /&gt;It’s time to see this solution to our problems in action. &lt;/p&gt; &lt;p&gt;&lt;b&gt;Code example of getting/setting the profile property from a C# application&lt;/b&gt; &lt;/p&gt; &lt;p&gt;The concept is the same for any source of information (web services, web applications, etc.):&lt;br /&gt;Get the user’s profile-&amp;gt;Get the required profile property-&amp;gt;Get/Set profile property value &lt;/p&gt; &lt;p&gt;&lt;b&gt;Code example&lt;/b&gt;: (note that to access profile properties, this code must run with elevated privileges)&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;string &lt;/span&gt;value;&lt;br /&gt;&lt;span style="color:blue;"&gt;try&lt;br /&gt;&lt;/span&gt;{&lt;br /&gt; SPSecurity.RunWithElevatedPrivileges(&lt;span style="color:blue;"&gt;delegate&lt;/span&gt;()&lt;br /&gt; {&lt;br /&gt;  &lt;br /&gt;     &lt;span style="color:green;"&gt;// Change the site address for different deployment environments&lt;br /&gt;     // Note: WIN2003STD is a place holder for your environment, usually your server name&lt;br /&gt;     &lt;/span&gt;SPSite site = &lt;span style="color:blue;"&gt;new &lt;/span&gt;SPSite(&lt;span style="color: rgb(163, 21, 21);"&gt;"http://WIN2003STD/"&lt;/span&gt;);&lt;br /&gt;     SPWeb web = site.OpenWeb();&lt;br /&gt;&lt;br /&gt;     &lt;span style="color:green;"&gt;// Get the profile manager object for the site&lt;br /&gt;     &lt;/span&gt;UserProfileManager profileManager = &lt;span style="color:blue;"&gt;new &lt;/span&gt;UserProfileManager(ServerContext.GetContext(site));&lt;br /&gt;&lt;br /&gt;     &lt;span style="color:green;"&gt;// Use the username from the User Information Item to get the full profile of an user&lt;br /&gt;     &lt;/span&gt;UserProfile user_profile = profileManager.GetUserProfile(System.Web.HttpContext.Current.User.Identity.Name);&lt;br /&gt;&lt;br /&gt;     &lt;span style="color:green;"&gt;// Get the required profile property value from the profile&lt;br /&gt;     &lt;/span&gt;value = user_profile[&lt;span style="color: rgb(163, 21, 21);"&gt;"MyProperty"&lt;/span&gt;].Value.ToString();&lt;br /&gt;&lt;br /&gt;  &lt;br /&gt; });&lt;br /&gt;}&lt;br /&gt;&lt;span style="color:blue;"&gt;catch &lt;/span&gt;(Exception e)&lt;br /&gt;{&lt;br /&gt; &lt;span style="color:blue;"&gt;return &lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"Error getting user info: " &lt;/span&gt;+ e.Message.ToString();&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;user_profile["MyProperty"].Value gets or sets the profile property value.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;This is a very convenient way of using profile properties to store required information for each user. Properties can be set as read-only or not to appear in the user’s profile, which gives you even more control. &lt;/p&gt;System.Web.HttpContext.Current.User.Identity.Name returns the username (the login username) and it is used in the code example above to get the profile of the currently logged-in user.&lt;br /&gt;&lt;p&gt;&lt;b&gt;Tools You Never Knew You Had… (and what to do with them now that you’ve wised up!)&lt;/b&gt; &lt;/p&gt;With this simple solution to getting/setting a user’s profile property value, endless opportunities are now at hand. This small code snippet helps developers control, validate and use values stored for each user, without corrupting the database or resorting to other more complex and error-prone solutions.&lt;br /&gt;For those not needing to use an external application to get information from the users, a custom SharePoint web application can be developed and deployed on SharePoint. This way all the controls offered by ASP .NET or custom controls can be used to perform required operations on the data before it’s stored.&lt;br /&gt;&lt;p&gt;External applications running on the server can access this information the same way, so a bridge between SharePoint and applications like web sites, game servers, messaging apps, etc. can be easily created.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;SharePoint Complications, As Usual&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Watch out that the profile property might be set as read-only in SharePoint. Even if it’s the case however, the above code should still be able to access the profile because it’s running with elevated privileges. So if there is a situation in which the user is allowed to see the data but only modify it by using a service (like a web application or web service), this is a good way of doing it. &lt;/p&gt;Another gotcha is that the code above can only be used on the SharePoint server machine. This is due to the framework that SharePoint uses. To get information or to change data from a network on internet location, a SharePoint custom web service or web application can come in handy. Other ways of passing information will work too, like server-client applications, as long as the part running the above code is on the SharePoint server machine.&lt;br /&gt;&lt;p&gt;So we now have a way to store data and manipulate it according to our needs. We can control it, we can validate it and most important of all, we decide how the user interacts with the data. &lt;/p&gt;We’re now ready to start doing some serious SharePoint development!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-8080723372392435717?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/F14K3bCydCU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/8080723372392435717/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=8080723372392435717" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/8080723372392435717" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/8080723372392435717" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2008/09/bridge-sharepoint-user-profiles-and_12.html" title="Bridge SharePoint - User Profiles and User Profile Properties (part 2 of 2)" /><author><name>Romeo Dumitrescu</name><uri>http://www.blogger.com/profile/12048678127751485032</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17144581606452115795" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-3480540278316123483</id><published>2008-09-10T11:51:00.000-04:00</published><updated>2008-09-10T13:07:05.673-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="web development" /><category scheme="http://www.blogger.com/atom/ns#" term="Authentication" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="SharePoint" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><title type="text">Bridge SharePoint - User Profiles and User Profile Properties (part 1 of 2)</title><content type="html">There is a constant need in SharePoint feature development to bridge SharePoint 2007 with other web applications. In order to create such a bridge, a variety of user information must be stored in the SharePoint database.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Warning: Do not tamper with the SharePoint database! No matter how tempting it is!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;         Although this might sound as simple as a small SQL application, tampering with SharePoint’s database could lead to disastrous results and even complete and irreversible server crashes, since many of SharePoint’s recovery features rely on the database being intact. “Feeding” information to SharePoint through its database is unadvisable and sometimes very hard to do, mainly due to the complex structure of the database.&lt;br /&gt;&lt;br /&gt;         Fortunately there is a built-in solution to this problem that is both simple and efficient: &lt;span style="font-weight: bold;"&gt;User Profiles and User Profile Properties.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;         In this post we will see how SharePoint’s user profiles and profile properties can help us do our job fast and easy without worrying about crashing the server or breaking more features than we create.&lt;br /&gt;&lt;br /&gt;         Let’s start with the storing information problem.&lt;br /&gt;         Many developers have already considered using Profile Properties as way to store the required data, but have given up on using them due to their limitations (limited validation, control, variety). Controlling the user’s input and making sure that the values are correct is essential in any bridge, and often auto-generated values based on that data are necessary. SharePoint can only do so much, and this is usually the main reason why developers avoid using the custom profile properties.&lt;br /&gt;&lt;br /&gt;         &lt;span style="font-weight: bold;"&gt;Solution:  Manage information using the Microsoft.Office.Server.UserProfiles namespaces.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;         SharePoint Server 2007 stores user profiles in SQL Server, but the information can be imported from other data sources, such as:&lt;br /&gt;·    Active Directory&lt;br /&gt;·    Lightweight Directory Access Protocol directories (which is not Active Directory)&lt;br /&gt;·    Databases&lt;br /&gt;·    Enterprise applications (such as SAP or PeopleSoft) by defining a Business Data Catalog connection&lt;br /&gt;·    Web applications&lt;br /&gt;·    Custom SharePoint web services&lt;br /&gt;·    Standard .NET applications, etc.&lt;br /&gt;         The main classes are found in the Microsoft.Office.Server.UserProfiles namespaces. The assembly is Microsoft.Office.Server.dll found in C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI.&lt;br /&gt;         The main objects to handle information within the User Profile store are:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;UserProfile&lt;/span&gt;&lt;br /&gt;Allows you to access profile properties, the My Site, personalization links, and so on.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;UserProfileManager&lt;/span&gt;&lt;br /&gt;Gives access to a collection of UserProfile objects and allows you to create, edit, and retrieve user profile objects and properties from the user profile store.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;UserProfileConfigManager&lt;/span&gt;&lt;br /&gt;Manages the user profile configuration.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Note&lt;/span&gt;: In order to manage data in a custom user profile property, the property must be first created. You can use the following steps to create a profile property:&lt;br /&gt;&lt;br /&gt;1.    Start &gt; Administrative Tools &gt; SharePoint 3.0 Central Administrator&lt;br /&gt;2.    In the left panel, under Shared Services Administration, click SharedServices1&lt;br /&gt;3.    Click User Profiles and Properties&lt;br /&gt;4.    Under User Profile Properties, click Add Profile Property&lt;br /&gt;5.    Fill in the required data and click OK&lt;br /&gt;&lt;br /&gt;Now that we know that SharePoint accepts data from external sources and that it stores individual user values in user profile properties, it’s time to put the two together and find out how to store user data in profile properties from external data sources. This is the topic for part two of this post: Getting/Storing user data from external sources.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-3480540278316123483?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/49b6k5y_50c" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/3480540278316123483/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=3480540278316123483" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/3480540278316123483" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/3480540278316123483" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2008/09/bridge-sharepoint-user-profiles-and.html" title="Bridge SharePoint - User Profiles and User Profile Properties (part 1 of 2)" /><author><name>Romeo Dumitrescu</name><uri>http://www.blogger.com/profile/12048678127751485032</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17144581606452115795" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-2892693250199788712</id><published>2008-09-04T15:50:00.002-04:00</published><updated>2008-09-04T16:12:49.197-04:00</updated><title type="text">SharePoint says "Unknown Error"</title><content type="html">&lt;strong&gt;ERROR: Only Content controls are allowed directly in a content page that contains Content controls.&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;By default, SharePoint doesn't seem willing to share some of its internal errors with developers opting instead to use a generic "Unknown Error" page.  The informative &lt;em&gt;(and I use the term loosely)&lt;/em&gt; error string above wasn't displayed in the browser until the file &lt;u&gt;C:\Inetpub\wwwroot\wss\VirtualDirectories\80\web.config&lt;/u&gt; was modified to disable custom error messages.&lt;br /&gt;&lt;br /&gt;By changing &lt;span style="color:#cc0000;"&gt;&amp;lt;SafeMode CallStack="false" ...&amp;gt;&lt;/span&gt; to &lt;span style="color:#cc0000;"&gt;&amp;lt;SafeMode CallStack="true" ...&amp;gt;&lt;/span&gt; and changing &lt;span style="color:#cc0000;"&gt;&amp;lt;customErrors mode="On" /&amp;gt;&lt;/span&gt; to &lt;span style="color:#cc0000;"&gt;&amp;lt;customErrors mode="Off" /&amp;gt;&lt;/span&gt;, the generic error page is replaced with a more detailed error message and maybe even a callstack.&lt;br /&gt;&lt;br /&gt;As for the error above?  It was caused by a comment that had been added to an .aspx file.  For some reasons, comments were not allowed because they didn't qualify as "content controls".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-2892693250199788712?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/X5XZauZV3NU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/2892693250199788712/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=2892693250199788712" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/2892693250199788712" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/2892693250199788712" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2008/09/sharepoint-says-unknown-error.html" title="SharePoint says &quot;Unknown Error&quot;" /><author><name>Frederic LeBel</name><uri>http://www.blogger.com/profile/01870456065216884794</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="16473002577108763503" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-4171678228936563604</id><published>2008-08-03T19:33:00.000-04:00</published><updated>2008-08-03T19:33:01.375-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="web development" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><title type="text">Performance reality check for web developers</title><content type="html">When I work on a web application, I usually have the luxury of running everything that I need locally on my developer machine. My browser, Web-server and database all working together without ever having to put a single packet on a real network.&lt;br /&gt;&lt;br /&gt;With today's web applications growing more complex and making use of asynchronous calls to the web server, this idealistic development environment makes it very difficult for the developer to assess the performance characteristics of the application. This can lead to surprises when the application is deployed to a real environment where users actually access it from remote locations.&lt;br /&gt;&lt;br /&gt;A good way to bring reality back to this equation is to make use of a proxy server. I like to use &lt;a href="http://donsproxy.sourceforge.net/"&gt;Don's Proxy&lt;/a&gt;. It is simple Java-based application that takes 1 minute to setup and lets you inject latency, errors and throttle your connection bandwidth. All of this is made in a manner that is independent of your browser or your web server. Most importantly. it does not require any changes to your application's code or setup.&lt;br /&gt;&lt;br /&gt;To use Don's Proxy, simply download the package, unzip and double-click the jar file. A simple GUI will open (&lt;a href="http://sourceforge.net/project/screenshots.php?group_id=211367"&gt;screenshot&lt;/a&gt;) that will prompt you for a port for the proxy to listen to and a host/port for the destination of your test web server. In the example screenshot, the test web server is running locally at port 8080 and the proxy is setup to listen on port 9090.&lt;br /&gt;&lt;br /&gt;Once the proxy is started, you just redirect your browser to the proxy's port and everything should work as before. The difference is that now, you can inject realistic network parameters like latency and bandwidth limitations. Don's Proxy also allows you to capture traffic as it goes through and perform other diagnostics without the use of a packet-sniffer.&lt;br /&gt;&lt;br /&gt;Hopefully, a more common use of tools like this will help curb developer enthusiasm for flashy Ajax behavior. Your users will thank you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-4171678228936563604?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/ZmbxKrH9bJQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/4171678228936563604/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=4171678228936563604" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/4171678228936563604" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/4171678228936563604" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2008/08/performance-reality-check-for-web.html" title="Performance reality check for web developers" /><author><name>Francis</name><uri>http://www.blogger.com/profile/11917210826902818268</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11658340314513383559" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-7183137287562820116</id><published>2008-07-30T16:30:00.005-04:00</published><updated>2008-07-31T15:44:11.654-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="c++" /><category scheme="http://www.blogger.com/atom/ns#" term="embedded" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="cross-compiling" /><title type="text">Snake On A Phone</title><content type="html">&lt;p&gt;For a few years now, my main task at work has been working on the firmware of an IP phone. The phone runs VxWorks on a MIPS32 CPU; the firmware is written in C and C++.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;For slightly less time, I've been dabbling in python on my own time. Freedom from explicit typing was a refreshing change, and python's tendency to Just Work was a nice bonus.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;It was perhaps inevitable that I would one day try to combine phone and language. (why? because they were both there)&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;It wasn't obvious that the idea stood a chance. VxWorks is a bit off the OS beaten track, and might not provide all the functionality needed by Python's "core" (not with the same names, anyway). There might be some processor-specific pieces that would rule out MIPS32. And even if I could get something built, would it fit in the 2 or 3 MB of RAM (and even less flash) I could spare?&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;As it turns out, there was very little to worry about. Python's code is impressively (if perhaps unsurprisingly) portable, only needing a couple of tweaks to its build system and none at all to its source code. There doesn't seem to be anything CPU-dependant; and in the end, adding python to my firmware only cost me 1MB. It took me only a few evenings of tinkering to get a libpython built, linked into my firmware, and loaded on my phone, to the point that I could run this little experiment at the VxWorks shell:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;  -&amp;gt; Py_Initialize()&lt;br /&gt;  value = 42 = 0x2a = '*'&lt;br /&gt;  -&amp;gt; PyRun_SimpleString("print 'Hello, World!'\n")&lt;br /&gt;  Hello, World!&lt;br /&gt;  value = 0 = 0x0&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;(the VxWorks shell being a peculiar animal that allows calling C functions by name, in this case giving me access to Python's C Extension API for a near-REPL experience)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;For my purposes, that's enough; I know it can work, and that's all I wanted. I don't expect to ever go further than this. But as little as it is, publishing how I got there might help someone get started on a real project; so here goes:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2&gt;Porting python in 10 easy* steps&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;*for a suitable definition of easy&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;As far as embedding Python in an existing application (or firmware) is concerned, &lt;a href="http://docs.python.org/api/embedding.html"&gt;Python's own documentation&lt;/a&gt; should give you most of what you need&lt;br /&gt;&lt;/li&gt;&lt;p&gt;&lt;/p&gt;&lt;li&gt;You'll need a cross-compiling toolchain, i.e. a compiler that can be used on one platform (e.g. x86) and produces executables for use on a different platform (e.g. MIPS32). GCC is your best bet; it's what will make python's build system happiest, and there's lots of resources on getting a GCC cross-compiler working on the web, though it looks a bit daunting to me. I was fortunate in that, since I was already set up to build firmwares, I already had all the needed tools; I would guess that most people engaging on a similar project would be in the same position.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;p&gt;&lt;/p&gt;&lt;li&gt;In addition to the compiler (and assembler, linker, etc), you'll want to have a Unix-like environment to run Python's configure script and makefiles. If you're on Windows, cygwin will serve nicely.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;p&gt;&lt;/p&gt;&lt;li&gt;The 'configure' script needs some tweaking: it contains a few uses of AC_TRY_RUN, which will fail when cross-compiling.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;If you have a working 'autoconf', the simplest is to edit the 'configure.in' file. You can either remove the AC_TRY_RUN tests altogether or replace them by the newer, more cross-compiler-friendly &lt;a href="http://www.gnu.org/software/autoconf/manual/html_node/Runtime.html"&gt;AC_RUN_IFELSE&lt;/a&gt;. Then run 'autoconf' to regenerate the 'configure' script.&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you don't (as I didn't), you can brace yourself and go edit the 'configure' script directly. Running the script produces error messages that gives something to search for. The fix is actually simple: just remove the calls to 'exit' to allow the error to get ignored.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;p&gt;&lt;/p&gt;&lt;li&gt;The makefile also needs tweaking: just like 'configure', at some point it tries to compile and run a program. This appears to be in order to autogenerate some source files, which fortunately are already provided in the source distribution; so it's safe to disable this step. The simplest way:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;open "Makefile.pre.in"&lt;br /&gt;&lt;/li&gt;&lt;li&gt;find the place where "$(PGEN)" shows up AFTER a ':'&lt;br /&gt;&lt;/li&gt;&lt;li&gt;remove "$(PGEN)"&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;(this will only prevent the executable from getting built. The makefile will still attempt to run it, but it's written so that the resulting failure is ignored)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;p&gt;&lt;/p&gt;&lt;li&gt;The configure script and makefile try to guess at the name of tools to use; you can give them a hint with environment variables. In my case I needed to set CC (the C Compiler) and AR (the "archiver", ie. what creates static libraries)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;p&gt;&lt;/p&gt;&lt;li&gt;If you need to specify special command-line options to the compiler, environment variables can also be used. Annoyingly, 'configure' and the makefiles use different variable; you'll want to set CFLAGS and BASECFLAGS to the same thing.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;p&gt;&lt;/p&gt;&lt;li&gt;Finally you'll be ready to run the 'configure' script. You need to give it the special options &lt;a href="http://www.gnu.org/software/autoconf/manual/html_node/Specifying-Names.html"&gt;--build and --host&lt;/a&gt; to tell it you're cross-compiling, something like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ ./configure --build=win32 --host=vxworks&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;(win32 and vxworks were a wild guess that happened to work for me. I got the impression the specific values didn't particularly matter)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;p&gt;&lt;/p&gt;&lt;li&gt;You can then run 'make' to compile everything. If, like me, all you need is a static library, this will do it:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ make libpython2.5.a&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;p&gt;&lt;/p&gt;&lt;li&gt;There's a good chance some files under Modules/ will fail to compile (in my case, posixmodule.c). The file Module/Setup specifies (in a rather well-documented way) which Python modules (written in C) should be built into the python library; comment out the failing one, and re-run 'make'. I only had to disable posixmodule and pwdmodule; YMMV.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;And for me, that was it; nothing else needed manual intervention. If you run into more troubles (e.g. trying to build the actual python.exe), I'm afraid you're on your own.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;My next step was to figure out how to integrate the python library into my firmware; you'll have to figure out the corresponding steps for your own firmware/embedded application/whatever. Start with the &lt;a href="http://docs.python.org/api/embedding.html"&gt;'embedding' link&lt;/a&gt; for how to access python code from your code.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;If you want to be able to load python source files with 'import', pay particular attention to what that page says about PYTHONHOME; as for me, I put a putenv(PYHONHOME=/whatever") before the Py_Initialize call, letting me import /whatever/python2.5/*.py files (and possibly, though I haven't tried, .py files contained in a /whatever/python2.5/libpython2.5.zip)&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Happy cross-compiling!&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-7183137287562820116?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/v2o2ra8yVWw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/7183137287562820116/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=7183137287562820116" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/7183137287562820116" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/7183137287562820116" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2008/07/snake-on-phone.html" title="Snake On A Phone" /><author><name>LPG</name><uri>http://www.blogger.com/profile/17088475660870758813</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="14634256068698141610" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-3825528010247369451</id><published>2008-07-24T07:00:00.001-04:00</published><updated>2008-07-25T14:31:21.824-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="outlook" /><category scheme="http://www.blogger.com/atom/ns#" term="oom" /><category scheme="http://www.blogger.com/atom/ns#" term="mapi" /><title type="text">Outlook Entry IDs Made Easy</title><content type="html">When developing for Outlook you will quickly realize that there's more than one way of doing things. For example, take a look at the number of APIs for interacting with Outlook:&lt;ul&gt;&lt;li&gt;Outlook Object Model (OOM)&lt;/li&gt;&lt;li&gt;MAPI&lt;/li&gt;&lt;li&gt;CDO&lt;/li&gt;&lt;li&gt;Office/Outlook COM Add-in (_IDTExtensibility2)&lt;/li&gt;&lt;li&gt;Exchange Client Extensions&lt;/li&gt;&lt;/ul&gt;That doesn't even include the six libraries included in the Outlook 2003 Integration API or the excellent 3rd-party &lt;a href="http://www.dimastr.com/redemption/"&gt;Redemption&lt;/a&gt; library. I'm positive there are others. Usually you won't use all these APIs in the same project. However, if you want to do anything significant in Outlook, you'll need to use the OOM and MAPI libraries.&lt;br /&gt;&lt;br /&gt;It's important to understand the relationship between MAPI and the OOM:&lt;ul&gt;&lt;li&gt;The MAPI API dates back to the early Outlook days. It's used for the messaging and storage subsystems in Outlook.&lt;/li&gt;&lt;li&gt;The Outlook Object Model sits on top of MAPI and wraps a minimal amount of its functionality. It also exposes some of the Outlook UI to the developer.&lt;/li&gt;&lt;/ul&gt;When you work with these APIs, you'll hit on the problem of linking them together. Outlook Entry IDs are a good example. Entry IDs uniquely identify most objects in the OOM and MAPI. Being very flexible, Entry IDs can take many shape or form and can cause headaches when you try to handle them.&lt;br /&gt;&lt;br /&gt;At its simplest, an Entry ID is a variable length byte buffer, sometimes represented with a simple byte array. In MAPI, most Entry IDs are represented by the ENTRYID structure:&lt;h3&gt;mapidefs.h&lt;/h3&gt;&lt;pre&gt;typedef struct { &lt;br /&gt;    BYTE abFlags[4]; &lt;br /&gt;    BYTE ab[MAPI_DIM]; &lt;br /&gt;} ENTRYID, FAR *LPENTRYID;&lt;/pre&gt;This structure usually comes wrapped in the SBinary structure.&lt;h3&gt;mapidefs.h&lt;/h3&gt;&lt;pre&gt;typedef struct _SBinary { &lt;br /&gt;    ULONG cb; &lt;br /&gt;    LPBYTE lpb; &lt;br /&gt;} SBinary, FAR *LPSBinary;&lt;/pre&gt;In the Outlook Object Model things take a turn for the worst:&lt;ul&gt;&lt;li&gt;Most times you see Entry IDs as a BSTR that is hex encoded (i.e. the strings look like this: "000F1329EC29A0382BC...").&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.msdn.com/stephen_griffin/archive/2007/07/03/you-mean-you-want-the-oom-to-actually-work.aspx"&gt;Sometimes&lt;/a&gt; it still uses a BSTR, but it doesn't encode the buffer, instead using the BSTR as a binary blob. Although inconsistent, this is &lt;a href="http://msdn.microsoft.com/en-us/library/ms221105(VS.85).aspx"&gt;perfectly valid&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Sometimes it's useful to represent the Entry ID as a SAFEARRAY of VARIANT VT_UI1 (this is the format VB uses for its byte arrays). For example, I've needed to have a function that can return a property any type from a MAPI object that needs to be called through automation (i.e. VB). For example, the &lt;a href="http://www.dimastr.com/redemption/utils.htm"&gt;IMAPIUtils::HrGetOneProp&lt;/a&gt; method from the Redemption Library does this.&lt;/li&gt;&lt;/ul&gt;Is your head spinning? Mine was.&lt;br /&gt;&lt;br /&gt;I solved the problem by creating a class (yet another format!) to facilitate manipulation of all these formats:&lt;pre&gt;class EntryId&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;    EntryId(EntryId const&amp; entryId);&lt;br /&gt;&lt;br /&gt;    // All explicit so that it's always clear what we are doing.&lt;br /&gt;    explicit EntryId(BSTR const* str, bool hexEncoded = true);&lt;br /&gt;    explicit EntryId(SBinary const* binary);&lt;br /&gt;    explicit EntryId(SAFEARRAY const* array);&lt;br /&gt;    explicit EntryId(unsigned long count, unsigned char const* bytes);&lt;br /&gt;&lt;br /&gt;    // Again, no implicit conversion&lt;br /&gt;    CComBSTR toString(bool hexEncoded = true) const;&lt;br /&gt;    CComSafeArray&lt;VARIANT&gt; toSafeArray() const;&lt;br /&gt;    std::vector&lt;unsigned char&gt; toByteArray() const;&lt;br /&gt;    // ... add more as you need them&lt;br /&gt;&lt;br /&gt;    // TODO: Add more custom helper functions.&lt;br /&gt;    bool isLongTermId() const;&lt;br /&gt;&lt;br /&gt;    // TODO: Add comparison operators for convenience and ordered &lt;br /&gt;    // container support (such as std::map keys). When comparing &lt;br /&gt;    // Entry Ids, remember you need to use the &lt;br /&gt;    // &lt;a href="http://msdn.microsoft.com/en-us/library/ms530706(EXCHG.10).aspx"&gt;IMAPISupport::CompareEntryIDs&lt;/a&gt; method.&lt;br /&gt;    &lt;br /&gt;private:&lt;br /&gt;    std::vector&amp;lt;unsigned char&amp;gt; m_buffer;&lt;br /&gt;}&lt;/pre&gt;Now whenever I get an Entry ID in any format, the first thing I do is convert it to an EntryId instance. This adds many convenient functionalities:&lt;ul&gt;&lt;li&gt;Standardized interface to all ids.&lt;/li&gt;&lt;li&gt;Easy comparison of entry ids.&lt;/li&gt;&lt;li&gt;EntryId is a copyable class and can be passed by value.&lt;/li&gt;&lt;li&gt;EntryId can be held in a STL container.&lt;/li&gt;&lt;li&gt;Your other helper classes and methods can use the EntryId as parameter instead of other formats.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-3825528010247369451?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/OBAwBqHLAfU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/3825528010247369451/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=3825528010247369451" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/3825528010247369451" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/3825528010247369451" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2008/07/outlook-entry-ids-made-easy.html" title="Outlook Entry IDs Made Easy" /><author><name>Jean-Yves Boudreau</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-8696210027750230726</id><published>2008-07-23T12:14:00.003-04:00</published><updated>2008-07-23T12:16:38.677-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="QA" /><category scheme="http://www.blogger.com/atom/ns#" term="software testing" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><category scheme="http://www.blogger.com/atom/ns#" term="QC" /><title type="text">Software Testers - Don't Underestimate Their Worth for Success</title><content type="html">Sometimes, testing your application isn’t enough: sometimes your test cases need to be tested!   Testing doesn’t always give you what you’d expect.  In extreme cases, it can even give you a false sense of confidence in a product that is a complete failure.&lt;br /&gt;&lt;br /&gt;Recently, I was managing an offshore team developing a component for our client's core enterprise application.  We wrote extensive test cases and, because we were concerned about a lack of domain knowledge, we even had architects write some of the test cases.   Things were looking good as we approached the end of the development cycle: the product was behaving as it was supposed to; we were passing test cases; we were greenlighted by the QC ‘process’.&lt;br /&gt;&lt;br /&gt;Our confidence was high, and we were ready to move on to automated testing.  Then we found the problem.  It turns out that our test cases were written with a single user in mind.  The minute we started to use this component with concurrent user access, the system would pretty much lock up.  Our confidence evaporated.&lt;br /&gt;&lt;br /&gt;This was a big mistake.  Architects and technical leads both reviewed the test cases.  Nobody found the oversight at the time.   This was compounded by an ‘if it passes the test cases then it works’ mentality.&lt;br /&gt;&lt;br /&gt;Unfortunately, a solution to this problem isn’t as easy as ‘follow these three steps’.  But if we can take away a lesson learned from this, it is that testing the right way is not only very important to the success of a product, but it also shouldn’t be taken for granted.  If you haven’t noticed, QC/QA and testers were not included in the writing of test cases, thus bypassing all kinds of valuable experience that would most likely caught our newbie mistakes.&lt;br /&gt;&lt;br /&gt;Bottom line - Don’t underestimate the worth of your testers and their experience, it might just come back to bite you in the future.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-8696210027750230726?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/kBR6_Z12-Dw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/8696210027750230726/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=8696210027750230726" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/8696210027750230726" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/8696210027750230726" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2008/07/software-testers-dont-underestimate.html" title="Software Testers - Don't Underestimate Their Worth for Success" /><author><name>Tony</name><uri>http://www.blogger.com/profile/17596211212687907094</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="09702771695631948195" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-7014789058428782665</id><published>2008-07-17T23:50:00.000-04:00</published><updated>2008-07-17T23:50:49.547-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="code quality" /><title type="text">Maintenance Nightmares: Commented out code</title><content type="html">I was working on an estimate for a prospective customer, and luckily I had the code to examine beforehand to see what it was doing.&lt;br /&gt;&lt;br /&gt;While examining the code, I noticed code like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;// Fix for bug 1021892&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;// some code that was commented out.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There were instances of this throughout the code.&lt;br /&gt;&lt;br /&gt;When I see this I instinctively cringe, I immediately think that there is no proper source control or defect tracking procedures (or tools) in place. While there may be the odd corner case where commented out code is acceptable, in general it is not and should be avoided.&lt;br /&gt;&lt;br /&gt;There are many better ways of dealing with this, the first way is to just delete the line of code, and when you commit/check-in the code, make sure you put a meaningful comment in the commit logs  that ties it to the defect it was changed for. You can often search the commit logs, and if you put the bug id in the commit log, you will get the change in your search.&lt;br /&gt;&lt;br /&gt;Another easy way to do this is to delete the line of code, make a patch, and when resolving the bug in your bug tracking software, attach the patch file to that issue. Then you can always see what you changed to fix the bug.&lt;br /&gt;&lt;br /&gt;Does anyone else having any suggestions for this?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-7014789058428782665?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/Uc0nEP5DPx8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/7014789058428782665/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=7014789058428782665" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/7014789058428782665" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/7014789058428782665" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2008/07/maintenance-nightmares-commented-out.html" title="Maintenance Nightmares: Commented out code" /><author><name>Jason Mawdsley</name><email>jason@macadamian.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-1187988472518294639</id><published>2008-07-11T14:25:00.009-04:00</published><updated>2008-07-15T10:08:27.413-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="c++" /><category scheme="http://www.blogger.com/atom/ns#" term="optimization" /><category scheme="http://www.blogger.com/atom/ns#" term="compiler" /><title type="text">Alignment Matters</title><content type="html">When do these two snippets behave differently?&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;void* p = something();&lt;br /&gt;int i = *(int*)p;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;int i;&lt;br /&gt;void* p = something();&lt;br /&gt;memcpy(&amp;amp;i, p, sizeof(int));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Answer: when 'something' returns a value that's not a multiple of "sizeof(int)".&lt;br /&gt;&lt;br /&gt;Some processor architectures only allow loading memory into N-byte registers from memory addresses that are a multiple of N (e.g. multiple of 4 for 32-bit registers). Using misaligned addresses can have some various interesting consequences, depending on the CPU; I've heard of at least these:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It works fine&lt;/li&gt;&lt;li&gt;It works, but slowly (e.g. because the misalignment is detected and alternate instructions are used to load 1 byte at a time - I've heard that x86 works this way)&lt;/li&gt;&lt;li&gt;The program may crash due on an "invalid address" trap&lt;/li&gt;&lt;li&gt;The CPU may load data from the wrong address (e.g. if only multiples of 4 are valid addresses, the instruction might ignore the bottom 2 bits of the address)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Last week, I got lucky: I discovered that the MIPS32 CPU on the phone I was programming falls in the "crash" category. (why lucky? because an "address load exception" message is much easier to debug than some corrupted data)&lt;br /&gt;&lt;br /&gt;Usually, we don't have to worry about such alignment issues; the compiler and runtime make sure that all objects it allocates go at addresses that have the right alignment for their type (e.g. malloc must return memory "suitably aligned" for all possible types).&lt;br /&gt;&lt;br /&gt;Trouble comes when we lie to the compiler, such as telling it by a cast that "p" points to an "int" when such is not the case. This is what happened to me: I was parsing a file, and the 4-byte-value-that-should-be-put-in-an-int followed an arbitrary-length string. It ended up on an odd address, and boom. (Here's another way I was lucky: it COULD have been a nice multiple of 4 in all my tests, only to come out odd on a client's desk)&lt;br /&gt;&lt;br /&gt;Functions like memcpy, of course, are required to work with all addresses (as expressed by taking void* parameters, which require no cast).&lt;br /&gt;&lt;br /&gt;Lesson of the day? Don't lie to your compiler!&lt;br /&gt;(alternate lesson: "casts: evil AND chaotic"?)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-1187988472518294639?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/ZpXpJTMT4as" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/1187988472518294639/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=1187988472518294639" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/1187988472518294639" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/1187988472518294639" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2008/07/alignment-matters.html" title="Alignment Matters" /><author><name>LPG</name><uri>http://www.blogger.com/profile/17088475660870758813</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="14634256068698141610" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-6155040441432892493</id><published>2008-07-10T14:43:00.003-04:00</published><updated>2008-07-11T10:34:29.373-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="semantic" /><category scheme="http://www.blogger.com/atom/ns#" term="c#" /><title type="text">Compile Time Semantic Checking</title><content type="html">C# is a TypeSafe language, what about SemanticSafe?&lt;br /&gt;&lt;br /&gt;In a project I'm working on we have a lot of database records ids being passed around as integers.  Today I needed to add a new record id to this list.  Adding the new item to the function signature is easy. The hard part comes in making sure the right value is being assigned.&lt;br /&gt;&lt;pre&gt;Public void MyFunction(int TableA_ID, int TableB_ID, String someOtherValue);&lt;br /&gt;&lt;br /&gt;int A_ID = 5;&lt;br /&gt;int B_ID = 4;&lt;br /&gt;MyFunction(B_ID, A_ID, "Hello World");&lt;/pre&gt;&lt;br /&gt;So what happens when I compile? Nothing, it works fine. Yet that line where I called the function has just corrupted the entire database because those database ID's were transposed.  Which kinda sucks.&lt;br /&gt;&lt;br /&gt;It's one thing to guarantee type safety, what what about semantic safety?  An idea popped into my head to use the existing type-checking to accomplish this.&lt;br /&gt;&lt;pre&gt;    public struct UserID&lt;br /&gt; {&lt;br /&gt;     private int value;&lt;br /&gt;     public static implicit operator int(UserID source)&lt;br /&gt;     { return source.value; }&lt;br /&gt;&lt;br /&gt;     public UserID(int intValue)&lt;br /&gt;     {&lt;br /&gt;         value = intValue;&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt; private void TryToFail(UserID test) { } &lt;br /&gt;&lt;br /&gt; UserId works = new UserId(5);&lt;br /&gt; int fails = works;&lt;br /&gt;&lt;br /&gt; TryToFail(works) //compiles fine&lt;br /&gt; TryToFail(fails) //Doesn't compile&lt;/pre&gt;&lt;br /&gt;Even though both works and fails contain the exact same value, the function can be made to fail if the values are put in the wrong order.  I used an implicit operator so that I didn't lose the convince of having a simple integer, neato.&lt;br /&gt;&lt;br /&gt;Obviously this technique is not something you would want to use for every possible field as there is one extra step involved in getting the value.  But if you only did this for the record IDs I think it would be enough gain to make it worthwhile.&lt;br /&gt;&lt;br /&gt;I would like to think of a way to do this so that it has compile time checking, but once compiled only contains the primitive value.   Any ideas?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-6155040441432892493?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/KA-Rvz2POno" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/6155040441432892493/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=6155040441432892493" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/6155040441432892493" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/6155040441432892493" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2008/07/compile-time-semantic-checking.html" title="Compile Time Semantic Checking" /><author><name>Jake</name><uri>http://www.blogger.com/profile/04529021825096290761</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="01965567926181683432" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-1109675262390353465</id><published>2008-07-09T11:31:00.009-04:00</published><updated>2008-07-10T13:51:15.376-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="IRM" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="SharePoint" /><title type="text">Trouble Getting Your Custom Protector Called?</title><content type="html">You might be getting a lot of grey hair by developing your own custom protector for SharePoint.  Until recently, I was right there with you.  Having troubles getting your custom protector to be called by SharePoint?  I'm here to help.  I'm happy to tell you that it could be a simple fix.  A simple flag as a matter of fact.  If you haven't heard of the IrmAddInsEnabled flag, then this is what you must do.&lt;br /&gt;&lt;br /&gt;You need to set the IrmAddInsEnabled flag to true in the Central Admin page to get SharePoint to call any of the protector function calls (HrIsProtected, HrProtect, HrUnprotect).  This sets a Boolean value that specifies whether to enable Information Rights Management (IRM) addins.&lt;br /&gt;&lt;br /&gt;You can do this directly on the MOSS server from the 12 Hive (C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\BIN) by calling the following:&lt;br /&gt;&lt;br /&gt;On the MOSS server:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;'stsadm -o setproperty -propertyname irmaddinsenabled -propertyvalue "yes"'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Alternatively, you can do this programmatically by using SharePoint via the IRM Settings by using SPIrmSettings.IrmAddins.  This can be done at the farm level or as granular as a per-list basis.&lt;br /&gt;&lt;br /&gt;IRM Settings for the FARM:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SPWebService svc = SPFarm.Local.Services.GetValue&lt;spwebservice&gt;();&lt;br /&gt;SPIrmSettings irmSettings = svc.IrmSettings;&lt;br /&gt;&lt;br /&gt;//Specifies whether to enable Information Rights Management (IRM)&lt;br /&gt;//locally for sites&lt;br /&gt;irmSettings.IrmRMSEnabled = true; &lt;br /&gt;&lt;br /&gt;//Specifies whether to enable Information Rights Management (IRM)&lt;br /&gt;//addins&lt;br /&gt;irmSettings.IrmAddinsEnabled = true;&lt;br /&gt;&lt;br /&gt;//Sets the number of times the Information Rights Management (IRM)&lt;br /&gt;//settings have been changed&lt;br /&gt;irmSettings.IrmChanges += 2; &lt;br /&gt;&lt;br /&gt;svc.Update();&lt;br /&gt;&lt;/spwebservice&gt;&lt;/pre&gt;&lt;br /&gt;IRM Settings for the Individual Lists on FeatureActivated:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SPWeb web = (SPWeb)properties.Feature.Parent; &lt;br /&gt;foreach (SPList list in web.Lists)&lt;br /&gt;{&lt;br /&gt;  // Specifies whether to enable Information Rights Management (IRM)&lt;br /&gt;  // for the list&lt;br /&gt;  list.IrmEnabled = true;&lt;br /&gt;&lt;br /&gt;  // Specifies whether to allow users to upload documents that do&lt;br /&gt;  // not support IRM &lt;br /&gt;  list.IrmReject = true;&lt;br /&gt; &lt;br /&gt;  list.Update();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;After you have done this, your custom protector should be called when the documents are checked in and out of your SharePoint system via the HrIsProtected, HrProtect, HrUnprotect methods.&lt;br /&gt;&lt;br /&gt;Goodluck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-1109675262390353465?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/iw8CD8AoYQo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/1109675262390353465/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=1109675262390353465" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/1109675262390353465" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/1109675262390353465" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2008/07/trouble-getting-your-custom-protector.html" title="Trouble Getting Your Custom Protector Called?" /><author><name>Aaron Gensey</name><email>agensey@lixar.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-6869938301668289971</id><published>2008-07-07T11:38:00.009-04:00</published><updated>2008-07-08T11:36:47.069-04:00</updated><title type="text">Mining Project Scope with Python + SVN</title><content type="html">After developing a component for a fairly large enterprise application, I was tasked with coordinating a complete review of all code touched by our team.  As the project involved hundreds of commits across every tier of the application, this was not a trivial task.  I didn’t want to make developers hunt through SVN logs and JIRA - even if the result was accurate, producing meta-documentation in the time allotted for actual documentation seemed wasteful.  There had to be a way to automate it.  After failing to find an appropriate SVN tool via Google, I weighed the pros and cons [1] then decided that using an SVN API would be easy enough.&lt;br /&gt;&lt;br /&gt;&lt;strike&gt;To make it interesting&lt;/strike&gt; As part of my commitment to Macadamian’s core value of continual improvement, I decided to try out Python.  The following script was maybe an hour of entertaining work that saved at least a day of tedium.&lt;br /&gt;&lt;pre style="overflow: scroll; height: 50em;"&gt;&lt;br /&gt;import pysvn&lt;br /&gt;&lt;br /&gt;# Script variables.  Could be read from a command line or config. file.&lt;br /&gt;username = "jlennon"&lt;br /&gt;password = "yoko"&lt;br /&gt;projectFirstRevision = 103991&lt;br /&gt;svnRoot = "http://path/to/svn/trunk/"&lt;br /&gt;&lt;br /&gt;# Team members’ names for SVN commits.&lt;br /&gt;users = set([&lt;br /&gt;          "gharrison",&lt;br /&gt;          "rstarkey",&lt;br /&gt;          "jlennon",&lt;br /&gt;          "pmccartney",&lt;br /&gt;          "gmartin",&lt;br /&gt;          "pbest"&lt;br /&gt;          ])&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;# Set up SVN callbacks.&lt;br /&gt;def get_login(realm, username, may_save):&lt;br /&gt;   return True, username, password, False;&lt;br /&gt;&lt;br /&gt;def get_log_message() :&lt;br /&gt;   return True, "log message called"&lt;br /&gt;&lt;br /&gt;client = pysvn.Client()&lt;br /&gt;client.callback_get_login = get_login&lt;br /&gt;client.callback_get_log_message = get_log_message&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;# Convert the revision number into a pysvn revision.&lt;br /&gt;projectFirstRevision = pysvn.Revision(pysvn.opt_revision_kind.number, projectFirstRevision)&lt;br /&gt;&lt;br /&gt;# Get all commits since the project's first commit.&lt;br /&gt;items = client.log(&lt;br /&gt;           svnRoot,&lt;br /&gt;           pysvn.Revision(pysvn.opt_revision_kind.head),&lt;br /&gt;           projectFirstRevision,&lt;br /&gt;           discover_changed_paths=True,&lt;br /&gt;           )&lt;br /&gt;&lt;br /&gt;# Set up variables for storing commit information&lt;br /&gt;allPaths = set([])&lt;br /&gt;removedPaths = set([])&lt;br /&gt;&lt;br /&gt;# For each commit entry *made by one of this project's users*&lt;br /&gt;#   Add any deleted files in the commit to removedPaths&lt;br /&gt;#   Add any added/updated files to the list of all paths&lt;br /&gt;for item in [ e for e in items if e.author in users ]:&lt;br /&gt;&lt;br /&gt;   for changed_path in item.changed_paths:&lt;br /&gt;&lt;br /&gt;      if changed_path.action == "D":&lt;br /&gt;         removedPaths.add(changed_path.path)&lt;br /&gt;      else:&lt;br /&gt;         allPaths.add(changed_path.path)&lt;br /&gt;&lt;br /&gt;# Remove deleted files from allPaths, then display&lt;br /&gt;allPaths = allPaths - removedPaths&lt;br /&gt;&lt;br /&gt;for path in sorted(allPaths):&lt;br /&gt;   print path&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Overall, I was impressed by Python.  My biggest problem was with the structure of the documentation, but that’s to be expected with any new language.  My biggest surprise was that the indentation rules didn’t bother me – why is this cited as a show-stopper by so many developers?  I’ll definitely be coming back to Python to test its OO facilities.&lt;br /&gt;&lt;br /&gt;[1] The main con being that a developer would much rather write a neat SVN spider than write documentation.  In a leadership role, you have to think twice before eagerly firing up your compiler to solve a problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-6869938301668289971?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/lDdXuGJrsFE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/6869938301668289971/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=6869938301668289971" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/6869938301668289971" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/6869938301668289971" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2008/07/mining-project-scope-with-python-svn.html" title="Mining Project Scope with Python + SVN" /><author><name>Gord. P</name><uri>http://www.blogger.com/profile/10684846302006538110</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="05573681110765124582" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-698633490157004878</id><published>2008-07-02T11:25:00.000-04:00</published><updated>2008-07-02T11:28:45.853-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="RIL" /><category scheme="http://www.blogger.com/atom/ns#" term="Windows Mobile" /><title type="text">Getting RIL!!</title><content type="html">Have you ever wanted to mess around with calling functionality of a mobile phone running Windows Mobile?&lt;br /&gt;&lt;br /&gt;I have this nifty phone but how do I control it programmatically?&lt;br /&gt;&lt;br /&gt;Well, first of all, the Windows Mobile Radio Interface Layer works by having specific modules control the cellular component. Since we are in North America there are two different cellular protocol implementations: GSM and CDMA. Above this layer is an abstraction layer that hides the implementation of the underlying protocol so that applications/OEM phone developers can use the functionality of call handling (and other useful information) without getting down to how things work under the hood. So how do we, as an application, talk to this abstraction layer, which we'll just clump together and call it the RIL( Radio Interface Layer )? Good Question!&lt;br /&gt;&lt;br /&gt;Since cellular devices are really just modems that use AT commands, the RIL operates mainly from an asynchronous callback system. In fact most of the RIL functions really just map to AT commands. The application accessing the RIL makes a request to the RIL, and the RIL takes some time to process this request and sends back a result code indicating the success or failure of the request. In addition the RIL spits out notifications which our application can hook into and be informed of status changes related to the cellular network. So let's dig a little with some RIL examples.&lt;br /&gt;&lt;br /&gt;There are a few pitfalls by going down this path. Firstly you might run into situations where you're fighting for control with the resident dialer (the default phone application supplied to the mobile device; developed by Microsoft). There may also be some undocumented internal states that need to be obeyed or else it can lead to unintended behavior (i.e. device lock up).&lt;br /&gt;&lt;br /&gt;There are also some differences to note between CDMA and GSM RIL implementations. With GSM devices there can be multiple lines, and as such the RIL can fetch call information for each line. RIL can also manage the GSM lines to perform actions such as putting the call on hold or switching lines. In the CDMA environment, there is only one "real" line and one "virtual" line. That is, one line is used to represent two lines. Access between the two lines is achieved by sending a "flash" command. Call management is also not possible with CDMA. So when you call "RIL_GetCallList" for GSM, for example, you may be returned information for one or more lines depending on the call state. For CDMA, you will only see at most one line.&lt;br /&gt;&lt;br /&gt;You will have to get your hands on the ril.h and ril.lib files. Both of these files are floating around somewhere on the internet (try &lt;a href="http://www.xs4all.nl/%7Eitsme/projects/xda/ril.html"&gt;here&lt;/a&gt;). If you can get both of these files, link your application with ril.lib and away you go. If you can’t find ril.lib but have ril.h, you can dynamically link with the ril.dll file (contained in the “windows” folder on the device) since you know what some of the prototypes are.&lt;br /&gt;&lt;br /&gt;First we need to initialize our application with the RIL so that we can receive both results and notifications callbacks. Here’s some code to do this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;// keep this handle handy as we need it for further RIL commands&lt;br /&gt;HRIL rilHandle;&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;HRESULT hr = RIL_Initialize(&lt;br /&gt;   1,                  // index of the RIL port to use (e.g., 1 for RIL1:)&lt;br /&gt;   &amp;amp;resultCallBack,    // this is a pointer to your result call back method&lt;br /&gt;   &amp;amp;notifyCallback,    // this is a pointer to your notify call back method&lt;br /&gt;   RIL_NCLASS_ALL,     // all notification (except device specific)&lt;br /&gt;   (DWORD) this,       // custom param (could be a pointer to an instance of a class)&lt;br /&gt;   &amp;amp;rilHandle);        // returned handle to RIL instance&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;void CALLBACK resultCallback(&lt;br /&gt;   DWORD dwCode,&lt;br /&gt;   HRESULT hrCmdID,&lt;br /&gt;   const void *lpData,&lt;br /&gt;   DWORD cbData,&lt;br /&gt;   DWORD dwParam)&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;   // handle the results&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;void CALLBACK notifyCallback(&lt;br /&gt;   DWORD dwCode,&lt;br /&gt;   const void *lpData,&lt;br /&gt;   DWORD cbData,&lt;br /&gt;   DWORD dwParam)&lt;br /&gt;{&lt;br /&gt;   // handle the notification&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note that we’ve initialize the RIL with a reference to our class as the user parameter which is passed to the result and notification callbacks. The parameter is optional; however having the class reference would be especially useful if you would like to perform further actions after receiving a result or notification.  More on this later.&lt;br /&gt;&lt;br /&gt;OK so what - I've just initialized myself with RIL - what can I do now?&lt;br /&gt;To answer that question, anything under the Sun related to call handling, and then some!!&lt;br /&gt;&lt;br /&gt;For example if you wish to check the call status of the phone you can do the following. First send a request for call list:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;HRESULT cmdID;&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;void getCallList()&lt;br /&gt;{&lt;br /&gt;   // call RIL_GetCallList with RIL handle from the initialization&lt;br /&gt;   cmdID = RIL_GetCallList(rilHandle);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Next we have to wait for the results:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;void CALLBACK resultCallback(&lt;br /&gt;   DWORD dwCode,&lt;br /&gt;   HRESULT hrCmdID,&lt;br /&gt;   const void *lpData,&lt;br /&gt;   DWORD cbData,&lt;br /&gt;   DWORD dwParam)&lt;br /&gt;{&lt;br /&gt;   If (cmdID == hrCmdID &amp;amp;&amp;amp; RIL_RESULT_OK == (dwCode &amp;amp; 0xff))&lt;br /&gt;   {&lt;br /&gt;       // lpData points to an array of &lt;t&gt; structures.&lt;br /&gt;       RILCALLINFO *lpCallInfo = (RILCALLINFO *)lpData;&lt;br /&gt;       // extract the call info from the structure and do something...&lt;br /&gt;...&lt;br /&gt;&lt;/t&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Notice how the cmdID return value of RIL_GetCallList matches hrCmdID in the callback. In a realistic scenario, multiple commands are sent and the results do not necessary return in the same order the commands were sent. As a result we would need to queue up the command IDs in order to properly identify the command represented by each callback&lt;br /&gt;&lt;br /&gt;Now what is notifiyCallback useful for? This function is called basically whenever an event occurs that is of a notification class that was registered during initialization (we registered with RIL_NCLASS_ALL in this case). For example, for an incoming call you would receive and handle the “ring” notification as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;void CALLBACK notifyCallback(&lt;br /&gt;   DWORD dwCode,&lt;br /&gt;   const void *lpData,&lt;br /&gt;   DWORD cbData,&lt;br /&gt;   DWORD dwParam)&lt;br /&gt;{&lt;br /&gt;   if(dwCode &amp;amp; RIL_NCLASS_CALLCTRL)&lt;br /&gt;   {&lt;br /&gt;       switch(dwCode &amp;amp; (0xff | RIL_NCLASS_CALLCTRL))&lt;br /&gt;       {&lt;br /&gt;       case RIL_NOTIFY_RING:&lt;br /&gt;           // do something here&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Since the phone is ringing, it is probably best to get more information about the incoming call. If you remember from initialization we use the class reference as the custom parameter. This gives us the flexibility to send further RIL commands by either passing in the RIL handle (HRIL) or point to a function in the class. In this case we can point back to the getCallList function created earlier.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;MyClass* myClass = (MyClass*)dwParam;&lt;br /&gt;myClass-&gt;getCallList();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If we don’t have a function to point to, we can always send an RIL command on the fly by passing in the RIL handle from our class. For example to answer the call right away:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;MyClass* myClass = (MyClass*)dwParam;&lt;br /&gt;HRESULT hr = RIL_Answer(myClass-&gt;rilHandle);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As a note, if we're not using the interface anymore we'll need to de-register ourselves:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;RIL_Deinitialize(rilHandle);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To learn more about RIL and all its wonders, you should closely examine the ril.h header. There is some information on the &lt;a href="http://msdn.microsoft.com/en-us/library/aa920441.aspx"&gt;msdn site&lt;/a&gt; as well. The best way to learn about it, of course, is to just try it out yourself.&lt;br /&gt;&lt;br /&gt;(Originally written and concept by Quan Nguyen; modified and edited by Henry Yi)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-698633490157004878?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/omvP7dgY7z4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/698633490157004878/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=698633490157004878" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/698633490157004878" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/698633490157004878" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2008/07/getting-ril.html" title="Getting RIL!!" /><author><name>Henry Yi</name><uri>http://www.blogger.com/profile/13165444059632676825</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="14559832009685559804" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-7005907291298653959</id><published>2008-06-27T18:52:00.004-04:00</published><updated>2008-06-27T19:02:20.847-04:00</updated><title type="text">Pure CSS Image Rollover without background-image</title><content type="html">The other day I was in a situation where I had an image that changed to another image when the user mouses over it. Usually I will do this in one of two very standard ways:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The typical javascript approach: using the onMouseOver and onMouseOut events to swap the images.&lt;/li&gt;&lt;li&gt;The typical css approach: an element that sets its background-image attribute to the default image, and changes its background-image attribute to the rollover image when the :hover pseudoclass is activated.&lt;/li&gt;&lt;/ul&gt;Unfortunately, neither of these solutions were optimal as I was looking for a pure-CSS solution (so no javascript) and needed the image to have its own &amp;lt;img&amp;gt; tag (so no background-image). After playing around with my selectors a little, I came up with this little gem:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;u&gt;The HTML&lt;/u&gt;:&lt;br /&gt;&lt;pre&gt;&amp;lt;div class="buttonContainer"&amp;gt;&lt;br /&gt; &amp;lt;img class="rest" src="link_rest.png" /&amp;gt;&lt;br /&gt; &amp;lt;img class="roll" src="link_roll.png" /&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;u&gt;The CSS&lt;/u&gt;:&lt;br /&gt;&lt;pre&gt;div.buttonContainer img.roll {&lt;br /&gt; display: none;&lt;br /&gt;}&lt;br /&gt;div.buttonContainer:hover img.roll {&lt;br /&gt; display: inline;&lt;br /&gt;}&lt;br /&gt;div.buttonContainer:hover img.rest {&lt;br /&gt; display: none;&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;This neat CSS trick leaves the images in the html and changes the image on rollover with minimal mark-up. It works by abstracting the :hover pseudoClass to the container, loading both images into the page, and controlling the rollover effect using the images' display attribute.&lt;br /&gt;&lt;br /&gt;One word of caution: some older browsers (I'm looking at you, IE6) have poor support for the :hover pseudoclass, which renders this example ineffective; thus if you're supporting a lot of legacy browsers, this may not be for you. However, if you need a rollover that uses actual image tags and want to avoid using javascript, this may be just what you need.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-7005907291298653959?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/BEcZ3WJb8ew" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/7005907291298653959/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=7005907291298653959" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/7005907291298653959" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/7005907291298653959" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2008/06/pure-css-image-rollover-without.html" title="Pure CSS Image Rollover without background-image" /><author><name>Dan M</name><uri>http://www.blogger.com/profile/07261008052647160453</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03229345788419499251" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35928092.post-202477328236774508</id><published>2008-06-17T17:19:00.021-04:00</published><updated>2008-06-25T16:41:19.077-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Windows Mobile" /><title type="text">Obtaining the voicemail number on Windows Mobile phones</title><content type="html">The voicemail number, if available, may be stored in various locations on the Windows Mobile phone device depending on the type and carrier. In most cases, the number will show up somewhere in the registry. From experience I have found them in one of several locations under HKEY_CURRENT_USER:&lt;br /&gt;&lt;br /&gt;\Software\Microsoft\Vmail\PhoneNumber1&lt;br /&gt;\Software\Microsoft\Vmail\PhoneNumber2&lt;br /&gt;\Software\Microsoft\Vmail\UserProvidedNumber1&lt;br /&gt;\Software\Microsoft\Vmail\CarrierProviderNumber1&lt;br /&gt;\System\State\Messages\vmail\VMailNumber&lt;br /&gt;\Palm\State\Messages\vmail\VMailNumber&lt;br /&gt;&lt;br /&gt;On some GSM devices however the number isn’t always updated properly in the registry. In that case you would have to fetch it direct from the SIM card. In fact it is probably safest to fetch it from the SIM card first since this ensures a more accurate number.&lt;br /&gt;&lt;br /&gt;If you do some internet searches and dig through some of the &lt;a href="http://www.3gpp.org/specs/specs.htm"&gt;3GPP specifications for (U)SIM&lt;/a&gt; (i.e. 3GPP TS 31.102, 51.011) you will find that the voicemail number is stored in the EF&lt;sub&gt;MBDN&lt;/sub&gt; (Mailbox Dialing Numbers) file located at either 6FC7 for 3G devices or 6F17 for 2G.&lt;br /&gt;&lt;br /&gt;We can get the voicemail file from the SIM using the &lt;a href="http://msdn.microsoft.com/en-us/library/aa454262.aspx"&gt;SIM Manager API&lt;/a&gt;. Note that some of these are &lt;a href="http://msdn.microsoft.com/en-us/library/aa919335.aspx"&gt;privileged functions&lt;/a&gt;. You also have to make sure to add “cellcore.lib” as a dependency to your project. The code would look as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// include the SIM Manager API&lt;br /&gt;#include &lt;simmgr.h&gt;&lt;br /&gt;&lt;br /&gt;// set the voicemail addresses&lt;br /&gt;#define EF_MBDN_2G 0x6F17&lt;br /&gt;#define EF_MBDN_3G 0x6FC7&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;std::string getVoicemailNumber()&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;std::string number;&lt;br /&gt;HSIM hSim = 0;&lt;br /&gt;HRESULT hr = S_OK;&lt;br /&gt;&lt;br /&gt;// initialize&lt;br /&gt;hr = SimInitialize (0, 0, 0, (LPHSIM)&amp;hSim);&lt;br /&gt;&lt;br /&gt;if (S_OK == hr)&lt;br /&gt;{&lt;br /&gt;    DWORD address = EF_MBDN_2G;&lt;br /&gt;    SIMRECORDINFO simRecordInfo = {0};&lt;br /&gt;    simRecordInfo.cbSize = sizeof(SIMRECORDINFO);&lt;br /&gt;&lt;br /&gt;    // check the 2G address for the file&lt;br /&gt;    hr = SimGetRecordInfo(hSim, address, &amp;simRecordInfo);&lt;br /&gt;&lt;br /&gt;    // The file may hold more than one number for devices with&lt;br /&gt;    // multiple lines; however we will assume only one line.&lt;br /&gt;    // A valid file needs to be "linear" type and at least 14 bytes.&lt;br /&gt;    if ( S_OK != hr ||&lt;br /&gt;         SIM_RECORDTYPE_LINEAR != simRecordInfo.dwRecordType ||&lt;br /&gt;         simRecordInfo.dwItemCount == 0 ||&lt;br /&gt;         simRecordInfo.dwSize &lt; 14 )&lt;br /&gt;    {&lt;br /&gt;        // no valid 2G file, check the 3G address&lt;br /&gt;        address = EF_MBDN_3G;&lt;br /&gt;        memset(&amp;simRecordInfo, 0, sizeof(simRecordInfo));&lt;br /&gt;        simRecordInfo.cbSize = sizeof(SIMRECORDINFO);&lt;br /&gt;        hr = SimGetRecordInfo(hSim, address, &amp;simRecordInfo);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    if ( S_OK == hr &amp;&amp;&lt;br /&gt;         SIM_RECORDTYPE_LINEAR == simRecordInfo.dwRecordType &amp;&amp;&lt;br /&gt;         simRecordInfo.dwItemCount &gt; 0 &amp;&amp;&lt;br /&gt;         simRecordInfo.dwSize &gt;= 14)&lt;br /&gt;    {&lt;br /&gt;        // allocate the specified size&lt;br /&gt;        LPBYTE buf = (LPBYTE)LocalAlloc(LPTR, simRecordInfo.dwSize);&lt;br /&gt;        DWORD bytesRead = 0;&lt;br /&gt;        &lt;br /&gt;        // read the SIM file&lt;br /&gt;        hr = SimReadRecord(hSim, address, SIM_RECORDTYPE_LINEAR, 1,&lt;br /&gt;                buf, simRecordInfo.dwSize, &amp;bytesRead);&lt;br /&gt;&lt;br /&gt;        if (S_OK ==  hr &amp;&amp; bytesRead &gt;= 14)&lt;br /&gt;        {&lt;br /&gt;            // handle the bytes received&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now that we have the file, we need to interpret the bytes into a useful number. The 3GPP specifications show the EF&lt;sub&gt;MBDN&lt;/sub&gt; structure as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Bytes        Description                                 M/O  Length&lt;br /&gt;----------------------------------------------------------------------&lt;br /&gt;1 to X       Alpha Identifier                             O   X bytes&lt;br /&gt;X+1          Length of BCD number/SSC contents            M   1 byte&lt;br /&gt;X+2          TON and NPI                                  M   1 byte&lt;br /&gt;X+3 to X+12  Dialling Number/SSC contents                 M   10 bytes&lt;br /&gt;X+13         Capability/Configuration2 Record Identifier  M   1 byte&lt;br /&gt;X+14         Extension 6 Record Identifier                M   1 byte&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The first few bytes (1 to X) are the optional identifier. In most cases it will just show the words “voicemail”.  The last 14 bytes describe the voicemail number with up to 10 bytes representing the number as binary coded decimals. For our purpose we can ignore Capability/Configuration2 Record Identifier and Extension 6 Record Identifier. The way to interpret the bytes is described in the 3GPP specifications 31.102 clause 4.4.2.3 for EF&lt;sub&gt;ADN&lt;/sub&gt; (Abbreviated dialing numbers). We can proceed to get the number from the bytes as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;        // use the last 14 bytes&lt;br /&gt;        char data[14];&lt;br /&gt;        memcpy(&amp;data, &amp;buf[bytesRead-14], 14);&lt;br /&gt;&lt;br /&gt;        // byte 0 (X+1) is the length of dialing number&lt;br /&gt;        int length = data[0];&lt;br /&gt;&lt;br /&gt;        std::stringstream ss;&lt;br /&gt;&lt;br /&gt;        // TON and NPI determines the type of number&lt;br /&gt;        // see 3GPP specifications 31.102 clause 4.4.2.3&lt;br /&gt;        if (0x90 == (0xF0 &amp; data[1]))&lt;br /&gt;        {&lt;br /&gt;            // add the + for international numbers&lt;br /&gt;            ss &lt;&lt; '+';&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        // convert the BCD bytes to Ascii chars&lt;br /&gt;        for (int idx=2; idx &lt; length+1; idx++)&lt;br /&gt;        {&lt;br /&gt;            // break the byte into 2 nibbles&lt;br /&gt;            BYTE nibble[2];&lt;br /&gt;            nibble[0] = data[idx] &amp; 0xF;&lt;br /&gt;            nibble[1] = (data[idx] &gt;&gt; 4) &amp; 0xF;&lt;br /&gt;&lt;br /&gt;            for (int i=0; i&lt;2; i++)&lt;br /&gt;            {&lt;br /&gt;                if (nibble[i] == 0xA)&lt;br /&gt;                {&lt;br /&gt;                    // 0xA represents a *&lt;br /&gt;                    ss &lt;&lt; '*';&lt;br /&gt;                }&lt;br /&gt;                else if (nibble[i] == 0xB)&lt;br /&gt;                {&lt;br /&gt;                    // 0xB represents a #&lt;br /&gt;                    ss &lt;&lt; '#';&lt;br /&gt;                }&lt;br /&gt;                else if (nibble[i] &lt; 0xA)&lt;br /&gt;                {&lt;br /&gt;                    // add the number&lt;br /&gt;                    ss &lt;&lt; (char) ('0' + nibble[i]);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        // set the voicemail number&lt;br /&gt;        ss &gt;&gt; number;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now that we have the voicemail number we should free the buffer and sim handle and return the number:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;        // free the buffer&lt;br /&gt;        LocalFree( buf );&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // deinitialize&lt;br /&gt;    SimDeinitialize( hSim );&lt;br /&gt;}&lt;br /&gt;return number;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There are a couple of things to note. Here I’ve handled both the 2G and 3G cases, however it is probably better to detect which type is being used beforehand. Also note that I have assumed the case of only one voicemail number. For a multi-line scenario you would have to check if there are more than one number stored in the SIM file. For a more detailed look on how the numbers are stored please refer to the 3GPP specifications.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35928092-202477328236774508?l=thefiles.macadamian.com%2Findex.html' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/macadamian/thefiles/~4/3bRpe3jnfz4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/202477328236774508/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=35928092&amp;postID=202477328236774508" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/202477328236774508" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/35928092/posts/default/202477328236774508" /><link rel="alternate" type="text/html" href="http://thefiles.macadamian.com/2008/06/obtaining-voicemail-number-on-windows.html" title="Obtaining the voicemail number on Windows Mobile phones" /><author><name>Henry Yi</name><uri>http://www.blogger.com/profile/13165444059632676825</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="14559832009685559804" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry></feed>
