在VB程序中调用系统计算器,怎么得到那个计算后的结果?

qq52016000 2009-07-24 08:04:20
在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



分不多(我的全部分了),权作学习。
...全文
811 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
Tiger_Zhao 2009-07-24
  • 打赏
  • 举报
回复
同意 Ctrl+C
SYSSZ 2009-07-24
  • 打赏
  • 举报
回复
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 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 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 Function

Private 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
无·法 2009-07-24
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 qq52016000 的回复:]
引用 9 楼 sysdzw 的回复:
郁闷,说了发送ctrl+c竟然没人有反应,其实那个calc每次操作焦点都会自动聚焦在结果框上的,所以只要其是活动窗口就可以一些基本的快捷键操作,比如复制粘贴等,可能就是为了给其他程序使用的。

VB codePrivateSub Form_Load()Dim ReturnValue, I

        ReturnValue= Shell("CALC.EXE",1)' ?s?ŽZŠí        AppActivate ReturnValue' ŒƒŠˆ?ŽZŠíFor I=1To30' ?’u?”z?            SendKeys I&"{+}",True' ˆÂ‰ºˆÂ???ŽZŠí' ?—¢œƒ?Žæ“¾?ŽZŠíiˆ½› –‹ãj?Ž¦“I?ŽŸi??j?‰ÊHNext 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.GetTextEnd Sub


这个程序(下称程序A)到这里就可以算完成了一半。

要是再写一个程序B,在这个程序A运行的时候,毫无遗漏地获取计数器里的每一次动态运算结果该这么办?

[/Quote]
你用模拟按键显然只能运行一个了,即时不是取结果,你光上面的1+2+3的这些也完成不了。

你要那样的话只有对每个句柄操作了,要按某个键都通过发送消息,这样显然相当复杂,建议你用au3,操作这些很方便。

如果你实在要用vb实现的话也行,不过够你受的了,以前我写过一个类,基本可以达到,对指定类,指定第几个,设置其capition,取其caption,有点类似于,dhtml里面的getElementsByName之类的
打死不掉牙 2009-07-24
  • 打赏
  • 举报
回复
用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 = &HE

Private 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
qq52016000 2009-07-24
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 sysdzw 的回复:]
郁闷,说了发送ctrl+c竟然没人有反应,其实那个calc每次操作焦点都会自动聚焦在结果框上的,所以只要其是活动窗口就可以一些基本的快捷键操作,比如复制粘贴等,可能就是为了给其他程序使用的。

VB codePrivateSub Form_Load()Dim ReturnValue, I

ReturnValue= Shell("CALC.EXE",1)' ?s?ŽZŠí AppActivate ReturnValue' ŒƒŠˆ?ŽZŠíFor I=1To30' ?’u?”z? SendKeys I&"{+}",True' ˆÂ‰ºˆÂ???ŽZŠí' ?—¢œƒ?Žæ“¾?ŽZŠíiˆ½› –‹ãj?Ž¦“I?ŽŸi??j?‰ÊHNext 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.GetTextEnd Sub
[/Quote]

这个程序(下称程序A)到这里就可以算完成了一半。

要是再写一个程序B,在这个程序A运行的时候,毫无遗漏地获取计数器里的每一次动态运算结果该这么办?
qq52016000 2009-07-24
  • 打赏
  • 举报
回复
是呀,1楼的程序只是个引子,让大家明白是什么问题。。。咱步步深入!

1 当有句柄的控件要实现这个功能时,要完全不遗漏地获取那个快速变化的“动态数据”,该怎样实现?

2 假如用sp++找不到控件的句柄时,又该怎样获取其他程序在屏幕上动态显示的数据?

感兴趣的话,一起学习,一起期待解决方案。
打死不掉牙 2009-07-24
  • 打赏
  • 举报
回复
我感觉屏幕取词应该不是这么简单的,比如vb的lable是没有句柄的,用findwindow就获取不来,而金山词霸屏幕取词却没有问题!
无·法 2009-07-24
  • 打赏
  • 举报
回复
郁闷,说了发送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
dingyanwei 2009-07-24
  • 打赏
  • 举报
回复
http://topic.csdn.net/t/20020403/17/620315.html
dingyanwei 2009-07-24
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 sulipeng007 的回复:]
没必要用屏幕取词那么复杂的技术吧,先用sp++找到计算器输出框的句柄,然后再用findwindow等api直接获取txt值啊!我去试试看!
[/Quote]

好像屏幕取词就是这个原理吧。
贝隆 2009-07-24
  • 打赏
  • 举报
回复
用FindWindows取得那个结果文本框的句柄,然后取得它的内容
打死不掉牙 2009-07-24
  • 打赏
  • 举报
回复
没必要用屏幕取词那么复杂的技术吧,先用sp++找到计算器输出框的句柄,然后再用findwindow等api直接获取txt值啊!我去试试看!
qq52016000 2009-07-24
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 alifriend 的回复:]
用findwindow找那个textbox
[/Quote]

感觉在自己的程序里是可以通过textbox找到计算结果的,毕竟这个每次运算的结果,是在自己的程序里用循环语句控制着。。。

但是,如果当1楼的程序完成后,在其运行过程中,由其他程序来读取这个计算器的文本框里的“动/静态数据”时,用什么方法可以实现呢?

就是如何用程序获取 其他EXE程序 在屏幕上显示的“动/静态数据”?

貌似“屏幕取词”吧,呵呵高手快来呀
qq52016000 2009-07-24
  • 打赏
  • 举报
回复
看起来要学习屏幕取词技术哦。。。
不知谁有vb的示例代码?
无·法 2009-07-24
  • 打赏
  • 举报
回复
发送ctrl+c
波导终结者 2009-07-24
  • 打赏
  • 举报
回复
用findwindow找那个textbox
qq52016000 2009-07-24
  • 打赏
  • 举报
回复
上面的代码可以读取具备text句柄的文本框内容,中间的每次运算结果也可以进行存储、显示。

所以本贴任务完成,可以结贴了。

再次感谢SYSSZ老张的指导以及大家的帮助!


我还想另外开贴,继续寻求下面的帮助:

A程序是一商业股票软件,其界面上动态地显示着曲线图和与曲线图对应的数值型数据,用Spy++只能发现窗体的句柄,却无法找到曲线框(PictureBox控件)的句柄 和 动态显示的数值数据(Label/TextBox/其他?)的句柄,用屏幕取词程序也无法识别出那些存在于屏幕特定位置的动态数值型数据(无任何显示),估计这个A程序是在内存DC绘好曲线图形并且在内存DC的指定位置(曲线旁)写好数值后再复制到屏幕DC进行显示的。

现在需要另外编写一段代码,将屏幕上面A程序动态显示的数值实时复制下来,这段功能代码该怎样编写?

备注:

1 这些动态显示的数值型数据是由若干个数组构成的,其在内存中连续存放,并且新数据内容将覆盖掉前一数据内容。

2 通过搜索A程序的内存区域,是可以找到这些动态变化的数值的。利用Timer控件不断地查询指定内存区域时,也可以发现并实时复制出最新数据到文本。但是只能通过自己的眼睛来判断数据的正确性。

3 现在的要求是要获取其他EXE应用程序 在 屏幕上显示的内容(虽然在内存中是以数值型数据存在,但貌似是以图形方式显示于窗体界面上?致使屏幕取词程序都无法识别这些数值?)

4 目的是为了实时验证这些在内存中获取到的数据的正确性,以解除用眼睛进行比对时的疲劳与痛苦。如果有其他方法可以实时地准确地获取到这些数值内容本人将不胜感谢!

5 另外求助一种方法:当特定的内存地址中的数据发生改变时,我的程序可以得到这个消息。
qq52016000 2009-07-24
  • 打赏
  • 举报
回复
感谢 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 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 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 Function

Private 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
落叶高精度表达式计算V1.0(32位)版 本计算程序是在win7 32位系统上,使用VB6.0开发的,本程序的主要特点是: 1) 高精度,支持万位精度的有理数常用运算; 包括:加,减,乘,除,乘方,开N次方,三角函数,反三角函数,双曲三角函数,反双曲三角函数等。 2) 表达式运算,本程序没有采用常用计算的边输入边计算,而是输入完所有数据或算式后,解析表达式,分解运算符和数据,最后在运算出结果。 点击程序界面上的等于按钮,计算开始运算。 3) 本计算的各种运算函数大都是自已所写,没有调用大数库或其它数学库,仅大数开平方调用GMP大数库。 本计算的各种子函数是通过定义的一个高精度数据结构接收和返回运算结果,这个高精度数据结构可以定义有符号(整数,小数,科学计数法表示的数), 函数内部集对数值,小数点位置,指数进行运算,优点是调用简单,不易出错,可以说比较完善,综合运算能力强。 这点和大数库的实现不同, 大数库大都只提供对整数的运算,假如要对有理数运算, 一:你需要很多的调用前和调用后处理工作,这些工作并不需要很高的知识,但却需要很长时间的调试,它并不会因为你的水平很高而获得很大的时间提升。 二:很难进行综合运算。当你把某一个函数调顺后,进行综合运算时,会出现很多新的问题。 高精度数据结构VB定义为: Type StrToZx '高精度数的结构头 ZhFhBz As Boolean '正负号标志 XsdWz As Long '小数点右边数字的长度。例1234.567这个数是3(为什么要这样定义,因为大多的基本运算都是右对齐的,这样定义减少了间一些不必要的转换) JzBz As Integer '标记数组存的是什么进制的数(十进制或其它进制数) strlen As Long '运算数长度 Zx() As Long '存放运算数的数组 eE As Long '存放指数 End Type 4)综合运算,里面的三角函数,用户界面的算式,表达式运算,都是综合运算的体现,综合运算是大量基础运算的集合,间稍有差错,就会算不出正确答案,里面内容繁琐,这里简单介绍一下。 5)本程序从2015年11月开始试编写,至2016年8月大致完成,开发周期很长,间代码写了一两万行,从零基础到运行效率,综合效率的初等水平,主要目的是练习编程,老外的数学软件已很强大,是我不可能相比的,我觉得我的程序如果把程序源码作为大数实例初级学习更合适。 6)程序函数都具有输入值较验功能,若输入错误,会弹出提示窗口提示那一个函数输入错误。 7)由于本人是初次编程练习,且自身知识的不足,加上精力有限,最后的测试收尾也只是简单测试,里面肯定存在很大的不足和没发现的BUG,请网友们在论坛,或 我的邮箱:wtbzhy@126.com, 微博:qq_34030789,指正,交流。 我若纠错后,会在下载网站更新,并根据您的地址发一份给您,谢谢! 再次欢迎大家使用本计算,本计算具有很好的表达式解析功能,会在以后的使用获得很好的用户体验!

7,763

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧