Thanks to several useful suggestions from readers, let’s improve our Notepad clone before moving on to add more new features.
And seriously, thanks again for the pointers, everyone. I appreciate this kind of feedback more than you may realize, and I want this series to be as interactive as possible. I’m not a real/professional developer and am learning as I go as well. Thanks.
As you may recall, I tried to implement a semi-reasonable clone of the Notepad dialog that appears when you try to exit with a document with unsaved changes. I assumed that this dialog was something provided not by the system because I couldn’t find anything like it in Visual Studio. But as and jhoersch pointed out, this dialog wasn’t created specifically for Notepad. Instead, it’s a system-provided feature called a Task Dialog that debuted alongside Windows Vista as a replacement for an extension to the capabilities provided by the Message Box dialog.
Task Dialog was implemented as part of the Win32 API and so its native interface is designed for C/C++. But Microsoft provided something called the Windows API Code Pack so that developers could access this and other then-new system features using the .NET Framework in frameworks like Windows Forms and Windows Presentation Foundation (WPF). Sadly, however, the website that Microsoft used to maintain for this project, and the download itself, are no longer available. (Here’s an archived version of the site if you’re curious.)
I wasn’t able to find a copy of the most recent Windows API Code Pack download, nor am I sure that it would even work with Visual Studio 2019, and I’m a bit stunned that Microsoft doesn’t provide a way for non-C/C++ developers to access this necessary control today. But in researching Task Dialog, I did see that some independent developers have worked to create their own C#/.NET wrappers for Task Dialog, though none of these seemed ideal for our needs.
But the more I think about it, the sillier it seems for us to create our own form window to try and replicate the Task Dialog. So we’ll use a simpler workaround that will do for now. And if Microsoft ever does bring Task Dialog to Windows Forms, it will be very easy to swap this out for the real thing.
The workaround, suggested by tjernst, is to use a Message Box. In doing so, all we’ll really lose is the layout/formatting that we’d get with a real Task Dialog, since Notepad only used some basic Task Dialog features. The MessageBox object in Windows Forms lets us throw up a modal dialog that displays the application name in its title bar, a message, and then provide three buttons—in this case, OK, No, and Cancel—that map very closely to the three buttons—Save, Don’t Save, and Cancel—that Notepad’s Task Dialog displays. It’s an acceptable compromise. (And it also lets us use standard return values, as Jordan Meyer had recommended; that was something we could have done with our home-spun Task Dialog as well.)
It’s also really easy to implement.
As you may remember, our Notepad clone currently includes two form windows, Form1, which is the main application window, and SavePrompt, which is what I now know should be a Task Dialog. So the first step is to remove SavePrompt from the Visual Studio project: Right-click it in the Solution Explorer pane in Visual Studio and select “Exclude From Project.” (You could also choose Delete, but that will permanently delete the file from your PC, and you never know.)
Now, we need to change Form1’s Closing event handler to use a MessageBox instead of the now-defunct SavePrompt form. So display Form1.vb and find the Form1_Closing event handler. Right now, it looks like so:
If TextHasChanged Then SavePrompt.ShowDialog() Select Case SavePromptValue Case "Save" ' More soon Case "DontSave" ' Do nothing Case Else e.Cancel = True End Select End If
We need to make a few changes. First, delete the line that currently reads as:
SavePrompt.ShowDialog()
And replace it with this:
Dim SavePrompt As DialogResult = MessageBox.Show("Do you want to save changes?", "NotepadWF", MessageBoxButtons.YesNoCancel)
Then we need to perform different actions based on which choice the user makes. I’ve decided to switch from the Select Case block we used previously to an If-Then block. So the entire Form1_Closing event handler now looks like so:
If TextHasChanged Then
Dim SavePrompt As DialogResult = MessageBox.Show("Do you want to save changes?", "NotepadWF", MessageBoxButtons.YesNoCancel)
If SavePrompt = vbYes Then
' Display a Save Dialog here
ElseIf SavePrompt = vbNo Then
Application.Exit()
Else
e.Cancel = True
End If
Else
Application.Exit()
End If
If you run the application now, you’ll see that it works as before but with a cleaner-looking Message Box. It’s not identical to the Task Dialog window that Notepad uses, but it looks more natural. And if we ever do get Task Dialog back, it will be easy to replace the Message Box then.

While we’re improving our code, Tony Ansley suggested another change that I think is worth making. I had used a SubString method in the text box’s TextChanged event handler to determine whether the text had previously changed. It currently looks like this:
TextHasChanged = True If Me.Text.Substring(0, 1) <> "*" Then Me.Text = "*" + Me.Text End If
But he recommends doing this more efficiently by eliminating that method call. So let’s make that change, along with a related addition suggested by SoundersFan. Delete the body of that event handler and replace it with the following:
If TextHasChanged = False Then Me.Text = "*" + Me.Text TextHasChanged = True End If
We need to make two other changes: We have to set TextHasChanged to False when the application first runs and when we open a text file. Otherwise, we’ll get the Save prompt when we try to exit, even if there are no changes.
To handle the first instance, select Form1 Events from the middle drop-down at the top of the code editor. Then, choose Load from the right-most drop-down. In the Load event handler code block that appears, add this:
TextHasChanged = False
And to handle the second, locate the OpenToolStripMenuItem_Click event handler. Add the same line of code shown right above the Catch statement in the Try block. The try block should now look like so:
Try
TextBox1.Text = File.ReadAllText(OpenFileDialog1.FileName)
Me.Text = OpenFileDialog1.SafeFileName + "- NotepadWF"
TextHasChanged = False
Catch ex As Exception
MessageBox.Show("Something happened.")
End Try
As you can see when you run the application, it still works as before.
Finally, Jordan_Meyer also recommended a method for testing for text changes more capable. This is actually pretty brilliant, and I may eventually make this change. But because it exceeds the capabilities of the real Notepad, as he points out, I’m going to sit on it for now. But that’s a great idea, and it could point to a future where this app actually offers features that the real Notepad does not. It’s a possibility.
With technology shaping our everyday lives, how could we not dig deeper?
Thurrott Premium delivers an honest and thorough perspective about the technologies we use and rely on everyday. Discover deeper content as a Premium member.