注册 登录
编程论坛 VFP论坛

请问如何正确选择记事本中的指定行?(问题延续)

sych 发布于 2024-11-12 13:45, 1648 次点击
编程论坛 - 请问如何正确选择记事本中的指定行?  https://bbs.bccn.net/thread-513979-1-1.html
上一个问题的延续,不知道大家发现了没有,如果我们多次执行选择行操作,然后记事本一旦获得焦点,选择的行自动切换回我们第一次执行的结果
比如我们第一次选择第2行,然后在随意的操作几次,然后点击记事本的标题栏使记事本窗口获得焦点,我们会发现选中的行自动变成了第2行,也就是我们第一次操作的结果


[此贴子已经被作者于2024-11-12 14:12编辑过]

16 回复
#2
sych2024-11-12 14:12
PUBLIC oform1
oform1=NEWOBJECT("form1")
oform1.Show
RETURN

DEFINE CLASS form1 AS form
    Height = 110
    Width = 193
    ShowWindow = 2
    DoCreate = .T.
    AutoCenter = .T.
    Caption = "Form1"
    AlwaysOnTop = .T.
    Name = "Form1"

    ADD OBJECT command1 AS commandbutton WITH ;
        Top = 60, ;
        Left = 68, ;
        Height = 25, ;
        Width = 60, ;
        Caption = "执行", ;
        Name = "Command1"


    ADD OBJECT text1 AS textbox WITH ;
        Alignment = 3, ;
        Value = 1, ;
        Height = 25, ;
        InputMask = "999", ;
        Left = 72, ;
        Top = 24, ;
        Width = 40, ;
        Name = "Text1"

    ADD OBJECT label1 AS label WITH ;
        Caption = "选择第:", ;
        Height = 16, ;
        Left = 24, ;
        Top = 29, ;
        Width = 46, ;
        Name = "Label1"

    ADD OBJECT label2 AS label WITH ;
        Caption = "行", ;
        Height = 16, ;
        Left = 116, ;
        Top = 29, ;
        Width = 46, ;
        Name = "Label2"

    PROCEDURE init
    PUBLIC lnSendHwnd,hwnd
    ENDPROC

    PROCEDURE command1.Click
    #Define EM_SETSEL 0xb1
    #Define EM_LINEINDEX 0xbb
    #Define WM_SYSCOMMAND 0x112
    #Define SC_MAXIMIZE 0xF030
    TEXT TO prgprg noshow
2343432435
34454t4365t43
ddffergter
rwew阿德顺丰到付归属感
谁丰东股份23424递四方速递
23424535
水电费45235
3424
    ENDTEXT
    DECLARE Long FindWindowEx IN WIN32API Long, Long, String, String
    Declare Integer SendMessage In WIN32API as SendMessages Integer,Integer,Integer,String
    Declare Integer SendMessage In WIN32API as SendMessagen Integer,Integer,Integer,Integer
    Declare Integer SendMessageW In WIN32API as SendMsgWn Integer,Integer,Integer,Integer
    Declare Integer WinExec in kernel32 string, integer
    hWnd = FindWindowEx( 0, 0, "Notepad", NULL )
    if hwnd=0
        winexec("NOTEPAD.EXE",5)
        hWnd = FindWindowEx( 0, 0, "Notepad", NULL )
        SendMessages(m.Hwnd,WM_SYSCOMMAND,SC_MAXIMIZE,null)
        lnSendHwnd=FindWindowEx(m.hwnd,0,"Edit",Null)
        SendMessages(lnSendHwnd,12,0,prgprg)
    endif
    i=thisform.text1.value
    SendMsgWn(lnSendHwnd, EM_SETSEL ;
        , SendMsgWn(lnSendHwnd,EM_LINEINDEX,i-1,0) ;
        , SendMsgWn(lnSendHwnd,EM_LINEINDEX,i,0) )
    ENDPROC
ENDDEFINE
#3
csyx2024-11-12 17:48
我这正常,不管选择多少次,焦点切换到记事本加亮行都是最后选择的行
Win10(x64) 22H2 19045.5011
只有本站会员才能查看附件,请 登录


[此贴子已经被作者于2024-11-12 18:24编辑过]

#4
sych2024-11-12 18:28
用我上面发的代码,然后选择几次后,点击记事本标题栏试试,不要用原来的代码
#5
sych2024-11-12 18:35
原来的代码是每次都新建一个记事本,这次是如果有打开的笔记本直接引用,不再新建笔记本了
#6
csyx2024-11-12 18:48
用的就是二楼代码
#7
sych2024-11-12 18:51
好奇怪,我用win10试试
#8
sych2024-11-12 19:01
win10确实执行结果正常,我刚才发的是win7环境下,看来是win7下不正常
#9
sych2024-11-12 19:15
只有本站会员才能查看附件,请 登录
#10
sych2024-11-12 19:15
win7下有点不正常,win10测试正常


#11
sych2024-11-12 20:42
每次选中后用EM_GETSEL(&HB0=176)获取的也是新的位置,为什么点击标题获得焦点后就又回到了第一次的选择了
#12
凝聚双眼2024-11-13 09:17
win7下问题复现
#13
sych2024-11-13 10:09
加一句=SetForegroundWindow(hwnd),激活窗口至前端就好了
PUBLIC oform1
oform1=NEWOBJECT("form1")
oform1.Show
RETURN

DEFINE CLASS form1 AS form
    Height = 110
    Width = 193
    ShowWindow = 2
    DoCreate = .T.
    AutoCenter = .T.
    Caption = "Form1"
    AlwaysOnTop = .T.
    Name = "Form1"

    ADD OBJECT command1 AS commandbutton WITH ;
        Top = 60, ;
        Left = 68, ;
        Height = 25, ;
        Width = 60, ;
        Caption = "执行", ;
        Name = "Command1"


    ADD OBJECT text1 AS textbox WITH ;
        Alignment = 3, ;
        Value = 1, ;
        Height = 25, ;
        InputMask = "999", ;
        Left = 72, ;
        Top = 24, ;
        Width = 40, ;
        Name = "Text1"

    ADD OBJECT label1 AS label WITH ;
        Caption = "选择第:", ;
        Height = 16, ;
        Left = 24, ;
        Top = 29, ;
        Width = 46, ;
        Name = "Label1"

    ADD OBJECT label2 AS label WITH ;
        Caption = "行", ;
        Height = 16, ;
        Left = 116, ;
        Top = 29, ;
        Width = 46, ;
        Name = "Label2"

    PROCEDURE init
    PUBLIC lnSendHwnd,hwnd
    ENDPROC

    PROCEDURE command1.Click
    #Define EM_SETSEL 0xb1
    #Define EM_LINEINDEX 0xbb
    #Define WM_SYSCOMMAND 0x112
    #Define SC_MAXIMIZE 0xF030
    TEXT TO prgprg noshow
2343432435
34454t4365t43
ddffergter
rwew阿德顺丰到付归属感
谁丰东股份23424递四方速递
23424535
水电费45235
3424
    ENDTEXT
    DECLARE Long FindWindowEx IN WIN32API Long, Long, String, String
    Declare Integer SendMessage In WIN32API as SendMessages Integer,Integer,Integer,String
    Declare Integer SendMessage In WIN32API as SendMessagen Integer,Integer,Integer,Integer
    Declare Integer SendMessageW In WIN32API as SendMsgWn Integer,Integer,Integer,Integer
    Declare Integer WinExec in kernel32 string, integer
       Declare SetForegroundWindow in win32api long hwnd
    hWnd = FindWindowEx( 0, 0, "Notepad", NULL )
    if hwnd=0
        winexec("NOTEPAD.EXE",5)
        hWnd = FindWindowEx( 0, 0, "Notepad", NULL )
        SendMessages(m.Hwnd,WM_SYSCOMMAND,SC_MAXIMIZE,null)
        lnSendHwnd=FindWindowEx(m.hwnd,0,"Edit",Null)
        SendMessages(lnSendHwnd,12,0,prgprg)
    endif
      =SetForegroundWindow(hwnd)
    i=thisform.text1.value
    SendMsgWn(lnSendHwnd, EM_SETSEL ;
        , SendMsgWn(lnSendHwnd,EM_LINEINDEX,i-1,0) ;
        , SendMsgWn(lnSendHwnd,EM_LINEINDEX,i,0) )
    ENDPROC
ENDDEFINE
#14
sych2024-11-13 10:25
查看网上说SetForegroundWindow调用有时候会失败,给出的解决办法是:
if(hWnd)
{
            HWND hForeWnd = ::GetForegroundWindow();
            DWORD dwForeID = ::GetWindowThreadProcessId(hForeWnd,NULL);
            DWORD dwCurID = ::GetCurrentThreadId();
            ::AttachThreadInput(dwCurID,dwForeID,TRUE);
            ::ShowWindow(hWnd,SW_SHOWNORMAL);
            ::SetWindowPos(hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
            ::SetWindowPos(hWnd,HWND_NOTOPMOST,0,0,0,0, SWP_NOSIZE|SWP_NOMOVE);
            ::SetForegroundWindow(hWnd);
            ::AttachThreadInput(dwCurID,dwForeID,FALSE);
//hWnd就是需要置前的窗口句柄
}
#15
schtg2024-11-13 19:41
回复 13楼 sych
这下正常啦
#16
sych2024-11-13 20:07
回复 15楼 schtg
应该达到目的了,不知道把窗口调到前台这样操作会不会有安全隐患
#17
zhaoshaoye6 天前 17:13










































1