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 デバッガに設定されなければなりません。
----------------------------------------------------------
何か解決策など無いでしょうか?
エラーメッセージ長くてすいません。
> test.cpp:line 42
ここがエラーの箇所です。
42行目のコードは何ですか?
> System::Windows::Forms::MouseEventArgs * e
と
> void Asd::Abc::load(System::Windows::Forms::PaintEventArgs * e
って、大丈夫でしたっけ?
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();
}
みたいにする。
> 大丈夫でしたっけ?
ダメならコンパイルエラーが出そうなもんだけどなぁ…
すいません、ソースコードミスってました。
----------------------------------------------------------
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はメンバ変数です。)
> temp_eはメンバ変数です。
はやっていいことなんだろうか。
ものすごく気持ち悪いんですけど。
ためしに
> Blue 2005/12/20(火) 01:55:24
のように書き換えてエラーが出ないかチェックしてくれませんか?
>> temp_eはメンバ変数です。
>はやっていいことなんだろうか。
>
>ものすごく気持ち悪いんですけど。
>ためしに
>> Blue 2005/12/20(火) 01:55:24
>のように書き換えてエラーが出ないかチェックしてくれませんか?
やってみましたら、エラーが出ました。
あと、何故か自己解決してしまいました。
すみませんでした。
> やってみましたら、エラーが出ました。
どんなエラーがでたか書いてほしいです。
でないと、私は間違った認識をしたままになってしまうので。
> >> temp_eはメンバ変数です。
> >はやっていいことなんだろうか。
はものすごく気になるが。。。
# そのようなサンプルをみたことないような。(検索が悪いだけかも)
> > >> 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を基に作られると推測されるわけですから……。
YuOさん
解説ありがとうございました。
ということは、どうして
> あと、何故か自己解決してしまいました。
したのか謎ですね。
特にソースを変更したとかかかれていませんし。
# とりあえず動いたからOKというのが一番怖いですが。
ツイート | ![]() |