Firemonkey实现Mac OS程序中内嵌浏览器的功能

XE系列虽然可以跨平台,但是在跨平台的道路上只是走了一小半的路,很多平台下的接口都没实现彻底,所以为了某些功能,还必须自己去摸索。

想实现程序中可以内嵌浏览器的功能,但是Firemonkey还没有对应的控件,

TMS 倒是提供了true native Mac OS-X application development, TMS mCL 以及 JVEsoft的组件包,提供了对应的web浏览器控件,但是都不是免费的,而且试用么TMS的问题还是有很多,为了省银子,卷起袖子自己搞。

思路其实很简单,苹果已经提供了webkit的框架,我的firemonkey只要能调用他的框架,就能使用它的功能了。

这也是XE系列的思路。

现在要做的是如何翻译Mac OS Api了,这还是第一次搞,所以还不知道怎么弄,翻山越岭搜了一下,发现翻译想自己实现webview的只有一个信息http://stackoverflow.com/questions/9731817/webview-not-displaying-in-macos-using-delphi-xe2,他遇到了无法显示出来的一个问题。我跑了他的代码,发现XE2下的代码已经不能在XE4下运行了,稍作修改后,程序可以正常运行了,但是一直没有效果,真的很困惑,问题出在哪里了呢?

在github上有搜到了类似的代码,看代码应该是日本人写的https://gist.github.com/tokibito/6945988/raw/6770e1fd3f8b3c8fd2e0da5498248a7e79f73944/Unit1.pas,还是打不开网页。

于是发帖求助,一个老外给出了实现的方案,真心感谢,也不得不佩服他们。


unit Unit1;
 
interface
 
uses
  System.SysUtils, System.Types, System.UITypes, System.Rtti, System.Classes,
  System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs,
  FMX.StdCtrls, Macapi.CocoaTypes, Macapi.Foundation, Macapi.AppKit,
  Macapi.ObjectiveC, FMX.Platform.Mac;
 
type
 
  WebFrameClass = interface(NSObjectClass)
  ['{7BE750C8-DFEC-4870-851A-12DBCB0B78F6}']
  end;
 
  WebFrame = interface(NSObject)
  ['{BCFA04BE-41AB-4B78-89C0-3330F12C7695}']
    procedure loadRequest(request: NSURLRequest); cdecl;
  end;
  TWebFrame = class(TOCGenericImport<WebFrameClass, WebFrame>)  end;
 
  WebViewClass = interface(NSViewClass)
  ['{0D9F44B7-09FD-4E35-B96E-8DB71B9A2537}']
    {class} function canShowMIMEType(MIMEType: NSString): Boolean; cdecl;
  end;
 
  WebView = interface(NSView)
  ['{C36D8016-2FCB-49F0-BA1C-C9913A37F9AC}']
    procedure clos; cdecl;
    procedure setHostWindow(hostWindow: NSWindow); cdecl;
    function initWithFrame(frame: NSRect; frameName: NSString; groupName: NSString): Pointer; cdecl;
    function mainFrame: WebFrame; cdecl;
  end;
  TWebView = class(TOCGenericImport<WebViewClass, WebView>)  end;
 
  TOCLocalAccess = class(TOCLocal);
 
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    MyWebView: WebView;
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.fmx}
 
procedure TForm1.FormCreate(Sender: TObject);
var
  PWebView: Pointer;
  FwkMod: HMODULE;
  urlStr: NSURL;
  urlreq: NSURLRequest;
  ObjTOC: TOCLocal;
  MyView: NSView;
const
  WebKitFWK: string = '/System/Library/Frameworks/WebKit.framework/WebKit';
begin
  FwkMod := System.SysUtils.LoadLibrary(PWideChar(WebKitFWK)); //必须要加
  MyView := WindowHandleToPlatform(Form1.Handle).View;
  PWebView := TWebView.Alloc.initWithFrame(MakeNSRect(10, 10, 200, 200), nil, nil);
  MyWebView := TWebView.Wrap(PWebView);
  MyView.addSubview(MyWebView);
 
  urlStr := TNSURL.Wrap(TNSURL.Alloc.initWithString(NSSTR('http://www.baidu.com/'))); // never ever call initWith... on an object created with "create". Some of these already fail on Mavericks, some may fail in the future
  urlreq := TNSURLRequest.Create;  // fixing this is left as an exercise for the reader :) see previous line
  urlreq.initWithURL(urlstr);      //  .....
  MyWebView.mainFrame.loadRequest(urlreq);
 
  urlreq.release; // if you call alloc or create, you also have to call release, otherwise you will leak your object (create rule)
  // same for urlstr, ...
end;
 
end.

var
  PWebView: Pointer;
  FwkMod: HMODULE;
  urlStr: NSURL;
  urlreq: NSURLRequest;
  ObjTOC: TOCLocal;
  MyNSWindow : NSWindow;
  MyView: NSView;
const
  WebKitFWK: string = '/System/Library/Frameworks/WebKit.framework/WebKit';
begin
  FwkMod := System.SysUtils.LoadLibrary(PWideChar(WebKitFWK));

  {//方法一
  ObjTOC := (WindowHandleToPlatform(Form1.Handle).Handle as TOCLocal);
   MyNSWindow := NSWindow(TOCLocalAccess(ObjTOC).Super);}
  //方法二
  MyNSWindow := WindowHandleToPlatform(Form1.Handle).Wnd;
  PWebView := TWebView.Alloc.initWithFrame(MakeNSRect(0, 0, 200, 200), nil, nil);
  MyWebView := TWebView.Wrap(PWebView);
  MyWebView.setHostWindow(MyNSWindow);

  //导致错误的地方
  //urlStr := TNSURL.Create;
  //urlstr.initWithString(NSSTR('http://www.google.com.hk/'));

  urlStr := TNSURL.Wrap(TNSURL.Alloc.initWithString(NSSTR('http://www.google.com.hk/')));
  urlreq := TNSURLRequest.Create;
  urlreq.initWithURL(urlstr);
  MyWebView.mainFrame.loadRequest(urlreq);
  MyNSWindow.setContentView(MyWebView);

end;


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值