如何通过PostMessage发送字符串?

发布于 2024-08-02 13:36:47 字数 547 浏览 10 评论 0原文

在我的应用程序中,我想从不同的线程向对话框发送消息。 我想将 std::exception 派生类引用传递给对话框。

像这样的事情:

try {
       //do stuff
}
catch (MyException& the_exception) {
    PostMessage(MyhWnd, CWM_SOME_ERROR, 0, 0); //send the_exception or the_exception.error_string() here
}

the_exception.error_string() 的 the_exception.error_string() 中的错误

LPARAM CMyDlg::SomeError(WPARAM, LPARAM)
{
    show_error( ?????
    return 0;
}

我想在对话框中接收消息并显示传递 std::string 我想使用 PostMessage 也可以。

Inside my app, I want to send a message to a dialog from a different thread.
I want to pass an std::exception derived class reference to the dialog.

Something like this:

try {
       //do stuff
}
catch (MyException& the_exception) {
    PostMessage(MyhWnd, CWM_SOME_ERROR, 0, 0); //send the_exception or the_exception.error_string() here
}

I want to receive the message in my dialog and show the error that is in the_exception.error_string()

LPARAM CMyDlg::SomeError(WPARAM, LPARAM)
{
    show_error( ?????
    return 0;
}

passing the std::string the_exception.error_string() using PostMessage would also be ok, I guess.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

还在原地等你 2024-08-09 13:36:47

您无法在 PostMessage 中传递字符串的地址,因为该字符串可能是堆栈上的线程本地的。当另一个线程拾取它时,它可能已经被销毁了。

相反,您应该通过 new 创建一个新的字符串或异常对象,并将其地址传递给另一个线程(通过 PostMessage 中的 WPARAM 或 LPARAM 参数)。然后另一个线程拥有该对象并负责销毁它。

以下是一些示例代码,展示了如何完成此操作:

try
{
    // do stuff
}
catch (const MyException& the_exception)
{
    PostMessage(myhWnd, CWM_SOME_ERROR, 0, new std::string(the_exception.error_string));
}


LPARAM CMyDlg::SomeError(WPARAM, LPARAM lParam)
{
    // Wrap in a unique_ptr so it is automatically destroyed.
    std::unique_ptr<std::string> msg = reinterpret_cast<std::string*>(lParam);

    // Do stuff with message

    return 0;
}

You can't pass the address of the string in PostMessage, since the string is probably thread-local on the stack. By the time the other thread picks it up, it could have been destroyed.

Instead, you should create a new string or exception object via new and pass its address to the other thread (via the WPARAM or LPARAM parameter in PostMessage.) The other thread then owns the object and is responsible for destroying it.

Here is some sample code that shows how this could be done:

try
{
    // do stuff
}
catch (const MyException& the_exception)
{
    PostMessage(myhWnd, CWM_SOME_ERROR, 0, new std::string(the_exception.error_string));
}


LPARAM CMyDlg::SomeError(WPARAM, LPARAM lParam)
{
    // Wrap in a unique_ptr so it is automatically destroyed.
    std::unique_ptr<std::string> msg = reinterpret_cast<std::string*>(lParam);

    // Do stuff with message

    return 0;
}
醉酒的小男人 2024-08-09 13:36:47

只要您在进程中,只需传递 void* 指针并注意对象生命周期就足够了。

如果是 SendMessage,您可以将其作为 void* 转换在 LPARAM 中传递,然后客户端将其取消转换回字符串类型。由于 SendMessage 是同步,因此您是安全的:

如果指定的窗口是由
调用线程,窗口
过程立即被调用为
子程序。如果指定窗口
是由不同的线程创建的,
系统切换到该线程并且
调用适当的窗口
程序。之间发送的消息
仅当以下情况时才处理线程
接收线程执行消息
检索码。发送线程是
阻塞直到接收线程
处理消息

如果您想使用 PostMessage,那么您必须进行显式切换,因为该调用是异步的:在堆上创建字符串的副本,并通过调用 PostMessage 您已将删除责任传递给 calee (对话框)。

如果你超出了进程(MyhWnd 属于不同的进程),那么情况就完全不同了,你必须将你的消息整理成类似全局原子的东西。

As long as you are within a process simply passing a void* pointer and some care on object lifetime are enough.

If is SendMessage you can pass it in LPARAM as a void* cast, and the client uncast it back to your string type. Because SendMessage is synchronous, you are safe:

If the specified window was created by
the calling thread, the window
procedure is called immediately as a
subroutine. If the specified window
was created by a different thread, the
system switches to that thread and
calls the appropriate window
procedure. Messages sent between
threads are processed only when the
receiving thread executes message
retrieval code. The sending thread is
blocked until the receiving thread
processes the message

If you want to use PostMessage then you'll have to do an explicit hand off because the call is asynchronous: make a copy of the string on the heap and by calling the PostMessage you have passed the delete responsability to the calee (the dialog).

If you go out of process (MyhWnd belongs to a different process) then is a whole different story and you'll have to marshal your message into something like a global atom.

烟雨扶苏 2024-08-09 13:36:47

只要您知道您的窗口(或 CMyDlg 的实例)在发布消息后仍然存在,您就可以简单地将错误字符串存储在成员变量中,并在消息处理程序中从中读取。

As long as you know that your window (or instance of CMyDlg) will still be around after posting the message you could simply store the error string in a member variable and read from this in your message handler.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文