本程序的控件名称显示不用 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
下面是不用 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那个简单?看来出题的人有毛病。
我估计是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。最方便,还绝不出错。。
但是在Windows中,所谓能看到的控件都是由窗口所建成的,
就是说你是要通过窗口句柄得到创建那个窗口类的类地址,
然后再通过类地址映射到一个对象来读取那个类中的Name属性,
但是因为这种窗口是通过类创建的,除非那个类在创建窗口时将它的类
地址写入了窗口相关信息的某个地方,否这没办法得到这个类地址的
所以,如果是针对所有程序,按照你的要求是不可行的但是,如果只是针对自己的程序,就可以通过很多方法实现。
还有,有可能你只想得到的是窗口标题的内容,并不是控件对象Name属性
因为通常控件会将自己的标题设置为Name属性相同的文本,这样让你误以
为那个控件的窗口标题就是那个控件的Name属性
本程序的控件名称显示不用 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
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那个简单?看来出题的人有毛病。
可以加一个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。最方便,还绝不出错。。
api里的代码也有mousemove,楼主要不用mousemove,加hook不知行不行
在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的子系统都已经帮你缓存
和处理好了,你只需要调用就出来了,不要弄得太复杂,就算把问题复杂化了也不见得可行,因为
很多底层的东西不像应用层的东西那样,有那么多方便的东西还有那么多应用层使用概念的。
控件是一个类,控件名称是类的实例的名称,就相当于声名的一个变量名而已,这个变量的名称经编译以后就不再是原来的名字了吧,也就是说在exe中存在的实例名称应该不会再是代码中的变量名.所以是无法获取的.