在VB程序中用下列代码调用系统中的计算器程序进行运算,可怎么得到那个计算后的结果呢?代码:    Option Explicit    Private Sub Form_Load()        Dim ReturnValue, I        ReturnValue = Shell("CALC.EXE", 1) ' 运行计算器
        AppActivate ReturnValue ' 激活计算器        For I = 1 To 100 ' 设置计数循环
            SendKeys I & "{+}", True ' 按下按键给计算器            ' 这里怎样取得计算器(或屏幕上)显示的每次(动态)结果?        Next I ' 将所有 I 值相加        SendKeys "=", True ' 取得总和        ' 这里怎样取得计算器(或屏幕上)显示的最终(静态)结果?        SendKeys "%{F4}", True ' 按 ALT+F4 关闭计算器    End Sub分不多(我的全部分了),权作学习。

解决方案 »

  1.   


    感觉在自己的程序里是可以通过textbox找到计算结果的,毕竟这个每次运算的结果,是在自己的程序里用循环语句控制着但是,如果当1楼的程序完成后,在其运行过程中,由其他程序来读取这个计算器的文本框里的“动/静态数据”时,用什么方法可以实现呢?就是如何用程序获取 其他EXE程序 在屏幕上显示的“动/静态数据”?貌似“屏幕取词”吧,呵呵高手快来呀
      

  2.   

    没必要用屏幕取词那么复杂的技术吧,先用sp++找到计算器输出框的句柄,然后再用findwindow等api直接获取txt值啊!我去试试看!
      

  3.   

    用FindWindows取得那个结果文本框的句柄,然后取得它的内容
      

  4.   

    http://topic.csdn.net/t/20020403/17/620315.html
      

  5.   

    郁闷,说了发送ctrl+c竟然没人有反应,其实那个calc每次操作焦点都会自动聚焦在结果框上的,所以只要其是活动窗口就可以一些基本的快捷键操作,比如复制粘贴等,可能就是为了给其他程序使用的。    Private Sub Form_Load()        Dim ReturnValue, I        ReturnValue = Shell("CALC.EXE", 1) ' ?s?ŽZŠí
            AppActivate ReturnValue ' ŒƒŠˆ?ŽZŠí        For I = 1 To 30 ' ?’u?”z?
                SendKeys I & "{+}", True ' ˆÂ‰ºˆÂ???ŽZŠí            ' ?—¢œƒ?Žæ“¾?ŽZŠíiˆ½› –‹ãj?Ž¦“I?ŽŸi??j?‰ÊH        Next I ' «Š—L I ?‘Š‰Á        SendKeys "=", True ' Žæ“¾?˜a        ' ?—¢œƒ?Žæ“¾?ŽZŠíiˆ½› –‹ãj?Ž¦“IÅ?iÃ?j?‰ÊH
            
            SendKeys "^C", True ' ˆÂ ALT+F4 ???ŽZŠí
            SendKeys "%{F4}", True ' ˆÂ ALT+F4 ???ŽZŠí
            
            Text1.Text = Clipboard.GetText
        End Sub
      

  6.   

    我感觉屏幕取词应该不是这么简单的,比如vb的lable是没有句柄的,用findwindow就获取不来,而金山词霸屏幕取词却没有问题!
      

  7.   


    这个程序(下称程序A)到这里就可以算完成了一半。要是再写一个程序B,在这个程序A运行的时候,毫无遗漏地获取计数器里的每一次动态运算结果该这么办?
      

  8.   

    用api实现,调用GetResult()就行。用timer定时取数据吧!Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long
    Private Const WM_GETTEXT = &HD
    Private Const WM_GETTEXTLENGTH = &HEPrivate Function GetResult() As String
        Dim hWndParent As Long
        Dim hWndChild As Long
        Dim strText As String
        Dim lngLen As Long    hWndParent = FindWindow("SciCalc", vbNullString)
        hWndChild = FindWindowEx(hWndParent, 0, "Edit", vbNullString)
        
        lngLen = SendMessage(hWndChild, WM_GETTEXTLENGTH, ByVal 0&, ByVal 0&)    strText = Space$(lngLen)
        SendMessage hWndChild, WM_GETTEXT, ByVal lngLen, strText
        If strText <> "" Then GetResult = Left(strText, lngLen - 1)
    End Function'//Timer 的 Interval设成10ms,这样每隔10ms自动取数据
    Private Sub timAuto_Timer()
        txtResult.Text = GetResult()
    End Sub
      

  9.   

    你用模拟按键显然只能运行一个了,即时不是取结果,你光上面的1+2+3的这些也完成不了。你要那样的话只有对每个句柄操作了,要按某个键都通过发送消息,这样显然相当复杂,建议你用au3,操作这些很方便。如果你实在要用vb实现的话也行,不过够你受的了,以前我写过一个类,基本可以达到,对指定类,指定第几个,设置其capition,取其caption,有点类似于,dhtml里面的getElementsByName之类的
      

  10.   

    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As LongPrivate Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As LongPrivate Const WM_GETTEXT = &HD
    Private Function Getsum() As Long
       Dim tempstr As String, strlong As Long, rtn As Long
    Dim winHwnd As Long
         Dim RetVal As Long
         winHwnd = FindWindow(vbNullString, "计算器")
         If winHwnd <> 0 Then
         winHwnd1& = FindWindowEx(winHwnd&, 0&, "Edit", vbNullString)
        
         tempstr = Space(200)
        strlong = Len(tempstr)
        rtn = SendMessage(winHwnd1, WM_GETTEXT, strlong + 1, tempstr)
        tempstr = Trim(tempstr)
      Getsum = tempstr
       
         Else
             MsgBox "计算器程序没有运行?"
         End If
     
    End FunctionPrivate Sub Form_Load()
     Dim ReturnValue, I
    ReturnValue = Shell("CALC.EXE", 1) ' 运行计算器
            AppActivate ReturnValue ' 激活计算器
    For I = 1 To 100 ' 设置计数循环
                SendKeys I & "{+}", True ' 按下按键给计算器
    Debug.Print Getsum
    Next I ' 将所有 I 值相加MsgBox Getsum
    End Sub
      

  11.   

    感谢 SYSSZ 的程序!完成得真好!代码复制如下: Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As LongPrivate Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As LongPrivate Const WM_GETTEXT = &HD
    Private Function Getsum() As Long
       Dim tempstr As String, strlong As Long, rtn As Long
    Dim winHwnd As Long
         Dim RetVal As Long
         winHwnd = FindWindow(vbNullString, "计算器")
         If winHwnd <> 0 Then
         winHwnd1& = FindWindowEx(winHwnd&, 0&, "Edit", vbNullString)
        
         tempstr = Space(200)
        strlong = Len(tempstr)
        rtn = SendMessage(winHwnd1, WM_GETTEXT, strlong + 1, tempstr)
        tempstr = Trim(tempstr)
      Getsum = tempstr
       
         Else
             MsgBox "计算器程序没有运行?"
         End If
     
    End FunctionPrivate Sub Form_Load()
     Dim ReturnValue, I
    ReturnValue = Shell("CALC.EXE", 1) ' 运行计算器
            AppActivate ReturnValue ' 激活计算器
    For I = 1 To 100 ' 设置计数循环
                SendKeys I & "{+}", True ' 按下按键给计算器
    Debug.Print Getsum
    Next I ' 将所有 I 值相加MsgBox Getsum
    End Sub
      

  12.   

    上面的代码可以读取具备text句柄的文本框内容,中间的每次运算结果也可以进行存储、显示。所以本贴任务完成,可以结贴了。再次感谢SYSSZ老张的指导以及大家的帮助!
    我还想另外开贴,继续寻求下面的帮助:A程序是一商业股票软件,其界面上动态地显示着曲线图和与曲线图对应的数值型数据,用Spy++只能发现窗体的句柄,却无法找到曲线框(PictureBox控件)的句柄 和 动态显示的数值数据(Label/TextBox/其他?)的句柄,用屏幕取词程序也无法识别出那些存在于屏幕特定位置的动态数值型数据(无任何显示),估计这个A程序是在内存DC绘好曲线图形并且在内存DC的指定位置(曲线旁)写好数值后再复制到屏幕DC进行显示的。现在需要另外编写一段代码,将屏幕上面A程序动态显示的数值实时复制下来,这段功能代码该怎样编写?备注:1 这些动态显示的数值型数据是由若干个数组构成的,其在内存中连续存放,并且新数据内容将覆盖掉前一数据内容。2 通过搜索A程序的内存区域,是可以找到这些动态变化的数值的。利用Timer控件不断地查询指定内存区域时,也可以发现并实时复制出最新数据到文本。但是只能通过自己的眼睛来判断数据的正确性。3 现在的要求是要获取其他EXE应用程序 在 屏幕上显示的内容(虽然在内存中是以数值型数据存在,但貌似是以图形方式显示于窗体界面上?致使屏幕取词程序都无法识别这些数值?)4 目的是为了实时验证这些在内存中获取到的数据的正确性,以解除用眼睛进行比对时的疲劳与痛苦。如果有其他方法可以实时地准确地获取到这些数值内容本人将不胜感谢!5 另外求助一种方法:当特定的内存地址中的数据发生改变时,我的程序可以得到这个消息。
      

  13.   

    上面的问题地址:
    http://topic.csdn.net/u/20090724/18/56a0e2a5-6fa2-4737-8916-a3d0e251399d.html?9829