0

我有两个 Windows 应用程序。第一个是 Windows 窗体应用程序。第二个是控制台应用程序。我必须从控制台应用程序向表单应用程序发送一条消息。我注册了广播消息并使用 ::PostMessage 函数能够将数字消息发送到表单应用程序。但我无法发送字符串消息。请在下面找到我的代码:-

// Sending Message (Console Application)
#define RT_UI_MSG      (WM_USER+1)
UINT msg_id = RegisterWindowMessage("Test-UI");
LPTSTR lpszString = "Hello";
COPYDATASTRUCT cds;
cds.dwData = 1; // can be anything
cds.cbData = sizeof(TCHAR) * (_tcslen(lpszString) + 1);
cds.lpData = &lpszString;
::PostMessage(HWND_BROADCAST, msg_id, WM_COPYDATA, (LPARAM)(LPVOID)&cds);
// Receiving Message (Forms Application)
BEGIN_MESSAGE_MAP(CRTUIDlg, CDialogEx)
   ON_WM_PAINT()
   ON_WM_QUERYDRAGICON()
   ON_BN_CLICKED(IDOK, &CRTUIDlg::OnBnClickedOk)
   ON_REGISTERED_MESSAGE(temp, OnRTUIMsg)
   ON_BN_CLICKED(IDC_BUTTON1, &CRTUIDlg::OnBnClickedButton1)
END_MESSAGE_MAP()

UINT temp = RegisterWindowMessage(L"Test-UI");
LRESULT CRTUIDlg::OnRTUIMsg(WPARAM wParam, LPARAM lParam)
{
    COPYDATASTRUCT* pcds = (COPYDATASTRUCT*)lParam;
    if (pcds->dwData == 1)
    {
        LPCTSTR lpszString = (LPCTSTR)(pcds->lpData);
        // do something with lpszString...
    }
    return 0;
}

请帮助我了解我做错了什么并使其正常工作

4

2 回答 2

4

没有PostMessage办法WM_COPYDATA。系统需要知道何时释放用于编组数据的内部缓冲区。这仅在您发送时才知道,而不是在您发布消息时。

请参阅为什么我不能 PostMessage WM_COPYDATA 消息,但我可以 SendMessageTimeout 它有一个微小的超时?

于 2017-06-28T08:31:39.443 回答
0

WM_COPYDATA 声明如下:

“传递的数据不得包含指针或其他对接收数据的应用程序无法访问的对象的引用。”

但是您将指向源应用程序堆 (lpszString) 的指针包含到不受支持的结构中,因为目标应用程序无法访问源应用程序的堆。WM_COPYDATA 将按原样复制该指针,它不会复制指针引用的字符串。

我建议查看 WM_COPYDATA 中的示例,该示例似乎可以满足您的需要,但不是从堆中传递字符串,而是使用 char 数组将字符串复制到堆栈中。

这是示例的链接: https ://msdn.microsoft.com/en-us/library/windows/desktop/ms649009(v=vs.85).aspx

于 2017-05-30T14:09:25.610 回答