Firemonkey实现Mac OS程序中内嵌浏览器的功能(自己动手翻译,调用苹果提供的webkit框架)

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,还是打不开网页。

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

[delphi] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. unit Unit1;  
  2.    
  3. interface  
  4.    
  5. uses  
  6.   System.SysUtils, System.Types, System.UITypes, System.Rtti, System.Classes,  
  7.   System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs,  
  8.   FMX.StdCtrls, Macapi.CocoaTypes, Macapi.Foundation, Macapi.AppKit,  
  9.   Macapi.ObjectiveC, FMX.Platform.Mac;  
  10.    
  11. type  
  12.    
  13.   WebFrameClass = interface(NSObjectClass)  
  14.   ['{7BE750C8-DFEC-4870-851A-12DBCB0B78F6}']  
  15.   end;  
  16.    
  17.   WebFrame = interface(NSObject)  
  18.   ['{BCFA04BE-41AB-4B78-89C0-3330F12C7695}']  
  19.     procedure loadRequest(request: NSURLRequest); cdecl;  
  20.   end;  
  21.   TWebFrame = class(TOCGenericImport<WebFrameClass, WebFrame>)  end;  
  22.    
  23.   WebViewClass = interface(NSViewClass)  
  24.   ['{0D9F44B7-09FD-4E35-B96E-8DB71B9A2537}']  
  25.     {class} function canShowMIMEType(MIMEType: NSString): Boolean; cdecl;  
  26.   end;  
  27.    
  28.   WebView = interface(NSView)  
  29.   ['{C36D8016-2FCB-49F0-BA1C-C9913A37F9AC}']  
  30.     procedure clos; cdecl;  
  31.     procedure setHostWindow(hostWindow: NSWindow); cdecl;  
  32.     function initWithFrame(frame: NSRect; frameName: NSString; groupName: NSString): Pointer; cdecl;  
  33.     function mainFrame: WebFrame; cdecl;  
  34.   end;  
  35.   TWebView = class(TOCGenericImport<WebViewClass, WebView>)  end;  
  36.    
  37.   TOCLocalAccess = class(TOCLocal);  
  38.    
  39.   TForm1 = class(TForm)  
  40.     procedure FormCreate(Sender: TObject);  
  41.   private  
  42.     MyWebView: WebView;  
  43.   end;  
  44.    
  45. var  
  46.   Form1: TForm1;  
  47.    
  48. implementation  
  49.    
  50. {$R *.fmx}  
  51.    
  52. procedure TForm1.FormCreate(Sender: TObject);  
  53. var  
  54.   PWebView: Pointer;  
  55.   FwkMod: HMODULE;  
  56.   urlStr: NSURL;  
  57.   urlreq: NSURLRequest;  
  58.   ObjTOC: TOCLocal;  
  59.   MyView: NSView;  
  60. const  
  61.   WebKitFWK: string = '/System/Library/Frameworks/WebKit.framework/WebKit';  
  62. begin  
  63.   FwkMod := System.SysUtils.LoadLibrary(PWideChar(WebKitFWK)); //必须要加  
  64.   MyView := WindowHandleToPlatform(Form1.Handle).View;  
  65.   PWebView := TWebView.Alloc.initWithFrame(MakeNSRect(10, 10, 200, 200), nil, nil);  
  66.   MyWebView := TWebView.Wrap(PWebView);  
  67.   MyView.addSubview(MyWebView);  
  68.    
  69.   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  
  70.   urlreq := TNSURLRequest.Create;  // fixing this is left as an exercise for the reader :) see previous line  
  71.   urlreq.initWithURL(urlstr);      //  .....  
  72.   MyWebView.mainFrame.loadRequest(urlreq);  
  73.    
  74.   urlreq.release; // if you call alloc or create, you also have to call release, otherwise you will leak your object (create rule)  
  75.   // same for urlstr, ...  
  76. end;  
  77.    
  78. end.  
[delphi] view plain copy
 
 在CODE上查看代码片派生到我的代码片
    1. var  
    2.   PWebView: Pointer;  
    3.   FwkMod: HMODULE;  
    4.   urlStr: NSURL;  
    5.   urlreq: NSURLRequest;  
    6.   ObjTOC: TOCLocal;  
    7.   MyNSWindow : NSWindow;  
    8.   MyView: NSView;  
    9. const  
    10.   WebKitFWK: string = '/System/Library/Frameworks/WebKit.framework/WebKit';  
    11. begin  
    12.   FwkMod := System.SysUtils.LoadLibrary(PWideChar(WebKitFWK));  
    13.   
    14.   {//方法一 
    15.   ObjTOC := (WindowHandleToPlatform(Form1.Handle).Handle as TOCLocal); 
    16.    MyNSWindow := NSWindow(TOCLocalAccess(ObjTOC).Super);}  
    17.   //方法二  
    18.   MyNSWindow := WindowHandleToPlatform(Form1.Handle).Wnd;  
    19.   PWebView := TWebView.Alloc.initWithFrame(MakeNSRect(0, 0, 200, 200), nil, nil);  
    20.   MyWebView := TWebView.Wrap(PWebView);  
    21.   MyWebView.setHostWindow(MyNSWindow);  
    22.   
    23.   //导致错误的地方  
    24.   //urlStr := TNSURL.Create;  
    25.   //urlstr.initWithString(NSSTR('http://www.google.com.hk/'));  
    26.   
    27.   urlStr := TNSURL.Wrap(TNSURL.Alloc.initWithString(NSSTR('http://www.google.com.hk/')));  
    28.   urlreq := TNSURLRequest.Create;  
    29.   urlreq.initWithURL(urlstr);  
    30.   MyWebView.mainFrame.loadRequest(urlreq);  
    31.   MyNSWindow.setContentView(MyWebView);  
    32.   
    33. end;  

http://blog.csdn.net/qustdong/article/details/17139137

原文地址:https://www.cnblogs.com/findumars/p/5361132.html