Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

Thursday, May 28, 2009

TomTom sucks for customisation.

I recently emailed TomTom technical support stating that I was a software developer (and TomTom owner) interested in writing software for the TomTom device. I wanted to know where to get the SDK that they did have available up to about 1 year ago but now seems to have disappeared. This was their response:

Dear Mr Clark,

Thank you for your query. Your incident reference number is 090526-001861.

Unfortunately the Software Development Kit is no longer available from TomTom.

Please note that we are unable to offer any technical support for 3rd party add ons or software tools used in conjunction with your TomTom device.

Best Regards,

David A

TomTom Customer Support

Damn that sucks. What is with companies that want to keep you locked down to the software they make on a device that you own. They don’t even sell the navcore, they make nothing from it – they sell the hardware and the maps! It should only increase the value of the device and maps if there is more software available, and the cost to them of releasing their SDK would be minimal. Pretty short sighted if you ask me.

There are lots of little software projects that are now dead in the water due to the lack of an SDK for the latest version.

Tuesday, May 26, 2009

How to make images look disabled (greyed out) when the Button or MenuItem they are within is disabled in WPF

By default in WPF image controls that are within disabled menus and buttons will not be greyed out. One common way to achieve a standard look is to apply a style to the image that will cause it to be partially transparent when its parent is disabled. You create a style with TargetType of Image that is a Setter for the Opacity property with a Style.Trigger bound to the IsEnabled property of the image's parent (via RelativeSource). (Code later...) I made two triggers initially, as some of my Images are in Buttons and some are in MenuItems.

Just looking at my output window, I noticed a whole bunch of errors when the UI was coming up, some like this:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 
'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.MenuItem', 
AncestorLevel='1''. BindingExpression:Path=IsEnabled; DataItem=null; target 
element is 'Image' (Name=''); target property is 'NoTarget' (type 'Object')

And others like this:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 
'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.Button', 
AncestorLevel='1''. BindingExpression:Path=IsEnabled; DataItem=null; target 
element is 'Image' (Name=''); target property is 'NoTarget' (type 'Object') 

Thinking about it for a second, you can see that both of the style triggers will get applied to each image. For each image one will work and one will fail - there can only be one type for the parent element, Button or MenuItem not both. It is a silent failure so could just be lived with but I wanted to fix it.

First I was trying to find a way to choose which trigger to apply depending on the type of the parent*. I know you could remove the TargetType from the style and apply it as a named style to each element, but that just becomes a mess. The whole idea of this solution is to make at as simple to use as possible - basically just letting it modify the behaviour of all images. The real solution of course is to realise that the IsEnabled property is not a member of Button nor MenuItem directly, but it is on the UIElement class.

The fix then is to have only one Style.Trigger with the AncestorType of UIElement:

<Style TargetType="{x:Type Image}">
    <Style.Triggers>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type UIElement}, AncestorLevel=1}, Path=IsEnabled}" Value="False">
            <Setter Property="Opacity" Value="0.3"></Setter>
        </DataTrigger>
    </Style.Triggers>
</Style> 

* I would still like to know how to do this, but that will have to wait until another time when I really do need to do it. No time!

Programmatically changing TreeViewItem IsSelected fails to set IsFocused

I was having an odd problem with the IsSelected property of TreeViewItems. After adding an item and setting its IsSelected property, the originally selected item is no longer selectable.

I am using the Model-View-ViewModel pattern and a HierarchicalDataTemplate to bind a TreeView. The ItemsSource is an ObservableCollection. I noticed that when I added a new item to the collection (making it IsExpanded and IsSelected) it was added fine and was selected, but the parent item was no longer selectable. Any other item in the TreeView was selectable, and if you select one then the parent was again selectable, but right after the Add on the collection it was broken.

Seems to be a known problem: the IsFocused property is not updated when you change IsSelected via code. I am a little surprised that it is also not kept up to date when you set it via a binding… but I guess in the end binding is just code that you didn’t have to write yourself. Hopefully someone, somewhere will decide that this is indeed a bug so I can remove the event handler that I have put in place as a workaround*

Sample reproduction code:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1;assembly="
    Title="Window1" Height="300" Width="300">
    <Window.CommandBindings>
        <CommandBinding Command="{x:Static local:Window1.AddChildItem}" 
                            CanExecute="AddChildItem_CanExecute"
                            Executed="AddChildItem_Executed" />
    </Window.CommandBindings>
    <Window.Resources>
        <HierarchicalDataTemplate DataType="{x:Type local:Item}"
                                  ItemsSource="{Binding Children}">
            <TextBlock>
                <TextBlock Text="Name -> " />
                <TextBlock Text="{Binding ItemName}" />
                <TextBox></TextBox>
            </TextBlock>
        </HierarchicalDataTemplate>
        <Style TargetType="{x:Type TreeViewItem}">
            <!-- property bindings -->
            <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
            <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
            <!-- Workaround: Keep the IsFocused property up to date when the IsSelected property changes -->
            <EventSetter Event="Selected" Handler="TreeViewItem_Selected" />
        </Style>
    </Window.Resources>
    <DockPanel LastChildFill="True">
        <ToolBarTray DockPanel.Dock="Top" Height="21">
            <ToolBar>
                <Button Command="{x:Static local:Window1.AddChildItem}">
                    <TextBlock Text="Add" />
                </Button>
            </ToolBar>
        </ToolBarTray>
        <TreeView Name="tv1" ItemsSource="{Binding Items}">
        </TreeView>
    </DockPanel>
</Window>

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;
 
namespace WpfApplication1 {
    public partial class Window1 : Window {
        private ObservableCollection<Item> _items = new ObservableCollection<Item>();
        public ObservableCollection<Item> Items {
            get { return _items; }
        }
 
        public static readonly RoutedCommand AddChildItem = new RoutedCommand("AddChildItem", typeof(Window1));
 
        public Window1() {
            InitializeComponent();
 
            _items.Add(new Item { ItemName = "One" });
            _items.Add(new Item { ItemName = "Two" });
            _items.Add(new Item { ItemName = "Three" });
 
            this.DataContext = this;
        }
 
        private void AddChildItem_CanExecute(object sender, CanExecuteRoutedEventArgs e) {
            if(tv1 != null && tv1.SelectedItem != null) {
                e.CanExecute = true;
            }
        }
 
        private void AddChildItem_Executed(object sender, ExecutedRoutedEventArgs e) {
            if(tv1.SelectedItem != null) {
                (tv1.SelectedItem as Item).AddChildItem();
            }
        }
 
        // Without this event handler you will see the problem
        private void TreeViewItem_Selected(object sender, RoutedEventArgs e){
            TreeViewItem tvi = e.OriginalSource as TreeViewItem;
            if(tvi != null && !tvi.IsFocused) {
                tvi.Focus();
            }
        }
    }
 
    public class Item : INotifyPropertyChanged {
        private string _itemName = "New Item";
        public string ItemName {
            get { return _itemName; }
            set { _itemName = value; }
        }
        private ObservableCollection<Item> _children = new ObservableCollection<Item>();
        public ObservableCollection<Item> Children {
            get { return _children; }
        }
        private Item _parent = null;
        public Item Parent {
            get { return _parent; }
        }
 
        public Item() : this(null) { }
        public Item(Item parent) {
            _parent = parent;
        }
 
        public void AddChildItem() {
            Item i = new Item(this);
            _children.Add(i);
            i.IsSelected = true;
        }
 
        private bool _isSelected;
        public bool IsSelected {
            get { return _isSelected; }
            set {
                if(_isSelected != value) {
                    _isSelected = value;
                    OnPropertyChanged("IsSelected");
                }
            }
        }
 
        private bool _isExpanded = true;
        public bool IsExpanded {
            get { return _isExpanded; }
            set {
                if(_isExpanded != value) {
                    _isExpanded = value;
                    if(_isExpanded && _parent != null) {
                        _parent.IsExpanded = true;
                    }
                    OnPropertyChanged("IsExpanded");
                }
            }
        }
 
        #region INotifyPropertyChanged Members
 
        public event PropertyChangedEventHandler PropertyChanged;
 
        #endregion
 
        protected virtual void OnPropertyChanged(string propertyName) {
            if(this.PropertyChanged != null) {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

Just Comment out the call to Focus to see the problem.

Of note also is the fact that you must set IsSelected after the new item is inserted into the visual tree. For me that meant a small refactor (seen in the example in AddChildItem) to create the item, add it to the collection then set its IsSelected property rather than creating it with IsSelected already set to true. Otherwise it seems that the call to Focus fails.


* I.e. my code was all nice and separated, I was not handling any TreeView or TreeViewItem events, it was all done with smoke and mirrors** in a layer between the UI and the BO

** Data binding

Wednesday, April 08, 2009

Page.IsAsync broken on ASP.Net MVC

I was just trying to add a condition to my validation code so it would not run when the page was asynchronously posted (my controls were getting highlighted as an error before the user has even had the chance to enter any values because of some ajax that was updating another area of the page), but I found that the Page.IsAsync member is always false.

I managed to find another member that you can access via the ScriptManager:

ScriptManager.GetCurrent(Page).IsInAsyncPostBack

Which seems to work.

Wednesday, March 18, 2009

TextChanged event of TextBox not raised by the Internet Explorer AutoComplete feature

As noted in this msdn article, The TextChanged event of a TextBox control may not fire if the AutoComplete feature is enabled in Internet Explorer. And it appears to be “by design” – I hate that.

Fortunately, it is pretty easy to add some JavaScript to make the ‘right thing’ happen.

All you need to do is raise the onchange event at the appropriate time. For me that is when the TextBox loses focus. As I am doing this from code behind (as usual) I am registering a client script, then when I add the TextBox I set its onblur attribute accordingly:

Page.ClientScript.RegisterClientScriptBlock(typeof(FormPage), "RaiseOnChange", "function RaiseOnChange(ctrl){ctrl.fireEvent('onchange');}", true);
tb.Attributes[HtmlAttributes.OnBlur] = string.Format("RaiseOnChange({0})", tb.UniqueID);

The server side TextChanged event only gets raised if the TextBox.Value has really changed. I needed to do this because I am using the TextChanged event of some TextBox controls to trigger an asyncpostback to update an UpdatePanel. The code that sets the content of the UpdatePanel is in the server side TextChanged handler.

Friday, March 13, 2009

Quoted strings

I posted something about this once before, but having just given myself a headache trying to fix something similar once again I feel like writing some more.

Using the quote delimiter character inside of a quoted string at always a minor problem. There are two ways you can fix it – you can escape the quote using whatever method is valid at the time* or you can change the type of quote delimiter, i.e. you can switch from " to ' or vice-versa. There is a deeper problem though that is only really seen when you are not just embedding a delimiter in a string, but (as seems to be often the case with web development) when you are passing such a string to someone or something else. Say for example you are writing ASP.Net code behind to output a __doPostback where one of the arguments is a string with an embedded delimiter. The string in .Net code will be delimited (say with ") then the argument to __doPostback will also be delimited (say with ') but then the data in that string might contain ' (e.g. O'Neil) which will have to be escaped.

My exact situation this time was slightly more complicated still – I have three levels of indirection! I am in c# code behind, setting the .Text property on a Telerik DataGridItem to be an html anchor tag which will do a postback. So the .Net string is delimited (with " naturally), the onclick of the a tag is delimited (with " also by convention, so escaped for .Net as \"), the argument to the __doPostback function is delimited (with ' because there is no way of escaping nested " characters for html) and finally the data in that argument might have ' characters so it needs to be escaped (by \')! And certain parts need to be UrlEncoded also, but before you put in the \' escaping or else you will UrlEncode the \ character. *Hum*

item[colName].Text = string.Format("<a href=\"#\" onclick=\"__doPostBack('', '{1}{0}{2}')\">{3}</a>", QueryString.PostBackArgSep, postbackType, item[colName].Text.Replace("'", "\\'"), item[colName].Text);

* Mmm, yes. Whatever method is valid at the time. This is not always straight forward with some situations calling for \ to give \' or \", some for a doubling up of the offending character giving '' or "", or even for escaping to be impossible in the current context, leaving you with only the ability to switch delimiters. This last problem with why I try to stick with " as the delimiter most of the time and escaping where required rather than the simpler change to ' so as to save the other character for situations where it is the only method (e.g. html). I think that it is probably possible to get yourself into a situation where there is no possible way to pass the string ‘down the line’ as it were without breaking something. If that happens either you need to encode and decode the whole string somewhere, or admit that you are doing something the hard way and find the right way to do it… I almost think that is what is going on here with my current problem – I think it could be solved by keeping the information that I am passing through to __doPostback somewhere else and just passing a key to it to the code I am calling, but I don’t have the time to do that right now, and this form will be soon superseded by an ASP.Net MVC version.

Tuesday, March 03, 2009

Telerik RadUploadProgressHandler and ASP.NET MVC

Just ran into a small problem with the Telerik radUpload control and ASP.NET MVC.

The upload progress needs to have a httpHandler and httpModule configured in Web.config for it to work correctly – I think it is that which handles the GUID that it tacks onto the end of the url to maintain state (among other things). The path is normally Telerik.RadUploadProgressHandler.ashx but with MVC this will be routed to a controller and the handler will not be found.

I have added an exclusion to my Global.asax.cs file and it seems to work.

routes.IgnoreRoute("Telerik.RadUploadProgressHandler.ashx/{*pathInfo}");

Remains to be seen if this is the right way to do it or if there is anything else wrong, but for now I am just trying to get two existing web applications merged together as one MVC application. A lot of the stuff that those apps are doing is not “correct” from a MVC point of view, but this is version 0.9 :)


[Edit] Meh. Don’t need to do that. There are instructions on the Telerik site for how to configure the httpHandler for RadUpload under ASP.NET MVC

Tuesday, February 24, 2009

Call a method on an object only when that object is not null

I have often wanted an operator or something that will do something like run a method on an object if that object is not null (returning a default value if it is null). An example:

string s = SomeClass.SomeMember.ToString(); 

maybe for output or something. Now this works just fine, unless SomeMember happens to be null, when this code will throw an exception. So the code has to become:

string s = SomeClass.SomeMember != null ? SomeClass.SomeMember.ToString() : ""; 

or something like that. Upon finding the ?? ‘null coalescing operator’ I thought that would do the trick, but that will only munge the ToString (say) return value to "" if it was null, not let you call members on a null reference. You could do something with a chain of ?? operators, but that looks nasty and if anything in the chain is actually a method call rather than a property access then it may be called multiple times…

I think that I have come up with something neat and simple that works.

public static TResult Try<T, TResult>(this T left, Func<T, TResult> func) { 
    return Try(left, func, default(TResult)); 
} 
 
public static TResult Try<T, TResult>(this T left, Func<T, TResult> func, TResult defaultValue) { 
    if(left != null) { 
        return func(left); 
    } else { 
        return defaultValue; 
    } 
} 

Which can be used like this:

string s = SomeClass.SomeMember.Try(m => m.ToString(), ""); 

I named it Try in reference to functions such as TryParse. Perhaps not the best choice of name, but I am pretty phenomenally bad a choosing names for things… If you use it on a null reference you will get back the default value you specify or if you don't specify one you get the default value of type of the lambda expression. This second case (not specifying the default explicitly) is more useful when the type is not nullable... It is useful for calling functions on members of a class that might be null. More than that of course though, as that is a lambda (well actually a Func<T, TResult> Generic Delegate which is most easily populated with a lambda) you can pretty much do whatever you like in there.

Now I understand that this is not for everybody and that it is not going to work in all situations. Sometimes a null return value will not always have the same meaning as the default value for that type, but if you keep this in mind to does clean up a lot of code.

Another example to illustrate:

public class DataObject { 
    public List<string> Strings; 
} 
 
DataObject myDataObject = new DataObject(); 
// int stringCount = myDataObject.Strings.Count; // *boom!*
int stringCount = myDataObject.Strings.Try(l => l.Count); 

So this does not give you all of the same information that you get from receiving the null value, but it makes some common stuff painless, like telling the user how many strings there are. I find myself hiding the null value a lot of the time anyway, converting it to "" or 0 or whatever, so there you go.

Real world ‘improvement’. This:

object obj = ExecuteScript(script);
if(obj != null) {
    return obj.ToString();
} else {
    return "";
}
Becomes this:
return ExecuteScript(script).Try(o => o.ToString(), "");

Incidentally, I really love how well the type inference works now. There is no need to specify the types when calling the function - like myDataObject.Strings.Try<string, int>(l => l.Count) - and the return type gets updated when you add or change the return type of the lambda expression. Very neat.

Sunday, February 22, 2009

Bad Xml – to accept or to reject, that is the question.

Was just reading this post which touches on accepting invalid Xml communications. And I agree.

I think it boils down to “make sure you produce good XML, but accept anything with the proviso that there may be odd behaviour if the format is not correct”. Library wise though, permissive reading is fine, but if your library produces bad XML you deserve to be stamped out. I have to say that the Microsoft Xml stuff is really pretty good. They are an option 1 library though, so don’t expect to be able to read in any old just, but they will not produce invalid Xml*.

This is the route that I have gone with all of the stuff that I have been doing lately. It is a little more complicated than that though because the data structure that I am using is created from the DTD** so I need to not only accept invalid XML but convert it into valid XML to store it.


* This is something that I have had to explain a few times… Sometimes is is difficult, sometimes people understand. Mostly I don’t bother complaining too much about receiving nasty Xml, but forcing myself to produce bad Xml because someone’s hand coded parser reacts badly to something valid in my valid Xml (namespace definition).

** Funny story. It’s their DTD, but they can’t manage to produce Xml that validates against it, and they expect values for certain elements that are not valid under it (value="" when value is an NMTOKEN). Chuckle…

Friday, February 20, 2009

Unfun things

Programmers tend to loathe writing documentation. I always have great documentation in mind while I am developing a nice solution to a problem, but it rarely gets realised. Usually the bare minimum gets done – sometimes less than that.

Another thing that is probably number two on the list of most not fun to do is error handling and logging.

I have just spent a little time cleaning up the error handling in the couple of applications that I am writing right now.

There are various components, running across various platforms – Windows and Web clients, .NET Remoting servers, Windows services, Web services, ASP.NET web sites (that are actually generated from specifications in xml files that are in turn created by a tool – one of the windows client applications). Anyway, the whole thing is getting a little too complex to hold in your head at once, and before it gets too complicated I wanted to put in a common logging component. I have wanted to do it for a while – get away from each component knowing how to ends an email or write the windows log. Now it is mostly done.

I guess the whole point of this ramble was just to say that I got myself to do something pretty unpleasant – fix up exception handling chains, move chunks of code around while deciding which of 3 similar implementations are correct, fix up dll referencing issues, test error conditions – by giving myself something a little but fun to do – write a nice class using generics to build and hold an error message (so a message can be build up as different components have more or less important problems), grow the re-usable library that I have and actually re-use it.

Wednesday, February 18, 2009

Remote debugging

Yesterday I had quite a bit of fun trying to get remote debugging of a web application working.

I did solve this problem a little (very short) while ago… but I forgot what I had done.

So after executing a couple (quite a few) iterations of a Modify, Compile, Deploy, TryToDebug, Uninstall loop I know what you have to do to get it working. At least if you are using a deployment project to put the files up on the server.

You have to add the debug output from any project that you want to debug into to the deployment project*.

You must make sure that those debug outputs are in the right directory in the File System configuration pane so that the TargetName will have the files going into the correct directory on the server**.

Then you can install and debug. The setup of the remote debugger is a bit complex too. Basically the way I got it to work was by adding my own domain user (I log into my machine by logging into the domain) to the Administrators group on the server, and then logged in (via mstsc /console) to the server as myself (so that user could reconnect back to my machine). Bingo.


* You can’t just copy them up to the server it seems. I don’t know what the difference is, but it just does not manage to find them. I have even tried loading the symbols from the modules window directly – if complains that the symbols are not for the same version of the dll. I have not seen what happens if you are not actually deploying with an msi – there could be trouble. It is just one of those cases where there is some mechanism there that is storing some information somewhere and when it works everything is rosy, but when it does not work it can be fairly opaque. I guess that is what comes from not technically knowing what you are doing, but we can’t all be experts on the internal workings of everything – there is just not time, and when most of the time it just automagically works there is not much point either.

** The target name for the debug output of some project types (e.g. ASP.Net Web Application) will be bin/AssemblyName.pdb so the output needs to be placed in the Web Application Folder (where they seem to go by default), whereas other types (e.g. Class Library) will just be AssemblyName.pdb so their output needs to be put into the bin folder – they won’t be there by default, they will be one level up in the Web Application Folder. If you do not get this right the debug symbols will fail to load. You can look at information about what is being loaded from where in the Modules window found in Debug > Windows > Modules when you are in debug mode.

Monday, February 16, 2009

Security.dll

I was getting a funky error when trying to call one of my WCF web service’s methods:

Unable to find an entry point named 'FreeCredentialsHandle' in DLL 'security.Dll'.

Fortunately my brain is working this morning and I remembered the last time I saw this kind of odd error. Looking in the bin directory of the web site, sure enough I see a dll called security.dll. Ruhroh… IIS kindly loads up any dlls that you ask it to, then when it tries to access the Microsoft Security.dll it seems to find your dll and routes calls into it. These entry points (normally) don’t exist hence the error.

The moral of the story is: Do not call your dll security.dll*.

I just went through the whole project and made sure that the outputs were called something useful like Company.Project.Thing.dll. You do need to restart the web server too so it will reload the (correct) Security.dll.


* Other bad names are probably things like System.dll, mscorlib.dll etc. A much better idea is to create a proper namespace for your code and make the assembly name something like the namespace – or even the whole namespace, why not? Knock yourself out.

Sunday, February 15, 2009

Reuse types in a Web Service

For some time I have trying, with no success, to get the Reuse types in referenced assemblies option to work after adding a web service reference to a project.

Finally I have found the answer: That option is not available for so called ‘legacy’ ASP.NET web services, only for WCF web services. So I just re-created my web service as a WCF service. My web service is a pretty simple one providing access to a .NET Remoting server hosted in a windows service. As such the code is pretty simple, and it was a matter of less than an hour to get it all going.

Just one small gotcha that I guess should be pretty obvious. The assembly with the types that you want to re-use must already be referenced in the project that you are adding the service reference to. I.e. it does not go and look for them. I don’t suppose it would have any way of doing that.

The only modification that I had to do was to the web service. It seems to work. I am a little surprised that I did not have to add the DataContractAttribute to the classes to use them… They are already marked Serializable and the members are XmlElements… perhaps that is why it works. I have not really tested it yet, just compiled the service and the client. I am thinking now that perhaps the data is not being passed at all. Will see tomorrow – when I am supposed to be working (rather than now, the weekend).


[Edit] I does work just fine. I wonder then what is the difference between using DataContract and just making them Serializable. I also wonder what is the benefit of using the ClientFactory rather than just using the Client object directly.


[Edit] There are, it seems, times when you do need to add the DataContractAttribute to your data classes. I just found that one class that I was using as a parameter caused an exception upon serialization:

There was an error while trying to serialize parameter http://tempuri.org/:Commands. The InnerException message was 'Type 'BSPG.Prism.Script.Table' with data contract name 'Table:http://schemas.datacontract.org/2004/07/BSPG.Prism.Script' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'.  Please see InnerException for more details.

This class contains members whose type is also not a standard class. The class that was working only had members of standard types. Fortunately, it seems to work if you just decorate the top level class with the DataContractAttribute – no need to go and change each other class in there (this would have been quite a pain for me, as they are all generated classes). That said, it might turn out that it only works because after the first level they are all standard types… That is not necessarily true for all possible data though – this is a class hierarchy created by XSDObjectGen from a quite deeply nested DOM… We will see.

Wednesday, February 11, 2009

AdSense JScript error

I don’t know wether it is just IE7 or what but I do seem to be getting a lot of JScript runtime errors on lots of different sites… I have opened a few in the debugger and found them to be, for the most part strangely, coming from within jQuery…

Now the AdSense stuff on this blog has started to have an error:

The bit where it barfs is:

<script>tick('1ad')</script>

with:

Object expected

so meh, not finding the tick function. I have not changed anything, but I am beginning to wonder if it is not something that I have done to this machine. Perhaps I am just paranoid, but I do seem pretty capable of some kind of voodoo against windows installations…


[Edit] S’not just me - there are some posts on the AdSense Help forum (which has a JScript error, haha) about this already (Recent Javascript Errors in Ads, Javascript errors, JavaScript error <script>tick('1ad')</script>) but no response from Google so far...


[Edit] Silently fixed by Google. I did not keep a copy of the offending source file from this morning, but looking at the same file generated just now, they seem to have totally removed the call to tick. That function by the way ends up injected into your main page and seems to be for storing timestamps for certain actions like the first load, the first time the page is scrolled, the load time of each ad etc.) Poor form really… perhaps an explanation will surface soon.

Tuesday, February 10, 2009

SQLServer 2005

Having failed to install SQLServer 2008 – don’t ask, I grabbed the 2005 dvd and ‘installed’ it… But the server setup could not find any of the client msi files. I looked at the directory structure on the disk and where they used to have Server and Client directories, there are now Server and Tools. I am not sure if that is the problem but I went into the Tools directory and ran the setup there. It got some way through its install, but still could not find the msi for the native client, and the ‘workstation, books online and development tools’ installer would not run. So I went spelunking in the \Tools\Setup directory and ran a few msi files by hand and now it seems to be happy.

Yay, I have my SQL Server Management Studio!

The msi installers that actually managed to do something were: \Tools\Setup\sqlncli.msi and \Tools\Setup\SqlRun_Tools.msi though there may be other stuff missing… we will see.

TortoiseSVN right drag

I did not know this: http://tortoisesvn.net/most-forgotten-feature

SVN global ignore pattern

I have just been fiddling with my global ignore pattern so I thought I would post it here (more for my future self than anything else). This modification was triggered by my having fun trying to use the same repo from two different machines where the directory structure is not identical, so the *.suo files and *.user files can cause problems. I also noticed that there were a few other odd files in the repo that I don’t really want.

[Bb]in [Oo]bj Debug Release *.suo *.user _UpgradeReport_Files UpgradeLog.XML RECYCLER Thumbs.db Desktop.ini

So a little explanation:

  • [Bb]in [Oo]bj – directories containing build files generated by studio, seems like older versions of studio create the files in all lowercase where 2008 has an initial cap and as SVN is case sensitive you unfortunately need to deal with both
  • Debug Release – directories created when building a deployment project
  • *.suo *.user – user project setting and general studio user settings files
  • _UpgradeReport_Files_ – directory containing log files and stuff created when you migrate a project from an older version of studio
  • UpgradeLog.XML – the main project migration report file
  • RECYCLER – not sure if this is still needed, but I was finding this directory sometimes gets created, I guess it is for storing deleted files… was just searching for it in the repo local copy but could not find it, oh well
  • Thumbs.db Desktop.ini – files created when you do certain things in explorer, like look at a directory of images in thumbnail view

Sunday, February 08, 2009

WLW Plug-in

I just finished working on a Windows Live Writer plug-in to allow insertion of snippets. You can define templates for snippets that you can then insert into the current document from the Insert list. The snippets can be anything basically, but I will be using it to insert HTML snippets of the right format to make error message blocks, command line blocks, basically all of the little bits of mark-up that I want to re-use all of the time.

To create a new template you access the options dialog via Tools > Options > Plug-ins where you select the Snippet plug-in and click Options.

You can insert the currently selected text or the clipboard contents into the template by specifying #content# or #clipboard# somewhere in the template. You can also take the content or the clipboard if the content is blank with #contentorclipboard# or the reverse with #clipboardorcontent#.

There is no documentation (other than the info here), no installer (you just need to copy the dll file to C:\Program Files\Windows Live\Writer\Plugins), and not too many features. So hopefully not too many bugs. There are a few things that I would like to work on: A context menu to select the #content# things; Pretty up the interface a bit; Add a different mode that can ask for user input to fill in the template; An installer.

I created a Google Code project for this one too, it is wlwsnippetplugin. I think that I have put the source up properly in the SVN repository… Regardless, the source is zipped there too, as is the SnippetPlugin.dll file that you can just grab and copy to the right directory.

Enjoy!

Friday, February 06, 2009

Erm… ForEach

Why did I not see this before? I was pretty sure that I looked for a ForEach function before I went off looking for Map etc… but bugger me if there isn’t an extension method on IEnumerable(Of T) that does just exactly what I want.

It’s even called ForEach!

List<thing> myList = new List<thing>();
myList.ForEach(item => item.DoSomething());

[Edit] Okay, I feel a little better now… I know why I didn’t see it before - ForEach is defined on List(Of T) and not, unfortunately, on IEnumerable(Of T) which is where I was looking for it. Perhaps next week in a spare moment I might get to try my hand at writing it.

Select method problems…

An issue that I have run into using Select as Map HOF.

The Select function is only evaluated when the returned Enumerable(Of T) is evaluated. That means that the code that I posted (which I did not test until now…) does not really do anything. I guess that means that the foreach method is probably the way to go for calling a function for each item in a list.

Thinking about this, and re-reading some information about the Map function, I come to the realisation that it is perhaps my understanding of what Map is supposed to do that is incorrect. It does say that map is for transforming the items. Perhaps what I want is another, slightly different HOF that is for operating on a list of items, i.e. calling a function for each of them, rather than for building a second list. Oh I don’t know, I will keep looking.