Thursday, May 26, 2005

The Ides of February

The first week of February turned out to be a really bad week.

I was working on several parts of the project where we had seriously underestimated the amount of time they would take. Added to that, Ted was taking too long on his tasks and needed more supervision than I had time to give. And the end-of-February deadline, now just four short weeks away, loomed larger than ever in my mind. All these factors compounded to exacerbate my worries, but I was relieved by the thought of my upcoming three-day weekend, a yearly family ski trip to visit my aunt and uncle in Vermont over Superbowl weekend.

A group of a customer's operators were traveling to Relay Corp. for a week of training so I arranged to have Ted sit in on the training for two days. It was expensive for us to pay for his time while he didn't work on the project, but it was worth it to get him up to speed on our business. At least it got him to stop calling our technology "widgets."

Late in the week Rutherford let us know that we had a meeting with Victor Relay, the President, about the timeline. (It was typical for him to let us in on meeting dates with about 15 minutes to prepare. I've always suspected it was to give himself a preparedness advantage.) I was enthused that we would finally be able to talk about our timeline concerns and project struggles. Our Engineering Dept. felt warm, so I grabbed a drink of water. I wasn't sure if it was pre-meeting jitters or our cantankerous HVAC acting up again.

Victor started the meeting with a very open-ended question.

   "Well, how's the Oswald Project coming?" he asked, looking at me.
   I explained frankly: "Not so good. We're running into some hurdles and it might mean that we'll miss our deadline."

There. I'd said it. It felt good to get it in the open and off of my chest. But surprisingly, Victor didn't follow it up. He seemed more interested in talking about the nuances of the UI than about Our Big Problem. He honed in on a particular part of the project that I had been working on, a representation of a folder-gluer with a symbol underneath it for every trigger position. I explained that in order to finish the UI in the time allotted I had changed the spec from showing each trigger directly under its position on the folder-gluer. The new method spaced out all triggers in a common area and drew a line from the trigger to its position on the gluer when it was selected.

(In the design phase I had shown a mock-up screen with 4 nicely spaced triggers, but the actual software was supposed to be able to support up to 24 triggers. Not that most installations shipped that way, but they could. There was no way to space 24 triggers directly beneath the folder-gluer. Faced with an impossible specification, I changed it.)

   I tried to carry the conversation forward, but he tenaciously held onto this single UI point. "That won't work!" he cried. "How will operators know which trigger they're looking at?"
   He had a point, but so did I. "They didn't know what trigger they were looking at in the mock-up, either," I countered. "This isn't any different."

But he wouldn't let it go. I could feel myself getting more frustrated. I stood up, grabbed a hanging whiteboard and put it sideways on the boardroom table. I drew the screen and drew out my problem. Aha! I'd clearly illustrated why I was right and he was wrong, I thought.

Rutherford quietly snuck out a side door, leaving his notes on the table as if he would come back. It was the second time he'd made such an exit at an Oswald meeting. He didn't return.

This meeting was quickly getting out of hand. Victor changed tack. "I have an idea. How about when the operator touches a trigger we draw the trigger number and the stations that it's assigned to over here," he proposed, gesturing towards an open area in my drawing.

I stared at him blankly. We didn't have a way of finding out what stations a trigger was assigned to, and what he was suggesting was about a week's worth of work. "I don't think we have the time to try to put that in," I said weakly, wishing we could go back to talking about the timeline. My arm-turned-easel was getting tired and my voice felt parched.

   He didn't let up. "It's not too hard. We could just draw it here and here," he pointed again to the whiteboard.
   "Victor, we can put it in, but then we won't have time to work on other things. Besides, it wasn't in the spec."
   "But I don't see what's so hard about it. Besides, you already changed the spec!" He was incessant.

That was it. How could he not see how trivial this was? "I changed the spec to make it easier, not harder! Look, Victor! This isn't important to the project. It wasn't in the spec and it will take time to add it. That's time we don't have. The entire project is in danger of missing our timeline!" Other people in the room became noticeably nervous, but I didn't care. George, who was sitting next to me, tugged at my sleeve to try to get me to sit down. "We're already working insane hours on this project without adding features to it. This isn't the way the project was supposed to go. This isn't what I signed up for!"

There was a long, uncomfortable silence. I was aware of how hot my head felt. "Look," I said, softening, "In a perfect world it would be a nice feature to have. But I don't see how we can put it in and do everything else and still meet our deadline."

Victor nodded, and changed the subject. We talked for a little while longer, and all agreed to meet with him the next day. It was late.

- - -

We got back to work--our 2nd shift--but later that evening Victor called and asked to see me. I walked into his office, a large, well-furnished room the size of Antonia's and my first apartment. I thought I knew what he was going to say but he surprised me. Instead of discussing the obvious, he talked to me about leadership. He pointed out that I had disillusioned my team and offered suggestions for building strong teams. Usually, I would have soaked up that kind of advice. But after our clash I was in no mood to learn. I told him that I thought the project had a 1 in 3 chance of success, and we would do our best. I left his office not knowing where the project was headed, and I wondered if he did, too.

Regardless, at least I had my weekend to look forward to.

The next day, after a fitful night's rest, I felt a little strange. I went into work but my head was in a vice and my bones were being stretched on the rack. Instead of Antonia picking me up at work on the way to the airport as planned, I drove home early take a nap and sleep it off. When I woke up, my fever registered 103°. We needed to leave immediately to catch the flight, but I could barely get out of bed, much less drive to the airport. I was loath to cancel the trip, but we had no other option.

Instead of swooshing down the snowy slopes I spent the weekend bottled up in bed.

On Sunday, I unpacked my unused suitcase. It was the symbol of an unrealized vacation, and combined with the knowledge that there would be no more vacations for a long time to come, it felt terrible. That was one of the worst weekends of my life.

Wednesday, May 25, 2005

This is the Part Where I Introduce Victor Relay

If there is a single reason why I still work at Relay Corp., it's Victor Relay. Victor offered me my first job, a summer internship, while I was still in college in the mid 90's. I accepted. I didn't have a job description, but I was handy with computers and Relay was starting to move into the digital age, so I made myself useful and carved out a niche. When I met Antonia that same summer and got a full-time offer that fall, I stayed.

Victor taught me about business, about dealing with people and about life. He wasn't just a boss, he was a mentor. As Relay Corp. grew (I'm employee #7) to over 50 employees, including a London branch, Victor had less time to spend with me, but the time that he did was just as important. When my salary came up for review last year I negotiated directly with Victor. My direct boss at the time, Rutherford, was present only as a token to his position.

Victor was a great motivator and leader. As great bosses do, he made work more than just work. Work became a place to better my skills and myself. Since I loved the work anyway, I thrived. I designed and developed an ERP system that ran the company. When I decided to finish my Computer Science degree, Relay Corp. offered to pay my tuition. (I didn't accept, but that was for other reasons.) When Victor stopped by, it was to check on how I was doing, or if I needed better tools. (I always needed better tools.) If I had just returned from a vacation, he was genuinely interested in how my trip had been.

I'm not alone in my adulation. Many people at Relay would say the same thing. So would people at Victor's church and in his personal life. Victor's unique quality is that he makes people feel important. No matter what he's doing, he always has time to talk. And when he talks, he looks you in the eye, smiles and makes you feel like the most important person in the building. Former President Bill Clinton was reported to have such a quality. I've met only two or three other people like that in my lifetime.

With his good looks, pleasant charm and mellifluous voice Victor could've made a run at anything and been successful. But he chose to grow Relay Corp. and grow the people that worked there.

Perhaps one day I'll own my own business. If that happens, it will be to a large degree because of the influence that Victor has had on my life. I will focus on my people, believe in my company and make others believe in my company, and lead by example like Victor.

Here's to you, Victor. I hope I grow up to be like you one day.

Tuesday, May 10, 2005

A Disheartening Discovery

January was a long, cold month. Like a Polar Bear Club member's inaugural dive, knowing in advance how much I was going to be working didn't prepare me for actually working that much. George worked three days per week, so Mondays and Tuesdays (nights included) were our days to really shine. As the nights wore on Ted worked alongside me out of loyalty, but he would eventually wear down and call it a night.

Getting George to work more hours was like pulling teeth, and since he was training for an upcoming marathon he liked to go out for a nightly run. I was envious that he was going out and taking care of his body while mine was slumped over a keyboard.

I persuaded Rutherford to let the company reimburse me for working dinners. This soon settled into a routine of Panera Monday, sandwich Tuesday and Chinese Monday. By Thursday and Friday we were so exhausted we just worked late and went straight home.

By midnights I was physically spent, but my mind wouldn't stop racing. To fall asleep I started reading Showstopper, the chronicle of Dave Cutler and the development of Windows NT from 1988 - 93. As a software developer on a death march reading about other developers on their death march, it was remarkably prescient--and sometimes depressing--reading material. Though I was falling asleep later and later, I found myself waking earlier and earlier, eager to get back to the project and implement a new idea.

But even though our project productivity soared, it seemed as though outside events were conspiring against us. Nitin, our new Systems Administrator, had been on the job about three months and was finally taking charge of all major systems. But two mission-critical systems crashed badly one week, and as the resident expert on the systems (I had written one of them) I was called on to resurrect them.

Also, the project's popularity was its own enemy. Everyone wanted to see a demo of the mock-up screens I had done in Visio. I wound up performing at least half a dozen demos of the software. One for the field servicemen's annual meeting, one for the salesmen, one for visitors from our UK division, etc. We even jury-rigged a complete demo controller running off of a laptop input for a trade show.

Every time I was called on to do the dog and pony for the project, that meant that I wasn't working on the project. It was frustrating, but not as frustrating as what I found out in our annual year-end meeting.

Every year at the end of January the entire company gets together for a year-end review. If we hit our sales target for the previous year, everyone receives a 3% bonus. Having already spent the money five times over in our minds, we all cheer, shake the president's hand, and go home happy. But this year--even though we had hit our target--I was more interested in the projected numbers for the upcoming year. On the charts, in big, bold fonts, were revenue numbers from the Oswald project starting in May. May!

I tried to ask a few shielded questions about the sales numbers, but my answers were deflected. John Dell (no relation), our ebullient and well-loved Sales & Marketing Director, was confident in his sales team's ability to sell our finished-by-May project. And then I realized that even though I had told my boss and our Engineering Director that the March demo with our OEM was in jeopardy and the May date wasn't going to be likely, either, no one else knew.

Wednesday, May 04, 2005

Double-Buffered Drawing

Double-buffered drawing has been around for a long time. I won't try to improve on any on the tutorials and examples out there, which are probably better than anything I could do anyway.

This is just a post to show some example code for how to do this in Windows CE. The principles remain the same:

  1. Create an off-screen buffer
  2. Draw in the off-screen buffer
  3. Copy the buffer to system (or graphics) memory
Source snippets:
// Create an off-screen buffer to draw in
CDC dcOffScreen;
CBitmap bmpOffScreen;
dcOffScreen.CreateCompatibleDC(pDC);
bmpOffScreen.CreateCompatibleBitmap(pDC,
rect.Width(), rect.Height());

CBitmap* pOldBmp =
dcOffScreen.SelectObject(&bmpOffScreen);
dcOffScreen.FillSolidRect(&rect,
GetSysColor(COLOR_STATIC));

// Set the pointer to the up or down bitmap (if it exists)
if (state & ODS_SELECTED)
pBmp = (m_bmpDn.m_hObject ? &m_bmpDn : &m_bmpUp);
else
pBmp = &m_bmpUp;

// Draw whichever bitmap the pointer is set to
pBmp->GetBitmap(&bmpInfo);
TransparentImage(pDC->GetSafeHdc(), /* hdcDest */
pRect->left, pRect->top,
bmpInfo.bmWidth, bmpInfo.bmHeight, /* dest */
(HBITMAP) bmp, /* hdcSrc */
0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight, /* src */
CLR_TRANSPARENT);

// Blit the off-screen DC back over to the button DC
pDC->BitBlt(rect.left, rect.top, rect.Width(),
rect.Height(), &dcOffScreen, 0, 0, SRCCOPY);