前几日看SendKeys语句的MSDN示例后想到一些问题,请各位大侠帮助一下,在此先谢谢大家了!
窗体名叫form1Option Explicit
Private Declare Function GetActiveWindow Lib "user32" () As Long
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 GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Sub Form_Load()End SubPrivate Sub Command1_Click()
Dim ReturnValue, I
ReturnValue = Shell("Calc.EXE", 1)   ' 运行计算器。 
AppActivate ReturnValue    ' 激活计算器。
Dim hw As Long
hw = GetActiveWindow()     '此处为我加的一语句, 
For I = 1 To 10   ' 设置计数循环。
   SendKeys I & "{+}", True   ' 按下按键给计算器
Next I   ' 将所有 I 值相加。
SendKeys "=", True   ' 取得总合。
hw = FindWindow(vbNullString, "计算器")
hw = FindWindowEx(hw, 0, "edit", vbNullString)
Dim te As String
Dim l As Long
GetWindowText hw, te, l
MsgBox teEnd Sub
________________________________________________
问题1
关于shell函数的MSDN上说的如下
   注意 缺省情况下,Shell 函数是以异步方式来执行其它程序的。也就是说,用 Shell 启动的程序可能还没有完成执行过程,就已经执行到 Shell 函数之后的语句。
哪什么时候Shell 函数是以同步方式来执行其它程序的,该如何设置?问题2
关于AppActivate函数的MSDN上说的如下
   AppActivate 语句将焦点移动到命名的应用程序或窗口,但并不影响焦点是否最大化或最小化
   可我用GetActiveWindow得到的句柄为调用计算器的应用程序窗口(即为Form1窗口句柄),照理说应为
   计算器的窗口句柄呀!因为此时它是具有焦点的窗口,否则Sendkeys发送的字符就不会送到活动窗口(计算器的窗口中)
   可为什么用GetActiveWindow得到的句柄为调用计算器的应用程序窗口(即为Form1窗口句柄)?
 
问题3
    通过Findwindow和FindwindowEx找到计算器的输入窗口句柄,可用GetWindowText得到的字符串是空的
为什么不是结果值?  有什么方法得到结果值(即不知道运算式子,我想得到计算器输入窗口中某一时刻的数据)?问题4
    知道一个窗口的PID即shell函数的返回值ReturnValue,能否用一个函数直接得到该窗口的句柄?
    如有是何函数?
 

解决方案 »

  1.   

    问题1与 http://community.csdn.net/Expert/topic/4661/4661621.xml?temp=.9562647

    问一下shell函数如何才能同步执行?即直到压缩文件完成后,再执行shell下面的代码。大家帮忙啦! 问题相同,难道没人帮忙解答吗?还是大家都在忙活?
      

  2.   

    希望某一 VB 程序利用 Shell 执行某一个外部程序(假设是 notepad.exe)之后,就一直等到此一程序结束执行时, 才回到 VB 程序继续执行, 该怎么办到呢?当我们调用 Shell 时, 会传回一个数值, 此一数值称为 Process Id, 利用此一 Process Id, 我们可以调用 OpenProcess API 取得 Process Handle, 然后再利用 Process Handle 调用 WaitForSingleObject, 即可等待被 Shell 执行的程序执行完毕, 才继续向下执行。细节如下:1. API 的声明:Const SYNCHRONIZE = &H100000
    Const INFINITE = &HFFFFFFFF
    Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long注:如果以上的声明放在「一般模块」底下, 应将 Declare 之前的 Private 保留字去掉, 并且在 Const 之前加上 Public 保留字。2. 程序范例:(以执行 Notepad 程序为例)Dim pId As Long, pHnd As Long ' 分别声明 Process Id 及 Process Handle 变数pId = Shell("Notepad", vbNormalFocus) ' Shell 传回 Process IdpHnd = OpenProcess(SYNCHRONIZE, 0, pId) ' 取得 Process Handle
    If pHnd <> 0 Then
        Call WaitForSingleObject(pHnd, INFINITE) ' 无限等待,直到程序结束
        Call CloseHandle(pHnd)
    End If
      

  3.   

    GetWindowText得到的字符串是空的
    为什么不是结果值? 
    -----------------------------------
    MSDN: GetWindowText cannot retrieve the text of a control in another application
    GetWindowText不能获得外部程序控件的Text,改为用SendMessage发送WM_GETTEXT
      

  4.   

    问题4
        知道一个窗口的PID即shell函数的返回值ReturnValue,能否用一个函数直接得到该窗口的句柄?
        如有是何函数?不能。它返回的是进程的 ID,与窗口句柄不相关。
      

  5.   

    在此先谢谢 faysky2(出来混,迟早是要还嘀)和of123()两位大侠, 
    对于问题2就没人回答了吗??? 解答完问题2后就结贴!!!
      

  6.   

    hw = FindWindowEx(hw, 0, "edit", vbNullString)
    家中的系统是Xp的所以能找到,但换成2000后由于它的输入窗口是Static类(用Spy++
    看过)找到的为hyp旁边的那个灰色方框(在FindWindowEx中用static代替edit后),那如何在2000中得到该输入窗口句柄呢??
      

  7.   

    将最后一个参数由""改为vbnullstring就可得到窗口句柄,但是用WM_GETTEXT消息还是得不到结果值,问题2和问题3还是没有解决???那位大侠可以帮帮忙!!!!!