Windows 填坑日记之Windows 8 虚拟键盘问题

WPF使用XAML来搭建一个登录窗口 WPF使用XAML来搭建一个登录窗口 在Wpf项目中的学习中,在WPF中,我了解到常用的窗口页面布局元素有五个,分别为Grid网格,DockPanel泊靠式面板,StackPanel栈式面板,WrapPanel自动折行面板,Canvas画布。 使用grid网格布局,通常采用grid网格面板来进行布局,grid网格面板,就好比如一张格子网,将一个页面分隔成我们想要的行列,在其中放入具体的内容,控件,或其他布局元素进行组合呈现预想中的样子。 泊靠式面板:内部元素可以选择泊靠的方向(上下左右)。 栈式面板 阅读详情

首先我要说一下,只有在Windows8.0/8.1/RT系统中才会遇到这种问题。也就是传说中的Windows平板电脑。

首先描述一下问题。使用Unity开发游戏的同志们都知道,Unity提供了TouchScreenKeyboard类来实现虚拟键盘的弹出和使用。但是当你导出应用程序装在平板电脑上的时候,你会悲剧的发现,它不好使!一开始我还以为是一个小BUG,但是当我深入研究的时候,发现这特么的是个大坑!Unity给出的答复是:微软没有提供接口。而微软提供的答复是:API就是这么设计的,平板电脑屏幕右下角有一个小图标,点击它才可以出键盘。否则就必须只能用Windows自带的XAML控件去唤醒虚拟键盘。但是游戏是全屏幕的好伐?!然后,微软的技术支持给我提供了一个非常非常复杂的解决方案。我没有试验,因为我后来采用其他方式解决了这个问题,那就是我给你贴个Windows自带的输入框上去!

前面说过,如果要解决这个问题,需要导出成XAML C# Solution。在这个情况下,Unity会为我们构建一个基于XAML的工程。这个工程基本上是下面这个样子:

(代码在公司的机器上,我不能随便用,以下给大家看的是网上下载的AppSample,另外我家里也没有Windows8的机器,不过基本上是一回事。)

(另外我也没装2013,只是给大家提供个思路)



下面是实际步骤

1. 首先你需要去了解一些关于XAML的知识:http://zh.wikipedia.org/zh-cn/XAML

2. 在MainPage.xaml中创建一个输入框控件,如果需要,让你的美术给你提供一张png格式的图片作为输入框的背板。代码如下

<Page
    x:Class="Template.MainPage"
    IsTabStop="false"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Template"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <SwapChainBackgroundPanel x:Name="DXSwapChainBackgroundPanel">
        <SwapChainBackgroundPanel.Resources>
            <ImageBrush x:Key="img_small" ImageSource="Assets/xaml_input_small.png"></ImageBrush>
            <ImageBrush x:Key="img_big" ImageSource="Assets/xaml_input_big.png"></ImageBrush>
        </SwapChainBackgroundPanel.Resources>
        <Grid x:Name="ExtendedSplashGrid">
            <Image x:Name="ExtendedSplashImage" Source="Assets/SplashScreen.png"/>
        </Grid>
        <TextBox BorderThickness="0" Background="{StaticResource img_small}" x:Name="textBase_Small" Height="48" Width="484" 
                 FontSize="20" KeyDown="fuckingText_KeyDown" HorizontalAlignment="Center" VerticalAlignment="Center" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"/>
        <TextBox BorderThickness="0" Background="{StaticResource img_big}" x:Name="textBase_Big" Height="98" Width="358" 
                 FontSize="20" KeyDown="fuckingText_KeyDown" />
        <TextBox BorderThickness="0" x:Name="textBase_Chat" Height="48" Width="484" KeyDown="fuckingText_KeyDown" FontSize="20" VerticalAlignment="Center" VerticalContentAlignment="Center" HorizontalAlignment="Center" HorizontalContentAlignment="Center"/>
        <PasswordBox BorderThickness="0" Background="{StaticResource img_small}" x:Name="passwordBase" VerticalAlignment="Center" VerticalContentAlignment="Center" HorizontalAlignment="Center" HorizontalContentAlignment="Center" KeyDown="fuckingPassword_KeyDown" FontSize="20" />
        <PasswordBox BorderThickness="0" Background="{StaticResource img_small}" x:Name="passwordBaseRepeat" VerticalAlignment="Center" VerticalContentAlignment="Center" HorizontalAlignment="Center" HorizontalContentAlignment="Center" KeyDown="fuckingPassword_KeyDown" FontSize="20" />
    </SwapChainBackgroundPanel>
</Page>
上面的代码中,我定义了若干种输入框,在游戏中用在了不同的地方。这个需要看实际需要来决定到底要多少。一般情况下这些输入框需要在初始化的时候被隐藏,在需要的时候再让它显示。

3. 下面需要解决的问题就是如何在游戏内控制“外壳”中的这些输入框。这里涉及到的最主要的核心技术就是Unity提供的WinRTBridge/AppCallbacks两个类(细节请移步http://docs.unity3d.com/Manual/windowsstore-appcallbacks.html)。这两个类为我们提供了从游戏内调用游戏外以及从游戏外调用游戏内的机制。值得一提的是,两者之间的调用大多是异步的,也就是说,想建立游戏外到游戏内的关系,还是要费一些周折。首先我们来看从游戏内到游戏外的调用。

4. 首先是游戏内,需要建立一个事件对象来监听游戏内对游戏外的请求。比如我们需要将某个输入框显示出来:

// ### SHOW ###
public delegate void OnShowTextBoxEvent(
        double centerX, double centerY, string initText, Main unityMain,
        double screenWidth, double screenHeight, int maxLength, byte kindOfBox);

public OnShowTextBoxEvent onShowTextBoxEvent = null;
这样我们就定义了一个打开文本框的事件,很简单。

5. 然后我们需要在外面接收这个事件。先在外壳中的MainPage.xaml.cs中找个地方写下文本框显示的基础代码:

public void ShowTextBox(double centerX, double centerY, string initText,
            double unityScreenWidth, double unityScreenHeight, int maxLength, byte kindOfBox)
{
// 此处为了节省篇幅,不写了,XAML相关的显示而已,很简单。
}
接下来,找个地方写下对事件的处理。这里要和游戏内定义好的事件参数对上:

        private double _centerX, _centerY;
        private double _unityScreenWidth, _unityScreenHeight;
        string _initText;
        private int _maxLength;
        private byte _kindOfBox;
public void OnShowTextBoxEvent(double centerX, double centerY, string initText, Main unityMain,
            double unityScreenWidth, double unityScreenHeight, int maxLength, byte kindOfBox)
        {
            CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
    <span style="white-space:pre">		</span>CoreDispatcherPriority.High,
    <span style="white-space:pre">		</span>ShowTextBox);

            this._centerX = centerX;
            this._centerY = centerY;
            this._initText = initText;
            this._unityMain = unityMain;
            this._unityScreenWidth = unityScreenWidth;
            this._unityScreenHeight = unityScreenHeight;
            this._maxLength = maxLength;
            this._kindOfBox = kindOfBox;
        }


        private async void ShowTextBox()
        {
           // 此处略过一些没有必要占用篇幅的代码
            if (AppCallbacks.Instance.IsInitialized())
            {
                AppCallbacks.Instance.InvokeOnAppThread(new AppCallbackItem(() =>
                {
                    if (_unityMain != null)
                    {
                        _unityMain.ShowTextBoxCallback(__isSuccess);
                    }
                }
                ), false);
            }
#endif
        }
代码比较乱,我就说两点。第一是CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync这个函数发出了一个异步执行ShowTextBox函数的请求。但是被执行的函数不能带参数,所以我定义了一些全局变量来暂存这些参数。第二是上面这段代码同时带了一个游戏外向游戏内的回调,这是我下一步要说的,现在先不说,一会儿说。

现在接收游戏内事件的代码已经写好了,然后我们需要把这个事件接收逻辑“挂”上。打开App.xaml.cs,在OnLaunched函数里面的末尾添加如下代码:

AppCallbacks.Instance.InvokeOnAppThread(new AppCallbackItem(() =>
                {
                    UnityEngine.GameObject.Find("GameWorld").GetComponent<Main>().onShowTextBoxEvent
                        = new Main.OnShowTextBoxEvent(xamlManager.OnShowTextBoxEvent);
                }), false); 
这段代码的功用就是将游戏内的事件和游戏外的事件接收器“连接”起来。如果你要调用游戏外的输入框,只需要发出事件就可以了:

    public void TryToShowTextBox(
        double centerX, double centerY, string initText, int maxLength, byte kindOfBox)
    {
        if (onShowTextBoxEvent != null)
        {
            onShowTextBoxEvent(centerX, centerY, initText, this, Screen.width, Screen.height, maxLength, kindOfBox);
        }
    }

6. 回调。

上面已经一笔带过了一下AppCallbacks,这段代码相对简单。


if (AppCallbacks.Instance.IsInitialized())
            {
                AppCallbacks.Instance.InvokeOnAppThread(new AppCallbackItem(() =>
                {
                    if (_unityMain != null)
                    {
                        _unityMain.ShowTextBoxCallback(__isSuccess);
                    }
                }
                ), false);
            }

这段代码是直接调用游戏内的一个函数,所以我就不解释了。唯一需要注意的是如果你需要通过某个对象来调用一个方法,那么这个对象要预先传递到外面。这里就不解释了。

有问题欢迎给我发邮件:stupidcodegenerator@gmail.com

或者直接回复本帖也行






WPF 控件样式之TextBox 输入框 TextBox 输入框 基础用法 <TextBox></TextBox> <TextBox lib:Assists.PlaceHolder="自定义水印内容和颜色" lib:Assists.PlaceHolderBrush="Red"></TextBox> 禁用状态 <TextBox IsEnabled="False"></TextBox> 可清空 <TextBox lib:Assis 阅读详情

相关推荐

弹出Windows10的虚拟键盘总结

由于公司的项目软件一直都在Windows的平板电脑上运行,所以当用户点击了输入框之类的控件时,就要在代码中主动让Windows的虚拟键盘启动并显示出来。这个功能分了几步的开发过程,现在来总结一下。 项目使用的界面库都是SoUI2。 一、通过在WM_LBUTTONUP中判断是否应该使用shellexecute启动虚拟键盘 一开始的解决方法是在窗体的WM_LBUTTONUP中处理,就是查看是否是需要输入的控件获取到当前焦点,是的话就用shellexecute启动虚拟键盘,然后再把WM_LBUTTONUP交回给窗

不定期更新的博客 1730

KeyboardPianoV1.7.1 Debug(贴图优化)

文章目录详细步骤例行说明具体步骤代码分析Option 详细步骤 例行说明 Debug 开篇引言——越往后越难,情况越多越复杂,坐稳啦 V1.5.1 中 switchCase & graphicsImageSet() 的代码解释下有引出一个 BUG 每 paint 一次,就会初始化一次按钮的贴图,重复的初始化,导致无缘无故地消耗内存,属于代码逻辑错误 具体步骤 正确的处理...

weixin_40344491的博客 289

两款免费的软键盘,适合平板电脑等无键盘系统

这是两款免费的软键盘,其中VB的带有源码,可以参考学习,至于输入秀还是不错的,网上免费的太少了,所以给大家分享一下.

windows虚拟键盘透明化小软件(AdjustTouchKeyboardOpacity)(无意发现的好东西)

今天逛贴吧时发现一个很好用的小软件,名字 叫AdjustTouchKeyboardOpacity。 百度云连接 如果用windows平板的时候被虚拟键盘挡住输入框肯定很郁闷,这个软件可以将其透明化,下载下来解压选择是32位还是64位运行一下就可以见到效果,修改另外一个配置文件里面的参数即可修改透明程度。 我的平板的效果如下: 但是想要一直保持这样可以进入控制面板里的计划

Kblacksmith的博客 7904

透明虚拟键盘

用C#winform开发的一个虚拟键盘,模拟类型Thinkpad,带隐藏按钮,觉得好的顶,欢迎提改善意见。

虚拟键盘软件

虚拟建盘好用不用说

Unity Windows 填坑日记之导出篇

1. .Net 2.0 Subset 顾名思义,.Net

StupidCodeGenerator的专栏 6971

wpf TextBox 做密码输入框

wpf 自带的密码输入框在触屏上无法自动唤出触控面板,因此修改了一个textbox的密码输入框

WindowsPhone&Windows8.1&Windows8&Unity3d 填坑日记

最近的游戏开发大体上接近尾声,总结了不少关于Unity3d面向Windows几大平台

StupidCodeGenerator的专栏 5180

Windows7全透明桌面小工具

全透明酷炫小工具,包括时钟,日历,回收站等10多款精美小工具,足以扮靓你的desktop。

AlphaFold-multimer 复合物结构预测

是DeepMind开发的AlphaFold项目的一个扩展,旨在预测蛋白质多聚体的三维结构。蛋白质多聚体是由多个蛋白质亚单位相互组装而成的结构,如酶、膜蛋白复合物和病毒颗粒。理解多聚体的结构对于揭示蛋白质的功能和相互作用非常重要。

MurphyStar的博客 5645

WindowsPhone&Windows8.1&Windows8&Unity3d 填坑日记

近期的游戏开发大体上接近尾声,总结了不少关于Unity3d面向Windows几大平台开发时遇到的各种坑以及怎样填坑的经验。总的来说,Windows8.1 Windows8/RT以及WindowsPhone这几个平台的开发人员很的少,文档也很的有限。甚至于MSDN的文档写的也是不清不楚。所以我认为有必要用一系列的文章具体的和大家分享一下。 这一篇仅仅是一个文件夹,先介绍一下我要写的一些部分...

weixin_34323858的博客 90

Spine换装系统深度优化:从局部换肤到动态合批的进阶之路

本文深入探讨了Spine换装系统的性能优化策略,从局部换肤到动态合批的进阶技术。通过分析传统方案的性能瓶颈,提出动态合批、GPU Instancing等高级优化方法,显著降低Draw Call和内存占用,提升游戏性能。适用于MMO和大型游戏开发,帮助技术美术和工程师突破大规模换装场景的性能限制。

vulkan6gpu的博客 553

WPF开发登录窗口之——添加文本输入框用户控件

WPF开发者QQ群:340500857 | 微信群 目前人数太多,暂不开放窗口开发完成后,接下来就是开发客户区中的输入框控件,但在开发之前,我们先开发一个输入框基类,然后通过继承的...

dotNET跨平台 2037

Transformer是什么?看完这篇你就醍醐灌顶

前言 由谷歌团队提出的预训练语言模型BERT近年来正在各大自然语言处理任务中屠榜(话说学者们也挺有意思的,模型名都强行凑个芝麻街的人物名,哈哈哈)。 BERT算法的最重要的部分便是Transformer的概念,它本质上是Transformer的编码器部分。 而Transformer是什么呢?transformer是永远的神,自从transformer使用了抛弃rnncnn的纯attention机制之后,各种基于transformer结构的预训练模型都如雨后春笋般雄起,而transformer中最重要就是使用

fs1341825137的博客 6万+

wsl2上运行带有Isaac Gym的程序报错: GPU Pipeline: disabled

显示GPU Pipeline:disabled,查找相关文档发现是WSL2目前不支持Isaac Gym,时,想要在wsl2上运行,最后报错如下。

2303_78660611的博客 957

WPF 使用TextBox做密码输入框

密码输入框需要输入的密码不能显示明文,用其他的特殊字符代替显示。 显示效果如下: Xaml部分代码如下:<Window x:Class="TextBoxPwd.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.m

SANYUNI的专栏 2万+

西电计组实验二 运算器实验

算术逻辑运算实验 一.实验目的   1.了解简单运算器的数据传输通路。   2.验证运算功能发生器的组合功能。   3.掌握算术逻辑运算加、减、与的工作原理。   4.验证实验台运算的8位加、减、与、直通功能。   5.按给定数据,完成几种指定的算术和逻辑运算。 二.实验原理   算术逻辑单元ALU的数据通路如图2-1所示。其中运算器ALU181根据74LS181的功能用VHDL硬件描述语言编辑而成,构成8位字长的ALU。参加运算的两个8位数据分别为A[7…0]和B[7…0],运算模式由S[3…0]的16种

Polaris的博客 1万+

WPF 数字输入框

一个简单的TextBox,数字输入控制中间件

xfeng20的博客 4293

UNet改进(12):融合小波变换与注意力机制的图像分割新方法

本文提出了一种改进的WaveletAttentionUNet架构,通过结合小波变换和注意力机制来增强传统UNet的多尺度特征提取能力。该网络使用分组卷积模拟小波分解,将输入通道扩展为4个子带(LL、LH、HL、HH),并通过通道注意力机制自适应加权各子带特征。网络保留了UNet的编码器-解码器结构,在关键位置集成了WaveletAttention模块。实验证明该方法在医学图像分割等任务中能更好地保持边缘细节和复杂纹理特征,同时保持计算效率。

2501_91516851的博客 758

【100%通过率】2024华为OD机试真题E卷 C++语言 实现【流浪地球】

流浪地球计划在赤道上均匀部署了N个转向发动机,按位置顺序编号为0~N-1。 1) 初始状态下所有的发动机都是未启动状态; 2) 发动机起动的方式分为“手动启动”和“关联启动”两种方式; 3) 如果在时刻1一个发动机被启动,下一个时刻2与之相邻的两个发动机就会被“关联启动”; 4) 如果准备启动某个发动机时,它已经被启动了,则什么都不用做; 5) 发动机0与发动机N-1是相邻; 地球联合政府准备挑选某些发动机在某些时刻进行“手动启动”,当然最终所有的发动机都会被启动。 哪些发动机最晚被启动呢?

MISAYAONE的博客 4210

XAML 文本框验证身份证

开发工具与关键技术:WPF XAML C# 正则 作者:李寿宇 撰写时间:2019/5/14 18位身份证验证: 在新增页面录入资料时特别是个人资料需要输入身份证、联系地址和出生日期······ 文本框输入身份证时在输入的过程中录入错误的身份证导致输入的数据不真实。我们在新增数据就作个判断用户输入的身份证是否合法,身份证前六位是个地址码首先判断用户输入前六位地址码号码时是否真确,如果不真确弹出提示...

weixin_42104218的博客 535

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

上一篇: Unity Windows 填坑日记之导出篇
下一篇: Windows8 & WindowsPhone 关于支付宝的问题
垃圾桶
博客等级 码龄15年 20粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值