How to Use a Managed (.NET) Control in an Unmanaged Container

It seems that in the first beta of the Visual Studio .NET tools, you were able to create a user control (like a button or a form), and the mark it for COM compatibility to use it like an ActiveX control in your legacy Visual Studio 6 projects. Unfortunately, Microsoft decided to yank that feature prior to the official 1.0 release of the .NET SDK. It has yet to reappear.


Fortunately, some clever folks have figured out how to work-around this and get it to work. The first clue I came across was a Microsoft hosted page that suggested building an interop ActiveX control in VC7, and then using the interop ActiveX control from within the VC6 project. I went along this idea for a while, but was eventually advised against it by some of the other developers here as they had seen issues in mixing VC6 and VC7 libraries.


Then I hit the jackpot. I found two websites that, when combined, got me exactly what I wanted. Those websites were:



http://www.ondotnet.com/pub/a/dotnet/2003/01/20/winformshosting.html

http://www.codeproject.com/cs/miscctrl/exposingdotnetcontrols.asp



I had to add two functions to my control class. One function to add some extra Registry information to mark the component as an ActiveX control, and the other to remove those entries when the component is unregistered. I also had to mark the class with a ClassInterface and a GUID. Below is the class declaration info:



[Guid("0B98FF25-E354-4e9b-AD66-4351D1F3D95B")]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class MyActiveXControl : System.Windows.Forms.Button

Then I used the following two functions for my extra registry settings.


#region COM Interop / ActiveX Functions

[ComRegisterFunction()]
public static void RegisterClass ( string key )
{
// Strip off HKEY_CLASSES_ROOT\ from the passed key as I don't need it
StringBuilder sb = new StringBuilder ( key ) ;
sb.Replace(
@"HKEY_CLASSES_ROOT\","") ;

// Open the CLSID\{guid} key for write access
RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(),true);

// And create the 'Control' key - this allows it to show up in
// the ActiveX control container
RegistryKey ctrl = k.CreateSubKey ( "Control" ) ;
ctrl.Close ( ) ;

// Next create the CodeBase entry - needed if not string named and GACced.
RegistryKey inprocServer32 = k.OpenSubKey ( "InprocServer32" , true ) ;
inprocServer32.SetValue (
"CodeBase" , Assembly.GetExecutingAssembly().CodeBase ) ;
inprocServer32.Close ( ) ;

// Create a miscellaneous status key to prevent flickering
RegistryKey miscStatus = k.CreateSubKey("MiscStatus");
miscStatus.SetValue(
"", "131457");

// Reference the type library
RegistryKey typeLib = k.CreateSubKey("TypeLib");
Guid libid = Marshal.GetTypeLibGuidForAssembly(Assembly.GetExecutingAssembly());
typeLib.SetValue(
"", libid.ToString("B"));

// Assign the version of the control
RegistryKey versionKey = k.CreateSubKey("Version");
Version ver = Assembly.GetExecutingAssembly().GetName().Version;
string version = string.Format("{0}.{1}", ver.Major, ver.Minor);

if( version == "0.0" )
{
version =
"1.0";
}
versionKey.SetValue(
"", version);

// Finally close the main key
k.Close ( ) ;
}

[ComUnregisterFunction()]
public static void UnregisterClass ( string key )
{
StringBuilder sb =
new StringBuilder ( key ) ;
sb.Replace(
@"HKEY_CLASSES_ROOT\","") ;

// Open HKCR\CLSID\{guid} for write access
RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(),true);

// Delete the 'Control' key, but don't throw an exception if it does not exist
k.DeleteSubKey ( "Control" , false ) ;

// Next open up InprocServer32
RegistryKey inprocServer32 = k.OpenSubKey ( "InprocServer32" , true ) ;

// And delete the CodeBase key, again not throwing if missing
k.DeleteSubKey ( "CodeBase" , false ) ;

// Finally close the main key
k.Close ( ) ;
}


#endregion


With that code inserted, I then compiled the .NET code. To prove that the object will work, go to the Tools menu and choose ActiveX Test Control Container. Here you can add a sample instance of your control to prove to yourself it is working. The next step is to actually embed the control in you Visual Studio 6.0 project. Open up your dialog editor in VC++ and right-click the dialog. Choose "Insert ActiveX Control" and pick your control out of the list. Next, right-click the form and choose "Class Wizard...". Go to the Member variables tab and double click the ResourceID for your control to add a member variable in your code to access the functionality of the object. This last step is only necessary if you need to call methods or set properties on your user control.


I'm not guaranteeing that this code will work for you, but it has been working quite well for me. Sometimes when I open the dialog editor, I get an error message that says that the ActiveX control could not be instantiated, but it always compiles and works at runtime. Your mileage may vary.

A Couple of Movie Reviews

Last night Jenn and I settled in for our Sunday Night Comfort Food and Movie time. That is to say, we had vanilla malts from Ritter's, popcorn, and pizza rolls for dinner in front of the TV. The movie for the night was "National Treasure". This was a really fun film to watch. It reminded me a lot of an Indiana Jones film, only centered on US History rather than religious artifacts. It was also nice to see Nicolas Cage break his string of bad movies. Jenn is an enormous Cage fan, and she has been rightfully disappointed with his films over the last couple of years.


The movie plot centers around a great treasure hidden by the Knights Templar to prevent it from falling into the control of any single person. The Free Masons took responsibility for protecting the treasure and keeping it secret. The treasure came to the US with the founding fathers, who were also Free Masons. The last of the Free Masons passed the secret onto the patriarch of the Gates family, and ever since the family has felt compelled to find the treasure. Cage plays the youngest of the Gates line, and is quickly double-crossed by his partner after finding the first in a series of clues that takes the setting to many important sites in American history such as the Liberty Bell, the olde north church, and The Declaration of Independence.


Jenn and I both really liked this one. It was just the reat mix of action, intrigue, and mystery to keep us interested.


After Jenn went to sleep, I watched Alien vs. Predator. Ï'm a fan of the Alien series of movies, and I was interested in seeing this one as soon as I saw the previews. The first alien movie was awesome, and I remember watching it with my dad. It scared the crap out of me, but it was a great movie. The second alien film was just as good, if not better. The third alien movie was a little flat for me. It wasn't necessarily bad, but it wasn't taking the story anywhere either. And the fourth alien film? Well, let's just try to forget that one, I think it's for the best. Still, even after the extraordinary stink-fest of Alien 4, I had hope for AVP.


AVP is set in 2004, when a satellite for the Weyland company picks up a strong thermal change in Antarctica. The satellite takes images of a heat signature that outlines walls that appear to be a temple. Charles Bishop Weyland, the founder of the company, seeks out a team to help him explore the site and make his last great claim in history. The temple appears to be hundreds of feet under ice, but when they arrive they find that a tunnel has already been burrowed to the site. What follows is a three-way clash between the humans who are trying to understand the significance of the site, the aliens who are struggling to escape, and the predators who are on the hunt.


I was very happy with this film. As a fan of the alien series, this movie really helped to expand on the world of the aliens. I've never seen the Predator movies through in a single sitting, but I may have to now. And, as with all Alien films, the ending leaves open the possiblity of a sequel. Heres hoping!

Wiring up User Interface Events in C#



One of the things I really l like about C# is the way events work. I was already accustomed to creating event listeners and adding them to the event source in Java, so it was a no brainer to switch to C#. One thing that was a little confusing at first, though, was how to easily wire up my events for user interface components. In VB6 and VB.NET it was simple enough to just select the event from the drop down list at the top of the code window. Unfortunately, the drop down windows in the C# code window down show events, only the methods already implemented.


Fortunately, it is just a matter of looking in a different place. If you are looking at your C# code page, hit Shift-F7 to flip back to designer mode. Select the component you want to wire up an event for. Now look at the properties window (if you don't have it up, go to the View menu and select it). Notice the little lightning bolt icon in the toolbar? Click this and you will get to the list of public events exposed by the control. If you double click an event, the IDE will automatically insert the code skeleton and wire up the event. If you already have an event handler written, just click the arrow to get a dropdown list of all of the functions that can listen to the event.



Property list for a Windows Form (events button circled)

Event list for a Windows Form

Database Connection String Wizard

Here's a simple trick for generating connection strings to your database. On your windows desktop, create a file with the *.udl extension. You'll notice that the icon for the file changes. Now double-click on the file to open it. This will launch the wizard for creating your connection string. Be careful, the wizard starts on page two. Backup to the first page and pick your target database protocol. Then step through the wizard to complete building your connection string. When you are finished, right click the file and open it with a text editor. You'll see that it contains your connection string!

Roly Poly


I made my first trip to Roly Poly today, and I must say that it was a good rolled sandwich. I had eaten some of their items before, but only as part of a company function where we had ordered a platter. I had the chicken caesar, and it was great! Good thing I ordered the full rather than the half though. Sometimes I get tired of eating typical fast food (Wendy's, McDonald's, Taco Bell, Arby's, KFC). It's nice to find something a little bit different. I think Roly Poly make it into my "something different" rotation.

Outsourcing

Is outsourcing really as bad as everyone makes it seem? On any given day, you can pull up the Slashdot website and find at least one story proclaiming that the number of jobs available for highly technical people are dwindling away. I'm not so sure that this is as big a problem as what popular media makes it out to be. What I believe is happening is that large businesses that aren't focused on technology are finding the right people to do the work, while companies that are focused on technology are demanding more from the people they do hire. Businesses that aren't focused on technology, such as the hotel industry, groceries, and services companies, don't need a lot of programmers and developers. What they do need are technicians, they need what are essentially the plumbers of the information age. Just as most companies don't hire pipe designers and fluid engineers when they have plumbing installed in their building, there isn't a need to hire software architects and developers when installing information systems. Instead, what these companies need are possibly a couple of maintenance and management staff on board to be sure that the current system runs well, and that the business is prepared for future developments. This roughly equates to the position of operations and facility manager, and a couple of on-site janitors.


Occassionally at my last job I would go on-site for a particular manufacturing customer and find that they had a huge software development office. The manufacturer wouldn't have anything to do with technology, yet they would employee more engineers to work on their internal information systems than the design of their product. It just didn't make any business sense. So I'm not altogether shocked when I hear about well educated, software engineers losing their jobs to outsourced developers. After all, the company has just realized that all they needed were technicians, and an occassional on-call specialist.


What I've seen from companies that are in the technology industry is that it is incredibly difficult to find good people. The folks flooding out of the non-technical industry and desperately looking for work had spent the better part of their career getting comfortable. Their technical knowledge is out of date, or so specialized in one particular vein that they don't offer much value to a company looking for a well-rounded developer. At my last job, I sat in on several interviews and spoke with our HR manager, and it was always difficult to find good people. Their were plenty of people out their looking for another cushy job that wouldn't demand much of them, but very few folks that had a well-rounded background in software development.


All of what I have seen first-hand has left me with somewhat of an unsympathetic attitude towards folks who have been hit by the latest wave of outsourcing. I'm sure that some truly good folks have lost their jobs, but I can't imagine that it will be difficult for them to find new work. I believe the vast majority are people who looked to cash in on the glut of venture capital dumped on the early dot-com market, and now businesses are learning to weed out those looking for a free ride from those looking to provide real value through their technical skill and ability to solve difficult problems.

Sirius2IM

I've been working on a little side project at home in the evenings. I love my Sirius satelite radio. I'm waiting to move into my new cube at work before I setup the antenna again, so I'm missing it terribly right now. While I was using it, I found a neat site - http://www.itsonsirius.com/ - which displays the current title and artist for every stream (they call them streams rather than stations since you aren't actually tuning to a different frequency). That got me to thinking about the latest version of MSN Messenger (version 7 or higher) which can display your Now Playing information from Windows Media Player. I thought, now why should WMP users have all the fun. So I wrote up a quick app that will read the info from ItsOnSirius. You select the stream you are listening to, and it sends that information to MSN 7 as your Now Playing information. I don't know that many Sirius listeners, but if you use a Sirius radio and MSN 7, you can find the tool here - http://www.sourceforge.net/projects/sirius2im

Book Review - The Dancing Wu Li Masters


This weekend, during the rides back and forth to Chicago (I'll explain later) I had the opportunity to finish a fantastic book. The Dancing Wu Li Masters : An Overview of the New Physics by Gary Zukav is a fascinating book that explores the revolution that has been taking place in physics since Einstein's theory of relativity and the birth of quantum physics. The book is made even better in that, rather than dive into the mathematical background behind the concepts of subatomic particles, quantum mechanics, relativity, and other theories, Zukav relates at almost a layman's level. Certainly a basic understanding of mechanics and would help, but really the less you know about physics, the better. This is due to the nature of what modern physics has discovered: the world doesn't work like we perceive it to work. So the fewer preconceived notions you have, the better.


About a third of the way through reading this book, I was sure that all physicist must be on some serious mind altering drugs. Concepts like Schroedinger's cat, multiple worlds, and relativity are just so different from the way we think about our world, that it is very difficult to wrap your mind around the concepts immediately. I think that is the gift that the great physicists of our time have. They have the ability to give up everything they have learned through experiencing the world, and accept new ways of thinking about how the world works.


If you are at all interested in what modern physics is saying about how our world works, if you just want an opportunity to marvel at the wacked out things these folks are thinking, I highly encourage you to pick up this book. I came away from it with a real sense of awe and wonder about how our world works.

Mice and Keyboards

As a programmer, I'm very particular about the tools I use. In college I got used to writing code using Vi, an antiquated command line only text editing program. To this day I still use Vi to occassionally edit text files or code. Sure, I use a slightly updated version with nice syntax highlighting and windows support, but it is still the same Vi where you could do all of your editing through a strange concoction of keystrokes and key combination. Using Vi, you never had to touch the mouse, which was good in its time since mice might not have been invented yet.


Just as I'm picky about the software tools I use, I'm very picky about the hardware that I use. Particularly keyboards and mice. I've become a very proficient touch typist. I'm frustrated each time I need to change keyboards, because invariably the keyboard maker has done something to "improve" their keyboard which throws off my ability to find the right keys. This comes up because when I arrived for my first day of work, I was greeted by a very, very poor keyboard. The keys didn't have the right clicky-ness feel, they stuck, the layout was all wrong.... I didn't like it and it had to go. When I went searching for a replacement, I realized just how much the tools of the trade have changed. Follow with me as we travel down my keyboard and mouse hall of memories.






The MacIntosh IIsi Keyboard and Mouse

The first keyboard and mouse and I used extensively were on the Mac IIsi we had growin up. Learning to type on this board was a "hunt and peck" affair. I didn't take a typing course until my senior year of high school, but I was quite good at using the "One-Finger-Wonder" technique to stab out what I needed. Mac's were unique, even at that time. One trait that endures even to this day is the one button mouse. Simple, yet utterly effective. Another neat feature of the Mac keyboard was the cabling. I plugged the cord into both sides of the keyboard to show that it had two ports. One port would plug into the back of the PC, and the other was used for the mouse. That's why the cable for the mouse is so short, it only had to run a couple of inches to the keyboard. Brilliant! As wth all keyboards of this time, it weighed about as much as it cost. The Mac keyboard is a good 10 pounds, if not more. All of the keys have a nice weight to them, and make an enticing clicking sound when you press them. Another unique Mac feature is the power button in the upper right hand corner.






Gateway AnyKey Keyboard and Mouse

Upon graduating high school and moving on to college, it was time to get a new PC of my own. I opted for a state of the art Gateway P100 with an Intel Pentium 100MHz processor, 16MB of RAM, and a full 1GB of hard drive space. It came with the Gateway AnyKey keyboard, and a standard two button mouse. The mouse is only interesting in that it had a half-hearted nod to ergonomics. The curved shaped was great.... if you were right handed. Lefties would be totally miffed by this mouse, but I didn't have to worry about that. This keyboard was awesome, and I used it for the longest that I ever used a single keyboard. It had an eight-way arrow pad, which was great for video games. I can't remember what the middle key does between all of the arrows, but I'm sure it had some use. It had not 12 but 24 Function keys (F1-F24). This was a boon when I needed to telnet into the school's UNIX machines and execute some odd-ball command. What really set this keyboard apart, though, was the fact that it was completely prorammable. The keyboard encoder could be reprogrammed on the fly to change any key to function in some other way. Software was available to backup and restore these configurations. Like I said before, I am a Vi user. The school labs all had Sun machines, and Sun machines have a different keyboard layout (sorry for the lack of a photo, but I never OWNED a Sun keyboard). On Sun keyboards, the Control key and CapsLock keys are switched. The Escape key and the tilde/squiggle (`/~) key are switched. And Sun keyboards had a variety of other special "function" keys (Stop and Halt come to mind). When I would back from my labs and go to work on my homework, I could download a new keyboard configuration and use my keyboard just like the Sun ones at the lab. Great! When I was done, I just switched it back to the original layout and I was on my way. I LOVED this keyboard. Unfortunately, it has seen too many years of use, and the keys started to fail. Something messed up the G and H keys, and when keys stop working, it's time for a new keyboard.






Ergonomic Keyboard and Optical Mouse

About the time the AnyKey died, the price of optical mice and ergonomic keyboards was falling. Optical mice had the benefit of not using a mouse ball to track movement, but instead detect motion through a tiny light sensor on the bottom of the mouse. It would detect the movement of the pattern under the mouse and move the cursor accordingly. Sun mice worked like this for years, but required a special mouse pad. The new series of mice would work on almost any surface, and you would never worry about cleaning the lint out of your mouse balls again (shiver). Another neat feature was the scroll wheel. This had been around for a while in non-optical mice, but this was the first mouse I had with a scroll wheel. The scroll wheels were a tremendously good idea. They allowed you to quickly scroll up and down a window, such as a web page or word document. No more hunting for the scroll bars. The wheel could also be depressed for a third mouse button. I never really used this feature until later software (Firefox's tabbed browsing) took good advantage of it.


The ergonomic keyboards were a pretty radical change as well. Mind you, I had spent the better part of the last ten years mastering a particular keyboard layout. I was more than a little wary of these strange beasts with their split layout and curved surface. I decided to take the plunge though, and after an adjustment period, found that the layout truly was much more natural. Regular keyboards cause your hands and wrists to be at too much of an strange angle. Your fingers are oriented straigh up and down while your wrists are bent to accomodate the width of your shoulders. This isn't such a problem for occassional PC users, but for someone who spends 8 or more hours a day typing, it can get to be quie a nuissance. I never realized how much so until I went from the ergo keyboard back to a laptop keyboard for work. They really are more comfortable, and only take a week or so of use to get really accustomed to. Still, I lost a lot with this keyboard. I was down 12 function keys, my 8 way arrow pad was down to a four-way cross, and my Insert-Home-Page Up / Delete-End-Page Down keys had been turned on their side.






Dual Optical Logitech Mouse

I liked my optical mouse, but I wanted more out of it. Enter the Logitech dual optical mouse. It was another right-handers only mouse, and the design really fit my hand well. It featured two motion tracking sensors on the bottom, which eliminated a lot of the jitter you get out of the single optical variety. It also had a handy extra button on the side. This button was configurable, but I liked the default, which was as a back button in your browser. The scroll wheel is still present. I absolutely love this mouse, and use it to this day.






Microsoft Comfort Wireless Desktop

Which brings us to my shopping trip today. I was really disappointed when I walked down the aisle at Fry's. All I really wanted was another ergonomic keyboard, and possibly a dual-optical mouse like I had at a cheap price. No chance. The hot feature now is wireless. At my desk, I really don't mind having wires, but there were very few choices for corded keyboards and mice. In addition, finding an ergonomic keyboard with a half-way sane key layout was a real chore. There are so many additional "feature" keys like homepage, e-mail, volume controls, finger-print readers, and so on that I was really put off. Frustrated with Fry's, I went to the local Target. There I found a reduced set of the same things, albeit at much lower prices. I decided I'd give the Microsoft Comfort Wireless Desktop set a try. It was an ergonomic keyboard with a mostly okay layout. Notice that my once mighty 8-way arrow layout is now down to an almost forgotten upside down T tucked at the bottom of the keyboard. My delete key up and swallowed (or did it delete it) the insert key. I'm not entirely upset about that as I found the insert key completely useless. Thankfully, I haven't lost any more function keys (although I do need F-Lock on to get to them), and I still have a full number pad. However, I am now completely surrounded by "helper" stuff around the keyboard. The left side has a zoom slider.... not sure I'll ever get into the routine of using that. It also has hot buttons for e-mail, web browsing, instant messenger, calendar, and my documents folder. Across the top are volume and playback controls, as well as a customizable set of keys. My function keys are now overloaded to offer common editing functions with the F-Lock is turned off. The built-in wrist pad is actually pretty comfortable. After using the keyboard this evening, and to write this post, I have to admit that I'm actually pretty hapy with it. Compared to the old mac keyboard, it is incredibly light, and the lack of cables dangling around does clean up some of the clutter in the room.


The mouse has it's ups and downs. I still prefer my logitech dual-optical mouse over this one, and when the wireless stuff goes to work on Monday, it will make a triumphant return to the mousepad. The wireless optical mouse is no longer bigoted to handed-ness (lefties welcome, Mr. Ned Flanders), but the design doesn't fit my hand quite as well as the logitech does. My back button is gone completely. There was a more expensive version of this setup which included a mouse with both a back, forward, and a couple of other extra buttons on it, but it wasn't worth doubling the price. The one new feature is that the scroll wheel now tips left and right to scroll horizontally. I'm not often faced with horizontal scrolling, so I'm not sure how useful this will be. It can't hurt anything though. One minor nuissance is that the wheel button itself is much more difficult to click. When doing so, it is very easy to lean and end up scrolling rather than clicking.


So there you have it. That is my history with keyboards and mice. I have pictures because I still have all of these old monsters laying around the house. The wireless stuff will travel with me to work on Monday, and I'll be back to hacking bliss!

The Rumors of my Death have been Greatly Exaggerated

Sorry for the long snap before posts. Over the holiday weekend, I caught some type of nasty sinus infection. Corbin had it first in the form of an ear infection. Jenn got him to the doctor and within a couple of days on meds he was back in good shape. I wasn't so lucky. I picked it up on Saturday. It got worse through Sunday. Monday I went golfing with my family, and added a sunburn to my misery. Tuesday we went to the zoo, which was a blast, but didn't help my cold or my sunburn. So my first day of work at Integral was a real struggle on Wednesday. Fortunately, I'm now starting to feel like I'm coming out of it. I'm not 100% back to good health, but at least I can breath through my nose again. I'll get some updates on here about the stuff I didn't have the energy to write about last week.

 
Jade Mason