rt

解决方案 »

  1.   

    设置控件的ToolTipText属性等于控件名
      

  2.   

    我的目的是让StatusBar 的Text显示出控件的Name
      

  3.   

    单从字面上看你要得到的是某个“对象”的“Name”属性值内容
    但是在Windows中,所谓能看到的控件都是由窗口所建成的,
    就是说你是要通过窗口句柄得到创建那个窗口类的类地址,
    然后再通过类地址映射到一个对象来读取那个类中的Name属性,
    但是因为这种窗口是通过类创建的,除非那个类在创建窗口时将它的类
    地址写入了窗口相关信息的某个地方,否这没办法得到这个类地址的
    所以,如果是针对所有程序,按照你的要求是不可行的但是,如果只是针对自己的程序,就可以通过很多方法实现。
    还有,有可能你只想得到的是窗口标题的内容,并不是控件对象Name属性
    因为通常控件会将自己的标题设置为Name属性相同的文本,这样让你误以
    为那个控件的窗口标题就是那个控件的Name属性
      

  4.   


    本程序的控件名称显示不用 API 也可以。用 API 反而复杂化。下面是用 API 窗口子类化的例子:模块:
    Option Explicit'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    'Copyright 2002 40Star, All Rights Reserved.
    '
    'E-Mail      :[email protected]
    'Distribution:你可以完全自由随便的使用这段代码,不管你用于任何目的
    '              程序在于交流和学习
    '              如有任何BUG请和我联系
    '
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
        (ByVal hwnd As Long, ByVal wMsg As Long, _
        ByVal wParam As Long, lParam As String) As LongPrivate Declare Function GetWindowLong Lib "user32" Alias _
        "GetWindowLongA" (ByVal hwnd As Long, _
        ByVal nIndex As Long) As LongPrivate Declare Function SetWindowLong Lib "user32" Alias _
            "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex _
            As Long, ByVal dwNewLong As Long) As Long
            
    Private Declare Function CallWindowProc Lib "user32" Alias _
            "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal _
            hwnd As Long, ByVal Msg As Long, ByVal wParam As _
            Long, ByVal lParam As Long) As Long
      
    Const GWL_WNDPROC = (-4&)Dim PrevWndProc&Private Const WM_DESTROY = &H2
    Public Declare Function TrackMouseEvent Lib "user32" (lpEventTrack As TRACKMOUSEEVENTTYPE) As LongPublic Const TME_CANCEL = &H80000000
    Public Const TME_HOVER = &H1&
    Public Const TME_LEAVE = &H2&
    Public Const TME_NONCLIENT = &H10&
    Public Const TME_QUERY = &H40000000Private Const WM_MOUSELEAVE = &H2A3&
    Public Const WM_MOUSEMOVE = &H200Public Type TRACKMOUSEEVENTTYPE
        cbSize As Long
        dwFlags As Long
        hwndTrack As Long
        dwHoverTime As Long
    End TypePublic bTracking As Boolean
    Dim evtTrack As TRACKMOUSEEVENTTYPE
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Public strName As StringPrivate Function SubWndProc(ByVal hwnd As Long, ByVal Msg As Long, _
                                ByVal wParam As Long, ByVal lParam As Long) _
                                As Long   If Msg = WM_DESTROY Then Terminate (hwnd)   '处理鼠标移出消息
       If Msg = WM_MOUSEMOVE Then
          Form1.StatusBar1.Panels(1) = strName
       End If
       If Msg = WM_MOUSELEAVE Then
          bTracking = False
          Form1.StatusBar1.Panels(1) = ""
       End If
       SubWndProc = CallWindowProc(PrevWndProc, hwnd, Msg, wParam, lParam)
    End FunctionPublic Sub Init(hwnd As Long)
      PrevWndProc = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf SubWndProc)
    End SubPublic Sub Terminate(hwnd As Long)
      Call SetWindowLong(hwnd, GWL_WNDPROC, PrevWndProc)
    End Sub' -- 模块结束 -- '窗体:(有控件 Command1)
    Option ExplicitPrivate Sub Command1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    If bTracking = False Then
       bTracking = True
        Dim ET As TRACKMOUSEEVENTTYPE
        'initialize structure
        ET.cbSize = Len(ET)
        ET.hwndTrack = Command1.hwnd
        ET.dwFlags = TME_LEAVE
        'start the tracking
        strName = Command1.Name
        TrackMouseEvent ET
    End If
    End SubPrivate Sub Form_Load()
    Call Init(Command1.hwnd)
    End SubPrivate Sub Form_Unload(Cancel As Integer)
    Call Terminate(Command1.hwnd)
    End Sub
      

  5.   

    下面是不用 API 的例子:Option ExplicitPrivate Sub Command1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
        StatusBar1.Panels(1) = Command1.Name
    End Sub
    Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
        StatusBar1.Panels(1) = ""
    End Sub那个简单?看来出题的人有毛病。
      

  6.   

    我估计是LZ贪方便,不像一个控件一个控件的写。
    可以加一个timer,用获取hwnd的方法。Dim ctr As Control
        Dim point As POINTAPI
        Dim hWnd As Long    GetCursorPos point
        hWnd = WindowFromPoint(point.x, point.y)
        For Each ctr In Controls
             If ctr.hWnd = hWnd Then
                StatusBar1.panels(1) = ctr.Name
             End If
        Next但由于lable、line、img等等等等控件没有hwnd。所有还有进行特殊处理。
    但是最简单的还是不显示在状态栏上,直接设置每个控件的ToolTipText。最方便,还绝不出错。。
      

  7.   

    实现是不要在控件的MouseMove中写代码。鼠标移动到控件上,就能在StatusBar的Text显示出该控件的Name信息。
      

  8.   

    路过.两种方案的代码复杂度与代码量很明显不同.在控件数量N多的情况下:API方案复杂度高,但有可能代码量少.MouseMove方案在控件很多的情况下会写多些代码,但并不复杂.
      

  9.   

    老马看漏了,
    api里的代码也有mousemove,楼主要不用mousemove,加hook不知行不行
      

  10.   

    看来大家都没搞清楚这个问题的关键,就是类地址,
    在VB中可以理解为 me,在vc中可以理解为 (LONG)this
    就是这个东西,单通过一个类所创建的窗口句柄就想取得
    整个类的地址,就我了解的技术来说,是取不了的,
    但是,如果没有这个类的地址,就谈不上从类中去读取什么属性值,
    因为无论是什么控件,都是基于类创建的,而控件的属性是在类中,当然其中
    也包括楼主所说的Name属性在内,如果得不到类地址,根本就不能去操作他,
    比如读写类的属性或调用类方法等,当然,如果能得到类的地址,相对的也可以
    读写类的属性或调用类的方法,通常如果有需要这么调用类的操作,开发人员会用
    一些窗口的特殊地址来存储类地址共程序使用,下面这个帖子就有说明类地址在VB中的一些应用方法:
    http://topic.csdn.net/u/20100220/21/5a935407-8fdf-4764-879f-0a1fba0b5b4b.html
    这种使用方法其实在微软的一个范例程序我有见过,就是托盘控件的范例程序。
    而且那些使用异步通讯的Winsock类代码中也使用相同的技术,
    但为什么要这么用呢?为什么非得先在程序中取出类地址然后用SetWindowLond存到窗口的用户信息处,
    然后再取出来还原类来使用呢?因为我觉得就不能直接通过窗口句柄取得类的地址,所以他们才通过这种
    方式来传递类地址(包括微软的代码都要这么做)。
    所以如果从API的角度来说,如果没有类地址的情况下,是行不通的。但是从VB的角度来看,vb中本来就有很多对象呀集合的,对自己的程序而言,要得到这些类的地址
    可以通过VB集合队列中取得,相对来说简单好用,因为这些复杂的操作VB的子系统都已经帮你缓存
    和处理好了,你只需要调用就出来了,不要弄得太复杂,就算把问题复杂化了也不见得可行,因为
    很多底层的东西不像应用层的东西那样,有那么多方便的东西还有那么多应用层使用概念的。
      

  11.   

    如果目标进程没有与本进程用约定的方式通信传递回控件名称,光用win API应该不能实现获取其他进程的控件名称吧.
    控件是一个类,控件名称是类的实例的名称,就相当于声名的一个变量名而已,这个变量的名称经编译以后就不再是原来的名字了吧,也就是说在exe中存在的实例名称应该不会再是代码中的变量名.所以是无法获取的.