Sunday, February 27, 2005

Doing a couple of cool things...

This is just a quick one about a couple of cool things I discovered not so long ago. They're nothing really new or anything, I just thought they were kinda fun and useful to know.

1) ControlPaint.DrawReversibleLine
If you're a DNR listener you'll have heard Carl and Mark Miller talking about this method. It does a very simple, but profoundly groovly little thing - it draws one of those lines where the colours are the negatives of whatever's on screen beneath it (are they called XOR lines?). It's a very cool thing. I've never used it in any proper application (well, as proper as mine get, anyway!).

2) Embedding Windows Forms Controls in HTML
I was vaguely aware that this could be done. But only vaguely, and never really seen it. However, thanks to the fine fine chaps at MSDN UK, I have. I even get what's going on, as well. Weird. The only bit that's a bugger to remember (although I'm sure it'll come in time) is the sntax for embedding an object. It looks like this:
<Object ID="myobject" classid="http:FullPathToAssembly/FileName.dll#FullyQualified.ClassName" />

And that's it. All done. I just never saw it before. I think I'm going to have a bit of a play with this and see what I can get done putting various controls in web form apps. I think it's got potential to be quite cool. Well, I know it's got potential to be very cool, but it's something I'm going to have to have a bit of a play with.

Oh yeah, and it looks like Firefox doesn't support it.

Just wanted to share.

Tuesday, February 22, 2005

I really must stop doing these stupid quizzes!

Apparently I'm Hannibal Lecter.



Not that I'm complaining. There are worse villains to be.

Mumbles from Dick Tracy, for instance.

Just wanted to share.

Wednesday, February 16, 2005

Chris Sells has seen it...

Just read on Chris Sells' blog that he's seen the Hitch Hiker's Guide to the Galaxy trailer.

Now I have too.

I must admit, it does fill me with a certain amount of dread. Being a big fan of the books. And the Radio series. And the TV series. It kind of gives me the same feeling as when I went to see Star Wars Episode 1. Hopefully I won't feel afterwards how I did when I went to see The Phantom Menace.

It's got plenty going for it, though. Great British talent. Great British author. Filmed in a Great British location. I'm sure there was some great British post-production and music in there as well. I guess that's why we only have to wait until 2 weeks after the US release date to be able to watch it here! Not that I'm bitter, of course.

Still, it's going to be a must-see one for me. And a must-buy DVD when it comes out.

Now where's my towel?...

Tuesday, February 15, 2005

The end of an Era

So I've just read here that Rory's left DotNetRocks.

It's a fair enough decision, I guess. Much as he was really cool, and a grat co-host, I sort of go the impression over the past couple of months that he was a bit preoccupied and generally knackered at the end of the week. Whereas he used to be really bubbly, active and really fun to listen to, over the past couple of months he's been really subdued, reduced to a bit of a 'hi' at the beginning of the show, and the occasional 'yeah. Uhuh' during the show. Who could forget the time when, half way through an interview, Rory shouts 'Gah! I'm gonna have to skip out for a sec. My dog's just crapped on the rug!' Ahh. Happy days (Or if you're me, Happy nights. Listening live meant staying up till 4 or 5 am Saturday morning. Killer!)

Not that I'm knocking it at all. You just have to listen to the guy's schedule and follow what he's been up to, and you can see any mere mortal would be ready to drop by the end of a week. To have to entertain and be informative after that? That ould take some doing.

So Rory's off to build his career. Good luck to him. And why not?

And Richard's a top notch replacement. I'd point to his blog, but he doesn't seem to have one. Suffice to say, he's gonna rock. It'll actually be quite interesting and a bit weird. I don't think I've ever heard him talk about code 'n' stuff. He's normally just the toy boy.

Just wanted to share, since it had me thinking.

At the end of the day, though. They could do anything they liked to the show, and as long as they had Geoff's hair at the helm it'd rule!

Apologies for sycophantism.

Would you credit such foolishness...

It would seem that I can't even wash the dishes without having some sort of accident.

This one bled and bled like a bugger (luckily Mrs Mawoo was on hand with tea-towels and other such stop-the-blood flowing stuff). I've never seen so much blood up close! Eugh!
So much blood, such a small cut!
And after it stopeed bleeding and oozing my life-force all over the kitchen, was I left with a souvenir? A nice scar to show the grandkids (embellished with a suitably tall story)? Anything? No. All I was left with was that nick. I can't even claim to have been a troubled teenager with a cut that small, dammit!

And although you can't see it in the image, there's a bruise underneath the cut that aches a bit when I write and type. Bugger.

So I've got:

  1. No big cut
  2. No tall story
  3. No hard-looking scar
  4. A slight ache when I write and type
Hardly seems worth dropping that bowl now...

Just wanted to share. Apologies for umimpressiveness.

The post I never thought I'd write...

... But I'm really really glad I am!

Because it would seem that I've managed to convince a real company, with its own real cheque-book and everything, that I can code stuff worth paying for.

that's right. After 4 years languishing in the wonderful world of charity fundraising, I've finally got myself a job building ASP.NET Intranet applications for a global supergiant of a company.

Which should be fun.

As I'm sure both of my regular readers know, this has been what I've been working for for ages, now. Reading, studying, ignoring Mrs Mawoo, shouting at my computer, all of it's been gearing up to a job writing code day-in-day-out.

No doubt once I start (need to work out my notice where I am) my blog'll start drifting back onto something that's at least vaguely relevant to code. I know it's been drifting about a bit aimlessly of late, but hey. it's my blog, so there!

Anyway, just wanted to share. Apologies for smugness!

Monday, February 14, 2005

Another thing that went 'click' today...

Although I've been using databinding expressions (the ones that are enclosed by '<%#...%>') in ASP.NET applications for a bit, I never really go how useful they are.

Now normally, I'll sling a repeater onto a page, and put in databinding expressions to populate bits and bobs in the ItemTemplate, like so:

<asp:repeater>
<ItemTemplate>
<asp:label runat="server" text='<%# container.dataitem("TheValue") %>' />
</ItemTemplate></asp:repeater>

But I didn't really realise until today that I could bind anything to anything the same way. The thing that really brought it home today was when I was thinking of having a repeater that contained a UserControl in the ItemTemplate. My UserControl has a public property, 'Item', that was a class that had a bunch of properties that were displayed in the control. I wanted to bind the repeater to an array of said classes.

What you can do in the ItemTemplate, using databinding expressions was this:
<asp:repeater>
<ItemTemplate>
<SB:ItemDisplayer runat="server" item='<%# Container.Dataitem() %>' />
</ItemTemplate>
</asp:repeater>

Isn't that clever? Well, I though so, anyway. It's one of those things that makes perfect sense when you look at it, but it had never really occurred to me that you could do it that way.

Just wanted to share.

Aaah Valentine's day...

The one day of the year when no matter how caring, considerate, kind and altogether frightfully lovely you are every single day, it ain't worth diddly if you don't turn to with a suitably romantic card and a bunch of flowers.

You can be a god-like boyfriend. You can:

  • Read your partner bed-time stories to help her sleep
  • Stroke her hair and cuddle her until she goes to sleep every night, any time of day or night, particulately if she's not feeling well
  • Be at her beck-and-call any time day or night to go to the kitchen and fetch a drink
And all manner of gestures and sweetitudes every day

But if you haven't got a card, maybe flowers, perhaps chocs, even a restaurant prepared and at the ready, everything you do all year round, every single day is worthless.

If men tried to pull that kind if stunt every darned year, we'd find ourselves pretty damned single pretty damned quick.

You see, much as I hate people who harp on about the commercialism of things, I never really liked valentine's day. Not because a bunch of roses that'd set you back about £5 for the rest of the year suddenly shoots up to £15. Not because even if you can find a restaurant with a table for 2, you're forced to eat what they want you to eat, whilst listening to Barry White. No. I really hate Valentine's Day because it encourages people to totally take their partners for granted. Which I hate.

And you're only allowed to argue with this point if you meet all the following criteria:
  • You have a partner
  • You didn't get a card or gift from them
  • You're cool with that
  • You looked your partner in the eyes (the eyes are important!) and told them you loved them within the last 24 hours
  • You hugged your partner in bed last night, and not just because it's February and freezing in your part of the world
Only then can you argue with me.

Just wanted to share. Apologies for grumpiness.

Sunday, February 13, 2005

I'm still here.

I know I haven't posted anything for a few days. Which is kinda out of character for me, but it's been a bit hectic in Benjimawoo-land of late.

However, I might ahve a bit of news soon. Can't really say anything now, since i really don't know anything. Wel,, I know some things, but nothing newsworthy.

But I'm still here.

More to follow.

Jusr wanted to share... nothing. Hmm.

Wednesday, February 09, 2005

Backwards Compatability for my head

My head, it would seem, is not backwards compatable.

I find it really counter-intuitive thinking in script, particularly when I'm writing ASP.old pages. I just want to pull everything out as a class and just make method calls on it! Gah!

Oh well. Keeps me interested, I suppose. And it is, at the very least, another string (or at least substring) to my developer's bow.

But really, whose idea was Server.CreateObject("TypeAsString") anyway?

Just wanted to share. I can do it really (It's just like VBA), but it just trips me up now and again.

Monday, February 07, 2005

More cheap toyness

In accordance with my love of toys, I have a added a BlogMap to my blog (Cool little widget by Chandu Thota). Apart from living in my sidebar, have another one here:

my blogmap

I think it's quite cool, anyway.

Thursday, February 03, 2005

Blogging on Demand #5

I was going through my referral logs this evening, as I sometimes do, and I came upon this search that piqued my interest a little bit:
how to display pictues with xml asp.net

Now I know it's spelt wrong, but that's the only reason it reached my blog in the first place.

So anyway, I interpreted this as meaning 'How can I retrieve and display images passed via an XML stream from, for example, a webservice?'

So I endeavored to find out.

First up I created the web service that was going to send the images across the wire. Now the System.Drawing.Bitmap class can't be serialized directly to a form that can be transmitted over http. You have to go around the houses a little bit.

So here are the two methods in my webservice:

<webmethod()> Public Function GetImageList() As String()
'This just gets a list of the files in the Images subdirectory in the
'webservice's home directory
Dim fs As DirectoryInfo = New DirectoryInfo(Server.MapPath("Images"))
GetImageList.CreateInstance(GetType(String), fs.GetFiles.Length)
Dim Imagelist As New ArrayList
For Each fi As FileInfo In fs.GetFiles()
Imagelist.Add(fi.Name)
Next
GetImageList = Imagelist.ToArray(GetType(String))
End Function

<WebMethod()> Public Function GetImage(ByVal fileName As String) As Byte()
'This Method gets the image specified in the parameter string
Dim img As New Drawing.Bitmap(Server.MapPath("Images/" & fileName))
Dim ImgStream As New MemoryStream
img.Save(ImgStream, Drawing.Imaging.ImageFormat.Bmp)
GetImage.CreateInstance(GetType(Byte), ImgStream.Length)
GetImage = ImgStream.ToArray
End Function


The first method is easy - it just iterates through the images subdirectory and gets the names of the files in it. I use this method in my client app, so I don't have to remember filenames and stuff!

The second method does a bit more. First up, it loads the file specified up into memory as a bitmap.

It then creates a System.IO.MemoryStream to store the serialized image data in.

The next line saves the bitmap data into the MemoryStream. We now have a stream of serialized data representing the image. After it's stuffed the image into the stream, it then uses the stream's ToArray method to return an array of unsigned bytes. Now, to be honest, I don't know what unsigned bytes are. I mean, I know what bytes are, but what the difference is between unsigned and signed bytes, I dunno.

So once it's turned it into an array of bytes, it can be sent over the web to your client app. I won't show you what the response stream looks like, since it's really really long. And gobbledegook.

So that's how the image is sent over the wire.

To display the image at the other end, you just have to do the reverse.

This is the code that calls the webmethod and puts the image in a PictureBox control:

Private Sub GetImage()
Dim ImgServ As ImageService.ImageService
ImgServ = New ImageService.ImageService

Dim ImgArray As Byte()
'FileList is a ListBox containing the list of images available
ImgArray = ImgServ.GetImage(FileList.SelectedValue)
Dim ImgStream As New System.IO.MemoryStream(ImgArray)
'RetImage is the name of the picturebox image that displays the image
RetImage.Image = New Bitmap(ImgStream)
End Sub


As you can see, this takes the array of bytes from the Webservice and writes it out to a memorystream. This stream can then be read into a new bitmap and put into the PictureBox. Hey Presto.

The code's a bit rough and ready. In real life you'd add type checking, security stuff (possibly) and whatnot like that, but for this demo it's fine.

As a further note, images can be pushed and pulled about to be displayed for all sorts of situations. Most notably, if you have images saved in an Image column in SQL Server, you'll have to do this (or at least something like this) to push images into and pull them out of SQL Server.

Second-to-Lastly, I'm no expert. Although I've read about this, I've only done it once. And that was only so I could write this blog entry. If you know of a better way, or you see a glaring mistake in the code, please let me know. It's the only way I'll learn!

Lastly, if you got this far, well done you!. Just wanted to share.

Paradoxical UI

I just had a thought. It was about how we like things just the way we like them, for no apparent reason.

I just had a minor mishap with Access, and it froze and wouldn't close down. What do I do? I open up Task Manager and hit 'End Task' to make it shut down.

So what happens then? A dialog pops up asking me if I really want to end the task or not. So I hit 'End Now', as I have done every single time I've ever seen this dialog box. I think in the years I've been using WinXP (I was on Win 98 before, and can't remember if it did that or not) I've hit cancel on that dialog maybe twice.

But (and here's where it gets weird) I feel strangely reassured that I'm given the choice. I don't exercise that right to chose. I choose the same thing each and every time. I even sometimes wish that 'End Now' was the default because I always use it. I don't, however, ever get annoyed with this unneccesary dialog popping up.

Weird that. I'm not even being sarcastic. I genuinely am reassured by the dialog that pops up and checks that after I've opened up Task Manager and chosen my task to end before hitting 'End Task' I really want to end it.

Just wanted to share.

Fun Fun Fun

I don't usually post links to pointless and frivolous sites, but this one's had me in stiches all afternoon.

http://asksnoop.com/

It's very entertaining. Especially when you point it at things like text-heavy blogs.

Wednesday, February 02, 2005

Hurdles and Wurdles...

I learnt a very important lesson today, and here it is:

... WHERE NOT Exists (Select SomeField FROM SomeRecords WHERE SomeCriteria)... Can be really really bad.

And I mean REALLY bad.

I wrote a SQL Server db to do some analysis for me. I wrote about it here back when I was trying to do the same thing in Access. Needless to say I gave up on that plan and rewrote the lot for SQL Server. Now up until yesterday, I hadn't really tried producing the output and everything all at once. I always did little bits, saw they worked and moved on. I think I did something yesterday to break it, somehow, though. Don't ask me what, just something.

So I fire up this stored procedure that does some crunching and produces some tables of numbers. Normally I reckon it'd take about 1 or 2 minutes to do it. I'm sure on one of my earlier versions it did.

I fire it up.

And wait...

And wait...

And wait...

After 3 hours I start thinking there's sopmething going wrong, so I look through perfmon looking at the usual SQL Server suspects (Disk IO queues, Pages being written out to disk, processor time and a whole bunch of other crap). All the numbers look to be what Star Trek types call 'Normal Operational Parameters'. No obvious problem. Nothing hardware's choking the system. Hmmm...

So at about hour 5, I think there's something up with my code. I kind of figured there would be, but I was hoping that I could get a pointer to what was taking the time from PerfMon. I was wrong.

So I was left taking wach and every bit of code apart. Every subquery. Every view, every criterion. Bugger.

Although having said that, I did manage to find the bit that was tripping it up. There was a 'WHERE EXISTS' clause in one of the views, and the subquery in there took ages and ages to run. So I'm guessing that that subquery was trying to run for each and every line in the view's source dataset. All 860,000 rows. No wonder it was taking its time.

So I changed that one bit. Instead of doing it that way, I just did a left join on the subquery and picked out the rows without a corresponding record in the subquery.

Doh!

It all tuned out nice in the end, though. It did mean that I cut down my stored procedure from 6 hrs+ (I never let it run all the way through in the end) to about 3 minutes.

Nice!

Just wanted to share.