C#编写ActiveX网页截图控件

前端技术 2023/09/08 C#

故事背景: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控件

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持phpstudy。

本文地址:https://www.stayed.cn/item/21586

转载请注明出处。

本站部分内容来源于网络,如侵犯到您的权益,请 联系我

我的博客

人生若只如初见,何事秋风悲画扇。