}
fd = kbd_fd; //设置文件描述符为鼠标描述符 /* If data is present on the keyboard fd, service it: */
if (fd >= 0 && FD_ISSET (fd, in)) {//如果fd大于0且位于可读文件描述符集中 FD_CLR (fd, in); //从可读文件描述符集中删除该描述符 if (read_key ()) //读取键盘按键信息成功
retvalue |= IAL_KEYEVENT; //返回值设为包含IAL_KEYEVENT else { /* play at a timeout event *///读取键盘按键信息失败 if (timeout) { //timeout不为0
timeout->tv_sec = 0; //设置timeout为0 timeout->tv_usec = 0; } } }
} else if (e < 0) {//如果e<0,表示出现错误,返回-1 return -1; }
return retvalue;//返回retvalue }
InitGUI ()?InitLWEvent ()?InitIAL (void)(确定输入输出引擎,当前为QVFB)? IAL_InitInput (__mg_cur_input, mdev, mtype)(当前为 InitQVFBInput)
6 、解析事件ParseEvent
1、数据结构:
typedef struct _LWEVENT {
int type; int count; DWORD status; LWEVENTDATA data; }LWEVENT;
typedef LWEVENT* PLWEVENT;
typedef union _LWEVENTDATA { MOUSEEVENT me; KEYEVENT ke; }LWEVENTDATA;
typedef struct _KEYEVENT { int event; int scancode; DWORD status;
}KEYEVENT;
typedef KEYEVENT* PKEYEVENT;
typedef struct _MOUSEEVENT { int event; int x; int y;
DWORD status; }MOUSEEVENT;
typedef MOUSEEVENT* PMOUSEEVENT;
2、函数分析
函数作用:将event时间转换成 MSG 类型的事件并加入到消息队列中
static void ParseEvent (PMSGQUEUE msg_que, int event) {
LWEVENT lwe; PMOUSEEVENT me; PKEYEVENT ke; MSG Msg;
ke = &(lwe.data.ke); me = &(lwe.data.me); me->x = 0; me->y = 0;
Msg.hwnd = HWND_DESKTOP; Msg.wParam = 0; Msg.lParam = 0;
lwe.status = 0L;
//根据event事件获得底层事件lwe的值 if (!GetLWEvent (event, &lwe)) return;
Msg.time = __mg_timer_counter; //若底层事件为超时事件
if (lwe.type == LWETYPE_TIMEOUT) {
Msg.message = MSG_TIMEOUT;//消息类型为MSG_TIMEOUT Msg.wParam = (WPARAM)lwe.count; Msg.lParam = 0;
QueueMessage (msg_que, &Msg);//将消息加入消息队列 }
else if (lwe.type == LWETYPE_KEY) {//若底层事件为键盘事件
Msg.wParam = ke->scancode;//消息的wParam成员值为键盘事件的扫描码成员 Msg.lParam = ke->status;//消息的wParam成员值为键盘事件的状态成员 if (ke->event == KE_KEYDOWN){//如果键盘事件为击键事件
Msg.message = MSG_KEYDOWN;//消息类型为MSG_KEYDOWN }
else if (ke->event == KE_KEYUP) {//如果键盘事件为按键释放事件 Msg.message = MSG_KEYUP;//消息类型为MSG_KEYUP }
else if (ke->event == KE_KEYLONGPRESS) { Msg.message = MSG_KEYLONGPRESS; }
else if (ke->event == KE_KEYALWAYSPRESS) { Msg.message = MSG_KEYALWAYSPRESS; }
if (!(srv_evt_hook && srv_evt_hook (&Msg))) { QueueMessage (msg_que, &Msg); } }
else if (lwe.type == LWETYPE_MOUSE) {//若底层事件为鼠标事件 Msg.wParam = me->status;//消息的wParam参数为鼠标的状态信息 switch (me->event) {//判断鼠标事件的类型,并依此确定消息的类型 case ME_MOVED: //鼠标移动事件 Msg.message = MSG_MOUSEMOVE; SetCursor (GetSystemCursor (IDC_ARROW)); break;
case ME_LEFTDOWN:
Msg.message = MSG_LBUTTONDOWN; break; case ME_LEFTUP:
Msg.message = MSG_LBUTTONUP; break;
case ME_LEFTDBLCLICK:
Msg.message = MSG_LBUTTONDBLCLK; break;
case ME_RIGHTDOWN:
Msg.message = MSG_RBUTTONDOWN; break; case ME_RIGHTUP:
Msg.message = MSG_RBUTTONUP; break;
case ME_RIGHTDBLCLICK:
Msg.message = MSG_RBUTTONDBLCLK; break; }
Msg.lParam = MAKELONG (me->x, me->y);//将鼠标信息转换为消息的lParam
if (!(srv_evt_hook && srv_evt_hook (&Msg))) {
QueueMessage (msg_que, &Msg);//将消息加入消息队列 } } }
7、获取底层事件:GetLWEvent
根据event的值确定lwe的成员值
BOOL GetLWEvent (int event, PLWEVENT lwe) {
static LWEVENT old_lwe = {0, 0}; unsigned int interval; int button;
PMOUSEEVENT me = &(lwe->data.me); PKEYEVENT ke = &(lwe->data.ke); const char* keystate; int i;
int make; /* 0 = release, 1 = presse */ //如果事件类型为0,表示超时事件或者错误事件 if (event == 0) {
/*#define DEF_USEC_TIMEOUT 300000 timeoutusec = DEF_USEC_TIMEOUT | timeoutusec = mytimeoutusec; timeout_threshold = timeoutusec / 10000; timeout_count = timeout_threshold;
#define DEF_REPEAT_TIME 50000 repeatusec = DEF_REPEAT_TIME; | repeatusec = myrepeatusec repeat_threshold = repeatusec / 10000; */ //如果超时
if (__mg_timer_counter >= timeout_count) {
timeout_count = __mg_timer_counter + repeat_threshold;
// repeat last event
if (old_lwe.type == LWETYPE_KEY //如果旧底层事件类型为LWETYPE_KEY && old_lwe.data.ke.event == KE_KEYDOWN) {//且为KEYDOWN类型 memcpy (lwe, &old_lwe, sizeof (LWEVENT)); //将旧事件复制给lwe lwe->data.ke.status |= KS_REPEATED;//将lwe的键盘状态设置为重复 return 1; }
if (!(old_lwe.type == LWETYPE_MOUSE //如果旧底层事件类型为鼠标事件 && (old_lwe.data.me.event == ME_LEFTDOWN || old_lwe.data.me.event == ME_RIGHTDOWN ||
old_lwe.data.me.event == ME_MIDDLEDOWN))) {
//且为鼠标左键或右键或者中间键的击键事件
// reset delay time
timeout_count = __mg_timer_counter + timeout_threshold; }
// reset delay time
lwe->type = LWETYPE_TIMEOUT;设置事件类型为超时事件 lwe->count = __mg_timer_counter;//计时器等与系统计时器事件 return 1; }
return 0; //如果是错误事件返回0 }
//event不等于0,此时表示有事件发生
timeout_count = __mg_timer_counter + timeout_threshold; // There was a event occurred.
if (event & IAL_MOUSEEVENT) { //如果事件类型包含IAL_MOUSEEVENT if (!IAL_UpdateMouse ())//更新鼠标信息 return 0;
lwe->type = LWETYPE_MOUSE;//设置底层事件类型为LWETYPE_MOUSE if (RefreshCursor(&me->x, &me->y, &button)) {//刷新光标信息 me->event = ME_MOVED;//鼠标事件为ME_MOVED time1 = 0; time2 = 0;
if (oldbutton == button) //如果前一个鼠标事件的类型与当前鼠标事件的类型相同 return 1; //返回1,表示获得事件成功 }
//如果前一个鼠标事件不是鼠标左键击键事件并且当前的鼠标事件是左键击键事件 if ( !(oldbutton & IAL_MOUSE_LEFTBUTTON) && (button & IAL_MOUSE_LEFTBUTTON) ) {
if (time1) {//如果time1不为0
interval = __mg_timer_counter - time1;//时间间隔等于当前时钟计数减去time1 if (interval <= dblclicktime)//如果时间间隔小于双击事件时间间隔 me->event = ME_LEFTDBLCLICK;//鼠标事件为左键双击事件 else
me->event = ME_LEFTDOWN;//否则为单击事件 time1 = 0; //time1设为0 } else {
time1 = __mg_timer_counter; //如果time1为0,设置time1为当前时钟计数 me->event = ME_LEFTDOWN; //鼠标事件为单击事件
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库minigui代码分析(7)在线全文阅读。
相关推荐: