今天又查了许多关于DirectInput的文档,甚至看了DirectX 9.0 SDK中的DirectInput Sample。他们的初始化方式都基本上一样,都从 directinput 的初始化一直到 directinputdevice 的 acquire。但是,M$的acquire是不对返回进行判断的,所以它不管acquire是否成功都会返回,退出初始化函数。而其他很多网上的事例初始化都大同小异,我写上去的也差不多。最后我看看圣剑2会不会出现相同的问题。果然,我用圣剑2窗口模式启动之后立刻将焦点移动去其他窗口,圣剑2就弹出了鼠标获取失败的对话框。哈哈~~
又对比了一下他们GetDeviceState的代码,基本上都差不多只是处理了 DIERR_LOSTINPUT 这个错误。后来我想,既然初始化不成功,并不重要,只要窗口在激活当中更新设备状态,那窗口一定会有焦点,再在GetDeviceState那个过程加上一个 DIERR_NOTACQUIRE 的错误判断,那就把这个问题完美搞掂了。初始化那里就可以不写device的acquire了。直接在刷新状态过程:
HRESULT
hr = lpDIDMouse->GetDeviceState(...);
if ( hr == DIERR_LOSTINPUT | DIERR_NOTACQUIRE )
{
hr = lpDIDMouse->Acquire();
if ( FAILED( hr ) )
return hr;
}
return S_OK;
hoho.
下面可以接着写窗口管理的类了.
再看了一下TSOnline,发现了它是用那种鼠标单独线程局部刷新的方法的。所以当它拖拽窗口移动的时候会出现一块小小的花屏,那个Bug它没有处理好。一篇文章提到这个问题,它的解决办法是当屏幕背景更新了以后改变一个flag,通知鼠标线程重新复制新的局部背景数据。其实这么麻烦,是不是比全屏刷新更好呢?虽然鼠标有可能会一跳一跳的,但是我个人还是喜欢全屏刷。
第二,TSOnline当鼠标移动到标题栏会出现系统指针,Sword2是没有的。当然我做的也没有。也许因为标题栏也算是窗口范围内。不知如何只是限定于重绘的区域之内。
第三,TSOnline当鼠标移动到窗口底部,指针是可以跑出窗体之外,而并不是仅仅限于重画区的。
这几点我得出1种结论:它用的是系统 .ani 标准鼠标文件。嗯……其实它的目录下的确有这么一个文件,也有bmp的。不过我觉得它更像用ani的方式。
DirectInput问题的完满解决
最新推荐文章于 2024-06-08 09:37:04 发布