Hexagon Geospatial
MENU

GeoMedia

Search for an answer, post a question, or answer other users' questions in our GeoMedia support discussions. This discussion board is a great way to collaborate with industry peers around the world. It is intended for discussion and support of the GeoMedia Desktop and Add-on applications.
Showing results for 
Search instead for 
Do you mean 
Reply
Highlighted
Contributor
Posts: 79
Registered: ‎05-30-2016
Accepted Solution

How to programmatically insert an image into a SmartFrame2d on Layout Window

I've determined through debugging that when you copy/paste an image into the layout window it is created as a SmartFrame2d object with no attribute sets. The same occurs if you have a Legend frame and you run the 'Convert to Graphics' command. 

 

However, the question is how to do that programmatically? I assume one needs to use a CreateEmbed command, but how?

Technical Evangelist
Posts: 531
Registered: ‎09-11-2015

Re: How to programmatically insert an image into a SmartFrame2d on Layout Window

These are basically two different questions. To insert an image, you can use either CreateEmbed or CreateLink method, specifying the file name of the image. The ability of GeoMedia to display the image depends on whether there is an OLE server for given image type registered in the system. This is usually true for .bmp and .jpg, but may not be true for .gif or .png. To display any file, an application must be installed and associated with the file extension, and the application must be so called OLE server. Typically, if you install MS Office, you have installed OLE server for .doc and .xls files, so you can embed such files in the SmartFrame2d object.

 

To insert a Legend, you can either use CreateEmbed method with appropriate Legend string and attributes, or use LayoutWindowPlacementService object. I think the latter one is obsolete.

 

Pavel

Contributor
Posts: 79
Registered: ‎05-30-2016

Re: How to programmatically insert an image into a SmartFrame2d on Layout Window

So, in a copy/paste operation there is no file name. Do you have to save it from memory after retrieving it from the clipboard, to a file and then embed it? If that's the case does GeoMedia save them somewhere in order to support this? If so, could they be deleted after embedding, or does the frame still need them each time the sheet is loaded into the layout window?

Technical Evangelist
Posts: 531
Registered: ‎09-11-2015

Re: How to programmatically insert an image into a SmartFrame2d on Layout Window

 I din't realize that you want to programmatically control the clipoboard and display its content in the layout window. I am just a bit curious why you would like to do that.

 

Anyway, I have no idea how GeoMedia accomplishes that and I am afraid that this is out of the scope of this forum. Just a quick look shows that there is Win32 API for manipulating clipboard and then each programing language, like C++ with MFC, C#, VB, Java ... has their own dedicated objects for manipulating clipoboard. Some of them can probably create an OLE link to the clipboard content, but ... as I said, it depends on what tool you want to use and what actually do you want to achieve. Of course, saving the clipboard content to a temporary file and then link that file would be the first solution. But in this case, you should not delete the file, if you open it with CreateLink. If you use CreateEmbed, you possibly could delete the file afterwards and you could even save the geoworkspace. But in this case the gws file would grow by the image size.

 

Well, this is really quite complex topic.

 

Pavel

Anonymous
Posts: 0

Re: How to programmatically insert an image into a SmartFrame2d on Layout Window

Hi,

 

If you mean an image such as an existing .png file or a .bmp file, etc., I have successfully gotten this to work with a .bmp file.  You create a Smartframe in you Layout Window for the Bitmap object and then call the CreateEmbed method with the name of the bitmap file.  Here is what worked for me and what I have passed on to a customer:

 

 

Here is sample VB.NET code:

 

       'Add a SmartFrame to the sheet

        objSF = objSheet.SmartFrames2d.AddBy2Points("GMLayoutMapview", 0.018, 0.0145, 0.4, 0.4) 

        objSF.BorderVisible = True

 

        'Test using CreateEmbed to place a bitmap in the Layout Window

        Dim strbitmap As String = "c:\image.bmp"

        objSF.CreateEmbed(strbitmap)

 

Hope this helps.

 

Kind Regards,

 

Carolyn

 

 

Contributor
Posts: 79
Registered: ‎05-30-2016

Re: How to programmatically insert an image into a SmartFrame2d on Layout Window

I've confirmed this works... mostly.

 

Here's what works:

  • bmp is displayed in a frame
  • sheet can be exported, deleted and imported back in, even after the bmp file is deleted

 

Issues:

  • it's created in a GMLayoutMapView style type frame, so when you import the sheet you get a warning dialog that it was created with a map that no longer exists. It thinks it is a map frame.

 

I tried creating my own style, rather than using one of the GMLayout... styles, but that fails on AddBy2Points. I realize now the style must indicate some kinda ole server or method of an ole server, not sure.

 

Anyway, the copy/paste operation, does not create frames with those style types. It creates a frame with a style type of 'Office Automation', so I tried that and that works, but... can I depend on that existing?

 

I don't have Office installed on the workstation I am testing from, and it works, so perhaps, yes. The embedded type is indicated as 'Paint'. I think that exists on all Windows editions, although I don't know if it is an ole server on all editions. I assume the frame requires an ole server object to render the content. I wonder if newer editions might be upgraded and no longer support ole??  

 

And, even if it is, what if the file extension is registered to an app, say some image editor tool, that is not an ole server? Maybe this doesn't matter as we are specifiying 'Office Automation'?? Seems rather fragile if that were the case.

 

Lots of things to test.

 

Thanks for your help on this Carolyn and Pavel.

Technical Evangelist
Posts: 531
Registered: ‎09-11-2015

Re: How to programmatically insert an image into a SmartFrame2d on Layout Window

Hi, after some long time I came back to this issue. Here is a code which works for me, the only drawback is that it temporarily opens the MS Paint window.

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Threading;

using GeoMedia = Intergraph.GeoMedia.GeoMedia;
using GMLayout = Intergraph.GeoMedia.GMLayout;

public partial class frmLyoutImage : Form
{
    private GeoMedia.Application m_pApp;

    public frmLyoutImage(GeoMedia.Application pApp)
    {
        InitializeComponent();
        m_pApp = pApp;
        SetupSheets();
    }

    private GeoMedia.LayoutWindow GetLayoutWnd()
    {
        GeoMedia.Document objDoc = m_pApp.Document as GeoMedia.Document;
        GeoMedia.Windows objWnds = objDoc.Windows as GeoMedia.Windows;
        Marshal.ReleaseComObject(objDoc);

        GeoMedia.LayoutWindow objRes = null;
        object obj;
        int i = 1;
        bool bFound = false;
        while(!bFound && (i <= objWnds.Count))
        {
            obj = objWnds.Item(i++);
            bFound = (obj.GetType().InvokeMember("Type", System.Reflection.BindingFlags.GetProperty, null, obj, null).ToString()
                == "LayoutWindow");
            if (bFound) objRes = obj as GeoMedia.LayoutWindow;
            else Marshal.ReleaseComObject(obj);
        }

        return objRes;
    }

    private void button3_Click(object sender, EventArgs e)
    {
        GeoMedia.LayoutWindow objLW = GetLayoutWnd();

        if (objLW == null)
        {
            textBox1.Text = "No layout window found";
            return;
        }

        string sImgPath = @"C:\Users\pavel\Documents\UserData\INGR AT\LayoutJpeg\engine.jpg";

        Process paintProc = new Process();
        paintProc.StartInfo.CreateNoWindow = true;
        paintProc.StartInfo.FileName = @"C:\Windows\System32\mspaint.exe";
        paintProc.StartInfo.Arguments = string.Format("\"{0}\"", sImgPath);
        paintProc.StartInfo.UseShellExecute = false;
        paintProc.Start();
        Thread.Sleep(1000);
        paintProc.WaitForInputIdle();

        GMLayout.Application objLayout = objLW.LayoutView as GMLayout.Application;

        GMLayout.SmartFrame2dStyles objStyles = objLayout.SmartFrame2dStyles;
        int i = 1;
        bool bFound = false;
        GMLayout.SmartFrame2dStyle objStyle;
        while(!bFound && (i <= objStyles.Count))
        {
            objStyle = objStyles.Item[i++];
            bFound = objStyle.Name == "Office Automation";
            Marshal.ReleaseComObject(objStyle);
        }

        if(!bFound)
        {
            objStyle = objStyles.Add("Office Automation", "");
            objStyle.BorderColor = GMLayout.ColorConstants.igBlackColor;
            objStyle.BorderDashTypeName = "";
            objStyle.BorderPrinted = true;
            objStyle.BorderVisible = true;
            objStyle.BorderWidth = 0.00035;
            objStyle.CropByFrameDimensionsAllowed = true;
            objStyle.CropByHandleAllowed = true;
            objStyle.CropByObjectDimensionsAllowed = true;
            objStyle.LocateChildren = false;
            objStyle.MoveByDragAllowed = true;
            objStyle.MoveByOffsetAllowed = true;
            objStyle.NonProportionalScalingAllowed = true;
            objStyle.Printed = true;
            objStyle.ProtectFromSelection = false;
            objStyle.RotateByHandleAllowed = true;
            objStyle.RotateByKeyinAllowed = true;
            objStyle.Rotation = 0.0;
            objStyle.ScaleByHandleAllowed = true;
            objStyle.ScaleByKeyinAllowed = true;
            objStyle.ScaleFactor = 0.0;
            objStyle.ShapeOption = GMLayout.FrameShapeConstants.igRectangularFrame;
            objStyle.SizeMode = GMLayout.SizeModeConstants.igFrameChangesSize;
            objStyle.UpdateOption = GMLayout.UpdateOptionConstants.igUpdateAutomatic;
            Marshal.ReleaseComObject(objStyle);
        }
        Marshal.ReleaseComObject(objStyles);

        GMLayout.Sheets objShts = objLayout.Sheets;
        GMLayout.Sheet objSht = objShts.Item[1];

        GMLayout.SmartFrame2d objSF = objSht.SmartFrames2d.AddBy2Points("Office Automation", 0.02, 0.08, 0.2, 0.2);
        objSF.CreateEmbed(sImgPath, "Paint"); 
        Marshal.ReleaseComObject(objSF);

        Marshal.ReleaseComObject(objSht);
        Marshal.ReleaseComObject(objShts);
        Marshal.ReleaseComObject(objLayout);
        Marshal.ReleaseComObject(objLW);

        paintProc.Kill();
    }
}

Pavel

Do you need immediate support?
If you encounter a critical issue and need immediate assistance please submit a Service Request through our Support Portal.