C#: DDE通讯

using System;
using System.Collections.Generic;
using System.Text;

namespace HisDataToSqlServer
{
    using System.Runtime.InteropServices;

    #region "Win32 API 结构声明例子"
    class Win32API
    {
        protected const uint DMLERR_NO_ERROR = 0;
        protected const int APPCLASS_STANDARD = 0x0;
        protected const int CBF_FAIL_SELFCONNECTIONS = 0x1000;
        protected const int DNS_REGISTER = 0x0001;
        protected const int CP_WINANSI = 1004;
        protected const uint TIMEOUT_ASYNC = 0xFFFFFFFF;
        protected const int XCLASS_FLAGS = 0x4000;
        protected const int XTYP_POKE = (0x0090 | XCLASS_FLAGS);
        protected const int XCLASS_DATA = 0x2000;
        protected const int XTYP_REQUEST = (0x00B0 | XCLASS_DATA);
        protected const int XCLASS_NOTIFICATION = 0x8000;
        protected const int XTYP_XACT_COMPLETE = 0x0080 | XCLASS_NOTIFICATION;


        [StructLayout(LayoutKind.Sequential)]
        protected struct SECURITY_QUALITY_OF_SERVICE
        {
            public ushort Length;
            public int ImpersonationLevel;
            public int ContextTrackingMode;
            public bool EffectiveOnly;
        }

        [StructLayout(LayoutKind.Sequential)]
        protected struct CONVCONTEXT
        {
            public uint cb;
            public uint wFlags;
            public uint wCountryID;
            public int iCodePage;
            public ushort dwLangID;
            public ushort dwSecurity;
            public SECURITY_QUALITY_OF_SERVICE qos;
        }

        [DllImport("user32.dll", EntryPoint = "DdeInitialize")]
        protected static extern int DdeInitialize(ref int pidInst, DdeCallback pfnCallback, int afCmd, int ulRes);

        [DllImport("user32.dll", EntryPoint = "DdeCreateStringHandle")]
        protected static extern int DdeCreateStringHandle(int idInst, string psz, int iCodePage);

        [DllImport("user32.dll", EntryPoint = "DdeFreeStringHandle")]
        protected static extern int DdeFreeStringHandle(int idInst, int hsz);

        [DllImport("user32.dll", EntryPoint = "DdeNameService")]
        protected static extern int DdeNameService(int idInst, int hsz1, int hsz2, int afCmd);

        [DllImport("user32.dll", EntryPoint = "DdeUninitialize")]
        protected static extern int DdeUninitialize(int idInst);

        [DllImport("user32.dll", EntryPoint = "DdeConnect")]
        protected unsafe static extern int DdeConnect(int idInst, int hszService, int hszTopic, ref CONVCONTEXT pCC);

        [DllImport("user32.dll", EntryPoint = "DdeDisconnect")]
        public static extern int DdeDisconnect(int hConv);

        [DllImport("user32.dll", EntryPoint = "DdeQueryString")]
        public unsafe static extern int DdeQueryString(int idInst, int hsz, sbyte* psz, int cchMax, int iCodePage);

        [DllImport("user32.dll", EntryPoint = "DdeClientTransaction")]
        protected static extern int DdeClientTransaction(char[] pData, int ByVal, int hConv, int hszItem,
                                                    int wFmt, int wType, uint dwTimeout, ref int pdwResult);

        protected delegate int DdeCallback(
            uint uType,
            uint uFmt,
            int hconv,
            int hsz1,
            int hsz2,
            int hdata,
            uint dwData1,
            uint dwData2
        );
    }
    #endregion

    public delegate void delegateWriteFile();
    
    class DdeItem : Win32API
    {
        private DdeCallback myCallback;
        private int dwDDEInst;
        private int m_hConv;

        protected unsafe int DdeClientCallback(
            uint uType,
            uint uFmt,
            int hconv,
            int hsz1,
            int hsz2,
            int hdata,
            uint dwData1,
            uint dwData2)
        {
            if (uType == XTYP_XACT_COMPLETE)
            {
                sbyte* pSZ = stackalloc sbyte[30];
                DdeQueryString(dwDDEInst, hsz2, pSZ, 28, (int)CP_WINANSI);
                string sTmp = new string(pSZ);
                if (sTmp == "WriteFile")
                {
                    
                }
            }

            return 0;
        }

        public DdeItem()
        {
            myCallback = new DdeCallback(DdeClientCallback);
            DdeInitialize(ref dwDDEInst, myCallback, (APPCLASS_STANDARD | CBF_FAIL_SELFCONNECTIONS), 0);
            int hszName = DdeCreateStringHandle(dwDDEInst, "MONITOR_DDE_SERVER", CP_WINANSI);
            int i = DdeNameService(dwDDEInst, hszName, 0, DNS_REGISTER);
        }

        public bool connect(string server, string topic)
        {
            m_hConv = DDE_Connect_Server(server, topic);

            if (m_hConv != 0)
            {
                if (DDE_Request(m_hConv) != 0)
                {
                    return true;
                }
            }
            return false;
        }

        public void Disconnect()
        {
            if (m_hConv != 0)
            {
                DdeDisconnect(m_hConv);
            }
        }

        public void Demolish()
        {
            if (m_hConv != 0)
            {
                DdeDisconnect(m_hConv);
            }

            if (dwDDEInst != 0)
            {
                DdeUninitialize(dwDDEInst);
            }
        }

        public void Poke(string csItem, string csData)
        {
            DDE_Poke(m_hConv, csItem, csData);
        }

        private int DDE_Connect_Server(string csServer, string csTopic)
        {
            int hszServer = DdeCreateStringHandle(dwDDEInst, csServer, CP_WINANSI);
            int hszTopic = DdeCreateStringHandle(dwDDEInst, csTopic, CP_WINANSI);

            CONVCONTEXT pc = new CONVCONTEXT();

            int hConv = DdeConnect(dwDDEInst, hszServer, hszTopic, ref pc);

            DdeFreeStringHandle(dwDDEInst, hszServer);
            DdeFreeStringHandle(dwDDEInst, hszTopic);
            return hConv;
        }

        private int DDE_Poke(int hConv, string csItem, string csData)
        {
            int hszData = DdeCreateStringHandle(dwDDEInst, csItem, CP_WINANSI);

            char[] inputBytes = csData.ToCharArray();

            int dwResult = 0;
            int hData = DdeClientTransaction(inputBytes, csData.Length + 1, hConv, hszData, 1, XTYP_POKE, TIMEOUT_ASYNC, ref dwResult);

            DdeFreeStringHandle(dwDDEInst, hszData);

            return hData;
        }

        private int DDE_Request(int hConv)
        {
            int hszData = DdeCreateStringHandle(dwDDEInst, "\"MONITOR_DDE_SERVER\"", CP_WINANSI);

            char[] inputBytes = { };
            int dwResult = 0;
            int hData = DdeClientTransaction(inputBytes, -1, hConv, hszData, 1, XTYP_REQUEST, TIMEOUT_ASYNC, ref dwResult);

            DdeFreeStringHandle(dwDDEInst, hszData);

            return hData;
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DDE(Dynamic Data Exchange)是一种在 Windows 操作系统中使用的进程间通信(IPC)机制。使用DDE,一个应用程序可以向另一个应用程序发送数据或请求数据。在C#中,可以使用System.Windows.Forms命名空间中的DdeClient类来实现DDE客户端。 以下是一个简单的DDE客户端示例,它将连接到Microsoft Excel并获取单元格A1的值: ```csharp using System; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Security.Permissions; namespace DDEClientExample { public partial class Form1 : Form { private const int WM_DDE_ACK = 0x03; private const int WM_DDE_DATA = 0x05; [DllImport("user32.dll")] private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] protected override void WndProc(ref Message m) { if (m.Msg == WM_DDE_DATA) { // Get the data from the DDE server string data = Marshal.PtrToStringAuto(m.LParam); // Display the data MessageBox.Show(data); } else if (m.Msg == WM_DDE_ACK) { // The DDE server has acknowledged our connection request MessageBox.Show("Connected to DDE server."); } base.WndProc(ref m); } public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { // Connect to Microsoft Excel DdeClient ddeClient = new DdeClient("excel", "sheet1"); // Subscribe to the DDE server's events ddeClient.Disconnected += DdeClient_Disconnected; ddeClient.Advise += DdeClient_Advise; // Connect to the DDE server ddeClient.Connect(); // Request data from the DDE server byte[] data = ddeClient.Request("A1"); // Disconnect from the DDE server ddeClient.Disconnect(); } private void DdeClient_Disconnected(object sender, EventArgs e) { MessageBox.Show("Disconnected from DDE server."); } private void DdeClient_Advise(object sender, DdeAdviseEventArgs e) { // Handle DDE advise events here } } } ``` 在此示例中,我们使用 DdeClient 类连接到 Microsoft Excel 的“sheet1”工作表,并使用 Request 方法获取单元格 A1 的值。我们还订阅了 DDE 服务器的 Disconnected 和 Advise 事件。 请注意,DDE 已经过时,Microsoft 建议使用其他通信机制,例如 COM、.NET Remoting 或 WCF。如果可能的话,应该尽量避免使用 DDE。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值