An Asynchronous MessageBox

Recently, I had a project I was working on where we needed to be able to notify the user of a possible problem during a long running process. The results would not be ruined, or wrong, just likely incomplete. In this particular case we were collecting several pieces of information and sometimes one of those pieces were not available (say, for example the server was down, the file was missing, or it took too long). We wanted to let the user know the process had encountered an issue, but not stop it. Yet we wanted to also give them the option to retry it. So we presented an Abort, Retry, Cancel dialog like this one:

messagebox

The problem is that with a traditional MessageBox the entire process would be frozen. If this happens immediately after the user heads off to lunch, when they get back there would be no report, no data and most of the process would not have been run yet, for example.

What I needed was for the process to continue, but to allow the user to be able to take action before the process completed on anything that was found. For example, they see this error above and think: “oh crap, I forgot to copy over the report file.” So they put the correct file in place and hit “Retry.”

Therefore, I created the AsyncMessageBox class:

using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
namespace NonModalMessageBox
{
/// <summary>
/// Provides an asyncronous MessageBox. You can use this static class to
/// present a message to the usser while your code can continue to run.
/// You can attach to the AsynMessagebox.MessageboxClosed event to get the
/// result from the dialog once the user does close it.
/// </summary>
public static class AsyncMessageBox
{
private static readonly IntPtr HWND_TOPMOST = new IntPtr(1);
private static readonly uint SWP_NOMOVE = 0x0002;
private static readonly uint SWP_NOSIZE = 0x0001;
private static readonly uint SWP_SHOWWINDOW = 0x0040;
[DllImport("user32")]
private static extern IntPtr FindWindow(string PstrClassName, string PstrCaption);
[DllImport("user32")]
private static extern void SetWindowPos(IntPtr PintWnd, IntPtr PintWndInsertAfter, int PintX, int PintY, int PintCx, int PintCy, uint uFlags);
public delegate void MessageBoxClosedHandler(object PobjSender, MessageBoxClosedEventArgs PobjEventArgs);
public static event MessageBoxClosedHandler MessageBoxClosed;
private static bool MbolAlreadyShowing = false;
/// <summary>
/// Shows an asyncronous dialog
/// Fires the MessageBoxClosed event when it is closed.
/// This is a static messagebox, so only one can be displayed at a time
/// Once called, the event handler is detached
/// </summary>
/// <param name="PstrText">The message in the message box</param>
/// <param name="PstrCaption">The cpation on the message box</param>
/// <param name="PobjButtons">The buttons for the message box</param>
/// <param name="PobjIcon">The icon for the messafe box</param>
/// <param name="PobjDefault">The default button selected in the messagebox</param>
/// <returns></returns>
public static bool Show(string PstrText, string PstrCaption = "", MessageBoxButtons PobjButtons = MessageBoxButtons.OK, MessageBoxIcon PobjIcon = MessageBoxIcon.None, MessageBoxDefaultButton PobjDefault = MessageBoxDefaultButton.Button1)
{
try
{
if (MbolAlreadyShowing) return false; // failed – already displayed
DialogResult LobjResult = DialogResult.None;
// start a thread to show the dialog
new Thread(() => {
MbolAlreadyShowing = true;
LobjResult = MessageBox.Show(PstrText, PstrCaption, PobjButtons, PobjIcon, PobjDefault);
MbolAlreadyShowing = false;
}).Start();
// start a separate thread to wait for the result from above
new Thread(() => {
// now make it topmost
IntPtr LintHwnd = FindWindow("#32770", PstrCaption);
SetWindowPos(LintHwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
// Stay here until we get a result
while (LobjResult == DialogResult.None)
{
Thread.Sleep(10);
Application.DoEvents();
}
// create a hidden form so we can invoke back to the UI thread
// otherwise anyone attached to the event handler will get an
// exception if they try anything with the UI
using (Form LobjForm = new Form { ShowInTaskbar = false, Opacity = 0 })
{
LobjForm.Show(); // show hidden form – ui thread
// fire the event
LobjForm.Invoke(new Action(() => {
MessageBoxClosed?.Invoke(new object(), new MessageBoxClosedEventArgs(LobjResult));
MessageBoxClosed = null; // important to release this
}));
LobjForm.Close(); // close hidden form
}
}).Start();
return true; // created
}
catch
{
return false; // failed
}
}
}
/// <summary>
/// Event arguments for an AsyncMessageBox
/// </summary>
public class MessageBoxClosedEventArgs
{
public DialogResult Result { get; private set; }
public MessageBoxClosedEventArgs(DialogResult PobjResult)
{
Result = PobjResult;
}
}
}

Under the covers this uses a traditional MessageBox, but on background thread. You need to attach to the MessageBoxClosed event before you make the AsyncMessageBox.Show() call if you want to get the result. Here is how you use this method:

AsyncMessageBox.MessageBoxClosed += (o, e) =>
{
// handle the user response here
if(e.Result == DialogResult.Retry)
{
// retry code here
}
};
AsyncMessageBox.Show("There was an issue accessing 'quaterly report.xlsx'.",
"Quarterly Report Generator",
MessageBoxButtons.AbortRetryIgnore,
MessageBoxIcon.Exclamation);

Anyway, thought this might be useful, so I have shared it. wlEmoticon-hotsmile.png

Goodbye ModNotebooks, Hello OfficeLens

I like taking notes, the old fashioned way (by hand in a notebook, on… paper), but I like finding them the new way (using search on my PC). I love OneNote and how easy it is to keep an online notebook with all sorts of data. For example, due to archival rules some of my email starts to “disappear” from my work account after a couple of years. But some emails I like to keep – little nuggets of wisdom, notices, personal information and such I like to keep around. So, I export them to OneNote, where I can keep them safe.

So, I was living this duplicitous life of daily note taking with pen and paper but also filling my online notebook with all sort of information. I wanted to find a way to bridge these two. A few years back I was at a Microsoft convention and ran into a member of the OneNote team that turned me on to a small startup firm called: ModNotebooks. Their website is now gone, this is all you see:

mod.PNG

What they did was to send you a very high quality notebook, you would fill it up and ship it off to them. In the back of the notebook was a folder with a mail pouch and prepaid postage. They would receive it, scan it in for you and then dump the contents into your OneNote file behind the scenes. I filled 7 notebooks with them. But alas, their business model did not work, I am guessing, and they have gone out of business.

Now, I am left with my seeming duplicity again. wlEmoticon-disappointedsmile.png How do I get back to having my handwritten notes in OneNote again? Enter, OfficeLens.

I have actually been using this app for some time to scan travel receipts to PDF to turn in for expense reimbursement. And while I have always known I can use it for OneNote notes, I never tried it – namely because I had a better thing in ModNotebooks – or so I thought. Being forced to use something is sometimes what it takes. So, I gave OfficeLens a shot.

First, you download it to your phone. It comes on all three platforms (Windows Phone, iOS, and Android). Next, you hook up your Microsoft account (Live/Hotmail/MSN) and then you start scanning. It automatically finds the page and draws a border around it:

20170717_145127000_iOS.png

When you click the button at the bottom, it shows you what it got:

20170717_143239000_iOS.png

In the lower left, you can click the (+1), to add more page (up to 10 at a time – my only complaint – more on that later)* Once complete with your scanning, you click Done at the top right. This will take you to the “Export To” page.

20170717_143248000_iOS.png

From here I select OneNote and it asks me where I want to put it in my Notebook and when I click Save, it begins to upload it to my OneNote notebook:

And once it is in OneNote, it is fully text searchable, based on my handwriting. Yes, I said “fully text searchable” from my handwriting. Here is what it looks like once it gets to the final destination and I perform a search:

OneNote.PNG

Amazing, eh?

So, my only complaint is that the tool only allows you to scan in 10 pages at once. I wish there was a way to override this, for two reasons:

  1. I take a lot of notes and I fill 10 pages quickly. I have to get into the habit of scanning every week at this point to keep up. It is not impossible, but it would be nice to skip a few weeks and then scan them all in – in bulk. Right now, I have to upload it in several different batches of 10.
  2. I recently was working with legal documents and needed to print them out, sign them, scan them in and then send them off. The document had 11 pages. 11. 11! So, I had to scan 10 pages, then scan the last one and then find PDF merge software to merge them all together. That was NOT fun.

With that said, Au Revoir ModNotebooks. You were great while you lasted. I will likely be going back to using Moleskin’s and then using OfficeLens to digitize. We shall see… TUL (the “u” is long, so “tool”) has some nice notebooks too – I love their fine-point pen:

20170717_152827116_iOS

If you have any suggestions, please leave comments below. wlEmoticon-hotsmile.png

Going back to taking notes by hand…

 

Blogging from WP7

I recently got the Samsung Focus, running Windows Phone 7. This phone is awesome, thin, great battery life, easy to use and lots of great applications. I am using a free blog application simply called: “Blog Client.” If you are in the market for a new phone you have to check out WP7 phones.

Humor, That is Still Valid (Sadly)

A Texan dies and goes to Hell. The devil is excited as he has never met a Texan before. So he runs down to the lowest depths to find the Texan sitting with his boots propped up and a big grin on his face. The devil shocked, as others are wailing in pain and asks the Texan what he is so happy about. The Texan coolly replies, “Well, Devil, I thought it would be much worse, but this reminds me of Texas in June.” This steams the Devil…

So the devil heads back to the control room and turns up the dial a few more notches. Almost instantly the wails of pain raise across all of hell. He returns to the Texan who has removed his shirt, but still had that damn grin on his face. So the devil asks why he is still so happy as he obviously sees the others around him writhing in agony. The Texan coolly replies,” Well, Devil, it did get a bit warmer, but it feels like Texas in July. And that is my favorite month.” Now the devil is incensed.

So the devil goes back to the control room and cranks up the heat as high as it will go. The instant deafening roar of screaming is almost too much for the devil. But he gets back to the Texan who is in nothing but his boxers. Without being asked, the Texan states, “Devil, did you know my birthday is in August and this feels great!” The devil blew his lid in anger.

So the devil heads back, feeling dejected by this first representative from the great state of Texas; but he hatches a new plan. We walks to the control panel and turns it down as low as it would go. All smug now, the devil returns to the Texan to find snow piled in the corners, kids throwing snow balls, laughing and playing, icicles hanging from the ceiling… but what was this? The Texan was running around in circles, jumping up and down and whopping an hollering. The devil stopped him for a moment and asked what had gotten into him. The Texan replied, “The Texas Rangers just won the World Series!”

Just moved

With Microsoft moving away from spaces.live.com, I have migrated my site to WordPress. So far so good. It looks like the migration went without a hitch. I customized the default site they gave me and still have many more options to review… Way more capability than spaces ever had.

Still here – just overwhelmed…

I have not had a lot of time lately to do much of anything. Two weeks ago I was in sunny Orlando for Convergence 2008. That was a FUN event, but quite tiring as I was manning the Microsoft Office SharePoint Server (MOSS) booth. Talk about a product that gets people excited…MOSS makes them crazy. Smile

This week I am finalizing training material for the Troubleshooting and Supporting Microsoft Office 2007 in the Enterprise workshop [link coming soon]. In two weeks I deliver the workshop listed above to a customer here in Dallas and then two weeks later I will be delivering it again in Chicago. I am told from that point I will be delivering it about every 4 to 6 weeks. Surprised

Additionally, I have been working on a tool inside Microsoft for detecting add-ins in the Enterprise Environment (Microsoft Office System Add-in Scanner). When that tool is ready we will likely add it to the web somewhere with a white paper or something. Currently, the tool is still in beta and being used at about a half dozen customer sites.

The feedback from the tool and the workload with the workshop and my standard case load is keeping me buried at Microsoft. Oh, and personally I have a lot going on. My son is going to be 6 this summer, he is finishing up kindergarten and there is a whole book to talk about there – more on this later…

Anyway, you get the point… lots going on. Hot

williamWilliam Craig (5 y/o). 

More on Gadgets….

My latest gadget project (which I have eluded to in previous posts) is called "Mycrocuts." My partner (a fellow Microsoftie – Matt Dyor) and I are still working on tweaking the specifications and making some changes to the data structure and advanced features. We started work on this back in September 2007 and at the current rate it may be another month or more before we release it to the world…as I have more information I will share it. I am chomping at the bit to share this with the community, but we want to make sure we get it working JUST right before we release it.

Where have I been…

It has been a little over two months since I have updated my blog. But I am still here. smile_regular 

I have been and am still working on a new gadget that is a joint project with a fellow Microsoftie. I have been fairly hush-hush about it, but it is now in a trial phase. For now we are still keeping it quiet. I hope that in the next month or so we can open this up to everyone on the web.

Several months ago, a fellow employee who really liked the idea of The Magic Folder came to me with an idea to create a somewhat related gadget, but with a very interesting spin. We started working together on hashing out the specifications and then completed the first fully functional Beta this week…we even entered it into a Science Fair at Microsoft (held today).

While it did not win the Science Fair, it did draw considerable excitement. I cannot wait to share it with everyone. smile_teeth In closing, I will leave you with a screen shot of the gadget and a short blurb on what it is about:

It is a gadget that helps you keep track of things and spans the desktop and the network.

image

Stay tuned – more coming soon… smile_wink

First American Home Buyers Protection – Yeah, Right…

I know this is unrelated to gadgets, but it goes to my experiences in dealing with companies that care very little about the customer and more about their bottom line. Home Warrantee companies are notoriously cheap (and crooked). If they can they would allow a vendor to fix your A/C with bubble-gum and saran wrap – IMHO. smile_angry Well, recently, First American took the cake:

  • In early August our A/C started to leak. It is located in the attic above the kitchen, so you can imagine the mess it made of the ceiling, walls, floor, etc. So we had to turn the darn thing off in the hottest of Texas months to avoid more damage to the house.
  • We called First American to get a repair person out ASAP.
  • After a ton of headaches and a lot of calls, two days later we found they had a backlog and NEVER faxed our claim to a vendor. After talking with a manager they called one of their "side" people on a special "because the customer is pissed off list." smile_baringteeth
  • The vendor came out to our place 2 hours after the talk with the manager, walked up to our attic, looked at our A/C unit, got our description of the problem and then threw up his arms and said he was not going to do the work, and then even asked us for our $50 check for making a service call. I kicked him out the door… smile_baringteethsmile_angrysmile_sad
  • Calling back to First American, they refused to send out another vendor until the first vendor filled his report. WTF!!!! smile_angry
  •  I was livid by this time, 3 days of NO A/C in the hundred degree days of August!!! So after getting to another manager they scheduled us another visit in 2 days. But to make the "pain and suffering more bearable" and because we had a five year old in the house, the promised us a $150 refund to buy a portable A/C unit.
  • We promptly bought the portable A/C unit and set it up in the smallest room in the house – where we hunkered down for 2 days.
  • We followed the paperwork requirement to get the refund from First American – fax receipt and a special form confirming the purchase of the unit.
  • Two days later the A/C repair man came out and fixed the flooding problem with the A/C and everything was cool again. First American even waived the $50 fee usually associated with such work since it took so longer to get a competent vendor to our home. smile_regular
  • However, here is is over two months later and we sill have not received our $150 check. After five follow-up calls to managers we keep getting the same story:
    • The first manager approved the $150 which sent it to a special refunds department.
    • The refunds department then awaited our fax – they got it and confirmed everything was on the up and up. They then sent it to Accounting for approval.
    • Accounting received it and then forwarded it back to the approving manager for final verification – this is where it has been stuck for 6 weeks. smile_sad
    • Next, it goes back to accounting where they will validate the managers approval, sent it to a special processing department where they will then proceed to cut and mail the check.
    • From there it will take 7 to 10 business days for the check to arrive.
  • Ok, but we still cannot get a manager to approve our refund. Honestly, I think they wanted us to buy the portable unit to shut us up while we wait. The promise for the $150 is very likely a red herring. Because here is the real kicker:
    • In the last 8 weeks we have received three follow-up calls from First American verifying that our issue was resolved and that they were closing our ticket.
    • Problem is: not once did they ever mention our refund.
    • When notified of that fact they all say: "Oh, I see that in the notes here, let me get your request forwarded to the right department."
    • This implies that none of the above process has even taken place.

Anyway, I wanted to get my experience out there – maybe others have a similar experience. The important thing is that I will NEVER be choosing First American as a Home Warrantee company ever again and I strongly suggest if given the option to choose another – although I am of the opinion this entire industry is run by a bunch of crooks anyway.

Anyone know of a good warrantee company?