向各位高手求助,本人初学MFC系一小菜鸟,写一画图程序,点击鼠标左键画点,但是做出来的程序一经过最小化,原来画的图形就都不见了,以下是在下的代码,请各位高手现身指点~
//Wind.h
class CMyApp : public CWinApp
{
BOOL virtual InitInstance();
};
class CMainWindow :public CFrameWnd
{
public:CMainWindow();
protected:
afx_msg void OnPaint();
afx_msg void OnLButtonDown(UINT nFlags,CPoint point);
afx_msg void OnLButtonUp(UINT nFlags,CPoint point);
afx_msg void OnMouseMove(UINT nFlags,CPoint Point);
DECLARE_MESSAGE_MAP()
protected: void Draw(CDC* pDC,CPoint point);//在鼠标当指定点画点
       void DText(CDC* pDc);//使用说明
       void InitData();//初始化成员数据
       CPoint mouse;//当前鼠标位置
   BOOL   key;//判断鼠标左键是否按下};
//Wind.cpp#include <afxwin.h>
#include "Wind.h"
#include <time.h>
CMyApp MyApp;
CMyApp::InitInstance()
{
m_pMainWnd=new CMainWindow;
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateData(TRUE);
return TRUE;
}
//MESSAGEMAP
BEGIN_MESSAGE_MAP(CMainWindow,CFrameWnd)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()
CMainWindow::CMainWindow()
{
Create(NULL,"The Application",WS_OVERLAPPED|WS_SYSMENU|WS_CAPTION|WS_MINIMIZEBOX);
CRect rect(0,0,400,300);
CalcWindowRect(&rect);
SetWindowPos(this,0,0,rect.Width(),rect.Height(),SWP_NOREDRAW|SWP_DEFERERASE|SWP_NOMOVE|SWP_NOZORDER);
InitData();
}
void CMainWindow::OnPaint()
{
CPaintDC dc(this);
    DText(&dc);
//Draw(mouse,&dc);

}
void CMainWindow::OnLButtonDown(UINT nFlags,CPoint point)
{
mouse=point;
key=1;
CClientDC dc(this);
Draw(&dc,mouse);

}
void CMainWindow::OnLButtonUp(UINT nFlags,CPoint point)
{

key=0;
}
void CMainWindow::OnMouseMove(UINT nFlags,CPoint point)
{
    mouse=point;
CClientDC dc(this);
Draw(&dc,mouse);
}
void CMainWindow::Draw(CDC* pDC,CPoint point)
{if(key)
{
int a,b,c;
a=rand()%255;
b=rand()%255;
c=rand()%255;
CPen pen(PS_INSIDEFRAME,3,RGB(a,b,c));
CPen* pOldPen=pDC->SelectObject(&pen);
CBrush brush(RGB(a,b,c));
pDC->SelectObject(&brush);
pDC->Ellipse(mouse.x-15,mouse.y-15,mouse.x+15,mouse.y+15);
pDC->SelectObject(pOldPen);
//Invalidate();CString str;
str.Format("%d,%d",mouse.x,mouse.y);
pDC->TextOut(400,400,str);
//MessageBox(str);
}
}
void CMainWindow::InitData()
{
mouse.x=100;
mouse.y=100;
key=0;
}
void CMainWindow::DText(CDC* pDc)
{
pDc->TextOut(130,0,_T("点击鼠标左键画点"));

}

解决方案 »

  1.   

    在OnPaint() 中需要重绘。
    最好的方法是利用双缓存画图。
    也就是先把图画到内存里。每次刷新只需要刷新图片就可以了。
      

  2.   

    void CMainWindow::OnPaint() 

    CPaintDC dc(this); 
        DText(&dc); 
    //Draw(mouse,&dc);  <-- 你都把他去掉了当然就玩完了.
    }
      

  3.   

    SetWindowPos(this,0,0,rect.Width(),rect.Height(),SWP_NOREDRAW|SWP_DEFERERASE|SWP_NOMOVE|SWP_NOZORDER);
    InitData();
    这个函数里那个SWP_NOREDRAW咋没效果呢  这个参数不是说不重绘 除非Invalidate()才重绘的吗
      

  4.   

    SetWindowPos(this,0,0,rect.Width(),rect.Height(),SWP_NOREDRAW|SWP_DEFERERASE|SWP_NOMOVE|SWP_NOZORDER); 
    InitData(); 
    这个函数里那个SWP_NOREDRAW咋没效果呢  这个参数不是说不重绘 除非Invalidate()才重绘的吗
      

  5.   


    你怎么保证最小化还原后,系统没有自动调用Invalidate()呢?
      

  6.   

    再发个代码下面代码生成的程序最小化还原 图像就不会消失 百思不得其解为什么 看不出来跟我第一次发的代码画图方式有什么不一样的···//TicTac.h
    #define EX 1
    #define OH 2class CMyApp : public CWinApp
    {
    public:
        virtual BOOL InitInstance ();
    };class CMainWindow : public CWnd
    {
    protected:
        static const CRect m_rcSquares[9]; // Grid coordinates
        int m_nGameGrid[9]; // Grid contents
        int m_nNextChar; // Next character (EX or OH)    int GetRectID (CPoint point);
        void DrawBoard (CDC* pDC);
        void DrawX (CDC* pDC, int nPos);
        void DrawO (CDC* pDC, int nPos);
        void ResetGame ();
        void CheckForGameOver ();
        int IsWinner ();
        BOOL IsDraw ();public:
        CMainWindow ();protected:
        virtual void PostNcDestroy ();    afx_msg void OnPaint ();
        afx_msg void OnLButtonDown (UINT nFlags, CPoint point);
        afx_msg void OnLButtonDblClk (UINT nFlags, CPoint point);
        afx_msg void OnRButtonDown (UINT nFlags, CPoint point);    DECLARE_MESSAGE_MAP ()
    };
    //TicTac.cpp
    #include <afxwin.h>
    #include "TicTac.h"CMyApp myApp;/////////////////////////////////////////////////////////////////////////
    // CMyApp member functionsBOOL CMyApp::InitInstance ()
    {
        m_pMainWnd = new CMainWindow;
        m_pMainWnd->ShowWindow (m_nCmdShow);
        m_pMainWnd->UpdateWindow ();
        return TRUE;
    }/////////////////////////////////////////////////////////////////////////
    // CMainWindow message map and member functionsBEGIN_MESSAGE_MAP (CMainWindow, CWnd)
        ON_WM_PAINT ()
        ON_WM_LBUTTONDOWN ()
        ON_WM_LBUTTONDBLCLK ()
        ON_WM_RBUTTONDOWN ()
    END_MESSAGE_MAP ()const CRect CMainWindow::m_rcSquares[9] = {
        CRect ( 16,  16, 112, 112),
        CRect (128,  16, 224, 112),
        CRect (240,  16, 336, 112),
        CRect ( 16, 128, 112, 224),
        CRect (128, 128, 224, 224),
        CRect (240, 128, 336, 224),
        CRect ( 16, 240, 112, 336),
        CRect (128, 240, 224, 336),
        CRect (240, 240, 336, 336)
    };CMainWindow::CMainWindow ()
    {
        m_nNextChar = EX;
        ::ZeroMemory (m_nGameGrid, 9 * sizeof (int)); //
    // Register a WNDCLASS.
    //
        CString strWndClass = AfxRegisterWndClass (
            CS_DBLCLKS, // Class style
            AfxGetApp ()->LoadStandardCursor (IDC_ARROW),   // Class cursor
            (HBRUSH) (COLOR_3DFACE + 1), // Background brush
            AfxGetApp ()->LoadStandardIcon (IDI_WINLOGO) // Class icon
        ); //
    // Create a window.
    //
        CreateEx (0, strWndClass, _T ("Tic-Tac-Toe"),
            WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX,
            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
            NULL, NULL); //
    // Size the window.
    //
        CRect rect (0, 0, 352, 352);
        CalcWindowRect (&rect);    SetWindowPos (NULL, 0, 0, rect.Width (), rect.Height (),
            SWP_NOZORDER | SWP_NOMOVE | SWP_NOREDRAW);
    }void CMainWindow::PostNcDestroy ()
    {
        delete this;
    }void CMainWindow::OnPaint ()
    {
        CPaintDC dc (this);
        DrawBoard (&dc);    
    }void CMainWindow::OnLButtonDown (UINT nFlags, CPoint point)
    {
    //
    // Do nothing if it's O's turn, if the click occurred outside the
    // tic-tac-toe grid, or if a nonempty square was clicked.
    //
        if (m_nNextChar != EX)
            return;    int nPos = GetRectID (point);
        if ((nPos == -1) || (m_nGameGrid[nPos] != 0))
            return; //
    // Add an X to the game grid and toggle m_nNextChar.
    //
        m_nGameGrid[nPos] = EX;
        m_nNextChar = OH; //
    // Draw an X on the screen and see if either player has won.
    //
        CClientDC dc (this);
        DrawX (&dc, nPos);
        CheckForGameOver ();
    }void CMainWindow::OnRButtonDown (UINT nFlags, CPoint point)
    {
    //
    // Do nothing if it's X's turn, if the click occurred outside the
    // tic-tac-toe grid, or if a nonempty square was clicked.
    //
        if (m_nNextChar != OH)
            return;    int nPos = GetRectID (point);
        if ((nPos == -1) || (m_nGameGrid[nPos] != 0))
            return; //
    // Add an O to the game grid and toggle m_nNextChar.
    //
        m_nGameGrid[nPos] = OH;
        m_nNextChar = EX; //
    // Draw an O on the screen and see if either player has won.
    //
        CClientDC dc (this);
        DrawO (&dc, nPos);
        CheckForGameOver ();
    }void CMainWindow::OnLButtonDblClk (UINT nFlags, CPoint point)
    {
    //
    // Reset the game if one of the thick black lines defining the game
    // grid is double-clicked with the left mouse button.
    //
        CClientDC dc (this);
        if (dc.GetPixel (point) == RGB (0, 0, 0))
            ResetGame ();
    }int CMainWindow::GetRectID (CPoint point)
    {
    //
    // Hit-test each of the grid's nine squares and return a rectangle ID
    // (0-8) if (point.x, point.y) lies inside a square.
    //
        for (int i=0; i<9; i++) {
            if (m_rcSquares[i].PtInRect (point))
                return i;
        }
        return -1;
    }void CMainWindow::DrawBoard (CDC* pDC)
    {
    //
    // Draw the lines that define the tic-tac-toe grid.
    //
        CPen pen (PS_SOLID, 16, RGB (0, 0, 0));
        CPen* pOldPen = pDC->SelectObject (&pen);    pDC->MoveTo (120, 16);
        pDC->LineTo (120, 336);    pDC->MoveTo (232, 16);
        pDC->LineTo (232, 336);    pDC->MoveTo (16, 120);
        pDC->LineTo (336, 120);    pDC->MoveTo (16, 232);
        pDC->LineTo (336, 232); //
    // Draw the Xs and Os.
    //
        for (int i=0; i<9; i++) {
            if (m_nGameGrid[i] == EX)
                DrawX (pDC, i);
            else if (m_nGameGrid[i] == OH)
                DrawO (pDC, i);
        }
        pDC->SelectObject (pOldPen);
    }void CMainWindow::DrawX (CDC* pDC, int nPos)
    {
        CPen pen (PS_SOLID, 16, RGB (255, 0, 0));
        CPen* pOldPen = pDC->SelectObject (&pen);    CRect rect = m_rcSquares[nPos];
        rect.DeflateRect (16, 16);
        pDC->MoveTo (rect.left, rect.top);
        pDC->LineTo (rect.right, rect.bottom);
        pDC->MoveTo (rect.left, rect.bottom);
        pDC->LineTo (rect.right, rect.top);    pDC->SelectObject (pOldPen);
    }void CMainWindow::DrawO (CDC* pDC, int nPos)
    {
        CPen pen (PS_SOLID, 16, RGB (0, 0, 255));
        CPen* pOldPen = pDC->SelectObject (&pen);
        pDC->SelectStockObject (NULL_BRUSH);    CRect rect = m_rcSquares[nPos];
        rect.DeflateRect (16, 16);
        pDC->Ellipse (rect);    pDC->SelectObject (pOldPen);
    }void CMainWindow::CheckForGameOver ()
    {
        int nWinner; //
    // If the grid contains three consecutive Xs or Os, declare a winner
    // and start a new game.
    //
        if (nWinner = IsWinner ()) {
            CString string = (nWinner == EX) ?
                _T ("X wins!") : _T ("O wins!");
            MessageBox (string, _T ("Game Over"), MB_ICONEXCLAMATION | MB_OK);
            ResetGame ();
        } //
    // If the grid is full, declare a draw and start a new game.
    //
        else if (IsDraw ()) {
            MessageBox (_T ("It's a draw!"), _T ("Game Over"),
                MB_ICONEXCLAMATION | MB_OK);
            ResetGame ();
        }
    }int CMainWindow::IsWinner ()
    {
        static int nPattern[8][3] = {
            0, 1, 2,
            3, 4, 5,
            6, 7, 8,
            0, 3, 6,
            1, 4, 7,
            2, 5, 8,
            0, 4, 8,
            2, 4, 6
        };    for (int i=0; i<8; i++) {
            if ((m_nGameGrid[nPattern[i][0]] == EX) &&
                (m_nGameGrid[nPattern[i][1]] == EX) &&
                (m_nGameGrid[nPattern[i][2]] == EX))
                return EX;        if ((m_nGameGrid[nPattern[i][0]] == OH) &&
                (m_nGameGrid[nPattern[i][1]] == OH) &&
                (m_nGameGrid[nPattern[i][2]] == OH))
                return OH;
        }
        return 0;
    }BOOL CMainWindow::IsDraw ()
    {
        for (int i=0; i<9; i++) {
            if (m_nGameGrid[i] == 0)
                return FALSE;
        }
        return TRUE;
    }void CMainWindow::ResetGame ()
    {
        m_nNextChar = EX;
        ::ZeroMemory (m_nGameGrid, 9 * sizeof (int));
        Invalidate ();
    }
    期待高手解惑