继续双缓冲(各位,我又来了)

luocan1986 2009-08-19 03:30:12
我写的双缓冲程序,运行一段时间界面就停住了,不知道下面代码由啥问题。


/*
* FILE: DrawClock.cpp
*/
#include "clock.h"
#include "resource.h"
#include <Windows.h>
#include <CommCtrl.h>
#define PI 3.141592

extern int hour, minute, second;
extern HDC hdc;
extern HWND hWnd;
extern HINSTANCE hInst;
extern HBITMAP hBitmap2;

/* Fuction:DrawClock
* 画时针,分针,和秒针的处理函数.
*/
void DrawLine(HDC hMemDC)
{
//获取系统时间的解构体
SYSTEMTIME sys;
HBRUSH hBr, hOldBr,hNewBr;
HPEN hPen,hOldPen;
TCHAR cTime[64];

//指针的终点坐标
int SecondX ,SecondY, MinuteX, MinuteY, HourX, HourY;

GetLocalTime(&sys);
SecondX = 140 + 90 * sin((sys.wSecond * PI) / 30 );
SecondY = 160 - 90 * cos((sys.wSecond * PI) / 30 );
MinuteX = 140 + 60 * sin((sys.wMinute * PI) / 30 );
MinuteY = 160 - 60 * cos((sys.wMinute * PI) / 30 );
HourX = 140 + 35 * sin((sys.wHour * PI) / 6 );
HourY = 160 - 35 * cos((sys.wHour * PI) / 6 );

//内存上画线
hPen = CreatePen(PS_SOLID, 1, RGB(0xff, 0xff, 0x00));
hOldBr = (HBRUSH) SelectObject(hMemDC, hPen);
MoveToEx(hMemDC, 140, 160, NULL);
LineTo(hMemDC, SecondX, SecondY);
SelectObject(hMemDC, hOldBr);
DeleteObject(hPen);

hPen = CreatePen(PS_SOLID, 2, RGB(0xff, 0xff, 0x00));
hOldBr = (HBRUSH) SelectObject(hMemDC, hPen);
MoveToEx(hMemDC, 140, 160, NULL);
LineTo(hMemDC, MinuteX, MinuteY);
SelectObject(hMemDC, hOldBr);
DeleteObject(hPen);

hPen = CreatePen(PS_SOLID, 3, RGB(0xff, 0xff, 0x00));
hOldBr = (HBRUSH) SelectObject(hMemDC, hPen);
MoveToEx(hMemDC, 140, 160, NULL);
LineTo(hMemDC, HourX, HourY);
SelectObject(hMemDC, hOldBr);
DeleteObject(hPen);



wsprintf(cTime, L"Hour:%2d Minute:%2d Second:%2d", sys.wHour, sys.wMinute, sys.wSecond);
SetDlgItemText(hWnd, IDC_EDIT1, cTime);

//如果时间相等 就像主窗口发送一个信号 要求处理闹钟
if ((sys.wHour == hour) && (sys.wMinute == minute) && (sys.wSecond == second))
{
MessageBox(hWnd, TEXT("Time is up!"), TEXT("ALARM"), MB_OKCANCEL);
PlaySound(TEXT("MouseClick"), NULL, SND_SYNC);
}

}



/* Fuction:clockDraw
* 绘制背景的双缓冲处理函数,这样避免了屏幕闪烁的问题。
*/

void clockDraw()
{
HDC hdcMem, hdcMemBuf;
RECT rt;
PAINTSTRUCT ps;
HBITMAP hBitmap;

HBITMAP hBitmap2;
hBitmap2 = LoadBitmap(hInst,MAKEINTRESOURCE(IDB_BITMAP1));

//创建第一个内存DC
hdcMem = CreateCompatibleDC( hdc );

//创建缓冲位图,先把图画到这张空白位图上,小心!第一个参数是用目的 DC 才能创建彩色位图,否则只是单色!
hBitmap = CreateCompatibleBitmap( hdc, 638, 429);

//创建第二个内存DC
hdcMemBuf = CreateCompatibleDC( hdc );

//将空白位图选进第一缓冲区
SelectObject( hdcMem, hBitmap );

//用背景色刷一下
GetClientRect(hWnd, &rt);
FillRect( hdcMem, &rt, NULL );

//将要贴上去的图选进第二缓冲区
SelectObject( hdcMemBuf, hBitmap2);

//将第二个内存DC传给第一内存DC
BitBlt( hdcMem, 0, 0, 638, 429, hdcMemBuf, 0, 0, SRCCOPY );

//画线
DrawLine(hdcMem);

//最后画到目的 DC 上
BitBlt( hdc, 0, 0, 638, 429, hdcMem, 0, 0, SRCCOPY );

//结束操作
DeleteDC( hdcMemBuf );
DeleteObject( hBitmap );
DeleteObject( hBitmap2 );
DeleteDC( hdcMem );

}
...全文
82 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
luocan1986 2009-08-19
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 lambochan 的回复:]
//将空白位图选进第一缓冲区
SelectObject( hdcMem, hBitmap );       

//将要贴上去的图选进第二缓冲区
SelectObject( hdcMemBuf, hBitmap2);

这两个有泄漏.
应该先保存,再选出,最后del:
HBITMAP hOldBmp1 = ( HBITMAP )SelectObject( hdcMem, hBitmap );
HBITMAP hOldBmp2 = ( HBITMAP )SelectObject( hdcMemBuf, hBitmap2);
..........
...
.
//结束操作
SelectObject( hdcMem, hOldBmp1 ); // 选出
SelectObject( hdcMemBuf, hOldBmp2 ); // 选出
DeleteDC( hdcMemBuf );
DeleteObject( hBitmap );
DeleteObject( hBitmap2 );
DeleteDC( hdcMem );



[/Quote]

感谢 感谢。。就是这个问题!导致内存泄露了。
lambochan 2009-08-19
  • 打赏
  • 举报
回复
//将空白位图选进第一缓冲区
SelectObject( hdcMem, hBitmap );

//将要贴上去的图选进第二缓冲区
SelectObject( hdcMemBuf, hBitmap2);

这两个有泄漏.
应该先保存,再选出,最后del:
HBITMAP hOldBmp1 = ( HBITMAP )SelectObject( hdcMem, hBitmap );
HBITMAP hOldBmp2 = ( HBITMAP )SelectObject( hdcMemBuf, hBitmap2);
..........
...
.
//结束操作
SelectObject( hdcMem, hOldBmp1 ); // 选出
SelectObject( hdcMemBuf, hOldBmp2 ); // 选出
DeleteDC( hdcMemBuf );
DeleteObject( hBitmap );
DeleteObject( hBitmap2 );
DeleteDC( hdcMem );


luocan1986 2009-08-19
  • 打赏
  • 举报
回复
MFC 还没怎么接触过 不太了解。
qingfeng_happy5 2009-08-19
  • 打赏
  • 举报
回复
给你贴一段代码,是我在开发过程中经常用到的双缓冲绘图方法。

void CIDLampStatic::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: 在此处添加消息处理程序代码
// 不为绘图消息调用 CStatic::OnPaint()

CRect rect,rectClient;
GetClientRect(rectClient);
rect=rectClient;

//创建内存DC
CDC memDC;
memDC.CreateCompatibleDC(&dc);

//创建一个和绘图对象尺寸相同的兼容位图,此即相当于是内存中绘图的画布
CBitmap bmp,*oldBmp;
bmp.CreateCompatibleBitmap(&dc,rect.Width(),rect.Height());

oldBmp=memDC.SelectObject(&bmp);

//以下就可以用内存DC进行任意绘图操作了。

CBrush brush,*oldBrush;
brush.CreateSolidBrush(MASTER_COLOR);

oldBrush=memDC.SelectObject(&brush);

memDC.FillRect(rect,&brush);

memDC.SetBkMode(TRANSPARENT);

memDC.DrawText(m_strIdText,m_rtTextRect,DT_LEFT|DT_VCENTER|DT_SINGLELINE);

//在内存中绘制完成后,将绘制好的图搬到屏幕上显示出来
dc.BitBlt(0,0,rectClient.Width(),rectClient.Height(),&memDC,0,0,SRCCOPY);

memDC.SelectObject(oldBmp);
memDC.SelectObject(oldBrush);

}
dushuchen 2009-08-19
  • 打赏
  • 举报
回复
啥叫双缓冲?

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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