DDE客户端的命令传递
DDE除可在应用程序之间传送信息之外,也允许从客户向服务器传送可执行命令。客户可通过向服务器邮寄WM_DDE_EXECUTE消息来为其传递命令。消息参数lParam的高字包含了命令字符串的全局共享内存块句柄:
// 服务器数据项内容 CString sCommand = "COMMAND A"; // 分配DDEDATA格式化的全局共享内存块 HGLOBAL hCommand = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (LONG)sCommand.GetLength() + 1); // 锁定内存块地址 LPSTR lpCommand = (LPSTR)GlobalLock(hCommand); // 填充数据项内容 ::strcpy(lpCommand, sCommand); // 解锁内存块 GlobalUnlock(hCommand); // 获取当前窗口的安全句柄 HWND hwndClient = GetSafeHwnd(); // 组合消息参数lParam LONG lDataPack = PackDDElParam(WM_DDE_EXECUTE, 0, (UINT)hCommand); // 发出远程命令消息 ::PostMessage(m_hwndServer, WM_DDE_EXECUTE, (WPARAM)hwndClient, (LPARAM)lDataPack); // 释放内存 GlobalFree(hCommand); |
DDE服务器对远程命令的执行
按照DDE协议规定,服务器窗口在收到WM_DDE_EXECUTE消息后要对命令字符串进行分析,然后再执行之。服务器还要将根据指定命令串的执行结果向客户返回WM_DDE_ACK应答消息。这里与前面的应答消息不同,在邮寄WM_DDE_ACK消息时要再次使用从WM_DDE_EXECUTE消息中传递过来的全局共享内存块句柄。下面给出服务器窗口对WM_DDE_EXECUTE消息的响应代码:
// lParam消息的低、高字 UINT uLo, uHi; // 对消息参数lParam进行解包 UnpackDDElParam(WM_DDE_EXECUTE, lParam, &uLo, &uHi); // 恢复出全局共享内存块句炳 HGLOBAL hCommand = (HGLOBAL)uHi; // 锁定内存 LPSTR lpCommand = (LPSTR)GlobalLock(hCommand); // 解锁内存 GlobalUnlock(hCommand); if (CString(lpCommand) == "COMMAND A") { // 执行命令A的相关操作 AfxMessageBox("命令A被执行"); // 组合消息参数lParam LONG lDataPack = PackDDElParam(WM_DDE_ACK, 0x8000, (UINT)hCommand); // 发出远程命令消息 ::PostMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)m_hwndServer, (LPARAM)lDataPack); } else { // 组合消息参数lParam LONG lDataPack = PackDDElParam(WM_DDE_ACK, 0, (UINT)hCommand); // 发出远程命令消息 ::PostMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)m_hwndServer, (LPARAM)lDataPack); } // 释放内存 GlobalFree(hCommand); |
小结
动态数据交换对远程命令的执行比其在应用程序间传送数据的应用更为重要,Windows操作系统及不少软件均留有此类接口(作为DDE服务器),在应用程序中可以通过从DDE客户端发出远程命令而可以非常方便的执行外部软件的相关命令和功能,比如可以命令Word新建一个文档窗口等。本文所述代码在Windows 2000 Professional下由Microsoft Visual C++ 6.0编译通过。
|