Entries:
Comments:
Posts:

Loading User Information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading User Information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

Possessed PC Pranks for Halloween

Pumpkin In this application, Brian Peek demonstrates how to create two spooky Halloween applications to trick your friends and colleagues.
ASPSOFT, Inc.

Difficulty: Easy
Time Required: Less than 1 hour
Cost: Free
Software: Visual Basic or Visual C# Express Editions, DirectX SDK (for application #1)
Hardware: None
Download: Download

 

Introduction

Last year I wrote two articles on how to annoy your friends and family by dripping blood down their computer screen, or by squirting them with (hopefully) fake blood from (even more hopefully) a fake skull.  Halloween is just around the corner, so here are two more applications which you can use to further bother the people around you.

 

Application #1 - Cursed Video

If you have ever seen the horror film The Ring, then you can likely guess the basic premise of this application.  For those that haven't, the film is about a video tape which, when watched, will cause the viewer to die within a week of viewing it.  So, what better way to annoy and terrify your friends than by playing the "cursed video" at a time you schedule without their knowing?

This application will use a library from Managed DirectX to play the video.  If you haven't already, grab the full DirectX SDK and install.  Note that we will be creating a dependency on DirectX, so the victim's PC will need to have DirectX 9.0c installed.  Almost every XP desktop has it installed at this point, but be sure to test the app on the target PC.  Additionally, I have had mixed success drawing a semi-transparent video with every method I've tried (DX, WPF, etc.).  It is very dependent on video drivers, so the intended effect may not be perfect on all PCs.  Again, be sure to test.

Next, create a new C#/VB Windows Application project and set references to the Microsoft.DirectX and Microsoft.DirectX.AudioVideoPlayback assemblies as shown:

image

Next, we need to make some modifications to the form.  The video will be played at 50% transparency against the victim's desktop, which gives a very creepy effect.  The form should also be hidden from view until the video is ready to be played at the selected time.  To do this, set the following properties on the form:

Property Value
BackColor Fuchsia
FormBorderStyle None
WindowState Minimized
Opacity 50%
ShowInTaskbar False
TopMost True
TransparencyKey Fuchsia

Next, we need to provide a surface onto which the video can be drawn.  Drop a PictureBox control onto the form and set its properties as follows:

Property Value
BackColor Fuchsia
Dock Fill

Now we need a method which will play the video.  Bring in the Microsoft.DirectX.AudioVideoPlayback namespace with the using/Imports keyword and then add the following method to the form:

C#

using Microsoft.DirectX.AudioVideoPlayback;

...

Video _video;

public void StartShow()
{
    // create a new video from a filename
    this._video = Video.FromFile("ring.wmv");

    // set the drawable surface to the picturebox
    this._video.Owner = pictureBox1;

    // setup an event handler so we can pop up a msgbox when the video is over
    this._video.Ending += new EventHandler(video_Ending);

    // play it!
    this._video.Play();
}

void video_Ending(object sender, EventArgs e)
{
    // called when the video ends
    MessageBox.Show("Happy Halloween!");
    this.Close();
}

VB

Imports Microsoft.DirectX.AudioVideoPlayback

...

Private _video As Video

Public Sub StartShow()
    ' create a new video from a filename
    Me._video = Video.FromFile("ring.wmv")

    ' set the drawable surface to the picturebox
    Me._video.Owner = pictureBox1

    ' setup an event handler so we can pop up a msgbox when the video is over
    AddHandler _video.Ending, AddressOf video_Ending

    ' play it!
    Me._video.Play()
End Sub

Private Sub video_Ending(ByVal sender As Object, ByVal e As EventArgs)
    ' called when the video ends
    MessageBox.Show("Happy Halloween!")
    Me.Close()
End Sub

This simply creates a new Video object by loading a specific filename (ring.wmv), then assigns the video's Owner property to the PictureBox, which is where the video will be drawn.  Next, an event is setup so we are notified when the clip has ended, and finally, the video is played with the Play method.

The video_Ending event handler displays a message box and closes down the application.

x86/x64

The Managed DirectX assemblies are compiled to run in x86 mode only.  If you are compiling the application on an x64 OS, you will have to ensure that the main application is built as an x86 target.  To do so, choose Configuration Manager from the build menu.  In the dialog that appears, choose <New...> from the Active solution platform drop down:

new

Finally, choose x86 from the Type or select the new platform drop down:

x86

Get back to the project and rebuild and you will have an x86-native application which will run successfully on both x86 and x64 platforms.

Config/Test/Scheduler

The code which handles the configuration, scheduling and testing will be the same for both of these applications, so please jump to that section by clicking here.

 

Application #2 - The Shining

If you have seen The Shining, you can probably guess where this one is heading, too.  The basic plot is that an author and his family retreat to an isolated hotel for the winter, and some paranormal activity causes the father to go a bit insane, among other things.  In the film, as the author goes crazy, he starts typing "All work and no play makes Jack a dull boy" over and over again on the typewriter.  So, this application will mimic that by, at the appointed time, popping up an instance of Notepad and having the computer type the phrase over and over again on its own.

Once again, create a new VB/C# Windows Application project.  As with the previous project, we want the main form to be hidden, but this time, it should be hidden at all times.  So, set the form properties as follows:

Property Value
FormBorderStyle None
WindowState Minimized
ShowInTaskbar False
Size 10, 10

Next, drag a timer onto the form named tmrType and create an event handler for the Tick event which we will fill in later.

Create a method named StartShow as follows:

C#

using System.Diagnostics;
...

private Process _process;

public void StartShow()
{
    _process = Process.Start("notepad.exe");
    tmrType.Start();
}

VB

Imports System.Diagnostics

...

' the Notepad process
Private _process As Process

Public Sub StartShow()
    _process = Process.Start("notepad.exe")
    tmrType.Start()
End Sub

This code starts an instance of Notepad and then starts the tmrType ticking.  That tick event will send the appropriate letter to the Notepad window from the phrase:

C#

using System.Runtime.InteropServices;

...

[DllImport("user32")]
public static extern int SetForegroundWindow(IntPtr hwnd);

// counter variables
private int i, j;

// the message to type out
private const string msg = "All work and no play makes Jack a dull boy.";

...

private void tmrType_Tick(object sender, EventArgs e)
{
    // make sure the Notepad window is at the front
    SetForegroundWindow(_process.MainWindowHandle);

    // send the next letter to the window
    if(i < msg.Length)
        SendKeys.Send(msg[i++].ToString());
    else
    {
        // send a carriage return if we're at the end of the line
        SendKeys.Send("{ENTER}");

        // write the line 5 times
        if(++j < 5)
            i = 0;
        else
        {
            // when done, stop the timer, display the msgbox and close it up
            tmrType.Stop();
            MessageBox.Show("Happy Halloween!");
            this.Close();
        }
    }
}

VB

Imports System.Runtime.InteropServices

...

<DllImport("user32")> _
Public Shared Function SetForegroundWindow(ByVal hwnd As IntPtr) As Integer
End Function

' counter variables
Private i, j As Integer

' the message to type out
Private Const msg As String = "All work and no play makes Jack a dull boy."

Private Sub tmrType_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles tmrType.Tick
    ' make sure the Notepad window is at the front
    SetForegroundWindow(_process.MainWindowHandle)

    ' send the next letter to the window
    If i < msg.Length Then
        SendKeys.Send(msg.Chars(i).ToString())
        i += 1
    Else
        ' send a carriage return if we're at the end of the line
        SendKeys.Send("{ENTER}")

        ' write the line 5 times
        j = j + 1
        If j < 5 Then
            i = 0
        Else
            ' when done, stop the timer, display the msgbox and close it up
            tmrType.Stop()
            MessageBox.Show("Happy Halloween!")
            Me.Close()
        End If
    End If
End Sub

At the start of the tick, a call is made to the Win32 API function SetForegroundWindow, passing in the window handle (_process.MainWindowHandle) of the Notepad process.  This ensures that the Notepad window is focused before we send the next letter to the window using the SendKeys method.  When the end of the phrase is reached, a carriage return is sent using SendKeys and the string {ENTER}.  This repeats 5 times at which point the timer is stopped, the message box is displayed, and the application closes.

 

The Scheduler

The final piece is to setup a time at which the effect will display on the victim's PC.  Create a simple dialog box with a DateTimePicker control that allows the choosing of the appropriate date/time to run:

image

Next, create a new application setting named Time as shown:

image

Next, setup the events on the Configuration form as follows:

C#

private void ConfigForm_Load(object sender, EventArgs e)
{
    // if no time has been specified, show today's date, otherwise, show the date previously selected
    if(Properties.Settings.Default.Time == DateTime.MinValue)
        dateTimePicker1.Value = DateTime.Now.Date;
    else
        dateTimePicker1.Value = Properties.Settings.Default.Time;
}

private void btnSave_Click(object sender, EventArgs e)
{
    // save the currently selected date/time to the Settings collection
    Properties.Settings.Default.Time = dateTimePicker1.Value;

    Properties.Settings.Default.Save();

    // tell the user what's up
    MessageBox.Show("Date and time saved.  When you click OK, the application will continue running and the show will start upon the specified date and time.  If you wish to reset the date/time, restart the application with the '-config' switch.", "Configuration updated", MessageBoxButtons.OK, MessageBoxIcon.Information);

    // close it up
    this.DialogResult = DialogResult.OK;
    this.Close();
}

private void btnCancel_Click(object sender, EventArgs e)
{
    // close it up
    this.DialogResult = DialogResult.Cancel;
    this.Close();
}

VB

Private Sub ConfigForm_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
    ' if no time has been specified, show today's date, otherwise, show the date previously selected
    If My.Settings.Default.Time = DateTime.MinValue Then
        dateTimePicker1.Value = DateTime.Now.Date
    Else
        dateTimePicker1.Value = My.Settings.Default.Time
    End If
End Sub

Private Sub btnSave_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnSave.Click
    ' save the currently selected date/time to the Settings collection
    My.Settings.Default.Time = dateTimePicker1.Value

    My.Settings.Default.Save()

    ' tell the user what's up
    MessageBox.Show("Date and time saved.  When you click OK, the application will continue running and the show will start upon the specified date and time.  If you wish to reset the date/time, restart the application with the '-config' switch.", "Configuration updated", MessageBoxButtons.OK, MessageBoxIcon.Information)

    ' close it up
    Me.DialogResult = System.Windows.Forms.DialogResult.OK
    Me.Close()
End Sub

Private Sub btnCancel_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnCancel.Click
    ' close it up
    Me.DialogResult = System.Windows.Forms.DialogResult.Cancel
    Me.Close()
End Sub

The code loads the current value at start (if it exists), saves it when the Save button is clicked, and does nothing when Cancel is clicked.

Back on the main form of either application, drag and drop a timer control named tmrScheduler to the main design surface.  Set the properties as follows:

Property Value
Enabled True
Interval 60000

This will start the timer immediately and call the Tick event once every minute.  That event will check to see whether the requested time has passed and, if so, starts the show:

C# - Cursed Video

private void tmrScheduler_Tick(object sender, EventArgs e)
{
    // if the current time is greater than the time set by the user
    if(DateTime.Now >= Properties.Settings.Default.Time)
    {
        // bring up the window
        this.WindowState = FormWindowState.Maximized;

        // disable this timer
        tmrScheduler.Enabled = false;

        // bring it to the top
        this.BringToFront();

        // play the movie
        StartShow();
    }
}

VB - Cursed Video

Private Sub tmrScheduler_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles tmrScheduler.Tick
    ' if the current time is greater than the time set by the user
    If DateTime.Now >= My.Settings.Default.Time Then
        ' bring up the window
        Me.WindowState = FormWindowState.Maximized

        ' disable this timer
        tmrScheduler.Enabled = False

        ' bring it to the top
        Me.BringToFront()

        ' play the movie
        StartShow()
    End If
End Sub

C# - The Shining

private void tmrScheduler_Tick(object sender, EventArgs e)
{
    // if the current time is greater than the time set by the user
    if(DateTime.Now >= Properties.Settings.Default.Time)
    {
        // disable this timer
        tmrScheduler.Enabled = false;

        // start typing
        StartShow();
    }
}

VB - The Shining

Private Sub tmrScheduler_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles tmrScheduler.Tick
    ' if the current time is greater than the time set by the user
    If DateTime.Now >= My.Settings.Default.Time Then
        ' disable this timer
        tmrScheduler.Enabled = False

        ' start typing
        StartShow()
    End If
End Sub

Configuration/Testing

To make it easy to reset the launch time, and to test the effect without scheduling it, two command line parameters can be added to Program.cs/vb to re-run the configuration or test.  Add the following code prior to the call to Application.Run:

C#

// test the effect
if(Environment.CommandLine.IndexOf("test") > -1)
{
    Form1 f = new Form1();
    f.StartShow();
    f.ShowDialog();
    return;
}

// if we haven't set the time, or the user requested the config dialog, display it
if(Properties.Settings.Default.Time == DateTime.MinValue || Environment.CommandLine.IndexOf("config") > -1)
{
    if(new ConfigForm().ShowDialog() == DialogResult.Cancel)
        return;
}

VB

' test the effect
If Environment.CommandLine.IndexOf("test") > -1 Then
    Dim f As Form1 = New Form1()
    f.StartShow()
    f.ShowDialog()
    Return
End If

' if we haven't set the time, or the user requested the config dialog, display it
If My.Settings.Default.Time = DateTime.MinValue OrElse Environment.CommandLine.IndexOf("config") > -1 Then
    If New ConfigForm().ShowDialog() = DialogResult.Cancel Then
        Return
    End If
End If

If -test is passed on the command line, the form is created and the show is started.  If -config is passed on the command line, the Configuration dialog is displayed and the application continues as it would the first time it ran.

Deployment

Cursed Video

Copy the exe, Microsoft.DirectX and Microsoft.DirectX.AudioVideoPlayback to a folder on the user's PC along with a video clip named ring.wmv.  Of course, you can replace that video clip with any clip of your choosing, though if you wish to use a different filename, you will have to change the code and recompile.

The Shining

Copy the exe to a folder on the user's PC.

 

For either, create a shortcut to it in the Startup program group, or set it up to run via the registry using the following key for the logged in user:

  • HKCU\Software\Microsoft\Windows\CurrentVersion\Run

Simply create a new string key with any Name, and a Data value of the path to the executable.

Next, start the application once on their PC to setup the date and time for the show to begin. Once that is done, the application will remain running in the background. If the PC is restarted, and the application is setup to run at startup as described above, it will start silently and remain running, waiting for the date and time specified.

Summary

Two Halloween applications for the price of one.  Not that you paid for either.  Be sure to have fun with them this Halloween and disturb anyone you can.  Enjoy!

Thanks

Thanks to Giovanni Montrone for testing out these applications during development.

Bio

Brian is a Microsoft C# MVP and a recognized .NET expert with over 6 years experience developing .NET solutions, and over 9 years of professional experience architecting and developing solutions using Microsoft technologies and platforms, although he has been "coding for fun" for as long as he can remember.  Outside the world of .NET and business applications, Brian enjoys developing both hardware and software projects in the areas of gaming, robotics, and whatever else strikes his fancy for the next ten minutes. He rarely passes up an opportunity to dive into a C/C++ or assembly language project.  You can reach Brian via his blog at http://www.brianpeek.com/.

Tags:

Follow the Discussion

  • HiramHiram

    Hi I'm using C# 2008 Express but the configuration manager in the build menu is not active,

    what can be happening?

  • Clint RutkasClint I'm a "developer"

    @Hiram:  use the contact page so I can get a better understanding of what is happening.

  • BrianPeek.comBrianPeek.​com

    Here is a list of my current Coding4Fun articles: WiiEarthVR Animated Musical Holiday Light Show - Version

  • WillWill

    What Type do you select for the Time settings, it is unclear from the picture..

  • Clint RutkasClint I'm a "developer"

    @Will If I understand what you're asking, that is a control built into the framework.

Remove this comment

Remove this thread

close

Comments Closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.