Hosting .NET controls in VB6

I recently ran into a need to interop a C# .NET user control with a VB6 form.

We all know that VB6 only allows you to reference a user control if it resides in an OCX.

The Interop Forms Toolkit, mentioned here, seems to be only good for VB.NET user controls.

Prior to this, I've been able to get by with dynamically adding the control via Controls.Add {COMClassname}, {ControlName}

But now, I need to be able to manipulate the control in design time.

So, based on the above experience, I created a very basic VB6 user control called DotNetControlWrapper. The tricks with this control are the following:

  • There's a public property called DotNetClassName, which is a COM class name of the .NET control.

  • It delegates resizing logic to the .NET control.

  • It exposes the .NET control via a DotNetObject property, thus allowing the user to sync the control's events if needed.



The bulk of DotNetControlWrapper.ctl looks like this:



Option Explicit

Private object As Object
Private ctlExtender As VBControlExtender
Private mstrDotNetClass As String

Public Property Get DotNetClassName() As String
DotNetClassName = mstrDotNetClass
End Property
Public Property Let DotNetClassName(ByVal clsname As String)
mstrDotNetClass = clsname
If mstrDotNetClass = "" Then Exit Property
' initialize the .NET control
If Not ctlExtender Is Nothing Then
Controls.Remove UserControl.Extender.Name + "_dotnet"
End If
Set ctlExtender = Controls.Add(mstrDotNetClass, UserControl.Extender.Name + "_dotnet")
ctlExtender.ZOrder 0
Set object = ctlExtender.object
End Property

Private Sub UserControl_Resize()
If object Is Nothing Then Exit Sub
ctlExtender.Move 0, 0, UserControl.Width, UserControl.Height
object.BringToFront ' Bring the .NET control to foreground
End Sub

Private Sub UserControl_Show()
If ctlExtender Is Nothing Then Exit Sub
ctlExtender.Visible = True
End Sub

Public Property Get DotNetObject() As Object
Set DotNetObject = object
End Property

Private Sub UserControl_Terminate()
If ctlExtender Is Nothing Then Exit Sub
Set ctlExtender = Nothing
object.Dispose
Set object = Nothing
End Sub

Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
PropBag.WriteProperty "DotNetClassName", mstrDotNetClass
PropBag.WriteProperty "Width", UserControl.Width
PropBag.WriteProperty "Height", UserControl.Height
End Sub

Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
On Error Resume Next
DotNetClassName = PropBag.ReadProperty("DotNetClassName")
Width = PropBag.ReadProperty("Width")
Height = PropBag.ReadProperty("Height")
End Sub


Open sauced Jaspersoft?

In the past, I've dabbled a bit with Jaspersoft's reporting engine, back in the days when it was still called Panscopic. I'm just getting back to working with Scope Server now as I'm revisiting an old project, did some checking and it turned out they've open sourced the product since early last year. Subscribed!

I Don’t Care How Your Program Works

Found this from the MSDN Blog: Why Software Sucks. It's an interesting title for a book by Harvard professor David S. Platt. The following snippet from his sample chapter really scratched my "itch":

I Don’t Care How Your Program Works

[A] mistake that programmers make when they design user interfaces is to force users to understand the internal workings of their programs. Instead of the programmer adjusting her user interface to the user’s thought processes, she forces the user to adjust to hers. Furthermore, she’ll usually see nothing wrong with that approach. “That’s how my program works,” she’ll say, puzzled that anyone would even ask the question of why her user interface works the way it does.
...
You shouldn’t have to know or care about her program’s internal workings to use it successfully, as you shouldn’t have to know or care whether your car’s engine uses fuel-injection or a carburetor in order to drive it.


As programmers, we tend to think like....duh...programmers, and often forget to think like users. Being able to make this leap is probably one of the distinguishing factors between a seasoned programmer and a rookie.

Note to Self: stop being a rookie.

Ctrl-Alt-Del via Remote Desktop Connection

Ever wonder how you could issue a Ctrl-Alt-Delete command to your remote desktop connection? Try Ctrl-Alt-End.

Yahoo! Pipes

Got the tip from Gav last night about Yahoo! Pipes and trying to check it out just now.

Too funny! Is it April already?

SSH proxying via Apache

Been working out of a customer site in the past few weeks and their firewall is a bit finicky. One day it would let me ssh into my office fine and the next day it would just kick me out right after the initial handshake. It doesn't actually refuse the connection at the onset. It would connect and then immediately drop the connection. Their IT guys tried to tell me it's my server, not their firewall that was the culprit. Hey, I'm an IT guy too, buddy! (amongst other things). If I can connect fine from my home network and two other guys can also connect from their home, I'm no Sherlock but something tells me it ain't my server. As improbable as it may be, because I know you think your firewall is perfect and that you haven't made any change to it that might cause this. My friend, I'd hate to tell you this but, it's your firewall! ;-)

Right. Next time, you try telling your customer's IT guy that his network firewall is faulty. See if that will get you anywhere.

Oh well. At least this gave me the chance to look into enabling our web server to allow SSH proxying. Found a useful article here: Tunneling SSH over HTTP(S).

This is essentially what you need to add to your httpd.conf on the Appache server:


# HTTP Proxy for SSH
AllowCONNECT 22
ProxyVia On
<ProxyMatch (192.168.1.1)> # Internal IP of your SSH server
Order deny,allow
Deny from all
### External (customer) sites allowed to connect
Allow from 199.243.1.61
Allow from 74.100.102.21
</ProxyMatch>


Then, to connect from the remote site, configure your PuTTY Connection host name to 192.168.1.1 (the internal IP address of your SSH server), set Connection>>Proxy setting to use HTTP proxy, enter in the public hostname and port of your Apache server.
That's it. Painless.

A slight diversion from real work, but this will come in handy the next time I'm at a customer site that blocks out all ports except port 80. I need my network to follow me everywhere I go. I'm effectively crippled without it.

Unless...I wonder, what would happen if the customer's network itself uses a proxy server to get out to the Internet...
Oh well. Not my problem to worry about right now. Will deal with it when I run into it.

Google and YouTube


From YouTube.

This Everly Brothers' song is a classic--brings back old memories of high school nights, sitting by the radio, doing my homework.

It wasn't until today when, by chance, I watched the video clip of this song, that the impact of Google's YouTube acquisition finally hit me: it's so totally consistent with their operational patterns ever since Google's inception in 1998.

In 2001, Google acquired the archives of web based UseNet search service called DejaNews, and as the result, surfers can search UseNet archives dating back to 1981. By the way, my "official" birth date as a netizen is Mon, Jun 21 1993 12:08 pm.

As the world turned, in 2003, Google acquired Pyra Labs, the maker of Blogger.com.

And then now...YouTube.

Microsoft's legacy may have been to make personal computers a common household name. Yahoo's legacy may have been to bring web based email to the consumers. But it may be the case that Google's legacy will be: to preserve memories.

May be I'm giving them all too much undued credits.

Posting from Windows Live Writer

Trying out the new Windows Live Writer Beta, posting to my blogspot blog.  Fingers crossed and hoping that it doesn't mess up my template (I have made a backup, just in case).

I'm liking it.  The user interface for this thing looks pretty simple (I like it simple). Apparently it also supports WordPressTypePad, and a few others. I'll try it out on WordPress next.

VB Interview Question

This is one of the easy-level questions that I give my interview candidates on the written test part of the interview:

Assume that a and b are Integer variables.

i. If a And b Then Call DoSomething()
ii. If (a And b) = b Then Call DoSomething()

Statements (i) and (ii) are equivalent. True or False?


I thought this was a no-brainer, but apparently not. This is often the source of many bugs in VB code.

So how many of you think the answer is True? ;-)

New Look

I recently tried the WordPress.com service. WordPress, the software, is nice, but the hosted service itself is limiting in that you can't customize the layout template--well you can, but i'll cost you 15 credits to upgrade. Blogger.com, on the other hand gives you full freedom to customize the layout as you'd like--hence the new look of this blog. I was thinking of switching to WordPress, because of the lame layouts that Blogger provides, but having discovered this, I think I'll stick with Blogger for a while longer.

Legend of the Pink Tie

UW Math Faculty's web site has an interesting article about the Pink Tie--an icon for UW mathies.

Back in those frosh days, my pink tie got tie-napped during orientation week by those damned artsies. Lousy TLO! Sign me up for the TG. I want my pink tie back, damn it!
:-)

ActiveLock lives on!

It's been over a year since the time I left the Activelock project, due to lack of time, after having coded the baseline for 2.0. I just checked in to have a quick peek a few days ago, and it looks like it's made great strides since. Kudos to Ismail for doing a great job keeping the project alive.

Back then I had to deal with low-level RSA and MD5 bit mangling in pure C/C++. Granted that much of the encryption code was "borrowed" heavily from the PuTTY project, but, boy, was debugging it ever a nightmare.

If I were to do it all over again now, I'd rewrite the core in .NET--It's sooo much easier now with all the encryption facilities built into the core .NET framework.

I've noticed that every time I do any code weaving in .NET, it seems to take 10 times faster to get things done than doing it the old ways. Suddenly, you're presented with many new possibilities.

How far is that extra mile anyway?

We have all heard of the phrase "going the extra mile" when people talk about providing exceptional service to their customers. And I'm definitely a proponent of this mentality.

However, I've also once heard of the phrase "your lack of planning does not constitute my emergency", murmured by a former colleague when referring to a particularly demanding customer, and also think that it makes perfect sense.

At the office, I sometimes get calls from our partners/resellers with requests of the kind "um...I've got this demo in 2 hours, and I need your help to build this integration against this application that I want to show for my demo."

First thought that always came to my mind was that wonderful phrase uttered by the colleague. I mean, c'mon! My day is usually fully planned out and these kind of things really throw a monkey wrench into things.

My following thought would be, well, they are trying to sell our product for us, and consider the alternative: I tell the partner to blow off and tell the customer to reschedule and give us more time. On such close notice, this would make the partner look very bad in front of the customer, not to mention the partner might have made a long trip onsite for this demo--all of which aren't the end of the world, but a lost opportunity nonetheless.

With that thought, I put my regular schedule aside, got online with the partner and in 2 hours, whipped up a prototype demo into shape, in time for them to show the customer. Everyone was happy...well, except may be me! <whine>You've taken 2 hours of my life on something you could have done yourself, and I want it back!</whine>.

So, although I think that my colleague's "lack of planning" speech is absolutely spot-on--just like the theory of communism is absolutely spot-on--unfortunately, just like communism, it's not very practical ;-)...which brings me to the subject of this blog post: how far is that extra mile? I'll get back to you when I have the answer.

Dead Dog's back

I used to love listening to the The Dead Dog Café on CBC RadioOne every Sunday morning. It had some really witty silliness sketches, done from an aboriginal perspective. I'm not aboriginal (heck, I don't even know if I'm original) but I really enjoyed this show, which was why I really missed it when it suddenly disappeared off the airwaves in 2000.

I tuned into CBC's Sounds Like Canada program on the way to work this morning, and noticed that it's back--I guess after 6 years, somebody at the CBC finally decided to respond to popular demands.

Noice!

Ingenuity: striving to stay ahead of the curve

As we've been struggling a bit in the past several weeks, dealing with the slight inadequacies of some of the less user-friendly third-party SDKs that we've had to work with, I'm reminded of the tale that might help boost some creative mojo's for us all. It's a tale about how we created one of our very first plugins for AppConnector four, five years ago, an exercise that attested to the ingenuity of our research team, of which yours truly had the great honour of being an insignificant contributing member.

We needed to build a plugin to integrate with this other application, but it had no documented API into its user interface (AppConnector is all about integration at the UI level), and the vendor had neither the interest nor the intention of helping us find out. Hmm...Sounds familiar? Anyway, our research team had to study it the hard way, devising various experiments to feed it various inputs and observed its responses to come up with some consistent patterns, and let me tell you, ladies and gentlemen, for a bunch of lowly developers and business analysts, our process was so scientific that we could have claimed a SRED grant for it if we wanted to. It was. ;-)

We did run into some snags, through no faults of our own, however, but rather it was a limitation in their product. I'll never forget the conversation with their support guys when we called. On the phone, we told them that we were trying to do this and this, driving the user interface using that and that, and we expected it to behave this way but it behaved that way, blah, blah, blah, and yadiyadiyada, is this a bug, and can you help? At the end, they said they would talk to their developers and get back to us. What happened right after that was totally hilarious, my product manager and I couldn't stop snickering as we listened. They started talking to each other as if we we had already gotten off the line. (sneaky us!). I'm paraphrasing from this point on as it is quite a few years back, but the jist of volleys were like this:

Guy A: Did you get all that? Did you understand what they're trying to do?
Guy B: Yeah, man, it's totally crazy s**t. Did you know that? What they're doing. Did you know that that can be done?
Guy A: No, man, that's pretty wild.
Guy B: ....
(dialogue continues for at least another minute...eventually)
Guy A: Anyway, let me talk to X and see if we can fix this for them. I'll let you know.


So...We figured out how to use the software in a way that the original creator hadn't conceived. We took it to a new level they didn't think possible. If that's not ingenuity, then I don't know what is.

The moral of the story here is this: we need to remind ourselves, from time to time, that we ARE the experts! People look to us for solutions to the problems, not the other way around--because we do things that they think impossible to achieve, and not because we're a small bunch of super geniuses, but because we invest, painstakingly, our blood and sweat, not to mention countless hours, in figuring out things that are too time consuming for them to do had they attempted to do it themselves. And although it is sometimes unavoidable to need some guidance from our customers/partners, most of the time we are the ones to show them how it's done. As little karoras in our own rights, we all have the creative spirits within us to do that, to make a difference, and to be a part of something of revolutionary potentials.

Recent breakthroughs made by one of the team members this week further convinced me that the feeling is mutual throughout our closed knit group. Kudos, MDM! Go get 'em, maestro!

Microsoft shocks world with Longhorn betas

Hmm...I wonder why the world would be so "shocked", seeing how Vista Beta 2 was at least 6 months overdue. :)

Skype Offers Free Calls to Regular Phones

Yep! It's true. (I just tried it!)
You can now skype out to regular North American phone numbers for free. Well, at least until the end of 2006.

Using the .NET Framework Class Library from Visual Basic 6

I stumbled onto this link while reading another blog. Using .NET framework classes from VB6? Now that's just plain crazy talk!
Or is it?

Freetext Search ≠ Meta Data Search ?

Gav reminded me the other day, when we were discussing the problem of searching, that freetext search does not equal metadata search (also known as field restricted search). Gav was right, of course, as it takes no stretch of the imagination to see that doing a (freetext) search, for documents whose content contains the words "John Doe", is not exactly the same as searching for documents whose Author is "John Doe" (metadata search). The problem with the former is that you may get results back with documents having "John Doe" the Author, as well as "John Doe" the Reviewer.

I claim, however, that metadata search and freetext search are computationally equivalent problems. That is, you can use a freetext search solution to solve the metadata search problem, and conversely, you can use a metadata search solution to solve the freetext search problem. In this post, though, I shall endeavour to prove the first part only, since that is the crux of the original point of discussion.

First, let's do a little bit of review in computational theory. We say that a problem A is reducible to problem B if we can apply a series of transformations that turn problem A into problem B, which, we hope, is less complex and more solveable than problem A. In effect, we're saying that if we could find a solution to problem B, then we would know a solution to problem A as well. It is a common approach that academic researchers like to use when dealing with computational complexity involving NP-complete problems, i.e. problems for which no solution has been found that can be computed in polynomial time. Researchers try to prove that a problem is NP-complete by trying to reduce it to another known NP-complete problem.

Well, I claim that the metadata search problem is reducible to freetext search. Or, in more layman's terms, you can satisfactorily simulate metadata searching using freetext searching capability. And below are the transformations that take the problem from the metadata search domain into the freetext search domain.

Let's say you want to index a PDF document with the metadata field: Invoice_Number = ABC100.
For this document, you provide a secondary file which will serve as the "index file" whose content contains some sort of encoding of the above name-value pair, in addition to the link to the real document. Something like:


<DocumentSummary>
<Invoice_Number>ABC100</Invoice_Number>
<A HREF="file:///C:/Accounting_Data/DOC00000018567.PDF">View Document</A>
<HASHCODE>51E88D049A06D7018D38740772FCAA0A<HASHCODE</CODE>
</DocumentSummary>


where 51E88D049A06D7018D38740772FCAA0A is the computed MD5 hash of the text <Invoice_Number>ABC100</Invoice_Number>.

You will then feed those two files to the freetext indexing engine.

Now then, since the MD5 hash is fairly unique, if I were to do a freetext search for the keyword 51E88D049A06D7018D38740772FCAA0A, it would be highly unlikely that I would get a mixed set of index file and real files in the search result, but rather I would only get a list of index files containing Invoice ABC100, which contained the link to the actual invoice PDF file itself.

Hence, we've proven that we can use a freetext search capability to do metadata search.
QED.

GMail ATOM feeds

Hmm...It seems that Google has been providing ATOM feeds into your GMail inbox for a while now. The question is, then, whether I should trust either of Bloglines or NewsGator enough to give them my GMail ID and password, so that they can fetch the mails for me. :-)