使用SharpDX在屏幕截图中包含鼠标光标 [英] Include mouse cursor in screen capture using SharpDX

查看:573
本文介绍了使用SharpDX在屏幕截图中包含鼠标光标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 SharpDX 的ScreenCapture 示例 库,以便可以全屏显示游戏的屏幕截图(因为此处常用的GDI +捕获技术不起作用,即使Windos默认的打印键也无法对游戏进行正确的屏幕截图。)

I'm using the ScreenCapture sample of SharpDX library to be able take a screenshot of a game that is in fullscreen (because common GDI+ capture techniques here doesn't work, even the Windos default "Print" key cannot take a proper screenshot of the game).

我在应用程序中使用的代码实际上与上面链接的官方示例相同(转换为VB.NET),因此我认为不必发布相同的代码

The code that I'm using in my application is practically the same of the official sample linked above (translated to VB.NET), so I think is not necessary to publish the same code block here.

我的问题是我想在捕获的图像中包含鼠标光标。

The problem I have is that I would like to include the mouse cursor in the captured image.

也许 SharpDX 有某种方法或属性/参数以友好的方式包含鼠标光标?如果没有,那么如何才能做到这一点呢? nto认为游戏的鼠标光标是个性化的(不是默认的白色Windows箭头)吗?。

Maybe SharpDX has some method or property/parameter to include the mouse cursor in a friendly way?, if not then how could acchieve this taking into account that the mouse cursor of the game is personalized (not the default white Windows arrow)?.

推荐答案

您可以利用WinAPI的 GetCursorInfo() 函数可获取当前光标的句柄。然后调用 Icon.FromHandle() 并将光标句柄作为参数传递,您将获得作为可绘制图标的光标。

You could utilize the WinAPI's GetCursorInfo() function to get a handle to the current cursor. By then calling Icon.FromHandle() and passing the cursor handle as a parameter you'll get the cursor as a drawable icon.

由于不同的游标可能具有不同的热点,因此您也必须考虑到这一点。为此,您可以使用WinAPI的 GetIconInfo() 函数获取热点的X和Y坐标,然后只需要减去光标的位置

As different cursors may have different hotspots you'll have to take that into account too. For this you can use the WinAPI's GetIconInfo() function to get the X and Y-coordinates for the hotspot, then you'll just have to substract the cursor's position with the hotspot's position.

绘制光标的方法:

Public Shared Sub DrawCursor(ByVal Graphics As Graphics)
    Dim CursorInfo As New NativeMethods.CURSORINFO With {.cbSize = Marshal.SizeOf(GetType(NativeMethods.CURSORINFO))}

    'Get the cursor info.
    If NativeMethods.GetCursorInfo(CursorInfo) = True Then
        Using CursorIcon As System.Drawing.Icon = System.Drawing.Icon.FromHandle(CursorInfo.hCursor) 'Get the cursor icon.
            Dim IconInfo As New NativeMethods.ICONINFO

            Try
                Dim ModifierPoint As New Point(0, 0) 'Declare the modifier point (the cursor's hotspot).

                'Get the info for the cursor icon.
                If NativeMethods.GetIconInfo(CursorInfo.hCursor, IconInfo) = True Then
                    If IconInfo.fIcon = False Then 'If the cursor is an icon the hotspot will always be (0, 0).
                        ModifierPoint = New Point(IconInfo.xHotspot, IconInfo.yHotspot) 'Set the hotspot modifier.
                    End If

                End If


                'Normalize the coordinates according to the hotspot.
                Dim FinalPoint As New Point(CursorInfo.ptScreenPos.x - ModifierPoint.X, CursorInfo.ptScreenPos.y - ModifierPoint.Y)

                'Draw the cursor.
                Graphics.DrawIcon(CursorIcon, New Rectangle(FinalPoint, CursorIcon.Size))

            Finally
                'Some cleaning up...
                If IconInfo.hbmMask <> IntPtr.Zero Then
                    NativeMethods.DeleteObject(IconInfo.hbmMask)
                    IconInfo.hbmMask = IntPtr.Zero
                End If

                If IconInfo.hbmColor <> IntPtr.Zero Then
                    NativeMethods.DeleteObject(IconInfo.hbmColor)
                    IconInfo.hbmColor = IntPtr.Zero
                End If

            End Try
        End Using
    End If
End Sub

NativeMethods.vb:

Imports System.Runtime.InteropServices

Public NotInheritable Class NativeMethods
    <StructLayout(LayoutKind.Sequential)> _
    Public Structure POINT
        Public x As Integer
        Public y As Integer
    End Structure

    <StructLayout(LayoutKind.Sequential)> _
    Public Structure CURSORINFO
        Public cbSize As Integer
        Public flags As Integer
        Public hCursor As IntPtr
        Public ptScreenPos As POINT
    End Structure

    <DllImport("user32.dll")> _
    Public Shared Function GetCursorInfo(ByRef pci As CURSORINFO) As Boolean
    End Function

    <StructLayout(LayoutKind.Sequential)> _
    Public Structure ICONINFO
        Public fIcon As Boolean
        Public xHotspot As Integer
        Public yHotspot As Integer
        Public hbmMask As IntPtr
        Public hbmColor As IntPtr
    End Structure

    <DllImport("user32.dll")> _
    Public Shared Function GetIconInfo(ByVal hIcon As IntPtr, ByRef piconinfo As ICONINFO) As Boolean
    End Function

    <DllImport("gdi32.dll")> _
    Public Shared Function DeleteObject(ByVal hObject As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function
End Class

如果您截取了结果截图, d像这样绘制光标:

If you take the resulting screenshot you'd draw the cursor onto it like this:

Using g As Graphics = Graphics.FromImage(yourImage)
    DrawCursor(g)
End Using

这篇关于使用SharpDX在屏幕截图中包含鼠标光标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆