Q&A

  • bitblt에서 에러 발생...
화면 캡쳐할 때



bitblt를 사용하면 처음에는 에러가 발생하지 않는데...



한 procedure에서 두번이상 사용하면



Project Server2.exe raised exception class EAccessViolation with

message 'Acces violation at address 00000000. Read of address

00000000'. Process stopped. Use Step or Run to continue.



라는 에러가 발생합니다.



이것을 해결하는 방법이 있을까요..



참고로 화면 캡쳐를 while문을 사용하여 계속하고 있습니다.

그래서 그 캡쳐한 것을 JPEG file로 저장하는데 잘 되지 않습니다.



많은 고수님들의 도움을 요청합니다...

4  COMMENTS
  • Profile
    여영식 2000.01.12 23:27
    소스가 있어야 확인이 가능하겠군요.

    소스를 올려주세요.

    ---

    곽효승 wrote:

    > 화면 캡쳐할 때

    >

    > bitblt를 사용하면 처음에는 에러가 발생하지 않는데...

    >

    > 한 procedure에서 두번이상 사용하면

    >

    > Project Server2.exe raised exception class EAccessViolation with

    > message 'Acces violation at address 00000000. Read of address

    > 00000000'. Process stopped. Use Step or Run to continue.

    >

    > 라는 에러가 발생합니다.

    >

    > 이것을 해결하는 방법이 있을까요..

    >

    > 참고로 화면 캡쳐를 while문을 사용하여 계속하고 있습니다.

    > 그래서 그 캡쳐한 것을 JPEG file로 저장하는데 잘 되지 않습니다.

    >

    > 많은 고수님들의 도움을 요청합니다...

  • Profile
    곽효승 2000.01.13 01:00
    procedure TClientThread.Execute;

    var

    JpegImage: TJpegImage;

    Bmp: TBitmap;

    DC: HDC;

    JpgStream: TMemoryStream;

    Length: integer;

    FileLocation: String;

    begin

    while Sendable do

    begin

    try

    FileLocation := ExtractFilePath(Application.ExeName);

    DeleteFile(FileLocation + Form1.ServerAddr + '.JPG');



    Bmp := TBitmap.Create;

    Bmp.Width := Screen.Width;

    Bmp.Height := Screen.Height;

    DC := GetDC(0);



    BitBlt(Bmp.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height,

    DC, 0, 0, SRCCOPY);



    JpegImage := TJpegImage.Create;

    JpegImage.CompressionQuality := 45;

    JpegImage.Assign(Bmp);

    JpgStream := TMemoryStream.Create;



    JpegImage.SaveToStream(JpgStream);

    JpegImage.SaveToFile(FileLocation + Form1.ServerAddr + '.JPG');



    Length := JpgStream.Size;



    JpgStream.Position := 0;

    finally

    Bmp.Free;

    ReleaseDC(0, DC);



    JpegImage.Free;

    JpgStream.Free;

    end;

    end;

    end;

  • Profile
    여영식 2000.01.13 02:26
    제가 시험한 결과 아무 문제없이 실행이 됩니다.

    다만 while 문에서 Application.ProcessMessages; 라는 문장을 넣어주어야 합니다.

    에러가 발생한다면 스레드 처리에서 동기화 문제가 발생하는것 같습니다.

    스레드 처리부분이 포함되어 있는 full 소스를 올려 주시면 스레드 처리부분을 확인해

    드리도록 하겠습니다.



    ---



    곽효승 wrote:

    > procedure TClientThread.Execute;

    > var

    > JpegImage: TJpegImage;

    > Bmp: TBitmap;

    > DC: HDC;

    > JpgStream: TMemoryStream;

    > Length: integer;

    > FileLocation: String;

    > begin

    > while Sendable do

    > begin

    > try

    > FileLocation := ExtractFilePath(Application.ExeName);

    > DeleteFile(FileLocation + Form1.ServerAddr + '.JPG');

    >

    > Bmp := TBitmap.Create;

    > Bmp.Width := Screen.Width;

    > Bmp.Height := Screen.Height;

    > DC := GetDC(0);

    >

    > BitBlt(Bmp.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height,

    > DC, 0, 0, SRCCOPY);

    >

    > JpegImage := TJpegImage.Create;

    > JpegImage.CompressionQuality := 45;

    > JpegImage.Assign(Bmp);

    > JpgStream := TMemoryStream.Create;

    >

    > JpegImage.SaveToStream(JpgStream);

    > JpegImage.SaveToFile(FileLocation + Form1.ServerAddr + '.JPG');

    >

    > Length := JpgStream.Size;

    >

    > JpgStream.Position := 0;

    > finally

    > Bmp.Free;

    > ReleaseDC(0, DC);

    >

    > JpegImage.Free;

    > JpgStream.Free;

    > end;

    > end;

    > end;

  • Profile
    곽효승 2000.01.13 06:04
    한번 확인해 보시고 답변 부탁 드립니다.



    unit Unit1;



    interface



    uses

    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, jpeg,

    StdCtrls;



    const

    wm_RefreshClients = wm_User;



    type

    TForm1 = class(TForm)

    Button1: TButton;

    procedure FormCreate(Sender: TObject);

    procedure Button1Click(Sender: TObject);

    private

    public

    procedure RefreshClients (var Msg: TMessage);

    message wm_RefreshClients;

    end;



    TClientthread = class(TThread)

    protected

    procedure Execute; override;

    end;



    var

    Form1: TForm1;

    Sendable : boolean;

    ClientThread : TClientThread;





    implementation



    {$R *.DFM}



    procedure TForm1.RefreshClients;

    begin

    end;



    {TClientThread=================================================================}



    procedure TClientThread.Execute;

    var

    JpegImage: TJpegImage;

    Bmp: TBitmap;

    DC: HDC;

    JpgStream: TMemoryStream;

    Length: integer;

    FileLocation: String;

    begin

    while Sendable do

    begin

    try

    Bmp := TBitmap.Create;

    Bmp.Width := Screen.Width;

    Bmp.Height := Screen.Height;

    DC := GetDC(0);



    BitBlt(Bmp.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height,

    DC, 0, 0, SRCCOPY);



    Application.ProcessMessages;



    JpegImage := TJpegImage.Create;

    JpegImage.CompressionQuality := 45;

    JpegImage.Assign(Bmp);

    JpgStream := TMemoryStream.Create;



    JpegImage.SaveToStream(JpgStream);

    JpegImage.SaveToFile('Test.JPG');



    Length := JpgStream.Size;



    JpgStream.Position := 0;

    finally

    Bmp.Free;

    ReleaseDC(0, DC);



    JpegImage.Free;

    JpgStream.Free;

    end;

    end;



    Terminate;

    end;



    procedure TForm1.FormCreate(Sender: TObject);

    begin

    Sendable := False;

    end;



    procedure TForm1.Button1Click(Sender: TObject);

    begin

    if Sendable then

    begin

    Sendable := False;

    Button1.Caption := 'Capture';

    end else

    begin

    Sendable := True;

    Button1.Caption := 'Not Capture';

    ClientThread := TClientThread.Create(True);

    ClientThread.FreeOnTerminate := True;

    ClientThread.Resume;

    end;

    end;



    end.



    꼭~ 답변을 주시기를 간절히 바라겠습니다...