当前位置: 首页 > news >正文

马宁的Windows Phone 7开发教程(3)——XNA下使用MessageBox和软键盘

作者:马宁

相信未来一段的业余时间,我都要和XNA为伍了。本来想向3D开发的纵深发展,但是遇到了一个实际的问题,就是如何在XNA下显示MessageBox和Software Input Panel。干脆先写出来吧,省得大家遇到这问题时抓狂。

按照为数不多的公开文档描述,XNA和Silverlight for Windows Phone应该是基于同一个.NET Compact Framework的CLR。但是,XNA并没有提供任何用户控件、MessageBox和软键盘等,也不能直接调用Silverlight for Windows Phone的类库。这样势必为XNA制造了很多人为的障碍。但调用MessageBox和Software Input Panel的后门,XNA还是给我们留下了,这就是Microsoft.Xna.Framework.GamerServices命名空间下的Guide类,类描述如下:

http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.gamerservices.guide.aspx

该类不但可以调用MessageBox和软键盘,还能够调用Marketplace、XBox Live等窗体。不过,值得注意的是,Guide类提供的方法都是异步调用,而非同步调用,这也好理解,游戏的处理过程是以时间驱动的,所以任何操作不应该阻塞住游戏主线程。

Guide类调用MessageBox和软键盘的描述在这里:

http://msdn.microsoft.com/en-us/library/ff827869.aspx

http://msdn.microsoft.com/en-us/library/ff827868.aspx

但MSDN文档还是有一些瑕疵,按上面提供的方法会产生Exception,所以我在下面给出修改后可以运行的方法。运行环境基于VS 2010 + Windows Phone 7 SDK RTW版。

调用MessageBox

创建Windows Phone 7中XNA 4.0的工程,然后,我们在Update方法里添加对于MessageBox的调用。当然,大家请不要认为把MessageBox加到Update里正确的,这样会造成MessageBox不断弹出。我只是为了简化代码,才这么做的。

        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // TODO: Add your update logic here
            Liststring> MBOPTIONS = new Liststring>(); 
            MBOPTIONS.Add("OK");
            MBOPTIONS.Add("CANCEL");
            if (!Guide.IsVisible)
                Guide.BeginShowMessageBox("test", "hello, XNA", MBOPTIONS, 0, MessageBoxIcon.Alert, new AsyncCallback(RespCallback), null);

            base.Update(gameTime);
        }
<style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style>

由于Microsoft.Xna.Framework.GamerServices是默认添加的组件,所以,我们可以直接使用Guide类。首先创建一个string类型的List,用于保存MessageBox中按钮的Text;然后通过List<string>的Add方法将需要显示的Button Text添加进去。 <p>接下来是Guide.IsVisible方法,由于MessageBox、SIP软键盘等公用一个绘制表面,必须保证没有其他UI显示时,才能够显示指定组件,如果不添加这句Guide.IsVisible的判断,将触发下面的异常。 </p> <p><a href="http://hi.csdn.net/attachment/201009/20/0_12849729609lUy.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image001" border="0" alt="clip_image001" src="http://hi.csdn.net/attachment/201009/20/0_1284972967oOeZ.gif" width="645" height="290"></a> </p> <p>接下来就是调用的主体Guide.BeginShowMessageBox了,这是一个异步方法,调用后立刻返回。参数比较好理解,下面是函数的声明:</p> <pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">static</span> IAsyncResult BeginShowMessageBox ( <span class="kwrd">string</span> title, <span class="kwrd">string</span> text, IEnumerablestring&gt; buttons, <span class="kwrd">int</span> focusButton, MessageBoxIcon icon, AsyncCallback callback, Object state ) </pre> <style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> <p>第一个参数是标题,第二个参数是对话框内容,第三个是button上文字的列表,也表示有几个Button出现,第四个是焦点在第几个Button上,第五个是图标,我们设置为null,第六个是结束时调用的Callback函数对象,最后一个是用户自定义状态对象,可以传递自定义信息。其他参数都容易理解,AsyncCallback对象需要一个Callback函数RespCallback,我们实现如下:</p> <pre class="csharpcode"> <span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">void</span> RespCallback(IAsyncResult asynchronousResult) { <span class="kwrd">int</span>? b = Guide.EndShowMessageBox(asynchronousResult); <span class="kwrd">if</span> (b &gt; 0) Debug.WriteLine(<span class="str">"Cancel"</span>); <span class="kwrd">else</span> Debug.WriteLine(<span class="str">"OK"</span>); } </pre> <style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> <p>Callback函数中最重要的工作是调用Guide.EndShowMessageBox函数,来关闭MessageBox。EndShowMessageBox需要传入一个IAsyncResult对象,来自Callback函数的参数。返回值是一个可为空的int,如果为空则表示没有返回值,如果不为空,返回值是Button的Index值,返回0表示点击了第一个按钮OK,返回1则表示点击了第二个按钮Cancel,以此类推。 </p> <p>显示MessageBox的效果如下: </p> <p><a href="http://hi.csdn.net/attachment/201009/20/0_128497296802B8.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image003" border="0" alt="clip_image003" src="http://hi.csdn.net/attachment/201009/20/0_1284972969l1Y0.gif" width="559" height="300"></a> </p> <h3>调用Software Input Panel</h3> <p>接下来是调用SIP软键盘的代码,仍旧放到Update方法里,Callback函数也一并给出。</p> <pre class="csharpcode"> <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> Update(GameTime gameTime) { <span class="rem">// Allows the game to exit</span> <span class="kwrd">if</span> (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) <span class="kwrd">this</span>.Exit(); <span class="kwrd">if</span> (!Guide.IsVisible) Guide.BeginShowKeyboardInput(PlayerIndex.One, <span class="str">"Here's your Keyboard"</span>, <span class="str">"Type something..."</span>, <span class="str">"abc"</span>, <span class="kwrd">new</span> AsyncCallback(GetTypedChars), <span class="kwrd">null</span>); <span class="kwrd">base</span>.Update(gameTime); } <span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">void</span> GetTypedChars(IAsyncResult asynchronousResult) { <span class="kwrd">string</span> output = Guide.EndShowKeyboardInput(asynchronousResult); Debug.WriteLine(output); } </pre> <style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> <p>前边都解释过了,直接来看Guide.BeginShowKeyboardInput,第一个参数要传PlayerIndex进去,这个是针对Xbox的,在Windows和Windows Phone 7上只支持一个用户,所以直接传PlayerIndex.One就好了。接下来的三个参数是标题、描述和默认字符,然后是异步调用方法和自定义状态。还有最后一个可选参数,表示是否用Password方式显示字符。</p> <pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">static</span> IAsyncResult BeginShowKeyboardInput ( PlayerIndex player, <span class="kwrd">string</span> title, <span class="kwrd">string</span> description, <span class="kwrd">string</span> defaultText, AsyncCallback callback, Object state, <span class="kwrd">bool</span> usePasswordMode ) </pre> <style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> <p>在异步调用方法中,Guide.EndShowKeyboardInput会返回一个字符串,该字符串为用户输入的字符串。为什么显示的是字符串呢,这和SIP的显示方式有关。在调用SIP函数后,会首先弹出第一个对话框,询问用户是否输入字符,如果用户点Cancel则关闭SIP,如果点OK则进入第二个界面,用户才能够使用SIP软键盘进行输入。 </p> <p>下面就是SIP显示的状态: </p> <p><a href="http://hi.csdn.net/attachment/201009/20/0_1284972969R88R.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image005" border="0" alt="clip_image005" src="http://hi.csdn.net/attachment/201009/20/0_1284972970Nok4.gif" width="602" height="325"></a> </p> <p><a href="http://hi.csdn.net/attachment/201009/20/0_1284972971prY3.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image007" border="0" alt="clip_image007" src="http://hi.csdn.net/attachment/201009/20/0_1284972972AHAV.gif" width="603" height="323"></a> </p> <h3>写到最后</h3> <p>今天的主角Guide类,还有很多有趣的函数调用,有兴趣的朋友按照这个方法调用就可以了。这次的代码量不多,所以就不给出单独Sample Code的下载了。再有就是,虚心接受批评,将文章里代码的格式弄好了。 </p> <p>我最近还是很勤快的,Windows Phone 7的开发都写了三篇了,这是之前文章的链接: </p> <p>马宁的Windows Phone 7开发教程(1)——<a href="http://www.cnblogs.com/aawolf/archive/2010/08/28/1811438.html">Windows Phone开发工具初体验</a> </p> <p>马宁的Windows Phone 7开发教程(2)——<a href="http://www.cnblogs.com/aawolf/archive/2010/08/29/1811686.html">Windows Phone XNA 4.0 3D游戏开发</a></p> <pre class="csharpcode"></pre> <style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style></string>

相关文章:

  • STP详解
  • 又见西安
  • 一次失败的网购:在兰蔻官网订购的货不对版
  • 多线程试题汇总
  • CentOS上配置LVS DR集群
  • Android应用加入微信分享
  • nowrap要与回车换行符结合才有意义
  • XMPP 基础
  • 初学3ds Max,做了个雪人,大家来评评哪个更好看
  • 精彩十年(3)——初露锋芒
  • Java常用工具类的使用
  • 精彩十年(4)——缔造神话
  • HibernateDaoSupport实现分页技术总结
  • 新作《.NET 4.0面向对象编程漫谈》之序“穿越梦想、起锚远航”
  • java synchronized详解(非常详细)
  • avalon2.2的VM生成过程
  • Java 内存分配及垃圾回收机制初探
  • JavaScript/HTML5图表开发工具JavaScript Charts v3.19.6发布【附下载】
  • Mac转Windows的拯救指南
  • MYSQL 的 IF 函数
  • node和express搭建代理服务器(源码)
  • python学习笔记-类对象的信息
  • Vue学习第二天
  • 程序员最讨厌的9句话,你可有补充?
  • 浮现式设计
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 简单基于spring的redis配置(单机和集群模式)
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 每天一个设计模式之命令模式
  • 实现菜单下拉伸展折叠效果demo
  • 移动端解决方案学习记录
  • 应用生命周期终极 DevOps 工具包
  • 云大使推广中的常见热门问题
  • nb
  • scrapy中间件源码分析及常用中间件大全
  • ​无人机石油管道巡检方案新亮点:灵活准确又高效
  • # Apache SeaTunnel 究竟是什么?
  • # include “ “ 和 # include < >两者的区别
  • #pragma multi_compile #pragma shader_feature
  • (delphi11最新学习资料) Object Pascal 学习笔记---第7章第3节(封装和窗体)
  • (附源码)springboot家庭装修管理系统 毕业设计 613205
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (附源码)ssm高校志愿者服务系统 毕业设计 011648
  • (附源码)ssm航空客运订票系统 毕业设计 141612
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (三)Honghu Cloud云架构一定时调度平台
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (心得)获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。
  • (新)网络工程师考点串讲与真题详解
  • (一)Java算法:二分查找
  • (原+转)Ubuntu16.04软件中心闪退及wifi消失
  • .babyk勒索病毒解析:恶意更新如何威胁您的数据安全
  • .bat批处理(十):从路径字符串中截取盘符、文件名、后缀名等信息
  • .net core IResultFilter 的 OnResultExecuted和OnResultExecuting的区别
  • .NET Core 实现 Redis 批量查询指定格式的Key