MFC设置状态栏文本导致崩溃的原因

⌚Time: 2023-11-28 00:51:08

👨‍💻Author: Jack Ge

问题和原因

本人在类A使用多线程执行操作并且调用了类B的设置状态栏文本的函数,导致崩溃

类A


void A::distribute_n_start_msg(){

    ((B*)m_parent)->received_msg_n_start();

}

类B


void B::received_msg_n_start(){

    m_statusBar.SetPaneText(2, text);

}

原因就是MFC不能多线程操作控件,解决办法就是不在其它线程中对状态栏进行操作。

解决办法

如果必须要在其它线程操作,解决办法本人想到两个,两种办法都”过滤"掉了线程:

1.消息机制

使用MFC原生的用户自定义消息

MFC提供了CWnd类中的PostMessage和SendMessage方法,可以向窗口发送自定义消息。要使用这些方法,需要先定义一个整型常量作为消息ID,例如:


#define WM_MY_CUSTOM_MSG WM_USER+1

然后,在窗口类的消息映射表中添加对应的处理函数:


BEGIN_MESSAGE_MAP(CMyWindow, CWnd)

    ON_MESSAGE(WM_MY_CUSTOM_MSG, OnMyCustomMsg)

END_MESSAGE_MAP()



LRESULT CMyWindow::OnMyCustomMsg(WPARAM wParam, LPARAM lParam)

{

    // 处理自定义消息

    m_statusBar.SetPaneText(2, text);

    return 0;

}

在需要发送自定义消息的地方,使用PostMessage或SendMessage方法:


// 发送自定义消息

PostMessage(WM_MY_CUSTOM_MSG, 0, 0);

在处理自定义消息的函数中,可以根据需要使用wParam和lParam参数传递数据。

2.定时器

使用定时器,在定时器中操作控件




void B::received_msg_n_start(){

    SetTimer(1,100,NULL);

}



void B::OnTimer(UINT_PTR nIDEvent)

{

    // TODO:  在此添加消息处理程序代码和/或调用默认值

    switch (nIDEvent)

    {

    case 1:

        ...

        m_statusBar.SetPaneText(2, text);

        KillTimer(1);

        break;

    default:

        break;

    }

    CDialogEx::OnTimer(nIDEvent);

}