【转】XE6/XE7多窗口操作的Z轴序列错乱问题解决办法(2014-09-2608:01:46)xe7分类:DelphiXE7盒子中的cywyes发现这个问题,并给出的答案,转贴过来,学习了!以下为原文:----------XE6/XE7多窗口操作的Z轴序列错乱问题解决办法bycyw(QQ:26890954)14.9.25----------一、问题现象:1、Win32/64MainForm--显示Form2--显示Form3--关闭Form3,MainForm显示在最前面,遮挡了Form2。(理论上:应该是Form2在前)。2、AndroidMainForm--显示Form2--显示Form3--关闭Form3--点击Form2上的TEdit控件,输入法不会弹出!二、演示步骤:1、在Form1上,Form2.Show;2、在Form2上,Form3.Show;3、在Form3上,Close;4、Android:再点击Form2上的TEdit控件,输入法不会弹出!Windows:Form1遮挡了Form2。三、解决方法(适用于XE6和XE7):修改FMX.Form.pas的以下代码:1、functionTScreen.NextActiveForm(constOldActiveForm:TCommonCustomForm):TCommonCustomForm;整个函数改为如下:functionTScreen.NextActiveForm(constOldActiveForm:TCommonCustomForm):TCommonCustomForm;varI,CurrIndex:integer;beginResult:=nil;CurrIndex:=IndexFormOfObject(OldActiveForm);(*总是优先找到OldActiveForm的前一个窗口(Z序列中的下一层).addbycyw14.9.25*)I:=-1;ifCurrIndex0thenbeginI:=CurrIndex-1;while(I=0)and(notForms[I].Visible)doDec(I);end;ifI=-1then//如果找不到,再依据原来的逻辑,先找OldActiveForm的最上层第1个窗口可视窗口。(*addover*)beginI:=FormCount-1;while(I=0)and(ICurrIndex)and(notForms[I].Visible)doDec(I);if(I0)or(I=CurrIndex)thenbeginI:=0;while(IFormCount)and(ICurrIndex)and(notForms[I].Visible)doInc(I);end;end;if(IFormCount)and(ICurrIndex)thenbeginResult:=Forms[I];ActiveForm:=Result;end;end;2、procedureTScreen.SetActiveForm(constValue:TCommonCustomForm);整个函数改为如下:procedureTScreen.SetActiveForm(constValue:TCommonCustomForm);varNewActiveForm:TCommonCustomForm;I:Integer;beginifAssigned(Value)thenbeginifnotValue.ReleasedthenbeginI:=IndexFormOfObject(Value);ifI0thenraiseEInvalidFmxHandle.Create(sArgumentInvalid);NewActiveForm:=Forms[I];//下面一行的条件屏蔽bycyw14.9.25//原因:因为在TCommonCustomForm.Activate里调用Screen.ActiveForm:=Self;之前,//已经设置了FActive:=True。如果这里保留条件“notNewActiveForm.Active”,//则Value窗口的Z序列就没有更新,导致所有窗口的Z序列错乱。if{(notNewActiveForm.Active)and}(IFormCount-1)thenbeginFForms.Delete(I);FForms.Add(NewActiveForm);end;forI:=0toFormCount-1doif(Forms[I]NewActiveForm)and(notIsParent(Forms[I],NewActiveForm))thenForms[I].Deactivate;ifnotNewActiveForm.ActivethenNewActiveForm.Activate;end;endelsebeginforI:=0toFormCount-1doForms[I].Deactivate;endend;原文地址后记:2015-04-19,XE8解决了这个问题。DelphiXE7学习笔记(二)Android键盘处理(2014-09-1109:29:39)转载▼分类:DelphiXE7XE7带了ScrollableFormDemo例子,演示如何实现输入键盘自适应当前的输入项。实现屏幕上下自动划动,不让输入键盘遮盖住当前正在输入的项。例子在安装目录X:\Embarcadero\Studio\15.0\Samples\ObjectPascal\MobileSamples\UserInterface\ScrollableForm编译并运行这个例子,在我的Note3上,效果非常好。在测试中,还是发现利用键盘上的隐藏键,隐藏键盘后,不触发OnVirtualKeyboardHidden事件,造成界面不能还原,如下图:第二个演示图:可以利用龟山的方法解决。后记:我试着利用Timer去触发OnVirtualKeyboardHidden,结果,应用有崩溃的时候,另外,在恢复屏的内容时,位置也计算不准,最下面的Edit在再次弹出keyBoard时也没算准,不显示。试着用backspace键,系统是正常的,问题的实质就在于emb没有处理keyboard上的隐藏键。功力有限,精力有限,等emb来处理吧!再后记:后记中利用Timer的所有问题都解决了!感谢盒子上的wang_80919,原文在这里,改后的FMX.VirtualKeyboard.Android.pas原代码在这里。DelphiXE7学习笔记(三)多窗体间如何调用(2014-09-1217:36:10)转载▼分类:DelphiXE7实作一个项目,一定由多个窗口组成的,对于Android来说,如何在A窗口中调用另外一个窗口呢?还有一个问题,当在项目中建立多个Form时,在dpr项目文件中,默认都是自动建立Form实例的,如果一个项目的Form很多,在启动项目时会非常耗时,也就是Splash显示完后,会黑屏很长时间,为了解决这个方法,我想,好的办法就是在调用时先判断这个Form是否已经建立,没有的话,先建立,再显示。这里有一个与Win32应用不同的是,Android不支持Form.ShowModal方法,只能使用Form.Show方法显示一个窗口。以XE7带的范例,对他做一下修改,这个例子在目录:C:\Embarcadero\Studio\15.0\Samples\ObjectPascal\MobileSamples\UserInterface\Forms1.打开项目文件:programForms;usesSystem.StartUpCopy,FMX.Forms,PortraitFormin'PortraitForm.pas'{PForm},LandscapeFormin'LandscapeForm.pas'{LSForm};{$R*.res}beginApplication.Initialize;Application.CreateForm(TPForm,PForm);//Application.CreateForm(TLSForm,LSForm);//把这行去掉,不在运行项目时自动建立Application.Run;end.2.打开PortraitForm单元,把调用第二个窗口的代码做下改造:procedureTPForm.FormResize(Sender:TObject);beginifnotAssigned(LSForm)then//如果LSForm没建立则创建他.LSForm:=TLSForm.Create(Application);if(HeightWidth)and(Visible)thenLSForm.Show;end;OK,这样改造后,就实现了上面提到的两个问题。本文让高手见笑了,只适合初学Delphi者,别喷我!DelphiXE7学习笔记(四)Android输入控件自适应虚拟键盘的位置转载▼(2014-09-2209:27:44)分类:DelphiXE7XE7带的Demo,演示了如何适应虚拟键盘,即当虚拟键盘弹出时,如果掩盖了当前的输入项,如Edit1,那么重新计算屏上所有控件的位置,让Edit1能够正常显示在键盘上面,让用户能看到输入的内容。问题是,键盘弹出后,如果用户利用键盘上的隐藏键,隐藏了键盘后,不能恢复屏上控件的位置,这个问题,其实XE5就存在。要感谢盒子上FlyingWang,用他的方法,很好的解决了上面的问题:原文在这里,改后的FMX.VirtualKeyboard.Android.pas代码在这里。DelphiXE7学习笔记(五)FMX.Types与FMX.Forms引用次序(2014-09-2216:34:19)转载▼标签:itxe7分类:DelphiXE7学习xe7带的VirtualKeyboardDemo例子,为了快速调试,改成win32平台,结果遇到退出程序时产生AV错误,于是开始清理代码,直到清理的只剩下建立新项目时生成的基本代码,问题还是依旧。后对比项目的源代码,再进一步测试,结论是:fmx.types与fmx.forms的引用次序有关,就是说要先引用fmx.forms,再引用fmx.types.附改后的dpr的代码,被我简化并修正后的:programVirtualKeyboardDemo;uses//System.StartUpCopy,//是否引用这个单元,不影响在win32与android下切换!FMX.Forms,//先引用,否则在win32平台下会出错.FMX.Types,//后引用VirtualKeyboardBasein'VirtualKeyboardBase.pas'{VKBaseForm};{$R*.res}beginApplication.Initialize;Application.CreateForm(TVKBaseForm,VKBaseForm);Application.Run;end.DelphiXE7学习笔记(六)TBlobStream的使用(2014-09-2308:19:13)转载▼分类:DelphiXE7盒子上有网友遇到问题,直接用TBlobStream来做类型转换,编译时提示无法找到这个类。查了下源码,发现这个类已经被定义在Data.DBXDataSets单元的TDBXReaderDataSet类中。简化的看一下,象下面这样定义:TDBXReaderDataSet=class(TDataSet)publictypeTBlobStream=class(TMemoryStream)private...对于象上面这种方式定义的类,使用时加上引用类所在的类名就可以了。比如:procedureTVKBaseForm.FormCreate(Sender:TObject);varb:TDBXReaderDataSet.TBlobStream;//声