VC DDE(Dynamic Data Exchange)与EXCEL连接

转载

项目中遇到需要通过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;
}
运行结果截图:

上图中A3这个单元格内容是实时变化的。Excel相当于数据展示的一个客户端,当然在Excel中还可以添加公式进行更复杂的计算、数据展示。

VC DDE 动态数据交换

分享到:
评论加载中,请稍后...
创APP如搭积木 - 创意无限,梦想即时!
回到顶部