qq_40506952 2023-01-09 11:11 采纳率: 0%
浏览 129
已结题

计算机锁定后,进入登录桌面,如何获取登录桌面截屏?

我需要实现一个截屏功能,截屏我已经实现了,但是当我的计算机锁定后,进入登录桌面后,截屏就失败了,截的是黑屏,我的问题是怎么样才能在计算机锁定后进入登录桌面我的程序还能截屏?

截屏代码

 var hWnd = WinAPI.GetDesktopWindow();
            IntPtr hSrcDC = WinAPI.GetWindowDC(hWnd);

            WinAPI.SetThreadDesktop(hSrcDC);

            IntPtr hDC = g.GetHdc();
            int retval = WinAPI.BitBlt(hDC, 0, 0, GetPhysicalDisplaySize().Width, GetPhysicalDisplaySize().Height, hSrcDC, 0, 0, (int)(CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt));
            g.ReleaseHdc();


windows api

 [DllImport("user32.dll")]
        public static extern IntPtr GetDesktopWindow();
        [DllImport("user32.dll")]
        public static extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll")]
        public static extern IntPtr GetWindowDC(IntPtr ptr);

        [DllImport("user32.dll")]
        public static extern bool SwitchDesktop(IntPtr hDesktop);

        [DllImport("user32.dll")]
        public static extern IntPtr CreateDesktop(string lpszDesktop,
         IntPtr lpszDevice,
         IntPtr pDevmode,
         int dwFlags,
         uint dwDesiredAccess,
         IntPtr lpsa);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr OpenInputDesktop(uint dwFlags, bool fInherit, uint dwDesiredAccess);

        [DllImport("user32.dll", EntryPoint = "CloseDesktop", CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool CloseDesktop(IntPtr handle);

        [DllImport("user32.dll")]
        public static extern IntPtr OpenDesktop(string lpszDesktop,
 uint dwFlags,
 bool fInherit,
 uint dwDesiredAccess);

        [DllImport("user32.dll")]
        public static extern bool SetThreadDesktop(IntPtr hDesktop);

  • 写回答

7条回答 默认 最新

  • heart_6662 2023-01-09 11:40
    关注

    我写了写给你

    
    using System.Drawing;
    using System.Runtime.InteropServices;
    
    // 定义 Windows API 函数
    [DllImport("user32.dll")]
    public static extern IntPtr GetDesktopWindow();
    
    [DllImport("user32.dll")]
    public static extern IntPtr GetWindowDC(IntPtr hWnd);
    
    [DllImport("gdi32.dll")]
    public static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int wDest, int hDest, IntPtr hdcSrc, int xSrc, int ySrc, int rop);
    
    [DllImport("user32.dll")]
    public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
    
    // 定义截屏函数
    public static Bitmap CaptureScreen()
    {
        // 获取桌面窗口句柄
        IntPtr hWnd = GetDesktopWindow();
        // 获取桌面窗口的设备上下文
        IntPtr hDC = GetWindowDC(hWnd);
        // 获取桌面窗口的尺寸
        Rectangle rect = new Rectangle(0, 0, GetPhysicalDisplaySize().Width, GetPhysicalDisplaySize().Height);
        // 创建位图
        Bitmap bmp = new Bitmap(rect.Width, rect.Height);
        // 创建位图的图形上下文
        Graphics g = Graphics.FromImage(bmp);
        // 将桌面窗口的图像复制到位图的图形上下文
        IntPtr hDC2 = g.GetHdc();
        bool retval = BitBlt(hDC2, 0, 0, rect.Width, rect.Height, hDC, 0, 0, (int)CopyPixelOperation.SourceCopy);
        g.ReleaseHdc(hDC2);
        // 释放桌面窗口的设备上下文
        ReleaseDC(hWnd, hDC);
        // 返回位图
        return bmp;
    }
    
    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr OpenInputDesktop(uint dwFlags, bool fInherit, uint dwDesiredAccess);
    
    [DllImport("user32.dll")]
    public static extern bool SetThreadDesktop(IntPtr hDesktop);
    
    // 访问桌面和窗口
    public static void AccessDesktop()
    {
    // 打开输入桌面
    IntPtr hDesktop = OpenInputDesktop(0, false, DESKTOP_SWITCHDESKTOP);
    // 设置线程桌面
    bool retval = SetThreadDesktop(hDesktop);
    }
    
    
    #然后,在服务中使用 BitBlt() 函数将屏幕的内容复制到缓冲区。 例如,您可以使用以下代码将屏幕的内容复制到缓冲区:
    
    // 定义常量
    public const int SRCCOPY = 0x00CC0020;
    
    // 将屏幕的内容复制到缓冲区
    public static void CopyScreenToBuffer(IntPtr hDC, Bitmap bmp)
    {
    // 获取屏幕的设备上下文
    IntPtr hSrcDC = GetWindowDC(GetDesktopWindow());
    // 创建位图的图形上下文
    Graphics g = Graphics.FromImage(bmp);
    // 将屏幕的图像复制到位图的图形上下文
    IntPtr hDC2 = g.GetHdc();
    bool ret
    
    val = BitBlt(hDC2, 0, 0, bmp.Width, bmp.Height, hSrcDC, 0, 0, SRCCOPY);
    g.ReleaseHdc(hDC2);
    // 释放屏幕的设备上下文
    ReleaseDC(GetDesktopWindow(), hSrcDC);
    }
    
    #最后,在服务中使用 Save() 方法将缓冲区的内容保存到文件中。 例如,您可以使用以下代码将缓冲区的内容保存到文件中:
    
    // 保存缓冲区的内容到文件
    public static void SaveBufferToFile(Bitmap bmp, string fileName)
    {
    bmp.Save(fileName);
    }
    
    评论

报告相同问题?

问题事件

  • 系统已结题 1月17日
  • 创建了问题 1月9日

悬赏问题

  • ¥15 kotlin multiplaform 的共享模块支持蓝牙吗还是说安卓和ios的蓝牙都要自己配
  • ¥15 为什么我的查询总是显示无数据,该怎么修改呢(语言-java)
  • ¥15 IDDPM采样结果异常
  • ¥100 求一个,王者荣耀查询隐藏战绩的教材,爬虫代码
  • ¥60 Cocos creator缓动问题
  • ¥15 专业问题提问,7月5号2点之前
  • ¥25 使用cube ai 导入onnx模型时报错
  • ¥15 关于#微信小程序#的问题:用一个网页显示所有关联的微信小程序数据,包括每个小程序的用户访问量
  • ¥15 root的安卓12系统上,如何使apk获得root或者高级别的系统权限?
  • ¥20 关于#matlab#的问题:如果用MATLAB函数delayseq可以对分数延时,但是延时后波形较原波形有幅度上的改变