VC DDE(Dynamic Data Exchange)与EXCEL连接
来源:转载 2016-01-20 13:16:10项目中遇到需要通过VC数据处理,并实时监测中间以及最终数据的方式,由于数据量大,并且现有的WINDOWS下现实界面都不能很好的实时显示。WINDOWS DDE功能可能实现项目这个需求。项目中遇到需要通过VC数据处理,并实时监测中间以及最终数据的方式,由于数据量大,并且现有的WINDOWS下现实界面都不能很好的实时显示。我在网上查了一下,发现WINDOWS DDE功能可能实现项目这个需求。DDE,中文名叫动态数据交换,是基于WINDOWS系统开发的一种消息传输的通信方案。花了半天时间研究了下,做了个案例,VC6.0下调试通过,很开心。作为一个产品经理,为产品设计搭建好平台,有人的平台,有技术平台,一切目标为了高效的做好产品。该C++控制台程序案例如下:// smdata.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include "windows.h"#include <string.h>#include "ddeml.h"#include "stdio.h"HDDEDATA CALLBACK DdeCallback( UINT uType, // Transaction type. UINT uFmt, // Clipboard data format. HCONV hconv, // Handle to the conversation. HSZ hsz1, // Handle to a string. HSZ hsz2, // Handle to a string. HDDEDATA hdata, // Handle to a global memory object. DWORD dwData1, // Transaction-specific data. DWORD dwData2) // Transaction-specific data.{ return 0;}void DDEExecute(DWORD idInst, HCONV hConv, char* szCommand){ HDDEDATA hData = DdeCreateDataHandle(idInst, (LPBYTE)szCommand, lstrlen(szCommand)+1, 0, NULL, CF_TEXT, 0); if (hData==NULL) { printf("Command failed: %s\n", szCommand); } else { DdeClientTransaction((LPBYTE)hData, 0xFFFFFFFF, hConv, 0L, 0, XTYP_EXECUTE, TIMEOUT_ASYNC, NULL); }}void DDERequest(DWORD idInst, HCONV hConv, char* szItem, char* sDesc){ HSZ hszItem = DdeCreateStringHandle(idInst, szItem, 0); HDDEDATA hData = DdeClientTransaction(NULL,0,hConv,hszItem,CF_TEXT, XTYP_REQUEST,5000 , NULL); if (hData==NULL) { printf("Request failed: %s\n", szItem); } else { char szResult[255]; DdeGetData(hData, (unsigned char *)szResult, 255, 0); printf("%s%s\n", sDesc, szResult); }}void DDEPoke(DWORD idInst, HCONV hConv, char* szItem, char* szData){ HSZ hszItem = DdeCreateStringHandle(idInst, szItem, 0); DdeClientTransaction((LPBYTE)szData, (DWORD)(lstrlen(szData)+1), hConv, hszItem, CF_TEXT, XTYP_POKE, 3000, NULL); DdeFreeStringHandle(idInst, hszItem);}int main(int argc, char* argv[]){ char szApp[] = "EXCEL"; char szTopic[] = "C:\\Test.xls"; //char szTopic[] = "E:\\project\aTouch\software\tmp\Test.xls"; char szCmd1[] = "[APP.MINIMIZE()]"; char szItem1[] = "R1C1"; char szDesc1[] = "A1 Contains: "; char szItem2[] = "R2C1"; char szDesc2[] = "A2 Contains: "; char szItem3[] = "R3C1"; char szData3[] = "Data from DDE Client"; char szItem4[] = "R3C1"; char szData4[] = "Hello World!"; char szItem5[] = "R3C1"; char szData5[16] = "0"; //char szCmd2[] = "[SELECT(\"R3C1\")][FONT.PROPERTIES(,\"Bold\")][SAVE()][QUIT()]"; char szCmd2[] = "[SELECT(\"R3C1\")][FONT.PROPERTIES(,\"Bold\")]"; char szCmd3[] = "[SELECT(\"R3C1\")][FONT.PROPERTIES(,\"Bold\")]"; int i,j,k; char string[16]; //DDE Initialization DWORD idInst=0; UINT iReturn; iReturn = DdeInitialize(&idInst, (PFNCALLBACK)DdeCallback, APPCLASS_STANDARD | APPCMD_CLIENTONLY, 0 ); if (iReturn!=DMLERR_NO_ERROR) { printf("DDE Initialization Failed: 0xx\n", iReturn); Sleep(1500); return 0; } //Start DDE Server and wait for it to become idle. HINSTANCE hRet = ShellExecute(0, "open", szTopic, 0, 0, SW_SHOWNORMAL); if ((int)hRet < 33) { printf("Unable to Start DDE Server: 0xx\n", hRet); Sleep(1500); DdeUninitialize(idInst); return 0; } Sleep(1000); //DDE Connect to Server using given AppName and topic. HSZ hszApp, hszTopic; HCONV hConv; hszApp = DdeCreateStringHandle(idInst, szApp, 0); hszTopic = DdeCreateStringHandle(idInst, szTopic, 0); hConv = DdeConnect(idInst, hszApp, hszTopic, NULL); DdeFreeStringHandle(idInst, hszApp); DdeFreeStringHandle(idInst, hszTopic); if (hConv == NULL) { printf("DDE Connection Failed.\n"); Sleep(1500); DdeUninitialize(idInst); return 0; } //Execute commands/requests specific to the DDE Server. DDEExecute(idInst, hConv, szCmd1); DDERequest(idInst, hConv, szItem1, szDesc1); DDERequest(idInst, hConv, szItem2, szDesc2); DDEPoke(idInst, hConv, szItem3, szData3); DDEExecute(idInst, hConv, szCmd2); for(i=0;i<65536;i++){for(j=0;j<1000;j++) {;}} DDEPoke(idInst, hConv, szItem4, szData4); DDEExecute(idInst, hConv, szCmd3); for(i=0;i<65536;i++){for(j=0;j<1000;j++) {;}} for(k=0;k<20;k++) { itoa(k, string, 10); printf("%s \n", string); strcpy(szData5, string); DDEPoke(idInst, hConv, szItem5, szData5); DDEExecute(idInst, hConv, szCmd3); for(i=0;i<65536;i++){for(j=0;j<1000;j++) {;}} } //DDE Disconnect and Uninitialize. DdeDisconnect(hConv); DdeUninitialize(idInst); Sleep(3000); return 1;}C++Copy运行结果截图:
上图中A3这个单元格内容是实时变化的。Excel相当于数据展示的一个客户端,当然在Excel中还可以添加公式进行更复杂的计算、数据展示。