调试错误:经加断点发现,半径r并没有随时间而减小
源代码:
/*在屏幕中心画一个圆,圆的半径r随时间减小(每隔一秒半径减小10)*/
/*调试错误:经加断点发现,半径r并没有随时间而减小*/
#include<windows.h>
#include<tchar.h>
#include<math.h>
#define PI 3.1415926
BOOLEAN InitWindowClass(HINSTANCE hInstance,int nCmdShow);
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
MSG msg;
if(!InitWindowClass(hInstance,nCmdShow))
{
MessageBox(NULL,L"创建窗口失败!",_T("创建窗口"),NULL);
return 1;
}
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg); //将消息的虚拟键转换为字符信息
DispatchMessage(&msg); //将参数指向的消息通过windows系统传送到指定的窗口函数
}
return(int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
HBRUSH hBrush;
HPEN hPen;
RECT clientrect;
POINT cer; //cer为圆心
int r; //r为圆半径
hDC=BeginPaint(hWnd,&ps); //获取设备环境
GetClientRect(hWnd,&clientrect);
cer.x=(clientrect.left+clientrect.right)/2;
cer.y=(clientrect.top+clientrect.bottom)/2;
r=min(cer.x,cer.y)-50;
switch(message)
{
case WM_CREATE:
SetTimer(hWnd,9999,1000,NULL);
break;
case WM_TIMER:
if(wParam==9999)
InvalidateRect(hWnd,NULL,true);
break;
case WM_SIZE:
InvalidateRect(hWnd,NULL,true);
break;
case WM_PAINT:
r-=10; //半径减小10 ?????????????????????????????????????????????????????????
hPen=CreatePen(PS_SOLID,0,RGB(0,0,0));
hBrush=CreateSolidBrush(RGB(255,220,220));
SelectObject(hDC,hPen);
SelectObject(hDC,hBrush);
Ellipse(hDC,cer.x-r,cer.y-r,cer.x+r,cer.y+r); //绘制圆
DeleteObject(hPen);
DeleteObject(hBrush);
EndPaint(hWnd,&ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd,message,wParam,lParam);
break;
}
return 0;
}
BOOLEAN InitWindowClass(HINSTANCE hInstance,int nCmdShow)
{
WNDCLASSEX wcex;
HWND hWnd;
TCHAR szWindowClass[]=L"窗口示例"; //窗口类名
TCHAR szTitle[]=L"ex4-6"; //窗口标题名
wcex.cbSize=sizeof(WNDCLASSEX);
wcex.style=0;
wcex.lpfnWndProc=WndProc;
wcex.cbClsExtra=0;
wcex.cbWndExtra=0;
wcex.hInstance=hInstance;
wcex.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_APPLICATION));
wcex.hCursor=LoadCursor(NULL,IDC_ARROW);
wcex.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wcex.lpszMenuName=NULL;
wcex.lpszClassName=szWindowClass;
wcex.hIconSm=LoadIcon(wcex.hInstance,MAKEINTRESOURCE(IDI_APPLICATION));
if(!RegisterClassEx(&wcex))
{
return FALSE;
}
hWnd=CreateWindow(szWindowClass,szTitle,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
if(!hWnd)
return FALSE;
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
8 个解决方案
#1
实在是很郁闷,理论上每接受一次WM_PAINT消息,半径r减10
运行的时候发现圆并没有随时间半径减小,加了断点发现r根本就没变化
运行的时候发现圆并没有随时间半径减小,加了断点发现r根本就没变化
#2
刚看了楼主的代码。
每一次消息进来后,
r就又变成min(cer.x,cer.y)-50;
进入后又减少10.
所以楼主看到的情况就是每次min(cer.x,cer.y)-50 - 10;
所以,我认为楼主你可以把r=min(cer.x,cer.y)-50;只初始化一次。
用个全局BOOL型bflagStart判断
每一次消息进来后,
r就又变成min(cer.x,cer.y)-50;
进入后又减少10.
所以楼主看到的情况就是每次min(cer.x,cer.y)-50 - 10;
所以,我认为楼主你可以把r=min(cer.x,cer.y)-50;只初始化一次。
用个全局BOOL型bflagStart判断
cer.x=(clientrect.left+clientrect.right)/2;
cer.y=(clientrect.top+clientrect.bottom)/2;
if(bflagStart == TRUE)
{
r=min(cer.x,cer.y)-50;
bflagStart = FALSE;
}
#3
另外我建议你把r -= 10;放到
case WM_TIMER:
if(wParam==9999)
{
r-= 10;
InvalidateRect(hWnd,NULL,true);
}
break;
case WM_TIMER:
if(wParam==9999)
{
r-= 10;
InvalidateRect(hWnd,NULL,true);
}
break;
#4
cer.x=(clientrect.left+clientrect.right)/2;
cer.y=(clientrect.top+clientrect.bottom)/2;
r=min(cer.x,cer.y)-50;//你的程序使r为常数啊,想变只能在初始化时执行一次。
cer.y=(clientrect.top+clientrect.bottom)/2;
r=min(cer.x,cer.y)-50;//你的程序使r为常数啊,想变只能在初始化时执行一次。
#5
r是自动变量啊,每次进入函数要在栈上重新生成执行代码
你要么把r定义成静态变量,要么定义成全局变量。
你要么把r定义成静态变量,要么定义成全局变量。
#6
原理:楼上几位已经说得很明白了 ,就是局部变量问题
把你的r声明位置换一下,比如:
#include<windows.h>
#include<tchar.h>
#include<math.h>
#define PI 3.1415926
int r=....;
把你的r声明位置换一下,比如:
#include<windows.h>
#include<tchar.h>
#include<math.h>
#define PI 3.1415926
int r=....;
#7
这画个圆再缩小半径。。这程序编的有点长了。。。
#8
感谢各位大神。。。。
本人10.3号发完求助帖,本来想等到第二天再看的,结果把这事儿给忘了
直到今天又上MFC,才想起来一个多星期前的帖子。
现在问题已经解决,就是变量r的问题。我把r声明为全局变量,然后又借用了二楼的方法,调试成功了
再次感谢CSDN上各位codeing 牛人
本人10.3号发完求助帖,本来想等到第二天再看的,结果把这事儿给忘了
直到今天又上MFC,才想起来一个多星期前的帖子。
现在问题已经解决,就是变量r的问题。我把r声明为全局变量,然后又借用了二楼的方法,调试成功了
再次感谢CSDN上各位codeing 牛人
#1
实在是很郁闷,理论上每接受一次WM_PAINT消息,半径r减10
运行的时候发现圆并没有随时间半径减小,加了断点发现r根本就没变化
运行的时候发现圆并没有随时间半径减小,加了断点发现r根本就没变化
#2
刚看了楼主的代码。
每一次消息进来后,
r就又变成min(cer.x,cer.y)-50;
进入后又减少10.
所以楼主看到的情况就是每次min(cer.x,cer.y)-50 - 10;
所以,我认为楼主你可以把r=min(cer.x,cer.y)-50;只初始化一次。
用个全局BOOL型bflagStart判断
每一次消息进来后,
r就又变成min(cer.x,cer.y)-50;
进入后又减少10.
所以楼主看到的情况就是每次min(cer.x,cer.y)-50 - 10;
所以,我认为楼主你可以把r=min(cer.x,cer.y)-50;只初始化一次。
用个全局BOOL型bflagStart判断
cer.x=(clientrect.left+clientrect.right)/2;
cer.y=(clientrect.top+clientrect.bottom)/2;
if(bflagStart == TRUE)
{
r=min(cer.x,cer.y)-50;
bflagStart = FALSE;
}
#3
另外我建议你把r -= 10;放到
case WM_TIMER:
if(wParam==9999)
{
r-= 10;
InvalidateRect(hWnd,NULL,true);
}
break;
case WM_TIMER:
if(wParam==9999)
{
r-= 10;
InvalidateRect(hWnd,NULL,true);
}
break;
#4
cer.x=(clientrect.left+clientrect.right)/2;
cer.y=(clientrect.top+clientrect.bottom)/2;
r=min(cer.x,cer.y)-50;//你的程序使r为常数啊,想变只能在初始化时执行一次。
cer.y=(clientrect.top+clientrect.bottom)/2;
r=min(cer.x,cer.y)-50;//你的程序使r为常数啊,想变只能在初始化时执行一次。
#5
r是自动变量啊,每次进入函数要在栈上重新生成执行代码
你要么把r定义成静态变量,要么定义成全局变量。
你要么把r定义成静态变量,要么定义成全局变量。
#6
原理:楼上几位已经说得很明白了 ,就是局部变量问题
把你的r声明位置换一下,比如:
#include<windows.h>
#include<tchar.h>
#include<math.h>
#define PI 3.1415926
int r=....;
把你的r声明位置换一下,比如:
#include<windows.h>
#include<tchar.h>
#include<math.h>
#define PI 3.1415926
int r=....;
#7
这画个圆再缩小半径。。这程序编的有点长了。。。
#8
感谢各位大神。。。。
本人10.3号发完求助帖,本来想等到第二天再看的,结果把这事儿给忘了
直到今天又上MFC,才想起来一个多星期前的帖子。
现在问题已经解决,就是变量r的问题。我把r声明为全局变量,然后又借用了二楼的方法,调试成功了
再次感谢CSDN上各位codeing 牛人
本人10.3号发完求助帖,本来想等到第二天再看的,结果把这事儿给忘了
直到今天又上MFC,才想起来一个多星期前的帖子。
现在问题已经解决,就是变量r的问题。我把r声明为全局变量,然后又借用了二楼的方法,调试成功了
再次感谢CSDN上各位codeing 牛人