2013-05-03 4 views
4

이 오류를 제공하는 프로그램. 나쁜 영어 죄송Delphi EOutOfResources 화면 캡처

임 디버깅하는 동안

http://www1.datafilehost.com/d/1cae7b24 EOufOfResources : 때때로 잠시 후 때때로 즉시,

http://www1.datafilehost.com/d/39f524c0 스레드는 마침내

소스를 차단하려고 일부를 일시 중단합니다. 나는 다음과 같은 문제가있다 : 나는 5 fps 스크린 샷을하고 그것들에 커서 아이콘을 그려 넣고, PNG로 BMP를 다시 코딩하고 Indy를 블로킹하여 네트워크를 통해 보낸다. 비례 적으로 압축 된 스크린 샷을 보낸 후 기본 양식의 TImage (desktopimage)에 배치합니다. 내가이 모든 것을 타이머에서하고 있다면 - 동기화()에서도이 코드를 모두 수행하면 모든 것이 잘 작동하지만 인터페이스가 멈추고 제거하고 싶습니다. 그래서 스레드에서 PNG 압축, 지금은 몇 가지 동기화() 오류 (내가 오류 EOutOfResources 얻을) 휴식을 시도했지만 못했습니다. 도와주세요. 여기에 내 코드 :

내 델파이 2010 년
TCaptureThread = class(TThread) 
    private 
    bmp: TBitmap; 
    DC: HDC; 
    h:hwnd; 
    thumbRect : TRect; 
    maxWidth, maxHeight:integer; 
    png:TPNGImage; 
    Stream:TMemoryStream; 
    RecBlock:TCommBlock; 
    r: TRect; 
    CI: TCursorInfo; 
    Icon: TIcon; 
    II: TIconInfo; 
    commblock:TCommblock; 
    procedure showthumb; 
    procedure send; 
    procedure stretch; 
    procedure getscreen; 
    procedure fixsize; 
    protected 
    procedure Execute; override; 
    constructor Create(CreateSuspended: Boolean); 
    destructor destroy; override; 
end; 

constructor TCaptureThread.Create(CreateSuspended: Boolean); 
begin 
    bmp:=TBitmap.Create; 
    Stream:=TMemoryStream.Create; 
    png:=TPNGImage.Create; 
    Icon := TIcon.Create; 
    inherited Create(CreateSuspended); 
end; 


destructor TCaptureThread.destroy; 
begin 
    png.Free; 
    bmp.Free; 
    Icon.Free; 
    stream.Free; 
    inherited; 
end; 

procedure TCaptureThread.Execute; 
begin 
    inherited; 
    while not Terminated do 
    begin 
    Synchronize(fixsize); 
    Synchronize(getscreen); 
    r := bmp.Canvas.ClipRect; 
    try 
    CI.cbSize := SizeOf(CI); 
    if GetCursorInfo(CI) then 
    if CI.Flags = CURSOR_SHOWING then 
    begin 
    Icon.Handle := CopyIcon(CI.hCursor); 
    if GetIconInfo(Icon.Handle, II) then 
    begin 
     bmp.Canvas.Draw(
      ci.ptScreenPos.x - Integer(II.xHotspot) - r.Left - Form4.Left, 
      ci.ptScreenPos.y - Integer(II.yHotspot) - r.Top - Form4.Top, 
      Icon 
      ); 
    end; 
    end; 
    finally 

    end; 
    try 
    png.Assign(bmp); 
    png.CompressionLevel := 9; 
    png.SaveToStream(stream); 
    stream.Position :=0; 
    Recblock.Command :='STREAM'; 
    Recblock.Msg :=''; 
    Recblock.NameFrom := MyName; 
    Synchronize(send); 
    finally 

    end; 
    try 
    thumbRect.Left := 0; 
    thumbRect.Top := 0; 
    if bmp.Width > bmp.Height then 
    begin 
    thumbRect.Right := maxWidth; 
    thumbRect.Bottom := (maxWidth * bmp.Height) div bmp.Width; 
    end 
    else 
    begin 
    thumbRect.Bottom := maxHeight; 
    thumbRect.Right := (maxHeight * bmp.Width) div bmp.Height; 
    end; 
    Synchronize(stretch); 
    bmp.Width := thumbRect.Right; 
    bmp.Height := thumbRect.Bottom; 
    Synchronize(showthumb); 
    finally 
    end; 

    sleep(200); 
    end; 

    end; 

    procedure TCaptureThread.getscreen; 
    begin 
    DC:=GetDC(0); 
    bitblt(bmp.Canvas.Handle, 0, 0, Form4.Width+Form4.Left, Form4.Height+Form4.Top,   
    DC, Form4.Left, Form4.Top, SRCCOPY); 
    ReleaseDC(0, DC); 
    end; 

    procedure TCaptureThread.fixsize; 
    begin 
    maxWidth := Form1.DesktopImage.Width; 
    maxHeight := Form1.DesktopImage.Height; 
    bmp.Height:=Form4.Height; 
    bmp.Width:=Form4.Width; 
    end; 

    procedure TCaptureThread.send; 
    begin 
    Form1.Streamclient.IOHandler.Write(RawToBytes(Recblock,sizeof(recblock)),sizeof(recblock)); 
    Form1.Streamclient.IOHandler.Write(stream,stream.Size,true); 
    end; 

    procedure TCaptureThread.showthumb; 
    begin 
    Form1.DesktopImage.Picture.Assign(bmp); 
    end; 

    procedure TCaptureThread.stretch; 
    begin 
    SetStretchBltMode(bmp.Canvas.Handle, HALFTONE); 
    StretchBlt(bmp.Canvas.Handle,0,0,thumbRect.Right,thumbRect.Bottom,bmp.Canvas.Handle,0,0,bmp.Width,bmp.Height,SRCCOPY); 
    end; 
+0

나는이 질문을 이해할 수 없다. –

+0

EOutOfResources 오류가 발생하고 그 문제를 해결할 수 없습니다. – Sibay

+0

해당 의견으로 내 이해가 개선되지 않았습니다. 나는 당신이 성취하려는 것을 말할 수 없다. 오류를 생성 한 프로그램을 게시 한 경우 실행할 수 있습니다. 나는 당신이 그 일을하기 위해 당신의 질문을 편집 할 것을 제안합니다. –

답변

0

문제가 해결되었습니다. 코드 Synchronize()에 PNG 압축을 제외하고 압축을 사용하기 전에 Canvas.Lock의 압축 Canvas.UnLock 이후의 방법을 사용했습니다. 이렇게하면 Canvas에 대한 다른 스레드의 영향을 피할 수 있습니다. bummi의 조언에 감사드립니다 (TCanvas는 쓰레드 세이브가 아닙니다). 올바르게 Execute 방법은 여기에있다 :

procedure TCaptureThread.Execute; 
begin 
inherited; 
while not Terminated do 
begin 
Synchronize(size); 
Synchronize(getscreen); 
Synchronize(drawcursor); 

try 
png.Canvas.Lock; 
bmp.Canvas.Lock; 
png.Assign(bmp); 
png.CompressionLevel := 9; 
png.Canvas.Unlock; 
bmp.Canvas.Unlock; 
finally 

end; 
try 
Synchronize(stretch); 
Synchronize(showthumb); 
finally 

end; 

sleep(200); 
end; 

end; 
2

먼저 내가 unit.pas에서 동일한 또한

unit CaptureUnit; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, 
    Classes, Graphics, Controls, Forms, Dialogs; 

unit CaptureUnit; 

interface 

uses 
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, 
    System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs; 

를 교체해야합니다

당신은 할당해서는 안됩니다 비트 맵을 Picture.Assign(bmp);

procedure TCaptureThread.showthumb; 
begin 
    CaptureForm.DesktopImage.Picture.Assign(bmp); 
end; 

잠시 후 EOutOfResources 오류가 발생합니다. 나는 그것을 변경 후

당신은 Picture.Bitmap.Assign(bmp);

procedure TCaptureThread.showthumb; 
begin 
    CaptureForm.DesktopImage.Picture.Bitmap.Assign(bmp); 
end; 

에 비트 맵을 할당해야합니다, 나는 오류가없이 20 분 동안 프로그램 실행을 얻었다. 그런 다음 수동으로 완료했습니다.

업데이트 :

스크린 샷 : VCL 비디오 재생 및 스트레칭과 캡처 영역을 이동하는 동안 프로그램을 실행합니다.

enter image description here

은 당신을 도움이되기를 바랍니다.

+0

노력에 감사드립니다. 터치하지 않고 메인 양식을 옮겨서 영역 형식을 캡처하지 않으면 UR 변경 사항과 함께 작동하지만 U가 시각적 구성 요소로 작업을 수행하면이 오류가 다시 발생합니다 (UR 변경과 함께). Canvas.Lock/UnLock 메서드를 사용해야 할 수도 있지만 제대로 수행하는 방법을 모릅니다. – Sibay

+0

@ 시비 :'당신의 테스트 프로그램 '으로 테스트 했습니까? 내가 지금이 글을 쓰면서 이미 40 분을 달린다. 캡처 영역이 확대되고 축소되어 20 개의 다른 응용 프로그램이 시작 되었습니까? 창문을 가로 질러 그린다. VLC Media PLayer에서 비디오가 캡처 영역 위로 실행되기 시작했습니다. 내가 뭘해야할 지, 달리는거야! –

+0

어쩌면 그것은 OS 버전에 의해 depens. 나는 Win7 x64를 사용하며 작동하지 않습니다. 코드를 올바르게 게시했습니다. 참여해 주셔서 감사합니다. – Sibay