线程中模拟Print Screen 按键失效的原因

林夕合鸟 2016-03-15 01:55:23
在主进程中模拟Print Screen 按键没有问题,但是在进程中,出现问题 Clipboard.GetImage()为空。

主要代码如下:
public void PrintScreen()
{
keybd_event((byte)0x2c, 0, 0, 0);//down
keybd_event((byte)0x2c, 0, 2, 0);//up
}

private Bitmap GetScreenImage()
{
Bitmap NewBitmap = null;

try
{
if (Clipboard.ContainsImage())
{
NewBitmap = (Bitmap)(Clipboard.GetImage().Clone());
}

return NewBitmap;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return null;
}
}

private void button10_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(new WaitCallback((s) => {
while (true)
{
PrintScreen();
Bitmap map = GetScreenImage();
if (map != null)
{
string strFile = DateTime.Now.ToString("mmss") + ".bmp";
map.Save(@"D:\2\" + strFile, ImageFormat.Bmp);
}

Thread.Sleep(5000);
}
}));
}
...全文
251 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
林夕合鸟 2016-03-16
  • 打赏
  • 举报
回复
非常感谢楼上,应该是这个问题。 饭后测试下。谢谢!
bu_ge 2016-03-16
  • 打赏
  • 举报
回复
确定是不能截屏吗? 还是线程中获取剪切板失败? 你可以分开测试,单独使用获取剪切板的代码,同时自己手动截个屏看看。 试试这样写

ThreadStart threadStart = new ThreadStart(new Action(() =>
            {
                while (true)
                {
                    PrintScreen();
                    Bitmap map = GetScreenImage();
                    if (map != null)
                    {
                        string strFile = DateTime.Now.ToString("mmss") + ".bmp";
                        map.Save(@"D:\2\" + strFile, ImageFormat.Bmp);
                    }

                    Thread.Sleep(5000);
                }
            }));

            Thread thread = new Thread(threadStart);

            thread.SetApartmentState(ApartmentState.STA);
林夕合鸟 2016-03-16
  • 打赏
  • 举报
回复
目前的疑问: 1.什么原因导致【线程】中不能上述方法截屏? 目前的解决方法: 1.单独开进程执行这个任务,执行完毕后关闭进程。(总有点恶心) 2.分析DirectX,调用其API,进行截屏。(不熟悉DirectX) 想问问大家,还有其他方法没有?
林夕合鸟 2016-03-16
  • 打赏
  • 举报
回复
不好意思,我说话也冲了,谢谢你的建议。 不过。 在【线程】中,SendKeys.SendWait("{PRTSC}"); 执行后, Clipboard.GetImage()取得的数据为null Graphics.CopyFromScreen()不用是因为准备拷贝的屏幕是DirectX全屏游戏截图。 谢楼上了。
crystal_lz 2016-03-15
  • 打赏
  • 举报
回复
Graphics.CopyFromScreen()直接就能获取屏幕
crystal_lz 2016-03-15
  • 打赏
  • 举报
回复
对不起啊 本菜并不知道 SendKeys 的原理 也不知道 keybd_event 只是把消息投递到消息队列里面 更不知道 Sendkeys的SendWait() 方法不仅投递消息 还会等待被处理 而且我也不知道 当你用keybd_event函数投递完 prtsc 的时候 你的程序立马获取剪切板 系统就一定会在你获取剪切板之前把prtsc键处理完成

//keybd_event((byte)0x2c, 0, 0, 0);//down  
//keybd_event((byte)0x2c, 0, 2, 0);//up
//System.Threading.Thread.Sleep(10);
SendKeys.SendWait("{PRTSC}");
this.BackgroundImage = Clipboard.GetImage();
林夕合鸟 2016-03-15
  • 打赏
  • 举报
回复
楼上的好冲啊! 1.在进程中模拟意思是在主程序中运行上面的代码,执行的没有问题。 2.我的模拟有没有问题的判断方式是:我的按键是Print Screen按键,执行成功了,在剪切板上自然有数据。 3.你知道SendKeys的原理吗? 4.我调用的API是很常见的API,代码也完全不复杂。 5.谢谢你的顶贴!
crystal_lz 2016-03-15
  • 打赏
  • 举报
回复
在进程中模拟?,。。什么鬼? 还有你怎么就知道 你的模拟是没有问题的? 按照你的逻辑是不是运行代码一定要报错才证明程序有问题? 仅仅是模拟一个 ptrscreen 居然调用这么复杂的api 直接一个 SendKeys.SendWait("{PRTSC}"); 就能搞定的事情

110,535

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧