/// <summary>
        ///
        /// </summary>
        /// <param name="className"></param>
        /// <param name="callback"></param>
        public RegisterWindow(string className, Action <WindowMessage> callback)
        {
            if (className == null)
            {
                throw new Exception("className is null");
            }
            if (className == string.Empty)
            {
                throw new Exception("className is empty");
            }

            _customWndProc = callback;

            _wndProcDelegate = ProxyWndProc;

            WndClassStruct wndClass = new WndClassStruct
            {
                lpszClassName = className,
                lpfnWndProc   = Marshal.GetFunctionPointerForDelegate(_wndProcDelegate)
            };

            ushort classAtom = RegisterClassW(ref wndClass);

            int lastError = Marshal.GetLastWin32Error();

            if (classAtom == 0 && lastError != ERROR_CLASS_ALREADY_EXISTS)
            {
                throw new Exception("Could not register window class");
            }

            _hwnd = CreateWindowExW(
                0,
                className,
                string.Empty,
                0,
                0,
                0,
                0,
                0,
                IntPtr.Zero,
                IntPtr.Zero,
                IntPtr.Zero,
                IntPtr.Zero
                );
            Logger.Info("Created window " + _hwnd);

            if (!ChangeWindowMessageFilterEx(_hwnd, WM_COPYDATA, ChangeWindowMessageFilterExAction.Allow, IntPtr.Zero))
            {
                var isAdmin = new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
                Logger.Warn("Failed to remove UIPI filter restrictions.");
                if (isAdmin)
                {
                    Logger.Fatal("Running as administrator, will not be able to communicate with GD due to UIPI filter.");
                }
                else
                {
                    Logger.Info("Not running as administrator, UIPI filter not required.");
                }
            }
        }
 private static extern ushort RegisterClassW([In] ref WndClassStruct lpWndClass);