zoukankan      html  css  js  c++  java
  • 怎样将GIS图形复制到Windows剪贴板,粘贴到Word中

        很久没写随笔了,有点想关了这个博客,不再更新,但还是没有下定决心。趁这些天比较闲,发一个以前写着玩的功能吧。
        复制、粘贴功能是一件很简单的事情,但怎样将GIS图形粘贴到word中呢?最简单的思路还是将GIS图形保存为Image形式,发送到剪贴板,再粘贴到Word。但如果Image格式采用栅格的格式,如BMP或JPEG,则粘贴后在Word中拉伸时,效果会受到影响,比较合适的格式是采用WMF或EMF这种矢量的格式。将Visio格式复制到Word中时,可以看到就是这种效果,而且文字还是可以编辑的。好,下面我们就看看怎样实现这个功能。

        第一步当然是将图形复制为一个MetaFile对象:

            public Metafile GetGeometryMetafile(ISymbol pSymbol, IGeometry pGeometry)
            
    {
                
    //先获取一个IDisplayTransformation对象
                IDisplayTransformation pDisTrans = new DisplayTransformationClass(); 
                IEnvelope pEnv 
    = pGeometry.Envelope;
                Rectangle rect 
    = new Rectangle(00500500); 
     
                tagRECT r;
                r.left 
    = rect.Left;
                r.right 
    = rect.Right;
                r.bottom 
    = rect.Bottom;
                r.top 
    = rect.Top;

                pDisTrans.set_DeviceFrame(
    ref r);
                pDisTrans.Bounds 
    = pEnv;

                pDisTrans.Resolution 
    = 72;

                pDisTrans.ReferenceScale 
    = 1.0;
                pDisTrans.ScaleRatio 
    = 1;

                
    //创建WMF
                MemoryStream ms = new MemoryStream();
                Graphics g 
    = CreateGraphics();
                IntPtr hdc 
    = g.GetHdc();
                Metafile mf 
    = new Metafile(ms, hdc, new Rectangle(0,0,500,500),MetafileFrameUnit.Pixel, EmfType.EmfPlusDual);
                g.ReleaseHdc(hdc);
                g.Dispose();
                g 
    = Graphics.FromImage(mf); 
            
                g.FillRectangle(
    new SolidBrush(Color.White), new Rectangle(00500500));

                pSymbol.SetupDC((
    int)g.GetHdc(), pDisTrans);
                pSymbol.Draw(pGeometry);            
                pSymbol.ResetDC();
                g.ReleaseHdc();

                g.DrawString(
    "by watson"this.Font, new SolidBrush(Color.Blue), new PointF(2020));

                g.Save();
                g.Dispose();

                
    return mf;
            }


    第二步:发送到剪贴板:

    IDataObject data = new DataObject();
                    data.SetData(DataFormats.MetafilePict, mf);
                    Clipboard.SetDataObject(data, 
    true);

    测试 .... 什么,不成功??
    估计是.net不支持将metafile格式复制到剪贴板吧。
    于是,用于搜索引擎,搜索一翻,在某国外论坛找到解决方案:
     public class ClipboardMetafileHelper
        
    {
            [DllImport(
    "user32.dll")]
            
    static extern bool OpenClipboard(IntPtr hWndNewOwner);
            [DllImport(
    "user32.dll")]
            
    static extern bool EmptyClipboard();
            [DllImport(
    "user32.dll")]
            
    static extern IntPtr SetClipboardData(uint uFormat, IntPtr hMem);
            [DllImport(
    "user32.dll")]
            
    static extern bool CloseClipboard();
            [DllImport(
    "gdi32.dll")]
            
    static extern IntPtr CopyEnhMetaFile(IntPtr hemfSrc, IntPtr hNULL);
            [DllImport(
    "gdi32.dll")]
            
    static extern bool DeleteEnhMetaFile(IntPtr hemf);

            
    // Metafile mf is set to an invalid state inside this function
            static public bool PutEnhMetafileOnClipboard(IntPtr hWnd, Metafile mf)
            
    {
                
    bool bResult = false;
                IntPtr hEMF, hEMF2;
                hEMF 
    = mf.GetHenhmetafile(); // invalidates mf
                if (!hEMF.Equals(new IntPtr(0)))
                
    {
                    hEMF2 
    = CopyEnhMetaFile(hEMF, new IntPtr(0));
                    
    if (!hEMF2.Equals(new IntPtr(0)))
                    
    {
                        
    if (OpenClipboard(hWnd))
                        
    {
                            
    if (EmptyClipboard())
                            
    {
                                IntPtr hRes 
    = SetClipboardData(14 /*CF_ENHMETAFILE*/, hEMF2);
                                bResult 
    = hRes.Equals(hEMF2);
                                CloseClipboard();
                            }

                        }

                    }

                    DeleteEnhMetaFile(hEMF);
                }

                
    return bResult;
            }

        }

    调用PutEnhMetafileOnClipboard方法就可以了,
    再测试....大功告成!

    再看一看PutEnhMetafileOnClipboard中的代码,比较特别的是CopyEnhMetaFile函数,将MetaFile在内存中复制一份,看来是.net中的metafile与Windows中的metafile格式有一定出入,windows剪贴板不认识的缘故吧。

  • 相关阅读:
    n个数字相加
    爬取编程常用词汇,保存为Excel
    Python对 Excel 的常用操作
    Python对Redis增删改查
    Python对MySql增删改查
    Python对MongoDB增删改查
    MySql事务的简单使用
    Python-判断回文
    Pyhton 连接数据库
    PyCharm设置完自动上传,却不会自动上传任何内容
  • 原文地址:https://www.cnblogs.com/watsonyin/p/968651.html
Copyright © 2011-2022 走看看