让 ActiveX 控件在没有表单的情况下工作?
我们使用黄玉签名板。他们以 ActiveX 控件的形式提供 API,并将其放置在 Winform 控件上。好吧,我们的项目的工作方式我们不希望有一个表单(至少不可见)。我们只想让签名 ActiveX 控件在后台获取图像。
static AxSigPlus sig = new AxSIGPLUSLib.AxSigPlus();
public static void Begin()
{
((System.ComponentModel.ISupportInitialize)(sig)).BeginInit();
sig.Name = "sig";
sig.Location = new System.Drawing.Point(0, 0);
sig.Size = new System.Drawing.Size(0, 0);
sig.Enabled = true;
sig.TabletState = 1; //error here
sig.SigCompressionMode = 0;
}
好的,我在标记行处收到错误。例外的是
Exception of type 'System.Windows.Forms.AxHost+InvalidActiveXStateException' was thrown.
我该怎么做才能解决这个问题?创建一个新的隐藏窗体并将控件放在其上以使其不可见会更容易吗?
We are using Topaz Signature pads. They provide their APIs in the from of an ActiveX control which is to be put on a Winform control. Well, the way our project will work we do not want to have a form(at least not visible). We just want for the signature ActiveX control to get an image in the background.
static AxSigPlus sig = new AxSIGPLUSLib.AxSigPlus();
public static void Begin()
{
((System.ComponentModel.ISupportInitialize)(sig)).BeginInit();
sig.Name = "sig";
sig.Location = new System.Drawing.Point(0, 0);
sig.Size = new System.Drawing.Size(0, 0);
sig.Enabled = true;
sig.TabletState = 1; //error here
sig.SigCompressionMode = 0;
}
Ok so I get an error at the marked line. The exception is
Exception of type 'System.Windows.Forms.AxHost+InvalidActiveXStateException' was thrown.
What do I do to solve this problem? Would it just be easier to create a new hidden form and put the control on it so it's invisible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
是的,这样不行。 AxHost 包装器需要先创建其句柄才能使用。这要求它是调用 Show() 方法的窗体上的子控件。
通常,您可以从 ActiveX 控件获得两个互操作包装器:一个包含 AxHost 包装器的 AxBlah.dll 和一个包装 COM 接口的 Blah.dll。您只需要引用 Blah.dll 即可。这是否有效是一个悬而未决的问题,许多 ActiveX 控件需要窗口句柄来处理线程同步。
如果这不起作用,您将需要一份主持人表格。您可以通过将此代码粘贴到表单类中来使其不可见:
您必须调用 Application.Run() 来泵送消息循环。
Yes, that can't work this way. The AxHost wrapper requires its Handle to be created before it is usable. Which requires it to be a child control on a form whose Show() method is called.
You normally get two interop wrappers from an ActiveX control, an AxBlah.dll which contains the AxHost wrapper and a Blah.dll which wraps the COM interfaces. You'd only need to reference Blah.dll. Whether that will work is an open question, many ActiveX controls require a window handle to deal with thread synchronization.
If that doesn't work out, you'll need a host form. You can keep it invisible by pasting this code into the form class:
You have to call Application.Run() to pump the message loop.
您也许可以直接使用 COM 对象(这实际上取决于他们如何实现控件)。通常,当您将 COM 对象导入到引用中时,它会创建一个包装器 AxHost,但它还应该导入基本类对象。找到它,然后将其创建为任何普通类,不要使用 AxHost 版本。如果似乎没有任何基类对象,您可以使用 Activator 以及控件的 CLSID 或 ProgID 创建该对象。类似于:
object o = Activator.CreateInstance(Type.GetTypeFromProgID("prog.id"))
You might be able to just use the COM object directly (it really depends how they implemented the control). Normally when you import the COM object into your references it will create a wrapper AxHost but it should also import the basic class objects. Find which that is then just create it as any normal class, do not use the AxHost version. If there doesn't seem to be any base class objects you can create the object using the Activator and either the CLSID or ProgID of the control. Something like:
object o = Activator.CreateInstance(Type.GetTypeFromProgID("prog.id"))
这就是我所做的(基本上添加了不可见的 Axe 控件并随后调用其方法):
This is what I did (basically added invisible Ax control and invoked its methods thereafter):
实际上,Topaz 提供了一个 ActiveX 控件和一个围绕它的 .Net 包装器。我切换到 .Net 包装器,它不需要放置在表单或任何东西上。不过,我将保留这个问题,因为如果没有那个包装器,我实际上会处理它。
Actually it ended up that Topaz provided an ActiveX control and a .Net wrapper around it. I switched to the .Net wrapper and it doesn't require being placed on a form or anything. I will leave the question up though because had it not been for that wrapper I would actually be dealing with it.