Disabling the PrtSc key by blocking input


A customer asked how to disable the PrtSc key in the On-Screen Keyboard.

There is no way to disable the PrtSc key in the On-Screen Keyboard. The On-Screen Keyboard shows a keyboard, and you can click any virtual key you like. There is no policy to remove specific keys from the On-Screen Keyboard.

But this was a case of a customer breaking down a problem and asking a question about a specific part of the problem instead of presenting the entire problem so that a solution to the overall problem could be developed.

The customer's real goal was to disable the PrtSc key in general. They had figured out how to disable it on their physical keyboards by using the PS/2 scan code mapper, but they found that users could circumvent the feature by using the On-Screen Keyboard, so they asked if there was something they could do about the On-Screen Keyboard.

They didn't mention this when they asked the original question, so I replied by saying, "The mechanism for blocking the screen capture functionality in the window manager should work regardless of whether the request came from the physical keyboard or the virtual keyboard."

Naturally, the customer liaison decided to direct follow-up questions to me directly, even though I was replying from my phone while doing a quick email check while on vacation, and I had to remind him that my response to your message should not be interpreted as meaning that I had taken responsibility for driving your issue to resolution. I had to steer the thread back to the distribution list so that somebody else could pick up the ball while I was out of the office. (Either that, or the customer ends up waiting until the next time I feel like checking email while on vacation, which could be quite a while.)

The solution to the original problem is not to try to identify every possible source of a PrtSc keypress and block it there, because even a simple script can use the Send­Keys method to inject the PrtSc key.

You block the message in the window manager by installing a low-level keyboard hook that rejects the VK_SNAP­SHOT key.

Today's Little Program is a printscreen blocker. Remember, Little Programs have little to no error checking, because that's the way they roll.

Take our scratch program and add the following lines of code:

HHOOK g_hhk;
LRESULT CALLBACK KHook(int nCode, WPARAM wParam, LPARAM lParam)
{
 if (nCode == HC_ACTION) {
 if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) {
  PKBDLLHOOKSTRUCT phs = (PKBDLLHOOKSTRUCT)lParam;
  if (phs->vkCode == VK_SNAPSHOT) {
   MessageBeep(0); // annoying beep
   return 1; // block the key
  }
 }
 }
 return CallNextHookEx(g_hhk, nCode, wParam, lParam);
}

...
    ShowWindow(hwnd, nShowCmd);

    g_hhk = SetWindowsHookEx(WH_KEYBOARD_LL, KHook,
                             NULL, 0);

    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    UnhookWindowsHookEx(g_hhk);

This program installs a low-level keyboard hook which listens for presses of the VK_SNAP­SHOT key, and if it sees one, it beeps and then returns 1 to block further processing.

Note that we are using a global solution to a local problem. If you want to block PrtSc because you have sensitive information in your application that you don't want captured, then tag your window to be excluded from screen capturing. That way, the user can still capture other windows. It also tells other screen capturing programs to exclude your window from the capture.

Comments (12)
  1. Vilx- says:

    I'm guessing this still doesn't prevent the Snipping Tool and it's moral equivalents from capturing the screen?

  2. Joshua says:

    Nor is it effective at blocking screen snapshot via RDP.

  3. Matt says:

    Or taking a picture of your screen with an iPhone or painting it in watercolours onto a canvas sitting next to your laptop.

    Seriously guys. This is a tiny program, and it does what it says it does, which is to reject PRNTSCRN button presses being sent to your window. Nothing more. Nothing less.

  4. SimonRev says:

    Yes, but as engineers if someone tells us that screen printing is blocked on a particular computer we will immediately put all our energies to figure out how to circumvent this.

  5. Boris says:

    Assuming the goal was to make screencaps harder, this couldn't have been done by group policy at the time?

  6. Adam Rosenfield says:

    This program caused my computer to completely lock up the moment I hit the PrtSc key, requiring it to be power cycled.  Almost like the time I thought it'd be a good idea to set the registry key "Image File Execution Optionscmd.exedebugger" — except that time my computer also locked up immediately after logging in, so I needed to use a recovery CD to manually fix my registry and undo my stupidity.

  7. ErikF says:

    Disallowing print screen and friends seems like a losing battle, but I'd rather the person doing these shenanigans using a keyboard hook than messing with my keyboard layout. At least I can remove a hook fairly easily; I'm pretty sure I wouldn't think about the keyboard mappings table as it's pretty obscure and a *very* global solution to a local problem!

  8. Antonio 'Grijan' says:

    @Adam: that's what God invented virtual machines for…

  9. Anil Kulkarni says:

    An important thing to consider when using LL hooks is to run them on a dedicated thread, so as to not tie up the system.

  10. Silly says:

    I wrote something similar to the above back in the late 90's, but its sole purpose was to beep on any keystroke if some small random number of milliseconds had passed since the last beep. So in other words its sole purpose was to annoy and confuse any workmates who liked to listen to music on their headphones and left their computer unlocked and unattended (basically I was a newly-graduated smart-a**). But I remember having to put the hook function in a separate dll, though the memory is hazy. Nowadays I'd consider such an action tantamount to vandalism… I've lost the edge.

  11. hacksoncode says:

    I know we're not to complain about error checking in "Little Programs", but… I'm curious about the documentation of "SetWindowsHookEx": "An error may occur if the hMod parameter is NULL and the dwThreadId parameter is zero or specifies the identifier of a thread created by another process." Perhaps the LL hooks don't have this limitation because they are never injected?

    I'm also really curious (because the documentation doesn't say), how CallNextHookEx works on the WH_KEYBOARD_LL hook, since LL hooks aren't injected/executed in the target thread context. I would guess that it just calls SendMessage to forward the hook call to the next process in the chain?

    And, of course, this only works if nothing else in the hook chain before this hook returned early or caused an error that resulted in nCode being <0. Like, say, the hook my devious application installed to circumvent this stupid feature :-).

  12. Dan says:

    Speaking of PrtSc, I know this is slightly (well ok, completely) off-topic, but has anyone ever had Alt+PrtSc fail them? Ever since I can remember Alt+PrtSc has perfectly captured _only_ the active window, but on an old Lenovo laptop I recently installed Windows 7 32-bit on (Intel XDDM driver installed in compatibility mode, no Aero support, only Aero Basic and Win Classic, works _very_ nicely once I installed 3GB max RAM and SSD), it ends up capturing the active window and the top of the taskbar! Here's a screenshot: http://i.imgur.com/BS5Dc7E.png

    Has anyone ever seen anything this weird? I take it it's the display driver's fault? (And Intel's of course, the only hardware manufacturer not to have released updated drivers for this model.)

    [Look closely. The taskbar overlaps the bottom window border. (You also have this problem on the other three edges of the window, but since you have a single-monitor system, you don't notice it.) -Raymond]

Comments are closed.

Skip to main content