• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天行健 君子當自強而不息

            【ZT】DirectInput 鼠標編程入門

            作者:樊一鵬

            前回同大家簡單介紹了如何用 DirectInput 來進行鍵盤編程,本回所要講述的就該是關于如何使用 DirectInput 來對另一個非常重要的輸入設備----鼠標的編程問題。

            鼠標的編程同鍵盤編程的過程是非常相似的,有了上次的基礎,你很快就能看出兩者在形式上其實完全是大同小異的。

            DIRECTINPUT 的初始化

            同前面講鍵盤編程的過程一樣,我們還是先從 DIRECTINPUT 的初始化開始吧:

            #include <dinput.h>

            #define DINPUT_BUFFERSIZE 16

            LPDIRECTINPUT           lpDirectInput;  
            // DirectInput object
            LPDIRECTINPUTDEVICE     lpMouse;        // DirectInput device

            BOOL InitDInput(HWND hWnd)
            {
                HRESULT hr;

                
            // 創建一個 DIRECTINPUT 對象
                hr = DirectInputCreate(hInstanceCopy, DIRECTINPUT_VERSION, &lpDirectInput, NULL);

                
            if FAILED(hr)
                {
                    
            // 失敗
                    return FALSE;
                }

                
            // 創建一個 DIRECTINPUTDEVICE 界面
                hr = lpDirectInput->CreateDevice(GUID_SysMouse, &lpMouse, NULL);
                
            if FAILED(hr)
                {
                    
            // 失敗
                    return FALSE;
                }

                
            // 設定查詢鼠標狀態的返回數據格式
                hr = lpMouse->SetDataFormat(&c_dfDIMouse);
                
            if FAILED(hr)
                {
                    
            // 失敗
                    return FALSE;
                }

                
            // 設定協作模式
                hr = lpMouse->SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND);
                
            if FAILED(hr)
                {
                    
            // 失敗
                    return FALSE;
                }

                
            // 設定緩沖區大小
                
            // 如果不設定,緩沖區大小默認值為 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 
            = lpMouse->SetProperty(DIPROP_BUFFERSIZE, &property.diph);

                
            if FAILED(hr)
                {
                    
            // 失敗
                    return FALSE;
                }

                hr 
            = lpMouse->Acquire();
                
            if FAILED(hr)
                {
                    
            // 失敗
                    return FALSE;
                }

                
            return TRUE;
            }

              除了少數幾處改動以外,這段代碼同前面講的鍵盤編程的代碼基本上完全一樣。

            注意調用 CreateDevice 來建立一個 DIRECTINPUTDEVICE 界面時,我們用的參數是 GUID_SysMouse 而不是 GUID_SysKeyboard,我們以此來指明了建立的是鼠標對象。相應的,在用 SetDataFormat 來設定返回數據的格式時,我們用的參數是 &c_dfDIMouse 而不是 &c_dfDIKeyboard。

            還有要特別注意的是,前面講到的鍵盤,在設置協作方式時,是只能按非獨占方式工作的,而鼠標即可以按非獨占方式工作,也可以按獨占方式工作。

            DIRECTINPUT 的數據查詢

            在作 DIRECTINPUT 的鼠標數據查詢時,我一般都是使用的緩沖模式而不是立即模式。原因很簡單,因為鼠標移動事件的頻率很高,按立即模式去處理就很難保證不丟失數據。至于 DIRECTX SDK 里的例程使用立即模式讀取數據則是因為它們用了一個多媒體計時器來保證以每秒三十次的頻率處理接受鼠標數據。

            明白這一點后,下面我們就來看看相應的代碼。由于 DIRECTX SDK 里的例程有立即模式的代碼,我就偷點懶,下面只給出了一段緩沖模式下的代碼:

            HRESULT UpdateInputState(void)
            {
                DWORD   i;

                
            if(lpMouse != NULL)
                {
                    DIDEVICEOBJECTDATA  didod;  
            // Receives buffered data
                    DWORD               dwElements;
                    HRESULT             hr;

                    
            while(TRUE)
                    {
                        dwElements 
            = 1;                     // 每次從緩沖區中讀一個數據
                        hr = lpMouse->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), &didod, &dwElements, 0);

                        
            if FAILED(hr)
                        {
                            
            // 發生了一個錯誤
                            if(hr == DIERR_INPUTLOST)
                            {
                                hr 
            = lpMouse->Acquire();    // 試圖重新取回設備
                                if FAILED(hr)
                                {
                                    
            return S_FALSE;         // 失敗
                                }
                            }
                        }
                        
            else
                            
            if(elements == 1)
                            {
                                
            switch(didod.dwOfs)
                                {
                                
            case DIMOFS_X:              // X 軸偏移量
                                    
            // didod.dwData 里是具體偏移相對值,單位為像素
                                    break;
                                
            case DIMOFS_Y:              // Y 軸偏移量
                                    
            // didod.dwData 里是具體偏移相對值,單位為像素
                                    break;
                                
            case DIMOFS_BUTTON0:        // 0 號鍵(左鍵)狀態
                                    
            // didod.dwData 里是具體狀態值
                                    
            // 低字節最高位為 1 則表示按下
                                    
            // 低字節最高位為 0 表示未按下
                                    break;
                                
            case DIMOFS_BUTTON1:        // 1 號鍵(右鍵)狀態
                                    
            // 同上
                                    break;
                                
            case DIMOFS_BUTTON2:        // 2 號鍵(中鍵)狀態
                                    
            // 同上
                                    break;
                                
            case DIMOFS_BUTTON3:        // 3 號鍵狀態
                                    
            // 同上
                                    break;
                                }
                            }
                        
            else if (elements == 0break;      // 緩沖區讀空
                    }
                }

                
            return S_OK;
            }

              這段代碼注釋得非常詳細,相信你很快就能看懂。

            DIRECTINPUT 的結束處理

            還記得當程序結束時必須要進行的釋放處理吧,其代碼如下:


            void ReleaseDInput(void)
            {
                
            if (lpDirectInput)
                {
                    
            if(lpMouse)
                    {
                        
            // Always unacquire the device before calling Release().
                        lpMouse->Unacquire();
                        lpMouse
            ->Release();
                        lpMouse 
            = NULL;
                    }
                    lpDirectInput
            ->Release();
                    lpDirectInput 
            = NULL;
                }
            }

             

            posted on 2007-05-06 19:34 lovedday 閱讀(693) 評論(0)  編輯 收藏 引用 所屬分類: ■ DirectX 9 Program

            公告

            導航

            統計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關鏈接

            搜索

            最新評論

            狠狠色丁香久久婷婷综合图片| 人人妻久久人人澡人人爽人人精品| 影音先锋女人AV鲁色资源网久久| 久久久无码精品亚洲日韩蜜臀浪潮| 亚洲AV伊人久久青青草原| 久久久久久久久久久| 久久综合香蕉国产蜜臀AV| 久久成人18免费网站| 狠狠色综合网站久久久久久久高清| 久久久久se色偷偷亚洲精品av| 亚洲女久久久噜噜噜熟女| 天天综合久久久网| 精品久久久久久无码专区 | 日韩欧美亚洲综合久久影院Ds| 久久国语露脸国产精品电影| 久久久久婷婷| 亚洲精品无码久久一线| 久久婷婷午色综合夜啪| 国产无套内射久久久国产| 天天综合久久久网| 精品久久久噜噜噜久久久| 99久久中文字幕| 久久久久久免费一区二区三区| 99久久夜色精品国产网站| 国产精品美女久久福利网站| 色狠狠久久AV五月综合| 一本色道久久综合狠狠躁| 欧美精品乱码99久久蜜桃| 色综合久久久久综合99| 亚洲国产成人精品91久久久 | 亚洲国产精品久久久天堂| 97精品伊人久久大香线蕉| 久久综合噜噜激激的五月天| AV无码久久久久不卡网站下载| 久久久青草青青亚洲国产免观| 久久精品国产精品国产精品污 | 久久精品人人做人人妻人人玩| 久久国产亚洲精品麻豆| 久久精品人妻中文系列| 狠狠精品干练久久久无码中文字幕| 伊人久久大香线蕉AV一区二区|