重新获取设备的问题

nut799 2010-02-27 06:22:57
最近写了个小游戏,发现一个bug,运行时,要是切换到别的程序,再回来 ,就无法重新获取键盘的输入了。
我 在判断键盘按键函数里面有判断的 ,如果获取不到 键盘输入,就重新获取键盘的使用权

if(DIERR_INPUTLOST==m_pKeyboardDevice->GetDeviceState(sizeof(m_KeyBuffer),(LPVOID)m_KeyBuffer)){
m_pKeyboardDevice->Acquire(); //重新获取键盘的使用权

但是,没有起到想要 的作用,跟踪调试发现,当切换到别的程序之后,会立刻进入该if 语句内部,由于此时是在别的界面,所以m_pKeyboardDevice->Acquire();会失败,这没有问题。但是,当重新切换回来,发现程序无法没有执行到if 里面了,
所以不会执行m_pKeyboardDevice->Acquire();语句,这是为什么?

另外 ,我把m_pKeyboardDevice->Acquire();语句放到 if外面,就是下面注释的那个地方,这样程序就能正常了
。切换回来,程序也可以继续接收键盘。

但是我很纳闷,为什么放到if里面就不可以呢?





//判断用户按键函数
bool CGameEngine_Input::ReadKeyboard(){
//m_pKeyboardDevice->Acquire(); //使用该语句就可以重新获取

if(DIERR_INPUTLOST==m_pKeyboardDevice->GetDeviceState(sizeof(m_KeyBuffer),(LPVOID)m_KeyBuffer)){
m_pKeyboardDevice->Acquire(); //重新获取键盘的使用权

if(FAILED(m_pKeyboardDevice->GetDeviceState(sizeof(m_KeyBuffer),(LPVOID)m_KeyBuffer))){
return false;
}
}
return true;
}
...全文
82 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
gamemagic 2010-03-03
  • 打赏
  • 举报
回复
用它的位移你根本算不出屏幕绝对坐标的,说了太灵敏了
jadedrip 2010-03-02
  • 打赏
  • 举报
回复
它给你了位移,你可以直接算坐标,所以就不给了
nut799 2010-03-01
  • 打赏
  • 举报
回复
为什么direct xinput 不可以设计成可以直接获得 鼠标的绝对坐标呢?我不明白
nut799 2010-03-01
  • 打赏
  • 举报
回复
DIERR_NOTACQUIRED
解决了 谢谢 。

if(DIERR_INPUTLOST==m_pKeyboardDevice->GetDeviceState(sizeof(m_KeyBuffer),(LPVOID)m_KeyBuffer)){
m_pKeyboardDevice->Acquire(); //重新获取键盘的使用权

if里面要判断DIERR_NOTACQUIRED
HRASULT hr=m_pKeyboardDevice->GetDeviceState(sizeof(m_KeyBuffer),(LPVOID)m_KeyBuffer);
if(hr==DIERR_INPUTLOST ||hr==DIERR_NOTACQUIRED)
{
m_pKeyboardDevice->Acquire(); //重新获取键盘的使用权
}

由于 切换到别的窗口后,程序失去设备,第一次执行GetDeviceState
会返回DIERR_INPUTLOST 失去设备的错误,以后再执行这儿,会返回DIERR_NOTACQUIRED的错误。
我没有判断DIERR_NOTACQUIRED, 所以 切换出去之后,只会进入if一次。


nut799 2010-03-01
  • 打赏
  • 举报
回复
引用 7 楼 gamemagic 的回复:
因为dinput很灵敏,api 检测不到的鼠标移动,dinput可以检测到。

所以它不能获得绝对坐标


很灵敏就是很准确,为什么所以不能获得绝对坐标?
gamemagic 2010-03-01
  • 打赏
  • 举报
回复
因为dinput很灵敏,api 检测不到的鼠标移动,dinput可以检测到。

所以它不能获得绝对坐标
leechrockgames 2010-02-28
  • 打赏
  • 举报
回复

#include "ENinput.h"
HRESULT ENInput::LHxxGET_INPUTCHAR(UINT msg, WPARAM wparam, LPARAM lparam ,
char *buffer)
{
if((msg == WM_CHAR) && (wparam != VK_RETURN) )//接收输入消息
{
int len;
switch(wparam)
{
case VK_BACK: // backspace, delete 2 char if chn, delete 1 char if eng
len=lstrlen(buffer);
if (len>0)
{
if ( buffer[len-1] < 0 && len > 1 ) // chinese character
{
buffer[len-1]=0;
buffer[len-2]=0;
}
else
buffer[len-1]=0;
}
break;
default: // catch the string
if (lstrlen(buffer)>99)
break;
char Chat[2];
Chat[0]=(char)wparam;
Chat[1]=0;
lstrcat(buffer,Chat);
break;
}
}
return 0;
}


//---------------------------------------------------------------
//name:LHxxGET_INPUTCHAR()
//Desc :读输入信息,和检测鼠标没按
//Parameter:
// msg :回调窗口参数
// wparam :回调窗口参数
// lparam :回调窗口参数
// buf :保存输入信息
// LkeyDown :鼠标左key不按下了会设0
// RkeyDown :鼠标右key不按下了会设0
//---------------------------------------------------------------
HRESULT LHxxGET_INPUTCHAR(UINT msg, WPARAM wparam, LPARAM lparam ,char *buffer);




//-----------------------------------------------------------------------------
// Desc: 窗口过程函数
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )//窗口事件
{
switch( msg )
{
case WM_ACTIVATE:
{

if(ENIGameOb_static!=NULL)
{
if(LOWORD(wParam)==WA_INACTIVE)
{
ENIGameOb_static->ENd3dOb->ENtoolOb->setActivateState(0);//不是当前windows
}
else //是当前windows
{
ENIGameOb_static->ENd3dOb->ENtoolOb->setActivateState(1);//是当前windows
}
}


}break;
case WM_DESTROY:
{
PostQuitMessage( 0 );//发送强行关闭信息
return 0;
}
case WM_PAINT:
{
ValidateRect( hWnd, NULL );//确定客户已更新;P12
return 0;
}

case WM_KEYDOWN:
{
break;
}
case WM_KEYUP:
{

break;
}
default:
{
//cout<<"msg:"<<msg<<endl;
break;
}
}


//按键消息
switch( wParam )
{
// case VK_ESCAPE:
case VK_SPACE:
{
// cout<<"按键消息处理"<<endl;
break;
}
default:
{
break;
}
}

//获取键盘消息
if(ENIGameOb_static!=NULL && ENIGameOb_static->ENd3dOb)
{
if(ENIGameOb_static->ENd3dOb)
{
// cout<<ENIGameOb_static->ENd3dOb<<endl;
char *ss=ENIGameOb_static->ENd3dOb->ENInputOb->GetKeyPressMessage();
if(strlen(ss)>50)
{
ENIGameOb_static->ENd3dOb->ENInputOb->SetKeyPressMessage("");
}
ENIGameOb_static->ENd3dOb->ENInputOb->LHxxGET_INPUTCHAR(msg, wParam, lParam ,ss);
}
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
gamemagic 2010-02-28
  • 打赏
  • 举报
回复
个人认为如果不是动作游戏和FPS游戏,直接用API获得键盘鼠标即可,DINPUT不能获得鼠标的绝对坐标,只能获得位移,极其不爽
gamemagic 2010-02-27
  • 打赏
  • 举报
回复
acquare本来就该放外面的…
DX的最大缺点就是健忘,把最重要的东西给丢了。OGL就不会
张赐 2010-02-27
  • 打赏
  • 举报
回复
关于设备丢失的问题已经讨论过很多了,建议楼主在论坛里自己搜索一下

8,304

社区成员

发帖
与我相关
我的任务
社区描述
游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧