How do I prevent print screen

老子叫甜甜 提交于 2019-11-27 08:28:17

You can't.

The best you can do is render to a hardware accelerated device on an overlay, similar to what video players used to do. Basically, you paint your entire window blue, and render your graphics onto the video card, and internally the video card will replace the blue with the graphics. The downside to this is you have to give up using winforms controls, and I don't know of any way to do this with .NET easily. I think if you use DirectShow.NET, one of their samples is putting your own graphics into a stream.

Even after doing all of that, it's still possible to get a screenshot. Just take a picture of the screen with a digital camera.

z -

From here:

A. Windows implements Print Screen using a registered hotkey. Windows uses the predefined hotkeys IDHOT_SNAPDESKTOP and IDHOT_SNAPWINDOW to handle Print Screen. These correspond to Print Screen, which captures the entire screen, and Alt+Print Screen, which captures only the active window. To disable these functions all you have to do is register the hotkeys, which causes Windows to send your app a WM_HOTKEY message when the user presses either hotkey. Your implementation can ignore the message to bypass the default screen-capture behavior. A good place to do it is in your mainframe class.

You'll have two cases here that you need to worry about. One, when your window/application has focus, the other when it doesn't have focus.

When it doesn't have focus, there's not a whole lot you can do, i.e. if the user clicks off of your app and onto the desktop, keys aren't sent to your app so you'll never see them. In that case, you can minimize to the tray when your app loses focus (or, perhaps, place a "blank" panel over the form to prevent users from seeing anything on it which will also prevent a print-screen from being useful).

In the other case, when you have focus, capture keystrokes and examine them. If the Alt key is down and the PrintScreen key is down, reset the value so that a print-screen doesn't occur. (Come to think of it, that may not work. I'd need to test it to be sure.)

You could look into what movie players do. I believe they render directly to a hardware surface (via DirectX). I suspect that you'd need to do this.

FWIW, it is possible. Here's some code:

This would be a dll that you create, then call the HookKeyboard method from your application. I've tested it and it works. Granted, if someone takes a picture with a camera it can't help, but, point made. NYAH!

    namespace KeyboardHook
    {
        public class Hooker
        {

            [StructLayout(LayoutKind.Sequential)]
            public struct KBDLLHOOKSTRUCT
            {
                public int vkCode;
                public int scanCode;
                public int flags;
                public int time

;
            public int extraInfo;
        }

        public delegate int HookProc(int nCode, int wParam, IntPtr ptrKBDLLHOOKSTRUCT);


        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern IntPtr SetWindowsHookEx(int idHook, HookProc callBack, IntPtr hMod, int threadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern int CallNextHookEx(IntPtr hhk, int nCode, int wParam, IntPtr lParam);

        private static IntPtr kbh_Handle;
        private static HookProc kbh_HookProc;

        private const int VK_SNAPSHOT = 0x2C;
        private const int WM_KEYDOWN = 0x0100;
        private const int WM_SYSKEYDOWN = 0x0104;
        private const int WH_KEYBOARD_LL = 13;

        private static int LowLevelKeyboardProc(int nCode, int wParam, IntPtr lParam)
        {
            if (nCode < 0)
            {
                CallNextHookEx(kbh_Handle, nCode, wParam, lParam);
                return 0;
            }

            if (wParam == WM_KEYDOWN)
            {
                IntPtr kbdll = lParam;
                KBDLLHOOKSTRUCT kbdllstruct = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(kbdll, typeof(KBDLLHOOKSTRUCT));

                if (kbdllstruct.vkCode == VK_SNAPSHOT)
                    return -1;

            }

            return CallNextHookEx(kbh_Handle, nCode, wParam, lParam);
        }

        public static void HookKeyboard()
        {
            try
            {
                kbh_HookProc = LowLevelKeyboardProc;

                kbh_Handle = SetWindowsHookEx(WH_KEYBOARD_LL, kbh_HookProc, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);

                if (kbh_Handle != IntPtr.Zero)
                    System.Diagnostics.Debug.WriteLine(String.Format("It worked! HookHandle: {0}", kbh_Handle));
                else
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(String.Format("ERROR: {0}", ex.Message));
            }
        }
    }
}

This doesn't really answer the questions, but keep in mind that there exists tools to capture screen, and that a simple camera breaks everything.

I mean ok you "have to", but I would (but I'm young and still student, so I don't know much about what can be said) answer that this is just stupid.

Mat

Check out the new tech - sivizion.com, they prevent print screen all together - no way to bypass it. If anyone will figure out a way how to hack it, please post here, I couldn't. I think they also license their tech, not sure, check it out.

You can try using IpcProtectWindow provided in msipc.dll.

[DllImport("msipc.dll", SetLastError = false, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
internal static extern int IpcProtectWindow([In] IntPtr hwnd);

Download the SDK from Microsoft

Call the function above and provide the handle of the form you would like to protect. (Form.Handle property)

Well, you could try capturing the button, but I'm not sure how well that will work.

One thing that always annoyed me was that whenever I played a movie, it would never take screenshots of it. If you can render through a separate context, it would make it really annoying to take a picture of it. Perhaps you can send your screen output through something like that?

There are applications that can capture the screen from OpenGL and DirectX apps ! (depending (they are used for recording game movies) ps. windows aero is DirectX

http://www.fraps.com/ i think thats the application

You can make any casual Print Screen useless using Visual Cryptography and taking advantage of retinal persistence (see this article for details, and bit.ly/vcrypto for a web demo).

The idea is to alternate at high frequency between two or more random noise images, that will combine through persistence of vision to reveal the content. A screen capture will only grab one image, with meaningless random noise.

This comes at the cost of flickering and inducing user headaches, can be defeated by a camera taking a picture of the screen, or by a less casual user that knows photoshop, but will defeat any kind of casual screen capture or frame grabbing.

Might occasionally be useful, in an academic meaning of the term!

It is too late but there is a quick work around, Simply use it in MDI form
Set TopMost Property of form True, then write below event private void frmMDI_Deactivate(object sender, EventArgs e){Clipboard.Clear();}

after taking print screen user have to minimize the application, the moment user minimize the app, we are clearing clipboard.

you can use this in logout function or when screen move or resize or any other form event as required :)

Snipping tool also can't copy screens by this if TopMost Property is true.

Yes we can't stop user from capturing screen from external device like phone or cam.

In windows form application, Use this code in form keyup event,

   if (e.KeyCode == Keys.PrintScreen)
                {
                    Clipboard.Clear();
                }

Form keypreview should be TRUE

Alireza

I solved it using a Timer object and Clipboard.Clear() method.

First add a Timer to your main form with Interval=1 (Very fast), then add the following code in its event:

Clipboard.Clear();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!