動的にバグを回避する

解決


ねじ  2005-12-09 11:49:35  No: 19145

いつも拝見しております。
Delphi 7 Professional
WindowsXP professional SP1

WebBrowserコントロール内に表示されたフォームの入力バグを回避する策を
過去ログで見つけたのですが、WebBrowser1に対して書かれたもので、タブブラウザの様に、動的にコンポーネントを生成する場合、それらのバグ回避はどのように書けばよいのでしょうか。。。

procedure TForm1.MsgHandler(var Msg: TMsg; var Handled: Boolean);
var
  iOIPAO: IOleInPlaceActiveObject;
  Dispatch: IDispatch;
begin
  if WebBrowser1 = nil then
    begin
    Handled := False;
    Exit;
  end;

    Handled := (IsDialogMessage(WebBrowser1.Handle, Msg) = True);

    if (Handled) and (not WebBrowser1.Busy) then
    begin
    Dispatch := WebBrowser1.Application;
        if Dispatch <> nil then
        begin
            Dispatch.QueryInterface(IOleInPlaceActiveObject, iOIPAO);
          if iOIPAO <> nil then
            begin
              FOleInPlaceActiveObject := iOIPAO;
          end;
      end;
      if FOleInPlaceActiveObject <> nil then
      begin
        if ((Msg.message = WM_KEYDOWN) or (Msg.message = WM_KEYUP)) and
            ((Msg.wParam = VK_BACK) or (Msg.wParam = VK_LEFT) or (Msg.wParam = VK_RIGHT)) then
          else
        FOleInPlaceActiveObject.TranslateAccelerator(Msg);
        end;
    end;
end;

initialization
    OleInitialize(nil);

finalization
    OleUninitialize;

end.

といったソースがあったのですが、WebBrowser1を直接書かれている為、困っています。
なにか対策がありましたらお願いします。


にしの  2005-12-10 03:27:54  No: 19146

タブブラウザの実装にもよるとおもいますが、WebBrowser1をアクティブなブラウザにすればよいかと思います。
アクティブなブラウザかどうかの判断は実装によります。全てのタブを閉じたときに1つもブラウザがないようなら、ブラウザがない場合の処理も必要になります。


にしの  2005-12-10 04:17:34  No: 19147

例です。
TTabSheetを継承して、property Browser: TWebBrowserを追加したものを使用。

毎回IOleInPlaceActiveObjectを取得するので、FOleInPlaceActiveObjectの宣言は不要かと思います。

procedure TForm1.MsgHandler(var Msg: TMsg; var Handled: Boolean);
var
  iOIPAO: IOleInPlaceActiveObject;
  Dispatch: IDispatch;
  wb: TWebBrowser;
begin
  Handled := False;
  if not Assigned(PageControl1.ActivePage) then
  begin
    Exit;
  end;
  wb := TTabBrowser(PageControl1.ActivePage).Browser;
  if wb = nil then
  begin
    Exit;
  end;
  Handled := (IsDialogMessage(wb.Handle, Msg) = True);
  if (Handled) and (not wb.Busy) then
  begin
    Dispatch := wb.Application;
    if Dispatch <> nil then
    begin
      Dispatch.QueryInterface(IOleInPlaceActiveObject, iOIPAO);
    end;
    if iOIPAO <> nil then
    begin
      if ((Msg.message = WM_KEYDOWN) or (Msg.message = WM_KEYUP)) and
        ((Msg.wParam = VK_BACK) or (Msg.wParam = VK_LEFT) or (Msg.wParam = VK_RIGHT)) then
      begin
      end
      else
      begin
        iOIPAO.TranslateAccelerator(Msg);
      end;
    end;
    Dispatch._Release;
  end;
end;


ねじ  2005-12-11 21:34:08  No: 19148

にしのさん、ありがとうございます。

>TTabSheetを継承して、property Browser: TWebBrowserを追加したものを使用。
クラスの継承等、色々調べてみたのですが、わからなくて色々悩んでいたのですが、上記のActivePageを参考に以下のように書き換えてなんとか解決しました。

procedure TForm1.MsgHandler(var Msg: TMsg; var Handled: Boolean);
var
  iOIPAO: IOleInPlaceActiveObject;
  Dispatch: IDispatch;
  twb:TWebBrowser;
begin
  twb := TWebBrowser(Form1.PageControl1.ActivePage.Controls[0]);

  if twb = nil then
    begin
    Handled := False;
    Exit;
  end;

    Handled := (IsDialogMessage(twb.Handle, Msg) = True);

    if (Handled) and (not twb.Busy) then
    begin
    Dispatch := twb.Application;
        if Dispatch <> nil then
        begin
            Dispatch.QueryInterface(IOleInPlaceActiveObject, iOIPAO);
          if iOIPAO <> nil then
            begin
              FOleInPlaceActiveObject := iOIPAO;
          end;
      end;
      if FOleInPlaceActiveObject <> nil then
      begin
        if ((Msg.message = WM_KEYDOWN) or (Msg.message = WM_KEYUP)) and
            ((Msg.wParam = VK_BACK) or (Msg.wParam = VK_LEFT) or (Msg.wParam = VK_RIGHT)) then
          else
        FOleInPlaceActiveObject.TranslateAccelerator(Msg);
        end;
    end;
end;

下位オブジェクトに対するキャストの方法を知らなかったので、にしのさんのソースが大変参考になりました。
せっかく提示いただいたソースを使う事ができなくて申し訳ありませんでした。。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加