Поиск:

Ответ в темуСоздание новой темы Создание опроса
> рисование без мерцания 
:(
    Опции темы
drazah
Дата 3.11.2010, 23:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 3.11.2010

Репутация: нет
Всего: нет



Мне нужно сделать примитивную анимацию - миниатюрный танк   "ползет" по формочке.
Я делаю так. Создаю таймер. В его обработчике пишу:


Код

void CMainWnd::OnTimer(UINT)
{
     xCurrent += 5; // увеличили текущую координату по иксу
     Invalidate(); // вызов метода OnPaint ?? 
}


Отрисовка окна такая:

Код

void CMainWnd::OnPaint()
{
      CPaintDC dc(this);
      drawTank(dc); //функции отрисовки танка
}


На выходе все рисуется, но мерцает =(  Подтолкните на путь истинный! В частности сам подход c этим Invalidate вообще верный или надо как-то по другому все организовывать?

P.S. Нашел похожую тему. http://forum.vingrad.ru/forum/topic-52762/unread-1.html 
взял код от туда, а именно

Код

void CMainWnd::OnPaint()
{
        CDC * pDCDest=GetDC();    
        CDC dcMem;    
        dcMem.CreateCompatibleDC(pDCDest);    
        CBitmap *pPrevBmpMem=dcMem.GetCurrentBitmap();    
        CRect rCl;    
        GetClientRect(rCl);    
        CBitmap BmpNewMem;    
        BmpNewMem.CreateCompatibleBitmap(pDCDest, rCl.Width(), rCl.Height());    
        dcMem.SelectObject(&BmpNewMem);    
        dcMem.FillSolidRect(rCl, RGB(255,255,255));    
        CDC *pDCTemp=pDCDest;    
        pDCDest=&dcMem;    


        CDC memDC;    
     
        my_tank.drawTank(pDCDest);   


        pDCDest=pDCTemp;    
        pDCDest->BitBlt(rCl.left, rCl.top, rCl.Width(), rCl.Height(), &dcMem,rCl.left, rCl.top, SRCCOPY);    
        dcMem.SelectObject(pPrevBmpMem);
}


Танк вообще не двигается. 

PM MAIL   Вверх
Cheloveck
Дата 3.11.2010, 23:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: нет
Всего: 32



Цитата(drazah @  3.11.2010,  23:50 Найти цитируемый пост)
Подтолкните на путь истинный! 

Для отрисовки анимации средствами GDI делают так:
  • Создают новый контекст рисования совместимый с тем, на котором нужно рисовать (CreateCompatibleDC);
  • Создают новый битмап, опять же, совместимый (CreateCompatibleBitmap);
  • Устанавливают новый битмап в новый контекст (SelectObject);
  • Рисуют на новом контексте;
  • Копируют новый контекст в тот, на который нужно рисовать (BitBlt).
Сие называется двойная буфиризация.

Это сообщение отредактировал(а) Cheloveck - 4.11.2010, 00:00


--------------------
user posted image
PM Jabber   Вверх
drazah
Дата 4.11.2010, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 3.11.2010

Репутация: нет
Всего: нет



Спасибо, Cheloveck.
Как я понимаю, это все писать в фунции отрисовки. Делал  так:
Код

void CMainWnd::OnPaint() 
{
    CPaintDC dc (this);

    // Создание совместимого контекста устройства 
    CDC dcMem;
    
    // Создаю битмап
    CBitmap bitmap;
        
    // Определение размеров клиентской области окна
    RECT rect;
    this->GetClientRect(&rect);


    dcMem.CreateCompatibleDC(&dc);
    bitmap.CreateCompatibleBitmap( &dcMem, rect. right, rect.bottom ) ;
    dcMem.SelectObject( &bitmap );
    //рисую на новом контексте
    dcMem.LineTo(11,400); //- вызов функции рисования 

    // Копирование содержимого одного контекста в другой 
    dc.BitBlt( 0, 0, rect.right, rect.bottom, &dcMem, 0, 0, 0) ; 

    // Удаление совместимого контекста устройства
    dcMem.DeleteDC(); 
}

В функции таймера не менял ничего. На выходе - черное мерцающее окно) 
Можете подправить где что не так?
PM MAIL   Вверх
voov
Дата 23.11.2010, 14:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Патамушта мы пилоты
**


Профиль
Группа: Участник
Сообщений: 460
Регистрация: 29.11.2007

Репутация: 8
Всего: 8



drazah, разбираться нету времени. Вот кусок рабочего кода, разберись сам.

Код

void CBarChildWnd::OnPaint()
{
    CPaintDC dc(this); // device context for painting
    // Do not call CWnd::OnPaint() for painting messages

    // Двойная буфферизация
    CRect rectBuf;                    // Это нам для координат
    GetClientRect(&rectBuf);        // Получим координаты
    CDC mem;                        // Вспомогательный контест
    mem.CreateCompatibleDC(&dc);    // Создаем его в памяти
    CBitmap btmp;                    // "Пустой вспомогательный растр"
    btmp.CreateCompatibleBitmap(&dc, rectBuf.Width(), rectBuf.Height());    //Создаем и его в памяти
    CBitmap* oldBitmap = mem.SelectObject(&btmp);        // Выбираем этот растр, тем самым создав "невидимое полотно"
    mem.SetBkMode(TRANSPARENT);
    //Начинаем рисовать на "невидимом полотне". Рисуем все что угодно. Даже можем передовать туда растр и т.д.

....
    // получаем размер окна и заливаем фон
    CRect rect;
    GetClientRect(&rect);

    // если установлено выделение - рисуем фокус
    if (m_selected) {
        mem.DrawFocusRect(&rect);
        rect.DeflateRect(SELECTED_OFFSET, SELECTED_OFFSET);
    }

....
    // Теперь все , что нарисовали в один прием передаем на "видимое полотно"
    dc.BitBlt(0, 0, rectBuf.Width(), rectBuf.Height(), &mem, 0, 0, SRCCOPY);

    mem.SelectObject(oldBitmap);
}

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.0503 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.