http://download.csdn.net/detail/luck_good/3798729
经过几天的努力终于实现了我的modscan36,几点笔记,
1.
使用api读写串口(网上下载的已经封装过的串口类CComControl)。
2.
按照modscan32的逻辑应该是所有new出来的childframe组是共享一个串口对象的。即一个app只开一个串口,所以将串口对象定义成全局的了,CComControl* m_Com;
并在InitInstance函数中创建对象 m_Com = new CComControl(pMainFrame->m_hWnd)(还有crc = new Crc(16,0X8005,1,0XFFFF,0);)
3.
3个view分别是
class CMdi_modbus1View : public CFormView
class CMyDataView : public CView
class CMyCurveView : public CView
上面的视modbus1View 用于用户交互,继承于CFormView,本来要和modscan32那样不用formview的,但动态new和create各个控件和排列控件还需要花时间去算,不如formview直接拖的省事。
左边的视CMyDataView 用于显示数据,继承于cview,打印数据。将发送数据缓冲区(从doc中get,是doc的成员变量,是CMdi_modbus1View传递给doc的buff指针)的值和接受数据缓冲区(全局)的值textout。
右边的CMyCurveView 用于绘图,将接受数据缓冲区(全局)的值画出来。
4.
接收数据:构造m_Com对象时,指定了了接收消息的HWND窗口句柄是pMainFrame->m_hWnd,因为想不到其他是什么窗口可以接收这个消息,所以就用这个了(用view去接收肯定不行的,应为这里即使打开一个childframe也会有3个view,并且在打开多个childframe时,有众多的view,他们大部分都需要串口接收到的数据以绘图,那么此时指定哪个view呢?所以不要用view)。这样的话,在mainframe的WindowProc虚函数里就要处理消息并分拣数据以传递给打开过的不同的doc(childframe组)的成员变量,然后附属于该doc的view就可以用 (CMdi_modbus1Doc*)GetDocument()获取到该doc的数据成员。从图中可明显看出3个view对应1个doc,,他们共同构成1个childframe。是3面1体。
有点麻烦的就是分拣了,那个childfram里的view(CMdi_modbus1View)发得请求,就把对应该请求的从机的回复分配到他的doc里。--当然如果仅打开一个childframe就不需要
分拣了,直接传递过去就行了。我这里就是这么搞的---O(∩_∩)O~。但比这个更随意一点,接收buff使用的是全局变量,传也没传,在view中直接使用全局变量buff绘图的,没拐到doc里要数据。--所以这个程序在打开多个childframe的时候response_times下的接收到数据就会紊乱。--恩,开一个childframe没问题的。
5
.发送数据:本来打算每打开一个childframe就添加一个线程用于定时发送数据。后来观察modscan32发现不管打开多少childframe都是4个线程,想了想,在线程函数中读取
view的数据也不太好办(新手),就按照每打开一个childframe就添加一个定时器去定时0.5s发送好了,使用主线程,不过没怎么影响界面操作。
发送数据缓冲区没必要用全局变量了,使用的是view中的一个局部变量yxdata,通过界面上控件获取各个信息以构造modbus帧的发送buff即yxdata,是static。然后调用m_Com发送,然后将yxdata首地址赋给给doc里的对应指针。这里yxdata需要使用static,因为是局部变量yxdata在每次函数执行完毕都会清掉,然后在下一次执行时,分的内存位置就不一定时上次的那个,这样传递到doc中,再被其他view访问的时候,可能这个内存区域已经是别的东东了,所以就有可能(或者说一定)出错。所以要用static修饰一下。
6.
view的重绘
在CMdi_modbus1View 的定时器函数中调用,
this->GetDocument()->UpdateAllViews(NULL);//更新所有view,发出消息
在CMyDataView 和CMyCurveView的 OnUpdate函数中调用 CWnd::Invalidate();以使本view调用OnDraw函数进行重绘
7.
CMyDataView和CMyCurveView中实现重绘功能即OnDraw函数,doc里没有实现保存功能即Serialize函数。没有modbus-tcp,没有modbus-ascii。O(∩_∩)O不是本业,要求不高。
但更重要的是默认是9600 even 8 1,而没将它开放出来,想使用就改源码吧