標籤:
directinput
鍵盤入門
遊戲程式設計可不僅僅是圖形程式的開發工作,實際上包含了許多方面,本文所要講述的就是關於如何使用directinput來對鍵盤程式設計的問題。
在 dos 時代,我們一般都習慣於接管鍵盤中斷來加入自己的處理**。但這一套生存方式在萬惡的 windows 社會下是行不通的,我們只能靠領 api 或者 directinput 的救濟金過活。
在 windows 的 api 中,有乙個 getasynckeystate() 的函式可以返回乙個指定鍵的當前狀態是按下還是鬆開。這個函式還能返回該指定鍵在上次呼叫 getasynckeystate() 函式以後,是否被按下過。雖然這個函式聽上去很不錯,但現在領這種救濟金的程式設計師是越來越少了。原因無它,只因為 directinput 的救濟金比這豐厚,而且看上去似乎更專業?
為了早日成為職業的救濟金使用者,我們就從學習 directinput 的鍵盤程式設計開始吧。
directinput 的初始化
前面講 directdraw 時,曾經提到,微軟是按 com 來設計directx的,所以就有了乙個 directinput 物件來表示輸入裝置,而某個具體的裝置由 directinputdevice 物件來表示。
實際的建立過程是先建立乙個 directinput 物件,然後在通過此物件的 createdevice 方法來建立 directinputdevice 物件。
示例如下:
#include
#define dinput_buffersize 16
lpdirectinput lpdirectinput; // directinput object
lpdirectinputdevice lpkeyboard; // directinput device
bool initdinput(hwnd hwnd)
// 建立乙個 directinputdevice 介面
hr = lpdirectinput->createdevice(guid_syskeyboard, &lpkeyboard, null);
if failed(hr)
// 設定為通過乙個 256 位元組的陣列返回查詢狀態值
hr = lpkeyboard->setdataformat(&c_dfdikeyboard);
if failed(hr)
// 設定協作模式
hr = lpkeyboard->setcooperativelevel(hwnd, discl_nonexclusive | discl_foreground);
if failed(hr)
// 設定緩衝區大小
// 如果不設定,緩衝區大小預設值為 0,程式就只能按立即模式工作
// 如果要用緩衝模式工作,必須使緩衝區大小超過 0
dipropdword property;
property.diph.dwsize = sizeof(dipropdword);
property.diph.dwheadersize = sizeof(dipropheader);
property.diph.dwobj = 0;
property.diph.dwhow = diph_device;
property.dwdata = dinput_buffersize;
hr = lpkeyboard->setproperty(diprop_buffersize, &property.diph);
if failed(hr)
hr = lpkeyboard->acquire();
if failed(hr)
return true;}
在這段**中,我們首先定義了 lpdirectinput 和 lpkeyboard 兩個指標,前者用來指向 directinput 物件,後者指向乙個 directinputdevice 介面。
通過 directinputcreate(), 我們為 lpdirectinput 建立了乙個 directinput 物件。然後我們呼叫 createdevice 來建立乙個 directinputdevice 介面。引數 guid_syskeyboard 指明了建立的是鍵盤物件。
接下來 setdataformat 設定資料格式,setcooperativelevel 設定協作模式,setproperty 設定緩衝區模式。因為這些函式方法的引數很多,我就不逐個去詳細解釋其作用了,請直接檢視 directx 的幫助資訊,那裡面寫得非常清楚。
完成這些工作以後,我們便呼叫 directinputdevice 物件的 acquire 方法來啟用對裝置的訪問許可權。在此要特別說明一點,任何乙個 directinput 裝置,如果未經 acquire,是無法進行訪問的。還有,當系統切換到別的程序時,必須用 unacquire 方法來釋放訪問許可權,在系統切換回本程序時再呼叫 acquire 來重新獲得訪問許可權。
所以,我們通常要在 windowproc 中做如下處理:
哦,對了,前一段例程中還提到了立即模式和緩衝模式。在 directinput 中,這兩種工作模式是有區別的。
如果使用立即模式的話,在查詢資料時,只能返回查詢時的裝置狀態。而緩衝模式則將記錄所有裝置狀態變化過程。就個人喜好而言,筆者偏好後者,因為這樣一般不會丟失任何按鍵資訊。對應的,如果在使用前者時的查詢頻度太低,則很難保證採集資料的完整性。
directinput 的資料查詢
立即模式的資料查詢比較簡單,請看下面的示例:
byte diks[256]; // directinput keyboard state buffer 鍵盤狀態資料緩衝區
hresult updateinputstate(void)
}if(failed(hr))
return hr;
}return s_ok;}
在上面的示例中,關鍵處就是使用 getdevicestate 方法來讀取輸入裝置狀態值以及對異常情況的處理。通過使用 getdevicestate 方法,我們把輸入裝置的狀態值放在了乙個 256 位元組的陣列裡。如果該陣列中某個陣列元素的最高位為 1,則表示相應編碼的那個鍵此時正被按下。例如,如果 diks[1]&0x80>0,那麼就表示 esc 鍵正被按下。
學會了立即模式的資料查詢以後,下面我們開始研究緩衝模式的情況:
hresult updateinputstate(void)
}if(failed(hr))
return hr;
}// getdevicedata() 同 getdevicestate() 不一樣,呼叫它之後,
// dwelements 將指明此次呼叫共讀取到了幾條緩衝區記錄
// 我們再用乙個迴圈來處理每條記錄
for(int i=0; i
其實,每條記錄還有 dwtimestamp 和 dwsequence 兩個欄位來記錄訊息發生的時間和序列編號,以便作更複雜的處理。本文是針對初學者寫的,就不打算去談論這些內容了。
directinput 的結束處理
我們在使用 directinput 時,還要注意的一件事就是當程式結束時,必須要進行釋放處理,其演示**如下:
void releasedinput(void)
lpdirectinput->release();
lpdirectinput = null;}}
這段**很簡單,就是對 directinput 的各個物件去呼叫 release 方法來釋放資源。這種過程同使用 directx 的其它部分時是基本上相同的。
DirectInput 鍵盤程式設計入門
哦,對了,前一段例程中還提到了立即模式和緩衝模式。在 directinput 中,這兩種工作模式是有區別的。如果使用立即模式的話,在查詢資料時,只能返回查詢時的裝置狀態。而緩衝模式則將記錄所有裝置狀態變化過程。就個人喜好而言,筆者偏好後者,因為這樣一般不會丟失任何按鍵資訊。對應的,如果在使用前者時的...
direct input 標準呼叫
讀書筆記 direct input 部分 1.取得idirectinput介面,directinput8create 2.獲得介面後建立裝置 滑鼠,鍵盤.3.設定裝置協作等級,setcooperativelevel 4.設定資料格式,setdataformat 5.獲取裝置,acquire 6.使用...
鍵盤顯示程式設計
include include include include include void defor void defor char dujian int i,k i 1 porta 0x0f if pind 0x0f break if pind 0x0d break if pind 0x0b br...