Как открыть URL с помощью браузера по умолчанию с кросс-платформенными приложениями FireMonkey? - PullRequest
28 голосов
/ 16 сентября 2011

Обычно я использую: ShellExecute(0, 'OPEN', PChar(edtURL.Text), '', '', SW_SHOWNORMAL);

Как мне вести себя одинаково (открывая ссылку в браузере по умолчанию) на всех платформах (Windows и OSX)?

Ответы [ 8 ]

18 голосов
/ 17 сентября 2011

Что касается ответа 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('/5957416/kak-otkryt-url-s-pomoschy-brauzera-po-umolchaniy-s-kross-platformennymi-prilozheniyami-firemonkey');
13 голосов
/ 16 сентября 2011

В дискуссионном форуме FireMonkey я нашел этот код для вопроса о NSWorkspace.URLForApplicationToOpenURL:

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

(не проверено мной)


Обновление : Posix недоступен в Windows, поэтому невозможно написать решение, использующее одинаковые вызовы ОС на всех платформах. Я предлагаю переместить такой код в центральный модуль «XPlatform», который имеет некоторый IFDEF POSIX и т. Д.

6 голосов
/ 23 августа 2017

Для всех платформ (Windows, MacO, 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.
3 голосов
/ 19 октября 2012

Код XE2 C ++, успешно протестированный (Windows 7 64 и OSX Lion), незначительные улучшения. Слава богу, боль прошла:)

#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
}
1 голос
/ 07 февраля 2016

Как упомянул @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;
1 голос
/ 16 апреля 2012

А теперь версия 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
}
0 голосов
/ 28 декабря 2016
LEncodedString : String;

begin
    LEncodedString := TIdURI.URLEncode('http://www.malcolmgroves.com');
    sharedApplication.openURL(StringToNSURL(LEncodedString));
end;
0 голосов
/ 06 июля 2015
_system(PAnsiChar('open ' + AnsiString(sCommand)));

не работает, если строка URL (sCommand) включает амперсанд и символ (&), необходимые для указания множества аргументов в строке запроса.

URL отправлен в def. браузер в OSX (Safari) усекается при первом появлении &.

...