2012-03-01 9 views
9

Kullanıcıların Google Haritalar'ı kullanmasına izin veren bir delphi sistemi oluşturmaya çalışıyorum. Her şey iyi çalışıyor, ancak her yeni bir TWebBrowser nesnesi oluşturulduğunda ve Google Haritalar'ı işleyen javascript'in yüklendiğini fark ettim, bir dizi yeni Threads oluşturuldu.Delphi'de Javascript TWebBrowser, Kapanış Konuları

Benim sorunum, web tarayıcısı bir kez imha edildiğinde (ve kesinlikle yok edildiğinde) oluşturulan parçacıkların devam etmesidir. Bu programı uzun çalışma sürelerine ve google haritalarının açılıp kapanmasına birçok kez ulaşacak şekilde tasarlıyorum ve bir süre sonra, çok fazla iş parçacığı oluşturuldu ve programın yavaş yavaş yavaşladığı gibi sonlanmadı.

Bu konuları imha etmenin bir yolu var mı, yoksa iş parçacığının kalmasına neden olan yanlış bir şey mi yapıyorum?

Aşağıdaki kod kapalı programımı dayandırarak: blank:

const 
HTMLStr: AnsiString = 
'<html> '+  
'<head> '+ 
'<meta name="viewport" content="initial-scale=1.0, user-scalable=yes" /> '+ 
'<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true">  </script> '+ 
'<script type="text/javascript"> '+ 
''+ 
''+ 
' var geocoder; '+ 
' var map; '+ 
' var trafficLayer;'+ 
' var bikeLayer;'+ 
' var markersArray = [];'+ 
''+ 
''+ 
' function initialize() { '+ 
' geocoder = new google.maps.Geocoder();'+ 
' var latlng = new google.maps.LatLng(40.714776,-74.019213); '+ 
' var myOptions = { '+ 
'  zoom: 13, '+ 
'  center: latlng, '+ 
'  mapTypeId: google.maps.MapTypeId.ROADMAP '+ 
' }; '+ 
' map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); '+ 
' trafficLayer = new google.maps.TrafficLayer();'+ 
' bikeLayer = new google.maps.BicyclingLayer();'+ 
' map.set("streetViewControl", false);'+ 
' } '+ 
''+ 
''+ 
' function codeAddress(address) { '+ 
' if (geocoder) {'+ 
'  geocoder.geocode({ address: address}, function(results, status) { '+ 
'  if (status == google.maps.GeocoderStatus.OK) {'+ 
'   map.setCenter(results[0].geometry.location);'+ 
'   PutMarker(results[0].geometry.location.lat(),  results[0].geometry.location.lng(),  results[0].geometry.location.lat()+","+results[0].geometry.location.lng());'+ 
'  } else {'+ 
'   alert("Geocode was not successful for the following reason: " + status);'+ 
'  }'+ 
'  });'+ 
' }'+ 
' }'+ 
''+ 
''+ 
' function GotoLatLng(Lat, Lang) { '+ 
' var latlng = new google.maps.LatLng(Lat,Lang);'+ 
' map.setCenter(latlng);'+ 
' PutMarker(Lat, Lang, Lat+","+Lang);'+ 
' }'+ 
''+ 
''+ 
'function ClearMarkers() { '+ 
' if (markersArray) {  '+ 
' for (i in markersArray) { '+ 
'  markersArray[i].setMap(null); '+ 
' } '+ 
' } '+ 
'} '+ 
''+ 
' function PutMarker(Lat, Lang, Msg) { '+ 
' var latlng = new google.maps.LatLng(Lat,Lang);'+ 
' var marker = new google.maps.Marker({'+ 
'  position: latlng, '+ 
'  map: map,'+ 
'  title: Msg+" ("+Lat+","+Lang+")"'+ 
' });'+ 
' markersArray.push(marker); '+ 
' }'+ 
''+ 
''+ 
' function TrafficOn() { trafficLayer.setMap(map); }'+ 
''+ 
' function TrafficOff() { trafficLayer.setMap(null); }'+ 
''+''+ 
' function BicyclingOn() { bikeLayer.setMap(map); }'+ 
''+ 
' function BicyclingOff(){ bikeLayer.setMap(null);}'+ 
''+ 
' function StreetViewOn() { map.set("streetViewControl", true); }'+ 
''+ 
' function StreetViewOff() { map.set("streetViewControl", false); }'+ 
''+ 
''+'</script> '+ 
'</head> '+ 
'<body onload="initialize()"> '+ 
' <div id="map_canvas" style="width:100%; height:100%"></div> '+ 
'</body> '+ 
'</html> '; 


procedure TfrmMain.FormCreate(Sender: TObject); 
var 
    aStream  : TMemoryStream; 
begin 
    WebBrowser1.Navigate('about:blank'); 
    if Assigned(WebBrowser1.Document) then 
    begin 
     aStream := TMemoryStream.Create; 
     try 
    aStream.WriteBuffer(Pointer(HTMLStr)^, Length(HTMLStr)); 
    //aStream.Write(HTMLStr[1], Length(HTMLStr)); 
    aStream.Seek(0, soFromBeginning); 
    (WebBrowser1.Document as IPersistStreamInit).Load(TStreamAdapter.Create(aStream)); 
    finally 
    aStream.Free; 
    end; 
    HTMLWindow2 := (WebBrowser1.Document as IHTMLDocument2).parentWindow; 

end; 
end; 


procedure TfrmMain.ButtonGotoLocationClick(Sender: TObject); 
begin 
    HTMLWindow2.execScript(Format('GotoLatLng(%s,%s)',[Latitude.Text,Longitude.Text]),   'JavaScript'); 
end; 

procedure TfrmMain.ButtonClearMarkersClick(Sender: TObject); 
begin 
    HTMLWindow2.execScript('ClearMarkers()', 'JavaScript') 
end; 

procedure TfrmMain.ButtonGotoAddressClick(Sender: TObject); 
var 
    address : string; 
begin 
    address := MemoAddress.Lines.Text; 
    address := StringReplace(StringReplace(Trim(address), #13, ' ', [rfReplaceAll]), #10, ' ' , [rfReplaceAll]); 
    HTMLWindow2.execScript(Format('codeAddress(%s)',[QuotedStr(address)]),  'JavaScript'); 
end; 

procedure TfrmMain.CheckBoxStreeViewClick(Sender: TObject); 
begin 
    if CheckBoxStreeView.Checked then 
    HTMLWindow2.execScript('StreetViewOn()', 'JavaScript') 
    else 
    HTMLWindow2.execScript('StreetViewOff()', 'JavaScript'); 

end; 

procedure TfrmMain.CheckBoxBicyclingClick(Sender: TObject); 
begin 
    if CheckBoxBicycling.Checked then 
    HTMLWindow2.execScript('BicyclingOn()', 'JavaScript') 
    else 
    HTMLWindow2.execScript('BicyclingOff()', 'JavaScript'); 
end; 


procedure TfrmMain.CheckBoxTrafficClick(Sender: TObject); 
begin 
    if CheckBoxTraffic.Checked then 
    HTMLWindow2.execScript('TrafficOn()', 'JavaScript') 
    else 
    HTMLWindow2.execScript('TrafficOff()', 'JavaScript'); 
end; 


end. 

Programı yaklaşık gitmek için HTMLWindow ayarlayan bir temel yıkıcı kullanır. Şimdiden teşekkürler.

+0

Web tarayıcısını nerede ve nasıl yok ediyorsunuz? – GolezTrol

+0

Webbrowser, bir ana TForm tarafından işlenen bir TForm üzerine oturur, Çocuk TForm'unu imha ederim ve aşağıdaki yıkıcı kodunu kullanıyorum: 'yıkıcı TGoogleMap.Destroy; başlamak HTMLWindow2.navigate ('about: blank'); HTMLWindow2: = nil; WebBrowser1.DestroyComponents; WebBrowser1.Destroy; kalıtsal sonu; ' – user1242937

+4

Başlamak için' yıkıcınızın 'hiç gerekli değildir. Orada büyük bir salata yapıyorsun. sahip formu, TWebBrowser’in kendisini serbest bırakacaktır. – kobik

cevap

2

Bu soruya cevap vermiyor, sadece simüle edilecek sorunu basitleştiriyor.

Her düğme tıklatıldıktan sonra kaç iş parçacığının çalıştığını görün. Simple Google Maps example kullanır, bu nedenle sorun javascript parçanızda bile değil.

Birimini1 - OnClick olay işleyicisi ile sadece bir butona ana formu içerir

unit Unit1; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls, PsAPI, TlHelp32, Unit2; 

type 
    TForm1 = class(TForm) 
    Button1: TButton; 
    procedure Button1Click(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

function GetThreadCount(const APID: Cardinal): Integer; 
var 
    NextProc: Boolean; 
    ProcHandle: THandle; 
    ThreadEntry: TThreadEntry32; 
begin 
    Result := 0; 
    ProcHandle := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); 
    if (ProcHandle <> INVALID_HANDLE_VALUE) then 
    try 
    ThreadEntry.dwSize := SizeOf(ThreadEntry); 
    NextProc := Thread32First(ProcHandle, ThreadEntry); 
    while NextProc do 
    begin 
     if ThreadEntry.th32OwnerProcessID = APID then 
     Inc(Result); 
     NextProc := Thread32Next(ProcHandle, ThreadEntry); 
    end; 
    finally 
    CloseHandle(ProcHandle); 
    end; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
var 
    ModalForm: TForm2; 
begin 
    ModalForm := TForm2.Create(nil); 
    try 
    ModalForm.ShowModal; 
    finally 
    ModalForm.Free; 
    end; 
    ShowMessage('Thread count: ' + 
    IntToStr(GetThreadCount(GetCurrentProcessId))); 
end; 

end. 

baskısı2 - Üzerinde TWebBrowser ve formun OnCreate olay işleyicisi ile form içeren

unit Unit2; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls, OleCtrls, SHDocVw, ActiveX; 

type 
    TForm2 = class(TForm) 
    WebBrowser1: TWebBrowser; 
    procedure FormCreate(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

var 
    Form2: TForm2; 

implementation 

{$R *.dfm} 

const 
    HTMLString: AnsiString = 
    '<!DOCTYPE html>' + 
    '<html>' + 
    ' <head>' + 
    ' <title>Google Maps JavaScript API v3 Example: Map Simple</title>' + 
    ' <meta name="viewport"' + 
    '  content="width=device-width, initial-scale=1.0, user-scalable=no">' + 
    ' <meta charset="UTF-8">' + 
    ' <style type="text/css">' + 
    '  html, body, #map_canvas {' + 
    '  margin: 0;' + 
    '  padding: 0;' + 
    '  height: 100%;' + 
    '  }' + 
    ' </style>' + 
    ' <script type="text/javascript"' + 
    '  src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>' + 
    ' <script type="text/javascript">' + 
    '  var map;' + 
    '  function initialize() {' + 
    '  var myOptions = {' + 
    '   zoom: 8,' + 
    '   center: new google.maps.LatLng(-34.397, 150.644),' + 
    '   mapTypeId: google.maps.MapTypeId.ROADMAP' + 
    '  };' + 
    '  map = new google.maps.Map(document.getElementById(''map_canvas''),' + 
    '   myOptions);' + 
    '  }' + 
    '  google.maps.event.addDomListener(window, ''load'', initialize);' + 
    ' </script>' + 
    ' </head>' + 
    ' <body>' + 
    ' <div id="map_canvas"></div>' + 
    ' </body>' + 
    '</html>'; 

procedure TForm2.FormCreate(Sender: TObject); 
var 
    HTMLStream: TMemoryStream; 
begin 
    WebBrowser1.Navigate('about:blank'); 
    if Assigned(WebBrowser1.Document) then 
    begin 
    HTMLStream := TMemoryStream.Create; 
    try 
     HTMLStream.WriteBuffer(Pointer(HTMLString)^, Length(HTMLString)); 
     HTMLStream.Seek(0, soFromBeginning); 
     (WebBrowser1.Document as IPersistStreamInit).Load(TStreamAdapter.Create(HTMLStream)); 
    finally 
     HTMLStream.Free; 
    end; 
    end; 
end; 

end. 
+0

Sorun, GoogleMaps'in sitesiyle ilişkili veya herhangi bir sayfada TWebBrowser sızıntısını yükledi? – EMBarbosa

+1

@EMBarbosa, bazı sayfalarda olur, ancak hepsi için değil. Yani sadece GoogleMaps ile ilgili değil. – TLama