Esempio n. 1
0
        /// <summary>
        /// グローバルのカーソルの情報を取得する
        /// </summary>
        /// <exception cref="PlatformInvokeException">
        /// Win32Apiの処理「DLL:user32.dll、メソッド:GetCursorInfo」の呼び出しに失敗した場合に発生
        /// </exception>
        /// <exception cref="Win32OperateException">
        /// Win32Apiの処理「DLL:user32.dll、メソッド:GetCursorInfo」の処理に失敗した場合に発生
        /// </exception>
        /// <returns>取得したカーソル情報</returns>
        private static Cursor.CURSORINFO GetCursorInfo()
        {
            // Win32Apiの実行処理
            // Win32ApiのWindou共通の呼び出し機能を用いて、グローバルのカーソルの情報を取得処理を呼び出す
            Win32ApiResult Function()
            {
                Cursor.CURSORINFO info = new Cursor.CURSORINFO
                {
                    StructureSize = Marshal.SizeOf(typeof(Cursor.CURSORINFO)),
                };
                bool win32Result    = Win32Api.GetCursorInfo(ref info);
                int  win32ErrorCode = Marshal.GetLastWin32Error();

                return(new Win32ApiResult(info, win32Result, win32ErrorCode));
            }

            // 実行
            string         dllName    = "user32.dll";
            string         methodName = nameof(Win32Api.GetCursorInfo);
            Win32ApiResult result     = Win32ApiCommon.Run(Function, dllName, methodName);

            // 正常終了したかチェック
            if (!result.Result && result.ErrorCode != (int)ErrorCode.NO_ERROR)
            {
                throw Win32ApiCommon.GetWin32OperateException(dllName, methodName, result.ErrorCode);
            }

            // 取得したカーソル情報を返却
            return((Cursor.CURSORINFO)result.ReturnValue);
        }
Esempio n. 2
0
        /// <summary>
        /// 現在のカーソルをキャプチャする(画像、座標情報を取得)
        /// </summary>
        /// <param name="backgroundImage">
        /// Iビームカーソル等の背景に応じで色が変化するカーソルを、
        /// 正確に描画するために使用するカーソルの下にある背景画像
        /// (NULLを指定した場合、白一色の背景としてカーソルをキャプチャする)
        /// </param>
        /// <param name="backgroundImageScreenPoint">
        /// 背景画像の画面上の座標(画像の左上の絶対座標)
        /// </param>
        /// <exception cref="PlatformInvokeException">
        /// Win32Apiの下記の処理の呼び出しに失敗した場合に発生
        /// ・「DLL:user32.dll、メソッド:GetCursorInfo」
        /// ・「DLL:user32.dll、メソッド:CopyIcon」
        /// ・「DLL:user32.dll、メソッド:GetIconInfo」
        /// ・「DLL:gdi32.dll、メソッド:CreateCompatibleDC」
        /// ・「DLL:gdi32.dll、メソッド:SelectObject」
        /// ・「DLL:gdi32.dll、メソッド:BitBlt」
        /// ・「DLL:gdi32.dll、メソッド:DeleteObject」
        /// ・「DLL:gdi32.dll、メソッド:DeleteDC」
        /// ・「DLL:user32.dll、メソッド:DestroyIcon」
        /// </exception>
        /// <exception cref="Win32OperateException">
        /// Win32Apiの下記の処理に失敗した場合に発生
        /// ・「DLL:user32.dll、メソッド:GetCursorInfo」
        /// ・「DLL:user32.dll、メソッド:CopyIcon」
        /// ・「DLL:user32.dll、メソッド:GetIconInfo」
        /// ・「DLL:gdi32.dll、メソッド:CreateCompatibleDC」
        /// ・「DLL:gdi32.dll、メソッド:SelectObject」
        /// ・「DLL:gdi32.dll、メソッド:BitBlt」
        /// ・「DLL:gdi32.dll、メソッド:DeleteObject」
        /// ・「DLL:gdi32.dll、メソッド:DeleteDC」
        /// ・「DLL:user32.dll、メソッド:DestroyIcon」
        /// </exception>
        /// <returns>
        /// 現在のカーソルの画像、座標情報
        /// (カーソルが取得できない場合はNULLを返却する)
        /// </returns>
        public static CursorInfo CaptureCurrentCursor(
            Bitmap backgroundImage, Point backgroundImageScreenPoint)
        {
            // カーソル情報を取得
            Cursor.CURSORINFO cursorInfo = GetCursorInfo();
            if (cursorInfo.Flag != (int)Cursor.State.CURSOR_SHOWING)
            {
                // カーソルを表示していない場合、NULL を返却する
                return(null);
            }

            // アイコン用のハンドルを宣言
            SafeCopyIconHandle iconHandle = null;

            IconInfo.ICONINFO iconInfo = default;
            try
            {
                // システムからアイコンのハンドルをコピーしておく
                iconHandle = CopyIcon(cursorInfo.CursorHandle);

                // アイコン情報を取得
                iconInfo = GetIconInfo(iconHandle);

                // 取得したアイコン情報がカーソルでない場合、NULL を返却する
                if (iconInfo.IsIcon)
                {
                    return(null);
                }

                // カーソルの座標を取得
                // 絶対座標(カーソルのホットスポットの分値を補正する)
                Point screenPoint = new Point(
                    x: cursorInfo.ScreenPosition.X - iconInfo.HotspotX,
                    y: cursorInfo.ScreenPosition.Y - iconInfo.HotspotY);

                // 背景画像からの相対座標
                Point imagePoint = new Point(
                    x: screenPoint.X - backgroundImageScreenPoint.X,
                    y: screenPoint.Y - backgroundImageScreenPoint.Y);

                // カーソルの画像を取得
                Bitmap cursorImage;
                if (backgroundImage != null)
                {
                    cursorImage = GetCursorImage(iconHandle, iconInfo, backgroundImage, imagePoint);
                }
                else
                {
                    cursorImage = GetCursorImage(iconHandle, iconInfo);
                }

                // カーソルの画像が取得できない場合は NULL を返す
                if (cursorImage == null)
                {
                    return(null);
                }

                // カーソル情報を生成して返す
                return(new CursorInfo(cursorImage, screenPoint, imagePoint));
            }
            finally
            {
                try
                {
                    // アイコン情報のマスクと画像情報を破棄する
                    if (!iconInfo.Equals(default(IconInfo.ICONINFO)))
                    {
                        DeleteObject(iconInfo.MaskBitmapHandle);
                        DeleteObject(iconInfo.ColorBitmapHandle);
                    }
                }
                finally
                {
                    // アイコンを破棄する
                    iconHandle?.Dispose();
                }
            }
        }