1

在使用 Google Map API for Delphi 创建标记时,我注意到一些奇怪的行为。我可以很容易地重现该问题,但没有任何解释。

在下面的代码中,您将看到一个 CreatePoint 方法,我在 TButton 的 OnClick 事件中调用该方法。标记按应有的方式创建。

但随后我在 IdHTTPServer 的 OnCommandGet 事件中使用相同的参数调用 SAME createpoint 方法。然后我使用 Curl 触发事件。但是随后没有创建标记,我收到消息:“模块'mshtml.dll'中地址5548985C的访问冲突。读取地址00000144”

我不明白为什么这会产生不同的结果。任何想法 ?

我使用的是 Delphi XE,所以我在运行时创建了 TWebBrowser(因为它不在 XE 的工具面板中)。

代码如下,示例项目可以在这里下载。

    unit main;

    interface

    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, IdBaseComponent, IdComponent, IdCustomTCPServer, IdCustomHTTPServer,
      IdHTTPServer, GMClasses, GMMap, GMMapVCL, ExtCtrls,
      OleCtrls, SHDocVw, StdCtrls, GMLinkedComponents, GMMarker, GMMarkerVCL,
      GMConstants, IdContext;

    type
      DeviceRange = 0..15;

      TModWallyForm = class(TForm)
        Panel1: TPanel;
        GMMap1: TGMMap;
        IdHTTPServer1: TIdHTTPServer;
        GMMarker1: TGMMarker;
        Button4: TButton;
        procedure FormCreate(Sender: TObject);
        procedure GMMap1AfterPageLoaded(Sender: TObject; First: Boolean);
        procedure Button4Click(Sender: TObject);
        procedure IdHTTPServer1CommandGet(AContext: TIdContext;
          ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
      private
        { Private declarations }
        WebBrowser1 : TWebBrowser;
        Marker : TGMMarker;
        procedure CreatePoint(DeviceID : String; Longitude, Latitude : Real);
      public
        { Public declarations }
      end;

    var
      ModWallyForm: TModWallyForm;

    implementation

    {$R *.dfm}

    procedure TModWallyForm.FormCreate(Sender: TObject);
    var
      i : Integer;
    begin
      WebBrowser1 := TWebBrowser.Create(Panel1);
      TControl(WebBrowser1).Parent := Panel1;
      WebBrowser1.Align := alClient;
      GMMap1.WebBrowser := WebBrowser1;
      // Instantiate Markers
      Marker := TGMMarker.Create(nil);
      Marker.Map := GMMap1;
      IdHTTPServer1.Active := True;
    end;

    procedure TModWallyForm.GMMap1AfterPageLoaded(Sender: TObject; First: Boolean);
    begin
      if First then
      begin
        GMMap1.DoMap;
      end;
    end;

    procedure TModWallyForm.Button4Click(Sender: TObject);
    begin
      CreatePoint('15',4.77,50.55900);
    end;

    procedure TModWallyForm.IdHTTPServer1CommandGet(AContext: TIdContext;
      ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
    begin
      CreatePoint('15',4.77,50.55900);
    end;

    procedure TModWallyForm.CreatePoint(DeviceID: string; Longitude: Real; Latitude: Real);
    begin
      with Marker.Add(Latitude, Longitude) do
        begin
          MarkerType := mtColored;
          InfoWindow.HTMLContent := DeviceID;
          ColoredMarker.Width := 48+(Index*20);
          ColoredMarker.Height := 48;
          ColoredMarker.PrimaryColor := clBlack;
          ColoredMarker.StrokeColor := clBlack;
          Title := '';  // Avoid showing the title when the mouse hovers over the marker
        end;
      GMMap1.RequiredProp.Center.Lat := Latitude;
      GMMap1.RequiredProp.Center.Lng := Longitude;
      GMMap1.RequiredProp.Zoom := 8;
    end;

    end.
4

2 回答 2

0

我做了一些测试,当尝试从加载的 HTML 页面执行 JavaScript 函数时,我看到 AV 被引发。组件的代码是这样的

function TGMMap.ExecuteScript(NameFunct, Params: string): Boolean;
var
  Doc2: IHTMLDocument2;
  Win2: IHTMLWindow2;
begin
  Result := Check;

  if not (FWebBrowser is TWebBrowser) then Exit;

  if not Result then Exit;

  Doc2 := TWebBrowser(FWebBrowser).Document as IHTMLDocument2;
  Win2 := Doc2.parentWindow;  // <==== FAIL ON THIS LINE

  Win2.execScript(NameFunct + '(' + Params + ')', 'JavaScript');

  if MapIsNull then
    raise Exception.Create(GetTranslateText('El mapa todavía no ha sido creado',     Language));
end;

我也做了一个没有任何 GMLib 组件的测试,只有一个 TWebBrowser(是的,它存在于 XE 中;-)),一个“做地图”的按钮和一个 IdHTTPServer 来创建具有相同结果的标记。

为此,我推断问题不在于 GMLib 组件。您可以从这里下载演示。

于 2013-11-28T06:43:37.460 回答
0

确保在 OnCommandGet 之前调用了您的构造函数(TModWallyForm.FormCreate),否则您的“Marker”为 nil

于 2013-11-27T11:01:26.240 回答