社区
进程/线程/DLL
帖子详情
如何创建一个具有消息循环 但是没有界面的子线程啊? 可以响应计时器消息
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)
Qt对话框的事件
循环
分析(
子
线程
中不能创建UI窗体分析)
重要: GUI
线程
和辅助
线程
如前所述,每个程序在启动时都有一个
线程
。这个
线程
被称为“主
线程
”(在Qt应用程序中也称为“GUI
线程
”)。Qt GUI必须在这个
线程
中运行。所有小部件和几个相关类(例如QPixmap)都不能在辅助
线程
中工作。辅助
线程
通常称为“工作
线程
”,因为它用于从主
线程
卸载处理工作。 首先,
子
线程
不能创建与UI有关的对象,但是可以这样
子
做.只能在
子
线程
中发一个信号到主
线程
中,由主
线程
创建对话窗口.
子
线程
发完信号后,在
子
线程
中while
循环
调用事件
循环
,.对话窗口退出之后,主
线程
调用接口,结
Windows中
子
线程
不能触发定时器的问题分析
对窗口来说,都会有一个
消息
循环
线程
(此
消息
线程
即UI
线程
)执行各类任务,一般情况此
线程
大部分时间都处于空闲状态,由
消息
泵等待
消息
触发各类操作(如
界面
刷新、定时器
响应
等),除非窗口退出,不然不会退出此
线程
。 在窗口
线程
或主
线程
中使用定时器由于有
消息
泵等待定时器
消息
,所以不会存在不
响应
定时器的情况。但
子
线程
在创建时一般不需要
消息
泵,所以按顺序执行完后直接退出,就算是有定时器需要触发,
子
线程
也不知道,
QT
消息
/事件
循环
机制
关于Qt
子
线程
和
消息
循环
一、QT
消息
/事件
循环
机制 Qt作为一个可视化GUI
界面
操作系统,是基于事件驱动的,我们程序执行的顺序不再是线性,而是由一个个应用程序内部或外部的事件进行驱动,无事件时便阻塞。这个
循环
概念类似于while的函数
循环
,函数体内不断处理用户的输入,类比到事件
循环
中,用户点击了鼠标、按下了键盘,便被称作为事件。 一般对于带UI窗口的程序来说,“事件”是由操作系统或程序框架在不同的时刻发出的。当用户按下鼠标、敲下键盘,或者是窗口需要重新绘制的时候,
计时器
触发的时候,都会发出一个相应的事件。
QT
消息
/事件
循环
机制与多
线程
的关系
关于Qt
子
线程
和
消息
循环
一、QT
消息
/事件
循环
机制 Qt作为一个可视化GUI
界面
操作系统,是基于事件驱动的,我们程序执行的顺序不再是线性,而是由一个个应用程序内部或外部的事件进行驱动,无事件时便阻塞。这个
循环
概念类似于while的函数
循环
,函数体内不断处理用户的输入,类比到事件
循环
中,用户点击了鼠标、按下了键盘,便被称作为事件。 一般对于带UI窗口的程序来说,“事件”是由操作系统或程序框架在不同的时刻发出的。当用户按下鼠标、敲下键盘,或者是窗口需要重新绘制的时候,
计时器
触发的时候,都会发出一个相应的事件
iOS
消息
循环
的原理runloop
runloop:原理https://blog.ibireme.com/2015/05/18/runloop/ 1.
消息
循环
概念RunLoop就是
消息
循环
,每一个
线程
内部都有一个
消息
循环
。只有主
线程
的
消息
循环
默认开启,
子
线程
的
消息
循环
默认不开启。 每个
线程
都有一个
消息
循环
,主
线程
消息
循环
默认开启,
子
线程
消息
循环
默认都是关闭的,需要手动开启。
消息
循环
与
线程
之间是一一对应的关系,其关系保存在一个...
进程/线程/DLL
15,471
社区成员
49,181
社区内容
发帖
与我相关
我的任务
进程/线程/DLL
VC/MFC 进程/线程/DLL
复制链接
扫一扫
分享
社区描述
VC/MFC 进程/线程/DLL
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章