搭建环境:VS2013(mfc120生成器)+python3.6
这是一个记录了遇到的大大小小的坑,真的是十个里面九个是坑!!这里是用来记录我遇到的坑的,当然里面还有许多未解之谜,我自己也不明白
串口方面:
1.COM控件方面:
据说这个控件其实是可以自己写的……然后我想了一下……不想写,然后去网上下载了一个。众所周知,COM控件32位的在64位系统中也是可以用的。然后,问题是我也成功注册了。
有cmd命令行注册,有直接regsvr32 C:\Windows\system32(sysWOW64)\MSComm32.ocx注册的,然后每次它都给我显示注册成功,但是到了VS上就是不能用……注意,这是针对你的目标平台和生成平台什么的都是x64的MFC工程的。
具体工程设置参考地方为:
显示是什么mfc120ud.dll有个什么地方代码错误。
注意:在它编译的过程中,你可以看到它的Output框中显示的所有文件加载路径都是 C:\Windows\system32\xxxxx之类的,所以私以为,正确注册路径应该是在system32文件夹之下,但是……问题是我也注册过了,也显示注册成功了,但是踏马就是不行……(ノ`Д)ノ敲里吗……同时你可以清楚的看到,你的Output框向上拉,能看到错误信息:
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\occsite.cpp(528) : AppMsg - CoCreateInstance of OLE control {648A5600-2C6E-101B-82B6-000000000014} failed.
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\occsite.cpp(529) : AppMsg - >>> Result code: 0x80040154
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\occsite.cpp(530) : AppMsg - >>> Is the control is properly registered?
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\occcont.cpp(919) : AppMsg - Warning: Resource items and Win32 Z-order lists are out of sync. Tab order may be not defined well.
Debug Assertion Failed!
然后通过mscomm1.h文件中
对比上面的错误信息中OLE control的号码,你能清楚的知道就是你的COM控件没有注册好的问题。那么问题来了,明明在注册表上能看到,明明显示注册成功,但是……为什么这个控件就是不能用呢?究竟是为什么呢?(ノ`Д)ノ最后我得出,敲里吗,我还不如用WINAPI写呢!!
注意,COM控件只能开com1-com9(似乎是9,也可能是15,忘了)的串口号!!但是WINAPI都能开,想开多少开多少,虽然确实没有控件写代码方便。至于上面那个问题,我仍然没有明白。知道的同学,希望能留言或者私信我,救救我这个在坑底的可怜孩子吧。(╥╯^╰╥)
2.WINAPI方面:
这里絮絮叨叨一些我知道的坑,我没有踩的坑,嘻嘻(#^.^#)……
1.COM1-9用的是:lpszPortName.Format(_T("COM%d"), port);
COM10以上包括10用的是:lpszPortName.Format(_T("\\\\.\\COM%d"), port);
这个很关键,很有决定你是不是能成功打开串口的关键!!!
2.关于用使用COMBO控件进行串口号选择时,可以使用for语句进行循环添加,但是注意!!!你的添加语句一定要格式对齐,不然它的列表会自动变成:COM1,COM11,COM12……这样,这时,你如果使用port = IDCOMBO.GetCurSel() + 1;语句来读取串口号的话,就相当于你在COMBO控件列表中选择的COM11->port=2。这样就很悲剧了。所以,我一般使用:
int i = 0;
CString TEMP = _T("COM");
for (i = 0; i < 30; i++)
{
TEMP.Format(_T("COM%2d"), i + 1);
IDUART.AddString(TEMP);
}
3.另外关于串口接收方面,我比较喜欢使用线程进行全程监听。这样写写比较方便,毕竟我的工程不算大,但是,这样做其实挺耗资源的,不过……反正我的工程不大,嘻嘻(#^.^#)
hThreadSerial_Recv = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Tread, (LPVOID)(Com), 0, &m_dwIOControlThreadId);
那么问题来了,使用线程我只能传进一个参数,而且,如果要显示的话你的编辑框的value不能是static的。那么怎么办呢?我在网上找到了办法……不过由于版本的问题,需要稍微修改一下,原网址我已经找不到了……抱歉,原作者看到我请留言,我会加上参考的,sorry啊……
哦,对了,你的线程函数声明的时候必须是static的,不然会报错的!
static DWORD WINAPI CWINAPIDlg::Tread(LPVOID lpvoid);这样的!!不然会报错。
好了,下面是怎么使你接受到的文本显示在接收框里面的方法:
这是我的线程function,其中Rdata是我用来进行接收缓存的。红笔画的是使接收的东西显示在编辑框的关键。注意,网上很多的PostMessage的第一个形参写的好像都是xxxx->m_hWnd的。但是那个是旧版本的!!现在更新了,使用的方法变成上述的了。另外,网上有些说你的线程函数传入的形参希望是m_hWnd的,也是走不通的!!因为这样你就没有办法访问到COM的句柄了!!!!
上面那个是让你把消息传递出去的函数,为了使函数不报错,你还需要在你的XXDlg.h文件声明一个:
#define COM_RECVDATA (WM_USER+1000)
同样在这个文件上声明这个函数:
这个函数是用于将消息显示在编辑框的函数。注意,它的返回类型必须是LRESULT 也有说是void,但是我的这个版本是LRESULT不然会报错。而且如果声明的位置不在DECLARE_MESSAGE_MAP()前面,也会报错,各种错,神奇的错误!!所以这点要注意!!!
让我们来看看这个函数的function内涵:
这个很好理解,RX_TXT是我接收编辑框的value值,然后更新编辑框显示,然后弹出个框框告诉我显示完毕了。
另外,还需要在这个xxDlg.c文件中的这个地方声明一下消息的传递
如果,你经历了这些,你的工程还是各种报错,那么……你还是重新新建工程吧……因为我也遭遇过这个状况,完全不知道哪里错了,然后新建工程重新按照这些重新写就能用了。节哀……
写的太多了,我把MFC使python脚本运行的东西放到下一篇博客进行书写。不喜欢写的又臭又长,嘻嘻(#^.^#)