注册 登录
编程论坛 VFP论坛

请教是否能获取编辑框中某个指定文字的距离左侧和顶部的像素?

wxzd123 发布于 6 天前 18:57, 915 次点击
只有本站会员才能查看附件,请 登录

请教能否获取图中“节”字的距离左侧和顶部的像素?谢谢
17 回复
#2
kangss6 天前 19:15
如果能用鼠标点击一下,就能获取鼠标的位置,再通过窗口句柄获取窗口的位置,就能计算x、y数值
关键点在是否有鼠标点击
#3
wxzd1236 天前 22:21
请问如何用代码实现,谢谢

#4
吹水佬5 天前 06:54
说说目的为何?或者可以拓展一下思路。

#5
wxzd1235 天前 07:53
谢谢 吹水佬 版主
只有本站会员才能查看附件,请 登录

首先点选编辑框要填入的横线位,定位要填入选项位置,然后点选下面的按钮把按钮上的英文字母天道横线上,最好是与文章字的颜色不同
#6
wxzd1235 天前 08:09
只有本站会员才能查看附件,请 登录

版主辛苦了,谢谢
#7
sych5 天前 10:22
在richtext的讨论贴中有示例,可以获取坐标
#defi EM_POSFROMCHAR  0xd6

[此贴子已经被作者于2025-9-11 10:23编辑过]

#8
wxzd1235 天前 14:55
只有本站会员才能查看附件,请 登录

nXCoord, nYCoord可以得到坐标,请教如何得到鼠标点击的字,比如下划线“__”,来判断是填空位置,然后在此位置添加一个标签,用来显示点选的字母,请老师帮助,谢谢
#9
wxzd1235 天前 15:30
只有本站会员才能查看附件,请 登录
只有本站会员才能查看附件,请 登录
鼠标点位置不同,标签的位置不同,不能准确定位
#10
csyx5 天前 17:18
你这是 vfp 原生的 Editbox 吧?如果是则它没有控件窗口句柄,所有的 EM_* 消息全都废泡
建议尝试下 GetCaretPos API,参考:
https://baike.baidu.com/item/GetCaretPos/6368797
https://learn.
#11
wxzd1235 天前 21:16
谢谢csyx ,没有vfp代码示例



[此贴子已经被作者于2025-9-12 05:34编辑过]

#12
csyx3 天前 08:19
粘贴下列代码到 Edit1.click 事件中,运行时可以看到点击位置的字符和坐标位置(相对于表单客户区原点)
只要明白了 GetCaretPos 的作用,取第二个“节”字的坐标也就易如反掌

程序代码:
Declare Long GetCaretPos in win32api String @

pt = BinToC(0,'rs') + BinToC(0,'rs')
GetCaretPos(@ pt)
x = CToBin(Substr(pt,1,4), 'rs')
y = CToBin(Substr(pt,5,4), 'rs')

cc = Substr(This.Text, This.SelStart+1, 1)
Do case
Case IsLeadByte(cc)
    cc = ["] + Substr(This.Text, This.SelStart+1, 2) + ["]
Case Asc(cc) < 33
    cc = Textmerge('CHR(<<Asc(cc)>>)')
Otherwise
    cc = ["] + cc + ["]
EndCase
cc = Textmerge('char=<<cc>>,x=<<x>>,y=<<y>>')
Wait windows cc nowait noclear
#13
wxzd1233 天前 11:02
以下是引用csyx在2025-9-13 08:19:39的发言:

粘贴下列代码到 Edit1.click 事件中,运行时可以看到点击位置的字符和坐标位置(相对于表单客户区原点)
只要明白了 GetCaretPos 的作用,取第二个“节”字的坐标也就易如反掌

Declare Long GetCaretPos in win32api String @

pt = BinToC(0,'rs') + BinToC(0,'rs')
GetCaretPos(@ pt)
x = CToBin(Substr(pt,1,4), 'rs')
y = CToBin(Substr(pt,5,4), 'rs')

cc = Substr(This.Text, This.SelStart+1, 1)
Do case
Case IsLeadByte(cc)
    cc = ["] + Substr(This.Text, This.SelStart+1, 2) + ["]
Case Asc(cc) < 33
    cc = Textmerge('CHR(<<Asc(cc)>>)')
Otherwise
    cc = ["] + cc + ["]
EndCase
cc = Textmerge('char=<<cc>>,x=<<x>>,y=<<y>>')
Wait windows cc nowait noclear

谢谢老师,这个太好了!
#14
wxzd1233 天前 14:34
再次请教csyx老师,如何把这段代码修改成:把编辑框的内容从头到尾把所有'_'的x,y坐标保存到表中?谢谢,辛苦了!
#15
吹水佬前天 00:23
回复 5楼 wxzd123
是不是这效果?
只有本站会员才能查看附件,请 登录

程序代码:

of = CREATEOBJECT("form1")
of.show(1)
CLEAR ALL
RETURN
DEFINE CLASS form1 as Form
    width       = 500
    height      = 400
    AllowOutput = .f.
    AutoCenter  = .t.
    FontSize    = 18
    word        = ""
    ADD OBJECT label1 as label WITH left= 50,top=300,width=50,height=28,fontsize=18,caption="填"
    ADD OBJECT label2 as label WITH left=110,top=300,width=50,height=28,fontsize=18,caption="空"
    ADD OBJECT label3 as label WITH left=170,top=300,width=50,height=28,fontsize=18,caption="选"
    ADD OBJECT label4 as label WITH left=230,top=300,width=50,height=28,fontsize=18,caption="择"
    PROCEDURE label1.click
        thisform.selWord(this)
    ENDPROC
    PROCEDURE label2.click
        thisform.selWord(this)
    ENDPROC
    PROCEDURE label3.click
        thisform.selWord(this)
    ENDPROC
    PROCEDURE label4.click
        thisform.selWord(this)
    ENDPROC
    FUNCTION selWord(obj)
        this.word = obj.Caption
        obj.ForeColor = 0x000000FF
        INKEY(0.1)
        obj.ForeColor = 0x00FF0000
    ENDFUNC
    PROCEDURE init
        txt = "请先 _ 点击下面 _ 选择要填空的内容,然后 _ 再点击上面 _ 要填空的下划线 _ 的空位置"
        DIMENSION aLowLine[OCCURS("_",txt),2]
        lowline = 0
        this.CurrentX = 10
        this.CurrentY = 10
        FOR i=1 TO LENC(txt)
            word = SUBSTRC(txt, i, 1)
            IF word == "_"
                lowline = lowline + 1
                aLowLine[lowline,1] = this.CurrentX + this.TextWidth ("_")/2
                aLowLine[lowline,2] = this.CurrentY + this.TextHeight("_")/2
            ENDIF
            this.Print(word)
            IF this.CurrentX > this.Width - 50
                this.CurrentX = 10
                this.CurrentY = this.CurrentY + this.TextHeight(SUBSTRC(txt, i+1, 1)) + 10
            ENDIF
        ENDFOR
    ENDPROC
    PROCEDURE click
        this.printf(this.word)
    ENDPROC
    FUNCTION printf(word)
        AMOUSEOBJ(arr)
        this.CurrentX = arr[3]-this.TextWidth (word)/2
        this.CurrentY = arr[4]-this.TextHeight(word)/2
        **可以判断当前点击的(x,y)与aLowLine数组保存的各"_"(x,y)是否有匹配才决定下一步。
        this.Print(word)
    ENDFUNC
ENDDEFINE
#16
schtg前天 06:17
回复 15楼 吹水佬
#17
吹水佬前天 09:33
加个判断点击下划线位置
程序代码:

of = CREATEOBJECT("form1")
of.show(1)
CLEAR ALL
RETURN
DEFINE CLASS form1 as Form
    width       = 500
    height      = 400
    AllowOutput = .f.
    AutoCenter  = .t.
    FontSize    = 18
    word        = ""
    DIMENSION aLowLine[1,2]
    ADD OBJECT label1 as label WITH left= 50,top=300,width=50,height=28,fontsize=18,caption="填"
    ADD OBJECT label2 as label WITH left=110,top=300,width=50,height=28,fontsize=18,caption="空"
    ADD OBJECT label3 as label WITH left=170,top=300,width=50,height=28,fontsize=18,caption="选"
    ADD OBJECT label4 as label WITH left=230,top=300,width=50,height=28,fontsize=18,caption="择"
    PROCEDURE label1.click
        thisform.selWord(this)
    ENDPROC
    PROCEDURE label2.click
        thisform.selWord(this)
    ENDPROC
    PROCEDURE label3.click
        thisform.selWord(this)
    ENDPROC
    PROCEDURE label4.click
        thisform.selWord(this)
    ENDPROC
    FUNCTION selWord(obj)
        this.word = obj.Caption
        obj.ForeColor = 0x000000FF
        INKEY(0.1)
        obj.ForeColor = 0x00FF0000
    ENDFUNC
    PROCEDURE init
        txt = "请先 _ 点击下面 _ 选择要填空的内容,然后 _ 再点击上面 _ 要填空的下划线 _ 的空位置"
        DIMENSION this.aLowLine[OCCURS("_",txt),2]
        lowline = 0
        this.CurrentX = 10
        this.CurrentY = 10
        FOR i=1 TO LENC(txt)
            word = SUBSTRC(txt, i, 1)
            IF word == "_"
                lowline = lowline + 1
                this.aLowLine[lowline,1] = this.CurrentX + this.TextWidth ("_")/2
                this.aLowLine[lowline,2] = this.CurrentY + this.TextHeight("_")/2
            ENDIF
            this.Print(word)
            IF this.CurrentX > this.Width - 50
                this.CurrentX = 10
                this.CurrentY = this.CurrentY + this.TextHeight(SUBSTRC(txt, i+1, 1)) + 10
            ENDIF
        ENDFOR
    ENDPROC
    PROCEDURE click
        this.printf(this.word)
    ENDPROC
    FUNCTION printf(word)
        AMOUSEOBJ(arr)
        this.CurrentX = arr[3]-this.TextWidth (word)/2
        this.CurrentY = arr[4]-this.TextHeight(word)/2
        **可以判断当前点击的(x,y)与aLowLine数组保存的各"_"(x,y)是否有匹配才决定下一步。
        IF this.isLowLine(arr[3], arr[4])
            this.Print(word)
        ENDIF
    ENDFUNC
    FUNCTION isLowLine(x, y)
        FOR i=1 TO ALEN(this.aLowLine,1)
            IF ABS(this.aLowLine[i,1] - x) < this.TextWidth ("_")/4 AND ;
               ABS(this.aLowLine[i,2] - y) < this.TextHeight("_")/4
               RETURN .t.
            ENDIF
        ENDFOR
        RETURN .f.
    ENDFUNC
ENDDEFINE


#18
wxzd123前天 10:24
谢谢 吹水佬 版主,辛苦了!代码高深得慢慢消化
1