VC中创建线程

时间:2021-11-16 18:35:43
我在自绘进度条时用到创建线程,在绘制进度条函数中CreateThread,现在问题是当打开显示进度条界面时就已经是全部画完的效果。

//绘制进度颜色
void CMyProgress::ProgressColor(HWND _hwnd)
{
   hThread = CreateThread(NULL, 0, ThreadProc, (LPVOID)this, 0, &m_dwRID);
  //创建事件对象
  hREvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  //无限等待
  WaitForSingleObject(hREvent, INFINITE);
  CloseHandle(hREvent);
  hREvent = NULL;
}

void CMyProgress::Draw_Color()
{
 HBITMAP hOldbmp = (HBITMAP) SelectObject(imgdc, m_hProgressColor);
 static int i=(PROGRESSBAR_X+1);
 BitBlt(g, i, PROGRESSBAR_Y, PROGRESSBAR_WIDE, PROGRESSBAR_HIGH, imgdc, 0, 0, SRCCOPY);
 SelectObject(imgdc, hOldbmp);
 //绘制结束
 (i<PROGRESSBAR_WIDE) ? (++i) : (msg.message = UM_QUITMSG);
}

//回调函数
DWORD ThreadProc(LPVOID lpParameter)
{
 CMyProgress* pProgress = (CMyProgress*)lpParameter;
 //事件已发生
 SetEvent(hREvent);
 //死循环
 while(1)
 {
  if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  {
 //结束消息
   if (UM_QUITMSG == msg.message)
   {
     return 0;
   }
  }
  else
  {
  //绘制进度颜色
   pProgress->Draw_Color();

  }
 }
  CloseHandle(hThread);
  hThread = NULL;
 return 0;
}

 请问线程哪里用错了呢? 谢谢大家

4 个解决方案

#1


线程创建后,你执行
//事件已发生
SetEvent(hREvent);
事件有效,因此会唤起父线程
//无限等待
WaitForSingleObject(hREvent, INFINITE);
CloseHandle(hREvent);//即此处
hREvent = NULL;
然后线程退出。。。。

#2


我觉得是你的线程函数里面没有加上延迟的代码,这样它就会很快的完成进度条,然后发出UM_QUITMSG 消息,你可以试试在你的循环里加上sleep(100)试试看,这样每绘制一次就停留0.1秒,才会形成视觉效果。

#3


首先你创建的线程没有必要使用消息循环,因为这个线程没有创建窗口,也就是不会接收到消息,除非你自己发送的线程消息

也就是因为如此,你的线程实际上只是执行了循环就结束了,加上没有Sleep,也就是说在你看清之前已经画完了
你可以在循环中加入Sleep(10);来试试

#4


如果只sleep(100)这样用.我觉得不对..影响速度..

#include "ENtime.h"
//每一帖起始时间
void ENtime::countGetTickCount()
{
IniFrameDelay=GetTickCount();//获得豪秒
// cout<<"IniFrameDelay:"<<IniFrameDelay<<endl;
}
//计算每一帖帖速
void ENtime::countFrameSpeed()
{
FrameDelay=GetTickCount() - IniFrameDelay;//每一帖的帖速
// cout<<"FrameDelay:"<<FrameDelay<<" SetSpeedValue:"<<SetSpeedValue<<endl;
}
//控制相对帖速
int ENtime::setFrameSpeed(float speed)
{
SetSpeedValue=speed;//设置帖速
return 1;
}
//获取相对帖速值
int ENtime::getFrameSpeed()
{
return SetSpeedValue;
}
//设置sleep
bool ENtime::FrameSleep()
{
FrameDelay=GetTickCount() - IniFrameDelay;//每一帖的帖速
if(FrameDelay < SetSpeedValue)
{
::Sleep(SetSpeedValue - FrameDelay);//主动放弃CPU使用时间
// ::Sleep(SetSpeedValue);//主动放弃CPU使用时间
return 0;//帖速不合符要求
}
return 1;//帖速合符要求
}
float ENtime::getFrameDelay()
{
return FrameDelay;
}
float ENtime::getSecond()
{
return Second;
}
int ENtime::CheckTimeOut(float &savetime,float space)
{
if(Second>=savetime+space)
{
savetime=Second;
return 1;
}
return 0;
}
//获取系统时间方法1
SYSTEMTIME ENtime::getSystemTime1()
{
SYSTEMTIME lpSystemTime;//系统时间
GetSystemTime(&lpSystemTime);
return lpSystemTime;
}
//获取系统时间方法2
tm* ENtime::getSystemTime2()
{
time_t t;  
struct tm *ptm;  
time(&t);  
ptm = localtime(&t);
return ptm;
}




#1


线程创建后,你执行
//事件已发生
SetEvent(hREvent);
事件有效,因此会唤起父线程
//无限等待
WaitForSingleObject(hREvent, INFINITE);
CloseHandle(hREvent);//即此处
hREvent = NULL;
然后线程退出。。。。

#2


我觉得是你的线程函数里面没有加上延迟的代码,这样它就会很快的完成进度条,然后发出UM_QUITMSG 消息,你可以试试在你的循环里加上sleep(100)试试看,这样每绘制一次就停留0.1秒,才会形成视觉效果。

#3


首先你创建的线程没有必要使用消息循环,因为这个线程没有创建窗口,也就是不会接收到消息,除非你自己发送的线程消息

也就是因为如此,你的线程实际上只是执行了循环就结束了,加上没有Sleep,也就是说在你看清之前已经画完了
你可以在循环中加入Sleep(10);来试试

#4


如果只sleep(100)这样用.我觉得不对..影响速度..

#include "ENtime.h"
//每一帖起始时间
void ENtime::countGetTickCount()
{
IniFrameDelay=GetTickCount();//获得豪秒
// cout<<"IniFrameDelay:"<<IniFrameDelay<<endl;
}
//计算每一帖帖速
void ENtime::countFrameSpeed()
{
FrameDelay=GetTickCount() - IniFrameDelay;//每一帖的帖速
// cout<<"FrameDelay:"<<FrameDelay<<" SetSpeedValue:"<<SetSpeedValue<<endl;
}
//控制相对帖速
int ENtime::setFrameSpeed(float speed)
{
SetSpeedValue=speed;//设置帖速
return 1;
}
//获取相对帖速值
int ENtime::getFrameSpeed()
{
return SetSpeedValue;
}
//设置sleep
bool ENtime::FrameSleep()
{
FrameDelay=GetTickCount() - IniFrameDelay;//每一帖的帖速
if(FrameDelay < SetSpeedValue)
{
::Sleep(SetSpeedValue - FrameDelay);//主动放弃CPU使用时间
// ::Sleep(SetSpeedValue);//主动放弃CPU使用时间
return 0;//帖速不合符要求
}
return 1;//帖速合符要求
}
float ENtime::getFrameDelay()
{
return FrameDelay;
}
float ENtime::getSecond()
{
return Second;
}
int ENtime::CheckTimeOut(float &savetime,float space)
{
if(Second>=savetime+space)
{
savetime=Second;
return 1;
}
return 0;
}
//获取系统时间方法1
SYSTEMTIME ENtime::getSystemTime1()
{
SYSTEMTIME lpSystemTime;//系统时间
GetSystemTime(&lpSystemTime);
return lpSystemTime;
}
//获取系统时间方法2
tm* ENtime::getSystemTime2()
{
time_t t;  
struct tm *ptm;  
time(&t);  
ptm = localtime(&t);
return ptm;
}