ある物体の円運動をタイマーを使って描画させるプログラムを作っています。xーy平面での運動を描画するウィンドウ、xーz平面での描画のウィンドウ、yーz平面での描画のウィンドウ計3つ出して、座標データのファイルを選択すると、3つのウィンドウに円運動が描画される流れにしました。実行できたのですが、なぜか運動の途中(全座標データがプロットされる前)に物体塗られている色が白色になったりするバグといいますかエラーが起きます。ウィンドウを一つだけ出して、実行した時は全座標データがプロットされるまで問題なく描画されました。ですが3つウィンドウを出すとこのような謎の現象が起きます。何が原因なのか検討もつかず、どなたかアドバイスいただけないでしょうか、、? 開発環境は、Visual studio C++です。下は正常な描画の時の写真と、エラー(白くなる)時の写真です。状況がイメージしやすいかなと思い添付します。
ソースコードに関しては、三つのウィンドウプロシージャのうち、xy平面についてのもの(WndProc3.cpp)、メモリ軸を描画する関数(disp_axes2.cpp)、xy座標を描画する関数(disp_xy.cpp)を添付しておきます。xz、yz、についても、これとコードはほぼ同じです。残り二つのウィンドウプロシージャと、xz、yz座標を描画する関数のコードも載せたかったのですが、最大文字数に達してしまい、全てを添付できませんでした。ご了承ください。
WndProc3.cpp #include "kobayashi.h" #define ID_MYTIMER 1 LRESULT CALLBACK WndProc3( HWND hWnd3, UINT msg, WPARAM wp, LPARAM lp ) { HDC hdc; PAINTSTRUCT ps; HPEN hPen3,h01dPen3; HBRUSH hBrush3, h01dBrush3; RECT rect;// ウィンドウの描画領域を格納する構造体 switch (msg) { case WM_CREATE: SetTimer(hWnd3, 1, 50, NULL); break; case WM_TIMER: if (wp != 1) return (DefWindowProc(hWnd3, msg, wp, lp)); k +=1; InvalidateRect(hWnd3, NULL, TRUE); break; case WM_PAINT: hdc = BeginPaint( hWnd3, &ps );// 画面のデバイスコンテキストを得て描画 GetClientRect( hWnd3, &rect );// ウィンドウの描画領域を得る PatBlt( hdc, 0, 0, rect.right, rect.bottom, BLACKNESS );// 最初に黒く塗りつぶす hPen3 = CreatePen(PS_SOLID, 10, RGB(0,160,233)); h01dPen3 = (HPEN)SelectObject(hdc, hPen3); hBrush3 = CreateSolidBrush(RGB(0,160,233)); h01dBrush3 = (HBRUSH)SelectObject(hdc, hBrush3); Ellipse( hdc, 293.5-7.479, 281-7.479, 293.5+7.479, 281+7.479); //ウィンドウの中心にシアンの色の円(地球)を描画 DeleteObject(hPen3); if ( IsDlgButtonChecked( hDlg, IDC_CHECK_DISPLAY1 ) == BST_CHECKED ) disp_xy( hdc, rect, hDlg, 1 );// データを表示する if ( IsDlgButtonChecked( hDlg, IDC_CHECK_DISPLAY2 ) == BST_CHECKED ) disp_xy( hdc, rect, hDlg, 2 );// データを表示する if ( IsDlgButtonChecked( hDlg, IDC_CHECK_DISPLAY3 ) == BST_CHECKED ) disp_xy( hdc, rect, hDlg, 3 );// データを表示する if ( IsDlgButtonChecked( hDlg, IDC_CHECK_DISPLAY4 ) == BST_CHECKED ) disp_xy( hdc, rect, hDlg, 4 );// データを表示する disp_axes2( hdc, rect ); EndPaint( hWnd3, &ps );// 描画終り ReleaseDC( hWnd3, hdc );// 画面のデバイスコンテキストhdcを破棄する break; case WM_LBUTTONDOWN: KillTimer(hWnd5, 1); KillTimer(hWnd4, 1); KillTimer(hWnd3, 1); KillTimer(hWnd2, 1); sprintf_s(szBuf, 256, "月面高度%12.2ekm %d番目のデータ",EQL_MOON[k]-1737,k); MessageBox(NULL, szBuf, "位置情報", MB_OK); break; case WM_RBUTTONDOWN: SendMessage(hWnd5, WM_CREATE, 0,0); SendMessage(hWnd4, WM_CREATE, 0,0); SendMessage(hWnd3, WM_CREATE, 0,0); SendMessage(hWnd2, WM_CREATE, 0,0); break; case WM_DESTROY: KillTimer(hWnd3, 1); PostQuitMessage(0); break; default: return (DefWindowProc(hWnd3, msg, wp, lp)); } return 0; }
disp_xy.cpp #include "kobayashi.h" #define _USE_MATH_DEFINES #include <math.h> // xy平面にデータを表示する関数 BOOL disp_xy( HDC hdc, RECT rect, HWND hDlg, int channel ) { COLORREF color; if ( (channel < 1) || (channel > 4) ) return FALSE;// チャンネル指定が間違っていた場合 // プロット色を決める if ( channel == 1 ) color = RGB(255,153,0);// チャンネル1はYellow if ( channel == 2 ) color = RGB(228,0,127);// チャンネル2はMagenta if ( channel == 3 ) color = RGB(0,160,233);// チャンネル3はCyan if ( channel == 4 ) color = RGB(51,153,102);// チャンネル4は緑 HPEN hPen_xy = CreatePen( PS_SOLID, 9, color); SelectObject( hdc, hPen_xy );// hdcで上記のペンを使うために選ぶ HBRUSH hBrush_xy, h01dBrush_xy; hBrush_xy = CreateSolidBrush(color); h01dBrush_xy = (HBRUSH)SelectObject(hdc, hBrush_xy); int nop= rect.right - rect.left + 1; double ppd= (rect.bottom - rect.top)/10.0;// 縦方向1div当たり何ピクセルか if ( channel == 4 ) j[k] = (int)( ((double)rect.right/2.0) + ((double)XEQL[k]/100000*(nop/10.0)+ 0.5) ); if ( channel == 1 ) j[k] = (int)( ((double)rect.right/2.0) + ((double)XMOON[k]/100000*(nop/10.0)+ 0.5) ); if ( channel == 2 ){ j[k] = (int)( 293.5/*((double)rect.right/2.0)*/ + 275*cos(a3[k]) ); if(XSUN[k]<0) j[k] = 293.5-(j[k]-293.5); } if ( channel == 4 ) y[k] = (int)( ((double)rect.bottom/2.0) - ((double)YEQL[k]/100000)*ppd + 0.5 ); if ( channel == 1 ) y[k] = (int)( ((double)rect.bottom/2.0) - ((double)YMOON[k]/100000)*ppd + 0.5 ); if ( channel == 2 ){ y[k] = (int)( 281-275*sin(a3[k]) ); if(XSUN[k]<0) y[k] = 281+(281-y[k]); if ( channel== 1 ) Ellipse(hdc, j[k]-2.039, y[k]-2.039, j[k]+2.039, y[k]+2.039); //黄色の円(月)を描画 if ( channel== 4 ) Ellipse(hdc, j[k]-0.1, y[k]-0.1, j[k]+0.1, y[k]+0.1); //緑の円(探査機)を描画 if ( channel== 2 ) { HPEN hPen_SUN = CreatePen( PS_SOLID, 0, RGB(228,0,127)); SelectObject( hdc, hPen_SUN ); HBRUSH hBrush_SUN, h01dBrush_SUN; hBrush_SUN = CreateSolidBrush( RGB(228,0,127)); h01dBrush_SUN = (HBRUSH)SelectObject(hdc, hBrush_SUN); if(XSUN[k]>0 && YSUN[k]>0){ POINT pt[3]={{j[k],y[k]}, {j[k]-15*cos(a3[k]-M_PI/12),y[k]+15*sin(a3[k]-M_PI/12)}, {j[k]-15*sin(5*M_PI/12-a3[k]),y[k]+15*cos(5*M_PI/12-a3[k])}}; Polygon(hdc, pt, 3); } if(XSUN[k]<0 && YSUN[k]>0){ POINT pt[3]={{j[k],y[k]}, {j[k]+15*sin(a3[k]+5*M_PI/12),y[k]+15*cos(a3[k]+5*M_PI/12)}, {j[k]+15*cos(-M_PI/12-a3[k]),y[k]+15*sin(-M_PI/12-a3[k])}}; Polygon(hdc, pt, 3); } if(XSUN[k]<0 && YSUN[k]<0){ POINT pt[3]={{j[k],y[k]}, {j[k]+15*cos(a3[k]-M_PI/12),y[k]-15*sin(a3[k]-M_PI/12)}, {j[k]+15*sin(5*M_PI/12-a3[k]),y[k]-15*cos(5*M_PI/12-a3[k])}}; Polygon(hdc, pt, 3); DeleteObject( hPen_SUN ); } //太陽の方向を三角形(矢印)で描画 } DeleteObject( hPen_xy );// ペンを破棄する return TRUE;// 戻り値TRUEを返す }
#include "kobayashi.h" // ウィンドウ中に目盛軸を描く関数 BOOL disp_axes2( HDC hdc, RECT rect ) { int i, x, y;// forで使う変数iと、縦横のグリッド線を引くときのx座標とy座標 HPEN hPen_a = CreatePen( PS_DOT, 0, RGB(0,0,0));// 黒色、破線のペンを作る(注:白と黒の破線になる) SelectObject( hdc, hPen_a );// hdcで上記のペンを使うために選ぶ double hdiv = (double)(rect.right - rect.left)/10.0; double vdiv = (double)(rect.bottom - rect.top)/10.0; for ( i=0; i<=10; i++ ) {// 縦線を描く x = (int)( hdiv * (double)i + 0.5 ); MoveToEx(hdc, x, rect.top, NULL);//ペンを移動する LineTo(hdc, x, rect.bottom);//線を引く if ( i == 0 ) TextOut(hdc, x, rect.bottom-20, "-5*10^5",7); if ( i == 5 ) TextOut(hdc, x, rect.bottom-20, "0",1); if ( i == 9 ) TextOut(hdc, x, rect.bottom-20, "5*10^5",6); } for ( i=0; i<=10; i++ ) {// 横線を描く y = (int)( vdiv * (double)i + 0.5 ); MoveToEx(hdc, rect.left, y, NULL); LineTo(hdc, rect.right, y); if ( i == 0 ){ TextOut(hdc, rect.left, y, "5*10^5",6); } if ( i == 5 ){ TextOut(hdc, rect.left, y, "0",1); } } DeleteObject( hPen_a );// ペンを破棄する return TRUE; }
回答2件
あなたの回答
tips
プレビュー