如何在OTA包向导内让欢迎页面浏览器导航到某个URI?

10
我想做的是创建一种能够查看(而不是编辑)项目中包含的HTML页面的能力。欢迎页已经嵌入了Web浏览器,因此它似乎是一个很好的选择。
为什么这样做呢?这里有一个带有背景信息的问题

大家好,感谢你们对这个问题的贡献!很抱歉让你们久等了,目前我有些工作上的事情需要处理,但是我真的希望能在明天完成,并且根据你们的想法采取一些措施来恢复受损 IDE 中的项目页面选项功能。 - OnTheFly
3个回答

26

以下是我为您特别制作的解决方案...

在此输入图片描述

这里下载源代码,然后在Delphi中加载该包(我是在Delphi XE中制作的,但它也可以在任何版本中加载!不过,在XE之前的版本中,您需要更改“项目选项”中的“单元输出路径”)... 然后安装这个包。

在帮助菜单中找到创建浏览器并单击它。然后会创建并显示一个选项卡,该选项卡导航到我的博客(只是为了示例而已)。

您可以轻松修改此选项卡以适应自己的需求!帮助菜单项代码位于EditWizard.MenuItem.pas中,可以忽略!请注意,当单击时它调用的是 (BorlandIDEServices as IOTAEditorViewServices).ShowEditorView(CreateTab('http://www.simonjstuart.com'));,这实际上是创建浏览器选项卡实例的代码!

所有与浏览器选项卡有关的代码(包括其框架布局)都包含在EditorWizard.Frame.pas中,这使得对其进行修改以适应自己的需求变得非常容易!

单元EditorWizard.Wizard.pas包含了注册自定义浏览器选项卡到IDE所需的少量代码。

当然,您需要进行一些微调,但这肯定可以作为您尝试实现的非常可接受的基础。

享受吧 :)


2
顺便说一下:你的问题(以及我制作这个解决方案的工作)给了我一个很好的想法!我将制作一个免费(可再分发的)插件,提供一个编辑器选项卡式的Chromium浏览器,其他插件可以非常容易地调用它来显示他们需要的任何内容(原始HTML、网页、文档站点等)。 - LaKraven
1
请注意,这不是欢迎页面(我对带有多个嵌入式Web浏览器的IDE的稳定性有疑虑),但它确实回答了将框架注册为选项卡式EditWindows页面的部分(请参见我对Remy Lebeau答案的评论)。 - OnTheFly
1
你的问题并没有明确规定必须使用欢迎页面浏览器。 - LaKraven
1
很好的简单示例,但问题特别涉及欢迎页面浏览器:“我如何从OTA包向导内部让欢迎页面浏览器导航到某个URI?”如果不是这样,我会提供类似于您的答案。 - Ondrej Kelle
1
@LaKraven 谢谢,正如我所说,我真的很喜欢你的样例!(欢迎页面浏览器似乎也使用了相同的技术!)我只是认为问题特别询问了欢迎页面浏览器,所以不幸的是,除非像我的那种黑客或类似的东西,否则这是不可能的。无论如何,让 OP 决定哪个答案最适合他。 - Ondrej Kelle
显示剩余2条评论

8
如果你想使用这样的hack:
type
  TOpenNewURLModule = procedure(const URL: string; EditorForm: TCustomForm);

procedure OpenURL(const URL: string);
var
  EditWindow: INTAEditWindow;
  Lib: HMODULE;
  OpenNewURLModule: TOpenNewURLModule;
begin
  EditWindow := (BorlandIDEServices as INTAEditorServices).TopEditWindow;
  if not Assigned(EditWindow) or not Assigned(EditWindow.Form) then
    Exit;

  Lib := GetModuleHandle('startpageide150.bpl');
  if Lib = 0 then
    Exit;
  OpenNewURLModule := GetProcAddress(Lib, '@Urlmodule@OpenNewURLModule$qqrx20System@UnicodeStringp22Editorform@TEditWindow');
  if @OpenNewURLModule <> nil then
    OpenNewURLModule(URL, EditWindow.Form);
end;

缺点:

  • 这是一个hack(startpageidexx.bpl未通过API或文档公开)
  • 它是为Delphi XE硬编码的(其他版本需要不同的文件名,方法签名也可能不同,例如在旧的AnsiString版本中)
  • 如果没有编辑窗口,则它什么也不做(至少必须有一个打开的模块)
  • 它总是打开一个新的浏览器视图

编辑:似乎可以重用现有的打开的欢迎页面,并且使此hack与旧版Delphi兼容。以下显示了两个替代方案,Delphi XE和Delphi 2007(两者似乎都可以工作):

type
  IURLModule = interface(IOTAModuleData)
  ['{9D215B02-6073-45DC-B007-1A2DBCE2D693}']
    function GetURL: string;
    procedure SetURL(const URL: string);
    property URL: string read GetURL write SetURL;
  end;
  TOpenNewURLModule = procedure(const URL: string; EditorForm: TCustomForm);

function FindURLModule: IURLModule;
var
  I: Integer;
begin
  Result := nil;
  with BorlandIDEServices as IOTAModuleServices do
    for I := 0 to ModuleCount - 1 do
      if Supports(Modules[I], IURLModule, Result) then
        Break;
end;

procedure OpenURL(const URL: string; ReuseExistingView: Boolean = True);
{$IFDEF VER220} // Delphi XE
const
  SStartPageIDE = 'startpageide150.bpl';
  SOpenNewURLModule = '@Urlmodule@OpenNewURLModule$qqrx20System@UnicodeStringp22Editorform@TEditWindow';
{$ENDIF}
{$IFDEF VER185} // Delphi 2007
const
  SStartPageIDE = 'startpageide100.bpl';
  SOpenNewURLModule = '@Urlmodule@OpenNewURLModule$qqrx17System@AnsiStringp22Editorform@TEditWindow';
{$ENDIF}
var
  Module: IURLModule;
  EditWindow: INTAEditWindow;
  Lib: HMODULE;
  OpenNewURLModule: TOpenNewURLModule;
begin
  EditWindow := nil;
  Module := nil;
  if ReuseExistingView then
    Module := FindURLModule;
  if Assigned(Module) then
  begin
    Module.URL := URL;
    (Module as IOTAModule).Show;
  end
  else
  begin
{$IFDEF VER220}
    EditWindow := (BorlandIDEServices as INTAEditorServices).TopEditWindow;
{$ENDIF}
{$IFDEF VER185}
  if Assigned((BorlandIDEServices as IOTAEditorServices).TopView) then
    EditWindow := (BorlandIDEServices as IOTAEditorServices).TopView.GetEditWindow;
{$ENDIF}
    if not Assigned(EditWindow) or not Assigned(EditWindow.Form) then
      Exit;
    Lib := GetModuleHandle(SStartPageIDE);
    if Lib = 0 then
      Exit;

    OpenNewURLModule := GetProcAddress(Lib, SOpenNewURLModule);
    if @OpenNewURLModule <> nil then
      OpenNewURLModule(URL, EditWindow.Form);
  end;
end;

剩余的不足之处:

  • 它仍然是一个hack
  • 它仍然是硬编码的,适用于Delphi XE(Unicode)和Delphi 2007(ANSI)
  • 如果没有编辑窗口,它仍然无法执行任何操作

如果您需要兼容其他版本,也许可以将此作为起点。


1
注意,我在使用包 DLL 中的函数进行早期绑定方面取得了一定的成功,例如:function KeyCodeToShortCut(KeyCode: Integer): TShortCut; overload; register; external 'coreide70.bpl' name '@Vedtypes@KeyCodeToShortCut$qqri';。只有当我们能从 .bpl 重构出 .dcp 时,我们才能将它们用作包(再见,基于版本号的分支)... - OnTheFly
是的,拥有 .dcp 文件将会非常棒! - Ondrej Kelle
不好意思,抱歉耽误了 :-) 我并没有预料到赏金会为这个问题带来新的东西,所以也没有安排时间来分析提出的解决方案。请问您是如何找出 IURLModule 接口结构的呢? - OnTheFly
2
我已经记不清细节了,但是我从(IOTAModule as TObject).ClassName开始,然后使用GetProcAddress(lib, '@unitname@classname@')获取类引用,再通过RTTI遍历祖先,获取实现的接口列表(GUID也存储在RTTI中)。当然,还有依赖项查看器和tdump startide150.bpl - Ondrej Kelle

3

最好使用带有TWebBrowser组件的自己的TForm来显示,您可以将HTML加载到其中。


当然,怎么做呢?TForm无法作为IDE选项卡进行托管。请具体说明。 - OnTheFly
OTA插件可以向IDE添加对话框,或者仅显示自己的浮动窗口。 - Remy Lebeau
1
在我看来,对于停靠布局而言,浮动窗口完全没有用处。我该如何将“页面”添加到“EditWindows”的选项卡界面中? - OnTheFly
@user539484,我会为您提供一个带有浏览器的编辑器停靠表格,让您在其上进行开发。实际上,这比您想象的要简单得多...但我们无法在此处记录太多细节!请稍等,大约一个小时左右我会提供解决方案。 - LaKraven

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接