Monday, December 31, 2007

it's coming

I have begun my migration to Blogsphere. Not being a Domino web developer I'm struggling mightily, but it is coming along. I'll be sure to post how I did the migration from Blogspot / Blogger to Blogsphere. It's not going to be easy.

Here is a preview of what I have so far: Not much so far. Watch this space for updates, or check the new URL if you want to watch me struggle. :-)

Friday, December 28, 2007

SnTT: Hiding an ActiveX control when you hide its layer

My friend Adam (aka Wombat) is working on an app for doing employee badges. The badges will have the employee photo on them, so the plan is for the HR people to take pictures of employees, crop them down, and print out the badge on a special printer. Adam already has an employee management system built in Notes, but he had never worked with image editing before. I pointed him in the direction of an imaging component. He settled on one, figured out how to make it work in Notes, then started adding it to his employee management system.

The users wanted to just click a button, have something pop up that would let them select the picture and crop it, then they just save it. That was easy enough if he launched a separate document, but that was a little intrusive. His first approach was to put the control on a form and call it using NotesUIWorkspace.DialogBox. However, ActiveX controls won't display at all if you use DialogBox.

The next approach was to use a layer, which worked... mostly. The problem was the control would remain visible after the layer was hidden:

Adam figured out that by adding a call to MessageBox after RefreshHideFormulas the control (the big box with DEMO in the center above) would disappear. He was okay with that solution, but it was another box for the users to click and I knew there had to be something less intrusive.

He sent the app to me and after extensive testing I learned that any change in focus would cause it to render properly. Eventually I stumbled across using Tab, which would consistently make the artifact disappear. Then the great hunt for how to get Tab to work.

Adding SendKeys "{TAB}" after the RefreshHideFormulas call always generated an "Invalid Procedure call" error. I went through everything I could think of short of closing and reopening the document -- which would have cleared the artifact, but was a little too harsh for such a simple thing. No matter what I still got an "Invalid Procedure Call". I finally decided to dig into my API toolkit. And after numerous failed attempts I decided to get medieval and dragged out keybd_event:

Declare Sub keybd_event Lib "user32" (Byval bVk As Byte, Byval bScan As Byte, Byval dwFlags As Long, Byval dwExtraInfo As Long)
Const VK_TAB = &H9

Then to call it:

keybd_event VK_TAB, 1, 0, 0

What it does is it stuffs the keyboard buffer with a Tab, and executes it immediately. That's what SendKeys supposedly does, too, but this works! No more weird artifacts, no errors, it just silently does its job. It isn't cross-platform, but Adam is in a Windows-only environment so this was an acceptable solution for him. He's using an ActiveX control so it's definitely not cross-platform anyway.

You can easily extend Notes with ActiveX controls, but presenting them in a way that makes them easy for users to interact with can be a little tricky. Maybe one day IBM will make controls on DialogBoxes display properly, and perhaps they'll get them to hide when you hide their containing layer. Until then hopefully this tip will help anyone else who has struggled with a similar problem. :-)

Geothermal works!

Our utilities company provides us with a year to year comparison of our gas and electricity usage. The October bill surprised us tremendously, but the November bill has proven that it is a trend.

Our total gas and electric bill for 2006 was nearly $260. This year it is closer to $130. Our heating season is only 3 - 4 months so we won't enjoy this level of savings for long. I'm sure going to enjoy it while it lasts, though.

I have some hunches about the increase in electricity. It is likely a combination of the geothermal pumps that run constantly to circulate the fluid, and us being gone for two weeks during a cold snap and the person house sitting turned on an electric blanket that we found was still on when we got home. I'm going to look at the pumps and see how many KWH they use and calculate how big of an impact they are having.

Wednesday, December 26, 2007

most (un)likely

In Facebook there is a Superlatives app that lets you vote on what your friends are most likely to do or be. One of my friends proposed this:

I think that is more UNlikely. :-)

Wednesday, December 19, 2007

Toolbox for troubleshooting processes and connectivity

I have had a rather nasty issue for the past month or so with a VB6 application I'm rewriting in VB.Net 2005. It uses free threading in VB6, and it's not done very well. It memory leaks like crazy, floods the DB server with connections, and crashes a lot. With the previous author using advanced techniques like "Dim X As Variant" and then assigning it to everything from strings to objects to function addresses -- all in the same procedure -- troubleshooting was exceedingly difficult. In the course of making sense of this madness I amassed a toolbox of free tools and Windows utilities you can use to troubleshoot processes and connectivity.

Stuff built into Windows (XP)

ipconfig - The first place to check when you're having network issues. Use this to verify the IP address is set, and add the /all switch to make sure you have the correct DNS entries.

- The second thing to look at when you're having network routing problems. With the print flag it shows you every identified route from your computer.

Free tools

Process Explorer - This gives you an accurate and complete picture of how memory is allocated and everything a process has loaded. It will even tell you every Registry key a process touches, which can be tremendously handy.

[Side Note: Task Manager has numerous limitations, but two really stand out as truly egregious. First, it doesn't accurately report virtual memory. It actually tells you the private bytes a process has allocated, which is not the VM size. Second, it doesn't tell you external modules (DLL's, spawned applications) a process has loaded. If you see that an app is hanging you don't know if it's a problem in the application or one of the DLL's or applications it calls. Process Explorer plugs both these holes, and a whole lot more.]

Network Monitor - Allows you to capture and analyze TCP/IP packets.

- A network protocol analyzer that takes the Network Monitor to new levels. It can be used with everything from TCP/IP to USB and FDDI. This is the ultimate tool, but it does have a steep learning curve.

iperf - This handy utility will measure the bandwidth, delay jitter and datagram loss between hosts. This is most useful in WAN scenarios so you can verify what the bandwidth is between locations, but you can also use it as an indicator of network congestion on a LAN. Note that this is also sometimes called lperf, with a lower case "L" at the beginning. The correct name starts with a lower case "i".

I also want to mention that a great collection of tools is available from Sysinternals. This was a private company making tools (such as Process Explorer and Network Monitor) to plug holes in the base offerings by Microsoft. Microsoft bought them in 2006, but the same people are still working on the tools so the quality is still great. There is a wide range of tools, so you'll probably find something useful. :-)

8th Annual Lotusphere session database now available

Ben has one again shown his commitment to our community by pulling this together on his own. Get your copy by starting here.

Tuesday, December 18, 2007

Ed Brill: Perception is reality

(the post title is a trackback link)

Karen Demerly (comment #16) makes an extremely compelling argument:
So what is IBM/Lotus doing to change the perception of IBM/Lotus? I think that's been asked here before. It's obviously not always about price points, or ship dates, or whether the refresh button is F5 or F9.

I think IBM ought to be throwing Lotus products off the parade float - giving it away, putting it in the hands of every youngster in the world. Our kids should grow up on IBM software. Then their perception will be changed, won't it?

This is exactly where IBM has always failed: IBM has never really marketed to consumers. Lotus never targeted Notes at consumers, either, but the world was different then. Most homes didn't have a computer, they were strictly the purview of business. IBM bought Lotus just as the consumer appeal of the Internet was building, but Notes and Domino continued as business-focused products while the widespread consumer adoption of the Internet passed it by. IBM/Lotus added Internet-oriented features to Notes and Domino and supported a wide array of protocols, but it was always in the context of business use. They never made any attempt to make Notes or Domino sexy or have mass appeal.

While they were ignoring the consumer side altogether IBM didn't count on a company like Microsoft entering the picture. Microsoft wanted a piece of the business pie but couldn't compete solely on technical merit, and had no chance of getting a foothold in large enterprise IT shops. So they started mudslinging and spreading FUD while they flailed about trying to create (or buy) products to compete with IBM's Lotus offerings. They used smaller companies who were less risk averse as their starting point, eventually ending up with some products that are mostly good enough for fairly sizable companies.

The number of these smaller companies that were started in the 80's and 90's and grew to be megacorps dwarfs the number from the previous 40 years. And virtually all of them grew up with Microsoft products. New companies in the new economy were looking for small and agile solutions that were easily integrated and extremely flexible. They didn't care if they had to rip it all out and start over every year, they only had 40 employees. By the time they grew to 400 employees Microsoft was so firmly entrenched that they couldn't back out.

IBM was still lumbering along in the old mindset while the world was changing around it. They had Domino, which with some TLC and attention could meet the growing SMB needs. Instead of responding to this by focusing on Domino they went the Workplace route because it was big, monolithic, and fit traditional business models IBM was comfortable with.

I agree completely that IBM needs to get Lotus products into consumer hands, because those are the products most relevant to consumers. They don't care about autonomic computing but they do care about having a one stop shop for all their needs. I don't think I've ever heard any end user type say "damn I wish I had more applications to open!" No, they want to open one application and have it do everything they need. Notes can do that. Domino could be scaled down and reworked so it could be used as a personal web server and file server.

Until IBM groks in fullness that consumers ultimately drive business IT they're going to be losing market share -- or at least the perception of market share.

Monday, December 17, 2007

Is multi-tasking making us dumber?

One of the business blogs I have in my Netvibes is Tim Berry. In a post today he picked up on an article from The Atlantic (via Paul Barsch)which states that neuroscientists have discovered that multitasking actually makes our brains atrophy.

Multi-tasking messes with our brains in several ways. At the most basic level, the mental balancing acts that it requires—the constant switching and pivoting—energize regions of the brain that specialize in visual processing and physical coordination and simultaneously appear to shortchange some of the higher areas related to memory and learning.

Certain studies find that multi-tasking boosts the level of stress related hormones such as cortisol and adrenaline and wears down our systems through biochemical friction—prematurely aging us. In the short term, the confusion, fatigue and chaos merely hamper our ability to focus and analyze, but in the long term they cause (our brain) to atrophy.

That buzz you get from Twitter-ing, Facebook-ing, RSS-ing and blogging, all while on Skype and rearranging your iTunes playlists is just your brain telling you to slow down. Sometimes being a Luddite geek is a good thing. :-)

Sunday, December 16, 2007

SnTT: Resolution-specific content (Windows only)

Okay, so it's not Thursday. As part of this application I'm working on I want to maximize visible content by making the UI fit to the whole screen. I'm using embedded views, which can be set to autofit both the height and width of the screen, but the height will get set to 1", which is about 3 - 5 lines. So what do you do?

I did a semi-hack to come up with something that's mostly good enough. It consists of:
  1. A two-frame frameset. The top frame has a header form, the bottom is computed to display a content form.
  2. Multiple content forms for the resolutions I know users will be using. They are named, for example, Content_1024x768 with an alias that is just the resolution.
  3. Some Win32 API code to get the current screen resolutions.
  4. Code in the header form's QueryOpen to get the current resolution.
  5. An interesting technique I learned from Kevin Pettit via SuperNTF for caching the resolution.
Here is how it fits together. The QueryOpen event of the Header form contains the following:

Option Declare
Use "LS.BE.Win32API"

Sub Queryopen(Source As Notesuidocument, Mode As Integer, Isnewdoc As Variant, Continue As Variant)
Dim session As New NotesSession
Dim db As NotesDatabase
Dim profile As NotesDocument

Dim resX As Long
Dim resY As Long

Call GetRes(resX, resY) 'LS.BE.Win32API

Set db = session.CurrentDatabase
'Here is the technique I lifted from SuperNTF
' You create a profile doc, but you don't save it
' This creates an in-memory cache but doesn't bloat the database
Set profile = db.GetProfileDocument("ServiceDatabase", Session.UserName)
Call profile.ReplaceItemValue("ScreenResolution", Cstr(resX) & "x" & Cstr(resY))

Set profile = Nothing
Set db = Nothing
Set session = Nothing
End Sub

The real magic happens in LS.BE.Win32API script library:

Const HORZRES = 8
Const VERTRES = 10

Declare Function GetDesktopWindow Lib "user32" () As Long
Declare Function GetWindowDC Lib "user32" (Byval hwnd As Long) As Long
Declare Function GetDeviceCaps Lib "gdi32" (Byval hdc As Long, Byval nIndex As Long) As Long

Sub GetRes(X As Long, Y As Long)
Dim hDesktop As Long
Dim dcDesktop As Long

'Get the handle to the desktop
hDesktop = GetDesktopWindow

'Now get the device context of the desktop
dcDesktop = GetWindowDC(hDesktop)

'And finally, get the dimensions of the desktop
X = GetDeviceCaps(dcDesktop, HORZRES)
Y = GetDeviceCaps(dcDesktop, VERTRES)

End Sub

The Content form is computed as follows:

When the frameset opens the Header form's QueryOpen grabs the screen resolution, then the content frame pulls that out and uses it to calculate the form to load. What this gives me is a way to create resolution-specific content and dynamically put it into a frame. Unfortunately this is a Windows-only approach, but I'm sure something similar could be done using Java.

This LotusScript was converted to HTML using the ls2html routine,
provided by Julian Robichaux at

Imitation is the sincerest form of flattery - Part 2

Subtitle: Why Development by Collaboration Is A Good Thing

First I borrowed from Notes 8 to update the UI for an app. Now I'm borrowing even more heavily from Ben Langhinrichs to make that application even more functional.

The challenge: Take four databases that have been in development for over five years and slowly grown into one application and provide a single cohesive interface. Provide a compelling UI that is intuitive and, well, prettier.

It's a pretty tall order, and it's something I have wanted to do for years. The core to these records is the workflow section, which was really rather simplistic. It consists of anywhere from two to six steps, with different groups responsible for each phase. The challenge was to present this in a coherent way without unnecessary screen clutter. The previous implementation was like this:

Lots of redundancy, lots of visual clutter. I started thinking about how I could use layers, and I remembered Ben's use of layers to put controls beside a section title. Perfect! It took some work to get it laid out (and a couple of e-mails to Ben), but I finally got it.

I came up with a technique I call section tables. This lets you present a single cohesive table to users, but they break apart to provide more information. I am using it for workflow. Here it is all collapsed...

And with a couple of sections expanded.

Here is a sample database for you to look at while I'm finishing up this application. I'm still pulling everything together to make it cohesive but I'll be doing some posts detailing how I did all this. Without the resources offered by the community I don't think this would be possible in such a short amount of time, and I'm humbled to be standing on the shoulders of giants.

Friday, December 14, 2007

Microsoft's idea of backwards compatability

Office 2007 SP1 was released recently. Anyone who installed it and recompiled their Access projects (accde, ade or mde) discovered that the application is now only usable by someone who also has Access 2007 SP1. Microsoft is aware of the problem and has included three options for correcting it:
  1. Install Office 2007 SP1 on the computer -- *duh*
  2. Create the compiled application on a computer without SP1 installed -- *double duh*
  3. Use the 2007 SP1 version of the Access 2007 executable file -- are you freaking kidding me?!
Apply Office service packs with caution.

Thursday, December 13, 2007

'tis the season for anniversaries

Quick, where were you on December 16, 1947? Chances are I don't have any readers who were even alive, but you're all reaping the benefits of that fateful day. It's when the transistor was invented by Bell Labs! :-) Computerworld has a nice writeup about how the transistor has changed our world. It makes me wonder what the future holds.

With all the craziness of the past few months I managed to miss a couple of more somber but very important anniversaries. Long-time readers may remember that Myron's father, Theodore Pstrak, died on December 2nd, 2006. Both Ted and Helen (Myron's mother) are of Ukrainian descent, and they have a pragmatic (some would stay stoic) outlook. When Ted died Helen related a conversation she had with her father shortly before he died in which he said "Die is die". There isn't anything the living can do to bring back the dead so you have to move on. We have, to the best of our ability, but that doesn't mean Ted isn't still remembered, missed and loved.

On October 12, 1998, Matthew Shepard was murdered in Laramie, Wyoming. The murderers used a "gay panic" defense, claiming that Matthew's sexual advances caused temporary insanity. Eventually one threw the other under the proverbial bus, brokering a deal where he would testify in exchange for not getting the death penalty. In an act of compassion Matthew's parents arranged a deal where the second murderer also would not get the death penalty. Matthew's father is quoted as saying life in prison shows "mercy to someone who refused to show any mercy."

This sparked a national debate on what constitutes a hate crime. Matthew's parents created the Matthew Shepard Foundation to champion equal rights, and the Matthew Shepard Act is making its way through Congress. This legislation would add gender identity and sexual orientation to the federal definition of a hate crimes. It passed the House in May and the Senate in September. The president vetoed it. It was then attached to a Defense Department authorization bill and resubmitted, but was dropped a few days ago when it failed to gain the necessary support. It is painfully obvious to me that "liberty and justice for all" is a foreign concept to our current administration.

Wednesday, December 12, 2007

Rooms for Lotusphere are all gone!

I guess I should have booked earlier. Where does one acquire a "corporate travel department"? Looks like I know what I'll be doing this weekend.

UPDATE (12/16): Thanks to everyone who expressed concern that I'd be sleeping in my car and bathing in the fountain outside the Swan. I have a room and am all set. :-)

Monday, December 10, 2007

If you use MS Access 2003 do not upgrade to Office 2003 SP3

Since I'm responsible for an ERP written in Access (yes, a full ERP in Access 2003) I'm extremely apprehensive of anything that might affect Access on end user's PC's. Office 2003 SP3 doesn't disappoint. There are several known issues but they pale in comparison to the problems being reported in the wild. These include Access applications that simply stop working in SP3, design elements being corrupted, and subforms that stop inserting records. Scary stuff indeed.

Couple this with Microsoft having to release the Access 2007 runtime three times -- and it's still got problems -- and I'm wondering if they do actually QA this stuff before they release it. I had a friend who worked for Oracle who used to joke their testing consisted of "SELECT * FROM Emp. Looks good? SHIP IT!"

Friday, December 07, 2007

Guess what company they're talking about

Here are some excerpts from a few blog comments. Can you guess what software vendor is being taken to task?

If you guys were in action, you'd have a beta.

Silence isn't exactly the way you develop a platform and engage developers. Silence isn't exactly the way you interact with customers and collect their pain points and desires to create a feature list for the next release. In the end, silence is a good way to create false expectations and alienate your developers and customers who care enough to follow this blog. People who follow this blog are not exactly your casual users. We are your power users. We are your core developers. We are your fans.

I'd like to point out that the community hasn't been confusing silence with inaction, but has been (correctly) equating silence with *uncertainty*.

You have zero credibility with developers. You need to be upfront, honest, and open.

So who is being raked over the coals? It's actually Microsoft and this is taking place on their own IE blog. The post from last week had a similarly icy reception. What has web developers so riled up? Well apparently there was a meeting in Redmond this week to discuss IE8. The only information coming out of that was that the next version of IE is going to be 8. No information about features, plans, or anything else, even to people who are design partners. It has been a year since IE7 was released and the IE product manager has been virtually silent about any future plans. Bill Gates committed to a 9 to 12 month release of IE updates, so some people are pretty pissed. Read more about it at Computerworld and Molly Holzschlag's blog.

See, MS developers do call MS to task sometimes. :-)

Tuesday, December 04, 2007

IdeaJam blog widget

Matt has updated the IdeaJam blog widget. I missed this when it was posted back in November.

UPDATE: Bruce has posted another version.