2017-12-02 3 views
1

現在MFCを学んでいて、Gomokuを作ることに決めました。これは私がこれまで持っていたコードです。gomokuにピースを収納する方法

**mainframe.h** 

class CMainFrame : public CFrameWnd 
{ 

public: 
CMainFrame(); 
protected: 
DECLARE_DYNAMIC(CMainFrame) 


public: 


public: 


public: 



public: 
virtual ~CMainFrame(); 
#ifdef _DEBUG 
virtual void AssertValid() const; 
virtual void Dump(CDumpContext& dc) const; 
#endif 


protected: 
DECLARE_MESSAGE_MAP() 
void DrawBoard(CDC* pDC); 
int m_nNextChar; 
int board[15][15]; 
static const int EMPTY = 0, WHITE = 1, BLACK = 2; 

public: 
afx_msg void OnLButtonDown(UINT nFlags, CPoint point); 
afx_msg void OnRButtonDown(UINT nFlags, CPoint point); 
afx_msg void OnPaint(); 
}; 


**mainframe.cpp** 

#include "stdafx.h" 
#include "01.win32tomfc.h" 

#include "MainFrm.h" 

#ifdef _DEBUG 
#define new DEBUG_NEW 
#endif 


// CMainFrame 

IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd) 

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) 

ON_WM_LBUTTONDOWN() 
ON_WM_RBUTTONDOWN() 
ON_WM_PAINT() 
END_MESSAGE_MAP() 

int diameter = 23; 
int size = 40; 
int xCod; 
int yCod; 
int xCodx; 
int yCody; 
// CMainFrame ¹¹Ôì/Îö¹¹ 

CMainFrame::CMainFrame() 
{ 
m_nNextChar = BLACK; 

Create(NULL, _T("Generic Sample Application")); 
CRect rect(0, 0, 700, 700); 
CalcWindowRect(&rect); 
SetWindowPos(NULL, 0, 0, rect.Width(), rect.Height(), 
    SWP_NOZORDER | SWP_NOMOVE | SWP_NOREDRAW); 
} 

CMainFrame::~CMainFrame() 
{ 
} 



// CMainFrame Õï¶Ï 

#ifdef _DEBUG 
void CMainFrame::AssertValid() const 
{ 
CFrameWnd::AssertValid(); 
} 

void CMainFrame::Dump(CDumpContext& dc) const 
{ 
CFrameWnd::Dump(dc); 
} 

#endif //_DEBUG 


// CMainFrame ÏûÏ¢´¦Àí³ÌÐò 



void CMainFrame::DrawBoard(CDC * pDC) 
{ 
CPen pen(PS_SOLID, 1, RGB(0, 0, 0)); 
CPen* pOldPen = pDC->SelectObject(&pen); 

for (int i = 1; i <= 16; i++) { 
    pDC->MoveTo(40 * i, 40); 
    pDC->LineTo(40 * i, 640); 

    pDC->MoveTo(40, 40 * i); 
    pDC->LineTo(640, 40 * i); 
} 

pDC->SelectObject(pOldPen); 
} 


void CMainFrame::OnLButtonDown(UINT nFlags, CPoint point) 
{ 
CClientDC dc(this); 

CPen pen(PS_SOLID, 1, RGB(0, 0, 0)); 
CPen* pOldPen = dc.SelectObject(&pen); 
dc.SelectStockObject(BLACK_BRUSH); 

xCod = (point.x + (size/2))/size; 
xCod = (xCod * size) - diameter/2; 
yCod = (point.y + (size/2))/size; 
yCod = (yCod * size) - diameter/2; 
xCodx = xCod + diameter; 
yCody = yCod + diameter; 

if (m_nNextChar != BLACK) 
    return; 
else { 

    if (xCod > 20 && yCod <= 640 && xCodx < 655 && yCody > 40) { 
     dc.Ellipse(xCod, yCod, xCodx, yCody); 
    } 
} 

m_nNextChar = WHITE; 


CFrameWnd::OnLButtonDown(nFlags, point); 
} 


void CMainFrame::OnRButtonDown(UINT nFlags, CPoint point) 
{ 
CClientDC dc(this); 

CPen pen(PS_SOLID, 1, RGB(0, 0, 0)); 
CPen* pOldPen = dc.SelectObject(&pen); 
dc.SelectStockObject(WHITE_BRUSH); 

xCod = (point.x + (size/2))/size; 
xCod = (xCod * size) - diameter/2; 
yCod = (point.y + (size/2))/size; 
yCod = (yCod * size) - diameter/2; 
xCodx = xCod + diameter; 
yCody = yCod + diameter; 


if (m_nNextChar != WHITE) 
    return; 

else { 

    if (xCod > 20 && yCod <= 640 && xCodx < 655 && yCody > 40) { 
      dc.Ellipse(xCod, yCod, xCodx, yCody); 
     } 
} 

m_nNextChar = BLACK; 

CFrameWnd::OnRButtonDown(nFlags, point); 
} 


void CMainFrame::OnPaint() 
{ 
CPaintDC dc(this); 
DrawBoard(&dc); 

} 

私が持っているコードは、(機能DrawBoardに15×15のグリッドを描き)及びOnLButtonDownとOnRButtonDownで黒と白の部分を描きます。私はプログラムを実行し、黒い部分をクリックして白い部分を描くときに、白い部分を黒い部分に引き寄せることができます。逆も同様です。そこで私は2次元配列ボードを作成して、現在のピース上に別のピースを描くことができないように描かれたときにピースを保存することを考えました(ここで正しいトラックにいます)。私はしようとしましたが、私はそれを行う方法を理解できないようです。プログラミングがうまくいかず、これは簡単かもしれませんが、いくつかの助けが本当に感謝しています。どのように私はそれについて正しい方法について説明してください説明してください。

これは私が試みたものです。

void CMainFrame::OnLButtonDown(UINT nFlags, CPoint point) 
{ 
CClientDC dc(this); 

CPen pen(PS_SOLID, 1, RGB(0, 0, 0)); 
CPen* pOldPen = dc.SelectObject(&pen); 
dc.SelectStockObject(BLACK_BRUSH); 

xCod = (point.x + (size/2))/size; 
xCod = (xCod * size) - diameter/2; 
yCod = (point.y + (size/2))/size; 
yCod = (yCod * size) - diameter/2; 
xCodx = xCod + diameter; 
yCody = yCod + diameter; 

if ((m_nNextChar != BLACK) && (board[xCod][yCod] = WHITE)) 
    return; 
else { 

    if (xCod > 20 && yCod <= 640 && xCodx < 655 && yCody > 40) { 
     dc.Ellipse(xCod, yCod, xCodx, yCody); 
     board[xCod][yCod] = BLACK; 
    } 
} 

void CMainFrame::OnRButtonDown(UINT nFlags, CPoint point) 
{ 
CClientDC dc(this); 

CPen pen(PS_SOLID, 1, RGB(0, 0, 0)); 
CPen* pOldPen = dc.SelectObject(&pen); 
dc.SelectStockObject(WHITE_BRUSH); 

xCod = (point.x + (size/2))/size; 
xCod = (xCod * size) - diameter/2; 
yCod = (point.y + (size/2))/size; 
yCod = (yCod * size) - diameter/2; 
xCodx = xCod + diameter; 
yCody = yCod + diameter; 


if (m_nNextChar != WHITE && (board[xCod][yCod] = BLACK)) 
    return; 
else { 

    if (xCod > 20 && yCod <= 640 && xCodx < 655 && yCody > 40) { 
      dc.Ellipse(xCod, yCod, xCodx, yCody); 
      board[xCod][yCod] = WHITE; 
     } 
} 

m_nNextChar = BLACK; 

CFrameWnd::OnRButtonDown(nFlags, point); 
} 

答えて

0

OnPaintですべての図面を行う必要があります。 OnLButtonDownのような他の関数を描画しないでください。代わりに、OnLButtonDownから必要な情報を取得し、Invalidateに電話すると、ウィンドウが再描画されます。

ここは例です。わかりやすくするために、構造infoと2次元配列dataを作成しました。 dataは、各セルのすべての情報、つまり長方形と色を格納します。あなたは一度dataを初期化する必要があり、かつ塗料がdata

#include <vector> 

class CMainFrame : public CFrameWnd 
{ 
    ... 
    struct info 
    { 
     CRect rect; 
     int color; 
    }; 
    std::vector<std::vector<info>> data; 
}; 

CMainFrame::CMainFrame() 
{ 
    ... 
    data.resize(15); 
    for(int i = 0; i < data.size(); i++) 
     data[i].resize(15); 

    int xoffset = 20; 
    int yoffset = 20; 
    for(int row = 0; row < 15; row++) 
    { 
     for(int col = 0; col < 15; col++) 
     { 
      data[row][col].rect.SetRect(0, 0, size + 1, size + 1); 
      data[row][col].rect.MoveToXY(xoffset + row * size, yoffset + col * size); 
     } 
    } 
} 

void CMainFrame::OnLButtonDown(UINT nFlags, CPoint point) 
{ 
    CFrameWnd::OnLButtonDown(nFlags, point); 
    for(int row = 0; row < 15; row++) 
    { 
     for(int col = 0; col < 15; col++) 
     { 
      if(data[row][col].color) 
       break; 

      if(data[row][col].rect.PtInRect(point)) 
      { 
       data[row][col].color = WHITE; 
       break; 
      } 
     } 
    } 
    Invalidate(FALSE); 
} 

void CMainFrame::OnRButtonDown(UINT nFlags, CPoint point) 
{ 
    CFrameWnd::OnRButtonDown(nFlags, point); 
    for(int row = 0; row < 15; row++) 
    { 
     for(int col = 0; col < 15; col++) 
     { 
      if(data[row][col].color) 
       break; 

      if(data[row][col].rect.PtInRect(point)) 
      { 
       data[row][col].color = BLACK; 
       break; 
      } 
     } 
    } 
    Invalidate(FALSE); 
} 

void CMainFrame::OnPaint() 
{ 
    CPaintDC dc(this); 
    CPen pen(PS_SOLID, 1, RGB(0, 0, 0)); 
    dc.SelectObject(&pen); 
    CBrush white, black; 
    white.CreateSolidBrush(RGB(255, 255, 255)); 
    black.CreateSolidBrush(RGB(0, 0, 0)); 

    for(int row = 0; row < 15; row++) 
    { 
     for(int col = 0; col < 15; col++) 
     { 
      dc.Rectangle(data[row][col].rect); 

      if(data[row][col].color) 
      { 
       CBrush *oldbrush; 
       if(data[row][col].color == WHITE) 
        oldbrush = dc.SelectObject(&white); 
       else 
        oldbrush = dc.SelectObject(&black); 
       dc.Ellipse(data[row][col].rect); 
       dc.SelectObject(oldbrush); 
      } 
     } 
    } 
} 
+0

やあ、おかげで助けのためにたくさんの情報に基づいて。他の機能で描画を行うべきではない特定の理由はありますか? – Elijah

+0

私は明確にすべきだった。ペイントが 'WM_PAINT'メッセージ(MFCが' WM_PAINT'をキャッチし、それを 'OnPaint'に渡す)に応答する限り、' DrawBoard(CDC * pDC) 'やその他の関数でペイントすることは可能です。以前に設定した方法では、ウィンドウのサイズを変更するとペイントメッセージが表示され、すべての省略記号が消去されます。 –

+0

大丈夫です。ありがとう – Elijah

関連する問題