エラーについて

解決


ghth  2005-12-20 07:31:21  No: 59994

Win XP Pro,Visual C++ .NET 2003,Windows フォーム アプリケーションでやっています。

今回、指定したファイルの一部を切り取って
指定したピクチャボックスにその部分を水色で塗りつぶして
貼り付けるといった動作をするようにプログラムを書いてみました。

下がソースです。
----------------------------------------------------------
void Asd::Abc::load(System::Windows::Forms::PaintEventArgs *  e,int x,int y,int mode)
{
    System::Drawing::Image* img=System::Drawing::Image::FromFile("a.gif");

    // デバイス ピクセルを長さの単位に指定
    System::Drawing::GraphicsUnit units=System::Drawing::GraphicsUnit::Pixel;
    // Penオブジェクトを作成
    System::Drawing::Pen* emppen=new Pen(System::Drawing::Color::FromArgb(0,255,255));
    // 背景色で塗りつぶす
    System::Drawing::Rectangle emprect(x,y,32,32);
    e->Graphics->DrawRectangle(emppen,emprect);
    // 長方形を指定
    System::Drawing::Rectangle srcrect(0,0,32,32);
    // 指定した位置に貼り付け
    if(mode==2){
        System::Drawing::Rectangle tiprect(x,y,x+16,y+16);
        e->Graphics->DrawImage(img,tiprect,srcrect,units);
    }
    else {
        e->Graphics->DrawImage(img,x,y,srcrect,units);
    }
    return;
}
----------------------------------------------------------
private: System::Void Picture_MouseDown(System::Object *  sender, System::Windows::Forms::MouseEventArgs *  e)
        {
            Abc::Asd::load(e,0,0,2);
        }
----------------------------------------------------------
このソースでコンパイルしても、エラーが出てきません。

しかし、実行すると、「使用されたパラメータが無効です」と
エラーのダイアログが出てきてしまいます。

ダイアログの詳細:
----------------------------------------------------------
このダイアログ ボックスではなく、Just-In-Time (JIT) デバッグを呼び出すための詳細については、 
このメッセージの最後を参照してください。

************** 例外テキスト **************
System.ArgumentException: 使用されたパラメータが無効です。
   at System.Drawing.Graphics.CheckErrorStatus(Int32 status)
   at System.Drawing.Graphics.DrawRectangle(Pen pen, Int32 x, Int32 y, Int32 width, Int32 height)
   at System.Drawing.Graphics.DrawRectangle(Pen pen, Rectangle rect)
   at Asd.Abc.load(SByte moji, PaintEventArgs e, Int32 x, Int32 y, Int32 mode) in c:\documents and settings\-----\my documents\visual studio projects\test\test.cpp:line 42
   at Test.Form1.Map_MouseDown(Object sender, MouseEventArgs e) in c:\documents and settings\-----\my documents\visual studio projects\test\form1.h:line 245
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

************** 読み込まれたアセンブリ **************
mscorlib
    アセンブリ バージョン : 1.0.5000.0
    Win32 バージョン : 1.1.4322.2032
    コードベース : file:///c:/windows/microsoft.net/framework/v1.1.4322/mscorlib.dll
----------------------------------------
Test
    アセンブリ バージョン : 1.0.2178.35023
    Win32 バージョン : 
    コードベース : file:///C:/Documents%20and%20Settings/-----/My%20Documents/Visual%20Studio%20Projects/Test/Debug/Test.exe
----------------------------------------
System.Windows.Forms
    アセンブリ バージョン : 1.0.5000.0
    Win32 バージョン : 1.1.4322.2032
    コードベース : file:///c:/windows/assembly/gac/system.windows.forms/1.0.5000.0__b77a5c561934e089/system.windows.forms.dll
----------------------------------------
System
    アセンブリ バージョン : 1.0.5000.0
    Win32 バージョン : 1.1.4322.2032
    コードベース : file:///c:/windows/assembly/gac/system/1.0.5000.0__b77a5c561934e089/system.dll
----------------------------------------
System.Drawing
    アセンブリ バージョン : 1.0.5000.0
    Win32 バージョン : 1.1.4322.2032
    コードベース : file:///c:/windows/assembly/gac/system.drawing/1.0.5000.0__b03f5f7f11d50a3a/system.drawing.dll
----------------------------------------
System.Xml
    アセンブリ バージョン : 1.0.5000.0
    Win32 バージョン : 1.1.4322.2032
    コードベース : file:///c:/windows/assembly/gac/system.xml/1.0.5000.0__b77a5c561934e089/system.xml.dll
----------------------------------------
System.Drawing.resources
    アセンブリ バージョン : 1.0.5000.0
    Win32 バージョン : 1.1.4322.573
    コードベース : file:///c:/windows/assembly/gac/system.drawing.resources/1.0.5000.0_ja_b03f5f7f11d50a3a/system.drawing.resources.dll
----------------------------------------
System.Windows.Forms.resources
    アセンブリ バージョン : 1.0.5000.0
    Win32 バージョン : 1.1.4322.573
    コードベース : file:///c:/windows/assembly/gac/system.windows.forms.resources/1.0.5000.0_ja_b77a5c561934e089/system.windows.forms.resources.dll
----------------------------------------

************** JIT デバッグ **************
Just-In-Time (JIT) デバッグを有効にするには、
このアプリケーション、またはコンピュータ (machine.config) の構成ファイルの
jitDebugging 値を system.windows.forms セクションで設定しなければなりません。
アプリケーションはまた、デバッグを
有効にしてコンパイルされなければなりません。

例 :

<configuration>
    <system.windows.forms jitDebugging="true" />
</configuration>

JIT デバッグが有効なときは、このダイアログで処理するよりも、ハンドルされていない例外はすべて

コンピュータに登録された JIT デバッガに設定されなければなりません。

----------------------------------------------------------

何か解決策など無いでしょうか?

エラーメッセージ長くてすいません。


シャノン  2005-12-20 09:41:08  No: 59995

> test.cpp:line 42

ここがエラーの箇所です。
42行目のコードは何ですか?


Blue  2005-12-20 10:36:00  No: 59996

> System::Windows::Forms::MouseEventArgs *  e

> void Asd::Abc::load(System::Windows::Forms::PaintEventArgs *  e
って、大丈夫でしたっけ?


Blue  2005-12-20 10:55:24  No: 59997

Graphicsを得るためだけだったら、関数の引数を変更して

void Asd::Abc::load(System::Drawing::Graphics*  g,int x,int y,int mode)
にして、
e->Graphicsを変更する。
(Graphicsプロパティを持つのはPaintEventArgsであって、MouseEventArgsではない)

呼び出しは、
private: System::Void Picture_MouseDown(System::Object *  sender, System::Windows::Forms::MouseEventArgs *  e)
        {
            System::Drawing::Graphics* g = pictureBox1->CreateGraphics();
            Abc::Asd::load(g,0,0,2);
            g->Dispose();
        }
みたいにする。


シャノン  2005-12-21 04:06:10  No: 59998

> 大丈夫でしたっけ?

ダメならコンパイルエラーが出そうなもんだけどなぁ…


ghth  2005-12-21 08:44:35  No: 59999

すいません、ソースコードミスってました。

----------------------------------------------------------
private: System::Void Picture_MouseDown(System::Object *  sender, System::Windows::Forms::MouseEventArgs *  e)
        {
            Abc::Asd::load(e,0,0,2);
        }
----------------------------------------------------------

のところを、

----------------------------------------------------------
private: System::Void Picture_Paint(System::Object *  sender, System::Windows::Forms::PaintEventArgs *  e)
        {
            temp_e=e;
        }
----------------------------------------------------------
private: System::Void Picture_MouseDown(System::Object *  sender, System::Windows::Forms::MouseEventArgs *  e)
        {
            Abc::Asd::load(temp_e,0,0,2);
        }

----------------------------------------------------------

に直してください。(temp_eはメンバ変数です。)


Blue  2005-12-21 08:47:43  No: 60000

> temp_eはメンバ変数です。
はやっていいことなんだろうか。

ものすごく気持ち悪いんですけど。
ためしに
> Blue 2005/12/20(火) 01:55:24
のように書き換えてエラーが出ないかチェックしてくれませんか?


ghth  2005-12-28 07:16:03  No: 60001

>> temp_eはメンバ変数です。
>はやっていいことなんだろうか。
>
>ものすごく気持ち悪いんですけど。
>ためしに
>> Blue 2005/12/20(火) 01:55:24
>のように書き換えてエラーが出ないかチェックしてくれませんか?

やってみましたら、エラーが出ました。

あと、何故か自己解決してしまいました。
すみませんでした。


Blue  2005-12-28 09:59:49  No: 60002

> やってみましたら、エラーが出ました。
どんなエラーがでたか書いてほしいです。
でないと、私は間違った認識をしたままになってしまうので。

> >> temp_eはメンバ変数です。
> >はやっていいことなんだろうか。
はものすごく気になるが。。。
# そのようなサンプルをみたことないような。(検索が悪いだけかも)


YuO  2005-12-29 01:44:24  No: 60003

> > >> temp_eはメンバ変数です。
> > >はやっていいことなんだろうか。
> はものすごく気になるが。。。

えーっと,PaintEventArgsはIDisposableを継承しています。
なので,Control::OnPaintを抜けた時点でPaintEventArgs::Disposeが呼ばれると考えるべきでしょう。
# PaintEventArgsを作ったのはOnPaintを呼ぶ存在。
さらに,その時点でGraphics::Disposeも呼ばれると考えられるので,
e->Graphicsを保持しておくのもだめです。
# ちなみに,Reflectorによる調査も,それを裏付けています。

なので,temp_eに代入すること自体はやっても問題ないが,
代入されたtemp_eを利用することは大問題ということになります。

まぁ,Win32に立ち返って考えれば当然で,
OnPaintはWM_PAINTによって発生し,
OnPaintにくるPaintEventArgsのGraphicsは,
BeginPaintによって得られたHDCを基に作られると推測されるわけですから……。


Blue  2005-12-29 03:09:50  No: 60004

YuOさん
解説ありがとうございました。

ということは、どうして
> あと、何故か自己解決してしまいました。
したのか謎ですね。
特にソースを変更したとかかかれていませんし。
# とりあえず動いたからOKというのが一番怖いですが。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加