본문 바로가기

프로그래밍/Chromium(CEF4Delphi)

[Chromium] CEF4Delphi - 웹페이지 Javascript Alert / Dialog 창 DETECT 및 재처리

[Chromium] CEF4Delphi - 웹페이지 Javascript Alert / Dialog 창 DETECT 및 재처리

웹페이지에서 발생되는 자바스크립트에 의한 웹페이지 메시지(Alert 창) 또는 다이얼로그(Dialog)창의 발생 시점을 인지(Detect)하고, 재처리 할수 있는 기능에 대한 탐구

관련 이벤트 설정

//OnJsDialog 이벤트 핸들러를 작성하여 Alert/Dialog창이 뜨는 것을 Detect
Chromium1.OnJsdialog := UserJsOnDalog;

 

가공 되지 않은 기본 메시지창 / 재처리된 메시지창 사례

기본 메시지창 재처리된 메시지창
Dialog Type : Alert
DialogType : Confirm
Dialog Type : Prompt
 
Dialog Type : Alert  --> ShowMessage
Dialog Type : Confirm --> MessageDlg
Dialog Type : Prompt  --> InputBox

 

사용자 이벤트 핸들러 작성(UserOnJsDialog)

const
  CEFBROWSER_SHOWJSDIALOG               = WM_APP + $101;
...
protected
	FJSDialogInfoCS    : TCriticalSection;
    FOriginUrl         : ustring;
    FMessageText       : ustring;
    FDefaultPromptText : ustring;
    FPendingDlg        : boolean;
    FDialogType        : TCefJsDialogType;
    FCallback          : ICefJsDialogCallback;
    ...
    //사용자 메시지 처리 핸들러 정의
    procedure ShowJSDialogMsg(var aMessage: TMessage); message CEFBROWSER_SHOWJSDIALOG; //
    ...
    
procedure TForm1.UserJsOnDalog(Sender : TObject;
                                                  const browser           : ICefBrowser;
                                                  const originUrl         : ustring;
                                                        dialogType        : TCefJsDialogType;
                                                  const messageText       : ustring;
                                                  const defaultPromptText : ustring;
                                                  const callback          : ICefJsDialogCallback;
                                                  out   suppressMessage   : Boolean;
                                                  out   Result            : Boolean);
begin
  // DETECT된 다이얼로그 정보 및 메시지를 저장
  FJSDialogInfoCS.Acquire; //Critical Section 획득
  
  if FPendingDlg then
    begin
      Result          := False;
      suppressMessage := True;
    end
   else
    begin
      FOriginUrl         := originUrl;
      FMessageText       := messageText;
      FDefaultPromptText := defaultPromptText;
      FDialogType        := dialogType;
      FCallback          := callback;
      FPendingDlg        := True;
      Result             := True;
      suppressMessage    := False;

	  // 여기에 직접사용자 다이얼로그 처리하는 모듈을 넣어도 되지만
      // 전용 메시지 핸들러를 호출하여 사용자 다이얼로그 실행 처리 하도록 함
      PostMessage(Handle, CEFBROWSER_SHOWJSDIALOG, 0, 0); 
    end;

  FJSDialogInfoCS.Release;//Critical Section 해제
end;
 
procedure TForm1.ShowJSDialogMsg(var aMessage: TMessage);
var
  TempCaption : string;
begin
  // 여기에서 메시지를 처리 하고 DETECT된 메시지 내용을 초기화 해 준다.
  // 다이얼로그 타입에 따라서 showmessage, MessageDlg and InputBox 는 사용자가 동일한 기능을 하도록 임의로 정의해서 다시 재처리 해 줄 수 있다
  FJSDialogInfoCS.Acquire; //Critical Section 획득

  if FPendingDlg then
    begin
      TempCaption := 'JavaScript message from : ' + FOriginUrl;

      case FDialogType of
      	// Alert창
        JSDIALOGTYPE_ALERT   : showmessage(TempCaption + CRLF + CRLF + FMessageText);
        //사용자 확인을 요구하는 다이얼로그(예 : Yes / No)
        JSDIALOGTYPE_CONFIRM : FCallback.cont((MessageDlg(TempCaption + CRLF + CRLF + FMessageText, mtConfirmation, [mbYes, mbNo], 0, mbYes) = mrYes), '');
        //사용자에게 문자열 입력을 요구하는 다이얼로그
        JSDIALOGTYPE_PROMPT  : FCallback.cont(True, InputBox(TempCaption, FMessageText, FDefaultPromptText));
      end;
    end;

  //처리후 초기화 
  FOriginUrl         := '';
  FMessageText       := '';
  FDefaultPromptText := '';
  FPendingDlg        := False;
  FDialogType        := JSDIALOGTYPE_ALERT;
  FCallback          := nil;

  FJSDialogInfoCS.Release; //Critical Section 해제
end;