1,VB中,知道了一个窗体的句柄,如何得到这个程序的程序名? 
2,知道了一个窗体的其中一个控件的句柄,如何得到这个窗体的句柄? 
3,一个窗体可能会有很控件,例如Text1 Text2,这些文本框有没有什么标志来区分?
   本来想用句柄,但下次启动后,句柄都变化了,还是没法区分这两个控件?求教高手!

解决方案 »

  1.   

    1,VB中,知道了一个窗体的句柄,如何得到这个程序的程序名?
    用GetWindowText\GetWindowTextLength 得到程序名
    2,知道了一个窗体的其中一个控件的句柄,如何得到这个窗体的句柄? 
    用GetParent得到其父窗体的句柄,如果有多级窗体可以多次使用GetParent
    3,一个窗体可能会有很控件,例如Text1 Text2,这些文本框有没有什么标志来区分?
       本来想用句柄,但下次启动后,句柄都变化了,还是没法区分这两个控件?
    看你的Text1 Text2有什么特征,试试FindWindow。
      

  2.   

    1,第一种情况,有的程序运行时GetWindowText是会变化的,就像写字板一样,其实我想得到的是程序名,如notePad.exe.
    2,如不知有多少级,怎样才知GetParent多少次咧?
    3,不知如何解?
      

  3.   

    1.
    Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
    Private Declare Function CloseHandle Lib "Kernel32.dll" (ByVal Handle As Long) As Long
    Private Declare Function OpenProcess Lib "Kernel32.dll" (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long
    Private Declare Function GetModuleFileNameExA Lib "psapi.dll" (ByVal hProcess As Long, ByVal hModule As Long, ByVal ModuleName As String, ByVal nSize As Long) As Long
    Private Declare Function EnumProcessModules Lib "psapi.dll" (ByVal hProcess As Long, ByRef lphModule As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long
       
    Private Const PROCESS_QUERY_INFORMATION = 1024
    Private Const PROCESS_VM_READ = 16
    Private Const MAX_PATH = 260
       
    Public Function GetPath(ByVal hWnd As Long) As String
           Dim hProcess   As Long
           Dim ProcID   As Long
           Dim mModules(1 To 200)     As Long
           Dim cbNeed   As Long
           Dim ModuleName   As String
           Dim nSize   As Long
           Dim lRet   As Long
     
           GetWindowThreadProcessId hWnd, ProcID
           hProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, 0, ProcID)
           lRet = EnumProcessModules(hProcess, mModules(1), 200, cbNeed)
           If lRet <> 0 Then
                   ModuleName = Space(MAX_PATH)
                   nSize = 500
                   lRet = GetModuleFileNameExA(hProcess, mModules(1), ModuleName, nSize)
                   GetPath = Left(ModuleName, lRet)
           End If
           lRet = CloseHandle(hProcess)
    End FunctionPrivate Sub Command1_Click()
    dim myhwnd as long
    myhwnd=123456'句柄
    MsgBox GetPath(myhwnd)
    End Sub
    2.
    用回调.
    用GetParent获得句柄,再用GetClassName获得这个句柄的类名.判断如果有form字样的就是窗体.
    3.
    没有
      

  4.   

    3. 内部可以用Tag区分。外部就没有什么好办法了。
      

  5.   

    //一个窗体可能会有很控件,例如Text1 Text2,这些文本框有没有什么标志来区分?
       本来想用句柄,但下次启动后,句柄都变化了,还是没法区分这两个控件?这些控件的control id(如果有的话)应该是固定的
      

  6.   

    1. 获得ProcessID以后,在快照列表里面查
       需要的API: GetWindowThreadProcessID, CreateToolHelp32Snapshot,Process32First,Process32Next。tztz520的方法更直接2. 不断地获得父窗体。当然,什么东西算是一个窗体不是很好判断。一般父窗体是桌面的,就是顶级窗体了。
       需要的API:GetWindow或者GetParent3. 如果是对话框,尝试获取控件ID。ID是不变的(否则这个程序就没法编了)
       需要的API:GetDlgCtrlID,GetDlgItem,GetDlgItemText
      

  7.   

    http://basic.nease.net/MyExe/EnumWnd.zip
      

  8.   

    3.两个Text没有重合吧,嘿嘿,判断其位置就oK了
      

  9.   

    //2,知道了一个窗体的其中一个控件的句柄,如何得到这个窗体的句柄?
    //   如不知有多少级,怎样才知GetParent多少次咧?窗体句柄 = GetAncestor( 控件句柄 , GA_ROOT )
      

  10.   

    3,一个窗体可能会有很控件,例如Text1 Text2,这些文本框有没有什么标志来区分?
       本来想用句柄,但下次启动后,句柄都变化了,还是没法区分这两个控件?text的类名应该都是'Edit'
      

  11.   

    如此说来,楼上的都是:"非高手不"了!!呵呵~
    楼不在高,有分则接第三个问题的话,据说用getdialogitem就行了!不过没用过,不敢乱吹
      

  12.   

    //回复人: sakurako(DearDream)//3.两个Text没有重合吧,嘿嘿,判断其位置就oK了这位朋友已经回答得很清楚了!
      

  13.   

    Option ExplicitPrivate Const GWL_ID = (-12)Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As LongPrivate Sub Command1_Click()
        MsgBox GetWindowLong(Text1.hwnd, GWL_ID)
        MsgBox GetWindowLong(Text2.hwnd, GWL_ID)
    End Sub不管两个Text有没有重合,控件ID(Control ID)是不变的关于句柄的终极问题的终极答案
      

  14.   

    //回复人: sakurako(DearDream)//3.两个Text没有重合吧,嘿嘿,判断其位置就oK了两个控件没重合,但是有时控件的位置会改变的情况怎么办呢?============================
    Hassle: GetWindowLong() ID 确实不会变,但是当程序关闭后重新运行时, ID就又变了,这样上次记录的ID还有什么意义咧? 终极问题还是没有找到终极答案啊!
      

  15.   

    记得还有强人做自动按下(未注册版)winzip继续执行按钮的程序时,是通过取按钮上的图片来区分不同控件的。
      

  16.   

    To Hassle :
         请问怎样 “一般情况下,可以装钩子记录加载顺序确定”?
      

  17.   

    GetWindowLong() ID 确实不会变,但是当程序关闭后重新运行时, ID就又变了,这样上次记录的ID还有什么意义咧? 
    ==========================
    一般来说,已经编译成为exe文件的程序,里面控件的id都不会改变....测试:
    程序1:
    在窗体中按顺序添加:text1、text2、command1、text3、picture1
    '模块中:
    Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
    Public Const GWL_ID = (-12)'程序:
    Private Sub Command1_Click()
    Text1.Text = CStr(Text1.hwnd) + " " + CStr(GetWindowLong(Text1.hwnd, GWL_ID))
    Text2.Text = CStr(Text2.hwnd) + " " + CStr(GetWindowLong(Text2.hwnd, GWL_ID))
    Text3.Text = CStr(Text3.hwnd) + " " + CStr(GetWindowLong(Text3.hwnd, GWL_ID))
    Command1.Caption = CStr(Command1.hwnd) + " " + CStr(GetWindowLong(Command1.hwnd, GWL_ID))
    Print CStr(Picture1.hwnd) + " " + CStr(GetWindowLong(Picture1.hwnd, GWL_ID))
    End Sub把它编译成exe文件程序2:
    在窗体中添加text1、command1
    '模块:
    Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
    Public Const GWL_ID = (-12)'程序:
    Private Sub Command1_Click()
    Dim id As Long
    id = GetWindowLong(CLng(Text1.Text), GWL_ID)
    Print id
    End Sub也编译成exe文件运行两个exe,按第一个exe的command1,会显示各个控件的句柄和其id,把随便一个看到的句柄填到第二个exe的text1,按第二个exe的command,也可得到那个控件的id。再试试把两个程序关闭再运行,对应控件的id没有改变。
    要改变控件的id,就要改变添加控件的顺序(这里不讨论用wm_create之类方法添加的控件)。。试试在第一个exe的ide中,把command1删除,然后又添加一个command1运行程序,按command1,看看那些控件的id是不是跟刚才有些不同了????
    一般来说,id越大,控件越早添加,id越小,控件越迟添加
      

  18.   

    记得还有强人做自动按下(未注册版)winzip继续执行按钮的程序时,是通过取按钮上的图片来区分不同控件的。
    ================
    那是用汇编做的。
    不过要做到这个要求用vb应该也可以。
      

  19.   

    Public Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As LongidHook取WH_CBTlpfn是CBTProc回调函数的地址CBTProc的传过来的参数nCode=HCBT_CREATEWND时记录有用的东东一般在dll里完成所有的活,VB调用一下说一般情况原因是do
    if ... then exit do
    取随机数i
    select case i
    case 1
    if ... then 
    createwindow...
    ...
    endif
    case 2
    if ... then 
    createwindow...
    ...
    endif
    ...
    end select
    loop如果没有特别的理由没谁会这么写吧,哈哈!
      

  20.   

    T0 lsftest:
       你所说的GetWindowLong() ID 的方法对VB生成的EXE文件确实有效,但对VC, C++ Bulider 等生成的EXE 就不起作用了,GetWindowLong得到的就是控件本身的句柄了。
       请问这个如何解决?
       另,反过来,知道了一个控件的ID,怎样得到这个控件的句柄咧?
      

  21.   

    T0 lsftest:
       你所说的GetWindowLong() ID 的方法对VB生成的EXE文件确实有效,但对VC, C++ Bulider 等生成的EXE 就不起作用了,GetWindowLong得到的就是控件本身的句柄了。
    ====================
    不会吧是不是系统有问题?????我的是xp sp2+vb6 sp5
    为了测试你的说法,我从URL http://www.hktk.com:8080/cgi-bin/dl.pl?url=ftp://ftp.cq.hktk.com/soft/soft_photo/vccolor.zip
    下载了一个用vc写的取屏幕颜色的小程序,然后用myspy得到里面的几个控件的句柄在把句柄填到我上面那个程序2的textbox中,点击按钮,可以得到结果左边那个edit框id为1007,中间那个是1001,右边那个是1002。那个颜色框是1006退出那个小程序后再重来反复三次。。都是一样的结果。
    对于你的问题,我估计是由于你所说的那些控件是动态加载生成的,而且加载的顺序并不确定导致控件的id也会不同。。
      

  22.   

    To lsftest:
       呵,我的系统应该没问题,xp sp1+vb6 sp5
       我把 url=ftp://ftp.cq.hktk.com/soft/soft_photo/vccolor.zip的下载下来试了一下,确实和你说的一样,不会变化,但是我用网上其它的试了一下,确实和我说的一样,得到的是控件的句柄.
    我试的程序是网上的一下串口程序SSCOM3.2 下载地址为 http://www.mcu51.com/download/sscom.rar
    另,我自己写了一个C++ Builder的程序,结果也是一样(控件不是动态加载生成的)
       lsftest 可否确认一下,是怎么回事?
      

  23.   

    修正一下:
       SSCOM3.2不是用VC写的,我用VC写了一个,可以用
       但 C++ Builder 和Delphi写的(非 Microsoft语言)好像就行不通了!
      

  24.   

    那个sscom3.2是用delphi写的你上面那个连接已失效,我在http://soft.laogu.com:20038/download/sscom30.rar下了一个。
    测试结果如你所说,只返回了句柄,用GetDlgCtrlID的结果也一样想来是编译的机理跟微软的不同吧
    现在我能想到的方法就剩下两个:
    1.试试用EnumWindows,EnumChildWindows巡行sscom3.2窗体里的所有控件,并把巡行的结果记录下来,多做几次看某个特定的控件在结果中出现的次序是否固定的。。如果是固定的,那么以后要使用的时候就巡行到那个次序直接读hwnd就是了不过这种方法我也没有测试过
    2.如果上面的方法都不行,那么只有如你上面所说的:“我自己倒想了一个解决方法,就是用控件在窗体中的位置来记录这个控件”了。
    另附sscom3.2的各个文本框的一些属性:
    object T1: TEdit
              Left = 16
              Top = 16
              Width = 169
              Height = 20
              TabOrder = 1
              Text = '12 00 FF 88'
            end
            object T2: TEdit
              Left = 16
              Top = 32
              Width = 169
              Height = 20
              TabOrder = 2
              Text = 'output string'
            end
    object T3: TEdit
              Left = 16
              Top = 48
              Width = 169
              Height = 20
              TabOrder = 4
            end
    object T4: TEdit
              Left = 16
              Top = 64
              Width = 169
              Height = 20
              TabOrder = 9
            end
            object T5: TEdit
              Left = 16
              Top = 80
              Width = 169
              Height = 20
              TabOrder = 10
            end
            object T6: TEdit
              Left = 16
              Top = 96
              Width = 169
              Height = 20
              TabOrder = 11
            end
            object T7: TEdit
              Left = 16
              Top = 112
              Width = 169
              Height = 20
              TabOrder = 12
            end
            object T8: TEdit
              Left = 16
              Top = 128
              Width = 169
              Height = 20
              TabOrder = 13
            end
            object T9: TEdit
              Left = 16
              Top = 144
              Width = 169
              Height = 20
              TabOrder = 14
            end
            object T10: TEdit
              Left = 16
              Top = 160
              Width = 169
              Height = 20
              TabOrder = 15
            end
            object T11: TEdit
              Left = 16
              Top = 176
              Width = 169
              Height = 20
              TabOrder = 16
            end
            object T12: TEdit
              Left = 16
              Top = 192
              Width = 169
              Height = 20
              TabOrder = 17
            end
            object T13: TEdit
              Left = 16
              Top = 208
              Width = 169
              Height = 20
              TabOrder = 18
            end
            object T14: TEdit
              Left = 16
              Top = 224
              Width = 169
              Height = 20
              TabOrder = 19
            end
            object T15: TEdit
              Left = 16
              Top = 240
              Width = 169
              Height = 20
              TabOrder = 20
            end
            object T16: TEdit
              Left = 16
              Top = 256
              Width = 169
              Height = 20
              TabOrder = 21
            end
            object T17: TEdit
              Left = 16
              Top = 272
              Width = 169
              Height = 20
              TabOrder = 22
            end
            object T18: TEdit
              Left = 16
              Top = 288
              Width = 169
              Height = 20
              TabOrder = 23
            end
            object T19: TEdit
              Left = 16
              Top = 304
              Width = 169
              Height = 20
              TabOrder = 24
            end
            object T20: TEdit
              Left = 16
              Top = 320
              Width = 169
              Height = 20
              TabOrder = 25
            end
            object T21: TEdit
              Left = 16
              Top = 336
              Width = 169
              Height = 20
              TabOrder = 26
            end
            object T22: TEdit
              Left = 16
              Top = 352
              Width = 169
              Height = 20
              TabOrder = 27
            end
            object T23: TEdit
              Left = 16
              Top = 368
              Width = 169
              Height = 20
              TabOrder = 28
            end
            object T24: TEdit
              Left = 16
              Top = 384
              Width = 169
              Height = 20
              TabOrder = 29
            end
            object T25: TEdit
              Left = 16
              Top = 400
              Width = 169
              Height = 20
              TabOrder = 30
            end
    object T26: TEdit
              Left = 16
              Top = 416
              Width = 169
              Height = 20
              TabOrder = 50
            end
            object T27: TEdit
              Left = 16
              Top = 432
              Width = 169
              Height = 20
              TabOrder = 51
            end
            object T28: TEdit
              Left = 16
              Top = 448
              Width = 169
              Height = 20
              TabOrder = 52
            end
            object T29: TEdit
              Left = 16
              Top = 464
              Width = 169
              Height = 20
              TabOrder = 53
            end
            object T30: TEdit
              Left = 16
              Top = 480
              Width = 169
              Height = 20
              TabOrder = 54
            end
            object T31: TEdit
              Left = 16
              Top = 496
              Width = 169
              Height = 20
              TabOrder = 55
            end
            object T32: TEdit
              Left = 16
              Top = 512
              Width = 169
              Height = 20
              TabOrder = 56
            end
    object Edit35: TEdit
                Left = 148
                Top = 2
                Width = 41
                Height = 20
                TabOrder = 0
                Text = '1000'
              end
    object Edit5: TEdit
              Left = 6
              Top = 86
              Width = 207
              Height = 20
              TabOrder = 0
              Text = 'RS232 技术'
              OnKeyPress = Edit5KeyPress
            end
    object Edit_Data: TEdit
          Left = 110
          Top = 76
          Width = 423
          Height = 20
          Font.Charset = GB2312_CHARSET
          Font.Color = clWindowText
          Font.Height = -12
          Font.Name = '宋体'
          Font.Style = []
          ParentFont = False
          TabOrder = 0
          Text = '12 00 FF'
          OnKeyPress = Edit_DataKeyPress
        end
    object Edit1: TEdit
          Left = 188
          Top = 22
          Width = 41
          Height = 21
          TabOrder = 7
          Text = '1000'
          OnKeyPress = Edit1KeyPress
        end
    object Edit2: TEdit
          Left = 64
          Top = 4
          Width = 217
          Height = 20
          Font.Charset = GB2312_CHARSET
          Font.Color = clWindowText
          Font.Height = -12
          Font.Name = '宋体'
          Font.Style = []
          ParentFont = False
          TabOrder = 2
          Text = '文件名'
        end
    object Edit3: TEdit
        Left = 78
        Top = 206
        Width = 97
        Height = 21
        Enabled = False
        TabOrder = 10
        Text = 'Edit3'
        Visible = False
      end
      object Edit4: TEdit
        Left = 176
        Top = 206
        Width = 33
        Height = 21
        Enabled = False
        TabOrder = 11
        Text = '8080'
        Visible = False
      end不过上面两种方法即使可行,但都没有普遍性。。烦
      

  25.   

    我是新手,对你们的问题我……
    I FOLLOW YOU