如何创建一个具有消息循环 但是没有界面的子线程啊? 可以响应计时器消息
如何创建一个具有消息循环 但是没有界面的子线程啊? 可以响应计时器消息 问题点数:20、回复次数:22Top
1 楼AntonlioX(做人要厚道)回复于 2005-05-23 10:02:29 得分 0
是不是需要创建一个窗口才行啊?Top
2 楼etre(林荃)回复于 2005-05-23 10:06:06 得分 8
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;;
};
Top
3 楼etre(林荃)回复于 2005-05-23 10:06:26 得分 0
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);
}Top
4 楼etre(林荃)回复于 2005-05-23 10:07:52 得分 0
在OnThreadMessage中实现if (Msg == WM_TIMER)
OnTimer(wParam, lParam);Top
5 楼AntonlioX(做人要厚道)回复于 2005-05-23 10:21:58 得分 0
CThreadBase 不是MFC的类 啊?Top
6 楼AntonlioX(做人要厚道)回复于 2005-05-23 10:23:01 得分 0
如何使用啊?Top
7 楼etre(林荃)回复于 2005-05-23 10:40:51 得分 0
CThreadBase 是的啊.你继承他就行了Top
8 楼AntonlioX(做人要厚道)回复于 2005-05-23 10:53:08 得分 0
thanksTop
9 楼AntonlioX(做人要厚道)回复于 2005-05-23 10:54:48 得分 0
从你的给的类的定义中,CThreadBase不是从CWinThread派生的啊
class CThreadBase
{
public:
CThreadBase();
protected:
virtual ~CThreadBase();
// Operationen
public:
DWORD m_dwThreadId;
HANDLE m_hThread;Top
10 楼idAnts(此广告位招租)回复于 2005-05-23 10:56:15 得分 0
给你个简单的例子,线程设定时器:
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;
}Top
11 楼etre(林荃)回复于 2005-05-23 10:59:32 得分 0
不是很好用的.我们在项目中都用Top
12 楼AntonlioX(做人要厚道)回复于 2005-05-23 11:19:08 得分 0
idAnts(你才无聊呢) ( )
你给的例子怎么用啊?Top
13 楼AntonlioX(做人要厚道)回复于 2005-05-23 11:22:21 得分 0
顺便问个问题 如何主窗口传递消息给用户界面线程的窗口啊?是不是使用PostThreadMessage()
当子线程得到了消息再进行处理啊 比如传递参数给它的窗口。 也就是说
主线程--》(PostThreadMessage)子线程--》子线程的窗口对象 ???
Top
14 楼AntonlioX(做人要厚道)回复于 2005-05-23 11:27:33 得分 0
是不是可以直接PostMessage()给子线程中的对话框啊? 到底消息循环需不需要窗口啊?我现在有点糊涂了Top
15 楼idAnts(此广告位招租)回复于 2005-05-23 11:29:14 得分 0
我的例子你只要直接用那个线程函数创建线程就可以了啊。
加上PostThreadMessage再给你个例子吧!Top
16 楼idAnts(此广告位招租)回复于 2005-05-23 11:33:25 得分 7
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 );
}
Top
17 楼idAnts(此广告位招租)回复于 2005-05-23 11:35:16 得分 0
你把PostThreadMessage(dwThreadId,WM_USER+1,0,0);注释掉就可以收到定时器消息了,或者是你在线程里循环的接收消息,否则只能接收到一条。Top
18 楼AntonlioX(做人要厚道)回复于 2005-05-23 11:39:35 得分 0
谢谢以上各位 啊 我先试试啊Top
19 楼younggle(洋溢)回复于 2005-05-23 12:28:01 得分 5
这是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;
}
Top
20 楼AntonlioX(做人要厚道)回复于 2005-05-23 16:57:58 得分 0
我的可用分不多了 所以实现不好意思阿 谢谢各位的支持阿Top
21 楼AntonlioX(做人要厚道)回复于 2005-05-23 17:07:37 得分 0
结贴了 分数大家分分了拉 不好意思啊Top
22 楼AntonlioX(做人要厚道)回复于 2005-05-23 17:07:59 得分 0
结贴了 分数大家分分了拉 不好意思啊Top




