Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 需要windows API InsertMenuItem中的帮助吗_.net_Vb.net_Winapi_Pinvoke_Menuitem - Fatal编程技术网

.net 需要windows API InsertMenuItem中的帮助吗

.net 需要windows API InsertMenuItem中的帮助吗,.net,vb.net,winapi,pinvoke,menuitem,.net,Vb.net,Winapi,Pinvoke,Menuitem,我想在其他进程中插入一个新菜单。但我有一个错误: 试图读取或写入受保护的内存。这通常表示其他内存已损坏 按钮代码: Mmenuhandle = GetMenu(mainhandle) Mmenucount = GetMenuItemCount(Mmenuhandle) Smenuhandle = GetSubMenu(Mmenuhandle, 0) Smenucount = GetMenuItemCount(Smenuhandle) With mii

我想在其他进程中插入一个新菜单。但我有一个错误:

试图读取或写入受保护的内存。这通常表示其他内存已损坏

按钮代码:

    Mmenuhandle = GetMenu(mainhandle) 
    Mmenucount = GetMenuItemCount(Mmenuhandle)
    Smenuhandle = GetSubMenu(Mmenuhandle, 0)
    Smenucount = GetMenuItemCount(Smenuhandle)  
    With mii  
        .cbSize = Len(mii)  
        .fMask = MIIM_STATE Or MIIM_ID Or MIIM_STRING Or MIIM_FTYPE  
        .fType = MFT_STRING  
        .fState = MFS_ENABLED  
        .wID = MENUID  
        .dwTypeData = "My Menu"  
        .cch = Len(.dwTypeData)  
    End With  
    InsertMenuItem(Smenuhandle, Smenucount + 1, True, mii) ' ERROR here  
    DrawMenuBar(mainhandle)  
为插入菜单项声明:

Private Declare Function InsertMenuItem Lib "user32" Alias "InsertMenuItemA" _
    (ByVal hMenu As Integer, ByVal uItem As Integer, ByVal fByPosition As Boolean, ByVal lpmii As MENUITEMINFO) As Integer
MENUITEMINFO
声明:

Public Structure MENUITEMINFO
    Public cbSize As Integer
    Public fMask As Integer
    Public fType As Integer
    Public fState As Integer
    Public wID As Integer
    Public hSubMenu As Integer
    Public hbmpChecked As Integer
    Public hbmpUnchecked As Integer
    Public dwItemData As Integer
    Public dwTypeData As String
    Public cch As Integer
    Public a As Integer  
End Structure

如何修复此错误?

p/Invoke代码不正确。。。它看起来是从VB 6源代码复制的,在VB 6中,等效名称的数据类型与在VB.NET中的数据类型具有非常不同的语义

此外,句柄/指针是使用固定整数类型声明的,这在64位环境中无法正常工作。应始终使用专门为此目的设计的
IntPtr
类型声明这些类型的值

而且,指向结构的指针需要在VB.NET中传递
ByRef
。您不能通过val传递它们

您需要使用和.NET封送拆收器中的工具来帮助您

这也是为什么在不了解代码的含义和作用的情况下,永远不要复制和粘贴在线找到的代码的另一个原因

声明应如下所示:

Imports System.Runtime.InteropServices

Public NotInheritable Class NativeMethods

   Public Const MIIM_STATE As Integer = &H1
   Public Const MIIM_ID As Integer = &H2
   Public Const MIIM_STRING As Integer = &H40
   Public Const MIIM_BITMAP As Integer = &H80
   Public Const MIIM_FTYPE As Integer = &H100

   Public Const MFT_STRING As Integer = &H0

   Public Const MFS_ENABLED As Integer = &H0

   <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
   Public Structure MENUITEMINFO
      Public cbSize As Integer
      Public fMask As Integer
      Public fType As Integer
      Public fState As Integer
      Public wID As Integer
      Public hSubMenu As IntPtr
      Public hbmpChecked As IntPtr
      Public hbmpUnchecked As IntPtr
      Public dwItemData As IntPtr
      <MarshalAs(UnmanagedType.LPTStr)> Public dwTypeData As String
      Public cch As Integer
      Public hbmpItem As IntPtr
   End Structure

   <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=False)> _
   Public Shared Function GetMenu(ByVal hWnd As IntPtr) As IntPtr
   End Function

   <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
   Public Shared Function GetMenuItemCount(ByVal hMenu As IntPtr) As Integer
   End Function

   <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=False)> _
   Public Shared Function GetSubMenu(ByVal hMenu As IntPtr, ByVal nPos As Integer) As IntPtr
   End Function

   <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
   Public Shared Function InsertMenuItem(ByVal hMenu As IntPtr,
                                         ByVal uItem As Integer,
                                         <MarshalAs(UnmanagedType.Bool)> fByPosition As Boolean,
                                         ByRef lpmii As MENUITEMINFO) _
                                    As <MarshalAs(UnmanagedType.Bool)> Boolean
   End Function

   <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
   Public Shared Function DrawMenuBar(ByVal hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
   End Function

End Class
一切都按预期进行,至少在相同的过程中。请注意,P/Invoke是一个相当困难的主题,您不仅需要对VB.NET有相当透彻的了解,还需要对Win32 API有相当透彻的了解,才能使其正常工作。复制和粘贴您在网上找到的代码是一个固有的风险主张。大多数情况下,这是行不通的。剩下的时间,这是一个可能的安全风险。不幸的是,您需要更多关于堆栈溢出的答案来解释它是如何工作的


Edit:事实上,上述代码在多个进程中也能正常工作。无需特别努力。我试着在记事本的一个运行实例中操纵菜单,结果一切正常。我不建议没有很好的理由就这样做…

p/Invoke代码不正确。。。它看起来是从VB 6源代码复制的,在VB 6中,等效名称的数据类型与在VB.NET中的数据类型具有非常不同的语义

此外,句柄/指针是使用固定整数类型声明的,这在64位环境中无法正常工作。应始终使用专门为此目的设计的
IntPtr
类型声明这些类型的值

而且,指向结构的指针需要在VB.NET中传递
ByRef
。您不能通过val传递它们

您需要使用和.NET封送拆收器中的工具来帮助您

这也是为什么在不了解代码的含义和作用的情况下,永远不要复制和粘贴在线找到的代码的另一个原因

声明应如下所示:

Imports System.Runtime.InteropServices

Public NotInheritable Class NativeMethods

   Public Const MIIM_STATE As Integer = &H1
   Public Const MIIM_ID As Integer = &H2
   Public Const MIIM_STRING As Integer = &H40
   Public Const MIIM_BITMAP As Integer = &H80
   Public Const MIIM_FTYPE As Integer = &H100

   Public Const MFT_STRING As Integer = &H0

   Public Const MFS_ENABLED As Integer = &H0

   <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
   Public Structure MENUITEMINFO
      Public cbSize As Integer
      Public fMask As Integer
      Public fType As Integer
      Public fState As Integer
      Public wID As Integer
      Public hSubMenu As IntPtr
      Public hbmpChecked As IntPtr
      Public hbmpUnchecked As IntPtr
      Public dwItemData As IntPtr
      <MarshalAs(UnmanagedType.LPTStr)> Public dwTypeData As String
      Public cch As Integer
      Public hbmpItem As IntPtr
   End Structure

   <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=False)> _
   Public Shared Function GetMenu(ByVal hWnd As IntPtr) As IntPtr
   End Function

   <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
   Public Shared Function GetMenuItemCount(ByVal hMenu As IntPtr) As Integer
   End Function

   <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=False)> _
   Public Shared Function GetSubMenu(ByVal hMenu As IntPtr, ByVal nPos As Integer) As IntPtr
   End Function

   <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
   Public Shared Function InsertMenuItem(ByVal hMenu As IntPtr,
                                         ByVal uItem As Integer,
                                         <MarshalAs(UnmanagedType.Bool)> fByPosition As Boolean,
                                         ByRef lpmii As MENUITEMINFO) _
                                    As <MarshalAs(UnmanagedType.Bool)> Boolean
   End Function

   <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
   Public Shared Function DrawMenuBar(ByVal hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
   End Function

End Class
一切都按预期进行,至少在相同的过程中。请注意,P/Invoke是一个相当困难的主题,您不仅需要对VB.NET有相当透彻的了解,还需要对Win32 API有相当透彻的了解,才能使其正常工作。复制和粘贴您在网上找到的代码是一个固有的风险主张。大多数情况下,这是行不通的。剩下的时间,这是一个可能的安全风险。不幸的是,您需要更多关于堆栈溢出的答案来解释它是如何工作的


Edit:事实上,上述代码在多个进程中也能正常工作。无需特别努力。我试着在记事本的一个运行实例中操纵菜单,结果一切正常。我不建议在没有充分理由的情况下这样做……

您是否使用钩子在另一个进程的上下文中执行?您是否使用钩子在另一个进程的上下文中执行?