Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Как реализовать двойную буферизацию?


Автор: devmstr 18.9.2004, 10:15
Как реализовать двойную буферизацию?

Вот я попробовал её реализовать, только что-то ничего не получается. А правильно ли я вообще понял идею буферизации. Вначале во временный DC загружаю BITMAP, потом расстягиваю его до нужных размеров, копируя в другой временный DC(StretchBlt). Затем функцией BitBtl "показываю" второй временный канвас(а такли нужно делать?). Где ошибка?


LONG WINAPI WindProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
HDC hdc,hCompatibleDC,hCD;
static HANDLE hBitmap;
HANDLE hOldBitmap;
BITMAP Bitmap;
PAINTSTRUCT ps;
RECT rect;
switch (msg)
{
case WM_CREATE:
hBitmap=LoadImage(NULL,"s.bmp",IMAGE_BITMAP,NULL,NULL,LR_LOADFROMFILE);
break;
case WM_DESTROY:
DeleteObject(hBitmap);
PostQuitMessage(0);
break;
case WM_PAINT:
hdc=BeginPaint(hwnd,&ps);
hCompatibleDC=CreateCompatibleDC(hdc);
hCD=CreateCompatibleDC(hdc);
hOldBitmap=SelectObject(hCompatibleDC,hBitmap);
GetObject(hBitmap,sizeof BITMAP,&Bitmap);
GetClientRect(hwnd,&rect);

SetStretchBltMode(hCD,COLORONCOLOR);
StretchBlt(hCD,0,0,rect.right,rect.bottom,
hCompatibleDC,0,0,Bitmap.bmWidth,
Bitmap.bmHeight,SRCCOPY);
BitBlt(hdc,0,0,rect.right,rect.bottom,hCD,0,0,SRCCOPY);

SelectObject(hdc,hOldBitmap);
EndPaint(hwnd,&ps);
DeleteDC(hCompatibleDC);
DeleteDC(hCD);

break;
case WM_SIZE:
InvalidateRect(hwnd,NULL,true);
break;
default:
return DefWindowProc(hwnd,msg,wparam,lparam);
}
return 0;
}

Просветите ламера?

Автор: Step 18.9.2004, 10:47
ИМХО
для hCD нужно установить битмеп пусть и нулевой....
и вообще при работе с битмепами необходима на каждое устройсво биткарту пусть даже пустую.....

Где то это обсуждалось сделайте поиск по StretchBlt или BitBlt

Автор: Атос 18.9.2004, 10:57
Не очень понял код... Читать трудно...

Но может не надо SelectObject(hdc, hOldBitmap)?

точнее:

Код

  HDC dc = BeginPaint(hwnd, &ps);

  hdc dcBUF = CreateComp....
  hbmp bmpBUF = CreateCompBitm...
  SelectObject(dcBUF, bmpBUF);

  // рисуем в bmpBUF посредством dcBUF

 BitBlt(hdc, 0, 0, width, height, dBUF);

 EndPaint(hwnd, &ps)

Автор: mr.DUDA 18.9.2004, 13:56

Модератор: пользуйтесь С++ FAQ или поиском!!!

ссылка на тему, являющуюся прямым ответом на поставленный вопрос:
http://forum.vingrad.ru/index.php?showtopic=19425&view=findpost&p=181201

Автор: devmstr 18.9.2004, 20:19
Спасибо Вам. Постараюсь воспользоваться Вашим советом.
Я посмотрел тот пример.
У меня вообщем был вначале полностью рабочий код
{
HDC hdc,hCompatibleDC;
static HANDLE hBitmap;
HANDLE hOldBitmap;
BITMAP Bitmap;
PAINTSTRUCT ps;
RECT rect;
switch (msg)
{
case WM_CREATE:
hBitmap=LoadImage(NULL,"s.bmp",IMAGE_BITMAP,NULL,NULL,LR_LOADFROMFILE);
break;
case WM_DESTROY:
DeleteObject(hBitmap);
PostQuitMessage(0);
break;
case WM_PAINT:
hdc=BeginPaint(hwnd,&ps);
hCompatibleDC=CreateCompatibleDC(hdc);
hOldBitmap=SelectObject(hCompatibleDC,hBitmap);
GetObject(hBitmap,sizeof BITMAP,&Bitmap);
GetClientRect(hwnd,&rect);
SetStretchBltMode(hdc,COLORONCOLOR);
StretchBlt(hdc,0,0,rect.right,rect.bottom,
hCompatibleDC,0,0,Bitmap.bmWidth,
Bitmap.bmHeight,SRCCOPY);
SelectObject(hdc,hOldBitmap);
EndPaint(hwnd,&ps);
DeleteDC(hCompatibleDC);


break;
case WM_SIZE:
InvalidateRect(hwnd,NULL,true);
break;
default:
return DefWindowProc(hwnd,msg,wparam,lparam);
}
return 0;
}


Все классно (ну почти) работало. Я имею некоторые проблемы с "пониманием" макросов и программ на WinApi, так как вообщем только недавно перешел на С++ и на API.
Посмотрев Ваш пример мне кажется, что приведенная программа и так поддерживает двойную буф., так как все действия я проводил на другом Dc, что в принцыпе и является(ну я так понимаю) основой метода двойной буфферизации.
Единственно, меня не устраивает во всем этом, так это появления небольших полос во время изменения размера формы.
Как от них избавиться.
sad.gif

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)