HI there,
It seems that there is some issue with the OnRightClick event, and you cannot make it work at the moment.
Maybe you could use some Windows event filtering or perhaps implement a Windows hook that would close the popup menu and would show your own instead.
Sorry about the bad news.
Cheers,
Adam Nagy
Autodesk Developer Network
Thank you Adam for that straight answer,
I'm currently working with a 2010 version, has this issue been modified in newer versions, or is it planned for the next one ?
I will try to do it the way you proposed, even if i can't realy figure out for the moment how to prevent the GripStretch Menu to Popup. Is there a simple way to get a reference to that menu, so i can modify it, before it pops ?
Cheers
Hi there,
After three days trying to understand how Hooking works, here is a code to Hook the GripStretch Context Menu.
The hook will stop the gripStretch context menu Popup and raise a Hooked event when done. On that event you can set your own Context menu. The hook is set on GripStart and destroyed on GripAbort or GripEnd.
Cheers
Protected Class CustomGripData
Inherits GripData
Private Shared ContextMenuHook As Win32APIUtil.ContextMenuHook
Public Overrides Sub OnGripStatusChanged(ByVal entityId As Autodesk.AutoCAD.DatabaseServices.ObjectId, ByVal newStatus As Autodesk.AutoCAD.DatabaseServices.GripData.Status)
MyBase.OnGripStatusChanged(entityId, newStatus)
Select newStatus
Case Status.GripStart
ContextMenuHook = New Win32APIUtil.ContextMenuHook()
AddHandler ContextMenuHook.Hooked, AddressOf ContextMenuHookProc
Case Status.GripEnd, Status.GripAbort
ContextMenuHook.UnHook()
RemoveHandler ContextMenuHook.Hooked, AddressOf ContextMenuHookProc
End Select
End Sub
Private Sub ContextMenuHookProc()
Dim newMenu As Windows.Forms.ContextMenuStrip = New Windows.Forms.ContextMenuStrip
newMenu.Items.Add("Test1")
newMenu.Items.Add("Test2")
newMenu.Items.Add("Test3")
newMenu.Items.Add("-")
newMenu.Items.Add("Test4")
Dim pos As System.Drawing.Point = DwgCiblé.Window.Location
pos.Offset(DwgCiblé.Editor.PointToScreen(GripPoint, Autodesk.AutoCAD.Internal.ViewUtil.GetCurrentViewportNumber))
newMenu.Show(pos)
End Sub
End Class
Friend Class Win32APIUtil
#Region "Win32 Imports"
<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall, SetLastError:=True)> _
Protected Shared Function SetWindowsHookEx _
(ByVal idHook As HookType, ByVal HookProc As HookProc, _
ByVal hInstance As IntPtr, ByVal wParam As Integer) As IntPtr
End Function
<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall, SetLastError:=True)> _
Protected Shared Function CallNextHookEx _
(ByVal idHook As IntPtr, ByVal nCode As Integer, _
ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
End Function
<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall, SetLastError:=True)> _
Protected Shared Function UnhookWindowsHookEx(ByVal idHook As IntPtr) As Boolean
End Function
<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall, SetLastError:=True)> _
Protected Shared Function IsMenu(ByVal hMenu As IntPtr) As IntPtr
End Function
<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall, SetLastError:=True)> _
Protected Shared Function DestroyMenu(ByVal hMenu As IntPtr) As Boolean
End Function
<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall, SetLastError:=True)> _
Protected Shared Function EndMenu() As Boolean
End Function
#End Region
Private Const HC_ACTION As Int32 = 0
Friend Enum HookType As Integer
WH_CALLWNDPROC = 4
End Enum
Friend Enum WndMsg As Integer
WM_INITMENUPOPUP = &H117
End Enum
<StructLayout(LayoutKind.Sequential)> _
Friend Structure CWPSTRUCT
Public lParam As IntPtr
Public wParam As IntPtr
Public message As Integer
Public hWnd As IntPtr
End Structure
Friend Delegate Function HookProc(ByVal code As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
Friend Class ContextMenuHook
Protected _hook As IntPtr = IntPtr.Zero
Protected _hookProc As HookProc = Nothing
Friend Sub New()
_hookProc = AddressOf CoreHookProc
_hook = SetWindowsHookEx(HookType.WH_CALLWNDPROC, _hookProc, IntPtr.Zero, AppDomain.GetCurrentThreadId())
End Sub
Friend Event Hooked()
Protected Function CoreHookProc(ByVal code As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
If (code < 0) Then
Return CallNextHookEx(_hook, code, wParam, lParam)
End If
If wParam.ToInt32 = HC_ACTION Then
Dim msgDetails As CWPSTRUCT = CType(System.Runtime.InteropServices.Marshal.PtrToStructure(lParam, msgDetails.GetType), CWPSTRUCT)
Select Case msgDetails.message
Case WndMsg.WM_INITMENUPOPUP
If IsMenu(msgDetails.wParam) <> IntPtr.Zero Then
If DestroyMenu(msgDetails.wParam) Then
If EndMenu() Then
RaiseEvent Hooked()
End If
End If
End If
Case Else
End Select
End If
Return CallNextHookEx(_hook, code, wParam, lParam)
End Function
Public Sub UnHook()
If _hook <> IntPtr.Zero Then
UnhookWindowsHookEx(_hook)
_hook = IntPtr.Zero
End If
End Sub
End Class
End Class
Nice work 🙂
Thank you for sharing the solution with others.
Unfortunately, I cannot talk about future products or updates, but I can tell you that the issue is being looked into.
Cheers,
Adam Nagy
Autodesk Developer Network
> It seems that there is some issue with the OnRightClick event
Does this issue still exist?
Is it .NET specific or also affects ObjectArx?
Wolfram Kuss,
imos AG
Hi Wolfram,
My understanding is that it was only an issue in .NET and that it has been fixed for AutoCAD 2013.
If you find othewise then you can make a comment here.
Cheers,
Thanks for th quick reply. I dug deeper and fixed one issue in our code and indeed my remaining issue is one that happens under specific conditions only:
We want to optionally treat AutoCAD groups as one object from the user's perspective.
One aspect of that is that we overrule the grips of all members of a group to show up in exact the same position. So, the user sees only one grip and to him it looks that this is the "grip of the group". This is like in this post:
http://adndevblog.typepad.com/autocad/2013/11/overruling-grips-for-a-group.html
I now found that for groups consisting of one member only, Right Click works and produces the popupmenu we created.
However if there are several grips at the same place, the right click handler is not called and instead an unspecific AutoCAD popupmenu appears.
Of course we set all grips to use the same right click handler.
I guess that there is no way to use a Right Click Handler when there are several grips in the same 3D spot?