方法:
BOOL CDlgCustomer::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
((CMainFrame*)AfxGetMainWnd())->OnProgress();
//OnProgress()执行SetTimer(1,1000,NULL);
//以下是打开数据库及相关操作
m_pBankSet=new CBankSet;
m_pBankSet->m_strSort="BANK_ID";
if (m_pBankSet->IsOpen())
m_pBankSet->Close();
m_pBankSet->Open();
if (!m_pBankSet->IsBOF())
m_pBankSet->MoveFirst();
while (!m_pBankSet->IsEOF())
{//将bank表中内容逐条显示在combobox中
m_comboBank.AddString(m_pBankSet->m_BANK_NAME);
m_pBankSet->MoveNext();
}
if (m_pBankSet->IsOpen())
m_pBankSet->Close();
if (m_pBankSet)
delete m_pBankSet;
((CMainFrame*)AfxGetMainWnd())->EndProgress();
//EndProgress执行m_Progress.SetPos(100);指向进度条末端, KillTimer(1);
return TRUE;
}
void CMainFrame::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
if (nIDEvent==1)
{
m_Progress.StepIt();
}
}
理论上应该SetTimer后进度条就一直增长,直到执行EnProgress(),这时候InitDialog完毕,进度条也指向末端。
但问题是,在执行打开数据库的时候,进度条一直没有动:(当我把网线拔了后,发现进度条要到弹出输入数据库DSN,UID,PWD的那个对话框(因为连接不上,所以弹出该对话框)后,才开始增长。
也就是说并不是一SetTimer就创建新进程,可以执行OnTimer,有时候几十秒以后进度条才开始动。为什么会这样?
大侠们快来帮忙啊。或者提供你们解决该类问题的方法。
马上给分,不够可以再加!!!
27 个解决方案
#1
SetTimer建立定时器后会发送WM_TIMER消息,但问题是该消息仅仅是放到消息队列中排队,并不会马上被执行,因为消息对列中可能还有其它消息等待执行,你可以试试通过建立另外一个线程的方式来实现你的目的。
#2
去掉nIDEvent == 1试试;
OnTimer一般是第一个Click后才执行,如果你定义Click时间是一秒,它就在定时器创建后一秒被激活
OnTimer一般是第一个Click后才执行,如果你定义Click时间是一秒,它就在定时器创建后一秒被激活
#3
就算排队一般时间也不会很长,计数器的优先级还是很高的,属于很重要(宝贵)的资源,所以msdn要求尽可能少用
#4
同意dominolili(domino) ,settimer后并不会立即进入ontimer
#5
你的主线程正在执行 OnInitDialog () 不可能去执行onTimer.
你只能直接调用m_Progress.StepIt();
你只能直接调用m_Progress.StepIt();
#6
SetTimer建立定时器后会发送WM_TIMER消息,但问题是该消息仅仅是放到消息队列中排队,并不会马上被执行,因为消息对列中可能还有其它消息等待执行,你可以试试通过建立另外一个线程的方式来实现你的目的。
#7
same to what sans(sans) said
#8
to dominolili:并不是第一个Click后才执行的,有时候要过几十秒。好像必须执行打开数据库的操作后才执行。
我的本意是如果打开数据库比较慢(或者发生网络故障),有个进度条可以显示进度,不至于让人以为死机了。但是,如果Init完成后再显示,就没有达到预期效果了。
建立另一个线程具体怎么做,能不能给个例子。
谢谢!!!
我的本意是如果打开数据库比较慢(或者发生网络故障),有个进度条可以显示进度,不至于让人以为死机了。但是,如果Init完成后再显示,就没有达到预期效果了。
建立另一个线程具体怎么做,能不能给个例子。
谢谢!!!
#9
昨天(13日)VC知识论坛中就有(Panic的),你自己去看吧!
#10
没搜索到啊。题目叫什么名字?
#11
先调用一次过程
settimer
ontimer()
{
调用过程
}
settimer
ontimer()
{
调用过程
}
#12
To ClickMore 你误会了。我知道Ontimer 要一个Click后执行的。
但是好像打开数据库的优先级比Ontimer大。所以,总是要先执行完打开数据库后才开始计数的。 照理应该0.1秒后开始计数,但是有时候要过几十秒,等数据库操作完毕后才开始计数。
但是好像打开数据库的优先级比Ontimer大。所以,总是要先执行完打开数据库后才开始计数的。 照理应该0.1秒后开始计数,但是有时候要过几十秒,等数据库操作完毕后才开始计数。
#13
如何通过进程控制MainFrame中的进度条啊?我用
HWND hWnd=GetSafeHwnd();
AfxBeginThread(ThreadProc,hWnd,THREAD_PRIORITY_NORMAL);
UINT ThreadProc(LPVOID param)
{
while (((CMainFrame*)AfxGetMainWnd())->m_Progress.GetPos()<90)
{
((CMainFrame*)AfxGetMainWnd())->m_Progress.StepIt();
Sleep(100);
}
return 0;
}
会出错。怎么用进程对对话框中的控件进行操作啊?Help!!!!
HWND hWnd=GetSafeHwnd();
AfxBeginThread(ThreadProc,hWnd,THREAD_PRIORITY_NORMAL);
UINT ThreadProc(LPVOID param)
{
while (((CMainFrame*)AfxGetMainWnd())->m_Progress.GetPos()<90)
{
((CMainFrame*)AfxGetMainWnd())->m_Progress.StepIt();
Sleep(100);
}
return 0;
}
会出错。怎么用进程对对话框中的控件进行操作啊?Help!!!!
#14
工作线程不要直接调用另外线程的界面,最好向界面发送一个消息,在界面的消息处理中做事情。
UINT ThreadProc(LPVOID param)
{
while (((CMainFrame*)AfxGetMainWnd())->m_Progress.GetPos()<90)
{
((CMainFrame*)AfxGetMainWnd())->PostMessage(WM_USER+1,0,0);
Sleep(100);
}
return 0;
}
然后在MainFrame中响应WM_USER+1,调用m_Progress.StepIt();
UINT ThreadProc(LPVOID param)
{
while (((CMainFrame*)AfxGetMainWnd())->m_Progress.GetPos()<90)
{
((CMainFrame*)AfxGetMainWnd())->PostMessage(WM_USER+1,0,0);
Sleep(100);
}
return 0;
}
然后在MainFrame中响应WM_USER+1,调用m_Progress.StepIt();
#15
但是在执行(((CMainFrame*)AfxGetMainWnd())->m_Progress.GetPos()的时候就出错了。
#16
最好的效果是采用多现成;
或者是控件
或者是控件
#17
发现错误在哪里了。
竟然在HWND hWnd=GetSafeHwnd();
AfxBeginThread(ThreadProc,hWnd,THREAD_PRIORITY_NORMAL);//这一句出错
CWinThread* AFXAPI AfxBeginThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam,
int nPriority, UINT nStackSize, DWORD dwCreateFlags,
LPSECURITY_ATTRIBUTES lpSecurityAttrs)
{
#ifndef _MT
pfnThreadProc;
pParam;
nPriority;
nStackSize;
dwCreateFlags;
lpSecurityAttrs;
return NULL;
#else
ASSERT(pfnThreadProc != NULL);
CWinThread* pThread = DEBUG_NEW CWinThread(pfnThreadProc, pParam);
ASSERT_VALID(pThread);
if (!pThread->CreateThread(dwCreateFlags|CREATE_SUSPENDED, nStackSize,
lpSecurityAttrs))
{
pThread->Delete();
return NULL;
}
VERIFY(pThread->SetThreadPriority(nPriority));
if (!(dwCreateFlags & CREATE_SUSPENDED))
VERIFY(pThread->ResumeThread() != (DWORD)-1);//调试到这个地方出错,不知道为什么。
return pThread;
#endif //!_MT)
}
竟然在HWND hWnd=GetSafeHwnd();
AfxBeginThread(ThreadProc,hWnd,THREAD_PRIORITY_NORMAL);//这一句出错
CWinThread* AFXAPI AfxBeginThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam,
int nPriority, UINT nStackSize, DWORD dwCreateFlags,
LPSECURITY_ATTRIBUTES lpSecurityAttrs)
{
#ifndef _MT
pfnThreadProc;
pParam;
nPriority;
nStackSize;
dwCreateFlags;
lpSecurityAttrs;
return NULL;
#else
ASSERT(pfnThreadProc != NULL);
CWinThread* pThread = DEBUG_NEW CWinThread(pfnThreadProc, pParam);
ASSERT_VALID(pThread);
if (!pThread->CreateThread(dwCreateFlags|CREATE_SUSPENDED, nStackSize,
lpSecurityAttrs))
{
pThread->Delete();
return NULL;
}
VERIFY(pThread->SetThreadPriority(nPriority));
if (!(dwCreateFlags & CREATE_SUSPENDED))
VERIFY(pThread->ResumeThread() != (DWORD)-1);//调试到这个地方出错,不知道为什么。
return pThread;
#endif //!_MT)
}
#18
为什么HWND hWnd=GetSafeHwnd();
AfxBeginThread(ThreadProc,hWnd,THREAD_PRIORITY_NORMAL);会出错啊?
没道理啊。
我的项目是单文档的。在主窗口分割为两个子窗口,和这有关系吗?
AfxBeginThread(ThreadProc,hWnd,THREAD_PRIORITY_NORMAL);会出错啊?
没道理啊。
我的项目是单文档的。在主窗口分割为两个子窗口,和这有关系吗?
#19
提示unhandled exception in **.exe(MFC42D.DLL):0xc0000005 Acess Violation
_AFXWIN_INLINE DWORD CWinThread::ResumeThread()
{ ASSERT(m_hThread != NULL); //在这调试出错了,为什么啊??
return ::ResumeThread(m_hThread); }
大侠们快救命啊!!!
_AFXWIN_INLINE DWORD CWinThread::ResumeThread()
{ ASSERT(m_hThread != NULL); //在这调试出错了,为什么啊??
return ::ResumeThread(m_hThread); }
大侠们快救命啊!!!
#20
http://www.codeguru.com/controls/WaitDialog.shtml
你可以试试。不过只是另一种解决方案
你可以试试。不过只是另一种解决方案
#21
郁闷啊。~~:(
#22
现在我改成用另一个线程发送消息给主进程,由主进程处理了。但这个方法和SetTimer一样。进程发的消息也是在消息队列中,要执行完数据库的操作后才响应我定义的消息。这样,还是不能达到同时进程条在数据库操作的同时增长。
怎么使进程条和数据库操作同时运行?
怎么使进程条和数据库操作同时运行?
#23
主线程被阻塞,不会响应Message,控件不会刷新
把数据库操作移到新线程中
把数据库操作移到新线程中
#24
同意: robothn(雷鸟)
#25
to robothn:
数据库操作是用CRecordSet.
try
{
m_pMySet->Open();
}
catch (CDBException *e){}
如果不是在主进程中执行m_pMySet->Open,我主进程中还要用到m_pMySet怎么办?
数据库操作是用CRecordSet.
try
{
m_pMySet->Open();
}
catch (CDBException *e){}
如果不是在主进程中执行m_pMySet->Open,我主进程中还要用到m_pMySet怎么办?
#26
当然是新线程使用主线程的m_pMySet
AfxBeginThread(ThreadProc,hWnd,THREAD_PRIORITY_NORMAL);
UINT ThreadProc(LPVOID param);
AfxBeginThread()的第二个参数就是给ThreadProc传参的,你传个hWnd有什么用?
改为:
AfxBeginThread(ThreadProc,m_pMySet,THREAD_PRIORITY_NORMAL);
...
UINT ThreadProc(LPVOID param)
{
CRecordSet* pset = (CRecordSet*)param;
...
}
AfxBeginThread(ThreadProc,hWnd,THREAD_PRIORITY_NORMAL);
UINT ThreadProc(LPVOID param);
AfxBeginThread()的第二个参数就是给ThreadProc传参的,你传个hWnd有什么用?
改为:
AfxBeginThread(ThreadProc,m_pMySet,THREAD_PRIORITY_NORMAL);
...
UINT ThreadProc(LPVOID param)
{
CRecordSet* pset = (CRecordSet*)param;
...
}
#27
行了,谢谢各位大侠,尤其是robothn
#1
SetTimer建立定时器后会发送WM_TIMER消息,但问题是该消息仅仅是放到消息队列中排队,并不会马上被执行,因为消息对列中可能还有其它消息等待执行,你可以试试通过建立另外一个线程的方式来实现你的目的。
#2
去掉nIDEvent == 1试试;
OnTimer一般是第一个Click后才执行,如果你定义Click时间是一秒,它就在定时器创建后一秒被激活
OnTimer一般是第一个Click后才执行,如果你定义Click时间是一秒,它就在定时器创建后一秒被激活
#3
就算排队一般时间也不会很长,计数器的优先级还是很高的,属于很重要(宝贵)的资源,所以msdn要求尽可能少用
#4
同意dominolili(domino) ,settimer后并不会立即进入ontimer
#5
你的主线程正在执行 OnInitDialog () 不可能去执行onTimer.
你只能直接调用m_Progress.StepIt();
你只能直接调用m_Progress.StepIt();
#6
SetTimer建立定时器后会发送WM_TIMER消息,但问题是该消息仅仅是放到消息队列中排队,并不会马上被执行,因为消息对列中可能还有其它消息等待执行,你可以试试通过建立另外一个线程的方式来实现你的目的。
#7
same to what sans(sans) said
#8
to dominolili:并不是第一个Click后才执行的,有时候要过几十秒。好像必须执行打开数据库的操作后才执行。
我的本意是如果打开数据库比较慢(或者发生网络故障),有个进度条可以显示进度,不至于让人以为死机了。但是,如果Init完成后再显示,就没有达到预期效果了。
建立另一个线程具体怎么做,能不能给个例子。
谢谢!!!
我的本意是如果打开数据库比较慢(或者发生网络故障),有个进度条可以显示进度,不至于让人以为死机了。但是,如果Init完成后再显示,就没有达到预期效果了。
建立另一个线程具体怎么做,能不能给个例子。
谢谢!!!
#9
昨天(13日)VC知识论坛中就有(Panic的),你自己去看吧!
#10
没搜索到啊。题目叫什么名字?
#11
先调用一次过程
settimer
ontimer()
{
调用过程
}
settimer
ontimer()
{
调用过程
}
#12
To ClickMore 你误会了。我知道Ontimer 要一个Click后执行的。
但是好像打开数据库的优先级比Ontimer大。所以,总是要先执行完打开数据库后才开始计数的。 照理应该0.1秒后开始计数,但是有时候要过几十秒,等数据库操作完毕后才开始计数。
但是好像打开数据库的优先级比Ontimer大。所以,总是要先执行完打开数据库后才开始计数的。 照理应该0.1秒后开始计数,但是有时候要过几十秒,等数据库操作完毕后才开始计数。
#13
如何通过进程控制MainFrame中的进度条啊?我用
HWND hWnd=GetSafeHwnd();
AfxBeginThread(ThreadProc,hWnd,THREAD_PRIORITY_NORMAL);
UINT ThreadProc(LPVOID param)
{
while (((CMainFrame*)AfxGetMainWnd())->m_Progress.GetPos()<90)
{
((CMainFrame*)AfxGetMainWnd())->m_Progress.StepIt();
Sleep(100);
}
return 0;
}
会出错。怎么用进程对对话框中的控件进行操作啊?Help!!!!
HWND hWnd=GetSafeHwnd();
AfxBeginThread(ThreadProc,hWnd,THREAD_PRIORITY_NORMAL);
UINT ThreadProc(LPVOID param)
{
while (((CMainFrame*)AfxGetMainWnd())->m_Progress.GetPos()<90)
{
((CMainFrame*)AfxGetMainWnd())->m_Progress.StepIt();
Sleep(100);
}
return 0;
}
会出错。怎么用进程对对话框中的控件进行操作啊?Help!!!!
#14
工作线程不要直接调用另外线程的界面,最好向界面发送一个消息,在界面的消息处理中做事情。
UINT ThreadProc(LPVOID param)
{
while (((CMainFrame*)AfxGetMainWnd())->m_Progress.GetPos()<90)
{
((CMainFrame*)AfxGetMainWnd())->PostMessage(WM_USER+1,0,0);
Sleep(100);
}
return 0;
}
然后在MainFrame中响应WM_USER+1,调用m_Progress.StepIt();
UINT ThreadProc(LPVOID param)
{
while (((CMainFrame*)AfxGetMainWnd())->m_Progress.GetPos()<90)
{
((CMainFrame*)AfxGetMainWnd())->PostMessage(WM_USER+1,0,0);
Sleep(100);
}
return 0;
}
然后在MainFrame中响应WM_USER+1,调用m_Progress.StepIt();
#15
但是在执行(((CMainFrame*)AfxGetMainWnd())->m_Progress.GetPos()的时候就出错了。
#16
最好的效果是采用多现成;
或者是控件
或者是控件
#17
发现错误在哪里了。
竟然在HWND hWnd=GetSafeHwnd();
AfxBeginThread(ThreadProc,hWnd,THREAD_PRIORITY_NORMAL);//这一句出错
CWinThread* AFXAPI AfxBeginThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam,
int nPriority, UINT nStackSize, DWORD dwCreateFlags,
LPSECURITY_ATTRIBUTES lpSecurityAttrs)
{
#ifndef _MT
pfnThreadProc;
pParam;
nPriority;
nStackSize;
dwCreateFlags;
lpSecurityAttrs;
return NULL;
#else
ASSERT(pfnThreadProc != NULL);
CWinThread* pThread = DEBUG_NEW CWinThread(pfnThreadProc, pParam);
ASSERT_VALID(pThread);
if (!pThread->CreateThread(dwCreateFlags|CREATE_SUSPENDED, nStackSize,
lpSecurityAttrs))
{
pThread->Delete();
return NULL;
}
VERIFY(pThread->SetThreadPriority(nPriority));
if (!(dwCreateFlags & CREATE_SUSPENDED))
VERIFY(pThread->ResumeThread() != (DWORD)-1);//调试到这个地方出错,不知道为什么。
return pThread;
#endif //!_MT)
}
竟然在HWND hWnd=GetSafeHwnd();
AfxBeginThread(ThreadProc,hWnd,THREAD_PRIORITY_NORMAL);//这一句出错
CWinThread* AFXAPI AfxBeginThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam,
int nPriority, UINT nStackSize, DWORD dwCreateFlags,
LPSECURITY_ATTRIBUTES lpSecurityAttrs)
{
#ifndef _MT
pfnThreadProc;
pParam;
nPriority;
nStackSize;
dwCreateFlags;
lpSecurityAttrs;
return NULL;
#else
ASSERT(pfnThreadProc != NULL);
CWinThread* pThread = DEBUG_NEW CWinThread(pfnThreadProc, pParam);
ASSERT_VALID(pThread);
if (!pThread->CreateThread(dwCreateFlags|CREATE_SUSPENDED, nStackSize,
lpSecurityAttrs))
{
pThread->Delete();
return NULL;
}
VERIFY(pThread->SetThreadPriority(nPriority));
if (!(dwCreateFlags & CREATE_SUSPENDED))
VERIFY(pThread->ResumeThread() != (DWORD)-1);//调试到这个地方出错,不知道为什么。
return pThread;
#endif //!_MT)
}
#18
为什么HWND hWnd=GetSafeHwnd();
AfxBeginThread(ThreadProc,hWnd,THREAD_PRIORITY_NORMAL);会出错啊?
没道理啊。
我的项目是单文档的。在主窗口分割为两个子窗口,和这有关系吗?
AfxBeginThread(ThreadProc,hWnd,THREAD_PRIORITY_NORMAL);会出错啊?
没道理啊。
我的项目是单文档的。在主窗口分割为两个子窗口,和这有关系吗?
#19
提示unhandled exception in **.exe(MFC42D.DLL):0xc0000005 Acess Violation
_AFXWIN_INLINE DWORD CWinThread::ResumeThread()
{ ASSERT(m_hThread != NULL); //在这调试出错了,为什么啊??
return ::ResumeThread(m_hThread); }
大侠们快救命啊!!!
_AFXWIN_INLINE DWORD CWinThread::ResumeThread()
{ ASSERT(m_hThread != NULL); //在这调试出错了,为什么啊??
return ::ResumeThread(m_hThread); }
大侠们快救命啊!!!
#20
http://www.codeguru.com/controls/WaitDialog.shtml
你可以试试。不过只是另一种解决方案
你可以试试。不过只是另一种解决方案
#21
郁闷啊。~~:(
#22
现在我改成用另一个线程发送消息给主进程,由主进程处理了。但这个方法和SetTimer一样。进程发的消息也是在消息队列中,要执行完数据库的操作后才响应我定义的消息。这样,还是不能达到同时进程条在数据库操作的同时增长。
怎么使进程条和数据库操作同时运行?
怎么使进程条和数据库操作同时运行?
#23
主线程被阻塞,不会响应Message,控件不会刷新
把数据库操作移到新线程中
把数据库操作移到新线程中
#24
同意: robothn(雷鸟)
#25
to robothn:
数据库操作是用CRecordSet.
try
{
m_pMySet->Open();
}
catch (CDBException *e){}
如果不是在主进程中执行m_pMySet->Open,我主进程中还要用到m_pMySet怎么办?
数据库操作是用CRecordSet.
try
{
m_pMySet->Open();
}
catch (CDBException *e){}
如果不是在主进程中执行m_pMySet->Open,我主进程中还要用到m_pMySet怎么办?
#26
当然是新线程使用主线程的m_pMySet
AfxBeginThread(ThreadProc,hWnd,THREAD_PRIORITY_NORMAL);
UINT ThreadProc(LPVOID param);
AfxBeginThread()的第二个参数就是给ThreadProc传参的,你传个hWnd有什么用?
改为:
AfxBeginThread(ThreadProc,m_pMySet,THREAD_PRIORITY_NORMAL);
...
UINT ThreadProc(LPVOID param)
{
CRecordSet* pset = (CRecordSet*)param;
...
}
AfxBeginThread(ThreadProc,hWnd,THREAD_PRIORITY_NORMAL);
UINT ThreadProc(LPVOID param);
AfxBeginThread()的第二个参数就是给ThreadProc传参的,你传个hWnd有什么用?
改为:
AfxBeginThread(ThreadProc,m_pMySet,THREAD_PRIORITY_NORMAL);
...
UINT ThreadProc(LPVOID param)
{
CRecordSet* pset = (CRecordSet*)param;
...
}
#27
行了,谢谢各位大侠,尤其是robothn