如何创建一个具有消息循环 但是没有界面的子线程啊? 可以响应计时器消息

AntonlioX 2005-05-23 10:00:18
如何创建一个具有消息循环 但是没有界面的子线程啊? 可以响应计时器消息
...全文
323 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
younggle 2005-05-23
  • 打赏
  • 举报
回复
这是MFC的CWinThread类的实现。我提供更好的给你:
首先创建一个线程 _beginthread(MainThread, DEFAULT_STACK_SIZE, NULL);
然后在MainThread中创建一个看不见的窗口(伪窗口):
WNDCLASS wcl;
HWND hWnd = NULL;

memset(&wcl,0,sizeof(wcl));

if (lpfnWndProc == NULL)
{
return NULL; /*失败*/
}

/*register class*/

wcl.cbClsExtra = 0;
wcl.cbWndExtra = 0;
wcl.hbrBackground = NULL;
wcl.hCursor = NULL;
wcl.hIcon = NULL;
wcl.hInstance = NULL;
wcl.lpfnWndProc = MainWindowProc;
wcl.lpszClassName = szWndName;
wcl.lpszMenuName = NULL;
wcl.style = CS_VREDRAW;
if (RegisterClass(&wcl) == 0)
{
return NULL;
}

/*create window*/
hWnd = CreateWindow(szWndName,NULL,WS_POPUP,0,0,
CW_USEDEFAULT,CW_USEDEFAULT,
NULL,NULL,NULL,NULL);

/*进入消息循环*/
do
{
ret = GetMessage(&msg,NULL,0,0);
if (ret > 0)
{
DispatchMessage(&msg);
}

}while(ret > 0);


DestroySTUNServerWindow(szWndName, s_hSTUNServerWnd);
最后可以在MainWindowProc中处理你的消息了:
LRESULT CALLBACK MainWindowProc(HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch(uMsg)
{
default:
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

return 0;
}
AntonlioX 2005-05-23
  • 打赏
  • 举报
回复
谢谢以上各位 啊 我先试试啊
idAnts 2005-05-23
  • 打赏
  • 举报
回复
你把PostThreadMessage(dwThreadId,WM_USER+1,0,0);注释掉就可以收到定时器消息了,或者是你在线程里循环的接收消息,否则只能接收到一条。
idAnts 2005-05-23
  • 打赏
  • 举报
回复
UINT_PTR hTimer = 0;
//定时器消息处理函数
VOID __stdcall TimerProc(HWND hwnd,UINT uMsg,UINT_PTR idEvent,DWORD dwTime)
{
KillTimer(NULL,hTimer);
MessageBox(NULL,"Speak in Timer!",":)",MB_OK);
}

//线程函数
DWORD __stdcall ThreadFun(void *)
{
MSG msg;
PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE);
hTimer = SetTimer(NULL,0,10,(TIMERPROC)TimerProc);
while(!PeekMessage(&msg,NULL,WM_TIMER,WM_USER+1,PM_NOREMOVE))
{
OutputDebugString("Not peek message\r\n");
Sleep(100);
}
if(msg.message == (WM_USER+1))
{
//收到主线程发来的消息
OutputDebugString("Rec message\r\n");
}
else
{
//收到定时器消息,派送之
OutputDebugString("what message\r\n");
DispatchMessage(&msg);
}
return 0;
}


//创建线程代码:
DWORD dwThreadId;
HANDLE hThread = NULL;
hThread = CreateThread(NULL,0,ThreadFun,NULL,0,&dwThreadId);
if (hThread == NULL)
{
MessageBox("CreateThread failed.", "main", MB_OK );
}
else
{
OutputDebugString("prepare post message\r\n");
Sleep(1000);//等待线程创建好了
PostThreadMessage(dwThreadId,WM_USER+1,0,0);//给线程发消息
OutputDebugString("Post message ok\r\n");
CloseHandle( hThread );
}
idAnts 2005-05-23
  • 打赏
  • 举报
回复
我的例子你只要直接用那个线程函数创建线程就可以了啊。
加上PostThreadMessage再给你个例子吧!
AntonlioX 2005-05-23
  • 打赏
  • 举报
回复
是不是可以直接PostMessage()给子线程中的对话框啊? 到底消息循环需不需要窗口啊?我现在有点糊涂了
AntonlioX 2005-05-23
  • 打赏
  • 举报
回复
顺便问个问题 如何主窗口传递消息给用户界面线程的窗口啊?是不是使用PostThreadMessage()
当子线程得到了消息再进行处理啊 比如传递参数给它的窗口。 也就是说

主线程--》(PostThreadMessage)子线程--》子线程的窗口对象 ???
AntonlioX 2005-05-23
  • 打赏
  • 举报
回复
idAnts(你才无聊呢) ( )

你给的例子怎么用啊?
etre 2005-05-23
  • 打赏
  • 举报
回复
不是很好用的.我们在项目中都用
idAnts 2005-05-23
  • 打赏
  • 举报
回复
给你个简单的例子,线程设定时器:
UINT_PTR hTimer = 0;
VOID __stdcall TimerProc(HWND hwnd,UINT uMsg,UINT_PTR idEvent,DWORD dwTime)
{
KillTimer(NULL,hTimer);
MessageBox(NULL,"Speak in Timer!",":)",MB_OK);
}

DWORD __stdcall ThreadFun(void *)
{
MSG msg;
PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE);
hTimer = SetTimer(NULL,0,10,(TIMERPROC)TimerProc);
while(!PeekMessage(&msg,NULL,WM_TIMER,WM_TIMER,PM_NOREMOVE))
{
OutputDebugString("Not peek message\r\n");
Sleep(100);
}
if(msg.message == (WM_TIMER))
{
DispatchMessage(&msg);
}
return 0;
}
AntonlioX 2005-05-23
  • 打赏
  • 举报
回复
从你的给的类的定义中,CThreadBase不是从CWinThread派生的啊

class CThreadBase
{
public:
CThreadBase();

protected:
virtual ~CThreadBase();

// Operationen
public:
DWORD m_dwThreadId;
HANDLE m_hThread;
AntonlioX 2005-05-23
  • 打赏
  • 举报
回复
thanks
etre 2005-05-23
  • 打赏
  • 举报
回复
CThreadBase 是的啊.你继承他就行了
AntonlioX 2005-05-23
  • 打赏
  • 举报
回复
如何使用啊?
AntonlioX 2005-05-23
  • 打赏
  • 举报
回复
CThreadBase 不是MFC的类 啊?
etre 2005-05-23
  • 打赏
  • 举报
回复
在OnThreadMessage中实现if (Msg == WM_TIMER)
OnTimer(wParam, lParam);
etre 2005-05-23
  • 打赏
  • 举报
回复


CThreadBase::CThreadBase()
{
m_hThread = 0;
m_dwThreadId = NULL;
m_hEventStarted = CreateEvent(0, FALSE, FALSE, NULL);
m_started = false;
}

CThreadBase::~CThreadBase()
{
CloseHandle(m_hEventStarted);
CloseHandle(m_hThread);
}

BOOL CThreadBase::Create(int nPriority /*=THREAD_PRIORITY_NORMAL*/, DWORD dwCreateFlags /*=0*/)
{
m_hThread=CreateThread(0, 0, ThreadProc, this, dwCreateFlags, &m_dwThreadId);
if (!m_hThread)
{
delete this;
return FALSE;
}
::SetThreadPriority(m_hThread, nPriority);
return TRUE;
}

BOOL CThreadBase::PostThreadMessage(UINT message, WPARAM wParam, LPARAM lParam)
{
BOOL res=::PostThreadMessage(m_dwThreadId, message, wParam, lParam);;
ASSERT(res);
return res;
}

DWORD CThreadBase::ResumeThread()
{
DWORD res=::ResumeThread(m_hThread);
if (!m_started)
{
WaitForSingleObject(m_hEventStarted, INFINITE);
}
return res;
}

DWORD CThreadBase::SuspendThread()
{
return ::SuspendThread(m_hThread);
}

DWORD WINAPI CThreadBase::ThreadProc(LPVOID lpParameter)
{
return ((CThreadBase *)lpParameter)->Run();
}

DWORD CThreadBase::Run()
{
InitInstance();
SetEvent(m_hEventStarted);
m_started = true;
MSG msg;
while (GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
if (!msg.hwnd)
OnThreadMessage(msg.message, msg.wParam, msg.lParam);
DispatchMessage(&msg);
}
DWORD res=ExitInstance();
delete this;
return res;
}

int CThreadBase::OnThreadMessage(UINT Msg, WPARAM wParam, LPARAM lParam)
{
return 0;
}

BOOL CThreadBase::InitInstance()
{
return TRUE;
}

DWORD CThreadBase::ExitInstance()
{
return 0;
}

BOOL CThreadBase::SetPriority(int nPriority)
{
if (!m_hThread)
return false;

return ::SetThreadPriority(m_hThread, nPriority);
}
etre 2005-05-23
  • 打赏
  • 举报
回复
class CThreadBase
{
public:
CThreadBase();

protected:
virtual ~CThreadBase();

// Operationen
public:
DWORD m_dwThreadId;
HANDLE m_hThread;
BOOL Create(int nPriority = THREAD_PRIORITY_NORMAL, DWORD dwCreateFlags = 0);
DWORD SuspendThread();
DWORD ResumeThread();
BOOL PostThreadMessage( UINT message , WPARAM wParam, LPARAM lParam );
BOOL SetPriority(int nPriority);

protected:
virtual int OnThreadMessage(UINT Msg, WPARAM wParam, LPARAM lParam);
virtual BOOL InitInstance();
virtual DWORD ExitInstance();
DWORD Run();
static DWORD WINAPI ThreadProc(LPVOID lpParameter);
HANDLE m_hEventStarted;
bool m_started;;
};

AntonlioX 2005-05-23
  • 打赏
  • 举报
回复
是不是需要创建一个窗口才行啊?
AntonlioX 2005-05-23
  • 打赏
  • 举报
回复
结贴了 分数大家分分了拉 不好意思啊
加载更多回复(2)

15,471

社区成员

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

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