<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' version='2.0'><channel><atom:id>tag:blogger.com,1999:blog-692066067587815234</atom:id><lastBuildDate>Mon, 11 Jan 2010 19:51:56 +0000</lastBuildDate><title>JSpot</title><description>A quiet little corner where I can post my coding issues &lt;br&gt; from blocks of C# code to Javascript oddities and
&lt;br&gt; everything in between.</description><link>http://www.jerryandcheryl.net/jspot/index.php</link><managingEditor>noreply@blogger.com (Jerry Hanel)</managingEditor><generator>Blogger</generator><openSearch:totalResults>13</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-692066067587815234.post-1374042251998606815</guid><pubDate>Tue, 21 Jul 2009 19:08:00 +0000</pubDate><atom:updated>2009-07-22T09:00:06.427-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>VSTO</category><category domain='http://www.blogger.com/atom/ns#'>Outlook</category><category domain='http://www.blogger.com/atom/ns#'>C-Sharp</category><title>VSTO with Outlook 2003</title><description>I'm creating a VSTO plugin for Outlook 2003. My problem? I'm using DevStudio 2008 professional.&lt;br /&gt;&lt;br /&gt;It has a project template for Outlook 2003 add-ins, but be warned. It is far from complete. &lt;br /&gt;&lt;br /&gt;I was able to build my add-in, but distributing it became a nightmare. A royal, amazingly difficult, pain in the gluteus-maximus.&lt;br /&gt;&lt;br /&gt;So, how'd I get it installed? First, I had to make sure that the Visual Studio Tools for Office Runtime was installed on each PC. &lt;br /&gt;&lt;li&gt; You can download that &lt;a href="http://www.microsoft.com/DOWNLOADS/details.aspx?familyid=F5539A90-DC41-4792-8EF8-F4DE62FF1E81&amp;displaylang=en"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Next, I had to make sure that (and THIS is the undocumented part that caused me SERIOUS headache) the Primary Interop Assemblies (PIA) for Office 2003 were installed on each PC.&lt;br /&gt;&lt;li&gt; You can find those &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=3c9a983a-ac14-4125-8ba0-d36d67e0f4ad&amp;displaylang=en"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Next, I had to copy the DLL(s) to the user's hard drive and register each one as able to run. Apparently VSTO (understandably so) has a very very tight security policy. You ahve to register EACH dll that you want to use, and any DLLs that THOSE use. Basically, if you copy it, you register it.&lt;br /&gt;&lt;br /&gt;In order to register the DLL's I used a batch file&lt;br /&gt;&lt;blockquote&gt;&lt;code&gt;&lt;br /&gt;echo Setting Security...&lt;br /&gt;REM Turn off prompting for a minute.&lt;br /&gt;"C:\Windows\Microsoft.NET\Framework\v2.0.50727\caspol.exe" -polchgprompt off&lt;br /&gt;&lt;br /&gt;REM Register each DLL using the FULL PATH to the DLL.&lt;br /&gt;REM Repeat this line for each DLL that you want to register. &lt;br /&gt;REM I used the same [Project Name] and [Description] for each DLL.&lt;br /&gt;"C:\Windows\Microsoft.NET\Framework\v2.0.50727\caspol.exe" -u -ag All_Code -url "[Full Path to DLL]" FullTrust -n "[Project Name]" -d "[Description]"&lt;br /&gt;&lt;br /&gt;REM Turn prompting back on. We're done.&lt;br /&gt;"C:\Windows\Microsoft.NET\Framework\v2.0.50727\caspol.exe" -polchgprompt on&lt;br /&gt;&lt;/code&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;After setting up all of the applications and security, we now have only one thing left to do... tell Outlook where to find it's new add-in. You ahve to do this via Registry settings.&lt;br /&gt;&lt;br /&gt;I put everything into HKEY_LOCAL_MACHINE instead of HKEY_CURRENT_USER. It seemed to work, but some people suggest against this on the forums. I prefer it, so use which ever one suits you best.&lt;br /&gt;&lt;br /&gt;You can find the registry keys to set &lt;a href="http://msdn.microsoft.com/en-us/library/ms269007(VS.80).aspx"&gt;here&lt;/a&gt; at the bottom of that page.&lt;br /&gt;&lt;br /&gt;After *ALL* of this, I was finally able to get my add-in off the ground. I hope this sincerely helps someone else.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/692066067587815234-1374042251998606815?l=www.jerryandcheryl.net%2Fjspot%2Findex.php' alt='' /&gt;&lt;/div&gt;</description><link>http://www.jerryandcheryl.net/jspot/2009/07/vsto-with-outlook-2003.html</link><author>noreply@blogger.com (Jerry Hanel)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-692066067587815234.post-3410685124464519827</guid><pubDate>Fri, 30 Jan 2009 20:10:00 +0000</pubDate><atom:updated>2009-01-30T12:40:10.121-08:00</atom:updated><title>Clean PropertyGrid selectors</title><description>Over the past week, I've been working alot with the PropertyGrid control. These controls are great if you have a bunch of wildly-differing or unknown classes. You can feed the class to the PropertyGrid and it allows the user to directly manipulate the object.&lt;br /&gt;&lt;br /&gt;The drawback, many times the field names or values are not user-friendly. In fact... they can be completely ugly.&lt;br /&gt;&lt;br /&gt;The key is being sure that your classes are PropertyGrid-friendly. Each field should specify some compile-time attributes like the ones below:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;        [&lt;br /&gt;         CategoryAttribute("2 - Bottom"),&lt;br /&gt;         DisplayName("Bottom Diameter"),&lt;br /&gt;         Description("The diameter of the bottom attachment.")&lt;br /&gt;        ]&lt;br /&gt;        public virtual double BottomDiameter {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;               ...&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;However, what happens when you want to edit something that's not a primitive like double or string? &lt;br /&gt;&lt;br /&gt;I had several fields that could take a string as input, but would parse the string and result in a specific object. I've found a very nice, clean, simple solution for this. Before I'd stumbled on this solution, I was using &lt;code&gt;UITypeEditor&lt;/code&gt;. &lt;br /&gt;&lt;br /&gt;First, I would have to identify all of the properties that I want to mangle with this UITypeEditor.&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;    [&lt;br /&gt;     EditorAttribute(typeof(ObjectSelector), typeof(UITypeEditor)),&lt;br /&gt;     DisplayName("The Object List")&lt;br /&gt;    ]&lt;br /&gt;    public SomeObject O&lt;br /&gt;    {&lt;br /&gt;        // ... get, set ...&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;I would create a UITypeEditor that relied on a corresponding form (which was nothing more than a form containing a listbox at 100% width and height.)&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;    class ObjectSelector: UITypeEditor&lt;br /&gt;    {&lt;br /&gt;        IWindowsFormsEditorService editorService = null;&lt;br /&gt;&lt;br /&gt;        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)&lt;br /&gt;        {&lt;br /&gt;            return UITypeEditorEditStyle.DropDown;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)&lt;br /&gt;        {&lt;br /&gt;            // ...&lt;br /&gt;            // Define some variables...&lt;br /&gt;            // ...&lt;br /&gt;&lt;br /&gt;            if (provider != null)&lt;br /&gt;            {&lt;br /&gt;                editorService =&lt;br /&gt;                    provider.GetService(&lt;br /&gt;                    typeof(IWindowsFormsEditorService))&lt;br /&gt;                    as IWindowsFormsEditorService;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            if (editorService != null)&lt;br /&gt;            {&lt;br /&gt;                MyDropdownForm f =&lt;br /&gt;                    new MyDropdownForm(&lt;br /&gt;                    (SomeObjectThing)value,&lt;br /&gt;                    editorService);&lt;br /&gt;&lt;br /&gt;                // Populate the listbox on the form before displaying it.&lt;br /&gt;                f.Populate();&lt;br /&gt;&lt;br /&gt;                editorService.DropDownControl(f);&lt;br /&gt;&lt;br /&gt;                value = f.SelectedObject;&lt;br /&gt;&lt;br /&gt;                if (value == null) return null;&lt;br /&gt;&lt;br /&gt;                // if the two objects are actually the same object, then return.&lt;br /&gt;                if (value.Equals(OldValue) || f. SelectedObject == OldValue) &lt;br /&gt;                {&lt;br /&gt;                    return value;&lt;br /&gt;                } else {&lt;br /&gt;                   // ...&lt;br /&gt;                   // Populate my new object as-needed.&lt;br /&gt;                   // ...&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            return value;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;I would then have to include a form MyDropdownForm:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;    public partial class MyDropdownForm : UserControl&lt;br /&gt;    {&lt;br /&gt;        private IWindowsFormsEditorService editorService = null;&lt;br /&gt;&lt;br /&gt;        public object SelectedObject = null;&lt;br /&gt;&lt;br /&gt;        public MyDropdownForm (&lt;br /&gt;            object CurrentValue,&lt;br /&gt;            IWindowsFormsEditorService EdService)&lt;br /&gt;        {&lt;br /&gt;            InitializeComponent();&lt;br /&gt;&lt;br /&gt;            editorService = EdService;&lt;br /&gt;            SelectedObject = CurrentValue;&lt;br /&gt;&lt;br /&gt;            ObjectList.SelectedIndexChanged += new EventHandler(ObjectList_SelectedIndexChanged);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        void ObjectList_SelectedIndexChanged(object sender, EventArgs e)&lt;br /&gt;        {&lt;br /&gt;            SelectedSObject = SegmentList.SelectedItem;&lt;br /&gt;&lt;br /&gt;            this.editorService.CloseDropDown();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        internal void Populate()&lt;br /&gt;        {&lt;br /&gt;&lt;br /&gt;        // ... you get the idea...&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;This was alot of code. the worst part is, if I wanted to change anything about how it worked, I needed to add two new files to my project. And they were clunky files, at that.&lt;br /&gt;&lt;br /&gt;That is... until I discovered TypeConverter. This simplified things INCREDIBLY. I still had to identify the properties, but the Attribute was much more concise:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;    [&lt;br /&gt;     TypeConverter(typeof(ObjectConverter)),&lt;br /&gt;     DisplayName("The Object List")&lt;br /&gt;    ]&lt;br /&gt;    // NOTE that it is a string. Use the private in the get and set to&lt;br /&gt;    // use the object's StringParse(str) method.&lt;br /&gt;    public string O&lt;br /&gt;    {&lt;br /&gt;        // ... get, set ...&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private SomeObject _o = new SomeObject();&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;The rest just became very easy.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;    internal class SegmentConverter : StringConverter&lt;br /&gt;    {&lt;br /&gt;        public override bool GetStandardValuesSupported&lt;br /&gt;            (ITypeDescriptorContext context)&lt;br /&gt;        {&lt;br /&gt;            //True - Show the Combobox&lt;br /&gt;            //False - Just take/set the string.&lt;br /&gt;            return true;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public override bool GetStandardValuesExclusive&lt;br /&gt;            (ITypeDescriptorContext context)&lt;br /&gt;        {&lt;br /&gt;            //False - Editable&lt;br /&gt;            //True - ReadOnly&lt;br /&gt;            return false;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public override StandardValuesCollection GetStandardValues&lt;br /&gt;            (ITypeDescriptorContext context)&lt;br /&gt;        {&lt;br /&gt;            // Do whatever you have to do here to get your object into a list&lt;br /&gt;            // or array of strings. Luckily, I already had one of those methods&lt;br /&gt;            // in a static Data-Access Object.&lt;br /&gt;            List&lt;string&gt; objNames = daoObject.GetNames();&lt;br /&gt;&lt;br /&gt;            return new StandardValuesCollection(segNames.ToArray());&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;This is MUCH simpler, faster, easier, and more maintainable. I hope this little review helps someone else to build the best PropertyGrid-enabled objects!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/692066067587815234-3410685124464519827?l=www.jerryandcheryl.net%2Fjspot%2Findex.php' alt='' /&gt;&lt;/div&gt;</description><link>http://www.jerryandcheryl.net/jspot/2009/01/clean-propertygrid-selectors.html</link><author>noreply@blogger.com (Jerry Hanel)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-692066067587815234.post-8072889750633973435</guid><pubDate>Wed, 28 Jan 2009 14:14:00 +0000</pubDate><atom:updated>2009-01-28T07:56:46.761-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>C-Sharp</category><title>A lesson in Extension Methods</title><description>With C# 3.0, you were given the ability to extend any object. That's right... if some object objFred has a method that takes two parameters -- string and int -- and you need it to take string and double, you can now "roll your own".&lt;br /&gt;&lt;br /&gt;I needed to do this very thing this week. In my class, I needed to make a call to a system class. But I needed it to return one of the objects I'd created instead of a double or string.&lt;br /&gt;&lt;br /&gt;Yes, I could have just created a method in my own class to handle this, but I wanted to logically keep the method as part of the main library.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;public EngVar ConvertToEng(this string str)&lt;br /&gt;{&lt;br /&gt;    if (String.IsNullOrEmpty(str)) return null;&lt;br /&gt;&lt;br /&gt;    EngVar V = new EngVar();&lt;br /&gt;    try {&lt;br /&gt;        V.Parse(str);&lt;br /&gt;    } &lt;br /&gt;    catch &lt;br /&gt;    {&lt;br /&gt;        return null;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Now, within my code (as long as this is in scope), intellisense has a new method called ConvertToEng() for every string in my project. Could I have just used the Parse(string x) method within my code? Yes. But having it handy within intellisense makes coding much faster. And I've found that, for my mind, having it hang off of 'string' makes much more sense.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;    ...&lt;br /&gt;    &lt;br /&gt;    string MyString = "E15ft/s^2";&lt;br /&gt;    &lt;br /&gt;    ...&lt;br /&gt;    &lt;br /&gt;    EngVar V = MyString.ConvertToEng();&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;This just seems to me to be much cleaner and more logical to read.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/692066067587815234-8072889750633973435?l=www.jerryandcheryl.net%2Fjspot%2Findex.php' alt='' /&gt;&lt;/div&gt;</description><link>http://www.jerryandcheryl.net/jspot/2009/01/lesson-in-extension-methods.html</link><author>noreply@blogger.com (Jerry Hanel)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-692066067587815234.post-2067557467965420512</guid><pubDate>Thu, 22 Jan 2009 22:09:00 +0000</pubDate><atom:updated>2009-01-22T14:23:10.198-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>C-Sharp</category><title>ListView SelectedIndexChanged vs ItemSelectionChanged</title><description>I stumbled upon the most frustrating C# dilemma to-date.&lt;br /&gt;&lt;br /&gt;I was trying to work out a solution to an issue, and -- naturally -- when an item was selected in my list of items, I wanted to do some magic. What would you reach for in this case? The standard SelectedIndexChanged event. That's what we use in Lists, ListBoxes, or even ComboBoxes. That should work in ListViews too... right?&lt;br /&gt;&lt;br /&gt;Wrong. ... sometimes.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;private void SomeList_SelectedIndexChanged(object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;    // Tell me which item in your list just changed... you can't.&lt;br /&gt;    // You only know that SOMETHING changed. Worse than that... for &lt;br /&gt;    // each item that changed, this event fires, but you don't know&lt;br /&gt;    // which one it was &lt;b&gt;nor&lt;/b&gt; if the selection went from selected&lt;br /&gt;    // to unselected or the other way around.&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;The event exists, so you can use it, but the "sender" is the actual ListView object, and the EventArgs does not contain any handle to let you know which item was selected/unselected. When a user un-selects an item from the list (with six or seven more still selected), I needed to know which one they disabled so that I could do some more magic. But without keeping a list of previously-selected items around, I couldn't immediately tell which one was freshly un-selected.&lt;br /&gt;&lt;br /&gt;ENTER: ItemSelectionChanged.&lt;br /&gt;&lt;br /&gt;This is the correct event to be using in these cases. It exists (apparently) only for ListViews. Why the change? I'm not sure. Backward-compatibility, maybe? Who knows!&lt;br /&gt;&lt;br /&gt;The thing that makes this most useful is that it has an event manager that is much more defined. This event manager returns not only which item is changing, but it tells you whether it is changing from selected to unselected (or vice-versa) and which index it is in the overall list. It's a very beautiful thing.&lt;br /&gt;&lt;br /&gt;So the next time you use a ListView control, keep this little gem in your back pocket.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;        private void SomeList_ItemSelectionChanged(object sender,&lt;br /&gt;                         ListViewItemSelectionChangedEventArgs e)&lt;br /&gt;        {&lt;br /&gt;            // Note the ListViewItemSelectionChangedEventArgs item.&lt;br /&gt;            // It is a HUGE name, but very important.&lt;br /&gt;        }&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/692066067587815234-2067557467965420512?l=www.jerryandcheryl.net%2Fjspot%2Findex.php' alt='' /&gt;&lt;/div&gt;</description><link>http://www.jerryandcheryl.net/jspot/2009/01/listview-selectedindexchanged-vs.html</link><author>noreply@blogger.com (Jerry Hanel)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-692066067587815234.post-6877198391113114589</guid><pubDate>Mon, 19 Jan 2009 17:55:00 +0000</pubDate><atom:updated>2009-01-19T11:03:24.193-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>C-Sharp</category><title>Tag-Data Pairs</title><description>Recently, someone asked me if Tag-Data pairs was a good idea. That's kind of like asking if elephants are good ideas: Sure, if you need a tree pushed over. Not so much if you need something that can fit through your front door.&lt;br /&gt;&lt;br /&gt;As with any design question, what parameters are limiting the idea?&lt;br /&gt;&lt;br /&gt;In general, yes... Tag-Data pairs can be a quick human-readable format that handle non-object-data efficiently. But if you need data that is hierarchical or object-oriented (as most data is), then no. If you need something more than a handful of fields, or if you need these fields to be grouped or bundled in a hierarchy, then use XML. There are a ton of tools built into the .NET platform for handling XML data.&lt;br /&gt;&lt;br /&gt;However, in my previous job, XML was much too bloated for their Nazi-style bandwidth usage. They had to pay per byte of transfer, so each character transferred was precious. In those cases, we actually did use tag-data pairs.&lt;br /&gt;&lt;br /&gt;It was quick, lightweight, simple and human-readable. The most annoying part of a TDP packet was that the data inside was not incredibly easy to get at. For example, if you needed to know the person's last name, you had to parse the TDPs into pairs, then loop through to find the tag that matched "LastName".&lt;br /&gt;&lt;br /&gt;In order to fix this, we needed a lightweight solution that would convert the TDP strings into something more usable... and back again once the values were modified.&lt;br /&gt;&lt;br /&gt;Enter the TDP class. In the end, the implementation of it was almost brainless, but the elegance was in its simplicity.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;public class TDP : Hashtable&lt;br /&gt;{&lt;br /&gt;    public string Sep1 { get; set; }&lt;br /&gt;    public string Sep2 { get; set; }&lt;br /&gt;&lt;br /&gt;    public TDP()&lt;br /&gt;    {&lt;br /&gt;        Sep1 = "=";&lt;br /&gt;        Sep2 = "|";&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public TDP (string initialString)&lt;br /&gt;    {&lt;br /&gt;        Sep1 = "=";&lt;br /&gt;        Sep2 = "|";&lt;br /&gt;        Parse (initialString);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public string ParseString&lt;br /&gt;    {&lt;br /&gt;        get&lt;br /&gt;        {&lt;br /&gt;            return ConvertToString();&lt;br /&gt;        }&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            Parse(value);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private void Parse(string value)&lt;br /&gt;    {&lt;br /&gt;        this.Clear();&lt;br /&gt;        string[] Pairs = value.Split(Sep2.ToCharArray());&lt;br /&gt;&lt;br /&gt;        foreach (string pair in Pairs)&lt;br /&gt;        {&lt;br /&gt;            string[] arr = pair.Split(Sep1.ToCharArray());&lt;br /&gt;            this.Add(arr[0], arr[1]);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private string ConvertToString()&lt;br /&gt;    {&lt;br /&gt;        StringBuilder sb = new StringBuilder();&lt;br /&gt;&lt;br /&gt;        foreach (string key in this.Keys)&lt;br /&gt;        {&lt;br /&gt;            sb.Append(key + Sep1 + this[key].ToString() + Sep2);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        return sb.ToString();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public override string ToString()&lt;br /&gt;    {&lt;br /&gt;        return ParseString;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Managing the data became nearly trivial:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;class Program&lt;br /&gt;{&lt;br /&gt;    static void Main(string[] args)&lt;br /&gt;    {&lt;br /&gt;        TDP tdp = new TDP();&lt;br /&gt;&lt;br /&gt;        tdp.ParseString = "Cheryl=Beautiful wife|Jerry=Cheryl's Husband|Time=3:00pm|";&lt;br /&gt;&lt;br /&gt;        Console.WriteLine(tdp["Jerry"]);&lt;br /&gt;&lt;br /&gt;        tdp["Jerry"] = "Awesome programmer";&lt;br /&gt;        tdp["New tag"] = "Some new tag";&lt;br /&gt;&lt;br /&gt;        Console.WriteLine(tdp.ToString());&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/692066067587815234-6877198391113114589?l=www.jerryandcheryl.net%2Fjspot%2Findex.php' alt='' /&gt;&lt;/div&gt;</description><link>http://www.jerryandcheryl.net/jspot/2009/01/tag-data-pairs.html</link><author>noreply@blogger.com (Jerry Hanel)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-692066067587815234.post-8508787166821346848</guid><pubDate>Sat, 17 Jan 2009 19:47:00 +0000</pubDate><atom:updated>2009-01-18T14:05:43.438-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>C-Sharp</category><title>Securing the code with 'License'</title><description>Recently, I've decided to lock down some of the code at work. We've had a problem with some of our code walking out the door without our permission.&lt;br /&gt;&lt;br /&gt;I'm not pointing fingers, but hey... we've gotta stop it from happening. Right? In the end, we need to make sure that our software checks a license file to make sure it has the rights to run.&lt;br /&gt;&lt;br /&gt;Enter System.ComponentModel.License. This is a .NET structure for building your own licensing model.  Within this setup, you can "validate" your license however you want to. My license "calls home" to make sure that it has permission to run. Or, you can check a license file on the PC. Or make the user enter a password. You can even have the thing look for a registry entry. Hey. It's up to you.&lt;br /&gt;&lt;br /&gt;Let me show you a quick example of a license library that I've created that will require a flat file on the PC with the words "All Good". If this file exists, the license is good to go.&lt;br /&gt;&lt;br /&gt;I know this particular example is not secure, but I wanted to keep it simple for the sake of example. In order to pull this off, we need to first create two classes that we'll use later.&lt;br /&gt;&lt;H3&gt;MyLicense&lt;/h3&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;    public class MyLicense : License&lt;br /&gt;    {&lt;br /&gt;        private Type type;&lt;br /&gt;&lt;br /&gt;        public MyLicense(Type type)&lt;br /&gt;        {&lt;br /&gt;            // use this to get the GUID... which we will use as the LicenseKey.&lt;br /&gt;            this.type = type;&lt;br /&gt;&lt;br /&gt;           string txt = File.ReadAllText("c:\\myLicense.lic");&lt;br /&gt;           if (txt != "All Good")&lt;br /&gt;           {&lt;br /&gt;               throw new LicenseException("Unable to validate license");&lt;br /&gt;           }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public override string LicenseKey&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                // Simply return the application's GUID&lt;br /&gt;                return type.GUID.ToString();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        // Required.&lt;br /&gt;        public override void Dispose() { }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;H3&gt;MyLicenseProvider&lt;/h3&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;    public class MyLicenseProvider : LicenseProvider&lt;br /&gt;    {&lt;br /&gt;        public override License GetLicense(LicenseContext context, Type type,&lt;br /&gt;            object instance, bool allowExceptions)&lt;br /&gt;        {&lt;br /&gt;            // I want to catch any file errors and throw a license error instead.&lt;br /&gt;            try&lt;br /&gt;            {&lt;br /&gt;                // Use this flag to license the runtime of your code from the &lt;br /&gt;                // development of your code.&lt;br /&gt;                if (context.UsageMode == LicenseUsageMode.Runtime)&lt;br /&gt;                {&lt;br /&gt;                    MyLicense L = new MyLicense(type);&lt;br /&gt;                    return (License)L;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            catch (Exception ex)&lt;br /&gt;            {&lt;br /&gt;                throw new LicenseException(type, instance, ex.Message);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            return null;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;With these two classes, we can now lock down our code with our simple license file. Note: The License model from Microsoft requires that it be applied to a class, not a program or static object.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Our Program&lt;/h3&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;    [LicenseProvider(typeof(MyLicenseProvider))]&lt;br /&gt;    public class MyClass&lt;br /&gt;    {&lt;br /&gt;        License Lic;&lt;br /&gt;&lt;br /&gt;        void MyClass()&lt;br /&gt;        {&lt;br /&gt;            // The very first thing we're going to do is see if we &lt;br /&gt;            // have permission to be here.&lt;br /&gt;            Lic = LicenseManager.Validate(typeof(MyClass), this);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Now, we've got the base code. But what does it do? When you create an instance of "MyClass" to be used in your code, it -- of course -- runs the constructor. The first line of the constructor is :&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;Lic = LicenseManager.Validate(typeof(MyClass), this);&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Thanks to the pre-processor line of LicenseProvider, it knows which class to call: MyLicenseProvider. Since MyLicenseProvider is a type of LicenseProvider, the License engine in .NET knows that GetLicense exists, so it gets called, which calls an instance of "MyLicense". &lt;br /&gt;&lt;br /&gt;NOW we get to the good stuff. Inside this license library, you can do ANYTHING. However you want to validate your license is up to you. I'm going to simply open a file, if it even exists, and see if it has the right string in it. If so, we're golden. &lt;br /&gt;&lt;br /&gt;However, if the license process should fail or return null for any reason, the LicenseManager from the constructor in our class will throw a LicenseException and the whole thing will come to a screeching halt.&lt;br /&gt;&lt;br /&gt;Nice, isn't it?&lt;br /&gt;&lt;br /&gt;And now, you know the basics for locking down your code. How you choose to handle these basics for doing more in securing your code is up to you.&lt;br /&gt;&lt;br /&gt;P.S. And for you developers... keep in mind that you can require a development license SEPARATE from your run-time license, giving you the ability to make money from your work without the fear of it growing legs and breeding like roaches in the cesspool of internet piracy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/692066067587815234-8508787166821346848?l=www.jerryandcheryl.net%2Fjspot%2Findex.php' alt='' /&gt;&lt;/div&gt;</description><link>http://www.jerryandcheryl.net/jspot/2009/01/securing-code-with-license.html</link><author>noreply@blogger.com (Jerry Hanel)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-692066067587815234.post-4752716544514533974</guid><pubDate>Thu, 15 Jan 2009 16:23:00 +0000</pubDate><atom:updated>2009-01-15T08:51:52.469-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>JavaScript</category><category domain='http://www.blogger.com/atom/ns#'>PHP</category><category domain='http://www.blogger.com/atom/ns#'>HTML</category><title>HTML Cache Problem</title><description>I was working on the web site this morning, and I noticed a typo. "No problem!" I tell myself. I'll just hop on over and fix it. So I did.&lt;br /&gt;&lt;br /&gt;I then went back to check my newly-corrected word. I wanted to see the work of my sheer genius. Okay... I know it's a single spelling correction, but it's the little things that make me happy. The problem was, it was still wrong.&lt;br /&gt;&lt;br /&gt;Then it dawned on me... my browser was wrong. The website it self was right, but I was looking at a cached version. And all of you loyal readers out there would be seeing that typo all the time if you've been here before. My reputation would be ruined. Well... almost.&lt;br /&gt;&lt;br /&gt;But being the perfectionist that I am, I still had to fix it. It is a simple fix, really. All I needed to do was add a line of meta data to my HTML page. If you have a server-side application -- such as a PHP page -- that needs to re-generate its information, or if you have JavaScript that updates frequently thanks to other services, you can use PRAGMA:NO-CACHE.&lt;br /&gt;&lt;br /&gt;While this is not a 100% shot that the browser still won't cache your page, most of the popular borwsers (IE, Firefox, Safari, etc) obey the PRAGMA:NO-CACHE convention.&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE"&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Just add that as the first line of your file and you're done. Oh, right... that is for HTML1.0 specification. What about HTML1.1? Well, there's the curve ball. An HTML1.1 site should use CACHE-CONTROL instead of PRAGMA. &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE"&amp;gt;&lt;br /&gt;&amp;lt;META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE"&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Why? Who knows. Some geek in the world convinced another set of geeks somewhere that the name PRAGMA made no sense, so CACHE-CONTROL was adopted as the new standard. For safety and just to be sure, I usually add both of the tags to my site so that I know it will always load the latest version of my page. &lt;br /&gt;&lt;br /&gt;Yes, I'm adding more work to my web server. Yes, I could use "EXPIRES" instead. But the amount I'm adding at this point is negligible, so I'm okay with that. I'll save EXPIRES for a future article. At least people will get the typo-corrected versions of the articles.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/692066067587815234-4752716544514533974?l=www.jerryandcheryl.net%2Fjspot%2Findex.php' alt='' /&gt;&lt;/div&gt;</description><link>http://www.jerryandcheryl.net/jspot/2009/01/html-cache-problem.html</link><author>noreply@blogger.com (Jerry Hanel)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-692066067587815234.post-6556863252634022352</guid><pubDate>Wed, 14 Jan 2009 14:00:00 +0000</pubDate><atom:updated>2009-01-14T06:00:02.189-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>C-Sharp</category><title>Command Line Parsing</title><description>I recently had a case where I needed to handle a series of command line arguments. I needed to know if flagA had been set with flagB, but not with flagC and flagD.&lt;br /&gt;&lt;br /&gt;Ripping through the list of command line arguments is easy enough, but tedious, so I wrote my own CommandLine class that lets me reference flags by name. For instance, if I need to check to see if flagA exists, I can just say cmd.ContainsKey("flagA"). &lt;br /&gt;&lt;br /&gt;The best part is that it only modified my master source by one line:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;CMD cmd = new CMD(args);&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;I thought that this little ditty -- while being trivial in concept -- was worth sharing. If you find it useful, let me know. Also, if you have comments, feel free to post them.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;    public class CMD : Hashtable&lt;br /&gt;    {&lt;br /&gt;        public CMD(string[] args)&lt;br /&gt;        {&lt;br /&gt;            if (args == null) return;&lt;br /&gt;&lt;br /&gt;            for (int x = 0; x &lt; args.Length; x++)&lt;br /&gt;            {&lt;br /&gt;                if (args[x].StartsWith("-") || args[x].StartsWith("/"))&lt;br /&gt;                {&lt;br /&gt;                    // take off the "-"&lt;br /&gt;                    string key = ((string)args[x]).Substring(1);&lt;br /&gt;&lt;br /&gt;                    // We have a flag. Is it a TF or a value flag?&lt;br /&gt;                    if ((x &lt; args.Length - 1) &amp;&amp; (!args[x + 1].StartsWith("-")))&lt;br /&gt;                    {&lt;br /&gt;                        // VALUE flag                        &lt;br /&gt;                        this[key] = args[x + 1];&lt;br /&gt;                        x++;&lt;br /&gt;                    }&lt;br /&gt;                    else&lt;br /&gt;                    {&lt;br /&gt;                        // True/False flag&lt;br /&gt;                        this[key] = true;&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Once you've defined the class, accessing the command line arguments becomes trivial. In the example below, I have a simple console application that needs command line parsing. Once CMD is initialized, I can access CMD from anywhere, and access all of my command line parameters by name.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;    class Program&lt;br /&gt;    {&lt;br /&gt;        static CMD cmd;&lt;br /&gt;&lt;br /&gt;        static void Main(string[] args)&lt;br /&gt;        {&lt;br /&gt;            cmd = new CMD(args);&lt;br /&gt;&lt;br /&gt;            // Do some magic stuff here&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/692066067587815234-6556863252634022352?l=www.jerryandcheryl.net%2Fjspot%2Findex.php' alt='' /&gt;&lt;/div&gt;</description><link>http://www.jerryandcheryl.net/jspot/2009/01/command-line-parsing.html</link><author>noreply@blogger.com (Jerry Hanel)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-692066067587815234.post-6335223603599888943</guid><pubDate>Tue, 13 Jan 2009 16:00:00 +0000</pubDate><atom:updated>2009-01-13T08:33:52.024-08:00</atom:updated><title>Virtual vs. Abstract</title><description>So, I know I'm going back to Object Oriented 101, but I've forgotten how powerful certain keywords can actually be. That is, until recently.&lt;br /&gt;&lt;br /&gt;I was asked to build a product that would be flexible enough to kiss it's own behind, but easy enough to maintain that non-programmer-types could mangle out a few lines of code to keep extending this. (i.e. engineers).&lt;br /&gt;&lt;br /&gt;Yeah. That's what everyone wants, right? And the general answer is usually "and people in hell want water." But this time, I think I've actually found a solution to one of their issues.&lt;br /&gt;&lt;br /&gt;Enter "VIRTUAL". It's a subtle change, but one that's Oh-so-important in this case.&lt;br /&gt;&lt;br /&gt;Let's say we have an object called circle. That object has a method called GetRadius(). GetRadius does exactly what it sounds like. It returns the distance from the center of the circle to the edge.&lt;br /&gt;&lt;br /&gt;Now, if we create a new object that inherits circle, let's call this one doughnut...mmmmmmmmm.... doughnuts... the term GetRadius becomes a bit more tricky. Are we talking about the inner circle or the outer circle? Lets say that we want it to be the difference between the two.&lt;br /&gt;&lt;br /&gt;So, how do circles apply to the issue of kissing your own behind? Let me show you.&lt;br /&gt;&lt;br /&gt;Library 1 contains our first object; Circle.&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;public class Circle&lt;br /&gt;{&lt;br /&gt;   public double diameter { get; set; }&lt;br /&gt;&lt;br /&gt;   public Circle (double OuterD)&lt;br /&gt;   {&lt;br /&gt;      diameter = OuterD;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public virtual double GetRadius_Virtual()&lt;br /&gt;   {&lt;br /&gt;      return diamter / 2;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public abstract double GetRadius_Abstract()&lt;br /&gt;   {&lt;br /&gt;      return diameter / 2;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class CircleCollection : List&amp;lt;Circle&amp;gt;&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Now, if we want to extend this library by creating new DLLs that inherit the Circle class, we can still add them to CircleCollection because they are, in fact, a type of circle. So if someone creates a new DLL called Doughnut, we might have:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;public class Doughnut : Circle&lt;br /&gt;{&lt;br /&gt;    public double innerDiameter { get; set; }&lt;br /&gt;&lt;br /&gt;    public Doughnut (double OuterD, double InnerD)&lt;br /&gt;    {&lt;br /&gt;        diameter = OuterD;&lt;br /&gt;        innerDiameter = InnerD;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public override double GetRadius_Virtual()&lt;br /&gt;    {&lt;br /&gt;        return (diameter - innerDiameter) / 2;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public override double GetRaidus_Abstract()&lt;br /&gt;    {&lt;br /&gt;        return (diameter - innerDiameter) / 2;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Since DOughnut is a type of Circle, we can add it to the previously-defined CircleCollection class with no problem.&lt;br /&gt;&lt;br /&gt;But let's take a look at the results of the numbers. We've defined doughnut the same, whether it is abstract or virtual, but the numbers will be different depending on HOW we ask the program to reference the object... as a Circle or as a Doughnut.&lt;br /&gt;&lt;br /&gt;When I loop through all of the elements in my CircleCollection, as Circles, we get some interesting results. Let's loop through a few and get the radius. First well get it by Virtual, then we'll get it again by abstract.&lt;br /&gt;&lt;br /&gt;&lt;Blockquote&gt;&lt;pre&gt;&lt;br /&gt;CircleCollection C = new CircleCollection();&lt;br /&gt;&lt;br /&gt;C.Add(new Doughnut(10,8));&lt;br /&gt;C.Add(new Doughnut(9:5));&lt;br /&gt;C.Add(new Circle(10));&lt;br /&gt;C.Add(new Circle(9));&lt;br /&gt;&lt;br /&gt;foreach (Circle circ in C)&lt;br /&gt;{&lt;br /&gt;   Console.WriteLine(circ.GetRadius_Virtual() + ":" + circ.GetRadius_Abstract());&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;You would think the answer for the left number would be the same as the right, but they are different for doughnuts. The Virtual will always be whatever the deepest answer in the tree is. In this case, doughnut was the deepest in the heirarchy. &lt;br /&gt;&lt;br /&gt;However, the abstract version will always be the answer from the requested type, in this case Circle (note: foreach circle...).&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;Output:&lt;br /&gt;1:5   &lt;--- doughnut&lt;br /&gt;2:4.5 &lt;--- doughnut&lt;br /&gt;5:5   &lt;--- Circle&lt;br /&gt;4.5:4.5 &lt;- Circle&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;The first number for each of the "doughnut" objects used the code within the doughnut class, while the second number used the code within the circle class. THAT's the difference between Abstract and Virtual.&lt;br /&gt;&lt;br /&gt;So, back to the engineers. As long as they inherit their new objects from my base type, all my libraries (which use "virtual") can reference the items in the collection by their base type.&lt;br /&gt;&lt;br /&gt;Since all of my base types are collections of other types (i.e. EngineeringObjectCollection) I can loop through my collections as I normally do. If they have created their own types and override the functionality of one of my methods, then I'll use their code. If not, I'll use mine. No extra coding on my part is required. No messy reflection. No fuss, no muss.&lt;br /&gt;&lt;br /&gt;And just like that, the code can now kiss it's own behind... well, provided the engineers can access the "clsBehind" object with the prgObject.Kiss() method. But you get the idea.&lt;br /&gt;&lt;br /&gt;Now, all this talk about doughnuts has made me hungry.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/692066067587815234-6335223603599888943?l=www.jerryandcheryl.net%2Fjspot%2Findex.php' alt='' /&gt;&lt;/div&gt;</description><link>http://www.jerryandcheryl.net/jspot/2009/01/virtual-vs-abstract.html</link><author>noreply@blogger.com (Jerry Hanel)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-692066067587815234.post-858061785073302328</guid><pubDate>Mon, 12 Jan 2009 15:14:00 +0000</pubDate><atom:updated>2009-01-12T07:14:00.568-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>JavaScript</category><title>Javascript getElementsById()</title><description>Okay... I know the moment I post this, I'm going to get a million messages that an ID is supposed to be unique to the page, thus there should never be more than one. Thus, "Get Element&lt;b&gt;S&lt;/b&gt; By Id" is a misnomer. There is no such thing. You can only "Get ELEMENT By Id."&lt;br /&gt;&lt;br /&gt;In a perfect world, you would be absolutely correct. But JavaScript is far from perfect, especially when you add in cross-browser dependencies.&lt;br /&gt;&lt;br /&gt;I ended up with a control that generated HTML for me, which was very nice. Unfortunately (as I always tend to do) I wanted to fiddle with the output to make it just like I wanted it. Change a font here. An alignment there. Add some text to the top of each block. Set a margin. Put some padding on it so it doesn't blend into other text... you know. The usual stuff.&lt;br /&gt;&lt;br /&gt;I could have solved most of this with CSS, but I needed to add some javascript (one line per block) to manage some of the data in it. *IF* I could get a handle to each DIV, I could assign a proper ID to it so that it would be unique, thus I could reference it later with a simpler JavaScript function.&lt;br /&gt;&lt;br /&gt;But the code that was generated didn't give me any clean way of deciphering its DIVs from any other DIV in the form. The code that was generated looked similar to the following:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;DIV ID='Block'&amp;gt;&lt;br /&gt;   &amp;lt;DIV ID=INNER&amp;gt;Do some nifty stuff in block 1.&amp;lt;/DIV&amp;gt;&lt;br /&gt;&amp;lt;/DIV&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;Now this isn't the extent of it, but you get the idea for the purposes of this demonstration. The important part here is that I don't have a name. All I have is an ID. And Javascript doesn't allow for document.getElementsById(...)&lt;br /&gt;&lt;br /&gt;So I wrote my own.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;function getElementsById(id)&lt;br /&gt;{&lt;br /&gt;   var divs = document.getElementsByTagName("div");&lt;br /&gt;   var arr = new Array();&lt;br /&gt;   &lt;br /&gt;   for (var i=0; i &amp;lt; divs.length; i++)&lt;br /&gt;   {&lt;br /&gt;      if (divs[i].id == id)&lt;br /&gt;      {&lt;br /&gt;         arr[arr.length] = divs[i];&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   return arr;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;This gave me exactly what I was looking for, works well in both IE and FireFox (I haven't tried Opera or Safari. Sorry.) and I could then loop through the returned elements and assign a proper "ID" to it so that it would fit into the nice perfect world that we've all come to expect and love.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/692066067587815234-858061785073302328?l=www.jerryandcheryl.net%2Fjspot%2Findex.php' alt='' /&gt;&lt;/div&gt;</description><link>http://www.jerryandcheryl.net/jspot/2009/01/javascript-getelementsbyid.html</link><author>noreply@blogger.com (Jerry Hanel)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-692066067587815234.post-5010928787008525247</guid><pubDate>Sat, 10 Jan 2009 16:00:00 +0000</pubDate><atom:updated>2009-01-10T08:00:01.128-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>C-Sharp</category><title>More File Permissions</title><description>In doing more research with file permissions, I've found that MS shares file permissions and directory permissions. (if you dig into the enums enough, you'll see duplicate values for multiple enum settings)&lt;br /&gt;&lt;br /&gt;I thought this was odd until I realized why. The FileSystemRights enum contains values for both FILES and DIRECTORIES. So, ListDirectory for directory access is the same flag as ReadData for file access.&lt;br /&gt;&lt;br /&gt;This may seem trivial until you want to list the contents of a directory, but not actually allow a person to view the file... which is exactly what my boss asked me to do. &lt;br /&gt;&lt;br /&gt;"Easy!" I said as I jumped to my desk. Until I discovered that -- for reasons unknown to me -- we must use file inheritance. &lt;br /&gt;&lt;br /&gt;So when the file inherits "ListDirectory" from it's containing folder... it is, in fact, inheriting the "ReadData" flag for the file.&lt;br /&gt;&lt;br /&gt;In short: If you use file inheritance, and you specify ListDirectory, you cannot make the file ReadOnly without going to the file and explicitly denying ReadData for a user. (UGH!)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/692066067587815234-5010928787008525247?l=www.jerryandcheryl.net%2Fjspot%2Findex.php' alt='' /&gt;&lt;/div&gt;</description><link>http://www.jerryandcheryl.net/jspot/2009/01/more-file-permissions.html</link><author>noreply@blogger.com (Jerry Hanel)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-692066067587815234.post-4299105174511120254</guid><pubDate>Fri, 09 Jan 2009 16:55:00 +0000</pubDate><atom:updated>2009-01-09T16:09:45.090-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>C-Sharp</category><title>Rounding errors...</title><description>This week, my life has been plagued with rounding errors. I have a library that converts to/from different units of measure. This  library is used within several objects with the idea to store distances in memory all in meters. Then, if the user wants to see that measurement in feet, or inches, or miles, or kilometers... you get the idea.&lt;br /&gt;&lt;br /&gt;Here's my problem... Some calculations need to be done in feet. Others in inches. With this nice, neat, creative library, this should be EASY... right?&lt;br /&gt;&lt;br /&gt;I couldn't have been more wrong.&lt;br /&gt;&lt;br /&gt;The library uses the following units for conversion from meters to feet and inches. Keep in mind that I'm keeping all units in meters in memory.&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;double ft = meter / 0.3048;&lt;br /&gt;double inch = meter / .0254;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;To keep it in meters in memory, when the user inputs a number, I have to convert that number from its respective distance into meters. I use the following conversions for that.&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;// if given inches&lt;br /&gt;double meter = inch * 0.0254;&lt;br /&gt;&lt;br /&gt;// if given feet&lt;br /&gt;double meter = ft * 0.3048;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Since it's divide for one, and multiply to put it back, it should come out the same... right? WRONG! &lt;br /&gt;&lt;br /&gt;Take a look at an input of 220 feet:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;// Store the value in memory...&lt;br /&gt;double meter = Convert.ToMeter(220); // 67.056&lt;br /&gt;&lt;br /&gt;// convert that back into "feet" for display.&lt;br /&gt;double ft = Convert.ToFeet(meter); // 219.99999999999997&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;That's right. 67.056 / 0.3048 rounds to 219.9999999... NOT 220. Keep in mind that 67.056 isn't a rounded number itself. That's the actual, complete number for 220 * 0.3048.&lt;br /&gt;&lt;br /&gt;In my calculations, I then tried to say "if (Feet entered by user) == (Feet previously entered by user) then go do some stuff" and it never would. &lt;br /&gt;&lt;br /&gt;Here's the magic bullet for this issue: First, determine how many significant digits you care about. For most of my calculations, 8 digits is absolute overkill. So, for cases like this, I will use 8 as my cutoff.&lt;br /&gt;&lt;br /&gt;My conversion class now has a property called "SignificantDigits" that defaults to 8. Inside my conversion routines, before I return the value, I round the value to the significant digits. So far, that's been working very well for me.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;// Forcibly round to 8 significant digits to prevent arbitrary rounding errors.&lt;br /&gt;double ft = Math.Round(meter / 0.3048, SignificantDigits);&lt;br /&gt;double inch = Math.Round(meter / .0254, SignificantDigits);&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;For those needing a very accurate number, you'll have to set the significant digits count so high that this approach will not be feasible. But for the average Joe making the average calculations, this is a quick fix.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/692066067587815234-4299105174511120254?l=www.jerryandcheryl.net%2Fjspot%2Findex.php' alt='' /&gt;&lt;/div&gt;</description><link>http://www.jerryandcheryl.net/jspot/2009/01/rounding-errors.html</link><author>noreply@blogger.com (Jerry Hanel)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-692066067587815234.post-4788873066393226364</guid><pubDate>Thu, 08 Jan 2009 16:50:00 +0000</pubDate><atom:updated>2009-01-09T16:10:01.320-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>C-Sharp</category><title>C# File/Directory Permissions</title><description>Today's code problem comes from my real-world experience. I was working on an app to help manage file-rights here at my job. &lt;br /&gt;&lt;br /&gt;The frustrating part was that it looked so simple. The default code from Microsoft shows that this is almost trivial:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;// Get the directory security object.&lt;br /&gt;DirectorySecurity dSecurity = Directory.GetAccessControl(dirName);&lt;br /&gt;&lt;br /&gt;// change the rights on the object.&lt;br /&gt;dSecurity.AddAccessRule(new FileSystemAccessRule(account, &lt;br /&gt;    rights, controlType));&lt;br /&gt;&lt;br /&gt;// Set the new access settings.&lt;br /&gt;Directory.SetAccessControl(dirName, dSecurity);&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;But when you do it this way, you can no longer see the checkmarks in the default security tab. You have to go into "Advanced" to see your permissions. &lt;br /&gt;&lt;br /&gt;Why?&lt;br /&gt;&lt;br /&gt;Because doing it this way sets all of your permissions as "special" permissions, not any of the default standard permissions. Note that your file permissions &lt;b&gt;are set properly.&lt;/b&gt; The rights really are set. You just can't see the nice little check marks in windows.&lt;br /&gt;&lt;br /&gt;I did some research to set the ACE (Access Control Entry) so that the checkmarks would re-appear, and found the following snippet of code:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;dSecurity.AddAccessRule(new FileSystemAccessRule(&lt;br /&gt;                            IdentityReference, FileSystemRights, &lt;br /&gt;                            InheritanceFlags.ContainerInherit |&lt;br /&gt;                            InheritanceFlags.ObjectInherit, &lt;br /&gt;                            PropagationFlags.None,&lt;br /&gt;                            AccessControlType));&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;So if I just do this after I set the new security the magic little checkboxes will reappear, right? YES! They did. But then all of the checkboxes for all OTHER users of that file or directory went away!!!&lt;br /&gt;&lt;br /&gt;(*sigh*)&lt;br /&gt;&lt;br /&gt;So, after doing some research, testing and playing, I've found a hack that will re-set the nice little checkboxes in the security tab. It's ugly. It's painful. But it works.... mostly. (more on that in just a second.)&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;DirectorySecurity dSecurity = Directory.GetAccessControl(dirName);&lt;br /&gt;&lt;br /&gt;// change the rights on the object.&lt;br /&gt;dSecurity.AddAccessRule(new FileSystemAccessRule(account, &lt;br /&gt;    rights, controlType));&lt;br /&gt;&lt;br /&gt;// Call my Bug-Fix routine&lt;br /&gt;MSBugFix(dSecurity);&lt;br /&gt;&lt;br /&gt;// Set the new access settings.&lt;br /&gt;Directory.SetAccessControl(dirName, dSecurity);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;private void MSBugFix(DirectorySecurity dSecurity)&lt;br /&gt;{&lt;br /&gt;    // RESET EVERYONE'S ACE So that it will view properly &lt;br /&gt;    // in the Security tab. (MS BUG FIX!!)&lt;br /&gt;    AuthorizationRuleCollection acl = dSecurity.GetAccessRules(&lt;br /&gt;        true, true,  typeof(System.Security.Principal.NTAccount));&lt;br /&gt;&lt;br /&gt;    foreach (FileSystemAccessRule ace in acl)&lt;br /&gt;    {&lt;br /&gt;            dSecurity.AddAccessRule(new FileSystemAccessRule(&lt;br /&gt;                ace.IdentityReference, ace.FileSystemRights, &lt;br /&gt;                InheritanceFlags.ContainerInherit | &lt;br /&gt;                InheritanceFlags.ObjectInherit, &lt;br /&gt;                PropagationFlags.None, ace.AccessControlType));&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;This works, but can be a bit slower if you have many files to do. Gee... I wonder why? Oh.. right. The nasty ALL USERS loop in there. But it does work.... until you install Service Patch 3 on the machine. &lt;br /&gt;&lt;br /&gt;When you install Service Pack 3, the nice little checkboxes go away again. Note that your permissions and access to the files remain. You can still get to your files, you just have to go to "Advanced" to see the actual settings on your files.&lt;br /&gt;&lt;br /&gt;If anyone has an actual fix for this issue, (not the ugly hack I had to develop) I would love to hear it. Until then, we just won't be installing SP3.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/692066067587815234-4788873066393226364?l=www.jerryandcheryl.net%2Fjspot%2Findex.php' alt='' /&gt;&lt;/div&gt;</description><link>http://www.jerryandcheryl.net/jspot/2009/01/c-filedirectory-permissions.html</link><author>noreply@blogger.com (Jerry Hanel)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item></channel></rss>