不能想象这个简单的程序会出什么问题

编程入门 行业动态 更新时间:2024-10-25 16:19:37
本文介绍了不能想象这个简单的程序会出什么问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

嗨.我是MFC编程的新手.我只是在写一些简单的井字游戏程序.我的代码如下所示.它仅在出现"l button down"消息的正方形中绘制X.但神秘地,它无法在所有正方形中绘制X.如果单击所有正方形,它只会绘制3或4次的X.之后,即使我单击一个正方形,它也会停止工作.没有错误.没有提示音消息提示音.它只是停止.但是我不明白错误在哪里. 这是我在头文件中的代码.

< blockquote class = " quote" >< div class = " op" >引用:</div> class MainWindow: public CFrameWnd { 公共: MainWindow() { Create(NULL,L " WINDOW" ); } 受保护的: afx_msg void OnPaint(); afx_msg void OnLButtonDown(UINT,CPoint); 私有: void DrawGrid(CDC *); void DrawO(CDC *, int ); // 忽略此 void DrawX(CDC *, int ); DECLARE_MESSAGE_MAP() }; class 应用程序: public CWinApp { 公共: BOOL InitInstance() { m_pMainWnd = 新 MainWindow; m_pMainWnd-> ShowWindow(m_nCmdShow); m_pMainWnd-> UpdateWindow(); CRect rec( 0 , 0 , 300 , 300 ); m_pMainWnd-> CalcWindowRect(rec); m_pMainWnd-> SetWindowPos(NULL, 0 , 0 ,rec.Width(),rec.Height( ),SWP_NOZORDER | SWP_NOMOVE | SWP_NOREDRAW); 返回 TRUE; } };</blockquote>

这是cpp文件.

#include " stdafx.h" #include " MFCApplication15.h" #define O 1 #define X 2 CRect sqs [ 9 ] = { { 0 , 0 , 100 , 100 }, { 100 , 0 , 200 , 100 }, { 200 , 0 , 300 , 100 }, { 0 , 100 , 100 , 200 }, { 100 , 100 , 200 , 200 }, { 200 , 100 , 300 , 200 }, { 0 , 200 , 100 , 300 }, { 100 , 200 , 200 , 300 }, { 200 , 200 , 300 , 300 } }; int vals [ 9 ] { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }; 无效 MainWindow :: OnPaint() { CClientDC dc(此); DrawGrid(& dc); for ( int i {}; i< 9 ; i ++) 如果(值[i] == X) DrawX(& dc,i); } 无效 MainWindow :: OnLButtonDown(UINT标志,CPoint cp) { for ( int i {}; i< 9 ; i ++) { 如果(PtInRect(sqs [i],cp)) vals [i] = X; } } 无效 MainWindow :: DrawGrid(CDC * pDC) { CPen * pen = 新的 CPen(PS_SOLID, 5 ,RGB( 0 , 0 , 0 ))); pDC-> SelectObject(pen); pDC-> MoveTo( 0 , 100 ); pDC-> LineTo( 300 , 100 ); pDC-> MoveTo( 0 , 200 ); pDC-> LineTo( 300 , 200 ); pDC-> MoveTo( 100 , 0 ); pDC-> LineTo( 100 , 300 ); pDC-> MoveTo( 200 , 0 ); pDC-> LineTo( 200 , 300 ); } 无效 MainWindow :: DrawO(CDC * pDC, int pos)// 忽略此 { CPen * pen = 新的 CPen(PS_SOLID, 3 ,RGB( 255 , 0 , 0 ))); pDC-> SelectObject(pen); pDC-> Ellipse(sqs [pos]); } 无效 MainWindow :: DrawX(CDC * pDC, int pos) { CPen * pen = 新的 CPen(PS_SOLID, 3 ,RGB( 0 , 0 , 255 ))); pDC-> SelectObject(pen); pDC-> MoveTo(sqs [pos] .left,sqs [pos] .top); pDC-> LineTo(sqs [pos] .right,sqs [pos] .bottom); pDC-> MoveTo(sqs [pos] .right,sqs [pos] .top); pDC-> LineTo(sqs [pos] .left,sqs [pos] .bottom); } 应用程序myApp; BEGIN_MESSAGE_MAP(MainWindow,CFrameWnd) ON_WM_PAINT() ON_WM_LBUTTONDOWN() END_MESSAGE_MAP()

我的代码有什么问题?为什么要在单击4次后停止绘图? 在此先谢谢您.

解决方案

谢谢大家的帮助.我解决了问题.是笔.

void MainWindow :: DrawX(CDC * pDC, int pos) { /* CPen * pen = new CPen(PS_SOLID,3,RGB(0,0,255)); pDC-> SelectObject(pen); */ pDC-> SelectObject(pn); pDC-> MoveTo(sqs [pos] .left,sqs [pos] .top); pDC-> LineTo(sqs [pos] .right,sqs [pos] .bottom); pDC-> MoveTo(sqs [pos] .right,sqs [pos] .top); pDC-> LineTo(sqs [pos] .left,sqs [pos] .bottom); }

在这种情况下,您必须在功能外部创建笔并在功能内部选择它. (因为我已经评论了前两行) 不知道为什么在函数内部创建笔会产生这样的问题.我认为这一定是占用了内存.

您应该致电 InvalidateRect [^ 设置所有正方形后,在OnLButtonDown函数中单击]. Windows仅在响应WM_PAINT消息时才重绘,因此,每当您在应用程序中更改某些会影响显示的内容时,都需要强制发送WM_PAINT,这是执行此操作的简单方法.

我已经注意到您每次在堆上创建新的GDI时都会创建对象,而不会像这样将其释放:

void MainWindow :: DrawX(CDC * pDC, int pos) { CPen * pen = 新的 CPen(PS_SOLID, 3 ,RGB( 0 , 0 , 255 )));

那是错的!尝试使用堆栈上的对象:

void MainWindow :: DrawX(CDC * pDC, int pos) { CP笔(PS_SOLID, 3 ,RGB( 0 , 0 , 255 ));

很好地看一下这篇文章:附加和分离对象 [ ^ ]

Hi. Im a novice to MFC programming. And I was just writing some simple tic tac toe program. My codes are shown below. It only draws X in a square where "l button down" messages occur. But mysteriously it fails to draw Xs in all the squares. If I click in all the squares, it only draws Xs for like 3 or 4 times. After that it stops working even though I click on a square. No errors. No beep message beep sounds. It just stops. But I cant understand where the error is. Heres my code in header file.

<blockquote class="quote"><div class="op">Quote:</div> class MainWindow : public CFrameWnd { public: MainWindow() { Create(NULL, L"WINDOW"); } protected: afx_msg void OnPaint(); afx_msg void OnLButtonDown(UINT, CPoint); private: void DrawGrid(CDC*); void DrawO(CDC*, int); //Ignore this void DrawX(CDC*, int); DECLARE_MESSAGE_MAP() }; class App : public CWinApp { public: BOOL InitInstance() { m_pMainWnd = new MainWindow; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); CRect rec(0, 0, 300, 300); m_pMainWnd->CalcWindowRect(rec); m_pMainWnd->SetWindowPos(NULL, 0, 0, rec.Width(), rec.Height(), SWP_NOZORDER | SWP_NOMOVE | SWP_NOREDRAW); return TRUE; } };</blockquote>

And here is the cpp file.

#include "stdafx.h" #include "MFCApplication15.h" #define O 1 #define X 2 CRect sqs[9] = { { 0, 0, 100, 100 }, { 100, 0, 200, 100 }, { 200, 0, 300, 100 }, { 0, 100, 100, 200 }, { 100, 100, 200, 200 }, { 200, 100, 300, 200 }, { 0, 200, 100, 300 }, { 100, 200, 200, 300 }, { 200, 200, 300, 300 } }; int vals[9]{0, 0, 0, 0, 0, 0, 0, 0, 0}; void MainWindow::OnPaint() { CClientDC dc(this); DrawGrid(&dc); for (int i{}; i < 9; i++) if (vals[i] == X) DrawX(&dc, i); } void MainWindow::OnLButtonDown(UINT flags, CPoint cp) { for (int i{}; i < 9; i++) { if (PtInRect(sqs[i], cp)) vals[i] = X; } } void MainWindow::DrawGrid(CDC* pDC) { CPen *pen = new CPen(PS_SOLID, 5, RGB(0, 0, 0)); pDC->SelectObject(pen); pDC->MoveTo(0, 100); pDC->LineTo(300, 100); pDC->MoveTo(0, 200); pDC->LineTo(300, 200); pDC->MoveTo(100, 0); pDC->LineTo(100, 300); pDC->MoveTo(200, 0); pDC->LineTo(200, 300); } void MainWindow::DrawO(CDC* pDC, int pos) //Ignore this { CPen* pen = new CPen(PS_SOLID, 3, RGB(255, 0, 0)); pDC->SelectObject(pen); pDC->Ellipse(sqs[pos]); } void MainWindow::DrawX(CDC* pDC, int pos) { CPen* pen = new CPen(PS_SOLID, 3, RGB(0, 0, 255)); pDC->SelectObject(pen); pDC->MoveTo(sqs[pos].left, sqs[pos].top); pDC->LineTo(sqs[pos].right, sqs[pos].bottom); pDC->MoveTo(sqs[pos].right, sqs[pos].top); pDC->LineTo(sqs[pos].left, sqs[pos].bottom); } App myApp; BEGIN_MESSAGE_MAP(MainWindow, CFrameWnd) ON_WM_PAINT() ON_WM_LBUTTONDOWN() END_MESSAGE_MAP()

What''s the wrong with my code ? Why it stops the drawing after like 4 clicks ? Thanks in advance.

解决方案

Thank you all for helps. I solved the problem. It was the pen.

void MainWindow::DrawX(CDC* pDC, int pos) { /*CPen* pen = new CPen(PS_SOLID, 3, RGB(0, 0, 255)); pDC->SelectObject(pen);*/ pDC->SelectObject(pn); pDC->MoveTo(sqs[pos].left, sqs[pos].top); pDC->LineTo(sqs[pos].right, sqs[pos].bottom); pDC->MoveTo(sqs[pos].right, sqs[pos].top); pDC->LineTo(sqs[pos].left, sqs[pos].bottom); }

In this, you have to create the pen outside the function and select it inside the function. (as i have commented the the first two lines) No idea why creating a pen inside a function creates such problems though. I reckon it must be something with memory consumption.

You should call InvalidateRect[^] in your OnLButtonDown function after setting all the squares. Windows only get redrawn in response to a WM_PAINT message, so whenever you change something in your application that affects the display you need to force a WM_PAINT to be sent, and this is the simple way to do it.

I''ve noticed that you create each time a new GDI objeects on the heap without to get it free like this:

void MainWindow::DrawX(CDC* pDC, int pos) { CPen* pen = new CPen(PS_SOLID, 3, RGB(0, 0, 255));

That is wrong! Try instead to work with objects on the stack:

void MainWindow::DrawX(CDC* pDC, int pos) { CPen pen(PS_SOLID, 3, RGB(0, 0, 255));

Take a look at this article aa well: Attaching and Detaching Objects[^]

更多推荐

不能想象这个简单的程序会出什么问题

本文发布于:2023-11-01 23:02:24,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1550661.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:什么问题   简单   程序

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!