#author("2020-10-20T00:24:56+00:00","default:ahyahya2","ahyahya2")
&size(20){&color(red){''古い情報です、現在メンテナンスされていません''};};

*Delphiでウェブタブブラウザを作る [#p1c2ccdb]
Delphiでウェブタブブラウザを作る際にハマった事や参照した場所等をメモしていきます。
#contents
#hr

*ソフト公開 [#a1b18e82]
まだ内容は秘密です!~
今使ってるブラウザから移行するようなものではなく、一緒に使う感じになると思います。~

*はまり雑記 [#fdd23294]
**参考にしたページ [#l93260d2]
-[[幻想遺電子観測地点-Dolphin技術情報>http://griffy.pekori.to/soft/technologies.html]]~
DelphiでTWebBrowserを使ってプログラミングされているDolphinの技術情報です

-[[窓の杜 - 【NEWS】「Sleipnir」「Firefox」などのタブ切り換え型Webブラウザーに存在する脆弱性>http://www.forest.impress.co.jp/article/2004/10/21/tabbrowsersecad.html]]~
タブ切り換え型Webブラウザーに存在する脆弱性…気をつけねば~

-[[TUIWebBrowser TDomEvent>http://www33.ocn.ne.jp/~takoyakusi/delphi/UIWebBrowser/index.htm]]~
TWebBrowserを拡張したTUIWebBrowserが公開されています。
ちょこちょこっといじればDelphi7Proで使えるみたいです。

**リターンキーやショートカットキー等の一部のキーが効かない [#m3064d22]
TWebBrowserそのままでは、ブラウザ内のリターンキー等が効きません。~
TUIWebBrowserはリターンキーは効きますが、その他のDelphiなどで設定したショートカットキー等が効きません。~

この解決法は以下のページに書かれています。~
[[幻想遺電子観測地点-Dolphin技術情報→IEコンポーネント使用時の注意点>http://griffy.pekori.to/soft/technologies.html]]~

-テストコード 幻想遺電子観測地点-Dolphin技術情報と同じもの
 //~省略~
 
   private
     { Private 宣言 }
     FOleInPlaceActiveObject: IOleInPlaceActiveObject;
 
 //~省略~
 
 procedure TForm1.FormCreate(Sender: TObject);
 begin
   Application.OnMessage := AppMessages;
 end;
 
 procedure TForm1.AppMessages(var Msg: TMsg; var Handled: Boolean);
 var
   Re: HRESULT;
 begin
   if Msg.message = WM_KEYDOWN then
   begin
     //WebBrowserにメッセージが送られてきたかを判定
     if IsChild(UIWebBrowser1.Handle, Msg.hwnd) then
     begin
       FOleInPlaceActiveObject :=
         UIWebBrowser1.ControlInterface as IOleInPlaceActiveObject;
 
       //メッセージをアクティブなWebBrowser(の子ウインド)に転送
       Re := FOleInPlaceActiveObject.TranslateAccelerator(Msg);
 
       if Re = S_OK then
       begin
         Handled := True;
       end
       else begin
         Handled := False;
       end;
     end;
   end;
 end;

-テストコード タブブラウザにした際のコード~
タブブラウザにする際も&color(blue){''メインフォームに1つはダミーでTUIWebBrowserを置いておく''};(使わないので他のコンポーネントの影にでも隠しておく)~
こうしないと&color(blue){''Applicationのメッセージループが全く来なくなる問題''};があるからです…なぜこれで直るかは謎。~
「TFrame」を継承した「TIEFrame」上に「CliantUIWebBrowser: TUIWebBrowser」を置き、「FOleInPlaceActiveObject: IOleInPlaceActiveObject」を用意して外部からプロパティで見えるようにする。~
~
後記1:あ…これだと&color(blue){''タブをフリーした瞬間にタイミング悪いとAppMessagesでエラー起きるしー''};良い方法思案中…とりあえず外道処理を入れてみる(汗)~
 //~省略~
     CliantUIWebBrowser: TUIWebBrowser;
   private
     { Private 宣言 }
     FOleInPlaceActiveObject: IOleInPlaceActiveObject;
   public
     { Public 宣言 }
     property OleInPlaceActiveObject: IOleInPlaceActiveObject
       read FOleInPlaceActiveObject write FOleInPlaceActiveObject;
 
     property WebBrowser: TUIWebBrowser
       read CliantUIWebBrowser write CliantUIWebBrowser;
 //~省略~
そのフレームをメインフォームの「WebBrowserPageControl:TPageControl」に乗せる。
 procedure TForm1.FormCreate(Sender: TObject);
 begin
   Application.OnMessage := AppMessages;
 end;
 
 function TForm1.AddIEFrameTab: TTabSheet;
 var
   WkTabSheet: TTabSheet;
   WkIEFrame: TIEFrame;
 begin
   // タブ(TTabSheet)を増やしてそこにフレーム(TIEFrame)を生成する。
   // 生成したタブシートを返す。
   WkTabSheet := TTabSheet.Create(WebBrowserPageControl);
   WkIEFrame := TIEFrame.Create(WkTabSheet);
   WkIEFrame.Parent := WkTabSheet;
   WkIEFrame.Name := '';
   WkIEFrame.Align := alClient;
   WkTabSheet.PageControl := WebBrowserPageControl;
 
   result := WkTabSheet;
 end;
 
 function TForm1.GetTabSheetToIEFrame(ATabSheet: TTabSheet): TIEFrame;
 var
   WkControlCount: Integer;
   WkControl: TControl;
 begin
   // タブシートの中からフレーム(TIEFrame)を探して返す。
   result := nil;
 
   if ATabSheet = nil then
   begin
     Exit;
   end;
 
   for WkControlCount := 0 to ATabSheet.ControlCount - 1 do
   begin
     WkControl := ATabSheet.Controls[WkControlCount];
     if WkControl.ClassName = 'TIEFrame' then
     begin
       result := TIEFrame(WkControl);
       Exit;
     end;
   end;
 end;
 
 function TForm1.GetActiveIEFrame: TIEFrame;
 begin
   // アクティブになっているTTabSheetのフレーム(TIEFrame)を取得
   result := GetTabSheetToIEFrame(WebBrowserPageControl.ActivePage);
 end;
 
 procedure TForm1.AppMessages(var Msg: TMsg;
   var Handled: Boolean);
 var
   Re: HRESULT;
   WkIEFrame: TIEFrame;
 begin
   begin
     try
       WkIEFrame := GetActiveIEFrame;
 
       // フレームおよびWebBrowserがnilなら通常のイベントとして回す
       if WkIEFrame = nil then
       begin
         Exit;
       end;
       if WkIEFrame.WebBrowser = nil then
       begin
         Exit;
       end;
 
       //WebBrowserにメッセージが送られてきたかを判定
       if IsChild(WkIEFrame.WebBrowser.Handle, Msg.hwnd) then
       begin
         WkIEFrame.OleInPlaceActiveObject :=
           WkIEFrame.WebBrowser.ControlInterface as IOleInPlaceActiveObject;
 
         //メッセージをアクティブなWebBrowser(の子ウインド)に転送
         Re := WkIEFrame.OleInPlaceActiveObject.TranslateAccelerator(Msg);
 
         if Re = S_OK then
         begin
           Handled := True;
         end
         else begin
           Handled := False;
         end;
       end;
     except
       // この処理をしている途中でフリーされたらエラーになるので
       // そうなったらメッセージを処理しないようにする
       // 外道な保険コード?
       Handled := False;
       Exit;
     end;
   end;
 end;

**TUIWebBrowserをDelphi7Proで使いたい [#rb9587fe]
USESの「MSHTML_TLB」を「MSHTML」にするだけです。