模态对话框阻塞了主线程

时间:2021-12-25 18:21:53
我是基于对话框程序的,在程序里我创建了另外一个线程,在这个另外创建的线程的Initial()里面
我用domodel创建了一个对话框,现象是,主对话框不能使用了,主线程好像被阻塞了,我已经创建另一个线程了
就算是阻塞,也应该是阻塞新创建的那个线程,怎么会是主线程?

18 个解决方案

#1


DoModal阻塞的是消息循环,主线程不能处理消息了,所以阻塞了

#2


线程应该不会被阻塞,只是DoModel是一个模态对话框,VC技术内幕里讲了,只有再响应完DoModel以后程序才一步一步的执行下一步骤,应该看你那个线程调用这个东西,那个线程才会阻塞

#3


你是以主线程中的窗口作为新线程对话框的父窗口的吧,模式对话框不会阻塞任何线程,也不会阻塞消息循环,只是他启动了一个内部的模式消息循环,父窗口的很多消息都被它屏蔽了。

#4


该回复于2009-03-12 11:14:22被版主删除

#5


引用 3 楼 jameshooo 的回复:
你是以主线程中的窗口作为新线程对话框的父窗口的吧,模式对话框不会阻塞任何线程,也不会阻塞消息循环,只是他启动了一个内部的模式消息循环,父窗口的很多消息都被它屏蔽了。

up

#6


众说纷纭 ,反正DoModel会暂停执行知道处理完这个窗口的消息..所以我个人认为 调用他的线程会一直停在这个函数上直到DoModel结束

#7


主线程没有被阻塞,是你在线程中构造对话框对象时将父窗口参数给了NULL(缺省值),这样会把主窗口作为其父窗口,模态对话框会禁用其父窗口,所以主窗口不能用了。可以在构造对话框对象时指定父窗口为CWnd::GetDesktopWindow()。

#8


up

#9


DoModal的时候,dialog会EnableWindow(hWndParent, FALSE);

#10


引用 1 楼 oyljerry 的回复:
DoModal阻塞的是消息循环,主线程不能处理消息了,所以阻塞了


up

#11


引用 7 楼 cnzdgs 的回复:
主线程没有被阻塞,是你在线程中构造对话框对象时将父窗口参数给了NULL(缺省值),这样会把主窗口作为其父窗口,模态对话框会禁用其父窗口,所以主窗口不能用了。可以在构造对话框对象时指定父窗口为CWnd::GetDesktopWindow()。

同意满天星大哥的说法

#12


调用对话框DoModal,主线程会执行到DoModal内部的消息循环处
该消息循环会屏蔽所有父窗口的界面消息
但是其他消息仍然路由到父窗口的消息处理
比如所父窗口的定时器消息依然处理

#13


当然是阻塞主线程,你以为还能阻力得了新建的线程?你domodel是在主线程调用的,不是在新建的线程中调用,谁调用就阻塞谁.

#14


模式对话框有自己的消息循环

#15


DoModal阻塞主线程,这是常识,你可以用new出来的对话框就不会出现这种事情了。

#16


创建的子线程需要有自己的消息循环,含有消息循环的线程,称之为用户界面线程,以下是示例代码:
1.创建一个子对话框类:
class CMyDlg : public CDialog
{
DECLARE_DYNAMIC(CMyDlg)

public:
CMyDlg(CWnd* pParent = NULL);   // standard constructor
virtual ~CMyDlg();

// Dialog Data
enum { IDD = IDD_MYDLG };

protected:
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    afx_msg void OnLButtonDown(UINT, CPoint);
DECLARE_MESSAGE_MAP()
};

BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()

void CMyDlg::OnLButtonDown(UINT, CPoint)
{
PostMessage(WM_CLOSE,0,0);  //发送关闭窗体命令,消毁子对话框,从而退出子线程
}

2.添加用户界面线程类
class CUIThread1 : public CWinThread
{
DECLARE_DYNCREATE(CUIThread1)

protected:
CUIThread1();           // protected constructor used by dynamic creation
virtual ~CUIThread1();

public:
virtual BOOL InitInstance();
virtual int ExitInstance();

protected:
DECLARE_MESSAGE_MAP()
};

IMPLEMENT_DYNCREATE(CUIThread1, CWinThread)



BOOL CUIThread1::InitInstance()
{
m_pMainWnd=new CMyDlg;    //将子对话框地址赋给m_pMainWnd,然后显示模态对话框
CMyDlg* pDlg=(CMyDlg*)m_pMainWnd;
pDlg->DoModal();
// TODO:  perform and per-thread initialization here
return TRUE;
}

int CUIThread1::ExitInstance()
{
// TODO:  perform any per-thread cleanup here
return CWinThread::ExitInstance();
}

BEGIN_MESSAGE_MAP(CUIThread1, CWinThread)
END_MESSAGE_MAP()

3.当主对话框需要启动用户线程时,使用如下代码:
 CWinThread* m_UIThread=AfxBeginThread(RUNTIME_CLASS(CUIThread1),THREAD_PRIORITY_BELOW_NORMAL,0,0,NULL);

#17


mark

#18


进来学习咯

#1


DoModal阻塞的是消息循环,主线程不能处理消息了,所以阻塞了

#2


线程应该不会被阻塞,只是DoModel是一个模态对话框,VC技术内幕里讲了,只有再响应完DoModel以后程序才一步一步的执行下一步骤,应该看你那个线程调用这个东西,那个线程才会阻塞

#3


你是以主线程中的窗口作为新线程对话框的父窗口的吧,模式对话框不会阻塞任何线程,也不会阻塞消息循环,只是他启动了一个内部的模式消息循环,父窗口的很多消息都被它屏蔽了。

#4


该回复于2009-03-12 11:14:22被版主删除

#5


引用 3 楼 jameshooo 的回复:
你是以主线程中的窗口作为新线程对话框的父窗口的吧,模式对话框不会阻塞任何线程,也不会阻塞消息循环,只是他启动了一个内部的模式消息循环,父窗口的很多消息都被它屏蔽了。

up

#6


众说纷纭 ,反正DoModel会暂停执行知道处理完这个窗口的消息..所以我个人认为 调用他的线程会一直停在这个函数上直到DoModel结束

#7


主线程没有被阻塞,是你在线程中构造对话框对象时将父窗口参数给了NULL(缺省值),这样会把主窗口作为其父窗口,模态对话框会禁用其父窗口,所以主窗口不能用了。可以在构造对话框对象时指定父窗口为CWnd::GetDesktopWindow()。

#8


up

#9


DoModal的时候,dialog会EnableWindow(hWndParent, FALSE);

#10


引用 1 楼 oyljerry 的回复:
DoModal阻塞的是消息循环,主线程不能处理消息了,所以阻塞了


up

#11


引用 7 楼 cnzdgs 的回复:
主线程没有被阻塞,是你在线程中构造对话框对象时将父窗口参数给了NULL(缺省值),这样会把主窗口作为其父窗口,模态对话框会禁用其父窗口,所以主窗口不能用了。可以在构造对话框对象时指定父窗口为CWnd::GetDesktopWindow()。

同意满天星大哥的说法

#12


调用对话框DoModal,主线程会执行到DoModal内部的消息循环处
该消息循环会屏蔽所有父窗口的界面消息
但是其他消息仍然路由到父窗口的消息处理
比如所父窗口的定时器消息依然处理

#13


当然是阻塞主线程,你以为还能阻力得了新建的线程?你domodel是在主线程调用的,不是在新建的线程中调用,谁调用就阻塞谁.

#14


模式对话框有自己的消息循环

#15


DoModal阻塞主线程,这是常识,你可以用new出来的对话框就不会出现这种事情了。

#16


创建的子线程需要有自己的消息循环,含有消息循环的线程,称之为用户界面线程,以下是示例代码:
1.创建一个子对话框类:
class CMyDlg : public CDialog
{
DECLARE_DYNAMIC(CMyDlg)

public:
CMyDlg(CWnd* pParent = NULL);   // standard constructor
virtual ~CMyDlg();

// Dialog Data
enum { IDD = IDD_MYDLG };

protected:
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    afx_msg void OnLButtonDown(UINT, CPoint);
DECLARE_MESSAGE_MAP()
};

BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()

void CMyDlg::OnLButtonDown(UINT, CPoint)
{
PostMessage(WM_CLOSE,0,0);  //发送关闭窗体命令,消毁子对话框,从而退出子线程
}

2.添加用户界面线程类
class CUIThread1 : public CWinThread
{
DECLARE_DYNCREATE(CUIThread1)

protected:
CUIThread1();           // protected constructor used by dynamic creation
virtual ~CUIThread1();

public:
virtual BOOL InitInstance();
virtual int ExitInstance();

protected:
DECLARE_MESSAGE_MAP()
};

IMPLEMENT_DYNCREATE(CUIThread1, CWinThread)



BOOL CUIThread1::InitInstance()
{
m_pMainWnd=new CMyDlg;    //将子对话框地址赋给m_pMainWnd,然后显示模态对话框
CMyDlg* pDlg=(CMyDlg*)m_pMainWnd;
pDlg->DoModal();
// TODO:  perform and per-thread initialization here
return TRUE;
}

int CUIThread1::ExitInstance()
{
// TODO:  perform any per-thread cleanup here
return CWinThread::ExitInstance();
}

BEGIN_MESSAGE_MAP(CUIThread1, CWinThread)
END_MESSAGE_MAP()

3.当主对话框需要启动用户线程时,使用如下代码:
 CWinThread* m_UIThread=AfxBeginThread(RUNTIME_CLASS(CUIThread1),THREAD_PRIORITY_BELOW_NORMAL,0,0,NULL);

#17


mark

#18


进来学习咯