进行屏幕截图时候,有部分机器不会,部分机器会瞬间停顿一下。cpu占用率也很高。因为要进行频繁抓图,不知道如何解决这个问题。谢谢各位大侠。屏幕抓图的代码如下
procedure TFrmClient.GetTargetBmp;
var
    dc: HDC;
    iII: LongBool;
begin
    dc := GetDC(GetDesktopWindow);
    repeat
        iII := StretchBlt(TheNewScrBmp.Canvas.Handle, 0, 0, TheNewScrBmp.Width,
            TheNewScrBmp.Height, dc, 0, 0,
            Screen.Width, Screen.Height, SRCCOPY);
    until iII = True;
    ReleaseDC(GetDesktopWindow, dc);
end;

解决方案 »

  1.   

    为什么要 repeat ....until .直接用 stretchBlt不可以吗
      

  2.   

    在循环里加一个application.processmessages;试试行吗
      

  3.   

    在循环里加一个application.processmessages;试试行吗
      

  4.   

    有的机器配置不是很差,就是显卡可能差点,抓图时候CPU占用率有时候也不是很高,但是可以明显感觉鼠标停滞了一下,
      

  5.   

    to Tensionli() 
      循环里面加入application.processmessages; 还是没有任何变化
      

  6.   

    根据你的需要,设定触发器,不要在repeat ..until里面抓。
    “一直抓”这种动作不好。
    普通屏幕12足够,30就流畅了,你抓那么多干吗?
      

  7.   

    试了一下,应该是StretchBlt太慢了。直接用Bitblt抓到bitmap快多了。如果需要缩放,自己写一个快速的缩放函数,或者分块缩放,在分块的过程中插入application.processmessage之类的函数,响应就没有那么慢了。
      

  8.   

    to keyz(keyz)  根据你的建议做了如下修改:
    procedure TFrmClient.GetTargetBmp3;
    var
        dc: HDC;
        ABegin: Cardinal;
    begin
        dc := GetDC(0);
        ABegin := GetTickCount;
        BitBlt(TheNewScrBmp.Canvas.Handle, 0, 0,
            TheNewScrBmp.Width, TheNewScrBmp.Height, dc, 0, 0, SRCCOPY);
        ReleaseDC(0, dc);
        suiForm1.Caption := IntToStr(GetTickCount - ABegin);
    end;
    速度还是没有变化 在显卡比较好的机器上一个屏幕抓图时间60-70毫秒  ,在有显卡差的机器上则需要800多毫秒,差距也太大了。。
      

  9.   

    确实是这个速度的!
    想快,就需要VGA的Mirror驱动程序实现
    例如VNC这类的
      

  10.   

    像平常用的pcanywhere ,vnc等其他远程控制软件,他们的屏幕图像传输前的对屏幕抓图什么的是怎么进行的?有什么其他方法呢?谢谢
    ly_liuyang(Liu Yang LYSoft http://lysoft.7u7.net)
    对 “VGA的Mirror驱动程序实现” 能不能讲的更具体点呢?
      

  11.   

    现在就是如果把这个放入独立线程,即时把线程的级别调很低 还是会有停滞。主要原因还是在部分机器上(这些机器配置不是很好,显卡也比较差)停滞感特别强,抓图瞬间鼠标会一顿一顿的,除了BitBlt,StretchBlt之外有没其他方法进行屏幕抓图的?想尝试一下。
      

  12.   

    试试分块使用BitBlt呢?应该可以提高响应速度。
      

  13.   

    模拟键盘的Print Screen按键,然后从粘贴板中获得图像呢?
      

  14.   

    to SonicX(SonicX) (   
        ABegin := GetTickCount;
        Keybd_event(VK_SNAPSHOT, MapVirtualKey(VK_SNAPSHOT, 0), 0, 0);
        Keybd_event(VK_SNAPSHOT, MapVirtualKey(VK_SNAPSHOT, 0), keyeventf_keyup, 0);
        if Clipboard.HasFormat(CF_BITMAP) then
        begin
            Bitmap := TBitMap.Create;
            Bitmap.Width := Screen.Width;
            Bitmap.Height := Screen.Height;
            try
                Bitmap.Assign(Clipboard);
                Image3.Picture.Assign(Bitmap);
            finally
                Bitmap.Free;
            end;
        end;
        FrmClient.suiForm1.Caption := IntToStr(GetTickCount - ABegin);
    用模拟printScreen实现,速度比原先更慢。。 这个应该是意料之中的
      

  15.   

    那个循环没什么关系的。速度慢,主要应该是从屏幕上复制数据,以及缩放复制引起的,你先创建一个大图,用bitblt的话,应该可以非常快的得到复制的数据(这里说一下,在GDI下从屏幕上复制位图,相比位图到位图和位图到屏幕来说,是非常慢的),然后都过其它手段,绕过大面积图形缩放的过程,比如使用更好的缩放算法,或者分区域缩放,或者只对变化的部分进行缩放,这样可以极大的提高速度。具体就要看你的需求和能力了。
      

  16.   

    发现QQ远程控制 ,PCanywhere在这些机器上同样也有这些问题。
    结帖,谢谢各位大侠。