첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestProject.zip
3.66MB

▶ BlockForm.cs

using System;
using System.Windows.Forms;

namespace TestProject
{
    /// <summary>
    /// 블럭 폼
    /// </summary>
    public partial class BlockForm : Form
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 최초 활성화 여부
        /// </summary>
        private bool firstActivated = true;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - BlockForm()

        /// <summary>
        /// 생성자
        /// </summary>
        public BlockForm()
        {
            InitializeComponent();

            SetStyle(ControlStyles.DoubleBuffer        , true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.UserPaint           , true);

            Activated               += Form_Activated;
            this.returnButton.Click += returnButton_Click;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 폼 활성화시 처리하기 - Form_Activated(sender, e)

        /// <summary>
        /// 폼 활성화시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void Form_Activated(object sender, EventArgs e)
        {
            if(this.firstActivated)
            {
                this.firstActivated = false;

                return;
            }

            if(WindowsHelper.IsLocked)
            {
                if(WindowsHelper.ScreenCount != System.Windows.Forms.Screen.AllScreens.Length)
                {
                    WindowsHelper.CloseBlockWindows();

                    WindowsHelper.ShowBlockWindows();
                }

                ////////// 개발시 사용 코드 START
                WindowsHelper.ShowCursor();
                ////////// 개발시 사용 코드 END

                ////////// 일반 사용 코드 START
                //WindowsHelper.DisableInput();
                //
                //WindowsHelper.HideCursor();
                ////////// 일반 사용 코드 END
            }
        }

        #endregion
        #region 돌아가기 버튼 클릭시 처리하기 - returnButton_Click(sender, e)

        /// <summary>
        /// 돌아가기 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void returnButton_Click(object sender, EventArgs e)
        {
            WindowsHelper.UnlockScreen();
        }

        #endregion
    }
}

 

728x90

 

▶ WindowsHelper.cs

using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace TestProject
{
    /// <summary>
    /// 윈도우즈 헬퍼
    /// </summary>
    public class WindowsHelper
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Structure
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 키보드 저수준 후킹 구조체 - KBDLLHOOKSTRUCT

        /// <summary>
        /// 키보드 저수준 후킹 구조체
        /// </summary>
        private struct KBDLLHOOKSTRUCT
        {
            //////////////////////////////////////////////////////////////////////////////////////////////////// Field
            ////////////////////////////////////////////////////////////////////////////////////////// Public

            #region Field

            /// <summary>
            /// 가상 키 코드
            /// </summary>
            public int VirtualKeyCode;

            /// <summary>
            /// 스캔 코드
            /// </summary>
            public int ScanCode;

            /// <summary>
            /// 플래그
            /// </summary>
            public int Flags;

            /// <summary>
            /// 시간
            /// </summary>
            public int Time;

            /// <summary>
            /// 부가 정보
            /// </summary>
            public int ExtraInfo;

            #endregion
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Delegate
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 키보드 후킹 처리 대리자 - ProcessKeyboardHookDelegate(code, wordParameter, longParameter)

        /// <summary>
        /// 키보드 후킹 처리 대리자
        /// </summary>
        /// <param name="code">코드</param>
        /// <param name="wordParameter">WORD 매개 변수</param>
        /// <param name="longParameter">LONG 매개 변수</param>
        /// <returns>처리 결과</returns>
        private delegate int ProcessKeyboardHookDelegate(int code, int wordParameter, ref KBDLLHOOKSTRUCT longParameter);

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Import
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region 윈도우 후킹 설정하기 - SetWindowsHookEx(hookID, processKeyboardHookDelegate, moduleHandle, threadID)

        /// <summary>
        /// 윈도우 후킹 설정하기
        /// </summary>
        /// <param name="hookID">후킹 ID</param>
        /// <param name="processKeyboardHookDelegate">키보드 후킹 처리 대리자</param>
        /// <param name="moduleHandle">모듈 핸들</param>
        /// <param name="threadID">스레드 ID</param>
        /// <returns>처리 결과</returns>
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int SetWindowsHookEx
        (
            int                         hookID,
            ProcessKeyboardHookDelegate processKeyboardHookDelegate,
            IntPtr                      moduleHandle,
            uint                        threadID
        );

        #endregion
        #region 윈도우 후킹 해제하기 - UnhookWindowsHookEx(hookHandle)

        /// <summary>
        /// 윈도우 후킹 해제하기
        /// </summary>
        /// <param name="hookHandle">후킹 핸들</param>
        /// <returns>처리 결과</returns>
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(int hookHandle);

        #endregion
        #region 다음 후킹 호출하기 - CallNextHookEx(hookHandle, code, wordParameter, longParameter)

        /// <summary>
        /// 다음 후킹 호출하기
        /// </summary>
        /// <param name="hookHandle">후킹 핸들</param>
        /// <param name="code">코드</param>
        /// <param name="wordParameter">WORD 매개 변수</param>
        /// <param name="longParameter">LONG 매개 변수</param>
        /// <returns>처리 결과</returns>
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int CallNextHookEx(int hookHandle, int code, int wordParameter, ref KBDLLHOOKSTRUCT longParameter);

        #endregion
        #region 모듈 핸들 구하기 - GetModuleHandle(modulName)

        /// <summary>
        /// 모듈 핸들 구하기
        /// </summary>
        /// <param name="modulName">모듈명</param>
        /// <returns>모듈 핸들</returns>
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string modulName);

        #endregion
        #region 입력 방지하기 - BlockInput(blocking)

        /// <summary>
        /// 입력 방지하기
        /// </summary>
        /// <param name="blocking">입력 방지 여부</param>
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        private static extern void BlockInput([In, MarshalAs(UnmanagedType.Bool)]bool blocking);

        #endregion
        #region 커서 표시하기 - ShowCursor(show)

        /// <summary>
        /// 커서 표시하기
        /// </summary>
        /// <param name="show">표시 여부</param>
        /// <returns>디스플레이 카운트</returns>
        [DllImport("user32.dll")]
        private static extern int ShowCursor(bool show);

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 키보드 후킹 처리 대리자
        /// </summary>
        private static ProcessKeyboardHookDelegate _processKeyboardHookDelegate = ProcessKeyboardHook;

        /// <summary>
        /// 후킹 ID
        /// </summary>
        private static int _hookID = 0;

        /// <summary>
        /// 태스크 관리자 이용 가능 여부
        /// </summary>
        private static bool _taskManagerEnabled = true;

        /// <summary>
        /// 특수 키보드 입력 이용 가능 여부
        /// </summary>
        private static bool _specialKeyboardInputEnabled = true;

        /// <summary>
        /// 잠금 여부
        /// </summary>
        private static bool _isLocked = false;

        /// <summary>
        /// 화면 리스트
        /// </summary>
        private static List<Screen> _screenList = null;

        /// <summary>
        /// 벽 폼 리스트
        /// </summary>
        private static List<BlockForm> _formList = null;

        /// <summary>
        /// 화면 카운트
        /// </summary>
        private static int _screenCount = 0; 

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Instance
        //////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// WH_KEYBOARD_LL
        /// </summary>
        private const int WH_KEYBOARD_LL = 13;

        /// <summary>
        /// WM_KEYDOWN
        /// </summary>
        private const int WM_KEYDOWN = 0x0100;

        /// <summary>
        /// WM_KEYUP
        /// </summary>
        private const int WM_KEYUP = 0x0101;

        /// <summary>
        /// WM_SYSKEYDOWN
        /// </summary>
        private const int WM_SYSKEYDOWN = 0x0104;

        /// <summary>
        /// WM_SYSKEYUP
        /// </summary>
        private const int WM_SYSKEYUP = 0x0105;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 화면 카운트 - ScreenCount

        /// <summary>
        /// 화면 카운트
        /// </summary>
        public static int ScreenCount
        {
            get
            {
                return _screenCount;
            }
        }

        #endregion
        #region 잠금 여부 - IsLocked

        /// <summary>
        /// 잠금 여부
        /// </summary>
        public static bool IsLocked
        {
            get
            {
                return _isLocked;
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Static

        #region 생성자 - WindowsHelper()

        /// <summary>
        /// 생성자
        /// </summary>
        static WindowsHelper()
        {
            SystemEvents.DisplaySettingsChanged += systemEvents_DisplaySettingsChanged;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 태스크 관리자 비활성화 하기 - DisableTaskManager()

        /// <summary>
        /// 태스크 관리자 비활성화 하기
        /// </summary>
        /// <remarks>Ctrl + Alt + Delete 키 입력을 거부한다.</remarks>
        public static void DisableTaskManager()
        {
            if(!_taskManagerEnabled)
            {
                return;
            }

            RegistryKey registryKey;
            int         keyValue = 1;
            string      subKey   = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";

            registryKey = Registry.CurrentUser.CreateSubKey(subKey);

            registryKey.SetValue("DisableTaskMgr", keyValue);

            registryKey.Close();

            _taskManagerEnabled = false;
        }

        #endregion
        #region 태스크 관리자 활성화 하기 - EnableTaskManager()

        /// <summary>
        /// 태스크 관리자 활성화 하기
        /// </summary>
        /// <remarks>Ctrl + Alt + Delete 키 입력을 허용한다.</remarks>
        public static void EnableTaskManager()
        {
            if(_taskManagerEnabled)
            {
                return;
            }

            RegistryKey currentUserRegistryKey = Registry.CurrentUser;
            string      subKey                 = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
            RegistryKey registryKey            = currentUserRegistryKey.OpenSubKey(subKey);

            if(registryKey != null)
            {
                currentUserRegistryKey.DeleteSubKeyTree(subKey);
            }

            _taskManagerEnabled = true;
        }

        #endregion

        #region 특수 키보드 입력 비활성 화기 - DisableSpecialKeyboardInput()

        /// <summary>
        /// 특수 키보드 입력 비활성 화기
        /// </summary>
        public static void DisableSpecialKeyboardInput()
        {
            if(!_specialKeyboardInputEnabled)
            {
                return;
            }

            _hookID = SetHook(_processKeyboardHookDelegate);

            _specialKeyboardInputEnabled = false;
        }

        #endregion
        #region 특수 키보드 입력 활성화 하기 - EnableSpecialKeyboardInput()

        /// <summary>
        /// 특수 키보드 입력 활성화 하기
        /// </summary>
        public static void EnableSpecialKeyboardInput()
        {
            if(_specialKeyboardInputEnabled)
            {
                return;
            }

            UnhookWindowsHookEx(_hookID);

            _specialKeyboardInputEnabled = true;
        }

        #endregion

        #region 입력 비활성화 하기 - DisableInput()

        /// <summary>
        /// 입력 비활성화 하기
        /// </summary>
        public static void DisableInput()
        {
            BlockInput(true);
        }

        #endregion
        #region 입력 활성화 하기 - EnableInput()

        /// <summary>
        /// 입력 활성화 하기
        /// </summary>
        public static void EnableInput()
        {
            BlockInput(false);
        }

        #endregion

        #region 커서 표시하기 - ShowCursor()

        /// <summary>
        /// 커서 표시하기
        /// </summary>
        public static void ShowCursor()
        {
            int displayCount = ShowCursor(true);

            while(displayCount < 0)
            {
                displayCount = ShowCursor(true);
            }
        }

        #endregion
        #region 커서 숨기기 - HideCursor()

        /// <summary>
        /// 커서 숨기기
        /// </summary>
        public static void HideCursor()
        {
            int displayCount = ShowCursor(false);

            while(displayCount >= 0)
            {
                displayCount = ShowCursor(false);
            }
        }

        #endregion

        #region 블럭 윈도우 보여주기 - ShowBlockWindows()

        /// <summary>
        /// 블럭 윈도우 보여주기
        /// </summary>
        public static void ShowBlockWindows()
        {
            _screenList = System.Windows.Forms.Screen.AllScreens.ToList();

            _screenCount = _screenList.Count;

            if(_formList == null)
            {
                _formList = new List<BlockForm>();
            }

            for(int i = 0; i < _screenList.Count; i++)
            {
                BlockForm form = new BlockForm();
                    
                form.FormBorderStyle = FormBorderStyle.None;
                form.WindowState     = FormWindowState.Maximized;
                form.StartPosition   = FormStartPosition.Manual;
                form.Left            = _screenList[i].WorkingArea.Left;
                form.Top             = _screenList[i].WorkingArea.Top;
                form.Width           = _screenList[i].WorkingArea.Width;
                form.Height          = _screenList[i].WorkingArea.Height;

                _formList.Add(form);

                form.Show();

                form.BringToFront();
            }
        }

        #endregion
        #region 블럭 윈도우 닫기 - CloseBlockWindows()

        /// <summary>
        /// 블럭 윈도우 닫기
        /// </summary>
        public static void CloseBlockWindows()
        {
            if(_formList.Count > 0)
            {
                for(int i = _formList.Count - 1; i > -1; i--)
                {
                    BlockForm form = _formList[i];

                    _formList.Remove(form);

                    form.Close();
                }

                _formList.Clear();
            }
        }

        #endregion

        #region 화면 잠그기 - LockScreen()

        /// <summary>
        /// 화면 잠그기
        /// </summary>
        public static void LockScreen()
        {
            if(_isLocked)
            {
                return;
            }

            HideCursor();

            DisableTaskManager();

            DisableSpecialKeyboardInput();

            DisableInput();

            ShowBlockWindows();

            _isLocked = true;
        }

        #endregion
        #region 화면 잠금 취소하기 - UnlockScreen()

        /// <summary>
        /// 화면 잠금 취소하기
        /// </summary>
        public static void UnlockScreen()
        {
            if(!_isLocked)
            {
                return;
            }

            CloseBlockWindows();

            EnableInput();

            EnableSpecialKeyboardInput();

            EnableTaskManager();

            ShowCursor();

            _isLocked = false;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Private
        ////////////////////////////////////////////////////////////////////// Event

        #region 시스템 이벤트 디스플레이 설정 변경시 처리하기 - systemEvents_DisplaySettingsChanged(sender, e)

        /// <summary>
        /// 시스템 이벤트 디스플레이 설정 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private static void systemEvents_DisplaySettingsChanged(object sender, EventArgs e)
        {
            if(_isLocked)
            {
                if(_screenCount != System.Windows.Forms.Screen.AllScreens.Length)
                {
                    CloseBlockWindows();

                    ShowBlockWindows();
                }

                HideCursor();
            }
        }

        #endregion

        ////////////////////////////////////////////////////////////////////// Function

        #region 후킹 설정하기 - SetHook(processKeyboardHookDelegate)

        /// <summary>
        /// 후킹 설정하기
        /// </summary>
        /// <param name="processKeyboardHookDelegate">키보드 후킹 처리 대리자</param>
        /// <returns>처리 결과</returns>
        private static int SetHook(ProcessKeyboardHookDelegate processKeyboardHookDelegate)
        {
            using(Process process = Process.GetCurrentProcess())
            {
                using(ProcessModule processModule = process.MainModule)
                {
                    return SetWindowsHookEx(WH_KEYBOARD_LL, processKeyboardHookDelegate, GetModuleHandle(processModule.ModuleName), 0);
                }
            }
        }

        #endregion
        #region 키보드 후킹 처리하기 - ProcessKeyboardHook(code, wordParameter, longParameter)

        /// <summary>
        /// 키보드 후킹 처리하기
        /// </summary>
        /// <param name="code">코드</param>
        /// <param name="wordParameter">WORD 매개 변수</param>
        /// <param name="longParameter">LONG 매개 변수</param>
        /// <returns>처리 결과</returns>
        private static int ProcessKeyboardHook(int code, int wordParameter, ref KBDLLHOOKSTRUCT longParameter)
        {
            bool result = false;

            switch(wordParameter)
            {
                case WM_KEYDOWN    :
                case WM_KEYUP      :
                case WM_SYSKEYDOWN :
                case WM_SYSKEYUP   :

                    result = ((longParameter.VirtualKeyCode == 0x09) && (longParameter.Flags == 0x20)) || // Alt + Tab
                             ((longParameter.VirtualKeyCode == 0x1B) && (longParameter.Flags == 0x20)) || // Alt + Esc
                             ((longParameter.VirtualKeyCode == 0x1B) && (longParameter.Flags == 0x00)) || // Ctrl + Esc
                             ((longParameter.VirtualKeyCode == 0x5B) && (longParameter.Flags == 0x01)) || // Left Windows Key
                             ((longParameter.VirtualKeyCode == 0x5C) && (longParameter.Flags == 0x01)) || // Right Windows Key
                             ((longParameter.VirtualKeyCode == 0x73) && (longParameter.Flags == 0x20));   // Alt + F4

                    break;
            }

            if(result == true)
            {
                return 1;
            }
            else
            {
                return CallNextHookEx(0, code, wordParameter, ref longParameter);
            }
        }

        #endregion
    }
}

 

300x250

 

▶ MainForm.cs

using System;
using System.Windows.Forms;

namespace TestProject
{
    /// <summary>
    /// 메인 폼
    /// </summary>
    public partial class MainForm : Form
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainForm()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            this.lockButton.Click   += lockButton_Click;
            this.unlockButton.Click += unlockButton_Click;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 화면 잠금 버튼 클릭시 처리하기 - lockButton_Click(sender, e)

        /// <summary>
        /// 화면 잠금 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void lockButton_Click(object sender, EventArgs e)
        {
            WindowsHelper.LockScreen();
        }

        #endregion
        #region 잠금 취소 버튼 클릭시 처리하기 - unlockButton_Click(sender, e)

        /// <summary>
        /// 잠금 취소 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void unlockButton_Click(object sender, EventArgs e)
        {
            WindowsHelper.UnlockScreen();
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요