C++ 如何通知动态数据交换(DDE)的任何更新?

C++ 如何通知动态数据交换(DDE)的任何更新?,c++,winapi,C++,Winapi,我遵循的是来自的示例,我设法能够从Excel中检索到值 现在的问题是,在这个例子中,我必须再次运行应用程序以获得必要的更新。如果Excel中有更新,我将通知我的应用程序,我如何做到这一点?你有什么建议 提前谢谢!Excel只是一个例子!不,我需要DDE而不是COM,即使它很旧 // DDEExample.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <w

我遵循的是来自的示例,我设法能够从Excel中检索到值

现在的问题是,在这个例子中,我必须再次运行应用程序以获得必要的更新。如果Excel中有更新,我将通知我的应用程序,我如何做到这一点?你有什么建议

提前谢谢!Excel只是一个例子!不,我需要DDE而不是COM,即使它很旧

// DDEExample.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h> 
#include "ddeml.h"

#define PAUSE system("pause")

HDDEDATA CALLBACK DdeCallback(UINT uType, UINT uFmt, HCONV hconv,
         HSZ hsz1, HSZ hsz2, HDDEDATA hdata,
         ULONG_PTR dwData1, ULONG_PTR dwData2)
{
 printf("uType: %d", uType);
 switch(uType)
 {
  case XTYP_REQUEST:
   printf("XTYP_REQUEST\n");
  break;

 }
 return 0;
}

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);
    }
}


int _tmain(int argc, _TCHAR* argv[])
{
 char szApp[] = "EXCEL";
 char szTopic[] = "C:\\Test.xlsx";
 char szCmd1[] = "[APP.MINIMIZE()]";
 char szItem1[] = "R1C1";  char szDesc1[] = "A1 Contains: ";


 UINT uiResult;
 DWORD m_dwDDEInstance = 0;
 uiResult = DdeInitialize(&m_dwDDEInstance, (PFNCALLBACK) &DdeCallback, APPCLASS_STANDARD|APPCMD_CLIENTONLY, 0);
 if(uiResult != DMLERR_NO_ERROR)
 {
  printf("DDE Initialization Failed: 0x%04x\n", uiResult);
  return FALSE;
 }
 printf("m_dwDDEInstance: %u\n", m_dwDDEInstance);
 //PAUSE;
 HSZ hszApp, hszTopic;
 HCONV hConv;
 hszApp = DdeCreateStringHandle(m_dwDDEInstance, szApp, 0);
 hszTopic = DdeCreateStringHandle(m_dwDDEInstance, szTopic, 0);
 hConv = DdeConnect(m_dwDDEInstance, hszApp, hszTopic, NULL);
 DdeFreeStringHandle(m_dwDDEInstance, hszApp);
 DdeFreeStringHandle(m_dwDDEInstance, hszTopic);
 if(hConv == NULL)
 {
  printf("DDE Connection Failed.\n");
 }

 DDERequest(m_dwDDEInstance, hConv, szItem1, szDesc1);
 DdeDisconnect(hConv);
 DdeUninitialize(m_dwDDEInstance);

 PAUSE;
}
//DDEExample.cpp:定义控制台应用程序的入口点。
//
#包括“stdafx.h”
#包括
#包括“ddeml.h”
#定义暂停系统(“暂停”)
HDDEDATA回调DdeCallback(UINT uType、UINT uFmt、HCONV HCONV、,
HSZ hsz1,HSZ hsz2,HDDEDATA HDDATA,
ULONG_PTR dwData1、ULONG_PTR dwData2)
{
printf(“uType:%d”,uType);
交换机(uType)
{
案例XTYP_请求:
printf(“XTYP_请求\n”);
打破
}
返回0;
}
无效DDE请求(DWORD IDIST、HCONV HCONV、char*szItem、char*sDesc)
{
HSZ hszItem=DdeCreateStringHandle(IDist,szItem,0);
HDDEDATA hData=DdeClientTransaction(NULL、0、hConv、hszItem、CF_TEXT、,
XTYP_请求,5000,空);
如果(hData==NULL)
{
printf(“请求失败:%s\n”,szItem);
}
其他的
{
结果[255];
DdeGetData(hData,(无符号字符*)szResult,255,0);
printf(“%s%s\n”,sDesc,szResult);
}
}
int _tmain(int argc,_TCHAR*argv[]
{
char szApp[]=“EXCEL”;
char szTopic[]=“C:\\Test.xlsx”;
char szCmd1[]=“[APP.MINIMIZE()]”;
char szItem1[]=“R1C1”;char szDesc1[]=“A1包含:”;
UINT-uiResult;
DWORD m_dwDDEInstance=0;
uiResult=DdeInitialize(&m_-dwDDEInstance,(PFNCALLBACK)&DdeCallback,APPCLASS_-STANDARD | APPCMD_-CLIENTONLY,0);
if(uiResult!=DMLERR\u无错误)
{
printf(“DDE初始化失败:0x%04x\n”,uiResult);
返回FALSE;
}
printf(“m_-dwDDEInstance:%u\n”,m_-dwDDEInstance);
//停顿;
HSZ hszApp、hszTopic;
HCONV-HCONV;
hszApp=DdeCreateStringHandle(m_dwDDEInstance,szApp,0);
hszTopic=DdeCreateStringHandle(m_dwDDEInstance,szTopic,0);
hConv=DdeConnect(m_dwDDEInstance,hszApp,hszTopic,NULL);
DdeFreeStringHandle(m_DwdedeInstance,hszApp);
DdeFreeStringHandle(m_dwDDEInstance,hszTopic);
if(hConv==NULL)
{
printf(“DDE连接失败。\n”);
}
DDERequest(m_dwDDEInstance、hConv、szItem1、szDesc1);
DDE断开(hConv);
DdeUninitialize(m_dwDDEInstance);
暂停;
}

这不是一个很好的答案,所以对此我很抱歉。无论如何,您是否有可能使用C#甚至C++/CLI?因为如果你可以的话,你就可以使用。所有低层管道都已准备就绪,可以执行建议循环,下载中包含了执行建议循环的示例。

来自MS Platform SDK: “客户端可以通过在对DdeClientTransaction的调用中指定XTYP\U ADVSTART事务类型来请求与服务器的热建议循环”

/#包括“stdafx.h”
#包括“windows.h”
#包括“ddeml.h”
#包括“stdio.h”
char szApp[]=“EXCEL”;
char szTopic[]=“C:\\Test.xls”;
char szCmd1[]=“[APP.MINIMIZE()]”;
char szItem1[]=“R1C1”;char szDesc1[]=“A1包含:”;
char szItem2[]=“R2C1”;char szDesc2[]=“A2包含:”;
char szItem3[]=“R3C1”;char szData3[]=“来自DDE客户端的数据”;
HSZ hszApp、hszTopic;
DWORD-idist=0;
HDDEDATA回调DdeCallback(
UINT uType,//事务类型。
UINT uFmt,//剪贴板数据格式。
HCONV HCONV,//会话的句柄。
HSZ hsz1,//字符串的句柄。
HSZ hsz2,//字符串的句柄。
HDDEDATA hdata,//全局内存对象的句柄。
DWORD dwData1,//特定于事务的数据。
DWORD dwData2)//特定于事务的数据。
{
if(uType==XTYP\u ADVDATA&&uFmt==CF\u TEXT)
{
HSZ hszItem1=DdeCreateStringHandle(IDist,szItem1,0);
HSZ hszItem2=DdeCreateStringHandle(IDist,szItem2,0);
结果[255];
如果((!DdeCmpStringHandles(hsz1,hszTopic))和(!DdeCmpStringHandles(hsz2,hszItem1)))
{
DdeGetData(hdata,(无符号字符*)szResult,255,0);
printf(“%s-%s\n”,szItem1,szResult);
}
如果(!DdeCmpStringHandles(hsz1,hszTopic))和(!DdeCmpStringHandles(hsz2,hszItem2)))
{
DdeGetData(hdata,(无符号字符*)szResult,255,0);
printf(“%s-%s\n”,szItem2,szResult);
}
}
返回0;
}
void DDEExecute(DWORD IDIST、HCONV HCONV、char*szCommand)
{
HDDEDATA hData=DdeCreateDataHandle(idist,(LPBYTE)sz命令,
lstrlen(szCommand)+1,0,NULL,CF_TEXT,0);
如果(hData==NULL){
printf(“命令失败:%s\n”,szCommand);
}
否则{
DdeClientTransaction((LPBYTE)hData,0xFFFFFFFF,hConv,0L,0,
XTYP_执行,超时_异步,空);
}
}
无效DDE请求(DWORD IDIST、HCONV HCONV、char*szItem、char*sDesc)
{
HSZ hszItem=DdeCreateStringHandle(IDist,szItem,0);
HDDEDATA hData=DdeClientTransaction(NULL、0、hConv、hszItem、CF_TEXT、,
XTYP_请求,5000,空);
如果(hData==NULL)
{
printf(“请求失败:%s\n”,szItem);
}
其他的
{
结果[255];
DdeGetData(hData,(无符号字符*)szResult,255,0);
printf(“%s%s\n”,sDesc,szResult);
}
}
无效DDEPoke(DWORD IDIST、HCONV HCONV、char*szItem、char*szData)
{
HSZ hszItem=DdeCreateStringHandle(IDist,szItem,0);
DdeClientTransaction((LPBYTE)szData,(DWORD)(lstrlen(szData)+1),
hConv、hszItem、CF_文本、,
XTYP_POKE,3000,空);
D自由串(idInst,hszItem);
}
int main(int argc,char*argv[])
{
char szCmd2[]=“[选择(\“R3C1\”)][FONT.PROPERTIES(,\“粗体\”)”;//[SAVE()][QUIT()]”;
//DDE初始化
UINT-iReturn;
iReturn=DdeInitialize(&IDist,(PFNCALLBACK)DdeCallback,
//#include "stdafx.h"
#include "windows.h"
#include "ddeml.h"
#include "stdio.h"

char szApp[] = "EXCEL";
char szTopic[] = "C:\\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";

HSZ hszApp, hszTopic;
DWORD idInst=0;

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.
{
    if(uType==XTYP_ADVDATA && uFmt==CF_TEXT)
    {
        HSZ hszItem1 = DdeCreateStringHandle(idInst, szItem1, 0);
        HSZ hszItem2 = DdeCreateStringHandle(idInst, szItem2, 0);
        char szResult[255];
        if((!DdeCmpStringHandles(hsz1, hszTopic)) && (!DdeCmpStringHandles(hsz2, hszItem1)))
        {
            DdeGetData(hdata, (unsigned char *)szResult, 255, 0);
            printf("%s - %s\n", szItem1,szResult);
        }
        else if((!DdeCmpStringHandles(hsz1, hszTopic)) && (!DdeCmpStringHandles(hsz2, hszItem2)))
        {
            DdeGetData(hdata, (unsigned char *)szResult, 255, 0);
            printf("%s - %s\n", szItem2,szResult);
        }
    }
    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 szCmd2[] = "[SELECT(\"R3C1\")][FONT.PROPERTIES(,\"Bold\")]";//[SAVE()][QUIT()]";

    //DDE Initialization
    UINT iReturn;
    iReturn = DdeInitialize(&idInst, (PFNCALLBACK)DdeCallback,
                            APPCLASS_STANDARD | APPCMD_CLIENTONLY, 0 );
    if (iReturn!=DMLERR_NO_ERROR)
    {
        printf("DDE Initialization Failed: 0x%04x\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: 0x%04x\n", (UINT)hRet);
        Sleep(1500); DdeUninitialize(idInst);
        return 0;
    }
    Sleep(1000);

    //DDE Connect to Server using given AppName and topic.
    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);

    HSZ hszItem = DdeCreateStringHandle(idInst, szItem1, 0);
    DdeClientTransaction(NULL,0,hConv,hszItem,CF_TEXT,
                                 XTYP_ADVSTART,5000 , NULL);


BOOL bRet;
MSG msg;

while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
    if (bRet == -1)
    {
        // handle the error and possibly exit
    }
    else
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

    //DDE Disconnect and Uninitialize.
    DdeDisconnect(hConv);
    DdeUninitialize(idInst);

    Sleep(3000);
    return 1;
}