在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
C#调用Delphi接口方法,有两种解决办法: 一、将Delphi程序编译成一个COM组件,然后在C#里引用COM组件。 二、非托管调用Dephi的DLL文件。
这里我们主要讲解一下第二种方法,讲第二种方法之前首先讲解下DllImport。 DllImport是System.Runtime.InteropServices命名空间下的一个属性类,其功能是提供从非托管DLL导出的函数的必要调用信息。 DllImport属性应用于方法,要求最少要提供包含入口点的dll的名称。
代码
1 [AttributeUsage(AttributeTargets.Method)]
2 public class DllImportAttribute: System.Attribute 3 { 4 public DllImportAttribute(string dllName) {…} //定位参数为dllName 5 public CallingConvention CallingConvention; //入口点调用约定 6 public CharSet CharSet; //入口点采用的字符接 7 public string EntryPoint; //入口点名称 8 public bool ExactSpelling; //是否必须与指示的入口点拼写完全一致,默认false 9 public bool PreserveSig; //方法的签名是被保留还是被转换 10 public bool SetLastError; //FindLastError方法的返回值保存在这里 11 public string Value { get {…} } 12 } 13
上面DLL的名字有时需要写上路径的如[DllImport(@"C:\OJ\Bin\Judge.dll")]这样指定DLL的绝对路径就可以正常装载。 假如没有路径的话,DllImport会按照顺序自动去寻找的地方: 说明:
下面讲解下如何调用: 用DllImport来调用的 一般是用非托管的。 其中第一个参数是指要引用DLL的名字, 这个名字应该是个常量(否则会出错)。
下面紧接着他的申明函数:
下面是参数的引用:即Delphi的类型向C#的转换。 第一个参数类型:IntPtr这个类型可以申明为其他语言的句柄,指针等。
下面说一下:如何将Dephi的窗体显示在自己的页面中(且不能显示Delphi窗体的标题栏,实现无缝的结合)。 将dephi的窗体签入到自己的C#系统里 还有一点比较重要,我们是调用Delphi的窗体,此时显示在我们C#窗体中会有Delphi的窗体, 这时我们怎么办呢, 怎么去除Delphi中的窗体呢? 这时我们就需要用API函数了。 因为WINDOWS API是一种比较底层的语言,可以通过它进行操作。 在C#中是这么引用的: [DllImport("user32.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] 下面插入一个类,这里面包含了怎么引用dephi的dll 以及怎么申明:
代码
1 public class CompliancePlatDLL
2 { 3 public static string strPath = ""; 4 /// <summary> 5 /// 初始化 6 /// </summary> 7 /// <param name="handle"></param> 8 /// <param name="methodAddress"></param> 9 [DllImport("WZFSE.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] 10 public static extern void InitDll(IntPtr handle, bool methodAddress); 11 /// <summary> 12 /// 加载相应的服务 13 /// </summary> 14 /// <param name="str"></param> 15 /// <param name="str2"></param> 16 /// <param name="i"></param> 17 /// <returns></returns> 18 [DllImport("WZFSE.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] 19 public static extern IntPtr wzLoadModule(string str, string str2, int i); 20 /// <summary> 21 /// 去除相应的服务 22 /// </summary> 23 /// <param name="handle"></param> 24 /// <returns></returns> 25 [DllImport("WZFSE.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] 26 public static extern bool wzUnloadModule(IntPtr handle); 27 28 #region API函数 29 /// <summary> 30 /// API函数 设置主辅窗体 31 /// </summary> 32 /// <param name="child"></param> 33 /// <param name="parent"></param> 34 [DllImport("user32.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] 35 public static extern void SetParent(IntPtr child, IntPtr parent); 36 /// <summary> 37 /// API函数 移动窗体 38 /// </summary> 39 /// <param name="handler"></param> 40 /// <param name="x"></param> 41 /// <param name="y"></param> 42 /// <param name="width"></param> 43 /// <param name="height"></param> 44 /// <param name="repaint"></param> 45 [DllImport("user32.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] 46 public static extern void MoveWindow(IntPtr handler, int x, int y, int width, int height, bool repaint); 47 48 [DllImport("user32.dll", EntryPoint = "GetWindowLong")] 49 public static extern long GetWindowLong(IntPtr hwnd, int nIndex); 50 /// <summary> 51 /// API函数 去除窗体的标题栏 52 /// </summary> 53 /// <param name="hwnd"></param> 54 /// <param name="nIndex"></param> 55 /// <param name="dwNewLong"></param> 56 /// <returns></returns> 57 [DllImport("user32.dll", EntryPoint = "SetWindowLong")] 58 public static extern long SetWindowLong(IntPtr hwnd, int nIndex, long dwNewLong); 59 public const int GWL_EXSTYLE = -16; 60 public const int WS_EX_TRANSPARENT = 0x20; 61 public const int WS_EX_LAYERED = 0x80000; 62 public const int LWA_ALPHA = 2; 63 public const int WS_CAPTION = 0xC00000; 64 #endregion 65 }
其中API中的SetWindowLong这个方法是可以实现去除窗体的标题栏的, 具体调用SetWindowLong(common.p, GWL_EXSTYLE, GetWindowLong(handle, GWL_EXSTYLE) & (~WS_CAPTION)); 但一般完整利用API函数的调用是这样的
代码
1 decallback de1 = new decallback(iscallback);//利用委托
2 InitDll(this.Handle, de1(this.Handle));//初始化 3 IntPtr p = wzLoadModule("DoRiskSetup", "", 0);//取得句柄 4 if (p != (IntPtr)0)//判断该句柄不是弹出窗体时 5 { 6 //去除dephi窗体的标题栏 7 SetParent(p, panel1.Handle); 8 SetWindowLong(p, GWL_EXSTYLE, GetWindowLong(p, GWL_EXSTYLE) & (~WS_CAPTION)); 9 MoveWindow(p, 0, 0, panel1.ClientSize.Width, panel1.ClientSize.Height, false); 10 } SetWindowLong(IntPtr handle, int t,long l) 第一个参数为句柄,是你调的dephi窗体的句柄,第二个参数为整型,在dephi用常量GWL_EXSTYLE表示,表示要显示的样式,在C#中翻译过来的他值为(-16),而第三个函则为长整型和第二个参数一起表示要去除第一个参数句柄窗体的标题栏在Delphi中表示为:GetWindowLong(handle,GWL_EXSTYLE) and (not WS_CAPTION) 在C#中则翻译为:GetWindowLong(handle,-16)&(~0xC00000),handle是指要调用的Delphi窗体的句柄,GetWindowLong这个函数是获得该窗体的相关信息。大体上是这个用法,如有不懂大家可以提出来 共同探讨。 一般类型对应如下: Dephi-->C# intger -->int longint -->long pchar -->string THandle -->IntPtr |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论