C#開發ActiveX網頁截圖控件


故事背景:Java組的小伙伴需要一個能在IE(還是6。。。)下截圖並返回給網頁的功能,但是IE做起來很麻煩(可能根本做不到),於是找到我寫一個ActiveX控件實現此功能,想着可能還有其他小伙伴需要這個功能,於是就PO出來,供需要的人使用,當然也可以作為學習C#編寫ActiveX的一個簡單入門教程(VC++效果更好)。

 

  功能截圖如下:

 

代碼分為兩個核心部分:1、C#屏幕截圖;2、C#開發ActivX控件。

1、屏幕截圖,這個在網上找到了一個只需要5行代碼的實現(超級精簡),當然你也可以費點功夫實現自由區域截取圖片,截圖后保存到本地,然后使用二進制讀取jpg文件,並編碼為base64返回給網頁

        public string PrintScreen()
        {
            Image baseImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
            Graphics g = Graphics.FromImage(baseImage);
            g.CopyFromScreen(new Point(0, 0), new Point(0, 0), Screen.AllScreens[0].Bounds.Size);
            g.Dispose();
            baseImage.Save("D:\\screen.jpg", ImageFormat.Jpeg);
            Stream file = new FileStream("D:\\screen.jpg", FileMode.Open);
            BinaryReader bw = new BinaryReader(file);
            var buffer = new byte[file.Length];
            bw.Read(buffer, 0, buffer.Length);
            bw.Close();
            string b64 = Convert.ToBase64String(buffer);
            return b64;
        }

 

2、c#開發ActiveX控件,網上示例比較多

  先新建一個類庫,並設置項目屬性,COM可見

並為COM互注冊,這樣編譯完了會自動注冊COM控件

 

  完成設置后,編寫代碼,如下:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace PrintScreenLib
{
    //為了讓ActiveX控件獲得客戶端的信任,控件類需要實現一個名為“IObjectSafety”的接口。先創建該接口(注意,不能修改該接口的GUID值)
    [ComImport, Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IObjectSafety
    {
        [PreserveSig]
        int GetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] ref int pdwSupportedOptions, [MarshalAs(UnmanagedType.U4)] ref int pdwEnabledOptions);

        [PreserveSig()]
        int SetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] int dwOptionSetMask, [MarshalAs(UnmanagedType.U4)] int dwEnabledOptions);
    }
}

 

新建用戶控件,並派生IObjectSafe接口,接口實現是固定內容

    [Guid("61D7F413-A1B2-48A9-B851-5BFBCF50280C")] //使用VS工具里的GUID生成器生成唯一碼
    public partial class PSLib : UserControl, IObjectSafety
    {
        #region IObjectSafety 成員
        private const string _IID_IDispatch = "{00020400-0000-0000-C000-000000000046}";
        private const string _IID_IDispatchEx = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}";
        private const string _IID_IPersistStorage = "{0000010A-0000-0000-C000-000000000046}";
        private const string _IID_IPersistStream = "{00000109-0000-0000-C000-000000000046}";
        private const string _IID_IPersistPropertyBag = "{37D84F60-42CB-11CE-8135-00AA004BB851}";

        private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001;
        private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002;
        private const int S_OK = 0;
        private const int E_FAIL = unchecked((int)0x80004005);
        private const int E_NOINTERFACE = unchecked((int)0x80004002);

        private bool _fSafeForScripting = true;
        private bool _fSafeForInitializing = true;


        public int GetInterfaceSafetyOptions(ref Guid riid, ref int pdwSupportedOptions, ref int pdwEnabledOptions)
        {
            int Rslt = E_FAIL;

            string strGUID = riid.ToString("B");
            pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
            switch (strGUID)
            {
                case _IID_IDispatch:
                case _IID_IDispatchEx:
                    Rslt = S_OK;
                    pdwEnabledOptions = 0;
                    if (_fSafeForScripting == true)
                        pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
                    break;
                case _IID_IPersistStorage:
                case _IID_IPersistStream:
                case _IID_IPersistPropertyBag:
                    Rslt = S_OK;
                    pdwEnabledOptions = 0;
                    if (_fSafeForInitializing == true)
                        pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
                    break;
                default:
                    Rslt = E_NOINTERFACE;
                    break;
            }

            return Rslt;
        }

        public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
        {
            int Rslt = E_FAIL;

            string strGUID = riid.ToString("B");
            switch (strGUID)
            {
                case _IID_IDispatch:
                case _IID_IDispatchEx:
                    if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) &&
                            (_fSafeForScripting == true))
                        Rslt = S_OK;
                    break;
                case _IID_IPersistStorage:
                case _IID_IPersistStream:
                case _IID_IPersistPropertyBag:
                    if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_DATA) &&
                            (_fSafeForInitializing == true))
                        Rslt = S_OK;
                    break;
                default:
                    Rslt = E_NOINTERFACE;
                    break;
            }

            return Rslt;
        }
        #endregion

 

IE調用ActiveX控件:

<!DOCTYPE html>
<html>
  <head>
    <title>測試</title>
    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <script>
        function jt(){
             var str="";
             try
             {
                var obj = document.getElementById("MyActiveX");    
                 str=obj.PrintScreen();
             }
             catch(e)
            {
                alert(e);
                return;
            }

             var img=document.getElementById("img");
             img.src="data:image/jpeg;base64,"+str;//接受base64編碼后的圖片
        }
    </script>
  </head>
  
  <body>
      <OBJECT ID="MyActiveX" WIDTH="120" HEIGHT=20" CLASSID="CLSID:61D7F413-A1B2-48A9-B851-5BFBCF50280C"></OBJECT>
      <input type="button" value="截圖" onclick="jt();">
    <Image id ="img" />
  </body>
</html>

 

一個完整的ActvieX控件就完成了,這里沒有使用到事件,如果使用事件的話會更加麻煩一點,這里就不啰嗦了

下載地址:屏幕截圖ActivX控件


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM