Excel2010がTWebBrowser内で開かない。

以前作成した「ExcelをTWebBrowserで開くソフト」がWindows 7、Office2010の環境では、ExcelがTWebBrowser内ではなく、単独に表示されました。そのソフトを使っていた環境がWindows XP、Office 2003だったから知らなかったのですが、About.com Delphi によるとWindows Vista、Office2007で既にそのような動作になっていたようですね。記事は、Vista + Office2007ですが、Windows7 + Office2010でも、記事と同じ設定で、期待の動作になりました。

次のレジストリの値を変更します。
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Excel.Sheet.8]
"BrowserFlags"=dword:80000A00
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Excel.Sheet.12]
"BrowserFlags"=dword:80000A00


About.com Delphi
Opening Office Documents (Word, Excel) in TWebBrowser on Vista and Office 2007
http://delphi.about.com/od/delphitips2008/qt/wbr_vista.htm

|

☆TWebBrowserのフォントサイズ変更

TWebBrowserのフォントサイズを実行時にアプリ側から変更するサンプルです。ついでに現在のフォントサイズを取得する処理も書いてみました。フォントサイズについては、よくわからないのですが、下記のサイトで0~4となっていて、IEの「文字のサイズ」が5段階であることから、これに該当すると勝手に判断しています。
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, OleCtrls, SHDocVw, StdCtrls;

type
  TForm1 = class(TForm)
    ComboBox1: TComboBox;
    WebBrowser1: TWebBrowser;
    procedure FormCreate(Sender: TObject);
    procedure ComboBox1Change(Sender: TObject);
    procedure WebBrowser1DocumentComplete(ASender: TObject;
      const pDisp: IDispatch; var URL: OleVariant);
  private
    F: Boolean;
    function GetFontSize: Integer; 
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  // ComboBox1の設定
  ComboBox1.Items.Clear;
  ComboBox1.Style := csDropDownList;
  ComboBox1.Items.AddObject('最小',TObject(0));
  ComboBox1.Items.AddObject('小'  ,TObject(1));
  ComboBox1.Items.AddObject('中'  ,TObject(2));
  ComboBox1.Items.AddObject('大'  ,TObject(3));
  ComboBox1.Items.AddObject('最大',TObject(4));
  F := False;
  // delphi-fanはサイズの違いがわかりにくいです(^^;
  // 適当に変えて下さい。
  WebBrowser1.Navigate('http://hiderin.air-nifty.com/delphi/');
end;

// 現在のフォントサイズを返します。
function TForm1.GetFontSize: Integer;
var
  Size: OleVariant;
begin
  WebBrowser1.ExecWB(OLECMDID_ZOOM,
    OLECMDEXECOPT_DONTPROMPTUSER, EmptyParam, Size);
  Result := Size;
end;

procedure TForm1.WebBrowser1DocumentComplete(ASender: TObject;
  const pDisp: IDispatch; var URL: OleVariant);
begin
  // プログラム起動時に現在のフォントサイズを設定します。
  if not F then
  begin
    ComboBox1.ItemIndex := GetFontSize;
    F := True;
  end;
end;

procedure TForm1.ComboBox1Change(Sender: TObject);
var
  Size: OleVariant;
begin
  // フォントサイズを変更します。
  Size := Integer(ComboBox1.Items.Objects[ComboBox1.ItemIndex]);
  WebBrowser1.ExecWB(OLECMDID_ZOOM,
    OLECMDEXECOPT_DONTPROMPTUSER, Size, EmptyParam);
end;

end.

この処理の問題点としては、TWebBrowserを使う他のアプリケーションにまで、ここで設定したフォントサイズが 影響することです。(IEには、影響しません)
影響を受けていないように見せるためには、アプリケーション毎に INIファイル等で設定を保存する必要がありそうです。ちょっと面倒です(笑)

Microsoft
サポート オンライン
Visual Basic アプリケーション内にホストされた WebBrowser コントロールのフォント サイズを変更する方法
※例によって機械翻訳されたものです。

|

☆英単語の検索

CodeGearのニュースグループを始め、英文に触れる機会が多いですよね。
わからない英単語を調べるのに私は、英辞郎 on the WEBを利用させて頂いてます。

今回は、英辞郎 on the WEBを利用する処理を考えてみます。
Edit1, WebBrowser1, Button1をフォームに配置し、次の処理をさせます。
uses
  HTTPApp;

procedure TForm1.Button1Click(Sender: TObject);
const
  S1 = 'http://eow.alc.co.jp/';
  S2 = '/UTF-8/';
var
  S: String;
begin
  S := S1 + HTTPEncode(AnsiToUtf8(Edit1.Text)) + S2;
  WebBrowser1.Navigate(S);
end;
これだけで、英和・和英の辞書が完成します。
しかし、不明な単語をいちいちコピーして、貼り付けて、検索させるとなると面倒ですよね。
私は、クリップボードを監視して、コピーされたときに自動で検索させるようにしています。
ぜひ実装してみて下さい。

※英辞郎 on the WEBでは、データの転載は禁じられていますので、ご注意を。
※今後、アドレス変更他の理由により、この処理では利用できなくなることもあります。


SPACE ALC
英辞郎 on the WEB
http://www.alc.co.jp/

Delphi Tips
クリップボードが更新された時のイベントを取得する
http://www2.big.or.jp/~osamu/Delphi/Tips/key.cgi?key=10

|

☆TWebBrowserで自動ログイン

フリーメール以外でもWEBからアクセスできるメールサービスが多くあり、ブラウザさえ見れる環境があれば外部からメールのチェックが可能ですよね。今回は、そういったメールに自動ログインして、メーラーとして使えるような処理を考えたいと思います。サンプルでは、コード中にユーザーIDやパスワードを入力していますが、危険なので暗号化し、別ファイルに保存して読み書きするのが便利だと思います。そしてUSBメモリーに入れて持ち歩くと、人のパソコンでも簡単に自分のメーラーにすることができます(^^;キー入力によるパスワード等の盗難?の可能性も減りますし・・・。

私は、簡易な暗号しか作れないので、IDは簡易な暗号化をしてファイルに保存し、パスワードのみ入力するようにしています。現在 @nifty、eo、Hotmail、Gmail、Yahoo Groupをチェックできるようにしています。

まず、フォームにTWebBrowserとTButtonを一つずつ配置します。
そして、ログインするための処理を作成します。

var
  IsLogin: Boolean;

procedure TForm1.Login;
var
  URL: String;
begin
  // Gmailの場合
  URL := 'https://www.google.com/accounts/ServiceLogin?'+
         'service=mail&passive=true&rm=false&continue=http%3A%2F%2'+
         'Fmail.google.com%2Fmail%3Fhl%3Dja%26ui%3Dhtml%26zy%3Dl'+
         '&l'+'tmpl=cm_tlsosm_t&l'+'tmplcache=2&hl=ja';
  UserName := 'xxxxxxx@gmail.com'; // ここにユーザーIDを入力します。
  Password := '*******'; // ここにパスワードを入力します。
  IsLogin := False;
  WebBrowser1.Navigate(URL);
end;


次に自動ログインする処理です。 この処理方法については、どのサイトだったのかわからないのですが、いろいろなサイトを参考にさせてもらっています。名前やアドレスが書けず、ごめんなさい。
procedure TForm1.WebBrowser1DocumentComplete(ASender: TObject;
  const pDisp: IDispatch; var URL: OleVariant);
var
  iDoc: IHtmlDocument2;
  I: integer;
  ov: OleVariant;
  iDisp: IDispatch;
  iColl: IHTMLElementCollection;
  iInputElement: IHTMLInputElement;
begin
  if IsLogin then Exit;

  WebBrowser1.ControlInterface.Document.QueryInterface(IID_IHTMLDocument, iDoc);
  if not assigned(iDoc) then
    Exit;

  ov := 'INPUT';
  IDisp := iDoc.all.tags(ov);
  if assigned(IDisp) then
  begin
    IDisp.QueryInterface(IID_IHTMLElementCollection, iColl);
    if assigned(iColl) then
    begin
      for I := 1 to iColl.Get_length do
      begin
        iDisp := iColl.item(pred(I), 0);
        iDisp.QueryInterface(IID_IHTMLInputElement, iInputElement);
        if assigned(iInputElement) then
        begin
          // username ※iInputElement.nameについては、事前にHTMLを見て調べます。
          if (iInputElement.type_='text') and (iInputElement.name='Email') then
            iInputElement.value:= UserName;

          // password ※iInputElement.nameについては、事前にHTMLを見て調べます。
          if (iInputElement.type_= 'password') and (iInputElement.name='Passwd') then
            iInputElement.value:= Password;

          // submit
          if (iInputElement.type_= 'submit') then
          begin
            IsLogin := True;
            iInputElement.form.submit;
          end;
        end;
      end;
    end;
  end;
end;


最後にログインボタンの処理です。
procedure TForm1.Button1Click(Sender: TObject);
begin
  Login;
end;


プログラムにパスワードを書き込んで試した場合、バックアップファイルに残っていたりしますので、ご注意下さい。

|

☆WebBrowserでHTMLな文字列を直接表示させる。

WebBrowserで、一時ファイルを使わずに、HTMLを直接表示させるには、次のような処理をしていました。 CSSを指定する必要もなく常に新規ウィンドウで表示させていたので、特に問題がなかったのですが、時々 target="_blank"を書き忘れたりして、OLEエラーが発生していました。

//HTMLのリンク先が同じウィンドウで開くときに問題のあるコード
//って、使ってたんですけど(^^;

uses ActiveX, MSHTML;

procedure TForm1.Button1Click(Sender: TObject);
begin
  WebBrowser1.Navigate('about:blank');
end;

procedure TForm1.WebBrowser1DocumentComplete(ASender: TObject;
  const pDisp: IDispatch; var URL: OleVariant);
begin
  (WebBrowser1.Document as IHTMLDocument2).body.innerHTML :=
  '<a href="http://hiderin.air-nifty.com/delphi/"' + 
  ' target="_blank">delphi-fan</a>';
end;

フラグを立てて、プログラム側から設定した文字列以外は読み込まないようにすれば問題ないかも知れませんが、次のリンク先にあるコードを使って解決しました。

about.com Delphi Programming
How to load HTML directly to a WebBrowser

|

☆WebBrowserでHTMLを編集する。

今まであまり興味がなく、試したことがなかったのですが、結構すごいですね。 きちんと作れば、高機能なHTMLエディタも簡単につくれそうです。 もちろん、インターフェースとかCOM系のややこしいプログラムを駆使できればの話ですけど(笑)

フォームにButton5個とWebBrowser1個を貼り付けます。

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, OleCtrls, SHDocVw;
type
  TForm1 = class(TForm)
    WebBrowser1: TWebBrowser;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Button5: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
  private
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses MSHTML, ActiveX;

// HTMLの設定
procedure TForm1.FormCreate(Sender: TObject);
begin
  WebBrowser1.Navigate('http://hiderin.air-nifty.com/');
  Button1.Caption := '編集モード';
  Button2.Caption := '閲覧モード';
  Button3.Caption := 'コピー';
  Button4.Caption := '貼り付け';
  Button5.Caption := '保存';
end;

// 編集モード
procedure TForm1.Button1Click(Sender: TObject);
begin
  (WebBrowser1.Document as IHTMLDocument2).designMode := 'on';
end;

// 閲覧モード
procedure TForm1.Button2Click(Sender: TObject);
begin
  (WebBrowser1.Document as IHTMLDocument2).designMode := 'off'
end;

// コピー
procedure TForm1.Button3Click(Sender: TObject);
begin
  (WebBrowser1.Document as IHTMLDocument2).execCommand('Copy', True, EmptyParam);
end;

// 貼り付け
procedure TForm1.Button4Click(Sender: TObject);
begin
  (WebBrowser1.Document as IHTMLDocument2).execCommand('Paste', False, EmptyParam);
end;

// ファイルに保存
//EmptyParamとすると「無題」ファイル名が設定される。
//'test.html'とかファイル名を設定してもいいみたい。
procedure TForm1.Button5Click(Sender: TObject);
begin
  (WebBrowser1.Document as IHTMLDocument2).execCommand('SaveAs', False, EmptyParam);
end;

initialization
  OleInitialize(nil);

finalization
  OleUninitialize;
end.


編集機能については、CTRL+C, CTRL+Z等の標準的なものは、プログラムしてなくても使えます。

参考にしたサイト
about.com
How to enable editing of a document in TWebBrowser
MSDN
MSHTML Editing

|