createevent(createevent js)

http://www.itjxue.com  2023-02-09 13:37  来源:未知  点击次数: 

React 事件委托

DOM事件发生之后,React通过事件委托减大部分事件代理至Document层.

1 .ReactEventListener:负责给元素绑定事件

2 .ReactEventEmitter:暴露接口给React组件层用于添加事件订阅

3 .EventPluginHub负责管理和注册各种插件

4 .事件分发的时候.React事件系统使用了插件机制来管理不同的事件

1 .可以进行浏览器原生事件的封装,对浏览器兼容性进行处理

2 .React通过syntheticEvent实现跨平台的事件机制

3 .原生事件的升级和改造.

1 .负责事件类型blur,focus,click,submit,touchMove,mouseMove,scroll,drag,load

2 .事件模型符合标准的捕获执行,冒泡流程,可以比较简单的绑定在document上面,和原生DOM事件式一一对应的关系,比较好处理

1 .负责事件类型

mouseEnter,mouseLeave,pointerEbnter,pointerLeave

2 .负责处理一些不支持冒泡的事件

1 .负责事件

onTouchTap

2 .为了解决ios移动端300ms点击延迟.onTouchTap这个事件会忽略300ms后的onClick事件

1 .自定义change事件

1 .为表单元素规范化了select事件,用于input,textarea,contentEditable元素

1 .befoerInput事件以及composition事件.当用户使用拼音输入法输入汉字的时候,这个事件就会被触发

1 .form 的submit,reset

2 .媒体触发事件,video/audio的相关事件onplaying,onprogress,onratechange事件.

1 .discreateEvent离散事件

2 .UserblockingEvent用户阻塞事件:这些事件会阻塞用户的交互,优先级是1

3 .continuousEvent连续事件.优先级是2,最高,不会被打断

串口读不到数据,错误在哪里?

帖了这么多代码还不够啊,你的布尔变量comOpened和hCom的赋值不在这里,有没有调试过这两个值会不会有问题?譬如你的comOpened和comOpened在执行到read()之前根本没有得到机会被初始化为FALSE和NULL的话,这两个变量很有有可能存储的是非零的垃圾值,这样的状态进入到read后也还是会跳过if语句,使hCom未被打开就被ReadFile了。 因此,问题可能不是出在这里,而是其他地方的初始化问题,下断点再看看呢!

如何用C语言控制计算机串口

基本方法是使用CreateFile来建立一个串口文件,然后用overlap的方式进行读写

#define SERAIL_PORT_BUF_MAX (1024*8)

typedef HRESULT (*PFN_CMD_PARSE_DATA)(HANDLE hParseApp, LPCSTR szRspCmd, int nCmdLen);

class CUsbSrvApp// : public CWinApp

{

public:

CUsbSrvApp();

~CUsbSrvApp();

BOOL OnSendData(const char *szBuf, int nLen);// 发送数据

int ComConnect(CString strPort); // 连接COM口

HANDLE OpenComPort(CString strPort, int nBaudRate, int nDataBits, int nStopBits, int nParity, int nFlowCtrlType); // 打开串口

void Close(); // 关闭串口

HANDLE m_hCom;

BOOL m_bConnected;

OVERLAPPED m_OverlappedRead;

OVERLAPPED m_OverlappedWrite;

CWinThread *m_pThread;

PFN_CMD_PARSE_DATA m_pRspCmdFunc; // 用来处理接受数据的CALLBACK

HANDLE m_hParseApp;

};

CUsbSrvApp::CUsbSrvApp()

{

// TODO: add construction code here,

// Place all significant initialization in InitInstance

m_bConnected = false;

m_hCom = NULL;

m_pRspCmdFunc = NULL;

}

CUsbSrvApp::~CUsbSrvApp()

{

}

//打开串口通信,并返回串口句柄

HANDLE CUsbSrvApp::OpenComPort(CString strPortName,

int nBaudRate,

int nDataBits,

int nStopBits,

int nParity,

int nFlowCtrlType)

{

DCB dcb;

COMMTIMEOUTS CommTimeOuts ;

COMMCONFIG ComConfig;

HANDLE hComPort;

CString strPort;

strPort.Format("\\\\.\\%s",strPortName); // COM口的文件名应该是 \\.\COMXX

//打开窗口其实就是创建一个文件

hComPort = CreateFile(strPort,

GENERIC_READ | GENERIC_WRITE,

FILE_SHARE_READ | FILE_SHARE_WRITE,

NULL,

OPEN_EXISTING,

FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,

NULL);

if (INVALID_HANDLE_VALUE == hComPort)

return INVALID_HANDLE_VALUE;

// 设置一些COM口通讯参数和OVERLAP

CommTimeOuts.ReadIntervalTimeout = -1;

CommTimeOuts.ReadTotalTimeoutConstant = 0;

CommTimeOuts.ReadTotalTimeoutMultiplier = 0;

CommTimeOuts.WriteTotalTimeoutConstant = 0;

CommTimeOuts.WriteTotalTimeoutMultiplier = 0x1388;

SetCommTimeouts( m_hCom, CommTimeOuts ) ;

SetDefaultCommConfig(strPortName, ComConfig, sizeof(COMMCONFIG));

GetCommState(m_hCom, dcb ) ;

dcb.BaudRate = nBaudRate;

dcb.ByteSize = nDataBits;

dcb.StopBits = nStopBits;

dcb.fParity = (NOPARITY != nParity);

dcb.Parity = nParity;

//set the receive char

dcb.EvtChar = 0x0D;

switch(nFlowCtrlType)

{

case 0: //no flow control

break;

case 1://HARD_FLOW_CTRL:

dcb.fOutxCtsFlow = TRUE;

dcb.fOutxDsrFlow = TRUE;

dcb.fDtrControl = DTR_CONTROL_DISABLE;

dcb.fDsrSensitivity = TRUE;

dcb.fRtsControl = RTS_CONTROL_TOGGLE;

break;

case 2://SOFT_FLOW_CTRL:

dcb.fOutX = TRUE;

dcb.fInX = TRUE;

break;

}

BuildCommDCB(_T("baud=115200 parity=N data=8 stop=1"),dcb);

SetCommState(hComPort, dcb ) ;

SetCommMask(hComPort, 0);

SetCommMask(hComPort, EV_RXCHAR|EV_CTS|EV_DSR|EV_RLSD|EV_RING);

SetupComm( hComPort, SERAIL_PORT_BUF_MAX,SERAIL_PORT_BUF_MAX) ;

//clear read and write buffer

PurgeComm( hComPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR );

return hComPort;

}

void CUsbSrvApp::Close()

{

if(m_bConnected)

{

m_bConnected = false;

CloseHandle(m_hCom);

m_hCom = NULL;

}

}

// 这个线程是监视串口数据,一旦有数据则读取并调用CALLBACK通知客户端

UINT ReceiveComData(LPVOID pParam)

{

CUsbSrvApp *pUsbSrv = (CUsbSrvApp *)pParam;

HANDLE hComPort = pUsbSrv-m_hCom;

DWORD dwEvtMask=0;

DWORD dwErrorFlags;

SetCommMask( hComPort, EV_RXCHAR);

OVERLAPPED osRead;

osRead.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);

DWORD dwTransfer = 0;

while(pUsbSrv-m_bConnected)

{

if( !WaitCommEvent( hComPort, dwEvtMask,osRead))

{

if( GetLastError()== ERROR_IO_PENDING)

{

WaitForSingleObject(osRead.hEvent, INFINITE);

if(dwEvtMaskEV_RXCHAR==EV_RXCHAR)

{

COMSTAT ComStat={0} ;

DWORD dwReadLen = 0;

DWORD dwBytesRead = 0;

DWORD dwTotalLen = 0;

ClearCommError(hComPort, dwErrorFlags, ComStat );

dwTotalLen = ComStat.cbInQue;

dwReadLen = (SERAIL_PORT_BUF_MAX dwTotalLen)?dwTotalLen:SERAIL_PORT_BUF_MAX;

BYTE *pBuf = new BYTE[dwTotalLen+1];

memset(pBuf, 0 , dwTotalLen+1);

DWORD nReadBufLen=0;

while(dwTotalLen0)

{

if(FALSE == ReadFile( hComPort, pBuf+nReadBufLen,dwReadLen, dwBytesRead,pUsbSrv-m_OverlappedRead))

{

if(GetLastError() == ERROR_IO_PENDING)

{

GetOverlappedResult(hComPort,osRead, dwTransfer, TRUE );

}

break;

}

nReadBufLen +=dwBytesRead;

dwTotalLen -=dwBytesRead;

dwReadLen -= dwBytesRead;

dwReadLen = (SERAIL_PORT_BUF_MAXdwReadLen)?dwReadLen:SERAIL_PORT_BUF_MAX;

}

if(pUsbSrv-m_pRspCmdFunc!=NULLnReadBufLen!=0)

{

pUsbSrv-m_pRspCmdFunc(pUsbSrv-m_hParseApp, (char*)pBuf,nReadBufLen);

}

delete pBuf;

ClearCommError(hComPort, dwErrorFlags, ComStat );

int len =0;//= m_retList.GetSize();

}//endif if(dwEvtMaskEV_RXCHAR==EV_RXCHAR)

}//endif if( GetLastError()== ERROR_IO_PENDING)

}//endif if( !WaitCommEvent( hComPort, dwEvtMask,o))

else

{

if(GetLastError() == ERROR_IO_PENDING) {

GetOverlappedResult(hComPort, osRead, dwTransfer, TRUE ); // sleep thread

}

}

Sleep(1);

} //endwhile while(m_bConnected)

return 0;

}

int CUsbSrvApp::ComConnect(CString strPort)

{

int nBaudRate = 115200;

int nDataBits = 8;

int nStopBits = 1;

int nParity = 0;

int nFlowCtrl = 1;

if (NULL != m_hCom || m_bConnected)

{

return 0;

}

m_hCom = OpenComPort(strPort,nBaudRate,nDataBits,nStopBits,nParity,nFlowCtrl);

if( INVALID_HANDLE_VALUE == m_hCom)

{

m_hCom = NULL;

return 0;

}

memset( m_OverlappedRead, 0, sizeof( OVERLAPPED ) );

memset( m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );

m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );

m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );

m_pThread = AfxBeginThread( ReceiveComData,(void*)this,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED ,NULL );

if( NULL == m_pThread )

{

CloseHandle( m_hCom );

m_hCom = NULL;

return FALSE;

}

else

{

m_bConnected = TRUE;

m_pThread-ResumeThread( );

}

return TRUE;

}

int CUsbSrvApp::OnSendData(const char *szBuf, int nLen)

{

BOOL bWriteStat;

BOOL bWrite = TRUE;

DWORD dwBytesWrite = 0;

DWORD dwBytesWritten = 0;

int dwByteswrittenTotal = 0;

if (NULL == m_hCom)

return 0;

int nSentTimes=0;

while(dwByteswrittenTotalnLennSentTimes10)

{

nSentTimes++;

dwBytesWrite = nLen-dwByteswrittenTotal;

bWriteStat = WriteFile( m_hCom, szBuf+dwByteswrittenTotal, dwBytesWrite, dwBytesWritten, m_OverlappedWrite );

if( !bWriteStat)

{

if ( GetLastError() == ERROR_IO_PENDING )

{

dwBytesWritten = 0;

bWrite = FALSE;

}

}

if (!bWrite)

{

bWrite = TRUE;

bWriteStat = GetOverlappedResult(m_hCom, // Handle to COMM port

m_OverlappedWrite, // Overlapped structure

dwBytesWritten, // Stores number of bytes sent

TRUE); // Wait flag

//deal with the error code

}

dwByteswrittenTotal += dwBytesWritten;

}

if(dwByteswrittenTotalnLen)

return 0;

else

return 1;

}

createeventa是什么函数

CreateEvent是一个Windows API函数。它用来创建或打开一个命名的或无名的事件对象。如果想为对象指定一个访问掩码,应当使用CreateEventEx函数。

vc++中,关于WaitForSingleObject和CreateEvent的用法

ExitHandle是一个标志事件,你可以把它理解为一个BOOL类型的变量

WaitForSingleObject是在指定的时间内等待这个事件发生,如果发生,返回值就是WAIT_OBJECT_0,你可以理解为在指定的时间内判断ExitHandle是否为真.

虽然效果上和BOOL变量类似,但实际上工作原理复杂的多,这涉及到WINDOWS的线程切换及线程同步等相关知识,有兴趣你可以仔细看下相关资料.

如何使用多媒体定时器

Timer定时器是由应用程序响应定时消息WM_TIMER实现定时。Timer定时器是IBM PC硬件和ROM BIOS构造的定时器的简单扩充。PC的ROM初始化8253定时器来产生硬件中断08H,而08H中断的频率为18.2Hz,即至少每隔54.925 ms中断一次。此外,这个定时消息的优先权太低,只有在除WM_PAINT外的所有消息被处理完后,才能得到处理。多媒体定时器也是利用系统定时器工作的,但它的工作机理和普通定时器有所不同。首先,多媒体定时器可以按精度要求设置8253的T/C0通道的计数初值,使定时器不存在54.945ms的限制;其次,多媒体定时器不依赖于消息机制,而是用函数产生一个独立的线程,在一定的中断次数到达后,直接调用预先设置好的回调函数进行处理,不必等到应用程序的消息队列为空,从而切实保障了定时中断得到实时响应,使其定时精度可达1ms。(4)在TimerThread.h文件中定义宏,代码如下:#define WM_THREADMSG WM_USER+1(5)在TimerThread.h文件中定义数据结构,代码如下:typedef struct THREAD_PARAM{ HWND hWnd; int nTime; HANDLE hTimerEvent; HANDLE hExitEvent;}_THREAD_PARAM;(6)在CWinThread类中添加成员变量,代码如下:public: THREAD_PARAM* m_pThreadParam;(7)在CTimerThread类中重载CWinThread::Run函数,代码如下:// TimerThread.cpp int CTimerThread::Run(){ while (TRUE) { //等待定时事件 while (WAIT_TIMEOUT == WaitForSingleObject(m_pThreadParam-hTimerEvent, 200)) { //等待退出事件 if (WaitForSingleObject(m_pThreadParam-hExitEvent, 0) == WAIT_OBJECT_0) { ::AfxEndThread(0); } } m_pThreadParam-nTime += 100; //向主线程窗口发送消息 ::PostMessage(m_pThreadParam-hWnd, WM_THREADMSG, 0, 0); //复位定时事件 ResetEvent(m_pThreadParam-hTimerEvent); }}(8)在CDemoDlg类中添加成员变量,代码如下:// DemoDlg.cpp private: UINT m_nTimerID; CTimerThread* m_pTimerThread; THREAD_PARAM m_ThreadParam;(9)在CDemoDlg类的构造函数和析构函数中添加如下代码:// DemoDlg.cpp CDemoDlg::CDemoDlg(CWnd* pParent /*=NULL*/) : CDialog(CDemoDlg::IDD, pParent){ // … m_nTimerID = 0; m_pTimerThread = NULL; m_ThreadParam.nTime = 0; m_ThreadParam.hTimerEvent = CreateEvent(NULL, TRUE, FALSE, NULL); m_ThreadParam.hExitEvent = CreateEvent(NULL, TRUE, FALSE, NULL);}CDemoDlg::~CDemoDlg(){ //取消定时器 if (m_nTimerID != 0) { timeKillEvent(m_nTimerID); } //结束定时线程 if (m_pTimerThread != NULL) { //设置退出事件 SetEvent(m_ThreadParam.hExitEvent); //等待定时线程结束 ::WaitForSingleObject(m_pTimerThread-m_hThread, INFINITE); delete m_pTimerThread; m_pTimerThread = NULL; } CloseHandle(m_ThreadParam.hTimerEvent); CloseHandle(m_ThreadParam.hExitEvent);}(10)在CDemoDlg类中为重载CDialog::OnInitDialog函数,代码如下:// DemoDlg.cpp BOOL CDemoDlg::OnInitDialog(){ CDialog::OnInitDialog(); // … SetDlgItemInt(IDC_TIME, 0); return TRUE;}(11)在CDemoDlg类中为WM_THREADMSG添加消息处理函数,代码如下:// DemoDlg.cpp BEGIN_MESSAGE_MAP(CDemoDlg, CDialog) //{{AFX_MSG_MAP(CDemoDlg) // … ON_MESSAGE(WM_THREADMSG, OnMsgFunc) //}}AFX_MSG_MAPEND_MESSAGE_MAP() LRESULT CDemoDlg::OnMsgFunc(){ SetDlgItemInt(IDC_TIME, m_ThreadParam.nTime); return 1;}(12)在CDemoDlg类中为Button控件添加BN_CLICKED消息处理函数,代码如下:// DemoDlg.cpp void CDemoDlg::OnTest1(){ //取消定时器 if (m_nTimerID != 0) { timeKillEvent(m_nTimerID); } //结束定时线程 if (m_pTimerThread != NULL) { //设置退出事件 SetEvent(m_ThreadParam.hExitEvent); //等待定时线程结束 ::WaitForSingleObject(m_pTimerThread-m_hThread, INFINITE); delete m_pTimerThread; m_pTimerThread = NULL; } m_ThreadParam.hWnd = GetSafeHwnd(); m_ThreadParam.nTime = 0; SetDlgItemInt(IDC_TIME, 0); TIMECAPS tc; //获得定时器分辨率 if (timeGetDevCaps(tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) { return; } UINT nResolution = min(max(tc.wPeriodMin, 1), tc.wPeriodMax); UINT nInterval = 100; if (nInterval nResolution) { nInterval = nResolution; } //设置定时最小分辨率 timeBeginPeriod(nResolution); //设置定时器 m_nTimerID = timeSetEvent(nInterval, nResolution, (LPTIMECALLBACK)m_ThreadParam.hTimerEvent, (DWORD)this, TIME_PERIODIC | TIME_CALLBACK_EVENT_SET); //创建定时线程 m_pTimerThread = (CTimerThread*)AfxBeginThread(RUNTIME_CLASS(CTimerThread), THREAD_PRIORITY_ABOVE_NORMAL, 0, CREATE_SUSPENDED); m_pTimerThread-m_bAutoDelete = FALSE; m_pTimerThread-m_pThreadParam = m_ThreadParam; m_pTimerThread-ResumeThread();}void CDemoDlg::OnTest2(){ //取消定时器 if (m_nTimerID != 0) { timeKillEvent(m_nTimerID); } //结束定时线程 if (m_pTimerThread != NULL) { //设置退出事件 SetEvent(m_ThreadParam.hExitEvent); //等待定时线程结束 ::WaitForSingleObject(m_pTimerThread-m_hThread, INFINITE); delete m_pTimerThread; m_pTimerThread = NULL; }}

(责任编辑:IT教学网)

更多

推荐excel文章