SDK の説明にもいい加減飽きたので SDK を使って実際に何かをしてみる事にしよう。 わかりやすいのはやはりブラウザだろう。 そういうわけで最小限のコードでブラウザのようなものを作ってみた。 Delphi 版 GeckoSDK の中身をライブラリパスの通ったフォルダに入れておくこと。 最小のブラウザは以下のコードで実現する。
unit BrowserWin;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, nsXPCOM, nsTypes;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private 宣言 }
FBrowser: nsIWebBrowser;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
nsXPCOMGlue;
type
nsIWidget = interface end;
nsIBaseWindow = interface(nsISupports)
['{046BC8A0-8015-11d3-AF70-00A024FFC08C}']
procedure InitWindow(parentNativeWindow: Pointer;
parentWidget: nsIWidget;
x: PRInt32;
y: PRInt32;
cx: PRInt32;
cy: PRInt32); safecall;
procedure Create(); safecall;
procedure Destroy(); safecall;
procedure SetPosition(x: PRInt32;
y: PRInt32); safecall;
procedure GetPosition(out x: PRInt32;
out y: PRInt32); safecall;
procedure SetSize(cx: PRInt32;
cy: PRInt32); safecall;
procedure GetSize(out cx: PRInt32;
out cy: PRInt32); safecall;
procedure SetPositionAndSize(x: PRInt32;
y: PRInt32;
cx: PRInt32;
cy: PRInt32); safecall;
procedure GetPositionAndSize(out x: PRInt32;
out y: PRInt32;
out cx: PRInt32;
out cy: PRInt32); safecall;
procedure Repaint(force: PRBool); safecall;
function GetParentWidget: nsIWidget; safecall;
procedure SetParentWidget(aParentWidget: nsIWidget); safecall;
function GetNativeWindow: Pointer; safecall;
procedure SetNativeWindow(aNativeWindow: Pointer); safecall;
function GetVisibility: PRBool; safecall;
procedure SetVisibility(aVisibility: PRBool); safecall;
function GetEnabled: PRBool; safecall;
procedure SetEnabled(aEnabled: PRBool); safecall;
function GetBlurSupression: PRBool; safecall;
procedure SetBlurSupression(aBlurSupression: PRBool); safecall;
function GetMainWidget: nsIWidget; safecall;
procedure SetFocus(); safecall;
function GetTitle: PWideChar; safecall;
procedure SetTitle(aTitle: PWideChar); safecall;
end;
nsIWebNavigation = interface(nsISupports)
['{F5D9E7B0-D930-11d3-B057-00A024FFC08C}']
function GetCanGoBack: PRBool; safecall;
function GetCanForward: PRBool; safecall;
procedure GoBack(); safecall;
procedure GoForward(); safecall;
procedure GotoIndex(index: PRInt32); safecall;
procedure LoadURI(uri: PWideChar;
loadFlags: PRUint32;
referer: nsIURI;
postData: nsIInputStream;
headers: nsIInputStream); safecall;
procedure Reload(reloadFlags: PRUint32); safecall;
procedure Stop(stopFlags: PRUint32); safecall;
function GetDocument: nsIDOMDocument; safecall;
function GetCurrentURI: nsIURI; safecall;
function GetReferringURI: nsIURI; safecall;
function GetSessionHistory: nsISHistory; safecall;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
basewin: nsIBaseWindow;
navigation: nsIWebNavigation;
begin
// GRE の初期化
GRE_Startup;
// nsWebBrowser の生成
NS_CreateInstance(NS_WEBBROWSER_CONTRACTID, nsIWebBrowser, FBrowser);
basewin := FBrowser as nsIBaseWindow;
// ブラウザとネイティブウィンドウの関連づけ
basewin.InitWindow(Pointer(Handle), nil, 0, 0, ClientWidth, ClientHeight);
// ブラウザウィンドウの生成
basewin.Create;
basewin.SetVisibility(True);
navigation := FBrowser as nsIWebNavigation;
// ページの読み込み
navigation.LoadURI('http://nesitive.net/', 0, nil, nil, nil);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
// nsWebBrowser の破棄
FBrowser := nil;
// GRE の終了
GRE_Shutdown;
end;
end.
implementation
節の3つの interface
は凍結されていないために GeckoSDK には含まれていないものだ。
このうち nsIWidget
は IDL を使っていない C++ ベースのインターフェースなので、宣言自体を省略した。
OnCreate
イベントに書かれている部分がブラウザの初期化になる。
コメント以上のことは特に説明する必要もないだろう。
OnDestroy
イベントが終了処理になる。
GRE_Shudown
よりも前にnsWebBrowser
オブジェクトの参照カウントが 0にならないといけないため、 FBrowser
に明示的に nil
を代入して解放するようにしている。
実行ファイルは Mozilla のフォルダや GRE のフォルダにコピーする必要はなく、任意のフォルダで実行することができる。 ただ、このままではいろいろと問題がある。 これからしばらくはこの問題を解決する方法を模索していくことにする。
Hello,
I downloaded the GeckoSDK and tried your sample above, but I get an Access violation on the line:
basewin.InitWindow(Pointer(handle), nil, 0, 0, ClientWidth, ClientHeight);
Can you please help me?
How to display svg (ebedded, inline in html or xhtml) in Gecko component. I can display in firefox but I cannot do the same in delphi.
L.Czerwosz