刷新图像 死机问题(在线的)

baifanmvp 2009-01-03 10:56:26
我写了个时钟的程序,但是打开运行以后,开始没什么问题,过不了多久屏幕就变花,就死机了,我不知道哪里有问题,请帮帮忙,谢谢(程序有点长,如果看起了太麻烦就放在编译器里运行一下吧,说不定你看到那个现象就知道问题是什么了,vc 6.0实现)

#define pai 3.1415
#define IDT_TIME 1

#include<windows.h>
#include<cmath>

void biaopang(HWND&,HDC&);
void zhizheng(HWND& ,HDC&);
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
int WINAPI WinMain(HINSTANCE hinstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
WNDCLASS wndclass;
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.hCursor=::LoadCursor(NULL,IDC_ARROW);
wndclass.hIcon=::LoadIcon(NULL,IDI_APPLICATION);
wndclass.hInstance=hinstance;
wndclass.lpfnWndProc=WndProc;
wndclass.lpszClassName="window";
wndclass.lpszMenuName=NULL;
wndclass.style=CS_HREDRAW|CS_VREDRAW;
if(::RegisterClass(&wndclass)==NULL)
{
MessageBox(NULL,"class error","错误",MB_OK|MB_ICONWARNING);
}

HWND hwnd=::CreateWindow("window","时钟",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hinstance,NULL);
if(hwnd==NULL)
{
MessageBox(NULL,"window error","错误",MB_OK|MB_ICONWARNING);

}
::ShowWindow(hwnd,SW_SHOW);
::UpdateWindow(hwnd);

MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc(HWND hwnd,UINT umsg,WPARAM wparam,LPARAM lparam)
{
HDC dc_biao_pang=GetDC(hwnd);
RECT rect;
::GetClientRect(hwnd,&rect);
::SetMapMode(dc_biao_pang,MM_ISOTROPIC);
::SetWindowExtEx(dc_biao_pang,500,500,NULL);
::SetViewportExtEx(dc_biao_pang,500,-500,NULL);
::SetViewportOrgEx(dc_biao_pang,rect.right/2,rect.bottom/2,NULL);

switch(umsg)
{
LPPAINTSTRUCT ps;
case WM_CREATE: ::SetTimer(hwnd,IDT_TIME,100,NULL);

break;
case WM_TIMER:
InvalidateRect(hwnd,NULL,TRUE );
break;
case WM_PAINT:
BeginPaint(hwnd, ps);
biaopang( hwnd,dc_biao_pang);
zhizheng( hwnd,dc_biao_pang);
EndPaint(hwnd, ps);
break;
case WM_DESTROY:
::PostQuitMessage(0);
break;
default:
return ::DefWindowProc(hwnd,umsg,wparam,lparam);

}
return 0;
}
void biaopang(HWND& hwnd,HDC & dc_biao_pang)
{
HPEN pen1;
HBRUSH brush1;
pen1=::CreatePen(PS_SOLID,1,RGB(0,0,0));
::SelectObject(dc_biao_pang,pen1);

::Ellipse(dc_biao_pang,-230,230,230,-230);
double x0=0;
double y0=220;
double x_temp=0;
double y_temp=220;
double r1=220;
double hudu= pai/6;
brush1=::CreateSolidBrush(RGB(255,0,0));
::SelectObject(dc_biao_pang,brush1);

for(int i=1;i<=12;i++)
{
x_temp=r1*cos(hudu*i);
y_temp=r1*sin(hudu*i);
::Ellipse(dc_biao_pang,(int)x_temp-10,(int)y_temp+10,(int)x_temp+10,(int)y_temp-10);
}
brush1=::CreateSolidBrush(RGB(0,0,0));
::SelectObject(dc_biao_pang,brush1);
::Ellipse(dc_biao_pang,10,10,-10,-10);
}
void zhizheng(HWND& hwnd,HDC& dc_biao_pang)
{
HDC dc_hour=dc_biao_pang;
HDC dc_minute=dc_biao_pang;
HDC dc_second=dc_biao_pang;
HPEN pen_hour=CreatePen(PS_SOLID,5,RGB(255,0,0));
HPEN pen_minute=CreatePen(PS_SOLID,3,RGB(0,255,0));
HPEN pen_second=CreatePen(PS_SOLID,1,RGB(0,0,255));


POINT hour;
POINT minute ;
POINT second ;
double r_hour=100;
double r_minute=150;
double r_second=200;

SYSTEMTIME systemtime;
::GetLocalTime(&systemtime);
hour.x=(LONG)(r_hour*sin(2*pai*systemtime.wHour/12+pai/6*systemtime.wMinute/60));
hour.y=(LONG)(r_hour*cos(2*pai*systemtime.wHour/12+pai/6*systemtime.wMinute/60));
minute.x=(LONG)(r_minute*sin(2*pai*systemtime.wMinute/60));
minute.y=(LONG)(r_minute*cos(2*pai*systemtime.wMinute/60));
second.x=(LONG)(r_second*sin(2*pai*systemtime.wSecond/60));
second.y=(LONG)(r_second*cos(2*pai*systemtime.wSecond/60));
::SelectObject(dc_hour,pen_hour);

::MoveToEx(dc_hour,0,0,NULL);
::LineTo(dc_hour,hour.x,hour.y);

::SelectObject(dc_minute,pen_minute);

::MoveToEx(dc_minute,0,0,NULL);
::LineTo(dc_minute,minute.x,minute.y);
::SelectObject(dc_second,pen_second);

::MoveToEx(dc_second,0,0,NULL);
::LineTo(dc_second,second.x,second.y);


}

...全文
171 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
aKAKAKABUTO 2010-12-20
  • 打赏
  • 举报
回复
请问?我看不懂你们说啥!
Show_Mike 2009-01-05
  • 打赏
  • 举报
回复
创建dc,用完后,要及时releaseDC().
dch4890164 2009-01-05
  • 打赏
  • 举报
回复

LRESULT CALLBACK WndProc(HWND hwnd,UINT umsg,WPARAM wparam,LPARAM lparam)
{
HDC dc_biao_pang=GetDC(hwnd);//注意你的这一句话
RECT rect;
::GetClientRect(hwnd,&rect);
::SetMapMode(dc_biao_pang,MM_ISOTROPIC);
::SetWindowExtEx(dc_biao_pang,500,500,NULL);
::SetViewportExtEx(dc_biao_pang,500,-500,NULL);
::SetViewportOrgEx(dc_biao_pang,rect.right/2,rect.bottom/2,NULL);

switch(umsg)
{
LPPAINTSTRUCT ps;
case WM_CREATE: ::SetTimer(hwnd,IDT_TIME,100,NULL);

break;
case WM_TIMER:
InvalidateRect(hwnd,NULL,TRUE );
break;
case WM_PAINT:
BeginPaint(hwnd, ps);
biaopang( hwnd,dc_biao_pang);
zhizheng( hwnd,dc_biao_pang);
EndPaint(hwnd, ps);
break;
case WM_DESTROY:
::PostQuitMessage(0);
break;
default:
return ::DefWindowProc(hwnd,umsg,wparam,lparam);

}
return 0;
}


每次处理一个消息你都会创建一个dc,不死机不太可能
Tinary3v0 2009-01-05
  • 打赏
  • 举报
回复
改了一下,主要部分注释了:
#define pai 3.1415
#define IDT_TIME 1

#include<windows.h>
#include<cmath>

void biaopang(HWND&,HDC&);

void zhizheng(HWND& ,HDC&);

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

int WINAPI WinMain(HINSTANCE hinstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
WNDCLASS wndclass;
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.hCursor=::LoadCursor(NULL,IDC_ARROW);
wndclass.hIcon=::LoadIcon(NULL,IDI_APPLICATION);
wndclass.hInstance=hinstance;
wndclass.lpfnWndProc=WndProc;
wndclass.lpszClassName="window";
wndclass.lpszMenuName=NULL;
wndclass.style=CS_HREDRAW|CS_VREDRAW;
if(::RegisterClass(&wndclass)==NULL)
{
MessageBox(NULL,"class error","错误",MB_OK|MB_ICONWARNING);
}

HWND hwnd=::CreateWindow("window","时钟",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hinstance,NULL);
if(hwnd==NULL)
{
MessageBox(NULL,"window error","错误",MB_OK|MB_ICONWARNING);

}
::ShowWindow(hwnd,SW_SHOW);
::UpdateWindow(hwnd);

MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam ;
}

LRESULT CALLBACK WndProc(HWND hwnd,UINT umsg,WPARAM wparam,LPARAM lparam)
{
switch(umsg)
{
PAINTSTRUCT ps;
case WM_CREATE:
::SetTimer(hwnd,IDT_TIME,100,NULL);
break;
case WM_TIMER:
{
InvalidateRect(hwnd,NULL,FALSE );
break;
}
case WM_PAINT:
{
HDC dc_biao_pang = GetDC(hwnd);
RECT rect;
::GetClientRect(hwnd,&rect);
::SetMapMode(dc_biao_pang,MM_ISOTROPIC);
::SetWindowExtEx(dc_biao_pang,500,500,NULL);
::SetViewportExtEx(dc_biao_pang,500,-500,NULL);
::SetViewportOrgEx(dc_biao_pang,rect.right/2,rect.bottom/2,NULL);

BeginPaint(hwnd, &ps); //PAINTSTRUCT ps;要这样定义 如果定义成LPPAINTSTRUCT ps;就成了指针了,需要new出来
biaopang( hwnd,dc_biao_pang);
zhizheng( hwnd,dc_biao_pang);
EndPaint(hwnd, &ps);

::DeleteDC(dc_biao_pang);

break;
}
case WM_DESTROY:
::PostQuitMessage(0);
break;
default:
return ::DefWindowProc(hwnd,umsg,wparam,lparam);
}

return 0;
}

void biaopang(HWND& hwnd,HDC & dc_biao_pang)
{
HPEN pen1;
HBRUSH brush1;
pen1=::CreatePen(PS_SOLID,1,RGB(0,0,0));
::SelectObject(dc_biao_pang,pen1);

::Ellipse(dc_biao_pang,-230,230,230,-230);
double x0=0;
double y0=220;
double x_temp=0;
double y_temp=220;
double r1=220;
double hudu= pai/6;
brush1=::CreateSolidBrush(RGB(255,0,0));
::SelectObject(dc_biao_pang,brush1);

for(int i=1;i<=12;i++)
{
x_temp=r1*cos(hudu*i);
y_temp=r1*sin(hudu*i);
::Ellipse(dc_biao_pang,(int)x_temp-10,(int)y_temp+10,(int)x_temp+10,(int)y_temp-10);
}
brush1=::CreateSolidBrush(RGB(0,0,0));
::SelectObject(dc_biao_pang,brush1);
::Ellipse(dc_biao_pang,10,10,-10,-10);

::DeleteObject(pen1); //清理资源
::DeleteObject(brush1);
}

void zhizheng(HWND& hwnd,HDC& dc_biao_pang)
{
HDC dc_hour=dc_biao_pang;
HDC dc_minute=dc_biao_pang;
HDC dc_second=dc_biao_pang;
HPEN pen_hour=CreatePen(PS_SOLID,5,RGB(255,0,0));
HPEN pen_minute=CreatePen(PS_SOLID,3,RGB(0,255,0));
HPEN pen_second=CreatePen(PS_SOLID,1,RGB(0,0,255));

POINT hour;
POINT minute ;
POINT second ;
double r_hour=100;
double r_minute=150;
double r_second=200;

SYSTEMTIME systemtime;
::GetLocalTime(&systemtime);
hour.x=(LONG)(r_hour*sin(2*pai*systemtime.wHour/12+pai/6*systemtime.wMinute/60));
hour.y=(LONG)(r_hour*cos(2*pai*systemtime.wHour/12+pai/6*systemtime.wMinute/60));
minute.x=(LONG)(r_minute*sin(2*pai*systemtime.wMinute/60));
minute.y=(LONG)(r_minute*cos(2*pai*systemtime.wMinute/60));
second.x=(LONG)(r_second*sin(2*pai*systemtime.wSecond/60));
second.y=(LONG)(r_second*cos(2*pai*systemtime.wSecond/60));
::SelectObject(dc_hour,pen_hour);

::MoveToEx(dc_hour,0,0,NULL);
::LineTo(dc_hour,hour.x,hour.y);

::SelectObject(dc_minute,pen_minute);

::MoveToEx(dc_minute,0,0,NULL);
::LineTo(dc_minute,minute.x,minute.y);
::SelectObject(dc_second,pen_second);

::MoveToEx(dc_second,0,0,NULL);
::LineTo(dc_second,second.x,second.y);

::DeleteDC(dc_hour); //清理GDI资源
::DeleteDC(dc_minute);
::DeleteDC(dc_second);
::DeleteObject(pen_hour);
::DeleteObject(pen_minute);
::DeleteObject(pen_second);
}
多了就不说了,楼上的已经说了很多了。
另外楼主最好是从建立一个Win32 Application 然后选择那个HelloWorld程序 在那个程序基础上改动实现楼主的功能比较好。
fandh 2009-01-04
  • 打赏
  • 举报
回复
很明显是GDI资源没有释放造成的!
对于GDI资源,create的,肯定要自己delete的
dc在用的话,如果是GetDC();要记得RealeseDC();
bitmap、brush、pen等要记得deleteobj;有些局部的,在2000以后的系统,感觉不明显,但是,在98系统里面,是不能释放的!所以,一定要养成配对使用的好习惯!
cnzdgs 2009-01-04
  • 打赏
  • 举报
回复
GetDC最后要ReleaseDC;自己创建的GDI对象,在选入DC时要保存SelectObject的返回值,画完后再次调用SelectObject选入上次的返回值,然后用DeleteObject把自己创建的对象删除。
另外,响应WM_PAINT消息不需要GetDC,BeginPaint会返回DC。
ringphone 2009-01-04
  • 打赏
  • 举报
回复
GetDC之后要ReleaseDC
最严重的是你把GetDC放在了消息过程的一开始,不管什么消息你都GetDC一下,又不Release,很快就会资源耗尽。
WM_PAINT消息里面你BeginPaint,EndPaint倒是没错,可是你又没用到BeginPaint获取的DC,又白费了。

程序修改:
删除HDC dc_biao_pang=GetDC(hwnd);那一行,
biaopang(hwnd,dc_biao_pang);和zhizheng( hwnd,dc_biao_pang);的第2个参数改成ps.hdc
其他创建的Brush或Pen要么改成全局变量,程序开始时创建,结束时DeleteObject,要么就在函数开始时Create,绘制结束时DeleteObject。

danxuezx 2009-01-04
  • 打赏
  • 举报
回复
释放资源很重要!
wltg2001 2009-01-03
  • 打赏
  • 举报
回复
你创建的GDI对象都没有释放,而且是在定时器中不停的创建,时间一长,资源不够当然会出问题
oyljerry 2009-01-03
  • 打赏
  • 举报
回复
GDI画图等,用完了要释放资源...
DeleteObject()

SelectObject()用完了要重置为old object
mynamelj 2009-01-03
  • 打赏
  • 举报
回复
说错了,是一毫秒
mynamelj 2009-01-03
  • 打赏
  • 举报
回复
建议你把那些GDI对象先创建,不要每次执行到那里都要去重要创建,尽量减少系统的开支.

另外定时器0.1毫秒执行一次刷屏,频率有些高,这几乎是用DirectDraw才能办到的事情.
============================== SkinMagic SDK Version Beta0.7 ============================== SkinMagic SDK是为C/C++程序员设计的函数库,通过使用该库提供的API可以很方便的为你 的应用程序增加最流行的换皮肤的功能。SkinMagic是基于图片的皮肤系统,只要简单的几个 函数调用你的应用程序就具有了换皮肤的功能。通过SkinMagicBuilder皮肤编辑工具,你可以 定制自己特色的皮肤。 欢迎访问:www.appspeed.com获得最新的SkinMagic SDK的信息和最新版本。 http://www.appspeed.com/ http://www.appspeed.com/download/SkinMagicSDK_beta0.7.exe ===== 开发历史 ===== 2002.12.29 Beta0.7 增加功能: 1,增加了Spin控制的换皮肤功能。 2,增加了ProgressBar的换皮肤功能。 3,增加了ScrollBar控制的换皮肤功能。 4,增加了Slider控制的换皮肤功能。 5,增加ComboBox换皮肤功能。 6,增加了ShapeWnd的支持。 解决问题: 1, 解决了MDI窗口菜单刷新很慢的问题。 2,解决了有时只有工具栏换了皮肤的问题。 3,解决了更换皮肤文件的时候工具栏没有及时刷新问题。 4,解决了MDI窗口多次换皮肤导致内存泄漏的问题。 7,设置皮肤后依照皮肤的要求调整窗口的大小,不至于显示不正常。 8,解决在Win98/WINNT下死机问题。 9, 解决了MDI窗口在切换皮肤的时候,子窗口的刷新速度太慢,另外MDIClient窗口有时候会没有完全刷新。 10,解决了如果定义了Client为图像会出现MDI子窗口无法刷新问题
请先阅读帮助文档:http://ismyway.com/help [2009.1.1] Ver 3.2.26 ※如果安装提示证书过期或无法安装,请在手机上将时间改为2008.8.8,安装设置完成后再将日期改回即可!※ 增加天语的按键映射 增加三星的背景灯控制功能(该功能未在真机上测试过) 删除图片浏览中的部分功能,由于这部分功能需要较大的内存,导致在大部分手机上无法完成,同时也引起背景图片无法设置成功 触摸屏用户可以不再受滚动条限制,在屏幕上任意地方都可以进行拖动 选择键盘映射为其它时无法再次更改的BUG 用户输入的颜色值无法保存的BUG 修正英文单词分词时会多添加一个空行的BUG 繁体语言措词上的修正 阅读设置中增加一个“文件缓存”选项,默认情况下是开启的,在NOKIA手机上会提高UMD等文件的表现,但由于测试并不充足,如果程序经常在阅读时出错,请关闭该选项(其它手机是否开启该选项并无明显的影响) 修正编辑文件后无法保存的BUG [2008.10.27] Ver 3.2.24 ※如果安装提示证书过期或无法安装,请在手机上将时间改为2008.8.8,安装设置完成后再将日期改回即可!※ 改进的颜色选择方式 允许用户重新选择键盘映射 HTML阅读时的错误 进一步完善编辑功能(仍有少许BUG,请继续反馈,谢谢) 新建文件后自动跳转到编辑中 改进的文件操作方式,速度轻微提升 UMD速度明显提升,并且减少内存占用,特别是在NOKIA手机上,表现提升超过600% 改进的输入框模式,以使得能适应更多的手机如天语等 [2008.10.21] Ver 3.2.23 为了提高运行效率,以下功能在LITE上将被取消(自定义欢迎页问候语;欢迎页背景图) 取消了JAR的支持,提高运行效率 修正打开大ZIP文件时的内存溢出错误 ·修正:  自动滚屏到末尾时,滚屏功能将停止 [2008.10.4] Ver 3.2.22 暂时删除了播放功能及网络相关的功能,由于以上两项功能一直没有能稳定下来,故暂时删除 增强了ZIP功能,支持带文件夹结构的ZIP/JAR文件 (对于大部分JAR电子书都,可以从文件管理器中找到非.class结尾的文件,并且选择打开为UNICODE/TXT阅读) (对于NOKIA手机及其它部分手机,由于安全策略的限制,在Anyview的文件管理器中无法查看后缀为.jar的文件) 自定义问候语(系统路径下dictum.rc文件,格式参见jar包中的dictum.rc文件,保存时使用UTF-8编码,可写条目为0~9/a~z/A~Z,置空时表示不显示问候语) ·修正:  0键在各偏好中切换时亮度混乱的问题  部分手机上无法新建文件夹 [2008.9.11] Ver 3.2.21 修正动画参数无法保存的BUG 动画效果不再对阅读翻页有作用 [2008.8.29] Ver 3.2.21 可将正在阅读的内容通过短信与好友分享 增加一种新的滚屏方式:波浪,同时,阅读时3键不再使用默认的像素滚屏,而会使用最后一次使用的滚屏方式 任何可用的外置字库都可以作为内置字库存在,在jar包中存在dot.font会被当为内置字库加载 加快大文件的打开速度,特别是对于NOKIA手机,S60上,打开20M文件,97%左右的位置不超过15秒 允许用户打开动画效果 ·M600/P990/P1/W950  修正键盘映射时“内存不足”的BUG ·E680/A780  选中后台播放后无法启动的BUG [2008.7.30] Ver 3.2.20 调整部分索爱手机上背景灯控制的逻辑 修正看图片时按0键出错的BUG 旋转屏幕引起的字外出 打开LRC最后出错 阅读到尾部弹出“上一个/下一个”窗口中的文件名过长不刷新问题 偏好切换时亮度混乱的问题 在NOKIA上,当系统路径设置为根目录是无法启动的BUG E398上可以开关键盘灯 UIQ系统在退出时可以保持亮度 索爱上按“返回”键后导致阅读出现白屏的BUG 阅读时切换屏幕方向导致字体超出屏幕的BUG 欢迎屏幕上的日期使用中文显示 如果使用触屏手机,跳转改为进度条模式,以方便触屏操作 系统路径下如果存在bg.png文件,则会作为欢迎界面的背景图片显示(右下角) 减少跳转及翻页中出现乱码的机率 提高阅读时绘图效率,滚屏效率同样提高 播放时,暂停会导致声音爆至最大的BUG 内置“忘记月亮”制作的两款主题《典雅红》《黑橙》,并且更换主题不再要求退出 文件管理器中支持“剪切”功能 文件管理器中新增转换UMD为TXT的功能(解开操作,解开2无效!) 增加了编辑功能(尽管没有限制文件大小,但请别编辑过大的文件,另外,为了提高速度,不进行全文排版,有时候表现可能会有些不习惯),以后会进一步完善 启动时,会自动识别NOKIA、SONYER

16,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧