如何在线程里控制进度条?

louifox 2004-09-11 02:11:28
UINT CEquipTreeView::ProgressThreadFunc(LPVOID pParam)
{
while(1)
{
::WaitForSingleObject(hEvent,INFINITE);
if(bThreadExit)
{
((CInitProgressDlg*)pParam)->m_Progress.SetPos(100);
break;
}
((CInitProgressDlg*)pParam)->m_Progress.SetPos(nProgress);


};
return 0;
CInitProgressDlg是非模态对话框,我想在一个线程里控制它的进度条,运行时,对话框出来了,可是进度条根本就不动,调试时发现nProgress的值是增加的。
...全文
1057 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhangy211 2004-10-08
  • 打赏
  • 举报
回复
up
janezhou 2004-09-22
  • 打赏
  • 举报
回复
up
roger_ding 2004-09-12
  • 打赏
  • 举报
回复
1. 确认发送的窗口句柄没错
2. 确认发送的nProgress是递增的
3. 在“((CInitProgressDlg*)pParam)->m_Progress.SetPos(nProgress);”语句的下面添加:
((CInitProgressDlg*)pParam)->m_Progress.UpdateWindow(); 试试看
louifox 2004-09-11
  • 打赏
  • 举报
回复
to: laiyiling(最熟悉的陌生人)
试过了,在主线程里发消息是成功的
Kudeet 2004-09-11
  • 打赏
  • 举报
回复
先试试不在线程里发消息!看看你的自定义消息是否成功了。然后再看是不是线程的问题
louifox 2004-09-11
  • 打赏
  • 举报
回复
消息映射是添加了的;
BEGIN_MESSAGE_MAP(CInitProgressDlg, CDialog)
//{{AFX_MSG_MAP(CInitProgressDlg)
ON_WM_DESTROY()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_USER_THREAD_SETPOS, OnThreadSetPos)
END_MESSAGE_MAP()
huwei001982 2004-09-11
  • 打赏
  • 举报
回复
你肯定没有添加消息映射

在CPP文件的 消息映射中, 添加一行

ON_MESSAGE(WM_USER_THREAD_SETPOS, OnThreadSetPos)
louifox 2004-09-11
  • 打赏
  • 举报
回复
...............
hEvent = ::CreateEvent(NULL,FALSE,FALSE,NULL);
bThreadExit = FALSE;
AfxBeginThread (ProgressThreadFunc,pDlg->GetSafeHwnd());
...........................
UINT CEquipTreeView::ProgressThreadFunc(LPVOID pParam)
{
while(1)
{
::WaitForSingleObject(hEvent,INFINITE);
if(bThreadExit)
{
::PostMessage((HWND)pParam, WM_USER_THREAD_SETPOS, 100, 0L);
::Sleep(200);
break;
}
::PostMessage((HWND)pParam, WM_USER_THREAD_SETPOS, nProgress, 0L);
::Sleep(200);

};
return 0;
}
...................
LRESULT CInitProgressDlg::OnThreadSetPos(WPARAM wParam,LPARAM lParam)
{
m_Progress.SetPos(wParam);
return 0;
}
................
我把程序改成上面这个样子,并在OnThreadSetPos里设置断点,发现程序根本就没有运行到断点处。难道我的自定义消息没有发送过去吗?
huwei001982 2004-09-11
  • 打赏
  • 举报
回复
线程内发消息;

用 PostMessage
oyljerry 2004-09-11
  • 打赏
  • 举报
回复
通过线程把process的指针传递进去看可否,或者传递句柄进去,然后从线程中传递消息出来,直接由对话框处理
DentistryDoctor 2004-09-11
  • 打赏
  • 举报
回复
在线程内调CProgressCtrl.SetPos,容易造成死锁UI线程和工作线程可以可时需要刷新显示
如果楼上各位所说用消息。记住,还得用PostMessage,用SendMessage与直接调其方法无异,还是会造成死锁的。
memory_xj 2004-09-11
  • 打赏
  • 举报
回复
必须用消息才行。
1、在InitProgressDlg.h中定义自定义消息:
#ifndef WM_UPDATE_DLG_POS //更新进度条位置和消息
#define WM_UPDATE_DLG_POS WM_USER + 100
#endif
2、在InitProgressDlg.cpp文件的END_MESSAGE_MAP()之前加入以下代码:
ON_MESSAGE(WM_UPDATE_DLG_POS, OnUpdateProgressPos)
//更新进度条位置的消息响应消息函数
3、在InitProgressDlg.h文件中DECLARE_MESSAGE_MAP()之前加入以下代码:
afx_msg LRESULT OnUpdateProgressPos(WPARAM wp, LPARAM lp);
4、在InitProgressDlg.cpp文件中添加消息响应函数实体。
LRESULT CInitProgressDlg::OnUpdateProgressPos(WPARAM wp, LPARAM lp)
{
//传入的wp即是计算过后当前进度条的位置
m_Progress.SetPos((int)wp);
........
}
5、在线程中可以这样:
UINT CEquipTreeView::ProgressThreadFunc(LPVOID pParam)
{
//定义一个计算出来进度条位置
DWORD dProssPos = 0;
CInitProgressDlg *pDlg = (CInitProgressDlg *)pParam; //传入的对话框指针
......各种操作,同时设置dProssPos的值
....需要设置进度条发送消息
::SendMessage(pDlg->GetSafeHwnd(), WM_UPDATE_DLG_POS, dProssPos, NULL);
.......
}
Pipi0714 2004-09-11
  • 打赏
  • 举报
回复
直接传入process的指针
刷新一下看看,在vc++6.0技术内幕上有个这样的例子
huwei001982 2004-09-11
  • 打赏
  • 举报
回复
To: lianglp() ( )
你的方法太复杂了

其实按照楼主的方法来做就可以了, 如果不行, 加上

((CInitProgressDlg*)pParam)->m_Progress.SetPos(nProgress);
MSG msg;
if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DiapatchMessage(&msg);
}

当然, 更好的办法是用发送消息来完成
lianglp 2004-09-11
  • 打赏
  • 举报
回复
用PostMessage()发送消息到主线程(可以是一个自定义消息),当主线程中接受到消息后用SetPos()方法设置进度条的位置
oyljerry 2004-09-11
  • 打赏
  • 举报
回复
可以把数据库查询也放到一个线程中去,这样,主线程应该就可以处理的过来了
rwdx 2004-09-11
  • 打赏
  • 举报
回复
up
saucer 2004-09-11
  • 打赏
  • 举报
回复
那样的话,你的编码里应该pump the message queue from time to time, 参考

http://www.thecodeproject.com/threads/xthread.asp
flyelf 2004-09-11
  • 打赏
  • 举报
回复
用发送消息来控制
SendDlgItemMessage
或者给对话框发送控制消息,让对话框来控制进度条的进度
yuantao 2004-09-11
  • 打赏
  • 举报
回复
消息队列是按照线程来的,不同的线程,有不同的消息队列

要想给别的线程发送消息,可以用postthreadmessage

PostThreadMessage
The PostThreadMessage function posts a message to the message queue of the specified thread. It returns without waiting for the thread to process the message.

BOOL PostThreadMessage(
DWORD idThread, // thread identifier
UINT Msg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
加载更多回复(10)

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧