نقل قول: پویانمایی (Animation)
اگر قرار هست که خودتان مستطیل ها را رسم کنید باید به شکل زیر عمل کنید تا flicker نداشته باشید:
شما در هر فراخوانی WM_Paint/OnDraw یا هر جای دیگر که رسم می کنید، باید یک بافر bitmap به اندازه کل تصویر بسازید، سپس مستطیل ها را در آن رسم کنید و در آخر همه تصویر که به اندازه client area هست را نمایش دهید.
به عبارت دیگر تک تک مستطیل ها را رسم نمی کنید، بلکه همه را در یک بافر عکس رسم می کنید و سپس عکس را نمایش می دهید.
تا جایی که یادم هست روش فوق به double buffer مرسوم هست.
نقل قول: پویانمایی (Animation)
سلام:
بله درست است. double buffer را در كتاب خوانده ام اما مي خواهم توابع مورد نياز و طريقه ي استفاده از آنها را برايم بنويسيد.
با تشكر.
نقل قول: پویانمایی (Animation)
قطعه کد زیر با win32 هست، برای MFC نیز توابع معادل با همین نام ها وجود دارد.
- در برنامه WM_ERASEBKGND را 1 قرار دادیم تا برنامه خودش پس زمینه رسم نکند.
- با CreateCompatibleDC و CreateCompatibleBitmap حافظه مورد نظر برای عکس را می گیریم.
- سپس با Rectangle یک مستطیل در این حافظه رسم می کنیم.
- در پایان نیز با BitBlt کل عکس را از حافظه به تصویر کپی می کنیم و نمایش می دهیم تا flicker نداشته باشیم.
- اگر انیمیشن هست، تایمر بسازید و هر دفعه WM_PAINT را فراخوانی کنید و مکان مستطیل ها را تغییر دهید.
case WM_ERASEBKGND:
return (LRESULT)1;
// ----------------------------------------------------------------
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
//------------------- Method one (Without flickers)-----------------------------
HDC hdcMem;
HBITMAP hbmMem, hbmOld;
HBRUSH hbrBkGnd;
// Get the size of the client rectangle.
GetClientRect(hWnd, &rc);
// Create a compatible DC.
hdcMem = CreateCompatibleDC(hdc);
// Create a bitmap big enough for our client rectangle.
hbmMem = CreateCompatibleBitmap(hdc, rc.right-rc.left,
rc.bottom-rc.top);
// Select the bitmap into the off-screen DC.
hbmOld = (HBITMAP)SelectObject(hdcMem, hbmMem);
// Erase the background.
hbrBkGnd = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
FillRect(hdcMem, &rc, hbrBkGnd);
DeleteObject(hbrBkGnd);
// Render the image into the offscreen DC.
SetBkMode(hdcMem, TRANSPARENT);
SetTextColor(hdcMem, GetSysColor(COLOR_WINDOWTEXT));
DrawText(hdcMem, TEXT("HELLO"), -1, &rc, DT_CENTER);
// Draw Rectangle into the offscreen DC.
hbr1 = CreateSolidBrush (RGB(0,0 ,155));
hbr2 = (HBRUSH) SelectObject (hdcMem, hbr1);
Rectangle (hdcMem, 100, 100, 300, 300);
// Blt the changes to the screen DC.
BitBlt(hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top,
hdcMem, 0, 0, SRCCOPY);
SelectObject (hdc, hbr2);
// Done with off-screen bitmap and DC.
SelectObject(hdcMem, hbmOld);
DeleteObject ( hbr1 );
DeleteObject(hbmMem);
DeleteDC(hdcMem);
//-------------------------------------------------------
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;