Chapter 27. Fun Stuff and Loose Ends

This chapter has a few topics that are slightly more frivolous than in the others. In it, you will learn some things that may be useful, but are more likely to lead to fun and games in some cases.

Create a Nonrectangular Window

Solution: Use a background image as a template and set a transparency key. When you do this, you are taking over all responsibility for painting and mouse interaction—the OS’s windowing system can no longer help you with standard tasks, such as moving, maximizing, resizing, and more.

In Windows Forms

First, you need to create the background image. In this case, it’s a simple black figure with a white background to represent transparency (see Figure 27.1).

Figure 27.1 This image is added as a resource in the app. You can use any image to represent the window for your application—as long as you’re willing to take responsibility for all interactions with it.

image

To allow the form to be moved, you need to handle the mouse messages yourself. In this case, to keep it simple, a mouse click anywhere on the form is translated into a simulated non-client mouse click to fool the OS into thinking the title bar has been clicked. The interop code is simple:

image

The form code intercepts the MouseDown event and sends a message to Windows telling it that we’ve clicked on the caption.

image

Figure 27.2 shows our custom window shape in action, complete with transparency.

Figure 27.2 Dragging on the black part will move the window, while clicking on the transparent holes goes through to the window behind it.

image

In WPF

The procedure is even simpler in WPF (see Listings 27.1 and 27.2). This code assumes the existence of an image in the project called WindowTemplate.png.

Listing 27.1 Window1.xaml

image

Listing 27.2 Window1.xaml.cs

image

Create a Notification Icon

Solution: Use the NotifyIcon class and attach a menu to it (see Figure 27.3).

Figure 27.3 Use notification icons with care—many users get annoyed at them if they are seen as useless and ever-present.

image

This example shows a simple menu attached to an icon (called DemoIcon.ico, which you will need to add to your project’s resources):

image

image

image

image

image

Note

Do you really need an icon down there? Many users resent them, so take care. Consider well if you really need it. Perhaps you can create one temporarily to notify the user of events, but then remove it once they’re acknowledged—much like the printer icon. At the very least, provide a way for the user to disable the icon.

You could also consider popping up a temporary window in a corner of the screen, like Outlook does with new mail notifications, or Windows Live Messenger does with various events. After a few seconds, these windows fade away.

Create a Screen Saver in WPF

Solution: There is nothing special about a screen saver, other than the following conventions:

• A single window that takes over the full screen.

• A configuration dialog box (optional).

• Responds to specific command-line arguments.

• File extension renamed from .exe to .scr.

The following sections detail the parts of a simple WPF screen saver that displays images from your pictures folder.

Options Dialog Box

When the /c option is passed, you should show an options form. Where you save your options is up to you (the registry, XML file, and so on).

In the case of this demo screen saver, it just shows a placeholder dialog box that says there are no options (see Listings 27.3 and 27.4).

Listing 27.3 OptionsWindow.xaml

image

Listing 27.4 OptionsWindow.xaml.cs

image

Screen Saver Window

The main screen saver window sizes itself to fit the entire screen, and it cycles through the gathered images (see Listings 27.5 and 27.6).

Listing 27.5 ScreenSaverWindow.xaml

image

Listing 27.6 ScreenSaverWindow.xaml.cs

image

image

image

image

image

image

image

image

image

The Application: Putting It All Together

The application XAML is mostly unremarkable, except for the fact that it does not specify a Window for the StartupURI property (see Listing 27.7).

Listing 27.7 App.xaml

image

The code-behind file handles the various options and starts up the screen saver in the right mode (see Listing 27.8).

Listing 27.8 App.xaml.cs

image

image

This screen saver handles three parameters:

image

If anything else is passed (or nothing at all), the screen saver should exit.

The preceding code relies on a little bit of interop to get the bounds of a native window:

image

Show a Splash Screen

Solution: Show a splash screen to display progress as you load the application.

In Windows Forms

If you want the splash screen to refresh itself correctly, you must run the initialization code on a separate thread so that the UI thread can refresh. Figure 27.4 shows the results with a simple splash screen with a progress bar and status label.

Figure 27.4 A splash screen can give the illusion your program is hard at work while the user waits for the app to be available.

image

The splash screen can be any form. In this case, it’s a dialog box with no border, an image control that fills the entire form, and a progress and label control.

image

The application shows the splash form before starting the main form.

image

image

In WPF

WPF actually has splash screen functionality built in, and if all you need is the image to show up while the main window loads, this will do it. To use it, set the build action for an image in your project to “SplashScreen” and the application will automatically show it during startup.

To get more functionality, like shown with the Windows Forms example, it’s a fairly simple translation, as shown in Listing 27.9.

Listing 27.9 SplashScreen.xaml

image

Here’s the code-behind:

image

The usage is similar to that in Windows Forms:

image

image

Figure 27.5 shows how we can take advantage of WPF’s visual richness to create a neater splash screen than with Windows Forms.

Figure 27.5 With WPF, we can have a much richer experience, such as the transparency in this splash screen demonstrates.

image

Play a Sound File

Solution: Use the PlaySound API via P/Invoke.

image

The first argument to PlaySound can be a filename, alias, or resource, depending on the flags you pass. The aliases are defined in the registry and the Sounds control panel applet.

image

The SND_ASYNC flag tells the system to start playing the sound, but to return immediately, before it’s done playing. This is usually what you want, to avoid hanging the UI while a sound plays.

Shuffle Cards

Solution: Although simple, this solution is a very easy thing to get wrong, algorithmically. For more information, look at Wikipedia’s entries on card-shuffling algorithms.

image

The accompanying source code wraps this algorithm into a test program that runs it millions of times and tracks the outcomes to see if the results are skewed in any way.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset