MFC を使用してインタラクティブなグラフを作成する必要があります
これはイコライザー コントロールのようなもので、ユーザーはイコライザー上のポイントをクリックしてドラッグし、y 軸の値を変更できるはずです。
私もMFCを学び始めたばかりです
ここまでは、ダイアログ ボックスにグラフを描画する関数を使用CPaintDC
してきました。OnPaint()
今のところ、グラフは非常に単純で、四角形の境界が白で塗りつぶされ、グラフ上に 4 つの点があります。OnMouseMove()
カーソルがグラフ領域内にあるかどうかを知るために関数を使用OnLButtonDown()
し、ユーザーがクリックした場所を知るために関数を使用します。ユーザーがその位置でグラフ ポイントの y 軸の値を変更したいことを意味する位置をクリックした場合は、内部を使用Invalidate()
して呼び出して図を再描画します。OnPaint()
OnLButtonDown()
. ただし、グラフを更新する必要があるたびに、ちらつきが見られます。今は問題ありませんが、このグラフを拡張して、少なくとも 64 個の変更可能なポイントがあり、移動したい場所をクリックするだけでなく、ドラッグしてポイントの y 軸の値を変更できるようにする必要があります。ポイントの数を増やし、グラフの外観を複雑にすると、ちらつきの問題は増えますか? グラフには、後で軸、グリッド線、ラベルなどが必要になります。ちらつきは気にする必要がありますか?それを防ぐ方法はありますか?
----UPDATE ----
これは、CodeDreamerの提案をどのように理解したかに応じて、OnPaint()関数を更新した方法です
void Cgraph_on_dlgboxDlg::OnPaint()
{
CPaintDC dc_blt(this);
CDC dc;
CBitmap bmpDC;
CRect rcClient;
GetClientRect(rcClient);
if (IsIconic())
{
// CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
dc.CreateCompatibleDC(&dc);
bmpDC.CreateCompatibleBitmap(&dc, theGraph.width,theGraph.height );
dc.SelectObject(&bmpDC);
CPen pen;
COLORREF pencolour = RGB(0, 0, 0);
COLORREF brushcolour = RGB(0, 0, 255);
COLORREF graphColour = RGB(0, 0, 150);
// Draw boarder
pen.CreatePen(PS_SOLID, 3, pencolour);
// CBrush brush(HS_CROSS, brushcolour);
dc.SetBkMode(TRANSPARENT);
dc.SetMapMode(MM_TEXT);
dc.SetViewportOrg(theGraph.x1, theGraph.y1);
dc.SelectObject(&pen);
// Draw graph boundary
CPoint point1(0,0);
point1.x = 0;
point1.y = 0;
CPoint point2(0,0);
point2.x = point1.x + theGraph.width;
point2.y = point1.y + theGraph.height;
dc.Rectangle(CRect(point1, point2));
pen.DeleteObject();
// Draw Horizontal at 0
pen.CreatePen(PS_SOLID, 1, pencolour);
dc.SelectObject(&pen);
dc.MoveTo(0, theGraph.height - ORG_DIST_FROM_BOTTOM);
dc.LineTo(theGraph.width, theGraph.height - ORG_DIST_FROM_BOTTOM);
pen.DeleteObject();
dc.SetViewportOrg(theGraph.x1, theGraph.y1 + theGraph.height - ORG_DIST_FROM_BOTTOM); // dc.SetViewportOrg() always works relative to the clinet origin
// Draw graph line
pen.CreatePen(PS_SOLID, 2, graphColour);
dc.SelectObject(&pen);
for(int i = 0; i<NUM_OF_SECTIONS_IN_GRAPH; i++){
dc.MoveTo(graphSamplePoints[i].x, graphSamplePoints[i].y);
dc.LineTo(graphSamplePoints[i+1].x, graphSamplePoints[i+1].y);
}
// draw circles at graph sample points
for(int i = 0; i<NUM_OF_POINTS_IN_GRAPH; i++){
CIRCLE(dc, graphSamplePoints[i].x, graphSamplePoints[i].y, GRP_SMP_RAD);
}
// dc_blt.BitBlt(0,0,rcClient.Width(), rcClient.Height(), &dc, 0, 0, SRCCOPY);
dc_blt.BitBlt(theGraph.x1,theGraph.y1,theGraph.width, theGraph.height, &dc, 0, 0, SRCCOPY);
}
ビューポートの原点を何度も変更する必要がありますが、これがエラーの原因の 1 つになっている可能性があります。どんな提案でも大歓迎です。
これは私の出力がダブルバッファリングなし
でどのように見えるかです これは私のダブルバッファリングの試みでどのように見えるかです