Yi's Blog

手机重力感应控制电脑(一)

2013-06-02

这几天没什么事,看着自己的手机nokia5530,想到这手机虽然过时了,但是能不能做点什么有意思的事呢?我喜欢在电脑上玩极品飞车,如果能用手机的重力感应器操控电脑玩极品飞车那多好啊!正好学过一点Qt,可以开发symbian应用,为什么不试试?咱们工科男,说干就干,马上就开始!

环境搭建

首先,搭建symbian应用开发环境。这里我使用的是Qt_SDK_Win_v1_1_2_en(1.78G),在nokia developer网站下载,需要注册一个账号。用它开发的程序,手机需要Qt 4.07(3)库的支持。另外Qt SDK还有1.2.1版的,如果用它开发,则手机需要Qt 4.07(4)库的支持。更多的详细内容可以参考CSDN一位前辈的博客:http://blog.csdn.net/htttw/article/details/7630831。安装过程很简单,我个人遇到的一个问题是:在虚拟机winXP sp3中安装之后会发现项目设置里没有模拟器选项,并且一些头文件会找不到。具体原因没有找到,我在主机win7 64bit下重新安装一切正常。

开发环境搭建起来以后,就可以写个hello world测试一下了。新建一个 Qt Gui应用 项目就可以,项目设置勾选塞班设备和模拟器就行。

HelloWorld

开发环境搭建起来以后,就可以写个hello world测试一下了。新建一个 Qt Gui应用 项目就可以,项目设置勾选塞班设备和模拟器就行。
项目设置

项目建成以后,和开发普通的windows桌面程序一样,ui文件注意调整一下大小。
点击左边的绿色箭头就可以调试运行了。
调试1

这里有两个选项,选择模拟器则直接在模拟器中运行程序。选择塞班设备,会提示1个错误,没有设备连接。(也许还会有很多警告,没有关系。)
调试2

不用担心,在项目文件夹中已经生成了.sis 文件,手动拷贝到手机上安装就可以了。
因为我只是想做一次塞班应用试一试,所以没有安装Nokia Ovi Suite.想要更方便的调试可以安装连接套件和调试工具。
具体方法还是看前辈的介绍吧:http://blog.csdn.net/htttw/article/details/7632122。

开发

要想用手机的重力感应器操控电脑,我的想法是写一个手机端程序不断获取传感器数据,通过wifi传输到电脑,电脑端的程序接收消息并作出响应。

那么就从手机端程序开始做起吧!

  1. 获取传感器数据
    我之前并没有开发symbian应用的经验,手上也没有参考资料,对于如何获取传感器的数据一点头绪也没有,那就上网搜搜看吧!
    在这里不得不再次感谢网上那些前辈们,这里介绍的十分详细:http://blog.csdn.net/htttw/article/details/7637674。
  2. 传输:我的手机是nokia5530,支持wifi。所以我使用wifi与电脑通信。因为我们要对电脑进行实时操控,并且使用wifi网络,所以这里我使用QUdpSocket来进行信息的传输,把重力感应器xyz三个方向上的数据以字符串的形式发送。这个相信有基础的都会,很多书中都有详细讲解,网上也有很多例子,不再具体介绍。
  3. 电脑端的开发:
    在这里我花了很多时间。我以为接收到手机端程序发送到的消息,根据重力感应器三个方向上的数值发送键盘消息响应即可。可是问题就出在这键盘消息上了。

最初我使用keybd_event();来模拟键盘消息。

函数原型:

1
VOID keybd_event(BYTE bVk,BYTE bScan,DWORD dwFlags,DWORD dwExtralnfo);

参数:
- bVk:定义一个虚拟键码。键码值必须在1~254之间。
- bScan:定义该键的硬件扫描码。
- dwFlags:定义函数操作的各个方面的一个标志位集。应用程序可使用如下一些预定义常数的组合设置标志位。
- KEYEVENTF_EXTENDEDKEY:若指定该值,则扫描码前一个值为OXEO(224)的前缀字节。
- KEYEVENTF_KEYUP:若指定该值,该键将被释放;若未指定该值,该键将被按下。
- dwExtralnfo:定义与击键相关的附加的32位值。
返回值:该函数无返回值。

这样做十分简单,很快程序就写好了。我模拟了键盘的方向键,通过手机的重力感应器控制,测试一下,正常工作!可以控制光标的移动,网页的上下滚动,焦点的选择。我天真的以为这样就没问题了,兴奋的打开极品飞车想要试试手感。游戏一打开,就被泼了盆冷水,刚才的兴奋全没了。在极品飞车中完全没有反应啊!好吧,没关系,有问题我们就去解决!

网上搜一下,看看问题出在哪里,原因是什么?原来很多游戏都用了DirectInpput技术,直接读硬件端口的。所以像我这样发键盘消息也自然没用了。原因找到了,那就去想办法解决它!我们需要做到驱动级的键盘模拟!像我这种小菜鸟怎么可能做得出来那样的东西嘛。幸运的是有一位国外大牛帮我们做好了!那就是很有名的WinIo.dll !