在DLL中:
头文件中:volatile DWORD postRecvId;
1、由VB调用的一个函数中:
postRecvId=GetCurrentThreadId();//叫它主线程吧2、接着创建一线程并在线程函数中:
long asdf;
asdf=PostThreadMessage(postRecvId,WM_COMMNOTIFY, (WPARAM)hCom, NULL);
//if(GetLastError()==ERROR_INVALID_THREAD) AfxMessageBox("POST消息失败");
if(asdf!=0) AfxMessageBox("POST消息可能成功");//调试时有显示3、再在在主线程中:
MSG Mmsg;
int test;
//while(test=GetMessage(&Gmsg,NULL,WM_COMMNOTIFY,WM_COMMNOTIFY)){
while(test=PeekMessage(&Mmsg,NULL,WM_COMMNOTIFY,WM_COMMNOTIFY,PM_REMOVE))
{
if(Mmsg.message==WM_COMMNOTIFY) AfxMessageBox("收到");
}问:为什么收不到消息啊?
还有我想用GetLastError()说我未定义ERROR_INVALID_THREAD
比我高的手救我啊!问题解决分不够再加啊
头文件中:volatile DWORD postRecvId;
1、由VB调用的一个函数中:
postRecvId=GetCurrentThreadId();//叫它主线程吧2、接着创建一线程并在线程函数中:
long asdf;
asdf=PostThreadMessage(postRecvId,WM_COMMNOTIFY, (WPARAM)hCom, NULL);
//if(GetLastError()==ERROR_INVALID_THREAD) AfxMessageBox("POST消息失败");
if(asdf!=0) AfxMessageBox("POST消息可能成功");//调试时有显示3、再在在主线程中:
MSG Mmsg;
int test;
//while(test=GetMessage(&Gmsg,NULL,WM_COMMNOTIFY,WM_COMMNOTIFY)){
while(test=PeekMessage(&Mmsg,NULL,WM_COMMNOTIFY,WM_COMMNOTIFY,PM_REMOVE))
{
if(Mmsg.message==WM_COMMNOTIFY) AfxMessageBox("收到");
}问:为什么收不到消息啊?
还有我想用GetLastError()说我未定义ERROR_INVALID_THREAD
比我高的手救我啊!问题解决分不够再加啊
[in] Identifier of the thread to which the message is to be posted.
The function fails if the specified thread does not have a message queue. The system creates a thread's message queue when the thread makes its first call to one of the User or GDI functions. For more information, see the Res section. Windows 2000/XP: This thread must either belong to the same desktop as the calling thread or to a process with the same LUID. Otherwise, the function fails and returns ERROR_INVALID_THREAD_ID.
postRecvId=GetCurrentThreadId();//叫它主线程吧再说明一点,VB的调用线程是有窗口的,也就是线程应该有大哥说的message queue
一般的主线程调用了生成窗口的API,就会有一个消息队列附在线程上,要不然,线程是不会拥有消息队列的,所以也接收不到消息。建议你的主线程首先产生一个窗体。然后再用子线程发消息。
建议看看上面的英文提示,具体的原理,由于好长时间没弄了,想不起来了
人家是在同一个线程内的。
人家是在同一个进程内的。
如果执行该函数的线程已经over了,自然ID号是无效的。
另外得到msg的方法应当是
MSG Mmsg;
int test;
while(1)
{
while(test=PeekMessage(&Mmsg,NULL,WM_COMMNOTIFY,WM_COMMNOTIFY,PM_REMOVE))
{
TransLateMsg(Mmsg);//
DispatchMsg(Mmsg);// 名字可能不大对,用来分发消息的
if(Mmsg.message==WM_COMMNOTIFY) AfxMessageBox("收到");
}
}
否则如果是工作者线程就会执行一次就退出,要一直等着拿MSG才成
extern double m;//获取数据,供VB用不没试到这一步//////////////////////////////////////////////////////////////////
volatile HANDLE hCom; //串行口句柄
#define MAXBLOCK 2048 //缓冲区
int y=0; //位置:发送命令,置0:数据分析
char buf[2048/4];
int winno;
unsigned char Wdata[11];
HANDLE pThread=NULL; //监视线程(句柄)
volatile BOOL bConnected=FALSE; //已连接否
/////////////监视线程相关//////////////////////////////////////////
//用volatile声明是为了防止优化编译器把二个线程都要用到的变量从内
//存装入CPU寄存器中,导致两个线程可能一个用寄存器的变量,一个用内存中
//的变量,造成程序的错误执行
volatile DWORD postRecvId; //通信处理窗口(线程)句柄
volatile HANDLE PostMsgEvent; //WCOMMNOTIFY消息的事件对象
volatile HANDLE hWAITMCUEvent; //确定mcu应答事件
OVERLAPPED osRead, osWrite; //重叠读/写///////////////函数声明/////////////////////////////////
int OpenComm();
BOOL dataany();
DWORD CommProc(LPVOID pParam);//通信处理函数
BOOL WriteComm();
_declspec(dllexport) DWORD WINAPI MyCommand(unsigned char com, unsigned char win,
unsigned char vari1,unsigned char vari2);
**函数名称:OpenComm
**输入:
**返回:0、已连接 1、监视线程创建失败 2、调用成功
**功能描述:打开并配置串口参数,建立工作者线程
**全局变量:postRecvId、hCom、bConnected、pThread、
** PostMsgEvent、hWAITMCUEvent、osRead、osWrite
**调用模块、函数:
**
**
**作者:商国华
**日期:2003-7-23
**修改日期:
**版本:
*********************************************************************/
int OpenComm()
{
//取得用于POSTTHREADMESSAGE()参数####
//postRecvId=GetCurrentThreadId();
//GetCurrentThread(); COMMTIMEOUTS TimeOuts;
if(bConnected) return 0;
//以重叠方式打开COM3,相应设置:串口基本配置4,中断请求:04,03E8-03EF
hCom=CreateFile("COM3",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL
);
if(hCom==INVALID_HANDLE_VALUE)
AfxMessageBox("Can't open connection");//连接失败
/////////////////一般通信参数设置////////////////////////////////////
DCB dcb;
SetupComm(hCom,MAXBLOCK,MAXBLOCK);
SetCommMask(hCom, EV_RXCHAR);
GetCommState(hCom,&dcb);
dcb.BaudRate=2400;
dcb.ByteSize=8;
dcb.Parity=0;
dcb.StopBits=0;
SetCommState(hCom,&dcb);
///////////////////////超时设置/////////////////////////////////////
//把间隔超时设为最大,把总超时设为0将导致ReadFile立即返回并完成操作
TimeOuts.ReadIntervalTimeout=MAXDWORD;
TimeOuts.ReadTotalTimeoutMultiplier=0;
TimeOuts.ReadTotalTimeoutConstant=0;
//设置写超时以指定GetOverlappedResult函数的等待时间
TimeOuts.WriteTotalTimeoutMultiplier=5000;
TimeOuts.WriteTotalTimeoutConstant=200000;
SetCommTimeouts(hCom, &TimeOuts);
////////////////创建同步对象////////////////////////////////////
// 为WCOMMNOTIFY消息创建事件对象,手工重置,初始化为有信号的
PostMsgEvent=CreateEvent(NULL, TRUE, TRUE, NULL);
memset(&osRead, 0, sizeof(OVERLAPPED));
memset(&osWrite, 0, sizeof(OVERLAPPED));
// 重叠读事件对象
osRead.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL);
// 重叠写事件对象
osWrite.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL);
hWAITMCUEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
//////////////创建监视线程//////////////////////////////////////////
DWORD dwThreadID; //监视线程ID
pThread=CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)CommProc,
(LPVOID)NULL,
0,
&dwThreadID
); if(pThread==NULL)
{
CloseHandle(hCom);
return 1;
}
else
{
bConnected=TRUE;
//ResumeThread(); // 恢复线程运行
}
//AfxMessageBox("串口已打开");
return 2;
}/*********************************************************************
**函数名称:CloseComm
**输入:
**返回:0、没有连接 1、操作成功
**功能描述:结束工作者线程,关闭串行口
**全局变量:bConnected、pThread、PostMsgEvent、hWAITMCUEvent、
** osRead、osWrite
**调用模块、函数:
**
**
**作者:商国华
**日期:2003-7-23
**修改日期:
**版本:
*********************************************************************/
_declspec(dllexport) BOOL WINAPI CloseComm()
{
if(!bConnected) return 0;
bConnected=FALSE;
//结束CommProc线程中WaitSingleObject函数的等待
SetEvent(PostMsgEvent);
SetEvent(hWAITMCUEvent);
//结束CommProc线程中WaitCommEvent的等待
SetCommMask(hCom, 0);
//等待辅助线程终止
WaitForSingleObject(pThread, INFINITE);
pThread=NULL;
CloseHandle(hCom);
//删除事件句柄
if(PostMsgEvent)
CloseHandle(PostMsgEvent);
if(osRead.hEvent)
CloseHandle(osRead.hEvent);
if(osWrite.hEvent)
CloseHandle(osWrite.hEvent);
if(hWAITMCUEvent)
CloseHandle(hWAITMCUEvent);
AfxMessageBox("DLL串口关闭操作成功");
return 1;
}
{
while(test=PeekMessage(&Mmsg,NULL,WM_COMMNOTIFY,WM_COMMNOTIFY,PM_REMOVE))
{
TransLateMsg(Mmsg);//
DispatchMsg(Mmsg);// 名字可能不大对,用来分发消息的
if(Mmsg.message==WM_COMMNOTIFY) AfxMessageBox("收到");
}
}
要加一个while(1)的循环,你的while(test=PeekMessage(&Mmsg,NULL,WM_COMMNOTIFY,WM_COMMNOTIFY,PM_REMOVE))
只能取一次MSG