如何获得鼠标所指的窗体的hwnd??

bjseaman 2000-02-10 03:19:00
小弟曾尝试的去做,用的方法是:
每1/1000秒 GetCursor 一次
然后用WindowFromPoint 获取 hwnd
可是如果鼠标所指的不是窗体而是控件就会得到控件的hwnd

请高手指点,如何获取鼠标所指控件所在窗体的hwnd
如果鼠标指向菜单,又如何获取该菜单所在窗体的hwnd?
...全文
507 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
benbenlittle 2000-03-01
  • 打赏
  • 举报
回复
Declare Function GetParent Lib "user32" Alias "GetParent" (ByVal hwnd As Long) As Long

有windowfrompoint获得句柄后
用GetParent后会返回它的父窗口的句柄
若没有则返回0
bjseaman 2000-02-24
  • 打赏
  • 举报
回复
To Lin:
可以的,你看看这个。
Dim TimeToEnd As Boolean
Private Sub MouseMove()
Do
GetCursorPos MousePoint
frmMain.Caption = "X:" & MousePoint.x & " Y:" & MousePoint.y
DoEvents
Loop Until GetPosEnd
End Sub
Private Sub Form_Load()
frmMain.Show
MouseMove
End Sub
Private Sub Form_Unload(Cancel As Integer)
GetPosEnd = True
End Sub
forgettor 2000-02-23
  • 打赏
  • 举报
回复
hook不错
Lin 2000-02-23
  • 打赏
  • 举报
回复
To bjseaman:
当鼠标在自己创建的窗口移动时,用do loop就能完成并最终得到窗口句柄(如果是控件,就调用GetParent API,直到其返回值为窗口句柄;
但是,如果鼠标移出窗体,He he,用do loop你再试试?恐怕不行。
所以,还是Hook鼠标移动消息吧。

rootGR 2000-02-22
  • 打赏
  • 举报
回复
调用“User32”中的GetCapture(),具体声明如下:
Declare Function GetCapture Lib "user32" Alias "GetCapture" () As Long
就可以获得一个窗口的句柄,且鼠标可以接收它。
xiaoy 2000-02-19
  • 打赏
  • 举报
回复
你去看一下那些查看密码程序的源代码,好象是有用WindowFromPoint然后再判断所获得的hwnd所指窗体的类别。
bjseaman 2000-02-19
  • 打赏
  • 举报
回复
huijp
我需要得到窗体的hwnd,然后对该窗体操作
对控件不管用的
泥娃 2000-02-19
  • 打赏
  • 举报
回复
在Windows中窗体的定义很广。
控件也是窗体。
窗体不也是控件吗?
bjseaman 2000-02-18
  • 打赏
  • 举报
回复
huijp的方法我试过,如果移动到control是会得到control的hwnd
而我想知道的是窗体的hwnd,也就是说所指control的所属窗体的hwnd.

hook的方法太麻烦,而且判断mouse移动用不着hook,用do loop就能完成

希望有人能给我满意的答复。
感谢各位给小弟帮助!
Lin 2000-02-18
  • 打赏
  • 举报
回复
bjseaman,我猜测你的意思,除非Hook鼠标移动消息,再调用WindowFromPoint就差不多行了。但说起容易做起难,在戴妃或VC中比较容易,在VB中嘛,太难。当然也可以,具体可参照SetWindowHookEx API和AddressOf操作符号。
Lin 2000-02-18
  • 打赏
  • 举报
回复
bjseaman,我猜测你的意思,除非Hook鼠标移动消息,再调用WindowFromPoint就差不多行了。但说起容易做起难,在戴妃或VC中比较容易,在VB中嘛,太难。当然也可以,具体可参照SetWindowHookEx API和AddressOf操作符号。
littletao 2000-02-17
  • 打赏
  • 举报
回复
huijp is right
windowfrompoint得到的是任何有hwnd的control的hwnd.
比如你把mouse移到一个textbox上,就得到这个textbox的hwnd.
普通菜单应该不可以吧,如果是98,得到会是一个toolbar window的hwnd
peacock 2000-02-17
  • 打赏
  • 举报
回复
这问题有意思,若是VC,一定很好解决,用VB,可能会用到SendMessage这个API函数,因为你的问题涉及到消息传送,具体......我还没找到这方面的资料
bjseaman 2000-02-16
  • 打赏
  • 举报
回复
对不起,是我误会了
i am sorry !
olo 2000-02-15
  • 打赏
  • 举报
回复
听听 就是说我不会但很想知道。
如果你提的问题不让别人旁听的话,以后我会注意,绝不介入。
bjseaman 2000-02-15
  • 打赏
  • 举报
回复
各位可能误会了,
我所说的不是仅限于一个程序,
而是所有在桌面上的窗口。
olo,请问"听听"是什麽意思?
你会听?
zzf 2000-02-13
  • 打赏
  • 举报
回复
VB下的全局对象集Forms包括你的程序所打开的所有窗体(包括MDI),遍历一遍Forms看看你得到的
hwnd是否是其中某一个Form的hwnd,有就是窗体,否则不是
olo 2000-02-12
  • 打赏
  • 举报
回复
听听
radish 2000-02-12
  • 打赏
  • 举报
回复
用循环呀,找到为止
bjseaman 2000-02-12
  • 打赏
  • 举报
回复
jiangtao 老兄
如果所指的控件的所属不是窗体,而是其他的容器,比如picturebox
那麽getparent得到的是窗体的还是容器的?
指向菜单了,又会如何?
能否详细一些?
中文可以吗?
加载更多回复(2)
VB6.0 为无标题的窗体添加鼠标效果,Rect返回当前窗口位置,Point返回当前鼠标位置,本代码主要是使用case语句来实现,可练习一下case语句的用法哦,分享代码:   Dim Point As POINTAPI   Call GetWindowRect(Me.hwnd, Rect) 'Rect返回当前窗口位置   Call GetCursorPos(Point) 'Point返回当前鼠标位置   Select Case True   Case Point.X < Rect.Left 5 And Point.Y < Rect.Top 5 '鼠标位于窗体左上方    Screen.MousePointer = vbSizeNWSE '45度双向鼠标    Action = "LeftUp"   Case Point.X > Rect.Right - 5 And Point.Y > Rect.Bottom - 5 '鼠标位于窗体右下方    Screen.MousePointer = vbSizeNWSE    Action = "RightDown"   Case Point.X > Rect.Right - 5 And Point.Y < Rect.Top 5 '鼠标位于窗体右上方    Screen.MousePointer = vbSizeNESW    Action = "RightUp"   Case Point.X < Rect.Left 5 And Point.Y > Rect.Bottom - 5 '鼠标位于窗体的左下方    Screen.MousePointer = vbSizeNESW    Action = "LeftDown"   Case Point.X < Rect.Left 5 '鼠标位于窗体的左侧    Screen.MousePointer = vbSizeWE    Action = "Left"   Case Point.X > Rect.Right - 5 '鼠标位于窗体的右侧    Screen.MousePointer = vbSizeWE    Action = "Right"   Case Point.Y < Rect.Top 5 '鼠标位于窗体的上面    Screen.MousePointer = vbSizeNS '垂直双向鼠标指针    Action = "Up"   Case Point.Y > Rect.Bottom - 5 '鼠标位于窗体底部    Screen.MousePointer = vbSizeNS    Action = "Down"   Case Else '鼠标移动    Screen.MousePointer = 0 '默认鼠标指针    Action = "Move"   End Select
自定义窗体的最大化、最小化和关闭按钮, C#移动无标题栏窗体的三种代码: C#移动无标题栏窗体的三种代码:第一种采用,需注意窗体上的控件是否把窗体覆盖了。。。MouseDown、MouseMove、MouseUp事件应该是鼠标所处位置最顶层的控件的事件 在窗体的类中声明两个变量 private Point mouseOffset; //记录鼠标指针的坐标 private bool isMouseDown = false; //记录鼠标按键是否按下 创建该窗体 MouseDown、MouseMove、MouseUp事件的相应处理程序 private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) { int xOffset; int yOffset; if (e.Button == MouseButtons.Left) { xOffset = -e.X ; yOffset = -e.Y ; mouseOffset = new Point(xOffset, yOffset); isMouseDown = true; } } private void Form1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) { if (isMouseDown) { Point mousePos = Control.MousePosition; mousePos.Offset(mouseOffset.X, mouseOffset.Y); Location = mousePos; } } private void Form1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) { // 修改鼠标状态isMouseDown的值 // 确保只有鼠标左键按下并移动时,才移动窗体 if (e.Button == MouseButtons.Left) { isMouseDown = false; } } 第二种调用API 未验证 using System.Runtime.InteropServices; [DllImport("user32.dll")] public static extern bool ReleaseCapture(); [DllImport("user32.dll")] public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam); public const int WM_SYSCOMMAND = 0x0112; public const int SC_MOVE = 0xF010; public const int HTCAPTION = 0x0002; private void Form1_MouseDown(object sender, MouseEventArgs e) { ReleaseCapture(); SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0); } 第三种未验证 private bool isMouseDown = false; private Point FormLocation; //form的location private Point mouseOffset; //鼠标的按下位置 [DllImport("user32.dll")] public static extern bool ReleaseCapture(); [DllImport("user32.dll")] public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam); private const int WM_SYSCOMMAND = 0x0112;//点击窗口左上角那个图标时的系统信息 private const int SC_MOVE = 0xF010;//移动信息 private const int HTCAPTION = 0x0002;//表示鼠标在窗口标题栏时的系统信息 private const int WM_NCHITTEST = 0x84;//鼠标窗体客户区(除了标题栏和边框以外的部分)时发送的消息 private const int HTCLIENT = 0x1;//表示鼠标在窗口客户区的系统消息 private const int SC_MAXIMIZE = 0xF030;//最大化信息 private const int SC_MINIMIZE = 0xF020;//最小化信息 protected override void WndProc(ref Message m) { switch (m.Msg) { case WM_SYSCOMMAND: if (m.WParam == (IntPtr)SC_MAXIMIZE) { m.WParam = (IntPtr)SC_MINIMIZE; } break; case WM_NCHITTEST: //如果鼠标移动或单击 base.WndProc(ref m);//调用基类的窗口过程——WndProc方法处理这个消息 if (m.Result == (IntPtr)HTCLIENT)//如果返回的是HTCLIENT { m.Result = (IntPtr)HTCAPTION;//把它改为HTCAPTION return;//直接返回退出方法 } break; } base.WndProc(ref m);//如果不是鼠标移动或单击消息就调用基类的窗口过程进行处理 } private void Form1_Load(object sender, EventArgs e) { } ------------------------------- 如何在窗体标题栏左边的控制菜单加入自己的菜单啊? 我们一般在窗口标题栏点右键 或 按Alt+空格 可以弹出那个菜单。 ------解决方案-------------------- using System.Runtime.InteropServices; [DllImport( "user32.dll ")] public static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert); [DllImport( "user32.dll ")] public static extern bool InsertMenu(IntPtr hMenu, uint uPosition, uint uFlags, uint uIDNewItem, string lpNewItem); public const int MF_BYCOMMAND = 0; public const int MF_STRING = 0; public const int MF_BYPOSITION = 0x400; public const int MF_SEPARATOR = 0x800; private const uint SC_ABOUT = 0x0001; public const int WM_SYSCOMMAND = 0x0112; private void Form1_Load(object sender, EventArgs e) { IntPtr vMenuHandle = GetSystemMenu(Handle, false); InsertMenu(vMenuHandle, 255, MF_STRING, SC_ABOUT, "About... "); } protected override void WndProc(ref Message m) { switch (m.Msg) { case WM_SYSCOMMAND: if ((uint)m.WParam == SC_ABOUT) { MessageBox.Show( "Zswang 路过! "); } break; } base.WndProc(ref m); }

7,762

社区成员

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

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