73
votes

I have started to convert the Webview interfaces to be consumed in Delphi. I have managed to get the webkit library to load, and the interface methods that is called appears to work correctly, however, I cannot seem to display the Webview on the main form.

Below is my interfaces that is declared

  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;

And here follows to code to construct a WebView:

procedure TForm2.Button1Click(Sender: TObject);
var
  PWebView: Pointer;
  FwkMod: HMODULE;
  MyWebView: WebView;
  urlStr: NSURL;
  urlreq: NSURLRequest;
const
  WebKitFWK: string = '/System/Library/Frameworks/WebKit.framework/WebKit';
begin
  FwkMod := System.SysUtils.LoadLibrary(PWideChar(WebKitFWK));
  PWebView := TWebView.Alloc.initWithFrame(MakeNSRect(10, 10, 300, 300), nil, nil);
  MyWebView := TWebView.Wrap(PWebView);

  urlStr := TNSURL.Create;
  urlstr.initWithString(NSSTR('http://google.com.au/'));
  urlreq := TNSURLRequest.Create;
  urlreq.initWithURL(urlstr);
  MyWebView.mainFrame.loadRequest(urlreq);
end;

The code executes without raising any exceptions, but just does not want to appear. What needs to be done differently in Delphi? The examples I found for objective C appears to be quite simple:

Some objective C examples I have seen mention IBOutlets. It does not look like this is relevant for Delphi.

How to make WebView OSX Xcode project load a URL on launch?

Thanks.

2
I think it is not possible since Delphi only use Cocoa to display a form, everything else is displayed using Quartz. Yous should'nt be able to display Cocoa objects without writing a complete vcl for Cocoa.Henri Gourvest
"freepascal" might not be an appropriate tag, since Free Pascal interfaces to Cocoa over Objective Pascal, not over interfaces and D2010 rtti (which FPC doesn't support yet). If you are interested in the matter, there is a rough start of a LCL Cocoa backend. (afaik it has basic FORM support working)Marco van de Voort
@HenriGourvest All I want to do is display a basic form with the webview control on it - Is there a way to only use cocoa without quartz?Phillip Roux
i don't know delphi at all, but reading your post it sounds like this has to do with either (the lack of a/proper) graphics context, or WebView needing a runloop in order to fetch/display the request.arri
I am not aware much about Delphi, but how it goes in normal programming is , you need to show window manually, to display the window/ widget etc..Amitg2k12

2 Answers

7
votes

Getting the NSWindow of a FMX form
convert a TForm reference to a NSWindow
set Host Window.
MyWebView.setHostWindow(MyNSWindow)

procedure TForm2.Button1Click(Sender: TObject);
var
[...]
 ObjTOC: TOCLocal;
 MyNSWindow : NSWindow;
[...]  
 ObjTOC := (FmxHandleToObjC(Form2.Handle) as TOCLocal);
 MyNSWindow := NSWindow(TOCLocalAccess(ObjTOC).Super);

PWebView := TWebView.Alloc.initWithFrame(MakeNSRect(10, 10, 300, 300), nil, nil);
 MyWebView := TWebView.Wrap(PWebView);
 MyWebView.setHostWindow(MyNSWindow);

[...]
 MyWebView.mainFrame.loadRequest(urlreq);
end;