[[戻る>DoldoWorkz#delphi]] *Delphiでウェブタブブラウザを作る [#p1c2ccdb] Delphiでウェブタブブラウザを作る際にハマった事や参照した場所等をメモしていきます。 #hr #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」にするだけです。 *コメント [#w17e250a] #Comment