您的位置:首页 > 编程语言 > Delphi

Delphi6.0的那些

2020-03-01 04:26 363 查看

使用Delphi6.0的那些琐事儿

公司目前还在用Delphi6.0的东西,各种控件Bug,造成的问题根本找不到完善的解决方案。但项目上的问题总得解决啊,所以往往到最后,只能退而求其次的使用一些临时的策略进行规避。很多时候,确实能够解决了当下的问题,但埋藏的其他未知的隐患,在不经意间,又会出现。按照同样的处理逻辑,又解决掉这一轮新的问题。但。。。 依此反复,似乎总是别无他法。

言归正传,在本篇文章中说的问题就是一个典型的控件bug。情况是这样的,假如一个界面中,有TListView、TEdit、TLabel等控件。TEdit的父级控件是一个ToolBar,给该TEdit类型的控件建立一个OnExit事件,这就表示,当焦点离开TEdit的时候,OnExit事件函数就会被触发,情况也确实如此。但令人困惑的不是OnExit有没有被触发,而是被触发几次的问题。假设当前,焦点就在该TEdit控件上,按下Tab键后,TEdit失焦,OnExit被调用,这自然没有问题。但是当在TListView上进行鼠标单击操作后,同样造成TEdit控件失焦,只是此时OnExit事件函数被调两次。这就表示此次的单击操作,造成了该TEdit控件两次失焦。

遗憾的是,最终依然没有找到原因。所以尴尬的局面来了,没有定位到原因,如何解决这个问题。或许唯一的办法就是另辟他径,简单的说就是摒弃当前的处理逻辑,如何做呢?

再回到问题本身,我们希望当焦点离开TEdit控件的时候,如果TEdit控件中输入的内容不满足需要,就在OnExit事件函数中,给出弹窗提示。那么好啦,既然弹窗提示存在连续弹出两次的问题(前文说的,OnExit被调两次),那干脆改变一些设计,就是弹窗不要了,如果用户在TEdit控件中的输入非法,直接就输入不进去(注:这里在设计上的改变并无不妥,因为与客户需求不冲突。假如客户一定要弹框提示,那这种改变自然不行了)。举个例子,假如TEdit控件中要求只输入数字,而且限定在闭区间[5, 120]这样的范围。其它非法的输入一律无效,那么该如何实现呢?

这个实现当然不难,只是逻辑控制。但其中一些细节问题相当令人头疼,比如删除键造成的问题。在Delphi6.0中,对控件TEdit建立事件函数OnKeyPress。奇怪的是,这个事件函数能够捕捉到键盘中的BackSpace键,却无法捕捉到Delete键。一开始,我只考虑了BackSpace键进行删除的动作,然而,当用Delete键进行删除,却发现错误百出。比如光标定位就不对,还有delete与BackSpace键不能混用等等。

我们知道,delete是从前往后的删除,而BackSpace则相反。我忽略了这个,但最后才发现,这两个不同的删除键,造成的事件函数的执行顺序完全不一样。简单来说TEdit控件的两个事件函数,一个是 OnKeyPress(前面提到过),另一个是OnChange。你会发现,当你使用BackSpace键之后,先是OnKeyPress被调,再是OnChange,但是Delete键只会触发OnChange,对于OnKeyPress完全不起效(我不大明白,为什么会出现这样的问题,OnKeyPress就是针对键盘按键下压后的事件函数,但为什么对Delete键的下压完全不起效。其实不止是Delete键,Tab键也一样不起效,不过Tab倒能理解,毕竟它的功能与Delete有很大差别)。

最后,为了解决这些问题,我使用了SetWindowsHookEx函数,目的是为了捕捉Delete按键。一开始我只捕捉了Delete按键,然后设置了一个标记,当进行Delete操作的时候,遵循与BackSpace按键不同的逻辑,但还是出问题了。因为Delete的删除操作会导致BackSpace按键失效。如TEdit中目前有输入值120,先使用Delete删掉1,TEdit中就剩20了,再用BackSpace进行删除的时候,发现只有光标在移动,删除失效。为什么会这样,依然不能理解,追踪代码下来,发现代码逻辑完全正确,可结果就是不对,崩溃啊!没有办法,只能在SetWindowsHookEx中又增加了对BackSpace键的捕捉,算是把问题解决了。

解决了一个小问题,却引出了一大堆大问题”,或许编程就是这样,当你真正的深入到细节当中去了,才会发现简单的问题并非预料的那么简单。这篇文章,说了一大堆的废话,却没有讲真正的技术,就先这么开始吧

  • 点赞
  • 收藏
  • 分享
  • 文章举报
WalkingNL 发布了1 篇原创文章 · 获赞 0 · 访问量 194 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: