スキップしてメイン コンテンツへ

 none
System.Drawing.Font.ToLogFont で System.ArgumentException が発生する。 RRS feed

  • 質問

  • C#でドロー系のツールを開発しています。開発したツールを実行するとまれに下記のような例外が発生します。

    再現性がないため調査が進まず困っています。原因としてどのようなことが考えられるでしょうか?

    環境はWindows XP SP3, ,Net 2.0SP2です。

     

    System.ArgumentException: 使用されたパラメータが有効ではありません。
       場所 System.Drawing.Font.ToLogFont(Object logFont, Graphics graphics)
       場所 System.Drawing.Font.ToLogFont(Object logFont)
       場所 System.Drawing.Font.ToHfont()
       場所 System.Windows.Forms.Control.FontHandleWrapper..ctor(Font font)
       場所 System.Windows.Forms.Control.get_FontHandle()
       場所 System.Windows.Forms.Control.SetWindowFont()
       場所 System.Windows.Forms.Control.OnHandleCreated(EventArgs e)
       場所 System.Windows.Forms.TabControl.OnHandleCreated(EventArgs e)
       場所 System.Windows.Forms.Control.WmCreate(Message& m)
       場所 System.Windows.Forms.Control.WndProc(Message& m)
       場所 System.Windows.Forms.TabControl.WndProc(Message& m)
       場所 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       場所 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       場所 System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

    2010年4月15日 10:46

回答

  • .NET Framework のソースは Reference Source Code Center のサイトからダウンロードできます。

     .NET Framework Libraries
     http://referencesource.microsoft.com/netframework.aspx

    今回の場合だと、Product Name は .NET ですかね。
    2010年4月16日 6:36
  • (下記の)参考サイトを元に、同様なエラーになるコードを作ってみました。一例として御参考までです。
    この場合の回避策は、これも参考サイトに書いてありますが
    label1.Font = font;
    label1.Font = new Font(font, font.Style);
    のように using(){} の影響を受けないようにすることです。

            private void button1_Click(object sender, EventArgs e)
            {
                using (Font font = new Font("Tahoma", 18F))
                {
                    label1.Font = font; //using してある font を設定。
                }

                LOGFONT obj = new LOGFONT();
                this.label1.Font.ToLogFont(obj); //←ここでエラー発生
            }
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public class LOGFONT
        {
            public int lfHeight = 0;
            public int lfWidth = 0;
            public int lfEscapement = 0;
            public int lfOrientation = 0;
            public int lfWeight = 0;
            public byte lfItalic = 0;
            public byte lfUnderline = 0;
            public byte lfStrikeOut = 0;
            public byte lfCharSet = 0;
            public byte lfOutPrecision = 0;
            public byte lfClipPrecision = 0;
            public byte lfQuality = 0;
            public byte lfPitchAndFamily = 0;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string lfFaceName = string.Empty;
        }

    参考サイト
    B135930 : System.ArgumentException was unhandled: Parameter is not valid: ToLogFont
    http://community.devexpress.com/forums/t/78745.aspx

    2010年4月16日 9:10

すべての返信

  • ToLogFont メソッドの logFont 引数に何を渡したのかは気になるところですね。
    2010年4月15日 18:24
  • MSDN ライブラリを見ると ArgumentNullException 例外の条件は
    「graphics が null です。」となっていますね。
    一歩進んだことになるかな。。

    Font.ToLogFont メソッド (Object, Graphics)
    http://msdn.microsoft.com/ja-jp/library/2k3dsz1b(v=VS.100).aspx
    2010年4月16日 1:41
  • totojo様、anningo様

    返信ありがとうございます。

    発生している例外はArgumentExceptionで、ArgumentNullExceptionではないことから、

    「ToLogFontに渡したgraphicsは、nullでない」と考えるべきでしょうか?

    ToLogFontのソースが見れれば良いのですが。。。

     

    2010年4月16日 4:37
  • うおっ!すみません見間違えてました

    ArgumentException なら Null ではなさそうですね

    Null かどうかを先に見ているだろうという憶測に過ぎませんが…

    ソースを見るのであれば Visual Studio だと見られるかもです

    2010年4月16日 4:48
  • .NET Framework のソースは Reference Source Code Center のサイトからダウンロードできます。

     .NET Framework Libraries
     http://referencesource.microsoft.com/netframework.aspx

    今回の場合だと、Product Name は .NET ですかね。
    2010年4月16日 6:36
  • (下記の)参考サイトを元に、同様なエラーになるコードを作ってみました。一例として御参考までです。
    この場合の回避策は、これも参考サイトに書いてありますが
    label1.Font = font;
    label1.Font = new Font(font, font.Style);
    のように using(){} の影響を受けないようにすることです。

            private void button1_Click(object sender, EventArgs e)
            {
                using (Font font = new Font("Tahoma", 18F))
                {
                    label1.Font = font; //using してある font を設定。
                }

                LOGFONT obj = new LOGFONT();
                this.label1.Font.ToLogFont(obj); //←ここでエラー発生
            }
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public class LOGFONT
        {
            public int lfHeight = 0;
            public int lfWidth = 0;
            public int lfEscapement = 0;
            public int lfOrientation = 0;
            public int lfWeight = 0;
            public byte lfItalic = 0;
            public byte lfUnderline = 0;
            public byte lfStrikeOut = 0;
            public byte lfCharSet = 0;
            public byte lfOutPrecision = 0;
            public byte lfClipPrecision = 0;
            public byte lfQuality = 0;
            public byte lfPitchAndFamily = 0;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string lfFaceName = string.Empty;
        }

    参考サイト
    B135930 : System.ArgumentException was unhandled: Parameter is not valid: ToLogFont
    http://community.devexpress.com/forums/t/78745.aspx

    2010年4月16日 9:10
  • totojo様、anningo様
    返信ありがとうございます。

    Reference Source Code Center のサイトからダウンロードしたFontクラスのソースには
    System.ArgumentExceptionをスローする部分は有りませんでした。
    .Netのバージョンが違うのだと思います。

    開発した部分のソースを検索したところusing文でFontを使っている箇所は見当たりませんでした。

    MSDNのサポートを受けることも検討していますが、この程度の情報で受け付けてもらえるものでしょうか?

    2010年4月20日 9:29
  • Reference Source Code Center のサイトからダウンロードしたFontクラスのソースには
    System.ArgumentExceptionをスローする部分は有りませんでした。
    .Netのバージョンが違うのだと思います。


    そんなことはありません。公開されているソースは .NET 3.5 のものですので、CLR 2.0 ベースになります。
    バグ修正などの可能性もあり、多少の違いはあるかもしれませんが、SP レベルでゴッソリとソースが変わることはないはずです。

    System.Drawing.Font.ToLogFont(Object logFont, Graphics graphics) の終わりに SafeNativeMethods.Gdip.StatusException(status) を呼んでいますが、
    この中で status の値を見て ArgumentException をスローしていますね。(インライン展開の関係でスタックトレースには出てこないかもしれません。)
    明示的に Font クラスのメソッドを呼んでいないのかもしれませんが、Font オブジェクトが壊れているのではないかと思われます。

    スタックトレースの中に TabControl が出てくるのが気になるのですが、TabControl にコードでフォントをセットしている、ということはありませんか?
    コードでフォントをセットする際に、1つの Font クラスのインスタンスを使い回していると、この現象が出るように思います。
    コードで動的にフォントをセットする際には、インスタンスを生成してセットする必要があります。

    2010年4月20日 10:47
  • 開発した部分のソースを検索したところusing文でFontを使っている箇所は見当たりませんでした。

     念のため繰り返しますが using は一例です。
    しかも再現性がないということなので
    そういうわかりやすいバグではない可能性はあるでしょうね。

    MSDNのサポートを受けることも検討していますが、この程度の情報で受け付けてもらえるものでしょうか?

    受け付けてもらえたとして、
    現象が再現するミニマムコードを要求されるかもしれません。
    再現性がないということなので、再現する条件の割り出しも必要になりそうです。

    そして、再現する条件の割り出しや、
    ミニマムコードを作成しているうちに自己解決しちゃうものなんですよね。

    現状のままだと MSDN サポートではなく↓の業務範囲になるかもしれません。 アドバイザリーサービス
    http://www.microsoft.com/japan/services/support/advisory_service.mspx

    2010年4月21日 0:57