<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" media="screen" href="/styles/xslt/rss.xslt"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:c9="http://channel9.msdn.com">
<channel>
	<title>Channel 9</title>
    <atom:link rel="self" type="application/rss+xml" href="http://channel9.msdn.com/Niners/c4f.Dan-Fernandez/Posts/RSS"></atom:link>
    <itunes:summary></itunes:summary>
    <itunes:author>Microsoft</itunes:author>
    <itunes:subtitle></itunes:subtitle>
    <image>
      <url>http://mschnlnine.vo.llnwd.net/d1/Dev/App_Themes/C9/images/feedimage.png</url>
      <title>Channel 9</title>
      <link>http://channel9.msdn.com/Niners/c4f.Dan-Fernandez/Posts</link>
    </image>
    <itunes:image href=""></itunes:image>
    <itunes:category text="Technology"></itunes:category>
    <description>Channel 9 keeps you up to date with the latest news and behind the scenes info from Microsoft that developers love to keep up with. From LINQ to SilverLight – Watch videos and hear about all the cool technologies coming and the people behind them.</description>
    <link>http://channel9.msdn.com/Niners/c4f.Dan-Fernandez/Posts</link>
    <language>en</language>
    <pubDate>Sat, 18 May 2013 19:33:45 GMT</pubDate>
    <lastBuildDate>Sat, 18 May 2013 19:33:45 GMT</lastBuildDate>
    <generator>Rev9</generator>
    <c9:totalResults>2</c9:totalResults>
    <c9:pageCount>1</c9:pageCount>
    <c9:pageSize>25</c9:pageSize>
  <item>
      <title>Where Did That Sound Come From?</title>
      <description><![CDATA[<span id="c4fmetadata">
<table class="" cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td class="" width="50">&nbsp;</td>
<td class=""><span class="entry_description">This April Fools' Day article walks you through how you can programmatically change the Windows system sound events to mess with a co-worker or family member. Like many other pranks, this one requires you to have
 physical access to your victim's computer at a time when they're not around.</span></td>
</tr>
<tr>
<td class="" colspan="2">
<div class="entry_author">Dan Fernandez</div>
<div class="entry_company"><a href="http://blogs.msdn.com/danielfe/">Dan's Blog</a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Easy</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
Less than 1 hour</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://msdn.com/express">Visual Basic or Visual C# Express Editions</a></span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input"></span></div>
<div class="entry_details"><b>Download: </b>
<ul>
<li><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/916051/RegistrySoundsCS.msi">C# Download</a>
</li><li><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/916051/RegistrySoundsVB.msi">VB Download</a></li></ul>
</div>
</td>
</tr>
</tbody>
</table>
</span>
<p><b>Video Demo</b></p>
<p><a href="http://download.microsoft.com/download/1/8/2/182200e0-cf87-47d6-87a7-32cb36bbfa42/systemsounds.wmv"><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/916051/splash.jpg" border="0"></a>
</p>
<p><a href="http://download.microsoft.com/download/1/8/2/182200e0-cf87-47d6-87a7-32cb36bbfa42/systemsounds.wmv"><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/916051/media6.jpg" border="0"></a>&nbsp;
<a href="http://download.microsoft.com/download/1/8/2/182200e0-cf87-47d6-87a7-32cb36bbfa42/systemsounds.wmv">
Download Video</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>This April Fools' Day article walks you through how you can programmatically change the Windows system sound events to mess with a co-worker or family member. Like many other pranks, this one requires you to have physical access to your victim's computer
 at a time when they're not around. As a best practice, I recommend that you back up your registry before running any code to manipulate registry settings, especially if you've never programmed the registry before.
</p>
<p>Microsoft Windows enables users to set sounds for system events, such as when Windows starts up, when a device is connected, when an error occurs, when a window is maximized, and more. What this article walks through is adding humorous or annoying system
 sounds for your victim for *every* Windows system sound. As with all pranks, you should find a way to personalize the sounds for your victim. Here are some ideas:
</p>
<ul>
<li>For the person with too much work, use C3PO from <i>Star Wars</i> saying,&quot;We're doomed.&quot;
</li><li>For <i>The Simpsons</i> fan, use Nelson the Bully's &quot;Ha Ha&quot; laugh or Homer Simpson's &quot;Doh.&quot;
</li><li>For the Warcraft player, use &quot;Leeeeeeroy Jennnnnnkins.&quot; </li><li>For the <i>South Park</i> fan, use Cartman's &quot;Respect My Authoritay&quot; clip. </li><li>For the disgruntled employee, use any quote from &quot;Office Space.&quot; </li></ul>
<p>If you're not sure where to find wave audio clips, you can find a good set of sound clips on sites like
<a href="http://www.reelwavs.com/">http://www.reelwavs.com/</a>and <a href="http://www.funwavs.com/">
http://www.funwavs.com/</a> among others. Below I'll show you two different ways to change system sounds, from requiring no code at all, to building a utility created with Express, to automate changing the system sounds.
</p>
<h4>No Tech System Sounds</h4>
<p>With your victim's machine unlocked, you can change their system sounds simply by opening the Control Panel and selecting &quot;Sounds.&quot; This will display the image below, which you can scroll through. Click &quot;Browse&quot; to assign a sound file to each system event.
 Then watch as just about every possible event triggers that sound file. </p>
<p>&nbsp;<img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/916051/sound_1.gif">
</p>
<p>&nbsp;</p>
<h4>Using Express to Change the System Sounds</h4>
<p>Using Visual Basic or Visual C# Express, you can take this a step further and create a utility that can automatically change all of the system sound files, back up and restore sounds settings, and test sounds.
</p>
<p><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/916051/sound_2.gif" width="485">
</p>
<p>&nbsp;</p>
<h4>How Does Windows Store Sound Events?</h4>
<p>The first thing we want to do is find out where the system sound files are stored. Since most Windows settings are stored in the registry, that seems like a logical place to start looking. To look inside the registry, click Start &gt; Run, then type &quot;regedit&quot;
 to open the Registry Editor. You can search the registry by clicking &quot;Edit &gt; Find,&quot; and since I know that the Windows Startup sound contains startup.wav, I simply search the registry for that sound. What you'll find is the registry hive that represents the
 system sounds, as shown below: </p>
<p>&nbsp;</p>
<p><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/916051/sound_3.gif">
</p>
<p>&nbsp;</p>
<p>The way this works is that each folder under Schemes/Apps/.Default represents an event you can map sounds to. For example, if you've ever unplugged a USB device, you know that there is a system sound associated with that event, the
<b>DeviceDisconnect</b> event. Underneath a specific event, like the <b>DeviceDisconnect</b> event, there will be a list of folders: .current, .Default, and one folder for any sound schemes they may have saved.</p>
<p><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/916051/sound_4.gif" width="485"> &nbsp;</p>
<p>&nbsp;</p>
<p>As you can see in the picture above, a specific system event has the following structure:
</p>
<ul>
<li><b>.current folder</b> — Contains a blank registry key whose value is the sound file currently set to play with that event. For the
<b>DeviceDisconnect</b> event, the current sound file for this event on my PC is &quot;%SystemRoot%\media\Windows XP Hardware Remove.wav&quot;, which maps to &quot;C:\WINDOWS\media\Windows XP Hardware Remove.wav&quot;.
</li><li><b>.Default folder</b> — Contains a blank registry key whose value is the default sound file to play with that event. Since I haven't changed my sound file, it is the same sound file as given in the .current key.
</li><li><b>other folders</b> — You may have other folders listed under each key (system event). This is because Windows allows you to save &quot;sound schemes,&quot; which represents your customized list of sound files. If you have a custom sound scheme, you'll see a directory
 for each scheme under every sound event. </li></ul>
<h4>Reading and Writing Event Sound Files </h4>
<p>Now that I know where the registry keys are located and what I want to do, I'm going to create a DataSet that represents the Windows sound event and the path to the sound file to play when that event occurs. To do this, I'm going to start a new Windows Forms
 project and select &quot;Add New Item...&quot; from the Solution Explorer window, and then select the DataSet template. To represent a sound event as a DataSet, I'll add two text fields, &quot;SoundName&quot; and &quot;SoundFile,&quot; as shown below:
</p>
<p><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/916051/sound_5.gif">
</p>
<p>&nbsp;</p>
<p>Next, I'll add a class file, RegistryWrapper.cs, which will wrap all of my registry functions, including reading and writing data. We'll walk through the major tasks we want to achieve here including registry tasks like reading, writing, backing up, restoring,
 and even playing a sound event. </p>
<p><b>Reading Sound Events from the Registry </b></p>
<p>Since I know the exact location of the sound events in the registry, I'm going to declare two variables in the RegistryWrapper class to store the registry prefix and suffix, so I won't have to declare the full path *everywhere* in my application.</p>
<p><b>Visual Basic</b></p>
<pre class="csharpcode"><span class="rem">'these represent the location in the registry with the user sounds</span><br><span class="kwrd">Private</span> hivePrefix <span class="kwrd">As</span> <span class="kwrd">String</span> = <span class="str">&quot;AppEvents\Schemes\Apps\.Default\&quot;</span><br><span class="kwrd">Private</span> hiveSuffix <span class="kwrd">As</span> <span class="kwrd">String</span> = <span class="str">&quot;\.current&quot;<br></span></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual C#</b></p>
<pre class="csharpcode"><span class="rem">//these represent the location in the registry with the user sounds</span><br><span class="kwrd">string</span> hivePrefix = <span class="str">@&quot;AppEvents\Schemes\Apps\.Default\&quot;;<br>string hiveSuffix = @&quot;</span>\.current&quot;;   </pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Next, we'll add a method called <b>GetSystemSound()</b> that returns a <b>RegSoundDataTable</b> containing the SoundName and SoundFile values for the registry. The first thing we do is get the list of all the subkeys for the path we specified above by calling
 the <b>GetSubKeyNames</b> method. This will return a list of all of the sound events. Next, we loop through each sound event, creating a new row for the DataTable while setting the SoundName to the current sound event and the SoundFile to the registry key
 value that contains the location of the sound. Note that when we call the <b>GetValue</b> method to get the sound file, we need to pass in the name of the key, which in our case is blank so we pass in
<b>&quot;&quot;</b>. We'll also add a helper function that simply concatenates the two variables declared earlier.</p>
<p><b>Visual Basic</b></p>
<pre class="csharpcode"><span class="kwrd"></span><span class="kwrd">Public</span> <span class="kwrd">Function</span> GetSystemSound() <span class="kwrd">As</span> RegSound.RegSoundDataTable<br>    <span class="rem">'Get the subkey key</span><br>    <span class="kwrd">Dim</span> values() <span class="kwrd">As</span> <span class="kwrd">String</span> = Registry.CurrentUser.OpenSubKey(hivePrefix).GetSubKeyNames<br>    <span class="kwrd">Dim</span> tb <span class="kwrd">As</span> RegSound.RegSoundDataTable = <span class="kwrd">New</span> RegSound.RegSoundDataTable<br>    <span class="kwrd">For</span> <span class="kwrd">Each</span> s <span class="kwrd">As</span> <span class="kwrd">String</span> <span class="kwrd">In</span> values<br>        <span class="rem">'Loop through rows</span><br>        <span class="kwrd">Dim</span> newRow <span class="kwrd">As</span> RegSound.RegSoundRow = tb.NewRegSoundRow<br>        newRow.SoundName = s<br>        newRow.SoundFile = _<br>            <span class="kwrd">CType</span>(My.Computer.Registry.CurrentUser.OpenSubKey(getRegKeyPath(s)).GetValue(<span class="str">&quot;&quot;</span>), _<br>            <span class="kwrd">String</span>)<br>        tb.Rows.Add(newRow)<br>    <span class="kwrd">Next</span><br>    <span class="kwrd">Return</span> tb<br><span class="kwrd">End</span> Function<br><br><span class="rem">'adds the full registry key including prefix and suffix</span><br><span class="kwrd">Private</span> <span class="kwrd">Function</span> getRegKeyPath(<span class="kwrd">ByVal</span> s <span class="kwrd">As</span> <span class="kwrd">String</span>) <span class="kwrd">As</span> <span class="kwrd">String</span><br>    <span class="kwrd">Return</span> (hivePrefix &amp; s &amp; hiveSuffix)<br><span class="kwrd">End</span> <span class="kwrd">Function</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual C#</b></p>
<pre class="csharpcode"><span class="kwrd">public</span> RegSound.RegSoundDataTable GetSystemSound()<br>{<br>    <span class="rem">//Get the subkey key</span><br>    <span class="kwrd">string</span>[] values = Registry.CurrentUser.OpenSubKey(hivePrefix).GetSubKeyNames();<br><br>    RegSound.RegSoundDataTable tb = <span class="kwrd">new</span> RegSound.RegSoundDataTable();<br><br>    <span class="kwrd">foreach</span> (<span class="kwrd">string</span> s <span class="kwrd">in</span> values)<br>    {<br>        <span class="rem">//Loop through rows</span><br>        RegSound.RegSoundRow newRow = tb.NewRegSoundRow();<br>        newRow.SoundName = s;<br>        newRow.SoundFile = <br>            (<span class="kwrd">string</span>)Registry.CurrentUser.OpenSubKey(getRegKeyPath(s)).GetValue(<span class="str">&quot;&quot;</span>) ;<br>        tb.Rows.Add(newRow);<br>    }<br>    <span class="kwrd">return</span> tb;<br>}<br><br><span class="rem">//adds the full registry key including prefix and suffix</span><br><span class="kwrd">private</span> <span class="kwrd">string</span> getRegKeyPath(<span class="kwrd">string</span> s)<br>{<br>    <span class="kwrd">return</span> hivePrefix &#43; s &#43; hiveSuffix;<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Writing Sound Events to the Registry </b></p>
<p>To set all of the sound events to a specific sound, we'll create another method that takes a
<b>RegSound DataTable</b> and the sound file we'll use for the change. We loop through every row in the DataTable and set the registry key value for the sound by calling the
<b>SetValue</b> method. To call the <b>SetValue</b> method, we need to know the key name (in our case its blank or
<b>&quot;&quot;</b>), the value to set it to (in our case the sound file path), and the RegistryKind, which describes the type or kind of value being stored (in our case a string) in the registry.
</p>
<p><b>Visual Basic</b></p>
<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">Sub</span> SetSystemSound(<span class="kwrd">ByVal</span> sounds <span class="kwrd">As</span> RegSound.RegSoundDataTable, <br>             <span class="kwrd">ByVal</span> soundPath <span class="kwrd">As</span> <span class="kwrd">String</span>)<br>    <span class="rem">'loop through all sounds</span><br>    <span class="kwrd">For</span> <span class="kwrd">Each</span> row <span class="kwrd">As</span> RegSound.RegSoundRow <span class="kwrd">In</span> sounds<br>        <span class="rem">'Set key and value</span><br>        <span class="kwrd">Dim</span> key <span class="kwrd">As</span> RegistryKey = _<br>           My.Computer.Registry.CurrentUser.OpenSubKey(getRegKeyPath(row.SoundName), _<br>           <span class="kwrd">True</span>)<br>        key.SetValue(<span class="str">&quot;&quot;</span>, soundPath, RegistryValueKind.<span class="kwrd">String</span>)<br>    <span class="kwrd">Next</span><br><span class="kwrd">End</span> <span class="kwrd">Sub</span><span class="kwrd"></span><br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual C#</b></p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> SetSystemSound(RegSound.RegSoundDataTable sounds, <br>        <span class="kwrd">string</span> soundPath)<br>{<br>    <span class="rem">//loop through all sounds</span><br>    <span class="kwrd">foreach</span> (RegSound.RegSoundRow row <span class="kwrd">in</span> sounds)<br>    {<br>        <span class="rem">//Set key and value</span><br>        RegistryKey key = <br>           Registry.CurrentUser.OpenSubKey(getRegKeyPath(row.SoundName), <span class="kwrd">true</span>);<br>        key.SetValue(<span class="str">&quot;&quot;</span>, soundPath, RegistryValueKind.String);    <br>    }<br>}</pre>
<p><b>Back Up Current Sound Settings</b> </p>
<p>Since your victim may be upset you changed his or her sounds, we'll add a way to save their current sound settings to the local hard drive where you can restore them later. To do this, we'll add the
<b>SaveSystemSound</b> method that takes the DataTable you want to save and the file location to save to. We can use the
<b>WriteXml</b> method on the DataTable object to save the DataTable as an XML file.</p>
<p><b>Visual Basic</b></p>
<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">Sub</span> SaveSystemSound(<br>         <span class="kwrd">ByVal</span> sounds <span class="kwrd">As</span> RegSound.RegSoundDataTable, <br>         <span class="kwrd">ByVal</span> savePath <span class="kwrd">As</span> <span class="kwrd">String</span>)<br>    <span class="rem">'Save Sound DataSet</span><br>    sounds.WriteXml(savePath)<br><span class="kwrd">End</span> Sub<span class="kwrd"></span></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual C#</b></p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> SaveSystemSound(<br>     RegSound.RegSoundDataTable sounds, <span class="kwrd">string</span> savePath)<br>{<br>    <span class="rem">//Save Sound DataSet</span><br>    sounds.WriteXml(savePath);<br>}<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Restoring Saved Sound Settings</b> </p>
<p>Now let's add a method to restore the sound settings from the previous step. In this case, we just need to know where the location of the saved DataTable is and call the
<b>ReadXml</b> method to read the data we stored previously. Once we have the data we can loop through each sound event and call the
<b>setValue</b> method to replace the current sound.<br>
<br>
<b>Visual Basic</b></p>
<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">Sub</span> RestoreSystemSound(<span class="kwrd">ByVal</span> savePath <span class="kwrd">As</span> <span class="kwrd">String</span>)<br>    <span class="rem">'Restore Sound DataSet</span><br>    <span class="kwrd">Dim</span> sounds <span class="kwrd">As</span> RegSound.RegSoundDataTable = _<br>         <span class="kwrd">New</span> RegSound.RegSoundDataTable<br>    sounds.ReadXml(savePath)<br>    <span class="kwrd">For</span> <span class="kwrd">Each</span> row <span class="kwrd">As</span> RegSound.RegSoundRow <span class="kwrd">In</span> sounds<br>        <span class="rem">'Set Key</span><br>        <span class="kwrd">Dim</span> key <span class="kwrd">As</span> RegistryKey = _<br>            My.Computer.Registry.CurrentUser.OpenSubKey( _<br>            getRegKeyPath(row.SoundName), <span class="kwrd">True</span>)<br>        key.SetValue(<span class="str">&quot;&quot;</span>, row.SoundFile, RegistryValueKind.<span class="kwrd">String</span>)<br>    <span class="kwrd">Next</span><br><span class="kwrd">End</span> Sub<span class="kwrd"></span></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual C#</b></p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> RestoreSystemSound(<span class="kwrd">string</span> savePath)<br>{<br>    <span class="rem">//Restore Sound DataSet</span><br>    RegSound.RegSoundDataTable sounds = <br>        <span class="kwrd">new</span> RegSound.RegSoundDataTable();<br>    sounds.ReadXml(savePath);<br><br>    <span class="kwrd">foreach</span> (RegSound.RegSoundRow row <span class="kwrd">in</span> sounds)<br>    {<br>        <span class="rem">//Set Key</span><br>        RegistryKey key = <br>               Registry.CurrentUser.OpenSubKey(<br>               getRegKeyPath(row.SoundName), <span class="kwrd">true</span>);<br>        key.SetValue(<span class="str">&quot;&quot;</span>, row.SoundFile, RegistryValueKind.String);<br>    }<br>}<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Playing a Registry Sound Event</b> </p>
<p>Finally, we'll add a way to play a registry sound. Since some sound files assume a path to the media folder under System root, we need to add a quick check to see if the file has any backslashes (&quot;\&quot;), which we'll use as a test to see if the sound file contains
 both a path and sound file. If it doesn't, we'll append the path to the sound file and play it.
</p>
<p><b>Visual Basic</b></p>
<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">Sub</span> PlayRegistrySound(<span class="kwrd">ByVal</span> soundFile <span class="kwrd">As</span> <span class="kwrd">String</span>)<br>    <span class="rem">'play sound if there is an associated file</span><br>    <span class="kwrd">If</span> (soundFile &lt;&gt; <span class="str">&quot;&quot;</span>) <span class="kwrd">Then</span><br><br>        <span class="rem">'add default path if there isn't one</span><br>        <span class="kwrd">Dim</span> a <span class="kwrd">As</span> <span class="kwrd">Integer</span> = soundFile.IndexOf(Microsoft.VisualBasic.ChrW(92))<br>        <span class="kwrd">If</span> (a &lt;&gt; 0) <span class="kwrd">Then</span><br><br>        <span class="kwrd">Else</span><br>            soundFile = <span class="str">&quot;%SystemRoot%\\media\\&quot;</span> &#43; soundFile<br>        <span class="kwrd">End</span> <span class="kwrd">If</span><br>        My.Computer.Audio.Play(soundFile)<br>    <span class="kwrd">End</span> <span class="kwrd">If</span><br><span class="kwrd">End</span> <span class="kwrd">Sub</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual C#</b></p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> PlayRegistrySound(<span class="kwrd">string</span> soundFile)<br>{<br>    <span class="rem">//play sound if there is an associated file</span><br>    <span class="kwrd">if</span> (soundFile != <span class="str">&quot;&quot;</span>)<br>    {<br>        SoundPlayer sp = <span class="kwrd">new</span> SoundPlayer();<br><br>        <span class="rem">//add default path if there isn't one</span><br>        <span class="kwrd">int</span> a = soundFile.IndexOf('\\');<br>        <span class="kwrd">if</span> (a != 0)<br>        {<br>            soundFile = &quot;%SystemRoot%\\media\\&quot; &#43; soundFile;<br>        }<br>        sp.SoundLocation = soundFile;<br>        sp.Play(); <br>    }       <br>}</pre>
<p><b>Creating the User Interface</b> </p>
<p>To create the user interface, we'll begin by adding some controls to our form including:
</p>
<ul>
<li>A ToolStrip control for the Backup, Restore, Select, and Apply Changes buttons.
</li><li>A DataGridView that we can drag and drop by clicking &quot;Data &gt; Show Data Sources,&quot; and dragging and dropping the RegSound DataGridView control.
</li><li>Two <b>OpenFileDialog</b> controls, one to choose where to restore from and another to choose the sound file to replace.
</li><li>One SaveFileDialog control to choose where to backup the current system sounds.
</li></ul>
<p>After adding in some nice IconBuffet icons that you get for <a href="http://msdn.microsoft.com/vstudio/express/register/">
registering Express</a>, your UI should look something like this: </p>
<p><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/916051/sound_6.gif" width="485">
</p>
<p>&nbsp;</p>
<p><b>Loading Data</b> </p>
<p>Finally, we're going to put it all together by adding a couple of functions to the Windows Form. The first thing we'll want to do is add two form variables, one to represent the RegistryWrapper we wrote before and another to store the RegSoundDataTable data.
 To populate the DataTable, well call the <b>GetRegistrySounds</b> method, which in turn calls the
<b>GetSystemSound</b> method we created earlier. We'll call the <b>GetRegistrySounds</b> method when the form loads, when we restore the sounds, or when we apply changes so that the DataGridView will display the current registry sounds.
</p>
<p><b>Visual Basic</b></p>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> frmMainForm_Load(<span class="kwrd">ByVal</span> sender <span class="kwrd">As</span> System.<span class="kwrd">Object</span>, _<br>        <span class="kwrd">ByVal</span> e <span class="kwrd">As</span> System.EventArgs) <span class="kwrd">Handles</span> <span class="kwrd">MyBase</span>.Load<br>    GetRegistrySounds()<br><span class="kwrd">End</span> Sub<span class="kwrd"></span><br><br><span class="kwrd">Private</span> <span class="kwrd">Sub</span> GetRegistrySounds()<br>    <span class="rem">'Call the RegistryWrapper Class</span><br>    sounds = myReg.GetSystemSound<br>    RegSoundDataGridView.DataSource = sounds<br><span class="kwrd">End</span> <span class="kwrd">Sub</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual C#</b></p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> frmMainMenu_Load(<span class="kwrd">object</span> sender, EventArgs e)<br>{<br>    GetRegistrySounds();            <br>}<br><span class="kwrd">private</span> <span class="kwrd">void</span> GetRegistrySounds()<br>{<br>    <span class="rem">//Call the RegistryWrapper Class</span><br>    sounds = myReg.GetSystemSound();<br>    regSoundDataGridView.DataSource = sounds;<br>}<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Formatting the DataGridView</b> </p>
<p>To add a nice UI, we'll format the DataGridView control by changing some of the properties, like setting the
<b>AlternatingRowsDefaultCellStyle</b> property to a different color, changing the DefaultCellStyle font to Arial 10, and turning off adding, editing, and deleting.
</p>
<p>We'll also add an image column with a &quot;play&quot; image so that we can here the currently associated sound. To do this, you can right-click on the DataGridView and select &quot;Edit Columns&quot; to bring up the Edit Column dialog box as shown below. Here we'll add a new
 column called &quot;Play,&quot; set the column type to DataGridViewImageColumn, set the <b>
Image</b> property to our sound image, and set the <b>ImageLayout property</b> to &quot;Zoom&quot; so that the image will fit the cell contents.
</p>
<p><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/916051/sound_7.gif" width="485">
</p>
<p>Finally, we'll want to add code to play a sound when someone clicks the sound image, and we can do this by adding the following code to the DataGridView CellContentClick event. As you can see below, we only play a sound if they clicked the third column (index
 start at 0 so the third is #2). To play a sound, we'll need the sound path, that we get by creating a
<b>DataGridViewTextBoxCell</b> for the SoundFile column and reading its value.</p>
<p><b>Visual Basic</b></p>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> RegSoundDataGridView_CellContentClick( _<br>        <span class="kwrd">ByVal</span> sender <span class="kwrd">As</span> System.<span class="kwrd">Object</span>, _<br>        <span class="kwrd">ByVal</span> e <span class="kwrd">As</span> System.Windows.Forms.DataGridViewCellEventArgs) _<br>        <span class="kwrd">Handles</span> RegSoundDataGridView.CellContentClick<br>    <span class="rem">'Represents col #3 the &quot;Play&quot; column</span><br>    <span class="kwrd">If</span> (e.ColumnIndex = 2) <span class="kwrd">Then</span><br>        <span class="kwrd">Dim</span> cell <span class="kwrd">As</span> DataGridViewTextBoxCell = _<br>           <span class="kwrd">CType</span>(RegSoundDataGridView.Rows(e.RowIndex).Cells((e.ColumnIndex - 1)), _<br>           DataGridViewTextBoxCell)<br>        <span class="rem">'Play Sound</span><br>        myReg.PlayRegistrySound(cell.Value.ToString)<br>    <span class="kwrd">End</span> <span class="kwrd">If</span><br><span class="kwrd">End</span> <span class="kwrd">Sub</span><br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual C#</b></p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> regSoundDataGridView_CellContentClick(<br>       <span class="kwrd">object</span> sender, DataGridViewCellEventArgs e)<br>{<br>    <span class="rem">//Represents col #3 the &quot;Play&quot; column</span><br>    <span class="kwrd">if</span> (e.ColumnIndex == 2)<br>    {<br>        DataGridViewTextBoxCell cell = (DataGridViewTextBoxCell)<br>          regSoundDataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex - 1]; <br>        <span class="rem">//Play Sound</span><br>        myReg.PlayRegistrySound(cell.Value.ToString());<br>    }<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<h4>Conclusion</h4>
<p>Reading and writing data out of the registry is pretty easy, as is saving structured data like a DataSet. It's almost too easy to find the right sound file on the Internet and of course make hilarity ensue when your poor unsuspecting victim tries to figure
 out what's wrong with their PC. If you want to extend this application, a couple of additions would be to add the ability to change sounds beyond the system sound, like logon sounds for MSN Messenger, blocked pop-ups by Internet Explorer, and a host of other
 sound files you can map your PC. </p>
<hr>
Daniel Fernandez is the Lead Product Manager for Visual Studio Express in the developer division at Microsoft.&nbsp; He has been with Microsoft since July 2001, previously working as a Developer Evangelist in the Mid-Atlantic district. Prior to joining Microsoft,
 he worked as a developer at several consulting firms including IBM Global Services specializing in web-based and mobile application development.
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/c4f.Dan-Fernandez/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:754a216c10e14229b0c89e7600da447d">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Where-Did-That-Sound-Come-From</comments>
      <itunes:summary>



&amp;nbsp;
This April Fools&#39; Day article walks you through how you can programmatically change the Windows system sound events to mess with a co-worker or family member. Like many other pranks, this one requires you to have
 physical access to your victim&#39;s computer at a time when they&#39;re not around.



Dan Fernandez
Dan&#39;s Blog

Difficulty: Easy
Time Required: 
Less than 1 hour
Cost: Free
Software: Visual Basic or Visual C# Express Editions
Hardware: 
Download: 

C# Download
VB Download






Video Demo 

 
&amp;nbsp;

Download Video 
&amp;nbsp; 
&amp;nbsp; 
This April Fools&#39; Day article walks you through how you can programmatically change the Windows system sound events to mess with a co-worker or family member. Like many other pranks, this one requires you to have physical access to your victim&#39;s computer
 at a time when they&#39;re not around. As a best practice, I recommend that you back up your registry before running any code to manipulate registry settings, especially if you&#39;ve never programmed the registry before.
 
Microsoft Windows enables users to set sounds for system events, such as when Windows starts up, when a device is connected, when an error occurs, when a window is maximized, and more. What this article walks through is adding humorous or annoying system
 sounds for your victim for *every* Windows system sound. As with all pranks, you should find a way to personalize the sounds for your victim. Here are some ideas:
 

For the person with too much work, use C3PO from Star Wars saying,&amp;quot;We&#39;re doomed.&amp;quot;
For The Simpsons fan, use Nelson the Bully&#39;s &amp;quot;Ha Ha&amp;quot; laugh or Homer Simpson&#39;s &amp;quot;Doh.&amp;quot;
For the Warcraft player, use &amp;quot;Leeeeeeroy Jennnnnnkins.&amp;quot; For the South Park fan, use Cartman&#39;s &amp;quot;Respect My Authoritay&amp;quot; clip. For the disgruntled employee, use any quote from &amp;quot;Office Space.&amp;quot; 
If you&#39;re not sure where to find wave audio clips, you can find a good set of sound clips on sites like
http://www.reelwavs.com/and 
htt</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Where-Did-That-Sound-Come-From</link>
      <pubDate>Tue, 31 Oct 2006 21:06:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Where-Did-That-Sound-Come-From</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/916051_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/916051_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Dan Fernandez</dc:creator>
      <itunes:author>Dan Fernandez</itunes:author>
      <slash:comments>7</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Where-Did-That-Sound-Come-From/RSS</wfw:commentRss>
    </item>
  <item>
      <title>When AutoCorrect Goes Bad</title>
      <description><![CDATA[<span id="c4fmetadata">
<table class="" cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td class="" width="50">&nbsp;</td>
<td class=""><span class="entry_description">This article showcases AutoCorrect feature of Microsoft Word 2003 and creates a sample application around it.</span></td>
</tr>
<tr>
<td class="" colspan="2">
<div class="entry_author">Dan Fernandez</div>
<div class="entry_company"><a href="http://blogs.msdn.com/danielfe/">Dan's Blog</a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Easy</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
1-3 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://msdn.com/express/">Visual Basic or Visual C# Express Editions</a>,
<a href="http://office.microsoft.com/">Microsoft Word 2003</a></span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input"></span></div>
<div class="entry_details"><b>Download: </b>
<ul>
<li><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/912524/FunWithAutoCorrect.msi">C# Download</a>
</li><li><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/912524/FunWithAutoCorrectVB.msi">VB Download</a></li></ul>
</div>
</td>
</tr>
</tbody>
</table>
</span>
<p><b>Video Demo</b></p>
<p>&nbsp;</p>
<p><a href="http://wm.microsoft.com/ms/msdn/coding4fun/april-fools/autocorrect.wmv"><img class="videosplash" height="346" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/912524/splash.jpg" width="463"></a>&nbsp;&nbsp;</p>
<p class="playercontainer" align="left"><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/912524/media5.jpg"><img height="46" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/912524/media6.jpg" width="46" align="left" border="0"></a>&nbsp;<a href="http://wm.microsoft.com/ms/msdn/coding4fun/april-fools/autocorrect.wmv">Download
 the video</a></p>
<p align="left"><br>
&nbsp;</p>
<p align="left">This April Fools' Day article walks you through adding entries into Microsoft Word 2003 AutoCorrect to mess with a co-worker or family member. As you might expect, this prank requires you to have physical access to your victim's computer at
 a time when they're not around. Luckily, it seems that the least technically inclined people are the most likely to leave their PCs unlocked for us to have fun with! As some of you probably know, AutoCorrect is a feature in Microsoft Word that, as its name
 states, automatically corrects text. What is does is replace misspelled words, such as &quot;teh,&quot; which it corrects to &quot;the&quot; automatically as you type. Using AutoCorrect, you can add a bunch of bogus AutoCorrect entries that ought to confuse and annoy your victim.
 I was inspired to use AutoCorrect for an April Fools' Day prank after using it in college on a nontech-savvy friend who was borrowing my computer and assured me that my computer had a virus because Word kept &quot;correcting&quot; his name to Moe Sislack (<i>The Simpsons</i>
 bar keep). Here are some fun AutoCorrect entries you can add to your hapless victim's computer:
</p>
<ul>
<li>
<div align="left">Replace a your victim's name with an amusing nickname, so &quot;Dan Fernandez&quot; becomes &quot;Danny 'two-tone' Fernandez.&quot;
</div>
</li><li>
<div align="left">Replace &quot;over&quot; with &quot;I see dead people&quot; so that they'll think their PC is haunted.
</div>
</li><li>
<div align="left">Replace &quot;the&quot; with &quot;le&quot; to make them think they somehow changed Word's default dictionary to French.
</div>
</li><li>
<div align="left">Replace &quot;Linux&quot; with &quot;Windows&quot; and watch as your office Linux bigot accidentally sends an e-mail praising Linux.
</div>
</li></ul>
<p align="left">If you're not sure what words to add, you can get the maximum impact by using the
<a href="http://esl.about.com/library/vocabulary/bl1000_list1.htm">most popular words in the English language</a>. Below I'll show you three different ways to add AutoCorrect entries, from requiring no code at all, to a utility created with Express, to automating
 adding multiple entries into AutoCorrect. </p>
<h4 align="left">No Tech AutoCorrect</h4>
<p align="left">With your victim's machine unlocked, you can add AutoCorrect entries simply by opening Word and clicking &quot;Tools &gt; AutoCorrect Options.&quot; This will display the image below, which you can use to add AutoCorrect entries. To add an entry, type the
 text you want replaced in the left text box and the replacement text to the right. As you can see in the screen shot, when &quot;c4f&quot; in Word has been automatically replaced by &quot;Coding4Fun.&quot;
</p>
<p align="left"><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/912524/AutoCorrect_1.gif">
</p>
<p align="left">Using Macros to Add AutoCorrect Entries </p>
<p align="left">One of the nice things about Word is that it includes a Macro Recorder which you can use to record actions and see the associated VBA Macro code. To record a macro, click &quot;Tool &gt; Macro &gt; Record New Macro.&quot; Enter a name in the Record Macro dialog
 box as shown below and click &quot;OK.&quot; </p>
<p align="left"><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/912524/AutoCorrect_2.gif">
</p>
<p align="left">Then simply follow the steps in the No Tech AutoCorrect section above to manually add an entry into AutoCorrect. The Macro Recorder will generate the code to add entries into AutoCorrect, which you can see by pressing ALT&#43;F11 to bring up the
 Visual Basic for Applications Editor. The code below shows how adding an AutoCorrect entry is only one line of code.
</p>
<div align="left">
<pre class="csharpcode">AutoCorrect.Entries.Add Name:=<span class="str">&quot;c4f&quot;</span>, Value:=<span class="str">&quot;Coding4Fun&quot;</span>&nbsp;</pre>
</div>
<h4 align="left">Using Express to Add AutoCorrect Entries</h4>
<p align="left">Using Visual Basic or Visual C# Express, we can take this a step further and create a utility that can automatically upload AutoCorrect entries represented as comma-separated values like &quot;hello, world&quot; to replace &quot;hello&quot; with &quot;world.&quot; To begin
 with, simply start a blank new Windows Form application in Express. To automate Word, you'll need to add a reference to the Microsoft Word 11.0 Object Library. To do this, click &quot;Project &gt; Add Reference&quot; and switch to the COM Tab. Scroll down to Microsoft
 Word 11.0 Object Library as shown below. </p>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p align="left"><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/912524/AutoCorrect_3.gif" width="485">
</p>
<p align="left">Next, we'll set up our Windows Form UI by dragging and dropping a text box and having it fill the entire form. Make sure to set the Textbox MultiLine property = &quot;True&quot;. To support opening and saving files, drag and drop the OpenFileDialog and
 SaveFileDialog controls onto the form. Finally, let's add a ToolStrip button and use the &quot;Insert Standard Items&quot; to get a classic Windows UI.
</p>
<p align="left"><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/912524/AutoCorrect_4.gif">
</p>
<p align="left">For this utility, we will only need the New, Open, Save, and Help buttons as well as two custom buttons, the first Add to AutoCorrect, another the other Remove from AutoCorrect. To make these prettier, I'm using the icons provided by IconBuffett
 when you register Express so that the final toolbar looks like this: </p>
<p align="left"><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/912524/AutoCorrect_5.gif">&nbsp;<br>
</p>
<p align="left">Our form uses some top-level variables that store a flag if the text in the text box has changed, the file name, and a generic Dictionary object that will hold the name/value pairs to be replaced.
</p>
<p align="left"><b>Visual Basic</b> </p>
<div align="left">
<pre class="csharpcode"><span class="rem">'Variables</span><br><span class="kwrd">Dim</span> textHasChanged <span class="kwrd">As</span> <span class="kwrd">Boolean</span> = <span class="kwrd">False</span><br><span class="kwrd">Dim</span> fileName <span class="kwrd">As</span> <span class="kwrd">String</span> = <span class="str">&quot;doc1.txt&quot;</span><br><span class="rem">'Use to hold a list of AutoCorrect entries</span><br><span class="kwrd">Dim</span> myAutoCorrect <span class="kwrd">As</span> <span class="kwrd">New</span> Dictionary(Of <span class="kwrd">String</span>, <span class="kwrd">String</span>)&nbsp;</pre>
</div>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p align="left"><b>Visual C#</b> </p>
<div align="left">
<pre class="csharpcode"><span class="rem">//Variables</span><br><span class="kwrd">
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">bool</span> textHasChanged = <span class="kwrd">false</span>;<br><span class="kwrd">private</span> <span class="kwrd">string</span> fileName = <span class="str">&quot;doc1.txt&quot;</span>;<br><br><span class="rem">//Use to hold a list of AutoCorrect entries</span><br>Dictionary&lt;<span class="kwrd">string</span>, <span class="kwrd">string</span>&gt; myAutoCorrect =<br>    <span class="kwrd">new</span> Dictionary&lt;<span class="kwrd">string</span>, <span class="kwrd">string</span>&gt;();</pre></span><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style></pre>
</div>
<p align="left"><b>Coding the New Button</b> </p>
<p align="left">When a user clicks the &quot;New&quot; button, we'll call the <b>promptToSave()</b> routine. The code below checks if the
<b>textHasChanged</b> property is set to true, and if so, it displays a message box asking them to save with Yes or No options. If the user clicks &quot;Yes,&quot; we'll call the
<b>Save Button</b> click event, to prompt them to save the file. </p>
<p align="left"><b>Visual Basic </b></p>
<div align="left">
<pre class="csharpcode"><span class="kwrd"><span class="rem">'Display a dialog to Save the text</span><br><span class="kwrd">Public</span> <span class="kwrd">Sub</span> promptToSave()<br><span class="kwrd">If</span> textHasChanged = <span class="kwrd">True</span> <span class="kwrd">Then</span><br>   <span class="rem">'Display a message box asking them to save</span><br>   <span class="kwrd">Dim</span> dr <span class="kwrd">As</span> DialogResult = MessageBox.Show(<span class="str">&quot;Do you want to save the changes to &quot;</span> &amp; _<br>       fileName &amp; <span class="str">&quot;?&quot;</span>, <span class="str">&quot;Save File&quot;</span>, MessageBoxButtons.YesNo, MessageBoxIcon.Warning)<br>   <span class="kwrd">If</span> dr = System.Windows.Forms.DialogResult.Yes <span class="kwrd">Then</span><br>       <span class="kwrd">Me</span>.SaveToolStripButton_Click(<span class="str">&quot;Save File&quot;</span>, EventArgs.Empty)<br>   <span class="kwrd">End</span> <span class="kwrd">If</span><br> <span class="kwrd">End</span> <span class="kwrd">If</span><br><span class="kwrd">End</span> <span class="kwrd">Sub</span></span></pre>
</div>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p align="left"><b>Visual C#</b> </p>
<p align="left"><b></b></p>
<div align="left">
<pre class="csharpcode"><span class="rem"><span class="rem"><span class="rem">//Display a dialog to Save the text</span><br><span class="kwrd">private</span> <span class="kwrd">void</span> promptToSave()<br>{<br><span class="kwrd">if</span> (textHasChanged == <span class="kwrd">true</span>)<br>   {<br>       <span class="rem">//Display a message box asking them to save</span><br>       DialogResult dr = MessageBox.Show(<span class="str">&quot;Do you want to save the changes to &quot;</span> &#43;<br>           fileName &#43; <span class="str">&quot;?&quot;</span>, <span class="str">&quot;Save File&quot;</span>, MessageBoxButtons.YesNo, <br>           MessageBoxIcon.Warning);<br>      <span class="kwrd">if</span> (dr == DialogResult.Yes)<br>       {<br>          <span class="kwrd">this</span>.saveToolStripButton_Click(<span class="str">&quot;Save File&quot;</span>, EventArgs.Empty);<br>       }<br>}<br>}<br></span><br></span><b>Coding the Open Button</b> </pre>
</div>
<p align="left">When a user clicks the &quot;Open&quot; button, we display the OpenFileDialog by calling the
<b>ShowDialog()</b> method. If the user clicks &quot;OK&quot; in that dialog, we'll set the file name and read in the contents of the file, in Visual Basic using My, and in Visual C# using the File class.
</p>
<p align="left"><b>Visual Basic</b> </p>
<div align="left">
<pre class="csharpcode"><span class="kwrd">
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> OpenToolStripButton_Click(<span class="kwrd">ByVal</span> sender <span class="kwrd">As</span> System.<span class="kwrd">Object</span>, <br>     <span class="kwrd">ByVal</span> e <span class="kwrd">As</span> System.EventArgs) <span class="kwrd">Handles</span> OpenToolStripButton.Click<br><span class="rem">'Open File Dialog</span><br>OpenFileDialog1.InitialDirectory = <br>      My.Computer.FileSystem.SpecialDirectories.Desktop<br>OpenFileDialog1.FileName = fileName<br><span class="kwrd">If</span> OpenFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK <span class="kwrd">Then</span><br>fileName = OpenFileDialog1.FileName<br>     txtWordList.Text = My.Computer.FileSystem.ReadAllText(fileName)<br><span class="kwrd">End</span> <span class="kwrd">If</span><br><span class="kwrd">End</span> <span class="kwrd">Sub</span></pre>
<pre class="csharpcode"><span class="kwrd"></span><br></pre></span><b>Visual C#</b> </pre>
</div>
<div align="left">
<pre class="csharpcode"><span class="rem">//Open document</span><br><span class="kwrd">private</span> <span class="kwrd">void</span> openToolStripButton_Click(<span class="kwrd">object</span> sender, EventArgs e)<br>{<br>    openFileDialog1.InitialDirectory = Environment.SpecialFolder.Desktop;<br>    <span class="rem">//Show the Open File Dialog</span><br>    openFileDialog1.FileName = fileName;<br>    <span class="kwrd">if</span> (openFileDialog1.ShowDialog() == DialogResult.OK)<br>    {<br>        fileName = openFileDialog1.FileName;<br>          txtWordList.Text = File.ReadAllText(fileName);<br>    }<br>}<br></pre>
</div>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p align="left"><b>Coding the Save Button</b> </p>
<p align="left">To wrap up, we'll display the SaveFileDialog when a user clicks the &quot;Save&quot; button and write the file to the file system, again in Visual Basic using My and in Visual C# using use the File class.
</p>
<p align="left"><b>Visual Basic</b> </p>
<div align="left">
<pre class="csharpcode"><span class="str">
<pre class="csharpcode"><span class="rem">'Save Document</span><br><span class="kwrd">Private</span> <span class="kwrd">Sub</span> SaveToolStripButton_Click(<span class="kwrd">ByVal</span> sender <span class="kwrd">As</span> System.<span class="kwrd">Object</span>, <br><span class="kwrd">ByVal</span> e <span class="kwrd">As</span> System.EventArgs) <span class="kwrd">Handles</span> SaveToolStripButton.Click<br><br><span class="rem">'Show the Save File Dialog</span><br>   SaveFileDialog1.FileName = fileName<br>   SaveFileDialog1.InitialDirectory = <br>          My.Computer.FileSystem.SpecialDirectories.Desktop<br><span class="kwrd">If</span> SaveFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK <span class="kwrd">Then</span><br>My.Computer.FileSystem.WriteAllText(SaveFileDialog1.FileName,<br>          txtWordList.Text, <span class="kwrd">False</span>)<br>      textHasChanged = <span class="kwrd">False</span><br><span class="kwrd">End</span> <span class="kwrd">If</span><br><span class="kwrd">End</span> <span class="kwrd">Sub</span><br><br></pre></span><b>Visual C#</b> </pre>
</div>
<div align="left">
<pre class="csharpcode"><span class="rem">//Save document</span><br><span class="kwrd">private</span> <span class="kwrd">void</span> saveToolStripButton_Click(<span class="kwrd">object</span> sender, EventArgs e)<br>{<br>    <span class="rem">//Show the Save File Dialog            </span><br>    saveFileDialog1.FileName = fileName;<br>    saveFileDialog1.InitialDirectory = Environment.SpecialFolder.Desktop.ToString();<br>    <span class="kwrd">if</span> (saveFileDialog1.ShowDialog() == DialogResult.OK)<br>    {<br>        File.WriteAllText(saveFileDialog1.FileName, txtWordList.Text);<br>        textHasChanged = <span class="kwrd">false</span>;<br>    }<br>}<br></pre>
</div>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p align="left"><b>Adding items to the AutoCorrect Dictionary Object</b> </p>
<p align="left">To add items to AutoCorrect, first we'll need to parse the text of the text box into name/value pairs and add them to the AutoCorrect dictionary object which will hold our new entries. To do this, we'll use the
<b>StringReader</b> class and read in the contents of the text box. Note that Visual Basic 2005 now has &quot;Using/End Using&quot; statements which enable you to automatically dispose of resources like file handles. We then use a
<b>While</b> loop to loop through every line in the text box and make sure the line isn't NULL. Next, we'll use the
<b>Split()</b> method to split the contents of a line into a string array using a comma (&quot;,&quot;) as our separator. For example, if
<b>currentLine</b> was set to &quot;Hello, World,&quot; calling <b>Split() </b>would return an array where
<b>element(0)</b> is &quot;Hello&quot; and <b>element(1)</b> is &quot;World.&quot; Finally we call the
<b>Add</b> method to add the key (Hello) and value (World) to the myAutoCorrect dictionary.
</p>
<p align="left"><b>Visual Basic</b> </p>
<div align="left">
<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">Sub</span> updateDictionary()<br>    <span class="kwrd">Dim</span> splitKeyValues() <span class="kwrd">As</span> <span class="kwrd">String</span><br>    <span class="kwrd">Dim</span> currentLine <span class="kwrd">As</span> <span class="kwrd">String</span><br>    Using sr <span class="kwrd">As</span> <span class="kwrd">New</span> StringReader(txtWordList.Text)<br>        <span class="rem">'loop through each line</span><br>        <span class="kwrd">While</span> <span class="kwrd">True</span><br>            currentLine = sr.ReadLine()<br>                <span class="kwrd">If</span> <span class="kwrd">Not</span> (currentLine <span class="kwrd">Is</span> <span class="kwrd">Nothing</span>) <span class="kwrd">Then</span><br>                <span class="rem">'split the text and add it to the AutoCorrect Dictionary</span><br>                    splitKeyValues = currentLine.Split(<span class="str">&quot;,&quot;</span>c)<br>                     myAutoCorrect.Add(splitKeyValues(0), splitKeyValues(1))<br>                  <span class="kwrd">Else</span>  <span class="rem">'break when we run out of lines</span><br>                    <span class="kwrd">Exit</span> <span class="kwrd">While</span><br>                  <span class="kwrd">End</span> <span class="kwrd">If</span><br>        <span class="kwrd">End</span> <span class="kwrd">While</span><br>    <span class="kwrd">End</span> Using<br><span class="kwrd">End</span> Sub</pre>
</div>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p align="left"><b>Visual C#</b> </p>
<div align="left">
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> updateDictionary()<br>{<br>    <span class="kwrd">string</span>[] splitKeyValues;<br>    <span class="kwrd">string</span> currentLine;<br>    <span class="kwrd">using</span> (StringReader sr = <span class="kwrd">new</span> StringReader(txtWordList.Text))<br>       {<br>               <span class="rem">//loop through each line</span><br>        <span class="kwrd">while</span> (<span class="kwrd">true</span>)<br>        {<br>            currentLine = sr.ReadLine();<br>                <span class="kwrd">if</span> (currentLine != <span class="kwrd">null</span>)<br>                 {<br>                <span class="rem">//split the text and add it to the AutoCorrect Dictionary</span><br>                splitKeyValues = currentLine.Split(<span class="str">','</span>);<br>                myAutoCorrect.Add(splitKeyValues[0], splitKeyValues[1]);<br>            }<br>                 <span class="kwrd">else</span> <span class="rem">//break when we run out of lines</span><br>                     <span class="kwrd">break</span>;<br>        }<br>    }<br>}<br></pre>
</div>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p align="left"><b>Adding AutoCorrect Entries Using the Word Object Library</b> </p>
<p align="left">Now that we have a dictionary of key/value pairs representing AutoCorrect entries, we need to add them to Word using the Microsoft Word Object Library. In this project, we'll wrap Word operations into a WordWrapperClass to encapsulate adding
 and removing items from AutoCorrect. The WordWrapperClass has two public methods,
<b>AddToAutoCorrect()</b> and <b>RemoveFromAutoCorrect()</b>, both of which expect a key/value generic dictionary class like myAutoCorrect. Notice below that we have two imports (&quot;using&quot; in C#) statements at the top of the file, one for the generic dictionary
 collection, and the other for interoperating with Word. The first thing we do in the
<b>AddToAutoCorrect</b> method is call the <b>startWord()</b> function, which creates a nonvisible instance of Microsoft Word. Next, for each of the keys in our dictionary, we get the value for a given key and call the
<b>AutoCorrect.Entries.Add(key,value)</b> method to add the entry into Word. When we're done adding, we call the
<b>quitWord()</b> method, which ensures the Word instance we created in the <b>startWord()</b> method is properly closed. One thing to note in the
<b>quitWord</b> method is that since Visual C# doesn't support optional parameters, we explicitly declare a variable named &quot;empty&quot; to represent a
<b>System.Reflection.Missing.Value</b> type. </p>
<p align="left"><b>Visual Basic</b> </p>
<div align="left">
<pre class="csharpcode"><span class="kwrd">Imports</span> System.Collections.Generic<br><span class="kwrd">Imports</span> Microsoft.Office.Interop.Word<br><br><span class="kwrd">Public</span> <span class="kwrd">Class</span> WordWrapper<br>    <span class="kwrd">Public</span> <span class="kwrd">Sub</span> AddToAutoCorrect(<span class="kwrd">ByVal</span> entries <span class="kwrd">As</span> Dictionary(Of <span class="kwrd">String</span>, <span class="kwrd">String</span>))<br>        <span class="kwrd">Dim</span> oWord <span class="kwrd">As</span> Application = startWord()<br>        <span class="kwrd">Dim</span> value <span class="kwrd">As</span> <span class="kwrd">String</span><br>        <span class="rem">'Loop through each entry from the dictionary</span><br>        <span class="kwrd">For</span> <span class="kwrd">Each</span> key <span class="kwrd">As</span> <span class="kwrd">String</span> <span class="kwrd">In</span> entries.Keys<br>        entries.TryGetValue(key, value) <span class="rem">'get the dictionary value</span><br>        <span class="rem">'***Add the AutoCorrect entry into Word***</span><br>        oWord.Application.AutoCorrect.Entries.Add(key, value)        <br>    <span class="kwrd">Next</span><br>        quitWord(oWord) <span class="rem">'cleanup</span><br>    <span class="kwrd">End</span> <span class="kwrd">Sub</span><br><br>    <span class="kwrd">Private</span> <span class="kwrd">Function</span> startWord() <span class="kwrd">As</span> Application<br>        <span class="rem">'Setup Word</span><br>        <span class="kwrd">Dim</span> oWord <span class="kwrd">As</span> Application = <span class="kwrd">New</span> Application()<br>        oWord.Visible = <span class="kwrd">False</span><br>        <span class="kwrd">Return</span> oWord<br>    <span class="kwrd">End</span> <span class="kwrd">Function</span><br><br>    <span class="kwrd">Private</span> <span class="kwrd">Sub</span> quitWord(<span class="kwrd">ByRef</span> oWord <span class="kwrd">As</span> Application)<br>        <span class="rem">'Quit Word</span><br>        oWord.Application.Quit()<br>    <span class="kwrd">End</span> <span class="kwrd">Sub</span><br><span class="kwrd">End</span> <span class="kwrd">Class</span><br></pre>
</div>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p align="left"><b>Visual C#</b> </p>
<div align="left">
<pre class="csharpcode"><span class="kwrd">using</span> System;<br><span class="kwrd">using</span> System.Collections.Generic;<br><span class="kwrd">using</span> System.Text;<br><span class="kwrd">using</span> Microsoft.Office.Interop.Word; <br><br><span class="kwrd">public</span> <span class="kwrd">class</span> WordWrapper<br>{<br>    <span class="kwrd">object</span> empty = System.Reflection.Missing.Value;<br>        <br>    <span class="kwrd">public</span> <span class="kwrd">void</span> AddToAutoCorrect(Dictionary&lt;<span class="kwrd">string</span>, <span class="kwrd">string</span>&gt; entries)<br>    {<br>        Application oWord = startWord(); <br>        <span class="kwrd">string</span> <span class="kwrd">value</span>;<br><br>        <span class="rem">//Loop through each entry from the dictionary</span><br>        <span class="kwrd">foreach</span> (<span class="kwrd">string</span> key <span class="kwrd">in</span> entries.Keys)<br>        {<br>            <span class="rem">//get the dictionary value </span><br>            entries.TryGetValue(key, <span class="kwrd">out</span> <span class="kwrd">value</span>);    <br>            <span class="rem">//***Add the AutoCorrect entry into Word***</span><br>            oWord.Application.AutoCorrect.Entries.Add(key, <span class="kwrd">value</span>);<br>        }<br>              quitWord(oWord); <span class="rem">//cleanup</span><br>    }<br><br>    <span class="kwrd">private</span> Application startWord()<br>    {<br>               Application oWord = <span class="kwrd">new</span> Application();<br>        oWord.Visible = <span class="kwrd">false</span>;<br>        <span class="kwrd">return</span> oWord;<br>    }<br><br>    <span class="kwrd">private</span> <span class="kwrd">void</span> quitWord(Application oWord)<br>    {<br>        <span class="rem">//Quit Word</span><br>        oWord.Application.Quit(<span class="kwrd">ref</span> empty, <span class="kwrd">ref</span> empty, <span class="kwrd">ref</span> empty);<br>    }<br>}<br></pre>
</div>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p align="left"><b>Removing AutoCorrect Entries from the Word Object Library</b> </p>
<p align="left">All good practical jokes hopefully leave no actual harm to your hapless victim and that's why we created a way to automate removing AutoCorrect Entries. This function is similar to the
<b>AddToAutoCorrect</b> method in that we pass in a generic Dictionary class containing key/value pairs for AutoCorrect entries. The difference here is that we have two loops, one for each Dictionary key, and another that loops through all of the AutoCorrect
 entries looking for matches. We need to loop through each AutoCorrect entry and verify that the key and value object match exactly those in our dictionary so that we don't delete any incorrect AutoCorrect entries. For example, we want to delete our &quot;Hello,World&quot;
 entry but don't want to fix &quot;helo,hello,&quot; for example. If we get an exact match on the key and value, we call the
<b>AutoCorrectEntry Delete()</b> method to remove it. </p>
<p align="left"><b>Visual Basic</b> </p>
<div align="left">
<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">Sub</span> RemoveFromAutoCorrect(<span class="kwrd">ByVal</span> entries <span class="kwrd">As</span> Dictionary(Of <span class="kwrd">String</span>, <span class="kwrd">String</span>))<br>    <span class="kwrd">Dim</span> oWord <span class="kwrd">As</span> Application = startWord()<br>    <span class="kwrd">Dim</span> value <span class="kwrd">As</span> <span class="kwrd">String</span><br><br>    <span class="rem">'Loop through each entry from the dictionary</span><br>    <span class="kwrd">For</span> <span class="kwrd">Each</span> key <span class="kwrd">As</span> <span class="kwrd">String</span> <span class="kwrd">In</span> entries.Keys<br>        entries.TryGetValue(key, value) <span class="rem">'get the dictionary value</span><br><br>        <span class="rem">'Loop through each Word AutoCorrect entry</span><br>        <span class="kwrd">For</span> <span class="kwrd">Each</span> a <span class="kwrd">As</span> AutoCorrectEntry <span class="kwrd">In</span> oWord.AutoCorrect.Entries<br>            <span class="rem">'Entries must match key and value</span><br>            <span class="kwrd">If</span> a.Name = key <span class="kwrd">And</span> a.Value = value <span class="kwrd">Then</span><br>                a.Delete() <span class="rem">'Delete the AutoCorrect entry</span><br>            <span class="kwrd">End</span> <span class="kwrd">If</span><br>        <span class="kwrd">Next</span><br>    <span class="kwrd">Next</span><br>    quitWord(oWord) <span class="rem">'cleanup</span><br><span class="kwrd">End</span> <span class="kwrd">Sub</span>
</pre>
</div>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p align="left"><b>Visual C#</b> </p>
<div align="left">
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> RemoveFromAutoCorrect(Dictionary&lt;<span class="kwrd">string</span>, <span class="kwrd">string</span>&gt; entries)<br>{<br>    Application oWord = startWord();<br>    <span class="kwrd">string</span> <span class="kwrd">value</span>;<br><br>    <span class="rem">//Loop through each entry from the dictionary</span><br>    <span class="kwrd">foreach</span> (<span class="kwrd">string</span> key <span class="kwrd">in</span> entries.Keys)<br>    {<br>        entries.TryGetValue(key, <span class="kwrd">out</span> <span class="kwrd">value</span>); <span class="rem">//get the dictionary value </span><br><br>        <span class="rem">//Loop through each Word AutoCorrect entry</span><br>        <span class="kwrd">foreach</span> (AutoCorrectEntry a <span class="kwrd">in</span> oWord.AutoCorrect.Entries)<br>        {<br>            <span class="rem">//Entries must match key and value</span><br>            <span class="kwrd">if</span> (a.Name == key &amp;&amp; a.Value == <span class="kwrd">value</span>)<br>            {<br>                a.Delete(); <span class="rem">//Delete the AutoCorrect entry </span><br>            }<br>        }<br>    }<br>    quitWord(oWord); <span class="rem">//cleanup       </span><br>}</pre>
</div>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<h4 align="left">Conclusion</h4>
<p align="left">AutoCorrect is a cool feature and automatically adding entries is both a great timesaver and (hopefully) humorous practical joke on your unsuspecting victim. If you're looking to modify this sample, you could add RichTextFile support so that,
 in addition to just changing text, you can have typed-in text be replaced by RT Text like images, colors, tables, and more. For example, you could AutoCorrect the word &quot;horse&quot; to a picture of Borat from the
<i>Ali G Show</i>. That will have to wait until next year though. </p>
<p align="left">Daniel Fernandez is the Lead Product Manager for Visual Studio Express in the developer division at Microsoft.&nbsp; He has been with Microsoft since July 2001, previously working as a Developer Evangelist in the Mid-Atlantic district. Prior to joining
 Microsoft, he worked as a developer at several consulting firms including IBM Global Services specializing in web-based and mobile application development.
</p>
<p align="left">&nbsp;</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/c4f.Dan-Fernandez/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:335a8042510243f49ad69e7600daec3b">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/When-AutoCorrect-Goes-Bad</comments>
      <itunes:summary>



&amp;nbsp;
This article showcases AutoCorrect feature of Microsoft Word 2003 and creates a sample application around it.



Dan Fernandez
Dan&#39;s Blog

Difficulty: Easy
Time Required: 
1-3 hours
Cost: Free
Software: Visual Basic or Visual C# Express Editions,
Microsoft Word 2003
Hardware: 
Download: 

C# Download
VB Download






Video Demo 
&amp;nbsp; 
&amp;nbsp;&amp;nbsp; 
&amp;nbsp;Download
 the video 

&amp;nbsp; 
This April Fools&#39; Day article walks you through adding entries into Microsoft Word 2003 AutoCorrect to mess with a co-worker or family member. As you might expect, this prank requires you to have physical access to your victim&#39;s computer at
 a time when they&#39;re not around. Luckily, it seems that the least technically inclined people are the most likely to leave their PCs unlocked for us to have fun with! As some of you probably know, AutoCorrect is a feature in Microsoft Word that, as its name
 states, automatically corrects text. What is does is replace misspelled words, such as &amp;quot;teh,&amp;quot; which it corrects to &amp;quot;the&amp;quot; automatically as you type. Using AutoCorrect, you can add a bunch of bogus AutoCorrect entries that ought to confuse and annoy your victim.
 I was inspired to use AutoCorrect for an April Fools&#39; Day prank after using it in college on a nontech-savvy friend who was borrowing my computer and assured me that my computer had a virus because Word kept &amp;quot;correcting&amp;quot; his name to Moe Sislack (The Simpsons
 bar keep). Here are some fun AutoCorrect entries you can add to your hapless victim&#39;s computer:
 


Replace a your victim&#39;s name with an amusing nickname, so &amp;quot;Dan Fernandez&amp;quot; becomes &amp;quot;Danny &#39;two-tone&#39; Fernandez.&amp;quot;


Replace &amp;quot;over&amp;quot; with &amp;quot;I see dead people&amp;quot; so that they&#39;ll think their PC is haunted.


Replace &amp;quot;the&amp;quot; with &amp;quot;le&amp;quot; to make them think they somehow changed Word&#39;s default dictionary to French.


Replace &amp;quot;Linux&amp;quot; with &amp;quot;Windows&amp;quot; and watch as your office Linux big</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/When-AutoCorrect-Goes-Bad</link>
      <pubDate>Tue, 31 Oct 2006 14:49:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/When-AutoCorrect-Goes-Bad</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/912524_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/912524_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Dan Fernandez</dc:creator>
      <itunes:author>Dan Fernandez</itunes:author>
      <slash:comments>3</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/When-AutoCorrect-Goes-Bad/RSS</wfw:commentRss>
    </item>    
</channel>
</rss>