当前线程为主线程,我想用PostThreadMessage 给当前线程(主线程)发送消息,没有反映这是为啥呀?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当前线程为主线程,我想用PostThreadMessage 给当前线程(主线程)发送消息,没有反映这是为啥呀?相关的知识,希望对你有一定的参考价值。

ON_THREAD_MESSAGE(20000,ThreadFunction)
PostThreadMessage(GetCurrentThreadId(),20000,0,0);
这样发也不行啊,这是为什么呀?请高手指点一二啊,不胜感激!
晓凡_C:谢谢你的回答,我的意思是当前线程就是主线程(并没有创建子线程),在主线程里用PostThreadMessage给主线程发消息(注意:不用SendMessage和PostMessage),是不是可以啊?

回复 春光闪烁:谢谢你的回答
1.主线程是MFC的,不是自己写的。
2.ON_THREAD_MESSAGE映射函数不是在CWinThread派生类中定义的,就是一个自己定义的消息映射函数,所以收不到消息。(这一点我知道了,谢谢!)
还有一个问题: 我现在就是想用PostThreadMessage在主线程里发送自定义的消息给当前线程(主线程),用ON_MESSAGE(20000,ThreadFunction)是不是应该行啊,但是我试了试,这样不行,这是为什么呀?是不是因为用PostThreadMessage发送的消息必须用ON_THREAD_MESSAGE宏来映射啊?

有两种可能
1. 你主线程如果不是MFC的(即自己怎么写的), 可能基本没有机会处理这个消息, 因为PostThreadMessage是立即返回
2. 关于宏ON_THREAD_MESSAGE MSDN里面有介绍
memberFxn
The name of the CWinThread-message-handler function to which the message is mapped.
不知道你这个函数是不是在CWinThread派生类写的

我在MFC的对话框中添加一个按钮, 处理按钮的单击事件如下
if (PostThreadMessage(GetCurrentThreadId(), WM_QUIT,0,0) == FALSE)

AfxMessageBox(_T("失败"));
return;

点击按钮之后, 程序会自动退出, 说明主线程有收到WM_QUIT消息

补充回答:
具体的我也不太清楚, 不过MSDN里面有说(关于PostThreadMessage)
Messages sent by PostThreadMessage are not associated with a window. As a general rule, messages that are not associated with a window cannot be dispatched by the DispatchMessage function.
因此我猜测可能是DispatchMessage 没有办法转发, 如果是跟窗口关联的可以通过ID获取HWND, 再使用PostMessage发送消息
所以我在PreTranslateMessage捕捉, 发现可以捕捉到消息
具体示例:
1. 在点击事件中
if (PostThreadMessage(GetCurrentThreadId(), 0x0401,0,0) == FALSE)

AfxMessageBox(_T("失败"));
return;

2. 在虚函数PreTranslateMessage中
添加(在return CDialog::PreTranslateMessage(pMsg);前面添加)
if (pMsg->message == 0x0401)

AfxMessageBox(_T("收到消息 "));
参考技术A 你的子线程调用GetCurrentThreadId()时得到的是子线程自身的ID。
建议你在创建子线程前,使用GetCurrentThreadId()保存主线程的ID。
然后创建子线程后,由于共享数据空间,你可以直接用前面保存的ID来给主线程发送消息。

希望对你有所帮助。

多线程知识点

1. for循环是不耗时的,i/o操作耗时

2. [NSThread currentThread]获取当前线程number代表线程的编号,name线程的名称,如果number为1则代表为主线程

3.使用pthread开启新的线程

  /*

        参数1:线程的编号地址

        参数2:线程的属性

        参数3:开启的线程要执行的函数 void*  (*)  (void *)

        参数4:给要执行的函数传递的参数

     */

   

    pthread_t ID;

    //开启子线程,自动销毁

    int result = pthread_create(&ID, NULL, demo, NULL);

    //如果返回值为0,则代表成功,其他的代表的失败

    if (result == 0) {

        NSLog(@"开启线程成功");

    }else

    {

        NSLog(@"开启线程失败");

    }

   

}

void* (demo)(void *param)

{

    NSLog(@"%@",[NSThread currentThread]);

    return NULL;

}

4. __bridge桥接 可以把c->oc语言的字符串

NSString *str = (__bridge NSString *)(param);

5.开启子线程的三种方式:

//方式1

//    NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(demo) object:nil];

//    [thread start];

   

   

    //方式2

//    [NSThread detachNewThreadSelector:@selector(demo) toTarget:self withObject:nil];

   

    //方式3

//    [self performSelectorInBackground:@selector(demo) withObject:nil];

6.线程的状态:新建,就绪,运行,阻塞,死亡

7.线程的属性:

thread.name = @"t1";名称

[thread setThreadPriority:0];优先级

[NSThread currentThread].stackSize/1024占用内存

8. //互斥锁 (单个的进行读写操作)

         锁对象: 1 必须继承与NSObject

         2:必须是全局的

@synchronized(self.obj) {加锁的内容}

9.使用UIScrollView的时候记得添加contentsize

self.sv.contentSize = img.size;

10.直接使用nsurl下载图片

NSURL *url = [NSURL URLWithString:@"http://b.hiphotos.baidu.com/image/pic/item/08f790529822720ea5d058ba7ccb0a46f21fab50.jpg"];

    //下载图片

    NSData *data = [NSData dataWithContentsOfURL:url];

    //NSData - >UIImage

    UIImage *img = [UIImage imageWithData:data];

11

1:字符串用copy

2:代理要用weak(防止循环引用self - >p(具有代理属性) - >delegate - > self 循环引用)

3:block用copy

以上是关于当前线程为主线程,我想用PostThreadMessage 给当前线程(主线程)发送消息,没有反映这是为啥呀?的主要内容,如果未能解决你的问题,请参考以下文章

方法 publishProgress 必须从工作线程调用,目前推断线程为主线程

多线程知识点

我可以从当前线程中保存一个值吗?

信号化线程以启动特定功能

C#--异步显示工作进度

登录窗体为主线程窗体时实现重登录的一个困难