31

通常,我使用:ShellExecute(0, 'OPEN', PChar(edtURL.Text), '', '', SW_SHOWNORMAL);

如何在所有平台(WindowsOSX)上具有相同的行为(在默认浏览器中打开链接)?

4

8 回答 8

24

关于mjn的答案,我写了以下单元。我已经在 Windows 上成功测试了它,但我没有 OSX 在这个平台上测试它。如果有人可以确认它有效,我将不胜感激。

unit fOpen;

interface

uses
{$IFDEF MSWINDOWS}
  Winapi.ShellAPI, Winapi.Windows;
{$ENDIF MSWINDOWS}
{$IFDEF POSIX}
  Posix.Stdlib;
{$ENDIF POSIX}

type
  TMisc = class
    class procedure Open(sCommand: string);
  end;

implementation

class procedure TMisc.Open(sCommand: string);
begin
{$IFDEF MSWINDOWS}
  ShellExecute(0, 'OPEN', PChar(sCommand), '', '', SW_SHOWNORMAL);
{$ENDIF MSWINDOWS}
{$IFDEF POSIX}
  _system(PAnsiChar('open ' + AnsiString(sCommand)));
{$ENDIF POSIX}
end;

end.

我这样称呼它:

TMisc.Open('https://stackoverflow.com/questions/7443264/how-to-open-an-url-with-the-default-browser-with-firemonkey-cross-platform-applic');
于 2011-09-17T09:27:36.980 回答
15

在 FireMonkey 讨论论坛中,我找到了有关 NSWorkspace.URLForApplicationToOpenURL 的问题的代码:

uses
  Posix.Stdlib;
....
  _system(PAnsiChar('open ' + ACommand));

(未经我测试)


更新:Posix 在 Windows 上不可用,因此无法编写在所有平台上使用相同操作系统调用的解决方案。我建议将此类代码移动到具有一些 IFDEF POSIX 等的中央“XPlatform”单元中。

于 2011-09-16T10:37:31.690 回答
12

对于所有平台(Windows、macOS、iOS 和 Android),您都可以使用我为博客编写的单元

unit u_urlOpen;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes,
  System.Variants,
{$IF Defined(IOS)}
  macapi.helpers, iOSapi.Foundation, FMX.helpers.iOS;
{$ELSEIF Defined(ANDROID)}
Androidapi.JNI.GraphicsContentViewText,
  Androidapi.JNI.Net,
   Androidapi.JNI.App,
  Androidapi.helpers;
{$ELSEIF Defined(MACOS)}
Posix.Stdlib;
{$ELSEIF Defined(MSWINDOWS)}
Winapi.ShellAPI, Winapi.Windows;
{$ENDIF}

type
  tUrlOpen = class
    class procedure Open(URL: string);
  end;

implementation

class procedure tUrlOpen.Open(URL: string);
{$IF Defined(ANDROID)}
var
  Intent: JIntent;
{$ENDIF}
begin
{$IF Defined(ANDROID)}
  Intent := TJIntent.Create;
  Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);
  Intent.setData(StrToJURI(URL));
  tandroidhelper.Activity.startActivity(Intent);
  // SharedActivity.startActivity(Intent);
{$ELSEIF Defined(MSWINDOWS)}
  ShellExecute(0, 'OPEN', PWideChar(URL), nil, nil, SW_SHOWNORMAL);
{$ELSEIF Defined(IOS)}
  SharedApplication.OpenURL(StrToNSUrl(URL));
{$ELSEIF Defined(MACOS)}
  _system(PAnsiChar('open ' + AnsiString(URL)));
{$ENDIF}
end;

end.
于 2017-08-23T09:11:25.173 回答
3

成功测试的 XE2 C++ 代码(Windows 7 64 和 OSX Lion),小幅改进。谢谢Whiler,痛苦结束了:)

#include <fmx.h>
// ---------------------------------------------------------------------------
#ifdef _WIN32
#include <shellapi.h>
#endif// Windows
#ifdef TARGET_OS_MAC
#include <Posix.Stdlib.hpp>
#endif // Mac

void OpenCommand(String _sCommand) {
    #ifdef _Windows
    String open = "open";
    ShellExecute(0, open.w_str(), _sCommand.c_str(), NULL, NULL, SW_SHOWNORMAL);
    #endif // Windows

    #ifdef TARGET_OS_MAC
    system(AnsiString("open " + AnsiString(_sCommand)).c_str());
    #endif // Mac
}
于 2012-10-19T08:21:15.217 回答
1

现在是 C++ 版本(OSx 代码未经测试,也不确定 _POSIX #def):

#ifdef _Windows
#include <Winapi.Windows.hpp>
#endif // _Windows
#ifdef _POSIX
#include <Posix.Stdlib.h>
#endif // _POSIX

void OpenCommand(String _sCommand)
{
    #ifdef _Windows
    ShellExecute(0, _T("open"), _sCommand.c_str(), _T(""), _T(""), SW_SHOWNORMAL);
    #endif // _Windows
    #ifdef _POSIX
    _system(AnsiString("open " + AnsiString(_sCommand)).c_str());
    #endif // _POSIX
}
于 2012-04-16T07:24:52.130 回答
1

正如@NicoBlu 提到的,接受的解决方案似乎会在第一次出现“&”后截断 URL。这是没有截断对我有用的方法:

uses Macapi.AppKit, Macapi.Foundation, Macapi.Helpers;

// ...

procedure OpenLinkInDefaultBrowser(const Link: string);
  var URL : NSURL;
      Workspace : NSWorkspace;
begin
  URL := TNSURL.Wrap(TNSURL.OCClass.URLWithString(StrToNSStr(Link)));
  Workspace := TNSWorkspace.Wrap(TNSWorkspace.OCClass.sharedWorkspace);
  Workspace.openURL(URL);
end;
于 2016-02-07T09:41:59.717 回答
0
_system(PAnsiChar('open ' + AnsiString(sCommand)));

如果 URL 字符串 ( sCommand) 包含 & 字符 ( &) 则不起作用,这是在查询字符串中指定许多参数所必需的。

发送到 def 的 URL。OSX (Safari) 中的浏览器在第一次出现&.

于 2015-07-06T07:57:04.350 回答
0
LEncodedString : String;

begin
    LEncodedString := TIdURI.URLEncode('http://www.malcolmgroves.com');
    sharedApplication.openURL(StringToNSURL(LEncodedString));
end;
于 2016-12-28T15:17:11.207 回答