QldblueQldblue Global Mapper UserPosts: 17
edited March 2012 in SDK
Hi Mike,

A quick question on GM_GetProject and interfacing with Delphi.

To initialise the program I load a single jpg and assign it a projection, then call GM_GetProject to obtain the projection.

I have called the routine with both a record (similar to struct) and a pointer to the record. See Delphi Code Below. Neither works or is close to working, ie. I cannot see the variable making up the record(struct) looking close to being correct. If there is a problem with the record I while debugging I can usually see some of the elements looking OK.

So some brief guidance is need wrt the call, is it a pointer,etc.

When I look at the sample program I see a declaration of theCurProj of type GM_Projection_t and the call is &theCurProj, which I take it to be the address of thecurProj, i.e. a pointer.

// Get the current view projection
GM_Projection_t theCurProj;
GM_Error_t32 theErr = GM_GetProjection( &theCurProj );

I have tried numerous combinations.

The call with a pointer is shown at the bottom. I get GM_Error_None, but the pointer is garbage "inaccessible value"

Thanks mark

{/// This type is used to describe a single projection attribute value }
PGM_ProjAttrValue_t = ^GM_ProjAttrValue_t;
GM_ProjAttrValue_t = record
mValue: Double;
end {GM_ProjAttrValue_t};

{/// This type is used to fully describe a projection. }
PGM_Projection_t = ^GM_Projection_t;
GM_Projection_t = record
mProjSys: PROJSYS;
mDatum: DATUM;
mUnit: GM_UNIT; //Note Unit is a reserved word in Delphi
mNumAttrs: LongWord; // This is an unsigned 32bit
mAttrList: Array [0..15] of GM_PROJATTRVALUE_T;
end {GM_Projection_t};

To ensure I have the correct types I have avoided enumeration types and simply declared a type. You will recognise most of your text.

{/// Enumeration of the projection types. This enumeration is shared by the plugins }
{/// so it is important that the order not change and that new projections be added }
{/// such that the enumerated value of existing projections is not disturbed. }
PROJSYS = type smallint; // Signed 16bit

{/// Enumeration of the unit types. This enumerator is shared by plugins and }
{/// the Global Mapper DLL interface, so it is important that the order does }
{/// not change and that new units are added to the end. }
GM_UNIT = type smallint;

{/// Enumeration of the datum types. This enumeration is shared by the plugins }
{/// so it is important that the order not change and that new datums be added }
{/// to the end (before the interplanetary datums is ok) }
DATUM = type smallint;

{/// Enumeration of projection attribute types. These values are shared with }
{/// the Global Mapper DLL so it is important that their values to not change. }
PROJATTR = type word; //Unsigned 16 bit

{ Code to get and change the projection}
procedure TForm1.Changeprojection1Click(Sender: TObject);
i: GM_Error_t32;
i:= GM_GetProjection(p);
i:= GM_SelectProjection(p1, p);
i:= GM_SetProjection(p1);


  • global_mapperglobal_mapper Administrator Posts: 17,238
    edited March 2012
    I'm not a Delphi programmer, but it looks like your declarations are correct. I think it is the call to GM_GetProjection that is wrong. It does indeed take a pointer to a GM_Projection_t structure, so you have to already have a completely allocated GM_Projection_t structure, then you pass in the address of that so the SDK can fill it in. It looks like you are just creating a pointer to a GM_Projection_t but it doesn't actually point to anything. In C# you would declare a parameter like 'ref GM_Projection_t' and in VB like 'ByRef GM_Projection_t' so that when you pass it the address of the value is passed and not the value itself. I'm guessing there is some equivalent in Delphi.


    Global Mapper Guru
  • QldblueQldblue Global Mapper User Posts: 17
    edited March 2012

    I was able to get it to work and no errors reported but it isn't exactly obvious why it works, something for later.
    Ive tried using all records or all pointers but will always generate errors.

    Thanks again


    procedure TForm1.Changeprojection1Click(Sender: TObject);
    i: GM_Error_t32;
    aproj_existing, aproj_new: GM_PROJECTION_T;
    p, p1: PGM_PROJECTION_T;
    i:= GM_GetProjection(aproj_existing); // Call this with a record
    p:= @aproj_existing;
    i:= GM_SelectProjection(aproj_new, p); // for some reason I need to mix records and pointers
    p1:= @aproj_new;
    i:= GM_SetProjection(p1); // Call this with a pointer
    FirstTimeDraw:= true; // Just redraw the entire screen figure out a smarter draw extent later
    PB_Display.Invalidate; // redraw Screen;
Sign In or Register to comment.