An ordeal of OLE

Source: Internet
Author: User
Tags int size ole

OLE (Object linking and embedding) is a critical technology by Microsoft to carry out its enterprise applications, based on COM It ' s also a quite old one. Despite of its importance, it doesn ' t seem to being so necessary to me as. NET are far more than enough. However in a recent task I has to touch on it.

The task is mainly about enabling the CAD exporting library to export embedded images in addition to linked images which I s supported well is both AutoCAD and the Teigha library underlying our library. After a bit of search online it is discovered that the image embedding in a similar manner to the image linking were not Supporte D or suggested. There is a few solutions/workarounds including

-Using OLE that embodies a paint brush application that includes the image, which are a supported feature by AutoCAD for E Xchanging embedded images.

-Leveraging AutoCAD Raster Design (ARD) that have introduced an iembed command to allow images to be embeddes as they can be linked; However ARD is not part of a normal version of AutoCAD and unlikely can be easily supported by the Teigha library that we is using (however the official AutoCAD secondary development may do)

-An uncofirmed solution proposed by a discussion thread, creates an AutoCAD entity that includes the image data and I s able to externalise it-a temporary file to is referenced by a normal linked image. (needs a bit investigation into what to create an object like that)

Due to the limit of time and resources available, the first option is chosen for the time being, although the third may b e proven the best as OLE was neither stable nor performant when being rendered in the AutoCAD. The development of this task involved a lot of investigation and experimentation and turned off to being purely based on a CO PY of online queries below,

Http://www.dimcax.com/hust/showpost.php?p=18114&postcount=1

The final implemenation mostly matches what's described in the link. It mainly involves in the following steps

-Obtain an COleDataSource object from the image file using certain APIs

-Retrieve COleDataObject from COleDataSource

-Create COleClientItem from COleDataObject

-Put the COleClientItem on clipboard (to mimic, the process of manual copy of image object to AutoCAD)

-Enumerate the binary data items from the Clipboard and pass them as a compound document to Teigha by calling Setcompound Document on its Oddbole2frame object

The link above suggested creating a static OLE data object from COleDataSource would be fine, which I muddled through and Got work with the code below,

The method of creating a compound document for a static OLE object from a picture file void Createstaticolecompounddoc

    Ument () {HANDLE hdibcopy = createdibfrombmp ("C:\\temp\\garbage\\sample.bmp");
    COleDataSource src; Src.

    CacheGlobalData (Cf_dib, hdibcopy); lpDataObject lpdataobject = (lpdataobject) src.

    GetInterface (&iid_idataobject);
    COleDataObject obj; Obj.

    Attach (lpDataObject);
    COleDocument Doc;
    COleClientItem item (&DOC); Item.

    Createstaticfromdata (&obj); Item.

    CopyToClipboard ();
    COleDataObject Objreceiver;
        
        if (Objreceiver.attachclipboard ()) {objreceiver.ensureclipboardobject ();
        Objreceiver.beginenumformats ();
        FORMATETC format;
        FILE *FP;
        Fopen_s (&FP, "C:\\temp\\garbage\\olestatic.bin", "WB"); while (Objreceiver.getnextformat (&format)) {Hglobal Hmem = Objreceiver.getglobaldata (format.cffor
            MAT); int size =:: GlobalSize (HMEM);

            byte *pdata = (BYTE *):: GlobalLock (HMEM);

            Fwrite (pdata, 1, size, FP);
        :: GlobalUnlock (HMEM);
    } fclose (FP); } obj.
    Detach ();
Objreceiver.release (); }

The bin file is being fed to the Teigha through invocation on its setcompounddocument

To do it work the image have to being converted to a DIB (Device independent Bitmap) which are given by the code below as a s Implified approach,

References: 
//http://www.codeguru.com/cpp/g-m/bitmap/article.php/c1693/ creating-a-dib-section-from-a-bmp-file.htm
hglobal createdibfrombmp (char *filename)
{
    file *fp;
    fopen_s (&FP, filename, "RB");
    Fseek (FP, 0, seek_end);
    int flen = Ftell (FP);
    Fseek (FP, 0, Seek_set);

    byte *buf = new Byte[flen];

    Fread (buf, 1, Flen, FP);

    This simplified version just takes off the header of the BMP to turn it into DIB
    hglobal hmem =:: GlobalAlloc (Gmem _moveable, flen-14);

    byte *pdib = (byte*):: GlobalLock (HMEM);
    memcpy (Pdib, buf+14, flen-14);

    :: GlobalUnlock (HMEM);

    Delete[] BUF;

    Fclose (FP);

    return hmem;
}

Unfortunately this solution however reasonable it looks doesn ' t work out well at all, the first and foremost issue it H As is the recent versions of AutoCAD show it as A white placeholder for image and upon editing the PLACEHOLDER&N Bsp;object an error message is popped up saying it's a static ActiveX Object and is unable to be activated. And it is truly a static ActiveX as was clearly indicated by the subroutine That is used to create a coleclientitem. And that subroutine cannot was replaced by Createfromdata () simply because the the-the-the-data object is-created from the PICT Ure file doesn ' t allow that.

So I had to find another-which apparently as suggested by the error message have to be creating a non-static OLE obj Ect. Hours of effort with alternate attempts for other possibilities was committed and the final solution were inspired by a Lin k http://support.microsoft.com/kb/220844 but not in the same flavour as I couldn ' t figure out a by-get a simple g Raft of the WIN32 approach to the OLE Objects manipulation that follows to work. Below is my current approach,

The method of creating a compound document for an OLE from a picture file void Createnonstaticcompounddocument () {

    * (&afxcurrentappname) = L "TestApp";
    COleDocument Doc;
    COleClientItem item (&DOC); Item.

    CreateFromFile (L "c:\\temp\\garbage\\sample.bmp"); Item.

    CopyToClipboard ();
    COleDataObject Objreceiver;
        
        if (Objreceiver.attachclipboard ()) {objreceiver.ensureclipboardobject ();
        Objreceiver.beginenumformats ();
        FORMATETC format;
        FILE *FP;
        Fopen_s (&FP, "C:\\temp\\garbage\\olenonstatic.bin", "WB"); while (Objreceiver.getnextformat (&format)) {Hglobal Hmem = Objreceiver.getglobaldata (format.cffor
            MAT);
            int size =:: GlobalSize (HMEM);

            byte *pdata = (BYTE *):: GlobalLock (HMEM);

            Fwrite (pdata, 1, size, FP);
        :: GlobalUnlock (HMEM);
    } fclose (FP);
} objreceiver.release (); }

The above approach brings me much closer to the goal. Although it still just creates a white box with no sign of image but AutoCAD doesn ' t complain when the user was trying to O Pen the OLE and it does show the right image in the paintbrush application.

Note both of the above approaches preserve the data fine as one can copy paste image from AutoCAD.

It can be obviously see how awkward ole/com Technologies is (I suppose I might have missed some COM object finalisation). They may provide some runtime performance benefit and extensibility, however it's far less productive than. NET and the P Erformance is not the much at all if. NET and its interoperability are optimally used. and I see products using this kind of technology as well as mfc/atl such as AutoCAD etc. for most part of it including the Architecture just because they ' ve long been used rather than they is necessary.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.