首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >PrintScreen后剪贴板上没有图像

PrintScreen后剪贴板上没有图像
EN

Stack Overflow用户
提问于 2013-09-20 11:04:29
回答 4查看 1.4K关注 0票数 1

我正在实现不同的屏幕抓取来比较它们。其中一个应该使用“printscreen”键和剪贴板。

我用keybd_event发送击键

代码语言:javascript
运行
复制
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern void keybd_event(byte vVK, byte bScan, int dwFlags,int dwExtraInfo);

public const int KEYEVENTF_EXTENDEDKEY=0x0001; //key down
public const int KEYEVENTF_KEYUP=0x0002; //key up

public const int VK_SNAPSHOT=0x2C; //VirtualKey code for print key

public static void PrintScreen(){
keybd_event(VK_SNAPSHOT,0,KEYEVENTF_EXTENDEDKEY,0);
keybd_event(VK_SNAPSHOT,0,KEYEVENTF_KEYUP,0);
}

在我的IEnumerable中,我调用这个方法,然后尝试获取图像:

代码语言:javascript
运行
复制
...
InputController.PrintScreen();
var img=Clipboard.GetImage();
...

返回的图像始终为null,而Clipboards.ContainsImage()始终为false。我已经试过在发送钥匙后等一会儿,但它也不起作用。我是遗漏了某种设置,还是有根本错误?

PS:在运行程序后,我能够将正确的图像粘贴到油漆或剪贴画中。

EN

回答 4

Stack Overflow用户

发布于 2013-09-20 12:21:23

这是一个控制台程序

这是最相关的细节,你应该把它写在你的问题上。剪贴板是一个系统对象,其底层api是基于COM的。这使得它对使用api的线程的单元状态很敏感。.NET剪贴板类有一点错误,如果线程的状态是错误的,它应该会抛出异常。在控制台模式应用程序中,它是错误的,它的主线程默认是MTA,您需要STA来使用api。

修复很简单,您可以在Main()方法上放置一个属性来请求STA:

代码语言:javascript
运行
复制
    [STAThread]
    static void Main(string[] args) {
        // etc...
    }

从技术上讲,STA线程也应该像Winforms或WPF应用程序那样,提供一个消息循环。但是,只要只从主线程发出方法调用,就可以逃脱它。

票数 4
EN

Stack Overflow用户

发布于 2013-09-20 11:17:59

您试过使用SendKeys类吗?

代码语言:javascript
运行
复制
public static Image TakeScreenSnapshot(bool activeWindowOnly)
{
    // PrtSc = Print Screen Key
    string keys = "{PrtSc}";
    if (activeWindowOnly)
        keys = "%" + keys; // % = Alt
    SendKeys.SendWait(keys);
    return Clipboard.GetImage();
}

代码样本的来源

票数 0
EN

Stack Overflow用户

发布于 2013-09-20 11:20:37

代码语言:javascript
运行
复制
public const int KEYEVENTF_EXTENDEDKEY=0x0001; //key down
public const int KEYEVENTF_KEYUP=0x0002; //key up

但你用的是:

代码语言:javascript
运行
复制
keybd_event(VK_SNAPSHOT,0,KEYEVENT_EXTENDEDKEY,0);
keybd_event(VK_SNAPSHOT,0,KEYEVENT_KEYUP,0);

使用KEYEVENTF_EXTENDEDKEY和KEYEVENTF_KEYUP它可以工作

整个过程运行在线程池上的一个工作线程中,我找不到将PrintScreen()发布到'Main-SynchronizationContext‘的方法,因为它是一个控制台程序。

你可以试试这个:

代码语言:javascript
运行
复制
class Program
{        
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern void keybd_event(byte vVK, byte bScan, int dwFlags, int dwExtraInfo);

    public const int KEYEVENTF_EXTENDEDKEY = 0x0001; //key down
    public const int KEYEVENTF_KEYUP = 0x0002; //key up

    public const int VK_SNAPSHOT = 0x2C; //VirtualKey code for print key

    public static void PrintScreen()
    {
        keybd_event(VK_SNAPSHOT, 0, KEYEVENTF_EXTENDEDKEY, 0);
        keybd_event(VK_SNAPSHOT, 0, KEYEVENTF_KEYUP, 0);
    }

    public static void test(Action<Image> action)
    {
        PrintScreen();
        var image = Clipboard.GetImage();
        action.BeginInvoke(image, ar => action.EndInvoke(ar), null);
    }

    [STAThread]
    static void Main(string[] args)
    {
        var processAction = new Action<Image>(img =>
        {
            if (img == null)
                Console.WriteLine("none");
            else
                Console.WriteLine(img.PixelFormat);
        });
        test(processAction);
        System.Console.ReadLine();
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18915209

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档