하는 Constructor에 대해 경고하고이 유일한 생성자 :코드 분석 나는 시스템 전체 단축키 작업을 수행하는 클래스를 작성했습니다
:''' <summary> ''' Creates a new system-wide hotkey. ''' </summary> ''' <param name="Modifier">The keys that must be pressed in combination with the specified key.</param> ''' <param name="Key">The key used for the hotkey.</param> ''' <exception cref="IsRegisteredException"></exception> <DebuggerStepperBoundary()> Public Sub New(ByVal Modifier As HotkeyModifier, ByVal Key As Keys) Me.CreateHandle(New CreateParams) Me.PressEventArgs.ID = GetHashCode() Me.PressEventArgs.Key = Key Me.PressEventArgs.Modifier = Modifier If Not NativeMethods.RegisterHotKey(Me.Handle, Me.PressEventArgs.ID, Me.PressEventArgs.Modifier, Me.PressEventArgs.Key) Then Throw New IsRegisteredException End If End Sub
그리고 프로젝트에 코드 분석이 말한다
CA2214 생성자의 GlobalHotkey.New (GlobalHotkey.HotkeyModifier, Keys)에서 재정의 가능한 메서드를 호출하지 마십시오. 에는 해당 클래스에서 정의한 가상 메서드 에 대한 호출을 발생시키는 호출 체인이 포함되어 있습니다. 의도하지 않은 결과에 대해 다음 호출 스택을 검토
GlobalHotkey..ctor (GlobalHotkey + HotkeyModifier, 키) NativeWindow.CreateHandle (CreateParams을) : 무효 Object.GetHashCode() : INT32 컬러 .NET GlobalHorkey.vb 213
을
PS : 라인 213은 이것이다 :
나는이 충돌을 피하기 위해해야 할 일은Public Sub New(ByVal Modifier As HotkeyModifier, ByVal Key As Keys)
? NativeMethods 클래스로 UPDATE
... :
<DllImport("user32.dll", SetLastError:=True)> Public Shared Function RegisterHotKey( ByVal hWnd As IntPtr, ByVal id As Integer, ByVal fsModifiers As UInteger, ByVal vk As UInteger ) As <MarshalAs(UnmanagedType.Bool)> Boolean End Function
업데이트 2
이 전체 클래스입니다 :
#Region " Usage Examples " 'Public Class Form1 ' ''' <summary> ' ''' Stores the system-wide hotkey object. ' ''' </summary> ' Private WithEvents Hotkey As GlobalHotkey = Nothing ' ''' <summary> ' ''' Initializes a new instance of the <see cref="Form1"/> class. ' ''' </summary> ' Public Sub New() ' InitializeComponent() ' ' Registers a new global hotkey on the system. (Alt + Ctrl + A) ' Hotkey = New GlobalHotkey(GlobalHotkey.HotkeyModifier.Alt Or GlobalHotkey.HotkeyModifier.Ctrl, Keys.A) ' ' Replaces the current registered hotkey with a new global hotkey on the system. (Alt + Escape) ' Hotkey = New GlobalHotkey([Enum].Parse(GetType(GlobalHotkey.HotkeyModifier), "Alt", True), ' [Enum].Parse(GetType(Keys), "Escape", True)) ' End Sub ' ''' <summary> ' ''' Handles the Press event of the HotKey control. ' ''' </summary> ' Private Sub HotKey_Press(ByVal sender As Object, ByVal e As GlobalHotkey.HotKeyEventArgs) _ ' Handles Hotkey.Press ' MsgBox(e.ID) ' MsgBox(e.Key.ToString) ' MsgBox(e.Modifier.ToString) ' End Sub 'End Class #End Region #Region " Imports " Imports System.Runtime.InteropServices #End Region #Region " Global Hotkey " ''' <summary> ''' Class to perform system-wide hotkey operations. ''' </summary> Class GlobalHotkey Inherits NativeWindow Implements IDisposable #Region " API " ''' <summary> ''' Native API Methods. ''' </summary> Public Class NativeMethods ''' <summary> ''' Defines a system-wide hotkey. ''' </summary> ''' <param name="hWnd">The hWND.</param> ''' <param name="id">The identifier of the hotkey. ''' If the hWnd parameter is NULL, then the hotkey is associated with the current thread rather than with a particular window. ''' If a hotkey already exists with the same hWnd and id parameters.</param> ''' <param name="fsModifiers">The keys that must be pressed in combination with the key specified by the uVirtKey parameter ''' in order to generate the WM_HOTKEY message. ''' The fsModifiers parameter can be a combination of the following values.</param> ''' <param name="vk">The virtual-key code of the hotkey.</param> ''' <returns> ''' <c>true</c> if the function succeeds, otherwise <c>false</c> ''' </returns> <DllImport("user32.dll", SetLastError:=True)> Public Shared Function RegisterHotKey( ByVal hWnd As IntPtr, ByVal id As Integer, ByVal fsModifiers As UInteger, ByVal vk As UInteger ) As <MarshalAs(UnmanagedType.Bool)> Boolean End Function ''' <summary> ''' Unregisters a hotkey previously registered. ''' </summary> ''' <param name="hWnd">The hWND.</param> ''' <param name="id">The identifier of the hotkey to be unregistered.</param> ''' <returns> ''' <c>true</c> if the function succeeds, otherwise <c>false</c> ''' </returns> <DllImport("user32.dll", SetLastError:=True)> Public Shared Function UnregisterHotKey( ByVal hWnd As IntPtr, ByVal id As Integer ) As <MarshalAs(UnmanagedType.Bool)> Boolean End Function End Class #End Region #Region " Members " ''' <summary> ''' The hotkey modifier used in combination with the key. ''' </summary> <Flags> Public Enum HotkeyModifier As Integer ''' <summary> ''' The none ''' </summary> None = &H0 ''' <summary> ''' The alt key ''' </summary> Alt = &H1 ''' <summary> ''' The control key ''' </summary> Ctrl = &H2 ''' <summary> ''' The shift key ''' </summary> Shift = &H4 ''' <summary> ''' The win key ''' </summary> Win = &H8 End Enum ''' <summary> ''' Event that is raised when a hotkey is pressed. ''' </summary> Public Event Press As EventHandler(Of HotKeyEventArgs) ''' <summary> ''' Stores the Press Event Arguments. ''' </summary> Protected PressEventArgs As New HotKeyEventArgs ''' <summary> ''' Event arguments for the Press event. ''' </summary> Public Class HotKeyEventArgs : Inherits EventArgs ''' <summary> ''' The identifier of the hotkey. ''' </summary> ''' <value>The identifier.</value> Public Property ID As Integer ''' <summary> ''' The key used for the hotkey. ''' </summary> ''' <value>The key.</value> Public Property Key As Keys ''' <summary> ''' The key modifier used for the hotkey. ''' </summary> ''' <value>The modifier.</value> Public Property Modifier As HotkeyModifier End Class ''' <summary> ''' Exception that is thrown when a hotkey is already registered. ''' </summary> <Serializable> Public Class IsRegisteredException : Inherits Exception ''' <summary> ''' Initializes a new instance of the <see cref="IsRegisteredException"/> class. ''' </summary> Sub New() MyBase.New("Hotkey combination is already in use.") End Sub End Class #End Region #Region " Constructor " ''' <summary> ''' Creates a new system-wide hotkey. ''' </summary> ''' <param name="Modifier">The keys that must be pressed in combination with the specified key.</param> ''' <param name="Key">The key used for the hotkey.</param> ''' <exception cref="IsRegisteredException"></exception> <DebuggerStepperBoundary()> Public Sub New(ByVal Modifier As HotkeyModifier, ByVal Key As Keys) Me.CreateHandle(New CreateParams) Me.PressEventArgs.ID = GetHashCode() Me.PressEventArgs.Key = Key Me.PressEventArgs.Modifier = Modifier If Not NativeMethods.RegisterHotKey(Me.Handle, Me.PressEventArgs.ID, Me.PressEventArgs.Modifier, Me.PressEventArgs.Key) Then Throw New IsRegisteredException End If End Sub #End Region #Region " WndProc " ''' <summary> ''' Invokes the default window procedure associated with this window. ''' </summary> ''' <param name="m"> ''' A <see cref="T:System.Windows.Forms.Message" /> that is associated with the current Windows message. ''' </param> Protected Overrides Sub WndProc(ByRef m As Message) If m.Msg = 786 Then RaiseEvent Press(Me, Me.PressEventArgs) Else MyBase.WndProc(m) End If End Sub #End Region #Region " IDisposable " ''' <summary> ''' To detect redundant calls when disposing. ''' </summary> Private IsDisposed As Boolean = False ''' <summary> ''' Prevent calls to methods after disposing. ''' </summary> ''' <exception cref="System.ObjectDisposedException"></exception> Private Sub DisposedCheck() If Me.IsDisposed Then Throw New ObjectDisposedException(Me.GetType().FullName) End If End Sub ''' <summary> ''' Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. ''' </summary> Public Sub Dispose() Implements IDisposable.Dispose Dispose(True) GC.SuppressFinalize(Me) End Sub ' IDisposable ''' <summary> ''' Releases unmanaged and - optionally - managed resources. ''' </summary> ''' <param name="IsDisposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> Protected Overridable Sub Dispose(IsDisposing As Boolean) If Not Me.IsDisposed Then If IsDisposing Then NativeMethods.UnregisterHotKey(Me.Handle, Me.PressEventArgs.ID) End If End If Me.IsDisposed = True End Sub #End Region End Class #End Region
클래스를 'NotInheritable'으로 표시 할 수 있습니까? –
@CodeCaster 나는 CAXXX가 식별자라는 것을 알지 못했다. 나는 지금 내 조사를하고있다. 정보를 주셔서 감사합니다. – ElektroStudios
@Damien_The_Unbeliever 아니요. 왜냐하면 제가 오버라이드 가능한 메소드 (Dispose)를 가지고 있기 때문에, – ElektroStudios