views:

928

answers:

4

I would like to embed mozilla firefox into my application WITHOUT using any activex control (TWebBrowser wrapper, mozilla ActiveX...). I tried using TWebBrowser (actually bsalsa's embedded webBrowser wich is by far better), but all versions of IE seem incompatible with some features of popular javascript framework and libs (JQuery, ExtJS...).

My question is : can I call firefox's Exe from my application (is it possible with DDE or OLE) and above all SHOW IT inside my app using a TFrame or anything similar ?

waiting for your suggestions Regards, M

+1  A: 

You can embed DLLs into your application and "load" then using BTMemoryModule.pas (just google it and you find it).

If this DLL is a COM object it might work to "load" the COM DLL factory and obtaining an instance of the COM interface you want:

var
    // Our own method of COM / OLE object loading!
    Lib:       HMODULE;
    Ptr:       TDllGetClassObject;
    Unl:       TDLLCanUnloadNow;
    I:         IClassFactory;
initialization
    Lib := LoadLibrary( 'zkemkeeper.dll' );
    Ptr := GetProcAddress( Lib, 'DllGetClassObject' );
    Unl := GetProcAddress( Lib, 'DllCanUnloadNow' );
    if Assigned( Ptr ) and ( Ptr( CLASS_CZKEM, IClassFactory, I ) <> S_OK ) then I := nil;
finalization
    I := nil;

OleInitialize( nil );
// Create a IZKEM interface instance
if not Assigned( I ) then Exit;
if I.CreateInstance( nil, IZKEM, CZ ) <> S_OK then Exit;
if not Assigned( CZ ) then Exit;

I do not know how to embed executables.

I hope this info helps.

Ritsaert Hornstra
Thank you Ritsaert. Actually, I am looking for a way to 'monitor' firefox (or any other app) from my own app, something like DDE or COM.My goal is to provide the features of that app without exiting my own software (for security and ergonomy reasons: users have access only to my app, no windows explorer)
Thus: you can install Firefox on a machine next to your applcation and run Firefox for example. Must it be inside your one of your windows=
Ritsaert Hornstra
yes, it has to be inside one of my app windows.
A: 

The simplest way to embed an EXE into your application is to add it as a resource.

Make a .RC file with something like the following text:

OTHER_EXE_FILE  RCDATA "nameofother.exe"

then using brcc32.exe you can compile a .RES file of the same name as the .RC with which you can then include ($I) the new .RES file in your application. The NAMEOFOTHER.EXE has to be in the same folder as the .RC file or be properly pathed, IIRC.

There is supposededly another way of doing this as well. You don't use the command line brcc32.exe compiler and just include ($I) the .RC file into your program and the compiler the compiles the .RC file on the fly.

Can't tell you if the second method works or not as I've never tried it.

Ryan J. Mills
Thank you Ryan. Is there any way to show the stored exe in a tframe inside the main form of my app? (like Adobe acrobat Reader).
You would need to save the resource to disk, then launch it and handle it accordingly. You can't, in theory anyways, launch and in memory .exe it has to be on disk. There are ways to do it but I believe it's becoming harder and harder to do because of the threat of trojans and viruses doing the same type of thing. The other thing is if your trying to do COM I believe the stored .EXE has to be registered with the COM subsystem to be used properly. I can't see that happening if you try to run it from within your application, unless you register/deregister it on the fly.
Ryan J. Mills
+2  A: 

You'll need to clean up the code a bit and work out how you'll "talk" to Firefox.
But here is how you can embed any app inside a Delphi form.

DFM File

object frmMain: TfrmMain
  Left = 195
  Top = 154
  Width = 527
  Height = 363
  Caption = 'Containership Test'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  DesignSize = (
    519
    329)
  PixelsPerInch = 96
  TextHeight = 13
  object pnlTop: TPanel
    Left = 0
    Top = 0
    Width = 519
    Height = 292
    Align = alTop
    Anchors = [akLeft, akTop, akRight, akBottom]
    BevelInner = bvLowered
    TabOrder = 0
  end
  object btnLoadApp: TButton
    Left = 172
    Top = 297
    Width = 75
    Height = 25
    Anchors = [akLeft, akBottom]
    Caption = 'Load'
    TabOrder = 1
    OnClick = btnLoadAppClick
  end
  object btnKill: TButton
    Left = 260
    Top = 297
    Width = 75
    Height = 25
    Anchors = [akLeft, akBottom]
    Caption = 'Kill'
    TabOrder = 2
    OnClick = btnKillClick
  end
end

main.pas file

unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, ShellApi;

type
  TfrmMain = class(TForm)
    pnlTop: TPanel;
    btnLoadApp: TButton;
    btnKill: TButton;
    procedure btnLoadAppClick(Sender: TObject);
    procedure btnKillClick(Sender: TObject);
  private
    { Private declarations }
    AppWnd : DWORD;
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

procedure TfrmMain.btnLoadAppClick(Sender: TObject);
var
  ExecuteFile : string;
  SEInfo: TShellExecuteInfo;
begin
  ExecuteFile:='c:\Windows\notepad.exe';

  FillChar(SEInfo, SizeOf(SEInfo), 0) ;
  SEInfo.cbSize := SizeOf(TShellExecuteInfo) ;
  with SEInfo do
  begin
    fMask := SEE_MASK_NOCLOSEPROCESS;
    Wnd := pnlTop.Handle;
    lpFile := PChar(ExecuteFile) ;
    nShow := SW_HIDE;
  end;
  if ShellExecuteEx(@SEInfo) then
  begin
    AppWnd := FindWindow(nil, PChar('Untitled - Notepad'));
    if AppWnd  0 then
    begin
      Windows.SetParent(AppWnd, SEInfo.Wnd);
      ShowWindow(AppWnd, SW_SHOWMAXIMIZED);
      ShowWindow(AppWnd, SW_SHOWMAXIMIZED);
    end;
  end
  else
    ShowMessage('Error starting notepad!') ;
end;

procedure TfrmMain.btnKillClick(Sender: TObject);
begin
  if (AppWnd  0) then
  begin
    PostMessage(AppWnd, WM_Close, 0, 0);
    AppWnd := 0;
  end;
end;

end.
Catharz
Thank you Catharz : this is exactly what I want to do.I'll try this and post my results here.Now my question is: can I post messages to FF? (open new tab, get last visited URL..)again, thank youMo3ez
I've not looked at it myself, but you can checkout the mozdev code and see if you can use something from there. Since you want to use JavaScript, the JavaScript bridge is probably exactly what you want.http://delphi.mozdev.org/source.htmlhttp://downloads.mozdev.org/delphi/javascript_bridge.zip
Catharz
Isn't missing an equal sign? I.e.: _if AppWnd 0 then_ needs to be _if AppWnd = 0 then_
MaD70
Anyway, it's interesting. Can you state the technique explicitly in your answer? That is essentially to transform a target executable top-level window in a child window of own application.
MaD70
MaD70,No, the if statement should be "if AppWnd is not equal to 0".Looks like the parser stripped out the less-than and greater-than signs when I pasted the code.The technique is similar to something the application I'm working on does. But it embeds forms inside the pages of a tab control.In the example above, I'm executing the application in a hidden state. I can then set its parent to any Windows Control (in this case a panel) before un-hiding it. This embeds the application inside that control. For some reason ShowWindow needs to be called twice for this to work.
Catharz
A: 

I think what the original guy actually wants is a Web browser rendering engine embedded as a control in his application. If so, Gecko (The mozilla rendering part) is available as a plugin for your Application. I don't think you want to run an EXE.

For example, Mozilla Firefox isn't just an EXE file, but requires other stuff including a profiles folder. YOu probably haven't thought about all the problems that would cause.

If you just want a web browser control, this is not the way to do it. Try this instead: http://ftp.newbielabs.com/Delphi%20Gecko%20SDK/ https://sourceforge.net/projects/d-gecko/

Warren P
Thank you warren : but as I said in my first post, I do not want to embed a webbroswer component inside my app (wether it is TWebBrowser IE wrapper, Mozilla ActiveX or gecko SDK) but show an external app into one of my windows (FF in this case).It is useful to know anyway: I did try Gecko SDK delphi wrapper and found it quiet useful.Thanks for the tip