개요
Chromium에는 TWebBrowser 컴포넌트처럼 웹브라우저를 직접 핸들링하는 기능을 제공하지 않습니다. 따라서 VCL Application에서 Embedding된 Chromium 웹브라우저에 특정 작업을 시키려면(예: 웹페이지 HTML을 얻는 등) Chromium의 메시징 처리 매커니즘을 이해할 필요가 있습니다.
Chromium 기본 메시지 처리 매커니즘
Chromium 어플리케이션 초기화 및 메시지 처리 핸들러 지정
Chromium을 Embedding하는 VCL 어플리케이션에서는 최초 1회 다음과 같은 초기화 작업을 해야 합니다.
GlobalCEFApp := TCefApplication.Create;
그리고 GlobalCEFApp.OnProcessMessageReceived 메시지 핸들러에서 Chromium에 전달되는 모든 이벤트를 처리해야 합니다. 이 이벤트 핸들러는 TChromium 컴포넌트별로 수신된 메시지를 각각 처리할 수 있기 때문에, 메시지를 수신받은 브라우저 등의 메타 정보를 인식할 수 있습니다. 이 이벤트 핸들러의 함수 원형은 다음과 같습니다.
procedure GlobalCEFApp_OnProcessMessageReceived(const browser : ICefBrowser;
const frame : ICefFrame;
sourceProcess : TCefProcessId;
const message : ICefProcessMessage;
var aHandled : boolean);
메시지 처리 핸들러를 다음과 같이 CEFApplication의 이벤트 핸들러로 등록해야 합니다.
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.RemoteDebuggingPort := 9000;
GlobalCEFApp.OnProcessMessageReceived := GlobalCEFApp_OnProcessMessageReceived;
GlobalCEFApp.DisableFeatures := 'NetworkService,OutOfBlinkCors';
GlobalCEFApp.LogFile := 'debug.log';
GlobalCEFApp.LogSeverity := LOGSEVERITY_ERROR;
Chromium에 처리할 메시지 생성 및 전송
Chromium에서 사용되는 메시지는 TCefProcessMessageRef 클래스를 사용하여 생성 후 전송합니다. 이때 TChromium에 전달할 대상은 PID_RENDERER 이어야 합니다.
TempMsg := TCefProcessMessageRef.New('HTML얻기');
Chromium1.SendProcessMessage(PID_RENDERER, TempMsg);
Chromium Application 메시지 핸들러에서 VISITDom 객체 생성 및 실행
앞서 등록한 Chromium Application 메시지 핸들러에서 message.name에 따른 각 용도별 VisitDom 객체를 생성하고 VisitDom을 호출함으로써 원하는 작업을 웹브라우저에 시킬 수 있습니다. 이때 VisitDom 객체 생성 시 동작할 Callback 함수를 함께 전달해야 하는데, 이는 VisitDom 객체 내부적으로 visit 함수가 실행될 때 지정된 콜백 함수가 실행되기 때문입니다.
VisitDom 객체는 유닛 uCEFDomVisitor.pas에 선언된 TCefDomVisitorOwn 클래스를 상속받아 작성된 클래스를 사용할 수 있으며, 이미 기정의된 두 개의 TCefDomVisitorOwn 객체를 사용할 수도 있습니다.
TCefFastDomVisitor = class(TCefDomVisitorOwn)
protected
FProc : TCefDomVisitorProc;
procedure visit(const document: ICefDomDocument); override;
public
constructor Create(const proc: TCefDomVisitorProc); reintroduce; virtual;
end;
TCefFastDomVisitor2 = class(TCefDomVisitorOwn)
protected
FProc : TCefDomVisitorProc2;
FBrowser : ICefBrowser;
FFrame : ICefFrame;
procedure visit(const document: ICefDomDocument); override;
public
constructor Create(const browser: ICefBrowser; const frame: ICefFrame; const proc: TCefDomVisitorProc2); reintroduce; virtual;
destructor Destroy; override;
end;
콜백 함수 타입인 TCefDomVisitorProc 또는 TCefDomVisitorProc2는 uCEFInterfaces.pas 유닛에 다음과 같이 정의되어 있습니다.
unit uCEFInterfaces;
...
TCefDomVisitorProc = {$IFDEF DELPHI12_UP}reference to{$ENDIF} procedure(const document: ICefDomDocument);
TCefDomVisitorProc2 = {$IFDEF DELPHI12_UP}reference to{$ENDIF} procedure(const browser : ICefBrowser; const frame: ICefFrame; const document: ICefDomDocument);
어플리케이션 이벤트 핸들러에서 메시지명에 따라 다음과 같이 VisitDOM을 호출할 수 있습니다.
procedure DOMVisitor_GETHTML(const browser: ICefBrowser; const frame: ICefFrame; const document: ICefDomDocument);
var
msg: ICefProcessMessage;
begin
msg := TCefProcessMessageRef.New(DOMVISITOR_MSGNAME_FULL);
msg.ArgumentList.SetString(0, document.Body.AsMarkup);
frame.SendProcessMessage(PID_BROWSER, msg);
end;
procedure DOMVisitor_GETTEXT(const browser: ICefBrowser; const frame: ICefFrame; const document: ICefDomDocument);
var
msg: ICefProcessMessage;
begin
msg := TCefProcessMessageRef.New(DOMVISITOR_MSGNAME_FULL);
msg.ArgumentList.SetString(0, document.Body.AsText);
frame.SendProcessMessage(PID_BROWSER, msg);
end;
procedure GlobalCEFApp_OnProcessMessageReceived(const browser : ICefBrowser;
const frame : ICefFrame;
sourceProcess : TCefProcessId;
const message : ICefProcessMessage;
var aHandled : boolean);
begin
aHandled := False;
if (browser <> nil) then
begin
if (message.name = 'HTML얻기') then
begin
TempFrame := browser.MainFrame;
if (TempFrame <> nil) then
begin
TempVisitor := TCefFastDomVisitor2.Create(browser, TempFrame, DOMVisitor_GETHTML);
TempFrame.VisitDom(TempVisitor);
end;
aHandled := True;
end
else if (message.name = 'TEXT얻기') then
begin
TempFrame := browser.MainFrame;
if (TempFrame <> nil) then
begin
TempVisitor := TCefFastDomVisitor2.Create(browser, TempFrame, DOMVisitor_GETTEXT);
TempFrame.VisitDom(TempVisitor);
end;
aHandled := True;
end
else
// 기타 메시지 처리
end;
end;
VisitDOM 처리 결과 받기
VisitDOM 콜백 함수에 의해 실행된 결과 메시지를 보냈다면 TChromium.OnProcessMessageReceived 핸들러에서 메시지를 받을 수 있습니다.
procedure TDOMVisitorFrm.Chromium1ProcessMessageReceived(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame; sourceProcess: TCefProcessId;
const message: ICefProcessMessage; out Result: Boolean);
begin
Result := False;
if (message = nil) or (message.ArgumentList = nil) then exit;
if (message.Name = DOMVISITOR_MSGNAME_GETHTML) then
begin
ShowStatusText('DOM Visitor result text : ' + message.ArgumentList.GetString(0));
Result := True;
end
else if (message.Name = DOMVISITOR_MSGNAME_GETTEXT) then
begin
ShowStatusText('DOM Visitor result text : ' + message.ArgumentList.GetString(0));
Result := True;
end
else
// 기타 메시지 처리
end;
결론
Chromium의 메시지 처리 매커니즘을 이해하고 이를 통해 VCL 어플리케이션 내에서 다양한 작업을 처리할 수 있습니다. 이를 위해 메시지 핸들러와 VisitDom 객체를 적절히 활용해야 합니다. 이러한 과정을 통해 웹브라우저와의 상호작용을 더욱 효과적으로 수행할 수 있습니다.
'IT > 델파이' 카테고리의 다른 글
Delphi 프로그램을 자동으로 종료하는 방법 (0) | 2024.07.30 |
---|---|
Delphi "coreide70.bpl" Access violation 오류 대처법 (0) | 2024.07.30 |
TChromium 컴포넌트를 활용한 브라우저 기능 확장 (0) | 2024.06.25 |
델파이 PNG파일 Image32로드 하기 (0) | 2024.02.05 |
[Delphi] 워터마크 표시와 이미지 줄이기 (0) | 2023.11.10 |