The Release of Start Here! Learn Microsoft Visual C# 2010 Programming

It’s always exciting to see a new book released. I had previously told you about my new book, “Start Here! Learn Microsoft Visual C# 2010 Programming” in my post entitled, “New Book Announcement: Start Here! Learn Microsoft Visual C# 2010 Programming.” That post provides some basic information about the book, including a list of the chapters and what you should expect as content. Today this book is finally in print, so you can see it for yourself. Interestingly enough, I’ve already received a few queries about this book. I’ll answer the most commonly asked question in this post, which is what prompted me to write it.

Every time I receive an e-mail, see a review of one of my books online, or obtain information about a book in some other way, I try to see if I can use the feedback to improve later editions or to write a better book. In fact, I maintain statistics about each of my books because I really value your input and want to make the best use of it. The statistics I obtain from all of these forms of input help me understand how you use books better.

One of the comments I receive fairly often is that most books feel like college courses. They’re highly structured and seem most interested in teaching how to write applications using a stilted, old fashioned approach that doesn’t fit the reader’s needs very well. At least one reader has associated this approach with learning how to play piano using textbooks—you spend hours performing boring exercises to learn how to play something relatively simple. In the reader’s words, “Such an approach sucks every bit of joy out of the process of learning to play piano.” Yes, many people do learn to play piano using textbooks, but others learn to “play by ear” (simply by doing it without learning any basics first). These readers wonder why computer books can’t be written in a way that let’s you learn how to program using the “play by ear” approach.

I agree that not everyone learns in the same way. All other things being equal, one person may require a completely different book from someone else in order to get anything out of it because the two people learn differently. So, even if I wrote the most error free and comprehensive book ever written about C# application development, some people would love it and others would hate it simply because of the approach I took. Trying to solve this problem of writing a book that uses the “play by ear” approach has proven difficult.

To solve this problem, I needed to come up with a technique that would allow the reader to write code and then “hear” what the code does by running it. However, simply seeing the output isn’t sufficient in this case. In order to understand the code, the reader has to trace through itessentially “hearing” the individual tasks performed by each line of code. I tried a tracing technique for the first time in LINQ for Dummies and received quite a few positive responses about it. Now, LINQ for Dummies does use the college approach for the most part, but some sections use this new “play by ear” approach and it seems to work well for readers who require that approach.

It was with great excitement then, that I took on a book that would approach C# development from a completely different perspective after Russell Jones asked me about it. Start Here! Learn Microsoft Visual C# 2010 Programming is the result of my efforts. This book uses the tracing technique I started to develop in LINQ for Dummies extensively. Instead of spending hours learning about basic programming constructs and then writing tiny programs to put the theory into practice, you begin writing code immediately.

The main plus I see in using this approach is that nearly anyone should be able to learn to write useful (but basic) applications in a fraction of the time normally required and without devoting nearly as much time to the activity. The learning process should also be significantly less boring because you’re always doing something that has real world results. Of course, I’m extremely interested in seeing how this approach works for you, the reader. The only way I’ll get that information is if you write me at John@JohnMuellerBooks.com and tell me what you think of the book.

Exploring the GrabAPicture Application (Part 7)

Last week, in the Exploring the GrabAPicture Application (Part 6) post, we discussed the use of the SystemParametersInfo() function call. Of course, this call is part of the Windows API, so you have to use P/Invoke to access it. The previous post doesn’t really tell you how to use the SystemParametersInfo() call—that’s the topic of this post.

Wallpaper is defined by three elements in the GrabAPicture application: Name, Location, and Style. The Name property is easyit can be any string. So, you don’t have to work really hard with it. The Location property is the most complex because a location can’t be anywhere there is a graphic that the application can grabeither local or remote. The Style property is still complex because of the way Windows stores information, but it’s not absurdly difficult because Windows only supports so many styles. The following code looks at the Style property in the WinWallpaper class first.

Public Property Style() As Styles
   Get
      ' Contains the registry key that holds the
      ' desktop values.
      Dim StyleKey As RegistryKey
 
      ' Get the desktop key.
      StyleKey = _
         Registry.CurrentUser.OpenSubKey( _
            "Control Panel\Desktop", False)
 
      ' Obtain the current value.
      If StyleKey.GetValue("WallpaperStyle") = 2 And _
         StyleKey.GetValue("TileWallpaper") = 0 Then
         Return Styles.Stretched
      End If
      If StyleKey.GetValue("WallpaperStyle") = 1 And _
         StyleKey.GetValue("TileWallpaper") = 0 Then
         Return Styles.Centered
      End If
      If StyleKey.GetValue("WallpaperStyle") = 1 And _
         StyleKey.GetValue("TileWallpaper") = 1 Then
         Return Styles.Tiled
      End If
 
      ' This value should only show up if someone has
      ' tampered with the registry and set the values
      ' incorrectly.
      Return Styles.Unknown
   End Get
   Set(ByVal Value As Styles)
      ' Because Styles.Unknown signifies an error
      ' condition, the developer can't provide it as an
      ' input value.
      If Value = Styles.Unknown Then
         Throw New ArgumentException( _
            "Cannot use Styles.Unknown as an input argument")
      End If
 
      ' Contains the registry key that holds the
      ' desktop values.
      Dim StyleKey As RegistryKey
 
      ' Get the desktop key.
      StyleKey = _
         Registry.CurrentUser.OpenSubKey( _
            "Control Panel\Desktop", True)
 
      ' Select one of the other input values and set the
      ' registry keys as needed.
      Select Case Value
         Case Styles.Stretched
            StyleKey.SetValue("WallpaperStyle", "2")
            StyleKey.SetValue("TileWallpaper", "0")
         Case Styles.Centered
            StyleKey.SetValue("WallpaperStyle", "1")
            StyleKey.SetValue("TileWallpaper", "0")
         Case Styles.Tiled
            StyleKey.SetValue("WallpaperStyle", "1")
            StyleKey.SetValue("TileWallpaper", "1")
      End Select
   End Set
End Property

The Style property defines which style to use to display an image on the Desktop. The current version of the GetAPicture program is compatible with all versions of Windows, including Windows XP. A later post will show how to upgrade this application so it also allows use with Windows 7-specific features (Fill and Fit). As you can see, the get portion of this property begins by accessing the HKEY_CURRENT_USER\Control Panel\Desktop key of the registry as shown here.

GrabAPicture0701

Eventually, you’ll use three values from this key: TileWallpaper, Wallpaper, and WallpaperStyle. For now, all you need to know about is TileWallpaper (used to define the wallpaper as Tiled) and WallpaperStyle (used for all of the other settings). The code examines the registry settings using the GetValue() method and returns a Styles enumeration value that reflects the current settings. If the code can’t recognize a setting, then it returns Styles.Unknown.

When it comes time to set the wallpaper style, the application verifies that the style is known and then uses two calls to SetValue() to configure the TitleWallpaper and WallpaperStyle settings in the registry. As you might imagine, updating the rudimentary functionality of the code won’t be hard, but to ensure that the code works properly with all versions of Windows, you need to add version checks. This is the part that will interest you the most in the future post.

The WallpaperURI property code is a lot more complex than you might imagine for a very good reason. If you simply try to set the wallpaper location using the registry values, you won’t see any change on screen. The system won’t know to perform the update. In order to see the update and ensure that the change is reflected in any running applications, you must use the SystemParametersInfo() call as shown in the following code.

Public Property WallpaperURI() As Uri
   Get
      ' Create a variable to hold the result.
      Dim Result As New StringBuilder(120)
 
      ' Get the wallpaper URI.
      If SystemParametersInfo( _
         Convert.ToUInt32(SPI_GETDESKWALLPAPER), _
         Convert.ToUInt32(Result.Capacity), _
         Result, _
         Convert.ToUInt32(0)) Then
 
         ' Return the result as a URI.
         Return New Uri(Result.ToString())
      Else
         ' Throw an exception if there is an error.
         Throw New Exception( _
            "Error Calling SystemParametersInfo: " + _
            Marshal.GetLastWin32Error().ToString())
      End If
   End Get
   Set(ByVal Value As Uri)
      ' The usable, local path, location of the
      ' wallpaper.
      Dim Location As String
 
      ' A connection to the wallpaper online.
      Dim GetData As Stream
 
      ' The online image.
      Dim Img As Image
 
      ' Wallpaper on a Web page requires somewhat
      ' different processing than local wallpaper.
      If Value.Scheme.ToUpper() = "HTTP" Then
 
         ' Create a new path to save the image
         ' locally so it can be placed on the desktop.
         Location = Path.GetTempPath() + "WallPaper.BMP"
 
         ' The Web connection could fail, so use a Try
         ' block to obtain the file.
         Try
 
            ' Obtain a connection to the wallpaper.
            GetData = _
               New WebClient().OpenRead(Value.ToString())
 
            ' Read the wallpaper data.
            Img = Image.FromStream(GetData)
 
            ' Save the image.
            Img.Save(Location, Imaging.ImageFormat.Bmp)
 
         Catch ex As WebException
            ' The Web connection has failed.
            ' Use the existing Wallpaper.BMP
            ' file if it exists.
            If File.Exists(Location) Then
 
               ' Read the existing file instead.
               Img = Image.FromFile(Location)
 
            Else
               ' Otherwise, use the local path instead.
               Location = Value.LocalPath
 
               ' Verify the wallpaper is a BMP.
               If Not Location.ToUpper().EndsWith("BMP") Then
 
                  ' Load the file from disk.
                  Img = Image.FromFile(Location)
 
                  ' Create a new path to save the image
                  ' locally so it can be placed on the desktop.
                  Location = Path.GetTempPath() + "WallPaper.BMP"
 
                  ' Save the image.
                  Img.Save(Location, Imaging.ImageFormat.Bmp)
               End If
            End If
         End Try
      Else
         ' Assume that the wallpaper is local.
         Location = Value.LocalPath
 
         ' Verify the wallpaper is a BMP.
         If Not Location.ToUpper().EndsWith("BMP") Then
 
            ' Load the file from disk.
            Img = Image.FromFile(Location)
 
            ' Create a new path to save the image
            ' locally so it can be placed on the desktop.
            Location = Path.GetTempPath() + "WallPaper.BMP"
 
            ' Save the image.
            Img.Save(Location, Imaging.ImageFormat.Bmp)
         End If
      End If
 
 
      If SystemParametersInfo( _
         Convert.ToUInt32(SPI_SETDESKWALLPAPER), _
         Convert.ToUInt32(Location.Length), _
         New StringBuilder(Location), _
         Convert.ToUInt32(SPIF_UPDATEINIFILE Or SPIF_SENDWININICHANGE)) Then
      Else
         ' Throw an exception if there is an error.
         Throw New Exception( _
            "Error Calling SystemParametersInfo: " + _
            Marshal.GetLastWin32Error().ToString())
      End If
   End Set
End Property

Working with a Windows API function requires that you do some special coding. Otherwise, the call will never work. It’s important to remember that the Windows API works mainly with numbers and not with other data types. If you want to work with a string, then the string parameter takes the form of a pointer to memory in the caller’s address space in most cases. Of course, Visual Basic doesn’t provide a means to do this directly. Creating a StringBuilder object tells Visual Basic to marshal the string as a pointer to the Windows API. In this case, the code creates a StringBuilder capable of holding 120 characters, which is normally enough to hold the location of the current wallpaper on disk.

 

PInvoke comes in handy for all sorts of purposes in Visual Basic. This application shows just one example. You can find another great example of working with PInvoke on Rod Stephen’s site with the “Remove the X Close button from a form’s system menu in Visual Basic .NET” example. I haven’t seen this particular use of PInvoke explained anywhere else, so you’ll definitely want to take a look. Of course, you can get all the information you need for working with PInvoke in my book, “.NET Framework Solutions: In Search of the Lost Win32 API.”

The call to SystemParametersInfo() comes next. Normally, you’d make a call that could fail in a try…catch block. However, a Windows API call won’t work that way. In this case, the call returns True when the call succeeds and False when it doesn’t (individual Windows API calls behave in different ways, so make sure you understand how errors are presented by individual call). When the call returns True, the property returns a new Uri containing the result provided by SystemParametersInfo(). Otherwise, the code throws an Exception. Unfortunately, you don’t know what happened. The only way to get this information is to call Marshal.GetLastWin32Error() and that information is only available when you set the value of the SetLastError property of the <DllImport> attribute (explained in the previous post) to True.

 

Some readers will take me to task for not providing a more specific exception, especially since I pound on this particular failing in many applications in my books. Because you don’t know the nature of the exception, you can’t provide anything better than an general Exception in most cases. The only way around this is to create code that laboriously tracks every sort of potential error returned by the Windows API and creates an appropriate exception for it. This may be a good topic for another post in the future, but definitely not the point of this post.

Setting the wallpaper location is complicated by the fact that the wallpaper can be either local or remote. The code pursues the remote route first. The example assumes that the remote wallpaper will be on an HTTP site. You’d need to modify the code to accommodate other schemes such as HTTPS. This might make a good future post, but let’s get into a common HTTP remote location first.

The first step is to create a copy of the wallpaper on the local drive in the user’s temporary folder. A call to Path.GetTempPath() obtains this information. The remote wallpaper is always stored in a file named Wallpaper.BMP (I chose the BMP format for compatibility purposes).

The code performs a number of tasks in a try…catch block. First, it attempts to read the file containing the image from the remote location into GetData (of type Stream). If this is successful (the image exists and you can read it), the code converts the stream into an Image object, Img. The image can be of any type that Image supports:

 

  • BMP
  • GIF
  • JPEG
  • PNG
  • TIFF

The final step is to save the image, using Img.Save() to Wallpaper.BMP in the BMP format. If there is an exception in any of these steps, the application automatically recovers in one of two ways. First, it looks for an example Wallpaper.BMP and uses it when the file exists. Second, if this first technique fails, then the application looks at the current value for the local wallpaper selection and uses it instead. In this case, the application uses the Image.FromFile() method to obtain a copy of the image and saves it to Wallpaper.BMP.

When the wallpaper is local, the code first checks to see if the wallpaper is already in BMP format. If it is, the application simply places the information in Location. Otherwise, the application reads the file using Image.FromFile() and saves the image in BMP format to Wallpaper.BMP.

No matter how the information gets there, eventually Location contains a path and filename for the file you want to display on the Desktop. At this point, the code calls SystemParametersInfo() to set the wallpaper, which indirectly sets the Wallpaper value in the registry. The call also notifies Windows that it needs to update the Desktop and any applications that are currently running that they need to repaint their displays. The user sees the new wallpaper displayed on screen.

At this point, you have a good idea of how the WinWallpaper class works. In the next post, you learn about the GrabAPictureSettings class, which is used to interact with the settings you’ve learned about in the past several posts. Please let me know if you have any questions at John@JohnMuellerBooks.com. You can see the next post in this series at Exploring the GrabAPicture Application (Part 8).

 

More on CFL Usage

Readers came back with a few questions about CFLs after reading my CFLs for Free post. The one thing I want to get across clearly is that the article is emphasizing that you can buy new CFLs using the savings from previous purchases. You need to make the investment in the first CFL to get started and then use the savings from that investment to buy future CFLs. No one is going to mysteriously pay you to buy CFLs, but if you buy smart, you can indeed get future CFLs for free after making the initial purchase. Eventually, you’ll pay off the initial purchase using the savings as well.

A number of people asked about the startup surge (also known as inrush current). The startup surge is something that occurs when you first apply power to the light. This surge is extra electricity that’s required to get the bulb started. The amount of power the bulb requires decreases as it gets to operating temperature, which isn’t very long in most cases. I’ve read a number of conflicting opinions about the startup surge of CFLs. My take on everything I’ve read is that the startup surge will vary by bulb vendor and type of light. A tube light has a smaller startup surge for a significantly smaller time than the twisted bulbs. Vendors who meet Energy Star requirements tend to produce bulbs that have a smaller startup surge than the less expensive bulbs.

A few readers also asked about long term efficiency of CFLs. From personal experience Rebecca and I have found that CFLs do provide an efficiency advantage if you use them for one long interval, rather than several short intervals. In other words, if you burn the light for four hours solid instead of two, two hour intervals, you’ll gain an efficiency advantage. In addition, turning the light on and off reduces its life expectancy.

Efficient energy use is why Rebecca and I tune our work schedule to follow the sun. We get up at 5:30 am (sometimes a bit earlier) during the summer months to make maximum use of the daylight hours, but we get up at 7:00 am during the winter months to ensure we won’t have to turn the lights on in the morning. The actual difference between summer and winter work times is 2½ hours due to the effect of daylight saving time. We do work later into the evening during the winter months to make up for the later start time, so everything evens out. Using this approach has had both health and monetary benefits, but we also understand that it’s not a solution that most people can use.

There are a lot of myths, misconceptions, and outright controversies about CFLs online. In addition, I’m finding that people have individual experiences based on how they use lighting in their home. However, after researching this topic intensively, I’m finding that the following tips about CFLs seem to be true for just about everyone:

 

  • Buying CFLs with the Energy Star label tends to pay dividends in reduced operating costs and longer life, but you must weigh these benefits against the increased initial cost. In general, buying Energy Star products save you money.
  • If you must use a CFL in a socket controlled by a dimmer, buy a CFL designed for that purpose. Using a standard CFL in a dimmer-controlled socket greatly reduces bulb life and could damage the dimmer.
  • CFLs require more air to work properly. They’re more heat sensitive, so putting one in a can or recessed fixture will result in a reduced life expectancy. The exception is that there are CFLs specially designed to work in recessed fixtures, but you’ll also pay a premium price for them.
  • CFLs also don’t like
    damp or wet conditions. If you need to use a CFL in a damp or wet
    condition, make sure you get one rated for that purpose.

  • Standard CFLs don’t work well in fixtures that vibrate, such as the lighting kits for fans. If you want to use a CFL with a fan or other fixture that will vibrate, you need to get a CFL designed for the purpose. (I finally gave up using a CFL in my garage door opener light socket because even the CFLs designed for use in vibration don’t last long in that particular application.)
  • Excessive on and off cycles in a given day will most definitely reduce the life expectancy of your CFL. I researched this one a lot and didn’t get a definitive answer for you. The most common guidelines say that you should strive to keep on/off cycles below 20 for any given CFL during one day. It’s commonly said that CFLs have a life expectancy of 7,000 on/off cycles if you observe the 20 on/off cycle per day limit. The source of problems in this case is the electronic ballast that CFLs use, which aren’t designed for heavy on/off cycles.
  • Faulty wiring affects CFLs considerably more than incandescent bulbs. If your wiring is such that it causes flickers or flashing with an incandescent bulb, the CFL won’t last very long. Even if you can’t see the flickering, small dips in power can cause early CFL failure. If you find that your bulbs aren’t lasting very long, have the power checked. Faulty wiring also affects the cost savings from a CFL in a big way because the bulb never quite gets to its operating range.
  • Line noise will also affect CFLs. For example, if you have a heavy duty motor (such as a refrigerator) on the same line as a CFL, the drop in line current when the motor starts can affect the life expectancy of the CFL. Line noise will also affect the cost savings you see from a CFL because the bulb isn’t operating properly.

Some readers have pointed out that CFLs are overrated. I’m not quite sure how to respond to this question other than to say that there isn’t any free lunch. Just about every solution we now have for fixing the planet’s carbon problem is flawed. Even if we were to all go back to burning candles, there would be problems. However, I did spend some time online looking for something a bit less hysterical and a little more scientific than something that says CFLs and other modern technologies are bad. You should embrace CFLs and other good for the planet technologies with open eyes. The best post I found on these issues is one entitled, “Directory:Compact Fluorescent Lighting (CFL) Downsides.” If someone else has a non-hysterical source of additional information, I’d be happy to address it in another post.

I’d welcome verifiable tips from other people. I verified each of these tips against three sources (including government sites when available). That doesn’t mean that every tip will work for you personally, but most people find that these tips work for them. Let me know about any additional thoughts you have about CFLs at John@JohnMuellerBooks.com

 

Review of Real Steel

Real Steel (starring Hugh Jackman and Evangeline Lilly) is a combination of two movie types I really like—science fiction and boxing. The synopsis of the movie sounds unique and in many respects, the movie is unique. However, once you see the movie, the first thing that comes to mind is that it’s faintly reminiscent of the Rocky movies. The movie is actually loosely based on a The Twilight Zone episode entitled, “Steel” (1963) penned by Richard Matheson (1956). Being a fan of the old television series (still being shown in some locations), I can see a faint resemblance to the way the show would have been put together, but don’t expect to see Rod Serling appear on screen.

Let’s get the required glitz review out of the way. The graphics in this movie are nothing less than spectacular in the fact that they look completely normal. There is a certain amount of flashing lights, explosions, and the like, but for the most part, this movie could happen in your neighborhood today. It’s this lack of over-stimulation that draws you into the movie. You find yourself believing that someone you know could be boxing robots. Whoever put the graphics together and came up with the creative ideas for this movie is amazing. I had expected eye popping effects and instead got normal, which actually suits this movie quite well.

The value of this movie is in the plot. Emotions run high because the plot is quite good and well acted. You find yourself wanting to cheer, cry, and yell all in a matter of minutes. Charlie Kelton (Jackman) ends up taking care of his little boy, Max (Dakota Goyo), after literally ignoring him all of his life and then selling him to his sister-in-law. Max is understandably upset at first, but then something happenshe gets interested in his own robot boxer. Even though Charlie is a complete loser on his own, when coupled with Max he becomes a winner. I don’t want to ruin the plot of this extraordinary film, but you can imagine what happens next.

Most of the performances in this movie are a little over the top, but well acted. The only actor that didn’t quite do the job was Evangeline Lilly (Bailey Tallet in the film). I found her performance a bit weak. It was almost as if she was overawed by Jackman. She did play an important part, but the performance could have been bettermore believable. It wasn’t until the end of the movie that I felt a bit for her character, but by that time I was almost too busy cheering Charlie and Max to really notice. It was a case of too little, too late.

If you like science fiction, boxing, or simply a well-acted emotional movie, you’ll like Real Steel. It has few warts and a lot to recommend it. I just hope that they don’t ruin this movie by coming out with a sequel.

 

Security Implications of the AT Command

I read the security post provided by Roger Grimes with interest this morning because I’ve always felt that the Task Scheduler is just another entry point for viruses and the like on any system. As he mentions, it’s an avenue that many administrators fail to check because they don’t really think about it. As Roger points out, there are three ways to add new entries, but this post focuses on the oldest of the three, the AT command.

Before you can interact with the Task Scheduler, you must have its service started. This is a given on Vista and Windows 7, where Windows relies heavily on the Task Scheduler. However, you’ll want to read my Interacting with the Task Scheduler Service for details about this service. It’s important to have the service setup correctly in order to work with it error free.

The AT command is the oldest way of working with the Task Scheduler. At one time you could access it from the command prompt even if you weren’t an administrator. This meant that any virus or other piece of nasty software could cause woe without notice on your part. However, if you try to use the AT command at a normal command prompt in Windows 7, you’ll receive an Access Denied error message, which is at least a start in the right direction.

To use the AT command to create a new entry, you must provide a time and command as a minimum. For example, if you type AT 15:00 “Dir C:\” and press Enter, you’ll create a new task that starts at 3:00 pm on the current day. You’ll receive a numeric identifier for the task. The entry also shows up in the Task Scheduler console (found in the Administrative Tools folder of the Control Panel) as At plus the identifier, such as At1 as shown here.

TaskSchedulerEntries01

If you want to list the jobs created by the AT command, you type AT and press Enter. The AT command only lists those jobs that it creates—you won’t see any jobs created using other Task Scheduler techniques.

Likewise, to delete jobs using the AT command, you provide the identifier you received when you created the job along with the /Delete command line switch. For example, if the identifier for the task you created earlier in this post is 1, then you’d type AT 1 /Delete and press Enter. In this case, the AT command doesn’t provide any output. In order to verify that the job is actually gone, you must type AT and press Enter. Here’s what the command output from this session looks like.

TaskSchedulerEntries02

The true power of AT lies in remote access. For example, if you have an Administrator command line open, have a server named WinServer on your network, and possess administrator privileges on that server, you can type AT \\WinServer 15:00 “Dir C:\” and press Enter to create a command that starts at 3:00 p.m. (local time) on WinServer. It’s important to realize that the command will execute when it’s 3:00 p.m. on the server, not 3:00 p.m. on your system. You can likewise list and delete remote entries using the same commands you’d use for local entries. Again, the Task Scheduler console will display these entries, but only on the host machine (so you’d need to access that system remotely to see it from your local computer).

Windows 7 does make it harder to use the AT command, but not impossible. If an outsider should gain access to an account with administrator privileges, it wouldn’t take long for a virus to add all sorts of nasty commands to every machine on the network. As Roger comments in his post, administrators need to exercise vigilance in order to catch potential security issues such as this one. Let me know if you have any questions at John@JohnMuellerBooks.com.

 

Cutting Up a Chicken

When you raise your own chickens, you eventually end up with a lot of whole chickens in your freezer and will need to cut at least a few of them up for use. Most people are used to seeing chickens already cut up for use in the store. If you do get a whole chicken, it’s usually with the idea that you’re going to roast it whole. In many cases, people don’t know where to begin cutting a chicken up for use because the butcher has done it for them for so many years. Following the chickens you find in the store as an example won’t work very well either because they’re cut up using a meat saw (think of a band saw specifically designed for cutting meat). Unless you also have a meat saw, you probably won’t be able to follow the butcher’s example. This post describes how to cut up a chicken using nothing more than a standard utility knife.

I recommend using a 6-inch knife with a fairly stiff blade. A boning knife will be too flexible and something small, such as a pairing knife, won’t give you enough leverage. Don’t use a knife with a serrated edge—the serrations will make for a poor cut and you won’t be able to split the breastbone with such a knife. The knife you use should be sharpthe sharper the better. A dull knife is dangerous to use.

Start with the wings. Your cut should begin behind the joint area. When you lift the wing up, you’ll actually see a bit of the flesh come up with it. Start your cut immediately behind this fleshy area and angle toward the joint as shown here.

CuttingChicken01

Cutting the wings in this way has the advantage of making them a bit meatier. After you cut off both wings, it’s time to cut off the combination of the leg and thigh. Start by lifting the thigh and cutting toward the joint from the front of the chicken as shown here.

CuttingChicken02

Once you get to the joint from the front, you’ll need to cut to the joint from the back as well. When this cut is finished, you’ll be able to rotate the leg/thigh combination downward and see the joint pop from the socket as shown here.

CuttingChicken03

You can finish the cut at this point. Remove both leg/thigh combinations using the same approach. Now you can separate the leg from the thigh. There is a natural division between the leg and the thigh. If you look carefully, you can actually see where the two separate because the meat goes in two directions. Look carefully at the following picture and you’ll see that the line shows this separation.

CuttingChicken04

Cut straight down through this point and you’ll find, with practice, that the knife will neatly separate the meat at the joint. At this point, you’ve cut off the wings, legs, and thighs. It’s time to remove the lower back (the part with the tail).

Look inside your chicken. You’ll see that there is a fleshy part between the rib cage and the lower back. The fleshy part extends on both sides of the chicken. You’ll cut through this fleshy part to separate the lower back starting midway at the opening as shown here.

CuttingChicken05

Cut through the fleshy part. You should then be able to flex the lower back and see the backbone separate from the rib cage as shown here.

CuttingChicken06

You can then cut through the spinal cord to separate the lower back from the rib cage. Cut straight down.

The hardest cut to make is to separate the two breast halves. However, like many things in life, there is a trick to it. Look at the center of the breastbone and you’ll see a line runs through it. Now, look at the first complete rib and trace it around to where it meets with the breastbone. You’ll see a second line of a sort that forms a cross as shown here.

CuttingChicken071

Put the tip of the knife through this point and you’ll find that the breastbone cracks easily. Now, draw the knife down much as you would with a paper cutter. You’ll find that the knife easily slices through the majority of the breastbone and the cartridge as shown here.

CuttingChicken08

After you make this cut, move your knife higher up. Don’t put it through the hole where the neck is, but do place it higher into the cavity. Use the point to finish breaking the breastbone apart. At this point, you should also be able to break the wishbone in half. Now you can separate the two halves of the breast like this because there is cartilage separating the breast from the upper back.

CuttingChicken09

Cut the cartilage holding the upper back to the breast halves. You’ll reach another joint after you cut the ribs. Separate the joint and the cut through it as shown here.

CuttingChicken10

You should now have ten pieces of chicken as shown here:

CuttingChicken11

These pieces are: left and right wing, left and right leg, left and right thigh, lower back, upper back, and left and right breast. Although this combination doesn’t look quite like the chicken you get in the store, it’s the most effective means of cutting a chicken up using just a utility knife. In addition, using this approach makes more of the pieces a usable size. Let me know if you have any questions at John@JohnMuellerBooks.com.

 

Exploring the GrabAPicture Application (Part 6)

In the previous post, Exploring the GrabAPicture Application (Part 5), you learned about two classes used to store desktop wallpaper settings: LocalUri and RemoveUri. In addition, you learned about the WinWallpaper class that contains the Styles enumeration. We need to stop talking about data for just a little while and look at some special code used to access the underlying Windows functionality in the form of the SystemParametersInfo() function. In order to do this, you need to work with Platform Invoke (P/Invoke) code. A lot of developers feel that P/Invoke is complex and impossible to understand, but it really isn’t and functions such as SystemParametersInfo() are extremely useful to the developer, especially when working with newer versions of Windows where Microsoft hasn’t added the required functionality to the .NET Framework. My book, “.NET Framework Solutions: In Search of the Lost Win32 API” discusses how to work with P/Invoke in detail, but this post provides enough information to use P/Invoke with the GrabAPicture application.

Before you do anything else, you should have already created WinWallpaper.vb using the instructions in the Exploring the GrabAPicture Application (Part 5) post. At this top of this file, you need to add some Imports statements to access the required .NET Framework functionality:

Imports System.Runtime.InteropServices
Imports System.Text
Imports System.IO
Imports System.Net
Imports System.Drawing
Imports Microsoft.Win32

Now that you have the required imports, you can begin working with the SystemParametersInfo() function. This function interacts with Windows in a low-level manner to set and get system information, such as the Desktop wallpaper settings. In fact, this is an incredibly versatile function that you’ll encounter quite a lot if you work with P/Invoke very often. Here’s the declaration you’ll need to access it.

<DllImport("User32.DLL", SetLastError:=True)> _
<CLSCompliant(False)> _
Public Shared Function SystemParametersInfo( _
   ByVal uiAction As UInteger, _
   ByVal uiParam As UInteger, _
   ByVal pvParam As StringBuilder, _
   ByVal fWinIni As UInteger) _
As Boolean
   ' uiAction contains a constant value that defines
   ' the action to perform.
   ' uiParam contains the size of the buffer used to
   ' hold the URI on return from a get call.
   ' pvParam contains the name of the file.
   ' fWinIni contains the flags for changing the
   ' wallpaper information.
   ' The return value is a Boolean indicating success or
   ' failure.
End Function

The function declaration begins with two attributes. Every time you use P/Invoke, you must define where to obtain the function using the <DllImport> attribute. This function appears in User32.DLL. Optionally, you can tell .NET to provide you with full error information from Windows. From my perspective, this isn’t an option—you should always configure your P/Invoke calls to return full error information.

The second attribute, <CLSCompliant>, has become a requirement in newer versions of Visual Studio. Most Windows functions aren’t CLS compliant, so you must mark them a such or the compiler will complain. The SystemParametersInfo() function uses unsigned 32-bit values, so it isn’t CLS compliant.

Also note that this function uses the UInteger data type. Earlier versions of P/Invoke calls for the SystemParametersInfo() function relied on the UInt32 data type. Both data types provide the same 32-bit unsigned integer value, but newer versions of Visual Studio prefer that you use the UInteger type and will complain if you use UInt32.

Notice that the function declaration includes comments that document every one of the input arguments. This is a best practice any time you use P/Invoke. The Visual Basic help system won’t help you, nor will other IDE features. If you don’t document the arguments as part of your code, you’ll find yourself wasting a huge amount of time rediscovering what these arguments mean by locating the Windows API online. In addition, when you’re using a multitasking function such as SystemParametersInfo(), even the Microsoft information will be too generic to be useful. The comments provided with the example code are specific to how the example uses the function.

Now that you have a little better understanding of SystemParametersInfo() (future posts will provide examples of it’s usage and explain them to you), it’s time to look at the constants used to make the call. The following list of constants is specific to this application. The actual list is considerably longer.

' Define constants to use with the SystemParametersInfo
' function. All of these values come from WinUser.h.
 
' Defines the action to take--get or set the wallpaper.
Const SPI_SETDESKWALLPAPER As UInteger = &H14
Const SPI_GETDESKWALLPAPER As UInteger = &H73
 
' Update the user's information.
Const SPIF_UPDATEINIFILE As UInteger = &H1
 
' Tell other applications about the change in status.
Const SPIF_SENDWININICHANGE As UInteger = &H2

Again, it’s essential to document the constants fully. For example, you need to know where these constants come fromWinUser.h in this case. The constant names are precisely the same as the names in WinUser.h. If you don’t use the same names, you’ll find it difficult to work with the SystemParametersInfo() function later and to obtain additional information about it.

Notice that these constants all have a data type of UInteger. As mentioned earlier, older versions of Visual Basic would have relied on UInt32 or not provided a type at all. The code defines the constant values using hexadecimal notationthe same notation found in WinUser.h.

As you can see, these constants tell the SystemParametersInfo() function to either get or set the current Desktop wallpaper settings. When the application sets the Desktop wallpaper, you must also tell SystemParametersInfo() to update the user’s settings and to inform other applications about the change (so they’ll redraw their windows as needed). Let me know if you have any questions about the SystemParametersInfo() function at John@JohnMuellerBooks.com. You can find the next post in this series at Exploring the GrabAPicture Application (Part 7).

 

Creating Raw Juice for Wine Making

Earlier this year I created a series of posts about making wine using the cubicontainer technique that relies on a single container, rather than using two containers for primary and secondary fermentation. This approach requires that you use juice, and not raw fruit/vegetables, as the source for the wine. Most people think that you can make juice only from a raw source, such as crushing grapes. However, wine makers know that you can use both raw and cooked juice. This post shows how to work with raw juice—pears in this case. If you haven’t read the wine making series of posts, you can find them at:

 


When working with any fruit for raw juice, you need to pick the fruit at the peak of ripeness. In the case of pears, this means smelling the fruit for the distinctive pear odor. The fruit should still be firm, but crush easily in the hand. Taste the fruit and you should smell a strong pear odor, along with a high sugar content. Check the inside for an off white appearance. If the fruit seems starchy, the inside has yellowed or browned a bit, or seems mushy to the touch, it’s overripe and won’t make good wine. Likewise, if the fruit is still greenish in color, seems a bit too firm, or lacks the strong pear odor, it  isn’t ripe enough. Every fruit has its peak time for picking that typically last one or two days. That’s rightyou must check the fruit absolutely every day or you’ll miss the perfect time to pick it.

In order to create the juice, you begin by running the raw pears through a Victorio Strainer. You need to be absolutely certain that the pears are ready for use in wine. Pears that aren’t ripe could damage your strainer. Normally, the juice turns a bit brown as you strain it due to oxidation and the presence of bacteria. In this case, you’ll prevent that from occurring by adding a campden tablet to the output of the Victorio Strainer and stirring the juice from time-to-time as you strain the juice. The result should be a slightly greenish yellow juice as shown here.

RawJuice01

However, this juice isn’t ready for wine making yet. It still contains a substantial amount of pulp. You need to make at least 2 quarts of strained pear juice to obtain 1 quart of juice ready for wine making. The next step is to place a jelly bag over a 1 quart measuring cup like this:

RawJuice02

Pour as much of the strained juice into the jelly bag as possible. Now you’ll squeeze the bag to separate the pulp from the juice like this:

RawJuice03

Once you have a quart of juice, you can use it immediately to make wine or freeze it for later use. A quart of pear juice will make one gallon of wine using the wine making techniques I discussed earlier. If you decide to freeze the juice, make absolutely certain that you mark it for wine use only because the juice already has the campden tablet in it.

This same technique works fine for any fruit that gets soft enough when ripe to put through the Victorio Strainer. For example, it works great with berries. However, I haven’t ever gotten this technique to work properly with applesmost apples are still too crisp when picked to get through the Victorio Strainer successfully. Apple wine requires the use of a cider press or the cooked juice method. Other fruits, such as rhubarb, require the cooked juice method. You can use this technique for some vegetables as well. This is the technique I use to make tomato wine. If you want to work with a harder vegetable, such as beets, then you need to use the cooked juice method. (I’ll describe the cooked juice method in a future post.) Let me know if you have any questions about this technique at John@JohnMuellerBooks.com.

 

Exercising Personal Privacy

In my post, “Is Privacy a Right?,” I tell developers that they really need to consider the right of the user to a certain amount of privacy. Books such as C# Design and Development will need to include sections on privacy as part of any update. In fact, privacy is a topic not covered to any extent in any development book on my shelf. The few mentions of privacy appear in older books I’ve written, along with a few moldy references to old books by other authors. If you really want to get a modern treatment of privacy as a question of what the individual requires, you need to look at a non-development book such as “Alone Together: Why We Expect More from Technology and Less from Each Other.” Unfortunately, this book discusses social ramifications—not the techniques a developer uses to ensure privacy. Of course, no matter what the developer does, the user can always thwart any effort to provide privacy, which is the topic of this post.

I find it amazing that people willingly give up their privacy for apparently little or no reason. I read John Dvorak’s post, “I’m Not Home Right Now. Please Come In.” with great interest this morning (after having read the news report that he discusses). The idea that a husband would be able to check up on his cheating wife through an iPhone application is amazing to me. The private detective industry should take note that they’ve been replaced by a phone. It won’t be long before someone comes up with an application to surreptitiously take pictures of the dupe who loads one or more of these applications on their cellphone.

After thinking about this issue for a long time, I’ve come to the conclusion that some people have watched one too many episodes of CSI (and shows of that ilk). There is a sense that someone is going to reach out and grab each of us, and that our cellphones are the only way anyone will find us again. It’s also human nature not to be left out. If people don’t know where we are, we might miss out on something that we think is important at the time, but turns out not to be much of an issue at all in hindsight. I’m sure that little Jerry can find his sock just fine without dad’s intervention over the telephone (a little self-sufficiency does everyone good). The announcement that Maggie has a new tooth can easily wait until mom gets home from the store.

There should be alarm bells going off in the minds of every person who currently owns a cellphone, OnStar, or any other tracking technology. Do you really want someone to follow absolutely every move you make in the interest of providing some uncertain sense of security? Privacy, once lost, is incredibly hard to regain. People should learn how to disconnect in comfort, keep their privacy intact, and discover the wonderful world of being alone every once in a while. I think you’ll find that you’re a lot less stressed once you get used to it. Consider Remembering to Rest as not just beneficial to yourself, but those around you.

Most of all, it’s time that people learn to demand privacy from their technology. Whoever created the new tracking application in the iPhone wasn’t thinking and people should disable it sooner than later. It’s not necessary for vendors to track your every move online. No one gains anything by knowing you’ve gone to the store to buy this week’s groceries. All of the applications that are tracking you are stealing your privacy and making you a target for all of the things you fear most. Don’t give criminals (or marketers) an edge. What is your privacy worth to you? Let me know at John@JohnMuellerBooks.com.

 

Celebrating with Birthday Butter

Rebecca grows quite a few herbs. In fact, the majority of herbs used in our house come from Rebecca’s garden and not from the store. People have asked us in the past how to use these herbs. Of course, there are the mundane uses of savory herbs (such as sage) in meat dishes and sweet herbs (such as mint) in cakes and cookies. However, if you’re really interested in shaking things up, you mix the herbs in new and interesting combinations. That’s what I decided to do in making birthday butter.

Birthday butter was actually created for Rebecca’s birthday. I used it for her breakfast. I spread the birthday butter on a bagel, but it tastes just fine on toast, crumpets, English muffins, or any other sort of bread. In this case, I filled the holes in the center of the bagel halves with cherry tomatoes to dress it up a bit. The result is an interesting mix of savory and sweet that is a delight to the palette. Here’s the birthday butter recipe:

1/2 cup Butter, Smart Balance, or Margarine
2 tsp Sugar or Splenda
2 tsp Rubbed Sage
1 tsp Mint Leaves
1 tsp Lemon Juice

Cream the butter in a bowl. Place the remaining ingredients in the bowl. Mix together until blended. The lemon juice will have a tendency to separate from the rest of the mixture, so remixing is needed if you store the unused portion.

I found that butter works far better for this recipe than margarine does. We’ve actually tried something new, Smart Balance Buttery Sticks with Omega 3 Fatty Acids. This product is half butter and half margarine. It cooks extremely well and tastes much like butter does. However, it significantly reduces the amount of cholesterol you receive and the Omega 3 fatty acids are actually good for you.  I’m not sure how this recipe would work using other alternative sweeteners, but the results with Splenda are quite good.

The kind of mint you use has a big impact on the taste of birthday butter. Try various mint varieties out to see for yourself. The original version uses spearmint, but peppermint or even wintergreen would probably work just fine. For something unusual, try orange or lime mint.

The best way to get the ingredients to mix properly is to use a mixer. However, I’ve been able to get them to mix just fine using a fork. The point is, this butter blend has a wonderful taste and is a great way to start the day. How do you use your herbs? Let me know at John@JohnMuellerBooks.com.