如何将ActiveX控件dll调用到另一个软件中 [英] how to call the ActiveX control dll into the another software

查看:100
本文介绍了如何将ActiveX控件dll调用到另一个软件中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在C#.NET中创建了类库.dll文件.然后使用regasm.exe命令注册该文件,当我将其注册时,它将其访问路径显示为mscoree.dll文件,但我的dll文件路径是另一个(C:\ program files \ mydll.dll).当我在ActiveX控件中使用此控件到另一个软件(例如,simantic HMI wincc flexible)时,将此控件拖动到wincc的屏幕中,将错误消息显示为

I have create the class library .dll file in C#.NET . then register this file using the regasm.exe command when i will register this file it display it''s access path as mscoree.dll file,but my dll file path is another(C:\program files\mydll.dll) . when i have used this in ActiveX control into the another software like (simantic HMI wincc flexible ) ,drag this control into the screen of the wincc it display the error message as

failed to create graphics object from type control 

推荐答案

尝试本文:Morgan Skinner撰写的将Windows窗体控件公开为ActiveX控件" [ 由于WinCC软件是用于开发工业自动化解决方案的专用系统(无疑是非常昂贵的),所以我认为最好的办法是从Siemens的WinCC支持中寻求澄清.

关键问题是:WinCC IDE是否允许任何类型的.NET组件...这些组件,当然取决于.NET FrameWork.如果此软件确实允许将.NET创建的元素与图形元素一起使用,那么我希望WinCC文档或Siemens网站中的某个地方有一个代码示例,或有关如何使用它们的指南,以及可以使用的确切内容. .

好吧,我们的朋友Google建议WinCC允许使用.NET组件: [
Try this article: "Exposing Windows Forms Controls as ActiveX controls" by Morgan Skinner[^].

... edit #1 ...

this question evidently refers to an attempt to use C# dll inside "SIMATIC WinCC Open Architecture"[^]

It appears the OP has used regasm.exe to "register," the C# DLL, then, inside WinCC, tried to import it, expecting its visual elements to show up.

Since the WinCC software is a dedicated system for developing industrial automation solutions (undoubtedly very expensive), I think the best thing to do, is to seek clarification from the WinCC support at Siemens.

The key questions is: does WinCC IDE allow .NET components of any type ... those components, of course being dependent on the .NET FrameWork. If this software does allow use of .NET created elements with graphic elements, then I would expect somewhere in the WinCC documentation, or the Siemens website, there is a code example, or guidelines on how to use them, and what exactly can be used.

Well, our friend Google suggests WinCC does allow .NET components:[^]

I''d suggest studying the links on that Google page that appear to specifically talk about using .NET controls in WinCC.

Also, why not ask questions on whatever forums Siemens offers on-line: surely for this level of very expensive software they have on-line,or e-mail, support ?

... end edit #1 ...

good luck, Bill


BillWoodruff建议的文章很简单,并解释得很好,我喜欢它,请关注它,如果仍然遇到问题,请与我们分享您的代码或存根,以便别人查看.

rushi
Article suggested by BillWoodruff is simple and well explained I like it, please follow it and if still getting problem share us your code or stub so someone can look it.

rushi


你好,

Morgan Skinner文章中描述的方式只是您应该处理的基本内容.

实际上,Winform conrol可处理OLE/COM控制的所有方面,但其中2个(我认为是必需的)被遗漏了.
1.一旦更改客户端站点已被激活并创建了窗口句柄,则不允许更改客户端站点(请参阅MSDN中的IOleObject.SetClientSite).
2.它不支持手动绘制(请参见MSDN中的IViewObject.Draw)

一旦设置了Control.Handle并且设置了父级,就会出现第一个问题,但是应用程序尝试进​​行更改.您应该使用WinAPI DestroyWindowSetParent(DestroyWindow放置句柄,.NET将使用新的父项重新创建它).

使用手动绘制激活控件后,第二个问题就会出现-如果应用程序不想绘制控件内容,则可能是第二个问题-它可以是它自己的DC或打印机DC(通常,具有打印支持并允许以下操作的应用程序:使用COM/OLE控件通过手动绘制参数激活控件).处理该问题的正确方法是进行手动绘制,但是至少您可以调用基本方法Control.DrawToBitmap在Bitmap上绘制内容,然后将该Bitmap绘制到给定的DC中.

为了使其正常工作,您应该更好地手动创建处理接口,大多数调用可以直接转发到AxHost,但是有些方法可以更好地覆盖.
在对象上实现所需的接口(这是最少的列表,但某些应用可能需要更多接口):IProvideClassInfoIProvideClassInfo2IQuickActivateIViewObjectIViewObject2IOleObjectIOleControlIOleInPlaceObjectIOleInPlaceObjectWindowlessIOleInPlaceActiveObjectIOleWindow.

某些应用程序可能需要永久存储或持久化流初始化接口,因此请记住这一点.

您应该设置reqistry条目,以将.NET控件标记为COM/OLE控件(如Morgan Skinner文章中所述),并进行更改.

注册功能:
Hello,

The way is described in Morgan Skinner article is only the basic stuff which you should handle.

Actually Winform conrol handle all aspects of OLE/COM control but 2 of them (I think mandatory) are missed.
1. It does not allow change client site once it already activated and window handle created (see IOleObject.SetClientSite in MSDN).
2. It does not support manual drawing (see IViewObject.Draw in MSDN)

The first issue appear once Control.Handle and parent is set, but the application try to changed. You should use a WinAPI DestroyWindow and SetParent (DestroyWindow dispose the handle and it will be recreated by .NET with new parent).

The second issue appear once the control activated with the manually drawing - this can be in case if application wan''t to draw the control content - it can be it own DC or the printer DC (Usually the applications with printing supports and allows to use COM/OLE controls activate control with manual draw parameter). The proper way to handle that is to make manual drawing, but at least you can just call you base method Control.DrawToBitmap to draw content on Bitmap and then draw that Bitmap into given DC.

To make it work you should better to make the handling interfaces manually, most of the calls can be just forwarded to AxHost but some methods better to override.
Interface necessary to implement on your object (Thats minimal list but some applicaions may require more): IProvideClassInfo, IProvideClassInfo2, IQuickActivate, IViewObject, IViewObject2, IOleObject, IOleControl, IOleInPlaceObject, IOleInPlaceObjectWindowless, IOleInPlaceActiveObject, IOleWindow.

Some applications may requre persits storage or persist stream initialization interfaces so keep that in mind.

You should set the reqistry entry to mark your .NET Control as COM/OLE Control as described in Morgan Skinner article but also with the changes.

Registration function:
[ComRegisterFunctionAttribute]
[RegistryPermissionAttribute(SecurityAction.Demand, Unrestricted=true)]
public static void RegisterFunction(Type _type)
{
    // Check your class type here 
    if (_type != null && _type.IsSubclassOf(typeof(MyCOMControl))) 
    {
        string sCLSID = "CLSID\\" + _type.GUID.ToString("B");
        try
        {
            RegistryKey _key = Registry.ClassesRoot.OpenSubKey(sCLSID, true);
            try
            {
                Guid _libID = Marshal.GetTypeLibGuidForAssembly(_type.Assembly);
                int _major, _minor;
                Marshal.GetTypeLibVersionForAssembly(_type.Assembly, out _major, out _minor);
                using (RegistryKey _sub = _key.CreateSubKey("Control")) { }
                using (RegistryKey _sub = _key.CreateSubKey("MiscStatus")) { _sub.SetValue("", "0", RegistryValueKind.String); }
                using (RegistryKey _sub = _key.CreateSubKey("TypeLib")) { _sub.SetValue("", _libID.ToString("B"), RegistryValueKind.String); }
                using (RegistryKey _sub = _key.CreateSubKey("Version")) { _sub.SetValue("", String.Format("{0}.{1}", _major, _minor), RegistryValueKind.String); }
                using (RegistryKey _sub = _key.CreateSubKey("Control")) { }
                using (RegistryKey _sub = _key.CreateSubKey("InprocServer32")) { _sub.SetValue("", Environment.SystemDirectory + "\\" + _sub.GetValue("", "mscoree.dll"), RegistryValueKind.String); }
            }
            finally
            {
               _key.Close();
            }
        }
        catch
        {
        }
    }
}


取消注册功能:


Unregister function:

[ComUnregisterFunctionAttribute]
[RegistryPermissionAttribute(SecurityAction.Demand, Unrestricted=true)]
public static void UnregisterFunction(Type _type)
{
    //Check Your type here
    if (_type != null && _type.IsSubclassOf(typeof(MyCOMControl)))
    {
        try
        {
            string sCLSID = "CLSID\\" + _type.GUID.ToString("B");
            Registry.ClassesRoot.DeleteSubKeyTree(sCLSID);
        }
        catch
        {
        }
    }
}


在那里有很多解决方案的代码;我将在文章中向其他水下石头展示如何进行适当的细节处理.我有时间在发表文章后,将在此处添加评论链接.

再次对辩论者(特别是对比尔):如果您不知道如何做到这一点,我要重复一遍,写这是不可能的-也许开始学习会更好?

问候,
Maxim.


As in there for full solution a lot of code; and I''ll show other underwater stones in the article how to proper make that in details. I''ll add link to comment here once I have time to post an article.

Again for debators (Especially for Bill): I repeating if you don''t know how to make that not write that it isn''t possible - maybe better to start learning?

Regards,
Maxim.


这篇关于如何将ActiveX控件dll调用到另一个软件中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆