Blog Home  Home RSS 2.0 Atom 1.0 CDF  
Hairy Spider Blog - c-sharp
A web of intrigue
 
 Tuesday, February 28, 2006
Well it's not all that difficult.

I've just created something that will enable one to view and edit any scripts that are loaded in the browser.



In essence all you need to do is to create a class library and include a reference to the DOMHelper dll. Then you just need to create a usercontrol. Design the control as usual and when you come to work on the code element make the class inherit the bho.csseditor.Plugin class.


The first method you'll want to override is the Activate method this will be called when a new document is loaded and when the tab is made visible. The title property will be what's displayed in the tab and there's a property on the base object called ParentFrame from which you can get a reference to the mshtml.WebBrowser and mshtml.Document objects.

Once you are happy about life and your coding, then you can import your shiny new plugin into the DOMHelper. To do this is actually a bit of a nightmare, much harder than I thought it would be, but I'll let you know how I managed it and you can do the same back to me:

I found out using FUSLOGVW that you may need to add the DOMHelper and interop.shdocvw assemblies to the GAC. Having thought about this again you may also be able to get away with placing your assembly in the same folder as the DOMHelper that is loaded by Internet Explorer. You'll have to try this yourself.

Anyway, once you've added the assemblies to the GAC using GACUtil (available as part of the 300Mb SDK) you can then load the assembly. Click the little monitor image and choose add-ins and follow the instructions from there.

There you go - you're up and away.

As a starter for 10 you can download the DOMScripter Visual Studio Project, which also contains a binary if you're too lazy to build the code yourself.

Any comments would be welcome.

Notes:
  • You won't be able to do anything in the designer when the the class inherits the Plugin class because it's an abstract class, ya de yada.
  • If you have a textbox on your own plugin then you may want to ensure that it receives the attention that it's due i.e. handles backspace correctly by handling the GotFocus() event and calling the ParentFrame.SetFocus().
  • You can use the CLR Debugger (also part of the SDK) to run IE and find any bugs.

Usual disclaimers apply.
2/28/2006 5:01:01 PM (GMT Standard Time, UTC+00:00)  #      .net | c-sharp | DOM Helper | Inline CSS Editor  | 
 Monday, February 27, 2006
I was asked if there was a simple way to write a browser helper object (BHO) using C#.

It's actually very easy to do this if you know what you're looking for, I used the information on steven cohn's weblog everything is there that you need to write a BHO. I recommend that you read the article - it's very concise and accurate. You can download my interpretation of this BHO article in a single file. When you download this file and include it in a project you'll need to add the Shdocvw COM object and in .Net version 2 there's a .net component called Microsoft.mshtml.

It's incredibly easy to write something that will do the very simple, however when you get into messing with the mshtml and shdocvw then you may run into problems. I had terrible trouble with the DOM Helper. There's absolutely no documentation for mshtml. So most of it is trial, error and a fair bit of guesswork.

If you're looking for something quick then I would recommend that you have a stab at implementing a menu extension. They are far easier to write and can be called from the context menu of IE.


2/27/2006 6:02:57 PM (GMT Standard Time, UTC+00:00)  #      .net | c-sharp  | 
 Friday, February 24, 2006
Well I've finally got round to producing the inline CSS editor that I wanted to do in the first place. The first stab, was in C++ and although it worked, it was a complete nightmare. It didn't allow you to alter CSS files that were loaded as "@import". This new version does, it parses the CSS and adds each individual rule back to the style sheet. Simply replacing the CSSText caused a memory corruption error in MSHTML.

It's been re-written it in C# using Pavel Zolnikov's BandObjects. I've also added a few extras such as a DOM Explorer and the ability to add plugins to the band object.

While it's been writting in C# 2.0 there's not much use of the new version 2 features. Mind I was most satisfied with my first foray into using generics. I didn't think that there'd be much use for them but I did find a use, albeit slightly contrived.

So you want to see the screen shot?



OK, so now you like the look of it, you want to know how to get it and play with it?

I really wanted to deploy this as with the proper installer however, C# Express doesn't include that so you going to have to install the file manually:

First of all download DOM Helper.

Extract the files in that archive to a location on your harddrive that you can remember (e.g. c:\DOMHelper\).

Next you'll need to regasm the assembly open a cmd shell ( Start -> Run -> cmd) and type:

"%windir%/Microsoft.Net/Framework/v2.0.50727/regasm" /codebase c:\DOMHelper\DOMHelper.dll

This should have registered the assembly, and the next time you open Internet Explorer you will be able to view DOM Helper by choosing it from View -> Explorer Bars -> DOM Helper.

If for any reason you don't like it to uninstall run the following command

"%windir%/Microsoft.Net/Framework/v2.0.50727/regasm" /u c:\DOMHelper\DOMHelper.dll


Thanks to www.famfamfam.com/lab/icons/silk/ for the icons

If you want to know more, then please let me know.

2/24/2006 2:32:05 PM (GMT Standard Time, UTC+00:00)  #      c-sharp | DOM Helper | Downloads | Inline CSS Editor  | 
 Tuesday, February 21, 2006
Following on from a previous entry on powerpoint presentations: http://www.hairy-spider.com/2004/10/29/ExtractingAFlashFileFromAPowerpointPresentation.aspx

I've compiled the source included in that entry and uploaded it to the website for general consumption. I've done nothing to the code other than compile it.

When you download the file, you must extract the file somewhere on your machine. Please put it in a memorable and easy location, e.g. c:\

Then you need to open a command window ( start -> run... -> cmd) then you need to type something like:

c:\extractaflash.exe path_to_my_scrap_file.scrap c:\outfile.swf

This will then create a new file in the c:\ location called outfile.swf which will be the shockwave flash object.

I would work on a gui application but I don't have any sample scrap files to hand. So you'll have to make do with this.

You can now download the extractaflash executable.

As a side note, it's amazing how something you do can end up all over the shop in all sorts of code that you as the original writer of the code have no knowledge about. I don't really mind people using my code but a little bit of appreciation would be nice. I know that licenses are supposed to stop this sort of thing, but it's just a rude not even including a reference to the originator of the code.

2/21/2006 1:29:18 PM (GMT Standard Time, UTC+00:00)  #      c-sharp  | 
 Thursday, February 02, 2006

Since I installed .Net version 2 I haven't been able to create any new version 1 websites in visual studio 2003. Any .net pages are 404'd and debugging has also broken. Old sites still works.

I found a way to work around this. To get a site working you need to create a new virtual directory, then copy the code over and change the relative settings in the csproj and webinfo files.

I believe that it's got something to do with the way that the virtual directories are being created by Visual Studio. Looking at the information in the IIS Metabase yeilds the following differences between a working application and a broken one:

Key nameworkingfailing
KeyType IIsWebVirtualDir IIsWebDirectory
Win23Error 0 !Missing!
Path !path to site! !Missing!
DirBrowseFlags 1073741886 !Missing!
AccessFlags 513 !Missing!
ScriptMaps !Missing! .htw,C:\WINNT\System32\webhits.dll,3,GET,HEAD,POST

There are also differences in the keys on the bin folder:

Key nameworkingfailing
KeyType !Missing! IIsWebDirectory

Updating the broken setting to those of the fixed settings seems to resolve the situation. If I were so inclined - I'd knock out a script. As it is, I'm tired after writing that dictionary definition thing.

2/2/2006 12:32:36 PM (GMT Standard Time, UTC+00:00)  #      .net | c-sharp  | 
 Wednesday, January 25, 2006
So how the hell do you convert from one coordinate system to another. Well the proper way would be to study and learn all about 3D trig.

The easy way is to read this paper: National GPS Network information: Annexe C. Converting between grid Eastings and Northings and ellipsoidal latitude and longitude

I've done this and it made my eyes bleed. I've taken the information in it and produced the following C# code:

using System;


namespace tt
{
/// /// /// public class LatLonConversions
{
const double a = 6377563.396;
const double b = 6356256.91;
const double e2 = (a -b)/a;
const double n0 = -100000;
const double e0 = 400000;
const double f0 = 0.999601272;
const double phi0 = 0.855211333;
const double lambda0 = -0.034906585;
const double n = (a-b)/(a+b);


private LatLonConversions()
{ }

public static LatLon ConvertOSToLatLon(double E, double N)
{
double phi = 0;
phi = (N-n0)/(a*f0) + phi0;
double M = b * f0 * ( (1 + n + 5/4*n*n + 5/4*n*n*n)*(phi - phi0) - (3*n + 3*n*n + 21/8*n*n*n) * Math.Sin(phi-phi0) * Math.Cos(phi+phi0) +
(15/8*n*n + 15/8*n*n*n) * Math.Sin(2*(phi-phi0))*Math.Cos(2*(phi+phi0))-35/24*n*n*n*Math.Sin(3*(phi-phi0))*Math.Cos(3*(phi+phi0)));

while (N-n0-M>=0.01)
{
phi = (N-n0-M)/(a*f0)+phi;
M = b * f0 * ( (1 + n + 5/4*n*n + 5/4*n*n*n)*(phi - phi0) - (3*n + 3*n*n + 21/8*n*n*n) * Math.Sin(phi-phi0) * Math.Cos(phi+phi0) +
(15/8*n*n + 15/8*n*n*n) * Math.Sin(2*(phi-phi0))*Math.Cos(2*(phi+phi0))-35/24*n*n*n*Math.Sin(3*(phi-phi0))*Math.Cos(3*(phi+phi0)));
}

double v = a*f0*Math.Pow(1-e2*Math.Sin(phi)*Math.Sin(phi),-0.5);

double p = a*f0*Math.Pow(1-e2*Math.Sin(phi)*Math.Sin(phi),-1.5)*(1-e2);
double n2 = v/p-1;

double vii = Math.Tan(phi)/(2*p*v);
double viii = Math.Tan(phi)/(24*p*v*v*v)*(5+3*Math.Tan(phi)*Math.Tan(phi) + n2 - 9*Math.Tan(phi)*Math.Tan(phi)*n2);
double ix = Math.Tan(phi)/(720*p*Math.Pow(v, 5)) * (61 + 90 * Math.Tan(phi) * Math.Tan(phi) + 45 * Math.Pow(Math.Tan(phi), 4));
double x = (1/Math.Cos(phi))/v;
double xi = (1/Math.Cos(phi))/(6*Math.Pow(v, 3)) * (v/p + 2*Math.Pow(Math.Tan(phi), 2));
double xii = (1/Math.Cos(phi))/(120*Math.Pow(v, 5)) * (5 + 28*Math.Pow(Math.Tan(phi), 2) +24*Math.Pow(Math.Tan(phi), 4));
double xiia = (1/Math.Cos(phi))/(5040*Math.Pow(v, 7)) * (61 + 662*Math.Pow(Math.Tan(phi), 2) +1320*Math.Pow(Math.Tan(phi), 4)+ 720*Math.Pow(Math.Tan(phi), 6));

double e = (E-e0);
double lon = (phi - vii * e*e + viii*e*e*e*e-ix*e*e*e*e*e*e ) * 180 / Math.PI;
double lat = (lambda0 + x*e - xi*e*e*e + xii*e*e*e*e*e - xiia*e*e*e*e*e*e*e) *180 / Math.PI;



return new LatLon(lon, lat);
}
}

public class LatLon
{
public double Latitude;
public double Longitude;


public LatLon()
{
Latitude =0;
Longitude =0;
}

public LatLon(double lat, double lon)
{
Latitude =lat;
Longitude =lon;
}

}

}

You can test an implementation of this code using my OS2LatLong webservice.
1/25/2006 10:54:01 AM (GMT Standard Time, UTC+00:00)  #      .net | c-sharp | gmap  | 
 Saturday, November 05, 2005

What with the advent of .Net 2.0 and a request from geniusleft. I've reworked my original MSIL addin for SnippetCompiler to work the version 2.0 beta.

Again you can download the source for MSIL2.0 for SnippetCompiler. You'll have to build it against .net version2. MSBuild seems to to a good job for me.

Usual caveats apply - remember to change the path to ILDASM (Line 88 of Class1.cs) to the copy you have on your machine.


11/5/2005 8:25:14 PM (GMT Standard Time, UTC+00:00)  #      .net | c-sharp | MSIL Addin  | 
 Friday, November 04, 2005

Back in the old days when all people had to access the internet was a dialup connection, it was very hard to consider this when you developed locally.

There was a setting under IIS on a server to throttle the server speed, however on a workstation there was nothing. I always new that it was possible to write a small proxy to sit between IIS and the browser but I never got round to writing one.

Well that's changed. I wrote a small console application to monitor what was traffic was being sent to and from an aspnet state server, it's not very interesting btw. Anyway having written that I realised with a few minor tweaks I could use the application as a general tcp proxy. Better than that with a few more tweaks I can control the speed that data is sent from client to server and back to client.

Anyway you can download the code for throttler, and use it yourself, to get something approximating a dialup connection I'd set the the time parameter to be between 75 and 100.
11/4/2005 8:50:58 PM (GMT Standard Time, UTC+00:00)  #      c-sharp  | 
 Thursday, October 20, 2005

SnippetCompiler is one of those must have tools.

I was wondering if I could use it to view the CIL that the code would produce. I then noticed that it supported add-ins.
 
I couldn't find many resources to help me write an addin but that doesn't stop me any other time. So I reached for my handy reflector to find out what makes it tick.

Well after disassembling to my heart content I finally found out how to add a toolbar, button, and with a bit of reflection managed to expose the CompileAndRun functionality. Sadly I ran out of steam trying to generate IL from an assembly, so instead I cheated by using the result of a call to ILDASM.

You can download the visual studio project that will allow you to build the msil addin for Snippet Compiler Remember to set the path to ILDASM.

Usual caveats apply - atleast this one doesn't mess with the registry.
10/20/2005 6:25:49 PM (GMT Daylight Time, UTC+01:00)  #      c-sharp | MSIL Addin  | 
 Wednesday, August 31, 2005

BrowserLauncher is a small windows forms application which acts as an intermediary between launching a url and the web browser.

My default browser these days is Firefox, but a number of sites that I access frequently Firefox can not handle. This isn't because Firefox is broken, it's just that the sites are written particularly badly. Also there are a number of sites which I want launched in their own browser.

So I wrote BrowserLauncher. When this runs it registers itself as the default browser through manipulating the StartMenuInternet registry key - it then adds itself to the HKCR\http key. The next time you launch a URL from the desktop, start bar or ShellExecute - the details are passed to BrowserLauncher. BrowserLauncher will search its list of browser entries and launch the URL with the specified browser.

Additionally I've added some DropMyRights code that allows you to launch the browser with 3 levels of privilege, therefore allowing IE to run in Normal or Constrained mode.

Please note:

  • This software works for me, it may not work for you, if you have a bug please let me know and I'll endeavour to fix it.
  • The software will try to manipulate some registry keys.

8/31/2005 9:57:23 AM (GMT Daylight Time, UTC+01:00)  #      .net | BrowserLauncher | c-sharp | Downloads | Source Code  | 
 Tuesday, May 10, 2005

I don't know if anyone uses the Microsoft.Applications.Data.SqlHelper class. I've just discover a small bug when using the
the FillDataset method to populate a dataset with a stored procedure that returns multiple recordsets.

In the version I was using the names of the table sources were Table, Table1, Table2. However they were being added to the TablemMappings collection
incorrectly: Table, Table1, Table12, Table123, etc.

While this obviously works for the first two recordsets, anyother recordsets except for 12, 123, 1234, 12345 would not be mapped correctly.

Here's the function that needs to be replaced in the SqlHelper class, line 1816 in my version.

private static void FillDataset(SqlConnection connection, SqlTransaction transaction, CommandType commandType,
    string commandText, DataSet dataSet, string[] tableNames,
    params SqlParameter[] commandParameters)
{
    if( connection == null ) throw new ArgumentNullException( "connection" );
    if( dataSet == null ) throw new ArgumentNullException( "dataSet" );

    // Create a command and prepare it for execution
    SqlCommand command = new SqlCommand();
    bool mustCloseConnection = false;
    PrepareCommand(command, connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection );

    // Create the DataAdapter & DataSet
    using( SqlDataAdapter dataAdapter = new SqlDataAdapter(command) )
    {

        // Add the table mappings specified by the user
        if (tableNames != null && tableNames.Length > 0)
        {
            string tableName = SqlDataAdapter.DefaultSourceTableName;
            for (int index=0; index < tableNames.Length; index++)
            {
                if( tableNames[index] == null || tableNames[index].Length == 0 ) throw new ArgumentException( "The tableNames parameter must contain a list of tables, a value was provided as null or empty string.", "tableNames" );
                dataAdapter.TableMappings.Add(tableName, tableNames[index]);
                tableName = SqlDataAdapter.DefaultSourceTableName + (index + 1).ToString();
            }
        }

        // Fill the DataSet using default values for DataTable names, etc
        dataAdapter.Fill(dataSet);
        
        // Detach the SqlParameters from the command object, so they can be used again
        command.Parameters.Clear();
    }

    if( mustCloseConnection )
        connection.Close();
}

5/10/2005 12:06:48 PM (GMT Daylight Time, UTC+01:00)  #      c-sharp  | 
 Wednesday, April 13, 2005

I had an idea a few weeks ago to implement ajax. I haven't had any time to chase up the idea but basically it involves hijacking the _doPostBack() function to make a call to the server using XMLHttp.

The server code intercepts the postback call and send the client an xml stream with the respective changes. The serverside would need to track any changes to webcontrols and build a document of changes to be applied on the by the client.

For simple controls like textboxes this would be a synch, however more complicated beasts, datagrids etc. would involve much more tracking.

Maybe when I get some time I can chase this more thoroughly, vaguely I have the idea that generics may be a very good solution.

 

 

4/13/2005 10:27:34 AM (GMT Daylight Time, UTC+01:00)  #      c-sharp | Misc  | 
 Friday, October 29, 2004

We had a Power Point Presentation file given us a few days ago with an embedded flash file which we needed to extract to use on the website.

We couldn't find any way to do this. We could drag and drop the swf onto another presentation, we could even drag the object onto the desktop. This created a scrap file which was rather annoying.

However, this led me to the discovery of the NeverShowExt registry key. I managed to rename the scrap to a have a .swf extension, but still no cookie.

So I started digging around the scrap to see if I could find the swf object inside and after reading an introduction to SWF I found what I was looking for.

Now I just wanted to extract this binary data from the scrap file, and I wanted to do it the hard way!

So I wrote a small amount of code to look through a file and extract the goodies. The main part of the code was to take a byte array and copy that into my SWF struct - using the System.Runtime.InteropServices.Marshal class.

After a bit of messing around the code runs like a dream. The final executable takes 2 parameters the first is the file containing the SWF and the second is the file to write the SWF.

View the code

In theory this could be used to extract many forms of embedded binary data.

10/29/2004 12:16:29 PM (GMT Daylight Time, UTC+01:00)  #      c-sharp  | 
Copyright © 2008 Rhys Jeremiah. All rights reserved.
DasBlog 'Portal' theme by Johnny Hughes.
Pick a theme: