#define NITEM 2 //定义ITEM的数量; const char szApp="Server"; //server DDE服务名; const char szTopic="Topic";//Server DDE目录名; const char *pszItem[NITEM]={"Item1","Item2"};//SERVER ITEM名称字符串数组; int count=0;//记数,在Static1中显示; CString ServerData[NITEM];//存放服务器中的数据项内容; HCONV hConv=0; //会话句柄; DWORD idlnst=0; //DDEML实例句柄; HWND hWnd; //窗口句柄; HANDLE hlnst; //实例句柄; HSZ hszApp=0; //SERVER服务字符串句柄; HSZ hszTopic=0; //SERVER目录字符串句柄; HSZ hszItem[NITEM]; //Server ITEM字符串句柄; BOOL bConnect; // 建立连接标志; |
4、输入代码,编译运行程序。
三、程序代码
//////////////////////////////////////DDE回调函数; HDDEDATA CALLBACK DdeCallback(UINT wType,UINT wFmt,HCONV hConv,HSZ Topic,HSZ Item, HDDEDATA hData,DWORD lData1,DWORD lData2) { int I ; char tmp[255]; switch(wType) { case XTYP_ADVSTART: case XTYP_CONNECT://请求连接; return ((HDDEDATA)TRUE);//允许; case XTYP_ADVDATA: //有数据到来; for(I=0;I<NITEM;I++) if(Item==hszItem[I]) { DdeGetData(hData,(PBYTE)tmp,255,0);//取得数据; switch(I) { case 0: SetDlgItemText(hWnd,IDC_STATIC2,tmp); break; case 1: SetDlgItemText(hWnd,IDC_STATIC3,tmp); break; } } return ((HDDEDATA)DDE_FACK);//回执; case XTYP_ADVREQ: case XTYP_REQUEST://数据请求; for(I=0;I<NITEM;I++) if(Item==hszItem[I]) return(DdeCreateDataHandle(idlnst,(PBYTE)(LPCTSTR)ServerData[I], ServerData[I].GetLength()+1,0,Item,wFmt,0)); } return(0); } ///////////////////////////////////////////////////// CddedemoDlg.cpp CDdedemoDlg::CDdedemoDlg(CWnd* pParent /*=NULL*/) : CDialog(CDdedemoDlg::IDD, pParent) { //{{AFX_DATA_INIT(CDdedemoDlg) m_edit = _T(""); //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CDdedemoDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDdedemoDlg) DDX_Text(pDX, IDC_EDIT1, m_edit); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDdedemoDlg, CDialog) //{{AFX_MSG_MAP(CDdedemoDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_TIMER() ON_WM_DESTROY() ON_EN_CHANGE(IDC_EDIT1, OnChangeEdit1) //}}AFX_MSG_MAP END_MESSAGE_MAP() //////////////////////////////////////////CDdedemoDlg message handlers BOOL CDdedemoDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About" menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application''s main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here hWnd=m_hWnd; if (DdeInitialize(&idlnst,(PFNCALLBACK)DdeCallback,APPCMD_FILTERINITS| CBF_FAIL_EXECUTES|CBF_SKIP_CONNECT_CONFIRMS|CBF_FAIL_SELFCONNECTIONS| CBF_FAIL_POKES,0)) { MessageBox("DDE SERVER初始化失败!"); return FALSE; } hlnst=AfxGetApp()->m_hInstance; //创建DDE string hszApp=DdeCreateStringHandle(idlnst,szApp,0); hszTopic=DdeCreateStringHandle(idlnst,szTopic,0); for(int I=0;I<NITEM;I++) hszItem[I]=DdeCreateStringHandle(idlnst,pszItem[I],0); //注册服务; DdeNameService(idlnst,hszApp,0,DNS_REGISTER); bConnect=FALSE; SetTimer(1,1000,NULL);//开始定时; return TRUE; // return TRUE unless you set the focus to a control } void CDdedemoDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CDdedemoDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CDdedemoDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CDdedemoDlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default count++; ServerData.Format("%d",count); SetDlgItemText(IDC_STATIC1,ServerData); DdePostAdvise(idlnst,hszTopic,hszItem);//通知更新; if(!bConnect)//如果没有建立连接 { hConv=DdeConnect(idlnst,hszApp,hszTopic,NULL); //连接服务器端; if(hConv) //如果建立成功 { DWORD dwResult; bConnect=TRUE; for(int I=0;I<NITEM;I++) DdeClientTransaction(NULL,0,hConv,hszItem[I],CF_TEXT,XTYP_ADVSTART, TIMEOUT_ASYNC,&dwResult); } } CDialog::OnTimer(nIDEvent); } void CDdedemoDlg::OnDestroy() { CDialog::OnDestroy(); // TODO: Add your message handler code here KillTimer(1);//销毁定时; DdeNameService(idlnst,0,0,DNS_UNREGISTER);//注销服务; DdeFreeStringHandle(idlnst,hszApp); DdeFreeStringHandle(idlnst,hszTopic); for(int I=0;I<NITEM;I++) DdeFreeStringHandle(idlnst,hszItem[I]); DdeUninitialize(idlnst); } void CDdedemoDlg::OnChangeEdit1() { // TODO: If this is a RICHEDIT control, the control will not // send this notification unless you override the CDialog::OnInitDialog() // function and call CRichEditCtrl().SetEventMask() // with the ENM_CHANGE flag ORed into the mask. // TODO: Add your control notification handler code here UpdateData(); ServerData[0]=m_edit; DdePostAdvise(idlnst,hszTopic,hszItem[0]); //通知DDE更新该数据项目; } |