Skip to content

2005

IE compatibility

Quirksmode is a very useful site regarding javascript and css compatibility across browsers. Using the snippet regarding mouse coordinates, both of the pages mentioned in the last two posts now work in IE as well.

Trigonometry and Javascript

Had some fun this weekend playing with Javascript, trying draw dynamic lines. Since Javascript doesn't actually have any kind of Draw() or Paint() methods, it comes down to manipulating images. I originally started by scaling images of lines, but even after adding a bunch of variations of lines for different lengths and angles, it always looked damn ugly.

Finally I decided to go the traditional line drawing way: One pixel at a time. Well, almost.. i have tiny segments with lovely alpha blurred edges and created them in horizontal, vertical and the two diagonal variations. And i create dashed lines from them, calculating points along the line.

The current state of this experiment can be found here. (Note: This does not work in IE right now. Really only because i didn't put in the alternate code for finding the mouse coordinates, so i'll fix that in time).

Next, time to play with XmlHttp and generate finalized line segments on the fly and place them, as well as save the information so you can recall the paths drawn. Then, I'll look into emulating the google maps code for panning the background around and bringing in offscreen content on the fly.

Atomic file replacement

A traditional way for overwriting a file atomically is to write the new file to temp file, and then use move to replace the original with the new. That way the replacement is atomic and no script that relies on the file existing and being complete will ever fail.

File.Move() in .NET is not the tool for this job. It'll throw an IOException because the destination exists, and there isn't an alternative way of calling it. You can delete the destination first, but then anyone relying on the file existing is screwed. Worse, someone might still try to re-create the file.

However, File.Copy(), does have an alternative overload that let's specify a bool to determine overwriting behavior. This way, the file will always exist, although someone could try to read it in an inconsistent state. And it's an ugly solution if the file is large. Grrrr...

Any better solutions out there?

Emacs, Nxml-Mode and Unicode

I've run into this too many times and fixed just as many.. grr. And i always forget.. Time to write it down.

I use James Clark's excellent nxml-mode to edit pretty much anything that's vaguely XML, i.e. i usually convert HTML i have to edit into XHTML so i can use this mode.

Problem is, if you just start writing XML in that mode, the resulting file will be Unicode encoded. There is a fix to this. Write proper XML :) Basically, first add this to your .emacs file:

(unify-8859-on-decoding-mode)

Next, make sure you got your proper XML header:

<?xml version="1.0" encoding="utf-8"?>

Tada! File is saved in proper form.

Just to be all proper and stuff, I use this header for my html/xhtmlL

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">

Asynchronous Postback in Web Applications

So a while back I read an an article about the Client Callback Feature in ASP.NET 2.0, which allows ASP.NET 2.0 to do updates to a page without a full page rountrip to the server. But wouldn't you know it, it was specific to Internet Explorer. The article ended on a hopeful note with:

Please note that not every browser supports client callbacks, so two new boolean properties named SupportsCallback and SupportsXmlHttp were added to the Request.Browser object. Currently, both properties will return the same value, but the two properties were created because client callbacks might be implemented using a different technique other than the XMLHTTP ActiveX object in the future.

2.0 is still not out, but cross-browser support using XMLHttpRequest is certainly possible to anyone wanting to roll their own code. A very nice example of this can be found here.

ASP.NET 2.0 isn't out yet. So i figured, i might as well see if the stance for Client Callbacks and cross-browser support has changed since that first article. Info was only vague, but i think the answer is indeed maybe? -- at least if this blog post is favorably interpreted... Although this blog did not interpret it as such...

If it's not in there, I'm sure going to find out how hard it would be to subclass the appropriate classes to create a W3C XMLHttpRequest capable version

Tweaking ContextMenu's for List Items

A little System.Windows.Forms diversion. One thing that's ill-documented, imho, is the CheckedListBox. And if you then want to add a context menu that's context sensitive to the Item in the list you are over, then good luck finding any useful info. Therefore, I figured i put this snippet in here before I forget again how do deal with this.

The best example I found for handling ContextMenu in the context of a list item recommended completely ignoring the ContextMenu property on the listbox and handling it all in the MouseDown event--creating the context menu on the fly and all.

That seemed a little overkill to me since all i wanted to to do was disable the one item Edit on the context menu. So, instead i capture the Popup event and tweak my menu there. First the setup of the context menu (in my constructor):

ContextMenu contextMenu = new ContextMenu();
MenuItem edit = new MenuItem("Edit");
contextMenu .MenuItems.Add(edit);
edit.Click += new EventHandler(edit_Click);
contextMenu .Popup +=new EventHandler(contextMenu _Popup);
checkedListBox.ContextMenu = contextMenu;

And here's the popup handler:

private void contextMenu_Popup(object sender, EventArgs e)
{
    //don't forget to translate the mouse coordinates to the control local coordinates
    int index = checkedListBox.IndexFromPoint(checkedListBox.PointToClient(MousePosition));
    if( index == -1 || !checkedListBox.GetItemChecked(index) )
    {
        ((ContextMenu)sender).MenuItems[0].Enabled = false;
    }
    else
    {
        ((ContextMenu)sender).MenuItems[0].Enabled = true;
        //storing the index in a class field so that i don't have to
        //do the math again and in case the mouse moved
        contextSelection = index;
    }
}

So there you have it.

An exercise in overcomplication

Ok, there really isn't a need for doing this, but since i'm already stuck on creating compact language independent binary representations, here's a quick struct with an int, a fixed sized string and a variable data field that implements a quick and dirty serialization to go along with it

/// <summary>
/// Example of completely manual serialization of a struct containing a  fixed
/// sized string and a variable sized data block
/// </summary>
struct FixedStringAndVariableData
{
    // the fixed size of the valueString
    const int VALUE_SIZE = 10;
    Int32 id;
    string valueString;
    byte[] data;

    public int Id
    {
        get { return id; }
        set { id = value; }
    }

    public int ValueSize
    {
        get { return VALUE_SIZE; }
    }

    public string Value
    {
        get
        {
            if( valueString == null )
            {
                valueString = "".PadRight(10,' ');
            }
            return valueString;
        }
        set
        {
            if( value == null )
            {
                valueString = "".PadRight(10,' ');
            }
            else if( value.Length < 10 )
            {
                valueString = value.PadRight(10,' ');
            }
            else if( value.Length > 10 )
            {
                valueString = value.Substring(0,10);
            }
        }
    }

    public byte[] Data
    {
        get { return data; }
        set { data = value; }
    }

    public FixedStringAndVariableData(byte[] pRaw)
    {
        id = BitConverter.ToInt32(pRaw,0);
        Int32 offset =  Marshal.SizeOf(id.GetType());
        valueString = Encoding.ASCII.GetString(pRaw,offset,VALUE_SIZE);
        offset += VALUE_SIZE;
        Int32 remainder = pRaw.Length - offset;
        data = new byte[remainder];
        for(int i=0;i<remainder;i++)
        {
            data[i] = pRaw[offset+i];
        }
    }

    public byte[] Serialize()
    {
        Int32 size = Marshal.SizeOf(id.GetType())+VALUE_SIZE+data.Length;
        IntPtr pnt = Marshal.AllocHGlobal(size);
        byte[] serialized = new byte[size];
        int position = 0;
        byte[] buffer = BitConverter.GetBytes(id);
        buffer.CopyTo(serialized,position);
        position += buffer.Length;
        buffer = Encoding.ASCII.GetBytes(this.Value);
        buffer.CopyTo(serialized,position);
        position += buffer.Length;
        data.CopyTo(serialized,position);
        return serialized;
    }
}

Ok, i'll get off this subject now :)

Fixed arrays in structs

Figured out that the good old C

struct foo
{
  int many[10];
}

does not work in C#. Best description of workarounds I found are on Eric Gunnerson blog here. Ho hum. Of course, it's a problem of limited application, i.e. dealing with legacy binary data or sending binary packets across the net. Now i know.

When casting is not enough

Dealing with raw bytes coming across the network has given me plenty of opportunity to figure out how to convert data from one type to another. As previously noted, the good old C method of memcpy'ing bytes into structs takes a bit more work in C#, but is reasonable enough for having the benefit of a GC.

However, when it comes to just taking 4 bytes and turning them into an Int32, i certainly didn't want to jump throuhg those hoops. And you don't have to. Between the static classes of Convert, BitConverter and Encoding.ASCII you can pretty much get any type into any other. This particular case it calls for:

int i = 123456789;
byte[] b = BitConverter.GetBytes(i);
int j = BitConverter.ToInt32(b,0);

I wonder if behind the scenes BitConverter does the whole pinning down of memory game or just does byte arithmetic.

Now, how to define fixed sized strings in structs... I mean i could just create a sub-struct that creates individual slots for each byte it can contain, but that seems as little cumbersome.