我最后的机会!!!

jing 2000-03-30 07:26:00
当mouse在窗体的标题栏或菜单栏上上click时如何让我的window得到mouse消息。就是在我的标准window任何地方click都能得到消息。就象游戏的fullScreen.谢大虾回答一定感激。详细一点
...全文
298 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
jing 2000-04-07
  • 打赏
  • 举报
回复
Thanks
peacock 2000-04-01
  • 打赏
  • 举报
回复
下面这个也许有用(我没用过):
得知目前Mouse所指的Menu Item是哪一个
请先查阅有BitMap的Menu取得Menu的相关知识,再查
如何拦截ComboBox MouseMove的SubClass之技巧
一些商业软件中,当滑鼠指向某个Menu Item时,在表单的底部STATUSBAR中会显示有该Item
功能的简要说明。而VB5中有关Menu的捕捉事件只有一个 CLICK,那该如何做呢。其实当
选择了Menu後,Mouse在Menu SubMenu MenuItem上移来移去时,会产生WM_MENUSELECT的
Message给Menu所在的表单,而其wParam的Low Word有两个意义,如果Mouse指到的Item
之下还有子Menu,该LowWord of wParam指的是该Item是第几个SubMenu,而lParam便是
Menu的Handle;相反的,如果Mouse所指的Item底下没有PopupMenu了,那 LowWord of
wParam指的是MenuID,而lParam是hSubMenu。


档案 编辑 选项 --> hMenu (功能表, Menu)
+-------+
and 复制 and ---------> hSubMenu (子功能表, SubMenu)
and 贴上 and
and 减下 -------------> MenuID (功能表项目,MenuItem)
and and
+-------+

所以了,这就得使用SubClass的技巧,取得WM_MENUSELECT的Message,进而得知到底是
选到了哪一个MenuItem。当然了,我们可以使用GetMenu GetSubMenu GetMenuItemID
等API来得知功能表上每一个项目的hMenu hSubMenu MenuID,如此一来,和WM_MENUSELECT
讯息所取得的lParam wParam做做比较,就可得知到底选上了哪一个,而本例则是使用
GetMenuString取得MenuItem的title,如果您的MenuItems没有相同的title,也不失一
得知方式。

'以下在form,请自行加Menu於Form上
Private Sub Form_Load()
Dim ret As Long
hMenu = GetMenu(Me.hwnd)

'记录原本的Window Procedure的位址
preWinProc = GetWindowLong(Me.hwnd, GWL_WNDPROC)
'设定Combo1的window Procedure到wndproc
ret = SetWindowLong(Me.hwnd, GWL_WNDPROC, AddressOf wndproc)
End Sub

Private Sub Form_Unload(Cancel As Integer)
Dim ret As Long
'取消Message的截取,而使之又只送往原来的Window Procedure
ret = SetWindowLong(Me.hwnd, GWL_WNDPROC, preWinProc)
End Sub


'以下在.Bas
'以下程式在module1.bas
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
(ByVal hwnd As Long, ByVal nIndex As Long) As Long
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
Declare Function GetMenuString Lib "user32" Alias "GetMenuStringA" (ByVal hMenu As Long, ByVal wIDItem As Long, ByVal lpString As String, ByVal nMaxCount As Long, ByVal wFlag As Long) As Long
Declare Function GetMenu Lib "user32" (ByVal hwnd As Long) As Long
Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long

Public Const GWL_WNDPROC = (-4)
Public Const WM_MENUSELECT = &H11F
Public Const MF_BYCOMMAND = &H0&
Public Const MF_BYPOSITION = &H400&

Public hMenu As Long
Public preWinProc As Long
Private Type tLong
ll As Long
End Type
Private Type TwoWord
LowWord As Integer
HiWord As Integer
End Type
Public Function wndproc(ByVal hwnd As Long, ByVal Msg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
Dim MenuItemStr As String, SubMenuStr As String
Dim hSubmenu As Long, MenuId As Long, i As Long
Dim tmpl As tLong, tmpt As TwoWord
'以下程式会截取WM_MENUSELECT处理完後,再将之送往原来的Window Procedure
If Msg = WM_MENUSELECT Then
SubMenuStr = String(255, 0)
MenuItemStr = String(255, 0)

tmpl.ll = wParam
LSet tmpt = tmpl
MenuId = tmpt.LowWord

hSubmenu = GetSubMenu(lParam, MenuId)
If hSubmenu = 0 Then '表示该item之下没有popupMenu了
Call GetMenuString(lParam, MenuId, MenuItemStr, 256, MF_BYCOMMAND)
MenuItemStr = Left(MenuItemStr, InStr(1, MenuItemStr, Chr(0)) - 1)
Debug.Print "正在 MenuItem " + MenuItemStr
Else
Call GetMenuString(hMenu, hSubmenu, SubMenuStr, 256, MF_BYCOMMAND)
SubMenuStr = Left(SubMenuStr, InStr(1, SubMenuStr, Chr(0)) - 1)
Debug.Print "正在 PopUpMenu " + SubMenuStr
End If
End If
'将之送往原来的Window Procedure
wndproc = CallWindowProc(preWinProc, hwnd, Msg, wParam, lParam)
End Function
Lin 2000-04-01
  • 打赏
  • 举报
回复
Jing:
  昨天有个哥们自远方来,喝大了...
  我以为我已经说的很详细了,其实这是窗口子类话的一些技巧,在你的窗口过程中只需处理你感兴趣的消息,其余的调用缺省的消息处理过程就行了,这也是为什么保存其返回值的原因。
Janven:
  鼠标在菜单中移动,窗口将检测到WM_MENUSELECT消息,具体请参照MSDN光盘的说明。
Janven 2000-03-31
  • 打赏
  • 举报
回复
鼠标移到非工作区,所产生的不是WM_MOUSEMOVE及WM_?BUTTON?消息,而是WM_NCMOUSEMOVE及WM_NC?BUTTON?消息,你可以编写窗口消息处理过程,用SetWindowLong(hwnd, GWL_WNDPROC, AddressOf Your Proc)使windows回调你自己定义的程序。记得窗口消息处理过程一定得在放在(.bas)文件中。
鼠标移到菜单栏的消息,我也不知道.我有空跟踪一下试试。希望你解决问题后也能给我回封信告之详情,谢谢。Janven@yeah.net.
apollo 2000-03-31
  • 打赏
  • 举报
回复
...
kxy 2000-03-30
  • 打赏
  • 举报
回复
VB我不知道它的机制。
delphi或VC中。WM_NCHITTEST就是你要的消息。
ReturnValue

HTBORDER In the border of a window that does not have a sizing border
HTBOTTOM In the lower horizontal border of a window
HTBOTTOMLEFT In the lower-left corner of a window border
HTBOTTOMRIGHT In the lower-right corner of a window border
HTCAPTION In a title bar
HTCLIENT In a client area
HTERROR On the screen background or on a dividing line between windows (same as HTNOWHERE, except that the DefWindowProc function produces a system beep to indicate an error)
HTGROWBOX In a size box (same as HTSIZE)
HTHSCROLL In a horizontal scroll bar
HTLEFT In the left border of a window
HTMENU In a menu
HTNOWHERE On the screen background or on a dividing line between windows
HTREDUCE In a Minimize button
HTRIGHT In the right border of a window
HTSIZE In a size box (same as HTGROWBOX)
HTSYSMENU In a System menu or in a Close button in a child window
HTTOP In the upper horizontal border of a window
HTTOPLEFT In the upper-left corner of a window border
HTTOPRIGHT In the upper right corner of a window border
HTTRANSPARENT In a window currently covered by another window
HTVSCROLL In the vertical scroll bar
HTZOOM In a Maximize button
long408 2000-03-30
  • 打赏
  • 举报
回复
不知你到底想干什么,如果仅仅想取得mouse消息而不是想截获mouse消息的话
可以用SetCapture
Public Declare Function SetCapture Lib "user32" (ByVal hwnd As Long) As Long
Private Sub Form_Load()
Call SetCapture(Form1.hwnd)
End Sub
这样即使mouse在form1之外也会得到mouse消息,但window其他地方得不到mouse消息

如果想截获mouse消息的话,应该用hook,这必须用c编写专门的hook dll

如果想些游戏的话最好用direct input
Implements DirectXEvent

Public objDX As New DirectX7
Public objDXEvent As DirectXEvent
Public objDI As DirectInput
Public objDIDev As DirectInputDevice
Public EventHandle As Long
Set objDI = objDX.DirectInputCreate
Set objDIDev = objDI.CreateDevice("guid_SysMouse")
Call objDIDev.SetCommonDataFormat(DIFORMAT_MOUSE)
Call objDIDev.SetCooperativeLevel(form1.hWnd, DISCL_FOREGROUND Or DISCL_EXCLUSIVE)
EventHandle = objDX.CreateEvent(form1)
objDIDev.Acquire

Private Sub DirectXEvent_DXCallback(ByVal eventid As Long)
'响应消息
End Sub

如果想单击除了窗口标题栏以外的区域使窗口移动的话
先定义PostMessage,MAKELPARM 和常数
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
PostMessage (WM_NCLBUTTONDOWN , HTCAPTION , MAKELPARM (X,Y) )
End Sub



jing 2000-03-30
  • 打赏
  • 举报
回复
在VB上可不用GetMessage之类的
函树呢
Lin快回答不然我就回不了家了。
jing 2000-03-30
  • 打赏
  • 举报
回复
再详细一点好不好
Lin 2000-03-30
  • 打赏
  • 举报
回复
用VB?太难,太危险:自己编写窗口消息处理过程,用SetWindowLong(hwnd, GWL_WNDPROC, AddressOf Your Proc);注意将返回值保存起来,以便调用缺省的消息处理过程。小心一点哦,系统Down了别怪我没提醒你。
peacock 2000-03-30
  • 打赏
  • 举报
回复
用SendMassage,可它太复杂,如你解决,别忘了告诉我!

7,762

社区成员

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

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