在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



分不多(我的全部分了),权作学习。
...全文
884 19 打赏 收藏 转发到动态 举报
AI 作业
写回复
用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

7,785

社区成员

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

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