| | doMapPoint 05-14-2007, 04:54 AM Hello,
I'm about to develop an Delphi 5 application using MapPoint 2006.
The problem is that when I close my application, I get an EAccessViolation in Module ole32.dll at 0008D65E, then a message "Runtime error 216 at 00003134".
Does someone of you have the same problem and know how to solve it?
Perhaps I do not close my application correctly... have I to free any objects before closing the application?
What do I have to do before closing my app?
I'm looking forward to get some help...
For your information:
On my form there is a TOlecontainer.
I initialize my application with the following code:
procedure TfrmData2Map.FormActivate(Sender: TObject);
var
vGuid : TGuid;
begin
OleContainer.CreateObject('MapPoint.Map.EU.13', False);
OleContainer.DoVerb(1);
OleContainer.OleObjectInterface.GetUserClassID(vGu id);
FMap := IDispatch(OleContainer.OleObject) as _Map; // global variable of type _Map
mpApplication.Units := geoKm;
end;
Best wishes
Dietmar Wilfried 05-14-2007, 02:04 PM Hi Dietmar,
Runtime error 216 is the same as a General Protection Fault. A GPF is most often caused by writing to something that doesn't belong to you (like a memory or variable overwrite). It can also be a stack error, meaning you write over the bounds of variables placed on the stack.
What if you open your application and close it ? I mean nothing more that a new application that open a map and do nothing ? Do you still have the error ? doMapPoint 05-15-2007, 01:54 AM Hello Wilfried,
I tried only to open and then close my application. The same error occurs.
Now I created a new application only with the OleContainer on the form and loaded MapPoint in it the same way I described in my previous post (without setting mpApplication.Units) It worked without error.
After that I put a MapPoint Application object on the form and the error was there again. It seems to have something to do with the mappoint application object... But why?
Another question is why I need the MP Application object at all? It seems not to be linked to the global FMap variable... So I think setting the mpApplication.Units (for example) has no effect on the FMap object.
Best wishes
Dietmar Wilfried 05-15-2007, 02:51 AM I did a small test (Delphi7) and it works. This is the mappoint unit:
unit uMP;
interface
uses
Controls, Classes, OleCtnrs, MapPoint_TLB;
type
TMP = class
private
FMap: _Map;
OleContainer: TOleContainer;
public
constructor Create(AOwner: TComponent; ParentControl: TWinControl);
destructor Destroy; override;
property Map: _Map read FMap;
end;
implementation
{ TMP }
constructor TMP.Create(AOwner: TComponent; ParentControl: TWinControl);
var
Guid: TGuid;
begin
OleContainer := TOleContainer.create(nil);
OleContainer.Parent := ParentControl;
OleContainer.Align := alClient;
OleContainer.CreateObject('MapPoint.Map.EU.13', False);
OleContainer.DoVerb(1);
OleContainer.OleObjectInterface.GetUserClassID(Gui d);
FMap:= IDispatch(OleContainer.OleObject) as _Map;
FMap.Application.Units := geoKm;
end;
destructor TMP.Destroy;
begin
OleContainer.DestroyObject;
OleContainer.Free;
inherited;
end;
This is the form:
procedure TMain.FormActivate(Sender: TObject);
begin
MP := TMP.Create(Self, MPPanel);
end;
procedure TMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
MP.Free;
end;
So there must be some other difference somewhere. doMapPoint 05-15-2007, 04:11 AM Hello Wilfried,
thanks, your code works!
Do you use MapPoint in every of your application like that?
The only question is if I have to place a separate Application Object (map point application!) on the form... or if it is ok to access the application object by FMap.Application, too.
Regards,
Dietmar Wilfried 05-17-2007, 12:46 PM Hi Dietmar,
FMap.Application is OK. No I have several solutions in Delphi but it is not always the same. I also have a component for MapPoint which I use in a few applications (Delphi 5, but should work in D7+ as well). doMapPoint 05-23-2007, 02:14 AM Hi!
Thanks, now I use such a MapPoint class in my Delphi App. The app now runs stable without errors.
But there is another problem I will tell you now:
In my application there is (simplified for you;-)) a button - when I click this button, Locations are created and it will be zoomed to the Locations. Zooming is visible on the screen (of course). Then I call the SaveAs method.
Now I found out that the Map.SaveAs method doesn't work anymore - the map is simply not saved.
I found out, that, if I place a (MP)Application object from the Delphi Toolbar on the form AND set the MP.FMap to its ActiveMap property AND set mpApplication.AutoConnect to true (in Delphi IDE), the map will be saved:
procedure TMain.FormActivate(Sender: TObject);
begin
MP := TMP.Create(Self, MPPanel);
MP.FMap := mpApplication.ActiveMap; // mpapplication is the object on the form
end;
But doing so, my zooming etc. isn't visible on screen anymore (but zooming etc. has effect on the saved map!).
What I want is to save the map in .ptm file AND see map changes (zooming e.g.) on the screen!
Has someone an idea how to achieve this?
Regards,
Dietmar Wilfried 05-23-2007, 02:05 PM Hi,
I'm not sure I understeand the problem. Can you tell (again) when the SaveAs work and when not ? doMapPoint 05-24-2007, 02:50 AM Ok,
I will try to explain it. I wrote a simplified program. First, look at my code, there are 2 units:
This is the Main Unit (see also the attachment to the post):
unit MainU;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, MapPntU, MapPoint_TLB, OleServer;
type
TForm1 = class(TForm)
pnlMapPoint: TPanel;
Panel1: TPanel;
btnChangeViewAndSave: TButton;
Label1: TLabel;
mpApplication: TApplication;
procedure FormShow(Sender: TObject);
procedure btnChangeViewAndSaveClick(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
MPnt: TMP;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormShow(Sender: TObject);
begin
MPnt := TMP.Create(Self, pnlMapPoint);
// Note: If I set MPnt.FMap to the mpApplication.ActiveMap property, the map
// will be saved. BUT change of view (zooming to Location = London, UK)
// IS NOT visible on screen (in the oleContainer), only in the .ptm file.
// If you remove the following line, change of view IS visible on screen,
// but the map isn't saved. Try it...
MPnt.FMap := mpApplication.ActiveMap;
Self.WindowState := wsMaximized;
end;
procedure TForm1.btnChangeViewAndSaveClick(Sender: TObject);
var
TestLoc: Location;
begin
// Example: Go to a Location and zoom (only to change the view)
// Changing the view is only visible if MPnt.FMap is not set
// to mpApplication.ActiveMap!
TestLoc := MPnt.FMap.GetLocation(51.5000, 0.5000, 0);
TestLoc.GoTo_;
MPnt.FMap.ZoomIn;
MPnt.FMap.ZoomIn;
MPnt.FMap.ZoomIn;
// The map will only be saved if MPnt.FMap is set to mpApplication.ActiveMap!
MPnt.FMap.SaveAs('c:\example_map.ptm', geoFormatMap, true);
end;
end.
This is the unit containing a mapPoint class:
unit MapPntU;
interface
uses MapPoint_TLB, Windows, SysUtils, Classes, Controls, OleServer, OleCtnrs;
type
TMP = class
constructor Create(AOwner: TComponent;ParentControl:TWinControl);
destructor Destroy;
private
OleContainer1: TOleContainer;
locNorthPole:Location;
locSantaCruz:Location; //Center of western hemisphere
Pi, dblHalfEarth, dblQuarterEarth:double;
public
FMap: _Map; // the active map
end;
implementation
constructor TMP.Create(AOwner: TComponent; ParentControl:TWinControl);
var
vGuid: TGuid;
begin;
OleContainer1:=TOleContainer.create(aowner);
OleContainer1.Parent:=ParentControl;
OleContainer1.Align := alClient;
OleContainer1.CreateObject('MapPoint.Map.EU.13',Fa lse);
OleContainer1.DoVerb(1);
OleContainer1.OleObjectInterface.GetUserClassID(vG uid);
FMap:= IDispatch(OleContainer1.OleObject) as _map;
locNorthPole:=fmap.GetLocation(90,0,0);
locSantaCruz:=fmap.GetLocation(0,-90,0);
dblHalfEarth:=fmap.Distance(locNorthPole, fmap.GetLocation(-90, 0,0));
dblQuarterEarth:=dblHalfEarth/2;
Pi:=3.14159265358979;
end;
destructor TMP.Destroy;
begin
FMap:=nil;
OleContainer1.DestroyObject;
end;
end.
So, now I try to explain 2 scenarios:
On the form there is a Map Point Application Object (you get it from the Delpi Toolbar, e.g. under "ActiveX"). It has a AutoConnect property which is set to TRUE.
FIRST scenario:
(In the first scenario the mpApplication object on the form is not needed.)
In the FormShow event procedure there is following line - Remove it! Or comment it out:
// MPnt.FMap := mpApplication.ActiveMap;Then run the app and click on the button. You see that the map zooms to London. But you won't find a saved .ptm file - the map is not saved.
SECOND scenario:
Now we need mpApplication object and the code line you comment out before: We set the MPnt.FMap to the ActiveMap property of our mpApplication object:
MPnt.FMap := mpApplication.ActiveMap; Run the app and click on the button. The map now is saved! You find a .ptm file! But you don't see the change of view on your screen!
(But only if you open the .ptm file with the original Microsoft MapPoint Application, you see that zooming was performed)
I believe that in the SECOND scenario there are two different maps - one in the oleContainer and the other one will be saved. Or not?
I hope you understood the problem. I want to have a saved .ptm file AND see changes of view on my oleContainer!
How can I do that?
Regards
Dietmar Wilfried 05-24-2007, 01:05 PM Hi,
You have 2 instance of MapPoint running (please check in task manager). One because you drop the component on a form and a second one you create yourself.
The problem is that you assign the Activemap from the one to the active map of the other. So what you see is the map from the other application.
So that is wy commenting out the line will let you see the right changes. You can as well remove the component and then check task manager there will be only one instance of MapPoint running.
However I talk a lot because that does not solve the problem wy it is not saved. I will try to try it myself later today if I find some spare time. Wilfried 05-24-2007, 01:51 PM Hi,
I just did try your demo application using Delphi 7. Indeed you have 2 MapPoint instances so that's the reason of view. However I have no idea wy the saveAs not works on the mappoint class.
I just tryed on an older application using a own made component for MapPoint (using Delphi 5) and the SaveAs do not work there also.
Do you really need the SaveAs ? Maybe it is better to save lat/long/alt of the map, including all pushpins etc and reload at next run ? Just a tought as I'm a little out of idea at the moment :( doMapPoint 05-30-2007, 09:40 AM Hi Wilfried,
thanks for your replies. You're right, I've seen in Task Manager two instances of Mappoint.exe.
To your last reply: I need SaveAs, because I want to give a .ptm file to other people that they can open it in their mappoint, so I would be glad if there was a solution to this problem.
But I have read in the MapPoint Help that the SaveAs isn't availible for embedded Maps and the MapPoint control. (From the German help: "Nicht verfügbar für eingebettete Karten und das MapPoint-Steuerelement.").
Does that indicate my problem? Do I have an embedded map?
Best wishes
Dietmar Wilfried 05-30-2007, 12:02 PM Hi,
Aha that explains wy it does not work. Yes you have an embedded map because you embed it into an ole container.
But as always there are workarounds. I have not the time to try this at the moment (sorry for that), but I think it is simple:
When you want to use the saveAs then you open a second MP instance (like you do now, eg with the component). Then put all in there like pushpins, zoom level etc and save it. then close it. Does this short explanation makee sence ?
I mean use the embedded map for view in your application, and use the second instance for the saveAs. Of course you will consume some more RAM. | |