Monday, January 19, 2009

Disable PrintScreen on C# without Keyboard Hooks


Yes, there is a simple solution to prevent grabbing information on your C# application screen with the keyboard's printscreen key without using keyboard hooks or calling COM interops. The solution makes use of Windows Forms Message Filter to trap keyboard events on your application window.

To trap keyboard events with Windows Message Filter, you need to implement the IMessageFilter interface and override the member PreFilterMessage(ref Message WM) method. This is the method called whenever a Form receives a keyboard or mouse event. You may want to read more about IMessageFilter.

The problem is that even though you have trapped the PrintScreen keypress event, the captured image will still persist to the clipboard. Therefore the simplest solution is to clear up the clipboard right after the PrintScreen is pressed on the keyboard.

This is how the overridden method will look like this:

public bool PreFilterMessage(ref Message WM)
{
Keys kCode = (Keys)(int)WM.WParam & Keys.KeyCode;

//block printscreen on KeyPress
if (kCode == Keys.Snapshot)
{
//remove the captured image from clipboard
Clipboard
.Clear();

MessageBox.Show("Printscreen not allowed.");

return true;

}

return false;

}

Another thing is that, if this method returns true, the Windows GDI Message will not be received by the Form.

Note: The PrintScreen event can only be captured if the Application window is active.


Enjoy!

12 comments:

  1. One question. I wrote code to capture the screen and save it as a .jpg file. Now i want to start that application when user press PrintScreen. Is there any chance to do that? Please answer as fast as you can. Thank you.
    Aleksandar

    ReplyDelete
  2. Hi Aleksandar,

    You will need to create a Windows Service Application to listen for the PrintScreen key presses and this will require you to use keyboard hook since Windows Services don't get a change to receive a focus.

    -Ross

    ReplyDelete
  3. Hehe, this made me laugh. Do you know that this code fails miserably? Sure, it deletes the clipboard, but only AFTER the OK button is clicked on the messagebox. Also, there are better ways to catch events beyond the form level.

    While you're at it, why don't you go ahead and turn off everything else which could remotely, possibly result in a theft of intellectual property. Like, say, the Shift, Control, and even the frigging arrow keys in this comment textbox. Oh wait, you've already done that. Lame.

    ReplyDelete
  4. hahaha... sorry. Just remove the MessageBox line (It's only to check if the event is captured). The objective of the code is not to use any Keyboard hooks and not to use Interop with user32.dll. And, blame blogspot/google for the frigging arrow in this comment box.

    ReplyDelete
  5. Will like to try this code - but i copied and paste without getting it work. Can I get from you a full working C# code in a blank form with only a exit button example?

    ReplyDelete
  6. First excuse me for my english... but i speak spanish... my question is: How prevent grabbing from all screen capture software (like Camtasia for example...)... thanks... I forget... In C# code please... Deener, Lima-PerĂº

    ReplyDelete
  7. @SAGYO SPORT - uninstall the screen capturing software. That's the best way to prevent it from capturing your screen.

    ReplyDelete
  8. what parameter should be passed in the PreFilterMessage in the KEyDown event of WinFoem app>>

    ReplyDelete
  9. No need to handle the Keydown event. What you need to do after doing the above is to use the form instance as a message filter. You can do this in the constructor:

    public partial class Form1 : Form
    {
    public Form1()
    {
    InitializeComponent();
    Application.AddMessageFilter(this);
    }
    }

    ReplyDelete
    Replies
    1. Thanks a lot for this reply. Solved my problem, together with the above article.

      Delete
  10. Window must be focused for the filter to work.

    ReplyDelete
  11. How to call this function

    ReplyDelete