C# 「CA1060 P/Invoke メソッドであるため、NativeMethods、SafeNativeMethods または UnsafeNativeMethods に名前指定されたクラスで定義しなければなりません。」

  • デル株式会社
  • Visual Studioコード分析の警告

    Visual Studioには、コード分析機能がありコード分析を行うことで、コードが綺麗になる。

    プログラム分析

    C#で、下記のようなコードを書いて、Visual Studioのコード分析を実行すると、
    警告が出た。

    
    using System.Runtime.InteropServices;
    
    [DllImport("USER32.DLL")]
    private static extern IntPtr GetSystemMenu(IntPtr hWnd, UInt32 bRevert);
    
    [DllImport("USER32.DLL")]
    private static extern  UInt32 RemoveMenu(IntPtr hMenu, UInt32 nPosition, UInt32 wFlags);
    
    public const UInt32 SC_CLOSE     = 0x0000F060;
    public const UInt32 MF_BYCOMMAND = 0x00000000;
    
    // システムメニュー(フォームの)ハンドル取得する
    IntPtr hMenu = NativeMethods.GetSystemMenu( hWnd, 0 );
    
    // [×]ボタンを無効化する。
    RemoveMenu( hMenu, NativeMethods.SC_CLOSE, NativeMethods.MF_BYCOMMAND );
    
    

    【警告内容】
    警告 CA1060 ’GetSystemMenu(IntPtr, uint)’ は P/Invoke メソッドであるため、NativeMethods、SafeNativeMethods または UnsafeNativeMethods に名前指定されたクラスで定義しなければなりません。

    なんじゃこれ?となるわけなんだけど、MSのヘルプを見ると、
    デザイン上の警告」らしい。



    プログラムの修正

    MSが警告するなら、修正しないと。。
    でっ、上記ページのリンクから「CA1060: P/Invoke を NativeMethods クラスに移動します」を参照して修正してみた。

    
    using System.Runtime.InteropServices;
    
        /// <summary>
        /// NativeMethods(アンマネージまとめるクラス)
        /// </summary>
      /// <returns>
        /// MSのヘルプ確認
        /// https://msdn.microsoft.com/library/ms182161.aspx
        /// 
        /// GetSystemMenu ヘルプ
        /// https://msdn.microsoft.com/ja-jp/library/cc364748.aspx
        /// 
        /// RemoveMenu ヘルプ
        /// https://msdn.microsoft.com/ja-jp/library/cc410998.aspx
        /// </returns>
        internal static class NativeMethods
        {
            [DllImport("USER32.DLL")]
            internal static extern IntPtr GetSystemMenu(IntPtr hWnd, UInt32 bRevert);
    
            [DllImport("USER32.DLL")]
            internal static extern UInt32 RemoveMenu(IntPtr hMenu, UInt32 nPosition, UInt32 wFlags);
    
            public const UInt32 SC_CLOSE     = 0x0000F060;
            public const UInt32 MF_BYCOMMAND = 0x00000000;
        }
    
        /// <summary>
        /// API使ってみますクラス
        /// </summary>
        /// <returns>
        /// MSのヘルプ確認
        /// https://msdn.microsoft.com/library/ms182161.aspx
        /// </returns>
        public static class TestWin32Apis
        {
    
            /// <summary>
            /// システムメニューの[×]ボタンを無効化する。
            /// </summary>
            /// <param name="hWnd">
            /// ウィンドウメニューを保持しているウィンドウ(ダイアログ)のハンドルを指定する。
            /// </param>
            /// <returns>
            /// エラーとなった場合は無視する。
            /// 
            /// </returns>
            public static void TestAppRemoveMenu( IntPtr hWnd )
            {
                // システムメニュー(フォームの)ハンドル取得する
                // 第二引数はヘルプ参照
                IntPtr hMenu = NativeMethods.GetSystemMenu( hWnd, 0 );
    
                // [×]ボタンを無効化する。
                // 戻り値みてエラー処理したほうがいいよね。。
                NativeMethods.RemoveMenu( hMenu, NativeMethods.SC_CLOSE, NativeMethods.MF_BYCOMMAND );
            }
        }
    
    
        // **************************************
        // 実行側
        // **************************************
    
        /// <summary>
        /// ダイアログクラスのこんすとらくた
        /// </summary>
      /// <returns>
        public frmSyaindetail()
        {
            InitializeComponent();
            
            // コントロールボックスの[閉じる]ボタンの無効化実行
            TestWin32Apis.TestAppRemoveMenu( this.Handle );
        }
    
    

    まぁ、NativeMethods に、突っ込んどけって話。

    警告は、消えたらしい。

    関連記事

    ページ上部へ戻る