亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 1225 | 回復(fù): 0
打印 上一主題 下一主題

鼠標(biāo)移動事件 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2009-07-14 16:58 |只看該作者 |倒序瀏覽
    當(dāng)鼠標(biāo)在屏幕上移動時,可以使用鼠標(biāo)移動事件跟蹤它的移動。移動事件是當(dāng)鼠標(biāo)指針在窗口內(nèi)移動時發(fā)生的,穿越事件是在鼠標(biāo)指針進(jìn)入或離開GdkWindow窗口時發(fā)生的。移動事件中的典型成員是GDK_MOTION_NOTIFY。有兩種類型的穿越事件:
  GDK_ENTER_NOTIFY和GDK_LEAVE_NOTIFY。
  有兩種方法跟蹤鼠標(biāo)移動事件。如果在窗口的事件屏蔽中指定了GDK_POINTER_MOTION_MASK,可以接收到X服務(wù)器能產(chǎn)生的盡可能多的事件。如果用戶快速移動指針,程序會被移動事件淹沒,必須快速處理它們,否則應(yīng)用程序在處理大量事件時會反應(yīng)遲鈍。
  如果還指定了GDK_POINTER_MOTION_HINT_MASK,那么每次只發(fā)送一個移動事件。也要調(diào)用gdk_window_get_pointer()函數(shù)、鼠標(biāo)指針離開并重新進(jìn)入窗口,或者鼠標(biāo)按鍵或鍵盤事件發(fā)生時,事件才會發(fā)送出去。也就是,每次接收到一個移動事件必須調(diào)用gdk_window_get_pointer()函數(shù)取得鼠標(biāo)指針的當(dāng)前位置,并通知X服務(wù)器已經(jīng)可以接收另一個事件了。
  選擇何種模式依賴于應(yīng)用程序。如果需要精確跟蹤指針的軌跡,就得捕獲所有的移動事件。如果僅僅關(guān)心最近的鼠標(biāo)指針位置,為了將網(wǎng)絡(luò)流量最小化,使應(yīng)用程序的響應(yīng)能力最大化,則應(yīng)在應(yīng)用程序的事件屏蔽中包含GDK_POINTER_MOTION_HINT_MASK。
  gdk_window_get_pointer()函數(shù)要求在服務(wù)器和客戶之間傳輸數(shù)據(jù)以獲得鼠標(biāo)指針的位置,所以它對應(yīng)用程序的響應(yīng)能力有很大的限制。如果能盡可能快地處理鼠標(biāo)運動事件而不被大量的事件淹沒,應(yīng)用程序看起來會比沒有設(shè)置事件屏蔽GDK_POINTER_MOTION_HINT_MASK要快些。鼠標(biāo)移動事件不可能在一秒鐘內(nèi)發(fā)生200次,所以如果能在5毫秒內(nèi)處理好鼠標(biāo)移動事件,情況就會不錯。
  如果想在一個或多個鼠標(biāo)按鍵按下時才接收鼠標(biāo)事件,可以用GDK_BUTTON_MOTION_MASK代替GDK_POINTER_MOTION_MASK。還可以用GDK_POINTER_MOTION_HINT_MASK和GDK_BUTTON_MOTION_MASK一起使用來限制要接收的事件的數(shù)量,就像和GDK_POINTER_MOTION_MASK一起使用一樣。如果僅僅對某個特定的鼠標(biāo)按鍵按下時的鼠標(biāo)移動事件感興趣,可以使用與特定鼠標(biāo)鍵相關(guān)的事件屏蔽GDK_BUTTON1_MOTION_MASK、GDK_BUTTON2_MOTION_MASK以及GDK_BUTTON3_MOTION_MASK。這三個事件屏蔽的任何組合都是允許的。它們也可以與GDK_POINTER_MOTION_HINT_MASK聯(lián)合使用以限制事件發(fā)生的數(shù)量。
  總而言之,可以用下面五個事件屏蔽值選擇在什么按鍵狀態(tài)下接收什么鼠標(biāo)移動事件:
  GDK_POINTER_MOTION_MASK:不管按鍵狀態(tài),接收所有事件。
  GDK_BUTTON_MOTION_MASK:有按鍵按下時接收所有事件。
   GDK_BUTTON1_MOTION_MASK:按鍵1按下時接收所有事件。
  GDK_BUTTON2_MOTION_MASK:按鍵2按下時接收所有事件。
  GDK_BUTTON3_MOTION_MASK:按鍵3按下時接收所有事件。
  缺省狀態(tài)下,應(yīng)用程序會被X服務(wù)器能生成的事件所淹沒,最好在事件屏蔽中添加一個GDK_POINTER_MOTION_HINT_MASK,讓事件“一段時間內(nèi)發(fā)生一次”。
  移動事件用GdkEventMotion結(jié)構(gòu)描述:
  typedefstruct_GdkEventMotionGdkEventMotion;
  struct_GdkEventMotion
  {
   GdkEventTypetype;
   GdkWindow*window;
   gint8send_event;
   guint32time;
   gdoublex;
   gdoubley;
   gdoublepressure;
   gdoublextilt;
   gdoubleytilt;
   guintstate;
   gint16is_hint;
   GdkInputSourcesource;
   guint32deviceid;
   gdoublex_root,y_root;
  };
  大多數(shù)成員與GdkEventButton中的成員是類似的。事實上,唯一與GdkEventMotion不同的成員是is_hint標(biāo)志。如果它是TRUE,GDK_POINTER_MOTION_HINT_MASK標(biāo)志會選中。
  如果要寫一個供其他人使用的構(gòu)件,并且想讓他們選擇怎樣接收移動事件,需要設(shè)置這個成員的值。在移動事件處理程序中,可以這么做:
  doublex,y;
  x=event->motion.x;
  y=event->motion.y;
  if(event->motion.is_hint)
  gdk_window_get_pointer(event->window,&x,&y,NULL);
  也就是說,只在必要時調(diào)用gdk_window_get_pointer()函數(shù)。
  如果正在使用GDK_POINTER_MOTION_HINT_MASK,給定事件的坐標(biāo)應(yīng)該使用從gdk_window_get_pointer()函數(shù)取得的值,因為它們是更新過的。如果正在接收每個事件,調(diào)用gdk_window_get_pointer()就沒有什么意義,因為這樣做太慢了,并且會引起嚴(yán)重事件積壓—這樣,最終會得到所有的事件,但是應(yīng)用程序的性能會很糟糕。
  穿越事件是在鼠標(biāo)指針進(jìn)入或離開一個窗口時發(fā)生的。如果在應(yīng)用程序的GdkWindow之間快速移動,Gdk會為每一個被穿越的窗口產(chǎn)生穿越事件。不過,Gtk+會試圖刪除在多個“穿越”過程中的事件,只將第一個離開窗口事件和最后一個進(jìn)入窗口事件傳給構(gòu)件。這種優(yōu)化能夠提高程序的響應(yīng)速度。如果感覺到應(yīng)該發(fā)生了進(jìn)入/離開事件,可實際上并沒有發(fā)生,可能是上面的優(yōu)化造成的。
  GdkEventCrossing結(jié)構(gòu)的定義如下:
  typedefstruct_GdkEventCrossingGdkEventCrossing;
  struct_GdkEventCrossing
  {
   GdkEventTypetype;
   GdkWindow*window;
   gint8send_event;
   GdkWindow*subwindow;
   guint32time;
   gdoublex;
   gdoubley;
   gdoublex_root;
   gdoubley_root;
   GdkCrossingModemode;
   GdkNotifyTypedetail;
   gbooleanfocus;
   guintstate;
  };
  上面所示結(jié)構(gòu)中的很多成員都應(yīng)該是很熟悉的,其中x和y坐標(biāo)是相對于發(fā)生穿越事件的窗口的坐標(biāo);x_root和y_root坐標(biāo)是相對于根窗口的;time成員指明事件的時間;state成員指明發(fā)生事件時按下的鼠標(biāo)按鍵和組合鍵。結(jié)構(gòu)中的前三個成員是GdkEventAny中的三個標(biāo)準(zhǔn)成員。不過,這里還有幾個新成員。
  GdkEventCrossing結(jié)構(gòu)中的window成員是一個指向鼠標(biāo)指針要進(jìn)入或離開的窗口指針,x和y坐標(biāo)就是相對于這個窗口的。但是,在“離開”事件發(fā)生之前,鼠標(biāo)指針也許已經(jīng)在接收事件的窗口的子窗口中存在了;當(dāng)“進(jìn)入”事件發(fā)生時,鼠標(biāo)指針也許在一個子窗口中消失了。在這些情況下,subwindow成員應(yīng)該設(shè)置為這個子窗口。否則,可以將subwindow設(shè)置為NULL。注意,如果在子窗口的事件屏蔽值中設(shè)置有GDK_ENTER_NOTIFY_MASK或GDK_LEAVE_NOTIFY_MASK,子窗口也會接收到它自己的“進(jìn)入”或者“離開”事件。
GdkEventCrossing中的mode成員指出事件是正常引發(fā)的還是作為指針獨占的一部分。
  當(dāng)指針被獨占或解除獨占時,指針也許會移動。由一個獨占引起的鼠標(biāo)移動事件的mode成員的值為GDK_CROSSING_GRAB,由解除獨占引起的的移動事件的mode成員為GDK_CROSSING_UNGRAB,所有其他情況mode都為GDK_CROSSING_NORMAL。
  GdkEventCrossing中的detail成員很少用到。它給出了關(guān)于要離開和進(jìn)入的窗口在X系統(tǒng)窗口樹中的相對位置的一些信息。它有兩個很簡單、很有用的值:
  GDK_NOTIFY_INFERIOR標(biāo)志一個當(dāng)指針移進(jìn)或移出一個子窗口時,由父窗口接收到的穿越事件。
  GDK_NOTIFY_ANCESTOR標(biāo)志一個當(dāng)指針移進(jìn)或者移出一個父窗口時,由子窗口接收到的穿越事件。其他幾種值也是可能的:GDK_NOTIFY_VIRTUAL,GDK_NOTIFY_INFERIOR,GDK_NOTIFY_NONLINEAR,GDK_NOTIFY_NONLINEAR_VIRTUAL以及GDK_NOTIFY_UNKNOWN。不過,它們絕不會用到,因為它們太復(fù)雜了。
  鍵盤焦點
  GdkEventCrossing的focus成員指出是事件窗口還是它的子窗口得到鍵盤輸入焦點。鍵盤焦點是一個X概念,用于決定哪一個窗口應(yīng)該接收按鍵事件。窗口管理器決定哪一個頂級窗口應(yīng)該獲得焦點。通常,獲得焦點的窗口是高亮顯示的,并在最前面顯示。大多數(shù)窗口管理器會讓你在“跟隨鼠標(biāo)獲得焦點”和“點擊獲得焦點”間作出選擇。當(dāng)應(yīng)用程序具有焦點時,可以將焦點在它的子窗口間自由移動(例如,在不同的GtkText構(gòu)件間移動)。不過,Gtk+并不對子窗口使用X的焦點機制。
  頂級GtkWindow構(gòu)件是唯一接收X焦點的窗口。因而,它們從X服務(wù)器(通過Gdk)接收所有的原始按鍵事件。Gtk+實現(xiàn)了它自己的構(gòu)件焦點概念,它和X的窗口焦點概念是類似的,但實際上是截然不同的。當(dāng)一個頂級窗口接收到按鍵事件,它會將事件傳給具有Gtk+焦點的構(gòu)件。
  簡而言之,如果包含事件窗口的頂級GtkWindow窗口目前具有X焦點,focus成員的值就會是TRUE。Focus成員與Gtk+的構(gòu)件焦點概念沒有直接的關(guān)系。

本文來自ChinaUnix博客,如果查看原文請點:http://blog.chinaunix.net/u3/93660/showart_1996129.html
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP