回 帖 发 新 帖 刷新版面

主题:输入如何跟随光标

请教编程高手、老师:
    我想在TEXT1中红色光标处输入列表框LIST2中的b2选项,如下图所示。可以设计成双击b2选项,b2自动进入红色光标处。这个程序应该如何编写?我现在可以做到双击b2,b2自动进入TEXT1,却始终位于文本框左边开始位置,不能跟随光标。谢谢!

回复列表 (共14个回复)

沙发

你在b2的 DblClick  里输入一个
thisform.text1.SetFocus

板凳

在列表框LIST2的DBLCLICK事件中
thisform.text1.Value=ALLTRIM(thisform.text1.text)+this.Value 
thisform.text1.SetFocus 

在TEXT1的GOTFocus事件中
KEYBOARD "{End}" 
KEYBOARD "{End}"  CLEAR 

3 楼

如果要在TEXT1的光标所在位置处插入双击LIST2所选的值,在列表框LIST2的DBLCLICK事件中使用下面的语句:

c1=LEFT(thisform.text1.Text,thisform.text1.SelStart)
c2=SUBSTR(thisform.text1.Text,thisform.text1.SelStart+1)
thisform.text1.Value=c1+ALLTRIM(this.Value)+c2 

4 楼

sywzs老师:
按照你的指示,复制代码到相应的事件中。我试了一下,结果TEXT1不能获得焦点,无法输入。
后来我把《在TEXT1的GOTFocus事件中
    KEYBOARD "{End}" 
    KEYBOARD "{End}"  CLEAR  
删除,保留其余。这样,运行基本成功,问题是TEXT1内的光标始终回到文本框左端起点!
   请你说明一下命令 KEYBOARD "{End}" 和 KEYBOARD "{End}"  CLEAR  的作用和功能。我
是初学者,多指教!




5 楼

[quote]如果要在TEXT1的光标所在位置处插入双击LIST2所选的值,在列表框LIST2的DBLCLICK事件中使用下面的语句:

c1=LEFT(thisform.text1.Text,thisform.text1.SelStart)
c2=SUBSTR(thisform.text1.Text,thisform.text1.SelStart+1)
thisform.text1.Value=c1+ALLTRIM(this.Value)+c2 
[/quote]
sywzs老师:
按照你的指示,复制代码到相应的事件中。我试了一下, 
运行成功!
 请你说明一下命令的作用和功能。
left(thisform.text1.Text,thisform.text1.SelStart) 这个函数是返回thisform.text1.Text指定数目的字符,
第二项参数应是字符数目,thisform.text1.SelStart是代表当前光标的位置吗?数目和位置等同如何理解。
   SUBSTR(thisform.text1.Text,thisform.text1.SelStart+1),如何理解?为什么不用left()? 请解释一下。
thisform.text1.SelStart+1是下一个光标的位置吗?如何理解?
我是初学者,多指教!

6 楼

我来替sywzs老师解释一下:
首先left(str,n)是一个返回字符串str左边n个字符的函数.selstar是text1中光标所在位置,sywzs的left函数返回了text1中光标所在位置及前面的字符串,

substr(str,p,n)是一个提取字符串str中从p开始的n个字符的函数,如果函数中将n参数省略,则返回str中从p开始以后的所有字符.sywzs的函数返回的是text1中光标所在位置后面的所有字符.

用left()和substr()两个函数,和text1的selstart属性值将text1的值一分为二,分别用c1,c2存储,以便将你在list2中选择的项目内容插入到text1光标所在位置.

其实你理解的非常到位,再自信点就好了,"为什么不用left()? "这个问题提得不太聪明.

7 楼

谢谢jinlonggao老师的正确解释
在解释一下 KEYBOARD "{End}" 和 KEYBOARD "{End}"  CLEAR  
KEYBOARD "{End}" 实在键盘缓冲区放入一个字符 {End}  并且执行它,把光标移到行尾。这个字符是占用内存的,为了减少不必要的内存的开销,用 KEYBOARD "{End}"  CLEAR  及时清除这个字符。

8 楼

俺有点不同意见,提出来和大家探讨:
KEYBOARD cKeyboardValue CLEAR 命令的这个CLEAR是先清除键盘缓冲区,然后再把cKeyboardValue送入缓冲区等待处理。因此
[quote]为了减少不必要的内存的开销,用 KEYBOARD "{End}"  CLEAR  及时清除这个字符。[/quote]
这个说法不对。
大多数情况下,我们没有必要自行处理键盘缓冲区,只要其中的内容系统处理了,缓冲区自动清空,除非我们一次送进去超过128个键码。这时系统会按出错处理。

在命令窗口实验:

实验1(预备实验):连续输入如下命令,然后全选中回车

KEYBOARD "Hello,vfp" 
KEYBOARD "This is a test"

结果:命令窗口下一行显示
Hello,vfpThis is a test

分析:两条命令连续向键盘缓冲区送入23个键码(字符),因为目前是命令窗口处理键盘输入,它的处理方式是把缓冲区内容原样输出到窗口中显示。那么显示完毕,键盘缓冲区还有内容吗?

实验2:追加命令?CHRSAW(),然后全选中回车

KEYBOARD "Hello,vfp" 
KEYBOARD "This is a test"
?CHRSAW()

注解:CHRSAW()判断键盘缓冲区是否有内容,为.T.表示缓冲区有内容,为.F.表示缓冲区空。

结果: 
命令窗口显示
Hello,vfpThis is a test
主窗口显示
.T.

分析:执行到第3句时,控制权还没有交还给命令窗口,换句话说,命令窗口还没有处理键盘缓冲区,因此函数返回.T.。该分析还基于以下对比实验的分析。

对比实验1:

先连续执行
KEYBOARD "Hello,vfp" 
KEYBOARD "This is a test"
然后执行
?CHRSAW()

结果: 
命令窗口显示
Hello,vfpThis is a test
主窗口显示
.F.

分析:连续执行完两句后,控制权交还命令窗口,窗口处理键盘缓冲区,在窗口显示Hello,vfpThis is a test。处理完毕,键盘缓冲区自动清空,CHRSAW()返回.F.

对比实验2:下面代码全选中回车

KEYBOARD "Hello,vfp" 
KEYBOARD "This is a test"
FOR i=1 TO 1000 &&目的是产生一点延时
 ?"wait"
ENDFOR 

结果:主窗口显示1000遍"wait",直到for结束,命令窗口才出现Hello,vfpThis is a test。

分析:该实验说明在命令窗口没有得到控制权之前,还无法处理键盘缓冲区

实验2结论:当系统处理完键盘缓冲区,会自动清空。

实验3:下面代码全选中回车
KEYBOARD "Hello,vfp" 
KEYBOARD "This is a test" CLEAR

结果:命令窗口显示This is a test。

分析:第2条命令执行时首先清空了键盘缓冲区,然后把"This is a test"送入。最后命令窗口得到控制权处理缓冲区时,该区只有第2条命令送入的键码。

实验4:
KEYBOARD "Hello"+space(121)+"VFP" &&共129个
结果:出错

对比实验:
KEYBOARD "Hello"+space(120)+"VFP" &&共128个
结果:正常输出(需耐心等待一下)

分析:不能一次性输入超过128个键码,缓冲区溢出

实验5:
KEYBOARD "Hello" 
KEYBOARD SPACE(128)
KEYBOARD "vfp" 
KEYBOARD SPACE(128)
KEYBOARD "This is a test"

结果:正常输出(提示,本实验需要很耐心的等待一下)

分析:对于用KEYBOARD多次输入的键码,系统会采取某种机制保证它们得到处理。到底是何种机制,实验无法知道。

全部结论:系统会自行处理键盘缓冲区,一般无需用户干预。

可能的疑问:
我向一个文本框(编辑框)输入字符,连续击键可能超过128个,怎么不会有错?
答:每击一键,文本框立刻处理了,键盘缓冲区马上清空。

9 楼

jinlonggao老师:你解释得很好,基本上懂了。只是有一点还请你解释一下,left(str,n)
和substr(str,p,n)中的n数为什么可用.selstar表示位置的属性替代?

10 楼




8 楼,Ilikefox老师:你分析得非常透出,很有说服力!辛苦了,谢谢!

我来回复

您尚未登录,请登录后再回复。点此登录或注册